Add AcpiOsPhysicalTableOverride interface.

This interface allows the host to override a table via a physical
address, instead of the logical address required by
AcpiOsTableOverride. This simplifies the host implementation.
Initial implementation by Thomas Renninger. ACPICA implementation
creates a single function for table overrides that attempts
both a logical and a physical override.
This commit is contained in:
Robert Moore 2012-02-09 12:29:19 -08:00
parent f7502f84f2
commit cca073748b
6 changed files with 174 additions and 61 deletions

View File

@ -200,7 +200,6 @@ AcpiTbAddTable (
{
UINT32 i;
ACPI_STATUS Status = AE_OK;
ACPI_TABLE_HEADER *OverrideTable = NULL;
ACPI_FUNCTION_TRACE (TbAddTable);
@ -315,25 +314,7 @@ AcpiTbAddTable (
* ACPI Table Override:
* Allow the host to override dynamically loaded tables.
*/
Status = AcpiOsTableOverride (TableDesc->Pointer, &OverrideTable);
if (ACPI_SUCCESS (Status) && OverrideTable)
{
ACPI_INFO ((AE_INFO,
"%4.4s @ 0x%p Table override, replaced with:",
TableDesc->Pointer->Signature,
ACPI_CAST_PTR (void, TableDesc->Address)));
/* We can delete the table that was passed as a parameter */
AcpiTbDeleteTable (TableDesc);
/* Setup descriptor for the new table */
TableDesc->Address = ACPI_PTR_TO_PHYSADDR (OverrideTable);
TableDesc->Pointer = OverrideTable;
TableDesc->Length = OverrideTable->Length;
TableDesc->Flags = ACPI_TABLE_ORIGIN_OVERRIDE;
}
AcpiTbTableOverride (TableDesc);
/* Add the table to the global root table list */
@ -353,6 +334,91 @@ Release:
}
/*******************************************************************************
*
* FUNCTION: AcpiTbTableOverride
*
* PARAMETERS: TableDesc - Table descriptor initialized for the
* original table.
*
* RETURN: If overridden, installs new table within the input table
* descriptor.
*
* DESCRIPTION: Attempt table override by calling the OSL override functions.
*
******************************************************************************/
void
AcpiTbTableOverride (
ACPI_TABLE_DESC *TableDesc)
{
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) */
Status = AcpiOsTableOverride (TableDesc->Pointer, &NewTable);
if (ACPI_SUCCESS (Status) && NewTable)
{
NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable);
NewTableLength = NewTable->Length;
NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE;
OverrideType = "Logical";
goto FinishOverride;
}
/* (2) Attempt physical override (returns a physical address) */
Status = AcpiOsPhysicalTableOverride (TableDesc->Pointer,
&NewAddress, &NewTableLength);
if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength)
{
/* Map memory for the new table */
NewTable = AcpiOsMapMemory (NewAddress, NewTableLength);
if (!NewTable)
{
ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
"%4.4s %p Attempted physical table override failed",
TableDesc->Pointer->Signature,
ACPI_CAST_PTR (void, TableDesc->Address)));
return;
}
OverrideType = "Physical";
NewFlags = ACPI_TABLE_ORIGIN_MAPPED;
goto FinishOverride;
}
return; /* There was no override */
FinishOverride:
ACPI_INFO ((AE_INFO,
"%4.4s %p %s table override, new table: %p",
TableDesc->Pointer->Signature,
ACPI_CAST_PTR (void, TableDesc->Address),
OverrideType, NewTable));
/* We can now unmap/delete the original table */
AcpiTbDeleteTable (TableDesc);
/* Setup descriptor for the new table */
TableDesc->Address = NewAddress;
TableDesc->Pointer = NewTable;
TableDesc->Length = NewTableLength;
TableDesc->Flags = NewFlags;
}
/*******************************************************************************
*
* FUNCTION: AcpiTbResizeRootTableList

View File

@ -122,6 +122,7 @@
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbutils")
/* Local prototypes */
static void
@ -497,7 +498,7 @@ AcpiTbCopyDsdt (
* RETURN: None
*
* DESCRIPTION: Install an ACPI table into the global data structure. The
* table override mechanism is implemented here to allow the host
* table override mechanism is called to allow the host
* OS to replace any table before it is installed in the root
* table array.
*
@ -509,11 +510,7 @@ AcpiTbInstallTable (
char *Signature,
UINT32 TableIndex)
{
UINT8 Flags;
ACPI_STATUS Status;
ACPI_TABLE_HEADER *TableToInstall;
ACPI_TABLE_HEADER *MappedTable;
ACPI_TABLE_HEADER *OverrideTable = NULL;
ACPI_TABLE_HEADER *Table;
if (!Address)
@ -525,8 +522,8 @@ AcpiTbInstallTable (
/* Map just the table header */
MappedTable = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
if (!MappedTable)
Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
if (!Table)
{
return;
}
@ -534,14 +531,25 @@ AcpiTbInstallTable (
/* If a particular signature is expected (DSDT/FACS), it must match */
if (Signature &&
!ACPI_COMPARE_NAME (MappedTable->Signature, Signature))
!ACPI_COMPARE_NAME (Table->Signature, Signature))
{
ACPI_ERROR ((AE_INFO,
"Invalid signature 0x%X for ACPI table, expected [%s]",
*ACPI_CAST_PTR (UINT32, MappedTable->Signature), Signature));
*ACPI_CAST_PTR (UINT32, Table->Signature), Signature));
goto UnmapAndExit;
}
/* Initialize the table entry */
AcpiGbl_RootTableList.Tables[TableIndex].Address = Address;
AcpiGbl_RootTableList.Tables[TableIndex].Pointer = Table;
AcpiGbl_RootTableList.Tables[TableIndex].Length = Table->Length;
AcpiGbl_RootTableList.Tables[TableIndex].Flags = ACPI_TABLE_ORIGIN_MAPPED;
ACPI_MOVE_32_TO_32 (
&(AcpiGbl_RootTableList.Tables[TableIndex].Signature),
Table->Signature);
/*
* ACPI Table Override:
*
@ -549,46 +557,21 @@ AcpiTbInstallTable (
* one if desired. Any table within the RSDT/XSDT can be replaced,
* including the DSDT which is pointed to by the FADT.
*/
Status = AcpiOsTableOverride (MappedTable, &OverrideTable);
if (ACPI_SUCCESS (Status) && OverrideTable)
{
ACPI_INFO ((AE_INFO,
"%4.4s @ 0x%p Table override, replaced with:",
MappedTable->Signature, ACPI_CAST_PTR (void, Address)));
AcpiTbTableOverride (&AcpiGbl_RootTableList.Tables[TableIndex]);
AcpiGbl_RootTableList.Tables[TableIndex].Pointer = OverrideTable;
Address = ACPI_PTR_TO_PHYSADDR (OverrideTable);
TableToInstall = OverrideTable;
Flags = ACPI_TABLE_ORIGIN_OVERRIDE;
}
else
{
TableToInstall = MappedTable;
Flags = ACPI_TABLE_ORIGIN_MAPPED;
}
/* Initialize the table entry */
AcpiGbl_RootTableList.Tables[TableIndex].Address = Address;
AcpiGbl_RootTableList.Tables[TableIndex].Length = TableToInstall->Length;
AcpiGbl_RootTableList.Tables[TableIndex].Flags = Flags;
ACPI_MOVE_32_TO_32 (
&(AcpiGbl_RootTableList.Tables[TableIndex].Signature),
TableToInstall->Signature);
AcpiTbPrintTableHeader (Address, TableToInstall);
Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer;
AcpiTbPrintTableHeader (AcpiGbl_RootTableList.Tables[TableIndex].Address,
Table);
if (TableIndex == ACPI_TABLE_INDEX_DSDT)
{
/* Global integer width is based upon revision of the DSDT */
AcpiUtSetIntegerWidth (TableToInstall->Revision);
AcpiUtSetIntegerWidth (Table->Revision);
}
UnmapAndExit:
AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER));
AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
}

