Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhwregs.c
Go to the documentation of this file.
00001 00002 /******************************************************************************* 00003 * 00004 * Module Name: hwregs - Read/write access functions for the various ACPI 00005 * control and status registers. 00006 * 00007 ******************************************************************************/ 00008 00009 /****************************************************************************** 00010 * 00011 * 1. Copyright Notice 00012 * 00013 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp. 00014 * All rights reserved. 00015 * 00016 * 2. License 00017 * 00018 * 2.1. This is your license from Intel Corp. under its intellectual property 00019 * rights. You may have additional license terms from the party that provided 00020 * you this software, covering your right to use that party's intellectual 00021 * property rights. 00022 * 00023 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 00024 * copy of the source code appearing in this file ("Covered Code") an 00025 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 00026 * base code distributed originally by Intel ("Original Intel Code") to copy, 00027 * make derivatives, distribute, use and display any portion of the Covered 00028 * Code in any form, with the right to sublicense such rights; and 00029 * 00030 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 00031 * license (with the right to sublicense), under only those claims of Intel 00032 * patents that are infringed by the Original Intel Code, to make, use, sell, 00033 * offer to sell, and import the Covered Code and derivative works thereof 00034 * solely to the minimum extent necessary to exercise the above copyright 00035 * license, and in no event shall the patent license extend to any additions 00036 * to or modifications of the Original Intel Code. No other license or right 00037 * is granted directly or by implication, estoppel or otherwise; 00038 * 00039 * The above copyright and patent license is granted only if the following 00040 * conditions are met: 00041 * 00042 * 3. Conditions 00043 * 00044 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 00045 * Redistribution of source code of any substantial portion of the Covered 00046 * Code or modification with rights to further distribute source must include 00047 * the above Copyright Notice, the above License, this list of Conditions, 00048 * and the following Disclaimer and Export Compliance provision. In addition, 00049 * Licensee must cause all Covered Code to which Licensee contributes to 00050 * contain a file documenting the changes Licensee made to create that Covered 00051 * Code and the date of any change. Licensee must include in that file the 00052 * documentation of any changes made by any predecessor Licensee. Licensee 00053 * must include a prominent statement that the modification is derived, 00054 * directly or indirectly, from Original Intel Code. 00055 * 00056 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 00057 * Redistribution of source code of any substantial portion of the Covered 00058 * Code or modification without rights to further distribute source must 00059 * include the following Disclaimer and Export Compliance provision in the 00060 * documentation and/or other materials provided with distribution. In 00061 * addition, Licensee may not authorize further sublicense of source of any 00062 * portion of the Covered Code, and must include terms to the effect that the 00063 * license from Licensee to its licensee is limited to the intellectual 00064 * property embodied in the software Licensee provides to its licensee, and 00065 * not to intellectual property embodied in modifications its licensee may 00066 * make. 00067 * 00068 * 3.3. Redistribution of Executable. Redistribution in executable form of any 00069 * substantial portion of the Covered Code or modification must reproduce the 00070 * above Copyright Notice, and the following Disclaimer and Export Compliance 00071 * provision in the documentation and/or other materials provided with the 00072 * distribution. 00073 * 00074 * 3.4. Intel retains all right, title, and interest in and to the Original 00075 * Intel Code. 00076 * 00077 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 00078 * Intel shall be used in advertising or otherwise to promote the sale, use or 00079 * other dealings in products derived from or relating to the Covered Code 00080 * without prior written authorization from Intel. 00081 * 00082 * 4. Disclaimer and Export Compliance 00083 * 00084 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 00085 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 00086 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 00087 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 00088 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 00089 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 00090 * PARTICULAR PURPOSE. 00091 * 00092 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 00093 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 00094 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 00095 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 00096 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 00097 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 00098 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 00099 * LIMITED REMEDY. 00100 * 00101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 00102 * software or system incorporating such software without first obtaining any 00103 * required license or other approval from the U. S. Department of Commerce or 00104 * any other agency or department of the United States Government. In the 00105 * event Licensee exports any such software from the United States or 00106 * re-exports any such software from a foreign destination, Licensee shall 00107 * ensure that the distribution and export/re-export of the software is in 00108 * compliance with all laws, regulations, orders, or other restrictions of the 00109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 00110 * any of its subsidiaries will export/re-export any technical data, process, 00111 * software, or service, directly or indirectly, to any country for which the 00112 * United States government or any agency thereof requires an export license, 00113 * other governmental approval, or letter of assurance, without first obtaining 00114 * such license, approval or letter. 00115 * 00116 *****************************************************************************/ 00117 00118 #define __HWREGS_C__ 00119 00120 #include "acpi.h" 00121 #include "accommon.h" 00122 #include "acevents.h" 00123 00124 #define _COMPONENT ACPI_HARDWARE 00125 ACPI_MODULE_NAME ("hwregs") 00126 00127 00128 /* Local Prototypes */ 00129 00130 static ACPI_STATUS 00131 AcpiHwReadMultiple ( 00132 UINT32 *Value, 00133 ACPI_GENERIC_ADDRESS *RegisterA, 00134 ACPI_GENERIC_ADDRESS *RegisterB); 00135 00136 static ACPI_STATUS 00137 AcpiHwWriteMultiple ( 00138 UINT32 Value, 00139 ACPI_GENERIC_ADDRESS *RegisterA, 00140 ACPI_GENERIC_ADDRESS *RegisterB); 00141 00142 00143 /****************************************************************************** 00144 * 00145 * FUNCTION: AcpiHwValidateRegister 00146 * 00147 * PARAMETERS: Reg - GAS register structure 00148 * MaxBitWidth - Max BitWidth supported (32 or 64) 00149 * Address - Pointer to where the gas->address 00150 * is returned 00151 * 00152 * RETURN: Status 00153 * 00154 * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS 00155 * pointer, Address, SpaceId, BitWidth, and BitOffset. 00156 * 00157 ******************************************************************************/ 00158 00159 ACPI_STATUS 00160 AcpiHwValidateRegister ( 00161 ACPI_GENERIC_ADDRESS *Reg, 00162 UINT8 MaxBitWidth, 00163 UINT64 *Address) 00164 { 00165 00166 /* Must have a valid pointer to a GAS structure */ 00167 00168 if (!Reg) 00169 { 00170 return (AE_BAD_PARAMETER); 00171 } 00172 00173 /* 00174 * Copy the target address. This handles possible alignment issues. 00175 * Address must not be null. A null address also indicates an optional 00176 * ACPI register that is not supported, so no error message. 00177 */ 00178 ACPI_MOVE_64_TO_64 (Address, &Reg->Address); 00179 if (!(*Address)) 00180 { 00181 return (AE_BAD_ADDRESS); 00182 } 00183 00184 /* Validate the SpaceID */ 00185 00186 if ((Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 00187 (Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_IO)) 00188 { 00189 ACPI_ERROR ((AE_INFO, 00190 "Unsupported address space: 0x%X", Reg->SpaceId)); 00191 return (AE_SUPPORT); 00192 } 00193 00194 /* Validate the BitWidth */ 00195 00196 if ((Reg->BitWidth != 8) && 00197 (Reg->BitWidth != 16) && 00198 (Reg->BitWidth != 32) && 00199 (Reg->BitWidth != MaxBitWidth)) 00200 { 00201 ACPI_ERROR ((AE_INFO, 00202 "Unsupported register bit width: 0x%X", Reg->BitWidth)); 00203 return (AE_SUPPORT); 00204 } 00205 00206 /* Validate the BitOffset. Just a warning for now. */ 00207 00208 if (Reg->BitOffset != 0) 00209 { 00210 ACPI_WARNING ((AE_INFO, 00211 "Unsupported register bit offset: 0x%X", Reg->BitOffset)); 00212 } 00213 00214 return (AE_OK); 00215 } 00216 00217 00218 /****************************************************************************** 00219 * 00220 * FUNCTION: AcpiHwRead 00221 * 00222 * PARAMETERS: Value - Where the value is returned 00223 * Reg - GAS register structure 00224 * 00225 * RETURN: Status 00226 * 00227 * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max 00228 * version of AcpiRead, used internally since the overhead of 00229 * 64-bit values is not needed. 00230 * 00231 * LIMITATIONS: <These limitations also apply to AcpiHwWrite> 00232 * BitWidth must be exactly 8, 16, or 32. 00233 * SpaceID must be SystemMemory or SystemIO. 00234 * BitOffset and AccessWidth are currently ignored, as there has 00235 * not been a need to implement these. 00236 * 00237 ******************************************************************************/ 00238 00239 ACPI_STATUS 00240 AcpiHwRead ( 00241 UINT32 *Value, 00242 ACPI_GENERIC_ADDRESS *Reg) 00243 { 00244 UINT64 Address; 00245 ACPI_STATUS Status; 00246 00247 00248 ACPI_FUNCTION_NAME (HwRead); 00249 00250 00251 /* Validate contents of the GAS register */ 00252 00253 Status = AcpiHwValidateRegister (Reg, 32, &Address); 00254 if (ACPI_FAILURE (Status)) 00255 { 00256 return (Status); 00257 } 00258 00259 /* Initialize entire 32-bit return value to zero */ 00260 00261 *Value = 0; 00262 00263 /* 00264 * Two address spaces supported: Memory or IO. PCI_Config is 00265 * not supported here because the GAS structure is insufficient 00266 */ 00267 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) 00268 { 00269 Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS) 00270 Address, Value, Reg->BitWidth); 00271 } 00272 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ 00273 { 00274 Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) 00275 Address, Value, Reg->BitWidth); 00276 } 00277 00278 ACPI_DEBUG_PRINT ((ACPI_DB_IO, 00279 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", 00280 *Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address), 00281 AcpiUtGetRegionName (Reg->SpaceId))); 00282 00283 return (Status); 00284 } 00285 00286 00287 /****************************************************************************** 00288 * 00289 * FUNCTION: AcpiHwWrite 00290 * 00291 * PARAMETERS: Value - Value to be written 00292 * Reg - GAS register structure 00293 * 00294 * RETURN: Status 00295 * 00296 * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max 00297 * version of AcpiWrite, used internally since the overhead of 00298 * 64-bit values is not needed. 00299 * 00300 ******************************************************************************/ 00301 00302 ACPI_STATUS 00303 AcpiHwWrite ( 00304 UINT32 Value, 00305 ACPI_GENERIC_ADDRESS *Reg) 00306 { 00307 UINT64 Address; 00308 ACPI_STATUS Status; 00309 00310 00311 ACPI_FUNCTION_NAME (HwWrite); 00312 00313 00314 /* Validate contents of the GAS register */ 00315 00316 Status = AcpiHwValidateRegister (Reg, 32, &Address); 00317 if (ACPI_FAILURE (Status)) 00318 { 00319 return (Status); 00320 } 00321 00322 /* 00323 * Two address spaces supported: Memory or IO. PCI_Config is 00324 * not supported here because the GAS structure is insufficient 00325 */ 00326 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) 00327 { 00328 Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS) 00329 Address, Value, Reg->BitWidth); 00330 } 00331 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ 00332 { 00333 Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) 00334 Address, Value, Reg->BitWidth); 00335 } 00336 00337 ACPI_DEBUG_PRINT ((ACPI_DB_IO, 00338 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", 00339 Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address), 00340 AcpiUtGetRegionName (Reg->SpaceId))); 00341 00342 return (Status); 00343 } 00344 00345 00346 /******************************************************************************* 00347 * 00348 * FUNCTION: AcpiHwClearAcpiStatus 00349 * 00350 * PARAMETERS: None 00351 * 00352 * RETURN: Status 00353 * 00354 * DESCRIPTION: Clears all fixed and general purpose status bits 00355 * 00356 ******************************************************************************/ 00357 00358 ACPI_STATUS 00359 AcpiHwClearAcpiStatus ( 00360 void) 00361 { 00362 ACPI_STATUS Status; 00363 ACPI_CPU_FLAGS LockFlags = 0; 00364 00365 00366 ACPI_FUNCTION_TRACE (HwClearAcpiStatus); 00367 00368 00369 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", 00370 ACPI_BITMASK_ALL_FIXED_STATUS, 00371 ACPI_FORMAT_UINT64 (AcpiGbl_XPm1aStatus.Address))); 00372 00373 LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock); 00374 00375 /* Clear the fixed events in PM1 A/B */ 00376 00377 Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS, 00378 ACPI_BITMASK_ALL_FIXED_STATUS); 00379 if (ACPI_FAILURE (Status)) 00380 { 00381 goto UnlockAndExit; 00382 } 00383 00384 /* Clear the GPE Bits in all GPE registers in all GPE blocks */ 00385 00386 Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, NULL); 00387 00388 UnlockAndExit: 00389 AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags); 00390 return_ACPI_STATUS (Status); 00391 } 00392 00393 00394 /******************************************************************************* 00395 * 00396 * FUNCTION: AcpiHwGetRegisterBitMask 00397 * 00398 * PARAMETERS: RegisterId - Index of ACPI Register to access 00399 * 00400 * RETURN: The bitmask to be used when accessing the register 00401 * 00402 * DESCRIPTION: Map RegisterId into a register bitmask. 00403 * 00404 ******************************************************************************/ 00405 00406 ACPI_BIT_REGISTER_INFO * 00407 AcpiHwGetBitRegisterInfo ( 00408 UINT32 RegisterId) 00409 { 00410 ACPI_FUNCTION_ENTRY (); 00411 00412 00413 if (RegisterId > ACPI_BITREG_MAX) 00414 { 00415 ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: 0x%X", RegisterId)); 00416 return (NULL); 00417 } 00418 00419 return (&AcpiGbl_BitRegisterInfo[RegisterId]); 00420 } 00421 00422 00423 /****************************************************************************** 00424 * 00425 * FUNCTION: AcpiHwWritePm1Control 00426 * 00427 * PARAMETERS: Pm1aControl - Value to be written to PM1A control 00428 * Pm1bControl - Value to be written to PM1B control 00429 * 00430 * RETURN: Status 00431 * 00432 * DESCRIPTION: Write the PM1 A/B control registers. These registers are 00433 * different than than the PM1 A/B status and enable registers 00434 * in that different values can be written to the A/B registers. 00435 * Most notably, the SLP_TYP bits can be different, as per the 00436 * values returned from the _Sx predefined methods. 00437 * 00438 ******************************************************************************/ 00439 00440 ACPI_STATUS 00441 AcpiHwWritePm1Control ( 00442 UINT32 Pm1aControl, 00443 UINT32 Pm1bControl) 00444 { 00445 ACPI_STATUS Status; 00446 00447 00448 ACPI_FUNCTION_TRACE (HwWritePm1Control); 00449 00450 00451 Status = AcpiHwWrite (Pm1aControl, &AcpiGbl_FADT.XPm1aControlBlock); 00452 if (ACPI_FAILURE (Status)) 00453 { 00454 return_ACPI_STATUS (Status); 00455 } 00456 00457 if (AcpiGbl_FADT.XPm1bControlBlock.Address) 00458 { 00459 Status = AcpiHwWrite (Pm1bControl, &AcpiGbl_FADT.XPm1bControlBlock); 00460 } 00461 return_ACPI_STATUS (Status); 00462 } 00463 00464 00465 /****************************************************************************** 00466 * 00467 * FUNCTION: AcpiHwRegisterRead 00468 * 00469 * PARAMETERS: RegisterId - ACPI Register ID 00470 * ReturnValue - Where the register value is returned 00471 * 00472 * RETURN: Status and the value read. 00473 * 00474 * DESCRIPTION: Read from the specified ACPI register 00475 * 00476 ******************************************************************************/ 00477 00478 ACPI_STATUS 00479 AcpiHwRegisterRead ( 00480 UINT32 RegisterId, 00481 UINT32 *ReturnValue) 00482 { 00483 UINT32 Value = 0; 00484 ACPI_STATUS Status; 00485 00486 00487 ACPI_FUNCTION_TRACE (HwRegisterRead); 00488 00489 00490 switch (RegisterId) 00491 { 00492 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 00493 00494 Status = AcpiHwReadMultiple (&Value, 00495 &AcpiGbl_XPm1aStatus, 00496 &AcpiGbl_XPm1bStatus); 00497 break; 00498 00499 00500 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ 00501 00502 Status = AcpiHwReadMultiple (&Value, 00503 &AcpiGbl_XPm1aEnable, 00504 &AcpiGbl_XPm1bEnable); 00505 break; 00506 00507 00508 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 00509 00510 Status = AcpiHwReadMultiple (&Value, 00511 &AcpiGbl_FADT.XPm1aControlBlock, 00512 &AcpiGbl_FADT.XPm1bControlBlock); 00513 00514 /* 00515 * Zero the write-only bits. From the ACPI specification, "Hardware 00516 * Write-Only Bits": "Upon reads to registers with write-only bits, 00517 * software masks out all write-only bits." 00518 */ 00519 Value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS; 00520 break; 00521 00522 00523 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 00524 00525 Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPm2ControlBlock); 00526 break; 00527 00528 00529 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 00530 00531 Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPmTimerBlock); 00532 break; 00533 00534 00535 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 00536 00537 Status = AcpiHwReadPort (AcpiGbl_FADT.SmiCommand, &Value, 8); 00538 break; 00539 00540 00541 default: 00542 ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X", 00543 RegisterId)); 00544 Status = AE_BAD_PARAMETER; 00545 break; 00546 } 00547 00548 if (ACPI_SUCCESS (Status)) 00549 { 00550 *ReturnValue = Value; 00551 } 00552 00553 return_ACPI_STATUS (Status); 00554 } 00555 00556 00557 /****************************************************************************** 00558 * 00559 * FUNCTION: AcpiHwRegisterWrite 00560 * 00561 * PARAMETERS: RegisterId - ACPI Register ID 00562 * Value - The value to write 00563 * 00564 * RETURN: Status 00565 * 00566 * DESCRIPTION: Write to the specified ACPI register 00567 * 00568 * NOTE: In accordance with the ACPI specification, this function automatically 00569 * preserves the value of the following bits, meaning that these bits cannot be 00570 * changed via this interface: 00571 * 00572 * PM1_CONTROL[0] = SCI_EN 00573 * PM1_CONTROL[9] 00574 * PM1_STATUS[11] 00575 * 00576 * ACPI References: 00577 * 1) Hardware Ignored Bits: When software writes to a register with ignored 00578 * bit fields, it preserves the ignored bit fields 00579 * 2) SCI_EN: OSPM always preserves this bit position 00580 * 00581 ******************************************************************************/ 00582 00583 ACPI_STATUS 00584 AcpiHwRegisterWrite ( 00585 UINT32 RegisterId, 00586 UINT32 Value) 00587 { 00588 ACPI_STATUS Status; 00589 UINT32 ReadValue; 00590 00591 00592 ACPI_FUNCTION_TRACE (HwRegisterWrite); 00593 00594 00595 switch (RegisterId) 00596 { 00597 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 00598 /* 00599 * Handle the "ignored" bit in PM1 Status. According to the ACPI 00600 * specification, ignored bits are to be preserved when writing. 00601 * Normally, this would mean a read/modify/write sequence. However, 00602 * preserving a bit in the status register is different. Writing a 00603 * one clears the status, and writing a zero preserves the status. 00604 * Therefore, we must always write zero to the ignored bit. 00605 * 00606 * This behavior is clarified in the ACPI 4.0 specification. 00607 */ 00608 Value &= ~ACPI_PM1_STATUS_PRESERVED_BITS; 00609 00610 Status = AcpiHwWriteMultiple (Value, 00611 &AcpiGbl_XPm1aStatus, 00612 &AcpiGbl_XPm1bStatus); 00613 break; 00614 00615 00616 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ 00617 00618 Status = AcpiHwWriteMultiple (Value, 00619 &AcpiGbl_XPm1aEnable, 00620 &AcpiGbl_XPm1bEnable); 00621 break; 00622 00623 00624 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 00625 00626 /* 00627 * Perform a read first to preserve certain bits (per ACPI spec) 00628 * Note: This includes SCI_EN, we never want to change this bit 00629 */ 00630 Status = AcpiHwReadMultiple (&ReadValue, 00631 &AcpiGbl_FADT.XPm1aControlBlock, 00632 &AcpiGbl_FADT.XPm1bControlBlock); 00633 if (ACPI_FAILURE (Status)) 00634 { 00635 goto Exit; 00636 } 00637 00638 /* Insert the bits to be preserved */ 00639 00640 ACPI_INSERT_BITS (Value, ACPI_PM1_CONTROL_PRESERVED_BITS, ReadValue); 00641 00642 /* Now we can write the data */ 00643 00644 Status = AcpiHwWriteMultiple (Value, 00645 &AcpiGbl_FADT.XPm1aControlBlock, 00646 &AcpiGbl_FADT.XPm1bControlBlock); 00647 break; 00648 00649 00650 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 00651 00652 /* 00653 * For control registers, all reserved bits must be preserved, 00654 * as per the ACPI spec. 00655 */ 00656 Status = AcpiHwRead (&ReadValue, &AcpiGbl_FADT.XPm2ControlBlock); 00657 if (ACPI_FAILURE (Status)) 00658 { 00659 goto Exit; 00660 } 00661 00662 /* Insert the bits to be preserved */ 00663 00664 ACPI_INSERT_BITS (Value, ACPI_PM2_CONTROL_PRESERVED_BITS, ReadValue); 00665 00666 Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPm2ControlBlock); 00667 break; 00668 00669 00670 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 00671 00672 Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPmTimerBlock); 00673 break; 00674 00675 00676 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 00677 00678 /* SMI_CMD is currently always in IO space */ 00679 00680 Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand, Value, 8); 00681 break; 00682 00683 00684 default: 00685 ACPI_ERROR ((AE_INFO, "Unknown Register ID: 0x%X", 00686 RegisterId)); 00687 Status = AE_BAD_PARAMETER; 00688 break; 00689 } 00690 00691 Exit: 00692 return_ACPI_STATUS (Status); 00693 } 00694 00695 00696 /****************************************************************************** 00697 * 00698 * FUNCTION: AcpiHwReadMultiple 00699 * 00700 * PARAMETERS: Value - Where the register value is returned 00701 * RegisterA - First ACPI register (required) 00702 * RegisterB - Second ACPI register (optional) 00703 * 00704 * RETURN: Status 00705 * 00706 * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B) 00707 * 00708 ******************************************************************************/ 00709 00710 static ACPI_STATUS 00711 AcpiHwReadMultiple ( 00712 UINT32 *Value, 00713 ACPI_GENERIC_ADDRESS *RegisterA, 00714 ACPI_GENERIC_ADDRESS *RegisterB) 00715 { 00716 UINT32 ValueA = 0; 00717 UINT32 ValueB = 0; 00718 ACPI_STATUS Status; 00719 00720 00721 /* The first register is always required */ 00722 00723 Status = AcpiHwRead (&ValueA, RegisterA); 00724 if (ACPI_FAILURE (Status)) 00725 { 00726 return (Status); 00727 } 00728 00729 /* Second register is optional */ 00730 00731 if (RegisterB->Address) 00732 { 00733 Status = AcpiHwRead (&ValueB, RegisterB); 00734 if (ACPI_FAILURE (Status)) 00735 { 00736 return (Status); 00737 } 00738 } 00739 00740 /* 00741 * OR the two return values together. No shifting or masking is necessary, 00742 * because of how the PM1 registers are defined in the ACPI specification: 00743 * 00744 * "Although the bits can be split between the two register blocks (each 00745 * register block has a unique pointer within the FADT), the bit positions 00746 * are maintained. The register block with unimplemented bits (that is, 00747 * those implemented in the other register block) always returns zeros, 00748 * and writes have no side effects" 00749 */ 00750 *Value = (ValueA | ValueB); 00751 return (AE_OK); 00752 } 00753 00754 00755 /****************************************************************************** 00756 * 00757 * FUNCTION: AcpiHwWriteMultiple 00758 * 00759 * PARAMETERS: Value - The value to write 00760 * RegisterA - First ACPI register (required) 00761 * RegisterB - Second ACPI register (optional) 00762 * 00763 * RETURN: Status 00764 * 00765 * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B) 00766 * 00767 ******************************************************************************/ 00768 00769 static ACPI_STATUS 00770 AcpiHwWriteMultiple ( 00771 UINT32 Value, 00772 ACPI_GENERIC_ADDRESS *RegisterA, 00773 ACPI_GENERIC_ADDRESS *RegisterB) 00774 { 00775 ACPI_STATUS Status; 00776 00777 00778 /* The first register is always required */ 00779 00780 Status = AcpiHwWrite (Value, RegisterA); 00781 if (ACPI_FAILURE (Status)) 00782 { 00783 return (Status); 00784 } 00785 00786 /* 00787 * Second register is optional 00788 * 00789 * No bit shifting or clearing is necessary, because of how the PM1 00790 * registers are defined in the ACPI specification: 00791 * 00792 * "Although the bits can be split between the two register blocks (each 00793 * register block has a unique pointer within the FADT), the bit positions 00794 * are maintained. The register block with unimplemented bits (that is, 00795 * those implemented in the other register block) always returns zeros, 00796 * and writes have no side effects" 00797 */ 00798 if (RegisterB->Address) 00799 { 00800 Status = AcpiHwWrite (Value, RegisterB); 00801 } 00802 00803 return (Status); 00804 } 00805 Generated on Fri May 25 2012 04:25:32 for ReactOS by
1.7.6.1
|