hwregs.c revision 85756
167754Smsmith 267754Smsmith/******************************************************************************* 367754Smsmith * 467754Smsmith * Module Name: hwregs - Read/write access functions for the various ACPI 567754Smsmith * control and status registers. 685756Smsmith * $Revision: 110 $ 767754Smsmith * 867754Smsmith ******************************************************************************/ 967754Smsmith 1067754Smsmith/****************************************************************************** 1167754Smsmith * 1267754Smsmith * 1. Copyright Notice 1367754Smsmith * 1471867Smsmith * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp. 1570243Smsmith * All rights reserved. 1667754Smsmith * 1767754Smsmith * 2. License 1867754Smsmith * 1967754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 2067754Smsmith * rights. You may have additional license terms from the party that provided 2167754Smsmith * you this software, covering your right to use that party's intellectual 2267754Smsmith * property rights. 2367754Smsmith * 2467754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2567754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2667754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2767754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2867754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2967754Smsmith * Code in any form, with the right to sublicense such rights; and 3067754Smsmith * 3167754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3267754Smsmith * license (with the right to sublicense), under only those claims of Intel 3367754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3467754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3567754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3667754Smsmith * license, and in no event shall the patent license extend to any additions 3767754Smsmith * to or modifications of the Original Intel Code. No other license or right 3867754Smsmith * is granted directly or by implication, estoppel or otherwise; 3967754Smsmith * 4067754Smsmith * The above copyright and patent license is granted only if the following 4167754Smsmith * conditions are met: 4267754Smsmith * 4367754Smsmith * 3. Conditions 4467754Smsmith * 4567754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4667754Smsmith * Redistribution of source code of any substantial portion of the Covered 4767754Smsmith * Code or modification with rights to further distribute source must include 4867754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4967754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 5067754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 5167754Smsmith * contain a file documenting the changes Licensee made to create that Covered 5267754Smsmith * Code and the date of any change. Licensee must include in that file the 5367754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5467754Smsmith * must include a prominent statement that the modification is derived, 5567754Smsmith * directly or indirectly, from Original Intel Code. 5667754Smsmith * 5767754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5867754Smsmith * Redistribution of source code of any substantial portion of the Covered 5967754Smsmith * Code or modification without rights to further distribute source must 6067754Smsmith * include the following Disclaimer and Export Compliance provision in the 6167754Smsmith * documentation and/or other materials provided with distribution. In 6267754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6367754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6467754Smsmith * license from Licensee to its licensee is limited to the intellectual 6567754Smsmith * property embodied in the software Licensee provides to its licensee, and 6667754Smsmith * not to intellectual property embodied in modifications its licensee may 6767754Smsmith * make. 6867754Smsmith * 6967754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 7067754Smsmith * substantial portion of the Covered Code or modification must reproduce the 7167754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 7267754Smsmith * provision in the documentation and/or other materials provided with the 7367754Smsmith * distribution. 7467754Smsmith * 7567754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7667754Smsmith * Intel Code. 7767754Smsmith * 7867754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7967754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 8067754Smsmith * other dealings in products derived from or relating to the Covered Code 8167754Smsmith * without prior written authorization from Intel. 8267754Smsmith * 8367754Smsmith * 4. Disclaimer and Export Compliance 8467754Smsmith * 8567754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8667754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8767754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8867754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8967754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 9067754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 9167754Smsmith * PARTICULAR PURPOSE. 9267754Smsmith * 9367754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9467754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9567754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9667754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9767754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9867754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9967754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 10067754Smsmith * LIMITED REMEDY. 10167754Smsmith * 10267754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10367754Smsmith * software or system incorporating such software without first obtaining any 10467754Smsmith * required license or other approval from the U. S. Department of Commerce or 10567754Smsmith * any other agency or department of the United States Government. In the 10667754Smsmith * event Licensee exports any such software from the United States or 10767754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10867754Smsmith * ensure that the distribution and export/re-export of the software is in 10967754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 11067754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 11167754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 11267754Smsmith * software, or service, directly or indirectly, to any country for which the 11367754Smsmith * United States government or any agency thereof requires an export license, 11467754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11567754Smsmith * such license, approval or letter. 11667754Smsmith * 11767754Smsmith *****************************************************************************/ 11867754Smsmith 11967754Smsmith#define __HWREGS_C__ 12067754Smsmith 12167754Smsmith#include "acpi.h" 12267754Smsmith#include "achware.h" 12367754Smsmith#include "acnamesp.h" 12467754Smsmith 12577424Smsmith#define _COMPONENT ACPI_HARDWARE 12667754Smsmith MODULE_NAME ("hwregs") 12767754Smsmith 12867754Smsmith 12967754Smsmith/******************************************************************************* 13067754Smsmith * 13167754Smsmith * FUNCTION: AcpiHwGetBitShift 13267754Smsmith * 13367754Smsmith * PARAMETERS: Mask - Input mask to determine bit shift from. 13467754Smsmith * Must have at least 1 bit set. 13567754Smsmith * 13667754Smsmith * RETURN: Bit location of the lsb of the mask 13767754Smsmith * 13867754Smsmith * DESCRIPTION: Returns the bit number for the low order bit that's set. 13967754Smsmith * 14067754Smsmith ******************************************************************************/ 14167754Smsmith 14271867SmsmithUINT32 14367754SmsmithAcpiHwGetBitShift ( 14467754Smsmith UINT32 Mask) 14567754Smsmith{ 14667754Smsmith UINT32 Shift; 14767754Smsmith 14867754Smsmith 14967754Smsmith FUNCTION_TRACE ("HwGetBitShift"); 15067754Smsmith 15167754Smsmith 15267754Smsmith for (Shift = 0; ((Mask >> Shift) & 1) == 0; Shift++) 15367754Smsmith { ; } 15467754Smsmith 15567754Smsmith return_VALUE (Shift); 15667754Smsmith} 15767754Smsmith 15867754Smsmith 15967754Smsmith/******************************************************************************* 16067754Smsmith * 16167754Smsmith * FUNCTION: AcpiHwClearAcpiStatus 16267754Smsmith * 16367754Smsmith * PARAMETERS: none 16467754Smsmith * 16567754Smsmith * RETURN: none 16667754Smsmith * 16767754Smsmith * DESCRIPTION: Clears all fixed and general purpose status bits 16867754Smsmith * 16967754Smsmith ******************************************************************************/ 17067754Smsmith 17167754Smsmithvoid 17267754SmsmithAcpiHwClearAcpiStatus (void) 17367754Smsmith{ 17467754Smsmith UINT16 GpeLength; 17567754Smsmith UINT16 Index; 17667754Smsmith 17767754Smsmith 17867754Smsmith FUNCTION_TRACE ("HwClearAcpiStatus"); 17967754Smsmith 18067754Smsmith 18182367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n", 18277424Smsmith ALL_FIXED_STS_BITS, 18377424Smsmith (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address))); 18467754Smsmith 18567754Smsmith 18677424Smsmith AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 18767754Smsmith 18869450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, ALL_FIXED_STS_BITS); 18967754Smsmith 19069450Smsmith 19170243Smsmith if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address)) 19267754Smsmith { 19383174Smsmith AcpiOsWritePort ((ACPI_IO_ADDRESS) 19480062Smsmith ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address), 19580062Smsmith ALL_FIXED_STS_BITS, 16); 19667754Smsmith } 19767754Smsmith 19867754Smsmith /* now clear the GPE Bits */ 19967754Smsmith 20069450Smsmith if (AcpiGbl_FADT->Gpe0BlkLen) 20167754Smsmith { 20269450Smsmith GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe0BlkLen); 20367754Smsmith 20467754Smsmith for (Index = 0; Index < GpeLength; Index++) 20567754Smsmith { 20680062Smsmith AcpiOsWritePort ((ACPI_IO_ADDRESS) ( 20777424Smsmith ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe0Blk.Address) + Index), 20880062Smsmith 0xFF, 8); 20967754Smsmith } 21067754Smsmith } 21167754Smsmith 21269450Smsmith if (AcpiGbl_FADT->Gpe1BlkLen) 21367754Smsmith { 21469450Smsmith GpeLength = (UINT16) DIV_2 (AcpiGbl_FADT->Gpe1BlkLen); 21567754Smsmith 21667754Smsmith for (Index = 0; Index < GpeLength; Index++) 21767754Smsmith { 21880062Smsmith AcpiOsWritePort ((ACPI_IO_ADDRESS) ( 21977424Smsmith ACPI_GET_ADDRESS (AcpiGbl_FADT->XGpe1Blk.Address) + Index), 22080062Smsmith 0xFF, 8); 22167754Smsmith } 22267754Smsmith } 22367754Smsmith 22477424Smsmith AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 22567754Smsmith return_VOID; 22667754Smsmith} 22767754Smsmith 22867754Smsmith 22967754Smsmith/******************************************************************************* 23067754Smsmith * 23167754Smsmith * FUNCTION: AcpiHwObtainSleepTypeRegisterData 23267754Smsmith * 23367754Smsmith * PARAMETERS: SleepState - Numeric state requested 23467754Smsmith * *Slp_TypA - Pointer to byte to receive SLP_TYPa value 23567754Smsmith * *Slp_TypB - Pointer to byte to receive SLP_TYPb value 23667754Smsmith * 23767754Smsmith * RETURN: Status - ACPI status 23867754Smsmith * 23967754Smsmith * DESCRIPTION: AcpiHwObtainSleepTypeRegisterData() obtains the SLP_TYP and 24067754Smsmith * SLP_TYPb values for the sleep state requested. 24167754Smsmith * 24267754Smsmith ******************************************************************************/ 24367754Smsmith 24467754SmsmithACPI_STATUS 24567754SmsmithAcpiHwObtainSleepTypeRegisterData ( 24667754Smsmith UINT8 SleepState, 24767754Smsmith UINT8 *Slp_TypA, 24867754Smsmith UINT8 *Slp_TypB) 24967754Smsmith{ 25067754Smsmith ACPI_STATUS Status = AE_OK; 25167754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 25267754Smsmith 25367754Smsmith 25467754Smsmith FUNCTION_TRACE ("HwObtainSleepTypeRegisterData"); 25567754Smsmith 25667754Smsmith 25767754Smsmith /* 25867754Smsmith * Validate parameters 25967754Smsmith */ 26067754Smsmith if ((SleepState > ACPI_S_STATES_MAX) || 26167754Smsmith !Slp_TypA || !Slp_TypB) 26267754Smsmith { 26367754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 26467754Smsmith } 26567754Smsmith 26667754Smsmith /* 26767754Smsmith * AcpiEvaluate the namespace object containing the values for this state 26867754Smsmith */ 26983174Smsmith Status = AcpiNsEvaluateByName ((NATIVE_CHAR *) AcpiGbl_DbSleepStates[SleepState], 27083174Smsmith NULL, &ObjDesc); 27167754Smsmith if (ACPI_FAILURE (Status)) 27267754Smsmith { 27367754Smsmith return_ACPI_STATUS (Status); 27467754Smsmith } 27567754Smsmith 27667754Smsmith if (!ObjDesc) 27767754Smsmith { 27867754Smsmith REPORT_ERROR (("Missing Sleep State object\n")); 27967754Smsmith return_ACPI_STATUS (AE_NOT_EXIST); 28067754Smsmith } 28167754Smsmith 28267754Smsmith /* 28367754Smsmith * We got something, now ensure it is correct. The object must 28467754Smsmith * be a package and must have at least 2 numeric values as the 28567754Smsmith * two elements 28667754Smsmith */ 28767754Smsmith 28877424Smsmith /* Even though AcpiEvaluateObject resolves package references, 28977424Smsmith * NsEvaluate dpesn't. So, we do it here. 29077424Smsmith */ 29177424Smsmith Status = AcpiUtResolvePackageReferences(ObjDesc); 29267754Smsmith 29367754Smsmith if (ObjDesc->Package.Count < 2) 29467754Smsmith { 29567754Smsmith /* Must have at least two elements */ 29667754Smsmith 29767754Smsmith REPORT_ERROR (("Sleep State package does not have at least two elements\n")); 29867754Smsmith Status = AE_ERROR; 29967754Smsmith } 30067754Smsmith 30167754Smsmith else if (((ObjDesc->Package.Elements[0])->Common.Type != 30271867Smsmith ACPI_TYPE_INTEGER) || 30367754Smsmith ((ObjDesc->Package.Elements[1])->Common.Type != 30471867Smsmith ACPI_TYPE_INTEGER)) 30567754Smsmith { 30667754Smsmith /* Must have two */ 30767754Smsmith 30867754Smsmith REPORT_ERROR (("Sleep State package elements are not both of type Number\n")); 30967754Smsmith Status = AE_ERROR; 31067754Smsmith } 31167754Smsmith 31267754Smsmith else 31367754Smsmith { 31467754Smsmith /* 31567754Smsmith * Valid _Sx_ package size, type, and value 31667754Smsmith */ 31771867Smsmith *Slp_TypA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value; 31867754Smsmith 31971867Smsmith *Slp_TypB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.Value; 32067754Smsmith } 32167754Smsmith 32267754Smsmith 32367754Smsmith if (ACPI_FAILURE (Status)) 32467754Smsmith { 32582367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad Sleep object %p type %X\n", 32667754Smsmith ObjDesc, ObjDesc->Common.Type)); 32767754Smsmith } 32867754Smsmith 32977424Smsmith AcpiUtRemoveReference (ObjDesc); 33067754Smsmith 33167754Smsmith return_ACPI_STATUS (Status); 33267754Smsmith} 33367754Smsmith 33467754Smsmith 33567754Smsmith/******************************************************************************* 33667754Smsmith * 33769450Smsmith * FUNCTION: AcpiHwRegisterBitAccess 33867754Smsmith * 33967754Smsmith * PARAMETERS: ReadWrite - Either ACPI_READ or ACPI_WRITE. 34067754Smsmith * UseLock - Lock the hardware 34169450Smsmith * RegisterId - index of ACPI Register to access 34267754Smsmith * Value - (only used on write) value to write to the 34369450Smsmith * Register. Shifted all the way right. 34467754Smsmith * 34569450Smsmith * RETURN: Value written to or read from specified Register. This value 34667754Smsmith * is shifted all the way right. 34767754Smsmith * 34869450Smsmith * DESCRIPTION: Generic ACPI Register read/write function. 34967754Smsmith * 35067754Smsmith ******************************************************************************/ 35167754Smsmith 35267754SmsmithUINT32 35369450SmsmithAcpiHwRegisterBitAccess ( 35467754Smsmith NATIVE_UINT ReadWrite, 35567754Smsmith BOOLEAN UseLock, 35667754Smsmith UINT32 RegisterId, 35767754Smsmith ...) /* Value (only used on write) */ 35867754Smsmith{ 35967754Smsmith UINT32 RegisterValue = 0; 36067754Smsmith UINT32 Mask = 0; 36167754Smsmith UINT32 Value = 0; 36277424Smsmith va_list marker; 36367754Smsmith 36477424Smsmith 36569450Smsmith FUNCTION_TRACE ("HwRegisterBitAccess"); 36667754Smsmith 36767754Smsmith 36867754Smsmith if (ReadWrite == ACPI_WRITE) 36967754Smsmith { 37067754Smsmith va_start (marker, RegisterId); 37167754Smsmith Value = va_arg (marker, UINT32); 37267754Smsmith va_end (marker); 37367754Smsmith } 37467754Smsmith 37577424Smsmith if (ACPI_MTX_LOCK == UseLock) 37677424Smsmith { 37777424Smsmith AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 37869450Smsmith } 37967754Smsmith 38067754Smsmith /* 38167754Smsmith * Decode the Register ID 38277424Smsmith * Register id = Register block id | bit id 38369450Smsmith * 38469450Smsmith * Check bit id to fine locate Register offset. 38577424Smsmith * Check Mask to determine Register offset, and then read-write. 38667754Smsmith */ 38777424Smsmith switch (REGISTER_BLOCK_ID (RegisterId)) 38867754Smsmith { 38969450Smsmith case PM1_STS: 39067754Smsmith 39169450Smsmith switch (RegisterId) 39267754Smsmith { 39369450Smsmith case TMR_STS: 39469450Smsmith Mask = TMR_STS_MASK; 39569450Smsmith break; 39667754Smsmith 39769450Smsmith case BM_STS: 39869450Smsmith Mask = BM_STS_MASK; 39969450Smsmith break; 40067754Smsmith 40169450Smsmith case GBL_STS: 40269450Smsmith Mask = GBL_STS_MASK; 40369450Smsmith break; 40467754Smsmith 40569450Smsmith case PWRBTN_STS: 40669450Smsmith Mask = PWRBTN_STS_MASK; 40769450Smsmith break; 40867754Smsmith 40969450Smsmith case SLPBTN_STS: 41069450Smsmith Mask = SLPBTN_STS_MASK; 41169450Smsmith break; 41267754Smsmith 41369450Smsmith case RTC_STS: 41469450Smsmith Mask = RTC_STS_MASK; 41569450Smsmith break; 41667754Smsmith 41769450Smsmith case WAK_STS: 41869450Smsmith Mask = WAK_STS_MASK; 41969450Smsmith break; 42067754Smsmith 42169450Smsmith default: 42269450Smsmith Mask = 0; 42369450Smsmith break; 42469450Smsmith } 42567754Smsmith 42669450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_STS); 42767754Smsmith 42869450Smsmith if (ReadWrite == ACPI_WRITE) 42969450Smsmith { 43069450Smsmith /* 43169450Smsmith * Status Registers are different from the rest. Clear by 43269450Smsmith * writing 1, writing 0 has no effect. So, the only relevent 43369450Smsmith * information is the single bit we're interested in, all 43469450Smsmith * others should be written as 0 so they will be left 43569450Smsmith * unchanged 43669450Smsmith */ 43769450Smsmith Value <<= AcpiHwGetBitShift (Mask); 43869450Smsmith Value &= Mask; 43967754Smsmith 44069450Smsmith if (Value) 44167754Smsmith { 44277424Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_STS, 44377424Smsmith (UINT16) Value); 44469450Smsmith RegisterValue = 0; 44567754Smsmith } 44667754Smsmith } 44767754Smsmith 44869450Smsmith break; 44967754Smsmith 45067754Smsmith 45169450Smsmith case PM1_EN: 45267754Smsmith 45369450Smsmith switch (RegisterId) 45469450Smsmith { 45569450Smsmith case TMR_EN: 45669450Smsmith Mask = TMR_EN_MASK; 45769450Smsmith break; 45867754Smsmith 45969450Smsmith case GBL_EN: 46069450Smsmith Mask = GBL_EN_MASK; 46169450Smsmith break; 46267754Smsmith 46369450Smsmith case PWRBTN_EN: 46469450Smsmith Mask = PWRBTN_EN_MASK; 46569450Smsmith break; 46667754Smsmith 46769450Smsmith case SLPBTN_EN: 46869450Smsmith Mask = SLPBTN_EN_MASK; 46969450Smsmith break; 47067754Smsmith 47169450Smsmith case RTC_EN: 47269450Smsmith Mask = RTC_EN_MASK; 47369450Smsmith break; 47467754Smsmith 47569450Smsmith default: 47669450Smsmith Mask = 0; 47769450Smsmith break; 47869450Smsmith } 47967754Smsmith 48069450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_EN); 48167754Smsmith 48269450Smsmith if (ReadWrite == ACPI_WRITE) 48369450Smsmith { 48469450Smsmith RegisterValue &= ~Mask; 48569450Smsmith Value <<= AcpiHwGetBitShift (Mask); 48669450Smsmith Value &= Mask; 48769450Smsmith RegisterValue |= Value; 48867754Smsmith 48969450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, PM1_EN, (UINT16) RegisterValue); 49069450Smsmith } 49167754Smsmith 49267754Smsmith break; 49367754Smsmith 49467754Smsmith 49567754Smsmith case PM1_CONTROL: 49667754Smsmith 49767754Smsmith switch (RegisterId) 49867754Smsmith { 49967754Smsmith case SCI_EN: 50067754Smsmith Mask = SCI_EN_MASK; 50167754Smsmith break; 50267754Smsmith 50367754Smsmith case BM_RLD: 50467754Smsmith Mask = BM_RLD_MASK; 50567754Smsmith break; 50667754Smsmith 50767754Smsmith case GBL_RLS: 50867754Smsmith Mask = GBL_RLS_MASK; 50967754Smsmith break; 51067754Smsmith 51167754Smsmith case SLP_TYPE_A: 51267754Smsmith case SLP_TYPE_B: 51367754Smsmith Mask = SLP_TYPE_X_MASK; 51467754Smsmith break; 51567754Smsmith 51667754Smsmith case SLP_EN: 51767754Smsmith Mask = SLP_EN_MASK; 51867754Smsmith break; 51967754Smsmith 52067754Smsmith default: 52167754Smsmith Mask = 0; 52267754Smsmith break; 52367754Smsmith } 52467754Smsmith 52569450Smsmith 52669450Smsmith /* 52769450Smsmith * Read the PM1 Control register. 52869450Smsmith * Note that at this level, the fact that there are actually TWO 52969450Smsmith * registers (A and B) and that B may not exist, are abstracted. 53069450Smsmith */ 53169450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM1_CONTROL); 53269450Smsmith 53382367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", RegisterValue)); 53469450Smsmith 53567754Smsmith if (ReadWrite == ACPI_WRITE) 53667754Smsmith { 53767754Smsmith RegisterValue &= ~Mask; 53867754Smsmith Value <<= AcpiHwGetBitShift (Mask); 53967754Smsmith Value &= Mask; 54067754Smsmith RegisterValue |= Value; 54167754Smsmith 54267754Smsmith /* 54369450Smsmith * SLP_TYPE_x Registers are written differently 54469450Smsmith * than any other control Registers with 54569450Smsmith * respect to A and B Registers. The value 54667754Smsmith * for A may be different than the value for B 54769746Smsmith * 54869746Smsmith * Therefore, pass the RegisterId, not just generic PM1_CONTROL, 54969746Smsmith * because we need to do different things. Yuck. 55067754Smsmith */ 55177424Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId, 55277424Smsmith (UINT16) RegisterValue); 55367754Smsmith } 55467754Smsmith break; 55567754Smsmith 55667754Smsmith 55767754Smsmith case PM2_CONTROL: 55867754Smsmith 55967754Smsmith switch (RegisterId) 56067754Smsmith { 56167754Smsmith case ARB_DIS: 56267754Smsmith Mask = ARB_DIS_MASK; 56367754Smsmith break; 56467754Smsmith 56567754Smsmith default: 56667754Smsmith Mask = 0; 56767754Smsmith break; 56867754Smsmith } 56967754Smsmith 57069450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, PM2_CONTROL); 57169450Smsmith 57285756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n", 57385756Smsmith RegisterValue, HIDWORD(AcpiGbl_FADT->XPm2CntBlk.Address), 57485756Smsmith LODWORD(AcpiGbl_FADT->XPm2CntBlk.Address))); 57569450Smsmith 57667754Smsmith if (ReadWrite == ACPI_WRITE) 57767754Smsmith { 57867754Smsmith RegisterValue &= ~Mask; 57967754Smsmith Value <<= AcpiHwGetBitShift (Mask); 58067754Smsmith Value &= Mask; 58167754Smsmith RegisterValue |= Value; 58267754Smsmith 58385756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", 58485756Smsmith RegisterValue, 58585756Smsmith HIDWORD(AcpiGbl_FADT->XPm2CntBlk.Address), 58685756Smsmith LODWORD(AcpiGbl_FADT->XPm2CntBlk.Address))); 58767754Smsmith 58869450Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 58969450Smsmith PM2_CONTROL, (UINT8) (RegisterValue)); 59067754Smsmith } 59167754Smsmith break; 59267754Smsmith 59367754Smsmith 59467754Smsmith case PM_TIMER: 59567754Smsmith 59669450Smsmith Mask = TMR_VAL_MASK; 59769450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 59869450Smsmith PM_TIMER); 59985756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM_TIMER: Read %X from %8.8X%8.8X\n", 60085756Smsmith RegisterValue, 60185756Smsmith HIDWORD(AcpiGbl_FADT->XPmTmrBlk.Address), 60285756Smsmith LODWORD(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 */ 62369450Smsmith Mask = REGISTER_BIT_ID(RegisterId); /* gpe_bit_number */ 62469450Smsmith RegisterId = REGISTER_BLOCK_ID(RegisterId) | (Mask >> 3); 62569450Smsmith Mask = AcpiGbl_DecodeTo8bit [Mask % 8]; 62667754Smsmith 62767754Smsmith /* 62867754Smsmith * The base address of the GPE 0 Register Block 62967754Smsmith * Plus 1/2 the length of the GPE 0 Register Block 63069450Smsmith * The enable Register is the Register following the Status Register 63169450Smsmith * and each Register is defined as 1/2 of the total Register Block 63267754Smsmith */ 63367754Smsmith 63467754Smsmith /* 63567754Smsmith * This sets the bit within EnableBit that needs to be written to 63669450Smsmith * the Register indicated in Mask to a 1, all others are 0 63767754Smsmith */ 63867754Smsmith 63967754Smsmith /* Now get the current Enable Bits in the selected Reg */ 64067754Smsmith 64169450Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, RegisterId); 64282367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_IO, "GPE Enable bits: Read %X from %X\n", 64377424Smsmith RegisterValue, RegisterId)); 64467754Smsmith 64567754Smsmith if (ReadWrite == ACPI_WRITE) 64667754Smsmith { 64767754Smsmith RegisterValue &= ~Mask; 64867754Smsmith Value <<= AcpiHwGetBitShift (Mask); 64967754Smsmith Value &= Mask; 65067754Smsmith RegisterValue |= Value; 65167754Smsmith 65283174Smsmith /* 65383174Smsmith * This write will put the Action state into the General Purpose 65483174Smsmith * Enable Register indexed by the value in Mask 65583174Smsmith */ 65682367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n", 65777424Smsmith RegisterValue, RegisterId)); 65877424Smsmith AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId, 65977424Smsmith (UINT8) RegisterValue); 66077424Smsmith RegisterValue = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 66177424Smsmith RegisterId); 66267754Smsmith } 66367754Smsmith break; 66467754Smsmith 66567754Smsmith 66669450Smsmith case SMI_CMD_BLOCK: 66767754Smsmith case PROCESSOR_BLOCK: 66883174Smsmith 66977424Smsmith /* Not used by any callers at this time - therefore, not implemented */ 67077424Smsmith 67167754Smsmith default: 67267754Smsmith 67367754Smsmith Mask = 0; 67467754Smsmith break; 67567754Smsmith } 67667754Smsmith 67769450Smsmith if (ACPI_MTX_LOCK == UseLock) { 67877424Smsmith AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 67969450Smsmith } 68067754Smsmith 68169450Smsmith 68267754Smsmith RegisterValue &= Mask; 68367754Smsmith RegisterValue >>= AcpiHwGetBitShift (Mask); 68467754Smsmith 68582367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Register I/O: returning %X\n", RegisterValue)); 68667754Smsmith return_VALUE (RegisterValue); 68767754Smsmith} 68869450Smsmith 68969450Smsmith 69069450Smsmith/****************************************************************************** 69169450Smsmith * 69269450Smsmith * FUNCTION: AcpiHwRegisterRead 69369450Smsmith * 69469450Smsmith * PARAMETERS: UseLock - Mutex hw access. 69569450Smsmith * RegisterId - RegisterID + Offset. 69669450Smsmith * 69769450Smsmith * RETURN: Value read or written. 69869450Smsmith * 69969450Smsmith * DESCRIPTION: Acpi register read function. Registers are read at the 70069450Smsmith * given offset. 70169450Smsmith * 70269450Smsmith ******************************************************************************/ 70369450Smsmith 70469450SmsmithUINT32 70569450SmsmithAcpiHwRegisterRead ( 70669450Smsmith BOOLEAN UseLock, 70769450Smsmith UINT32 RegisterId) 70869450Smsmith{ 70980062Smsmith UINT32 Value = 0; 71069450Smsmith UINT32 BankOffset; 71169450Smsmith 71277424Smsmith 71383174Smsmith FUNCTION_TRACE ("HwRegisterRead"); 71469450Smsmith 71577424Smsmith 71669450Smsmith if (ACPI_MTX_LOCK == UseLock) 71769450Smsmith { 71877424Smsmith AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 71969450Smsmith } 72069450Smsmith 72169450Smsmith 72269450Smsmith switch (REGISTER_BLOCK_ID(RegisterId)) 72369450Smsmith { 72469450Smsmith case PM1_STS: /* 16-bit access */ 72569450Smsmith 72669746Smsmith Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, 0); 72769746Smsmith Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, 0); 72869450Smsmith break; 72969450Smsmith 73069450Smsmith 73169450Smsmith case PM1_EN: /* 16-bit access*/ 73269450Smsmith 73369450Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Pm1EvtLen); 73469746Smsmith Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset); 73569746Smsmith Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset); 73669450Smsmith break; 73769450Smsmith 73869450Smsmith 73969450Smsmith case PM1_CONTROL: /* 16-bit access */ 74069450Smsmith 74171867Smsmith Value = AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1aCntBlk, 0); 74271867Smsmith Value |= AcpiHwLowLevelRead (16, &AcpiGbl_FADT->XPm1bCntBlk, 0); 74369450Smsmith break; 74469450Smsmith 74569450Smsmith 74669450Smsmith case PM2_CONTROL: /* 8-bit access */ 74769450Smsmith 74869746Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XPm2CntBlk, 0); 74969450Smsmith break; 75069450Smsmith 75169450Smsmith 75269450Smsmith case PM_TIMER: /* 32-bit access */ 75369450Smsmith 75469746Smsmith Value = AcpiHwLowLevelRead (32, &AcpiGbl_FADT->XPmTmrBlk, 0); 75569450Smsmith break; 75669450Smsmith 75769450Smsmith 75882367Smsmith /* 75983174Smsmith * For the GPE? Blocks, the lower word of RegisterId contains the 76083174Smsmith * byte offset for which to read, as each part of each block may be 76182367Smsmith * several bytes long. 76282367Smsmith */ 76369450Smsmith case GPE0_STS_BLOCK: /* 8-bit access */ 76469450Smsmith 76583174Smsmith BankOffset = REGISTER_BIT_ID(RegisterId); 76682367Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset); 76769450Smsmith break; 76869450Smsmith 76969450Smsmith case GPE0_EN_BLOCK: /* 8-bit access */ 77069450Smsmith 77182367Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen) + REGISTER_BIT_ID(RegisterId); 77282367Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe0Blk, BankOffset); 77369450Smsmith break; 77469450Smsmith 77569450Smsmith case GPE1_STS_BLOCK: /* 8-bit access */ 77669450Smsmith 77783174Smsmith BankOffset = REGISTER_BIT_ID(RegisterId); 77882367Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset); 77969450Smsmith break; 78069450Smsmith 78169450Smsmith case GPE1_EN_BLOCK: /* 8-bit access */ 78269450Smsmith 78382367Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen) + REGISTER_BIT_ID(RegisterId); 78482367Smsmith Value = AcpiHwLowLevelRead (8, &AcpiGbl_FADT->XGpe1Blk, BankOffset); 78569450Smsmith break; 78669450Smsmith 78769450Smsmith case SMI_CMD_BLOCK: /* 8bit */ 78869450Smsmith 78980062Smsmith AcpiOsReadPort (AcpiGbl_FADT->SmiCmd, &Value, 8); 79069450Smsmith break; 79169450Smsmith 79269450Smsmith default: 79380062Smsmith /* Value will be returned as 0 */ 79469450Smsmith break; 79569450Smsmith } 79669450Smsmith 79769450Smsmith 79869450Smsmith if (ACPI_MTX_LOCK == UseLock) 79969450Smsmith { 80077424Smsmith AcpiUtReleaseMutex (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 83083174Smsmith FUNCTION_TRACE ("HwRegisterWrite"); 83169450Smsmith 83283174Smsmith 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 88983174Smsmith BankOffset = REGISTER_BIT_ID(RegisterId); 89082367Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset); 89169450Smsmith break; 89269450Smsmith 89369450Smsmith 89469450Smsmith case GPE0_EN_BLOCK: /* 8-bit access */ 89569450Smsmith 89682367Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe0BlkLen) + REGISTER_BIT_ID(RegisterId); 89769746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe0Blk, BankOffset); 89869450Smsmith break; 89969450Smsmith 90069450Smsmith 90169450Smsmith case GPE1_STS_BLOCK: /* 8-bit access */ 90269450Smsmith 90383174Smsmith BankOffset = REGISTER_BIT_ID(RegisterId); 90482367Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset); 90569450Smsmith break; 90669450Smsmith 90769450Smsmith 90869450Smsmith case GPE1_EN_BLOCK: /* 8-bit access */ 90969450Smsmith 91082367Smsmith BankOffset = DIV_2 (AcpiGbl_FADT->Gpe1BlkLen) + REGISTER_BIT_ID(RegisterId); 91169746Smsmith AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XGpe1Blk, BankOffset); 91269450Smsmith break; 91369450Smsmith 91469450Smsmith 91569450Smsmith case SMI_CMD_BLOCK: /* 8bit */ 91669450Smsmith 91769450Smsmith /* For 2.0, SMI_CMD is always in IO space */ 91869450Smsmith /* TBD: what about 1.0? 0.71? */ 91969450Smsmith 92080062Smsmith AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, Value, 8); 92169450Smsmith break; 92269450Smsmith 92369450Smsmith 92469450Smsmith default: 92569450Smsmith Value = 0; 92669450Smsmith break; 92769450Smsmith } 92869450Smsmith 92969450Smsmith 93069450Smsmith if (ACPI_MTX_LOCK == UseLock) 93169450Smsmith { 93277424Smsmith AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 93369450Smsmith } 93469450Smsmith 93569450Smsmith return_VOID; 93669450Smsmith} 93769450Smsmith 93869450Smsmith 93969450Smsmith/****************************************************************************** 94069450Smsmith * 94169450Smsmith * FUNCTION: AcpiHwLowLevelRead 94269450Smsmith * 94369450Smsmith * PARAMETERS: Register - GAS register structure 94469450Smsmith * Offset - Offset from the base address in the GAS 94569450Smsmith * Width - 8, 16, or 32 94669450Smsmith * 94769450Smsmith * RETURN: Value read 94869450Smsmith * 94969450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space. 95069450Smsmith * 95169450Smsmith ******************************************************************************/ 95269450Smsmith 95369450SmsmithUINT32 95469450SmsmithAcpiHwLowLevelRead ( 95569450Smsmith UINT32 Width, 95677424Smsmith ACPI_GENERIC_ADDRESS *Reg, 95769450Smsmith UINT32 Offset) 95869450Smsmith{ 95969450Smsmith UINT32 Value = 0; 96069450Smsmith ACPI_PHYSICAL_ADDRESS MemAddress; 96169450Smsmith ACPI_IO_ADDRESS IoAddress; 96280062Smsmith ACPI_PCI_ID PciId; 96380062Smsmith UINT16 PciRegister; 96469450Smsmith 96569450Smsmith 96683174Smsmith FUNCTION_ENTRY (); 96783174Smsmith 96883174Smsmith 96969450Smsmith /* 97069450Smsmith * Must have a valid pointer to a GAS structure, and 97169450Smsmith * a non-zero address within 97269450Smsmith */ 97369450Smsmith if ((!Reg) || 97470243Smsmith (!ACPI_VALID_ADDRESS (Reg->Address))) 97569450Smsmith { 97669450Smsmith return 0; 97769450Smsmith } 97869450Smsmith 97969450Smsmith 98069450Smsmith /* 98169450Smsmith * Three address spaces supported: 98269450Smsmith * Memory, Io, or PCI config. 98369450Smsmith */ 98469450Smsmith switch (Reg->AddressSpaceId) 98569450Smsmith { 98677424Smsmith case ACPI_ADR_SPACE_SYSTEM_MEMORY: 98769450Smsmith 98870243Smsmith MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 98969450Smsmith 99080062Smsmith AcpiOsReadMemory (MemAddress, &Value, Width); 99169450Smsmith break; 99269450Smsmith 99369450Smsmith 99477424Smsmith case ACPI_ADR_SPACE_SYSTEM_IO: 99569450Smsmith 99670243Smsmith IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 99769450Smsmith 99880062Smsmith AcpiOsReadPort (IoAddress, &Value, Width); 99969450Smsmith break; 100069450Smsmith 100169450Smsmith 100277424Smsmith case ACPI_ADR_SPACE_PCI_CONFIG: 100369450Smsmith 100480062Smsmith PciId.Segment = 0; 100580062Smsmith PciId.Bus = 0; 100680062Smsmith PciId.Device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address)); 100780062Smsmith PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address)); 100880062Smsmith PciRegister = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset); 100969450Smsmith 101080062Smsmith AcpiOsReadPciConfiguration (&PciId, PciRegister, &Value, Width); 101169450Smsmith break; 101269450Smsmith } 101369450Smsmith 101469450Smsmith return Value; 101569450Smsmith} 101669450Smsmith 101769450Smsmith 101869450Smsmith/****************************************************************************** 101969450Smsmith * 102069450Smsmith * FUNCTION: AcpiHwLowLevelWrite 102169450Smsmith * 102269450Smsmith * PARAMETERS: Width - 8, 16, or 32 102369450Smsmith * Value - To be written 102469450Smsmith * Register - GAS register structure 102569450Smsmith * Offset - Offset from the base address in the GAS 102669450Smsmith * 102769450Smsmith * 102869450Smsmith * RETURN: Value read 102969450Smsmith * 103069450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space. 103169450Smsmith * 103269450Smsmith ******************************************************************************/ 103369450Smsmith 103469450Smsmithvoid 103569450SmsmithAcpiHwLowLevelWrite ( 103669450Smsmith UINT32 Width, 103769450Smsmith UINT32 Value, 103877424Smsmith ACPI_GENERIC_ADDRESS *Reg, 103969450Smsmith UINT32 Offset) 104069450Smsmith{ 104169450Smsmith ACPI_PHYSICAL_ADDRESS MemAddress; 104269450Smsmith ACPI_IO_ADDRESS IoAddress; 104380062Smsmith ACPI_PCI_ID PciId; 104480062Smsmith UINT16 PciRegister; 104569450Smsmith 104669450Smsmith 104783174Smsmith FUNCTION_ENTRY (); 104883174Smsmith 104983174Smsmith 105069450Smsmith /* 105169450Smsmith * Must have a valid pointer to a GAS structure, and 105269450Smsmith * a non-zero address within 105369450Smsmith */ 105469450Smsmith if ((!Reg) || 105570243Smsmith (!ACPI_VALID_ADDRESS (Reg->Address))) 105669450Smsmith { 105769450Smsmith return; 105869450Smsmith } 105969450Smsmith 106069450Smsmith 106169450Smsmith /* 106269450Smsmith * Three address spaces supported: 106369450Smsmith * Memory, Io, or PCI config. 106469450Smsmith */ 106569450Smsmith switch (Reg->AddressSpaceId) 106669450Smsmith { 106777424Smsmith case ACPI_ADR_SPACE_SYSTEM_MEMORY: 106869450Smsmith 106970243Smsmith MemAddress = (ACPI_PHYSICAL_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 107069450Smsmith 107180062Smsmith AcpiOsWriteMemory (MemAddress, Value, Width); 107269450Smsmith break; 107369450Smsmith 107469450Smsmith 107577424Smsmith case ACPI_ADR_SPACE_SYSTEM_IO: 107669450Smsmith 107770243Smsmith IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) + Offset); 107869450Smsmith 107980062Smsmith AcpiOsWritePort (IoAddress, Value, Width); 108069450Smsmith break; 108169450Smsmith 108269450Smsmith 108377424Smsmith case ACPI_ADR_SPACE_PCI_CONFIG: 108469450Smsmith 108580062Smsmith PciId.Segment = 0; 108680062Smsmith PciId.Bus = 0; 108780062Smsmith PciId.Device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address)); 108880062Smsmith PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address)); 108980062Smsmith PciRegister = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) + Offset); 109069450Smsmith 109180062Smsmith AcpiOsWritePciConfiguration (&PciId, PciRegister, Value, Width); 109269450Smsmith break; 109369450Smsmith } 109469450Smsmith} 1095