hwregs.c revision 69746
167754Smsmith 267754Smsmith/******************************************************************************* 367754Smsmith * 467754Smsmith * Module Name: hwregs - Read/write access functions for the various ACPI 567754Smsmith * control and status registers. 669746Smsmith * $Revision: 84 $ 767754Smsmith * 867754Smsmith ******************************************************************************/ 967754Smsmith 1067754Smsmith/****************************************************************************** 1167754Smsmith * 1267754Smsmith * 1. Copyright Notice 1367754Smsmith * 1467754Smsmith * Some or all of this work - Copyright (c) 1999, Intel Corp. All rights 1567754Smsmith * 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 12567754Smsmith#define _COMPONENT HARDWARE 12667754Smsmith MODULE_NAME ("hwregs") 12767754Smsmith 12867754Smsmith 12967754Smsmith/* This matches the #defines in actypes.h. */ 13067754Smsmith 13169450SmsmithNATIVE_CHAR *SleepStateTable[] = {"\\_S0_","\\_S1_","\\_S2_","\\_S3_", 13269450Smsmith "\\_S4_","\\_S4B","\\_S5_"}; 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 14869450Smsmithstatic UINT32 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 18767754Smsmith DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n", 18869450Smsmith ALL_FIXED_STS_BITS, 18969450Smsmith (UINT16) AcpiGbl_FADT->XPm1aEvtBlk.Address)); 19067754Smsmith 19167754Smsmith 19267754Smsmith AcpiCmAcquireMutex (ACPI_MTX_HARDWARE); 19367754Smsmith 19469450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS); 19567754Smsmith 19669450Smsmith 19769450Smsmith if (AcpiGbl_FADT->XPm1bEvtBlk.Address) 19867754Smsmith { 19969450Smsmith AcpiOsOut16 ((ACPI_IO_ADDRESS) AcpiGbl_FADT->XPm1bEvtBlk.Address, 20067754Smsmith (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 { 21169450Smsmith AcpiOsOut8 ((ACPI_IO_ADDRESS) (AcpiGbl_FADT->XGpe0Blk.Address + Index), 21269450Smsmith (UINT8) 0xff); 21367754Smsmith } 21467754Smsmith } 21567754Smsmith 21669450Smsmith if (AcpiGbl_FADT->Gpe1BlkLen) 21767754Smsmith { 21869450Smsmith GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); 21967754Smsmith 22067754Smsmith for (Index = 0; Index < GpeLength; Index++) 22167754Smsmith { 22269450Smsmith AcpiOsOut8 ((ACPI_IO_ADDRESS) (AcpiGbl_FADT->XGpe1Blk.Address + Index), 22369450Smsmith (UINT8) 0xff); 22467754Smsmith } 22567754Smsmith } 22667754Smsmith 22767754Smsmith AcpiCmReleaseMutex (ACPI_MTX_HARDWARE); 22867754Smsmith return_VOID; 22967754Smsmith} 23067754Smsmith 23167754Smsmith 23267754Smsmith/******************************************************************************* 23367754Smsmith * 23467754Smsmith * FUNCTION: AcpiHwObtainSleepTypeRegisterData 23567754Smsmith * 23667754Smsmith * PARAMETERS: SleepState - Numeric state requested 23767754Smsmith * *Slp_TypA - Pointer to byte to receive SLP_TYPa value 23867754Smsmith * *Slp_TypB - Pointer to byte to receive SLP_TYPb value 23967754Smsmith * 24067754Smsmith * RETURN: Status - ACPI status 24167754Smsmith * 24267754Smsmith * DESCRIPTION: AcpiHwObtainSleepTypeRegisterData() obtains the SLP_TYP and 24367754Smsmith * SLP_TYPb values for the sleep state requested. 24467754Smsmith * 24567754Smsmith ******************************************************************************/ 24667754Smsmith 24767754SmsmithACPI_STATUS 24867754SmsmithAcpiHwObtainSleepTypeRegisterData ( 24967754Smsmith UINT8 SleepState, 25067754Smsmith UINT8 *Slp_TypA, 25167754Smsmith UINT8 *Slp_TypB) 25267754Smsmith{ 25367754Smsmith ACPI_STATUS Status = AE_OK; 25467754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 25567754Smsmith 25667754Smsmith 25767754Smsmith FUNCTION_TRACE ("HwObtainSleepTypeRegisterData"); 25867754Smsmith 25967754Smsmith 26067754Smsmith /* 26167754Smsmith * Validate parameters 26267754Smsmith */ 26367754Smsmith 26467754Smsmith if ((SleepState > ACPI_S_STATES_MAX) || 26567754Smsmith !Slp_TypA || !Slp_TypB) 26667754Smsmith { 26767754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 26867754Smsmith } 26967754Smsmith 27067754Smsmith /* 27167754Smsmith * AcpiEvaluate the namespace object containing the values for this state 27267754Smsmith */ 27367754Smsmith 27467754Smsmith Status = AcpiNsEvaluateByName (SleepStateTable[SleepState], NULL, &ObjDesc); 27567754Smsmith if (ACPI_FAILURE (Status)) 27667754Smsmith { 27767754Smsmith return_ACPI_STATUS (Status); 27867754Smsmith } 27967754Smsmith 28067754Smsmith if (!ObjDesc) 28167754Smsmith { 28267754Smsmith REPORT_ERROR (("Missing Sleep State object\n")); 28367754Smsmith return_ACPI_STATUS (AE_NOT_EXIST); 28467754Smsmith } 28567754Smsmith 28667754Smsmith /* 28767754Smsmith * We got something, now ensure it is correct. The object must 28867754Smsmith * be a package and must have at least 2 numeric values as the 28967754Smsmith * two elements 29067754Smsmith */ 29167754Smsmith 29267754Smsmith Status = AcpiCmResolvePackageReferences(ObjDesc); 29367754Smsmith 29467754Smsmith if (ObjDesc->Package.Count < 2) 29567754Smsmith { 29667754Smsmith /* Must have at least two elements */ 29767754Smsmith 29867754Smsmith REPORT_ERROR (("Sleep State package does not have at least two elements\n")); 29967754Smsmith Status = AE_ERROR; 30067754Smsmith } 30167754Smsmith 30267754Smsmith else if (((ObjDesc->Package.Elements[0])->Common.Type != 30367754Smsmith ACPI_TYPE_NUMBER) || 30467754Smsmith ((ObjDesc->Package.Elements[1])->Common.Type != 30567754Smsmith ACPI_TYPE_NUMBER)) 30667754Smsmith { 30767754Smsmith /* Must have two */ 30867754Smsmith 30967754Smsmith REPORT_ERROR (("Sleep State package elements are not both of type Number\n")); 31067754Smsmith Status = AE_ERROR; 31167754Smsmith } 31267754Smsmith 31367754Smsmith else 31467754Smsmith { 31567754Smsmith /* 31667754Smsmith * Valid _Sx_ package size, type, and value 31767754Smsmith */ 31867754Smsmith *Slp_TypA = (UINT8) (ObjDesc->Package.Elements[0])->Number.Value; 31967754Smsmith 32067754Smsmith *Slp_TypB = (UINT8) (ObjDesc->Package.Elements[1])->Number.Value; 32167754Smsmith } 32267754Smsmith 32367754Smsmith 32467754Smsmith if (ACPI_FAILURE (Status)) 32567754Smsmith { 32667754Smsmith DEBUG_PRINT (ACPI_ERROR, 32767754Smsmith ("SleepTypeRegisterData: Bad Sleep object %p type %X\n", 32867754Smsmith ObjDesc, ObjDesc->Common.Type)); 32967754Smsmith } 33067754Smsmith 33167754Smsmith AcpiCmRemoveReference (ObjDesc); 33267754Smsmith 33367754Smsmith return_ACPI_STATUS (Status); 33467754Smsmith} 33567754Smsmith 33667754Smsmith 33767754Smsmith/******************************************************************************* 33867754Smsmith * 33969450Smsmith * FUNCTION: AcpiHwRegisterBitAccess 34067754Smsmith * 34167754Smsmith * PARAMETERS: ReadWrite - Either ACPI_READ or ACPI_WRITE. 34267754Smsmith * UseLock - Lock the hardware 34369450Smsmith * RegisterId - index of ACPI Register to access 34467754Smsmith * Value - (only used on write) value to write to the 34569450Smsmith * Register. Shifted all the way right. 34667754Smsmith * 34769450Smsmith * RETURN: Value written to or read from specified Register. This value 34867754Smsmith * is shifted all the way right. 34967754Smsmith * 35069450Smsmith * DESCRIPTION: Generic ACPI Register read/write function. 35167754Smsmith * 35267754Smsmith ******************************************************************************/ 35367754Smsmith 35467754SmsmithUINT32 35569450SmsmithAcpiHwRegisterBitAccess ( 35667754Smsmith NATIVE_UINT ReadWrite, 35767754Smsmith BOOLEAN UseLock, 35867754Smsmith UINT32 RegisterId, 35967754Smsmith ...) /* Value (only used on write) */ 36067754Smsmith{ 36167754Smsmith UINT32 RegisterValue = 0; 36267754Smsmith UINT32 Mask = 0; 36367754Smsmith UINT32 Value = 0; 36467754Smsmith 36569450Smsmith FUNCTION_TRACE ("HwRegisterBitAccess"); 36667754Smsmith 36767754Smsmith 36867754Smsmith if (ReadWrite == ACPI_WRITE) 36967754Smsmith { 37067754Smsmith va_list marker; 37167754Smsmith 37267754Smsmith va_start (marker, RegisterId); 37367754Smsmith Value = va_arg (marker, UINT32); 37467754Smsmith va_end (marker); 37567754Smsmith } 37667754Smsmith 37769450Smsmith if (ACPI_MTX_LOCK == UseLock) { 37869450Smsmith AcpiCmAcquireMutex (ACPI_MTX_HARDWARE); 37969450Smsmith } 38067754Smsmith 38167754Smsmith /* 38267754Smsmith * Decode the Register ID 38369450Smsmith * Register id = Register block id | bit id 38469450Smsmith * 38569450Smsmith * Check bit id to fine locate Register offset. 38669450Smsmith * check Mask to determine Register offset, and then read-write. 38767754Smsmith */ 38867754Smsmith 38969450Smsmith switch (REGISTER_BLOCK_ID(RegisterId)) 39067754Smsmith { 39169450Smsmith case PM1_STS: 39267754Smsmith 39369450Smsmith switch (RegisterId) 39467754Smsmith { 39569450Smsmith case TMR_STS: 39669450Smsmith Mask = TMR_STS_MASK; 39769450Smsmith break; 39867754Smsmith 39969450Smsmith case BM_STS: 40069450Smsmith Mask = BM_STS_MASK; 40169450Smsmith break; 40267754Smsmith 40369450Smsmith case GBL_STS: 40469450Smsmith Mask = GBL_STS_MASK; 40569450Smsmith break; 40667754Smsmith 40769450Smsmith case PWRBTN_STS: 40869450Smsmith Mask = PWRBTN_STS_MASK; 40969450Smsmith break; 41067754Smsmith 41169450Smsmith case SLPBTN_STS: 41269450Smsmith Mask = SLPBTN_STS_MASK; 41369450Smsmith break; 41467754Smsmith 41569450Smsmith case RTC_STS: 41669450Smsmith Mask = RTC_STS_MASK; 41769450Smsmith break; 41867754Smsmith 41969450Smsmith case WAK_STS: 42069450Smsmith Mask = WAK_STS_MASK; 42169450Smsmith break; 42267754Smsmith 42369450Smsmith default: 42469450Smsmith Mask = 0; 42569450Smsmith break; 42669450Smsmith } 42767754Smsmith 42869450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_STS); 42967754Smsmith 43069450Smsmith if (ReadWrite == ACPI_WRITE) 43169450Smsmith { 43269450Smsmith /* 43369450Smsmith * Status Registers are different from the rest. Clear by 43469450Smsmith * writing 1, writing 0 has no effect. So, the only relevent 43569450Smsmith * information is the single bit we're interested in, all 43669450Smsmith * others should be written as 0 so they will be left 43769450Smsmith * unchanged 43869450Smsmith */ 43967754Smsmith 44069450Smsmith Value <<= AcpiHwGetBitShift (Mask); 44169450Smsmith Value &= Mask; 44267754Smsmith 44369450Smsmith if (Value) 44467754Smsmith { 44569450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, (UINT16) Value); 44667754Smsmith 44769450Smsmith RegisterValue = 0; 44867754Smsmith } 44967754Smsmith } 45067754Smsmith 45169450Smsmith break; 45267754Smsmith 45367754Smsmith 45469450Smsmith case PM1_EN: 45567754Smsmith 45669450Smsmith switch (RegisterId) 45769450Smsmith { 45869450Smsmith case TMR_EN: 45969450Smsmith Mask = TMR_EN_MASK; 46069450Smsmith break; 46167754Smsmith 46269450Smsmith case GBL_EN: 46369450Smsmith Mask = GBL_EN_MASK; 46469450Smsmith break; 46567754Smsmith 46669450Smsmith case PWRBTN_EN: 46769450Smsmith Mask = PWRBTN_EN_MASK; 46869450Smsmith break; 46967754Smsmith 47069450Smsmith case SLPBTN_EN: 47169450Smsmith Mask = SLPBTN_EN_MASK; 47269450Smsmith break; 47367754Smsmith 47469450Smsmith case RTC_EN: 47569450Smsmith Mask = RTC_EN_MASK; 47669450Smsmith break; 47767754Smsmith 47869450Smsmith default: 47969450Smsmith Mask = 0; 48069450Smsmith break; 48169450Smsmith } 48267754Smsmith 48369450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_EN); 48467754Smsmith 48569450Smsmith if (ReadWrite == ACPI_WRITE) 48669450Smsmith { 48769450Smsmith RegisterValue &= ~Mask; 48869450Smsmith Value <<= AcpiHwGetBitShift (Mask); 48969450Smsmith Value &= Mask; 49069450Smsmith RegisterValue |= Value; 49167754Smsmith 49269450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (UINT16) RegisterValue); 49369450Smsmith } 49467754Smsmith 49567754Smsmith break; 49667754Smsmith 49767754Smsmith 49867754Smsmith case PM1_CONTROL: 49967754Smsmith 50067754Smsmith switch (RegisterId) 50167754Smsmith { 50267754Smsmith case SCI_EN: 50367754Smsmith Mask = SCI_EN_MASK; 50467754Smsmith break; 50567754Smsmith 50667754Smsmith case BM_RLD: 50767754Smsmith Mask = BM_RLD_MASK; 50867754Smsmith break; 50967754Smsmith 51067754Smsmith case GBL_RLS: 51167754Smsmith Mask = GBL_RLS_MASK; 51267754Smsmith break; 51367754Smsmith 51467754Smsmith case SLP_TYPE_A: 51567754Smsmith case SLP_TYPE_B: 51667754Smsmith Mask = SLP_TYPE_X_MASK; 51767754Smsmith break; 51867754Smsmith 51967754Smsmith case SLP_EN: 52067754Smsmith Mask = SLP_EN_MASK; 52167754Smsmith break; 52267754Smsmith 52367754Smsmith default: 52467754Smsmith Mask = 0; 52567754Smsmith break; 52667754Smsmith } 52767754Smsmith 52869450Smsmith 52969450Smsmith /* 53069450Smsmith * Read the PM1 Control register. 53169450Smsmith * Note that at this level, the fact that there are actually TWO 53269450Smsmith * registers (A and B) and that B may not exist, are abstracted. 53369450Smsmith */ 53469450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL); 53569450Smsmith 53669746Smsmith DEBUG_PRINT (TRACE_IO, ("PM1 control: Read %X\n", RegisterValue)); 53769450Smsmith 53867754Smsmith if (ReadWrite == ACPI_WRITE) 53967754Smsmith { 54067754Smsmith RegisterValue &= ~Mask; 54167754Smsmith Value <<= AcpiHwGetBitShift (Mask); 54267754Smsmith Value &= Mask; 54367754Smsmith RegisterValue |= Value; 54467754Smsmith 54567754Smsmith /* 54669450Smsmith * SLP_TYPE_x Registers are written differently 54769450Smsmith * than any other control Registers with 54869450Smsmith * respect to A and B Registers. The value 54967754Smsmith * for A may be different than the value for B 55069746Smsmith * 55169746Smsmith * Therefore, pass the RegisterId, not just generic PM1_CONTROL, 55269746Smsmith * because we need to do different things. Yuck. 55367754Smsmith */ 55467754Smsmith 55569450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 55669746Smsmith RegisterId, (UINT16) RegisterValue); 55767754Smsmith } 55867754Smsmith break; 55967754Smsmith 56067754Smsmith 56167754Smsmith case PM2_CONTROL: 56267754Smsmith 56367754Smsmith switch (RegisterId) 56467754Smsmith { 56567754Smsmith case ARB_DIS: 56667754Smsmith Mask = ARB_DIS_MASK; 56767754Smsmith break; 56867754Smsmith 56967754Smsmith default: 57067754Smsmith Mask = 0; 57167754Smsmith break; 57267754Smsmith } 57367754Smsmith 57469450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); 57569450Smsmith 57669746Smsmith DEBUG_PRINT (TRACE_IO, ("PM2 control: Read %X from %p\n", 57769450Smsmith RegisterValue, AcpiGbl_FADT->XPm2CntBlk.Address)); 57869450Smsmith 57967754Smsmith if (ReadWrite == ACPI_WRITE) 58067754Smsmith { 58167754Smsmith RegisterValue &= ~Mask; 58267754Smsmith Value <<= AcpiHwGetBitShift (Mask); 58367754Smsmith Value &= Mask; 58467754Smsmith RegisterValue |= Value; 58567754Smsmith 58667754Smsmith DEBUG_PRINT (TRACE_IO, 58769746Smsmith ("About to write %04X to %p\n", RegisterValue, 58869450Smsmith AcpiGbl_FADT->XPm2CntBlk.Address)); 58967754Smsmith 59069450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 59169450Smsmith PM2_CONTROL, (UINT8) (RegisterValue)); 59267754Smsmith } 59367754Smsmith break; 59467754Smsmith 59567754Smsmith 59667754Smsmith case PM_TIMER: 59767754Smsmith 59869450Smsmith Mask = TMR_VAL_MASK; 59969450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 60069450Smsmith PM_TIMER); 60169746Smsmith DEBUG_PRINT (TRACE_IO, ("PM_TIMER: Read %X from %p\n", 60269450Smsmith RegisterValue, AcpiGbl_FADT->XPmTmrBlk.Address)); 60367754Smsmith 60467754Smsmith break; 60567754Smsmith 60667754Smsmith 60767754Smsmith case GPE1_EN_BLOCK: 60867754Smsmith case GPE1_STS_BLOCK: 60967754Smsmith case GPE0_EN_BLOCK: 61067754Smsmith case GPE0_STS_BLOCK: 61167754Smsmith 61269450Smsmith /* Determine the bit to be accessed 61369450Smsmith * 61469450Smsmith * (UINT32) RegisterId: 61569450Smsmith * 31 24 16 8 0 61669450Smsmith * +--------+--------+--------+--------+ 61769450Smsmith * | gpe_block_id | gpe_bit_number | 61869450Smsmith * +--------+--------+--------+--------+ 61969450Smsmith * 62069450Smsmith * gpe_block_id is one of GPE[01]_EN_BLOCK and GPE[01]_STS_BLOCK 62169450Smsmith * gpe_bit_number is relative from the gpe_block (0x00~0xFF) 62269450Smsmith */ 62367754Smsmith 62469450Smsmith Mask = REGISTER_BIT_ID(RegisterId); /* gpe_bit_number */ 62569450Smsmith RegisterId = REGISTER_BLOCK_ID(RegisterId) | (Mask >> 3); 62669450Smsmith Mask = AcpiGbl_DecodeTo8bit [Mask % 8]; 62767754Smsmith 62867754Smsmith /* 62967754Smsmith * The base address of the GPE 0 Register Block 63067754Smsmith * Plus 1/2 the length of the GPE 0 Register Block 63169450Smsmith * The enable Register is the Register following the Status Register 63269450Smsmith * and each Register is defined as 1/2 of the total Register Block 63367754Smsmith */ 63467754Smsmith 63567754Smsmith /* 63667754Smsmith * This sets the bit within EnableBit that needs to be written to 63769450Smsmith * the Register indicated in Mask to a 1, all others are 0 63867754Smsmith */ 63967754Smsmith 64067754Smsmith /* Now get the current Enable Bits in the selected Reg */ 64167754Smsmith 64269450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId); 64369746Smsmith DEBUG_PRINT (TRACE_IO, ("GPE Enable bits: Read %X from %X\n", 64469450Smsmith RegisterValue, RegisterId)); 64567754Smsmith 64667754Smsmith if (ReadWrite == ACPI_WRITE) 64767754Smsmith { 64867754Smsmith RegisterValue &= ~Mask; 64967754Smsmith Value <<= AcpiHwGetBitShift (Mask); 65067754Smsmith Value &= Mask; 65167754Smsmith RegisterValue |= Value; 65267754Smsmith 65367754Smsmith /* This write will put the Action state into the General Purpose */ 65467754Smsmith /* Enable Register indexed by the value in Mask */ 65567754Smsmith 65667754Smsmith DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n", 65769450Smsmith RegisterValue, RegisterId)); 65869450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 65969450Smsmith RegisterId, (UINT8) RegisterValue); 66069450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId); 66167754Smsmith } 66267754Smsmith break; 66367754Smsmith 66467754Smsmith 66569450Smsmith case SMI_CMD_BLOCK: 66667754Smsmith case PROCESSOR_BLOCK: 66769450Smsmith /* not used */ 66867754Smsmith default: 66967754Smsmith 67067754Smsmith Mask = 0; 67167754Smsmith break; 67267754Smsmith } 67367754Smsmith 67469450Smsmith if (ACPI_MTX_LOCK == UseLock) { 67569450Smsmith AcpiCmReleaseMutex (ACPI_MTX_HARDWARE); 67669450Smsmith } 67767754Smsmith 67869450Smsmith 67967754Smsmith RegisterValue &= Mask; 68067754Smsmith RegisterValue >>= AcpiHwGetBitShift (Mask); 68167754Smsmith 68269746Smsmith DEBUG_PRINT (TRACE_IO, ("Register I/O: returning %X\n", RegisterValue)); 68367754Smsmith return_VALUE (RegisterValue); 68467754Smsmith} 68569450Smsmith 68669450Smsmith 68769450Smsmith/****************************************************************************** 68869450Smsmith * 68969450Smsmith * FUNCTION: AcpiHwRegisterRead 69069450Smsmith * 69169450Smsmith * PARAMETERS: UseLock - Mutex hw access. 69269450Smsmith * RegisterId - RegisterID + Offset. 69369450Smsmith * 69469450Smsmith * RETURN: Value read or written. 69569450Smsmith * 69669450Smsmith * DESCRIPTION: Acpi register read function. Registers are read at the 69769450Smsmith * given offset. 69869450Smsmith * 69969450Smsmith ******************************************************************************/ 70069450Smsmith 70169450SmsmithUINT32 70269450SmsmithAcpiHwRegisterRead ( 70369450Smsmith BOOLEAN UseLock, 70469450Smsmith UINT32 RegisterId) 70569450Smsmith{ 70669450Smsmith UINT32 Value = 0; 70769450Smsmith UINT32 BankOffset; 70869450Smsmith 70969450Smsmith FUNCTION_TRACE ("AcpiHwRegisterRead"); 71069450Smsmith 71169450Smsmith if (ACPI_MTX_LOCK == UseLock) 71269450Smsmith { 71369450Smsmith AcpiCmAcquireMutex (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 73669450Smsmith if (RegisterId != SLP_TYPE_B) 73769450Smsmith { 73869450Smsmith Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aCntBlk, 0); 73969450Smsmith } 74069450Smsmith 74169450Smsmith if (RegisterId != SLP_TYPE_A) 74269450Smsmith { 74369450Smsmith Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bCntBlk, 0); 74469450Smsmith } 74569450Smsmith break; 74669450Smsmith 74769450Smsmith 74869450Smsmith case PM2_CONTROL: /* 8-bit access */ 74969450Smsmith 75069746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XPm2CntBlk, 0); 75169450Smsmith break; 75269450Smsmith 75369450Smsmith 75469450Smsmith case PM_TIMER: /* 32-bit access */ 75569450Smsmith 75669746Smsmith Value = AcpiHwLowLevelRead (32, &AcpiGbl_FADT->XPmTmrBlk, 0); 75769450Smsmith break; 75869450Smsmith 75969450Smsmith 76069450Smsmith case GPE0_STS_BLOCK: /* 8-bit access */ 76169450Smsmith 76269746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, 0); 76369450Smsmith break; 76469450Smsmith 76569450Smsmith 76669450Smsmith case GPE0_EN_BLOCK: /* 8-bit access */ 76769450Smsmith 76869450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen); 76969746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset); 77069450Smsmith break; 77169450Smsmith 77269450Smsmith 77369450Smsmith case GPE1_STS_BLOCK: /* 8-bit access */ 77469450Smsmith 77569746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, 0); 77669450Smsmith break; 77769450Smsmith 77869450Smsmith 77969450Smsmith case GPE1_EN_BLOCK: /* 8-bit access */ 78069450Smsmith 78169450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); 78269746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset); 78369450Smsmith break; 78469450Smsmith 78569450Smsmith 78669450Smsmith case SMI_CMD_BLOCK: /* 8bit */ 78769450Smsmith 78869450Smsmith Value = (UINT32) AcpiOsIn8 (AcpiGbl_FADT->SmiCmd); 78969450Smsmith break; 79069450Smsmith 79169450Smsmith 79269450Smsmith default: 79369450Smsmith Value = 0; 79469450Smsmith break; 79569450Smsmith } 79669450Smsmith 79769450Smsmith 79869450Smsmith if (ACPI_MTX_LOCK == UseLock) 79969450Smsmith { 80069450Smsmith AcpiCmReleaseMutex (ACPI_MTX_HARDWARE); 80169450Smsmith } 80269450Smsmith 80369450Smsmith return_VALUE (Value); 80469450Smsmith} 80569450Smsmith 80669450Smsmith 80769450Smsmith/****************************************************************************** 80869450Smsmith * 80969450Smsmith * FUNCTION: AcpiHwRegisterWrite 81069450Smsmith * 81169450Smsmith * PARAMETERS: UseLock - Mutex hw access. 81269450Smsmith * RegisterId - RegisterID + Offset. 81369450Smsmith * 81469450Smsmith * RETURN: Value read or written. 81569450Smsmith * 81669450Smsmith * DESCRIPTION: Acpi register Write function. Registers are written at the 81769450Smsmith * given offset. 81869450Smsmith * 81969450Smsmith ******************************************************************************/ 82069450Smsmith 82169450Smsmithvoid 82269450SmsmithAcpiHwRegisterWrite ( 82369450Smsmith BOOLEAN UseLock, 82469450Smsmith UINT32 RegisterId, 82569450Smsmith UINT32 Value) 82669450Smsmith{ 82769450Smsmith UINT32 BankOffset; 82869450Smsmith 82969450Smsmith FUNCTION_TRACE ("AcpiHwRegisterWrite"); 83069450Smsmith 83169450Smsmith 83269450Smsmith if (ACPI_MTX_LOCK == UseLock) 83369450Smsmith { 83469450Smsmith AcpiCmAcquireMutex (ACPI_MTX_HARDWARE); 83569450Smsmith } 83669450Smsmith 83769450Smsmith 83869450Smsmith switch (REGISTER_BLOCK_ID (RegisterId)) 83969450Smsmith { 84069450Smsmith case PM1_STS: /* 16-bit access */ 84169450Smsmith 84269746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, 0); 84369746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, 0); 84469450Smsmith break; 84569450Smsmith 84669450Smsmith 84769450Smsmith case PM1_EN: /* 16-bit access*/ 84869450Smsmith 84969450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen); 85069746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset); 85169746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset); 85269450Smsmith break; 85369450Smsmith 85469450Smsmith 85569450Smsmith case PM1_CONTROL: /* 16-bit access */ 85669450Smsmith 85769450Smsmith /* 85869450Smsmith * If SLP_TYP_A or SLP_TYP_B, only write to one reg block. 85969450Smsmith * Otherwise, write to both. 86069450Smsmith */ 86169450Smsmith if (RegisterId == SLP_TYPE_A) 86269450Smsmith { 86369746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0); 86469450Smsmith } 86569450Smsmith else if (RegisterId == SLP_TYPE_B) 86669450Smsmith { 86769746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0); 86869450Smsmith } 86969450Smsmith else 87069450Smsmith { 87169450Smsmith /* disable/re-enable interrupts if sleeping */ 87269450Smsmith if (RegisterId == SLP_EN) 87369450Smsmith { 87469450Smsmith disable(); 87569450Smsmith } 87669450Smsmith 87769746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0); 87869746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0); 87969450Smsmith 88069450Smsmith if (RegisterId == SLP_EN) 88169450Smsmith { 88269450Smsmith enable(); 88369450Smsmith } 88469450Smsmith } 88569450Smsmith 88669450Smsmith break; 88769450Smsmith 88869450Smsmith 88969450Smsmith case PM2_CONTROL: /* 8-bit access */ 89069450Smsmith 89169746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, 0); 89269450Smsmith break; 89369450Smsmith 89469450Smsmith 89569450Smsmith case PM_TIMER: /* 32-bit access */ 89669450Smsmith 89769746Smsmith AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, 0); 89869450Smsmith break; 89969450Smsmith 90069450Smsmith 90169450Smsmith case GPE0_STS_BLOCK: /* 8-bit access */ 90269450Smsmith 90369746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, 0); 90469450Smsmith break; 90569450Smsmith 90669450Smsmith 90769450Smsmith case GPE0_EN_BLOCK: /* 8-bit access */ 90869450Smsmith 90969450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen); 91069746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset); 91169450Smsmith break; 91269450Smsmith 91369450Smsmith 91469450Smsmith case GPE1_STS_BLOCK: /* 8-bit access */ 91569450Smsmith 91669746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, 0); 91769450Smsmith break; 91869450Smsmith 91969450Smsmith 92069450Smsmith case GPE1_EN_BLOCK: /* 8-bit access */ 92169450Smsmith 92269450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); 92369746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset); 92469450Smsmith break; 92569450Smsmith 92669450Smsmith 92769450Smsmith case SMI_CMD_BLOCK: /* 8bit */ 92869450Smsmith 92969450Smsmith /* For 2.0, SMI_CMD is always in IO space */ 93069450Smsmith /* TBD: what about 1.0? 0.71? */ 93169450Smsmith 93269450Smsmith AcpiOsOut8 (AcpiGbl_FADT->SmiCmd, (UINT8) Value); 93369450Smsmith break; 93469450Smsmith 93569450Smsmith 93669450Smsmith default: 93769450Smsmith Value = 0; 93869450Smsmith break; 93969450Smsmith } 94069450Smsmith 94169450Smsmith 94269450Smsmith if (ACPI_MTX_LOCK == UseLock) 94369450Smsmith { 94469450Smsmith AcpiCmReleaseMutex (ACPI_MTX_HARDWARE); 94569450Smsmith } 94669450Smsmith 94769450Smsmith return_VOID; 94869450Smsmith} 94969450Smsmith 95069450Smsmith 95169450Smsmith/****************************************************************************** 95269450Smsmith * 95369450Smsmith * FUNCTION: AcpiHwLowLevelRead 95469450Smsmith * 95569450Smsmith * PARAMETERS: Register - GAS register structure 95669450Smsmith * Offset - Offset from the base address in the GAS 95769450Smsmith * Width - 8, 16, or 32 95869450Smsmith * 95969450Smsmith * RETURN: Value read 96069450Smsmith * 96169450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space. 96269450Smsmith * 96369450Smsmith ******************************************************************************/ 96469450Smsmith 96569450SmsmithUINT32 96669450SmsmithAcpiHwLowLevelRead ( 96769450Smsmith UINT32 Width, 96869450Smsmith ACPI_GAS *Reg, 96969450Smsmith UINT32 Offset) 97069450Smsmith{ 97169450Smsmith UINT32 Value = 0; 97269450Smsmith ACPI_PHYSICAL_ADDRESS MemAddress; 97369450Smsmith ACPI_IO_ADDRESS IoAddress; 97469450Smsmith UINT32 PciRegister; 97569450Smsmith UINT32 PciDevFunc; 97669450Smsmith 97769450Smsmith 97869450Smsmith /* 97969450Smsmith * Must have a valid pointer to a GAS structure, and 98069450Smsmith * a non-zero address within 98169450Smsmith */ 98269450Smsmith if ((!Reg) || 98369450Smsmith (!Reg->Address)) 98469450Smsmith { 98569450Smsmith return 0; 98669450Smsmith } 98769450Smsmith 98869450Smsmith 98969450Smsmith /* 99069450Smsmith * Three address spaces supported: 99169450Smsmith * Memory, Io, or PCI config. 99269450Smsmith */ 99369450Smsmith 99469450Smsmith switch (Reg->AddressSpaceId) 99569450Smsmith { 99669450Smsmith case ADDRESS_SPACE_SYSTEM_MEMORY: 99769450Smsmith 99869450Smsmith MemAddress = (ACPI_PHYSICAL_ADDRESS) Reg->Address + Offset; 99969450Smsmith 100069450Smsmith switch (Width) 100169450Smsmith { 100269450Smsmith case 8: 100369450Smsmith Value = AcpiOsMemIn8 (MemAddress); 100469450Smsmith break; 100569450Smsmith case 16: 100669450Smsmith Value = AcpiOsMemIn16 (MemAddress); 100769450Smsmith break; 100869450Smsmith case 32: 100969450Smsmith Value = AcpiOsMemIn32 (MemAddress); 101069450Smsmith break; 101169450Smsmith } 101269450Smsmith break; 101369450Smsmith 101469450Smsmith 101569450Smsmith case ADDRESS_SPACE_SYSTEM_IO: 101669450Smsmith 101769450Smsmith IoAddress = (ACPI_IO_ADDRESS) Reg->Address + Offset; 101869450Smsmith 101969450Smsmith switch (Width) 102069450Smsmith { 102169450Smsmith case 8: 102269450Smsmith Value = AcpiOsIn8 (IoAddress); 102369450Smsmith break; 102469450Smsmith case 16: 102569450Smsmith Value = AcpiOsIn16 (IoAddress); 102669450Smsmith break; 102769450Smsmith case 32: 102869450Smsmith Value = AcpiOsIn32 (IoAddress); 102969450Smsmith break; 103069450Smsmith } 103169450Smsmith break; 103269450Smsmith 103369450Smsmith 103469450Smsmith case ADDRESS_SPACE_PCI_CONFIG: 103569450Smsmith 103669450Smsmith PciDevFunc = ACPI_PCI_DEVFUN (Reg->Address); 103769450Smsmith PciRegister = ACPI_PCI_REGISTER (Reg->Address) + Offset; 103869450Smsmith 103969450Smsmith switch (Width) 104069450Smsmith { 104169450Smsmith case 8: 104269450Smsmith AcpiOsReadPciCfgByte (0, PciDevFunc, PciRegister, (UINT8 *) &Value); 104369450Smsmith break; 104469450Smsmith case 16: 104569450Smsmith AcpiOsReadPciCfgWord (0, PciDevFunc, PciRegister, (UINT16 *) &Value); 104669450Smsmith break; 104769450Smsmith case 32: 104869450Smsmith AcpiOsReadPciCfgDword (0, PciDevFunc, PciRegister, (UINT32 *) &Value); 104969450Smsmith break; 105069450Smsmith } 105169450Smsmith break; 105269450Smsmith } 105369450Smsmith 105469450Smsmith return Value; 105569450Smsmith} 105669450Smsmith 105769450Smsmith 105869450Smsmith/****************************************************************************** 105969450Smsmith * 106069450Smsmith * FUNCTION: AcpiHwLowLevelWrite 106169450Smsmith * 106269450Smsmith * PARAMETERS: Width - 8, 16, or 32 106369450Smsmith * Value - To be written 106469450Smsmith * Register - GAS register structure 106569450Smsmith * Offset - Offset from the base address in the GAS 106669450Smsmith * 106769450Smsmith * 106869450Smsmith * RETURN: Value read 106969450Smsmith * 107069450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space. 107169450Smsmith * 107269450Smsmith ******************************************************************************/ 107369450Smsmith 107469450Smsmithvoid 107569450SmsmithAcpiHwLowLevelWrite ( 107669450Smsmith UINT32 Width, 107769450Smsmith UINT32 Value, 107869450Smsmith ACPI_GAS *Reg, 107969450Smsmith UINT32 Offset) 108069450Smsmith{ 108169450Smsmith ACPI_PHYSICAL_ADDRESS MemAddress; 108269450Smsmith ACPI_IO_ADDRESS IoAddress; 108369450Smsmith UINT32 PciRegister; 108469450Smsmith UINT32 PciDevFunc; 108569450Smsmith 108669450Smsmith 108769450Smsmith /* 108869450Smsmith * Must have a valid pointer to a GAS structure, and 108969450Smsmith * a non-zero address within 109069450Smsmith */ 109169450Smsmith if ((!Reg) || 109269450Smsmith (!Reg->Address)) 109369450Smsmith { 109469450Smsmith return; 109569450Smsmith } 109669450Smsmith 109769450Smsmith 109869450Smsmith /* 109969450Smsmith * Three address spaces supported: 110069450Smsmith * Memory, Io, or PCI config. 110169450Smsmith */ 110269450Smsmith 110369450Smsmith switch (Reg->AddressSpaceId) 110469450Smsmith { 110569450Smsmith case ADDRESS_SPACE_SYSTEM_MEMORY: 110669450Smsmith 110769450Smsmith MemAddress = (ACPI_PHYSICAL_ADDRESS) Reg->Address + Offset; 110869450Smsmith 110969450Smsmith switch (Width) 111069450Smsmith { 111169450Smsmith case 8: 111269450Smsmith AcpiOsMemOut8 (MemAddress, (UINT8) Value); 111369450Smsmith break; 111469450Smsmith case 16: 111569450Smsmith AcpiOsMemOut16 (MemAddress, (UINT16) Value); 111669450Smsmith break; 111769450Smsmith case 32: 111869450Smsmith AcpiOsMemOut32 (MemAddress, (UINT32) Value); 111969450Smsmith break; 112069450Smsmith } 112169450Smsmith break; 112269450Smsmith 112369450Smsmith 112469450Smsmith case ADDRESS_SPACE_SYSTEM_IO: 112569450Smsmith 112669450Smsmith IoAddress = (ACPI_IO_ADDRESS) Reg->Address + Offset; 112769450Smsmith 112869450Smsmith switch (Width) 112969450Smsmith { 113069450Smsmith case 8: 113169450Smsmith AcpiOsOut8 (IoAddress, (UINT8) Value); 113269450Smsmith break; 113369450Smsmith case 16: 113469450Smsmith AcpiOsOut16 (IoAddress, (UINT16) Value); 113569450Smsmith break; 113669450Smsmith case 32: 113769450Smsmith AcpiOsOut32 (IoAddress, (UINT32) Value); 113869450Smsmith break; 113969450Smsmith } 114069450Smsmith break; 114169450Smsmith 114269450Smsmith 114369450Smsmith case ADDRESS_SPACE_PCI_CONFIG: 114469450Smsmith 114569450Smsmith PciDevFunc = ACPI_PCI_DEVFUN (Reg->Address); 114669450Smsmith PciRegister = ACPI_PCI_REGISTER (Reg->Address) + Offset; 114769450Smsmith 114869450Smsmith switch (Width) 114969450Smsmith { 115069450Smsmith case 8: 115169450Smsmith AcpiOsWritePciCfgByte (0, PciDevFunc, PciRegister, (UINT8) Value); 115269450Smsmith break; 115369450Smsmith case 16: 115469450Smsmith AcpiOsWritePciCfgWord (0, PciDevFunc, PciRegister, (UINT16) Value); 115569450Smsmith break; 115669450Smsmith case 32: 115769450Smsmith AcpiOsWritePciCfgDword (0, PciDevFunc, PciRegister, (UINT32) Value); 115869450Smsmith break; 115969450Smsmith } 116069450Smsmith break; 116169450Smsmith } 116269450Smsmith} 1163