hwregs.c revision 102550
167754Smsmith 267754Smsmith/******************************************************************************* 367754Smsmith * 467754Smsmith * Module Name: hwregs - Read/write access functions for the various ACPI 567754Smsmith * control and status registers. 6102550Siwasaki * $Revision: 134 $ 767754Smsmith * 867754Smsmith ******************************************************************************/ 967754Smsmith 1067754Smsmith/****************************************************************************** 1167754Smsmith * 1267754Smsmith * 1. Copyright Notice 1367754Smsmith * 1491116Smsmith * Some or all of this work - Copyright (c) 1999 - 2002, 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 "acnamesp.h" 12367754Smsmith 12477424Smsmith#define _COMPONENT ACPI_HARDWARE 12591116Smsmith ACPI_MODULE_NAME ("hwregs") 12667754Smsmith 12767754Smsmith 12867754Smsmith/******************************************************************************* 12967754Smsmith * 13067754Smsmith * FUNCTION: AcpiHwClearAcpiStatus 13167754Smsmith * 13267754Smsmith * PARAMETERS: none 13367754Smsmith * 13467754Smsmith * RETURN: none 13567754Smsmith * 13667754Smsmith * DESCRIPTION: Clears all fixed and general purpose status bits 13767754Smsmith * 13867754Smsmith ******************************************************************************/ 13967754Smsmith 14099679SiwasakiACPI_STATUS 14167754SmsmithAcpiHwClearAcpiStatus (void) 14267754Smsmith{ 14399679Siwasaki NATIVE_UINT_MAX32 i; 14491116Smsmith NATIVE_UINT GpeBlock; 14591116Smsmith ACPI_STATUS Status; 14667754Smsmith 14767754Smsmith 14891116Smsmith ACPI_FUNCTION_TRACE ("HwClearAcpiStatus"); 14967754Smsmith 15067754Smsmith 15182367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %04X\n", 15291116Smsmith ACPI_BITMASK_ALL_FIXED_STATUS, 15377424Smsmith (UINT16) ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm1aEvtBlk.Address))); 15467754Smsmith 15567754Smsmith 15691116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 15791116Smsmith if (ACPI_FAILURE (Status)) 15891116Smsmith { 15999679Siwasaki return_ACPI_STATUS (Status); 16091116Smsmith } 16167754Smsmith 16299679Siwasaki Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS, 16399679Siwasaki ACPI_BITMASK_ALL_FIXED_STATUS); 16499679Siwasaki if (ACPI_FAILURE (Status)) 16599679Siwasaki { 16699679Siwasaki goto UnlockAndExit; 16799679Siwasaki } 16867754Smsmith 16991116Smsmith /* Clear the fixed events */ 17069450Smsmith 17170243Smsmith if (ACPI_VALID_ADDRESS (AcpiGbl_FADT->XPm1bEvtBlk.Address)) 17267754Smsmith { 17399679Siwasaki Status = AcpiHwLowLevelWrite (16, ACPI_BITMASK_ALL_FIXED_STATUS, 17499679Siwasaki &AcpiGbl_FADT->XPm1bEvtBlk, 0); 17599679Siwasaki if (ACPI_FAILURE (Status)) 17699679Siwasaki { 17799679Siwasaki goto UnlockAndExit; 17899679Siwasaki } 17967754Smsmith } 18067754Smsmith 18191116Smsmith /* Clear the GPE Bits */ 18267754Smsmith 18391116Smsmith for (GpeBlock = 0; GpeBlock < ACPI_MAX_GPE_BLOCKS; GpeBlock++) 18467754Smsmith { 18591116Smsmith for (i = 0; i < AcpiGbl_GpeBlockInfo[GpeBlock].RegisterCount; i++) 18667754Smsmith { 18799679Siwasaki Status = AcpiHwLowLevelWrite (8, 0xFF, 18899679Siwasaki AcpiGbl_GpeBlockInfo[GpeBlock].BlockAddress, i); 18999679Siwasaki if (ACPI_FAILURE (Status)) 19099679Siwasaki { 19199679Siwasaki goto UnlockAndExit; 19299679Siwasaki } 19367754Smsmith } 19467754Smsmith } 19567754Smsmith 19699679SiwasakiUnlockAndExit: 19791116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 19899679Siwasaki return_ACPI_STATUS (Status); 19967754Smsmith} 20067754Smsmith 20167754Smsmith 20267754Smsmith/******************************************************************************* 20367754Smsmith * 20499679Siwasaki * FUNCTION: AcpiGetSleepTypeData 20567754Smsmith * 20691116Smsmith * PARAMETERS: SleepState - Numeric sleep state 20791116Smsmith * *SleepTypeA - Where SLP_TYPa is returned 20891116Smsmith * *SleepTypeB - Where SLP_TYPb is returned 20967754Smsmith * 21067754Smsmith * RETURN: Status - ACPI status 21167754Smsmith * 21291116Smsmith * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep 21391116Smsmith * state. 21467754Smsmith * 21567754Smsmith ******************************************************************************/ 21667754Smsmith 21767754SmsmithACPI_STATUS 21899679SiwasakiAcpiGetSleepTypeData ( 21967754Smsmith UINT8 SleepState, 22091116Smsmith UINT8 *SleepTypeA, 22191116Smsmith UINT8 *SleepTypeB) 22267754Smsmith{ 22367754Smsmith ACPI_STATUS Status = AE_OK; 22467754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 22567754Smsmith 22667754Smsmith 22799679Siwasaki ACPI_FUNCTION_TRACE ("AcpiGetSleepTypeData"); 22867754Smsmith 22967754Smsmith 23067754Smsmith /* 23199679Siwasaki * Validate parameters 23267754Smsmith */ 23367754Smsmith if ((SleepState > ACPI_S_STATES_MAX) || 23491116Smsmith !SleepTypeA || !SleepTypeB) 23567754Smsmith { 23667754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 23767754Smsmith } 23867754Smsmith 23967754Smsmith /* 24099679Siwasaki * Evaluate the namespace object containing the values for this state 24167754Smsmith */ 24283174Smsmith Status = AcpiNsEvaluateByName ((NATIVE_CHAR *) AcpiGbl_DbSleepStates[SleepState], 24383174Smsmith NULL, &ObjDesc); 24467754Smsmith if (ACPI_FAILURE (Status)) 24567754Smsmith { 24667754Smsmith return_ACPI_STATUS (Status); 24767754Smsmith } 24867754Smsmith 24999679Siwasaki /* Must have a return object */ 25099679Siwasaki 25167754Smsmith if (!ObjDesc) 25267754Smsmith { 25391116Smsmith ACPI_REPORT_ERROR (("Missing Sleep State object\n")); 25499679Siwasaki Status = AE_NOT_EXIST; 25567754Smsmith } 25667754Smsmith 25799679Siwasaki /* It must be of type Package */ 25867754Smsmith 25999679Siwasaki else if (ACPI_GET_OBJECT_TYPE (ObjDesc) != ACPI_TYPE_PACKAGE) 26099679Siwasaki { 26199679Siwasaki ACPI_REPORT_ERROR (("Sleep State object not a Package\n")); 26299679Siwasaki Status = AE_AML_OPERAND_TYPE; 26399679Siwasaki } 26467754Smsmith 26599679Siwasaki /* The package must have at least two elements */ 26699679Siwasaki 26799679Siwasaki else if (ObjDesc->Package.Count < 2) 26867754Smsmith { 26991116Smsmith ACPI_REPORT_ERROR (("Sleep State package does not have at least two elements\n")); 27091116Smsmith Status = AE_AML_NO_OPERAND; 27167754Smsmith } 27299679Siwasaki 27399679Siwasaki /* The first two elements must both be of type Integer */ 27499679Siwasaki 27599679Siwasaki else if ((ACPI_GET_OBJECT_TYPE (ObjDesc->Package.Elements[0]) != ACPI_TYPE_INTEGER) || 27699679Siwasaki (ACPI_GET_OBJECT_TYPE (ObjDesc->Package.Elements[1]) != ACPI_TYPE_INTEGER)) 27767754Smsmith { 27899679Siwasaki ACPI_REPORT_ERROR (("Sleep State package elements are not both Integers (%s, %s)\n", 27999679Siwasaki AcpiUtGetObjectTypeName (ObjDesc->Package.Elements[0]), 28099679Siwasaki AcpiUtGetObjectTypeName (ObjDesc->Package.Elements[1]))); 28191116Smsmith Status = AE_AML_OPERAND_TYPE; 28267754Smsmith } 28367754Smsmith else 28467754Smsmith { 28567754Smsmith /* 28699679Siwasaki * Valid _Sx_ package size, type, and value 28767754Smsmith */ 28891116Smsmith *SleepTypeA = (UINT8) (ObjDesc->Package.Elements[0])->Integer.Value; 28991116Smsmith *SleepTypeB = (UINT8) (ObjDesc->Package.Elements[1])->Integer.Value; 29067754Smsmith } 29167754Smsmith 29267754Smsmith if (ACPI_FAILURE (Status)) 29367754Smsmith { 29499679Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Bad Sleep object %p type %s\n", 29599679Siwasaki ObjDesc, AcpiUtGetObjectTypeName (ObjDesc))); 29667754Smsmith } 29767754Smsmith 29877424Smsmith AcpiUtRemoveReference (ObjDesc); 29967754Smsmith return_ACPI_STATUS (Status); 30067754Smsmith} 30167754Smsmith 30267754Smsmith 30367754Smsmith/******************************************************************************* 30467754Smsmith * 30591116Smsmith * FUNCTION: AcpiHwGetRegisterBitMask 30667754Smsmith * 30799679Siwasaki * PARAMETERS: RegisterId - Index of ACPI Register to access 308102550Siwasaki * 30991116Smsmith * RETURN: The bit mask to be used when accessing the register 31091116Smsmith * 31191116Smsmith * DESCRIPTION: Map RegisterId into a register bit mask. 31291116Smsmith * 31391116Smsmith ******************************************************************************/ 31491116Smsmith 31591116SmsmithACPI_BIT_REGISTER_INFO * 31691116SmsmithAcpiHwGetBitRegisterInfo ( 31791116Smsmith UINT32 RegisterId) 31891116Smsmith{ 31991116Smsmith ACPI_FUNCTION_NAME ("HwGetBitRegisterInfo"); 32091116Smsmith 32191116Smsmith 32291116Smsmith if (RegisterId > ACPI_BITREG_MAX) 32391116Smsmith { 32491116Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid BitRegister ID: %X\n", RegisterId)); 32591116Smsmith return (NULL); 32691116Smsmith } 32791116Smsmith 32891116Smsmith return (&AcpiGbl_BitRegisterInfo[RegisterId]); 32991116Smsmith} 33091116Smsmith 33191116Smsmith 33291116Smsmith/******************************************************************************* 33391116Smsmith * 33499679Siwasaki * FUNCTION: AcpiGetRegister 33591116Smsmith * 33699679Siwasaki * PARAMETERS: RegisterId - Index of ACPI Register to access 33799679Siwasaki * UseLock - Lock the hardware 33867754Smsmith * 33991116Smsmith * RETURN: Value is read from specified Register. Value returned is 34091116Smsmith * normalized to bit0 (is shifted all the way right) 34167754Smsmith * 34291116Smsmith * DESCRIPTION: ACPI BitRegister read function. 34367754Smsmith * 34467754Smsmith ******************************************************************************/ 34567754Smsmith 34699679SiwasakiACPI_STATUS 34799679SiwasakiAcpiGetRegister ( 34867754Smsmith UINT32 RegisterId, 34999679Siwasaki UINT32 *ReturnValue, 35091116Smsmith UINT32 Flags) 35167754Smsmith{ 35267754Smsmith UINT32 RegisterValue = 0; 35391116Smsmith ACPI_BIT_REGISTER_INFO *BitRegInfo; 35499679Siwasaki ACPI_STATUS Status; 35567754Smsmith 35677424Smsmith 35799679Siwasaki ACPI_FUNCTION_TRACE ("AcpiGetRegister"); 35867754Smsmith 35967754Smsmith 36091116Smsmith /* Get the info structure corresponding to the requested ACPI Register */ 36191116Smsmith 36291116Smsmith BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId); 36391116Smsmith if (!BitRegInfo) 36477424Smsmith { 36591116Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 36669450Smsmith } 36767754Smsmith 36899679Siwasaki if (Flags & ACPI_MTX_LOCK) 36999679Siwasaki { 37099679Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 37199679Siwasaki if (ACPI_FAILURE (Status)) 37299679Siwasaki { 37399679Siwasaki return_ACPI_STATUS (Status); 37499679Siwasaki } 37599679Siwasaki } 37691116Smsmith 377102550Siwasaki Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 37899679Siwasaki BitRegInfo->ParentRegister, &RegisterValue); 37999679Siwasaki 38091116Smsmith if (Flags & ACPI_MTX_LOCK) 38167754Smsmith { 38291116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 38391116Smsmith } 38467754Smsmith 38599679Siwasaki if (ACPI_SUCCESS (Status)) 38699679Siwasaki { 38799679Siwasaki /* Normalize the value that was read */ 38867754Smsmith 389102550Siwasaki RegisterValue = ((RegisterValue & BitRegInfo->AccessBitMask) 39099679Siwasaki >> BitRegInfo->BitPosition); 39167754Smsmith 39299679Siwasaki *ReturnValue = RegisterValue; 39399679Siwasaki 39499679Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_IO, "Read value %X\n", RegisterValue)); 39599679Siwasaki } 39699679Siwasaki 39799679Siwasaki return_ACPI_STATUS (Status); 39891116Smsmith} 39967754Smsmith 40067754Smsmith 40191116Smsmith/******************************************************************************* 40291116Smsmith * 40399679Siwasaki * FUNCTION: AcpiSetRegister 40491116Smsmith * 40591116Smsmith * PARAMETERS: RegisterId - ID of ACPI BitRegister to access 40691116Smsmith * Value - (only used on write) value to write to the 40791116Smsmith * Register, NOT pre-normalized to the bit pos. 40891116Smsmith * Flags - Lock the hardware or not 40991116Smsmith * 41099679Siwasaki * RETURN: None 41191116Smsmith * 41291116Smsmith * DESCRIPTION: ACPI Bit Register write function. 41391116Smsmith * 41491116Smsmith ******************************************************************************/ 41567754Smsmith 41699679SiwasakiACPI_STATUS 41799679SiwasakiAcpiSetRegister ( 41891116Smsmith UINT32 RegisterId, 41991116Smsmith UINT32 Value, 42091116Smsmith UINT32 Flags) 42191116Smsmith{ 42291116Smsmith UINT32 RegisterValue = 0; 42391116Smsmith ACPI_BIT_REGISTER_INFO *BitRegInfo; 42499679Siwasaki ACPI_STATUS Status; 42567754Smsmith 42667754Smsmith 42799679Siwasaki ACPI_FUNCTION_TRACE_U32 ("AcpiSetRegister", RegisterId); 42867754Smsmith 42967754Smsmith 43091116Smsmith /* Get the info structure corresponding to the requested ACPI Register */ 43167754Smsmith 43291116Smsmith BitRegInfo = AcpiHwGetBitRegisterInfo (RegisterId); 43391116Smsmith if (!BitRegInfo) 43491116Smsmith { 43599679Siwasaki ACPI_REPORT_ERROR (("Bad ACPI HW RegisterId: %X\n", RegisterId)); 43691116Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 43791116Smsmith } 43867754Smsmith 43999679Siwasaki if (Flags & ACPI_MTX_LOCK) 44099679Siwasaki { 44199679Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 44299679Siwasaki if (ACPI_FAILURE (Status)) 44399679Siwasaki { 44499679Siwasaki return_ACPI_STATUS (Status); 44599679Siwasaki } 44699679Siwasaki } 44799679Siwasaki 44891116Smsmith /* Always do a register read first so we can insert the new bits */ 44967754Smsmith 450102550Siwasaki Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 45199679Siwasaki BitRegInfo->ParentRegister, &RegisterValue); 45299679Siwasaki if (ACPI_FAILURE (Status)) 45399679Siwasaki { 45499679Siwasaki goto UnlockAndExit; 45599679Siwasaki } 45667754Smsmith 45791116Smsmith /* 45891116Smsmith * Decode the Register ID 45991116Smsmith * Register id = Register block id | bit id 46091116Smsmith * 46191116Smsmith * Check bit id to fine locate Register offset. 46291116Smsmith * Check Mask to determine Register offset, and then read-write. 46391116Smsmith */ 46491116Smsmith switch (BitRegInfo->ParentRegister) 46591116Smsmith { 46691116Smsmith case ACPI_REGISTER_PM1_STATUS: 46767754Smsmith 46891116Smsmith /* 46991116Smsmith * Status Registers are different from the rest. Clear by 47091116Smsmith * writing 1, writing 0 has no effect. So, the only relevent 47191116Smsmith * information is the single bit we're interested in, all others should 47291116Smsmith * be written as 0 so they will be left unchanged 47391116Smsmith */ 474102550Siwasaki Value = ACPI_REGISTER_PREPARE_BITS (Value, 47599679Siwasaki BitRegInfo->BitPosition, BitRegInfo->AccessBitMask); 47691116Smsmith if (Value) 47769450Smsmith { 478102550Siwasaki Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 47999679Siwasaki ACPI_REGISTER_PM1_STATUS, (UINT16) Value); 48091116Smsmith RegisterValue = 0; 48169450Smsmith } 48267754Smsmith break; 48367754Smsmith 48467754Smsmith 48591116Smsmith case ACPI_REGISTER_PM1_ENABLE: 48667754Smsmith 487102550Siwasaki ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition, 48899679Siwasaki BitRegInfo->AccessBitMask, Value); 48967754Smsmith 490102550Siwasaki Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 49199679Siwasaki ACPI_REGISTER_PM1_ENABLE, (UINT16) RegisterValue); 49291116Smsmith break; 49367754Smsmith 49467754Smsmith 49591116Smsmith case ACPI_REGISTER_PM1_CONTROL: 49667754Smsmith 49769450Smsmith /* 49869450Smsmith * Read the PM1 Control register. 49969450Smsmith * Note that at this level, the fact that there are actually TWO 50091116Smsmith * registers (A and B - and that B may not exist) is abstracted. 50169450Smsmith */ 50282367Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM1 control: Read %X\n", RegisterValue)); 50369450Smsmith 504102550Siwasaki ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition, 50599679Siwasaki BitRegInfo->AccessBitMask, Value); 50667754Smsmith 50799679Siwasaki Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, RegisterId, 50891116Smsmith (UINT16) RegisterValue); 50967754Smsmith break; 51067754Smsmith 51167754Smsmith 51291116Smsmith case ACPI_REGISTER_PM2_CONTROL: 51367754Smsmith 514102550Siwasaki Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 51599679Siwasaki ACPI_REGISTER_PM2_CONTROL, &RegisterValue); 51699679Siwasaki if (ACPI_FAILURE (Status)) 51799679Siwasaki { 51899679Siwasaki goto UnlockAndExit; 51999679Siwasaki } 52067754Smsmith 52185756Smsmith ACPI_DEBUG_PRINT ((ACPI_DB_IO, "PM2 control: Read %X from %8.8X%8.8X\n", 522102550Siwasaki RegisterValue, 52399679Siwasaki ACPI_HIDWORD (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)), 52499679Siwasaki ACPI_LODWORD (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)))); 52569450Smsmith 526102550Siwasaki ACPI_REGISTER_INSERT_VALUE (RegisterValue, BitRegInfo->BitPosition, 52799679Siwasaki BitRegInfo->AccessBitMask, Value); 52867754Smsmith 52999679Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %4.4X to %8.8X%8.8X\n", 53085756Smsmith RegisterValue, 53199679Siwasaki ACPI_HIDWORD (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)), 53299679Siwasaki ACPI_LODWORD (ACPI_GET_ADDRESS (AcpiGbl_FADT->XPm2CntBlk.Address)))); 53367754Smsmith 53499679Siwasaki Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 53591116Smsmith ACPI_REGISTER_PM2_CONTROL, (UINT8) (RegisterValue)); 53667754Smsmith break; 53767754Smsmith 53867754Smsmith 53967754Smsmith default: 54067754Smsmith break; 54167754Smsmith } 54267754Smsmith 54399679Siwasaki 54499679SiwasakiUnlockAndExit: 54599679Siwasaki 54691116Smsmith if (Flags & ACPI_MTX_LOCK) 54791116Smsmith { 54891116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 54969450Smsmith } 55067754Smsmith 55191116Smsmith /* Normalize the value that was read */ 55269450Smsmith 55399679Siwasaki ACPI_DEBUG_EXEC (RegisterValue = ((RegisterValue & BitRegInfo->AccessBitMask) >> BitRegInfo->BitPosition)); 55467754Smsmith 55599679Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_IO, "ACPI Register Write actual %X\n", RegisterValue)); 55699679Siwasaki return_ACPI_STATUS (Status); 55767754Smsmith} 55869450Smsmith 55969450Smsmith 56069450Smsmith/****************************************************************************** 56169450Smsmith * 56269450Smsmith * FUNCTION: AcpiHwRegisterRead 56369450Smsmith * 56469450Smsmith * PARAMETERS: UseLock - Mutex hw access. 56569450Smsmith * RegisterId - RegisterID + Offset. 56669450Smsmith * 56769450Smsmith * RETURN: Value read or written. 56869450Smsmith * 56969450Smsmith * DESCRIPTION: Acpi register read function. Registers are read at the 57069450Smsmith * given offset. 57169450Smsmith * 57269450Smsmith ******************************************************************************/ 57369450Smsmith 57499679SiwasakiACPI_STATUS 57569450SmsmithAcpiHwRegisterRead ( 57669450Smsmith BOOLEAN UseLock, 57799679Siwasaki UINT32 RegisterId, 57899679Siwasaki UINT32 *ReturnValue) 57969450Smsmith{ 58099679Siwasaki UINT32 Value1 = 0; 58199679Siwasaki UINT32 Value2 = 0; 58269450Smsmith UINT32 BankOffset; 58399679Siwasaki ACPI_STATUS Status; 58469450Smsmith 58577424Smsmith 58691116Smsmith ACPI_FUNCTION_TRACE ("HwRegisterRead"); 58769450Smsmith 58877424Smsmith 58969450Smsmith if (ACPI_MTX_LOCK == UseLock) 59069450Smsmith { 59199679Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 59299679Siwasaki if (ACPI_FAILURE (Status)) 59391116Smsmith { 59499679Siwasaki return_ACPI_STATUS (Status); 59591116Smsmith } 59669450Smsmith } 59769450Smsmith 59891116Smsmith switch (RegisterId) 59969450Smsmith { 60091116Smsmith case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 60169450Smsmith 60299679Siwasaki Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aEvtBlk, 0); 60399679Siwasaki if (ACPI_FAILURE (Status)) 60499679Siwasaki { 60599679Siwasaki goto UnlockAndExit; 60699679Siwasaki } 60799679Siwasaki 60899679Siwasaki Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bEvtBlk, 0); 60999679Siwasaki Value1 |= Value2; 61069450Smsmith break; 61169450Smsmith 61269450Smsmith 61391116Smsmith case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access*/ 61469450Smsmith 61591116Smsmith BankOffset = ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen); 61699679Siwasaki Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset); 61799679Siwasaki if (ACPI_FAILURE (Status)) 61899679Siwasaki { 61999679Siwasaki goto UnlockAndExit; 62099679Siwasaki } 62199679Siwasaki 62299679Siwasaki Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset); 62399679Siwasaki Value1 |= Value2; 62469450Smsmith break; 62569450Smsmith 62669450Smsmith 62791116Smsmith case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ 62869450Smsmith 62999679Siwasaki Status = AcpiHwLowLevelRead (16, &Value1, &AcpiGbl_FADT->XPm1aCntBlk, 0); 63099679Siwasaki if (ACPI_FAILURE (Status)) 63199679Siwasaki { 63299679Siwasaki goto UnlockAndExit; 63399679Siwasaki } 63499679Siwasaki 63599679Siwasaki Status = AcpiHwLowLevelRead (16, &Value2, &AcpiGbl_FADT->XPm1bCntBlk, 0); 63699679Siwasaki Value1 |= Value2; 63769450Smsmith break; 63869450Smsmith 63969450Smsmith 64091116Smsmith case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 64169450Smsmith 64299679Siwasaki Status = AcpiHwLowLevelRead (8, &Value1, &AcpiGbl_FADT->XPm2CntBlk, 0); 64369450Smsmith break; 64469450Smsmith 64569450Smsmith 64691116Smsmith case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 64769450Smsmith 64899679Siwasaki Status = AcpiHwLowLevelRead (32, &Value1, &AcpiGbl_FADT->XPmTmrBlk, 0); 64969450Smsmith break; 65069450Smsmith 65191116Smsmith case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 65269450Smsmith 65399679Siwasaki Status = AcpiOsReadPort (AcpiGbl_FADT->SmiCmd, &Value1, 8); 65469450Smsmith break; 65569450Smsmith 65669450Smsmith default: 65799679Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Register ID: %X\n", RegisterId)); 65899679Siwasaki Status = AE_BAD_PARAMETER; 65969450Smsmith break; 66069450Smsmith } 66169450Smsmith 66299679SiwasakiUnlockAndExit: 66369450Smsmith if (ACPI_MTX_LOCK == UseLock) 66469450Smsmith { 66591116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 66669450Smsmith } 66769450Smsmith 66899679Siwasaki if (ACPI_SUCCESS (Status)) 66999679Siwasaki { 67099679Siwasaki *ReturnValue = Value1; 67199679Siwasaki } 67299679Siwasaki 67399679Siwasaki return_ACPI_STATUS (Status); 67469450Smsmith} 67569450Smsmith 67669450Smsmith 67769450Smsmith/****************************************************************************** 67869450Smsmith * 67969450Smsmith * FUNCTION: AcpiHwRegisterWrite 68069450Smsmith * 68169450Smsmith * PARAMETERS: UseLock - Mutex hw access. 68269450Smsmith * RegisterId - RegisterID + Offset. 68369450Smsmith * 68469450Smsmith * RETURN: Value read or written. 68569450Smsmith * 68669450Smsmith * DESCRIPTION: Acpi register Write function. Registers are written at the 68769450Smsmith * given offset. 68869450Smsmith * 68969450Smsmith ******************************************************************************/ 69069450Smsmith 69199679SiwasakiACPI_STATUS 69269450SmsmithAcpiHwRegisterWrite ( 69369450Smsmith BOOLEAN UseLock, 69469450Smsmith UINT32 RegisterId, 69569450Smsmith UINT32 Value) 69669450Smsmith{ 69769450Smsmith UINT32 BankOffset; 69899679Siwasaki ACPI_STATUS Status; 69969450Smsmith 70069450Smsmith 70191116Smsmith ACPI_FUNCTION_TRACE ("HwRegisterWrite"); 70269450Smsmith 70383174Smsmith 70469450Smsmith if (ACPI_MTX_LOCK == UseLock) 70569450Smsmith { 70699679Siwasaki Status = AcpiUtAcquireMutex (ACPI_MTX_HARDWARE); 70799679Siwasaki if (ACPI_FAILURE (Status)) 70891116Smsmith { 70999679Siwasaki return_ACPI_STATUS (Status); 71091116Smsmith } 71169450Smsmith } 71269450Smsmith 71391116Smsmith switch (RegisterId) 71469450Smsmith { 71591116Smsmith case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ 71669450Smsmith 71799679Siwasaki Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, 0); 71899679Siwasaki if (ACPI_FAILURE (Status)) 71999679Siwasaki { 72099679Siwasaki goto UnlockAndExit; 72199679Siwasaki } 72299679Siwasaki 72399679Siwasaki Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, 0); 72469450Smsmith break; 72569450Smsmith 72669450Smsmith 72791116Smsmith case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access*/ 72869450Smsmith 72991116Smsmith BankOffset = ACPI_DIV_2 (AcpiGbl_FADT->Pm1EvtLen); 73099679Siwasaki Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aEvtBlk, BankOffset); 73199679Siwasaki if (ACPI_FAILURE (Status)) 73299679Siwasaki { 73399679Siwasaki goto UnlockAndExit; 73499679Siwasaki } 73599679Siwasaki 73699679Siwasaki Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bEvtBlk, BankOffset); 73769450Smsmith break; 73869450Smsmith 73969450Smsmith 74091116Smsmith case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ 74169450Smsmith 74299679Siwasaki Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0); 74399679Siwasaki if (ACPI_FAILURE (Status)) 74499679Siwasaki { 74599679Siwasaki goto UnlockAndExit; 74699679Siwasaki } 74799679Siwasaki 74899679Siwasaki Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0); 74971867Smsmith break; 75069450Smsmith 75169450Smsmith 75291116Smsmith case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ 75369450Smsmith 75499679Siwasaki Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1aCntBlk, 0); 75569450Smsmith break; 75669450Smsmith 75769450Smsmith 75891116Smsmith case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ 75971867Smsmith 76099679Siwasaki Status = AcpiHwLowLevelWrite (16, Value, &AcpiGbl_FADT->XPm1bCntBlk, 0); 76171867Smsmith break; 76271867Smsmith 76371867Smsmith 76491116Smsmith case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 76569450Smsmith 76699679Siwasaki Status = AcpiHwLowLevelWrite (8, Value, &AcpiGbl_FADT->XPm2CntBlk, 0); 76769450Smsmith break; 76869450Smsmith 76969450Smsmith 77091116Smsmith case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 77169450Smsmith 77299679Siwasaki Status = AcpiHwLowLevelWrite (32, Value, &AcpiGbl_FADT->XPmTmrBlk, 0); 77369450Smsmith break; 77469450Smsmith 77569450Smsmith 77691116Smsmith case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 77769450Smsmith 77891116Smsmith /* SMI_CMD is currently always in IO space */ 77969450Smsmith 78099679Siwasaki Status = AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, (ACPI_INTEGER) Value, 8); 78169450Smsmith break; 78269450Smsmith 78369450Smsmith 78469450Smsmith default: 78599679Siwasaki Status = AE_BAD_PARAMETER; 78669450Smsmith break; 78769450Smsmith } 78869450Smsmith 78999679SiwasakiUnlockAndExit: 79069450Smsmith if (ACPI_MTX_LOCK == UseLock) 79169450Smsmith { 79291116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_HARDWARE); 79369450Smsmith } 79469450Smsmith 79599679Siwasaki return_ACPI_STATUS (Status); 79669450Smsmith} 79769450Smsmith 79869450Smsmith 79969450Smsmith/****************************************************************************** 80069450Smsmith * 80169450Smsmith * FUNCTION: AcpiHwLowLevelRead 80269450Smsmith * 80369450Smsmith * PARAMETERS: Register - GAS register structure 80469450Smsmith * Offset - Offset from the base address in the GAS 80569450Smsmith * Width - 8, 16, or 32 80669450Smsmith * 80769450Smsmith * RETURN: Value read 80869450Smsmith * 80969450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space. 81069450Smsmith * 81169450Smsmith ******************************************************************************/ 81269450Smsmith 81399679SiwasakiACPI_STATUS 81469450SmsmithAcpiHwLowLevelRead ( 81569450Smsmith UINT32 Width, 81699679Siwasaki UINT32 *Value, 81777424Smsmith ACPI_GENERIC_ADDRESS *Reg, 81869450Smsmith UINT32 Offset) 81969450Smsmith{ 82069450Smsmith ACPI_PHYSICAL_ADDRESS MemAddress; 82169450Smsmith ACPI_IO_ADDRESS IoAddress; 82280062Smsmith ACPI_PCI_ID PciId; 82380062Smsmith UINT16 PciRegister; 82499679Siwasaki ACPI_STATUS Status; 82569450Smsmith 82669450Smsmith 82799679Siwasaki ACPI_FUNCTION_NAME ("HwLowLevelRead"); 82883174Smsmith 82983174Smsmith 83069450Smsmith /* 83169450Smsmith * Must have a valid pointer to a GAS structure, and 83299679Siwasaki * a non-zero address within. However, don't return an error 83399679Siwasaki * because the PM1A/B code must not fail if B isn't present. 83469450Smsmith */ 83569450Smsmith if ((!Reg) || 83670243Smsmith (!ACPI_VALID_ADDRESS (Reg->Address))) 83769450Smsmith { 83899679Siwasaki return (AE_OK); 83969450Smsmith } 84099679Siwasaki *Value = 0; 84169450Smsmith 84269450Smsmith /* 84369450Smsmith * Three address spaces supported: 84469450Smsmith * Memory, Io, or PCI config. 84569450Smsmith */ 84669450Smsmith switch (Reg->AddressSpaceId) 84769450Smsmith { 84877424Smsmith case ACPI_ADR_SPACE_SYSTEM_MEMORY: 84969450Smsmith 850102550Siwasaki MemAddress = (ACPI_GET_ADDRESS (Reg->Address) 85199679Siwasaki + (ACPI_PHYSICAL_ADDRESS) Offset); 85269450Smsmith 85399679Siwasaki Status = AcpiOsReadMemory (MemAddress, Value, Width); 85469450Smsmith break; 85569450Smsmith 85669450Smsmith 85777424Smsmith case ACPI_ADR_SPACE_SYSTEM_IO: 85869450Smsmith 859102550Siwasaki IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) 86099679Siwasaki + (ACPI_PHYSICAL_ADDRESS) Offset); 86169450Smsmith 86299679Siwasaki Status = AcpiOsReadPort (IoAddress, Value, Width); 86369450Smsmith break; 86469450Smsmith 86569450Smsmith 86677424Smsmith case ACPI_ADR_SPACE_PCI_CONFIG: 86769450Smsmith 86880062Smsmith PciId.Segment = 0; 86980062Smsmith PciId.Bus = 0; 87080062Smsmith PciId.Device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address)); 87180062Smsmith PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address)); 87299679Siwasaki PciRegister = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) 87399679Siwasaki + Offset); 87469450Smsmith 87599679Siwasaki Status = AcpiOsReadPciConfiguration (&PciId, PciRegister, Value, Width); 87669450Smsmith break; 87799679Siwasaki 87899679Siwasaki 87999679Siwasaki default: 88099679Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported address space: %X\n", Reg->AddressSpaceId)); 88199679Siwasaki Status = AE_BAD_PARAMETER; 88299679Siwasaki break; 88369450Smsmith } 88469450Smsmith 88599679Siwasaki return (Status); 88669450Smsmith} 88769450Smsmith 88869450Smsmith 88969450Smsmith/****************************************************************************** 89069450Smsmith * 89169450Smsmith * FUNCTION: AcpiHwLowLevelWrite 89269450Smsmith * 89369450Smsmith * PARAMETERS: Width - 8, 16, or 32 89469450Smsmith * Value - To be written 89569450Smsmith * Register - GAS register structure 89669450Smsmith * Offset - Offset from the base address in the GAS 89769450Smsmith * 89869450Smsmith * 89969450Smsmith * RETURN: Value read 90069450Smsmith * 90169450Smsmith * DESCRIPTION: Read from either memory, IO, or PCI config space. 90269450Smsmith * 90369450Smsmith ******************************************************************************/ 90469450Smsmith 90599679SiwasakiACPI_STATUS 90669450SmsmithAcpiHwLowLevelWrite ( 90769450Smsmith UINT32 Width, 90869450Smsmith UINT32 Value, 90977424Smsmith ACPI_GENERIC_ADDRESS *Reg, 91069450Smsmith UINT32 Offset) 91169450Smsmith{ 91269450Smsmith ACPI_PHYSICAL_ADDRESS MemAddress; 91369450Smsmith ACPI_IO_ADDRESS IoAddress; 91480062Smsmith ACPI_PCI_ID PciId; 91580062Smsmith UINT16 PciRegister; 91699679Siwasaki ACPI_STATUS Status; 91769450Smsmith 91869450Smsmith 91999679Siwasaki ACPI_FUNCTION_NAME ("HwLowLevelWrite"); 92083174Smsmith 92183174Smsmith 92269450Smsmith /* 92369450Smsmith * Must have a valid pointer to a GAS structure, and 92499679Siwasaki * a non-zero address within. However, don't return an error 92599679Siwasaki * because the PM1A/B code must not fail if B isn't present. 92669450Smsmith */ 92769450Smsmith if ((!Reg) || 92870243Smsmith (!ACPI_VALID_ADDRESS (Reg->Address))) 92969450Smsmith { 93099679Siwasaki return (AE_OK); 93169450Smsmith } 93269450Smsmith /* 93369450Smsmith * Three address spaces supported: 93469450Smsmith * Memory, Io, or PCI config. 93569450Smsmith */ 93669450Smsmith switch (Reg->AddressSpaceId) 93769450Smsmith { 93877424Smsmith case ACPI_ADR_SPACE_SYSTEM_MEMORY: 93969450Smsmith 940102550Siwasaki MemAddress = (ACPI_GET_ADDRESS (Reg->Address) 94199679Siwasaki + (ACPI_PHYSICAL_ADDRESS) Offset); 94269450Smsmith 94399679Siwasaki Status = AcpiOsWriteMemory (MemAddress, (ACPI_INTEGER) Value, Width); 94469450Smsmith break; 94569450Smsmith 94669450Smsmith 94777424Smsmith case ACPI_ADR_SPACE_SYSTEM_IO: 94869450Smsmith 949102550Siwasaki IoAddress = (ACPI_IO_ADDRESS) (ACPI_GET_ADDRESS (Reg->Address) 95099679Siwasaki + (ACPI_PHYSICAL_ADDRESS) Offset); 95169450Smsmith 95299679Siwasaki Status = AcpiOsWritePort (IoAddress, (ACPI_INTEGER) Value, Width); 95369450Smsmith break; 95469450Smsmith 95569450Smsmith 95677424Smsmith case ACPI_ADR_SPACE_PCI_CONFIG: 95769450Smsmith 95880062Smsmith PciId.Segment = 0; 95980062Smsmith PciId.Bus = 0; 96080062Smsmith PciId.Device = ACPI_PCI_DEVICE (ACPI_GET_ADDRESS (Reg->Address)); 96180062Smsmith PciId.Function = ACPI_PCI_FUNCTION (ACPI_GET_ADDRESS (Reg->Address)); 962102550Siwasaki PciRegister = (UINT16) (ACPI_PCI_REGISTER (ACPI_GET_ADDRESS (Reg->Address)) 96399679Siwasaki + Offset); 96469450Smsmith 96599679Siwasaki Status = AcpiOsWritePciConfiguration (&PciId, PciRegister, (ACPI_INTEGER) Value, Width); 96669450Smsmith break; 96799679Siwasaki 96899679Siwasaki 96999679Siwasaki default: 97099679Siwasaki ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported address space: %X\n", Reg->AddressSpaceId)); 97199679Siwasaki Status = AE_BAD_PARAMETER; 97299679Siwasaki break; 97369450Smsmith } 97499679Siwasaki 97599679Siwasaki return (Status); 97669450Smsmith} 977