hwacpi.c revision 85756
154976Sache
254976Sache/******************************************************************************
354976Sache *
454976Sache * Module Name: hwacpi - ACPI Hardware Initialization/Mode Interface
554976Sache *              $Revision: 46 $
654976Sache *
754976Sache *****************************************************************************/
854976Sache
954976Sache/******************************************************************************
1054976Sache *
1154976Sache * 1. Copyright Notice
1254976Sache *
1354976Sache * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
1454976Sache * All rights reserved.
1554976Sache *
1654976Sache * 2. License
1754976Sache *
1854976Sache * 2.1. This is your license from Intel Corp. under its intellectual property
1954976Sache * rights.  You may have additional license terms from the party that provided
2054976Sache * you this software, covering your right to use that party's intellectual
2154976Sache * property rights.
2254976Sache *
2354976Sache * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2454976Sache * copy of the source code appearing in this file ("Covered Code") an
2554976Sache * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2654976Sache * base code distributed originally by Intel ("Original Intel Code") to copy,
2754976Sache * make derivatives, distribute, use and display any portion of the Covered
2854976Sache * Code in any form, with the right to sublicense such rights; and
2954976Sache *
3054976Sache * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3154976Sache * license (with the right to sublicense), under only those claims of Intel
3254976Sache * patents that are infringed by the Original Intel Code, to make, use, sell,
3354976Sache * offer to sell, and import the Covered Code and derivative works thereof
3454976Sache * solely to the minimum extent necessary to exercise the above copyright
3554976Sache * license, and in no event shall the patent license extend to any additions
3654976Sache * to or modifications of the Original Intel Code.  No other license or right
3754976Sache * is granted directly or by implication, estoppel or otherwise;
3854976Sache *
3954976Sache * The above copyright and patent license is granted only if the following
4054976Sache * conditions are met:
4154976Sache *
4254976Sache * 3. Conditions
4354976Sache *
4454976Sache * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4554976Sache * Redistribution of source code of any substantial portion of the Covered
4654976Sache * Code or modification with rights to further distribute source must include
4754976Sache * the above Copyright Notice, the above License, this list of Conditions,
4854976Sache * and the following Disclaimer and Export Compliance provision.  In addition,
4954976Sache * Licensee must cause all Covered Code to which Licensee contributes to
5054976Sache * contain a file documenting the changes Licensee made to create that Covered
5154976Sache * Code and the date of any change.  Licensee must include in that file the
5254976Sache * documentation of any changes made by any predecessor Licensee.  Licensee
5354976Sache * must include a prominent statement that the modification is derived,
5454976Sache * directly or indirectly, from Original Intel Code.
5554976Sache *
5654976Sache * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5754976Sache * Redistribution of source code of any substantial portion of the Covered
5854976Sache * Code or modification without rights to further distribute source must
5954976Sache * include the following Disclaimer and Export Compliance provision in the
6054976Sache * documentation and/or other materials provided with distribution.  In
6154976Sache * addition, Licensee may not authorize further sublicense of source of any
6254976Sache * portion of the Covered Code, and must include terms to the effect that the
6354976Sache * license from Licensee to its licensee is limited to the intellectual
6454976Sache * property embodied in the software Licensee provides to its licensee, and
6554976Sache * not to intellectual property embodied in modifications its licensee may
6654976Sache * make.
6754976Sache *
6854976Sache * 3.3. Redistribution of Executable. Redistribution in executable form of any
6954976Sache * substantial portion of the Covered Code or modification must reproduce the
7054976Sache * above Copyright Notice, and the following Disclaimer and Export Compliance
7154976Sache * provision in the documentation and/or other materials provided with the
7254976Sache * distribution.
7354976Sache *
7454976Sache * 3.4. Intel retains all right, title, and interest in and to the Original
7554976Sache * Intel Code.
7654976Sache *
7754976Sache * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7854976Sache * Intel shall be used in advertising or otherwise to promote the sale, use or
7954976Sache * other dealings in products derived from or relating to the Covered Code
8054976Sache * without prior written authorization from Intel.
8154976Sache *
8254976Sache * 4. Disclaimer and Export Compliance
8354976Sache *
8454976Sache * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8554976Sache * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8654976Sache * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8754976Sache * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8854976Sache * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
8954976Sache * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
9054976Sache * PARTICULAR PURPOSE.
9154976Sache *
9254976Sache * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9354976Sache * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9454976Sache * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9554976Sache * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9654976Sache * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9754976Sache * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9854976Sache * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
9954976Sache * LIMITED REMEDY.
10054976Sache *
10154976Sache * 4.3. Licensee shall not export, either directly or indirectly, any of this
10254976Sache * software or system incorporating such software without first obtaining any
10354976Sache * required license or other approval from the U. S. Department of Commerce or
10454976Sache * any other agency or department of the United States Government.  In the
10554976Sache * event Licensee exports any such software from the United States or
10654976Sache * re-exports any such software from a foreign destination, Licensee shall
10754976Sache * ensure that the distribution and export/re-export of the software is in
10854976Sache * compliance with all laws, regulations, orders, or other restrictions of the
10954976Sache * U.S. Export Administration Regulations. Licensee agrees that neither it nor
11054976Sache * any of its subsidiaries will export/re-export any technical data, process,
11154976Sache * software, or service, directly or indirectly, to any country for which the
11254976Sache * United States government or any agency thereof requires an export license,
11354976Sache * other governmental approval, or letter of assurance, without first obtaining
11454976Sache * such license, approval or letter.
11554976Sache *
11654976Sache *****************************************************************************/
11754976Sache
11854976Sache#define __HWACPI_C__
11954976Sache
12054976Sache#include "acpi.h"
12154976Sache#include "achware.h"
12254976Sache
12354976Sache
12454976Sache#define _COMPONENT          ACPI_HARDWARE
12554976Sache        MODULE_NAME         ("hwacpi")
12654976Sache
12754976Sache
12854976Sache/******************************************************************************
12954976Sache *
13054976Sache * FUNCTION:    AcpiHwInitialize
13154976Sache *
13254976Sache * PARAMETERS:  None
13354976Sache *
13454976Sache * RETURN:      Status
13554976Sache *
13654976Sache * DESCRIPTION: Initialize and validate various ACPI registers
13754976Sache *
13854976Sache ******************************************************************************/
13954976Sache
14054976SacheACPI_STATUS
14154976SacheAcpiHwInitialize (
14254976Sache    void)
14354976Sache{
14454976Sache    ACPI_STATUS             Status = AE_OK;
14554976Sache    UINT32                  Index;
14654976Sache
14754976Sache
14854976Sache    FUNCTION_TRACE ("HwInitialize");
14954976Sache
15054976Sache
15154976Sache    /* We must have the ACPI tables by the time we get here */
15254976Sache
15354976Sache    if (!AcpiGbl_FADT)
15454976Sache    {
15554976Sache        AcpiGbl_RestoreAcpiChipset = FALSE;
15654976Sache
15754976Sache        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No FADT!\n"));
15854976Sache
15954976Sache        return_ACPI_STATUS (AE_NO_ACPI_TABLES);
16054976Sache    }
16154976Sache
16254976Sache    /* Identify current ACPI/legacy mode   */
16354976Sache
16454976Sache    switch (AcpiGbl_SystemFlags & SYS_MODES_MASK)
16554976Sache    {
16654976Sache    case (SYS_MODE_ACPI):
16754976Sache
16854976Sache        AcpiGbl_OriginalMode = SYS_MODE_ACPI;
16954976Sache        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "System supports ACPI mode only.\n"));
17054976Sache        break;
17154976Sache
17254976Sache
17354976Sache    case (SYS_MODE_LEGACY):
17454976Sache
17554976Sache        AcpiGbl_OriginalMode = SYS_MODE_LEGACY;
17654976Sache        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
17754976Sache            "Tables loaded from buffer, hardware assumed to support LEGACY mode only.\n"));
17854976Sache        break;
17954976Sache
18054976Sache
18154976Sache    case (SYS_MODE_ACPI | SYS_MODE_LEGACY):
18254976Sache
18354976Sache        if (AcpiHwGetMode () == SYS_MODE_ACPI)
18454976Sache        {
18554976Sache            AcpiGbl_OriginalMode = SYS_MODE_ACPI;
18654976Sache        }
18754976Sache        else
18854976Sache        {
18954976Sache            AcpiGbl_OriginalMode = SYS_MODE_LEGACY;
19054976Sache        }
19154976Sache
19254976Sache        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
19354976Sache            "System supports both ACPI and LEGACY modes.\n"));
19454976Sache
19554976Sache        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
19654976Sache            "System is currently in %s mode.\n",
19754976Sache            (AcpiGbl_OriginalMode == SYS_MODE_ACPI) ? "ACPI" : "LEGACY"));
19854976Sache        break;
19954976Sache    }
20054976Sache
20154976Sache
20254976Sache    if (AcpiGbl_SystemFlags & SYS_MODE_ACPI)
20354976Sache    {
20454976Sache        /* Target system supports ACPI mode */
20554976Sache
20654976Sache        /*
20754976Sache         * The purpose of this code is to save the initial state
20854976Sache         * of the ACPI event enable registers. An exit function will be
20954976Sache         * registered which will restore this state when the application
21054976Sache         * exits. The exit function will also clear all of the ACPI event
21154976Sache         * status bits prior to restoring the original mode.
21254976Sache         *
21354976Sache         * The location of the PM1aEvtBlk enable registers is defined as the
21454976Sache         * base of PM1aEvtBlk + DIV_2(PM1aEvtBlkLength). Since the spec further
21554976Sache         * fully defines the PM1aEvtBlk to be a total of 4 bytes, the offset
21654976Sache         * for the enable registers is always 2 from the base. It is hard
21754976Sache         * coded here. If this changes in the spec, this code will need to
21854976Sache         * be modified. The PM1bEvtBlk behaves as expected.
21954976Sache         */
22054976Sache        AcpiGbl_Pm1EnableRegisterSave = (UINT16) AcpiHwRegisterRead (
22154976Sache                                                    ACPI_MTX_LOCK, PM1_EN);
22254976Sache
22354976Sache
22454976Sache        /*
22554976Sache         * The GPEs behave similarly, except that the length of the register
22654976Sache         * block is not fixed, so the buffer must be allocated with malloc
22754976Sache         */
22854976Sache        if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address) &&
22954976Sache            AcpiGbl_FADT->Gpe0BlkLen)
23054976Sache        {
23154976Sache            /* GPE0 specified in FADT  */
23254976Sache
23354976Sache            AcpiGbl_Gpe0EnableRegisterSave = ACPI_MEM_ALLOCATE (
23454976Sache                                            DIV_2 (AcpiGbl_FADT->Gpe0BlkLen));
23554976Sache            if (!AcpiGbl_Gpe0EnableRegisterSave)
23654976Sache            {
23754976Sache                return_ACPI_STATUS (AE_NO_MEMORY);
23854976Sache            }
23954976Sache
24054976Sache            /* Save state of GPE0 enable bits */
24154976Sache
24254976Sache            for (Index = 0; Index < DIV_2 (AcpiGbl_FADT->Gpe0BlkLen); Index++)
24354976Sache            {
24454976Sache                AcpiGbl_Gpe0EnableRegisterSave[Index] =
24554976Sache                    (UINT8) AcpiHwRegisterRead (ACPI_MTX_LOCK, GPE0_EN_BLOCK | Index);
24654976Sache            }
24754976Sache        }
24854976Sache
24954976Sache        else
25054976Sache        {
25154976Sache            AcpiGbl_Gpe0EnableRegisterSave = NULL;
25254976Sache        }
25354976Sache
25454976Sache        if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address) &&
25554976Sache            AcpiGbl_FADT->Gpe1BlkLen)
25654976Sache        {
25754976Sache            /* GPE1 defined */
25854976Sache
25954976Sache            AcpiGbl_Gpe1EnableRegisterSave = ACPI_MEM_ALLOCATE (
26054976Sache                                            DIV_2 (AcpiGbl_FADT->Gpe1BlkLen));
26154976Sache            if (!AcpiGbl_Gpe1EnableRegisterSave)
26254976Sache            {
26354976Sache                return_ACPI_STATUS (AE_NO_MEMORY);
26454976Sache            }
26554976Sache
26654976Sache            /* save state of GPE1 enable bits */
26754976Sache
26854976Sache            for (Index = 0; Index < DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); Index++)
26954976Sache            {
27054976Sache                AcpiGbl_Gpe1EnableRegisterSave[Index] =
27154976Sache                    (UINT8) AcpiHwRegisterRead (ACPI_MTX_LOCK, GPE1_EN_BLOCK | Index);
27254976Sache            }
27354976Sache        }
27454976Sache
27554976Sache        else
27654976Sache        {
27754976Sache            AcpiGbl_Gpe1EnableRegisterSave = NULL;
27854976Sache        }
27954976Sache    }
28054976Sache
28154976Sache    return_ACPI_STATUS (Status);
28254976Sache}
28354976Sache
28454976Sache
28554976Sache/******************************************************************************
28654976Sache *
287 * FUNCTION:    AcpiHwSetMode
288 *
289 * PARAMETERS:  Mode            - SYS_MODE_ACPI or SYS_MODE_LEGACY
290 *
291 * RETURN:      Status
292 *
293 * DESCRIPTION: Transitions the system into the requested mode or does nothing
294 *              if the system is already in that mode.
295 *
296 ******************************************************************************/
297
298ACPI_STATUS
299AcpiHwSetMode (
300    UINT32                  Mode)
301{
302
303    ACPI_STATUS             Status = AE_NO_HARDWARE_RESPONSE;
304
305
306    FUNCTION_TRACE ("HwSetMode");
307
308
309    if (Mode == SYS_MODE_ACPI)
310    {
311        /* BIOS should have disabled ALL fixed and GP events */
312
313        AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, AcpiGbl_FADT->AcpiEnable, 8);
314        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Attempting to enable ACPI mode\n"));
315    }
316
317    else if (Mode == SYS_MODE_LEGACY)
318    {
319        /*
320         * BIOS should clear all fixed status bits and restore fixed event
321         * enable bits to default
322         */
323        AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, AcpiGbl_FADT->AcpiDisable, 8);
324        ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
325                    "Attempting to enable Legacy (non-ACPI) mode\n"));
326    }
327
328    /* Give the platform some time to react */
329
330    AcpiOsStall (20000);
331
332    if (AcpiHwGetMode () == Mode)
333    {
334        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n", Mode));
335        Status = AE_OK;
336    }
337
338    return_ACPI_STATUS (Status);
339}
340
341
342/******************************************************************************
343 *
344 * FUNCTION:    AcpiHwGetMode
345 *
346 * PARAMETERS:  none
347 *
348 * RETURN:      SYS_MODE_ACPI or SYS_MODE_LEGACY
349 *
350 * DESCRIPTION: Return current operating state of system.  Determined by
351 *              querying the SCI_EN bit.
352 *
353 ******************************************************************************/
354
355UINT32
356AcpiHwGetMode (void)
357{
358
359    FUNCTION_TRACE ("HwGetMode");
360
361
362    if (AcpiHwRegisterBitAccess (ACPI_READ, ACPI_MTX_LOCK, SCI_EN))
363    {
364        return_VALUE (SYS_MODE_ACPI);
365    }
366    else
367    {
368        return_VALUE (SYS_MODE_LEGACY);
369    }
370}
371
372
373/******************************************************************************
374 *
375 * FUNCTION:    AcpiHwGetModeCapabilities
376 *
377 * PARAMETERS:  none
378 *
379 * RETURN:      logical OR of SYS_MODE_ACPI and SYS_MODE_LEGACY determined at initial
380 *              system state.
381 *
382 * DESCRIPTION: Returns capablities of system
383 *
384 ******************************************************************************/
385
386UINT32
387AcpiHwGetModeCapabilities (void)
388{
389
390    FUNCTION_TRACE ("HwGetModeCapabilities");
391
392
393    if (!(AcpiGbl_SystemFlags & SYS_MODES_MASK))
394    {
395        if (AcpiHwGetMode () == SYS_MODE_LEGACY)
396        {
397            /*
398             * Assume that if this call is being made, AcpiInit has been called
399             * and ACPI support has been established by the presence of the
400             * tables.  Therefore since we're in SYS_MODE_LEGACY, the system
401             * must support both modes
402             */
403            AcpiGbl_SystemFlags |= (SYS_MODE_ACPI | SYS_MODE_LEGACY);
404        }
405
406        else
407        {
408            /* TBD: [Investigate] !!! this may be unsafe... */
409            /*
410             * system is is ACPI mode, so try to switch back to LEGACY to see if
411             * it is supported
412             */
413            AcpiHwSetMode (SYS_MODE_LEGACY);
414
415            if (AcpiHwGetMode () == SYS_MODE_LEGACY)
416            {
417                /* Now in SYS_MODE_LEGACY, so both are supported */
418
419                AcpiGbl_SystemFlags |= (SYS_MODE_ACPI | SYS_MODE_LEGACY);
420                AcpiHwSetMode (SYS_MODE_ACPI);
421            }
422
423            else
424            {
425                /* Still in SYS_MODE_ACPI so this must be an ACPI only system */
426
427                AcpiGbl_SystemFlags |= SYS_MODE_ACPI;
428            }
429        }
430    }
431
432    return_VALUE (AcpiGbl_SystemFlags & SYS_MODES_MASK);
433}
434
435
436