hwregs.c revision 77424
167754Smsmith 267754Smsmith/******************************************************************************* 367754Smsmith * 467754Smsmith * Module Name: hwregs - Read/write access functions for the various ACPI 567754Smsmith * control and status registers. 677424Smsmith * $Revision: 97 $ 767754Smsmith * 867754Smsmith ******************************************************************************/ 967754Smsmith 1067754Smsmith/****************************************************************************** 1167754Smsmith * 1267754Smsmith * 1. Copyright Notice 1367754Smsmith * 1471867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 1570243Smsmith * All rights reserved. 1667754Smsmith * 1767754Smsmith * 2. License 1867754Smsmith * 1967754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 2067754Smsmith * rights. You may have additional license terms from the party that provided 2167754Smsmith * you this software, covering your right to use that party's intellectual 2267754Smsmith * property rights. 2367754Smsmith * 2467754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2567754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2667754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2767754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2867754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2967754Smsmith * Code in any form, with the right to sublicense such rights; and 3067754Smsmith * 3167754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3267754Smsmith * license (with the right to sublicense), under only those claims of Intel 3367754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3467754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3567754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3667754Smsmith * license, and in no event shall the patent license extend to any additions 3767754Smsmith * to or modifications of the Original Intel Code. No other license or right 3867754Smsmith * is granted directly or by implication, estoppel or otherwise; 3967754Smsmith * 4067754Smsmith * The above copyright and patent license is granted only if the following 4167754Smsmith * conditions are met: 4267754Smsmith * 4367754Smsmith * 3. Conditions 4467754Smsmith * 4567754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4667754Smsmith * Redistribution of source code of any substantial portion of the Covered 4767754Smsmith * Code or modification with rights to further distribute source must include 4867754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4967754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 5067754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 5167754Smsmith * contain a file documenting the changes Licensee made to create that Covered 5267754Smsmith * Code and the date of any change. Licensee must include in that file the 5367754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5467754Smsmith * must include a prominent statement that the modification is derived, 5567754Smsmith * directly or indirectly, from Original Intel Code. 5667754Smsmith * 5767754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5867754Smsmith * Redistribution of source code of any substantial portion of the Covered 5967754Smsmith * Code or modification without rights to further distribute source must 6067754Smsmith * include the following Disclaimer and Export Compliance provision in the 6167754Smsmith * documentation and/or other materials provided with distribution. In 6267754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6367754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6467754Smsmith * license from Licensee to its licensee is limited to the intellectual 6567754Smsmith * property embodied in the software Licensee provides to its licensee, and 6667754Smsmith * not to intellectual property embodied in modifications its licensee may 6767754Smsmith * make. 6867754Smsmith * 6967754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 7067754Smsmith * substantial portion of the Covered Code or modification must reproduce the 7167754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 7267754Smsmith * provision in the documentation and/or other materials provided with the 7367754Smsmith * distribution. 7467754Smsmith * 7567754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7667754Smsmith * Intel Code. 7767754Smsmith * 7867754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7967754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 8067754Smsmith * other dealings in products derived from or relating to the Covered Code 8167754Smsmith * without prior written authorization from Intel. 8267754Smsmith * 8367754Smsmith * 4. Disclaimer and Export Compliance 8467754Smsmith * 8567754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8667754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8767754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8867754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8967754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 9067754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 9167754Smsmith * PARTICULAR PURPOSE. 9267754Smsmith * 9367754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9467754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9567754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9667754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9767754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9867754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9967754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 10067754Smsmith * LIMITED REMEDY. 10167754Smsmith * 10267754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10367754Smsmith * software or system incorporating such software without first obtaining any 10467754Smsmith * required license or other approval from the U. S. Department of Commerce or 10567754Smsmith * any other agency or department of the United States Government. In the 10667754Smsmith * event Licensee exports any such software from the United States or 10767754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10867754Smsmith * ensure that the distribution and export/re-export of the software is in 10967754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 11067754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 11167754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 11267754Smsmith * software, or service, directly or indirectly, to any country for which the 11367754Smsmith * United States government or any agency thereof requires an export license, 11467754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11567754Smsmith * such license, approval or letter. 11667754Smsmith * 11767754Smsmith *****************************************************************************/ 11867754Smsmith 11967754Smsmith#define __HWREGS_C__ 12067754Smsmith 12167754Smsmith#include "acpi.h" 12267754Smsmith#include "achware.h" 12367754Smsmith#include "acnamesp.h" 12467754Smsmith 12577424Smsmith#define _COMPONENT ACPI_HARDWARE 12667754Smsmith MODULE_NAME ("hwregs") 12767754Smsmith 12867754Smsmith 12967754Smsmith/* This matches the #defines in actypes.h. */ 13067754Smsmith 13169450SmsmithNATIVE_CHAR *SleepStateTable[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_", 13271867Smsmith "\\_S4_","\\_S5_","\\_S4B"}; 13367754Smsmith 13467754Smsmith 13567754Smsmith/******************************************************************************* 13667754Smsmith * 13767754Smsmith * FUNCTION: AcpiHwGetBitShift 13867754Smsmith * 13967754Smsmith * PARAMETERS: Mask - Input mask to determine bit shift from. 14067754Smsmith * Must have at least 1 bit set. 14167754Smsmith * 14267754Smsmith * RETURN: Bit location of the lsb of the mask 14367754Smsmith * 14467754Smsmith * DESCRIPTION: Returns the bit number for the low order bit that's set. 14567754Smsmith * 14667754Smsmith ******************************************************************************/ 14767754Smsmith 14871867SmsmithUINT32 14967754SmsmithAcpiHwGetBitShift ( 15067754Smsmith UINT32 Mask) 15167754Smsmith{ 15267754Smsmith UINT32 Shift; 15367754Smsmith 15467754Smsmith 15567754Smsmith FUNCTION_TRACE ("HwGetBitShift"); 15667754Smsmith 15767754Smsmith 15867754Smsmith for (Shift = 0; ((Mask >> Shift) & 1) == 0; Shift++) 15967754Smsmith { ; } 16067754Smsmith 16167754Smsmith return_VALUE (Shift); 16267754Smsmith} 16367754Smsmith 16467754Smsmith 16567754Smsmith/******************************************************************************* 16667754Smsmith * 16767754Smsmith * FUNCTION: AcpiHwClearAcpiStatus 16867754Smsmith * 16967754Smsmith * PARAMETERS: none 17067754Smsmith * 17167754Smsmith * RETURN: none 17267754Smsmith * 17367754Smsmith * DESCRIPTION: Clears all fixed and general purpose status bits 17467754Smsmith * 17567754Smsmith ******************************************************************************/ 17667754Smsmith 17767754Smsmithvoid 17867754SmsmithAcpiHwClearAcpiStatus (void) 17967754Smsmith{ 18067754Smsmith UINT16 GpeLength; 18167754Smsmith UINT16 Index; 18267754Smsmith 18367754Smsmith 18467754Smsmith FUNCTION_TRACE ("HwClearAcpiStatus"); 18567754Smsmith 18667754Smsmith 18777424Smsmith DEBUG_PRINTP (TRACE_IO, ("About to write %04X to %04X\n", 18877424Smsmith ALL_FIXED_STS_BITS, 18977424Smsmith (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address))); 19067754Smsmith 19167754Smsmith 19277424Smsmith AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 19367754Smsmith 19469450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS); 19567754Smsmith 19669450Smsmith 19770243Smsmith if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address)) 19867754Smsmith { 19970243Smsmith AcpiOsOut16 ((ACPI_IO_ADDRESS) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address), 20077424Smsmith (UINT16) ALL_FIXED_STS_BITS); 20167754Smsmith } 20267754Smsmith 20367754Smsmith /* now clear the GPE Bits */ 20467754Smsmith 20569450Smsmith if (AcpiGbl_FADT->Gpe0BlkLen) 20667754Smsmith { 20769450Smsmith GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe0BlkLen); 20867754Smsmith 20967754Smsmith for (Index = 0; Index < GpeLength; Index++) 21067754Smsmith { 21177424Smsmith AcpiOsOut8 ((ACPI_IO_ADDRESS) ( 21277424Smsmith ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address) + Index), 21377424Smsmith (UINT8) 0xff); 21467754Smsmith } 21567754Smsmith } 21667754Smsmith 21769450Smsmith if (AcpiGbl_FADT->Gpe1BlkLen) 21867754Smsmith { 21969450Smsmith GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); 22067754Smsmith 22167754Smsmith for (Index = 0; Index < GpeLength; Index++) 22267754Smsmith { 22377424Smsmith AcpiOsOut8 ((ACPI_IO_ADDRESS) ( 22477424Smsmith ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address) + Index), 22577424Smsmith (UINT8) 0xff); 22667754Smsmith } 22767754Smsmith } 22867754Smsmith 22977424Smsmith AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 23067754Smsmith return_VOID; 23167754Smsmith} 23267754Smsmith 23367754Smsmith 23467754Smsmith/******************************************************************************* 23567754Smsmith * 23667754Smsmith * FUNCTION: AcpiHwObtainSleepTypeRegisterData 23767754Smsmith * 23867754Smsmith * PARAMETERS: SleepState - Numeric state requested 23967754Smsmith * *Slp_TypA - Pointer to byte to receive SLP_TYPa value 24067754Smsmith * *Slp_TypB - Pointer to byte to receive SLP_TYPb value 24167754Smsmith * 24267754Smsmith * RETURN: Status - ACPI status 24367754Smsmith * 24467754Smsmith * DESCRIPTION: AcpiHwObtainSleepTypeRegisterData() obtains the SLP_TYP and 24567754Smsmith * SLP_TYPb values for the sleep state requested. 24667754Smsmith * 24767754Smsmith ******************************************************************************/ 24867754Smsmith 24967754SmsmithACPI_STATUS 25067754SmsmithAcpiHwObtainSleepTypeRegisterData ( 25167754Smsmith UINT8 SleepState, 25267754Smsmith UINT8 *Slp_TypA, 25367754Smsmith UINT8 *Slp_TypB) 25467754Smsmith{ 25567754Smsmith ACPI_STATUS Status = AE_OK; 25667754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 25767754Smsmith 25867754Smsmith 25967754Smsmith FUNCTION_TRACE ("HwObtainSleepTypeRegisterData"); 26067754Smsmith 26167754Smsmith 26267754Smsmith /* 26367754Smsmith * Validate parameters 26467754Smsmith */ 26567754Smsmith 26667754Smsmith if ((SleepState > ACPI_S_STATES_MAX) || 26767754Smsmith !Slp_TypA || !Slp_TypB) 26867754Smsmith { 26967754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 27067754Smsmith } 27167754Smsmith 27267754Smsmith /* 27367754Smsmith * AcpiEvaluate the namespace object containing the values for this state 27467754Smsmith */ 27567754Smsmith 27667754Smsmith Status = AcpiNsEvaluateByName (SleepStateTable[SleepState], NULL, &ObjDesc); 27767754Smsmith if (ACPI_FAILURE (Status)) 27867754Smsmith { 27967754Smsmith return_ACPI_STATUS (Status); 28067754Smsmith } 28167754Smsmith 28267754Smsmith if (!ObjDesc) 28367754Smsmith { 28467754Smsmith REPORT_ERROR (("Missing Sleep State object\n")); 28567754Smsmith return_ACPI_STATUS (AE_NOT_EXIST); 28667754Smsmith } 28767754Smsmith 28867754Smsmith /* 28967754Smsmith * We got something, now ensure it is correct. The object must 29067754Smsmith * be a package and must have at least 2 numeric values as the 29167754Smsmith * two elements 29267754Smsmith */ 29367754Smsmith 29477424Smsmith /* Even though AcpiEvaluateObject resolves package references, 29577424Smsmith * NsEvaluate dpesn't. So, we do it here. 29677424Smsmith */ 29777424Smsmith Status = AcpiUtResolvePackageReferences(ObjDesc); 29867754Smsmith 29967754Smsmith if (ObjDesc->Package.Count < 2) 30067754Smsmith { 30167754Smsmith /* Must have at least two elements */ 30267754Smsmith 30367754Smsmith REPORT_ERROR (("Sleep State package does not have at least two elements\n")); 30467754Smsmith Status = AE_ERROR; 30567754Smsmith } 30667754Smsmith 30767754Smsmith else if (((ObjDesc->Package.Elements[0])->Common.Type != 30871867Smsmith ACPI_TYPE_INTEGER) || 30967754Smsmith ((ObjDesc->Package.Elements[1])->Common.Type != 31071867Smsmith ACPI_TYPE_INTEGER)) 31167754Smsmith { 31267754Smsmith /* Must have two */ 31367754Smsmith 31467754Smsmith REPORT_ERROR (("Sleep State package elements are not both of type Number\n")); 31567754Smsmith Status = AE_ERROR; 31667754Smsmith } 31767754Smsmith 31867754Smsmith else 31967754Smsmith { 32067754Smsmith /* 32167754Smsmith * Valid _Sx_ package size, type, and value 32267754Smsmith */ 32371867Smsmith *Slp_TypA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value; 32467754Smsmith 32571867Smsmith *Slp_TypB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.Value; 32667754Smsmith } 32767754Smsmith 32867754Smsmith 32967754Smsmith if (ACPI_FAILURE (Status)) 33067754Smsmith { 33177424Smsmith DEBUG_PRINTP (ACPI_ERROR, ("Bad Sleep object %p type %X\n", 33267754Smsmith ObjDesc, ObjDesc->Common.Type)); 33367754Smsmith } 33467754Smsmith 33577424Smsmith AcpiUtRemoveReference (ObjDesc); 33667754Smsmith 33767754Smsmith return_ACPI_STATUS (Status); 33867754Smsmith} 33967754Smsmith 34067754Smsmith 34167754Smsmith/******************************************************************************* 34267754Smsmith * 34369450Smsmith * FUNCTION: AcpiHwRegisterBitAccess 34467754Smsmith * 34567754Smsmith * PARAMETERS: ReadWrite - Either ACPI_READ or ACPI_WRITE. 34667754Smsmith * UseLock - Lock the hardware 34769450Smsmith * RegisterId - index of ACPI Register to access 34867754Smsmith * Value - (only used on write) value to write to the 34969450Smsmith * Register. Shifted all the way right. 35067754Smsmith * 35169450Smsmith * RETURN: Value written to or read from specified Register. This value 35267754Smsmith * is shifted all the way right. 35367754Smsmith * 35469450Smsmith * DESCRIPTION: Generic ACPI Register read/write function. 35567754Smsmith * 35667754Smsmith ******************************************************************************/ 35767754Smsmith 35867754SmsmithUINT32 35969450SmsmithAcpiHwRegisterBitAccess ( 36067754Smsmith NATIVE_UINT ReadWrite, 36167754Smsmith BOOLEAN UseLock, 36267754Smsmith UINT32 RegisterId, 36367754Smsmith ...) /* Value (only used on write) */ 36467754Smsmith{ 36567754Smsmith UINT32 RegisterValue = 0; 36667754Smsmith UINT32 Mask = 0; 36767754Smsmith UINT32 Value = 0; 36877424Smsmith va_list marker; 36967754Smsmith 37077424Smsmith 37169450Smsmith FUNCTION_TRACE ("HwRegisterBitAccess"); 37267754Smsmith 37367754Smsmith 37467754Smsmith if (ReadWrite == ACPI_WRITE) 37567754Smsmith { 37667754Smsmith va_start (marker, RegisterId); 37767754Smsmith Value = va_arg (marker, UINT32); 37867754Smsmith va_end (marker); 37967754Smsmith } 38067754Smsmith 38177424Smsmith if (ACPI_MTX_LOCK == UseLock) 38277424Smsmith { 38377424Smsmith AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 38469450Smsmith } 38567754Smsmith 38667754Smsmith /* 38767754Smsmith * Decode the Register ID 38877424Smsmith * Register id = Register block id | bit id 38969450Smsmith * 39069450Smsmith * Check bit id to fine locate Register offset. 39177424Smsmith * Check Mask to determine Register offset, and then read-write. 39267754Smsmith */ 39367754Smsmith 39477424Smsmith switch (REGISTER_BLOCK_ID (RegisterId)) 39567754Smsmith { 39669450Smsmith case PM1_STS: 39767754Smsmith 39869450Smsmith switch (RegisterId) 39967754Smsmith { 40069450Smsmith case TMR_STS: 40169450Smsmith Mask = TMR_STS_MASK; 40269450Smsmith break; 40367754Smsmith 40469450Smsmith case BM_STS: 40569450Smsmith Mask = BM_STS_MASK; 40669450Smsmith break; 40767754Smsmith 40869450Smsmith case GBL_STS: 40969450Smsmith Mask = GBL_STS_MASK; 41069450Smsmith break; 41167754Smsmith 41269450Smsmith case PWRBTN_STS: 41369450Smsmith Mask = PWRBTN_STS_MASK; 41469450Smsmith break; 41567754Smsmith 41669450Smsmith case SLPBTN_STS: 41769450Smsmith Mask = SLPBTN_STS_MASK; 41869450Smsmith break; 41967754Smsmith 42069450Smsmith case RTC_STS: 42169450Smsmith Mask = RTC_STS_MASK; 42269450Smsmith break; 42367754Smsmith 42469450Smsmith case WAK_STS: 42569450Smsmith Mask = WAK_STS_MASK; 42669450Smsmith break; 42767754Smsmith 42869450Smsmith default: 42969450Smsmith Mask = 0; 43069450Smsmith break; 43169450Smsmith } 43267754Smsmith 43369450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_STS); 43467754Smsmith 43569450Smsmith if (ReadWrite == ACPI_WRITE) 43669450Smsmith { 43769450Smsmith /* 43869450Smsmith * Status Registers are different from the rest. Clear by 43969450Smsmith * writing 1, writing 0 has no effect. So, the only relevent 44069450Smsmith * information is the single bit we're interested in, all 44169450Smsmith * others should be written as 0 so they will be left 44269450Smsmith * unchanged 44369450Smsmith */ 44467754Smsmith 44569450Smsmith Value <<= AcpiHwGetBitShift (Mask); 44669450Smsmith Value &= Mask; 44767754Smsmith 44869450Smsmith if (Value) 44967754Smsmith { 45077424Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, 45177424Smsmith (UINT16) Value); 45269450Smsmith RegisterValue = 0; 45367754Smsmith } 45467754Smsmith } 45567754Smsmith 45669450Smsmith break; 45767754Smsmith 45867754Smsmith 45969450Smsmith case PM1_EN: 46067754Smsmith 46169450Smsmith switch (RegisterId) 46269450Smsmith { 46369450Smsmith case TMR_EN: 46469450Smsmith Mask = TMR_EN_MASK; 46569450Smsmith break; 46667754Smsmith 46769450Smsmith case GBL_EN: 46869450Smsmith Mask = GBL_EN_MASK; 46969450Smsmith break; 47067754Smsmith 47169450Smsmith case PWRBTN_EN: 47269450Smsmith Mask = PWRBTN_EN_MASK; 47369450Smsmith break; 47467754Smsmith 47569450Smsmith case SLPBTN_EN: 47669450Smsmith Mask = SLPBTN_EN_MASK; 47769450Smsmith break; 47867754Smsmith 47969450Smsmith case RTC_EN: 48069450Smsmith Mask = RTC_EN_MASK; 48169450Smsmith break; 48267754Smsmith 48369450Smsmith default: 48469450Smsmith Mask = 0; 48569450Smsmith break; 48669450Smsmith } 48767754Smsmith 48869450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_EN); 48967754Smsmith 49069450Smsmith if (ReadWrite == ACPI_WRITE) 49169450Smsmith { 49269450Smsmith RegisterValue &= ~Mask; 49369450Smsmith Value <<= AcpiHwGetBitShift (Mask); 49469450Smsmith Value &= Mask; 49569450Smsmith RegisterValue |= Value; 49667754Smsmith 49769450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (UINT16) RegisterValue); 49869450Smsmith } 49967754Smsmith 50067754Smsmith break; 50167754Smsmith 50267754Smsmith 50367754Smsmith case PM1_CONTROL: 50467754Smsmith 50567754Smsmith switch (RegisterId) 50667754Smsmith { 50767754Smsmith case SCI_EN: 50867754Smsmith Mask = SCI_EN_MASK; 50967754Smsmith break; 51067754Smsmith 51167754Smsmith case BM_RLD: 51267754Smsmith Mask = BM_RLD_MASK; 51367754Smsmith break; 51467754Smsmith 51567754Smsmith case GBL_RLS: 51667754Smsmith Mask = GBL_RLS_MASK; 51767754Smsmith break; 51867754Smsmith 51967754Smsmith case SLP_TYPE_A: 52067754Smsmith case SLP_TYPE_B: 52167754Smsmith Mask = SLP_TYPE_X_MASK; 52267754Smsmith break; 52367754Smsmith 52467754Smsmith case SLP_EN: 52567754Smsmith Mask = SLP_EN_MASK; 52667754Smsmith break; 52767754Smsmith 52867754Smsmith default: 52967754Smsmith Mask = 0; 53067754Smsmith break; 53167754Smsmith } 53267754Smsmith 53369450Smsmith 53469450Smsmith /* 53569450Smsmith * Read the PM1 Control register. 53669450Smsmith * Note that at this level, the fact that there are actually TWO 53769450Smsmith * registers (A and B) and that B may not exist, are abstracted. 53869450Smsmith */ 53969450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL); 54069450Smsmith 54169746Smsmith DEBUG_PRINT (TRACE_IO, ("PM1 control: Read %X\n", RegisterValue)); 54269450Smsmith 54367754Smsmith if (ReadWrite == ACPI_WRITE) 54467754Smsmith { 54567754Smsmith RegisterValue &= ~Mask; 54667754Smsmith Value <<= AcpiHwGetBitShift (Mask); 54767754Smsmith Value &= Mask; 54867754Smsmith RegisterValue |= Value; 54967754Smsmith 55067754Smsmith /* 55169450Smsmith * SLP_TYPE_x Registers are written differently 55269450Smsmith * than any other control Registers with 55369450Smsmith * respect to A and B Registers. The value 55467754Smsmith * for A may be different than the value for B 55569746Smsmith * 55669746Smsmith * Therefore, pass the RegisterId, not just generic PM1_CONTROL, 55769746Smsmith * because we need to do different things. Yuck. 55867754Smsmith */ 55967754Smsmith 56077424Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId, 56177424Smsmith (UINT16) RegisterValue); 56267754Smsmith } 56367754Smsmith break; 56467754Smsmith 56567754Smsmith 56667754Smsmith case PM2_CONTROL: 56767754Smsmith 56867754Smsmith switch (RegisterId) 56967754Smsmith { 57067754Smsmith case ARB_DIS: 57167754Smsmith Mask = ARB_DIS_MASK; 57267754Smsmith break; 57367754Smsmith 57467754Smsmith default: 57567754Smsmith Mask = 0; 57667754Smsmith break; 57767754Smsmith } 57867754Smsmith 57969450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); 58069450Smsmith 58169746Smsmith DEBUG_PRINT (TRACE_IO, ("PM2 control: Read %X from %p\n", 58277424Smsmith RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address))); 58369450Smsmith 58467754Smsmith if (ReadWrite == ACPI_WRITE) 58567754Smsmith { 58667754Smsmith RegisterValue &= ~Mask; 58767754Smsmith Value <<= AcpiHwGetBitShift (Mask); 58867754Smsmith Value &= Mask; 58967754Smsmith RegisterValue |= Value; 59067754Smsmith 59177424Smsmith DEBUG_PRINT (TRACE_IO, ("About to write %04X to %p\n", RegisterValue, 59269450Smsmith AcpiGbl_FADT->XPm2CntBlk.Address)); 59367754Smsmith 59469450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 59569450Smsmith PM2_CONTROL, (UINT8) (RegisterValue)); 59667754Smsmith } 59767754Smsmith break; 59867754Smsmith 59967754Smsmith 60067754Smsmith case PM_TIMER: 60167754Smsmith 60269450Smsmith Mask = TMR_VAL_MASK; 60369450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 60469450Smsmith PM_TIMER); 60569746Smsmith DEBUG_PRINT (TRACE_IO, ("PM_TIMER: Read %X from %p\n", 60677424Smsmith RegisterValue, ACPI_GET_ADDRESS (AcpiGbl_FADT->XPmTmrBlk.Address))); 60767754Smsmith 60867754Smsmith break; 60967754Smsmith 61067754Smsmith 61167754Smsmith case GPE1_EN_BLOCK: 61267754Smsmith case GPE1_STS_BLOCK: 61367754Smsmith case GPE0_EN_BLOCK: 61467754Smsmith case GPE0_STS_BLOCK: 61567754Smsmith 61669450Smsmith /* Determine the bit to be accessed 61769450Smsmith * 61869450Smsmith * (UINT32) RegisterId: 61969450Smsmith * 31 24 16 8 0 62069450Smsmith * +--------+--------+--------+--------+ 62169450Smsmith * | gpe_block_id | gpe_bit_number | 62269450Smsmith * +--------+--------+--------+--------+ 62369450Smsmith * 62469450Smsmith * gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK 62569450Smsmith * gpe_bit_number is relative from the gpe_block (0x00~0xFF) 62669450Smsmith */ 62767754Smsmith 62869450Smsmith Mask = REGISTER_BIT_ID(RegisterId); /* gpe_bit_number */ 62969450Smsmith RegisterId = REGISTER_BLOCK_ID(RegisterId) | (Mask >> 3); 63069450Smsmith Mask = AcpiGbl_DecodeTo8bit [Mask % 8]; 63167754Smsmith 63267754Smsmith /* 63367754Smsmith * The base address of the GPE 0 Register Block 63467754Smsmith * Plus 1/2 the length of the GPE 0 Register Block 63569450Smsmith * The enable Register is the Register following the Status Register 63669450Smsmith * and each Register is defined as 1/2 of the total Register Block 63767754Smsmith */ 63867754Smsmith 63967754Smsmith /* 64067754Smsmith * This sets the bit within EnableBit that needs to be written to 64169450Smsmith * the Register indicated in Mask to a 1, all others are 0 64267754Smsmith */ 64367754Smsmith 64467754Smsmith /* Now get the current Enable Bits in the selected Reg */ 64567754Smsmith 64669450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId); 64769746Smsmith DEBUG_PRINT (TRACE_IO, ("GPE Enable bits: Read %X from %X\n", 64877424Smsmith RegisterValue, RegisterId)); 64967754Smsmith 65067754Smsmith if (ReadWrite == ACPI_WRITE) 65167754Smsmith { 65267754Smsmith RegisterValue &= ~Mask; 65367754Smsmith Value <<= AcpiHwGetBitShift (Mask); 65467754Smsmith Value &= Mask; 65567754Smsmith RegisterValue |= Value; 65667754Smsmith 65767754Smsmith /* This write will put the Action state into the General Purpose */ 65867754Smsmith /* Enable Register indexed by the value in Mask */ 65967754Smsmith 66067754Smsmith DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n", 66177424Smsmith RegisterValue, RegisterId)); 66277424Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId, 66377424Smsmith (UINT8) RegisterValue); 66477424Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 66577424Smsmith RegisterId); 66667754Smsmith } 66767754Smsmith break; 66867754Smsmith 66967754Smsmith 67069450Smsmith case SMI_CMD_BLOCK: 67167754Smsmith case PROCESSOR_BLOCK: 67277424Smsmith /* Not used by any callers at this time - therefore, not implemented */ 67377424Smsmith 67467754Smsmith default: 67567754Smsmith 67667754Smsmith Mask = 0; 67767754Smsmith break; 67867754Smsmith } 67967754Smsmith 68069450Smsmith if (ACPI_MTX_LOCK == UseLock) { 68177424Smsmith AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 68269450Smsmith } 68367754Smsmith 68469450Smsmith 68567754Smsmith RegisterValue &= Mask; 68667754Smsmith RegisterValue >>= AcpiHwGetBitShift (Mask); 68767754Smsmith 68869746Smsmith DEBUG_PRINT (TRACE_IO, ("Register I/O: returning %X\n", RegisterValue)); 68967754Smsmith return_VALUE (RegisterValue); 69067754Smsmith} 69169450Smsmith 69269450Smsmith 69369450Smsmith/****************************************************************************** 69469450Smsmith * 69569450Smsmith * FUNCTION: AcpiHwRegisterRead 69669450Smsmith * 69769450Smsmith * PARAMETERS: UseLock - Mutex hw access. 69869450Smsmith * RegisterId - RegisterID + Offset. 69969450Smsmith * 70069450Smsmith * RETURN: Value read or written. 70169450Smsmith * 70269450Smsmith * DESCRIPTION: Acpi register read function. Registers are read at the 70369450Smsmith * given offset. 70469450Smsmith * 70569450Smsmith ******************************************************************************/ 70669450Smsmith 70769450SmsmithUINT32 70869450SmsmithAcpiHwRegisterRead ( 70969450Smsmith BOOLEAN UseLock, 71069450Smsmith UINT32 RegisterId) 71169450Smsmith{ 71269450Smsmith UINT32 Value = 0; 71369450Smsmith UINT32 BankOffset; 71469450Smsmith 71577424Smsmith 71669450Smsmith FUNCTION_TRACE ("AcpiHwRegisterRead"); 71769450Smsmith 71877424Smsmith 71969450Smsmith if (ACPI_MTX_LOCK == UseLock) 72069450Smsmith { 72177424Smsmith AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 72269450Smsmith } 72369450Smsmith 72469450Smsmith 72569450Smsmith switch (REGISTER_BLOCK_ID(RegisterId)) 72669450Smsmith { 72769450Smsmith case PM1_STS: /* 16-bit access */ 72869450Smsmith 72969746Smsmith Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, 0); 73069746Smsmith Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, 0); 73169450Smsmith break; 73269450Smsmith 73369450Smsmith 73469450Smsmith case PM1_EN: /* 16-bit access*/ 73569450Smsmith 73669450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen); 73769746Smsmith Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset); 73869746Smsmith Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset); 73969450Smsmith break; 74069450Smsmith 74169450Smsmith 74269450Smsmith case PM1_CONTROL: /* 16-bit access */ 74369450Smsmith 74471867Smsmith Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aCntBlk, 0); 74571867Smsmith Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bCntBlk, 0); 74669450Smsmith break; 74769450Smsmith 74869450Smsmith 74969450Smsmith case PM2_CONTROL: /* 8-bit access */ 75069450Smsmith 75169746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XPm2CntBlk, 0); 75269450Smsmith break; 75369450Smsmith 75469450Smsmith 75569450Smsmith case PM_TIMER: /* 32-bit access */ 75669450Smsmith 75769746Smsmith Value = AcpiHwLowLevelRead (32, &AcpiGbl_FADT->XPmTmrBlk, 0); 75869450Smsmith break; 75969450Smsmith 76069450Smsmith 76169450Smsmith case GPE0_STS_BLOCK: /* 8-bit access */ 76269450Smsmith 76369746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, 0); 76469450Smsmith break; 76569450Smsmith 76669450Smsmith 76769450Smsmith case GPE0_EN_BLOCK: /* 8-bit access */ 76869450Smsmith 76969450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen); 77069746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset); 77169450Smsmith break; 77269450Smsmith 77369450Smsmith 77469450Smsmith case GPE1_STS_BLOCK: /* 8-bit access */ 77569450Smsmith 77669746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, 0); 77769450Smsmith break; 77869450Smsmith 77969450Smsmith 78069450Smsmith case GPE1_EN_BLOCK: /* 8-bit access */ 78169450Smsmith 78269450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); 78369746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset); 78469450Smsmith break; 78569450Smsmith 78669450Smsmith 78769450Smsmith case SMI_CMD_BLOCK: /* 8bit */ 78869450Smsmith 78969450Smsmith Value = (UINT32) AcpiOsIn8 (AcpiGbl_FADT->SmiCmd); 79069450Smsmith break; 79169450Smsmith 79269450Smsmith 79369450Smsmith default: 79469450Smsmith Value = 0; 79569450Smsmith break; 79669450Smsmith } 79769450Smsmith 79869450Smsmith 79969450Smsmith if (ACPI_MTX_LOCK == UseLock) 80069450Smsmith { 80177424Smsmith AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 80269450Smsmith } 80369450Smsmith 80469450Smsmith return_VALUE (Value); 80569450Smsmith} 80669450Smsmith 80769450Smsmith 80869450Smsmith/****************************************************************************** 80969450Smsmith * 81069450Smsmith * FUNCTION: AcpiHwRegisterWrite 81169450Smsmith * 81269450Smsmith * PARAMETERS: UseLock - Mutex hw access. 81369450Smsmith * RegisterId - RegisterID + Offset. 81469450Smsmith * 81569450Smsmith * RETURN: Value read or written. 81669450Smsmith * 81769450Smsmith * DESCRIPTION: Acpi register Write function. Registers are written at the 81869450Smsmith * given offset. 81969450Smsmith * 82069450Smsmith ******************************************************************************/ 82169450Smsmith 82269450Smsmithvoid 82369450SmsmithAcpiHwRegisterWrite ( 82469450Smsmith BOOLEAN UseLock, 82569450Smsmith UINT32 RegisterId, 82669450Smsmith UINT32 Value) 82769450Smsmith{ 82869450Smsmith UINT32 BankOffset; 82969450Smsmith 83069450Smsmith FUNCTION_TRACE ("AcpiHwRegisterWrite"); 83169450Smsmith 83269450Smsmith 83369450Smsmith if (ACPI_MTX_LOCK == UseLock) 83469450Smsmith { 83577424Smsmith AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 83669450Smsmith } 83769450Smsmith 83869450Smsmith 83969450Smsmith switch (REGISTER_BLOCK_ID (RegisterId)) 84069450Smsmith { 84169450Smsmith case PM1_STS: /* 16-bit access */ 84269450Smsmith 84369746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, 0); 84469746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, 0); 84569450Smsmith break; 84669450Smsmith 84769450Smsmith 84869450Smsmith case PM1_EN: /* 16-bit access*/ 84969450Smsmith 85069450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen); 85169746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset); 85269746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset); 85369450Smsmith break; 85469450Smsmith 85569450Smsmith 85669450Smsmith case PM1_CONTROL: /* 16-bit access */ 85769450Smsmith 85871867Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0); 85971867Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0); 86071867Smsmith break; 86169450Smsmith 86269450Smsmith 86371867Smsmith case PM1A_CONTROL: /* 16-bit access */ 86469450Smsmith 86571867Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0); 86669450Smsmith break; 86769450Smsmith 86869450Smsmith 86971867Smsmith case PM1B_CONTROL: /* 16-bit access */ 87071867Smsmith 87171867Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0); 87271867Smsmith break; 87371867Smsmith 87471867Smsmith 87569450Smsmith case PM2_CONTROL: /* 8-bit access */ 87669450Smsmith 87769746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, 0); 87869450Smsmith break; 87969450Smsmith 88069450Smsmith 88169450Smsmith case PM_TIMER: /* 32-bit access */ 88269450Smsmith 88369746Smsmith AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, 0); 88469450Smsmith break; 88569450Smsmith 88669450Smsmith 88769450Smsmith case GPE0_STS_BLOCK: /* 8-bit access */ 88869450Smsmith 88969746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, 0); 89069450Smsmith break; 89169450Smsmith 89269450Smsmith 89369450Smsmith case GPE0_EN_BLOCK: /* 8-bit access */ 89469450Smsmith 89569450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen); 89669746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset); 89769450Smsmith break; 89869450Smsmith 89969450Smsmith 90069450Smsmith case GPE1_STS_BLOCK: /* 8-bit access */ 90169450Smsmith 90269746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, 0); 90369450Smsmith break; 90469450Smsmith 90569450Smsmith 90669450Smsmith case GPE1_EN_BLOCK: /* 8-bit access */ 90769450Smsmith 90869450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); 90969746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset); 91069450Smsmith break; 91169450Smsmith 91269450Smsmith 91369450Smsmith case SMI_CMD_BLOCK: /* 8bit */ 91469450Smsmith 91569450Smsmith /* For 2.0, SMI_CMD is always in IO space */ 91669450Smsmith /* TBD: what about 1.0? 0.71? */ 91769450Smsmith 91877424Smsmith AcpiOsOut8 (AcpiGbl_FADT->SmiCmd, (UINT8) Value); 91969450Smsmith break; 92069450Smsmith 92169450Smsmith 92269450Smsmith default: 92369450Smsmith Value = 0; 92469450Smsmith break; 92569450Smsmith } 92669450Smsmith 92769450Smsmith 92869450Smsmith if (ACPI_MTX_LOCK == UseLock) 92969450Smsmith { 93077424Smsmith AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 93169450Smsmith } 93269450Smsmith 93369450Smsmith return_VOID; 93469450Smsmith} 93569450Smsmith 93669450Smsmith 93769450Smsmith/****************************************************************************** 93869450Smsmith * 93969450Smsmith * FUNCTION: AcpiHwLowLevelRead 94069450Smsmith * 94169450Smsmith * PARAMETERS: Register - GAS register structure 94269450Smsmith * Offset - Offset from the base address in the GAS 94369450Smsmith * Width - 8, 16, or 32 94469450Smsmith * 94569450Smsmith * RETURN: Value read 94669450Smsmith * 94769450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space. 94869450Smsmith * 94969450Smsmith ******************************************************************************/ 95069450Smsmith 95169450SmsmithUINT32 95269450SmsmithAcpiHwLowLevelRead ( 95369450Smsmith UINT32 Width, 95477424Smsmith ACPI_GENERIC_ADDRESS *Reg, 95569450Smsmith UINT32 Offset) 95669450Smsmith{ 95769450Smsmith UINT32 Value = 0; 95869450Smsmith ACPI_PHYSICAL_ADDRESS MemAddress; 95969450Smsmith ACPI_IO_ADDRESS IoAddress; 96069450Smsmith UINT32 PciRegister; 96169450Smsmith UINT32 PciDevFunc; 96269450Smsmith 96369450Smsmith 96469450Smsmith /* 96569450Smsmith * Must have a valid pointer to a GAS structure, and 96669450Smsmith * a non-zero address within 96769450Smsmith */ 96869450Smsmith if ((!Reg) || 96970243Smsmith (!ACPI_VALID_ADDRESS (Reg->Address))) 97069450Smsmith { 97169450Smsmith return 0; 97269450Smsmith } 97369450Smsmith 97469450Smsmith 97569450Smsmith /* 97669450Smsmith * Three address spaces supported: 97769450Smsmith * Memory, Io, or PCI config. 97869450Smsmith */ 97969450Smsmith 98069450Smsmith switch (Reg->AddressSpaceId) 98169450Smsmith { 98277424Smsmith case ACPI_ADR_SPACE_SYSTEM_MEMORY: 98369450Smsmith 98470243Smsmith MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 98569450Smsmith 98669450Smsmith switch (Width) 98769450Smsmith { 98869450Smsmith case 8: 98969450Smsmith Value = AcpiOsMemIn8 (MemAddress); 99069450Smsmith break; 99169450Smsmith case 16: 99269450Smsmith Value = AcpiOsMemIn16 (MemAddress); 99369450Smsmith break; 99469450Smsmith case 32: 99569450Smsmith Value = AcpiOsMemIn32 (MemAddress); 99669450Smsmith break; 99769450Smsmith } 99869450Smsmith break; 99969450Smsmith 100069450Smsmith 100177424Smsmith case ACPI_ADR_SPACE_SYSTEM_IO: 100269450Smsmith 100370243Smsmith IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 100469450Smsmith 100569450Smsmith switch (Width) 100669450Smsmith { 100769450Smsmith case 8: 100869450Smsmith Value = AcpiOsIn8 (IoAddress); 100969450Smsmith break; 101069450Smsmith case 16: 101169450Smsmith Value = AcpiOsIn16 (IoAddress); 101269450Smsmith break; 101369450Smsmith case 32: 101469450Smsmith Value = AcpiOsIn32 (IoAddress); 101569450Smsmith break; 101669450Smsmith } 101769450Smsmith break; 101869450Smsmith 101969450Smsmith 102077424Smsmith case ACPI_ADR_SPACE_PCI_CONFIG: 102169450Smsmith 102270243Smsmith PciDevFunc = ACPI_PCI_DEVFUN (ACPI_GET_ADDRESS (Reg->Address)); 102370243Smsmith PciRegister = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset; 102469450Smsmith 102569450Smsmith switch (Width) 102669450Smsmith { 102769450Smsmith case 8: 102869450Smsmith AcpiOsReadPciCfgByte (0, PciDevFunc, PciRegister, (UINT8 *) &Value); 102969450Smsmith break; 103069450Smsmith case 16: 103169450Smsmith AcpiOsReadPciCfgWord (0, PciDevFunc, PciRegister, (UINT16 *) &Value); 103269450Smsmith break; 103369450Smsmith case 32: 103469450Smsmith AcpiOsReadPciCfgDword (0, PciDevFunc, PciRegister, (UINT32 *) &Value); 103569450Smsmith break; 103669450Smsmith } 103769450Smsmith break; 103869450Smsmith } 103969450Smsmith 104069450Smsmith return Value; 104169450Smsmith} 104269450Smsmith 104369450Smsmith 104469450Smsmith/****************************************************************************** 104569450Smsmith * 104669450Smsmith * FUNCTION: AcpiHwLowLevelWrite 104769450Smsmith * 104869450Smsmith * PARAMETERS: Width - 8, 16, or 32 104969450Smsmith * Value - To be written 105069450Smsmith * Register - GAS register structure 105169450Smsmith * Offset - Offset from the base address in the GAS 105269450Smsmith * 105369450Smsmith * 105469450Smsmith * RETURN: Value read 105569450Smsmith * 105669450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space. 105769450Smsmith * 105869450Smsmith ******************************************************************************/ 105969450Smsmith 106069450Smsmithvoid 106169450SmsmithAcpiHwLowLevelWrite ( 106269450Smsmith UINT32 Width, 106369450Smsmith UINT32 Value, 106477424Smsmith ACPI_GENERIC_ADDRESS *Reg, 106569450Smsmith UINT32 Offset) 106669450Smsmith{ 106769450Smsmith ACPI_PHYSICAL_ADDRESS MemAddress; 106869450Smsmith ACPI_IO_ADDRESS IoAddress; 106969450Smsmith UINT32 PciRegister; 107069450Smsmith UINT32 PciDevFunc; 107169450Smsmith 107269450Smsmith 107369450Smsmith /* 107469450Smsmith * Must have a valid pointer to a GAS structure, and 107569450Smsmith * a non-zero address within 107669450Smsmith */ 107769450Smsmith if ((!Reg) || 107870243Smsmith (!ACPI_VALID_ADDRESS (Reg->Address))) 107969450Smsmith { 108069450Smsmith return; 108169450Smsmith } 108269450Smsmith 108369450Smsmith 108469450Smsmith /* 108569450Smsmith * Three address spaces supported: 108669450Smsmith * Memory, Io, or PCI config. 108769450Smsmith */ 108869450Smsmith 108969450Smsmith switch (Reg->AddressSpaceId) 109069450Smsmith { 109177424Smsmith case ACPI_ADR_SPACE_SYSTEM_MEMORY: 109269450Smsmith 109370243Smsmith MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 109469450Smsmith 109569450Smsmith switch (Width) 109669450Smsmith { 109769450Smsmith case 8: 109869450Smsmith AcpiOsMemOut8 (MemAddress, (UINT8) Value); 109969450Smsmith break; 110069450Smsmith case 16: 110169450Smsmith AcpiOsMemOut16 (MemAddress, (UINT16) Value); 110269450Smsmith break; 110369450Smsmith case 32: 110469450Smsmith AcpiOsMemOut32 (MemAddress, (UINT32) Value); 110569450Smsmith break; 110669450Smsmith } 110769450Smsmith break; 110869450Smsmith 110969450Smsmith 111077424Smsmith case ACPI_ADR_SPACE_SYSTEM_IO: 111169450Smsmith 111270243Smsmith IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 111369450Smsmith 111469450Smsmith switch (Width) 111569450Smsmith { 111669450Smsmith case 8: 111769450Smsmith AcpiOsOut8 (IoAddress, (UINT8) Value); 111869450Smsmith break; 111969450Smsmith case 16: 112069450Smsmith AcpiOsOut16 (IoAddress, (UINT16) Value); 112169450Smsmith break; 112269450Smsmith case 32: 112369450Smsmith AcpiOsOut32 (IoAddress, (UINT32) Value); 112469450Smsmith break; 112569450Smsmith } 112669450Smsmith break; 112769450Smsmith 112869450Smsmith 112977424Smsmith case ACPI_ADR_SPACE_PCI_CONFIG: 113069450Smsmith 113170243Smsmith PciDevFunc = ACPI_PCI_DEVFUN (ACPI_GET_ADDRESS (Reg->Address)); 113270243Smsmith PciRegister = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset; 113369450Smsmith 113469450Smsmith switch (Width) 113569450Smsmith { 113669450Smsmith case 8: 113769450Smsmith AcpiOsWritePciCfgByte (0, PciDevFunc, PciRegister, (UINT8) Value); 113869450Smsmith break; 113969450Smsmith case 16: 114069450Smsmith AcpiOsWritePciCfgWord (0, PciDevFunc, PciRegister, (UINT16) Value); 114169450Smsmith break; 114269450Smsmith case 32: 114369450Smsmith AcpiOsWritePciCfgDword (0, PciDevFunc, PciRegister, (UINT32) Value); 114469450Smsmith break; 114569450Smsmith } 114669450Smsmith break; 114769450Smsmith } 114869450Smsmith} 1149