Print this page
update to acpica-unix2-20130927
acpica-unix2-20130823
PANKOVs restructure
@@ -1,14 +1,13 @@
-
/******************************************************************************
*
* Module Name: hwxface - Public ACPICA hardware interfaces
*
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2011, Intel Corp.
+ * Copyright (C) 2000 - 2013, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -40,10 +39,12 @@
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*/
+#define EXPORT_ACPI_INTERFACES
+
#include "acpi.h"
#include "accommon.h"
#include "acnamesp.h"
#define _COMPONENT ACPI_HARDWARE
@@ -89,13 +90,19 @@
{
/*
* For I/O space, write directly to the OSL. This bypasses the port
* validation mechanism, which may block a valid write to the reset
* register.
+ *
+ * NOTE:
+ * The ACPI spec requires the reset register width to be 8, so we
+ * hardcode it here and ignore the FADT value. This maintains
+ * compatibility with other ACPI implementations that have allowed
+ * BIOS code with bad register width values to go unnoticed.
*/
Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ResetReg->Address,
- AcpiGbl_FADT.ResetValue, ResetReg->BitWidth);
+ AcpiGbl_FADT.ResetValue, ACPI_RESET_REGISTER_WIDTH);
}
else
{
/* Write the reset value to the reset register */
@@ -130,11 +137,12 @@
ACPI_STATUS
AcpiRead (
UINT64 *ReturnValue,
ACPI_GENERIC_ADDRESS *Reg)
{
- UINT32 Value;
+ UINT32 ValueLo;
+ UINT32 ValueHi;
UINT32 Width;
UINT64 Address;
ACPI_STATUS Status;
@@ -152,79 +160,65 @@
if (ACPI_FAILURE (Status))
{
return (Status);
}
- Width = Reg->BitWidth;
- if (Width == 64)
- {
- Width = 32; /* Break into two 32-bit transfers */
- }
-
- /* Initialize entire 64-bit return value to zero */
-
- *ReturnValue = 0;
- Value = 0;
-
/*
- * Two address spaces supported: Memory or IO. PCI_Config is
+ * Two address spaces supported: Memory or I/O. PCI_Config is
* not supported here because the GAS structure is insufficient
*/
if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
{
Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
- Address, &Value, Width);
+ Address, ReturnValue, Reg->BitWidth);
if (ACPI_FAILURE (Status))
{
return (Status);
}
- *ReturnValue = Value;
-
- if (Reg->BitWidth == 64)
+ }
+ else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
{
- /* Read the top 32 bits */
+ ValueLo = 0;
+ ValueHi = 0;
- Status = AcpiOsReadMemory ((ACPI_PHYSICAL_ADDRESS)
- (Address + 4), &Value, 32);
- if (ACPI_FAILURE (Status))
+ Width = Reg->BitWidth;
+ if (Width == 64)
{
- return (Status);
+ Width = 32; /* Break into two 32-bit transfers */
}
- *ReturnValue |= ((UINT64) Value << 32);
- }
- }
- else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
- {
+
Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
- Address, &Value, Width);
+ Address, &ValueLo, Width);
if (ACPI_FAILURE (Status))
{
return (Status);
}
- *ReturnValue = Value;
if (Reg->BitWidth == 64)
{
/* Read the top 32 bits */
Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
- (Address + 4), &Value, 32);
+ (Address + 4), &ValueHi, 32);
if (ACPI_FAILURE (Status))
{
return (Status);
}
- *ReturnValue |= ((UINT64) Value << 32);
}
+
+ /* Set the return value only if status is AE_OK */
+
+ *ReturnValue = (ValueLo | ((UINT64) ValueHi << 32));
}
ACPI_DEBUG_PRINT ((ACPI_DB_IO,
"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);
+ return (AE_OK);
}
ACPI_EXPORT_SYMBOL (AcpiRead)
@@ -260,41 +254,31 @@
if (ACPI_FAILURE (Status))
{
return (Status);
}
- Width = Reg->BitWidth;
- if (Width == 64)
- {
- Width = 32; /* Break into two 32-bit transfers */
- }
-
/*
* Two address spaces supported: Memory or IO. PCI_Config is
* not supported here because the GAS structure is insufficient
*/
if (Reg->SpaceId == ACPI_ADR_SPACE_SYSTEM_MEMORY)
{
Status = AcpiOsWriteMemory ((ACPI_PHYSICAL_ADDRESS)
- Address, ACPI_LODWORD (Value), Width);
+ Address, Value, Reg->BitWidth);
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 */
{
+ Width = Reg->BitWidth;
+ if (Width == 64)
+ {
+ Width = 32; /* Break into two 32-bit transfers */
+ }
+
Status = AcpiHwWritePort ((ACPI_IO_ADDRESS)
Address, ACPI_LODWORD (Value), Width);
if (ACPI_FAILURE (Status))
{
return (Status);
@@ -321,10 +305,11 @@
}
ACPI_EXPORT_SYMBOL (AcpiWrite)
+#if (!ACPI_REDUCED_HARDWARE)
/*******************************************************************************
*
* FUNCTION: AcpiReadBitRegister
*
* PARAMETERS: RegisterId - ID of ACPI Bit Register to access
@@ -399,11 +384,11 @@
*
* FUNCTION: AcpiWriteBitRegister
*
* PARAMETERS: RegisterId - ID of ACPI Bit Register to access
* Value - Value to write to the register, in bit
- * position zero. The bit is automaticallly
+ * position zero. The bit is automatically
* shifted to the correct position.
*
* RETURN: Status
*
* DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
@@ -503,44 +488,69 @@
return_ACPI_STATUS (Status);
}
ACPI_EXPORT_SYMBOL (AcpiWriteBitRegister)
+#endif /* !ACPI_REDUCED_HARDWARE */
+
/*******************************************************************************
*
* FUNCTION: AcpiGetSleepTypeData
*
* PARAMETERS: SleepState - Numeric sleep state
* *SleepTypeA - Where SLP_TYPa is returned
* *SleepTypeB - Where SLP_TYPb is returned
*
- * RETURN: Status - ACPI status
+ * RETURN: Status
*
- * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
- * state.
+ * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested
+ * sleep state via the appropriate \_Sx object.
*
+ * The sleep state package returned from the corresponding \_Sx_ object
+ * must contain at least one integer.
+ *
+ * March 2005:
+ * Added support for a package that contains two integers. This
+ * goes against the ACPI specification which defines this object as a
+ * package with one encoded DWORD integer. However, existing practice
+ * by many BIOS vendors is to return a package with 2 or more integer
+ * elements, at least one per sleep type (A/B).
+ *
+ * January 2013:
+ * Therefore, we must be prepared to accept a package with either a
+ * single integer or multiple integers.
+ *
+ * The single integer DWORD format is as follows:
+ * BYTE 0 - Value for the PM1A SLP_TYP register
+ * BYTE 1 - Value for the PM1B SLP_TYP register
+ * BYTE 2-3 - Reserved
+ *
+ * The dual integer format is as follows:
+ * Integer 0 - Value for the PM1A SLP_TYP register
+ * Integer 1 - Value for the PM1A SLP_TYP register
+ *
******************************************************************************/
ACPI_STATUS
AcpiGetSleepTypeData (
UINT8 SleepState,
UINT8 *SleepTypeA,
UINT8 *SleepTypeB)
{
- ACPI_STATUS Status = AE_OK;
+ ACPI_STATUS Status;
ACPI_EVALUATE_INFO *Info;
+ ACPI_OPERAND_OBJECT **Elements;
ACPI_FUNCTION_TRACE (AcpiGetSleepTypeData);
/* Validate parameters */
if ((SleepState > ACPI_S_STATES_MAX) ||
- !SleepTypeA ||
- !SleepTypeB)
+ !SleepTypeA || !SleepTypeB)
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Allocate the evaluation information block */
@@ -549,90 +559,95 @@
if (!Info)
{
return_ACPI_STATUS (AE_NO_MEMORY);
}
- Info->Pathname = ACPI_CAST_PTR (char, AcpiGbl_SleepStateNames[SleepState]);
-
- /* Evaluate the namespace object containing the values for this state */
-
+ /*
+ * Evaluate the \_Sx namespace object containing the register values
+ * for this state
+ */
+ Info->RelativePathname = ACPI_CAST_PTR (
+ char, AcpiGbl_SleepStateNames[SleepState]);
Status = AcpiNsEvaluate (Info);
if (ACPI_FAILURE (Status))
{
- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "%s while evaluating SleepState [%s]\n",
- AcpiFormatException (Status), Info->Pathname));
-
goto Cleanup;
}
/* Must have a return object */
if (!Info->ReturnObject)
{
ACPI_ERROR ((AE_INFO, "No Sleep State object returned from [%s]",
- Info->Pathname));
- Status = AE_NOT_EXIST;
+ Info->RelativePathname));
+ Status = AE_AML_NO_RETURN_VALUE;
+ goto Cleanup;
}
- /* It must be of type Package */
+ /* Return object must be of type Package */
- else if (Info->ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
+ if (Info->ReturnObject->Common.Type != ACPI_TYPE_PACKAGE)
{
ACPI_ERROR ((AE_INFO, "Sleep State return object is not a Package"));
Status = AE_AML_OPERAND_TYPE;
+ goto Cleanup1;
}
/*
- * The package must have at least two elements. NOTE (March 2005): This
- * goes against the current ACPI spec which defines this object as a
- * package with one encoded DWORD element. However, existing practice
- * by BIOS vendors seems to be to have 2 or more elements, at least
- * one per sleep type (A/B).
+ * Any warnings about the package length or the object types have
+ * already been issued by the predefined name module -- there is no
+ * need to repeat them here.
*/
- else if (Info->ReturnObject->Package.Count < 2)
+ Elements = Info->ReturnObject->Package.Elements;
+ switch (Info->ReturnObject->Package.Count)
{
- ACPI_ERROR ((AE_INFO,
- "Sleep State return package does not have at least two elements"));
- Status = AE_AML_NO_OPERAND;
- }
+ case 0:
- /* The first two elements must both be of type Integer */
+ Status = AE_AML_PACKAGE_LIMIT;
+ break;
- else if (((Info->ReturnObject->Package.Elements[0])->Common.Type
- != ACPI_TYPE_INTEGER) ||
- ((Info->ReturnObject->Package.Elements[1])->Common.Type
- != ACPI_TYPE_INTEGER))
+ case 1:
+
+ if (Elements[0]->Common.Type != ACPI_TYPE_INTEGER)
{
- ACPI_ERROR ((AE_INFO,
- "Sleep State return package elements are not both Integers "
- "(%s, %s)",
- AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[0]),
- AcpiUtGetObjectTypeName (Info->ReturnObject->Package.Elements[1])));
Status = AE_AML_OPERAND_TYPE;
+ break;
}
- else
+
+ /* A valid _Sx_ package with one integer */
+
+ *SleepTypeA = (UINT8) Elements[0]->Integer.Value;
+ *SleepTypeB = (UINT8) (Elements[0]->Integer.Value >> 8);
+ break;
+
+ case 2:
+ default:
+
+ if ((Elements[0]->Common.Type != ACPI_TYPE_INTEGER) ||
+ (Elements[1]->Common.Type != ACPI_TYPE_INTEGER))
{
- /* Valid _Sx_ package size, type, and value */
+ Status = AE_AML_OPERAND_TYPE;
+ break;
+ }
- *SleepTypeA = (UINT8)
- (Info->ReturnObject->Package.Elements[0])->Integer.Value;
- *SleepTypeB = (UINT8)
- (Info->ReturnObject->Package.Elements[1])->Integer.Value;
+ /* A valid _Sx_ package with two integers */
+
+ *SleepTypeA = (UINT8) Elements[0]->Integer.Value;
+ *SleepTypeB = (UINT8) Elements[1]->Integer.Value;
+ break;
}
+Cleanup1:
+ AcpiUtRemoveReference (Info->ReturnObject);
+
+Cleanup:
if (ACPI_FAILURE (Status))
{
ACPI_EXCEPTION ((AE_INFO, Status,
- "While evaluating SleepState [%s], bad Sleep object %p type %s",
- Info->Pathname, Info->ReturnObject,
- AcpiUtGetObjectTypeName (Info->ReturnObject)));
+ "While evaluating Sleep State [%s]", Info->RelativePathname));
}
- AcpiUtRemoveReference (Info->ReturnObject);
-
-Cleanup:
ACPI_FREE (Info);
return_ACPI_STATUS (Status);
}
ACPI_EXPORT_SYMBOL (AcpiGetSleepTypeData)