hwregs.c revision 83174
167754Smsmith
267754Smsmith/*******************************************************************************
367754Smsmith *
467754Smsmith * Module Name: hwregs - Read/write access functions for the various ACPI
567754Smsmith *                       control and status registers.
683174Smsmith *              $Revision: 109 $
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/*******************************************************************************
13067754Smsmith *
13167754Smsmith * FUNCTION:    AcpiHwGetBitShift
13267754Smsmith *
13367754Smsmith * PARAMETERS:  Mask            - Input mask to determine bit shift from.
13467754Smsmith *                                Must have at least 1 bit set.
13567754Smsmith *
13667754Smsmith * RETURN:      Bit location of the lsb of the mask
13767754Smsmith *
13867754Smsmith * DESCRIPTION: Returns the bit number for the low order bit that's set.
13967754Smsmith *
14067754Smsmith ******************************************************************************/
14167754Smsmith
14271867SmsmithUINT32
14367754SmsmithAcpiHwGetBitShift (
14467754Smsmith    UINT32                  Mask)
14567754Smsmith{
14667754Smsmith    UINT32                  Shift;
14767754Smsmith
14867754Smsmith
14967754Smsmith    FUNCTION_TRACE ("HwGetBitShift");
15067754Smsmith
15167754Smsmith
15267754Smsmith    for (Shift = 0; ((Mask >> Shift) & 1) == 0; Shift++)
15367754Smsmith    { ; }
15467754Smsmith
15567754Smsmith    return_VALUE (Shift);
15667754Smsmith}
15767754Smsmith
15867754Smsmith
15967754Smsmith/*******************************************************************************
16067754Smsmith *
16167754Smsmith * FUNCTION:    AcpiHwClearAcpiStatus
16267754Smsmith *
16367754Smsmith * PARAMETERS:  none
16467754Smsmith *
16567754Smsmith * RETURN:      none
16667754Smsmith *
16767754Smsmith * DESCRIPTION: Clears all fixed and general purpose status bits
16867754Smsmith *
16967754Smsmith ******************************************************************************/
17067754Smsmith
17167754Smsmithvoid
17267754SmsmithAcpiHwClearAcpiStatus (void)
17367754Smsmith{
17467754Smsmith    UINT16                  GpeLength;
17567754Smsmith    UINT16                  Index;
17667754Smsmith
17767754Smsmith
17867754Smsmith    FUNCTION_TRACE ("HwClearAcpiStatus");
17967754Smsmith
18067754Smsmith
18182367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n",
18277424Smsmith        ALL_FIXED_STS_BITS,
18377424Smsmith        (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address)));
18467754Smsmith
18567754Smsmith
18677424Smsmith    AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
18767754Smsmith
18869450Smsmith    AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS);
18967754Smsmith
19069450Smsmith
19170243Smsmith    if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address))
19267754Smsmith    {
19383174Smsmith        AcpiOsWritePort ((ACPI_IO_ADDRESS)
19480062Smsmith            ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address),
19580062Smsmith            ALL_FIXED_STS_BITS, 16);
19667754Smsmith    }
19767754Smsmith
19867754Smsmith    /* now clear the GPE Bits */
19967754Smsmith
20069450Smsmith    if (AcpiGbl_FADT->Gpe0BlkLen)
20167754Smsmith    {
20269450Smsmith        GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe0BlkLen);
20367754Smsmith
20467754Smsmith        for (Index = 0; Index < GpeLength; Index++)
20567754Smsmith        {
20680062Smsmith            AcpiOsWritePort ((ACPI_IO_ADDRESS) (
20777424Smsmith                ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address) + Index),
20880062Smsmith                    0xFF, 8);
20967754Smsmith        }
21067754Smsmith    }
21167754Smsmith
21269450Smsmith    if (AcpiGbl_FADT->Gpe1BlkLen)
21367754Smsmith    {
21469450Smsmith        GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe1BlkLen);
21567754Smsmith
21667754Smsmith        for (Index = 0; Index < GpeLength; Index++)
21767754Smsmith        {
21880062Smsmith            AcpiOsWritePort ((ACPI_IO_ADDRESS) (
21977424Smsmith                ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address) + Index),
22080062Smsmith                0xFF, 8);
22167754Smsmith        }
22267754Smsmith    }
22367754Smsmith
22477424Smsmith    AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
22567754Smsmith    return_VOID;
22667754Smsmith}
22767754Smsmith
22867754Smsmith
22967754Smsmith/*******************************************************************************
23067754Smsmith *
23167754Smsmith * FUNCTION:    AcpiHwObtainSleepTypeRegisterData
23267754Smsmith *
23367754Smsmith * PARAMETERS:  SleepState        - Numeric state requested
23467754Smsmith *              *Slp_TypA         - Pointer to byte to receive SLP_TYPa value
23567754Smsmith *              *Slp_TypB         - Pointer to byte to receive SLP_TYPb value
23667754Smsmith *
23767754Smsmith * RETURN:      Status - ACPI status
23867754Smsmith *
23967754Smsmith * DESCRIPTION: AcpiHwObtainSleepTypeRegisterData() obtains the SLP_TYP and
24067754Smsmith *              SLP_TYPb values for the sleep state requested.
24167754Smsmith *
24267754Smsmith ******************************************************************************/
24367754Smsmith
24467754SmsmithACPI_STATUS
24567754SmsmithAcpiHwObtainSleepTypeRegisterData (
24667754Smsmith    UINT8                   SleepState,
24767754Smsmith    UINT8                   *Slp_TypA,
24867754Smsmith    UINT8                   *Slp_TypB)
24967754Smsmith{
25067754Smsmith    ACPI_STATUS             Status = AE_OK;
25167754Smsmith    ACPI_OPERAND_OBJECT     *ObjDesc;
25267754Smsmith
25367754Smsmith
25467754Smsmith    FUNCTION_TRACE ("HwObtainSleepTypeRegisterData");
25567754Smsmith
25667754Smsmith
25767754Smsmith    /*
25867754Smsmith     *  Validate parameters
25967754Smsmith     */
26067754Smsmith    if ((SleepState > ACPI_S_STATES_MAX) ||
26167754Smsmith        !Slp_TypA || !Slp_TypB)
26267754Smsmith    {
26367754Smsmith        return_ACPI_STATUS (AE_BAD_PARAMETER);
26467754Smsmith    }
26567754Smsmith
26667754Smsmith    /*
26767754Smsmith     *  AcpiEvaluate the namespace object containing the values for this state
26867754Smsmith     */
26983174Smsmith    Status = AcpiNsEvaluateByName ((NATIVE_CHAR *) AcpiGbl_DbSleepStates[SleepState],
27083174Smsmith                    NULL, &ObjDesc);
27167754Smsmith    if (ACPI_FAILURE (Status))
27267754Smsmith    {
27367754Smsmith        return_ACPI_STATUS (Status);
27467754Smsmith    }
27567754Smsmith
27667754Smsmith    if (!ObjDesc)
27767754Smsmith    {
27867754Smsmith        REPORT_ERROR (("Missing Sleep State object\n"));
27967754Smsmith        return_ACPI_STATUS (AE_NOT_EXIST);
28067754Smsmith    }
28167754Smsmith
28267754Smsmith    /*
28367754Smsmith     *  We got something, now ensure it is correct.  The object must
28467754Smsmith     *  be a package and must have at least 2 numeric values as the
28567754Smsmith     *  two elements
28667754Smsmith     */
28767754Smsmith
28877424Smsmith    /* Even though AcpiEvaluateObject resolves package references,
28977424Smsmith     * NsEvaluate dpesn't. So, we do it here.
29077424Smsmith     */
29177424Smsmith    Status = AcpiUtResolvePackageReferences(ObjDesc);
29267754Smsmith
29367754Smsmith    if (ObjDesc->Package.Count < 2)
29467754Smsmith    {
29567754Smsmith        /* Must have at least two elements */
29667754Smsmith
29767754Smsmith        REPORT_ERROR (("Sleep State package does not have at least two elements\n"));
29867754Smsmith        Status = AE_ERROR;
29967754Smsmith    }
30067754Smsmith
30167754Smsmith    else if (((ObjDesc->Package.Elements[0])->Common.Type !=
30271867Smsmith                ACPI_TYPE_INTEGER) ||
30367754Smsmith             ((ObjDesc->Package.Elements[1])->Common.Type !=
30471867Smsmith                ACPI_TYPE_INTEGER))
30567754Smsmith    {
30667754Smsmith        /* Must have two  */
30767754Smsmith
30867754Smsmith        REPORT_ERROR (("Sleep State package elements are not both of type Number\n"));
30967754Smsmith        Status = AE_ERROR;
31067754Smsmith    }
31167754Smsmith
31267754Smsmith    else
31367754Smsmith    {
31467754Smsmith        /*
31567754Smsmith         *  Valid _Sx_ package size, type, and value
31667754Smsmith         */
31771867Smsmith        *Slp_TypA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value;
31867754Smsmith
31971867Smsmith        *Slp_TypB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.Value;
32067754Smsmith    }
32167754Smsmith
32267754Smsmith
32367754Smsmith    if (ACPI_FAILURE (Status))
32467754Smsmith    {
32582367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad Sleep object %p type %X\n",
32667754Smsmith            ObjDesc, ObjDesc->Common.Type));
32767754Smsmith    }
32867754Smsmith
32977424Smsmith    AcpiUtRemoveReference (ObjDesc);
33067754Smsmith
33167754Smsmith    return_ACPI_STATUS (Status);
33267754Smsmith}
33367754Smsmith
33467754Smsmith
33567754Smsmith/*******************************************************************************
33667754Smsmith *
33769450Smsmith * FUNCTION:    AcpiHwRegisterBitAccess
33867754Smsmith *
33967754Smsmith * PARAMETERS:  ReadWrite       - Either ACPI_READ or ACPI_WRITE.
34067754Smsmith *              UseLock         - Lock the hardware
34169450Smsmith *              RegisterId      - index of ACPI Register to access
34267754Smsmith *              Value           - (only used on write) value to write to the
34369450Smsmith *                                Register.  Shifted all the way right.
34467754Smsmith *
34569450Smsmith * RETURN:      Value written to or read from specified Register.  This value
34667754Smsmith *              is shifted all the way right.
34767754Smsmith *
34869450Smsmith * DESCRIPTION: Generic ACPI Register read/write function.
34967754Smsmith *
35067754Smsmith ******************************************************************************/
35167754Smsmith
35267754SmsmithUINT32
35369450SmsmithAcpiHwRegisterBitAccess (
35467754Smsmith    NATIVE_UINT             ReadWrite,
35567754Smsmith    BOOLEAN                 UseLock,
35667754Smsmith    UINT32                  RegisterId,
35767754Smsmith    ...)                    /* Value (only used on write) */
35867754Smsmith{
35967754Smsmith    UINT32                  RegisterValue = 0;
36067754Smsmith    UINT32                  Mask = 0;
36167754Smsmith    UINT32                  Value = 0;
36277424Smsmith    va_list                 marker;
36367754Smsmith
36477424Smsmith
36569450Smsmith    FUNCTION_TRACE ("HwRegisterBitAccess");
36667754Smsmith
36767754Smsmith
36867754Smsmith    if (ReadWrite == ACPI_WRITE)
36967754Smsmith    {
37067754Smsmith        va_start (marker, RegisterId);
37167754Smsmith        Value = va_arg (marker, UINT32);
37267754Smsmith        va_end (marker);
37367754Smsmith    }
37467754Smsmith
37577424Smsmith    if (ACPI_MTX_LOCK == UseLock)
37677424Smsmith    {
37777424Smsmith        AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
37869450Smsmith    }
37967754Smsmith
38067754Smsmith    /*
38167754Smsmith     * Decode the Register ID
38277424Smsmith     * Register id = Register block id | bit id
38369450Smsmith     *
38469450Smsmith     * Check bit id to fine locate Register offset.
38577424Smsmith     * Check Mask to determine Register offset, and then read-write.
38667754Smsmith     */
38777424Smsmith    switch (REGISTER_BLOCK_ID (RegisterId))
38867754Smsmith    {
38969450Smsmith    case PM1_STS:
39067754Smsmith
39169450Smsmith        switch (RegisterId)
39267754Smsmith        {
39369450Smsmith        case TMR_STS:
39469450Smsmith            Mask = TMR_STS_MASK;
39569450Smsmith            break;
39667754Smsmith
39769450Smsmith        case BM_STS:
39869450Smsmith            Mask = BM_STS_MASK;
39969450Smsmith            break;
40067754Smsmith
40169450Smsmith        case GBL_STS:
40269450Smsmith            Mask = GBL_STS_MASK;
40369450Smsmith            break;
40467754Smsmith
40569450Smsmith        case PWRBTN_STS:
40669450Smsmith            Mask = PWRBTN_STS_MASK;
40769450Smsmith            break;
40867754Smsmith
40969450Smsmith        case SLPBTN_STS:
41069450Smsmith            Mask = SLPBTN_STS_MASK;
41169450Smsmith            break;
41267754Smsmith
41369450Smsmith        case RTC_STS:
41469450Smsmith            Mask = RTC_STS_MASK;
41569450Smsmith            break;
41667754Smsmith
41769450Smsmith        case WAK_STS:
41869450Smsmith            Mask = WAK_STS_MASK;
41969450Smsmith            break;
42067754Smsmith
42169450Smsmith        default:
42269450Smsmith            Mask = 0;
42369450Smsmith            break;
42469450Smsmith        }
42567754Smsmith
42669450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_STS);
42767754Smsmith
42869450Smsmith        if (ReadWrite == ACPI_WRITE)
42969450Smsmith        {
43069450Smsmith            /*
43169450Smsmith             * Status Registers are different from the rest.  Clear by
43269450Smsmith             * writing 1, writing 0 has no effect.  So, the only relevent
43369450Smsmith             * information is the single bit we're interested in, all
43469450Smsmith             * others should be written as 0 so they will be left
43569450Smsmith             * unchanged
43669450Smsmith             */
43769450Smsmith            Value <<= AcpiHwGetBitShift (Mask);
43869450Smsmith            Value &= Mask;
43967754Smsmith
44069450Smsmith            if (Value)
44167754Smsmith            {
44277424Smsmith                AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS,
44377424Smsmith                    (UINT16) Value);
44469450Smsmith                RegisterValue = 0;
44567754Smsmith            }
44667754Smsmith        }
44767754Smsmith
44869450Smsmith        break;
44967754Smsmith
45067754Smsmith
45169450Smsmith    case PM1_EN:
45267754Smsmith
45369450Smsmith        switch (RegisterId)
45469450Smsmith        {
45569450Smsmith        case TMR_EN:
45669450Smsmith            Mask = TMR_EN_MASK;
45769450Smsmith            break;
45867754Smsmith
45969450Smsmith        case GBL_EN:
46069450Smsmith            Mask = GBL_EN_MASK;
46169450Smsmith            break;
46267754Smsmith
46369450Smsmith        case PWRBTN_EN:
46469450Smsmith            Mask = PWRBTN_EN_MASK;
46569450Smsmith            break;
46667754Smsmith
46769450Smsmith        case SLPBTN_EN:
46869450Smsmith            Mask = SLPBTN_EN_MASK;
46969450Smsmith            break;
47067754Smsmith
47169450Smsmith        case RTC_EN:
47269450Smsmith            Mask = RTC_EN_MASK;
47369450Smsmith            break;
47467754Smsmith
47569450Smsmith        default:
47669450Smsmith            Mask = 0;
47769450Smsmith            break;
47869450Smsmith        }
47967754Smsmith
48069450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_EN);
48167754Smsmith
48269450Smsmith        if (ReadWrite == ACPI_WRITE)
48369450Smsmith        {
48469450Smsmith            RegisterValue &= ~Mask;
48569450Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
48669450Smsmith            Value          &= Mask;
48769450Smsmith            RegisterValue |= Value;
48867754Smsmith
48969450Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (UINT16) RegisterValue);
49069450Smsmith        }
49167754Smsmith
49267754Smsmith        break;
49367754Smsmith
49467754Smsmith
49567754Smsmith    case PM1_CONTROL:
49667754Smsmith
49767754Smsmith        switch (RegisterId)
49867754Smsmith        {
49967754Smsmith        case SCI_EN:
50067754Smsmith            Mask = SCI_EN_MASK;
50167754Smsmith            break;
50267754Smsmith
50367754Smsmith        case BM_RLD:
50467754Smsmith            Mask = BM_RLD_MASK;
50567754Smsmith            break;
50667754Smsmith
50767754Smsmith        case GBL_RLS:
50867754Smsmith            Mask = GBL_RLS_MASK;
50967754Smsmith            break;
51067754Smsmith
51167754Smsmith        case SLP_TYPE_A:
51267754Smsmith        case SLP_TYPE_B:
51367754Smsmith            Mask = SLP_TYPE_X_MASK;
51467754Smsmith            break;
51567754Smsmith
51667754Smsmith        case SLP_EN:
51767754Smsmith            Mask = SLP_EN_MASK;
51867754Smsmith            break;
51967754Smsmith
52067754Smsmith        default:
52167754Smsmith            Mask = 0;
52267754Smsmith            break;
52367754Smsmith        }
52467754Smsmith
52569450Smsmith
52669450Smsmith        /*
52769450Smsmith         * Read the PM1 Control register.
52869450Smsmith         * Note that at this level, the fact that there are actually TWO
52969450Smsmith         * registers (A and B) and that B may not exist, are abstracted.
53069450Smsmith         */
53169450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL);
53269450Smsmith
53382367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", RegisterValue));
53469450Smsmith
53567754Smsmith        if (ReadWrite == ACPI_WRITE)
53667754Smsmith        {
53767754Smsmith            RegisterValue  &= ~Mask;
53867754Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
53967754Smsmith            Value          &= Mask;
54067754Smsmith            RegisterValue  |= Value;
54167754Smsmith
54267754Smsmith            /*
54369450Smsmith             * SLP_TYPE_x Registers are written differently
54469450Smsmith             * than any other control Registers with
54569450Smsmith             * respect to A and B Registers.  The value
54667754Smsmith             * for A may be different than the value for B
54769746Smsmith             *
54869746Smsmith             * Therefore, pass the RegisterId, not just generic PM1_CONTROL,
54969746Smsmith             * because we need to do different things. Yuck.
55067754Smsmith             */
55177424Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId,
55277424Smsmith                    (UINT16) RegisterValue);
55367754Smsmith        }
55467754Smsmith        break;
55567754Smsmith
55667754Smsmith
55767754Smsmith    case PM2_CONTROL:
55867754Smsmith
55967754Smsmith        switch (RegisterId)
56067754Smsmith        {
56167754Smsmith        case ARB_DIS:
56267754Smsmith            Mask = ARB_DIS_MASK;
56367754Smsmith            break;
56467754Smsmith
56567754Smsmith        default:
56667754Smsmith            Mask = 0;
56767754Smsmith            break;
56867754Smsmith        }
56967754Smsmith
57069450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL);
57169450Smsmith
57282367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %p\n",
57377424Smsmith            RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)));
57469450Smsmith
57567754Smsmith        if (ReadWrite == ACPI_WRITE)
57667754Smsmith        {
57767754Smsmith            RegisterValue  &= ~Mask;
57867754Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
57967754Smsmith            Value          &= Mask;
58067754Smsmith            RegisterValue  |= Value;
58167754Smsmith
58282367Smsmith            ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %p\n", RegisterValue,
58369450Smsmith                AcpiGbl_FADT->XPm2CntBlk.Address));
58467754Smsmith
58569450Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
58669450Smsmith                                PM2_CONTROL, (UINT8) (RegisterValue));
58767754Smsmith        }
58867754Smsmith        break;
58967754Smsmith
59067754Smsmith
59167754Smsmith    case PM_TIMER:
59267754Smsmith
59369450Smsmith        Mask = TMR_VAL_MASK;
59469450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
59569450Smsmith                                            PM_TIMER);
59682367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM_TIMER: Read %X from %p\n",
59777424Smsmith            RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPmTmrBlk.Address)));
59867754Smsmith
59967754Smsmith        break;
60067754Smsmith
60167754Smsmith
60267754Smsmith    case GPE1_EN_BLOCK:
60367754Smsmith    case GPE1_STS_BLOCK:
60467754Smsmith    case GPE0_EN_BLOCK:
60567754Smsmith    case GPE0_STS_BLOCK:
60667754Smsmith
60769450Smsmith        /* Determine the bit to be accessed
60869450Smsmith         *
60969450Smsmith         *  (UINT32) RegisterId:
61069450Smsmith         *      31      24       16       8        0
61169450Smsmith         *      +--------+--------+--------+--------+
61269450Smsmith         *      |  gpe_block_id   |  gpe_bit_number |
61369450Smsmith         *      +--------+--------+--------+--------+
61469450Smsmith         *
61569450Smsmith         *     gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK
61669450Smsmith         *     gpe_bit_number is relative from the gpe_block (0x00~0xFF)
61769450Smsmith         */
61869450Smsmith        Mask = REGISTER_BIT_ID(RegisterId); /* gpe_bit_number */
61969450Smsmith        RegisterId = REGISTER_BLOCK_ID(RegisterId) | (Mask >> 3);
62069450Smsmith        Mask = AcpiGbl_DecodeTo8bit [Mask % 8];
62167754Smsmith
62267754Smsmith        /*
62367754Smsmith         * The base address of the GPE 0 Register Block
62467754Smsmith         * Plus 1/2 the length of the GPE 0 Register Block
62569450Smsmith         * The enable Register is the Register following the Status Register
62669450Smsmith         * and each Register is defined as 1/2 of the total Register Block
62767754Smsmith         */
62867754Smsmith
62967754Smsmith        /*
63067754Smsmith         * This sets the bit within EnableBit that needs to be written to
63169450Smsmith         * the Register indicated in Mask to a 1, all others are 0
63267754Smsmith         */
63367754Smsmith
63467754Smsmith        /* Now get the current Enable Bits in the selected Reg */
63567754Smsmith
63669450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId);
63782367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_IO, "GPE Enable bits: Read %X from %X\n",
63877424Smsmith            RegisterValue, RegisterId));
63967754Smsmith
64067754Smsmith        if (ReadWrite == ACPI_WRITE)
64167754Smsmith        {
64267754Smsmith            RegisterValue  &= ~Mask;
64367754Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
64467754Smsmith            Value          &= Mask;
64567754Smsmith            RegisterValue  |= Value;
64667754Smsmith
64783174Smsmith            /*
64883174Smsmith             * This write will put the Action state into the General Purpose
64983174Smsmith             * Enable Register indexed by the value in Mask
65083174Smsmith             */
65182367Smsmith            ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n",
65277424Smsmith                RegisterValue, RegisterId));
65377424Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId,
65477424Smsmith                (UINT8) RegisterValue);
65577424Smsmith            RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
65677424Smsmith                                RegisterId);
65767754Smsmith        }
65867754Smsmith        break;
65967754Smsmith
66067754Smsmith
66169450Smsmith    case SMI_CMD_BLOCK:
66267754Smsmith    case PROCESSOR_BLOCK:
66383174Smsmith
66477424Smsmith        /* Not used by any callers at this time - therefore, not implemented */
66577424Smsmith
66667754Smsmith    default:
66767754Smsmith
66867754Smsmith        Mask = 0;
66967754Smsmith        break;
67067754Smsmith    }
67167754Smsmith
67269450Smsmith    if (ACPI_MTX_LOCK == UseLock) {
67377424Smsmith        AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
67469450Smsmith    }
67567754Smsmith
67669450Smsmith
67767754Smsmith    RegisterValue &= Mask;
67867754Smsmith    RegisterValue >>= AcpiHwGetBitShift (Mask);
67967754Smsmith
68082367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Register I/O: returning %X\n", RegisterValue));
68167754Smsmith    return_VALUE (RegisterValue);
68267754Smsmith}
68369450Smsmith
68469450Smsmith
68569450Smsmith/******************************************************************************
68669450Smsmith *
68769450Smsmith * FUNCTION:    AcpiHwRegisterRead
68869450Smsmith *
68969450Smsmith * PARAMETERS:  UseLock                - Mutex hw access.
69069450Smsmith *              RegisterId             - RegisterID + Offset.
69169450Smsmith *
69269450Smsmith * RETURN:      Value read or written.
69369450Smsmith *
69469450Smsmith * DESCRIPTION: Acpi register read function.  Registers are read at the
69569450Smsmith *              given offset.
69669450Smsmith *
69769450Smsmith ******************************************************************************/
69869450Smsmith
69969450SmsmithUINT32
70069450SmsmithAcpiHwRegisterRead (
70169450Smsmith    BOOLEAN                 UseLock,
70269450Smsmith    UINT32                  RegisterId)
70369450Smsmith{
70480062Smsmith    UINT32                  Value = 0;
70569450Smsmith    UINT32                  BankOffset;
70669450Smsmith
70777424Smsmith
70883174Smsmith    FUNCTION_TRACE ("HwRegisterRead");
70969450Smsmith
71077424Smsmith
71169450Smsmith    if (ACPI_MTX_LOCK == UseLock)
71269450Smsmith    {
71377424Smsmith        AcpiUtAcquireMutex (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
75382367Smsmith    /*
75483174Smsmith     * For the GPE? Blocks, the lower word of RegisterId contains the
75583174Smsmith     * byte offset for which to read, as each part of each block may be
75682367Smsmith     * several bytes long.
75782367Smsmith     */
75869450Smsmith    case GPE0_STS_BLOCK: /* 8-bit access */
75969450Smsmith
76083174Smsmith        BankOffset = REGISTER_BIT_ID(RegisterId);
76182367Smsmith        Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
76269450Smsmith        break;
76369450Smsmith
76469450Smsmith    case GPE0_EN_BLOCK: /* 8-bit access */
76569450Smsmith
76682367Smsmith        BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen) + REGISTER_BIT_ID(RegisterId);
76782367Smsmith        Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
76869450Smsmith        break;
76969450Smsmith
77069450Smsmith    case GPE1_STS_BLOCK: /* 8-bit access */
77169450Smsmith
77283174Smsmith        BankOffset = REGISTER_BIT_ID(RegisterId);
77382367Smsmith        Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
77469450Smsmith        break;
77569450Smsmith
77669450Smsmith    case GPE1_EN_BLOCK: /* 8-bit access */
77769450Smsmith
77882367Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen) + REGISTER_BIT_ID(RegisterId);
77982367Smsmith        Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
78069450Smsmith        break;
78169450Smsmith
78269450Smsmith    case SMI_CMD_BLOCK: /* 8bit */
78369450Smsmith
78480062Smsmith        AcpiOsReadPort (AcpiGbl_FADT->SmiCmd, &Value, 8);
78569450Smsmith        break;
78669450Smsmith
78769450Smsmith    default:
78880062Smsmith        /* Value will be returned as 0 */
78969450Smsmith        break;
79069450Smsmith    }
79169450Smsmith
79269450Smsmith
79369450Smsmith    if (ACPI_MTX_LOCK == UseLock)
79469450Smsmith    {
79577424Smsmith        AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
79669450Smsmith    }
79769450Smsmith
79869450Smsmith    return_VALUE (Value);
79969450Smsmith}
80069450Smsmith
80169450Smsmith
80269450Smsmith/******************************************************************************
80369450Smsmith *
80469450Smsmith * FUNCTION:    AcpiHwRegisterWrite
80569450Smsmith *
80669450Smsmith * PARAMETERS:  UseLock                - Mutex hw access.
80769450Smsmith *              RegisterId             - RegisterID + Offset.
80869450Smsmith *
80969450Smsmith * RETURN:      Value read or written.
81069450Smsmith *
81169450Smsmith * DESCRIPTION: Acpi register Write function.  Registers are written at the
81269450Smsmith *              given offset.
81369450Smsmith *
81469450Smsmith ******************************************************************************/
81569450Smsmith
81669450Smsmithvoid
81769450SmsmithAcpiHwRegisterWrite (
81869450Smsmith    BOOLEAN                 UseLock,
81969450Smsmith    UINT32                  RegisterId,
82069450Smsmith    UINT32                  Value)
82169450Smsmith{
82269450Smsmith    UINT32                  BankOffset;
82369450Smsmith
82469450Smsmith
82583174Smsmith    FUNCTION_TRACE ("HwRegisterWrite");
82669450Smsmith
82783174Smsmith
82869450Smsmith    if (ACPI_MTX_LOCK == UseLock)
82969450Smsmith    {
83077424Smsmith        AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
83169450Smsmith    }
83269450Smsmith
83369450Smsmith
83469450Smsmith    switch (REGISTER_BLOCK_ID (RegisterId))
83569450Smsmith    {
83669450Smsmith    case PM1_STS: /* 16-bit access */
83769450Smsmith
83869746Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, 0);
83969746Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, 0);
84069450Smsmith        break;
84169450Smsmith
84269450Smsmith
84369450Smsmith    case PM1_EN: /* 16-bit access*/
84469450Smsmith
84569450Smsmith        BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
84669746Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset);
84769746Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset);
84869450Smsmith        break;
84969450Smsmith
85069450Smsmith
85169450Smsmith    case PM1_CONTROL: /* 16-bit access */
85269450Smsmith
85371867Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0);
85471867Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0);
85571867Smsmith        break;
85669450Smsmith
85769450Smsmith
85871867Smsmith    case PM1A_CONTROL: /* 16-bit access */
85969450Smsmith
86071867Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0);
86169450Smsmith        break;
86269450Smsmith
86369450Smsmith
86471867Smsmith    case PM1B_CONTROL: /* 16-bit access */
86571867Smsmith
86671867Smsmith        AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0);
86771867Smsmith        break;
86871867Smsmith
86971867Smsmith
87069450Smsmith    case PM2_CONTROL: /* 8-bit access */
87169450Smsmith
87269746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, 0);
87369450Smsmith        break;
87469450Smsmith
87569450Smsmith
87669450Smsmith    case PM_TIMER: /* 32-bit access */
87769450Smsmith
87869746Smsmith        AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, 0);
87969450Smsmith        break;
88069450Smsmith
88169450Smsmith
88269450Smsmith    case GPE0_STS_BLOCK: /* 8-bit access */
88369450Smsmith
88483174Smsmith        BankOffset = REGISTER_BIT_ID(RegisterId);
88582367Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
88669450Smsmith        break;
88769450Smsmith
88869450Smsmith
88969450Smsmith    case GPE0_EN_BLOCK: /* 8-bit access */
89069450Smsmith
89182367Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen) + REGISTER_BIT_ID(RegisterId);
89269746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
89369450Smsmith        break;
89469450Smsmith
89569450Smsmith
89669450Smsmith    case GPE1_STS_BLOCK: /* 8-bit access */
89769450Smsmith
89883174Smsmith        BankOffset = REGISTER_BIT_ID(RegisterId);
89982367Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
90069450Smsmith        break;
90169450Smsmith
90269450Smsmith
90369450Smsmith    case GPE1_EN_BLOCK: /* 8-bit access */
90469450Smsmith
90582367Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen) + REGISTER_BIT_ID(RegisterId);
90669746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
90769450Smsmith        break;
90869450Smsmith
90969450Smsmith
91069450Smsmith    case SMI_CMD_BLOCK: /* 8bit */
91169450Smsmith
91269450Smsmith        /* For 2.0, SMI_CMD is always in IO space */
91369450Smsmith        /* TBD: what about 1.0? 0.71? */
91469450Smsmith
91580062Smsmith        AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, Value, 8);
91669450Smsmith        break;
91769450Smsmith
91869450Smsmith
91969450Smsmith    default:
92069450Smsmith        Value = 0;
92169450Smsmith        break;
92269450Smsmith    }
92369450Smsmith
92469450Smsmith
92569450Smsmith    if (ACPI_MTX_LOCK == UseLock)
92669450Smsmith    {
92777424Smsmith        AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
92869450Smsmith    }
92969450Smsmith
93069450Smsmith    return_VOID;
93169450Smsmith}
93269450Smsmith
93369450Smsmith
93469450Smsmith/******************************************************************************
93569450Smsmith *
93669450Smsmith * FUNCTION:    AcpiHwLowLevelRead
93769450Smsmith *
93869450Smsmith * PARAMETERS:  Register            - GAS register structure
93969450Smsmith *              Offset              - Offset from the base address in the GAS
94069450Smsmith *              Width               - 8, 16, or 32
94169450Smsmith *
94269450Smsmith * RETURN:      Value read
94369450Smsmith *
94469450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space.
94569450Smsmith *
94669450Smsmith ******************************************************************************/
94769450Smsmith
94869450SmsmithUINT32
94969450SmsmithAcpiHwLowLevelRead (
95069450Smsmith    UINT32                  Width,
95177424Smsmith    ACPI_GENERIC_ADDRESS    *Reg,
95269450Smsmith    UINT32                  Offset)
95369450Smsmith{
95469450Smsmith    UINT32                  Value = 0;
95569450Smsmith    ACPI_PHYSICAL_ADDRESS   MemAddress;
95669450Smsmith    ACPI_IO_ADDRESS         IoAddress;
95780062Smsmith    ACPI_PCI_ID             PciId;
95880062Smsmith    UINT16                  PciRegister;
95969450Smsmith
96069450Smsmith
96183174Smsmith    FUNCTION_ENTRY ();
96283174Smsmith
96383174Smsmith
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    switch (Reg->AddressSpaceId)
98069450Smsmith    {
98177424Smsmith    case ACPI_ADR_SPACE_SYSTEM_MEMORY:
98269450Smsmith
98370243Smsmith        MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
98469450Smsmith
98580062Smsmith        AcpiOsReadMemory (MemAddress, &Value, Width);
98669450Smsmith        break;
98769450Smsmith
98869450Smsmith
98977424Smsmith    case ACPI_ADR_SPACE_SYSTEM_IO:
99069450Smsmith
99170243Smsmith        IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
99269450Smsmith
99380062Smsmith        AcpiOsReadPort (IoAddress, &Value, Width);
99469450Smsmith        break;
99569450Smsmith
99669450Smsmith
99777424Smsmith    case ACPI_ADR_SPACE_PCI_CONFIG:
99869450Smsmith
99980062Smsmith        PciId.Segment  = 0;
100080062Smsmith        PciId.Bus      = 0;
100180062Smsmith        PciId.Device   = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address));
100280062Smsmith        PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address));
100380062Smsmith        PciRegister    = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset);
100469450Smsmith
100580062Smsmith        AcpiOsReadPciConfiguration  (&PciId, PciRegister, &Value, Width);
100669450Smsmith        break;
100769450Smsmith    }
100869450Smsmith
100969450Smsmith    return Value;
101069450Smsmith}
101169450Smsmith
101269450Smsmith
101369450Smsmith/******************************************************************************
101469450Smsmith *
101569450Smsmith * FUNCTION:    AcpiHwLowLevelWrite
101669450Smsmith *
101769450Smsmith * PARAMETERS:  Width               - 8, 16, or 32
101869450Smsmith *              Value               - To be written
101969450Smsmith *              Register            - GAS register structure
102069450Smsmith *              Offset              - Offset from the base address in the GAS
102169450Smsmith *
102269450Smsmith *
102369450Smsmith * RETURN:      Value read
102469450Smsmith *
102569450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space.
102669450Smsmith *
102769450Smsmith ******************************************************************************/
102869450Smsmith
102969450Smsmithvoid
103069450SmsmithAcpiHwLowLevelWrite (
103169450Smsmith    UINT32                  Width,
103269450Smsmith    UINT32                  Value,
103377424Smsmith    ACPI_GENERIC_ADDRESS    *Reg,
103469450Smsmith    UINT32                  Offset)
103569450Smsmith{
103669450Smsmith    ACPI_PHYSICAL_ADDRESS   MemAddress;
103769450Smsmith    ACPI_IO_ADDRESS         IoAddress;
103880062Smsmith    ACPI_PCI_ID             PciId;
103980062Smsmith    UINT16                  PciRegister;
104069450Smsmith
104169450Smsmith
104283174Smsmith    FUNCTION_ENTRY ();
104383174Smsmith
104483174Smsmith
104569450Smsmith    /*
104669450Smsmith     * Must have a valid pointer to a GAS structure, and
104769450Smsmith     * a non-zero address within
104869450Smsmith     */
104969450Smsmith    if ((!Reg) ||
105070243Smsmith        (!ACPI_VALID_ADDRESS (Reg->Address)))
105169450Smsmith    {
105269450Smsmith        return;
105369450Smsmith    }
105469450Smsmith
105569450Smsmith
105669450Smsmith    /*
105769450Smsmith     * Three address spaces supported:
105869450Smsmith     * Memory, Io, or PCI config.
105969450Smsmith     */
106069450Smsmith    switch (Reg->AddressSpaceId)
106169450Smsmith    {
106277424Smsmith    case ACPI_ADR_SPACE_SYSTEM_MEMORY:
106369450Smsmith
106470243Smsmith        MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
106569450Smsmith
106680062Smsmith        AcpiOsWriteMemory (MemAddress, Value, Width);
106769450Smsmith        break;
106869450Smsmith
106969450Smsmith
107077424Smsmith    case ACPI_ADR_SPACE_SYSTEM_IO:
107169450Smsmith
107270243Smsmith        IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
107369450Smsmith
107480062Smsmith        AcpiOsWritePort (IoAddress, Value, Width);
107569450Smsmith        break;
107669450Smsmith
107769450Smsmith
107877424Smsmith    case ACPI_ADR_SPACE_PCI_CONFIG:
107969450Smsmith
108080062Smsmith        PciId.Segment  = 0;
108180062Smsmith        PciId.Bus      = 0;
108280062Smsmith        PciId.Device   = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address));
108380062Smsmith        PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address));
108480062Smsmith        PciRegister    = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset);
108569450Smsmith
108680062Smsmith        AcpiOsWritePciConfiguration (&PciId, PciRegister, Value, Width);
108769450Smsmith        break;
108869450Smsmith    }
108969450Smsmith}
1090