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