hwregs.c revision 80062
167754Smsmith 267754Smsmith/******************************************************************************* 367754Smsmith * 467754Smsmith * Module Name: hwregs - Read/write access functions for the various ACPI 567754Smsmith * control and status registers. 680062Smsmith * $Revision: 102 $ 767754Smsmith * 867754Smsmith ******************************************************************************/ 967754Smsmith 1067754Smsmith/****************************************************************************** 1167754Smsmith * 1267754Smsmith * 1. Copyright Notice 1367754Smsmith * 1471867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 1570243Smsmith * All rights reserved. 1667754Smsmith * 1767754Smsmith * 2. License 1867754Smsmith * 1967754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 2067754Smsmith * rights. You may have additional license terms from the party that provided 2167754Smsmith * you this software, covering your right to use that party's intellectual 2267754Smsmith * property rights. 2367754Smsmith * 2467754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2567754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2667754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2767754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2867754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2967754Smsmith * Code in any form, with the right to sublicense such rights; and 3067754Smsmith * 3167754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3267754Smsmith * license (with the right to sublicense), under only those claims of Intel 3367754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3467754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3567754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3667754Smsmith * license, and in no event shall the patent license extend to any additions 3767754Smsmith * to or modifications of the Original Intel Code. No other license or right 3867754Smsmith * is granted directly or by implication, estoppel or otherwise; 3967754Smsmith * 4067754Smsmith * The above copyright and patent license is granted only if the following 4167754Smsmith * conditions are met: 4267754Smsmith * 4367754Smsmith * 3. Conditions 4467754Smsmith * 4567754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4667754Smsmith * Redistribution of source code of any substantial portion of the Covered 4767754Smsmith * Code or modification with rights to further distribute source must include 4867754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4967754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 5067754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 5167754Smsmith * contain a file documenting the changes Licensee made to create that Covered 5267754Smsmith * Code and the date of any change. Licensee must include in that file the 5367754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5467754Smsmith * must include a prominent statement that the modification is derived, 5567754Smsmith * directly or indirectly, from Original Intel Code. 5667754Smsmith * 5767754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5867754Smsmith * Redistribution of source code of any substantial portion of the Covered 5967754Smsmith * Code or modification without rights to further distribute source must 6067754Smsmith * include the following Disclaimer and Export Compliance provision in the 6167754Smsmith * documentation and/or other materials provided with distribution. In 6267754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6367754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6467754Smsmith * license from Licensee to its licensee is limited to the intellectual 6567754Smsmith * property embodied in the software Licensee provides to its licensee, and 6667754Smsmith * not to intellectual property embodied in modifications its licensee may 6767754Smsmith * make. 6867754Smsmith * 6967754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 7067754Smsmith * substantial portion of the Covered Code or modification must reproduce the 7167754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 7267754Smsmith * provision in the documentation and/or other materials provided with the 7367754Smsmith * distribution. 7467754Smsmith * 7567754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7667754Smsmith * Intel Code. 7767754Smsmith * 7867754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7967754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 8067754Smsmith * other dealings in products derived from or relating to the Covered Code 8167754Smsmith * without prior written authorization from Intel. 8267754Smsmith * 8367754Smsmith * 4. Disclaimer and Export Compliance 8467754Smsmith * 8567754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8667754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8767754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8867754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8967754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 9067754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 9167754Smsmith * PARTICULAR PURPOSE. 9267754Smsmith * 9367754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9467754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9567754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9667754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9767754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9867754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9967754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 10067754Smsmith * LIMITED REMEDY. 10167754Smsmith * 10267754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10367754Smsmith * software or system incorporating such software without first obtaining any 10467754Smsmith * required license or other approval from the U. S. Department of Commerce or 10567754Smsmith * any other agency or department of the United States Government. In the 10667754Smsmith * event Licensee exports any such software from the United States or 10767754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10867754Smsmith * ensure that the distribution and export/re-export of the software is in 10967754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 11067754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 11167754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 11267754Smsmith * software, or service, directly or indirectly, to any country for which the 11367754Smsmith * United States government or any agency thereof requires an export license, 11467754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11567754Smsmith * such license, approval or letter. 11667754Smsmith * 11767754Smsmith *****************************************************************************/ 11867754Smsmith 11967754Smsmith#define __HWREGS_C__ 12067754Smsmith 12167754Smsmith#include "acpi.h" 12267754Smsmith#include "achware.h" 12367754Smsmith#include "acnamesp.h" 12467754Smsmith 12577424Smsmith#define _COMPONENT ACPI_HARDWARE 12667754Smsmith MODULE_NAME ("hwregs") 12767754Smsmith 12867754Smsmith 12967754Smsmith/* This matches the #defines in actypes.h. */ 13067754Smsmith 13169450SmsmithNATIVE_CHAR *SleepStateTable[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_", 13271867Smsmith "\\_S4_","\\_S5_","\\_S4B"}; 13367754Smsmith 13467754Smsmith 13567754Smsmith/******************************************************************************* 13667754Smsmith * 13767754Smsmith * FUNCTION: AcpiHwGetBitShift 13867754Smsmith * 13967754Smsmith * PARAMETERS: Mask - Input mask to determine bit shift from. 14067754Smsmith * Must have at least 1 bit set. 14167754Smsmith * 14267754Smsmith * RETURN: Bit location of the lsb of the mask 14367754Smsmith * 14467754Smsmith * DESCRIPTION: Returns the bit number for the low order bit that's set. 14567754Smsmith * 14667754Smsmith ******************************************************************************/ 14767754Smsmith 14871867SmsmithUINT32 14967754SmsmithAcpiHwGetBitShift ( 15067754Smsmith UINT32 Mask) 15167754Smsmith{ 15267754Smsmith UINT32 Shift; 15367754Smsmith 15467754Smsmith 15567754Smsmith FUNCTION_TRACE ("HwGetBitShift"); 15667754Smsmith 15767754Smsmith 15867754Smsmith for (Shift = 0; ((Mask >> Shift) & 1) == 0; Shift++) 15967754Smsmith { ; } 16067754Smsmith 16167754Smsmith return_VALUE (Shift); 16267754Smsmith} 16367754Smsmith 16467754Smsmith 16567754Smsmith/******************************************************************************* 16667754Smsmith * 16767754Smsmith * FUNCTION: AcpiHwClearAcpiStatus 16867754Smsmith * 16967754Smsmith * PARAMETERS: none 17067754Smsmith * 17167754Smsmith * RETURN: none 17267754Smsmith * 17367754Smsmith * DESCRIPTION: Clears all fixed and general purpose status bits 17467754Smsmith * 17567754Smsmith ******************************************************************************/ 17667754Smsmith 17767754Smsmithvoid 17867754SmsmithAcpiHwClearAcpiStatus (void) 17967754Smsmith{ 18067754Smsmith UINT16 GpeLength; 18167754Smsmith UINT16 Index; 18267754Smsmith 18367754Smsmith 18467754Smsmith FUNCTION_TRACE ("HwClearAcpiStatus"); 18567754Smsmith 18667754Smsmith 18777424Smsmith DEBUG_PRINTP (TRACE_IO, ("About to write %04X to %04X\n", 18877424Smsmith ALL_FIXED_STS_BITS, 18977424Smsmith (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address))); 19067754Smsmith 19167754Smsmith 19277424Smsmith AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 19367754Smsmith 19469450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS); 19567754Smsmith 19669450Smsmith 19770243Smsmith if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address)) 19867754Smsmith { 19980062Smsmith AcpiOsWritePort ((ACPI_IO_ADDRESS) 20080062Smsmith ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address), 20180062Smsmith ALL_FIXED_STS_BITS, 16); 20267754Smsmith } 20367754Smsmith 20467754Smsmith /* now clear the GPE Bits */ 20567754Smsmith 20669450Smsmith if (AcpiGbl_FADT->Gpe0BlkLen) 20767754Smsmith { 20869450Smsmith GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe0BlkLen); 20967754Smsmith 21067754Smsmith for (Index = 0; Index < GpeLength; Index++) 21167754Smsmith { 21280062Smsmith AcpiOsWritePort ((ACPI_IO_ADDRESS) ( 21377424Smsmith ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address) + Index), 21480062Smsmith 0xFF, 8); 21567754Smsmith } 21667754Smsmith } 21767754Smsmith 21869450Smsmith if (AcpiGbl_FADT->Gpe1BlkLen) 21967754Smsmith { 22069450Smsmith GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); 22167754Smsmith 22267754Smsmith for (Index = 0; Index < GpeLength; Index++) 22367754Smsmith { 22480062Smsmith AcpiOsWritePort ((ACPI_IO_ADDRESS) ( 22577424Smsmith ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address) + Index), 22680062Smsmith 0xFF, 8); 22767754Smsmith } 22867754Smsmith } 22967754Smsmith 23077424Smsmith AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 23167754Smsmith return_VOID; 23267754Smsmith} 23367754Smsmith 23467754Smsmith 23567754Smsmith/******************************************************************************* 23667754Smsmith * 23767754Smsmith * FUNCTION: AcpiHwObtainSleepTypeRegisterData 23867754Smsmith * 23967754Smsmith * PARAMETERS: SleepState - Numeric state requested 24067754Smsmith * *Slp_TypA - Pointer to byte to receive SLP_TYPa value 24167754Smsmith * *Slp_TypB - Pointer to byte to receive SLP_TYPb value 24267754Smsmith * 24367754Smsmith * RETURN: Status - ACPI status 24467754Smsmith * 24567754Smsmith * DESCRIPTION: AcpiHwObtainSleepTypeRegisterData() obtains the SLP_TYP and 24667754Smsmith * SLP_TYPb values for the sleep state requested. 24767754Smsmith * 24867754Smsmith ******************************************************************************/ 24967754Smsmith 25067754SmsmithACPI_STATUS 25167754SmsmithAcpiHwObtainSleepTypeRegisterData ( 25267754Smsmith UINT8 SleepState, 25367754Smsmith UINT8 *Slp_TypA, 25467754Smsmith UINT8 *Slp_TypB) 25567754Smsmith{ 25667754Smsmith ACPI_STATUS Status = AE_OK; 25767754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 25867754Smsmith 25967754Smsmith 26067754Smsmith FUNCTION_TRACE ("HwObtainSleepTypeRegisterData"); 26167754Smsmith 26267754Smsmith 26367754Smsmith /* 26467754Smsmith * Validate parameters 26567754Smsmith */ 26667754Smsmith 26767754Smsmith if ((SleepState > ACPI_S_STATES_MAX) || 26867754Smsmith !Slp_TypA || !Slp_TypB) 26967754Smsmith { 27067754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 27167754Smsmith } 27267754Smsmith 27367754Smsmith /* 27467754Smsmith * AcpiEvaluate the namespace object containing the values for this state 27567754Smsmith */ 27667754Smsmith 27767754Smsmith Status = AcpiNsEvaluateByName (SleepStateTable[SleepState], NULL, &ObjDesc); 27867754Smsmith if (ACPI_FAILURE (Status)) 27967754Smsmith { 28067754Smsmith return_ACPI_STATUS (Status); 28167754Smsmith } 28267754Smsmith 28367754Smsmith if (!ObjDesc) 28467754Smsmith { 28567754Smsmith REPORT_ERROR (("Missing Sleep State object\n")); 28667754Smsmith return_ACPI_STATUS (AE_NOT_EXIST); 28767754Smsmith } 28867754Smsmith 28967754Smsmith /* 29067754Smsmith * We got something, now ensure it is correct. The object must 29167754Smsmith * be a package and must have at least 2 numeric values as the 29267754Smsmith * two elements 29367754Smsmith */ 29467754Smsmith 29577424Smsmith /* Even though AcpiEvaluateObject resolves package references, 29677424Smsmith * NsEvaluate dpesn't. So, we do it here. 29777424Smsmith */ 29877424Smsmith Status = AcpiUtResolvePackageReferences(ObjDesc); 29967754Smsmith 30067754Smsmith if (ObjDesc->Package.Count < 2) 30167754Smsmith { 30267754Smsmith /* Must have at least two elements */ 30367754Smsmith 30467754Smsmith REPORT_ERROR (("Sleep State package does not have at least two elements\n")); 30567754Smsmith Status = AE_ERROR; 30667754Smsmith } 30767754Smsmith 30867754Smsmith else if (((ObjDesc->Package.Elements[0])->Common.Type != 30971867Smsmith ACPI_TYPE_INTEGER) || 31067754Smsmith ((ObjDesc->Package.Elements[1])->Common.Type != 31171867Smsmith ACPI_TYPE_INTEGER)) 31267754Smsmith { 31367754Smsmith /* Must have two */ 31467754Smsmith 31567754Smsmith REPORT_ERROR (("Sleep State package elements are not both of type Number\n")); 31667754Smsmith Status = AE_ERROR; 31767754Smsmith } 31867754Smsmith 31967754Smsmith else 32067754Smsmith { 32167754Smsmith /* 32267754Smsmith * Valid _Sx_ package size, type, and value 32367754Smsmith */ 32471867Smsmith *Slp_TypA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value; 32567754Smsmith 32671867Smsmith *Slp_TypB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.Value; 32767754Smsmith } 32867754Smsmith 32967754Smsmith 33067754Smsmith if (ACPI_FAILURE (Status)) 33167754Smsmith { 33277424Smsmith DEBUG_PRINTP (ACPI_ERROR, ("Bad Sleep object %p type %X\n", 33367754Smsmith ObjDesc, ObjDesc->Common.Type)); 33467754Smsmith } 33567754Smsmith 33677424Smsmith AcpiUtRemoveReference (ObjDesc); 33767754Smsmith 33867754Smsmith return_ACPI_STATUS (Status); 33967754Smsmith} 34067754Smsmith 34167754Smsmith 34267754Smsmith/******************************************************************************* 34367754Smsmith * 34469450Smsmith * FUNCTION: AcpiHwRegisterBitAccess 34567754Smsmith * 34667754Smsmith * PARAMETERS: ReadWrite - Either ACPI_READ or ACPI_WRITE. 34767754Smsmith * UseLock - Lock the hardware 34869450Smsmith * RegisterId - index of ACPI Register to access 34967754Smsmith * Value - (only used on write) value to write to the 35069450Smsmith * Register. Shifted all the way right. 35167754Smsmith * 35269450Smsmith * RETURN: Value written to or read from specified Register. This value 35367754Smsmith * is shifted all the way right. 35467754Smsmith * 35569450Smsmith * DESCRIPTION: Generic ACPI Register read/write function. 35667754Smsmith * 35767754Smsmith ******************************************************************************/ 35867754Smsmith 35967754SmsmithUINT32 36069450SmsmithAcpiHwRegisterBitAccess ( 36167754Smsmith NATIVE_UINT ReadWrite, 36267754Smsmith BOOLEAN UseLock, 36367754Smsmith UINT32 RegisterId, 36467754Smsmith ...) /* Value (only used on write) */ 36567754Smsmith{ 36667754Smsmith UINT32 RegisterValue = 0; 36767754Smsmith UINT32 Mask = 0; 36867754Smsmith UINT32 Value = 0; 36977424Smsmith va_list marker; 37067754Smsmith 37177424Smsmith 37269450Smsmith FUNCTION_TRACE ("HwRegisterBitAccess"); 37367754Smsmith 37467754Smsmith 37567754Smsmith if (ReadWrite == ACPI_WRITE) 37667754Smsmith { 37767754Smsmith va_start (marker, RegisterId); 37867754Smsmith Value = va_arg (marker, UINT32); 37967754Smsmith va_end (marker); 38067754Smsmith } 38167754Smsmith 38277424Smsmith if (ACPI_MTX_LOCK == UseLock) 38377424Smsmith { 38477424Smsmith AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 38569450Smsmith } 38667754Smsmith 38767754Smsmith /* 38867754Smsmith * Decode the Register ID 38977424Smsmith * Register id = Register block id | bit id 39069450Smsmith * 39169450Smsmith * Check bit id to fine locate Register offset. 39277424Smsmith * Check Mask to determine Register offset, and then read-write. 39367754Smsmith */ 39467754Smsmith 39577424Smsmith switch (REGISTER_BLOCK_ID (RegisterId)) 39667754Smsmith { 39769450Smsmith case PM1_STS: 39867754Smsmith 39969450Smsmith switch (RegisterId) 40067754Smsmith { 40169450Smsmith case TMR_STS: 40269450Smsmith Mask = TMR_STS_MASK; 40369450Smsmith break; 40467754Smsmith 40569450Smsmith case BM_STS: 40669450Smsmith Mask = BM_STS_MASK; 40769450Smsmith break; 40867754Smsmith 40969450Smsmith case GBL_STS: 41069450Smsmith Mask = GBL_STS_MASK; 41169450Smsmith break; 41267754Smsmith 41369450Smsmith case PWRBTN_STS: 41469450Smsmith Mask = PWRBTN_STS_MASK; 41569450Smsmith break; 41667754Smsmith 41769450Smsmith case SLPBTN_STS: 41869450Smsmith Mask = SLPBTN_STS_MASK; 41969450Smsmith break; 42067754Smsmith 42169450Smsmith case RTC_STS: 42269450Smsmith Mask = RTC_STS_MASK; 42369450Smsmith break; 42467754Smsmith 42569450Smsmith case WAK_STS: 42669450Smsmith Mask = WAK_STS_MASK; 42769450Smsmith break; 42867754Smsmith 42969450Smsmith default: 43069450Smsmith Mask = 0; 43169450Smsmith break; 43269450Smsmith } 43367754Smsmith 43469450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_STS); 43567754Smsmith 43669450Smsmith if (ReadWrite == ACPI_WRITE) 43769450Smsmith { 43869450Smsmith /* 43969450Smsmith * Status Registers are different from the rest. Clear by 44069450Smsmith * writing 1, writing 0 has no effect. So, the only relevent 44169450Smsmith * information is the single bit we're interested in, all 44269450Smsmith * others should be written as 0 so they will be left 44369450Smsmith * unchanged 44469450Smsmith */ 44567754Smsmith 44669450Smsmith Value <<= AcpiHwGetBitShift (Mask); 44769450Smsmith Value &= Mask; 44867754Smsmith 44969450Smsmith if (Value) 45067754Smsmith { 45177424Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, 45277424Smsmith (UINT16) Value); 45369450Smsmith RegisterValue = 0; 45467754Smsmith } 45567754Smsmith } 45667754Smsmith 45769450Smsmith break; 45867754Smsmith 45967754Smsmith 46069450Smsmith case PM1_EN: 46167754Smsmith 46269450Smsmith switch (RegisterId) 46369450Smsmith { 46469450Smsmith case TMR_EN: 46569450Smsmith Mask = TMR_EN_MASK; 46669450Smsmith break; 46767754Smsmith 46869450Smsmith case GBL_EN: 46969450Smsmith Mask = GBL_EN_MASK; 47069450Smsmith break; 47167754Smsmith 47269450Smsmith case PWRBTN_EN: 47369450Smsmith Mask = PWRBTN_EN_MASK; 47469450Smsmith break; 47567754Smsmith 47669450Smsmith case SLPBTN_EN: 47769450Smsmith Mask = SLPBTN_EN_MASK; 47869450Smsmith break; 47967754Smsmith 48069450Smsmith case RTC_EN: 48169450Smsmith Mask = RTC_EN_MASK; 48269450Smsmith break; 48367754Smsmith 48469450Smsmith default: 48569450Smsmith Mask = 0; 48669450Smsmith break; 48769450Smsmith } 48867754Smsmith 48969450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_EN); 49067754Smsmith 49169450Smsmith if (ReadWrite == ACPI_WRITE) 49269450Smsmith { 49369450Smsmith RegisterValue &= ~Mask; 49469450Smsmith Value <<= AcpiHwGetBitShift (Mask); 49569450Smsmith Value &= Mask; 49669450Smsmith RegisterValue |= Value; 49767754Smsmith 49869450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (UINT16) RegisterValue); 49969450Smsmith } 50067754Smsmith 50167754Smsmith break; 50267754Smsmith 50367754Smsmith 50467754Smsmith case PM1_CONTROL: 50567754Smsmith 50667754Smsmith switch (RegisterId) 50767754Smsmith { 50867754Smsmith case SCI_EN: 50967754Smsmith Mask = SCI_EN_MASK; 51067754Smsmith break; 51167754Smsmith 51267754Smsmith case BM_RLD: 51367754Smsmith Mask = BM_RLD_MASK; 51467754Smsmith break; 51567754Smsmith 51667754Smsmith case GBL_RLS: 51767754Smsmith Mask = GBL_RLS_MASK; 51867754Smsmith break; 51967754Smsmith 52067754Smsmith case SLP_TYPE_A: 52167754Smsmith case SLP_TYPE_B: 52267754Smsmith Mask = SLP_TYPE_X_MASK; 52367754Smsmith break; 52467754Smsmith 52567754Smsmith case SLP_EN: 52667754Smsmith Mask = SLP_EN_MASK; 52767754Smsmith break; 52867754Smsmith 52967754Smsmith default: 53067754Smsmith Mask = 0; 53167754Smsmith break; 53267754Smsmith } 53367754Smsmith 53469450Smsmith 53569450Smsmith /* 53669450Smsmith * Read the PM1 Control register. 53769450Smsmith * Note that at this level, the fact that there are actually TWO 53869450Smsmith * registers (A and B) and that B may not exist, are abstracted. 53969450Smsmith */ 54069450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL); 54169450Smsmith 54269746Smsmith DEBUG_PRINT (TRACE_IO, ("PM1 control: Read %X\n", RegisterValue)); 54369450Smsmith 54467754Smsmith if (ReadWrite == ACPI_WRITE) 54567754Smsmith { 54667754Smsmith RegisterValue &= ~Mask; 54767754Smsmith Value <<= AcpiHwGetBitShift (Mask); 54867754Smsmith Value &= Mask; 54967754Smsmith RegisterValue |= Value; 55067754Smsmith 55167754Smsmith /* 55269450Smsmith * SLP_TYPE_x Registers are written differently 55369450Smsmith * than any other control Registers with 55469450Smsmith * respect to A and B Registers. The value 55567754Smsmith * for A may be different than the value for B 55669746Smsmith * 55769746Smsmith * Therefore, pass the RegisterId, not just generic PM1_CONTROL, 55869746Smsmith * because we need to do different things. Yuck. 55967754Smsmith */ 56067754Smsmith 56177424Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId, 56277424Smsmith (UINT16) RegisterValue); 56367754Smsmith } 56467754Smsmith break; 56567754Smsmith 56667754Smsmith 56767754Smsmith case PM2_CONTROL: 56867754Smsmith 56967754Smsmith switch (RegisterId) 57067754Smsmith { 57167754Smsmith case ARB_DIS: 57267754Smsmith Mask = ARB_DIS_MASK; 57367754Smsmith break; 57467754Smsmith 57567754Smsmith default: 57667754Smsmith Mask = 0; 57767754Smsmith break; 57867754Smsmith } 57967754Smsmith 58069450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); 58169450Smsmith 58269746Smsmith DEBUG_PRINT (TRACE_IO, ("PM2 control: Read %X from %p\n", 58377424Smsmith RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address))); 58469450Smsmith 58567754Smsmith if (ReadWrite == ACPI_WRITE) 58667754Smsmith { 58767754Smsmith RegisterValue &= ~Mask; 58867754Smsmith Value <<= AcpiHwGetBitShift (Mask); 58967754Smsmith Value &= Mask; 59067754Smsmith RegisterValue |= Value; 59167754Smsmith 59277424Smsmith DEBUG_PRINT (TRACE_IO, ("About to write %04X to %p\n", RegisterValue, 59369450Smsmith AcpiGbl_FADT->XPm2CntBlk.Address)); 59467754Smsmith 59569450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 59669450Smsmith PM2_CONTROL, (UINT8) (RegisterValue)); 59767754Smsmith } 59867754Smsmith break; 59967754Smsmith 60067754Smsmith 60167754Smsmith case PM_TIMER: 60267754Smsmith 60369450Smsmith Mask = TMR_VAL_MASK; 60469450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 60569450Smsmith PM_TIMER); 60669746Smsmith DEBUG_PRINT (TRACE_IO, ("PM_TIMER: Read %X from %p\n", 60777424Smsmith RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPmTmrBlk.Address))); 60867754Smsmith 60967754Smsmith break; 61067754Smsmith 61167754Smsmith 61267754Smsmith case GPE1_EN_BLOCK: 61367754Smsmith case GPE1_STS_BLOCK: 61467754Smsmith case GPE0_EN_BLOCK: 61567754Smsmith case GPE0_STS_BLOCK: 61667754Smsmith 61769450Smsmith /* Determine the bit to be accessed 61869450Smsmith * 61969450Smsmith * (UINT32) RegisterId: 62069450Smsmith * 31 24 16 8 0 62169450Smsmith * +--------+--------+--------+--------+ 62269450Smsmith * | gpe_block_id | gpe_bit_number | 62369450Smsmith * +--------+--------+--------+--------+ 62469450Smsmith * 62569450Smsmith * gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK 62669450Smsmith * gpe_bit_number is relative from the gpe_block (0x00~0xFF) 62769450Smsmith */ 62867754Smsmith 62969450Smsmith Mask = REGISTER_BIT_ID(RegisterId); /* gpe_bit_number */ 63069450Smsmith RegisterId = REGISTER_BLOCK_ID(RegisterId) | (Mask >> 3); 63169450Smsmith Mask = AcpiGbl_DecodeTo8bit [Mask % 8]; 63267754Smsmith 63367754Smsmith /* 63467754Smsmith * The base address of the GPE 0 Register Block 63567754Smsmith * Plus 1/2 the length of the GPE 0 Register Block 63669450Smsmith * The enable Register is the Register following the Status Register 63769450Smsmith * and each Register is defined as 1/2 of the total Register Block 63867754Smsmith */ 63967754Smsmith 64067754Smsmith /* 64167754Smsmith * This sets the bit within EnableBit that needs to be written to 64269450Smsmith * the Register indicated in Mask to a 1, all others are 0 64367754Smsmith */ 64467754Smsmith 64567754Smsmith /* Now get the current Enable Bits in the selected Reg */ 64667754Smsmith 64769450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId); 64869746Smsmith DEBUG_PRINT (TRACE_IO, ("GPE Enable bits: Read %X from %X\n", 64977424Smsmith RegisterValue, RegisterId)); 65067754Smsmith 65167754Smsmith if (ReadWrite == ACPI_WRITE) 65267754Smsmith { 65367754Smsmith RegisterValue &= ~Mask; 65467754Smsmith Value <<= AcpiHwGetBitShift (Mask); 65567754Smsmith Value &= Mask; 65667754Smsmith RegisterValue |= Value; 65767754Smsmith 65867754Smsmith /* This write will put the Action state into the General Purpose */ 65967754Smsmith /* Enable Register indexed by the value in Mask */ 66067754Smsmith 66167754Smsmith DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n", 66277424Smsmith RegisterValue, RegisterId)); 66377424Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId, 66477424Smsmith (UINT8) RegisterValue); 66577424Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 66677424Smsmith RegisterId); 66767754Smsmith } 66867754Smsmith break; 66967754Smsmith 67067754Smsmith 67169450Smsmith case SMI_CMD_BLOCK: 67267754Smsmith case PROCESSOR_BLOCK: 67377424Smsmith /* Not used by any callers at this time - therefore, not implemented */ 67477424Smsmith 67567754Smsmith default: 67667754Smsmith 67767754Smsmith Mask = 0; 67867754Smsmith break; 67967754Smsmith } 68067754Smsmith 68169450Smsmith if (ACPI_MTX_LOCK == UseLock) { 68277424Smsmith AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 68369450Smsmith } 68467754Smsmith 68569450Smsmith 68667754Smsmith RegisterValue &= Mask; 68767754Smsmith RegisterValue >>= AcpiHwGetBitShift (Mask); 68867754Smsmith 68969746Smsmith DEBUG_PRINT (TRACE_IO, ("Register I/O: returning %X\n", RegisterValue)); 69067754Smsmith return_VALUE (RegisterValue); 69167754Smsmith} 69269450Smsmith 69369450Smsmith 69469450Smsmith/****************************************************************************** 69569450Smsmith * 69669450Smsmith * FUNCTION: AcpiHwRegisterRead 69769450Smsmith * 69869450Smsmith * PARAMETERS: UseLock - Mutex hw access. 69969450Smsmith * RegisterId - RegisterID + Offset. 70069450Smsmith * 70169450Smsmith * RETURN: Value read or written. 70269450Smsmith * 70369450Smsmith * DESCRIPTION: Acpi register read function. Registers are read at the 70469450Smsmith * given offset. 70569450Smsmith * 70669450Smsmith ******************************************************************************/ 70769450Smsmith 70869450SmsmithUINT32 70969450SmsmithAcpiHwRegisterRead ( 71069450Smsmith BOOLEAN UseLock, 71169450Smsmith UINT32 RegisterId) 71269450Smsmith{ 71380062Smsmith UINT32 Value = 0; 71469450Smsmith UINT32 BankOffset; 71569450Smsmith 71677424Smsmith 71769450Smsmith FUNCTION_TRACE ("AcpiHwRegisterRead"); 71869450Smsmith 71977424Smsmith 72069450Smsmith if (ACPI_MTX_LOCK == UseLock) 72169450Smsmith { 72277424Smsmith AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 72369450Smsmith } 72469450Smsmith 72569450Smsmith 72669450Smsmith switch (REGISTER_BLOCK_ID(RegisterId)) 72769450Smsmith { 72869450Smsmith case PM1_STS: /* 16-bit access */ 72969450Smsmith 73069746Smsmith Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, 0); 73169746Smsmith Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, 0); 73269450Smsmith break; 73369450Smsmith 73469450Smsmith 73569450Smsmith case PM1_EN: /* 16-bit access*/ 73669450Smsmith 73769450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen); 73869746Smsmith Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset); 73969746Smsmith Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset); 74069450Smsmith break; 74169450Smsmith 74269450Smsmith 74369450Smsmith case PM1_CONTROL: /* 16-bit access */ 74469450Smsmith 74571867Smsmith Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aCntBlk, 0); 74671867Smsmith Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bCntBlk, 0); 74769450Smsmith break; 74869450Smsmith 74969450Smsmith 75069450Smsmith case PM2_CONTROL: /* 8-bit access */ 75169450Smsmith 75269746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XPm2CntBlk, 0); 75369450Smsmith break; 75469450Smsmith 75569450Smsmith 75669450Smsmith case PM_TIMER: /* 32-bit access */ 75769450Smsmith 75869746Smsmith Value = AcpiHwLowLevelRead (32, &AcpiGbl_FADT->XPmTmrBlk, 0); 75969450Smsmith break; 76069450Smsmith 76169450Smsmith 76269450Smsmith case GPE0_STS_BLOCK: /* 8-bit access */ 76369450Smsmith 76469746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, 0); 76569450Smsmith break; 76669450Smsmith 76769450Smsmith 76869450Smsmith case GPE0_EN_BLOCK: /* 8-bit access */ 76969450Smsmith 77069450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen); 77169746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset); 77269450Smsmith break; 77369450Smsmith 77469450Smsmith 77569450Smsmith case GPE1_STS_BLOCK: /* 8-bit access */ 77669450Smsmith 77769746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, 0); 77869450Smsmith break; 77969450Smsmith 78069450Smsmith 78169450Smsmith case GPE1_EN_BLOCK: /* 8-bit access */ 78269450Smsmith 78369450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); 78469746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset); 78569450Smsmith break; 78669450Smsmith 78769450Smsmith 78869450Smsmith case SMI_CMD_BLOCK: /* 8bit */ 78969450Smsmith 79080062Smsmith AcpiOsReadPort (AcpiGbl_FADT->SmiCmd, &Value, 8); 79169450Smsmith break; 79269450Smsmith 79369450Smsmith 79469450Smsmith default: 79580062Smsmith /* Value will be returned as 0 */ 79669450Smsmith break; 79769450Smsmith } 79869450Smsmith 79969450Smsmith 80069450Smsmith if (ACPI_MTX_LOCK == UseLock) 80169450Smsmith { 80277424Smsmith AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 80369450Smsmith } 80469450Smsmith 80569450Smsmith return_VALUE (Value); 80669450Smsmith} 80769450Smsmith 80869450Smsmith 80969450Smsmith/****************************************************************************** 81069450Smsmith * 81169450Smsmith * FUNCTION: AcpiHwRegisterWrite 81269450Smsmith * 81369450Smsmith * PARAMETERS: UseLock - Mutex hw access. 81469450Smsmith * RegisterId - RegisterID + Offset. 81569450Smsmith * 81669450Smsmith * RETURN: Value read or written. 81769450Smsmith * 81869450Smsmith * DESCRIPTION: Acpi register Write function. Registers are written at the 81969450Smsmith * given offset. 82069450Smsmith * 82169450Smsmith ******************************************************************************/ 82269450Smsmith 82369450Smsmithvoid 82469450SmsmithAcpiHwRegisterWrite ( 82569450Smsmith BOOLEAN UseLock, 82669450Smsmith UINT32 RegisterId, 82769450Smsmith UINT32 Value) 82869450Smsmith{ 82969450Smsmith UINT32 BankOffset; 83069450Smsmith 83169450Smsmith FUNCTION_TRACE ("AcpiHwRegisterWrite"); 83269450Smsmith 83369450Smsmith 83469450Smsmith if (ACPI_MTX_LOCK == UseLock) 83569450Smsmith { 83677424Smsmith AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 83769450Smsmith } 83869450Smsmith 83969450Smsmith 84069450Smsmith switch (REGISTER_BLOCK_ID (RegisterId)) 84169450Smsmith { 84269450Smsmith case PM1_STS: /* 16-bit access */ 84369450Smsmith 84469746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, 0); 84569746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, 0); 84669450Smsmith break; 84769450Smsmith 84869450Smsmith 84969450Smsmith case PM1_EN: /* 16-bit access*/ 85069450Smsmith 85169450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen); 85269746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset); 85369746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset); 85469450Smsmith break; 85569450Smsmith 85669450Smsmith 85769450Smsmith case PM1_CONTROL: /* 16-bit access */ 85869450Smsmith 85971867Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0); 86071867Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0); 86171867Smsmith break; 86269450Smsmith 86369450Smsmith 86471867Smsmith case PM1A_CONTROL: /* 16-bit access */ 86569450Smsmith 86671867Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0); 86769450Smsmith break; 86869450Smsmith 86969450Smsmith 87071867Smsmith case PM1B_CONTROL: /* 16-bit access */ 87171867Smsmith 87271867Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0); 87371867Smsmith break; 87471867Smsmith 87571867Smsmith 87669450Smsmith case PM2_CONTROL: /* 8-bit access */ 87769450Smsmith 87869746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, 0); 87969450Smsmith break; 88069450Smsmith 88169450Smsmith 88269450Smsmith case PM_TIMER: /* 32-bit access */ 88369450Smsmith 88469746Smsmith AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, 0); 88569450Smsmith break; 88669450Smsmith 88769450Smsmith 88869450Smsmith case GPE0_STS_BLOCK: /* 8-bit access */ 88969450Smsmith 89069746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, 0); 89169450Smsmith break; 89269450Smsmith 89369450Smsmith 89469450Smsmith case GPE0_EN_BLOCK: /* 8-bit access */ 89569450Smsmith 89669450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen); 89769746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset); 89869450Smsmith break; 89969450Smsmith 90069450Smsmith 90169450Smsmith case GPE1_STS_BLOCK: /* 8-bit access */ 90269450Smsmith 90369746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, 0); 90469450Smsmith break; 90569450Smsmith 90669450Smsmith 90769450Smsmith case GPE1_EN_BLOCK: /* 8-bit access */ 90869450Smsmith 90969450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); 91069746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset); 91169450Smsmith break; 91269450Smsmith 91369450Smsmith 91469450Smsmith case SMI_CMD_BLOCK: /* 8bit */ 91569450Smsmith 91669450Smsmith /* For 2.0, SMI_CMD is always in IO space */ 91769450Smsmith /* TBD: what about 1.0? 0.71? */ 91869450Smsmith 91980062Smsmith AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, Value, 8); 92069450Smsmith break; 92169450Smsmith 92269450Smsmith 92369450Smsmith default: 92469450Smsmith Value = 0; 92569450Smsmith break; 92669450Smsmith } 92769450Smsmith 92869450Smsmith 92969450Smsmith if (ACPI_MTX_LOCK == UseLock) 93069450Smsmith { 93177424Smsmith AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 93269450Smsmith } 93369450Smsmith 93469450Smsmith return_VOID; 93569450Smsmith} 93669450Smsmith 93769450Smsmith 93869450Smsmith/****************************************************************************** 93969450Smsmith * 94069450Smsmith * FUNCTION: AcpiHwLowLevelRead 94169450Smsmith * 94269450Smsmith * PARAMETERS: Register - GAS register structure 94369450Smsmith * Offset - Offset from the base address in the GAS 94469450Smsmith * Width - 8, 16, or 32 94569450Smsmith * 94669450Smsmith * RETURN: Value read 94769450Smsmith * 94869450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space. 94969450Smsmith * 95069450Smsmith ******************************************************************************/ 95169450Smsmith 95269450SmsmithUINT32 95369450SmsmithAcpiHwLowLevelRead ( 95469450Smsmith UINT32 Width, 95577424Smsmith ACPI_GENERIC_ADDRESS *Reg, 95669450Smsmith UINT32 Offset) 95769450Smsmith{ 95869450Smsmith UINT32 Value = 0; 95969450Smsmith ACPI_PHYSICAL_ADDRESS MemAddress; 96069450Smsmith ACPI_IO_ADDRESS IoAddress; 96180062Smsmith ACPI_PCI_ID PciId; 96280062Smsmith UINT16 PciRegister; 96369450Smsmith 96469450Smsmith 96569450Smsmith /* 96669450Smsmith * Must have a valid pointer to a GAS structure, and 96769450Smsmith * a non-zero address within 96869450Smsmith */ 96969450Smsmith if ((!Reg) || 97070243Smsmith (!ACPI_VALID_ADDRESS (Reg->Address))) 97169450Smsmith { 97269450Smsmith return 0; 97369450Smsmith } 97469450Smsmith 97569450Smsmith 97669450Smsmith /* 97769450Smsmith * Three address spaces supported: 97869450Smsmith * Memory, Io, or PCI config. 97969450Smsmith */ 98069450Smsmith 98169450Smsmith switch (Reg->AddressSpaceId) 98269450Smsmith { 98377424Smsmith case ACPI_ADR_SPACE_SYSTEM_MEMORY: 98469450Smsmith 98570243Smsmith MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 98669450Smsmith 98780062Smsmith AcpiOsReadMemory (MemAddress, &Value, Width); 98869450Smsmith break; 98969450Smsmith 99069450Smsmith 99177424Smsmith case ACPI_ADR_SPACE_SYSTEM_IO: 99269450Smsmith 99370243Smsmith IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 99469450Smsmith 99580062Smsmith AcpiOsReadPort (IoAddress, &Value, Width); 99669450Smsmith break; 99769450Smsmith 99869450Smsmith 99977424Smsmith case ACPI_ADR_SPACE_PCI_CONFIG: 100069450Smsmith 100180062Smsmith PciId.Segment = 0; 100280062Smsmith PciId.Bus = 0; 100380062Smsmith PciId.Device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address)); 100480062Smsmith PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address)); 100580062Smsmith PciRegister = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset); 100669450Smsmith 100780062Smsmith AcpiOsReadPciConfiguration (&PciId, PciRegister, &Value, Width); 100869450Smsmith break; 100969450Smsmith } 101069450Smsmith 101169450Smsmith return Value; 101269450Smsmith} 101369450Smsmith 101469450Smsmith 101569450Smsmith/****************************************************************************** 101669450Smsmith * 101769450Smsmith * FUNCTION: AcpiHwLowLevelWrite 101869450Smsmith * 101969450Smsmith * PARAMETERS: Width - 8, 16, or 32 102069450Smsmith * Value - To be written 102169450Smsmith * Register - GAS register structure 102269450Smsmith * Offset - Offset from the base address in the GAS 102369450Smsmith * 102469450Smsmith * 102569450Smsmith * RETURN: Value read 102669450Smsmith * 102769450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space. 102869450Smsmith * 102969450Smsmith ******************************************************************************/ 103069450Smsmith 103169450Smsmithvoid 103269450SmsmithAcpiHwLowLevelWrite ( 103369450Smsmith UINT32 Width, 103469450Smsmith UINT32 Value, 103577424Smsmith ACPI_GENERIC_ADDRESS *Reg, 103669450Smsmith UINT32 Offset) 103769450Smsmith{ 103869450Smsmith ACPI_PHYSICAL_ADDRESS MemAddress; 103969450Smsmith ACPI_IO_ADDRESS IoAddress; 104080062Smsmith ACPI_PCI_ID PciId; 104180062Smsmith UINT16 PciRegister; 104269450Smsmith 104369450Smsmith 104469450Smsmith /* 104569450Smsmith * Must have a valid pointer to a GAS structure, and 104669450Smsmith * a non-zero address within 104769450Smsmith */ 104869450Smsmith if ((!Reg) || 104970243Smsmith (!ACPI_VALID_ADDRESS (Reg->Address))) 105069450Smsmith { 105169450Smsmith return; 105269450Smsmith } 105369450Smsmith 105469450Smsmith 105569450Smsmith /* 105669450Smsmith * Three address spaces supported: 105769450Smsmith * Memory, Io, or PCI config. 105869450Smsmith */ 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