]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/ACPI: Install ACPI table from HOB.
authorZhiguang Liu <zhiguang.liu@intel.com>
Fri, 30 Apr 2021 06:17:56 +0000 (14:17 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 16 Jun 2021 05:20:19 +0000 (05:20 +0000)
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.

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

Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Ray Ni <ray.ni@intel.com>
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
Tested-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c

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