diff options
Diffstat (limited to 'source/components')
-rw-r--r-- | source/components/debugger/dbfileio.c | 10 | ||||
-rw-r--r-- | source/components/debugger/dbinput.c | 6 | ||||
-rw-r--r-- | source/components/dispatcher/dsfield.c | 2 | ||||
-rw-r--r-- | source/components/dispatcher/dsutils.c | 16 | ||||
-rw-r--r-- | source/components/dispatcher/dswexec.c | 3 | ||||
-rw-r--r-- | source/components/dispatcher/dswload.c | 2 | ||||
-rw-r--r-- | source/components/events/evgpeblk.c | 7 | ||||
-rw-r--r-- | source/components/events/evgpeutil.c | 21 | ||||
-rw-r--r-- | source/components/executer/exresnte.c | 4 | ||||
-rw-r--r-- | source/components/namespace/nsxfeval.c | 16 | ||||
-rw-r--r-- | source/components/parser/psopinfo.c | 52 | ||||
-rw-r--r-- | source/components/tables/tbfadt.c | 313 | ||||
-rw-r--r-- | source/components/tables/tbutils.c | 150 | ||||
-rw-r--r-- | source/components/utilities/utaddress.c | 14 | ||||
-rw-r--r-- | source/components/utilities/utalloc.c | 10 | ||||
-rw-r--r-- | source/components/utilities/utcache.c | 12 | ||||
-rw-r--r-- | source/components/utilities/utdebug.c | 4 | ||||
-rw-r--r-- | source/components/utilities/utxfinit.c | 12 |
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) |