hwregs.c revision 71867
167754Smsmith
267754Smsmith/*******************************************************************************
367754Smsmith *
467754Smsmith * Module Name: hwregs - Read/write access functions for the various ACPI
567754Smsmith *                       control and status registers.
671867Smsmith *              $Revision: 88 $
767754Smsmith *
867754Smsmith ******************************************************************************/
967754Smsmith
1067754Smsmith/******************************************************************************
1167754Smsmith *
1267754Smsmith * 1. Copyright Notice
1367754Smsmith *
1471867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
1570243Smsmith * All rights reserved.
1667754Smsmith *
1767754Smsmith * 2. License
1867754Smsmith *
1967754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property
2067754Smsmith * rights.  You may have additional license terms from the party that provided
2167754Smsmith * you this software, covering your right to use that party's intellectual
2267754Smsmith * property rights.
2367754Smsmith *
2467754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
2567754Smsmith * copy of the source code appearing in this file ("Covered Code") an
2667754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the
2767754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy,
2867754Smsmith * make derivatives, distribute, use and display any portion of the Covered
2967754Smsmith * Code in any form, with the right to sublicense such rights; and
3067754Smsmith *
3167754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
3267754Smsmith * license (with the right to sublicense), under only those claims of Intel
3367754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell,
3467754Smsmith * offer to sell, and import the Covered Code and derivative works thereof
3567754Smsmith * solely to the minimum extent necessary to exercise the above copyright
3667754Smsmith * license, and in no event shall the patent license extend to any additions
3767754Smsmith * to or modifications of the Original Intel Code.  No other license or right
3867754Smsmith * is granted directly or by implication, estoppel or otherwise;
3967754Smsmith *
4067754Smsmith * The above copyright and patent license is granted only if the following
4167754Smsmith * conditions are met:
4267754Smsmith *
4367754Smsmith * 3. Conditions
4467754Smsmith *
4567754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source.
4667754Smsmith * Redistribution of source code of any substantial portion of the Covered
4767754Smsmith * Code or modification with rights to further distribute source must include
4867754Smsmith * the above Copyright Notice, the above License, this list of Conditions,
4967754Smsmith * and the following Disclaimer and Export Compliance provision.  In addition,
5067754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to
5167754Smsmith * contain a file documenting the changes Licensee made to create that Covered
5267754Smsmith * Code and the date of any change.  Licensee must include in that file the
5367754Smsmith * documentation of any changes made by any predecessor Licensee.  Licensee
5467754Smsmith * must include a prominent statement that the modification is derived,
5567754Smsmith * directly or indirectly, from Original Intel Code.
5667754Smsmith *
5767754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
5867754Smsmith * Redistribution of source code of any substantial portion of the Covered
5967754Smsmith * Code or modification without rights to further distribute source must
6067754Smsmith * include the following Disclaimer and Export Compliance provision in the
6167754Smsmith * documentation and/or other materials provided with distribution.  In
6267754Smsmith * addition, Licensee may not authorize further sublicense of source of any
6367754Smsmith * portion of the Covered Code, and must include terms to the effect that the
6467754Smsmith * license from Licensee to its licensee is limited to the intellectual
6567754Smsmith * property embodied in the software Licensee provides to its licensee, and
6667754Smsmith * not to intellectual property embodied in modifications its licensee may
6767754Smsmith * make.
6867754Smsmith *
6967754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any
7067754Smsmith * substantial portion of the Covered Code or modification must reproduce the
7167754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance
7267754Smsmith * provision in the documentation and/or other materials provided with the
7367754Smsmith * distribution.
7467754Smsmith *
7567754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original
7667754Smsmith * Intel Code.
7767754Smsmith *
7867754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by
7967754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or
8067754Smsmith * other dealings in products derived from or relating to the Covered Code
8167754Smsmith * without prior written authorization from Intel.
8267754Smsmith *
8367754Smsmith * 4. Disclaimer and Export Compliance
8467754Smsmith *
8567754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
8667754Smsmith * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
8767754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
8867754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
8967754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
9067754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
9167754Smsmith * PARTICULAR PURPOSE.
9267754Smsmith *
9367754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
9467754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
9567754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
9667754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
9767754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
9867754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
9967754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
10067754Smsmith * LIMITED REMEDY.
10167754Smsmith *
10267754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this
10367754Smsmith * software or system incorporating such software without first obtaining any
10467754Smsmith * required license or other approval from the U. S. Department of Commerce or
10567754Smsmith * any other agency or department of the United States Government.  In the
10667754Smsmith * event Licensee exports any such software from the United States or
10767754Smsmith * re-exports any such software from a foreign destination, Licensee shall
10867754Smsmith * ensure that the distribution and export/re-export of the software is in
10967754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the
11067754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor
11167754Smsmith * any of its subsidiaries will export/re-export any technical data, process,
11267754Smsmith * software, or service, directly or indirectly, to any country for which the
11367754Smsmith * United States government or any agency thereof requires an export license,
11467754Smsmith * other governmental approval, or letter of assurance, without first obtaining
11567754Smsmith * such license, approval or letter.
11667754Smsmith *
11767754Smsmith *****************************************************************************/
11867754Smsmith
11967754Smsmith#define __HWREGS_C__
12067754Smsmith
12167754Smsmith#include "acpi.h"
12267754Smsmith#include "achware.h"
12367754Smsmith#include "acnamesp.h"
12467754Smsmith
12567754Smsmith#define _COMPONENT          HARDWARE
12667754Smsmith        MODULE_NAME         ("hwregs")
12767754Smsmith
12867754Smsmith
12967754Smsmith/* This matches the #defines in actypes.h. */
13067754Smsmith
13169450SmsmithNATIVE_CHAR                 *SleepStateTable[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_",
13271867Smsmith                                                  "\\_S4_","\\_S5_","\\_S4B"};
13367754Smsmith
13467754Smsmith
13567754Smsmith/*******************************************************************************
13667754Smsmith *
13767754Smsmith * FUNCTION:    AcpiHwGetBitShift
13867754Smsmith *
13967754Smsmith * PARAMETERS:  Mask            - Input mask to determine bit shift from.
14067754Smsmith *                                Must have at least 1 bit set.
14167754Smsmith *
14267754Smsmith * RETURN:      Bit location of the lsb of the mask
14367754Smsmith *
14467754Smsmith * DESCRIPTION: Returns the bit number for the low order bit that's set.
14567754Smsmith *
14667754Smsmith ******************************************************************************/
14767754Smsmith
14871867SmsmithUINT32
14967754SmsmithAcpiHwGetBitShift (
15067754Smsmith    UINT32                  Mask)
15167754Smsmith{
15267754Smsmith    UINT32                  Shift;
15367754Smsmith
15467754Smsmith
15567754Smsmith    FUNCTION_TRACE ("HwGetBitShift");
15667754Smsmith
15767754Smsmith
15867754Smsmith    for (Shift = 0; ((Mask >> Shift) & 1) == 0; Shift++)
15967754Smsmith    { ; }
16067754Smsmith
16167754Smsmith    return_VALUE (Shift);
16267754Smsmith}
16367754Smsmith
16467754Smsmith
16567754Smsmith/*******************************************************************************
16667754Smsmith *
16767754Smsmith * FUNCTION:    AcpiHwClearAcpiStatus
16867754Smsmith *
16967754Smsmith * PARAMETERS:  none
17067754Smsmith *
17167754Smsmith * RETURN:      none
17267754Smsmith *
17367754Smsmith * DESCRIPTION: Clears all fixed and general purpose status bits
17467754Smsmith *
17567754Smsmith ******************************************************************************/
17667754Smsmith
17767754Smsmithvoid
17867754SmsmithAcpiHwClearAcpiStatus (void)
17967754Smsmith{
18067754Smsmith    UINT16                  GpeLength;
18167754Smsmith    UINT16                  Index;
18267754Smsmith
18367754Smsmith
18467754Smsmith    FUNCTION_TRACE ("HwClearAcpiStatus");
18567754Smsmith
18667754Smsmith
18767754Smsmith    DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n",
18869450Smsmith                    ALL_FIXED_STS_BITS,
18970243Smsmith                    (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address)));
19067754Smsmith
19167754Smsmith
19267754Smsmith    AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
19367754Smsmith
19469450Smsmith    AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS);
19567754Smsmith
19669450Smsmith
19770243Smsmith    if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address))
19867754Smsmith    {
19970243Smsmith        AcpiOsOut16 ((ACPI_IO_ADDRESS) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address),
20067754Smsmith                        (UINT16) ALL_FIXED_STS_BITS);
20167754Smsmith    }
20267754Smsmith
20367754Smsmith    /* now clear the GPE Bits */
20467754Smsmith
20569450Smsmith    if (AcpiGbl_FADT->Gpe0BlkLen)
20667754Smsmith    {
20769450Smsmith        GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
20867754Smsmith
20967754Smsmith        for (Index = 0; Index < GpeLength; Index++)
21067754Smsmith        {
21170243Smsmith            AcpiOsOut8 ((ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address) + Index),
21269450Smsmith                            (UINT8) 0xff);
21367754Smsmith        }
21467754Smsmith    }
21567754Smsmith
21669450Smsmith    if (AcpiGbl_FADT->Gpe1BlkLen)
21767754Smsmith    {
21869450Smsmith        GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
21967754Smsmith
22067754Smsmith        for (Index = 0; Index < GpeLength; Index++)
22167754Smsmith        {
22270243Smsmith            AcpiOsOut8 ((ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address) + Index),
22369450Smsmith                            (UINT8) 0xff);
22467754Smsmith        }
22567754Smsmith    }
22667754Smsmith
22767754Smsmith    AcpiCmReleaseMutex (ACPI_MTX_HARDWARE);
22867754Smsmith    return_VOID;
22967754Smsmith}
23067754Smsmith
23167754Smsmith
23267754Smsmith/*******************************************************************************
23367754Smsmith *
23467754Smsmith * FUNCTION:    AcpiHwObtainSleepTypeRegisterData
23567754Smsmith *
23667754Smsmith * PARAMETERS:  SleepState        - Numeric state requested
23767754Smsmith *              *Slp_TypA         - Pointer to byte to receive SLP_TYPa value
23867754Smsmith *              *Slp_TypB         - Pointer to byte to receive SLP_TYPb value
23967754Smsmith *
24067754Smsmith * RETURN:      Status - ACPI status
24167754Smsmith *
24267754Smsmith * DESCRIPTION: AcpiHwObtainSleepTypeRegisterData() obtains the SLP_TYP and
24367754Smsmith *              SLP_TYPb values for the sleep state requested.
24467754Smsmith *
24567754Smsmith ******************************************************************************/
24667754Smsmith
24767754SmsmithACPI_STATUS
24867754SmsmithAcpiHwObtainSleepTypeRegisterData (
24967754Smsmith    UINT8                   SleepState,
25067754Smsmith    UINT8                   *Slp_TypA,
25167754Smsmith    UINT8                   *Slp_TypB)
25267754Smsmith{
25367754Smsmith    ACPI_STATUS             Status = AE_OK;
25467754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
25567754Smsmith
25667754Smsmith
25767754Smsmith    FUNCTION_TRACE ("HwObtainSleepTypeRegisterData");
25867754Smsmith
25967754Smsmith
26067754Smsmith    /*
26167754Smsmith     *  Validate parameters
26267754Smsmith     */
26367754Smsmith
26467754Smsmith    if ((SleepState > ACPI_S_STATES_MAX) ||
26567754Smsmith        !Slp_TypA || !Slp_TypB)
26667754Smsmith    {
26767754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
26867754Smsmith    }
26967754Smsmith
27067754Smsmith    /*
27167754Smsmith     *  AcpiEvaluate the namespace object containing the values for this state
27267754Smsmith     */
27367754Smsmith
27467754Smsmith    Status = AcpiNsEvaluateByName (SleepStateTable[SleepState], NULL, &ObjDesc);
27567754Smsmith    if (ACPI_FAILURE (Status))
27667754Smsmith    {
27767754Smsmith        return_ACPI_STATUS (Status);
27867754Smsmith    }
27967754Smsmith
28067754Smsmith    if (!ObjDesc)
28167754Smsmith    {
28267754Smsmith        REPORT_ERROR (("Missing Sleep State object\n"));
28367754Smsmith        return_ACPI_STATUS (AE_NOT_EXIST);
28467754Smsmith    }
28567754Smsmith
28667754Smsmith    /*
28767754Smsmith     *  We got something, now ensure it is correct.  The object must
28867754Smsmith     *  be a package and must have at least 2 numeric values as the
28967754Smsmith     *  two elements
29067754Smsmith     */
29167754Smsmith
29267754Smsmith    Status = AcpiCmResolvePackageReferences(ObjDesc);
29367754Smsmith
29467754Smsmith    if (ObjDesc->Package.Count < 2)
29567754Smsmith    {
29667754Smsmith        /* Must have at least two elements */
29767754Smsmith
29867754Smsmith        REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
29967754Smsmith        Status = AE_ERROR;
30067754Smsmith    }
30167754Smsmith
30267754Smsmith    else if (((ObjDesc->Package.Elements[0])->Common.Type !=
30371867Smsmith                ACPI_TYPE_INTEGER) ||
30467754Smsmith             ((ObjDesc->Package.Elements[1])->Common.Type !=
30571867Smsmith                ACPI_TYPE_INTEGER))
30667754Smsmith    {
30767754Smsmith        /* Must have two  */
30867754Smsmith
30967754Smsmith        REPORT_ERROR (("Sleep State package elements are not both of type Number\n"));
31067754Smsmith        Status = AE_ERROR;
31167754Smsmith    }
31267754Smsmith
31367754Smsmith    else
31467754Smsmith    {
31567754Smsmith        /*
31667754Smsmith         *  Valid _Sx_ package size, type, and value
31767754Smsmith         */
31871867Smsmith        *Slp_TypA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value;
31967754Smsmith
32071867Smsmith        *Slp_TypB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.Value;
32167754Smsmith    }
32267754Smsmith
32367754Smsmith
32467754Smsmith    if (ACPI_FAILURE (Status))
32567754Smsmith    {
32667754Smsmith        DEBUG_PRINT (ACPI_ERROR,
32767754Smsmith            ("SleepTypeRegisterData: Bad Sleep object %p type %X\n",
32867754Smsmith            ObjDesc, ObjDesc->Common.Type));
32967754Smsmith    }
33067754Smsmith
33167754Smsmith    AcpiCmRemoveReference (ObjDesc);
33267754Smsmith
33367754Smsmith    return_ACPI_STATUS (Status);
33467754Smsmith}
33567754Smsmith
33667754Smsmith
33767754Smsmith/*******************************************************************************
33867754Smsmith *
33969450Smsmith * FUNCTION:    AcpiHwRegisterBitAccess
34067754Smsmith *
34167754Smsmith * PARAMETERS:  ReadWrite       - Either ACPI_READ or ACPI_WRITE.
34267754Smsmith *              UseLock         - Lock the hardware
34369450Smsmith *              RegisterId      - index of ACPI Register to access
34467754Smsmith *              Value           - (only used on write) value to write to the
34569450Smsmith *                                Register.  Shifted all the way right.
34667754Smsmith *
34769450Smsmith * RETURN:      Value written to or read from specified Register.  This value
34867754Smsmith *              is shifted all the way right.
34967754Smsmith *
35069450Smsmith * DESCRIPTION: Generic ACPI Register read/write function.
35167754Smsmith *
35267754Smsmith ******************************************************************************/
35367754Smsmith
35467754SmsmithUINT32
35569450SmsmithAcpiHwRegisterBitAccess (
35667754Smsmith    NATIVE_UINT             ReadWrite,
35767754Smsmith    BOOLEAN                 UseLock,
35867754Smsmith    UINT32                  RegisterId,
35967754Smsmith    ...)                    /* Value (only used on write) */
36067754Smsmith{
36167754Smsmith    UINT32                  RegisterValue = 0;
36267754Smsmith    UINT32                  Mask = 0;
36367754Smsmith    UINT32                  Value = 0;
36467754Smsmith
36569450Smsmith    FUNCTION_TRACE ("HwRegisterBitAccess");
36667754Smsmith
36767754Smsmith
36867754Smsmith    if (ReadWrite == ACPI_WRITE)
36967754Smsmith    {
37067754Smsmith        va_list         marker;
37167754Smsmith
37267754Smsmith        va_start (marker, RegisterId);
37367754Smsmith        Value = va_arg (marker, UINT32);
37467754Smsmith        va_end (marker);
37567754Smsmith    }
37667754Smsmith
37769450Smsmith    if (ACPI_MTX_LOCK == UseLock) {
37869450Smsmith        AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
37969450Smsmith    }
38067754Smsmith
38167754Smsmith    /*
38267754Smsmith     * Decode the Register ID
38369450Smsmith     *  Register id = Register block id | bit id
38469450Smsmith     *
38569450Smsmith     * Check bit id to fine locate Register offset.
38669450Smsmith     *  check Mask to determine Register offset, and then read-write.
38767754Smsmith     */
38867754Smsmith
38969450Smsmith    switch (REGISTER_BLOCK_ID(RegisterId))
39067754Smsmith    {
39169450Smsmith    case PM1_STS:
39267754Smsmith
39369450Smsmith        switch (RegisterId)
39467754Smsmith        {
39569450Smsmith        case TMR_STS:
39669450Smsmith            Mask = TMR_STS_MASK;
39769450Smsmith            break;
39867754Smsmith
39969450Smsmith        case BM_STS:
40069450Smsmith            Mask = BM_STS_MASK;
40169450Smsmith            break;
40267754Smsmith
40369450Smsmith        case GBL_STS:
40469450Smsmith            Mask = GBL_STS_MASK;
40569450Smsmith            break;
40667754Smsmith
40769450Smsmith        case PWRBTN_STS:
40869450Smsmith            Mask = PWRBTN_STS_MASK;
40969450Smsmith            break;
41067754Smsmith
41169450Smsmith        case SLPBTN_STS:
41269450Smsmith            Mask = SLPBTN_STS_MASK;
41369450Smsmith            break;
41467754Smsmith
41569450Smsmith        case RTC_STS:
41669450Smsmith            Mask = RTC_STS_MASK;
41769450Smsmith            break;
41867754Smsmith
41969450Smsmith        case WAK_STS:
42069450Smsmith            Mask = WAK_STS_MASK;
42169450Smsmith            break;
42267754Smsmith
42369450Smsmith        default:
42469450Smsmith            Mask = 0;
42569450Smsmith            break;
42669450Smsmith        }
42767754Smsmith
42869450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_STS);
42967754Smsmith
43069450Smsmith        if (ReadWrite == ACPI_WRITE)
43169450Smsmith        {
43269450Smsmith            /*
43369450Smsmith             * Status Registers are different from the rest.  Clear by
43469450Smsmith             * writing 1, writing 0 has no effect.  So, the only relevent
43569450Smsmith             * information is the single bit we're interested in, all
43669450Smsmith             * others should be written as 0 so they will be left
43769450Smsmith             * unchanged
43869450Smsmith             */
43967754Smsmith
44069450Smsmith            Value <<= AcpiHwGetBitShift (Mask);
44169450Smsmith            Value &= Mask;
44267754Smsmith
44369450Smsmith            if (Value)
44467754Smsmith            {
44569450Smsmith                AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, (UINT16) Value);
44667754Smsmith
44769450Smsmith                RegisterValue = 0;
44867754Smsmith            }
44967754Smsmith        }
45067754Smsmith
45169450Smsmith        break;
45267754Smsmith
45367754Smsmith
45469450Smsmith    case PM1_EN:
45567754Smsmith
45669450Smsmith        switch (RegisterId)
45769450Smsmith        {
45869450Smsmith        case TMR_EN:
45969450Smsmith            Mask = TMR_EN_MASK;
46069450Smsmith            break;
46167754Smsmith
46269450Smsmith        case GBL_EN:
46369450Smsmith            Mask = GBL_EN_MASK;
46469450Smsmith            break;
46567754Smsmith
46669450Smsmith        case PWRBTN_EN:
46769450Smsmith            Mask = PWRBTN_EN_MASK;
46869450Smsmith            break;
46967754Smsmith
47069450Smsmith        case SLPBTN_EN:
47169450Smsmith            Mask = SLPBTN_EN_MASK;
47269450Smsmith            break;
47367754Smsmith
47469450Smsmith        case RTC_EN:
47569450Smsmith            Mask = RTC_EN_MASK;
47669450Smsmith            break;
47767754Smsmith
47869450Smsmith        default:
47969450Smsmith            Mask = 0;
48069450Smsmith            break;
48169450Smsmith        }
48267754Smsmith
48369450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_EN);
48467754Smsmith
48569450Smsmith        if (ReadWrite == ACPI_WRITE)
48669450Smsmith        {
48769450Smsmith            RegisterValue &= ~Mask;
48869450Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
48969450Smsmith            Value          &= Mask;
49069450Smsmith            RegisterValue |= Value;
49167754Smsmith
49269450Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (UINT16) RegisterValue);
49369450Smsmith        }
49467754Smsmith
49567754Smsmith        break;
49667754Smsmith
49767754Smsmith
49867754Smsmith    case PM1_CONTROL:
49967754Smsmith
50067754Smsmith        switch (RegisterId)
50167754Smsmith        {
50267754Smsmith        case SCI_EN:
50367754Smsmith            Mask = SCI_EN_MASK;
50467754Smsmith            break;
50567754Smsmith
50667754Smsmith        case BM_RLD:
50767754Smsmith            Mask = BM_RLD_MASK;
50867754Smsmith            break;
50967754Smsmith
51067754Smsmith        case GBL_RLS:
51167754Smsmith            Mask = GBL_RLS_MASK;
51267754Smsmith            break;
51367754Smsmith
51467754Smsmith        case SLP_TYPE_A:
51567754Smsmith        case SLP_TYPE_B:
51667754Smsmith            Mask = SLP_TYPE_X_MASK;
51767754Smsmith            break;
51867754Smsmith
51967754Smsmith        case SLP_EN:
52067754Smsmith            Mask = SLP_EN_MASK;
52167754Smsmith            break;
52267754Smsmith
52367754Smsmith        default:
52467754Smsmith            Mask = 0;
52567754Smsmith            break;
52667754Smsmith        }
52767754Smsmith
52869450Smsmith
52969450Smsmith        /*
53069450Smsmith         * Read the PM1 Control register.
53169450Smsmith         * Note that at this level, the fact that there are actually TWO
53269450Smsmith         * registers (A and B) and that B may not exist, are abstracted.
53369450Smsmith         */
53469450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL);
53569450Smsmith
53669746Smsmith        DEBUG_PRINT (TRACE_IO, ("PM1 control: Read %X\n", RegisterValue));
53769450Smsmith
53867754Smsmith        if (ReadWrite == ACPI_WRITE)
53967754Smsmith        {
54067754Smsmith            RegisterValue  &= ~Mask;
54167754Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
54267754Smsmith            Value          &= Mask;
54367754Smsmith            RegisterValue  |= Value;
54467754Smsmith
54567754Smsmith            /*
54669450Smsmith             * SLP_TYPE_x Registers are written differently
54769450Smsmith             * than any other control Registers with
54869450Smsmith             * respect to A and B Registers.  The value
54967754Smsmith             * for A may be different than the value for B
55069746Smsmith             *
55169746Smsmith             * Therefore, pass the RegisterId, not just generic PM1_CONTROL,
55269746Smsmith             * because we need to do different things. Yuck.
55367754Smsmith             */
55467754Smsmith
55569450Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
55669746Smsmith                RegisterId, (UINT16) RegisterValue);
55767754Smsmith        }
55867754Smsmith        break;
55967754Smsmith
56067754Smsmith
56167754Smsmith    case PM2_CONTROL:
56267754Smsmith
56367754Smsmith        switch (RegisterId)
56467754Smsmith        {
56567754Smsmith        case ARB_DIS:
56667754Smsmith            Mask = ARB_DIS_MASK;
56767754Smsmith            break;
56867754Smsmith
56967754Smsmith        default:
57067754Smsmith            Mask = 0;
57167754Smsmith            break;
57267754Smsmith        }
57367754Smsmith
57469450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL);
57569450Smsmith
57669746Smsmith        DEBUG_PRINT (TRACE_IO, ("PM2 control: Read %X from %p\n",
57770243Smsmith                        RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)));
57869450Smsmith
57967754Smsmith        if (ReadWrite == ACPI_WRITE)
58067754Smsmith        {
58167754Smsmith            RegisterValue  &= ~Mask;
58267754Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
58367754Smsmith            Value          &= Mask;
58467754Smsmith            RegisterValue  |= Value;
58567754Smsmith
58667754Smsmith            DEBUG_PRINT (TRACE_IO,
58769746Smsmith                ("About to write %04X to %p\n", RegisterValue,
58869450Smsmith                AcpiGbl_FADT->XPm2CntBlk.Address));
58967754Smsmith
59069450Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
59169450Smsmith                                PM2_CONTROL, (UINT8) (RegisterValue));
59267754Smsmith        }
59367754Smsmith        break;
59467754Smsmith
59567754Smsmith
59667754Smsmith    case PM_TIMER:
59767754Smsmith
59869450Smsmith        Mask = TMR_VAL_MASK;
59969450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
60069450Smsmith                                            PM_TIMER);
60169746Smsmith        DEBUG_PRINT (TRACE_IO, ("PM_TIMER: Read %X from %p\n",
60270243Smsmith                        RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPmTmrBlk.Address)));
60367754Smsmith
60467754Smsmith        break;
60567754Smsmith
60667754Smsmith
60767754Smsmith    case GPE1_EN_BLOCK:
60867754Smsmith    case GPE1_STS_BLOCK:
60967754Smsmith    case GPE0_EN_BLOCK:
61067754Smsmith    case GPE0_STS_BLOCK:
61167754Smsmith
61269450Smsmith        /* Determine the bit to be accessed
61369450Smsmith         *
61469450Smsmith         *  (UINT32) RegisterId:
61569450Smsmith         *      31      24       16       8        0
61669450Smsmith         *      +--------+--------+--------+--------+
61769450Smsmith         *      |  gpe_block_id   |  gpe_bit_number |
61869450Smsmith         *      +--------+--------+--------+--------+
61969450Smsmith         *
62069450Smsmith         *     gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK
62169450Smsmith         *     gpe_bit_number is relative from the gpe_block (0x00~0xFF)
62269450Smsmith         */
62367754Smsmith
62469450Smsmith        Mask = REGISTER_BIT_ID(RegisterId); /* gpe_bit_number */
62569450Smsmith        RegisterId = REGISTER_BLOCK_ID(RegisterId) | (Mask >> 3);
62669450Smsmith        Mask = AcpiGbl_DecodeTo8bit [Mask % 8];
62767754Smsmith
62867754Smsmith        /*
62967754Smsmith         * The base address of the GPE 0 Register Block
63067754Smsmith         * Plus 1/2 the length of the GPE 0 Register Block
63169450Smsmith         * The enable Register is the Register following the Status Register
63269450Smsmith         * and each Register is defined as 1/2 of the total Register Block
63367754Smsmith         */
63467754Smsmith
63567754Smsmith        /*
63667754Smsmith         * This sets the bit within EnableBit that needs to be written to
63769450Smsmith         * the Register indicated in Mask to a 1, all others are 0
63867754Smsmith         */
63967754Smsmith
64067754Smsmith        /* Now get the current Enable Bits in the selected Reg */
64167754Smsmith
64269450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId);
64369746Smsmith        DEBUG_PRINT (TRACE_IO, ("GPE Enable bits: Read %X from %X\n",
64469450Smsmith                                RegisterValue, RegisterId));
64567754Smsmith
64667754Smsmith        if (ReadWrite == ACPI_WRITE)
64767754Smsmith        {
64867754Smsmith            RegisterValue  &= ~Mask;
64967754Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
65067754Smsmith            Value          &= Mask;
65167754Smsmith            RegisterValue  |= Value;
65267754Smsmith
65367754Smsmith            /* This write will put the Action state into the General Purpose */
65467754Smsmith            /* Enable Register indexed by the value in Mask */
65567754Smsmith
65667754Smsmith            DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n",
65769450Smsmith                                    RegisterValue, RegisterId));
65869450Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
65969450Smsmith                                RegisterId, (UINT8) RegisterValue);
66069450Smsmith            RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId);
66167754Smsmith        }
66267754Smsmith        break;
66367754Smsmith
66467754Smsmith
66569450Smsmith    case SMI_CMD_BLOCK:
66667754Smsmith    case PROCESSOR_BLOCK:
66769450Smsmith        /* not used */
66867754Smsmith    default:
66967754Smsmith
67067754Smsmith        Mask = 0;
67167754Smsmith        break;
67267754Smsmith    }
67367754Smsmith
67469450Smsmith    if (ACPI_MTX_LOCK == UseLock) {
67569450Smsmith        AcpiCmReleaseMutex (ACPI_MTX_HARDWARE);
67669450Smsmith    }
67767754Smsmith
67869450Smsmith
67967754Smsmith    RegisterValue &= Mask;
68067754Smsmith    RegisterValue >>= AcpiHwGetBitShift (Mask);
68167754Smsmith
68269746Smsmith    DEBUG_PRINT (TRACE_IO, ("Register I/O: returning %X\n", RegisterValue));
68367754Smsmith    return_VALUE (RegisterValue);
68467754Smsmith}
68569450Smsmith
68669450Smsmith
68769450Smsmith/******************************************************************************
68869450Smsmith *
68969450Smsmith * FUNCTION:    AcpiHwRegisterRead
69069450Smsmith *
69169450Smsmith * PARAMETERS:  UseLock                - Mutex hw access.
69269450Smsmith *              RegisterId             - RegisterID + Offset.
69369450Smsmith *
69469450Smsmith * RETURN:      Value read or written.
69569450Smsmith *
69669450Smsmith * DESCRIPTION: Acpi register read function.  Registers are read at the
69769450Smsmith *              given offset.
69869450Smsmith *
69969450Smsmith ******************************************************************************/
70069450Smsmith
70169450SmsmithUINT32
70269450SmsmithAcpiHwRegisterRead (
70369450Smsmith    BOOLEAN                 UseLock,
70469450Smsmith    UINT32                  RegisterId)
70569450Smsmith{
70669450Smsmith    UINT32                  Value       = 0;
70769450Smsmith    UINT32                  BankOffset;
70869450Smsmith
70969450Smsmith    FUNCTION_TRACE ("AcpiHwRegisterRead");
71069450Smsmith
71169450Smsmith    if (ACPI_MTX_LOCK == UseLock)
71269450Smsmith    {
71369450Smsmith        AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
71469450Smsmith    }
71569450Smsmith
71669450Smsmith
71769450Smsmith    switch (REGISTER_BLOCK_ID(RegisterId))
71869450Smsmith    {
71969450Smsmith    case PM1_STS: /* 16-bit access */
72069450Smsmith
72169746Smsmith        Value =  AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, 0);
72269746Smsmith        Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, 0);
72369450Smsmith        break;
72469450Smsmith
72569450Smsmith
72669450Smsmith    case PM1_EN: /* 16-bit access*/
72769450Smsmith
72869450Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
72969746Smsmith        Value =  AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset);
73069746Smsmith        Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset);
73169450Smsmith        break;
73269450Smsmith
73369450Smsmith
73469450Smsmith    case PM1_CONTROL: /* 16-bit access */
73569450Smsmith
73671867Smsmith        Value =  AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aCntBlk, 0);
73771867Smsmith        Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bCntBlk, 0);
73869450Smsmith        break;
73969450Smsmith
74069450Smsmith
74169450Smsmith    case PM2_CONTROL: /* 8-bit access */
74269450Smsmith
74369746Smsmith        Value =  AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XPm2CntBlk, 0);
74469450Smsmith        break;
74569450Smsmith
74669450Smsmith
74769450Smsmith    case PM_TIMER: /* 32-bit access */
74869450Smsmith
74969746Smsmith        Value =  AcpiHwLowLevelRead (32, &AcpiGbl_FADT->XPmTmrBlk, 0);
75069450Smsmith        break;
75169450Smsmith
75269450Smsmith
75369450Smsmith    case GPE0_STS_BLOCK: /* 8-bit access */
75469450Smsmith
75569746Smsmith        Value =  AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, 0);
75669450Smsmith        break;
75769450Smsmith
75869450Smsmith
75969450Smsmith    case GPE0_EN_BLOCK: /* 8-bit access */
76069450Smsmith
76169450Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
76269746Smsmith        Value =  AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
76369450Smsmith        break;
76469450Smsmith
76569450Smsmith
76669450Smsmith    case GPE1_STS_BLOCK: /* 8-bit access */
76769450Smsmith
76869746Smsmith        Value =  AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, 0);
76969450Smsmith        break;
77069450Smsmith
77169450Smsmith
77269450Smsmith    case GPE1_EN_BLOCK: /* 8-bit access */
77369450Smsmith
77469450Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
77569746Smsmith        Value =  AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
77669450Smsmith        break;
77769450Smsmith
77869450Smsmith
77969450Smsmith    case SMI_CMD_BLOCK: /* 8bit */
78069450Smsmith
78169450Smsmith        Value = (UINT32) AcpiOsIn8 (AcpiGbl_FADT->SmiCmd);
78269450Smsmith        break;
78369450Smsmith
78469450Smsmith
78569450Smsmith    default:
78669450Smsmith        Value = 0;
78769450Smsmith        break;
78869450Smsmith    }
78969450Smsmith
79069450Smsmith
79169450Smsmith    if (ACPI_MTX_LOCK == UseLock)
79269450Smsmith    {
79369450Smsmith        AcpiCmReleaseMutex (ACPI_MTX_HARDWARE);
79469450Smsmith    }
79569450Smsmith
79669450Smsmith    return_VALUE (Value);
79769450Smsmith}
79869450Smsmith
79969450Smsmith
80069450Smsmith/******************************************************************************
80169450Smsmith *
80269450Smsmith * FUNCTION:    AcpiHwRegisterWrite
80369450Smsmith *
80469450Smsmith * PARAMETERS:  UseLock                - Mutex hw access.
80569450Smsmith *              RegisterId             - RegisterID + Offset.
80669450Smsmith *
80769450Smsmith * RETURN:      Value read or written.
80869450Smsmith *
80969450Smsmith * DESCRIPTION: Acpi register Write function.  Registers are written at the
81069450Smsmith *              given offset.
81169450Smsmith *
81269450Smsmith ******************************************************************************/
81369450Smsmith
81469450Smsmithvoid
81569450SmsmithAcpiHwRegisterWrite (
81669450Smsmith    BOOLEAN                 UseLock,
81769450Smsmith    UINT32                  RegisterId,
81869450Smsmith    UINT32                  Value)
81969450Smsmith{
82069450Smsmith    UINT32                  BankOffset;
82169450Smsmith
82269450Smsmith    FUNCTION_TRACE ("AcpiHwRegisterWrite");
82369450Smsmith
82469450Smsmith
82569450Smsmith    if (ACPI_MTX_LOCK == UseLock)
82669450Smsmith    {
82769450Smsmith        AcpiCmAcquireMutex (ACPI_MTX_HARDWARE);
82869450Smsmith    }
82969450Smsmith
83069450Smsmith
83169450Smsmith    switch (REGISTER_BLOCK_ID (RegisterId))
83269450Smsmith    {
83369450Smsmith    case PM1_STS: /* 16-bit access */
83469450Smsmith
83569746Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, 0);
83669746Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, 0);
83769450Smsmith        break;
83869450Smsmith
83969450Smsmith
84069450Smsmith    case PM1_EN: /* 16-bit access*/
84169450Smsmith
84269450Smsmith        BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
84369746Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset);
84469746Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset);
84569450Smsmith        break;
84669450Smsmith
84769450Smsmith
84869450Smsmith    case PM1_CONTROL: /* 16-bit access */
84969450Smsmith
85071867Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0);
85171867Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0);
85271867Smsmith        break;
85369450Smsmith
85469450Smsmith
85571867Smsmith    case PM1A_CONTROL: /* 16-bit access */
85669450Smsmith
85771867Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0);
85869450Smsmith        break;
85969450Smsmith
86069450Smsmith
86171867Smsmith    case PM1B_CONTROL: /* 16-bit access */
86271867Smsmith
86371867Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0);
86471867Smsmith        break;
86571867Smsmith
86671867Smsmith
86769450Smsmith    case PM2_CONTROL: /* 8-bit access */
86869450Smsmith
86969746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, 0);
87069450Smsmith        break;
87169450Smsmith
87269450Smsmith
87369450Smsmith    case PM_TIMER: /* 32-bit access */
87469450Smsmith
87569746Smsmith        AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, 0);
87669450Smsmith        break;
87769450Smsmith
87869450Smsmith
87969450Smsmith    case GPE0_STS_BLOCK: /* 8-bit access */
88069450Smsmith
88169746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, 0);
88269450Smsmith        break;
88369450Smsmith
88469450Smsmith
88569450Smsmith    case GPE0_EN_BLOCK: /* 8-bit access */
88669450Smsmith
88769450Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
88869746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
88969450Smsmith        break;
89069450Smsmith
89169450Smsmith
89269450Smsmith    case GPE1_STS_BLOCK: /* 8-bit access */
89369450Smsmith
89469746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, 0);
89569450Smsmith        break;
89669450Smsmith
89769450Smsmith
89869450Smsmith    case GPE1_EN_BLOCK: /* 8-bit access */
89969450Smsmith
90069450Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
90169746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
90269450Smsmith        break;
90369450Smsmith
90469450Smsmith
90569450Smsmith    case SMI_CMD_BLOCK: /* 8bit */
90669450Smsmith
90769450Smsmith        /* For 2.0, SMI_CMD is always in IO space */
90869450Smsmith        /* TBD: what about 1.0? 0.71? */
90969450Smsmith
91069450Smsmith       AcpiOsOut8 (AcpiGbl_FADT->SmiCmd, (UINT8) Value);
91169450Smsmith        break;
91269450Smsmith
91369450Smsmith
91469450Smsmith    default:
91569450Smsmith        Value = 0;
91669450Smsmith        break;
91769450Smsmith    }
91869450Smsmith
91969450Smsmith
92069450Smsmith    if (ACPI_MTX_LOCK == UseLock)
92169450Smsmith    {
92269450Smsmith        AcpiCmReleaseMutex (ACPI_MTX_HARDWARE);
92369450Smsmith    }
92469450Smsmith
92569450Smsmith    return_VOID;
92669450Smsmith}
92769450Smsmith
92869450Smsmith
92969450Smsmith/******************************************************************************
93069450Smsmith *
93169450Smsmith * FUNCTION:    AcpiHwLowLevelRead
93269450Smsmith *
93369450Smsmith * PARAMETERS:  Register            - GAS register structure
93469450Smsmith *              Offset              - Offset from the base address in the GAS
93569450Smsmith *              Width               - 8, 16, or 32
93669450Smsmith *
93769450Smsmith * RETURN:      Value read
93869450Smsmith *
93969450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space.
94069450Smsmith *
94169450Smsmith ******************************************************************************/
94269450Smsmith
94369450SmsmithUINT32
94469450SmsmithAcpiHwLowLevelRead (
94569450Smsmith    UINT32                  Width,
94669450Smsmith    ACPI_GAS                *Reg,
94769450Smsmith    UINT32                  Offset)
94869450Smsmith{
94969450Smsmith    UINT32                  Value = 0;
95069450Smsmith    ACPI_PHYSICAL_ADDRESS   MemAddress;
95169450Smsmith    ACPI_IO_ADDRESS         IoAddress;
95269450Smsmith    UINT32                  PciRegister;
95369450Smsmith    UINT32                  PciDevFunc;
95469450Smsmith
95569450Smsmith
95669450Smsmith    /*
95769450Smsmith     * Must have a valid pointer to a GAS structure, and
95869450Smsmith     * a non-zero address within
95969450Smsmith     */
96069450Smsmith    if ((!Reg) ||
96170243Smsmith        (!ACPI_VALID_ADDRESS (Reg->Address)))
96269450Smsmith    {
96369450Smsmith        return 0;
96469450Smsmith    }
96569450Smsmith
96669450Smsmith
96769450Smsmith    /*
96869450Smsmith     * Three address spaces supported:
96969450Smsmith     * Memory, Io, or PCI config.
97069450Smsmith     */
97169450Smsmith
97269450Smsmith    switch (Reg->AddressSpaceId)
97369450Smsmith    {
97469450Smsmith    case ADDRESS_SPACE_SYSTEM_MEMORY:
97569450Smsmith
97670243Smsmith        MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
97769450Smsmith
97869450Smsmith        switch (Width)
97969450Smsmith        {
98069450Smsmith        case 8:
98169450Smsmith            Value = AcpiOsMemIn8  (MemAddress);
98269450Smsmith            break;
98369450Smsmith        case 16:
98469450Smsmith            Value = AcpiOsMemIn16 (MemAddress);
98569450Smsmith            break;
98669450Smsmith        case 32:
98769450Smsmith            Value = AcpiOsMemIn32 (MemAddress);
98869450Smsmith            break;
98969450Smsmith        }
99069450Smsmith        break;
99169450Smsmith
99269450Smsmith
99369450Smsmith    case ADDRESS_SPACE_SYSTEM_IO:
99469450Smsmith
99570243Smsmith        IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
99669450Smsmith
99769450Smsmith        switch (Width)
99869450Smsmith        {
99969450Smsmith        case 8:
100069450Smsmith            Value = AcpiOsIn8  (IoAddress);
100169450Smsmith            break;
100269450Smsmith        case 16:
100369450Smsmith            Value = AcpiOsIn16 (IoAddress);
100469450Smsmith            break;
100569450Smsmith        case 32:
100669450Smsmith            Value = AcpiOsIn32 (IoAddress);
100769450Smsmith            break;
100869450Smsmith        }
100969450Smsmith        break;
101069450Smsmith
101169450Smsmith
101269450Smsmith    case ADDRESS_SPACE_PCI_CONFIG:
101369450Smsmith
101470243Smsmith        PciDevFunc  = ACPI_PCI_DEVFUN   (ACPI_GET_ADDRESS (Reg->Address));
101570243Smsmith        PciRegister = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset;
101669450Smsmith
101769450Smsmith        switch (Width)
101869450Smsmith        {
101969450Smsmith        case 8:
102069450Smsmith            AcpiOsReadPciCfgByte  (0, PciDevFunc, PciRegister, (UINT8 *) &Value);
102169450Smsmith            break;
102269450Smsmith        case 16:
102369450Smsmith            AcpiOsReadPciCfgWord  (0, PciDevFunc, PciRegister, (UINT16 *) &Value);
102469450Smsmith            break;
102569450Smsmith        case 32:
102669450Smsmith            AcpiOsReadPciCfgDword (0, PciDevFunc, PciRegister, (UINT32 *) &Value);
102769450Smsmith            break;
102869450Smsmith        }
102969450Smsmith        break;
103069450Smsmith    }
103169450Smsmith
103269450Smsmith    return Value;
103369450Smsmith}
103469450Smsmith
103569450Smsmith
103669450Smsmith/******************************************************************************
103769450Smsmith *
103869450Smsmith * FUNCTION:    AcpiHwLowLevelWrite
103969450Smsmith *
104069450Smsmith * PARAMETERS:  Width               - 8, 16, or 32
104169450Smsmith *              Value               - To be written
104269450Smsmith *              Register            - GAS register structure
104369450Smsmith *              Offset              - Offset from the base address in the GAS
104469450Smsmith *
104569450Smsmith *
104669450Smsmith * RETURN:      Value read
104769450Smsmith *
104869450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space.
104969450Smsmith *
105069450Smsmith ******************************************************************************/
105169450Smsmith
105269450Smsmithvoid
105369450SmsmithAcpiHwLowLevelWrite (
105469450Smsmith    UINT32                  Width,
105569450Smsmith    UINT32                  Value,
105669450Smsmith    ACPI_GAS                *Reg,
105769450Smsmith    UINT32                  Offset)
105869450Smsmith{
105969450Smsmith    ACPI_PHYSICAL_ADDRESS   MemAddress;
106069450Smsmith    ACPI_IO_ADDRESS         IoAddress;
106169450Smsmith    UINT32                  PciRegister;
106269450Smsmith    UINT32                  PciDevFunc;
106369450Smsmith
106469450Smsmith
106569450Smsmith    /*
106669450Smsmith     * Must have a valid pointer to a GAS structure, and
106769450Smsmith     * a non-zero address within
106869450Smsmith     */
106969450Smsmith    if ((!Reg) ||
107070243Smsmith        (!ACPI_VALID_ADDRESS (Reg->Address)))
107169450Smsmith    {
107269450Smsmith        return;
107369450Smsmith    }
107469450Smsmith
107569450Smsmith
107669450Smsmith    /*
107769450Smsmith     * Three address spaces supported:
107869450Smsmith     * Memory, Io, or PCI config.
107969450Smsmith     */
108069450Smsmith
108169450Smsmith    switch (Reg->AddressSpaceId)
108269450Smsmith    {
108369450Smsmith    case ADDRESS_SPACE_SYSTEM_MEMORY:
108469450Smsmith
108570243Smsmith        MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
108669450Smsmith
108769450Smsmith        switch (Width)
108869450Smsmith        {
108969450Smsmith        case 8:
109069450Smsmith            AcpiOsMemOut8  (MemAddress, (UINT8) Value);
109169450Smsmith            break;
109269450Smsmith        case 16:
109369450Smsmith            AcpiOsMemOut16 (MemAddress, (UINT16) Value);
109469450Smsmith            break;
109569450Smsmith        case 32:
109669450Smsmith            AcpiOsMemOut32 (MemAddress, (UINT32) Value);
109769450Smsmith            break;
109869450Smsmith        }
109969450Smsmith        break;
110069450Smsmith
110169450Smsmith
110269450Smsmith    case ADDRESS_SPACE_SYSTEM_IO:
110369450Smsmith
110470243Smsmith        IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
110569450Smsmith
110669450Smsmith        switch (Width)
110769450Smsmith        {
110869450Smsmith        case 8:
110969450Smsmith            AcpiOsOut8  (IoAddress, (UINT8) Value);
111069450Smsmith            break;
111169450Smsmith        case 16:
111269450Smsmith            AcpiOsOut16 (IoAddress, (UINT16) Value);
111369450Smsmith            break;
111469450Smsmith        case 32:
111569450Smsmith            AcpiOsOut32 (IoAddress, (UINT32) Value);
111669450Smsmith            break;
111769450Smsmith        }
111869450Smsmith        break;
111969450Smsmith
112069450Smsmith
112169450Smsmith    case ADDRESS_SPACE_PCI_CONFIG:
112269450Smsmith
112370243Smsmith        PciDevFunc  = ACPI_PCI_DEVFUN   (ACPI_GET_ADDRESS (Reg->Address));
112470243Smsmith        PciRegister = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset;
112569450Smsmith
112669450Smsmith        switch (Width)
112769450Smsmith        {
112869450Smsmith        case 8:
112969450Smsmith            AcpiOsWritePciCfgByte  (0, PciDevFunc, PciRegister, (UINT8) Value);
113069450Smsmith            break;
113169450Smsmith        case 16:
113269450Smsmith            AcpiOsWritePciCfgWord  (0, PciDevFunc, PciRegister, (UINT16) Value);
113369450Smsmith            break;
113469450Smsmith        case 32:
113569450Smsmith            AcpiOsWritePciCfgDword (0, PciDevFunc, PciRegister, (UINT32) Value);
113669450Smsmith            break;
113769450Smsmith        }
113869450Smsmith        break;
113969450Smsmith    }
114069450Smsmith}
1141