hwregs.c revision 77424
167754Smsmith
267754Smsmith/*******************************************************************************
367754Smsmith *
467754Smsmith * Module Name: hwregs - Read/write access functions for the various ACPI
567754Smsmith *                       control and status registers.
677424Smsmith *              $Revision: 97 $
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
12577424Smsmith#define _COMPONENT          ACPI_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
18777424Smsmith    DEBUG_PRINTP (TRACE_IO, ("About to write %04X to %04X\n",
18877424Smsmith        ALL_FIXED_STS_BITS,
18977424Smsmith        (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address)));
19067754Smsmith
19167754Smsmith
19277424Smsmith    AcpiUtAcquireMutex (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),
20077424Smsmith            (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        {
21177424Smsmith            AcpiOsOut8 ((ACPI_IO_ADDRESS) (
21277424Smsmith                ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address) + Index),
21377424Smsmith                (UINT8) 0xff);
21467754Smsmith        }
21567754Smsmith    }
21667754Smsmith
21769450Smsmith    if (AcpiGbl_FADT->Gpe1BlkLen)
21867754Smsmith    {
21969450Smsmith        GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
22067754Smsmith
22167754Smsmith        for (Index = 0; Index < GpeLength; Index++)
22267754Smsmith        {
22377424Smsmith            AcpiOsOut8 ((ACPI_IO_ADDRESS) (
22477424Smsmith                ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address) + Index),
22577424Smsmith                (UINT8) 0xff);
22667754Smsmith        }
22767754Smsmith    }
22867754Smsmith
22977424Smsmith    AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
23067754Smsmith    return_VOID;
23167754Smsmith}
23267754Smsmith
23367754Smsmith
23467754Smsmith/*******************************************************************************
23567754Smsmith *
23667754Smsmith * FUNCTION:    AcpiHwObtainSleepTypeRegisterData
23767754Smsmith *
23867754Smsmith * PARAMETERS:  SleepState        - Numeric state requested
23967754Smsmith *              *Slp_TypA         - Pointer to byte to receive SLP_TYPa value
24067754Smsmith *              *Slp_TypB         - Pointer to byte to receive SLP_TYPb value
24167754Smsmith *
24267754Smsmith * RETURN:      Status - ACPI status
24367754Smsmith *
24467754Smsmith * DESCRIPTION: AcpiHwObtainSleepTypeRegisterData() obtains the SLP_TYP and
24567754Smsmith *              SLP_TYPb values for the sleep state requested.
24667754Smsmith *
24767754Smsmith ******************************************************************************/
24867754Smsmith
24967754SmsmithACPI_STATUS
25067754SmsmithAcpiHwObtainSleepTypeRegisterData (
25167754Smsmith    UINT8                   SleepState,
25267754Smsmith    UINT8                   *Slp_TypA,
25367754Smsmith    UINT8                   *Slp_TypB)
25467754Smsmith{
25567754Smsmith    ACPI_STATUS             Status = AE_OK;
25667754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
25767754Smsmith
25867754Smsmith
25967754Smsmith    FUNCTION_TRACE ("HwObtainSleepTypeRegisterData");
26067754Smsmith
26167754Smsmith
26267754Smsmith    /*
26367754Smsmith     *  Validate parameters
26467754Smsmith     */
26567754Smsmith
26667754Smsmith    if ((SleepState > ACPI_S_STATES_MAX) ||
26767754Smsmith        !Slp_TypA || !Slp_TypB)
26867754Smsmith    {
26967754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
27067754Smsmith    }
27167754Smsmith
27267754Smsmith    /*
27367754Smsmith     *  AcpiEvaluate the namespace object containing the values for this state
27467754Smsmith     */
27567754Smsmith
27667754Smsmith    Status = AcpiNsEvaluateByName (SleepStateTable[SleepState], NULL, &ObjDesc);
27767754Smsmith    if (ACPI_FAILURE (Status))
27867754Smsmith    {
27967754Smsmith        return_ACPI_STATUS (Status);
28067754Smsmith    }
28167754Smsmith
28267754Smsmith    if (!ObjDesc)
28367754Smsmith    {
28467754Smsmith        REPORT_ERROR (("Missing Sleep State object\n"));
28567754Smsmith        return_ACPI_STATUS (AE_NOT_EXIST);
28667754Smsmith    }
28767754Smsmith
28867754Smsmith    /*
28967754Smsmith     *  We got something, now ensure it is correct.  The object must
29067754Smsmith     *  be a package and must have at least 2 numeric values as the
29167754Smsmith     *  two elements
29267754Smsmith     */
29367754Smsmith
29477424Smsmith    /* Even though AcpiEvaluateObject resolves package references,
29577424Smsmith     * NsEvaluate dpesn't. So, we do it here.
29677424Smsmith     */
29777424Smsmith    Status = AcpiUtResolvePackageReferences(ObjDesc);
29867754Smsmith
29967754Smsmith    if (ObjDesc->Package.Count < 2)
30067754Smsmith    {
30167754Smsmith        /* Must have at least two elements */
30267754Smsmith
30367754Smsmith        REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
30467754Smsmith        Status = AE_ERROR;
30567754Smsmith    }
30667754Smsmith
30767754Smsmith    else if (((ObjDesc->Package.Elements[0])->Common.Type !=
30871867Smsmith                ACPI_TYPE_INTEGER) ||
30967754Smsmith             ((ObjDesc->Package.Elements[1])->Common.Type !=
31071867Smsmith                ACPI_TYPE_INTEGER))
31167754Smsmith    {
31267754Smsmith        /* Must have two  */
31367754Smsmith
31467754Smsmith        REPORT_ERROR (("Sleep State package elements are not both of type Number\n"));
31567754Smsmith        Status = AE_ERROR;
31667754Smsmith    }
31767754Smsmith
31867754Smsmith    else
31967754Smsmith    {
32067754Smsmith        /*
32167754Smsmith         *  Valid _Sx_ package size, type, and value
32267754Smsmith         */
32371867Smsmith        *Slp_TypA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value;
32467754Smsmith
32571867Smsmith        *Slp_TypB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.Value;
32667754Smsmith    }
32767754Smsmith
32867754Smsmith
32967754Smsmith    if (ACPI_FAILURE (Status))
33067754Smsmith    {
33177424Smsmith        DEBUG_PRINTP (ACPI_ERROR, ("Bad Sleep object %p type %X\n",
33267754Smsmith            ObjDesc, ObjDesc->Common.Type));
33367754Smsmith    }
33467754Smsmith
33577424Smsmith    AcpiUtRemoveReference (ObjDesc);
33667754Smsmith
33767754Smsmith    return_ACPI_STATUS (Status);
33867754Smsmith}
33967754Smsmith
34067754Smsmith
34167754Smsmith/*******************************************************************************
34267754Smsmith *
34369450Smsmith * FUNCTION:    AcpiHwRegisterBitAccess
34467754Smsmith *
34567754Smsmith * PARAMETERS:  ReadWrite       - Either ACPI_READ or ACPI_WRITE.
34667754Smsmith *              UseLock         - Lock the hardware
34769450Smsmith *              RegisterId      - index of ACPI Register to access
34867754Smsmith *              Value           - (only used on write) value to write to the
34969450Smsmith *                                Register.  Shifted all the way right.
35067754Smsmith *
35169450Smsmith * RETURN:      Value written to or read from specified Register.  This value
35267754Smsmith *              is shifted all the way right.
35367754Smsmith *
35469450Smsmith * DESCRIPTION: Generic ACPI Register read/write function.
35567754Smsmith *
35667754Smsmith ******************************************************************************/
35767754Smsmith
35867754SmsmithUINT32
35969450SmsmithAcpiHwRegisterBitAccess (
36067754Smsmith    NATIVE_UINT             ReadWrite,
36167754Smsmith    BOOLEAN                 UseLock,
36267754Smsmith    UINT32                  RegisterId,
36367754Smsmith    ...)                    /* Value (only used on write) */
36467754Smsmith{
36567754Smsmith    UINT32                  RegisterValue = 0;
36667754Smsmith    UINT32                  Mask = 0;
36767754Smsmith    UINT32                  Value = 0;
36877424Smsmith    va_list                 marker;
36967754Smsmith
37077424Smsmith
37169450Smsmith    FUNCTION_TRACE ("HwRegisterBitAccess");
37267754Smsmith
37367754Smsmith
37467754Smsmith    if (ReadWrite == ACPI_WRITE)
37567754Smsmith    {
37667754Smsmith        va_start (marker, RegisterId);
37767754Smsmith        Value = va_arg (marker, UINT32);
37867754Smsmith        va_end (marker);
37967754Smsmith    }
38067754Smsmith
38177424Smsmith    if (ACPI_MTX_LOCK == UseLock)
38277424Smsmith    {
38377424Smsmith        AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
38469450Smsmith    }
38567754Smsmith
38667754Smsmith    /*
38767754Smsmith     * Decode the Register ID
38877424Smsmith     * Register id = Register block id | bit id
38969450Smsmith     *
39069450Smsmith     * Check bit id to fine locate Register offset.
39177424Smsmith     * Check Mask to determine Register offset, and then read-write.
39267754Smsmith     */
39367754Smsmith
39477424Smsmith    switch (REGISTER_BLOCK_ID (RegisterId))
39567754Smsmith    {
39669450Smsmith    case PM1_STS:
39767754Smsmith
39869450Smsmith        switch (RegisterId)
39967754Smsmith        {
40069450Smsmith        case TMR_STS:
40169450Smsmith            Mask = TMR_STS_MASK;
40269450Smsmith            break;
40367754Smsmith
40469450Smsmith        case BM_STS:
40569450Smsmith            Mask = BM_STS_MASK;
40669450Smsmith            break;
40767754Smsmith
40869450Smsmith        case GBL_STS:
40969450Smsmith            Mask = GBL_STS_MASK;
41069450Smsmith            break;
41167754Smsmith
41269450Smsmith        case PWRBTN_STS:
41369450Smsmith            Mask = PWRBTN_STS_MASK;
41469450Smsmith            break;
41567754Smsmith
41669450Smsmith        case SLPBTN_STS:
41769450Smsmith            Mask = SLPBTN_STS_MASK;
41869450Smsmith            break;
41967754Smsmith
42069450Smsmith        case RTC_STS:
42169450Smsmith            Mask = RTC_STS_MASK;
42269450Smsmith            break;
42367754Smsmith
42469450Smsmith        case WAK_STS:
42569450Smsmith            Mask = WAK_STS_MASK;
42669450Smsmith            break;
42767754Smsmith
42869450Smsmith        default:
42969450Smsmith            Mask = 0;
43069450Smsmith            break;
43169450Smsmith        }
43267754Smsmith
43369450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_STS);
43467754Smsmith
43569450Smsmith        if (ReadWrite == ACPI_WRITE)
43669450Smsmith        {
43769450Smsmith            /*
43869450Smsmith             * Status Registers are different from the rest.  Clear by
43969450Smsmith             * writing 1, writing 0 has no effect.  So, the only relevent
44069450Smsmith             * information is the single bit we're interested in, all
44169450Smsmith             * others should be written as 0 so they will be left
44269450Smsmith             * unchanged
44369450Smsmith             */
44467754Smsmith
44569450Smsmith            Value <<= AcpiHwGetBitShift (Mask);
44669450Smsmith            Value &= Mask;
44767754Smsmith
44869450Smsmith            if (Value)
44967754Smsmith            {
45077424Smsmith                AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS,
45177424Smsmith                    (UINT16) Value);
45269450Smsmith                RegisterValue = 0;
45367754Smsmith            }
45467754Smsmith        }
45567754Smsmith
45669450Smsmith        break;
45767754Smsmith
45867754Smsmith
45969450Smsmith    case PM1_EN:
46067754Smsmith
46169450Smsmith        switch (RegisterId)
46269450Smsmith        {
46369450Smsmith        case TMR_EN:
46469450Smsmith            Mask = TMR_EN_MASK;
46569450Smsmith            break;
46667754Smsmith
46769450Smsmith        case GBL_EN:
46869450Smsmith            Mask = GBL_EN_MASK;
46969450Smsmith            break;
47067754Smsmith
47169450Smsmith        case PWRBTN_EN:
47269450Smsmith            Mask = PWRBTN_EN_MASK;
47369450Smsmith            break;
47467754Smsmith
47569450Smsmith        case SLPBTN_EN:
47669450Smsmith            Mask = SLPBTN_EN_MASK;
47769450Smsmith            break;
47867754Smsmith
47969450Smsmith        case RTC_EN:
48069450Smsmith            Mask = RTC_EN_MASK;
48169450Smsmith            break;
48267754Smsmith
48369450Smsmith        default:
48469450Smsmith            Mask = 0;
48569450Smsmith            break;
48669450Smsmith        }
48767754Smsmith
48869450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_EN);
48967754Smsmith
49069450Smsmith        if (ReadWrite == ACPI_WRITE)
49169450Smsmith        {
49269450Smsmith            RegisterValue &= ~Mask;
49369450Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
49469450Smsmith            Value          &= Mask;
49569450Smsmith            RegisterValue |= Value;
49667754Smsmith
49769450Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (UINT16) RegisterValue);
49869450Smsmith        }
49967754Smsmith
50067754Smsmith        break;
50167754Smsmith
50267754Smsmith
50367754Smsmith    case PM1_CONTROL:
50467754Smsmith
50567754Smsmith        switch (RegisterId)
50667754Smsmith        {
50767754Smsmith        case SCI_EN:
50867754Smsmith            Mask = SCI_EN_MASK;
50967754Smsmith            break;
51067754Smsmith
51167754Smsmith        case BM_RLD:
51267754Smsmith            Mask = BM_RLD_MASK;
51367754Smsmith            break;
51467754Smsmith
51567754Smsmith        case GBL_RLS:
51667754Smsmith            Mask = GBL_RLS_MASK;
51767754Smsmith            break;
51867754Smsmith
51967754Smsmith        case SLP_TYPE_A:
52067754Smsmith        case SLP_TYPE_B:
52167754Smsmith            Mask = SLP_TYPE_X_MASK;
52267754Smsmith            break;
52367754Smsmith
52467754Smsmith        case SLP_EN:
52567754Smsmith            Mask = SLP_EN_MASK;
52667754Smsmith            break;
52767754Smsmith
52867754Smsmith        default:
52967754Smsmith            Mask = 0;
53067754Smsmith            break;
53167754Smsmith        }
53267754Smsmith
53369450Smsmith
53469450Smsmith        /*
53569450Smsmith         * Read the PM1 Control register.
53669450Smsmith         * Note that at this level, the fact that there are actually TWO
53769450Smsmith         * registers (A and B) and that B may not exist, are abstracted.
53869450Smsmith         */
53969450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL);
54069450Smsmith
54169746Smsmith        DEBUG_PRINT (TRACE_IO, ("PM1 control: Read %X\n", RegisterValue));
54269450Smsmith
54367754Smsmith        if (ReadWrite == ACPI_WRITE)
54467754Smsmith        {
54567754Smsmith            RegisterValue  &= ~Mask;
54667754Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
54767754Smsmith            Value          &= Mask;
54867754Smsmith            RegisterValue  |= Value;
54967754Smsmith
55067754Smsmith            /*
55169450Smsmith             * SLP_TYPE_x Registers are written differently
55269450Smsmith             * than any other control Registers with
55369450Smsmith             * respect to A and B Registers.  The value
55467754Smsmith             * for A may be different than the value for B
55569746Smsmith             *
55669746Smsmith             * Therefore, pass the RegisterId, not just generic PM1_CONTROL,
55769746Smsmith             * because we need to do different things. Yuck.
55867754Smsmith             */
55967754Smsmith
56077424Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId,
56177424Smsmith                    (UINT16) RegisterValue);
56267754Smsmith        }
56367754Smsmith        break;
56467754Smsmith
56567754Smsmith
56667754Smsmith    case PM2_CONTROL:
56767754Smsmith
56867754Smsmith        switch (RegisterId)
56967754Smsmith        {
57067754Smsmith        case ARB_DIS:
57167754Smsmith            Mask = ARB_DIS_MASK;
57267754Smsmith            break;
57367754Smsmith
57467754Smsmith        default:
57567754Smsmith            Mask = 0;
57667754Smsmith            break;
57767754Smsmith        }
57867754Smsmith
57969450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL);
58069450Smsmith
58169746Smsmith        DEBUG_PRINT (TRACE_IO, ("PM2 control: Read %X from %p\n",
58277424Smsmith            RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)));
58369450Smsmith
58467754Smsmith        if (ReadWrite == ACPI_WRITE)
58567754Smsmith        {
58667754Smsmith            RegisterValue  &= ~Mask;
58767754Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
58867754Smsmith            Value          &= Mask;
58967754Smsmith            RegisterValue  |= Value;
59067754Smsmith
59177424Smsmith            DEBUG_PRINT (TRACE_IO, ("About to write %04X to %p\n", RegisterValue,
59269450Smsmith                AcpiGbl_FADT->XPm2CntBlk.Address));
59367754Smsmith
59469450Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
59569450Smsmith                                PM2_CONTROL, (UINT8) (RegisterValue));
59667754Smsmith        }
59767754Smsmith        break;
59867754Smsmith
59967754Smsmith
60067754Smsmith    case PM_TIMER:
60167754Smsmith
60269450Smsmith        Mask = TMR_VAL_MASK;
60369450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
60469450Smsmith                                            PM_TIMER);
60569746Smsmith        DEBUG_PRINT (TRACE_IO, ("PM_TIMER: Read %X from %p\n",
60677424Smsmith            RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPmTmrBlk.Address)));
60767754Smsmith
60867754Smsmith        break;
60967754Smsmith
61067754Smsmith
61167754Smsmith    case GPE1_EN_BLOCK:
61267754Smsmith    case GPE1_STS_BLOCK:
61367754Smsmith    case GPE0_EN_BLOCK:
61467754Smsmith    case GPE0_STS_BLOCK:
61567754Smsmith
61669450Smsmith        /* Determine the bit to be accessed
61769450Smsmith         *
61869450Smsmith         *  (UINT32) RegisterId:
61969450Smsmith         *      31      24       16       8        0
62069450Smsmith         *      +--------+--------+--------+--------+
62169450Smsmith         *      |  gpe_block_id   |  gpe_bit_number |
62269450Smsmith         *      +--------+--------+--------+--------+
62369450Smsmith         *
62469450Smsmith         *     gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK
62569450Smsmith         *     gpe_bit_number is relative from the gpe_block (0x00~0xFF)
62669450Smsmith         */
62767754Smsmith
62869450Smsmith        Mask = REGISTER_BIT_ID(RegisterId); /* gpe_bit_number */
62969450Smsmith        RegisterId = REGISTER_BLOCK_ID(RegisterId) | (Mask >> 3);
63069450Smsmith        Mask = AcpiGbl_DecodeTo8bit [Mask % 8];
63167754Smsmith
63267754Smsmith        /*
63367754Smsmith         * The base address of the GPE 0 Register Block
63467754Smsmith         * Plus 1/2 the length of the GPE 0 Register Block
63569450Smsmith         * The enable Register is the Register following the Status Register
63669450Smsmith         * and each Register is defined as 1/2 of the total Register Block
63767754Smsmith         */
63867754Smsmith
63967754Smsmith        /*
64067754Smsmith         * This sets the bit within EnableBit that needs to be written to
64169450Smsmith         * the Register indicated in Mask to a 1, all others are 0
64267754Smsmith         */
64367754Smsmith
64467754Smsmith        /* Now get the current Enable Bits in the selected Reg */
64567754Smsmith
64669450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId);
64769746Smsmith        DEBUG_PRINT (TRACE_IO, ("GPE Enable bits: Read %X from %X\n",
64877424Smsmith            RegisterValue, RegisterId));
64967754Smsmith
65067754Smsmith        if (ReadWrite == ACPI_WRITE)
65167754Smsmith        {
65267754Smsmith            RegisterValue  &= ~Mask;
65367754Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
65467754Smsmith            Value          &= Mask;
65567754Smsmith            RegisterValue  |= Value;
65667754Smsmith
65767754Smsmith            /* This write will put the Action state into the General Purpose */
65867754Smsmith            /* Enable Register indexed by the value in Mask */
65967754Smsmith
66067754Smsmith            DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n",
66177424Smsmith                RegisterValue, RegisterId));
66277424Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId,
66377424Smsmith                (UINT8) RegisterValue);
66477424Smsmith            RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
66577424Smsmith                                RegisterId);
66667754Smsmith        }
66767754Smsmith        break;
66867754Smsmith
66967754Smsmith
67069450Smsmith    case SMI_CMD_BLOCK:
67167754Smsmith    case PROCESSOR_BLOCK:
67277424Smsmith        /* Not used by any callers at this time - therefore, not implemented */
67377424Smsmith
67467754Smsmith    default:
67567754Smsmith
67667754Smsmith        Mask = 0;
67767754Smsmith        break;
67867754Smsmith    }
67967754Smsmith
68069450Smsmith    if (ACPI_MTX_LOCK == UseLock) {
68177424Smsmith        AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
68269450Smsmith    }
68367754Smsmith
68469450Smsmith
68567754Smsmith    RegisterValue &= Mask;
68667754Smsmith    RegisterValue >>= AcpiHwGetBitShift (Mask);
68767754Smsmith
68869746Smsmith    DEBUG_PRINT (TRACE_IO, ("Register I/O: returning %X\n", RegisterValue));
68967754Smsmith    return_VALUE (RegisterValue);
69067754Smsmith}
69169450Smsmith
69269450Smsmith
69369450Smsmith/******************************************************************************
69469450Smsmith *
69569450Smsmith * FUNCTION:    AcpiHwRegisterRead
69669450Smsmith *
69769450Smsmith * PARAMETERS:  UseLock                - Mutex hw access.
69869450Smsmith *              RegisterId             - RegisterID + Offset.
69969450Smsmith *
70069450Smsmith * RETURN:      Value read or written.
70169450Smsmith *
70269450Smsmith * DESCRIPTION: Acpi register read function.  Registers are read at the
70369450Smsmith *              given offset.
70469450Smsmith *
70569450Smsmith ******************************************************************************/
70669450Smsmith
70769450SmsmithUINT32
70869450SmsmithAcpiHwRegisterRead (
70969450Smsmith    BOOLEAN                 UseLock,
71069450Smsmith    UINT32                  RegisterId)
71169450Smsmith{
71269450Smsmith    UINT32                  Value       = 0;
71369450Smsmith    UINT32                  BankOffset;
71469450Smsmith
71577424Smsmith
71669450Smsmith    FUNCTION_TRACE ("AcpiHwRegisterRead");
71769450Smsmith
71877424Smsmith
71969450Smsmith    if (ACPI_MTX_LOCK == UseLock)
72069450Smsmith    {
72177424Smsmith        AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
72269450Smsmith    }
72369450Smsmith
72469450Smsmith
72569450Smsmith    switch (REGISTER_BLOCK_ID(RegisterId))
72669450Smsmith    {
72769450Smsmith    case PM1_STS: /* 16-bit access */
72869450Smsmith
72969746Smsmith        Value =  AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, 0);
73069746Smsmith        Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, 0);
73169450Smsmith        break;
73269450Smsmith
73369450Smsmith
73469450Smsmith    case PM1_EN: /* 16-bit access*/
73569450Smsmith
73669450Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
73769746Smsmith        Value =  AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset);
73869746Smsmith        Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset);
73969450Smsmith        break;
74069450Smsmith
74169450Smsmith
74269450Smsmith    case PM1_CONTROL: /* 16-bit access */
74369450Smsmith
74471867Smsmith        Value =  AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aCntBlk, 0);
74571867Smsmith        Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bCntBlk, 0);
74669450Smsmith        break;
74769450Smsmith
74869450Smsmith
74969450Smsmith    case PM2_CONTROL: /* 8-bit access */
75069450Smsmith
75169746Smsmith        Value =  AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XPm2CntBlk, 0);
75269450Smsmith        break;
75369450Smsmith
75469450Smsmith
75569450Smsmith    case PM_TIMER: /* 32-bit access */
75669450Smsmith
75769746Smsmith        Value =  AcpiHwLowLevelRead (32, &AcpiGbl_FADT->XPmTmrBlk, 0);
75869450Smsmith        break;
75969450Smsmith
76069450Smsmith
76169450Smsmith    case GPE0_STS_BLOCK: /* 8-bit access */
76269450Smsmith
76369746Smsmith        Value =  AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, 0);
76469450Smsmith        break;
76569450Smsmith
76669450Smsmith
76769450Smsmith    case GPE0_EN_BLOCK: /* 8-bit access */
76869450Smsmith
76969450Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
77069746Smsmith        Value =  AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
77169450Smsmith        break;
77269450Smsmith
77369450Smsmith
77469450Smsmith    case GPE1_STS_BLOCK: /* 8-bit access */
77569450Smsmith
77669746Smsmith        Value =  AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, 0);
77769450Smsmith        break;
77869450Smsmith
77969450Smsmith
78069450Smsmith    case GPE1_EN_BLOCK: /* 8-bit access */
78169450Smsmith
78269450Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
78369746Smsmith        Value =  AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
78469450Smsmith        break;
78569450Smsmith
78669450Smsmith
78769450Smsmith    case SMI_CMD_BLOCK: /* 8bit */
78869450Smsmith
78969450Smsmith        Value = (UINT32) AcpiOsIn8 (AcpiGbl_FADT->SmiCmd);
79069450Smsmith        break;
79169450Smsmith
79269450Smsmith
79369450Smsmith    default:
79469450Smsmith        Value = 0;
79569450Smsmith        break;
79669450Smsmith    }
79769450Smsmith
79869450Smsmith
79969450Smsmith    if (ACPI_MTX_LOCK == UseLock)
80069450Smsmith    {
80177424Smsmith        AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
80269450Smsmith    }
80369450Smsmith
80469450Smsmith    return_VALUE (Value);
80569450Smsmith}
80669450Smsmith
80769450Smsmith
80869450Smsmith/******************************************************************************
80969450Smsmith *
81069450Smsmith * FUNCTION:    AcpiHwRegisterWrite
81169450Smsmith *
81269450Smsmith * PARAMETERS:  UseLock                - Mutex hw access.
81369450Smsmith *              RegisterId             - RegisterID + Offset.
81469450Smsmith *
81569450Smsmith * RETURN:      Value read or written.
81669450Smsmith *
81769450Smsmith * DESCRIPTION: Acpi register Write function.  Registers are written at the
81869450Smsmith *              given offset.
81969450Smsmith *
82069450Smsmith ******************************************************************************/
82169450Smsmith
82269450Smsmithvoid
82369450SmsmithAcpiHwRegisterWrite (
82469450Smsmith    BOOLEAN                 UseLock,
82569450Smsmith    UINT32                  RegisterId,
82669450Smsmith    UINT32                  Value)
82769450Smsmith{
82869450Smsmith    UINT32                  BankOffset;
82969450Smsmith
83069450Smsmith    FUNCTION_TRACE ("AcpiHwRegisterWrite");
83169450Smsmith
83269450Smsmith
83369450Smsmith    if (ACPI_MTX_LOCK == UseLock)
83469450Smsmith    {
83577424Smsmith        AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
83669450Smsmith    }
83769450Smsmith
83869450Smsmith
83969450Smsmith    switch (REGISTER_BLOCK_ID (RegisterId))
84069450Smsmith    {
84169450Smsmith    case PM1_STS: /* 16-bit access */
84269450Smsmith
84369746Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, 0);
84469746Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, 0);
84569450Smsmith        break;
84669450Smsmith
84769450Smsmith
84869450Smsmith    case PM1_EN: /* 16-bit access*/
84969450Smsmith
85069450Smsmith        BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
85169746Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset);
85269746Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset);
85369450Smsmith        break;
85469450Smsmith
85569450Smsmith
85669450Smsmith    case PM1_CONTROL: /* 16-bit access */
85769450Smsmith
85871867Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0);
85971867Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0);
86071867Smsmith        break;
86169450Smsmith
86269450Smsmith
86371867Smsmith    case PM1A_CONTROL: /* 16-bit access */
86469450Smsmith
86571867Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0);
86669450Smsmith        break;
86769450Smsmith
86869450Smsmith
86971867Smsmith    case PM1B_CONTROL: /* 16-bit access */
87071867Smsmith
87171867Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0);
87271867Smsmith        break;
87371867Smsmith
87471867Smsmith
87569450Smsmith    case PM2_CONTROL: /* 8-bit access */
87669450Smsmith
87769746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, 0);
87869450Smsmith        break;
87969450Smsmith
88069450Smsmith
88169450Smsmith    case PM_TIMER: /* 32-bit access */
88269450Smsmith
88369746Smsmith        AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, 0);
88469450Smsmith        break;
88569450Smsmith
88669450Smsmith
88769450Smsmith    case GPE0_STS_BLOCK: /* 8-bit access */
88869450Smsmith
88969746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, 0);
89069450Smsmith        break;
89169450Smsmith
89269450Smsmith
89369450Smsmith    case GPE0_EN_BLOCK: /* 8-bit access */
89469450Smsmith
89569450Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
89669746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
89769450Smsmith        break;
89869450Smsmith
89969450Smsmith
90069450Smsmith    case GPE1_STS_BLOCK: /* 8-bit access */
90169450Smsmith
90269746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, 0);
90369450Smsmith        break;
90469450Smsmith
90569450Smsmith
90669450Smsmith    case GPE1_EN_BLOCK: /* 8-bit access */
90769450Smsmith
90869450Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
90969746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
91069450Smsmith        break;
91169450Smsmith
91269450Smsmith
91369450Smsmith    case SMI_CMD_BLOCK: /* 8bit */
91469450Smsmith
91569450Smsmith        /* For 2.0, SMI_CMD is always in IO space */
91669450Smsmith        /* TBD: what about 1.0? 0.71? */
91769450Smsmith
91877424Smsmith        AcpiOsOut8 (AcpiGbl_FADT->SmiCmd, (UINT8) Value);
91969450Smsmith        break;
92069450Smsmith
92169450Smsmith
92269450Smsmith    default:
92369450Smsmith        Value = 0;
92469450Smsmith        break;
92569450Smsmith    }
92669450Smsmith
92769450Smsmith
92869450Smsmith    if (ACPI_MTX_LOCK == UseLock)
92969450Smsmith    {
93077424Smsmith        AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
93169450Smsmith    }
93269450Smsmith
93369450Smsmith    return_VOID;
93469450Smsmith}
93569450Smsmith
93669450Smsmith
93769450Smsmith/******************************************************************************
93869450Smsmith *
93969450Smsmith * FUNCTION:    AcpiHwLowLevelRead
94069450Smsmith *
94169450Smsmith * PARAMETERS:  Register            - GAS register structure
94269450Smsmith *              Offset              - Offset from the base address in the GAS
94369450Smsmith *              Width               - 8, 16, or 32
94469450Smsmith *
94569450Smsmith * RETURN:      Value read
94669450Smsmith *
94769450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space.
94869450Smsmith *
94969450Smsmith ******************************************************************************/
95069450Smsmith
95169450SmsmithUINT32
95269450SmsmithAcpiHwLowLevelRead (
95369450Smsmith    UINT32                  Width,
95477424Smsmith    ACPI_GENERIC_ADDRESS    *Reg,
95569450Smsmith    UINT32                  Offset)
95669450Smsmith{
95769450Smsmith    UINT32                  Value = 0;
95869450Smsmith    ACPI_PHYSICAL_ADDRESS   MemAddress;
95969450Smsmith    ACPI_IO_ADDRESS         IoAddress;
96069450Smsmith    UINT32                  PciRegister;
96169450Smsmith    UINT32                  PciDevFunc;
96269450Smsmith
96369450Smsmith
96469450Smsmith    /*
96569450Smsmith     * Must have a valid pointer to a GAS structure, and
96669450Smsmith     * a non-zero address within
96769450Smsmith     */
96869450Smsmith    if ((!Reg) ||
96970243Smsmith        (!ACPI_VALID_ADDRESS (Reg->Address)))
97069450Smsmith    {
97169450Smsmith        return 0;
97269450Smsmith    }
97369450Smsmith
97469450Smsmith
97569450Smsmith    /*
97669450Smsmith     * Three address spaces supported:
97769450Smsmith     * Memory, Io, or PCI config.
97869450Smsmith     */
97969450Smsmith
98069450Smsmith    switch (Reg->AddressSpaceId)
98169450Smsmith    {
98277424Smsmith    case ACPI_ADR_SPACE_SYSTEM_MEMORY:
98369450Smsmith
98470243Smsmith        MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
98569450Smsmith
98669450Smsmith        switch (Width)
98769450Smsmith        {
98869450Smsmith        case 8:
98969450Smsmith            Value = AcpiOsMemIn8  (MemAddress);
99069450Smsmith            break;
99169450Smsmith        case 16:
99269450Smsmith            Value = AcpiOsMemIn16 (MemAddress);
99369450Smsmith            break;
99469450Smsmith        case 32:
99569450Smsmith            Value = AcpiOsMemIn32 (MemAddress);
99669450Smsmith            break;
99769450Smsmith        }
99869450Smsmith        break;
99969450Smsmith
100069450Smsmith
100177424Smsmith    case ACPI_ADR_SPACE_SYSTEM_IO:
100269450Smsmith
100370243Smsmith        IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
100469450Smsmith
100569450Smsmith        switch (Width)
100669450Smsmith        {
100769450Smsmith        case 8:
100869450Smsmith            Value = AcpiOsIn8  (IoAddress);
100969450Smsmith            break;
101069450Smsmith        case 16:
101169450Smsmith            Value = AcpiOsIn16 (IoAddress);
101269450Smsmith            break;
101369450Smsmith        case 32:
101469450Smsmith            Value = AcpiOsIn32 (IoAddress);
101569450Smsmith            break;
101669450Smsmith        }
101769450Smsmith        break;
101869450Smsmith
101969450Smsmith
102077424Smsmith    case ACPI_ADR_SPACE_PCI_CONFIG:
102169450Smsmith
102270243Smsmith        PciDevFunc  = ACPI_PCI_DEVFUN   (ACPI_GET_ADDRESS (Reg->Address));
102370243Smsmith        PciRegister = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset;
102469450Smsmith
102569450Smsmith        switch (Width)
102669450Smsmith        {
102769450Smsmith        case 8:
102869450Smsmith            AcpiOsReadPciCfgByte  (0, PciDevFunc, PciRegister, (UINT8 *) &Value);
102969450Smsmith            break;
103069450Smsmith        case 16:
103169450Smsmith            AcpiOsReadPciCfgWord  (0, PciDevFunc, PciRegister, (UINT16 *) &Value);
103269450Smsmith            break;
103369450Smsmith        case 32:
103469450Smsmith            AcpiOsReadPciCfgDword (0, PciDevFunc, PciRegister, (UINT32 *) &Value);
103569450Smsmith            break;
103669450Smsmith        }
103769450Smsmith        break;
103869450Smsmith    }
103969450Smsmith
104069450Smsmith    return Value;
104169450Smsmith}
104269450Smsmith
104369450Smsmith
104469450Smsmith/******************************************************************************
104569450Smsmith *
104669450Smsmith * FUNCTION:    AcpiHwLowLevelWrite
104769450Smsmith *
104869450Smsmith * PARAMETERS:  Width               - 8, 16, or 32
104969450Smsmith *              Value               - To be written
105069450Smsmith *              Register            - GAS register structure
105169450Smsmith *              Offset              - Offset from the base address in the GAS
105269450Smsmith *
105369450Smsmith *
105469450Smsmith * RETURN:      Value read
105569450Smsmith *
105669450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space.
105769450Smsmith *
105869450Smsmith ******************************************************************************/
105969450Smsmith
106069450Smsmithvoid
106169450SmsmithAcpiHwLowLevelWrite (
106269450Smsmith    UINT32                  Width,
106369450Smsmith    UINT32                  Value,
106477424Smsmith    ACPI_GENERIC_ADDRESS    *Reg,
106569450Smsmith    UINT32                  Offset)
106669450Smsmith{
106769450Smsmith    ACPI_PHYSICAL_ADDRESS   MemAddress;
106869450Smsmith    ACPI_IO_ADDRESS         IoAddress;
106969450Smsmith    UINT32                  PciRegister;
107069450Smsmith    UINT32                  PciDevFunc;
107169450Smsmith
107269450Smsmith
107369450Smsmith    /*
107469450Smsmith     * Must have a valid pointer to a GAS structure, and
107569450Smsmith     * a non-zero address within
107669450Smsmith     */
107769450Smsmith    if ((!Reg) ||
107870243Smsmith        (!ACPI_VALID_ADDRESS (Reg->Address)))
107969450Smsmith    {
108069450Smsmith        return;
108169450Smsmith    }
108269450Smsmith
108369450Smsmith
108469450Smsmith    /*
108569450Smsmith     * Three address spaces supported:
108669450Smsmith     * Memory, Io, or PCI config.
108769450Smsmith     */
108869450Smsmith
108969450Smsmith    switch (Reg->AddressSpaceId)
109069450Smsmith    {
109177424Smsmith    case ACPI_ADR_SPACE_SYSTEM_MEMORY:
109269450Smsmith
109370243Smsmith        MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
109469450Smsmith
109569450Smsmith        switch (Width)
109669450Smsmith        {
109769450Smsmith        case 8:
109869450Smsmith            AcpiOsMemOut8  (MemAddress, (UINT8) Value);
109969450Smsmith            break;
110069450Smsmith        case 16:
110169450Smsmith            AcpiOsMemOut16 (MemAddress, (UINT16) Value);
110269450Smsmith            break;
110369450Smsmith        case 32:
110469450Smsmith            AcpiOsMemOut32 (MemAddress, (UINT32) Value);
110569450Smsmith            break;
110669450Smsmith        }
110769450Smsmith        break;
110869450Smsmith
110969450Smsmith
111077424Smsmith    case ACPI_ADR_SPACE_SYSTEM_IO:
111169450Smsmith
111270243Smsmith        IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
111369450Smsmith
111469450Smsmith        switch (Width)
111569450Smsmith        {
111669450Smsmith        case 8:
111769450Smsmith            AcpiOsOut8  (IoAddress, (UINT8) Value);
111869450Smsmith            break;
111969450Smsmith        case 16:
112069450Smsmith            AcpiOsOut16 (IoAddress, (UINT16) Value);
112169450Smsmith            break;
112269450Smsmith        case 32:
112369450Smsmith            AcpiOsOut32 (IoAddress, (UINT32) Value);
112469450Smsmith            break;
112569450Smsmith        }
112669450Smsmith        break;
112769450Smsmith
112869450Smsmith
112977424Smsmith    case ACPI_ADR_SPACE_PCI_CONFIG:
113069450Smsmith
113170243Smsmith        PciDevFunc  = ACPI_PCI_DEVFUN   (ACPI_GET_ADDRESS (Reg->Address));
113270243Smsmith        PciRegister = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset;
113369450Smsmith
113469450Smsmith        switch (Width)
113569450Smsmith        {
113669450Smsmith        case 8:
113769450Smsmith            AcpiOsWritePciCfgByte  (0, PciDevFunc, PciRegister, (UINT8) Value);
113869450Smsmith            break;
113969450Smsmith        case 16:
114069450Smsmith            AcpiOsWritePciCfgWord  (0, PciDevFunc, PciRegister, (UINT16) Value);
114169450Smsmith            break;
114269450Smsmith        case 32:
114369450Smsmith            AcpiOsWritePciCfgDword (0, PciDevFunc, PciRegister, (UINT32) Value);
114469450Smsmith            break;
114569450Smsmith        }
114669450Smsmith        break;
114769450Smsmith    }
114869450Smsmith}
1149