hwregs.c revision 71867
167754Smsmith 267754Smsmith/******************************************************************************* 367754Smsmith * 467754Smsmith * Module Name: hwregs - Read/write access functions for the various ACPI 567754Smsmith * control and status registers. 671867Smsmith * $Revision: 88 $ 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 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_", 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 18767754Smsmith DEBUG_PRINT (TRACE_IO, ("About to write %04X to %04X\n", 18869450Smsmith ALL_FIXED_STS_BITS, 18970243Smsmith (UINT16) ACPI_GET_ADDRESS (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 19770243Smsmith if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address)) 19867754Smsmith { 19970243Smsmith AcpiOsOut16 ((ACPI_IO_ADDRESS) ACPI_GET_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 { 21170243Smsmith AcpiOsOut8 ((ACPI_IO_ADDRESS) (ACPI_GET_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 { 22270243Smsmith AcpiOsOut8 ((ACPI_IO_ADDRESS) (ACPI_GET_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 != 30371867Smsmith ACPI_TYPE_INTEGER) || 30467754Smsmith ((ObjDesc->Package.Elements[1])->Common.Type != 30571867Smsmith ACPI_TYPE_INTEGER)) 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 */ 31871867Smsmith *Slp_TypA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value; 31967754Smsmith 32071867Smsmith *Slp_TypB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.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", 57770243Smsmith RegisterValue, ACPI_GET_ADDRESS (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", 60270243Smsmith RegisterValue, ACPI_GET_ADDRESS (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 73671867Smsmith Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aCntBlk, 0); 73771867Smsmith Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bCntBlk, 0); 73869450Smsmith break; 73969450Smsmith 74069450Smsmith 74169450Smsmith case PM2_CONTROL: /* 8-bit access */ 74269450Smsmith 74369746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XPm2CntBlk, 0); 74469450Smsmith break; 74569450Smsmith 74669450Smsmith 74769450Smsmith case PM_TIMER: /* 32-bit access */ 74869450Smsmith 74969746Smsmith Value = AcpiHwLowLevelRead (32, &AcpiGbl_FADT->XPmTmrBlk, 0); 75069450Smsmith break; 75169450Smsmith 75269450Smsmith 75369450Smsmith case GPE0_STS_BLOCK: /* 8-bit access */ 75469450Smsmith 75569746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, 0); 75669450Smsmith break; 75769450Smsmith 75869450Smsmith 75969450Smsmith case GPE0_EN_BLOCK: /* 8-bit access */ 76069450Smsmith 76169450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen); 76269746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset); 76369450Smsmith break; 76469450Smsmith 76569450Smsmith 76669450Smsmith case GPE1_STS_BLOCK: /* 8-bit access */ 76769450Smsmith 76869746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, 0); 76969450Smsmith break; 77069450Smsmith 77169450Smsmith 77269450Smsmith case GPE1_EN_BLOCK: /* 8-bit access */ 77369450Smsmith 77469450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); 77569746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset); 77669450Smsmith break; 77769450Smsmith 77869450Smsmith 77969450Smsmith case SMI_CMD_BLOCK: /* 8bit */ 78069450Smsmith 78169450Smsmith Value = (UINT32) AcpiOsIn8 (AcpiGbl_FADT->SmiCmd); 78269450Smsmith break; 78369450Smsmith 78469450Smsmith 78569450Smsmith default: 78669450Smsmith Value = 0; 78769450Smsmith break; 78869450Smsmith } 78969450Smsmith 79069450Smsmith 79169450Smsmith if (ACPI_MTX_LOCK == UseLock) 79269450Smsmith { 79369450Smsmith AcpiCmReleaseMutex (ACPI_MTX_HARDWARE); 79469450Smsmith } 79569450Smsmith 79669450Smsmith return_VALUE (Value); 79769450Smsmith} 79869450Smsmith 79969450Smsmith 80069450Smsmith/****************************************************************************** 80169450Smsmith * 80269450Smsmith * FUNCTION: AcpiHwRegisterWrite 80369450Smsmith * 80469450Smsmith * PARAMETERS: UseLock - Mutex hw access. 80569450Smsmith * RegisterId - RegisterID + Offset. 80669450Smsmith * 80769450Smsmith * RETURN: Value read or written. 80869450Smsmith * 80969450Smsmith * DESCRIPTION: Acpi register Write function. Registers are written at the 81069450Smsmith * given offset. 81169450Smsmith * 81269450Smsmith ******************************************************************************/ 81369450Smsmith 81469450Smsmithvoid 81569450SmsmithAcpiHwRegisterWrite ( 81669450Smsmith BOOLEAN UseLock, 81769450Smsmith UINT32 RegisterId, 81869450Smsmith UINT32 Value) 81969450Smsmith{ 82069450Smsmith UINT32 BankOffset; 82169450Smsmith 82269450Smsmith FUNCTION_TRACE ("AcpiHwRegisterWrite"); 82369450Smsmith 82469450Smsmith 82569450Smsmith if (ACPI_MTX_LOCK == UseLock) 82669450Smsmith { 82769450Smsmith AcpiCmAcquireMutex (ACPI_MTX_HARDWARE); 82869450Smsmith } 82969450Smsmith 83069450Smsmith 83169450Smsmith switch (REGISTER_BLOCK_ID (RegisterId)) 83269450Smsmith { 83369450Smsmith case PM1_STS: /* 16-bit access */ 83469450Smsmith 83569746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, 0); 83669746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, 0); 83769450Smsmith break; 83869450Smsmith 83969450Smsmith 84069450Smsmith case PM1_EN: /* 16-bit access*/ 84169450Smsmith 84269450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen); 84369746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset); 84469746Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset); 84569450Smsmith break; 84669450Smsmith 84769450Smsmith 84869450Smsmith case PM1_CONTROL: /* 16-bit access */ 84969450Smsmith 85071867Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0); 85171867Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0); 85271867Smsmith break; 85369450Smsmith 85469450Smsmith 85571867Smsmith case PM1A_CONTROL: /* 16-bit access */ 85669450Smsmith 85771867Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0); 85869450Smsmith break; 85969450Smsmith 86069450Smsmith 86171867Smsmith case PM1B_CONTROL: /* 16-bit access */ 86271867Smsmith 86371867Smsmith AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0); 86471867Smsmith break; 86571867Smsmith 86671867Smsmith 86769450Smsmith case PM2_CONTROL: /* 8-bit access */ 86869450Smsmith 86969746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, 0); 87069450Smsmith break; 87169450Smsmith 87269450Smsmith 87369450Smsmith case PM_TIMER: /* 32-bit access */ 87469450Smsmith 87569746Smsmith AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, 0); 87669450Smsmith break; 87769450Smsmith 87869450Smsmith 87969450Smsmith case GPE0_STS_BLOCK: /* 8-bit access */ 88069450Smsmith 88169746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, 0); 88269450Smsmith break; 88369450Smsmith 88469450Smsmith 88569450Smsmith case GPE0_EN_BLOCK: /* 8-bit access */ 88669450Smsmith 88769450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen); 88869746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset); 88969450Smsmith break; 89069450Smsmith 89169450Smsmith 89269450Smsmith case GPE1_STS_BLOCK: /* 8-bit access */ 89369450Smsmith 89469746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, 0); 89569450Smsmith break; 89669450Smsmith 89769450Smsmith 89869450Smsmith case GPE1_EN_BLOCK: /* 8-bit access */ 89969450Smsmith 90069450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); 90169746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset); 90269450Smsmith break; 90369450Smsmith 90469450Smsmith 90569450Smsmith case SMI_CMD_BLOCK: /* 8bit */ 90669450Smsmith 90769450Smsmith /* For 2.0, SMI_CMD is always in IO space */ 90869450Smsmith /* TBD: what about 1.0? 0.71? */ 90969450Smsmith 91069450Smsmith AcpiOsOut8 (AcpiGbl_FADT->SmiCmd, (UINT8) Value); 91169450Smsmith break; 91269450Smsmith 91369450Smsmith 91469450Smsmith default: 91569450Smsmith Value = 0; 91669450Smsmith break; 91769450Smsmith } 91869450Smsmith 91969450Smsmith 92069450Smsmith if (ACPI_MTX_LOCK == UseLock) 92169450Smsmith { 92269450Smsmith AcpiCmReleaseMutex (ACPI_MTX_HARDWARE); 92369450Smsmith } 92469450Smsmith 92569450Smsmith return_VOID; 92669450Smsmith} 92769450Smsmith 92869450Smsmith 92969450Smsmith/****************************************************************************** 93069450Smsmith * 93169450Smsmith * FUNCTION: AcpiHwLowLevelRead 93269450Smsmith * 93369450Smsmith * PARAMETERS: Register - GAS register structure 93469450Smsmith * Offset - Offset from the base address in the GAS 93569450Smsmith * Width - 8, 16, or 32 93669450Smsmith * 93769450Smsmith * RETURN: Value read 93869450Smsmith * 93969450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space. 94069450Smsmith * 94169450Smsmith ******************************************************************************/ 94269450Smsmith 94369450SmsmithUINT32 94469450SmsmithAcpiHwLowLevelRead ( 94569450Smsmith UINT32 Width, 94669450Smsmith ACPI_GAS *Reg, 94769450Smsmith UINT32 Offset) 94869450Smsmith{ 94969450Smsmith UINT32 Value = 0; 95069450Smsmith ACPI_PHYSICAL_ADDRESS MemAddress; 95169450Smsmith ACPI_IO_ADDRESS IoAddress; 95269450Smsmith UINT32 PciRegister; 95369450Smsmith UINT32 PciDevFunc; 95469450Smsmith 95569450Smsmith 95669450Smsmith /* 95769450Smsmith * Must have a valid pointer to a GAS structure, and 95869450Smsmith * a non-zero address within 95969450Smsmith */ 96069450Smsmith if ((!Reg) || 96170243Smsmith (!ACPI_VALID_ADDRESS (Reg->Address))) 96269450Smsmith { 96369450Smsmith return 0; 96469450Smsmith } 96569450Smsmith 96669450Smsmith 96769450Smsmith /* 96869450Smsmith * Three address spaces supported: 96969450Smsmith * Memory, Io, or PCI config. 97069450Smsmith */ 97169450Smsmith 97269450Smsmith switch (Reg->AddressSpaceId) 97369450Smsmith { 97469450Smsmith case ADDRESS_SPACE_SYSTEM_MEMORY: 97569450Smsmith 97670243Smsmith MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 97769450Smsmith 97869450Smsmith switch (Width) 97969450Smsmith { 98069450Smsmith case 8: 98169450Smsmith Value = AcpiOsMemIn8 (MemAddress); 98269450Smsmith break; 98369450Smsmith case 16: 98469450Smsmith Value = AcpiOsMemIn16 (MemAddress); 98569450Smsmith break; 98669450Smsmith case 32: 98769450Smsmith Value = AcpiOsMemIn32 (MemAddress); 98869450Smsmith break; 98969450Smsmith } 99069450Smsmith break; 99169450Smsmith 99269450Smsmith 99369450Smsmith case ADDRESS_SPACE_SYSTEM_IO: 99469450Smsmith 99570243Smsmith IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 99669450Smsmith 99769450Smsmith switch (Width) 99869450Smsmith { 99969450Smsmith case 8: 100069450Smsmith Value = AcpiOsIn8 (IoAddress); 100169450Smsmith break; 100269450Smsmith case 16: 100369450Smsmith Value = AcpiOsIn16 (IoAddress); 100469450Smsmith break; 100569450Smsmith case 32: 100669450Smsmith Value = AcpiOsIn32 (IoAddress); 100769450Smsmith break; 100869450Smsmith } 100969450Smsmith break; 101069450Smsmith 101169450Smsmith 101269450Smsmith case ADDRESS_SPACE_PCI_CONFIG: 101369450Smsmith 101470243Smsmith PciDevFunc = ACPI_PCI_DEVFUN (ACPI_GET_ADDRESS (Reg->Address)); 101570243Smsmith PciRegister = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset; 101669450Smsmith 101769450Smsmith switch (Width) 101869450Smsmith { 101969450Smsmith case 8: 102069450Smsmith AcpiOsReadPciCfgByte (0, PciDevFunc, PciRegister, (UINT8 *) &Value); 102169450Smsmith break; 102269450Smsmith case 16: 102369450Smsmith AcpiOsReadPciCfgWord (0, PciDevFunc, PciRegister, (UINT16 *) &Value); 102469450Smsmith break; 102569450Smsmith case 32: 102669450Smsmith AcpiOsReadPciCfgDword (0, PciDevFunc, PciRegister, (UINT32 *) &Value); 102769450Smsmith break; 102869450Smsmith } 102969450Smsmith break; 103069450Smsmith } 103169450Smsmith 103269450Smsmith return Value; 103369450Smsmith} 103469450Smsmith 103569450Smsmith 103669450Smsmith/****************************************************************************** 103769450Smsmith * 103869450Smsmith * FUNCTION: AcpiHwLowLevelWrite 103969450Smsmith * 104069450Smsmith * PARAMETERS: Width - 8, 16, or 32 104169450Smsmith * Value - To be written 104269450Smsmith * Register - GAS register structure 104369450Smsmith * Offset - Offset from the base address in the GAS 104469450Smsmith * 104569450Smsmith * 104669450Smsmith * RETURN: Value read 104769450Smsmith * 104869450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space. 104969450Smsmith * 105069450Smsmith ******************************************************************************/ 105169450Smsmith 105269450Smsmithvoid 105369450SmsmithAcpiHwLowLevelWrite ( 105469450Smsmith UINT32 Width, 105569450Smsmith UINT32 Value, 105669450Smsmith ACPI_GAS *Reg, 105769450Smsmith UINT32 Offset) 105869450Smsmith{ 105969450Smsmith ACPI_PHYSICAL_ADDRESS MemAddress; 106069450Smsmith ACPI_IO_ADDRESS IoAddress; 106169450Smsmith UINT32 PciRegister; 106269450Smsmith UINT32 PciDevFunc; 106369450Smsmith 106469450Smsmith 106569450Smsmith /* 106669450Smsmith * Must have a valid pointer to a GAS structure, and 106769450Smsmith * a non-zero address within 106869450Smsmith */ 106969450Smsmith if ((!Reg) || 107070243Smsmith (!ACPI_VALID_ADDRESS (Reg->Address))) 107169450Smsmith { 107269450Smsmith return; 107369450Smsmith } 107469450Smsmith 107569450Smsmith 107669450Smsmith /* 107769450Smsmith * Three address spaces supported: 107869450Smsmith * Memory, Io, or PCI config. 107969450Smsmith */ 108069450Smsmith 108169450Smsmith switch (Reg->AddressSpaceId) 108269450Smsmith { 108369450Smsmith case ADDRESS_SPACE_SYSTEM_MEMORY: 108469450Smsmith 108570243Smsmith MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 108669450Smsmith 108769450Smsmith switch (Width) 108869450Smsmith { 108969450Smsmith case 8: 109069450Smsmith AcpiOsMemOut8 (MemAddress, (UINT8) Value); 109169450Smsmith break; 109269450Smsmith case 16: 109369450Smsmith AcpiOsMemOut16 (MemAddress, (UINT16) Value); 109469450Smsmith break; 109569450Smsmith case 32: 109669450Smsmith AcpiOsMemOut32 (MemAddress, (UINT32) Value); 109769450Smsmith break; 109869450Smsmith } 109969450Smsmith break; 110069450Smsmith 110169450Smsmith 110269450Smsmith case ADDRESS_SPACE_SYSTEM_IO: 110369450Smsmith 110470243Smsmith IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 110569450Smsmith 110669450Smsmith switch (Width) 110769450Smsmith { 110869450Smsmith case 8: 110969450Smsmith AcpiOsOut8 (IoAddress, (UINT8) Value); 111069450Smsmith break; 111169450Smsmith case 16: 111269450Smsmith AcpiOsOut16 (IoAddress, (UINT16) Value); 111369450Smsmith break; 111469450Smsmith case 32: 111569450Smsmith AcpiOsOut32 (IoAddress, (UINT32) Value); 111669450Smsmith break; 111769450Smsmith } 111869450Smsmith break; 111969450Smsmith 112069450Smsmith 112169450Smsmith case ADDRESS_SPACE_PCI_CONFIG: 112269450Smsmith 112370243Smsmith PciDevFunc = ACPI_PCI_DEVFUN (ACPI_GET_ADDRESS (Reg->Address)); 112470243Smsmith PciRegister = ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset; 112569450Smsmith 112669450Smsmith switch (Width) 112769450Smsmith { 112869450Smsmith case 8: 112969450Smsmith AcpiOsWritePciCfgByte (0, PciDevFunc, PciRegister, (UINT8) Value); 113069450Smsmith break; 113169450Smsmith case 16: 113269450Smsmith AcpiOsWritePciCfgWord (0, PciDevFunc, PciRegister, (UINT16) Value); 113369450Smsmith break; 113469450Smsmith case 32: 113569450Smsmith AcpiOsWritePciCfgDword (0, PciDevFunc, PciRegister, (UINT32) Value); 113669450Smsmith break; 113769450Smsmith } 113869450Smsmith break; 113969450Smsmith } 114069450Smsmith} 1141