[Patch V3 8/9] MdeModulePkg/ACPI: Install ACPI table from HOB.


Zhiguang Liu
 

V1:
If HOB contains APCI table information, entry point of AcpiTableDxe.inf
should parse the APCI table from HOB, and install these tables.
We assume the whole ACPI table (starting with EFI_ACPI_2_0_ROOT_SYSTEM_DESC=
RIPTION_POINTER)
is contained by a single gEfiAcpiTableGuid HOB.

V2:
If error happens when installing ACPI table, stop installing and removing a=
ll the tables that
are already added.

Cc: Jian J Wang <jian.j.wang@...>
Cc: Hao A Wu <hao.a.wu@...>
Cc: Dandan Bi <dandan.bi@...>
Cc: Liming Gao <gaoliming@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Zhiguang Liu <zhiguang.liu@...>
---
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c | 92 +++++++=
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------=
----------
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h | 38 +++++++=
++++++++++++++++++++++++++++++-
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf | 8 +++++---
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c | 171 +++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++=
+++++++-------
4 files changed, 271 insertions(+), 38 deletions(-)

diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c b/MdeModule=
Pkg/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=0D
ACPI Sdt Protocol Driver=0D
=0D
- Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>=
=0D
+ Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved. <BR>=
=0D
SPDX-License-Identifier: BSD-2-Clause-Patent=0D
=0D
**/=0D
@@ -191,8 +191,7 @@ SdtNotifyAcpiList (
/**=0D
Returns a requested ACPI table.=0D
=0D
- The GetAcpiTable() function returns a pointer to a buffer containing the=
ACPI table associated=0D
- with the Index that was input. The following structures are not consider=
ed elements in the list of=0D
+ The following structures are not considered elements in the list of=0D
ACPI tables:=0D
- Root System Description Pointer (RSD_PTR)=0D
- Root System Description Table (RSDT)=0D
@@ -201,42 +200,32 @@ SdtNotifyAcpiList (
member. For tables installed via the EFI_ACPI_TABLE_PROTOCOL.InstallAcpi=
Table() interface,=0D
the function returns the value of EFI_ACPI_STD_PROTOCOL.AcpiVersion.=0D
=0D
- @param[in] Index The zero-based index of the table to retrieve.=
=0D
- @param[out] Table Pointer for returning the table buffer.=0D
- @param[out] Version On return, updated with the ACPI versions to w=
hich this table belongs. Type=0D
- EFI_ACPI_TABLE_VERSION is defined in "Related =
Definitions" in the=0D
- EFI_ACPI_SDT_PROTOCOL.=0D
- @param[out] TableKey On return, points to the table key for the spe=
cified ACPI system definition table.=0D
- This is identical to the table key used in the=
EFI_ACPI_TABLE_PROTOCOL.=0D
- The TableKey can be passed to EFI_ACPI_TABLE_P=
ROTOCOL.UninstallAcpiTable()=0D
- to uninstall the table.=0D
- @retval EFI_SUCCESS The function completed successfully.=0D
- @retval EFI_NOT_FOUND The requested index is too large and a table w=
as not found.=0D
+ @param[in] AcpiTableInstance ACPI table Instance.=0D
+ @param[in] Index The zero-based index of the table to re=
trieve.=0D
+ @param[out] Table Pointer for returning the table buffer.=
=0D
+ @param[out] Version On return, updated with the ACPI versio=
ns to which this table belongs. Type=0D
+ EFI_ACPI_TABLE_VERSION is defined in "R=
elated Definitions" in the=0D
+ EFI_ACPI_SDT_PROTOCOL.=0D
+ @param[out] TableKey On return, points to the table key for =
the specified ACPI system definition table.=0D
+ This is identical to the table key used=
in the EFI_ACPI_TABLE_PROTOCOL.=0D
+ The TableKey can be passed to EFI_ACPI_=
TABLE_PROTOCOL.UninstallAcpiTable()=0D
+ to uninstall the table.=0D
+ @retval EFI_SUCCESS The function completed successfully.=0D
+ @retval EFI_NOT_FOUND The requested index is too large and a =
table was not found.=0D
**/=0D
EFI_STATUS=0D
-EFIAPI=0D
-GetAcpiTable2 (=0D
+SdtGetAcpiTable (=0D
+ IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,=0D
IN UINTN Index,=0D
OUT EFI_ACPI_SDT_HEADER **Table,=0D
OUT EFI_ACPI_TABLE_VERSION *Version,=0D
OUT UINTN *TableKey=0D
)=0D
{=0D
- EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;=0D
UINTN TableIndex;=0D
LIST_ENTRY *CurrentLink;=0D
LIST_ENTRY *StartLink;=0D
EFI_ACPI_TABLE_LIST *CurrentTable;=0D
-=0D
- ASSERT (Table !=3D NULL);=0D
- ASSERT (Version !=3D NULL);=0D
- ASSERT (TableKey !=3D NULL);=0D
-=0D
- //=0D
- // Get the instance of the ACPI Table=0D
- //=0D
- AcpiTableInstance =3D SdtGetAcpiTableInstance ();=0D
-=0D
//=0D
// Find the table=0D
//=0D
@@ -270,6 +259,55 @@ GetAcpiTable2 (
return EFI_SUCCESS;=0D
}=0D
=0D
+/**=0D
+ Returns a requested ACPI table.=0D
+=0D
+ The GetAcpiTable() function returns a pointer to a buffer containing the=
ACPI table associated=0D
+ with the Index that was input. The following structures are not consider=
ed elements in the list of=0D
+ ACPI tables:=0D
+ - Root System Description Pointer (RSD_PTR)=0D
+ - Root System Description Table (RSDT)=0D
+ - Extended System Description Table (XSDT)=0D
+ Version is updated with a bit map containing all the versions of ACPI of=
which the table is a=0D
+ member. For tables installed via the EFI_ACPI_TABLE_PROTOCOL.InstallAcpi=
Table() interface,=0D
+ the function returns the value of EFI_ACPI_STD_PROTOCOL.AcpiVersion.=0D
+=0D
+ @param[in] Index The zero-based index of the table to retrieve.=
=0D
+ @param[out] Table Pointer for returning the table buffer.=0D
+ @param[out] Version On return, updated with the ACPI versions to w=
hich this table belongs. Type=0D
+ EFI_ACPI_TABLE_VERSION is defined in "Related =
Definitions" in the=0D
+ EFI_ACPI_SDT_PROTOCOL.=0D
+ @param[out] TableKey On return, points to the table key for the spe=
cified ACPI system definition table.=0D
+ This is identical to the table key used in the=
EFI_ACPI_TABLE_PROTOCOL.=0D
+ The TableKey can be passed to EFI_ACPI_TABLE_P=
ROTOCOL.UninstallAcpiTable()=0D
+ to uninstall the table.=0D
+ @retval EFI_SUCCESS The function completed successfully.=0D
+ @retval EFI_NOT_FOUND The requested index is too large and a table w=
as not found.=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+GetAcpiTable2 (=0D
+ IN UINTN Index,=0D
+ OUT EFI_ACPI_SDT_HEADER **Table,=0D
+ OUT EFI_ACPI_TABLE_VERSION *Version,=0D
+ OUT UINTN *TableKey=0D
+ )=0D
+{=0D
+ EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;=0D
+=0D
+ ASSERT (Table !=3D NULL);=0D
+ ASSERT (Version !=3D NULL);=0D
+ ASSERT (TableKey !=3D NULL);=0D
+=0D
+ //=0D
+ // Get the instance of the ACPI Table=0D
+ //=0D
+ AcpiTableInstance =3D SdtGetAcpiTableInstance ();=0D
+=0D
+ return SdtGetAcpiTable (AcpiTableInstance, Index, Table, Version, TableK=
ey);=0D
+}=0D
+=0D
+=0D
/**=0D
Register a callback when an ACPI table is installed.=0D
=0D
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h b/MdeModu=
lePkg/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=0D
ACPI Table Protocol Driver=0D
=0D
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>=0D
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>=0D
SPDX-License-Identifier: BSD-2-Clause-Patent=0D
=0D
**/=0D
@@ -24,6 +24,8 @@
#include <Library/MemoryAllocationLib.h>=0D
#include <Library/UefiBootServicesTableLib.h>=0D
#include <Library/PcdLib.h>=0D
+#include <Library/HobLib.h>=0D
+#include <UniversalPayload/AcpiTable.h>=0D
=0D
//=0D
// Statements that include other files=0D
@@ -228,6 +230,40 @@ SdtAcpiTableAcpiSdtConstructor (
IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance=0D
);=0D
=0D
+/**=0D
+ Returns a requested ACPI table.=0D
+=0D
+ The following structures are not considered elements in the list of=0D
+ ACPI tables:=0D
+ - Root System Description Pointer (RSD_PTR)=0D
+ - Root System Description Table (RSDT)=0D
+ - Extended System Description Table (XSDT)=0D
+ Version is updated with a bit map containing all the versions of ACPI of=
which the table is a=0D
+ member. For tables installed via the EFI_ACPI_TABLE_PROTOCOL.InstallAcpi=
Table() interface,=0D
+ the function returns the value of EFI_ACPI_STD_PROTOCOL.AcpiVersion.=0D
+=0D
+ @param[in] AcpiTableInstance ACPI table Instance.=0D
+ @param[in] Index The zero-based index of the table to re=
trieve.=0D
+ @param[out] Table Pointer for returning the table buffer.=
=0D
+ @param[out] Version On return, updated with the ACPI versio=
ns to which this table belongs. Type=0D
+ EFI_ACPI_TABLE_VERSION is defined in "R=
elated Definitions" in the=0D
+ EFI_ACPI_SDT_PROTOCOL.=0D
+ @param[out] TableKey On return, points to the table key for =
the specified ACPI system definition table.=0D
+ This is identical to the table key used=
in the EFI_ACPI_TABLE_PROTOCOL.=0D
+ The TableKey can be passed to EFI_ACPI_=
TABLE_PROTOCOL.UninstallAcpiTable()=0D
+ to uninstall the table.=0D
+ @retval EFI_SUCCESS The function completed successfully.=0D
+ @retval EFI_NOT_FOUND The requested index is too large and a =
table was not found.=0D
+**/=0D
+EFI_STATUS=0D
+SdtGetAcpiTable (=0D
+ IN EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance,=0D
+ IN UINTN Index,=0D
+ OUT EFI_ACPI_SDT_HEADER **Table,=0D
+ OUT EFI_ACPI_TABLE_VERSION *Version,=0D
+ OUT UINTN *TableKey=0D
+ );=0D
+=0D
//=0D
// export PrivateData symbol, because we need that in AcpiSdtProtol implem=
entation=0D
//=0D
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf b/Md=
eModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
index d341df439e..9e34f8ea41 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=0D
# services to install/uninstall/manage ACPI tables.=0D
#=0D
-# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>=
=0D
+# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>=
=0D
# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>=0D
# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
#=0D
@@ -51,10 +51,12 @@
DebugLib=0D
BaseLib=0D
PcdLib=0D
+ HobLib=0D
=0D
[Guids]=0D
- gEfiAcpi10TableGuid ## PRODUCES ## SystemTable=
=0D
- gEfiAcpiTableGuid ## PRODUCES ## SystemTable=
=0D
+ gEfiAcpi10TableGuid ## PRODUCES ## S=
ystemTable=0D
+ gEfiAcpiTableGuid ## PRODUCES ## S=
ystemTable=0D
+ gPldAcpiTableGuid ## SOMETIMES_CONSUMES ## H=
OB=0D
=0D
[FeaturePcd]=0D
gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol ## CONSUMES=0D
diff --git a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c b=
/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
index 5a2afdff27..cd79a1082c 100644
--- a/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
+++ b/MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c
@@ -1,7 +1,7 @@
/** @file=0D
ACPI Table Protocol Implementation=0D
=0D
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>=0D
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>=0D
Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>=0D
SPDX-License-Identifier: BSD-2-Clause-Patent=0D
=0D
@@ -30,6 +30,7 @@ STATIC EFI_ALLOCATE_TYPE mAcpiTableAllocType;
@param Table Table to add.=0D
@param Checksum Does the table require checksumming.=0D
@param Version The version of the list to add the tab=
le to.=0D
+ @param IsFromHob True, if add Apci Table from Hob List.=
=0D
@param Handle Pointer for returning the handle.=0D
=0D
@return EFI_SUCCESS The function completed successfully.=0D
@@ -44,6 +45,7 @@ AddTableToList (
IN VOID *Table,=0D
IN BOOLEAN Checksum,=0D
IN EFI_ACPI_TABLE_VERSION Version,=0D
+ IN BOOLEAN IsFromHob,=0D
OUT UINTN *Handle=0D
);=0D
=0D
@@ -238,6 +240,7 @@ InstallAcpiTable (
AcpiTableBufferConst,=0D
TRUE,=0D
Version,=0D
+ FALSE,=0D
TableKey=0D
);=0D
if (!EFI_ERROR (Status)) {=0D
@@ -472,6 +475,7 @@ FreeTableMemory (
@param Table Table to add.=0D
@param Checksum Does the table require checksumming.=0D
@param Version The version of the list to add the tab=
le to.=0D
+ @param IsFromHob True, if add Apci Table from Hob List.=
=0D
@param Handle Pointer for returning the handle.=0D
=0D
@return EFI_SUCCESS The function completed successfully.=0D
@@ -487,6 +491,7 @@ AddTableToList (
IN VOID *Table,=0D
IN BOOLEAN Checksum,=0D
IN EFI_ACPI_TABLE_VERSION Version,=0D
+ IN BOOLEAN IsFromHob,=0D
OUT UINTN *Handle=0D
)=0D
{=0D
@@ -553,12 +558,17 @@ AddTableToList (
// SMM communication ACPI table.=0D
//=0D
ASSERT ((EFI_PAGE_SIZE % 64) =3D=3D 0);=0D
- Status =3D gBS->AllocatePages (=0D
- AllocateMaxAddress,=0D
- EfiACPIMemoryNVS,=0D
- EFI_SIZE_TO_PAGES (CurrentTableList->TableSize),=0D
- &AllocPhysAddress=0D
- );=0D
+ if (IsFromHob){=0D
+ AllocPhysAddress =3D (UINTN)Table;=0D
+ Status =3D EFI_SUCCESS;=0D
+ } else {=0D
+ Status =3D gBS->AllocatePages (=0D
+ AllocateMaxAddress,=0D
+ EfiACPIMemoryNVS,=0D
+ EFI_SIZE_TO_PAGES (CurrentTableList->TableSize),=0D
+ &AllocPhysAddress=0D
+ );=0D
+ }=0D
} else if (mAcpiTableAllocType =3D=3D AllocateAnyPages) {=0D
//=0D
// If there is no allocation limit, there is also no need to use page=
=0D
@@ -1689,6 +1699,151 @@ ChecksumCommonTables (
return EFI_SUCCESS;=0D
}=0D
=0D
+/**=0D
+ This function will find gPldAcpiTableGuid Guid Hob, and install Acpi tab=
le from it.=0D
+=0D
+ @param AcpiTableInstance Protocol instance private data.=0D
+=0D
+ @return EFI_SUCCESS The function completed successfully.=0D
+ @return EFI_NOT_FOUND The function doesn't find the gEfiAcpiTableGu=
id Guid Hob.=0D
+ @return EFI_ABORTED The function could not complete successfully.=
=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+InstallAcpiTableFromHob (=0D
+ EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance=0D
+ )=0D
+{=0D
+ EFI_HOB_GUID_TYPE *GuidHob;=0D
+ EFI_ACPI_TABLE_VERSION Version;=0D
+ EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;=0D
+ EFI_ACPI_DESCRIPTION_HEADER *Rsdt;=0D
+ EFI_ACPI_DESCRIPTION_HEADER *ChildTable;=0D
+ UINT64 ChildTableAddress;=0D
+ UINTN Count;=0D
+ UINTN Index;=0D
+ UINTN TableKey;=0D
+ EFI_STATUS Status;=0D
+ UINTN EntrySize;=0D
+ PLD_ACPI_TABLE *AcpiTableAdress;=0D
+ VOID *TableToInstall;=0D
+ EFI_ACPI_SDT_HEADER *Table;=0D
+ PLD_GENERIC_HEADER *GenericHeader;=0D
+=0D
+ TableKey =3D 0;=0D
+ Version =3D PcdGet32 (PcdAcpiExposedTableVersions);=0D
+ Status =3D EFI_SUCCESS;=0D
+ //=0D
+ // HOB only contains the ACPI table in 2.0+ format.=0D
+ //=0D
+ GuidHob =3D GetFirstGuidHob (&gPldAcpiTableGuid);=0D
+ if (GuidHob =3D=3D NULL) {=0D
+ return EFI_NOT_FOUND;=0D
+ }=0D
+=0D
+ GenericHeader =3D (PLD_GENERIC_HEADER *) GET_GUID_HOB_DATA (GuidHob);=0D
+ if ((sizeof (PLD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob)) || =
(GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob))) {=0D
+ return EFI_NOT_FOUND;=0D
+ }=0D
+ if (GenericHeader->Revision =3D=3D PLD_ACPI_TABLE_REVISION) {=0D
+ //=0D
+ // PLD_ACPI_TABLE structure is used when Revision equals to PLD_ACPI_T=
ABLE_REVISION=0D
+ //=0D
+ AcpiTableAdress =3D (PLD_ACPI_TABLE *) GET_GUID_HOB_DATA (GuidHob);=0D
+ if (AcpiTableAdress->PldHeader.Length < PLD_SIZEOF_THROUGH_FIELD (PLD_=
ACPI_TABLE, Rsdp)) {=0D
+ //=0D
+ // Retrun if can't find the ACPI Info Hob with enough length=0D
+ //=0D
+ return EFI_NOT_FOUND;=0D
+ }=0D
+ Rsdp =3D (EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *) (UINTN) (Acp=
iTableAdress->Rsdp);=0D
+=0D
+ //=0D
+ // An ACPI-compatible OS must use the XSDT if present.=0D
+ // It shouldn't happen that XsdtAddress points beyond 4G range in 32-b=
it environment.=0D
+ //=0D
+ ASSERT ((UINTN) Rsdp->XsdtAddress =3D=3D Rsdp->XsdtAddress);=0D
+=0D
+ EntrySize =3D sizeof (UINT64);=0D
+ Rsdt =3D (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->XsdtAddress;=0D
+ if (Rsdt =3D=3D NULL) {=0D
+ //=0D
+ // XsdtAddress is zero, then we use Rsdt which has 32 bit entry=0D
+ //=0D
+ Rsdt =3D (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) Rsdp->RsdtAddress;=
=0D
+ EntrySize =3D sizeof (UINT32);=0D
+ }=0D
+=0D
+ if (Rsdt->Length <=3D sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {=0D
+ return EFI_ABORTED;=0D
+ }=0D
+=0D
+ Count =3D (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / Entr=
ySize;=0D
+=0D
+ for (Index =3D 0; Index < Count; Index++){=0D
+ ChildTableAddress =3D 0;=0D
+ CopyMem (&ChildTableAddress, (UINT8 *) (Rsdt + 1) + EntrySize * Inde=
x, EntrySize);=0D
+ //=0D
+ // If the address is of UINT64 while this module runs at 32 bits,=0D
+ // make sure the upper bits are all-zeros.=0D
+ //=0D
+ ASSERT (ChildTableAddress =3D=3D (UINTN) ChildTableAddress);=0D
+ if (ChildTableAddress !=3D (UINTN) ChildTableAddress) {=0D
+ Status =3D EFI_ABORTED;=0D
+ break;=0D
+ }=0D
+=0D
+ ChildTable =3D (EFI_ACPI_DESCRIPTION_HEADER *) (UINTN) ChildTableAdd=
ress;=0D
+ Status =3D AddTableToList (AcpiTableInstance, ChildTable, TRUE, Vers=
ion, TRUE, &TableKey);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACPI ta=
ble at 0x%p\n", ChildTable));=0D
+ ASSERT_EFI_ERROR (Status);=0D
+ break;=0D
+ }=0D
+ if (ChildTable->Signature =3D=3D EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION=
_TABLE_SIGNATURE){=0D
+ //=0D
+ // Add the FACS and DSDT tables if it is not NULL.=0D
+ //=0D
+ if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) ChildTable)->Fi=
rmwareCtrl !=3D 0) {=0D
+ TableToInstall =3D (VOID *) (UINTN) ((EFI_ACPI_3_0_FIXED_ACPI_DE=
SCRIPTION_TABLE *) ChildTable)->FirmwareCtrl;=0D
+ Status =3D AddTableToList (AcpiTableInstance, TableToInstall, TR=
UE, Version, TRUE, &TableKey);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACP=
I table FACS\n"));=0D
+ ASSERT_EFI_ERROR (Status);=0D
+ break;=0D
+ }=0D
+ }=0D
+=0D
+ if (((EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE *) ChildTable)->Ds=
dt !=3D 0) {=0D
+ TableToInstall =3D (VOID *) (UINTN) ((EFI_ACPI_3_0_FIXED_ACPI_DE=
SCRIPTION_TABLE *) ChildTable)->Dsdt;=0D
+ Status =3D AddTableToList (AcpiTableInstance, TableToInstall, TR=
UE, Version, TRUE, &TableKey);=0D
+ if (EFI_ERROR (Status)) {=0D
+ DEBUG ((DEBUG_ERROR, "InstallAcpiTableFromHob: Fail to add ACP=
I table DSDT\n"));=0D
+ ASSERT_EFI_ERROR (Status);=0D
+ break;=0D
+ }=0D
+ }=0D
+ }=0D
+ }=0D
+ } else {=0D
+ return EFI_NOT_FOUND;=0D
+ }=0D
+=0D
+ if (EFI_ERROR (Status)) {=0D
+ //=0D
+ // Error happens when trying to add ACPI table to the list.=0D
+ // Remove all of them from list because at this time, no other tables =
except from HOB are in the list=0D
+ //=0D
+ while (SdtGetAcpiTable (AcpiTableInstance, 0, &Table, &Version, &Table=
Key) =3D=3D EFI_SUCCESS) {=0D
+ RemoveTableFromList (AcpiTableInstance, Version, TableKey);=0D
+ }=0D
+ } else {=0D
+ Status =3D PublishTables (AcpiTableInstance, Version);=0D
+ }=0D
+=0D
+ ASSERT_EFI_ERROR (Status);=0D
+ return Status;=0D
+}=0D
=0D
/**=0D
Constructor for the ACPI table protocol. Initializes instance=0D
@@ -1918,6 +2073,8 @@ AcpiTableAcpiTableConstructor (
=0D
ChecksumCommonTables (AcpiTableInstance);=0D
=0D
+ InstallAcpiTableFromHob (AcpiTableInstance);=0D
+=0D
//=0D
// Completed successfully=0D
//=0D
--=20
2.30.0.windows.2


Wu, Hao A
 

-----Original Message-----
From: Liu, Zhiguang <zhiguang.liu@...>
Sent: Friday, June 4, 2021 5:42 PM
To: devel@edk2.groups.io
Cc: Wang, Jian J <jian.j.wang@...>; Wu, Hao A <hao.a.wu@...>;
Bi, Dandan <dandan.bi@...>; Liming Gao
<gaoliming@...>; Ni, Ray <ray.ni@...>
Subject: [Patch V3 8/9] MdeModulePkg/ACPI: Install ACPI table from HOB.

V1:
If HOB contains APCI table information, entry point of AcpiTableDxe.inf
should parse the APCI table from HOB, and install these tables.
We assume the whole ACPI table (starting with
EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER)
is contained by a single gEfiAcpiTableGuid HOB.

V2:
If error happens when installing ACPI table, stop installing and removing all
the tables that
are already added.

Reviewed-by: Hao A Wu <hao.a.wu@...>

Best Regards,
Hao Wu



Cc: Jian J Wang <jian.j.wang@...>
Cc: Hao A Wu <hao.a.wu@...>
Cc: Dandan Bi <dandan.bi@...>
Cc: Liming Gao <gaoliming@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Zhiguang Liu <zhiguang.liu@...>
---
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c | 92
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++---------------------------
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h | 38
+++++++++++++++++++++++++++++++++++++-
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf | 8
+++++---
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c | 171
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++-------
4 files changed, 271 insertions(+), 38 deletions(-)

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. <BR>

+ Copyright (c) 2010 - 2021, Intel Corporation. All rights reserved. <BR>

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.<BR>

+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent



**/

@@ -24,6 +24,8 @@
#include <Library/MemoryAllocationLib.h>

#include <Library/UefiBootServicesTableLib.h>

#include <Library/PcdLib.h>

+#include <Library/HobLib.h>

+#include <UniversalPayload/AcpiTable.h>



//

// 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..9e34f8ea41 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.<BR>

+# Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>

# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>

# 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

+ gPldAcpiTableGuid ## 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..cd79a1082c 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.<BR>

+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>

Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>

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 gPldAcpiTableGuid 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;

+ PLD_ACPI_TABLE *AcpiTableAdress;

+ VOID *TableToInstall;

+ EFI_ACPI_SDT_HEADER *Table;

+ PLD_GENERIC_HEADER *GenericHeader;

+

+ TableKey = 0;

+ Version = PcdGet32 (PcdAcpiExposedTableVersions);

+ Status = EFI_SUCCESS;

+ //

+ // HOB only contains the ACPI table in 2.0+ format.

+ //

+ GuidHob = GetFirstGuidHob (&gPldAcpiTableGuid);

+ if (GuidHob == NULL) {

+ return EFI_NOT_FOUND;

+ }

+

+ GenericHeader = (PLD_GENERIC_HEADER *) GET_GUID_HOB_DATA
(GuidHob);

+ if ((sizeof (PLD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE
(GuidHob)) || (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE
(GuidHob))) {

+ return EFI_NOT_FOUND;

+ }

+ if (GenericHeader->Revision == PLD_ACPI_TABLE_REVISION) {

+ //

+ // PLD_ACPI_TABLE structure is used when Revision equals to
PLD_ACPI_TABLE_REVISION

+ //

+ AcpiTableAdress = (PLD_ACPI_TABLE *) GET_GUID_HOB_DATA
(GuidHob);

+ if (AcpiTableAdress->PldHeader.Length < PLD_SIZEOF_THROUGH_FIELD
(PLD_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

//

--
2.30.0.windows.2