summaryrefslogtreecommitdiffstats
path: root/source/components
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2013-12-19 05:51:01 +0000
committerjkim <jkim@FreeBSD.org>2013-12-19 05:51:01 +0000
commitb37c83dbb637fc63c5ba07fe61555d4d6e29dd7c (patch)
tree7fcfdcc62c3319ffd669b18b080d40c9c5897210 /source/components
parenta1672476f94b0c9ac84a682574aeb1eb481c484c (diff)
downloadFreeBSD-src-b37c83dbb637fc63c5ba07fe61555d4d6e29dd7c.zip
FreeBSD-src-b37c83dbb637fc63c5ba07fe61555d4d6e29dd7c.tar.gz
Import ACPICA 20131218.
Diffstat (limited to 'source/components')
-rw-r--r--source/components/debugger/dbfileio.c10
-rw-r--r--source/components/debugger/dbinput.c6
-rw-r--r--source/components/dispatcher/dsfield.c2
-rw-r--r--source/components/dispatcher/dsutils.c16
-rw-r--r--source/components/dispatcher/dswexec.c3
-rw-r--r--source/components/dispatcher/dswload.c2
-rw-r--r--source/components/events/evgpeblk.c7
-rw-r--r--source/components/events/evgpeutil.c21
-rw-r--r--source/components/executer/exresnte.c4
-rw-r--r--source/components/namespace/nsxfeval.c16
-rw-r--r--source/components/parser/psopinfo.c52
-rw-r--r--source/components/tables/tbfadt.c313
-rw-r--r--source/components/tables/tbutils.c150
-rw-r--r--source/components/utilities/utaddress.c14
-rw-r--r--source/components/utilities/utalloc.c10
-rw-r--r--source/components/utilities/utcache.c12
-rw-r--r--source/components/utilities/utdebug.c4
-rw-r--r--source/components/utilities/utxfinit.c12
18 files changed, 429 insertions, 225 deletions
diff --git a/source/components/debugger/dbfileio.c b/source/components/debugger/dbfileio.c
index 373e7ad..0785c7d 100644
--- a/source/components/debugger/dbfileio.c
+++ b/source/components/debugger/dbfileio.c
@@ -60,16 +60,6 @@
#define _COMPONENT ACPI_CA_DEBUGGER
ACPI_MODULE_NAME ("dbfileio")
-/*
- * NOTE: this is here for lack of a better place. It is used in all
- * flavors of the debugger, need LCD file
- */
-#ifdef ACPI_APPLICATION
-#include <stdio.h>
-FILE *AcpiGbl_DebugFile = NULL;
-#endif
-
-
#ifdef ACPI_DEBUGGER
/* Local prototypes */
diff --git a/source/components/debugger/dbinput.c b/source/components/debugger/dbinput.c
index 147a023..e1beed3 100644
--- a/source/components/debugger/dbinput.c
+++ b/source/components/debugger/dbinput.c
@@ -128,7 +128,7 @@ enum AcpiExDebuggerCommands
CMD_METHODS,
CMD_NAMESPACE,
CMD_NOTIFY,
- CMD_OBJECT,
+ CMD_OBJECTS,
CMD_OPEN,
CMD_OSI,
CMD_OWNER,
@@ -201,7 +201,7 @@ static const ACPI_DB_COMMAND_INFO AcpiGbl_DbCommands[] =
{"METHODS", 0},
{"NAMESPACE", 0},
{"NOTIFY", 2},
- {"OBJECT", 1},
+ {"OBJECTS", 1},
{"OPEN", 1},
{"OSI", 0},
{"OWNER", 1},
@@ -1000,7 +1000,7 @@ AcpiDbCommandDispatch (
AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp);
break;
- case CMD_OBJECT:
+ case CMD_OBJECTS:
AcpiUtStrupr (AcpiGbl_DbArgs[1]);
Status = AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]);
diff --git a/source/components/dispatcher/dsfield.c b/source/components/dispatcher/dsfield.c
index 2fb4f0e..90428aa 100644
--- a/source/components/dispatcher/dsfield.c
+++ b/source/components/dispatcher/dsfield.c
@@ -116,7 +116,7 @@ AcpiDsCreateExternalRegion (
* OperationRegion not found. Generate an External for it, and
* insert the name into the namespace.
*/
- AcpiDmAddToExternalList (Op, Path, ACPI_TYPE_REGION, 0);
+ AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_REGION, 0, 0);
Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_REGION,
ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, WalkState, Node);
if (ACPI_FAILURE (Status))
diff --git a/source/components/dispatcher/dsutils.c b/source/components/dispatcher/dsutils.c
index 9fedbe6..08cb250 100644
--- a/source/components/dispatcher/dsutils.c
+++ b/source/components/dispatcher/dsutils.c
@@ -779,16 +779,16 @@ AcpiDsCreateOperands (
Index++;
}
- Index--;
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "NumOperands %d, ArgCount %d, Index %d\n",
+ WalkState->NumOperands, ArgCount, Index));
- /* It is the appropriate order to get objects from the Result stack */
+ /* Create the interpreter arguments, in reverse order */
+ Index--;
for (i = 0; i < ArgCount; i++)
{
Arg = Arguments[Index];
-
- /* Force the filling of the operand stack in inverse order */
-
WalkState->OperandIndex = (UINT8) Index;
Status = AcpiDsCreateOperand (WalkState, Arg, Index);
@@ -797,10 +797,10 @@ AcpiDsCreateOperands (
goto Cleanup;
}
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Created Arg #%u (%p) %u args total\n",
+ Index, Arg, ArgCount));
Index--;
-
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Arg #%u (%p) done, Arg1=%p\n",
- Index, Arg, FirstArg));
}
return_ACPI_STATUS (Status);
diff --git a/source/components/dispatcher/dswexec.c b/source/components/dispatcher/dswexec.c
index 25de7f7..e9c178b 100644
--- a/source/components/dispatcher/dswexec.c
+++ b/source/components/dispatcher/dswexec.c
@@ -541,7 +541,8 @@ AcpiDsExecEndOp (
return_ACPI_STATUS (AE_OK);
}
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method invocation, Op=%p\n", Op));
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Method invocation, Op=%p\n", Op));
/*
* (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
diff --git a/source/components/dispatcher/dswload.c b/source/components/dispatcher/dswload.c
index 7050c87..339586a 100644
--- a/source/components/dispatcher/dswload.c
+++ b/source/components/dispatcher/dswload.c
@@ -193,7 +193,7 @@ AcpiDsLoad1BeginOp (
* Target of Scope() not found. Generate an External for it, and
* insert the name into the namespace.
*/
- AcpiDmAddToExternalList (Op, Path, ACPI_TYPE_DEVICE, 0);
+ AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_DEVICE, 0, 0);
Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,
ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
WalkState, &Node);
diff --git a/source/components/events/evgpeblk.c b/source/components/events/evgpeblk.c
index ccbe6a61..0f0da18 100644
--- a/source/components/events/evgpeblk.c
+++ b/source/components/events/evgpeblk.c
@@ -97,10 +97,9 @@ AcpiEvInstallGpeBlock (
return_ACPI_STATUS (Status);
}
- GpeXruptBlock = AcpiEvGetGpeXruptBlock (InterruptNumber);
- if (!GpeXruptBlock)
+ Status = AcpiEvGetGpeXruptBlock (InterruptNumber, &GpeXruptBlock);
+ if (ACPI_FAILURE (Status))
{
- Status = AE_NO_MEMORY;
goto UnlockAndExit;
}
@@ -128,7 +127,7 @@ AcpiEvInstallGpeBlock (
UnlockAndExit:
- Status = AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
+ (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
return_ACPI_STATUS (Status);
}
diff --git a/source/components/events/evgpeutil.c b/source/components/events/evgpeutil.c
index 492c16f..a48520c 100644
--- a/source/components/events/evgpeutil.c
+++ b/source/components/events/evgpeutil.c
@@ -217,8 +217,9 @@ AcpiEvGetGpeDevice (
* FUNCTION: AcpiEvGetGpeXruptBlock
*
* PARAMETERS: InterruptNumber - Interrupt for a GPE block
+ * GpeXruptBlock - Where the block is returned
*
- * RETURN: A GPE interrupt block
+ * RETURN: Status
*
* DESCRIPTION: Get or Create a GPE interrupt block. There is one interrupt
* block per unique interrupt level used for GPEs. Should be
@@ -227,9 +228,10 @@ AcpiEvGetGpeDevice (
*
******************************************************************************/
-ACPI_GPE_XRUPT_INFO *
+ACPI_STATUS
AcpiEvGetGpeXruptBlock (
- UINT32 InterruptNumber)
+ UINT32 InterruptNumber,
+ ACPI_GPE_XRUPT_INFO **GpeXruptBlock)
{
ACPI_GPE_XRUPT_INFO *NextGpeXrupt;
ACPI_GPE_XRUPT_INFO *GpeXrupt;
@@ -247,7 +249,8 @@ AcpiEvGetGpeXruptBlock (
{
if (NextGpeXrupt->InterruptNumber == InterruptNumber)
{
- return_PTR (NextGpeXrupt);
+ *GpeXruptBlock = NextGpeXrupt;
+ return_ACPI_STATUS (AE_OK);
}
NextGpeXrupt = NextGpeXrupt->Next;
@@ -258,7 +261,7 @@ AcpiEvGetGpeXruptBlock (
GpeXrupt = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_XRUPT_INFO));
if (!GpeXrupt)
{
- return_PTR (NULL);
+ return_ACPI_STATUS (AE_NO_MEMORY);
}
GpeXrupt->InterruptNumber = InterruptNumber;
@@ -281,6 +284,7 @@ AcpiEvGetGpeXruptBlock (
{
AcpiGbl_GpeXruptListHead = GpeXrupt;
}
+
AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
/* Install new interrupt handler if not SCI_INT */
@@ -291,14 +295,15 @@ AcpiEvGetGpeXruptBlock (
AcpiEvGpeXruptHandler, GpeXrupt);
if (ACPI_FAILURE (Status))
{
- ACPI_ERROR ((AE_INFO,
+ ACPI_EXCEPTION ((AE_INFO, Status,
"Could not install GPE interrupt handler at level 0x%X",
InterruptNumber));
- return_PTR (NULL);
+ return_ACPI_STATUS (Status);
}
}
- return_PTR (GpeXrupt);
+ *GpeXruptBlock = GpeXrupt;
+ return_ACPI_STATUS (AE_OK);
}
diff --git a/source/components/executer/exresnte.c b/source/components/executer/exresnte.c
index c26cbb9..56a7a32 100644
--- a/source/components/executer/exresnte.c
+++ b/source/components/executer/exresnte.c
@@ -134,8 +134,8 @@ AcpiExResolveNodeToValue (
if (!SourceDesc)
{
- ACPI_ERROR ((AE_INFO, "No object attached to node %p",
- Node));
+ ACPI_ERROR ((AE_INFO, "No object attached to node [%4.4s] %p",
+ Node->Name.Ascii, Node));
return_ACPI_STATUS (AE_AML_NO_OPERAND);
}
diff --git a/source/components/namespace/nsxfeval.c b/source/components/namespace/nsxfeval.c
index a1af583..e0022a8 100644
--- a/source/components/namespace/nsxfeval.c
+++ b/source/components/namespace/nsxfeval.c
@@ -92,7 +92,7 @@ AcpiEvaluateObjectTyped (
ACPI_OBJECT_TYPE ReturnType)
{
ACPI_STATUS Status;
- BOOLEAN MustFree = FALSE;
+ BOOLEAN FreeBufferOnError = FALSE;
ACPI_FUNCTION_TRACE (AcpiEvaluateObjectTyped);
@@ -107,12 +107,13 @@ AcpiEvaluateObjectTyped (
if (ReturnBuffer->Length == ACPI_ALLOCATE_BUFFER)
{
- MustFree = TRUE;
+ FreeBufferOnError = TRUE;
}
/* Evaluate the object */
- Status = AcpiEvaluateObject (Handle, Pathname, ExternalParams, ReturnBuffer);
+ Status = AcpiEvaluateObject (Handle, Pathname,
+ ExternalParams, ReturnBuffer);
if (ACPI_FAILURE (Status))
{
return_ACPI_STATUS (Status);
@@ -147,13 +148,14 @@ AcpiEvaluateObjectTyped (
AcpiUtGetTypeName (((ACPI_OBJECT *) ReturnBuffer->Pointer)->Type),
AcpiUtGetTypeName (ReturnType)));
- if (MustFree)
+ if (FreeBufferOnError)
{
/*
- * Caller used ACPI_ALLOCATE_BUFFER, free the return buffer.
+ * Free a buffer created via ACPI_ALLOCATE_BUFFER.
* Note: We use AcpiOsFree here because AcpiOsAllocate was used
- * to allocate the buffer. This purposefully bypasses the internal
- * allocation tracking mechanism (if it is enabled).
+ * to allocate the buffer. This purposefully bypasses the
+ * (optionally enabled) allocation tracking mechanism since we
+ * only want to track internal allocations.
*/
AcpiOsFree (ReturnBuffer->Pointer);
ReturnBuffer->Pointer = NULL;
diff --git a/source/components/parser/psopinfo.c b/source/components/parser/psopinfo.c
index f079c33..081b808 100644
--- a/source/components/parser/psopinfo.c
+++ b/source/components/parser/psopinfo.c
@@ -76,6 +76,10 @@ const ACPI_OPCODE_INFO *
AcpiPsGetOpcodeInfo (
UINT16 Opcode)
{
+#ifdef ACPI_DEBUG_OUTPUT
+ const char *OpcodeName = "Unknown AML opcode";
+#endif
+
ACPI_FUNCTION_NAME (PsGetOpcodeInfo);
@@ -97,10 +101,56 @@ AcpiPsGetOpcodeInfo (
return (&AcpiGbl_AmlOpInfo [AcpiGbl_LongOpIndex [(UINT8) Opcode]]);
}
+#if defined ACPI_ASL_COMPILER && defined ACPI_DEBUG_OUTPUT
+#include "asldefine.h"
+
+ switch (Opcode)
+ {
+ case AML_RAW_DATA_BYTE:
+ OpcodeName = "-Raw Data Byte-";
+ break;
+
+ case AML_RAW_DATA_WORD:
+ OpcodeName = "-Raw Data Word-";
+ break;
+
+ case AML_RAW_DATA_DWORD:
+ OpcodeName = "-Raw Data Dword-";
+ break;
+
+ case AML_RAW_DATA_QWORD:
+ OpcodeName = "-Raw Data Qword-";
+ break;
+
+ case AML_RAW_DATA_BUFFER:
+ OpcodeName = "-Raw Data Buffer-";
+ break;
+
+ case AML_RAW_DATA_CHAIN:
+ OpcodeName = "-Raw Data Buffer Chain-";
+ break;
+
+ case AML_PACKAGE_LENGTH:
+ OpcodeName = "-Package Length-";
+ break;
+
+ case AML_UNASSIGNED_OPCODE:
+ OpcodeName = "-Unassigned Opcode-";
+ break;
+
+ case AML_DEFAULT_ARG_OP:
+ OpcodeName = "-Default Arg-";
+ break;
+
+ default:
+ break;
+ }
+#endif
+
/* Unknown AML opcode */
ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
- "Unknown AML opcode [%4.4X]\n", Opcode));
+ "%s [%4.4X]\n", OpcodeName, Opcode));
return (&AcpiGbl_AmlOpInfo [_UNK]);
}
diff --git a/source/components/tables/tbfadt.c b/source/components/tables/tbfadt.c
index eb4e0e5..5e315ef 100644
--- a/source/components/tables/tbfadt.c
+++ b/source/components/tables/tbfadt.c
@@ -65,13 +65,15 @@ AcpiTbConvertFadt (
void);
static void
-AcpiTbValidateFadt (
- void);
-
-static void
AcpiTbSetupFadtRegisters (
void);
+static UINT64
+AcpiTbSelectAddress (
+ char *RegisterName,
+ UINT32 Address32,
+ UINT64 Address64);
+
/* Table for conversion of FADT to common internal format and FADT validation */
@@ -194,6 +196,7 @@ static ACPI_FADT_PM_INFO FadtPmInfoTable[] =
* SpaceId - ACPI Space ID for this register
* ByteWidth - Width of this register
* Address - Address of the register
+ * RegisterName - ASCII name of the ACPI register
*
* RETURN: None
*
@@ -245,6 +248,72 @@ AcpiTbInitGenericAddress (
/*******************************************************************************
*
+ * FUNCTION: AcpiTbSelectAddress
+ *
+ * PARAMETERS: RegisterName - ASCII name of the ACPI register
+ * Address32 - 32-bit address of the register
+ * Address64 - 64-bit address of the register
+ *
+ * RETURN: The resolved 64-bit address
+ *
+ * DESCRIPTION: Select between 32-bit and 64-bit versions of addresses within
+ * the FADT. Used for the FACS and DSDT addresses.
+ *
+ * NOTES:
+ *
+ * Check for FACS and DSDT address mismatches. An address mismatch between
+ * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
+ * DSDT/X_DSDT) could be a corrupted address field or it might indicate
+ * the presence of two FACS or two DSDT tables.
+ *
+ * November 2013:
+ * By default, as per the ACPICA specification, a valid 64-bit address is
+ * used regardless of the value of the 32-bit address. However, this
+ * behavior can be overridden via the AcpiGbl_Use32BitFadtAddresses flag.
+ *
+ ******************************************************************************/
+
+static UINT64
+AcpiTbSelectAddress (
+ char *RegisterName,
+ UINT32 Address32,
+ UINT64 Address64)
+{
+
+ if (!Address64)
+ {
+ /* 64-bit address is zero, use 32-bit address */
+
+ return ((UINT64) Address32);
+ }
+
+ if (Address32 &&
+ (Address64 != (UINT64) Address32))
+ {
+ /* Address mismatch between 32-bit and 64-bit versions */
+
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "32/64X %s address mismatch in FADT: "
+ "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
+ RegisterName, Address32, ACPI_FORMAT_UINT64 (Address64),
+ AcpiGbl_Use32BitFadtAddresses ? 32 : 64));
+
+ /* 32-bit address override */
+
+ if (AcpiGbl_Use32BitFadtAddresses)
+ {
+ return ((UINT64) Address32);
+ }
+ }
+
+ /* Default is to use the 64-bit address */
+
+ return (Address64);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiTbParseFadt
*
* PARAMETERS: TableIndex - Index for the FADT
@@ -365,10 +434,6 @@ AcpiTbCreateLocalFadt (
AcpiTbConvertFadt ();
- /* Validate FADT values now, before we make any changes */
-
- AcpiTbValidateFadt ();
-
/* Initialize the global ACPI register structures */
AcpiTbSetupFadtRegisters ();
@@ -379,33 +444,43 @@ AcpiTbCreateLocalFadt (
*
* FUNCTION: AcpiTbConvertFadt
*
- * PARAMETERS: None, uses AcpiGbl_FADT
+ * PARAMETERS: None - AcpiGbl_FADT is used.
*
* RETURN: None
*
* DESCRIPTION: Converts all versions of the FADT to a common internal format.
- * Expand 32-bit addresses to 64-bit as necessary.
+ * Expand 32-bit addresses to 64-bit as necessary. Also validate
+ * important fields within the FADT.
*
- * NOTE: AcpiGbl_FADT must be of size (ACPI_TABLE_FADT),
- * and must contain a copy of the actual FADT.
+ * NOTE: AcpiGbl_FADT must be of size (ACPI_TABLE_FADT), and must
+ * contain a copy of the actual BIOS-provided FADT.
*
* Notes on 64-bit register addresses:
*
* After this FADT conversion, later ACPICA code will only use the 64-bit "X"
* fields of the FADT for all ACPI register addresses.
*
- * The 64-bit "X" fields are optional extensions to the original 32-bit FADT
+ * The 64-bit X fields are optional extensions to the original 32-bit FADT
* V1.0 fields. Even if they are present in the FADT, they are optional and
* are unused if the BIOS sets them to zero. Therefore, we must copy/expand
- * 32-bit V1.0 fields if the corresponding X field is zero.
+ * 32-bit V1.0 fields to the 64-bit X fields if the the 64-bit X field is
+ * originally zero.
*
- * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the
- * corresponding "X" fields in the internal FADT.
+ * For ACPI 1.0 FADTs (that contain no 64-bit addresses), all 32-bit address
+ * fields are expanded to the corresponding 64-bit X fields in the internal
+ * common FADT.
*
* For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
- * to the corresponding 64-bit X fields. For compatibility with other ACPI
- * implementations, we ignore the 64-bit field if the 32-bit field is valid,
- * regardless of whether the host OS is 32-bit or 64-bit.
+ * to the corresponding 64-bit X fields, if the 64-bit field is originally
+ * zero. Adhering to the ACPI specification, we completely ignore the 32-bit
+ * field if the 64-bit field is valid, regardless of whether the host OS is
+ * 32-bit or 64-bit.
+ *
+ * Possible additional checks:
+ * (AcpiGbl_FADT.Pm1EventLength >= 4)
+ * (AcpiGbl_FADT.Pm1ControlLength >= 2)
+ * (AcpiGbl_FADT.PmTimerLength >= 4)
+ * Gpe block lengths must be multiple of 2
*
******************************************************************************/
@@ -413,25 +488,14 @@ static void
AcpiTbConvertFadt (
void)
{
+ char *Name;
ACPI_GENERIC_ADDRESS *Address64;
UINT32 Address32;
+ UINT8 Length;
UINT32 i;
/*
- * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
- * Later code will always use the X 64-bit field.
- */
- if (!AcpiGbl_FADT.XFacs)
- {
- AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs;
- }
- if (!AcpiGbl_FADT.XDsdt)
- {
- AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt;
- }
-
- /*
* For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
* should be zero are indeed zero. This will workaround BIOSs that
* inadvertently place values in these fields.
@@ -458,113 +522,14 @@ AcpiTbConvertFadt (
AcpiGbl_FADT.Header.Length = sizeof (ACPI_TABLE_FADT);
/*
- * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
- * generic address structures as necessary. Later code will always use
- * the 64-bit address structures.
- *
- * March 2009:
- * We now always use the 32-bit address if it is valid (non-null). This
- * is not in accordance with the ACPI specification which states that
- * the 64-bit address supersedes the 32-bit version, but we do this for
- * compatibility with other ACPI implementations. Most notably, in the
- * case where both the 32 and 64 versions are non-null, we use the 32-bit
- * version. This is the only address that is guaranteed to have been
- * tested by the BIOS manufacturer.
- */
- for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
- {
- Address32 = *ACPI_ADD_PTR (UINT32,
- &AcpiGbl_FADT, FadtInfoTable[i].Address32);
-
- Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
- &AcpiGbl_FADT, FadtInfoTable[i].Address64);
-
- /*
- * If both 32- and 64-bit addresses are valid (non-zero),
- * they must match.
- */
- if (Address64->Address && Address32 &&
- (Address64->Address != (UINT64) Address32))
- {
- ACPI_BIOS_ERROR ((AE_INFO,
- "32/64X address mismatch in FADT/%s: "
- "0x%8.8X/0x%8.8X%8.8X, using 32",
- FadtInfoTable[i].Name, Address32,
- ACPI_FORMAT_UINT64 (Address64->Address)));
- }
-
- /* Always use 32-bit address if it is valid (non-null) */
-
- if (Address32)
- {
- /*
- * Copy the 32-bit address to the 64-bit GAS structure. The
- * Space ID is always I/O for 32-bit legacy address fields
- */
- AcpiTbInitGenericAddress (Address64, ACPI_ADR_SPACE_SYSTEM_IO,
- *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT, FadtInfoTable[i].Length),
- (UINT64) Address32, FadtInfoTable[i].Name);
- }
- }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION: AcpiTbValidateFadt
- *
- * PARAMETERS: Table - Pointer to the FADT to be validated
- *
- * RETURN: None
- *
- * DESCRIPTION: Validate various important fields within the FADT. If a problem
- * is found, issue a message, but no status is returned.
- * Used by both the table manager and the disassembler.
- *
- * Possible additional checks:
- * (AcpiGbl_FADT.Pm1EventLength >= 4)
- * (AcpiGbl_FADT.Pm1ControlLength >= 2)
- * (AcpiGbl_FADT.PmTimerLength >= 4)
- * Gpe block lengths must be multiple of 2
- *
- ******************************************************************************/
-
-static void
-AcpiTbValidateFadt (
- void)
-{
- char *Name;
- ACPI_GENERIC_ADDRESS *Address64;
- UINT8 Length;
- UINT32 i;
-
-
- /*
- * Check for FACS and DSDT address mismatches. An address mismatch between
- * the 32-bit and 64-bit address fields (FIRMWARE_CTRL/X_FIRMWARE_CTRL and
- * DSDT/X_DSDT) would indicate the presence of two FACS or two DSDT tables.
+ * Expand the 32-bit FACS and DSDT addresses to 64-bit as necessary.
+ * Later ACPICA code will always use the X 64-bit field.
*/
- if (AcpiGbl_FADT.Facs &&
- (AcpiGbl_FADT.XFacs != (UINT64) AcpiGbl_FADT.Facs))
- {
- ACPI_BIOS_WARNING ((AE_INFO,
- "32/64X FACS address mismatch in FADT - "
- "0x%8.8X/0x%8.8X%8.8X, using 32",
- AcpiGbl_FADT.Facs, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XFacs)));
+ AcpiGbl_FADT.XFacs = AcpiTbSelectAddress ("FACS",
+ AcpiGbl_FADT.Facs, AcpiGbl_FADT.XFacs);
- AcpiGbl_FADT.XFacs = (UINT64) AcpiGbl_FADT.Facs;
- }
-
- if (AcpiGbl_FADT.Dsdt &&
- (AcpiGbl_FADT.XDsdt != (UINT64) AcpiGbl_FADT.Dsdt))
- {
- ACPI_BIOS_WARNING ((AE_INFO,
- "32/64X DSDT address mismatch in FADT - "
- "0x%8.8X/0x%8.8X%8.8X, using 32",
- AcpiGbl_FADT.Dsdt, ACPI_FORMAT_UINT64 (AcpiGbl_FADT.XDsdt)));
-
- AcpiGbl_FADT.XDsdt = (UINT64) AcpiGbl_FADT.Dsdt;
- }
+ AcpiGbl_FADT.XDsdt = AcpiTbSelectAddress ("DSDT",
+ AcpiGbl_FADT.Dsdt, AcpiGbl_FADT.XDsdt);
/* If Hardware Reduced flag is set, we are all done */
@@ -578,16 +543,82 @@ AcpiTbValidateFadt (
for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++)
{
/*
- * Generate pointer to the 64-bit address, get the register
- * length (width) and the register name
+ * Get the 32-bit and 64-bit addresses, as well as the register
+ * length and register name.
*/
+ Address32 = *ACPI_ADD_PTR (UINT32,
+ &AcpiGbl_FADT, FadtInfoTable[i].Address32);
+
Address64 = ACPI_ADD_PTR (ACPI_GENERIC_ADDRESS,
- &AcpiGbl_FADT, FadtInfoTable[i].Address64);
+ &AcpiGbl_FADT, FadtInfoTable[i].Address64);
+
Length = *ACPI_ADD_PTR (UINT8,
- &AcpiGbl_FADT, FadtInfoTable[i].Length);
+ &AcpiGbl_FADT, FadtInfoTable[i].Length);
+
Name = FadtInfoTable[i].Name;
/*
+ * Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
+ * generic address structures as necessary. Later code will always use
+ * the 64-bit address structures.
+ *
+ * November 2013:
+ * Now always use the 64-bit address if it is valid (non-zero), in
+ * accordance with the ACPI specification which states that a 64-bit
+ * address supersedes the 32-bit version. This behavior can be
+ * overridden by the AcpiGbl_Use32BitFadtAddresses flag.
+ *
+ * During 64-bit address construction and verification,
+ * these cases are handled:
+ *
+ * Address32 zero, Address64 [don't care] - Use Address64
+ *
+ * Address32 non-zero, Address64 zero - Copy/use Address32
+ * Address32 non-zero == Address64 non-zero - Use Address64
+ * Address32 non-zero != Address64 non-zero - Warning, use Address64
+ *
+ * Override: if AcpiGbl_Use32BitFadtAddresses is TRUE, and:
+ * Address32 non-zero != Address64 non-zero - Warning, copy/use Address32
+ *
+ * Note: SpaceId is always I/O for 32-bit legacy address fields
+ */
+ if (Address32)
+ {
+ if (!Address64->Address)
+ {
+ /* 64-bit address is zero, use 32-bit address */
+
+ AcpiTbInitGenericAddress (Address64,
+ ACPI_ADR_SPACE_SYSTEM_IO,
+ *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT,
+ FadtInfoTable[i].Length),
+ (UINT64) Address32, Name);
+ }
+ else if (Address64->Address != (UINT64) Address32)
+ {
+ /* Address mismatch */
+
+ ACPI_BIOS_WARNING ((AE_INFO,
+ "32/64X address mismatch in FADT/%s: "
+ "0x%8.8X/0x%8.8X%8.8X, using %u-bit address",
+ Name, Address32,
+ ACPI_FORMAT_UINT64 (Address64->Address),
+ AcpiGbl_Use32BitFadtAddresses ? 32 : 64));
+
+ if (AcpiGbl_Use32BitFadtAddresses)
+ {
+ /* 32-bit address override */
+
+ AcpiTbInitGenericAddress (Address64,
+ ACPI_ADR_SPACE_SYSTEM_IO,
+ *ACPI_ADD_PTR (UINT8, &AcpiGbl_FADT,
+ FadtInfoTable[i].Length),
+ (UINT64) Address32, Name);
+ }
+ }
+ }
+
+ /*
* For each extended field, check for length mismatch between the
* legacy length field and the corresponding 64-bit X length field.
* Note: If the legacy length field is > 0xFF bits, ignore this
diff --git a/source/components/tables/tbutils.c b/source/components/tables/tbutils.c
index 7c84d5e..159a7d9 100644
--- a/source/components/tables/tbutils.c
+++ b/source/components/tables/tbutils.c
@@ -53,6 +53,10 @@
/* Local prototypes */
+static ACPI_STATUS
+AcpiTbValidateXsdt (
+ ACPI_PHYSICAL_ADDRESS Address);
+
static ACPI_PHYSICAL_ADDRESS
AcpiTbGetRootTableEntry (
UINT8 *TableEntry,
@@ -353,7 +357,7 @@ AcpiTbGetRootTableEntry (
* Get the table physical address (32-bit for RSDT, 64-bit for XSDT):
* Note: Addresses are 32-bit aligned (not 64) in both RSDT and XSDT
*/
- if (TableEntrySize == sizeof (UINT32))
+ if (TableEntrySize == ACPI_RSDT_ENTRY_SIZE)
{
/*
* 32-bit platform, RSDT: Return 32-bit table entry
@@ -388,6 +392,92 @@ AcpiTbGetRootTableEntry (
/*******************************************************************************
*
+ * FUNCTION: AcpiTbValidateXsdt
+ *
+ * PARAMETERS: Address - Physical address of the XSDT (from RSDP)
+ *
+ * RETURN: Status. AE_OK if the table appears to be valid.
+ *
+ * DESCRIPTION: Validate an XSDT to ensure that it is of minimum size and does
+ * not contain any NULL entries. A problem that is seen in the
+ * field is that the XSDT exists, but is actually useless because
+ * of one or more (or all) NULL entries.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiTbValidateXsdt (
+ ACPI_PHYSICAL_ADDRESS XsdtAddress)
+{
+ ACPI_TABLE_HEADER *Table;
+ UINT8 *NextEntry;
+ ACPI_PHYSICAL_ADDRESS Address;
+ UINT32 Length;
+ UINT32 EntryCount;
+ ACPI_STATUS Status;
+ UINT32 i;
+
+
+ /* Get the XSDT length */
+
+ Table = AcpiOsMapMemory (XsdtAddress, sizeof (ACPI_TABLE_HEADER));
+ if (!Table)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ Length = Table->Length;
+ AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
+
+ /*
+ * Minimum XSDT length is the size of the standard ACPI header
+ * plus one physical address entry
+ */
+ if (Length < (sizeof (ACPI_TABLE_HEADER) + ACPI_XSDT_ENTRY_SIZE))
+ {
+ return (AE_INVALID_TABLE_LENGTH);
+ }
+
+ /* Map the entire XSDT */
+
+ Table = AcpiOsMapMemory (XsdtAddress, Length);
+ if (!Table)
+ {
+ return (AE_NO_MEMORY);
+ }
+
+ /* Get the number of entries and pointer to first entry */
+
+ Status = AE_OK;
+ NextEntry = ACPI_ADD_PTR (UINT8, Table, sizeof (ACPI_TABLE_HEADER));
+ EntryCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) /
+ ACPI_XSDT_ENTRY_SIZE);
+
+ /* Validate each entry (physical address) within the XSDT */
+
+ for (i = 0; i < EntryCount; i++)
+ {
+ Address = AcpiTbGetRootTableEntry (NextEntry, ACPI_XSDT_ENTRY_SIZE);
+ if (!Address)
+ {
+ /* Detected a NULL entry, XSDT is invalid */
+
+ Status = AE_NULL_ENTRY;
+ break;
+ }
+
+ NextEntry += ACPI_XSDT_ENTRY_SIZE;
+ }
+
+ /* Unmap table */
+
+ AcpiOsUnmapMemory (Table, Length);
+ return (Status);
+}
+
+
+/*******************************************************************************
+ *
* FUNCTION: AcpiTbParseRootTable
*
* PARAMETERS: Rsdp - Pointer to the RSDP
@@ -421,9 +511,8 @@ AcpiTbParseRootTable (
ACPI_FUNCTION_TRACE (TbParseRootTable);
- /*
- * Map the entire RSDP and extract the address of the RSDT or XSDT
- */
+ /* Map the entire RSDP and extract the address of the RSDT or XSDT */
+
Rsdp = AcpiOsMapMemory (RsdpAddress, sizeof (ACPI_TABLE_RSDP));
if (!Rsdp)
{
@@ -433,24 +522,26 @@ AcpiTbParseRootTable (
AcpiTbPrintTableHeader (RsdpAddress,
ACPI_CAST_PTR (ACPI_TABLE_HEADER, Rsdp));
- /* Differentiate between RSDT and XSDT root tables */
+ /* Use XSDT if present and not overridden. Otherwise, use RSDT */
- if (Rsdp->Revision > 1 && Rsdp->XsdtPhysicalAddress)
+ if ((Rsdp->Revision > 1) &&
+ Rsdp->XsdtPhysicalAddress &&
+ !AcpiGbl_DoNotUseXsdt)
{
/*
- * Root table is an XSDT (64-bit physical addresses). We must use the
- * XSDT if the revision is > 1 and the XSDT pointer is present, as per
- * the ACPI specification.
+ * RSDP contains an XSDT (64-bit physical addresses). We must use
+ * the XSDT if the revision is > 1 and the XSDT pointer is present,
+ * as per the ACPI specification.
*/
Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->XsdtPhysicalAddress;
- TableEntrySize = sizeof (UINT64);
+ TableEntrySize = ACPI_XSDT_ENTRY_SIZE;
}
else
{
/* Root table is an RSDT (32-bit physical addresses) */
Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
- TableEntrySize = sizeof (UINT32);
+ TableEntrySize = ACPI_RSDT_ENTRY_SIZE;
}
/*
@@ -459,6 +550,24 @@ AcpiTbParseRootTable (
*/
AcpiOsUnmapMemory (Rsdp, sizeof (ACPI_TABLE_RSDP));
+ /*
+ * If it is present and used, validate the XSDT for access/size
+ * and ensure that all table entries are at least non-NULL
+ */
+ if (TableEntrySize == ACPI_XSDT_ENTRY_SIZE)
+ {
+ Status = AcpiTbValidateXsdt (Address);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_BIOS_WARNING ((AE_INFO, "XSDT is invalid (%s), using RSDT",
+ AcpiFormatException (Status)));
+
+ /* Fall back to the RSDT */
+
+ Address = (ACPI_PHYSICAL_ADDRESS) Rsdp->RsdtPhysicalAddress;
+ TableEntrySize = ACPI_RSDT_ENTRY_SIZE;
+ }
+ }
/* Map the RSDT/XSDT table header to get the full table length */
@@ -470,12 +579,14 @@ AcpiTbParseRootTable (
AcpiTbPrintTableHeader (Address, Table);
- /* Get the length of the full table, verify length and map entire table */
-
+ /*
+ * Validate length of the table, and map entire table.
+ * Minimum length table must contain at least one entry.
+ */
Length = Table->Length;
AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
- if (Length < sizeof (ACPI_TABLE_HEADER))
+ if (Length < (sizeof (ACPI_TABLE_HEADER) + TableEntrySize))
{
ACPI_BIOS_ERROR ((AE_INFO,
"Invalid table length 0x%X in RSDT/XSDT", Length));
@@ -497,22 +608,21 @@ AcpiTbParseRootTable (
return_ACPI_STATUS (Status);
}
- /* Calculate the number of tables described in the root table */
+ /* Get the number of entries and pointer to first entry */
TableCount = (UINT32) ((Table->Length - sizeof (ACPI_TABLE_HEADER)) /
TableEntrySize);
+ TableEntry = ACPI_ADD_PTR (UINT8, Table, sizeof (ACPI_TABLE_HEADER));
/*
* First two entries in the table array are reserved for the DSDT
* and FACS, which are not actually present in the RSDT/XSDT - they
* come from the FADT
*/
- TableEntry = ACPI_CAST_PTR (UINT8, Table) + sizeof (ACPI_TABLE_HEADER);
AcpiGbl_RootTableList.CurrentTableCount = 2;
- /*
- * Initialize the root table array from the RSDT/XSDT
- */
+ /* Initialize the root table array from the RSDT/XSDT */
+
for (i = 0; i < TableCount; i++)
{
if (AcpiGbl_RootTableList.CurrentTableCount >=
@@ -554,7 +664,7 @@ AcpiTbParseRootTable (
AcpiTbInstallTable (AcpiGbl_RootTableList.Tables[i].Address,
NULL, i);
- /* Special case for FADT - get the DSDT and FACS */
+ /* Special case for FADT - validate it then get the DSDT and FACS */
if (ACPI_COMPARE_NAME (
&AcpiGbl_RootTableList.Tables[i].Signature, ACPI_SIG_FADT))
diff --git a/source/components/utilities/utaddress.c b/source/components/utilities/utaddress.c
index 7eae5a5..a361cb3 100644
--- a/source/components/utilities/utaddress.c
+++ b/source/components/utilities/utaddress.c
@@ -248,10 +248,11 @@ AcpiUtCheckAddressRange (
while (RangeInfo)
{
/*
- * Check if the requested Address/Length overlaps this AddressRange.
- * Four cases to consider:
+ * Check if the requested address/length overlaps this
+ * address range. There are four cases to consider:
*
- * 1) Input address/length is contained completely in the address range
+ * 1) Input address/length is contained completely in the
+ * address range
* 2) Input address/length overlaps range at the range start
* 3) Input address/length overlaps range at the range end
* 4) Input address/length completely encompasses the range
@@ -267,10 +268,13 @@ AcpiUtCheckAddressRange (
Pathname = AcpiNsGetExternalPathname (RangeInfo->RegionNode);
ACPI_WARNING ((AE_INFO,
- "0x%p-0x%p %s conflicts with Region %s %d",
+ "%s range 0x%p-0x%p conflicts with OpRegion 0x%p-0x%p (%s)",
+ AcpiUtGetRegionName (SpaceId),
ACPI_CAST_PTR (void, Address),
ACPI_CAST_PTR (void, EndAddress),
- AcpiUtGetRegionName (SpaceId), Pathname, OverlapCount));
+ ACPI_CAST_PTR (void, RangeInfo->StartAddress),
+ ACPI_CAST_PTR (void, RangeInfo->EndAddress),
+ Pathname));
ACPI_FREE (Pathname);
}
}
diff --git a/source/components/utilities/utalloc.c b/source/components/utilities/utalloc.c
index 51eee97..be7eaf07 100644
--- a/source/components/utilities/utalloc.c
+++ b/source/components/utilities/utalloc.c
@@ -324,9 +324,13 @@ AcpiUtInitializeBuffer (
return (AE_BUFFER_OVERFLOW);
case ACPI_ALLOCATE_BUFFER:
-
- /* Allocate a new buffer */
-
+ /*
+ * Allocate a new buffer. We directectly call AcpiOsAllocate here to
+ * purposefully bypass the (optionally enabled) internal allocation
+ * tracking mechanism since we only want to track internal
+ * allocations. Note: The caller should use AcpiOsFree to free this
+ * buffer created via ACPI_ALLOCATE_BUFFER.
+ */
Buffer->Pointer = AcpiOsAllocate (RequiredLength);
break;
diff --git a/source/components/utilities/utcache.c b/source/components/utilities/utcache.c
index 54c73e2..7d84f84 100644
--- a/source/components/utilities/utcache.c
+++ b/source/components/utilities/utcache.c
@@ -286,13 +286,13 @@ AcpiOsAcquireObject (
if (!Cache)
{
- return (NULL);
+ return_PTR (NULL);
}
Status = AcpiUtAcquireMutex (ACPI_MTX_CACHES);
if (ACPI_FAILURE (Status))
{
- return (NULL);
+ return_PTR (NULL);
}
ACPI_MEM_TRACKING (Cache->Requests++);
@@ -315,7 +315,7 @@ AcpiOsAcquireObject (
Status = AcpiUtReleaseMutex (ACPI_MTX_CACHES);
if (ACPI_FAILURE (Status))
{
- return (NULL);
+ return_PTR (NULL);
}
/* Clear (zero) the previously used Object */
@@ -340,16 +340,16 @@ AcpiOsAcquireObject (
Status = AcpiUtReleaseMutex (ACPI_MTX_CACHES);
if (ACPI_FAILURE (Status))
{
- return (NULL);
+ return_PTR (NULL);
}
Object = ACPI_ALLOCATE_ZEROED (Cache->ObjectSize);
if (!Object)
{
- return (NULL);
+ return_PTR (NULL);
}
}
- return (Object);
+ return_PTR (Object);
}
#endif /* ACPI_USE_LOCAL_CACHE */
diff --git a/source/components/utilities/utdebug.c b/source/components/utilities/utdebug.c
index 87dbf53..0b9018b 100644
--- a/source/components/utilities/utdebug.c
+++ b/source/components/utilities/utdebug.c
@@ -220,9 +220,9 @@ AcpiDebugPrint (
*/
AcpiOsPrintf ("%9s-%04ld ", ModuleName, LineNumber);
-#ifdef ACPI_EXEC_APP
+#ifdef ACPI_APPLICATION
/*
- * For AcpiExec only, emit the thread ID and nesting level.
+ * For AcpiExec/iASL only, emit the thread ID and nesting level.
* Note: nesting level is really only useful during a single-thread
* execution. Otherwise, multiple threads will keep resetting the
* level.
diff --git a/source/components/utilities/utxfinit.c b/source/components/utilities/utxfinit.c
index b395c15..984a600 100644
--- a/source/components/utilities/utxfinit.c
+++ b/source/components/utilities/utxfinit.c
@@ -131,8 +131,16 @@ AcpiInitializeSubsystem (
/* If configured, initialize the AML debugger */
- ACPI_DEBUGGER_EXEC (Status = AcpiDbInitialize ());
- return_ACPI_STATUS (Status);
+#ifdef ACPI_DEBUGGER
+ Status = AcpiDbInitialize ();
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "During Debugger initialization"));
+ return_ACPI_STATUS (Status);
+ }
+#endif
+
+ return_ACPI_STATUS (AE_OK);
}
ACPI_EXPORT_SYMBOL_INIT (AcpiInitializeSubsystem)
OpenPOWER on IntegriCloud