summaryrefslogtreecommitdiff
path: root/source/components/tables
diff options
context:
space:
mode:
Diffstat (limited to 'source/components/tables')
-rw-r--r--source/components/tables/tbdata.c86
-rw-r--r--source/components/tables/tbfadt.c23
-rw-r--r--source/components/tables/tbutils.c96
-rw-r--r--source/components/tables/tbxface.c133
-rw-r--r--source/components/tables/tbxfload.c35
5 files changed, 266 insertions, 107 deletions
diff --git a/source/components/tables/tbdata.c b/source/components/tables/tbdata.c
index 81b3abcfdd7bf..95b5b2672cd27 100644
--- a/source/components/tables/tbdata.c
+++ b/source/components/tables/tbdata.c
@@ -937,9 +937,9 @@ AcpiTbLoadTable (
*
* FUNCTION: AcpiTbInstallAndLoadTable
*
- * PARAMETERS: Table - Pointer to the table
- * Address - Physical address of the table
+ * PARAMETERS: Address - Physical address of the table
* Flags - Allocation flags of the table
+ * Override - Whether override should be performed
* TableIndex - Where table index is returned
*
* RETURN: Status
@@ -950,7 +950,6 @@ AcpiTbLoadTable (
ACPI_STATUS
AcpiTbInstallAndLoadTable (
- ACPI_TABLE_HEADER *Table,
ACPI_PHYSICAL_ADDRESS Address,
UINT8 Flags,
BOOLEAN Override,
@@ -958,10 +957,9 @@ AcpiTbInstallAndLoadTable (
{
ACPI_STATUS Status;
UINT32 i;
- ACPI_OWNER_ID OwnerId;
- ACPI_FUNCTION_TRACE (AcpiLoadTable);
+ ACPI_FUNCTION_TRACE (TbInstallAndLoadTable);
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
@@ -975,48 +973,68 @@ AcpiTbInstallAndLoadTable (
goto UnlockAndExit;
}
- /*
- * Note: Now table is "INSTALLED", it must be validated before
- * using.
- */
- Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
- if (ACPI_FAILURE (Status))
- {
- goto UnlockAndExit;
- }
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ Status = AcpiTbLoadTable (i, AcpiGbl_RootNode);
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+UnlockAndExit:
+ *TableIndex = i;
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
- Status = AcpiNsLoadTable (i, AcpiGbl_RootNode);
+ return_ACPI_STATUS (Status);
+}
- /* Execute any module-level code that was found in the table */
- if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode)
- {
- AcpiNsExecModuleCodeList ();
- }
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbUnloadTable
+ *
+ * PARAMETERS: TableIndex - Table index
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Unload an ACPI table
+ *
+ ******************************************************************************/
- /*
- * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
- * responsible for discovering any new wake GPEs by running _PRW methods
- * that may have been loaded by this table.
- */
- Status = AcpiTbGetOwnerId (i, &OwnerId);
- if (ACPI_SUCCESS (Status))
+ACPI_STATUS
+AcpiTbUnloadTable (
+ UINT32 TableIndex)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_TABLE_HEADER *Table;
+
+
+ ACPI_FUNCTION_TRACE (TbUnloadTable);
+
+
+ /* Ensure the table is still loaded */
+
+ if (!AcpiTbIsTableLoaded (TableIndex))
{
- AcpiEvUpdateGpes (OwnerId);
+ return_ACPI_STATUS (AE_NOT_EXIST);
}
/* Invoke table handler if present */
if (AcpiGbl_TableHandler)
{
- (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
- AcpiGbl_TableHandlerContext);
+ Status = AcpiGetTableByIndex (TableIndex, &Table);
+ if (ACPI_SUCCESS (Status))
+ {
+ (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, Table,
+ AcpiGbl_TableHandlerContext);
+ }
}
- (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
-UnlockAndExit:
- *TableIndex = i;
- (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ /* Delete the portion of the namespace owned by this table */
+
+ Status = AcpiTbDeleteNamespaceByOwner (TableIndex);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ (void) AcpiTbReleaseOwnerId (TableIndex);
+ AcpiTbSetTableLoadedFlag (TableIndex, FALSE);
return_ACPI_STATUS (Status);
}
diff --git a/source/components/tables/tbfadt.c b/source/components/tables/tbfadt.c
index b75b52d9d0b97..1d327dc3113bb 100644
--- a/source/components/tables/tbfadt.c
+++ b/source/components/tables/tbfadt.c
@@ -341,6 +341,8 @@ AcpiTbParseFadt (
{
UINT32 Length;
ACPI_TABLE_HEADER *Table;
+ ACPI_TABLE_DESC *FadtDesc;
+ ACPI_STATUS Status;
/*
@@ -350,14 +352,13 @@ AcpiTbParseFadt (
* Get a local copy of the FADT and convert it to a common format
* Map entire FADT, assumed to be smaller than one page.
*/
- Length = AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex].Length;
-
- Table = AcpiOsMapMemory (
- AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex].Address, Length);
- if (!Table)
+ FadtDesc = &AcpiGbl_RootTableList.Tables[AcpiGbl_FadtIndex];
+ Status = AcpiTbGetTable (FadtDesc, &Table);
+ if (ACPI_FAILURE (Status))
{
return;
}
+ Length = FadtDesc->Length;
/*
* Validate the FADT checksum before we copy the table. Ignore
@@ -371,7 +372,7 @@ AcpiTbParseFadt (
/* All done with the real FADT, unmap it */
- AcpiOsUnmapMemory (Table, Length);
+ AcpiTbPutTable (FadtDesc);
/* Obtain the DSDT and FACS tables via their addresses within the FADT */
@@ -522,19 +523,17 @@ AcpiTbConvertFadt (
/*
- * For ACPI 1.0 FADTs (revision 1), ensure that reserved fields which
+ * For ACPI 1.0 FADTs (revision 1 or 2), ensure that reserved fields which
* should be zero are indeed zero. This will workaround BIOSs that
* inadvertently place values in these fields.
*
* The ACPI 1.0 reserved fields that will be zeroed are the bytes located
* at offset 45, 55, 95, and the word located at offset 109, 110.
*
- * Note: The FADT revision value is unreliable because of BIOS errors.
- * The table length is instead used as the final word on the version.
- *
- * Note: FADT revision 3 is the ACPI 2.0 version of the FADT.
+ * Note: The FADT revision value is unreliable. Only the length can be
+ * trusted.
*/
- if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V3_SIZE)
+ if (AcpiGbl_FADT.Header.Length <= ACPI_FADT_V2_SIZE)
{
AcpiGbl_FADT.PreferredProfile = 0;
AcpiGbl_FADT.PstateControl = 0;
diff --git a/source/components/tables/tbutils.c b/source/components/tables/tbutils.c
index 85b9c3e4c561a..6fc30a69fa388 100644
--- a/source/components/tables/tbutils.c
+++ b/source/components/tables/tbutils.c
@@ -411,3 +411,99 @@ NextTable:
AcpiOsUnmapMemory (Table, Length);
return_ACPI_STATUS (AE_OK);
}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbGetTable
+ *
+ * PARAMETERS: TableDesc - Table descriptor
+ * OutTable - Where the pointer to the table is returned
+ *
+ * RETURN: Status and pointer to the requested table
+ *
+ * DESCRIPTION: Increase a reference to a table descriptor and return the
+ * validated table pointer.
+ * If the table descriptor is an entry of the root table list,
+ * this API must be invoked with ACPI_MTX_TABLES acquired.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiTbGetTable (
+ ACPI_TABLE_DESC *TableDesc,
+ ACPI_TABLE_HEADER **OutTable)
+{
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (AcpiTbGetTable);
+
+
+ if (TableDesc->ValidationCount == 0)
+ {
+ /* Table need to be "VALIDATED" */
+
+ Status = AcpiTbValidateTable (TableDesc);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+ }
+
+ TableDesc->ValidationCount++;
+ if (TableDesc->ValidationCount == 0)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Table %p, Validation count is zero after increment\n",
+ TableDesc));
+ TableDesc->ValidationCount--;
+ return_ACPI_STATUS (AE_LIMIT);
+ }
+
+ *OutTable = TableDesc->Pointer;
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiTbPutTable
+ *
+ * PARAMETERS: TableDesc - Table descriptor
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Decrease a reference to a table descriptor and release the
+ * validated table pointer if no references.
+ * If the table descriptor is an entry of the root table list,
+ * this API must be invoked with ACPI_MTX_TABLES acquired.
+ *
+ ******************************************************************************/
+
+void
+AcpiTbPutTable (
+ ACPI_TABLE_DESC *TableDesc)
+{
+
+ ACPI_FUNCTION_TRACE (AcpiTbPutTable);
+
+
+ if (TableDesc->ValidationCount == 0)
+ {
+ ACPI_WARNING ((AE_INFO,
+ "Table %p, Validation count is zero before decrement\n",
+ TableDesc));
+ return_VOID;
+ }
+ TableDesc->ValidationCount--;
+
+ if (TableDesc->ValidationCount == 0)
+ {
+ /* Table need to be "INVALIDATED" */
+
+ AcpiTbInvalidateTable (TableDesc);
+ }
+
+ return_VOID;
+}
diff --git a/source/components/tables/tbxface.c b/source/components/tables/tbxface.c
index 4c8c065cf3730..9346933cf5274 100644
--- a/source/components/tables/tbxface.c
+++ b/source/components/tables/tbxface.c
@@ -184,6 +184,7 @@ AcpiReallocateRootTable (
void)
{
ACPI_STATUS Status;
+ UINT32 i;
ACPI_FUNCTION_TRACE (AcpiReallocateRootTable);
@@ -198,6 +199,22 @@ AcpiReallocateRootTable (
return_ACPI_STATUS (AE_SUPPORT);
}
+ /*
+ * Ensure OS early boot logic, which is required by some hosts. If the
+ * table state is reported to be wrong, developers should fix the
+ * issue by invoking AcpiPutTable() for the reported table during the
+ * early stage.
+ */
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
+ {
+ if (AcpiGbl_RootTableList.Tables[i].Pointer)
+ {
+ ACPI_ERROR ((AE_INFO,
+ "Table [%4.4s] is not invalidated during early boot stage",
+ AcpiGbl_RootTableList.Tables[i].Signature.Ascii));
+ }
+ }
+
AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE;
Status = AcpiTbResizeRootTableList ();
@@ -307,6 +324,11 @@ ACPI_EXPORT_SYMBOL (AcpiGetTableHeader)
*
* DESCRIPTION: Finds and verifies an ACPI table. Table must be in the
* RSDT/XSDT.
+ * Note that an early stage AcpiGetTable() call must be paired
+ * with an early stage AcpiPutTable() call. otherwise the table
+ * pointer mapped by the early stage mapping implementation may be
+ * erroneously unmapped by the late stage unmapping implementation
+ * in an AcpiPutTable() invoked during the late stage.
*
******************************************************************************/
@@ -318,7 +340,8 @@ AcpiGetTable (
{
UINT32 i;
UINT32 j;
- ACPI_STATUS Status;
+ ACPI_STATUS Status = AE_NOT_FOUND;
+ ACPI_TABLE_DESC *TableDesc;
/* Parameter validation */
@@ -328,12 +351,22 @@ AcpiGetTable (
return (AE_BAD_PARAMETER);
}
+ /*
+ * Note that the following line is required by some OSPMs, they only
+ * check if the returned table is NULL instead of the returned status
+ * to determined if this function is succeeded.
+ */
+ *OutTable = NULL;
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
/* Walk the root table list */
for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
{
- if (!ACPI_COMPARE_NAME (
- &(AcpiGbl_RootTableList.Tables[i].Signature), Signature))
+ TableDesc = &AcpiGbl_RootTableList.Tables[i];
+
+ if (!ACPI_COMPARE_NAME (&TableDesc->Signature, Signature))
{
continue;
}
@@ -343,19 +376,66 @@ AcpiGetTable (
continue;
}
- Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
- if (ACPI_SUCCESS (Status))
+ Status = AcpiTbGetTable (TableDesc, OutTable);
+ break;
+ }
+
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return (Status);
+}
+
+ACPI_EXPORT_SYMBOL (AcpiGetTable)
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPutTable
+ *
+ * PARAMETERS: Table - The pointer to the table
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Release a table returned by AcpiGetTable() and its clones.
+ * Note that it is not safe if this function was invoked after an
+ * uninstallation happened to the original table descriptor.
+ * Currently there is no OSPMs' requirement to handle such
+ * situations.
+ *
+ ******************************************************************************/
+
+void
+AcpiPutTable (
+ ACPI_TABLE_HEADER *Table)
+{
+ UINT32 i;
+ ACPI_TABLE_DESC *TableDesc;
+
+
+ ACPI_FUNCTION_TRACE (AcpiPutTable);
+
+
+ (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
+
+ /* Walk the root table list */
+
+ for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
+ {
+ TableDesc = &AcpiGbl_RootTableList.Tables[i];
+
+ if (TableDesc->Pointer != Table)
{
- *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer;
+ continue;
}
- return (Status);
+ AcpiTbPutTable (TableDesc);
+ break;
}
- return (AE_NOT_FOUND);
+ (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
+ return_VOID;
}
-ACPI_EXPORT_SYMBOL (AcpiGetTable)
+ACPI_EXPORT_SYMBOL (AcpiPutTable)
/*******************************************************************************
@@ -363,7 +443,7 @@ ACPI_EXPORT_SYMBOL (AcpiGetTable)
* FUNCTION: AcpiGetTableByIndex
*
* PARAMETERS: TableIndex - Table index
- * Table - Where the pointer to the table is returned
+ * OutTable - Where the pointer to the table is returned
*
* RETURN: Status and pointer to the requested table
*
@@ -375,7 +455,7 @@ ACPI_EXPORT_SYMBOL (AcpiGetTable)
ACPI_STATUS
AcpiGetTableByIndex (
UINT32 TableIndex,
- ACPI_TABLE_HEADER **Table)
+ ACPI_TABLE_HEADER **OutTable)
{
ACPI_STATUS Status;
@@ -385,37 +465,34 @@ AcpiGetTableByIndex (
/* Parameter validation */
- if (!Table)
+ if (!OutTable)
{
return_ACPI_STATUS (AE_BAD_PARAMETER);
}
+ /*
+ * Note that the following line is required by some OSPMs, they only
+ * check if the returned table is NULL instead of the returned status
+ * to determined if this function is succeeded.
+ */
+ *OutTable = NULL;
+
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
/* Validate index */
if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
{
- (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
- return_ACPI_STATUS (AE_BAD_PARAMETER);
+ Status = AE_BAD_PARAMETER;
+ goto UnlockAndExit;
}
- if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer)
- {
- /* Table is not mapped, map it */
-
- Status = AcpiTbValidateTable (
- &AcpiGbl_RootTableList.Tables[TableIndex]);
- if (ACPI_FAILURE (Status))
- {
- (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
- return_ACPI_STATUS (Status);
- }
- }
+ Status = AcpiTbGetTable (
+ &AcpiGbl_RootTableList.Tables[TableIndex], OutTable);
- *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer;
+UnlockAndExit:
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
- return_ACPI_STATUS (AE_OK);
+ return_ACPI_STATUS (Status);
}
ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex)
diff --git a/source/components/tables/tbxfload.c b/source/components/tables/tbxfload.c
index 43fe397fde568..30c6534a56995 100644
--- a/source/components/tables/tbxfload.c
+++ b/source/components/tables/tbxfload.c
@@ -372,7 +372,7 @@ AcpiLoadTable (
/* Install the table and load it into the namespace */
ACPI_INFO (("Host-directed Dynamic ACPI Table Load:"));
- Status = AcpiTbInstallAndLoadTable (Table, ACPI_PTR_TO_PHYSADDR (Table),
+ Status = AcpiTbInstallAndLoadTable (ACPI_PTR_TO_PHYSADDR (Table),
ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, FALSE, &TableIndex);
return_ACPI_STATUS (Status);
}
@@ -459,39 +459,8 @@ AcpiUnloadParentTable (
break;
}
- /* Ensure the table is actually loaded */
-
(void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
- if (!AcpiTbIsTableLoaded (i))
- {
- Status = AE_NOT_EXIST;
- (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
- break;
- }
-
- /* Invoke table handler if present */
-
- if (AcpiGbl_TableHandler)
- {
- (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD,
- AcpiGbl_RootTableList.Tables[i].Pointer,
- AcpiGbl_TableHandlerContext);
- }
-
- /*
- * Delete all namespace objects owned by this table. Note that
- * these objects can appear anywhere in the namespace by virtue
- * of the AML "Scope" operator. Thus, we need to track ownership
- * by an ID, not simply a position within the hierarchy.
- */
- Status = AcpiTbDeleteNamespaceByOwner (i);
- if (ACPI_FAILURE (Status))
- {
- break;
- }
-
- Status = AcpiTbReleaseOwnerId (i);
- AcpiTbSetTableLoadedFlag (i, FALSE);
+ Status = AcpiTbUnloadTable (i);
(void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
break;
}