1 /*******************************************************************************
3 * Module Name: hwregs - Read/write access functions for the various ACPI
4 * control and status registers.
6 ******************************************************************************/
9 * Copyright (C) 2000 - 2013, Intel Corp.
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
51 #define _COMPONENT ACPI_HARDWARE
52 ACPI_MODULE_NAME ("hwregs")
55 #if (!ACPI_REDUCED_HARDWARE)
57 /* Local Prototypes */
62 ACPI_GENERIC_ADDRESS
*RegisterA
,
63 ACPI_GENERIC_ADDRESS
*RegisterB
);
68 ACPI_GENERIC_ADDRESS
*RegisterA
,
69 ACPI_GENERIC_ADDRESS
*RegisterB
);
71 #endif /* !ACPI_REDUCED_HARDWARE */
73 /******************************************************************************
75 * FUNCTION: AcpiHwValidateRegister
77 * PARAMETERS: Reg - GAS register structure
78 * MaxBitWidth - Max BitWidth supported (32 or 64)
79 * Address - Pointer to where the gas->address
84 * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS
85 * pointer, Address, SpaceId, BitWidth, and BitOffset.
87 ******************************************************************************/
90 AcpiHwValidateRegister (
91 ACPI_GENERIC_ADDRESS
*Reg
,
96 /* Must have a valid pointer to a GAS structure */
100 return (AE_BAD_PARAMETER
);
104 * Copy the target address. This handles possible alignment issues.
105 * Address must not be null. A null address also indicates an optional
106 * ACPI register that is not supported, so no error message.
108 ACPI_MOVE_64_TO_64 (Address
, &Reg
->Address
);
111 return (AE_BAD_ADDRESS
);
114 /* Validate the SpaceID */
116 if ((Reg
->SpaceId
!= ACPI_ADR_SPACE_SYSTEM_MEMORY
) &&
117 (Reg
->SpaceId
!= ACPI_ADR_SPACE_SYSTEM_IO
))
119 ACPI_ERROR ((AE_INFO
,
120 "Unsupported address space: 0x%X", Reg
->SpaceId
));
124 /* Validate the BitWidth */
126 if ((Reg
->BitWidth
!= 8) &&
127 (Reg
->BitWidth
!= 16) &&
128 (Reg
->BitWidth
!= 32) &&
129 (Reg
->BitWidth
!= MaxBitWidth
))
131 ACPI_ERROR ((AE_INFO
,
132 "Unsupported register bit width: 0x%X", Reg
->BitWidth
));
136 /* Validate the BitOffset. Just a warning for now. */
138 if (Reg
->BitOffset
!= 0)
140 ACPI_WARNING ((AE_INFO
,
141 "Unsupported register bit offset: 0x%X", Reg
->BitOffset
));
148 /******************************************************************************
150 * FUNCTION: AcpiHwRead
152 * PARAMETERS: Value - Where the value is returned
153 * Reg - GAS register structure
157 * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max
158 * version of AcpiRead, used internally since the overhead of
159 * 64-bit values is not needed.
161 * LIMITATIONS: <These limitations also apply to AcpiHwWrite>
162 * BitWidth must be exactly 8, 16, or 32.
163 * SpaceID must be SystemMemory or SystemIO.
164 * BitOffset and AccessWidth are currently ignored, as there has
165 * not been a need to implement these.
167 ******************************************************************************/
172 ACPI_GENERIC_ADDRESS
*Reg
)
179 ACPI_FUNCTION_NAME (HwRead
);
182 /* Validate contents of the GAS register */
184 Status
= AcpiHwValidateRegister (Reg
, 32, &Address
);
185 if (ACPI_FAILURE (Status
))
190 /* Initialize entire 32-bit return value to zero */
195 * Two address spaces supported: Memory or IO. PCI_Config is
196 * not supported here because the GAS structure is insufficient
198 if (Reg
->SpaceId
== ACPI_ADR_SPACE_SYSTEM_MEMORY
)
200 Status
= AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS
)
201 Address
, &Value64
, Reg
->BitWidth
);
203 *Value
= (UINT32
) Value64
;
205 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
207 Status
= AcpiHwReadPort ((ACPI_IO_ADDRESS
)
208 Address
, Value
, Reg
->BitWidth
);
211 ACPI_DEBUG_PRINT ((ACPI_DB_IO
,
212 "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
213 *Value
, Reg
->BitWidth
, ACPI_FORMAT_UINT64 (Address
),
214 AcpiUtGetRegionName (Reg
->SpaceId
)));
220 /******************************************************************************
222 * FUNCTION: AcpiHwWrite
224 * PARAMETERS: Value - Value to be written
225 * Reg - GAS register structure
229 * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max
230 * version of AcpiWrite, used internally since the overhead of
231 * 64-bit values is not needed.
233 ******************************************************************************/
238 ACPI_GENERIC_ADDRESS
*Reg
)
244 ACPI_FUNCTION_NAME (HwWrite
);
247 /* Validate contents of the GAS register */
249 Status
= AcpiHwValidateRegister (Reg
, 32, &Address
);
250 if (ACPI_FAILURE (Status
))
256 * Two address spaces supported: Memory or IO. PCI_Config is
257 * not supported here because the GAS structure is insufficient
259 if (Reg
->SpaceId
== ACPI_ADR_SPACE_SYSTEM_MEMORY
)
261 Status
= AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS
)
262 Address
, (UINT64
) Value
, Reg
->BitWidth
);
264 else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
266 Status
= AcpiHwWritePort ((ACPI_IO_ADDRESS
)
267 Address
, Value
, Reg
->BitWidth
);
270 ACPI_DEBUG_PRINT ((ACPI_DB_IO
,
271 "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
272 Value
, Reg
->BitWidth
, ACPI_FORMAT_UINT64 (Address
),
273 AcpiUtGetRegionName (Reg
->SpaceId
)));
279 #if (!ACPI_REDUCED_HARDWARE)
280 /*******************************************************************************
282 * FUNCTION: AcpiHwClearAcpiStatus
288 * DESCRIPTION: Clears all fixed and general purpose status bits
290 ******************************************************************************/
293 AcpiHwClearAcpiStatus (
297 ACPI_CPU_FLAGS LockFlags
= 0;
300 ACPI_FUNCTION_TRACE (HwClearAcpiStatus
);
303 ACPI_DEBUG_PRINT ((ACPI_DB_IO
, "About to write %04X to %8.8X%8.8X\n",
304 ACPI_BITMASK_ALL_FIXED_STATUS
,
305 ACPI_FORMAT_UINT64 (AcpiGbl_XPm1aStatus
.Address
)));
307 LockFlags
= AcpiOsAcquireLock (AcpiGbl_HardwareLock
);
309 /* Clear the fixed events in PM1 A/B */
311 Status
= AcpiHwRegisterWrite (ACPI_REGISTER_PM1_STATUS
,
312 ACPI_BITMASK_ALL_FIXED_STATUS
);
313 if (ACPI_FAILURE (Status
))
318 /* Clear the GPE Bits in all GPE registers in all GPE blocks */
320 Status
= AcpiEvWalkGpeList (AcpiHwClearGpeBlock
, NULL
);
323 AcpiOsReleaseLock (AcpiGbl_HardwareLock
, LockFlags
);
324 return_ACPI_STATUS (Status
);
328 /*******************************************************************************
330 * FUNCTION: AcpiHwGetBitRegisterInfo
332 * PARAMETERS: RegisterId - Index of ACPI Register to access
334 * RETURN: The bitmask to be used when accessing the register
336 * DESCRIPTION: Map RegisterId into a register bitmask.
338 ******************************************************************************/
340 ACPI_BIT_REGISTER_INFO
*
341 AcpiHwGetBitRegisterInfo (
344 ACPI_FUNCTION_ENTRY ();
347 if (RegisterId
> ACPI_BITREG_MAX
)
349 ACPI_ERROR ((AE_INFO
, "Invalid BitRegister ID: 0x%X", RegisterId
));
353 return (&AcpiGbl_BitRegisterInfo
[RegisterId
]);
357 /******************************************************************************
359 * FUNCTION: AcpiHwWritePm1Control
361 * PARAMETERS: Pm1aControl - Value to be written to PM1A control
362 * Pm1bControl - Value to be written to PM1B control
366 * DESCRIPTION: Write the PM1 A/B control registers. These registers are
367 * different than than the PM1 A/B status and enable registers
368 * in that different values can be written to the A/B registers.
369 * Most notably, the SLP_TYP bits can be different, as per the
370 * values returned from the _Sx predefined methods.
372 ******************************************************************************/
375 AcpiHwWritePm1Control (
382 ACPI_FUNCTION_TRACE (HwWritePm1Control
);
385 Status
= AcpiHwWrite (Pm1aControl
, &AcpiGbl_FADT
.XPm1aControlBlock
);
386 if (ACPI_FAILURE (Status
))
388 return_ACPI_STATUS (Status
);
391 if (AcpiGbl_FADT
.XPm1bControlBlock
.Address
)
393 Status
= AcpiHwWrite (Pm1bControl
, &AcpiGbl_FADT
.XPm1bControlBlock
);
395 return_ACPI_STATUS (Status
);
399 /******************************************************************************
401 * FUNCTION: AcpiHwRegisterRead
403 * PARAMETERS: RegisterId - ACPI Register ID
404 * ReturnValue - Where the register value is returned
406 * RETURN: Status and the value read.
408 * DESCRIPTION: Read from the specified ACPI register
410 ******************************************************************************/
421 ACPI_FUNCTION_TRACE (HwRegisterRead
);
426 case ACPI_REGISTER_PM1_STATUS
: /* PM1 A/B: 16-bit access each */
428 Status
= AcpiHwReadMultiple (&Value
,
429 &AcpiGbl_XPm1aStatus
,
430 &AcpiGbl_XPm1bStatus
);
433 case ACPI_REGISTER_PM1_ENABLE
: /* PM1 A/B: 16-bit access each */
435 Status
= AcpiHwReadMultiple (&Value
,
436 &AcpiGbl_XPm1aEnable
,
437 &AcpiGbl_XPm1bEnable
);
440 case ACPI_REGISTER_PM1_CONTROL
: /* PM1 A/B: 16-bit access each */
442 Status
= AcpiHwReadMultiple (&Value
,
443 &AcpiGbl_FADT
.XPm1aControlBlock
,
444 &AcpiGbl_FADT
.XPm1bControlBlock
);
447 * Zero the write-only bits. From the ACPI specification, "Hardware
448 * Write-Only Bits": "Upon reads to registers with write-only bits,
449 * software masks out all write-only bits."
451 Value
&= ~ACPI_PM1_CONTROL_WRITEONLY_BITS
;
454 case ACPI_REGISTER_PM2_CONTROL
: /* 8-bit access */
456 Status
= AcpiHwRead (&Value
, &AcpiGbl_FADT
.XPm2ControlBlock
);
459 case ACPI_REGISTER_PM_TIMER
: /* 32-bit access */
461 Status
= AcpiHwRead (&Value
, &AcpiGbl_FADT
.XPmTimerBlock
);
464 case ACPI_REGISTER_SMI_COMMAND_BLOCK
: /* 8-bit access */
466 Status
= AcpiHwReadPort (AcpiGbl_FADT
.SmiCommand
, &Value
, 8);
471 ACPI_ERROR ((AE_INFO
, "Unknown Register ID: 0x%X",
473 Status
= AE_BAD_PARAMETER
;
477 if (ACPI_SUCCESS (Status
))
479 *ReturnValue
= Value
;
482 return_ACPI_STATUS (Status
);
486 /******************************************************************************
488 * FUNCTION: AcpiHwRegisterWrite
490 * PARAMETERS: RegisterId - ACPI Register ID
491 * Value - The value to write
495 * DESCRIPTION: Write to the specified ACPI register
497 * NOTE: In accordance with the ACPI specification, this function automatically
498 * preserves the value of the following bits, meaning that these bits cannot be
499 * changed via this interface:
501 * PM1_CONTROL[0] = SCI_EN
506 * 1) Hardware Ignored Bits: When software writes to a register with ignored
507 * bit fields, it preserves the ignored bit fields
508 * 2) SCI_EN: OSPM always preserves this bit position
510 ******************************************************************************/
513 AcpiHwRegisterWrite (
521 ACPI_FUNCTION_TRACE (HwRegisterWrite
);
526 case ACPI_REGISTER_PM1_STATUS
: /* PM1 A/B: 16-bit access each */
528 * Handle the "ignored" bit in PM1 Status. According to the ACPI
529 * specification, ignored bits are to be preserved when writing.
530 * Normally, this would mean a read/modify/write sequence. However,
531 * preserving a bit in the status register is different. Writing a
532 * one clears the status, and writing a zero preserves the status.
533 * Therefore, we must always write zero to the ignored bit.
535 * This behavior is clarified in the ACPI 4.0 specification.
537 Value
&= ~ACPI_PM1_STATUS_PRESERVED_BITS
;
539 Status
= AcpiHwWriteMultiple (Value
,
540 &AcpiGbl_XPm1aStatus
,
541 &AcpiGbl_XPm1bStatus
);
544 case ACPI_REGISTER_PM1_ENABLE
: /* PM1 A/B: 16-bit access each */
546 Status
= AcpiHwWriteMultiple (Value
,
547 &AcpiGbl_XPm1aEnable
,
548 &AcpiGbl_XPm1bEnable
);
551 case ACPI_REGISTER_PM1_CONTROL
: /* PM1 A/B: 16-bit access each */
553 * Perform a read first to preserve certain bits (per ACPI spec)
554 * Note: This includes SCI_EN, we never want to change this bit
556 Status
= AcpiHwReadMultiple (&ReadValue
,
557 &AcpiGbl_FADT
.XPm1aControlBlock
,
558 &AcpiGbl_FADT
.XPm1bControlBlock
);
559 if (ACPI_FAILURE (Status
))
564 /* Insert the bits to be preserved */
566 ACPI_INSERT_BITS (Value
, ACPI_PM1_CONTROL_PRESERVED_BITS
, ReadValue
);
568 /* Now we can write the data */
570 Status
= AcpiHwWriteMultiple (Value
,
571 &AcpiGbl_FADT
.XPm1aControlBlock
,
572 &AcpiGbl_FADT
.XPm1bControlBlock
);
575 case ACPI_REGISTER_PM2_CONTROL
: /* 8-bit access */
577 * For control registers, all reserved bits must be preserved,
578 * as per the ACPI spec.
580 Status
= AcpiHwRead (&ReadValue
, &AcpiGbl_FADT
.XPm2ControlBlock
);
581 if (ACPI_FAILURE (Status
))
586 /* Insert the bits to be preserved */
588 ACPI_INSERT_BITS (Value
, ACPI_PM2_CONTROL_PRESERVED_BITS
, ReadValue
);
590 Status
= AcpiHwWrite (Value
, &AcpiGbl_FADT
.XPm2ControlBlock
);
593 case ACPI_REGISTER_PM_TIMER
: /* 32-bit access */
595 Status
= AcpiHwWrite (Value
, &AcpiGbl_FADT
.XPmTimerBlock
);
598 case ACPI_REGISTER_SMI_COMMAND_BLOCK
: /* 8-bit access */
600 /* SMI_CMD is currently always in IO space */
602 Status
= AcpiHwWritePort (AcpiGbl_FADT
.SmiCommand
, Value
, 8);
607 ACPI_ERROR ((AE_INFO
, "Unknown Register ID: 0x%X",
609 Status
= AE_BAD_PARAMETER
;
614 return_ACPI_STATUS (Status
);
618 /******************************************************************************
620 * FUNCTION: AcpiHwReadMultiple
622 * PARAMETERS: Value - Where the register value is returned
623 * RegisterA - First ACPI register (required)
624 * RegisterB - Second ACPI register (optional)
628 * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
630 ******************************************************************************/
635 ACPI_GENERIC_ADDRESS
*RegisterA
,
636 ACPI_GENERIC_ADDRESS
*RegisterB
)
643 /* The first register is always required */
645 Status
= AcpiHwRead (&ValueA
, RegisterA
);
646 if (ACPI_FAILURE (Status
))
651 /* Second register is optional */
653 if (RegisterB
->Address
)
655 Status
= AcpiHwRead (&ValueB
, RegisterB
);
656 if (ACPI_FAILURE (Status
))
663 * OR the two return values together. No shifting or masking is necessary,
664 * because of how the PM1 registers are defined in the ACPI specification:
666 * "Although the bits can be split between the two register blocks (each
667 * register block has a unique pointer within the FADT), the bit positions
668 * are maintained. The register block with unimplemented bits (that is,
669 * those implemented in the other register block) always returns zeros,
670 * and writes have no side effects"
672 *Value
= (ValueA
| ValueB
);
677 /******************************************************************************
679 * FUNCTION: AcpiHwWriteMultiple
681 * PARAMETERS: Value - The value to write
682 * RegisterA - First ACPI register (required)
683 * RegisterB - Second ACPI register (optional)
687 * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
689 ******************************************************************************/
692 AcpiHwWriteMultiple (
694 ACPI_GENERIC_ADDRESS
*RegisterA
,
695 ACPI_GENERIC_ADDRESS
*RegisterB
)
700 /* The first register is always required */
702 Status
= AcpiHwWrite (Value
, RegisterA
);
703 if (ACPI_FAILURE (Status
))
709 * Second register is optional
711 * No bit shifting or clearing is necessary, because of how the PM1
712 * registers are defined in the ACPI specification:
714 * "Although the bits can be split between the two register blocks (each
715 * register block has a unique pointer within the FADT), the bit positions
716 * are maintained. The register block with unimplemented bits (that is,
717 * those implemented in the other register block) always returns zeros,
718 * and writes have no side effects"
720 if (RegisterB
->Address
)
722 Status
= AcpiHwWrite (Value
, RegisterB
);
728 #endif /* !ACPI_REDUCED_HARDWARE */