aboutsummaryrefslogtreecommitdiff
path: root/hardware/hwxface.c
diff options
context:
space:
mode:
Diffstat (limited to 'hardware/hwxface.c')
-rw-r--r--hardware/hwxface.c186
1 files changed, 111 insertions, 75 deletions
diff --git a/hardware/hwxface.c b/hardware/hwxface.c
index 63641d38935a..901b178fa579 100644
--- a/hardware/hwxface.c
+++ b/hardware/hwxface.c
@@ -159,7 +159,7 @@ AcpiReset (
/* Write the reset value to the reset register */
- Status = AcpiWrite (AcpiGbl_FADT.ResetValue, ResetReg);
+ Status = AcpiHwWrite (AcpiGbl_FADT.ResetValue, ResetReg);
return_ACPI_STATUS (Status);
}
@@ -177,13 +177,20 @@ ACPI_EXPORT_SYMBOL (AcpiReset)
*
* DESCRIPTION: Read from either memory or IO space.
*
+ * LIMITATIONS: <These limitations also apply to AcpiWrite>
+ * BitWidth must be exactly 8, 16, 32, or 64.
+ * SpaceID must be SystemMemory or SystemIO.
+ * BitOffset and AccessWidth are currently ignored, as there has
+ * not been a need to implement these.
+ *
******************************************************************************/
ACPI_STATUS
AcpiRead (
- UINT32 *Value,
+ UINT64 *ReturnValue,
ACPI_GENERIC_ADDRESS *Reg)
{
+ UINT32 Value;
UINT32 Width;
UINT64 Address;
ACPI_STATUS Status;
@@ -192,63 +199,85 @@ AcpiRead (
ACPI_FUNCTION_NAME (AcpiRead);
- /*
- * Must have a valid pointer to a GAS structure, and a non-zero address
- * within.
- */
- if (!Reg)
+ if (!ReturnValue)
{
return (AE_BAD_PARAMETER);
}
- /* Get a local copy of the address. Handles possible alignment issues */
+ /* Validate contents of the GAS register. Allow 64-bit transfers */
- ACPI_MOVE_64_TO_64 (&Address, &Reg->Address);
- if (!Address)
+ Status = AcpiHwValidateRegister (Reg, 64, &Address);
+ if (ACPI_FAILURE (Status))
{
- return (AE_BAD_ADDRESS);
+ return (Status);
}
- /* Supported widths are 8/16/32 */
-
Width = Reg->BitWidth;
- if ((Width != 8) && (Width != 16) && (Width != 32))
+ if (Width == 64)
{
- return (AE_SUPPORT);
+ Width = 32; /* Break into two 32-bit transfers */
}
- /* Initialize entire 32-bit return value to zero */
+ /* Initialize entire 64-bit return value to zero */
- *Value = 0;
+ *ReturnValue = 0;
+ Value = 0;
/*
* Two address spaces supported: Memory or IO. PCI_Config is
* not supported here because the GAS structure is insufficient
*/
- switch (Reg->SpaceId)
+ if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
{
- case ACPI_ADR_SPACE_SYSTEM_MEMORY:
-
- Status = AcpiOsReadMemory (
- (ACPI_PHYSICAL_ADDRESS) Address, Value, Width);
- break;
-
-
- case ACPI_ADR_SPACE_SYSTEM_IO:
-
- Status = AcpiHwReadPort ((ACPI_IO_ADDRESS) Address, Value, Width);
- break;
+ Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
+ Address, &Value, Width);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ *ReturnValue = Value;
+ if (Reg->BitWidth == 64)
+ {
+ /* Read the top 32 bits */
+
+ Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
+ (Address + 4), &Value, 32);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ *ReturnValue |= ((UINT64) Value << 32);
+ }
+ }
+ else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
+ {
+ Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
+ Address, &Value, Width);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ *ReturnValue = Value;
- default:
- ACPI_ERROR ((AE_INFO,
- "Unsupported address space: %X", Reg->SpaceId));
- return (AE_BAD_PARAMETER);
+ if (Reg->BitWidth == 64)
+ {
+ /* Read the top 32 bits */
+
+ Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
+ (Address + 4), &Value, 32);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ *ReturnValue |= ((UINT64) Value << 32);
+ }
}
ACPI_DEBUG_PRINT ((ACPI_DB_IO,
- "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n",
- *Value, Width, ACPI_FORMAT_UINT64 (Address),
+ "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n",
+ ACPI_FORMAT_UINT64 (*ReturnValue), Reg->BitWidth,
+ ACPI_FORMAT_UINT64 (Address),
AcpiUtGetRegionName (Reg->SpaceId)));
return (Status);
@@ -261,7 +290,7 @@ ACPI_EXPORT_SYMBOL (AcpiRead)
*
* FUNCTION: AcpiWrite
*
- * PARAMETERS: Value - To be written
+ * PARAMETERS: Value - Value to be written
* Reg - GAS register structure
*
* RETURN: Status
@@ -272,7 +301,7 @@ ACPI_EXPORT_SYMBOL (AcpiRead)
ACPI_STATUS
AcpiWrite (
- UINT32 Value,
+ UINT64 Value,
ACPI_GENERIC_ADDRESS *Reg)
{
UINT32 Width;
@@ -283,60 +312,67 @@ AcpiWrite (
ACPI_FUNCTION_NAME (AcpiWrite);
- /*
- * Must have a valid pointer to a GAS structure, and a non-zero address
- * within.
- */
- if (!Reg)
- {
- return (AE_BAD_PARAMETER);
- }
-
- /* Get a local copy of the address. Handles possible alignment issues */
+ /* Validate contents of the GAS register. Allow 64-bit transfers */
- ACPI_MOVE_64_TO_64 (&Address, &Reg->Address);
- if (!Address)
+ Status = AcpiHwValidateRegister (Reg, 64, &Address);
+ if (ACPI_FAILURE (Status))
{
- return (AE_BAD_ADDRESS);
+ return (Status);
}
- /* Supported widths are 8/16/32 */
-
Width = Reg->BitWidth;
- if ((Width != 8) && (Width != 16) && (Width != 32))
+ if (Width == 64)
{
- return (AE_SUPPORT);
+ Width = 32; /* Break into two 32-bit transfers */
}
/*
- * Two address spaces supported: Memory or IO.
- * PCI_Config is not supported here because the GAS struct is insufficient
+ * Two address spaces supported: Memory or IO. PCI_Config is
+ * not supported here because the GAS structure is insufficient
*/
- switch (Reg->SpaceId)
+ if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
{
- case ACPI_ADR_SPACE_SYSTEM_MEMORY:
-
- Status = AcpiOsWriteMemory (
- (ACPI_PHYSICAL_ADDRESS) Address, Value, Width);
- break;
-
-
- case ACPI_ADR_SPACE_SYSTEM_IO:
-
- Status = AcpiHwWritePort (
- (ACPI_IO_ADDRESS) Address, Value, Width);
- break;
+ Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
+ Address, ACPI_LODWORD (Value), Width);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ if (Reg->BitWidth == 64)
+ {
+ Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
+ (Address + 4), ACPI_HIDWORD (Value), 32);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
+ }
+ else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
+ {
+ Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
+ Address, ACPI_LODWORD (Value), Width);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
- default:
- ACPI_ERROR ((AE_INFO,
- "Unsupported address space: %X", Reg->SpaceId));
- return (AE_BAD_PARAMETER);
+ if (Reg->BitWidth == 64)
+ {
+ Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
+ (Address + 4), ACPI_HIDWORD (Value), 32);
+ if (ACPI_FAILURE (Status))
+ {
+ return (Status);
+ }
+ }
}
ACPI_DEBUG_PRINT ((ACPI_DB_IO,
- "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n",
- Value, Width, ACPI_FORMAT_UINT64 (Address),
+ "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n",
+ ACPI_FORMAT_UINT64 (Value), Reg->BitWidth,
+ ACPI_FORMAT_UINT64 (Address),
AcpiUtGetRegionName (Reg->SpaceId)));
return (Status);