View File

@ -185,6 +185,12 @@ AcpiOsTableOverride (
ACPI_TABLE_HEADER *ExistingTable,
ACPI_TABLE_HEADER **NewTable);
ACPI_STATUS
AcpiOsPhysicalTableOverride (
ACPI_TABLE_HEADER *ExistingTable,
ACPI_PHYSICAL_ADDRESS *NewAddress,
UINT32 *NewTableLength);
/*
* Spinlock primitives

View File

@ -156,6 +156,10 @@ ACPI_STATUS
AcpiTbVerifyTable (
ACPI_TABLE_DESC *TableDesc);
void
AcpiTbTableOverride (
ACPI_TABLE_DESC *TableDesc);
ACPI_STATUS
AcpiTbAddTable (
ACPI_TABLE_DESC *TableDesc,

View File

@ -284,6 +284,33 @@ AcpiOsTableOverride (
}
/******************************************************************************
*
* FUNCTION: AcpiOsPhysicalTableOverride
*
* PARAMETERS: ExistingTable - Header of current table (probably firmware)
* NewAddress - Where new table address is returned
* (Physical address)
* NewTableLength - Where new table length is returned
*
* RETURN: Status, address/length of new table. Null pointer returned
* if no table is available to override.
*
* DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
*
*****************************************************************************/
ACPI_STATUS
AcpiOsPhysicalTableOverride (
ACPI_TABLE_HEADER *ExistingTable,
ACPI_PHYSICAL_ADDRESS *NewAddress,
UINT32 *NewTableLength)
{
return (AE_SUPPORT);
}
/******************************************************************************
*
* FUNCTION: AcpiOsRedirectOutput

View File

@ -359,6 +359,33 @@ AcpiOsTableOverride (
}
/******************************************************************************
*
* FUNCTION: AcpiOsPhysicalTableOverride
*
* PARAMETERS: ExistingTable - Header of current table (probably firmware)
* NewAddress - Where new table address is returned
* (Physical address)
* NewTableLength - Where new table length is returned
*
* RETURN: Status, address/length of new table. Null pointer returned
* if no table is available to override.
*
* DESCRIPTION: Returns AE_SUPPORT, function not used in user space.
*
*****************************************************************************/
ACPI_STATUS
AcpiOsPhysicalTableOverride (
ACPI_TABLE_HEADER *ExistingTable,
ACPI_PHYSICAL_ADDRESS *NewAddress,
UINT32 *NewTableLength)
{
return (AE_SUPPORT);
}
/******************************************************************************
*
* FUNCTION: AcpiOsGetTimer