Print this page
update to acpica-unix2-20130927
acpica-unix2-20130823
PANKOVs restructure
*** 1,14 ****
-
/******************************************************************************
*
* Module Name: hwxface - Public ACPICA hardware interfaces
*
*****************************************************************************/
/*
! * Copyright (C) 2000 - 2011, 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:
--- 1,13 ----
/******************************************************************************
*
* Module Name: hwxface - Public ACPICA hardware interfaces
*
*****************************************************************************/
/*
! * 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,49 ****
--- 39,50 ----
* 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,101 ****
{
/*
* 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.
*/
Status = AcpiOsWritePort ((ACPI_IO_ADDRESS) ResetReg->Address,
! AcpiGbl_FADT.ResetValue, ResetReg->BitWidth);
}
else
{
/* Write the reset value to the reset register */
--- 90,108 ----
{
/*
* 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, ACPI_RESET_REGISTER_WIDTH);
}
else
{
/* Write the reset value to the reset register */
*** 130,140 ****
ACPI_STATUS
AcpiRead (
UINT64 *ReturnValue,
ACPI_GENERIC_ADDRESS *Reg)
{
! UINT32 Value;
UINT32 Width;
UINT64 Address;
ACPI_STATUS Status;
--- 137,148 ----
ACPI_STATUS
AcpiRead (
UINT64 *ReturnValue,
ACPI_GENERIC_ADDRESS *Reg)
{
! UINT32 ValueLo;
! UINT32 ValueHi;
UINT32 Width;
UINT64 Address;
ACPI_STATUS Status;
*** 152,230 ****
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
* 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);
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;
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%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);
}
ACPI_EXPORT_SYMBOL (AcpiRead)
--- 160,224 ----
if (ACPI_FAILURE (Status))
{
return (Status);
}
/*
! * 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, ReturnValue, Reg->BitWidth);
if (ACPI_FAILURE (Status))
{
return (Status);
}
! }
! else /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */
{
! ValueLo = 0;
! ValueHi = 0;
! Width = Reg->BitWidth;
! if (Width == 64)
{
! Width = 32; /* Break into two 32-bit transfers */
}
!
Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
! Address, &ValueLo, Width);
if (ACPI_FAILURE (Status))
{
return (Status);
}
if (Reg->BitWidth == 64)
{
/* Read the top 32 bits */
Status = AcpiHwReadPort ((ACPI_IO_ADDRESS)
! (Address + 4), &ValueHi, 32);
if (ACPI_FAILURE (Status))
{
return (Status);
}
}
+
+ /* 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 (AE_OK);
}
ACPI_EXPORT_SYMBOL (AcpiRead)
*** 260,300 ****
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);
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);
--- 254,284 ----
if (ACPI_FAILURE (Status))
{
return (Status);
}
/*
* 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, Value, Reg->BitWidth);
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,330 ****
--- 305,315 ----
}
ACPI_EXPORT_SYMBOL (AcpiWrite)
+ #if (!ACPI_REDUCED_HARDWARE)
/*******************************************************************************
*
* FUNCTION: AcpiReadBitRegister
*
* PARAMETERS: RegisterId - ID of ACPI Bit Register to access
*** 399,409 ****
*
* 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
* shifted to the correct position.
*
* RETURN: Status
*
* DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
--- 384,394 ----
*
* 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 automatically
* shifted to the correct position.
*
* RETURN: Status
*
* DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
*** 503,546 ****
return_ACPI_STATUS (Status);
}
ACPI_EXPORT_SYMBOL (AcpiWriteBitRegister)
/*******************************************************************************
*
* FUNCTION: AcpiGetSleepTypeData
*
* PARAMETERS: SleepState - Numeric sleep state
* *SleepTypeA - Where SLP_TYPa is returned
* *SleepTypeB - Where SLP_TYPb is returned
*
! * RETURN: Status - ACPI status
*
! * DESCRIPTION: Obtain the SLP_TYPa and SLP_TYPb values for the requested sleep
! * state.
*
******************************************************************************/
ACPI_STATUS
AcpiGetSleepTypeData (
UINT8 SleepState,
UINT8 *SleepTypeA,
UINT8 *SleepTypeB)
{
! ACPI_STATUS Status = AE_OK;
ACPI_EVALUATE_INFO *Info;
ACPI_FUNCTION_TRACE (AcpiGetSleepTypeData);
/* Validate parameters */
if ((SleepState > ACPI_S_STATES_MAX) ||
! !SleepTypeA ||
! !SleepTypeB)
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Allocate the evaluation information block */
--- 488,556 ----
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
*
! * 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;
ACPI_EVALUATE_INFO *Info;
+ ACPI_OPERAND_OBJECT **Elements;
ACPI_FUNCTION_TRACE (AcpiGetSleepTypeData);
/* Validate parameters */
if ((SleepState > ACPI_S_STATES_MAX) ||
! !SleepTypeA || !SleepTypeB)
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
/* Allocate the evaluation information block */
*** 549,638 ****
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 */
!
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;
}
! /* It must be of type Package */
! else 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;
}
/*
! * 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).
*/
! else if (Info->ReturnObject->Package.Count < 2)
{
! ACPI_ERROR ((AE_INFO,
! "Sleep State return package does not have at least two elements"));
! Status = AE_AML_NO_OPERAND;
! }
! /* The first two elements must both be of type Integer */
! else if (((Info->ReturnObject->Package.Elements[0])->Common.Type
! != ACPI_TYPE_INTEGER) ||
! ((Info->ReturnObject->Package.Elements[1])->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;
}
! else
{
! /* Valid _Sx_ package size, type, and value */
! *SleepTypeA = (UINT8)
! (Info->ReturnObject->Package.Elements[0])->Integer.Value;
! *SleepTypeB = (UINT8)
! (Info->ReturnObject->Package.Elements[1])->Integer.Value;
}
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)));
}
- AcpiUtRemoveReference (Info->ReturnObject);
-
- Cleanup:
ACPI_FREE (Info);
return_ACPI_STATUS (Status);
}
ACPI_EXPORT_SYMBOL (AcpiGetSleepTypeData)
--- 559,653 ----
if (!Info)
{
return_ACPI_STATUS (AE_NO_MEMORY);
}
! /*
! * 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))
{
goto Cleanup;
}
/* Must have a return object */
if (!Info->ReturnObject)
{
ACPI_ERROR ((AE_INFO, "No Sleep State object returned from [%s]",
! Info->RelativePathname));
! Status = AE_AML_NO_RETURN_VALUE;
! goto Cleanup;
}
! /* Return object must be of 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;
}
/*
! * 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.
*/
! Elements = Info->ReturnObject->Package.Elements;
! switch (Info->ReturnObject->Package.Count)
{
! case 0:
! Status = AE_AML_PACKAGE_LIMIT;
! break;
! case 1:
!
! if (Elements[0]->Common.Type != ACPI_TYPE_INTEGER)
{
Status = AE_AML_OPERAND_TYPE;
+ break;
}
!
! /* 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))
{
! Status = AE_AML_OPERAND_TYPE;
! break;
! }
! /* 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 Sleep State [%s]", Info->RelativePathname));
}
ACPI_FREE (Info);
return_ACPI_STATUS (Status);
}
ACPI_EXPORT_SYMBOL (AcpiGetSleepTypeData)