Skip to content

Commit dd8c272

Browse files
GeorgeLiao012mergify[bot]
authored andcommitted
MdeModulePkg/AcpiTableDxe: Add function for extract ACPI table from HOB.
1. Got RSDP table which installed during the FSP phase from Hob, then pass it to the DXE AcpiTableInstance. 2. Got XSDT from RSDP and extract necessary data from XSDT, according to the old XSDT to Initialize a new XSDT. 3. Re-install ACPI table from old XSDT to the new XSDT. a. If Hob has DSDT table then re-install DSDT table in the new XSDT. If not, then skip it. b. If Hob has FACS table then re-install FACS table in the new XSDT. If not, then skip it. Signed-off-by: George Liao <george.liao@intel.com>
1 parent 225bf12 commit dd8c272

File tree

1 file changed

+165
-45
lines changed

1 file changed

+165
-45
lines changed

MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c

Lines changed: 165 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1968,17 +1968,27 @@ InstallAcpiTableFromAcpiSiliconHob (
19681968
EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *SiAcpiHobRsdp;
19691969
EFI_ACPI_DESCRIPTION_HEADER *SiCommonAcpiTable;
19701970
EFI_STATUS Status;
1971-
UINT8 *TempBuffer;
19721971
UINTN NumOfTblEntries;
1972+
EFI_ACPI_TABLE_VERSION Version;
1973+
UINT64 SocTablePtr;
1974+
EFI_ACPI_DESCRIPTION_HEADER *SocEntryTable;
1975+
UINTN Index;
1976+
UINTN TableKey;
1977+
VOID *NeedToInstallTable;
1978+
UINT8 *Buffer;
1979+
EFI_PHYSICAL_ADDRESS PageAddress;
1980+
UINTN TotalSocTablesize;
19731981

1974-
DEBUG ((DEBUG_INFO, "InstallAcpiTableFromAcpiSiliconHob\n"));
1982+
DEBUG ((DEBUG_INFO, "InstallAcpiTableFromAcpiSiliconHob - Start\n"));
19751983
//
19761984
// Initial variable.
19771985
//
19781986
SiAcpiHobRsdp = NULL;
19791987
SiCommonAcpiTable = NULL;
19801988
AcpiSiliconHob = GET_GUID_HOB_DATA (GuidHob);
19811989
Status = EFI_SUCCESS;
1990+
Version = PcdGet32 (PcdAcpiExposedTableVersions);
1991+
TableKey = 0;
19821992
//
19831993
// Got RSDP table from ACPI Silicon Hob.
19841994
//
@@ -1988,63 +1998,173 @@ InstallAcpiTableFromAcpiSiliconHob (
19881998
return EFI_NOT_FOUND;
19891999
}
19902000

1991-
DEBUG ((DEBUG_INFO, "Silicon ACPI RSDP address : 0x%lx\n", SiAcpiHobRsdp));
2001+
DEBUG ((DEBUG_INFO, "Silicon ACPI RSDP address : 0x%016lx\n", SiAcpiHobRsdp));
19922002
AcpiTableInstance->Rsdp3 = SiAcpiHobRsdp;
19932003

1994-
if (SiAcpiHobRsdp->RsdtAddress != 0x00000000) {
1995-
//
1996-
// Initial RSDT.
1997-
//
1998-
TempBuffer = (UINT8 *)(UINTN)(SiAcpiHobRsdp->RsdtAddress);
1999-
SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)TempBuffer;
2000-
AcpiTableInstance->Rsdt3 = SiCommonAcpiTable;
2004+
//
2005+
// Got XSDT address from RSDP table.
2006+
//
2007+
Buffer = (UINT8 *)(UINTN)(SiAcpiHobRsdp->XsdtAddress);
2008+
SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)Buffer;
20012009

2002-
if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
2003-
DEBUG ((DEBUG_ERROR, "RSDT length is incorrect\n"));
2004-
return EFI_ABORTED;
2005-
}
2010+
DEBUG ((DEBUG_INFO, "Silicon ACPI XSDT address : 0x%016lx\n", SiCommonAcpiTable));
20062011

