hwregs.c revision 85756
167754Smsmith
267754Smsmith/*******************************************************************************
367754Smsmith *
467754Smsmith * Module Name: hwregs - Read/write access functions for the various ACPI
567754Smsmith *                       control and status registers.
685756Smsmith *              $Revision: 110 $
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
57285756Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n",
57385756Smsmith            RegisterValue, HIDWORD(AcpiGbl_FADT->XPm2CntBlk.Address),
57485756Smsmith            LODWORD(AcpiGbl_FADT->XPm2CntBlk.Address)));
57569450Smsmith
57667754Smsmith        if (ReadWrite == ACPI_WRITE)
57767754Smsmith        {
57867754Smsmith            RegisterValue  &= ~Mask;
57967754Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
58067754Smsmith            Value          &= Mask;
58167754Smsmith            RegisterValue  |= Value;
58267754Smsmith
58385756Smsmith            ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n",
58485756Smsmith                RegisterValue,
58585756Smsmith                HIDWORD(AcpiGbl_FADT->XPm2CntBlk.Address),
58685756Smsmith                LODWORD(AcpiGbl_FADT->XPm2CntBlk.Address)));
58767754Smsmith
58869450Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK,
58969450Smsmith                                PM2_CONTROL, (UINT8) (RegisterValue));
59067754Smsmith        }
59167754Smsmith        break;
59267754Smsmith
59367754Smsmith
59467754Smsmith    case PM_TIMER:
59567754Smsmith
59669450Smsmith        Mask = TMR_VAL_MASK;
59769450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
59869450Smsmith                                            PM_TIMER);
59985756Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM_TIMER: Read %X from %8.8X%8.8X\n",
60085756Smsmith            RegisterValue,
60185756Smsmith            HIDWORD(AcpiGbl_FADT->XPmTmrBlk.Address),
60285756Smsmith            LODWORD(AcpiGbl_FADT->XPmTmrBlk.Address)));
60367754Smsmith
60467754Smsmith        break;
60567754Smsmith
60667754Smsmith
60767754Smsmith    case GPE1_EN_BLOCK:
60867754Smsmith    case GPE1_STS_BLOCK:
60967754Smsmith    case GPE0_EN_BLOCK:
61067754Smsmith    case GPE0_STS_BLOCK:
61167754Smsmith
61269450Smsmith        /* Determine the bit to be accessed
61369450Smsmith         *
61469450Smsmith         *  (UINT32) RegisterId:
61569450Smsmith         *      31      24       16       8        0
61669450Smsmith         *      +--------+--------+--------+--------+
61769450Smsmith         *      |  gpe_block_id   |  gpe_bit_number |
61869450Smsmith         *      +--------+--------+--------+--------+
61969450Smsmith         *
62069450Smsmith         *     gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK
62169450Smsmith         *     gpe_bit_number is relative from the gpe_block (0x00~0xFF)
62269450Smsmith         */
62369450Smsmith        Mask = REGISTER_BIT_ID(RegisterId); /* gpe_bit_number */
62469450Smsmith        RegisterId = REGISTER_BLOCK_ID(RegisterId) | (Mask >> 3);
62569450Smsmith        Mask = AcpiGbl_DecodeTo8bit [Mask % 8];
62667754Smsmith
62767754Smsmith        /*
62867754Smsmith         * The base address of the GPE 0 Register Block
62967754Smsmith         * Plus 1/2 the length of the GPE 0 Register Block
63069450Smsmith         * The enable Register is the Register following the Status Register
63169450Smsmith         * and each Register is defined as 1/2 of the total Register Block
63267754Smsmith         */
63367754Smsmith
63467754Smsmith        /*
63567754Smsmith         * This sets the bit within EnableBit that needs to be written to
63669450Smsmith         * the Register indicated in Mask to a 1, all others are 0
63767754Smsmith         */
63867754Smsmith
63967754Smsmith        /* Now get the current Enable Bits in the selected Reg */
64067754Smsmith
64169450Smsmith        RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId);
64282367Smsmith        ACPI_DEBUG_PRINT ((ACPI_DB_IO, "GPE Enable bits: Read %X from %X\n",
64377424Smsmith            RegisterValue, RegisterId));
64467754Smsmith
64567754Smsmith        if (ReadWrite == ACPI_WRITE)
64667754Smsmith        {
64767754Smsmith            RegisterValue  &= ~Mask;
64867754Smsmith            Value          <<= AcpiHwGetBitShift (Mask);
64967754Smsmith            Value          &= Mask;
65067754Smsmith            RegisterValue  |= Value;
65167754Smsmith
65283174Smsmith            /*
65383174Smsmith             * This write will put the Action state into the General Purpose
65483174Smsmith             * Enable Register indexed by the value in Mask
65583174Smsmith             */
65682367Smsmith            ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n",
65777424Smsmith                RegisterValue, RegisterId));
65877424Smsmith            AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId,
65977424Smsmith                (UINT8) RegisterValue);
66077424Smsmith            RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK,
66177424Smsmith                                RegisterId);
66267754Smsmith        }
66367754Smsmith        break;
66467754Smsmith
66567754Smsmith
66669450Smsmith    case SMI_CMD_BLOCK:
66767754Smsmith    case PROCESSOR_BLOCK:
66883174Smsmith
66977424Smsmith        /* Not used by any callers at this time - therefore, not implemented */
67077424Smsmith
67167754Smsmith    default:
67267754Smsmith
67367754Smsmith        Mask = 0;
67467754Smsmith        break;
67567754Smsmith    }
67667754Smsmith
67769450Smsmith    if (ACPI_MTX_LOCK == UseLock) {
67877424Smsmith        AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
67969450Smsmith    }
68067754Smsmith
68169450Smsmith
68267754Smsmith    RegisterValue &= Mask;
68367754Smsmith    RegisterValue >>= AcpiHwGetBitShift (Mask);
68467754Smsmith
68582367Smsmith    ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Register I/O: returning %X\n", RegisterValue));
68667754Smsmith    return_VALUE (RegisterValue);
68767754Smsmith}
68869450Smsmith
68969450Smsmith
69069450Smsmith/******************************************************************************
69169450Smsmith *
69269450Smsmith * FUNCTION:    AcpiHwRegisterRead
69369450Smsmith *
69469450Smsmith * PARAMETERS:  UseLock                - Mutex hw access.
69569450Smsmith *              RegisterId             - RegisterID + Offset.
69669450Smsmith *
69769450Smsmith * RETURN:      Value read or written.
69869450Smsmith *
69969450Smsmith * DESCRIPTION: Acpi register read function.  Registers are read at the
70069450Smsmith *              given offset.
70169450Smsmith *
70269450Smsmith ******************************************************************************/
70369450Smsmith
70469450SmsmithUINT32
70569450SmsmithAcpiHwRegisterRead (
70669450Smsmith    BOOLEAN                 UseLock,
70769450Smsmith    UINT32                  RegisterId)
70869450Smsmith{
70980062Smsmith    UINT32                  Value = 0;
71069450Smsmith    UINT32                  BankOffset;
71169450Smsmith
71277424Smsmith
71383174Smsmith    FUNCTION_TRACE ("HwRegisterRead");
71469450Smsmith
71577424Smsmith
71669450Smsmith    if (ACPI_MTX_LOCK == UseLock)
71769450Smsmith    {
71877424Smsmith        AcpiUtAcquireMutex (ACPI_MTX_HARDWARE);
71969450Smsmith    }
72069450Smsmith
72169450Smsmith
72269450Smsmith    switch (REGISTER_BLOCK_ID(RegisterId))
72369450Smsmith    {
72469450Smsmith    case PM1_STS: /* 16-bit access */
72569450Smsmith
72669746Smsmith        Value =  AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, 0);
72769746Smsmith        Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, 0);
72869450Smsmith        break;
72969450Smsmith
73069450Smsmith
73169450Smsmith    case PM1_EN: /* 16-bit access*/
73269450Smsmith
73369450Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Pm1EvtLen);
73469746Smsmith        Value =  AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset);
73569746Smsmith        Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset);
73669450Smsmith        break;
73769450Smsmith
73869450Smsmith
73969450Smsmith    case PM1_CONTROL: /* 16-bit access */
74069450Smsmith
74171867Smsmith        Value =  AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aCntBlk, 0);
74271867Smsmith        Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bCntBlk, 0);
74369450Smsmith        break;
74469450Smsmith
74569450Smsmith
74669450Smsmith    case PM2_CONTROL: /* 8-bit access */
74769450Smsmith
74869746Smsmith        Value =  AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XPm2CntBlk, 0);
74969450Smsmith        break;
75069450Smsmith
75169450Smsmith
75269450Smsmith    case PM_TIMER: /* 32-bit access */
75369450Smsmith
75469746Smsmith        Value =  AcpiHwLowLevelRead (32, &AcpiGbl_FADT->XPmTmrBlk, 0);
75569450Smsmith        break;
75669450Smsmith
75769450Smsmith
75882367Smsmith    /*
75983174Smsmith     * For the GPE? Blocks, the lower word of RegisterId contains the
76083174Smsmith     * byte offset for which to read, as each part of each block may be
76182367Smsmith     * several bytes long.
76282367Smsmith     */
76369450Smsmith    case GPE0_STS_BLOCK: /* 8-bit access */
76469450Smsmith
76583174Smsmith        BankOffset = REGISTER_BIT_ID(RegisterId);
76682367Smsmith        Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
76769450Smsmith        break;
76869450Smsmith
76969450Smsmith    case GPE0_EN_BLOCK: /* 8-bit access */
77069450Smsmith
77182367Smsmith        BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen) + REGISTER_BIT_ID(RegisterId);
77282367Smsmith        Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
77369450Smsmith        break;
77469450Smsmith
77569450Smsmith    case GPE1_STS_BLOCK: /* 8-bit access */
77669450Smsmith
77783174Smsmith        BankOffset = REGISTER_BIT_ID(RegisterId);
77882367Smsmith        Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
77969450Smsmith        break;
78069450Smsmith
78169450Smsmith    case GPE1_EN_BLOCK: /* 8-bit access */
78269450Smsmith
78382367Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen) + REGISTER_BIT_ID(RegisterId);
78482367Smsmith        Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
78569450Smsmith        break;
78669450Smsmith
78769450Smsmith    case SMI_CMD_BLOCK: /* 8bit */
78869450Smsmith
78980062Smsmith        AcpiOsReadPort (AcpiGbl_FADT->SmiCmd, &Value, 8);
79069450Smsmith        break;
79169450Smsmith
79269450Smsmith    default:
79380062Smsmith        /* Value will be returned as 0 */
79469450Smsmith        break;
79569450Smsmith    }
79669450Smsmith
79769450Smsmith
79869450Smsmith    if (ACPI_MTX_LOCK == UseLock)
79969450Smsmith    {
80077424Smsmith        AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
80169450Smsmith    }
80269450Smsmith
80369450Smsmith    return_VALUE (Value);
80469450Smsmith}
80569450Smsmith
80669450Smsmith
80769450Smsmith/******************************************************************************
80869450Smsmith *
80969450Smsmith * FUNCTION:    AcpiHwRegisterWrite
81069450Smsmith *
81169450Smsmith * PARAMETERS:  UseLock                - Mutex hw access.
81269450Smsmith *              RegisterId             - RegisterID + Offset.
81369450Smsmith *
81469450Smsmith * RETURN:      Value read or written.
81569450Smsmith *
81669450Smsmith * DESCRIPTION: Acpi register Write function.  Registers are written at the
81769450Smsmith *              given offset.
81869450Smsmith *
81969450Smsmith ******************************************************************************/
82069450Smsmith
82169450Smsmithvoid
82269450SmsmithAcpiHwRegisterWrite (
82369450Smsmith    BOOLEAN                 UseLock,
82469450Smsmith    UINT32                  RegisterId,
82569450Smsmith    UINT32                  Value)
82669450Smsmith{
82769450Smsmith    UINT32                  BankOffset;
82869450Smsmith
82969450Smsmith
83083174Smsmith    FUNCTION_TRACE ("HwRegisterWrite");
83169450Smsmith
83283174Smsmith
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
88983174Smsmith        BankOffset = REGISTER_BIT_ID(RegisterId);
89082367Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
89169450Smsmith        break;
89269450Smsmith
89369450Smsmith
89469450Smsmith    case GPE0_EN_BLOCK: /* 8-bit access */
89569450Smsmith
89682367Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen) + REGISTER_BIT_ID(RegisterId);
89769746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset);
89869450Smsmith        break;
89969450Smsmith
90069450Smsmith
90169450Smsmith    case GPE1_STS_BLOCK: /* 8-bit access */
90269450Smsmith
90383174Smsmith        BankOffset = REGISTER_BIT_ID(RegisterId);
90482367Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
90569450Smsmith        break;
90669450Smsmith
90769450Smsmith
90869450Smsmith    case GPE1_EN_BLOCK: /* 8-bit access */
90969450Smsmith
91082367Smsmith        BankOffset  = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen) + REGISTER_BIT_ID(RegisterId);
91169746Smsmith        AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset);
91269450Smsmith        break;
91369450Smsmith
91469450Smsmith
91569450Smsmith    case SMI_CMD_BLOCK: /* 8bit */
91669450Smsmith
91769450Smsmith        /* For 2.0, SMI_CMD is always in IO space */
91869450Smsmith        /* TBD: what about 1.0? 0.71? */
91969450Smsmith
92080062Smsmith        AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, Value, 8);
92169450Smsmith        break;
92269450Smsmith
92369450Smsmith
92469450Smsmith    default:
92569450Smsmith        Value = 0;
92669450Smsmith        break;
92769450Smsmith    }
92869450Smsmith
92969450Smsmith
93069450Smsmith    if (ACPI_MTX_LOCK == UseLock)
93169450Smsmith    {
93277424Smsmith        AcpiUtReleaseMutex (ACPI_MTX_HARDWARE);
93369450Smsmith    }
93469450Smsmith
93569450Smsmith    return_VOID;
93669450Smsmith}
93769450Smsmith
93869450Smsmith
93969450Smsmith/******************************************************************************
94069450Smsmith *
94169450Smsmith * FUNCTION:    AcpiHwLowLevelRead
94269450Smsmith *
94369450Smsmith * PARAMETERS:  Register            - GAS register structure
94469450Smsmith *              Offset              - Offset from the base address in the GAS
94569450Smsmith *              Width               - 8, 16, or 32
94669450Smsmith *
94769450Smsmith * RETURN:      Value read
94869450Smsmith *
94969450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space.
95069450Smsmith *
95169450Smsmith ******************************************************************************/
95269450Smsmith
95369450SmsmithUINT32
95469450SmsmithAcpiHwLowLevelRead (
95569450Smsmith    UINT32                  Width,
95677424Smsmith    ACPI_GENERIC_ADDRESS    *Reg,
95769450Smsmith    UINT32                  Offset)
95869450Smsmith{
95969450Smsmith    UINT32                  Value = 0;
96069450Smsmith    ACPI_PHYSICAL_ADDRESS   MemAddress;
96169450Smsmith    ACPI_IO_ADDRESS         IoAddress;
96280062Smsmith    ACPI_PCI_ID             PciId;
96380062Smsmith    UINT16                  PciRegister;
96469450Smsmith
96569450Smsmith
96683174Smsmith    FUNCTION_ENTRY ();
96783174Smsmith
96883174Smsmith
96969450Smsmith    /*
97069450Smsmith     * Must have a valid pointer to a GAS structure, and
97169450Smsmith     * a non-zero address within
97269450Smsmith     */
97369450Smsmith    if ((!Reg) ||
97470243Smsmith        (!ACPI_VALID_ADDRESS (Reg->Address)))
97569450Smsmith    {
97669450Smsmith        return 0;
97769450Smsmith    }
97869450Smsmith
97969450Smsmith
98069450Smsmith    /*
98169450Smsmith     * Three address spaces supported:
98269450Smsmith     * Memory, Io, or PCI config.
98369450Smsmith     */
98469450Smsmith    switch (Reg->AddressSpaceId)
98569450Smsmith    {
98677424Smsmith    case ACPI_ADR_SPACE_SYSTEM_MEMORY:
98769450Smsmith
98870243Smsmith        MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
98969450Smsmith
99080062Smsmith        AcpiOsReadMemory (MemAddress, &Value, Width);
99169450Smsmith        break;
99269450Smsmith
99369450Smsmith
99477424Smsmith    case ACPI_ADR_SPACE_SYSTEM_IO:
99569450Smsmith
99670243Smsmith        IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
99769450Smsmith
99880062Smsmith        AcpiOsReadPort (IoAddress, &Value, Width);
99969450Smsmith        break;
100069450Smsmith
100169450Smsmith
100277424Smsmith    case ACPI_ADR_SPACE_PCI_CONFIG:
100369450Smsmith
100480062Smsmith        PciId.Segment  = 0;
100580062Smsmith        PciId.Bus      = 0;
100680062Smsmith        PciId.Device   = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address));
100780062Smsmith        PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address));
100880062Smsmith        PciRegister    = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset);
100969450Smsmith
101080062Smsmith        AcpiOsReadPciConfiguration  (&PciId, PciRegister, &Value, Width);
101169450Smsmith        break;
101269450Smsmith    }
101369450Smsmith
101469450Smsmith    return Value;
101569450Smsmith}
101669450Smsmith
101769450Smsmith
101869450Smsmith/******************************************************************************
101969450Smsmith *
102069450Smsmith * FUNCTION:    AcpiHwLowLevelWrite
102169450Smsmith *
102269450Smsmith * PARAMETERS:  Width               - 8, 16, or 32
102369450Smsmith *              Value               - To be written
102469450Smsmith *              Register            - GAS register structure
102569450Smsmith *              Offset              - Offset from the base address in the GAS
102669450Smsmith *
102769450Smsmith *
102869450Smsmith * RETURN:      Value read
102969450Smsmith *
103069450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space.
103169450Smsmith *
103269450Smsmith ******************************************************************************/
103369450Smsmith
103469450Smsmithvoid
103569450SmsmithAcpiHwLowLevelWrite (
103669450Smsmith    UINT32                  Width,
103769450Smsmith    UINT32                  Value,
103877424Smsmith    ACPI_GENERIC_ADDRESS    *Reg,
103969450Smsmith    UINT32                  Offset)
104069450Smsmith{
104169450Smsmith    ACPI_PHYSICAL_ADDRESS   MemAddress;
104269450Smsmith    ACPI_IO_ADDRESS         IoAddress;
104380062Smsmith    ACPI_PCI_ID             PciId;
104480062Smsmith    UINT16                  PciRegister;
104569450Smsmith
104669450Smsmith
104783174Smsmith    FUNCTION_ENTRY ();
104883174Smsmith
104983174Smsmith
105069450Smsmith    /*
105169450Smsmith     * Must have a valid pointer to a GAS structure, and
105269450Smsmith     * a non-zero address within
105369450Smsmith     */
105469450Smsmith    if ((!Reg) ||
105570243Smsmith        (!ACPI_VALID_ADDRESS (Reg->Address)))
105669450Smsmith    {
105769450Smsmith        return;
105869450Smsmith    }
105969450Smsmith
106069450Smsmith
106169450Smsmith    /*
106269450Smsmith     * Three address spaces supported:
106369450Smsmith     * Memory, Io, or PCI config.
106469450Smsmith     */
106569450Smsmith    switch (Reg->AddressSpaceId)
106669450Smsmith    {
106777424Smsmith    case ACPI_ADR_SPACE_SYSTEM_MEMORY:
106869450Smsmith
106970243Smsmith        MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
107069450Smsmith
107180062Smsmith        AcpiOsWriteMemory (MemAddress, Value, Width);
107269450Smsmith        break;
107369450Smsmith
107469450Smsmith
107577424Smsmith    case ACPI_ADR_SPACE_SYSTEM_IO:
107669450Smsmith
107770243Smsmith        IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset);
107869450Smsmith
107980062Smsmith        AcpiOsWritePort (IoAddress, Value, Width);
108069450Smsmith        break;
108169450Smsmith
108269450Smsmith
108377424Smsmith    case ACPI_ADR_SPACE_PCI_CONFIG:
108469450Smsmith
108580062Smsmith        PciId.Segment  = 0;
108680062Smsmith        PciId.Bus      = 0;
108780062Smsmith        PciId.Device   = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address));
108880062Smsmith        PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address));
108980062Smsmith        PciRegister    = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset);
109069450Smsmith
109180062Smsmith        AcpiOsWritePciConfiguration (&PciId, PciRegister, Value, Width);
109269450Smsmith        break;
109369450Smsmith    }
109469450Smsmith}
1095