public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Kun Qin" <kuqin12@gmail.com>
To: devel@edk2.groups.io
Cc: Sami Mujawar <Sami.Mujawar@arm.com>,
	Alexei Fedorov <Alexei.Fedorov@arm.com>,
	Joe Lopez <joelopez@microsoft.com>
Subject: [PATCH v1 4/6] DynamicTablesPkg: DynamicTableManagerDxe: Added check for installed tables
Date: Mon, 18 Jul 2022 17:22:52 -0700	[thread overview]
Message-ID: <20220719002254.1891-5-kuqin12@gmail.com> (raw)
In-Reply-To: <20220719002254.1891-1-kuqin12@gmail.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3997

This change added an extra step to allow check for installed ACPI tables.

For FADT, MADT, GTDT, DSDT and DBG2 tables, either pre-installed or
supplied through AcpiTableInfo can be accepted.

An extra check for FADT ACPI table existence during installation step is
also added.

Cc: Sami Mujawar <Sami.Mujawar@arm.com>
Cc: Alexei Fedorov <Alexei.Fedorov@arm.com>

Co-authored-by: Joe Lopez <joelopez@microsoft.com>
Signed-off-by: Kun Qin <kuqin12@gmail.com>
---
 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c   | 200 ++++++++++++++++----
 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf |   1 +
 2 files changed, 167 insertions(+), 34 deletions(-)

diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
index ed62299f9bbd..ac5fe0bed91b 100644
--- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c
@@ -11,6 +11,7 @@
 #include <Library/PcdLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Protocol/AcpiTable.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
 
 // Module specific include files.
 #include <AcpiTableGenerator.h>
@@ -387,6 +388,57 @@ BuildAndInstallAcpiTable (
   return Status;
 }
 
