hwregs.c revision 193341
167754Smsmith 267754Smsmith/******************************************************************************* 367754Smsmith * 467754Smsmith * Module Name: hwregs - Read/write access functions for the various ACPI 567754Smsmith * control and status registers. 667754Smsmith * 767754Smsmith ******************************************************************************/ 867754Smsmith 967754Smsmith/****************************************************************************** 1067754Smsmith * 1167754Smsmith * 1. Copyright Notice 1267754Smsmith * 13193267Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 1470243Smsmith * All rights reserved. 1567754Smsmith * 1667754Smsmith * 2. License 1767754Smsmith * 1867754Smsmith * 2.1. This is your license from Intel Corp. under its intellectual property 1967754Smsmith * rights. You may have additional license terms from the party that provided 2067754Smsmith * you this software, covering your right to use that party's intellectual 2167754Smsmith * property rights. 2267754Smsmith * 2367754Smsmith * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 2467754Smsmith * copy of the source code appearing in this file ("Covered Code") an 2567754Smsmith * irrevocable, perpetual, worldwide license under Intel's copyrights in the 2667754Smsmith * base code distributed originally by Intel ("Original Intel Code") to copy, 2767754Smsmith * make derivatives, distribute, use and display any portion of the Covered 2867754Smsmith * Code in any form, with the right to sublicense such rights; and 2967754Smsmith * 3067754Smsmith * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 3167754Smsmith * license (with the right to sublicense), under only those claims of Intel 3267754Smsmith * patents that are infringed by the Original Intel Code, to make, use, sell, 3367754Smsmith * offer to sell, and import the Covered Code and derivative works thereof 3467754Smsmith * solely to the minimum extent necessary to exercise the above copyright 3567754Smsmith * license, and in no event shall the patent license extend to any additions 3667754Smsmith * to or modifications of the Original Intel Code. No other license or right 3767754Smsmith * is granted directly or by implication, estoppel or otherwise; 3867754Smsmith * 3967754Smsmith * The above copyright and patent license is granted only if the following 4067754Smsmith * conditions are met: 4167754Smsmith * 4267754Smsmith * 3. Conditions 4367754Smsmith * 4467754Smsmith * 3.1. Redistribution of Source with Rights to Further Distribute Source. 4567754Smsmith * Redistribution of source code of any substantial portion of the Covered 4667754Smsmith * Code or modification with rights to further distribute source must include 4767754Smsmith * the above Copyright Notice, the above License, this list of Conditions, 4867754Smsmith * and the following Disclaimer and Export Compliance provision. In addition, 4967754Smsmith * Licensee must cause all Covered Code to which Licensee contributes to 5067754Smsmith * contain a file documenting the changes Licensee made to create that Covered 5167754Smsmith * Code and the date of any change. Licensee must include in that file the 5267754Smsmith * documentation of any changes made by any predecessor Licensee. Licensee 5367754Smsmith * must include a prominent statement that the modification is derived, 5467754Smsmith * directly or indirectly, from Original Intel Code. 5567754Smsmith * 5667754Smsmith * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 5767754Smsmith * Redistribution of source code of any substantial portion of the Covered 5867754Smsmith * Code or modification without rights to further distribute source must 5967754Smsmith * include the following Disclaimer and Export Compliance provision in the 6067754Smsmith * documentation and/or other materials provided with distribution. In 6167754Smsmith * addition, Licensee may not authorize further sublicense of source of any 6267754Smsmith * portion of the Covered Code, and must include terms to the effect that the 6367754Smsmith * license from Licensee to its licensee is limited to the intellectual 6467754Smsmith * property embodied in the software Licensee provides to its licensee, and 6567754Smsmith * not to intellectual property embodied in modifications its licensee may 6667754Smsmith * make. 6767754Smsmith * 6867754Smsmith * 3.3. Redistribution of Executable. Redistribution in executable form of any 6967754Smsmith * substantial portion of the Covered Code or modification must reproduce the 7067754Smsmith * above Copyright Notice, and the following Disclaimer and Export Compliance 7167754Smsmith * provision in the documentation and/or other materials provided with the 7267754Smsmith * distribution. 7367754Smsmith * 7467754Smsmith * 3.4. Intel retains all right, title, and interest in and to the Original 7567754Smsmith * Intel Code. 7667754Smsmith * 7767754Smsmith * 3.5. Neither the name Intel nor any other trademark owned or controlled by 7867754Smsmith * Intel shall be used in advertising or otherwise to promote the sale, use or 7967754Smsmith * other dealings in products derived from or relating to the Covered Code 8067754Smsmith * without prior written authorization from Intel. 8167754Smsmith * 8267754Smsmith * 4. Disclaimer and Export Compliance 8367754Smsmith * 8467754Smsmith * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 8567754Smsmith * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 8667754Smsmith * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 8767754Smsmith * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 8867754Smsmith * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 8967754Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 9067754Smsmith * PARTICULAR PURPOSE. 9167754Smsmith * 9267754Smsmith * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 9367754Smsmith * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 9467754Smsmith * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 9567754Smsmith * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 9667754Smsmith * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 9767754Smsmith * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 9867754Smsmith * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 9967754Smsmith * LIMITED REMEDY. 10067754Smsmith * 10167754Smsmith * 4.3. Licensee shall not export, either directly or indirectly, any of this 10267754Smsmith * software or system incorporating such software without first obtaining any 10367754Smsmith * required license or other approval from the U. S. Department of Commerce or 10467754Smsmith * any other agency or department of the United States Government. In the 10567754Smsmith * event Licensee exports any such software from the United States or 10667754Smsmith * re-exports any such software from a foreign destination, Licensee shall 10767754Smsmith * ensure that the distribution and export/re-export of the software is in 10867754Smsmith * compliance with all laws, regulations, orders, or other restrictions of the 10967754Smsmith * U.S. Export Administration Regulations. Licensee agrees that neither it nor 11067754Smsmith * any of its subsidiaries will export/re-export any technical data, process, 11167754Smsmith * software, or service, directly or indirectly, to any country for which the 11267754Smsmith * United States government or any agency thereof requires an export license, 11367754Smsmith * other governmental approval, or letter of assurance, without first obtaining 11467754Smsmith * such license, approval or letter. 11567754Smsmith * 11667754Smsmith *****************************************************************************/ 11767754Smsmith 11867754Smsmith#define __HWREGS_C__ 11967754Smsmith 120193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 121193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 122193341Sjkim#include <contrib/dev/acpica/include/acevents.h> 12367754Smsmith 12477424Smsmith#define _COMPONENT ACPI_HARDWARE 12591116Smsmith ACPI_MODULE_NAME ("hwregs") 12667754Smsmith 12767754Smsmith 128193267Sjkim/* Local Prototypes */ 129193267Sjkim 130193267Sjkimstatic ACPI_STATUS 131193267SjkimAcpiHwReadMultiple ( 132193267Sjkim UINT32 *Value, 133193267Sjkim ACPI_GENERIC_ADDRESS *RegisterA, 134193267Sjkim ACPI_GENERIC_ADDRESS *RegisterB); 135193267Sjkim 136193267Sjkimstatic ACPI_STATUS 137193267SjkimAcpiHwWriteMultiple ( 138193267Sjkim UINT32 Value, 139193267Sjkim ACPI_GENERIC_ADDRESS *RegisterA, 140193267Sjkim ACPI_GENERIC_ADDRESS *RegisterB); 141193267Sjkim 142193267Sjkim 14367754Smsmith/******************************************************************************* 14467754Smsmith * 14567754Smsmith * FUNCTION: AcpiHwClearAcpiStatus 14667754Smsmith * 147167802Sjkim * PARAMETERS: None 14867754Smsmith * 149193267Sjkim * RETURN: Status 15067754Smsmith * 15167754Smsmith * DESCRIPTION: Clears all fixed and general purpose status bits 15267754Smsmith * 15367754Smsmith ******************************************************************************/ 15467754Smsmith 15599679SiwasakiACPI_STATUS 156117521SnjlAcpiHwClearAcpiStatus ( 157167802Sjkim void) 15867754Smsmith{ 15991116Smsmith ACPI_STATUS Status; 160167802Sjkim ACPI_CPU_FLAGS LockFlags = 0; 16167754Smsmith 16267754Smsmith 163167802Sjkim ACPI_FUNCTION_TRACE (HwClearAcpiStatus); 16467754Smsmith 16567754Smsmith 166193267Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", 16791116Smsmith ACPI_BITMASK_ALL_FIXED_STATUS, 168193267Sjkim ACPI_FORMAT_UINT64 (AcpiGbl_XPm1aStatus.Address))); 16967754Smsmith 170167802Sjkim LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock); 17167754Smsmith 172193267Sjkim /* Clear the fixed events in PM1 A/B */ 173193267Sjkim 174193267Sjkim Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS, 175151937Sjkim ACPI_BITMASK_ALL_FIXED_STATUS); 17699679Siwasaki if (ACPI_FAILURE (Status)) 17799679Siwasaki { 17899679Siwasaki goto UnlockAndExit; 17999679Siwasaki } 18067754Smsmith 181114237Snjl /* Clear the GPE Bits in all GPE registers in all GPE blocks */ 18267754Smsmith 183193267Sjkim Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, NULL); 184117521Snjl 185117521SnjlUnlockAndExit: 186167802Sjkim AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags); 18799679Siwasaki return_ACPI_STATUS (Status); 18867754Smsmith} 18967754Smsmith 19067754Smsmith 19167754Smsmith/******************************************************************************* 19267754Smsmith * 19391116Smsmith * FUNCTION: AcpiHwGetRegisterBitMask 19467754Smsmith * 19599679Siwasaki * PARAMETERS: RegisterId - Index of ACPI Register to access 196102550Siwasaki * 197151937Sjkim * RETURN: The bitmask to be used when accessing the register 19891116Smsmith * 199151937Sjkim * DESCRIPTION: Map RegisterId into a register bitmask. 20091116Smsmith * 20191116Smsmith ******************************************************************************/ 20291116Smsmith 20391116SmsmithACPI_BIT_REGISTER_INFO * 20491116SmsmithAcpiHwGetBitRegisterInfo ( 20591116Smsmith UINT32 RegisterId) 20691116Smsmith{ 207167802Sjkim ACPI_FUNCTION_ENTRY (); 20891116Smsmith 20991116Smsmith 21091116Smsmith if (RegisterId > ACPI_BITREG_MAX) 21191116Smsmith { 212167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: %X", RegisterId)); 21391116Smsmith return (NULL); 21491116Smsmith } 21591116Smsmith 21691116Smsmith return (&AcpiGbl_BitRegisterInfo[RegisterId]); 21791116Smsmith} 21891116Smsmith 21991116Smsmith 220193267Sjkim/****************************************************************************** 22191116Smsmith * 222193267Sjkim * FUNCTION: AcpiHwWritePm1Control 22391116Smsmith * 224193267Sjkim * PARAMETERS: Pm1aControl - Value to be written to PM1A control 225193267Sjkim * Pm1bControl - Value to be written to PM1B control 22667754Smsmith * 227138287Smarks * RETURN: Status 22891116Smsmith * 229193267Sjkim * DESCRIPTION: Write the PM1 A/B control registers. These registers are 230193267Sjkim * different than than the PM1 A/B status and enable registers 231193267Sjkim * in that different values can be written to the A/B registers. 232193267Sjkim * Most notably, the SLP_TYP bits can be different, as per the 233193267Sjkim * values returned from the _Sx predefined methods. 23491116Smsmith * 23591116Smsmith ******************************************************************************/ 23667754Smsmith 23799679SiwasakiACPI_STATUS 238193267SjkimAcpiHwWritePm1Control ( 239193267Sjkim UINT32 Pm1aControl, 240193267Sjkim UINT32 Pm1bControl) 24191116Smsmith{ 24299679Siwasaki ACPI_STATUS Status; 24367754Smsmith 24467754Smsmith 245193267Sjkim ACPI_FUNCTION_TRACE (HwWritePm1Control); 24667754Smsmith 24767754Smsmith 248193267Sjkim Status = AcpiWrite (Pm1aControl, &AcpiGbl_FADT.XPm1aControlBlock); 24999679Siwasaki if (ACPI_FAILURE (Status)) 25099679Siwasaki { 251193267Sjkim return_ACPI_STATUS (Status); 25299679Siwasaki } 25367754Smsmith 254193267Sjkim if (AcpiGbl_FADT.XPm1bControlBlock.Address) 25591116Smsmith { 256193267Sjkim Status = AcpiWrite (Pm1bControl, &AcpiGbl_FADT.XPm1bControlBlock); 25767754Smsmith } 25899679Siwasaki return_ACPI_STATUS (Status); 25967754Smsmith} 26069450Smsmith 26169450Smsmith 26269450Smsmith/****************************************************************************** 26369450Smsmith * 26469450Smsmith * FUNCTION: AcpiHwRegisterRead 26569450Smsmith * 266193267Sjkim * PARAMETERS: RegisterId - ACPI Register ID 267151937Sjkim * ReturnValue - Where the register value is returned 26869450Smsmith * 269138287Smarks * RETURN: Status and the value read. 27069450Smsmith * 271167802Sjkim * DESCRIPTION: Read from the specified ACPI register 27269450Smsmith * 27369450Smsmith ******************************************************************************/ 27469450Smsmith 27599679SiwasakiACPI_STATUS 27669450SmsmithAcpiHwRegisterRead ( 27799679Siwasaki UINT32 RegisterId, 27899679Siwasaki UINT32 *ReturnValue) 27969450Smsmith{ 280193267Sjkim UINT32 Value = 0; 28199679Siwasaki ACPI_STATUS Status; 28269450Smsmith 28377424Smsmith 284167802Sjkim ACPI_FUNCTION_TRACE (HwRegisterRead); 28569450Smsmith 28677424Smsmith 28791116Smsmith switch (RegisterId) 28869450Smsmith { 289193267Sjkim case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 29069450Smsmith 291193267Sjkim Status = AcpiHwReadMultiple (&Value, 292193267Sjkim &AcpiGbl_XPm1aStatus, 293193267Sjkim &AcpiGbl_XPm1bStatus); 29469450Smsmith break; 29569450Smsmith 29669450Smsmith 297193267Sjkim case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ 29869450Smsmith 299193267Sjkim Status = AcpiHwReadMultiple (&Value, 300193267Sjkim &AcpiGbl_XPm1aEnable, 301193267Sjkim &AcpiGbl_XPm1bEnable); 30269450Smsmith break; 30369450Smsmith 30469450Smsmith 305193267Sjkim case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 30669450Smsmith 307193267Sjkim Status = AcpiHwReadMultiple (&Value, 308193267Sjkim &AcpiGbl_FADT.XPm1aControlBlock, 309193267Sjkim &AcpiGbl_FADT.XPm1bControlBlock); 31099679Siwasaki 311193267Sjkim /* 312193267Sjkim * Zero the write-only bits. From the ACPI specification, "Hardware 313193267Sjkim * Write-Only Bits": "Upon reads to registers with write-only bits, 314193267Sjkim * software masks out all write-only bits." 315193267Sjkim */ 316193267Sjkim Value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS; 31769450Smsmith break; 31869450Smsmith 31969450Smsmith 32091116Smsmith case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 32169450Smsmith 322193267Sjkim Status = AcpiRead (&Value, &AcpiGbl_FADT.XPm2ControlBlock); 32369450Smsmith break; 32469450Smsmith 32569450Smsmith 32691116Smsmith case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 32769450Smsmith 328193267Sjkim Status = AcpiRead (&Value, &AcpiGbl_FADT.XPmTimerBlock); 32969450Smsmith break; 33069450Smsmith 331193267Sjkim 33291116Smsmith case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 33369450Smsmith 334193267Sjkim Status = AcpiHwReadPort (AcpiGbl_FADT.SmiCommand, &Value, 8); 33569450Smsmith break; 33669450Smsmith 337193267Sjkim 33869450Smsmith default: 339167802Sjkim ACPI_ERROR ((AE_INFO, "Unknown Register ID: %X", 340151937Sjkim RegisterId)); 34199679Siwasaki Status = AE_BAD_PARAMETER; 34269450Smsmith break; 34369450Smsmith } 34469450Smsmith 34599679Siwasaki if (ACPI_SUCCESS (Status)) 34699679Siwasaki { 347193267Sjkim *ReturnValue = Value; 34899679Siwasaki } 34999679Siwasaki 35099679Siwasaki return_ACPI_STATUS (Status); 35169450Smsmith} 35269450Smsmith 35369450Smsmith 35469450Smsmith/****************************************************************************** 35569450Smsmith * 35669450Smsmith * FUNCTION: AcpiHwRegisterWrite 35769450Smsmith * 358193267Sjkim * PARAMETERS: RegisterId - ACPI Register ID 359138287Smarks * Value - The value to write 36069450Smsmith * 361138287Smarks * RETURN: Status 36269450Smsmith * 363167802Sjkim * DESCRIPTION: Write to the specified ACPI register 36469450Smsmith * 365167802Sjkim * NOTE: In accordance with the ACPI specification, this function automatically 366167802Sjkim * preserves the value of the following bits, meaning that these bits cannot be 367167802Sjkim * changed via this interface: 368167802Sjkim * 369167802Sjkim * PM1_CONTROL[0] = SCI_EN 370167802Sjkim * PM1_CONTROL[9] 371167802Sjkim * PM1_STATUS[11] 372167802Sjkim * 373167802Sjkim * ACPI References: 374167802Sjkim * 1) Hardware Ignored Bits: When software writes to a register with ignored 375167802Sjkim * bit fields, it preserves the ignored bit fields 376167802Sjkim * 2) SCI_EN: OSPM always preserves this bit position 377167802Sjkim * 37869450Smsmith ******************************************************************************/ 37969450Smsmith 38099679SiwasakiACPI_STATUS 38169450SmsmithAcpiHwRegisterWrite ( 38269450Smsmith UINT32 RegisterId, 38369450Smsmith UINT32 Value) 38469450Smsmith{ 38599679Siwasaki ACPI_STATUS Status; 386167802Sjkim UINT32 ReadValue; 38769450Smsmith 38869450Smsmith 389167802Sjkim ACPI_FUNCTION_TRACE (HwRegisterWrite); 39069450Smsmith 39183174Smsmith 39291116Smsmith switch (RegisterId) 39369450Smsmith { 394193267Sjkim case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 395193267Sjkim /* 396193267Sjkim * Handle the "ignored" bit in PM1 Status. According to the ACPI 397193267Sjkim * specification, ignored bits are to be preserved when writing. 398193267Sjkim * Normally, this would mean a read/modify/write sequence. However, 399193267Sjkim * preserving a bit in the status register is different. Writing a 400193267Sjkim * one clears the status, and writing a zero preserves the status. 401193267Sjkim * Therefore, we must always write zero to the ignored bit. 402193267Sjkim * 403193267Sjkim * This behavior is clarified in the ACPI 4.0 specification. 404193267Sjkim */ 405193267Sjkim Value &= ~ACPI_PM1_STATUS_PRESERVED_BITS; 40669450Smsmith 407193267Sjkim Status = AcpiHwWriteMultiple (Value, 408193267Sjkim &AcpiGbl_XPm1aStatus, 409193267Sjkim &AcpiGbl_XPm1bStatus); 41069450Smsmith break; 41169450Smsmith 41269450Smsmith 413193267Sjkim case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ 41469450Smsmith 415193267Sjkim Status = AcpiHwWriteMultiple (Value, 416193267Sjkim &AcpiGbl_XPm1aEnable, 417193267Sjkim &AcpiGbl_XPm1bEnable); 41869450Smsmith break; 41969450Smsmith 42069450Smsmith 421193267Sjkim case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 42269450Smsmith 423167802Sjkim /* 424167802Sjkim * Perform a read first to preserve certain bits (per ACPI spec) 425167802Sjkim * Note: This includes SCI_EN, we never want to change this bit 426167802Sjkim */ 427193267Sjkim Status = AcpiHwReadMultiple (&ReadValue, 428193267Sjkim &AcpiGbl_FADT.XPm1aControlBlock, 429193267Sjkim &AcpiGbl_FADT.XPm1bControlBlock); 43099679Siwasaki if (ACPI_FAILURE (Status)) 43199679Siwasaki { 432193267Sjkim goto Exit; 43399679Siwasaki } 43499679Siwasaki 435167802Sjkim /* Insert the bits to be preserved */ 436167802Sjkim 437167802Sjkim ACPI_INSERT_BITS (Value, ACPI_PM1_CONTROL_PRESERVED_BITS, ReadValue); 438167802Sjkim 439167802Sjkim /* Now we can write the data */ 440167802Sjkim 441193267Sjkim Status = AcpiHwWriteMultiple (Value, 442193267Sjkim &AcpiGbl_FADT.XPm1aControlBlock, 443193267Sjkim &AcpiGbl_FADT.XPm1bControlBlock); 44471867Smsmith break; 44569450Smsmith 44669450Smsmith 447193267Sjkim case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 44869450Smsmith 449193267Sjkim /* 450193267Sjkim * For control registers, all reserved bits must be preserved, 451193267Sjkim * as per the ACPI spec. 452193267Sjkim */ 453193267Sjkim Status = AcpiRead (&ReadValue, &AcpiGbl_FADT.XPm2ControlBlock); 454193267Sjkim if (ACPI_FAILURE (Status)) 455193267Sjkim { 456193267Sjkim goto Exit; 457193267Sjkim } 45869450Smsmith 459193267Sjkim /* Insert the bits to be preserved */ 46069450Smsmith 461193267Sjkim ACPI_INSERT_BITS (Value, ACPI_PM2_CONTROL_PRESERVED_BITS, ReadValue); 46271867Smsmith 463193267Sjkim Status = AcpiWrite (Value, &AcpiGbl_FADT.XPm2ControlBlock); 46471867Smsmith break; 46571867Smsmith 46671867Smsmith 46791116Smsmith case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 46869450Smsmith 469193267Sjkim Status = AcpiWrite (Value, &AcpiGbl_FADT.XPmTimerBlock); 47069450Smsmith break; 47169450Smsmith 47269450Smsmith 47391116Smsmith case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 47469450Smsmith 47591116Smsmith /* SMI_CMD is currently always in IO space */ 47669450Smsmith 477193267Sjkim Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand, Value, 8); 47869450Smsmith break; 47969450Smsmith 48069450Smsmith 48169450Smsmith default: 482193267Sjkim ACPI_ERROR ((AE_INFO, "Unknown Register ID: %X", 483193267Sjkim RegisterId)); 48499679Siwasaki Status = AE_BAD_PARAMETER; 48569450Smsmith break; 48669450Smsmith } 48769450Smsmith 488193267SjkimExit: 48999679Siwasaki return_ACPI_STATUS (Status); 49069450Smsmith} 49169450Smsmith 49269450Smsmith 49369450Smsmith/****************************************************************************** 49469450Smsmith * 495193267Sjkim * FUNCTION: AcpiHwReadMultiple 49669450Smsmith * 497193267Sjkim * PARAMETERS: Value - Where the register value is returned 498193267Sjkim * RegisterA - First ACPI register (required) 499193267Sjkim * RegisterB - Second ACPI register (optional) 50069450Smsmith * 501117521Snjl * RETURN: Status 50269450Smsmith * 503193267Sjkim * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B) 50469450Smsmith * 50569450Smsmith ******************************************************************************/ 50669450Smsmith 507193267Sjkimstatic ACPI_STATUS 508193267SjkimAcpiHwReadMultiple ( 50999679Siwasaki UINT32 *Value, 510193267Sjkim ACPI_GENERIC_ADDRESS *RegisterA, 511193267Sjkim ACPI_GENERIC_ADDRESS *RegisterB) 51269450Smsmith{ 513193267Sjkim UINT32 ValueA = 0; 514193267Sjkim UINT32 ValueB = 0; 51599679Siwasaki ACPI_STATUS Status; 51669450Smsmith 51769450Smsmith 518193267Sjkim /* The first register is always required */ 51983174Smsmith 520193267Sjkim Status = AcpiRead (&ValueA, RegisterA); 521193267Sjkim if (ACPI_FAILURE (Status)) 52269450Smsmith { 523193267Sjkim return (Status); 52469450Smsmith } 525138287Smarks 526193267Sjkim /* Second register is optional */ 527138287Smarks 528193267Sjkim if (RegisterB->Address) 529138287Smarks { 530193267Sjkim Status = AcpiRead (&ValueB, RegisterB); 531193267Sjkim if (ACPI_FAILURE (Status)) 532193267Sjkim { 533193267Sjkim return (Status); 534193267Sjkim } 535138287Smarks } 53669450Smsmith 53769450Smsmith /* 538193267Sjkim * OR the two return values together. No shifting or masking is necessary, 539193267Sjkim * because of how the PM1 registers are defined in the ACPI specification: 540193267Sjkim * 541193267Sjkim * "Although the bits can be split between the two register blocks (each 542193267Sjkim * register block has a unique pointer within the FADT), the bit positions 543193267Sjkim * are maintained. The register block with unimplemented bits (that is, 544193267Sjkim * those implemented in the other register block) always returns zeros, 545193267Sjkim * and writes have no side effects" 54669450Smsmith */ 547193267Sjkim *Value = (ValueA | ValueB); 548193267Sjkim return (AE_OK); 54969450Smsmith} 55069450Smsmith 55169450Smsmith 55269450Smsmith/****************************************************************************** 55369450Smsmith * 554193267Sjkim * FUNCTION: AcpiHwWriteMultiple 55569450Smsmith * 556193267Sjkim * PARAMETERS: Value - The value to write 557193267Sjkim * RegisterA - First ACPI register (required) 558193267Sjkim * RegisterB - Second ACPI register (optional) 55969450Smsmith * 560117521Snjl * RETURN: Status 56169450Smsmith * 562193267Sjkim * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B) 56369450Smsmith * 56469450Smsmith ******************************************************************************/ 56569450Smsmith 566193267Sjkimstatic ACPI_STATUS 567193267SjkimAcpiHwWriteMultiple ( 56869450Smsmith UINT32 Value, 569193267Sjkim ACPI_GENERIC_ADDRESS *RegisterA, 570193267Sjkim ACPI_GENERIC_ADDRESS *RegisterB) 57169450Smsmith{ 57299679Siwasaki ACPI_STATUS Status; 57369450Smsmith 57469450Smsmith 575193267Sjkim /* The first register is always required */ 57683174Smsmith 577193267Sjkim Status = AcpiWrite (Value, RegisterA); 578193267Sjkim if (ACPI_FAILURE (Status)) 57969450Smsmith { 580193267Sjkim return (Status); 58169450Smsmith } 582123315Snjl 58369450Smsmith /* 584193267Sjkim * Second register is optional 585193267Sjkim * 586193267Sjkim * No bit shifting or clearing is necessary, because of how the PM1 587193267Sjkim * registers are defined in the ACPI specification: 588193267Sjkim * 589193267Sjkim * "Although the bits can be split between the two register blocks (each 590193267Sjkim * register block has a unique pointer within the FADT), the bit positions 591193267Sjkim * are maintained. The register block with unimplemented bits (that is, 592193267Sjkim * those implemented in the other register block) always returns zeros, 593193267Sjkim * and writes have no side effects" 59469450Smsmith */ 595193267Sjkim if (RegisterB->Address) 59669450Smsmith { 597193267Sjkim Status = AcpiWrite (Value, RegisterB); 59869450Smsmith } 59999679Siwasaki 60099679Siwasaki return (Status); 60169450Smsmith} 602193267Sjkim 603