2012+
if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
2013+
DEBUG ((DEBUG_ERROR, "XSDT length is incorrect\n"));
2014+
return EFI_ABORTED;
2015+
}
2016+
2017+
//
2018+
// Calcaue 64bit Acpi table number.
2019+
//
2020+
NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT64);
2021+
DEBUG ((DEBUG_ERROR, "64bit NumOfTblEntries : 0x%x\n", NumOfTblEntries));
2022+
//
2023+
// Reserved the ACPI reclaim memory for XSDT.
2024+
//
2025+
//
2026+
TotalSocTablesize = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + sizeof (UINT64);
2027+
PageAddress = 0xFFFFFFFF;
2028+
Status = gBS->AllocatePages (
2029+
mAcpiTableAllocType,
2030+
EfiACPIReclaimMemory,
2031+
EFI_SIZE_TO_PAGES (TotalSocTablesize),
2032+
&PageAddress
2033+
);
2034+
if (EFI_ERROR (Status)) {
2035+
DEBUG ((DEBUG_ERROR, "Fail to allocate EfiACPIReclaimMemory for XSDT. Status : %r\n", Status));
2036+
return EFI_OUT_OF_RESOURCES;
2037+
}
2038+
2039+
ZeroMem (&PageAddress, TotalSocTablesize);
2040+
AcpiTableInstance->Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)PageAddress;
2041+
2042+
//
2043+
// Initial XSDT table content.
2044+
//
2045+
AcpiTableInstance->Xsdt->Signature = SiCommonAcpiTable->Signature;
2046+
//
2047+
// Always reserve first one for FADT table.
2048+
//
2049+
AcpiTableInstance->Xsdt->Length = sizeof (EFI_ACPI_DESCRIPTION_HEADER) + sizeof (UINT64);
2050+
AcpiTableInstance->Xsdt->Revision = SiCommonAcpiTable->Revision;
2051+
CopyMem (
2052+
&AcpiTableInstance->Xsdt->OemId,
2053+
SiCommonAcpiTable->OemId,
2054+
sizeof (AcpiTableInstance->Xsdt->OemId)
2055+
);
2056+
CopyMem (
2057+
&AcpiTableInstance->Xsdt->OemTableId,
2058+
&SiCommonAcpiTable->OemTableId,
2059+
sizeof (UINT64)
2060+
);
2061+
AcpiTableInstance->Xsdt->OemRevision = SiCommonAcpiTable->OemRevision;
2062+
AcpiTableInstance->Xsdt->CreatorId = SiCommonAcpiTable->CreatorId;
2063+
AcpiTableInstance->Xsdt->CreatorRevision = SiCommonAcpiTable->CreatorRevision;
2064+
AcpiTableInstance->NumberOfTableEntries3 = 1;
2065+
//
2066+
// Extract ACPI table from AcpiSiliconHob XSDT.
2067+
//
2068+
for (Index = 0; Index < NumOfTblEntries; Index++) {
2069+
CopyMem (&SocTablePtr, (((UINT8 *)(SiCommonAcpiTable + 1)) + ((sizeof (UINT64)) * Index)), sizeof (UINT64));
2070+
SocEntryTable = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN)SocTablePtr;
20072071
//
2008-
// Calcaue 32bit Acpi table number.
2072+
// Display table information.
20092073
//
2010-
NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT32);
2011-
AcpiTableInstance->NumberOfTableEntries1 = NumOfTblEntries;
2012-
DEBUG ((DEBUG_INFO, "32bit NumOfTblEntries : 0x%x\n", NumOfTblEntries));
2074+
DEBUG ((DEBUG_INFO, "[%x] Table address : 0x%016lx\n", Index, SocTablePtr));
2075+
2076+
Buffer = (UINT8 *)&SocEntryTable->Signature;
2077+
DEBUG ((DEBUG_INFO, "Table signature = %c%c%c%c\n", Buffer[0], Buffer[1], Buffer[2], Buffer[3]));
2078+
2079+
DEBUG ((DEBUG_INFO, "Table Length : 0x%x\n", SocEntryTable->Length));
2080+
2081+
Buffer = (UINT8 *)&SocEntryTable->OemId;
2082+
DEBUG (
2083+
(DEBUG_INFO, "Table OemId = %c%c%c%c%c%c\n",
2084+
Buffer[0],
2085+
Buffer[1],
2086+
Buffer[2],
2087+
Buffer[3],
2088+
Buffer[4],
2089+
Buffer[5]
2090+
)
2091+
);
2092+
2093+
Buffer = (UINT8 *)&SocEntryTable->OemTableId;
2094+
DEBUG (
2095+
(DEBUG_INFO, "Table OemTableId = %c%c%c%c%c%c%c%c\n",
2096+
Buffer[0],
2097+
Buffer[1],
2098+
Buffer[2],
2099+
Buffer[3],
2100+
Buffer[4],
2101+
Buffer[5],
2102+
Buffer[6],
2103+
Buffer[7]
2104+
)
2105+
);
2106+
DEBUG ((DEBUG_INFO, "\n"));
20132107
//
2014-
// Enlarge the max table number from mEfiAcpiMaxNumTables to current ACPI tables + EFI_ACPI_MAX_NUM_TABLES
2108+
// Add ACPI table in the DXE AcpiTableInstance.
20152109
//
2016-
if (AcpiTableInstance->NumberOfTableEntries1 >= EFI_ACPI_MAX_NUM_TABLES) {
2017-
mEfiAcpiMaxNumTables = AcpiTableInstance->NumberOfTableEntries1 + EFI_ACPI_MAX_NUM_TABLES;
2018-
DEBUG ((DEBUG_ERROR, "mEfiAcpiMaxNumTables : 0x%x\n", mEfiAcpiMaxNumTables));
2110+
Status = AddTableToList (AcpiTableInstance, SocEntryTable, TRUE, Version, TRUE, &TableKey);
2111+
if (EFI_ERROR (Status)) {
2112+
DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromAcpiSiliconHob: Fail to add ACPI table at 0x%p\n", SocEntryTable));
2113+
ASSERT_EFI_ERROR (Status);
2114+
break;
20192115
}
2020-
} else {
2021-
//
2022-
// Initial XSDT.
2023-
//
2024-
TempBuffer = (UINT8 *)(UINTN)(SiAcpiHobRsdp->XsdtAddress);
2025-
SiCommonAcpiTable = (EFI_ACPI_DESCRIPTION_HEADER *)TempBuffer;
2026-
AcpiTableInstance->Xsdt = SiCommonAcpiTable;
20272116

2028-
if (SiCommonAcpiTable->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
2029-
DEBUG ((DEBUG_ERROR, "XSDT length is incorrect\n"));
2030-
return EFI_ABORTED;
2031-
}
2117+
if (SocEntryTable->Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
2118+
//
2119+
// According ACPI spec, if XDsdt field contains a nonzero value which can be used by the OSPM, then the Dsdt field must be ignored by the OSPM.
2120+
//
2121+
if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->XDsdt != 0) {
2122+
NeedToInstallTable = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->XDsdt;
2123+
} else if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->Dsdt != 0) {
2124+
NeedToInstallTable = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->Dsdt;
2125+
}
20322126