+/**
+  This function uses the ACPI SDT protocol to locate an ACPI table.
+  It is really only useful for finding tables that only have a single instance,
+  e.g. FADT, FACS, MADT, etc.  It is not good for locating SSDT, etc.
+
+  @param[in] Signature           - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+  @param[in, out] Table          - Updated with a pointer to the table
+  @param[in, out] Handle         - AcpiSupport protocol table handle for the table found
+
+  @retval EFI_SUCCESS            - The function completed successfully.
+**/
+STATIC
+EFI_STATUS
+LocateAcpiTableBySignature (
+  IN      UINT32                       Signature,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER  **Table,
+  IN OUT  UINTN                        *Handle
+  )
+{
+  EFI_STATUS              Status;
+  INTN                    Index;
+  EFI_ACPI_TABLE_VERSION  Version;
+  EFI_ACPI_SDT_PROTOCOL   *AcpiSdt;
+
+  AcpiSdt = NULL;
+  Status  = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiSdt);
+
+  if (EFI_ERROR (Status) || (AcpiSdt == NULL)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Locate table with matching ID
+  //
+  Version = 0;
+  Index   = 0;
+  do {
+    Status = AcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER **)Table, &Version, Handle);
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+
+    Index++;
+  } while ((*Table)->Signature != Signature);
+
+  //
+  // If we found the table, there will be no error.
+  //
+  return Status;
+}
+
 /** The function checks if the Configuration Manager has provided the
     mandatory ACPI tables for installation.
 
@@ -411,6 +463,9 @@ VerifyMandatoryTablesArePresent (
   BOOLEAN     DsdtFound;
   BOOLEAN     Dbg2Found;
   BOOLEAN     SpcrFound;
+  UINTN       Handle;
+
+  EFI_ACPI_DESCRIPTION_HEADER  *DummyHeader;
 
   Status    = EFI_SUCCESS;
   FadtFound = FALSE;
@@ -447,32 +502,99 @@ VerifyMandatoryTablesArePresent (
   }
 
   // We need at least the FADT, MADT, GTDT and the DSDT tables to boot
-  if (!FadtFound) {
-    DEBUG ((DEBUG_ERROR, "ERROR: FADT Table not found\n"));
+  // But they also might be published already, so we can search from there
+  Handle = 0;
+  Status = LocateAcpiTableBySignature (
+             EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+             &DummyHeader,
+             &Handle
+             );
+  if (EFI_ERROR (Status) && !FadtFound) {
+    DEBUG ((DEBUG_ERROR, "ERROR: FADT Table not found.\n"));
     Status = EFI_NOT_FOUND;
+  } else if (!EFI_ERROR (Status) && FadtFound) {
+    DEBUG ((DEBUG_ERROR, "ERROR: FADT Table found while already published.\n"));
+    Status = EFI_ALREADY_STARTED;
+  } else {
+    FadtFound = TRUE;
   }
 
-  if (!MadtFound) {
+  Handle = 0;
+  Status = LocateAcpiTableBySignature (
+             EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+             &DummyHeader,
+             &Handle
+             );
+  if (EFI_ERROR (Status) && !MadtFound) {
     DEBUG ((DEBUG_ERROR, "ERROR: MADT Table not found.\n"));
     Status = EFI_NOT_FOUND;
+  } else if (!EFI_ERROR (Status) && MadtFound) {
+    DEBUG ((DEBUG_ERROR, "ERROR: MADT Table found while already published.\n"));
+    Status = EFI_ALREADY_STARTED;
+  } else {
+    MadtFound = TRUE;
   }
 
-  if (!GtdtFound) {
+  Handle = 0;
+  Status = LocateAcpiTableBySignature (
+             EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
+             &DummyHeader,
+             &Handle
+             );
+  if (EFI_ERROR (Status) && !GtdtFound) {
     DEBUG ((DEBUG_ERROR, "ERROR: GTDT Table not found.\n"));
     Status = EFI_NOT_FOUND;
+  } else if (!EFI_ERROR (Status) && GtdtFound) {
+    DEBUG ((DEBUG_ERROR, "ERROR: GTDT Table found while already published.\n"));
+    Status = EFI_ALREADY_STARTED;
+  } else {
+    GtdtFound = TRUE;
   }
 
-  if (!DsdtFound) {
+  Handle = 0;
+  Status = LocateAcpiTableBySignature (
+             EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+             &DummyHeader,
+             &Handle
+             );
+  if (EFI_ERROR (Status) && !DsdtFound) {
     DEBUG ((DEBUG_ERROR, "ERROR: DSDT Table not found.\n"));
     Status = EFI_NOT_FOUND;
+  } else if (!EFI_ERROR (Status) && DsdtFound) {
+    DEBUG ((DEBUG_ERROR, "ERROR: DSDT Table found while already published.\n"));
+    Status = EFI_ALREADY_STARTED;
+  } else {
+    DsdtFound = TRUE;
   }
 
-  if (!Dbg2Found) {
+  Handle = 0;
+  Status = LocateAcpiTableBySignature (
+             EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE,
+             &DummyHeader,
+             &Handle
+             );
+  if (EFI_ERROR (Status) && !Dbg2Found) {
     DEBUG ((DEBUG_WARN, "WARNING: DBG2 Table not found.\n"));
+  } else if (!EFI_ERROR (Status) && Dbg2Found) {
+    DEBUG ((DEBUG_ERROR, "ERROR: DBG2 Table found while already published.\n"));
+    Status = EFI_ALREADY_STARTED;
+  } else {
+    Dbg2Found = TRUE;
   }
 
-  if (!SpcrFound) {
+  Handle = 0;
+  Status = LocateAcpiTableBySignature (
+             EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
+             &DummyHeader,
+             &Handle
+             );
+  if (EFI_ERROR (Status) && !SpcrFound) {
     DEBUG ((DEBUG_WARN, "WARNING: SPCR Table not found.\n"));
+  } else if (!EFI_ERROR (Status) && SpcrFound) {
+    DEBUG ((DEBUG_ERROR, "ERROR: SPCR Table found while already published.\n"));
+    Status = EFI_ALREADY_STARTED;
+  } else {
+    SpcrFound = TRUE;
   }
 
   return Status;
@@ -500,11 +622,13 @@ ProcessAcpiTables (
   IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol
   )
 {
-  EFI_STATUS                  Status;
-  EFI_ACPI_TABLE_PROTOCOL     *AcpiTableProtocol;
-  CM_STD_OBJ_ACPI_TABLE_INFO  *AcpiTableInfo;
-  UINT32                      AcpiTableCount;
-  UINT32                      Idx;
+  EFI_STATUS                   Status;
+  EFI_ACPI_TABLE_PROTOCOL      *AcpiTableProtocol;
+  CM_STD_OBJ_ACPI_TABLE_INFO   *AcpiTableInfo;
+  UINT32                       AcpiTableCount;
+  UINT32                       Idx;
+  UINTN                        Handle;
+  EFI_ACPI_DESCRIPTION_HEADER  *DummyHeader;
 
   ASSERT (TableFactoryProtocol != NULL);
   ASSERT (CfgMgrProtocol != NULL);
@@ -570,29 +694,37 @@ ProcessAcpiTables (
   }
 
   // Add the FADT Table first.
-  for (Idx = 0; Idx < AcpiTableCount; Idx++) {
-    if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) ==
-        AcpiTableInfo[Idx].TableGeneratorId)
-    {
-      Status = BuildAndInstallAcpiTable (
-                 TableFactoryProtocol,
-                 CfgMgrProtocol,
-                 AcpiTableProtocol,
-                 &AcpiTableInfo[Idx]
-                 );
-      if (EFI_ERROR (Status)) {
-        DEBUG ((
-          DEBUG_ERROR,
-          "ERROR: Failed to find build and install ACPI FADT Table." \
-          " Status = %r\n",
-          Status
-          ));
-        return Status;
+  Status = LocateAcpiTableBySignature (
+             EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+             &DummyHeader,
+             &Handle
+             );
+  if (EFI_ERROR (Status)) {
+    // FADT is not yet installed
+    for (Idx = 0; Idx < AcpiTableCount; Idx++) {
+      if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) ==
+          AcpiTableInfo[Idx].TableGeneratorId)
+      {
+        Status = BuildAndInstallAcpiTable (
+                   TableFactoryProtocol,
+                   CfgMgrProtocol,
+                   AcpiTableProtocol,
+                   &AcpiTableInfo[Idx]
+                   );
+        if (EFI_ERROR (Status)) {
+          DEBUG ((
+            DEBUG_ERROR,
+            "ERROR: Failed to find build and install ACPI FADT Table." \
+            " Status = %r\n",
+            Status
+            ));
+          return Status;
+        }
+
+        break;
       }
-
-      break;
-    }
-  } // for
+    } // for
+  }
 
   // Add remaining ACPI Tables
   for (Idx = 0; Idx < AcpiTableCount; Idx++) {
diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
index 028c3d413cf8..5ca98c8b4895 100644
--- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
+++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf
@@ -36,6 +36,7 @@ [LibraryClasses]
 
 [Protocols]
   gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
+  gEfiAcpiSdtProtocolGuid                       # PROTOCOL ALWAYS_CONSUMED
 
   gEdkiiConfigurationManagerProtocolGuid        # PROTOCOL ALWAYS_CONSUMED
   gEdkiiDynamicTableFactoryProtocolGuid         # PROTOCOL ALWAYS_CONSUMED
-- 
2.36.0.windows.1


  parent reply	other threads:[~2022-07-19  0:25 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-19  0:22 [PATCH v1 0/6] Enhance DynamicTablesPkg modules Kun Qin
2022-07-19  0:22 ` [PATCH v1 1/6] DynamicTablesPkg: DynamicPlatRepoLib: Added MemoryAllocationLib to inf Kun Qin
2022-07-20 10:03   ` Sami Mujawar
2022-07-19  0:22 ` [PATCH v1 2/6] DynamicTablesPkg: DynamicPlatRepoLib: Fix incorrect dereferencing Kun Qin
2022-07-20 10:06   ` Sami Mujawar
2022-07-19  0:22 ` [PATCH v1 3/6] DynamicTablesPkg: DynamicPlatRepoLib: Adding more token fixers Kun Qin
2022-07-20 10:39   ` Sami Mujawar
2022-07-19  0:22 ` Kun Qin [this message]
2022-07-20 11:00   ` [PATCH v1 4/6] DynamicTablesPkg: DynamicTableManagerDxe: Added check for installed tables Sami Mujawar
2022-07-21  1:48     ` Kun Qin
2022-07-20 13:36   ` [edk2-devel] " PierreGondois
2022-07-19  0:22 ` [PATCH v1 5/6] DynamicTablesPkg: AcpiSsdtPcieLibArm: Added function to reserve ECAM space Kun Qin
2022-07-20 13:36   ` [edk2-devel] " PierreGondois
2022-07-19  0:22 ` [PATCH v1 6/6] DynamicTablesPkg: AcpiSsdtPcieLibArm: Added case handling for PCI config Kun Qin
2022-07-20 13:38 ` [edk2-devel] [PATCH v1 0/6] Enhance DynamicTablesPkg modules PierreGondois
2022-07-21  1:45   ` Kun Qin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220719002254.1891-5-kuqin12@gmail.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox