diff options
Diffstat (limited to 'source/components/tables')
-rw-r--r-- | source/components/tables/tbdata.c | 816 | ||||
-rw-r--r-- | source/components/tables/tbfadt.c | 4 | ||||
-rw-r--r-- | source/components/tables/tbfind.c | 2 | ||||
-rw-r--r-- | source/components/tables/tbinstal.c | 889 | ||||
-rw-r--r-- | source/components/tables/tbutils.c | 175 | ||||
-rw-r--r-- | source/components/tables/tbxface.c | 6 | ||||
-rw-r--r-- | source/components/tables/tbxfload.c | 92 |
7 files changed, 1225 insertions, 759 deletions
diff --git a/source/components/tables/tbdata.c b/source/components/tables/tbdata.c new file mode 100644 index 0000000000000..549c5551bcb10 --- /dev/null +++ b/source/components/tables/tbdata.c @@ -0,0 +1,816 @@ +/****************************************************************************** + * + * Module Name: tbdata - Table manager data structure functions + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2014, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#define __TBDATA_C__ + +#include "acpi.h" +#include "accommon.h" +#include "acnamesp.h" +#include "actables.h" + +#define _COMPONENT ACPI_TABLES + ACPI_MODULE_NAME ("tbdata") + + +/******************************************************************************* + * + * FUNCTION: AcpiTbInitTableDescriptor + * + * PARAMETERS: TableDesc - Table descriptor + * Address - Physical address of the table + * Flags - Allocation flags of the table + * Table - Pointer to the table + * + * RETURN: None + * + * DESCRIPTION: Initialize a new table descriptor + * + ******************************************************************************/ + +void +AcpiTbInitTableDescriptor ( + ACPI_TABLE_DESC *TableDesc, + ACPI_PHYSICAL_ADDRESS Address, + UINT8 Flags, + ACPI_TABLE_HEADER *Table) +{ + + /* + * Initialize the table descriptor. Set the pointer to NULL, since the + * table is not fully mapped at this time. + */ + ACPI_MEMSET (TableDesc, 0, sizeof (ACPI_TABLE_DESC)); + TableDesc->Address = Address; + TableDesc->Length = Table->Length; + TableDesc->Flags = Flags; + ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbAcquireTable + * + * PARAMETERS: TableDesc - Table descriptor + * TablePtr - Where table is returned + * TableLength - Where table length is returned + * TableFlags - Where table allocation flags are returned + * + * RETURN: Status + * + * DESCRIPTION: Acquire an ACPI table. It can be used for tables not + * maintained in the AcpiGbl_RootTableList. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbAcquireTable ( + ACPI_TABLE_DESC *TableDesc, + ACPI_TABLE_HEADER **TablePtr, + UINT32 *TableLength, + UINT8 *TableFlags) +{ + ACPI_TABLE_HEADER *Table = NULL; + + + switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) + { + case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: + + Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length); + break; + + case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: + case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: + + Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER, TableDesc->Address); + break; + + default: + + break; + } + + /* Table is not valid yet */ + + if (!Table) + { + return (AE_NO_MEMORY); + } + + /* Fill the return values */ + + *TablePtr = Table; + *TableLength = TableDesc->Length; + *TableFlags = TableDesc->Flags; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbReleaseTable + * + * PARAMETERS: Table - Pointer for the table + * TableLength - Length for the table + * TableFlags - Allocation flags for the table + * + * RETURN: None + * + * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable(). + * + ******************************************************************************/ + +void +AcpiTbReleaseTable ( + ACPI_TABLE_HEADER *Table, + UINT32 TableLength, + UINT8 TableFlags) +{ + + switch (TableFlags & ACPI_TABLE_ORIGIN_MASK) + { + case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: + + AcpiOsUnmapMemory (Table, TableLength); + break; + + case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: + case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: + default: + + break; + } +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbAcquireTempTable + * + * PARAMETERS: TableDesc - Table descriptor to be acquired + * Address - Address of the table + * Flags - Allocation flags of the table + * + * RETURN: Status + * + * DESCRIPTION: This function validates the table header to obtain the length + * of a table and fills the table descriptor to make its state as + * "INSTALLED". Such a table descriptor is only used for verified + * installation. + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbAcquireTempTable ( + ACPI_TABLE_DESC *TableDesc, + ACPI_PHYSICAL_ADDRESS Address, + UINT8 Flags) +{ + ACPI_TABLE_HEADER *TableHeader; + + + switch (Flags & ACPI_TABLE_ORIGIN_MASK) + { + case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: + + /* Get the length of the full table from the header */ + + TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); + if (!TableHeader) + { + return (AE_NO_MEMORY); + } + + AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); + AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER)); + return (AE_OK); + + case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: + case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: + + TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Address); + if (!TableHeader) + { + return (AE_NO_MEMORY); + } + + AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader); + return (AE_OK); + + default: + + break; + } + + /* Table is not valid yet */ + + return (AE_NO_MEMORY); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbReleaseTempTable + * + * PARAMETERS: TableDesc - Table descriptor to be released + * + * RETURN: Status + * + * DESCRIPTION: The inverse of AcpiTbAcquireTempTable(). + * + *****************************************************************************/ + +void +AcpiTbReleaseTempTable ( + ACPI_TABLE_DESC *TableDesc) +{ + + /* + * Note that the .Address is maintained by the callers of + * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable() + * where .Address will be freed. + */ + AcpiTbInvalidateTable (TableDesc); +} + + +/****************************************************************************** + * + * FUNCTION: AcpiTbValidateTable + * + * PARAMETERS: TableDesc - Table descriptor + * + * RETURN: Status + * + * DESCRIPTION: This function is called to validate the table, the returned + * table descriptor is in "VALIDATED" state. + * + *****************************************************************************/ + +ACPI_STATUS +AcpiTbValidateTable ( + ACPI_TABLE_DESC *TableDesc) +{ + ACPI_STATUS Status = AE_OK; + + + ACPI_FUNCTION_TRACE (TbValidateTable); + + + /* Validate the table if necessary */ + + if (!TableDesc->Pointer) + { + Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer, + &TableDesc->Length, &TableDesc->Flags); + if (!TableDesc->Pointer) + { + Status = AE_NO_MEMORY; + } + } + + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbInvalidateTable + * + * PARAMETERS: TableDesc - Table descriptor + * + * RETURN: None + * + * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of + * AcpiTbValidateTable(). + * + ******************************************************************************/ + +void +AcpiTbInvalidateTable ( + ACPI_TABLE_DESC *TableDesc) +{ + + ACPI_FUNCTION_TRACE (TbInvalidateTable); + + + /* Table must be validated */ + + if (!TableDesc->Pointer) + { + return_VOID; + } + + AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length, + TableDesc->Flags); + TableDesc->Pointer = NULL; + + return_VOID; +} + + +/****************************************************************************** + * + * FUNCTION: AcpiTbVerifyTable + * + * PARAMETERS: TableDesc - Table descriptor + * Signature - Table signature to verify + * + * RETURN: Status + * + * DESCRIPTION: This function is called to validate and verify the table, the + * returned table descriptor is in "VALIDATED" state. + * + *****************************************************************************/ + +ACPI_STATUS +AcpiTbVerifyTable ( + ACPI_TABLE_DESC *TableDesc, + char *Signature) +{ + ACPI_STATUS Status = AE_OK; + + + ACPI_FUNCTION_TRACE (TbVerifyTable); + + + /* Validate the table */ + + Status = AcpiTbValidateTable (TableDesc); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* If a particular signature is expected (DSDT/FACS), it must match */ + + if (Signature && + !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature)) + { + ACPI_BIOS_ERROR ((AE_INFO, + "Invalid signature 0x%X for ACPI table, expected [%s]", + TableDesc->Signature.Integer, Signature)); + Status = AE_BAD_SIGNATURE; + goto InvalidateAndExit; + } + + /* Verify the checksum */ + + Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); + if (ACPI_FAILURE (Status)) + { + ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY, + "%4.4s " ACPI_PRINTF_UINT + " Attempted table install failed", + AcpiUtValidAcpiName (TableDesc->Signature.Ascii) ? + TableDesc->Signature.Ascii : "????", + ACPI_FORMAT_TO_UINT (TableDesc->Address))); + goto InvalidateAndExit; + } + + return_ACPI_STATUS (AE_OK); + +InvalidateAndExit: + AcpiTbInvalidateTable (TableDesc); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbResizeRootTableList + * + * PARAMETERS: None + * + * RETURN: Status + * + * DESCRIPTION: Expand the size of global table array + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbResizeRootTableList ( + void) +{ + ACPI_TABLE_DESC *Tables; + UINT32 TableCount; + + + ACPI_FUNCTION_TRACE (TbResizeRootTableList); + + + /* AllowResize flag is a parameter to AcpiInitializeTables */ + + if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) + { + ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); + return_ACPI_STATUS (AE_SUPPORT); + } + + /* Increase the Table Array size */ + + if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) + { + TableCount = AcpiGbl_RootTableList.MaxTableCount; + } + else + { + TableCount = AcpiGbl_RootTableList.CurrentTableCount; + } + + Tables = ACPI_ALLOCATE_ZEROED ( + ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) * + sizeof (ACPI_TABLE_DESC)); + if (!Tables) + { + ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); + return_ACPI_STATUS (AE_NO_MEMORY); + } + + /* Copy and free the previous table array */ + + if (AcpiGbl_RootTableList.Tables) + { + ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, + (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC)); + + if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) + { + ACPI_FREE (AcpiGbl_RootTableList.Tables); + } + } + + 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: AcpiTbGetNextRootIndex + * + * PARAMETERS: TableIndex - Where table index is returned + * + * RETURN: Status and table index. + * + * DESCRIPTION: Allocate a new ACPI table entry to the global table list + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbGetNextRootIndex ( + UINT32 *TableIndex) +{ + ACPI_STATUS Status; + + + /* Ensure that there is room for the table in the Root Table List */ + + if (AcpiGbl_RootTableList.CurrentTableCount >= + AcpiGbl_RootTableList.MaxTableCount) + { + Status = AcpiTbResizeRootTableList(); + if (ACPI_FAILURE (Status)) + { + return (Status); + } + } + + *TableIndex = AcpiGbl_RootTableList.CurrentTableCount; + AcpiGbl_RootTableList.CurrentTableCount++; + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbTerminate + * + * PARAMETERS: None + * + * RETURN: None + * + * DESCRIPTION: Delete all internal ACPI tables + * + ******************************************************************************/ + +void +AcpiTbTerminate ( + void) +{ + UINT32 i; + + + ACPI_FUNCTION_TRACE (TbTerminate); + + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + + /* Delete the individual tables */ + + for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) + { + AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]); + } + + /* + * 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) + { + ACPI_FREE (AcpiGbl_RootTableList.Tables); + } + + 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; +} + + +/******************************************************************************* + * + * 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); + + + Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) + { + /* The table index does not exist */ + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return_ACPI_STATUS (AE_NOT_EXIST); + } + + /* Get the owner ID for this table, used to delete namespace nodes */ + + OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + + /* + * 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. + */ + (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); + Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); + + AcpiNsDeleteNamespaceByOwner (OwnerId); + if (ACPI_FAILURE (Status)) + { + return_ACPI_STATUS (Status); + } + + AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); + + Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbAllocateOwnerId + * + * PARAMETERS: TableIndex - Table index + * + * RETURN: Status + * + * DESCRIPTION: Allocates OwnerId in TableDesc + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbAllocateOwnerId ( + UINT32 TableIndex) +{ + ACPI_STATUS Status = AE_BAD_PARAMETER; + + + ACPI_FUNCTION_TRACE (TbAllocateOwnerId); + + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + { + Status = AcpiUtAllocateOwnerId ( + &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); + } + + (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; + } + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbGetOwnerId + * + * PARAMETERS: TableIndex - Table index + * OwnerId - Where the table OwnerId is returned + * + * RETURN: Status + * + * DESCRIPTION: returns OwnerId for the ACPI table + * + ******************************************************************************/ + +ACPI_STATUS +AcpiTbGetOwnerId ( + UINT32 TableIndex, + ACPI_OWNER_ID *OwnerId) +{ + ACPI_STATUS Status = AE_BAD_PARAMETER; + + + ACPI_FUNCTION_TRACE (TbGetOwnerId); + + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + { + *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; + Status = AE_OK; + } + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + return_ACPI_STATUS (Status); +} + + +/******************************************************************************* + * + * FUNCTION: AcpiTbIsTableLoaded + * + * PARAMETERS: TableIndex - Index into the root table + * + * RETURN: Table Loaded Flag + * + ******************************************************************************/ + +BOOLEAN +AcpiTbIsTableLoaded ( + UINT32 TableIndex) +{ + BOOLEAN IsLoaded = FALSE; + + + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) + { + IsLoaded = (BOOLEAN) + (AcpiGbl_RootTableList.Tables[TableIndex].Flags & + ACPI_TABLE_IS_LOADED); + } + + (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); +} diff --git a/source/components/tables/tbfadt.c b/source/components/tables/tbfadt.c index 9010825883feb..789161dfc765b 100644 --- a/source/components/tables/tbfadt.c +++ b/source/components/tables/tbfadt.c @@ -365,14 +365,14 @@ AcpiTbParseFadt ( /* Obtain the DSDT and FACS tables via their addresses within the FADT */ - AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt, + AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XDsdt, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT); /* If Hardware Reduced flag is set, there is no FACS */ if (!AcpiGbl_ReducedHardware) { - AcpiTbInstallTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs, + AcpiTbInstallFixedTable ((ACPI_PHYSICAL_ADDRESS) AcpiGbl_FADT.XFacs, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS); } } diff --git a/source/components/tables/tbfind.c b/source/components/tables/tbfind.c index 8940437046bfb..bbd8523e40595 100644 --- a/source/components/tables/tbfind.c +++ b/source/components/tables/tbfind.c @@ -108,7 +108,7 @@ AcpiTbFindTable ( { /* Table is not currently mapped, map it */ - Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); + Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); 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; } diff --git a/source/components/tables/tbutils.c b/source/components/tables/tbutils.c index a9c2d138cd6a6..fc580f6b0e1fc 100644 --- a/source/components/tables/tbutils.c +++ b/source/components/tables/tbutils.c @@ -197,9 +197,12 @@ AcpiTbCopyDsdt ( } ACPI_MEMCPY (NewTable, TableDesc->Pointer, TableDesc->Length); - AcpiTbDeleteTable (TableDesc); - TableDesc->Pointer = NewTable; - TableDesc->Flags = ACPI_TABLE_ORIGIN_ALLOCATED; + AcpiTbUninstallTable (TableDesc); + + AcpiTbInitTableDescriptor ( + &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT], + ACPI_PTR_TO_PHYSADDR (NewTable), ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL, + NewTable); ACPI_INFO ((AE_INFO, "Forced DSDT copy: length 0x%05X copied locally, original unmapped", @@ -211,125 +214,6 @@ AcpiTbCopyDsdt ( /******************************************************************************* * - * FUNCTION: AcpiTbInstallTable - * - * PARAMETERS: Address - Physical address of DSDT or FACS - * Signature - Table signature, NULL if no need to - * match - * TableIndex - Index into root table array - * - * RETURN: None - * - * 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. - * - ******************************************************************************/ - -void -AcpiTbInstallTable ( - ACPI_PHYSICAL_ADDRESS Address, - char *Signature, - UINT32 TableIndex) -{ - ACPI_TABLE_HEADER *Table; - ACPI_TABLE_HEADER *FinalTable; - ACPI_TABLE_DESC *TableDesc; - - - if (!Address) - { - ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]", - Signature)); - return; - } - - /* Map just the table header */ - - Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER)); - if (!Table) - { - ACPI_ERROR ((AE_INFO, "Could not map memory for table [%s] at %p", - Signature, ACPI_CAST_PTR (void, Address))); - return; - } - - /* If a particular signature is expected (DSDT/FACS), it must match */ - - if (Signature && - !ACPI_COMPARE_NAME (Table->Signature, Signature)) - { - ACPI_BIOS_ERROR ((AE_INFO, - "Invalid signature 0x%X for ACPI table, expected [%s]", - *ACPI_CAST_PTR (UINT32, Table->Signature), Signature)); - goto UnmapAndExit; - } - - /* - * Initialize the table entry. Set the pointer to NULL, since the - * table is not fully mapped at this time. - */ - TableDesc = &AcpiGbl_RootTableList.Tables[TableIndex]; - - TableDesc->Address = Address; - TableDesc->Pointer = NULL; - TableDesc->Length = Table->Length; - TableDesc->Flags = ACPI_TABLE_ORIGIN_MAPPED; - ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature); - - /* - * ACPI Table Override: - * - * 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. - * - * NOTE: If the table is overridden, then FinalTable will contain a - * mapped pointer to the full new table. If the table is not overridden, - * or if there has been a physical override, then the table will be - * fully mapped later (in verify table). In any case, we must - * unmap the header that was mapped above. - */ - FinalTable = AcpiTbTableOverride (Table, TableDesc); - if (!FinalTable) - { - FinalTable = Table; /* There was no override */ - } - - AcpiTbPrintTableHeader (TableDesc->Address, FinalTable); - - /* Set the global integer width (based upon revision of the DSDT) */ - - if (TableIndex == ACPI_TABLE_INDEX_DSDT) - { - AcpiUtSetIntegerWidth (FinalTable->Revision); - } - - /* - * If we have a physical override during this early loading of the ACPI - * tables, unmap the table for now. It will be mapped again later when - * it is actually used. This supports very early loading of ACPI tables, - * before virtual memory is fully initialized and running within the - * host OS. Note: A logical override has the ACPI_TABLE_ORIGIN_OVERRIDE - * flag set and will not be deleted below. - */ - if (FinalTable != Table) - { - AcpiTbDeleteTable (TableDesc); - } - - -UnmapAndExit: - - /* Always unmap the table header that we mapped above */ - - AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER)); -} - - -/******************************************************************************* - * * FUNCTION: AcpiTbGetRootTableEntry * * PARAMETERS: TableEntry - Pointer to the RSDT/XSDT table entry @@ -506,6 +390,7 @@ AcpiTbParseRootTable ( UINT32 Length; UINT8 *TableEntry; ACPI_STATUS Status; + UINT32 TableIndex; ACPI_FUNCTION_TRACE (TbParseRootTable); @@ -625,28 +510,20 @@ AcpiTbParseRootTable ( for (i = 0; i < TableCount; i++) { - if (AcpiGbl_RootTableList.CurrentTableCount >= - AcpiGbl_RootTableList.MaxTableCount) - { - /* There is no more room in the root table array, attempt resize */ - - Status = AcpiTbResizeRootTableList (); - if (ACPI_FAILURE (Status)) - { - ACPI_WARNING ((AE_INFO, "Truncating %u table entries!", - (unsigned) (TableCount - - (AcpiGbl_RootTableList.CurrentTableCount - 2)))); - break; - } - } - /* Get the table physical address (32-bit for RSDT, 64-bit for XSDT) */ - AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount].Address = - AcpiTbGetRootTableEntry (TableEntry, TableEntrySize); + Status = AcpiTbInstallStandardTable ( + AcpiTbGetRootTableEntry (TableEntry, TableEntrySize), + ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, FALSE, TRUE, &TableIndex); + + if (ACPI_SUCCESS (Status) && + ACPI_COMPARE_NAME (&AcpiGbl_RootTableList.Tables[TableIndex].Signature, + ACPI_SIG_FADT)) + { + AcpiTbParseFadt (TableIndex); + } TableEntry += TableEntrySize; - AcpiGbl_RootTableList.CurrentTableCount++; } /* @@ -655,23 +532,5 @@ AcpiTbParseRootTable ( */ AcpiOsUnmapMemory (Table, Length); - /* - * Complete the initialization of the root table array by examining - * the header of each table - */ - for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; i++) - { - AcpiTbInstallTable (AcpiGbl_RootTableList.Tables[i].Address, - NULL, i); - - /* Special case for FADT - validate it then get the DSDT and FACS */ - - if (ACPI_COMPARE_NAME ( - &AcpiGbl_RootTableList.Tables[i].Signature, ACPI_SIG_FADT)) - { - AcpiTbParseFadt (i); - } - } - return_ACPI_STATUS (AE_OK); } diff --git a/source/components/tables/tbxface.c b/source/components/tables/tbxface.c index dc6374bb091e5..26ee44bd9ed4f 100644 --- a/source/components/tables/tbxface.c +++ b/source/components/tables/tbxface.c @@ -262,7 +262,7 @@ AcpiGetTableHeader ( { if ((AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_ORIGIN_MASK) == - ACPI_TABLE_ORIGIN_MAPPED) + ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL) { Header = AcpiOsMapMemory ( AcpiGbl_RootTableList.Tables[i].Address, @@ -345,7 +345,7 @@ AcpiGetTable ( continue; } - Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); + Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]); if (ACPI_SUCCESS (Status)) { *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer; @@ -406,7 +406,7 @@ AcpiGetTableByIndex ( { /* Table is not mapped, map it */ - Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[TableIndex]); + Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]); if (ACPI_FAILURE (Status)) { (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); diff --git a/source/components/tables/tbxfload.c b/source/components/tables/tbxfload.c index f39c2c679796e..f28aa091bfc04 100644 --- a/source/components/tables/tbxfload.c +++ b/source/components/tables/tbxfload.c @@ -131,7 +131,7 @@ AcpiTbLoadNamespace ( !ACPI_COMPARE_NAME ( &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature), ACPI_SIG_DSDT) || - ACPI_FAILURE (AcpiTbVerifyTable ( + ACPI_FAILURE (AcpiTbValidateTable ( &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]))) { Status = AE_NO_ACPI_TABLES; @@ -142,7 +142,7 @@ AcpiTbLoadNamespace ( * Save the DSDT pointer for simple access. This is the mapped memory * address. We must take care here because the address of the .Tables * array can change dynamically as tables are loaded at run-time. Note: - * .Pointer field is not validated until after call to AcpiTbVerifyTable. + * .Pointer field is not validated until after call to AcpiTbValidateTable. */ AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer; @@ -187,24 +187,12 @@ AcpiTbLoadNamespace ( ACPI_SIG_SSDT) && !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature), ACPI_SIG_PSDT)) || - ACPI_FAILURE (AcpiTbVerifyTable ( + ACPI_FAILURE (AcpiTbValidateTable ( &AcpiGbl_RootTableList.Tables[i]))) { continue; } - /* - * Optionally do not load any SSDTs from the RSDT/XSDT. This can - * be useful for debugging ACPI problems on some machines. - */ - if (AcpiGbl_DisableSsdtTableLoad) - { - ACPI_INFO ((AE_INFO, "Ignoring %4.4s at %p", - AcpiGbl_RootTableList.Tables[i].Signature.Ascii, - ACPI_CAST_PTR (void, AcpiGbl_RootTableList.Tables[i].Address))); - continue; - } - /* Ignore errors while loading tables, get as many as possible */ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); @@ -222,6 +210,53 @@ UnlockAndExit: /******************************************************************************* * + * FUNCTION: AcpiInstallTable + * + * PARAMETERS: Address - Address of the ACPI table to be installed. + * Physical - Whether the address is a physical table + * address or not + * + * RETURN: Status + * + * DESCRIPTION: Dynamically install an ACPI table. + * Note: This function should only be invoked after + * AcpiInitializeTables() and before AcpiLoadTables(). + * + ******************************************************************************/ + +ACPI_STATUS +AcpiInstallTable ( + ACPI_PHYSICAL_ADDRESS Address, + BOOLEAN Physical) +{ + ACPI_STATUS Status; + UINT8 Flags; + UINT32 TableIndex; + + + ACPI_FUNCTION_TRACE (AcpiInstallTable); + + + if (Physical) + { + Flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL; + } + else + { + Flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL; + } + + Status = AcpiTbInstallStandardTable (Address, Flags, + FALSE, FALSE, &TableIndex); + + return_ACPI_STATUS (Status); +} + +ACPI_EXPORT_SYMBOL_INIT (AcpiInstallTable) + + +/******************************************************************************* + * * FUNCTION: AcpiLoadTable * * PARAMETERS: Table - Pointer to a buffer containing the ACPI @@ -242,7 +277,6 @@ AcpiLoadTable ( ACPI_TABLE_HEADER *Table) { ACPI_STATUS Status; - ACPI_TABLE_DESC TableDesc; UINT32 TableIndex; @@ -256,14 +290,6 @@ AcpiLoadTable ( return_ACPI_STATUS (AE_BAD_PARAMETER); } - /* Init local table descriptor */ - - ACPI_MEMSET (&TableDesc, 0, sizeof (ACPI_TABLE_DESC)); - TableDesc.Address = ACPI_PTR_TO_PHYSADDR (Table); - TableDesc.Pointer = Table; - TableDesc.Length = Table->Length; - TableDesc.Flags = ACPI_TABLE_ORIGIN_UNKNOWN; - /* Must acquire the interpreter lock during this operation */ Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); @@ -275,7 +301,23 @@ AcpiLoadTable ( /* Install the table and load it into the namespace */ ACPI_INFO ((AE_INFO, "Host-directed Dynamic ACPI Table Load:")); - Status = AcpiTbAddTable (&TableDesc, &TableIndex); + (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); + + Status = AcpiTbInstallStandardTable (ACPI_PTR_TO_PHYSADDR (Table), + ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, TRUE, FALSE, + &TableIndex); + + (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); + if (ACPI_FAILURE (Status)) + { + goto UnlockAndExit; + } + + /* + * Note: Now table is "INSTALLED", it must be validated before + * using. + */ + Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[TableIndex]); if (ACPI_FAILURE (Status)) { goto UnlockAndExit; |