mirror of
https://github.com/acpica/acpica/
synced 2025-03-14 02:02:52 +03:00
Allow OS override of all ACPI tables.
Previously, the table override mechanism was implemented for the DSDT only. Now, any table in the RSDT/XSDT can be replaced by the host OS. (including the DSDT).
This commit is contained in:
parent
7d19af2188
commit
2d8f95c694
@ -563,10 +563,6 @@ AcpiDbTerminate (
|
||||
void)
|
||||
{
|
||||
|
||||
if (AcpiGbl_DbTablePtr)
|
||||
{
|
||||
AcpiOsFree (AcpiGbl_DbTablePtr);
|
||||
}
|
||||
if (AcpiGbl_DbBuffer)
|
||||
{
|
||||
AcpiOsFree (AcpiGbl_DbBuffer);
|
||||
|
@ -320,7 +320,10 @@ AcpiTbChecksum (
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Install an ACPI table into the global data structure.
|
||||
* DESCRIPTION: Install an ACPI table into the global data structure. The
|
||||
* table override mechanism is implemented here to allow the host
|
||||
* OS to replace any table before it is installed in the root
|
||||
* table array.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@ -331,7 +334,10 @@ AcpiTbInstallTable (
|
||||
char *Signature,
|
||||
UINT32 TableIndex)
|
||||
{
|
||||
ACPI_TABLE_HEADER *Table;
|
||||
ACPI_STATUS Status;
|
||||
ACPI_TABLE_HEADER *TableToInstall;
|
||||
ACPI_TABLE_HEADER *MappedTable;
|
||||
ACPI_TABLE_HEADER *OverrideTable = NULL;
|
||||
|
||||
|
||||
if (!Address)
|
||||
@ -343,43 +349,68 @@ AcpiTbInstallTable (
|
||||
|
||||
/* Map just the table header */
|
||||
|
||||
Table = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
|
||||
if (!Table)
|
||||
MappedTable = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
|
||||
if (!MappedTable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* If a particular signature is expected, signature must match */
|
||||
/* If a particular signature is expected (DSDT/FACS), it must match */
|
||||
|
||||
if (Signature &&
|
||||
!ACPI_COMPARE_NAME (Table->Signature, Signature))
|
||||
!ACPI_COMPARE_NAME (MappedTable->Signature, Signature))
|
||||
{
|
||||
ACPI_ERROR ((AE_INFO, "Invalid signature 0x%X for ACPI table [%s]",
|
||||
*ACPI_CAST_PTR (UINT32, Table->Signature), Signature));
|
||||
ACPI_ERROR ((AE_INFO, "Invalid signature 0x%X for ACPI table, expected [%s]",
|
||||
*ACPI_CAST_PTR (UINT32, MappedTable->Signature), Signature));
|
||||
goto UnmapAndExit;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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)));
|
||||
|
||||
AcpiGbl_RootTableList.Tables[TableIndex].Pointer = OverrideTable;
|
||||
Flags = ACPI_TABLE_ORIGIN_OVERRIDE;
|
||||
Address = ACPI_PTR_TO_PHYSADDR (OverrideTable);
|
||||
|
||||
TableToInstall = OverrideTable;
|
||||
}
|
||||
else
|
||||
{
|
||||
TableToInstall = MappedTable;
|
||||
}
|
||||
|
||||
/* Initialize the table entry */
|
||||
|
||||
AcpiGbl_RootTableList.Tables[TableIndex].Address = Address;
|
||||
AcpiGbl_RootTableList.Tables[TableIndex].Length = Table->Length;
|
||||
AcpiGbl_RootTableList.Tables[TableIndex].Length = TableToInstall->Length;
|
||||
AcpiGbl_RootTableList.Tables[TableIndex].Flags = Flags;
|
||||
|
||||
ACPI_MOVE_32_TO_32 (
|
||||
&(AcpiGbl_RootTableList.Tables[TableIndex].Signature),
|
||||
Table->Signature);
|
||||
TableToInstall->Signature);
|
||||
|
||||
AcpiTbPrintTableHeader (Address, Table);
|
||||
AcpiTbPrintTableHeader (Address, TableToInstall);
|
||||
|
||||
if (TableIndex == ACPI_TABLE_INDEX_DSDT)
|
||||
{
|
||||
/* Global integer width is based upon revision of the DSDT */
|
||||
|
||||
AcpiUtSetIntegerWidth (Table->Revision);
|
||||
AcpiUtSetIntegerWidth (TableToInstall->Revision);
|
||||
}
|
||||
|
||||
UnmapAndExit:
|
||||
AcpiOsUnmapMemory (Table, sizeof (ACPI_TABLE_HEADER));
|
||||
AcpiOsUnmapMemory (MappedTable, sizeof (ACPI_TABLE_HEADER));
|
||||
}
|
||||
|
||||
|
||||
|
@ -534,7 +534,6 @@ AcpiTbLoadNamespace (
|
||||
void)
|
||||
{
|
||||
ACPI_STATUS Status;
|
||||
ACPI_TABLE_HEADER *Table;
|
||||
UINT32 i;
|
||||
|
||||
|
||||
@ -556,30 +555,11 @@ AcpiTbLoadNamespace (
|
||||
goto UnlockAndExit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find DSDT table
|
||||
*/
|
||||
Status = AcpiOsTableOverride (
|
||||
AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer, &Table);
|
||||
if (ACPI_SUCCESS (Status) && Table)
|
||||
{
|
||||
/*
|
||||
* DSDT table has been found
|
||||
*/
|
||||
AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]);
|
||||
AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer = Table;
|
||||
AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Length = Table->Length;
|
||||
AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Flags = ACPI_TABLE_ORIGIN_UNKNOWN;
|
||||
|
||||
ACPI_INFO ((AE_INFO, "Table DSDT replaced by host OS"));
|
||||
AcpiTbPrintTableHeader (0, Table);
|
||||
}
|
||||
/* A valid DSDT is required */
|
||||
|
||||
Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
/* A valid DSDT is required */
|
||||
|
||||
Status = AE_NO_ACPI_TABLES;
|
||||
goto UnlockAndExit;
|
||||
}
|
||||
|
@ -459,7 +459,6 @@ ACPI_EXTERN char *AcpiGbl_DbBuffer;
|
||||
ACPI_EXTERN char *AcpiGbl_DbFilename;
|
||||
ACPI_EXTERN UINT32 AcpiGbl_DbDebugLevel;
|
||||
ACPI_EXTERN UINT32 AcpiGbl_DbConsoleDebugLevel;
|
||||
ACPI_EXTERN ACPI_TABLE_HEADER *AcpiGbl_DbTablePtr;
|
||||
ACPI_EXTERN ACPI_NAMESPACE_NODE *AcpiGbl_DbScopeNode;
|
||||
|
||||
/*
|
||||
|
@ -409,8 +409,9 @@ typedef struct acpi_table_desc
|
||||
#define ACPI_TABLE_ORIGIN_UNKNOWN (0)
|
||||
#define ACPI_TABLE_ORIGIN_MAPPED (1)
|
||||
#define ACPI_TABLE_ORIGIN_ALLOCATED (2)
|
||||
#define ACPI_TABLE_ORIGIN_MASK (3)
|
||||
#define ACPI_TABLE_IS_LOADED (4)
|
||||
#define ACPI_TABLE_ORIGIN_OVERRIDE (4)
|
||||
#define ACPI_TABLE_ORIGIN_MASK (7)
|
||||
#define ACPI_TABLE_IS_LOADED (8)
|
||||
|
||||
|
||||
/*
|
||||
|
@ -140,10 +140,18 @@
|
||||
extern FILE *AcpiGbl_DebugFile;
|
||||
FILE *AcpiGbl_OutputFile;
|
||||
|
||||
|
||||
/* Upcalls to AcpiExec */
|
||||
|
||||
ACPI_PHYSICAL_ADDRESS
|
||||
AeLocalGetRootPointer (
|
||||
void);
|
||||
|
||||
void
|
||||
AeTableOverride (
|
||||
ACPI_TABLE_HEADER *ExistingTable,
|
||||
ACPI_TABLE_HEADER **NewTable);
|
||||
|
||||
typedef void* (*PTHREAD_CALLBACK) (void *);
|
||||
|
||||
/******************************************************************************
|
||||
@ -254,14 +262,7 @@ AcpiOsTableOverride (
|
||||
|
||||
#ifdef ACPI_EXEC_APP
|
||||
|
||||
/* This code exercises the table override mechanism in the core */
|
||||
|
||||
if (ACPI_COMPARE_NAME (ExistingTable->Signature, ACPI_SIG_DSDT))
|
||||
{
|
||||
/* override DSDT with itself */
|
||||
|
||||
*NewTable = AcpiGbl_DbTablePtr;
|
||||
}
|
||||
AeTableOverride (ExistingTable, NewTable);
|
||||
return (AE_OK);
|
||||
#else
|
||||
return AE_NO_ACPI_TABLES;
|
||||
|
@ -158,10 +158,18 @@ typedef struct semaphore_entry
|
||||
SEMAPHORE_ENTRY AcpiGbl_Semaphores[NUM_SEMAPHORES];
|
||||
extern FILE *AcpiGbl_DebugFile;
|
||||
|
||||
/* Upcalls to AcpiExec */
|
||||
|
||||
ACPI_PHYSICAL_ADDRESS
|
||||
AeLocalGetRootPointer (
|
||||
void);
|
||||
|
||||
void
|
||||
AeTableOverride (
|
||||
ACPI_TABLE_HEADER *ExistingTable,
|
||||
ACPI_TABLE_HEADER **NewTable);
|
||||
|
||||
|
||||
FILE *AcpiGbl_OutputFile;
|
||||
UINT64 TimerFrequency;
|
||||
|
||||
@ -450,15 +458,7 @@ AcpiOsTableOverride (
|
||||
#ifndef ACPI_BIN_APP
|
||||
#ifdef ACPI_EXEC_APP
|
||||
|
||||
/* This code exercises the table override mechanism in the core */
|
||||
|
||||
if (ACPI_COMPARE_NAME (ExistingTable->Signature, ACPI_SIG_DSDT))
|
||||
{
|
||||
/* override DSDT with itself */
|
||||
|
||||
*NewTable = AcpiGbl_DbTablePtr;
|
||||
}
|
||||
|
||||
AeTableOverride (ExistingTable, NewTable);
|
||||
#else
|
||||
|
||||
/* Construct a null-terminated string from table signature */
|
||||
|
@ -131,6 +131,20 @@ ACPI_TABLE_RSDP LocalRsdp;
|
||||
/*
|
||||
* Misc ACPI tables to be installed
|
||||
*/
|
||||
|
||||
/* Default DSDT. This will be replaced with the input DSDT */
|
||||
|
||||
unsigned char DsdtCode[] =
|
||||
{
|
||||
0x44,0x53,0x44,0x54,0x24,0x00,0x00,0x00, /* 00000000 "DSDT$..." */
|
||||
0x02,0x6F,0x49,0x6E,0x74,0x65,0x6C,0x00, /* 00000008 ".oIntel." */
|
||||
0x4E,0x75,0x6C,0x6C,0x44,0x53,0x44,0x54, /* 00000010 "NullDSDT" */
|
||||
0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */
|
||||
0x04,0x12,0x08,0x20,
|
||||
};
|
||||
|
||||
/* Several example SSDTs */
|
||||
|
||||
unsigned char Ssdt1Code[] = /* Has method _T98 */
|
||||
{
|
||||
0x53,0x53,0x44,0x54,0x30,0x00,0x00,0x00, /* 00000000 "SSDT0..." */
|
||||
@ -161,6 +175,8 @@ unsigned char Ssdt3Code[] = /* Has method _T97 */
|
||||
0x39,0x37,0x00,0x70,0x0A,0x04,0x60,0xA4, /* 00000028 "97.p..`." */
|
||||
};
|
||||
|
||||
/* Example OEM table */
|
||||
|
||||
unsigned char Oem1Code[] =
|
||||
{
|
||||
0x4F,0x45,0x4D,0x31,0x38,0x00,0x00,0x00, /* 00000000 "OEM18..." */
|
||||
@ -177,6 +193,7 @@ unsigned char Oem1Code[] =
|
||||
* even though the underlying OSD HW access functions don't do
|
||||
* anything.
|
||||
*/
|
||||
ACPI_TABLE_HEADER *DsdtToInstallOverride;
|
||||
ACPI_TABLE_RSDP LocalRSDP;
|
||||
ACPI_TABLE_FADT LocalFADT;
|
||||
ACPI_TABLE_FACS LocalFACS;
|
||||
@ -194,6 +211,33 @@ static ACPI_TABLE_DESC Tables[ACPI_MAX_INIT_TABLES];
|
||||
|
||||
UINT32 SigintCount = 0;
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: AeTableOverride
|
||||
*
|
||||
* DESCRIPTION: Local implementation of AcpiOsTableOverride.
|
||||
*
|
||||
* Exercise the override mechanism
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void
|
||||
AeTableOverride (
|
||||
ACPI_TABLE_HEADER *ExistingTable,
|
||||
ACPI_TABLE_HEADER **NewTable)
|
||||
{
|
||||
|
||||
|
||||
/* This code exercises the table override mechanism in the core */
|
||||
|
||||
if (ACPI_COMPARE_NAME (ExistingTable->Signature, ACPI_SIG_DSDT))
|
||||
{
|
||||
*NewTable = DsdtToInstallOverride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* FUNCTION: AeCtrlCHandler
|
||||
@ -293,7 +337,8 @@ AeBuildLocalTables (
|
||||
{
|
||||
/* The incoming user table is a DSDT */
|
||||
|
||||
DsdtAddress = ACPI_PTR_TO_PHYSADDR (UserTable);
|
||||
DsdtAddress = ACPI_PTR_TO_PHYSADDR (&DsdtCode);
|
||||
DsdtToInstallOverride = UserTable;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -309,6 +354,7 @@ AeBuildLocalTables (
|
||||
|
||||
LocalRSDT->TableOffsetEntry[3] = ACPI_PTR_TO_PHYSADDR (UserTable);
|
||||
DsdtAddress = ACPI_PTR_TO_PHYSADDR (&LocalDSDT);
|
||||
DsdtToInstallOverride = &LocalDSDT;
|
||||
}
|
||||
|
||||
/* Set checksums for both RSDT and RSDP */
|
||||
|
Loading…
x
Reference in New Issue
Block a user