|
||||
Warning, cross-references for /kernel/drivers/acpica/hwregs.c need to be fixed.
0001 0002 /******************************************************************************* 0003 * 0004 * Module Name: hwregs - Read/write access functions for the various ACPI 0005 * control and status registers. 0006 * 0007 ******************************************************************************/ 0008 0009 /****************************************************************************** 0010 * 0011 * 1. Copyright Notice 0012 * 0013 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 0014 * All rights reserved. 0015 * 0016 * 2. License 0017 * 0018 * 2.1. This is your license from Intel Corp. under its intellectual property 0019 * rights. You may have additional license terms from the party that provided 0020 * you this software, covering your right to use that party's intellectual 0021 * property rights. 0022 * 0023 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 0024 * copy of the source code appearing in this file ("Covered Code") an 0025 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 0026 * base code distributed originally by Intel ("Original Intel Code") to copy, 0027 * make derivatives, distribute, use and display any portion of the Covered 0028 * Code in any form, with the right to sublicense such rights; and 0029 * 0030 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 0031 * license (with the right to sublicense), under only those claims of Intel 0032 * patents that are infringed by the Original Intel Code, to make, use, sell, 0033 * offer to sell, and import the Covered Code and derivative works thereof 0034 * solely to the minimum extent necessary to exercise the above copyright 0035 * license, and in no event shall the patent license extend to any additions 0036 * to or modifications of the Original Intel Code. No other license or right 0037 * is granted directly or by implication, estoppel or otherwise; 0038 * 0039 * The above copyright and patent license is granted only if the following 0040 * conditions are met: 0041 * 0042 * 3. Conditions 0043 * 0044 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 0045 * Redistribution of source code of any substantial portion of the Covered 0046 * Code or modification with rights to further distribute source must include 0047 * the above Copyright Notice, the above License, this list of Conditions, 0048 * and the following Disclaimer and Export Compliance provision. In addition, 0049 * Licensee must cause all Covered Code to which Licensee contributes to 0050 * contain a file documenting the changes Licensee made to create that Covered 0051 * Code and the date of any change. Licensee must include in that file the 0052 * documentation of any changes made by any predecessor Licensee. Licensee 0053 * must include a prominent statement that the modification is derived, 0054 * directly or indirectly, from Original Intel Code. 0055 * 0056 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 0057 * Redistribution of source code of any substantial portion of the Covered 0058 * Code or modification without rights to further distribute source must 0059 * include the following Disclaimer and Export Compliance provision in the 0060 * documentation and/or other materials provided with distribution. In 0061 * addition, Licensee may not authorize further sublicense of source of any 0062 * portion of the Covered Code, and must include terms to the effect that the 0063 * license from Licensee to its licensee is limited to the intellectual 0064 * property embodied in the software Licensee provides to its licensee, and 0065 * not to intellectual property embodied in modifications its licensee may 0066 * make. 0067 * 0068 * 3.3. Redistribution of Executable. Redistribution in executable form of any 0069 * substantial portion of the Covered Code or modification must reproduce the 0070 * above Copyright Notice, and the following Disclaimer and Export Compliance 0071 * provision in the documentation and/or other materials provided with the 0072 * distribution. 0073 * 0074 * 3.4. Intel retains all right, title, and interest in and to the Original 0075 * Intel Code. 0076 * 0077 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 0078 * Intel shall be used in advertising or otherwise to promote the sale, use or 0079 * other dealings in products derived from or relating to the Covered Code 0080 * without prior written authorization from Intel. 0081 * 0082 * 4. Disclaimer and Export Compliance 0083 * 0084 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 0085 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 0086 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 0087 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 0088 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 0089 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 0090 * PARTICULAR PURPOSE. 0091 * 0092 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 0093 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 0094 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 0095 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 0096 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 0097 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 0098 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 0099 * LIMITED REMEDY. 0100 * 0101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 0102 * software or system incorporating such software without first obtaining any 0103 * required license or other approval from the U. S. Department of Commerce or 0104 * any other agency or department of the United States Government. In the 0105 * event Licensee exports any such software from the United States or 0106 * re-exports any such software from a foreign destination, Licensee shall 0107 * ensure that the distribution and export/re-export of the software is in 0108 * compliance with all laws, regulations, orders, or other restrictions of the 0109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 0110 * any of its subsidiaries will export/re-export any technical data, process, 0111 * software, or service, directly or indirectly, to any country for which the 0112 * United States government or any agency thereof requires an export license, 0113 * other governmental approval, or letter of assurance, without first obtaining 0114 * such license, approval or letter. 0115 * 0116 *****************************************************************************/ 0117 0118 #define __HWREGS_C__ 0119 0120 #include "acpi.h" 0121 #include "accommon.h" 0122 #include "acevents.h" 0123 0124 #define _COMPONENT ACPI_HARDWARE 0125 ACPI_MODULE_NAME ("hwregs") 0126 0127 0128 /* Local Prototypes */ 0129 0130 static ACPI_STATUS 0131 AcpiHwReadMultiple ( 0132 UINT32 *Value, 0133 ACPI_GENERIC_ADDRESS *RegisterA, 0134 ACPI_GENERIC_ADDRESS *RegisterB); 0135 0136 static ACPI_STATUS 0137 AcpiHwWriteMultiple ( 0138 UINT32 Value, 0139 ACPI_GENERIC_ADDRESS *RegisterA, 0140 ACPI_GENERIC_ADDRESS *RegisterB); 0141 0142 0143 /****************************************************************************** 0144 * 0145 * FUNCTION: AcpiHwValidateRegister 0146 * 0147 * PARAMETERS: Reg - GAS register structure 0148 * MaxBitWidth - Max BitWidth supported (32 or 64) 0149 * Address - Pointer to where the gas->address 0150 * is returned 0151 * 0152 * RETURN: Status 0153 * 0154 * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS 0155 * pointer, Address, SpaceId, BitWidth, and BitOffset. 0156 * 0157 ******************************************************************************/ 0158 0159 ACPI_STATUS 0160 AcpiHwValidateRegister ( 0161 ACPI_GENERIC_ADDRESS *Reg, 0162 UINT8 MaxBitWidth, 0163 UINT64 *Address) 0164 { 0165 0166 /* Must have a valid pointer to a GAS structure */ 0167 0168 if (!Reg) 0169 { 0170 return (AE_BAD_PARAMETER); 0171 } 0172 0173 /* 0174 * Copy the target address. This handles possible alignment issues. 0175 * Address must not be null. A null address also indicates an optional 0176 * ACPI register that is not supported, so no error message. 0177 */ 0178 ACPI_MOVE_64_TO_64 (Address, &Reg->Address); 0179 if (!(*Address)) 0180 { 0181 return (AE_BAD_ADDRESS); 0182 } 0183 0184 /* Validate the SpaceID */ 0185 0186 if ((Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_MEMORY) && 0187 (Reg->SpaceId != ACPI_ADR_SPACE_SYSTEM_IO)) 0188 { 0189 ACPI_ERROR ((AE_INFO, 0190 "Unsupported address space: 0x%X", Reg->SpaceId)); 0191 return (AE_SUPPORT); 0192 } 0193 0194 /* Validate the BitWidth */ 0195 0196 if ((Reg->BitWidth != 8) && 0197 (Reg->BitWidth != 16) && 0198 (Reg->BitWidth != 32) && 0199 (Reg->BitWidth != MaxBitWidth)) 0200 { 0201 ACPI_ERROR ((AE_INFO, 0202 "Unsupported register bit width: 0x%X", Reg->BitWidth)); 0203 return (AE_SUPPORT); 0204 } 0205 0206 /* Validate the BitOffset. Just a warning for now. */ 0207 0208 if (Reg->BitOffset != 0) 0209 { 0210 ACPI_WARNING ((AE_INFO, 0211 "Unsupported register bit offset: 0x%X", Reg->BitOffset)); 0212 } 0213 0214 return (AE_OK); 0215 } 0216 0217 0218 /****************************************************************************** 0219 * 0220 * FUNCTION: AcpiHwRead 0221 * 0222 * PARAMETERS: Value - Where the value is returned 0223 * Reg - GAS register structure 0224 * 0225 * RETURN: Status 0226 * 0227 * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max 0228 * version of AcpiRead, used internally since the overhead of 0229 * 64-bit values is not needed. 0230 * 0231 * LIMITATIONS: <These limitations also apply to AcpiHwWrite> 0232 * BitWidth must be exactly 8, 16, or 32. 0233 * SpaceID must be SystemMemory or SystemIO. 0234 * BitOffset and AccessWidth are currently ignored, as there has 0235 * not been a need to implement these. 0236 * 0237 ******************************************************************************/ 0238 0239 ACPI_STATUS 0240 AcpiHwRead ( 0241 UINT32 *Value, 0242 ACPI_GENERIC_ADDRESS *Reg) 0243 { 0244 UINT64 Address; 0245 ACPI_STATUS Status; 0246 0247 0248 ACPI_FUNCTION_NAME (HwRead); 0249 0250 0251 /* Validate contents of the GAS register */ 0252 0253 Status = AcpiHwValidateRegister (Reg, 32, &Address); 0254 if (ACPI_FAILURE (Status)) 0255 { 0256 return (Status); 0257 } 0258 0259 /* Initialize entire 32-bit return value to zero */ 0260 0261 *Value = 0; 0262 0263 /* 0264 * Two address spaces supported: Memory or IO. PCI_Config is 0265 * not supported here because the GAS structure is insufficient 0266 */ 0267 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) 0268 { 0269 Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS) 0270 Address, Value, Reg->BitWidth); 0271 } 0272 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ 0273 { 0274 Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) 0275 Address, Value, Reg->BitWidth); 0276 } 0277 0278 ACPI_DEBUG_PRINT ((ACPI_DB_IO, 0279 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", 0280 *Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address), 0281 AcpiUtGetRegionName (Reg->SpaceId))); 0282 0283 return (Status); 0284 } 0285 0286 0287 /****************************************************************************** 0288 * 0289 * FUNCTION: AcpiHwWrite 0290 * 0291 * PARAMETERS: Value - Value to be written 0292 * Reg - GAS register structure 0293 * 0294 * RETURN: Status 0295 * 0296 * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max 0297 * version of AcpiWrite, used internally since the overhead of 0298 * 64-bit values is not needed. 0299 * 0300 ******************************************************************************/ 0301 0302 ACPI_STATUS 0303 AcpiHwWrite ( 0304 UINT32 Value, 0305 ACPI_GENERIC_ADDRESS *Reg) 0306 { 0307 UINT64 Address; 0308 ACPI_STATUS Status; 0309 0310 0311 ACPI_FUNCTION_NAME (HwWrite); 0312 0313 0314 /* Validate contents of the GAS register */ 0315 0316 Status = AcpiHwValidateRegister (Reg, 32, &Address); 0317 if (ACPI_FAILURE (Status)) 0318 { 0319 return (Status); 0320 } 0321 0322 /* 0323 * Two address spaces supported: Memory or IO. PCI_Config is 0324 * not supported here because the GAS structure is insufficient 0325 */ 0326 if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY) 0327 { 0328 Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS) 0329 Address, Value, Reg->BitWidth); 0330 } 0331 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ 0332 { 0333 Status = AcpiHwWritePort ((ACPI_IO_ADDRESS) 0334 Address, Value, Reg->BitWidth); 0335 } 0336 0337 ACPI_DEBUG_PRINT ((ACPI_DB_IO, 0338 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", 0339 Value, Reg->BitWidth, ACPI_FORMAT_UINT64 (Address), 0340 AcpiUtGetRegionName (Reg->SpaceId))); 0341 0342 return (Status); 0343 } 0344 0345 0346 /******************************************************************************* 0347 * 0348 * FUNCTION: AcpiHwClearAcpiStatus 0349 * 0350 * PARAMETERS: None 0351 * 0352 * RETURN: Status 0353 * 0354 * DESCRIPTION: Clears all fixed and general purpose status bits 0355 * 0356 ******************************************************************************/ 0357 0358 ACPI_STATUS 0359 AcpiHwClearAcpiStatus ( 0360 void) 0361 { 0362 ACPI_STATUS Status; 0363 ACPI_CPU_FLAGS LockFlags = 0; 0364 0365 0366 ACPI_FUNCTION_TRACE (HwClearAcpiStatus); 0367 0368 0369 ACPI_DEBUG_PRINT ((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n", 0370 ACPI_BITMASK_ALL_FIXED_STATUS, 0371 ACPI_FORMAT_UINT64 (AcpiGbl_XPm1aStatus.Address))); 0372 0373 LockFlags = AcpiOsAcquireLock (AcpiGbl_HardwareLock); 0374 0375 /* Clear the fixed events in PM1 A/B */ 0376 0377 Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS, 0378 ACPI_BITMASK_ALL_FIXED_STATUS); 0379 if (ACPI_FAILURE (Status)) 0380 { 0381 goto UnlockAndExit; 0382 } 0383 0384 /* Clear the GPE Bits in all GPE registers in all GPE blocks */ 0385 0386 Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, NULL); 0387 0388 UnlockAndExit: 0389 AcpiOsReleaseLock (AcpiGbl_HardwareLock, LockFlags); 0390 return_ACPI_STATUS (Status); 0391 } 0392 0393 0394 /******************************************************************************* 0395 * 0396 * FUNCTION: AcpiHwGetRegisterBitMask 0397 * 0398 * PARAMETERS: RegisterId - Index of ACPI Register to access 0399 * 0400 * RETURN: The bitmask to be used when accessing the register 0401 * 0402 * DESCRIPTION: Map RegisterId into a register bitmask. 0403 * 0404 ******************************************************************************/ 0405 0406 ACPI_BIT_REGISTER_INFO * 0407 AcpiHwGetBitRegisterInfo ( 0408 UINT32 RegisterId) 0409 { 0410 ACPI_FUNCTION_ENTRY (); 0411 0412 0413 if (RegisterId > ACPI_BITREG_MAX) 0414 { 0415 ACPI_ERROR ((AE_INFO, "Invalid BitRegister ID: %X", RegisterId)); 0416 return (NULL); 0417 } 0418 0419 return (&AcpiGbl_BitRegisterInfo[RegisterId]); 0420 } 0421 0422 0423 /****************************************************************************** 0424 * 0425 * FUNCTION: AcpiHwWritePm1Control 0426 * 0427 * PARAMETERS: Pm1aControl - Value to be written to PM1A control 0428 * Pm1bControl - Value to be written to PM1B control 0429 * 0430 * RETURN: Status 0431 * 0432 * DESCRIPTION: Write the PM1 A/B control registers. These registers are 0433 * different than than the PM1 A/B status and enable registers 0434 * in that different values can be written to the A/B registers. 0435 * Most notably, the SLP_TYP bits can be different, as per the 0436 * values returned from the _Sx predefined methods. 0437 * 0438 ******************************************************************************/ 0439 0440 ACPI_STATUS 0441 AcpiHwWritePm1Control ( 0442 UINT32 Pm1aControl, 0443 UINT32 Pm1bControl) 0444 { 0445 ACPI_STATUS Status; 0446 0447 0448 ACPI_FUNCTION_TRACE (HwWritePm1Control); 0449 0450 0451 Status = AcpiHwWrite (Pm1aControl, &AcpiGbl_FADT.XPm1aControlBlock); 0452 if (ACPI_FAILURE (Status)) 0453 { 0454 return_ACPI_STATUS (Status); 0455 } 0456 0457 if (AcpiGbl_FADT.XPm1bControlBlock.Address) 0458 { 0459 Status = AcpiHwWrite (Pm1bControl, &AcpiGbl_FADT.XPm1bControlBlock); 0460 } 0461 return_ACPI_STATUS (Status); 0462 } 0463 0464 0465 /****************************************************************************** 0466 * 0467 * FUNCTION: AcpiHwRegisterRead 0468 * 0469 * PARAMETERS: RegisterId - ACPI Register ID 0470 * ReturnValue - Where the register value is returned 0471 * 0472 * RETURN: Status and the value read. 0473 * 0474 * DESCRIPTION: Read from the specified ACPI register 0475 * 0476 ******************************************************************************/ 0477 0478 ACPI_STATUS 0479 AcpiHwRegisterRead ( 0480 UINT32 RegisterId, 0481 UINT32 *ReturnValue) 0482 { 0483 UINT32 Value = 0; 0484 ACPI_STATUS Status; 0485 0486 0487 ACPI_FUNCTION_TRACE (HwRegisterRead); 0488 0489 0490 switch (RegisterId) 0491 { 0492 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 0493 0494 Status = AcpiHwReadMultiple (&Value, 0495 &AcpiGbl_XPm1aStatus, 0496 &AcpiGbl_XPm1bStatus); 0497 break; 0498 0499 0500 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ 0501 0502 Status = AcpiHwReadMultiple (&Value, 0503 &AcpiGbl_XPm1aEnable, 0504 &AcpiGbl_XPm1bEnable); 0505 break; 0506 0507 0508 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 0509 0510 Status = AcpiHwReadMultiple (&Value, 0511 &AcpiGbl_FADT.XPm1aControlBlock, 0512 &AcpiGbl_FADT.XPm1bControlBlock); 0513 0514 /* 0515 * Zero the write-only bits. From the ACPI specification, "Hardware 0516 * Write-Only Bits": "Upon reads to registers with write-only bits, 0517 * software masks out all write-only bits." 0518 */ 0519 Value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS; 0520 break; 0521 0522 0523 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 0524 0525 Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPm2ControlBlock); 0526 break; 0527 0528 0529 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 0530 0531 Status = AcpiHwRead (&Value, &AcpiGbl_FADT.XPmTimerBlock); 0532 break; 0533 0534 0535 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 0536 0537 Status = AcpiHwReadPort (AcpiGbl_FADT.SmiCommand, &Value, 8); 0538 break; 0539 0540 0541 default: 0542 ACPI_ERROR ((AE_INFO, "Unknown Register ID: %X", 0543 RegisterId)); 0544 Status = AE_BAD_PARAMETER; 0545 break; 0546 } 0547 0548 if (ACPI_SUCCESS (Status)) 0549 { 0550 *ReturnValue = Value; 0551 } 0552 0553 return_ACPI_STATUS (Status); 0554 } 0555 0556 0557 /****************************************************************************** 0558 * 0559 * FUNCTION: AcpiHwRegisterWrite 0560 * 0561 * PARAMETERS: RegisterId - ACPI Register ID 0562 * Value - The value to write 0563 * 0564 * RETURN: Status 0565 * 0566 * DESCRIPTION: Write to the specified ACPI register 0567 * 0568 * NOTE: In accordance with the ACPI specification, this function automatically 0569 * preserves the value of the following bits, meaning that these bits cannot be 0570 * changed via this interface: 0571 * 0572 * PM1_CONTROL[0] = SCI_EN 0573 * PM1_CONTROL[9] 0574 * PM1_STATUS[11] 0575 * 0576 * ACPI References: 0577 * 1) Hardware Ignored Bits: When software writes to a register with ignored 0578 * bit fields, it preserves the ignored bit fields 0579 * 2) SCI_EN: OSPM always preserves this bit position 0580 * 0581 ******************************************************************************/ 0582 0583 ACPI_STATUS 0584 AcpiHwRegisterWrite ( 0585 UINT32 RegisterId, 0586 UINT32 Value) 0587 { 0588 ACPI_STATUS Status; 0589 UINT32 ReadValue; 0590 0591 0592 ACPI_FUNCTION_TRACE (HwRegisterWrite); 0593 0594 0595 switch (RegisterId) 0596 { 0597 case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ 0598 /* 0599 * Handle the "ignored" bit in PM1 Status. According to the ACPI 0600 * specification, ignored bits are to be preserved when writing. 0601 * Normally, this would mean a read/modify/write sequence. However, 0602 * preserving a bit in the status register is different. Writing a 0603 * one clears the status, and writing a zero preserves the status. 0604 * Therefore, we must always write zero to the ignored bit. 0605 * 0606 * This behavior is clarified in the ACPI 4.0 specification. 0607 */ 0608 Value &= ~ACPI_PM1_STATUS_PRESERVED_BITS; 0609 0610 Status = AcpiHwWriteMultiple (Value, 0611 &AcpiGbl_XPm1aStatus, 0612 &AcpiGbl_XPm1bStatus); 0613 break; 0614 0615 0616 case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ 0617 0618 Status = AcpiHwWriteMultiple (Value, 0619 &AcpiGbl_XPm1aEnable, 0620 &AcpiGbl_XPm1bEnable); 0621 break; 0622 0623 0624 case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ 0625 0626 /* 0627 * Perform a read first to preserve certain bits (per ACPI spec) 0628 * Note: This includes SCI_EN, we never want to change this bit 0629 */ 0630 Status = AcpiHwReadMultiple (&ReadValue, 0631 &AcpiGbl_FADT.XPm1aControlBlock, 0632 &AcpiGbl_FADT.XPm1bControlBlock); 0633 if (ACPI_FAILURE (Status)) 0634 { 0635 goto Exit; 0636 } 0637 0638 /* Insert the bits to be preserved */ 0639 0640 ACPI_INSERT_BITS (Value, ACPI_PM1_CONTROL_PRESERVED_BITS, ReadValue); 0641 0642 /* Now we can write the data */ 0643 0644 Status = AcpiHwWriteMultiple (Value, 0645 &AcpiGbl_FADT.XPm1aControlBlock, 0646 &AcpiGbl_FADT.XPm1bControlBlock); 0647 break; 0648 0649 0650 case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ 0651 0652 /* 0653 * For control registers, all reserved bits must be preserved, 0654 * as per the ACPI spec. 0655 */ 0656 Status = AcpiHwRead (&ReadValue, &AcpiGbl_FADT.XPm2ControlBlock); 0657 if (ACPI_FAILURE (Status)) 0658 { 0659 goto Exit; 0660 } 0661 0662 /* Insert the bits to be preserved */ 0663 0664 ACPI_INSERT_BITS (Value, ACPI_PM2_CONTROL_PRESERVED_BITS, ReadValue); 0665 0666 Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPm2ControlBlock); 0667 break; 0668 0669 0670 case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ 0671 0672 Status = AcpiHwWrite (Value, &AcpiGbl_FADT.XPmTimerBlock); 0673 break; 0674 0675 0676 case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ 0677 0678 /* SMI_CMD is currently always in IO space */ 0679 0680 Status = AcpiHwWritePort (AcpiGbl_FADT.SmiCommand, Value, 8); 0681 break; 0682 0683 0684 default: 0685 ACPI_ERROR ((AE_INFO, "Unknown Register ID: %X", 0686 RegisterId)); 0687 Status = AE_BAD_PARAMETER; 0688 break; 0689 } 0690 0691 Exit: 0692 return_ACPI_STATUS (Status); 0693 } 0694 0695 0696 /****************************************************************************** 0697 * 0698 * FUNCTION: AcpiHwReadMultiple 0699 * 0700 * PARAMETERS: Value - Where the register value is returned 0701 * RegisterA - First ACPI register (required) 0702 * RegisterB - Second ACPI register (optional) 0703 * 0704 * RETURN: Status 0705 * 0706 * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B) 0707 * 0708 ******************************************************************************/ 0709 0710 static ACPI_STATUS 0711 AcpiHwReadMultiple ( 0712 UINT32 *Value, 0713 ACPI_GENERIC_ADDRESS *RegisterA, 0714 ACPI_GENERIC_ADDRESS *RegisterB) 0715 { 0716 UINT32 ValueA = 0; 0717 UINT32 ValueB = 0; 0718 ACPI_STATUS Status; 0719 0720 0721 /* The first register is always required */ 0722 0723 Status = AcpiHwRead (&ValueA, RegisterA); 0724 if (ACPI_FAILURE (Status)) 0725 { 0726 return (Status); 0727 } 0728 0729 /* Second register is optional */ 0730 0731 if (RegisterB->Address) 0732 { 0733 Status = AcpiHwRead (&ValueB, RegisterB); 0734 if (ACPI_FAILURE (Status)) 0735 { 0736 return (Status); 0737 } 0738 } 0739 0740 /* 0741 * OR the two return values together. No shifting or masking is necessary, 0742 * because of how the PM1 registers are defined in the ACPI specification: 0743 * 0744 * "Although the bits can be split between the two register blocks (each 0745 * register block has a unique pointer within the FADT), the bit positions 0746 * are maintained. The register block with unimplemented bits (that is, 0747 * those implemented in the other register block) always returns zeros, 0748 * and writes have no side effects" 0749 */ 0750 *Value = (ValueA | ValueB); 0751 return (AE_OK); 0752 } 0753 0754 0755 /****************************************************************************** 0756 * 0757 * FUNCTION: AcpiHwWriteMultiple 0758 * 0759 * PARAMETERS: Value - The value to write 0760 * RegisterA - First ACPI register (required) 0761 * RegisterB - Second ACPI register (optional) 0762 * 0763 * RETURN: Status 0764 * 0765 * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B) 0766 * 0767 ******************************************************************************/ 0768 0769 static ACPI_STATUS 0770 AcpiHwWriteMultiple ( 0771 UINT32 Value, 0772 ACPI_GENERIC_ADDRESS *RegisterA, 0773 ACPI_GENERIC_ADDRESS *RegisterB) 0774 { 0775 ACPI_STATUS Status; 0776 0777 0778 /* The first register is always required */ 0779 0780 Status = AcpiHwWrite (Value, RegisterA); 0781 if (ACPI_FAILURE (Status)) 0782 { 0783 return (Status); 0784 } 0785 0786 /* 0787 * Second register is optional 0788 * 0789 * No bit shifting or clearing is necessary, because of how the PM1 0790 * registers are defined in the ACPI specification: 0791 * 0792 * "Although the bits can be split between the two register blocks (each 0793 * register block has a unique pointer within the FADT), the bit positions 0794 * are maintained. The register block with unimplemented bits (that is, 0795 * those implemented in the other register block) always returns zeros, 0796 * and writes have no side effects" 0797 */ 0798 if (RegisterB->Address) 0799 { 0800 Status = AcpiHwWrite (Value, RegisterB); 0801 } 0802 0803 return (Status); 0804 } 0805
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 1.2.0 LXR engine. |