2033-
//
2034-
// Calcaue 64bit Acpi table number.
2035-
//
2036-
NumOfTblEntries = (SiCommonAcpiTable->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof (UINT64);
2037-
AcpiTableInstance->NumberOfTableEntries3 = NumOfTblEntries;
2038-
DEBUG ((DEBUG_ERROR, "64bit NumOfTblEntries : 0x%x\n", NumOfTblEntries));
2039-
//
2040-
// Enlarge the max table number from mEfiAcpiMaxNumTables to current ACPI tables + EFI_ACPI_MAX_NUM_TABLES
2041-
//
2042-
if (AcpiTableInstance->NumberOfTableEntries3 >= EFI_ACPI_MAX_NUM_TABLES) {
2043-
mEfiAcpiMaxNumTables = AcpiTableInstance->NumberOfTableEntries3 + EFI_ACPI_MAX_NUM_TABLES;
2044-
DEBUG ((DEBUG_ERROR, "mEfiAcpiMaxNumTables : 0x%x\n", mEfiAcpiMaxNumTables));
2127+
//
2128+
// if signature can not be found from the XDsdt / Dsdt field then skip it.
2129+
//
2130+
if (((EFI_ACPI_DESCRIPTION_HEADER *)NeedToInstallTable)->Signature == EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
2131+
Status = AddTableToList (AcpiTableInstance, NeedToInstallTable, TRUE, Version, TRUE, &TableKey);
2132+
if (EFI_ERROR (Status)) {
2133+
DEBUG ((DEBUG_ERROR, "Fail to add DSDT in the DXE Table list!\n"));
2134+
ASSERT_EFI_ERROR (Status);
2135+
break;
2136+
} else {
2137+
DEBUG ((DEBUG_ERROR, "Installed DSDT in the DXE Table list!\n"));
2138+
}
2139+
} else {
2140+
DEBUG ((DEBUG_ERROR, "The DSDT content is not correct, then skip it!\n"));
2141+
}
2142+
2143+
//
2144+
// According ACPI spec, if XFirmwareCtrl field contains a nonzero value which can be used by the OSPM, then the FirmwareCtrl field must be ignored by the OSPM.
2145+
//
2146+
if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->XFirmwareCtrl != 0) {
2147+
NeedToInstallTable = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->XFirmwareCtrl;
2148+
} else if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->FirmwareCtrl != 0) {
2149+
NeedToInstallTable = (VOID *)(UINTN)((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *)SocEntryTable)->FirmwareCtrl;
2150+
}
2151+
2152+
if (((EFI_ACPI_DESCRIPTION_HEADER *)NeedToInstallTable)->Signature == EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) {
2153+
Status = AddTableToList (AcpiTableInstance, NeedToInstallTable, TRUE, Version, TRUE, &TableKey);
2154+
if (EFI_ERROR (Status)) {
2155+
DEBUG ((DEBUG_ERROR, "Fail to add FACS in the DXE Table list!\n"));
2156+
ASSERT_EFI_ERROR (Status);
2157+
break;
2158+
} else {
2159+
DEBUG ((DEBUG_ERROR, "Installed FACS in the DXE Table list!\n"));
2160+
}
2161+
} else {
2162+
DEBUG ((DEBUG_ERROR, "The FACS content is not correct, then skip it!\n"));
2163+
}
20452164
}
20462165
}
20472166

2167+
DEBUG ((DEBUG_INFO, "InstallAcpiTableFromAcpiSiliconHob - End\n"));
20482168
return Status;
20492169
}
20502170

0 commit comments

Comments
 (0)