diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c
index 14ced68e64..d98573d613 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c
@@ -1,7 +1,7 @@
/** @file
ACPI Sdt Protocol Driver
- Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -191,8 +191,7 @@ SdtNotifyAcpiList (
/**
Returns a requested ACPI table.
- The GetAcpiTable() function returns a pointer to a buffer containing the ACPI table associated
- with the Index that was input. The following structures are not considered elements in the list of
+ The following structures are not considered elements in the list of
ACPI tables:
- Root System Description Pointer (RSD_PTR)
- Root System Description Table (RSDT)
@@ -201,42 +200,32 @@ SdtNotifyAcpiList (
member. For tables installed via the EFI_ACPI_TABLE_PROTOCOL.InstallAcpiTable() interface,
the function returns the value of EFI_ACPI_STD_PROTOCOL.AcpiVersion.
- @param[in] Index The zero-based index of the table to retrieve.
- @param[out] Table Pointer for returning the table buffer.
- @param[out] Version On return, updated with the ACPI versions to which this table belongs. Type
- EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the
- EFI_ACPI_SDT_PROTOCOL.
- @param[out] TableKey On return, points to the table key for the specified ACPI system definition table.
- This is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.
- The TableKey can be passed to EFI_ACPI_TABLE_PROTOCOL.UninstallAcpiTable()
- to uninstall the table.
- @retval EFI_SUCCESS The function completed successfully.
- @retval EFI_NOT_FOUND The requested index is too large and a table was not found.
+ @param[in] AcpiTableInstance ACPI table Instance.
+ @param[in] Index The zero-based index of the table to retrieve.
+ @param[out] Table Pointer for returning the table buffer.
+ @param[out] Version On return, updated with the ACPI versions to which this table belongs. Type
+ EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the
+ EFI_ACPI_SDT_PROTOCOL.
+ @param[out] TableKey On return, points to the table key for the specified ACPI system definition table.
+ This is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.
+ The TableKey can be passed to EFI_ACPI_TABLE_PROTOCOL.UninstallAcpiTable()
+ to uninstall the table.
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND The requested index is too large and a table was not found.
**/
EFI_STATUS
-EFIAPI
-GetAcpiTable2 (
+SdtGetAcpiTable (
+ IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,
IN UINTN Index,
OUT EFI_ACPI_SDT_HEADER **Table,
OUT EFI_ACPI_TABLE_VERSION *Version,
OUT UINTN *TableKey
)
{
- EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;
UINTN TableIndex;
LIST_ENTRY *CurrentLink;
LIST_ENTRY *StartLink;
EFI_ACPI_TABLE_LIST *CurrentTable;
-
- ASSERT (Table != NULL);
- ASSERT (Version != NULL);
- ASSERT (TableKey != NULL);
-
- //
- // Get the instance of the ACPI Table
- //
- AcpiTableInstance = SdtGetAcpiTableInstance ();
-
//
// Find the table
//
@@ -270,6 +259,55 @@ GetAcpiTable2 (
return EFI_SUCCESS;
}
+/**
+ Returns a requested ACPI table.
+
+ The GetAcpiTable() function returns a pointer to a buffer containing the ACPI table associated
+ with the Index that was input. The following structures are not considered elements in the list of
+ ACPI tables:
+ - Root System Description Pointer (RSD_PTR)
+ - Root System Description Table (RSDT)
+ - Extended System Description Table (XSDT)
+ Version is updated with a bit map containing all the versions of ACPI of which the table is a
+ member. For tables installed via the EFI_ACPI_TABLE_PROTOCOL.InstallAcpiTable() interface,
+ the function returns the value of EFI_ACPI_STD_PROTOCOL.AcpiVersion.
+
+ @param[in] Index The zero-based index of the table to retrieve.
+ @param[out] Table Pointer for returning the table buffer.
+ @param[out] Version On return, updated with the ACPI versions to which this table belongs. Type
+ EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the
+ EFI_ACPI_SDT_PROTOCOL.
+ @param[out] TableKey On return, points to the table key for the specified ACPI system definition table.
+ This is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.
+ The TableKey can be passed to EFI_ACPI_TABLE_PROTOCOL.UninstallAcpiTable()
+ to uninstall the table.
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND The requested index is too large and a table was not found.
+**/
+EFI_STATUS
+EFIAPI
+GetAcpiTable2 (
+ IN UINTN Index,
+ OUT EFI_ACPI_SDT_HEADER **Table,
+ OUT EFI_ACPI_TABLE_VERSION *Version,
+ OUT UINTN *TableKey
+ )
+{
+ EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;
+
+ ASSERT (Table != NULL);
+ ASSERT (Version != NULL);
+ ASSERT (TableKey != NULL);
+
+ //
+ // Get the instance of the ACPI Table
+ //
+ AcpiTableInstance = SdtGetAcpiTableInstance ();
+
+ return SdtGetAcpiTable (AcpiTableInstance, Index, Table, Version, TableKey);
+}
+
+
/**
Register a callback when an ACPI table is installed.
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h
index 9d7cf7ccfc..0af2d11a1a 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h
@@ -1,7 +1,7 @@
/** @file
ACPI Table Protocol Driver
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -24,6 +24,8 @@
#include
#include
#include
+#include
+#include
//
// Statements that include other files
@@ -228,6 +230,40 @@ SdtAcpiTableAcpiSdtConstructor (
IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance
);
+/**
+ Returns a requested ACPI table.
+
+ The following structures are not considered elements in the list of
+ ACPI tables:
+ - Root System Description Pointer (RSD_PTR)
+ - Root System Description Table (RSDT)
+ - Extended System Description Table (XSDT)
+ Version is updated with a bit map containing all the versions of ACPI of which the table is a
+ member. For tables installed via the EFI_ACPI_TABLE_PROTOCOL.InstallAcpiTable() interface,
+ the function returns the value of EFI_ACPI_STD_PROTOCOL.AcpiVersion.
+
+ @param[in] AcpiTableInstance ACPI table Instance.
+ @param[in] Index The zero-based index of the table to retrieve.
+ @param[out] Table Pointer for returning the table buffer.
+ @param[out] Version On return, updated with the ACPI versions to which this table belongs. Type
+ EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the
+ EFI_ACPI_SDT_PROTOCOL.
+ @param[out] TableKey On return, points to the table key for the specified ACPI system definition table.
+ This is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.
+ The TableKey can be passed to EFI_ACPI_TABLE_PROTOCOL.UninstallAcpiTable()
+ to uninstall the table.
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND The requested index is too large and a table was not found.
+**/
+EFI_STATUS
+SdtGetAcpiTable (
+ IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,
+ IN UINTN Index,
+ OUT EFI_ACPI_SDT_HEADER **Table,
+ OUT EFI_ACPI_TABLE_VERSION *Version,
+ OUT UINTN *TableKey
+ );
+
//
// export PrivateData symbol, because we need that in AcpiSdtProtol implementation
//
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
index d341df439e..86dea43e27 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
@@ -4,7 +4,7 @@
# This driver initializes ACPI tables (Rsdp, Rsdt and Xsdt) and produces UEFI/PI
# services to install/uninstall/manage ACPI tables.
#
-# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
# Copyright (c) 2016, Linaro Ltd. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@@ -51,10 +51,12 @@
DebugLib
BaseLib
PcdLib
+ HobLib
[Guids]
- gEfiAcpi10TableGuid ## PRODUCES ## SystemTable
- gEfiAcpiTableGuid ## PRODUCES ## SystemTable
+ gEfiAcpi10TableGuid ## PRODUCES ## SystemTable
+ gEfiAcpiTableGuid ## PRODUCES ## SystemTable
+ gUniversalPayloadAcpiTableGuid ## SOMETIMES_CONSUMES ## HOB
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol ## CONSUMES
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
index 5a2afdff27..34d4a1cec0 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
@@ -1,7 +1,7 @@
/** @file
ACPI Table Protocol Implementation
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
Copyright (c) 2016, Linaro Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -30,6 +30,7 @@ STATIC EFI_ALLOCATE_TYPE mAcpiTableAllocType;
@param Table Table to add.
@param Checksum Does the table require checksumming.
@param Version The version of the list to add the table to.
+ @param IsFromHob True, if add Apci Table from Hob List.
@param Handle Pointer for returning the handle.
@return EFI_SUCCESS The function completed successfully.
@@ -44,6 +45,7 @@ AddTableToList (
IN VOID *Table,
IN BOOLEAN Checksum,
IN EFI_ACPI_TABLE_VERSION Version,
+ IN BOOLEAN IsFromHob,
OUT UINTN *Handle
);
@@ -238,6 +240,7 @@ InstallAcpiTable (
AcpiTableBufferConst,
TRUE,
Version,
+ FALSE,
TableKey
);
if (!EFI_ERROR (Status)) {
@@ -472,6 +475,7 @@ FreeTableMemory (
@param Table Table to add.
@param Checksum Does the table require checksumming.
@param Version The version of the list to add the table to.
+ @param IsFromHob True, if add Apci Table from Hob List.
@param Handle Pointer for returning the handle.
@return EFI_SUCCESS The function completed successfully.
@@ -487,6 +491,7 @@ AddTableToList (
IN VOID *Table,
IN BOOLEAN Checksum,
IN EFI_ACPI_TABLE_VERSION Version,
+ IN BOOLEAN IsFromHob,
OUT UINTN *Handle
)
{
@@ -553,12 +558,17 @@ AddTableToList (
// SMM communication ACPI table.
//
ASSERT ((EFI_PAGE_SIZE % 64) == 0);
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiACPIMemoryNVS,
- EFI_SIZE_TO_PAGES (CurrentTableList->TableSize),
- &AllocPhysAddress
- );
+ if (IsFromHob){
+ AllocPhysAddress = (UINTN)Table;
+ Status = EFI_SUCCESS;
+ } else {
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiACPIMemoryNVS,
+ EFI_SIZE_TO_PAGES (CurrentTableList->TableSize),
+ &AllocPhysAddress
+ );
+ }
} else if (mAcpiTableAllocType == AllocateAnyPages) {
//
// If there is no allocation limit, there is also no need to use page
@@ -1689,6 +1699,151 @@ ChecksumCommonTables (
return EFI_SUCCESS;
}
+/**
+ This function will find gUniversalPayloadAcpiTableGuid Guid Hob, and install Acpi table from it.
+
+ @param AcpiTableInstance Protocol instance private data.
+
+ @return EFI_SUCCESS The function completed successfully.
+ @return EFI_NOT_FOUND The function doesn't find the gEfiAcpiTableGuid Guid Hob.
+ @return EFI_ABORTED The function could not complete successfully.
+
+**/
+EFI_STATUS
+InstallAcpiTableFromHob (
+ EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ EFI_ACPI_TABLE_VERSION Version;
+ EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
+ EFI_ACPI_DESCRIPTION_HEADER *Rsdt;
+ EFI_ACPI_DESCRIPTION_HEADER *ChildTable;
+ UINT64 ChildTableAddress;
+ UINTN Count;
+ UINTN Index;
+ UINTN TableKey;
+ EFI_STATUS Status;
+ UINTN EntrySize;
+ UNIVERSAL_PAYLOAD_ACPI_TABLE *AcpiTableAdress;
+ VOID *TableToInstall;
+ EFI_ACPI_SDT_HEADER *Table;
+ UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader;
+
+ TableKey = 0;
+ Version = PcdGet32 (PcdAcpiExposedTableVersions);
+ Status = EFI_SUCCESS;
+ //
+ // HOB only contains the ACPI table in 2.0+ format.
+ //
+ GuidHob = GetFirstGuidHob (&gUniversalPayloadAcpiTableGuid);
+ if (GuidHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *) GET_GUID_HOB_DATA (GuidHob);
+ if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob)) || (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob))) {
+ return EFI_NOT_FOUND;
+ }
+ if (GenericHeader->Revision == UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION) {
+ //
+ // UNIVERSAL_PAYLOAD_ACPI_TABLE structure is used when Revision equals to UNIVERSAL_PAYLOAD_ACPI_TABLE_REVISION
+ //
+ AcpiTableAdress = (UNIVERSAL_PAYLOAD_ACPI_TABLE *) GET_GUID_HOB_DATA (GuidHob);
+ if (AcpiTableAdress->Header.Length < UNIVERSAL_PAYLOAD_SIZEOF_THROUGH_FIELD (UNIVERSAL_PAYLOAD_ACPI_TABLE, Rsdp)) {
+ //
+ // Retrun if can't find the ACPI Info Hob with enough length
+ //
+ return EFI_NOT_FOUND;
+ }
+ Rsdp = (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) (UINTN) (AcpiTableAdress->Rsdp);
+
+ //
+ // An ACPI-compatible OS must use the XSDT if present.
+ // It shouldn't happen that XsdtAddress points beyond 4G range in 32-bit environment.
+ //
+ ASSERT ((UINTN) Rsdp->XsdtAddress == Rsdp->XsdtAddress);
+
+ EntrySize = sizeof (UINT64);
+ Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->XsdtAddress;
+ if (Rsdt == NULL) {
+ //
+ // XsdtAddress is zero, then we use Rsdt which has 32 bit entry
+ //
+ Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress;
+ EntrySize = sizeof (UINT32);
+ }
+
+ if (Rsdt->Length <= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
+ return EFI_ABORTED;
+ }
+
+ Count = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / EntrySize;
+
+ for (Index = 0; Index < Count; Index++){
+ ChildTableAddress = 0;
+ CopyMem (&ChildTableAddress, (UINT8 *) (Rsdt + 1) + EntrySize * Index, EntrySize);
+ //
+ // If the address is of UINT64 while this module runs at 32 bits,
+ // make sure the upper bits are all-zeros.
+ //
+ ASSERT (ChildTableAddress == (UINTN) ChildTableAddress);
+ if (ChildTableAddress != (UINTN) ChildTableAddress) {
+ Status = EFI_ABORTED;
+ break;
+ }
+
+ ChildTable = (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) ChildTableAddress;
+ Status = AddTableToList (AcpiTableInstance, ChildTable, TRUE, Version, TRUE, &TableKey);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI table at 0x%p\n", ChildTable));
+ ASSERT_EFI_ERROR (Status);
+ break;
+ }
+ if (ChildTable->Signature == EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE){
+ //
+ // Add the FACS and DSDT tables if it is not NULL.
+ //
+ if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) ChildTable)->FirmwareCtrl != 0) {
+ TableToInstall = (VOID *) (UINTN) ((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) ChildTable)->FirmwareCtrl;
+ Status = AddTableToList (AcpiTableInstance, TableToInstall, TRUE, Version, TRUE, &TableKey);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI table FACS\n"));
+ ASSERT_EFI_ERROR (Status);
+ break;
+ }
+ }
+
+ if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) ChildTable)->Dsdt != 0) {
+ TableToInstall = (VOID *) (UINTN) ((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) ChildTable)->Dsdt;
+ Status = AddTableToList (AcpiTableInstance, TableToInstall, TRUE, Version, TRUE, &TableKey);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI table DSDT\n"));
+ ASSERT_EFI_ERROR (Status);
+ break;
+ }
+ }
+ }
+ }
+ } else {
+ return EFI_NOT_FOUND;
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Error happens when trying to add ACPI table to the list.
+ // Remove all of them from list because at this time, no other tables except from HOB are in the list
+ //
+ while (SdtGetAcpiTable (AcpiTableInstance, 0, &Table, &Version, &TableKey) == EFI_SUCCESS) {
+ RemoveTableFromList (AcpiTableInstance, Version, TableKey);
+ }
+ } else {
+ Status = PublishTables (AcpiTableInstance, Version);
+ }
+
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
/**
Constructor for the ACPI table protocol. Initializes instance
@@ -1918,6 +2073,8 @@ AcpiTableAcpiTableConstructor (
ChecksumCommonTables (AcpiTableInstance);
+ InstallAcpiTableFromHob (AcpiTableInstance);
+
//
// Completed successfully
//