diff options
Diffstat (limited to 'source/components/tables/tbinstal.c')
-rw-r--r-- | source/components/tables/tbinstal.c | 889 |
1 files changed, 319 insertions, 570 deletions
diff --git a/source/components/tables/tbinstal.c b/source/components/tables/tbinstal.c index ce4a93d87adf8..9dcaa9115c3c4 100644 --- a/source/components/tables/tbinstal.c +++ b/source/components/tables/tbinstal.c @@ -41,779 +41,528 @@ * POSSIBILITY OF SUCH DAMAGES. */ - #define __TBINSTAL_C__ #include "acpi.h" #include "accommon.h" -#include "acnamesp.h" #include "actables.h" - #define _COMPONENT ACPI_TABLES ACPI_MODULE_NAME ("tbinstal") +/* Local prototypes */ -/****************************************************************************** +static BOOLEAN +AcpiTbCompareTables ( + ACPI_TABLE_DESC *TableDesc, + UINT32 TableIndex); + + +/******************************************************************************* * - * FUNCTION: AcpiTbVerifyTable + * FUNCTION: AcpiTbCompareTables * - * PARAMETERS: TableDesc - table + * PARAMETERS: TableDesc - Table 1 descriptor to be compared + * TableIndex - Index of table 2 to be compared * - * RETURN: Status + * RETURN: TRUE if both tables are identical. * - * DESCRIPTION: this function is called to verify and map table + * DESCRIPTION: This function compares a table with another table that has + * already been installed in the root table list. * - *****************************************************************************/ + ******************************************************************************/ -ACPI_STATUS -AcpiTbVerifyTable ( - ACPI_TABLE_DESC *TableDesc) +static BOOLEAN +AcpiTbCompareTables ( + ACPI_TABLE_DESC *TableDesc, + UINT32 TableIndex) { ACPI_STATUS Status = AE_OK; + BOOLEAN IsIdentical; + ACPI_TABLE_HEADER *Table; + UINT32 TableLength; + UINT8 TableFlags; - ACPI_FUNCTION_TRACE (TbVerifyTable); - - - /* Map the table if necessary */ - - if (!TableDesc->Pointer) + Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex], + &Table, &TableLength, &TableFlags); + if (ACPI_FAILURE (Status)) { - if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) == - ACPI_TABLE_ORIGIN_MAPPED) - { - TableDesc->Pointer = AcpiOsMapMemory ( - TableDesc->Address, TableDesc->Length); - } - - if (!TableDesc->Pointer) - { - return_ACPI_STATUS (AE_NO_MEMORY); - } + return (FALSE); } - /* Always calculate checksum, ignore bad checksum if requested */ + /* + * Check for a table match on the entire table length, + * not just the header. + */ + IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength || + ACPI_MEMCMP (TableDesc->Pointer, Table, TableLength)) ? + FALSE : TRUE); - Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); + /* Release the acquired table */ - return_ACPI_STATUS (Status); + AcpiTbReleaseTable (Table, TableLength, TableFlags); + return (IsIdentical); } /******************************************************************************* * - * FUNCTION: AcpiTbAddTable + * FUNCTION: AcpiTbInstallTableWithOverride * - * PARAMETERS: TableDesc - Table descriptor - * TableIndex - Where the table index is returned + * PARAMETERS: TableIndex - Index into root table array + * NewTableDesc - New table descriptor to install + * Override - Whether override should be performed * - * RETURN: Status + * RETURN: None * - * DESCRIPTION: This function is called to add an ACPI table. It is used to - * dynamically load tables via the Load and LoadTable AML - * operators. + * DESCRIPTION: Install an ACPI table into the global data structure. The + * table override mechanism is called to allow the host + * OS to replace any table before it is installed in the root + * table array. * ******************************************************************************/ -ACPI_STATUS -AcpiTbAddTable ( - ACPI_TABLE_DESC *TableDesc, - UINT32 *TableIndex) +void +AcpiTbInstallTableWithOverride ( + UINT32 TableIndex, + ACPI_TABLE_DESC *NewTableDesc, + BOOLEAN Override) { - UINT32 i; - ACPI_STATUS Status = AE_OK; - - - ACPI_FUNCTION_TRACE (TbAddTable); - - if (!TableDesc->Pointer) + if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) { - Status = AcpiTbVerifyTable (TableDesc); - if (ACPI_FAILURE (Status) || !TableDesc->Pointer) - { - return_ACPI_STATUS (Status); - } + return; } /* - * Validate the incoming table signature. + * ACPI Table Override: * - * 1) Originally, we checked the table signature for "SSDT" or "PSDT". - * 2) We added support for OEMx tables, signature "OEM". - * 3) Valid tables were encountered with a null signature, so we just - * gave up on validating the signature, (05/2008). - * 4) We encountered non-AML tables such as the MADT, which caused - * interpreter errors and kernel faults. So now, we once again allow - * only "SSDT", "OEMx", and now, also a null signature. (05/2011). + * Before we install the table, let the host OS override it with a new + * one if desired. Any table within the RSDT/XSDT can be replaced, + * including the DSDT which is pointed to by the FADT. */ - if ((TableDesc->Pointer->Signature[0] != 0x00) && - (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) && - (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3))) + if (Override) { - ACPI_BIOS_ERROR ((AE_INFO, - "Table has invalid signature [%4.4s] (0x%8.8X), " - "must be SSDT or OEMx", - AcpiUtValidAcpiName (TableDesc->Pointer->Signature) ? - TableDesc->Pointer->Signature : "????", - *(UINT32 *) TableDesc->Pointer->Signature)); - - return_ACPI_STATUS (AE_BAD_SIGNATURE); + AcpiTbOverrideTable (NewTableDesc); } - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - - /* Check if table is already registered */ - - for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) - { - if (!AcpiGbl_RootTableList.Tables[i].Pointer) - { - Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); - if (ACPI_FAILURE (Status) || - !AcpiGbl_RootTableList.Tables[i].Pointer) - { - continue; - } - } - - /* - * Check for a table match on the entire table length, - * not just the header. - */ - if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length) - { - continue; - } - - if (ACPI_MEMCMP (TableDesc->Pointer, - AcpiGbl_RootTableList.Tables[i].Pointer, - AcpiGbl_RootTableList.Tables[i].Length)) - { - continue; - } - - /* - * Note: the current mechanism does not unregister a table if it is - * dynamically unloaded. The related namespace entries are deleted, - * but the table remains in the root table list. - * - * The assumption here is that the number of different tables that - * will be loaded is actually small, and there is minimal overhead - * in just keeping the table in case it is needed again. - * - * If this assumption changes in the future (perhaps on large - * machines with many table load/unload operations), tables will - * need to be unregistered when they are unloaded, and slots in the - * root table list should be reused when empty. - */ - - /* - * Table is already registered. - * We can delete the table that was passed as a parameter. - */ - AcpiTbDeleteTable (TableDesc); - *TableIndex = i; - - if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) - { - /* Table is still loaded, this is an error */ - - Status = AE_ALREADY_EXISTS; - goto Release; - } - else - { - /* Table was unloaded, allow it to be reloaded */ - - TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer; - TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address; - Status = AE_OK; - goto PrintHeader; - } - } + AcpiTbInitTableDescriptor (&AcpiGbl_RootTableList.Tables[TableIndex], + NewTableDesc->Address, NewTableDesc->Flags, NewTableDesc->Pointer); - /* - * ACPI Table Override: - * Allow the host to override dynamically loaded tables. - * NOTE: the table is fully mapped at this point, and the mapping will - * be deleted by TbTableOverride if the table is actually overridden. - */ - (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc); + AcpiTbPrintTableHeader (NewTableDesc->Address, NewTableDesc->Pointer); - /* Add the table to the global root table list */ + /* Set the global integer width (based upon revision of the DSDT) */ - Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer, - TableDesc->Length, TableDesc->Flags, TableIndex); - if (ACPI_FAILURE (Status)) + if (TableIndex == ACPI_TABLE_INDEX_DSDT) { - goto Release; + AcpiUtSetIntegerWidth (NewTableDesc->Pointer->Revision); } - -PrintHeader: - AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); - -Release: - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (Status); } /******************************************************************************* * - * FUNCTION: AcpiTbTableOverride + * FUNCTION: AcpiTbInstallFixedTable * - * PARAMETERS: TableHeader - Header for the original table - * TableDesc - Table descriptor initialized for the - * original table. May or may not be mapped. + * PARAMETERS: Address - Physical address of DSDT or FACS + * Signature - Table signature, NULL if no need to + * match + * TableIndex - Index into root table array * - * RETURN: Pointer to the entire new table. NULL if table not overridden. - * If overridden, installs the new table within the input table - * descriptor. + * RETURN: Status * - * DESCRIPTION: Attempt table override by calling the OSL override functions. - * Note: If the table is overridden, then the entire new table - * is mapped and returned by this function. + * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data + * structure. * ******************************************************************************/ -ACPI_TABLE_HEADER * -AcpiTbTableOverride ( - ACPI_TABLE_HEADER *TableHeader, - ACPI_TABLE_DESC *TableDesc) +ACPI_STATUS +AcpiTbInstallFixedTable ( + ACPI_PHYSICAL_ADDRESS Address, + char *Signature, + UINT32 TableIndex) { + ACPI_TABLE_DESC NewTableDesc; ACPI_STATUS Status; - ACPI_TABLE_HEADER *NewTable = NULL; - ACPI_PHYSICAL_ADDRESS NewAddress = 0; - UINT32 NewTableLength = 0; - UINT8 NewFlags; - char *OverrideType; - /* (1) Attempt logical override (returns a logical address) */ + ACPI_FUNCTION_TRACE (TbInstallFixedTable); - Status = AcpiOsTableOverride (TableHeader, &NewTable); - if (ACPI_SUCCESS (Status) && NewTable) + + if (!Address) { - NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable); - NewTableLength = NewTable->Length; - NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE; - OverrideType = "Logical"; - goto FinishOverride; + ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]", + Signature)); + return (AE_NO_MEMORY); } - /* (2) Attempt physical override (returns a physical address) */ + /* Fill a table descriptor for validation */ - Status = AcpiOsPhysicalTableOverride (TableHeader, - &NewAddress, &NewTableLength); - if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength) + Status = AcpiTbAcquireTempTable (&NewTableDesc, Address, + ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); + if (ACPI_FAILURE (Status)) { - /* Map the entire new table */ - - NewTable = AcpiOsMapMemory (NewAddress, NewTableLength); - if (!NewTable) - { - ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, - "%4.4s " ACPI_PRINTF_UINT - " Attempted physical table override failed", - TableHeader->Signature, - ACPI_FORMAT_TO_UINT (TableDesc->Address))); - return (NULL); - } - - OverrideType = "Physical"; - NewFlags = ACPI_TABLE_ORIGIN_MAPPED; - goto FinishOverride; + ACPI_ERROR ((AE_INFO, "Could not acquire table length at %p", + ACPI_CAST_PTR (void, Address))); + return_ACPI_STATUS (Status); } - return (NULL); /* There was no override */ - - -FinishOverride: - - ACPI_INFO ((AE_INFO, "%4.4s " ACPI_PRINTF_UINT - " %s table override, new table: " ACPI_PRINTF_UINT, - TableHeader->Signature, - ACPI_FORMAT_TO_UINT (TableDesc->Address), - OverrideType, ACPI_FORMAT_TO_UINT (NewTable))); + /* Validate and verify a table before installation */ - /* We can now unmap/delete the original table (if fully mapped) */ + Status = AcpiTbVerifyTable (&NewTableDesc, Signature); + if (ACPI_FAILURE (Status)) + { + goto ReleaseAndExit; + } - AcpiTbDeleteTable (TableDesc); + AcpiTbInstallTableWithOverride (TableIndex, &NewTableDesc, TRUE); - /* Setup descriptor for the new table */ +ReleaseAndExit: - TableDesc->Address = NewAddress; - TableDesc->Pointer = NewTable; - TableDesc->Length = NewTableLength; - TableDesc->Flags = NewFlags; + /* Release the temporary table descriptor */ - return (NewTable); + AcpiTbReleaseTempTable (&NewTableDesc); + return_ACPI_STATUS (Status); } /******************************************************************************* * - * FUNCTION: AcpiTbResizeRootTableList + * FUNCTION: AcpiTbInstallStandardTable * - * PARAMETERS: None + * PARAMETERS: Address - Address of the table (might be a virtual + * address depending on the TableFlags) + * Flags - Flags for the table + * Reload - Whether reload should be performed + * Override - Whether override should be performed + * TableIndex - Where the table index is returned * * RETURN: Status * - * DESCRIPTION: Expand the size of global table array + * DESCRIPTION: This function is called to install an ACPI table that is + * neither DSDT nor FACS (a "standard" table.) + * When this function is called by "Load" or "LoadTable" opcodes, + * or by AcpiLoadTable() API, the "Reload" parameter is set. + * After sucessfully returning from this function, table is + * "INSTALLED" but not "VALIDATED". * ******************************************************************************/ ACPI_STATUS -AcpiTbResizeRootTableList ( - void) +AcpiTbInstallStandardTable ( + ACPI_PHYSICAL_ADDRESS Address, + UINT8 Flags, + BOOLEAN Reload, + BOOLEAN Override, + UINT32 *TableIndex) { - ACPI_TABLE_DESC *Tables; - UINT32 TableCount; + UINT32 i; + ACPI_STATUS Status = AE_OK; + ACPI_TABLE_DESC NewTableDesc; - ACPI_FUNCTION_TRACE (TbResizeRootTableList); + ACPI_FUNCTION_TRACE (TbInstallStandardTable); - /* AllowResize flag is a parameter to AcpiInitializeTables */ + /* Acquire a temporary table descriptor for validation */ - if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) + Status = AcpiTbAcquireTempTable (&NewTableDesc, Address, Flags); + if (ACPI_FAILURE (Status)) { - ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); - return_ACPI_STATUS (AE_SUPPORT); + ACPI_ERROR ((AE_INFO, "Could not acquire table length at %p", + ACPI_CAST_PTR (void, Address))); + return_ACPI_STATUS (Status); } - /* Increase the Table Array size */ - - if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) - { - TableCount = AcpiGbl_RootTableList.MaxTableCount; - } - else + /* + * Optionally do not load any SSDTs from the RSDT/XSDT. This can + * be useful for debugging ACPI problems on some machines. + */ + if (!Reload && + AcpiGbl_DisableSsdtTableInstall && + ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT)) { - TableCount = AcpiGbl_RootTableList.CurrentTableCount; + ACPI_INFO ((AE_INFO, "Ignoring installation of %4.4s at %p", + NewTableDesc.Signature.Ascii, ACPI_CAST_PTR (void, Address))); + goto ReleaseAndExit; } - Tables = ACPI_ALLOCATE_ZEROED ( - ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) * - sizeof (ACPI_TABLE_DESC)); - if (!Tables) + /* Validate and verify a table before installation */ + + Status = AcpiTbVerifyTable (&NewTableDesc, NULL); + if (ACPI_FAILURE (Status)) { - ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); - return_ACPI_STATUS (AE_NO_MEMORY); + goto ReleaseAndExit; } - /* Copy and free the previous table array */ - - if (AcpiGbl_RootTableList.Tables) + if (Reload) { - ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, - (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC)); - - if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) + /* + * Validate the incoming table signature. + * + * 1) Originally, we checked the table signature for "SSDT" or "PSDT". + * 2) We added support for OEMx tables, signature "OEM". + * 3) Valid tables were encountered with a null signature, so we just + * gave up on validating the signature, (05/2008). + * 4) We encountered non-AML tables such as the MADT, which caused + * interpreter errors and kernel faults. So now, we once again allow + * only "SSDT", "OEMx", and now, also a null signature. (05/2011). + */ + if ((NewTableDesc.Signature.Ascii[0] != 0x00) && + (!ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT)) && + (ACPI_STRNCMP (NewTableDesc.Signature.Ascii, "OEM", 3))) { - ACPI_FREE (AcpiGbl_RootTableList.Tables); + ACPI_BIOS_ERROR ((AE_INFO, + "Table has invalid signature [%4.4s] (0x%8.8X), " + "must be SSDT or OEMx", + AcpiUtValidAcpiName (NewTableDesc.Signature.Ascii) ? + NewTableDesc.Signature.Ascii : "????", + NewTableDesc.Signature.Integer)); + + Status = AE_BAD_SIGNATURE; + goto ReleaseAndExit; } - } - - AcpiGbl_RootTableList.Tables = Tables; - AcpiGbl_RootTableList.MaxTableCount = - TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT; - AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED; - return_ACPI_STATUS (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiTbStoreTable - * - * PARAMETERS: Address - Table address - * Table - Table header - * Length - Table length - * Flags - flags - * - * RETURN: Status and table index. - * - * DESCRIPTION: Add an ACPI table to the global table list - * - ******************************************************************************/ - -ACPI_STATUS -AcpiTbStoreTable ( - ACPI_PHYSICAL_ADDRESS Address, - ACPI_TABLE_HEADER *Table, - UINT32 Length, - UINT8 Flags, - UINT32 *TableIndex) -{ - ACPI_STATUS Status; - ACPI_TABLE_DESC *NewTable; + /* Check if table is already registered */ + for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) + { + /* + * Check for a table match on the entire table length, + * not just the header. + */ + if (!AcpiTbCompareTables (&NewTableDesc, i)) + { + continue; + } - /* Ensure that there is room for the table in the Root Table List */ + /* + * Note: the current mechanism does not unregister a table if it is + * dynamically unloaded. The related namespace entries are deleted, + * but the table remains in the root table list. + * + * The assumption here is that the number of different tables that + * will be loaded is actually small, and there is minimal overhead + * in just keeping the table in case it is needed again. + * + * If this assumption changes in the future (perhaps on large + * machines with many table load/unload operations), tables will + * need to be unregistered when they are unloaded, and slots in the + * root table list should be reused when empty. + */ + if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) + { + /* Table is still loaded, this is an error */ - if (AcpiGbl_RootTableList.CurrentTableCount >= - AcpiGbl_RootTableList.MaxTableCount) - { - Status = AcpiTbResizeRootTableList(); - if (ACPI_FAILURE (Status)) - { - return (Status); + Status = AE_ALREADY_EXISTS; + goto ReleaseAndExit; + } + else + { + /* + * Table was unloaded, allow it to be reloaded. + * As we are going to return AE_OK to the caller, we should + * take the responsibility of freeing the input descriptor. + * Refill the input descriptor to ensure + * AcpiTbInstallTableWithOverride() can be called again to + * indicate the re-installation. + */ + AcpiTbUninstallTable (&NewTableDesc); + *TableIndex = i; + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return_ACPI_STATUS (AE_OK); + } } } - NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount]; - - /* Initialize added table */ - - NewTable->Address = Address; - NewTable->Pointer = Table; - NewTable->Length = Length; - NewTable->OwnerId = 0; - NewTable->Flags = Flags; - - ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature); - - *TableIndex = AcpiGbl_RootTableList.CurrentTableCount; - AcpiGbl_RootTableList.CurrentTableCount++; - return (AE_OK); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiTbDeleteTable - * - * PARAMETERS: TableIndex - Table index - * - * RETURN: None - * - * DESCRIPTION: Delete one internal ACPI table - * - ******************************************************************************/ - -void -AcpiTbDeleteTable ( - ACPI_TABLE_DESC *TableDesc) -{ - - /* Table must be mapped or allocated */ + /* Add the table to the global root table list */ - if (!TableDesc->Pointer) + Status = AcpiTbGetNextRootIndex (&i); + if (ACPI_FAILURE (Status)) { - return; + goto ReleaseAndExit; } - switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) - { - case ACPI_TABLE_ORIGIN_MAPPED: - - AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length); - break; - - case ACPI_TABLE_ORIGIN_ALLOCATED: + *TableIndex = i; + AcpiTbInstallTableWithOverride (i, &NewTableDesc, Override); - ACPI_FREE (TableDesc->Pointer); - break; +ReleaseAndExit: - /* Not mapped or allocated, there is nothing we can do */ + /* Release the temporary table descriptor */ - default: - - return; - } - - TableDesc->Pointer = NULL; + AcpiTbReleaseTempTable (&NewTableDesc); + return_ACPI_STATUS (Status); } /******************************************************************************* * - * FUNCTION: AcpiTbTerminate + * FUNCTION: AcpiTbOverrideTable * - * PARAMETERS: None + * PARAMETERS: OldTableDesc - Validated table descriptor to be + * overridden * * RETURN: None * - * DESCRIPTION: Delete all internal ACPI tables + * DESCRIPTION: Attempt table override by calling the OSL override functions. + * Note: If the table is overridden, then the entire new table + * is acquired and returned by this function. + * Before/after invocation, the table descriptor is in a state + * that is "VALIDATED". * ******************************************************************************/ void -AcpiTbTerminate ( - void) +AcpiTbOverrideTable ( + ACPI_TABLE_DESC *OldTableDesc) { - UINT32 i; - - - ACPI_FUNCTION_TRACE (TbTerminate); - + ACPI_STATUS Status; + char *OverrideType; + ACPI_TABLE_DESC NewTableDesc; + ACPI_TABLE_HEADER *Table; + ACPI_PHYSICAL_ADDRESS Address; + UINT32 Length; - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - /* Delete the individual tables */ + /* (1) Attempt logical override (returns a logical address) */ - for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) + Status = AcpiOsTableOverride (OldTableDesc->Pointer, &Table); + if (ACPI_SUCCESS (Status) && Table) { - AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]); + AcpiTbAcquireTempTable (&NewTableDesc, ACPI_PTR_TO_PHYSADDR (Table), + ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL); + OverrideType = "Logical"; + goto FinishOverride; } - /* - * Delete the root table array if allocated locally. Array cannot be - * mapped, so we don't need to check for that flag. - */ - if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) + /* (2) Attempt physical override (returns a physical address) */ + + Status = AcpiOsPhysicalTableOverride (OldTableDesc->Pointer, + &Address, &Length); + if (ACPI_SUCCESS (Status) && Address && Length) { - ACPI_FREE (AcpiGbl_RootTableList.Tables); + AcpiTbAcquireTempTable (&NewTableDesc, Address, + ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); + OverrideType = "Physical"; + goto FinishOverride; } - AcpiGbl_RootTableList.Tables = NULL; - AcpiGbl_RootTableList.Flags = 0; - AcpiGbl_RootTableList.CurrentTableCount = 0; - - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - - return_VOID; -} - + return; /* There was no override */ -/******************************************************************************* - * - * FUNCTION: AcpiTbDeleteNamespaceByOwner - * - * PARAMETERS: TableIndex - Table index - * - * RETURN: Status - * - * DESCRIPTION: Delete all namespace objects created when this table was loaded. - * - ******************************************************************************/ -ACPI_STATUS -AcpiTbDeleteNamespaceByOwner ( - UINT32 TableIndex) -{ - ACPI_OWNER_ID OwnerId; - ACPI_STATUS Status; - - - ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); +FinishOverride: + /* Validate and verify a table before overriding */ - Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); + Status = AcpiTbVerifyTable (&NewTableDesc, NULL); if (ACPI_FAILURE (Status)) { - return_ACPI_STATUS (Status); + return; } - if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) - { - /* The table index does not exist */ - - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (AE_NOT_EXIST); - } + ACPI_INFO ((AE_INFO, "%4.4s " ACPI_PRINTF_UINT + " %s table override, new table: " ACPI_PRINTF_UINT, + OldTableDesc->Signature.Ascii, + ACPI_FORMAT_TO_UINT (OldTableDesc->Address), + OverrideType, ACPI_FORMAT_TO_UINT (NewTableDesc.Address))); - /* Get the owner ID for this table, used to delete namespace nodes */ + /* We can now uninstall the original table */ - OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + AcpiTbUninstallTable (OldTableDesc); /* - * Need to acquire the namespace writer lock to prevent interference - * with any concurrent namespace walks. The interpreter must be - * released during the deletion since the acquisition of the deletion - * lock may block, and also since the execution of a namespace walk - * must be allowed to use the interpreter. + * Replace the original table descriptor and keep its state as + * "VALIDATED". */ - (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); - Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); - - AcpiNsDeleteNamespaceByOwner (OwnerId); - if (ACPI_FAILURE (Status)) - { - return_ACPI_STATUS (Status); - } + AcpiTbInitTableDescriptor (OldTableDesc, NewTableDesc.Address, + NewTableDesc.Flags, NewTableDesc.Pointer); + AcpiTbValidateTable (OldTableDesc); - AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); + /* Release the temporary table descriptor */ - Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); - return_ACPI_STATUS (Status); + AcpiTbReleaseTempTable (&NewTableDesc); } /******************************************************************************* * - * FUNCTION: AcpiTbAllocateOwnerId + * FUNCTION: AcpiTbStoreTable * - * PARAMETERS: TableIndex - Table index + * PARAMETERS: Address - Table address + * Table - Table header + * Length - Table length + * Flags - Install flags + * TableIndex - Where the table index is returned * - * RETURN: Status + * RETURN: Status and table index. * - * DESCRIPTION: Allocates OwnerId in TableDesc + * DESCRIPTION: Add an ACPI table to the global table list * ******************************************************************************/ ACPI_STATUS -AcpiTbAllocateOwnerId ( - UINT32 TableIndex) +AcpiTbStoreTable ( + ACPI_PHYSICAL_ADDRESS Address, + ACPI_TABLE_HEADER *Table, + UINT32 Length, + UINT8 Flags, + UINT32 *TableIndex) { - ACPI_STATUS Status = AE_BAD_PARAMETER; - - - ACPI_FUNCTION_TRACE (TbAllocateOwnerId); + ACPI_STATUS Status; + ACPI_TABLE_DESC *TableDesc; - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + Status = AcpiTbGetNextRootIndex (TableIndex); + if (ACPI_FAILURE (Status)) { - Status = AcpiUtAllocateOwnerId - (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); + return (Status); } - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (Status); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiTbReleaseOwnerId - * - * PARAMETERS: TableIndex - Table index - * - * RETURN: Status - * - * DESCRIPTION: Releases OwnerId in TableDesc - * - ******************************************************************************/ - -ACPI_STATUS -AcpiTbReleaseOwnerId ( - UINT32 TableIndex) -{ - ACPI_STATUS Status = AE_BAD_PARAMETER; - - - ACPI_FUNCTION_TRACE (TbReleaseOwnerId); - - - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) - { - AcpiUtReleaseOwnerId ( - &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); - Status = AE_OK; - } + /* Initialize added table */ - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (Status); + TableDesc = &AcpiGbl_RootTableList.Tables[*TableIndex]; + AcpiTbInitTableDescriptor (TableDesc, Address, Flags, Table); + TableDesc->Pointer = Table; + return (AE_OK); } /******************************************************************************* * - * FUNCTION: AcpiTbGetOwnerId + * FUNCTION: AcpiTbUninstallTable * - * PARAMETERS: TableIndex - Table index - * OwnerId - Where the table OwnerId is returned + * PARAMETERS: TableDesc - Table descriptor * - * RETURN: Status + * RETURN: None * - * DESCRIPTION: returns OwnerId for the ACPI table + * DESCRIPTION: Delete one internal ACPI table * ******************************************************************************/ -ACPI_STATUS -AcpiTbGetOwnerId ( - UINT32 TableIndex, - ACPI_OWNER_ID *OwnerId) +void +AcpiTbUninstallTable ( + ACPI_TABLE_DESC *TableDesc) { - ACPI_STATUS Status = AE_BAD_PARAMETER; + ACPI_FUNCTION_TRACE (TbUninstallTable); - ACPI_FUNCTION_TRACE (TbGetOwnerId); + /* Table must be installed */ - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + if (!TableDesc->Address) { - *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; - Status = AE_OK; + return_VOID; } - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return_ACPI_STATUS (Status); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiTbIsTableLoaded - * - * PARAMETERS: TableIndex - Table index - * - * RETURN: Table Loaded Flag - * - ******************************************************************************/ - -BOOLEAN -AcpiTbIsTableLoaded ( - UINT32 TableIndex) -{ - BOOLEAN IsLoaded = FALSE; - + AcpiTbInvalidateTable (TableDesc); - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) == + ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) { - IsLoaded = (BOOLEAN) - (AcpiGbl_RootTableList.Tables[TableIndex].Flags & - ACPI_TABLE_IS_LOADED); + ACPI_FREE (ACPI_CAST_PTR (void, TableDesc->Address)); } - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); - return (IsLoaded); -} - - -/******************************************************************************* - * - * FUNCTION: AcpiTbSetTableLoadedFlag - * - * PARAMETERS: TableIndex - Table index - * IsLoaded - TRUE if table is loaded, FALSE otherwise - * - * RETURN: None - * - * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. - * - ******************************************************************************/ - -void -AcpiTbSetTableLoadedFlag ( - UINT32 TableIndex, - BOOLEAN IsLoaded) -{ - - (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); - if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) - { - if (IsLoaded) - { - AcpiGbl_RootTableList.Tables[TableIndex].Flags |= - ACPI_TABLE_IS_LOADED; - } - else - { - AcpiGbl_RootTableList.Tables[TableIndex].Flags &= - ~ACPI_TABLE_IS_LOADED; - } - } - - (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + TableDesc->Address = ACPI_PTR_TO_PHYSADDR (NULL); + return_VOID; } |