]> git.proxmox.com Git - mirror_edk2.git/blobdiff - OvmfPkg/AcpiPlatformDxe/EntryPoint.c
OvmfPkg: AcpiPlatformDxe: make dependency on PCI enumeration dynamic
[mirror_edk2.git] / OvmfPkg / AcpiPlatformDxe / EntryPoint.c
index d782b610bd0814ab2914d6fc8d3033a532106c0b..d713b0d44b1b96f55caaa8f10166be8d1f3169b5 100644 (file)
@@ -13,6 +13,7 @@
   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 **/\r
 \r
+#include <Protocol/PciEnumerationComplete.h>\r
 #include "AcpiPlatform.h"\r
 \r
 STATIC\r
@@ -33,6 +34,27 @@ FindAcpiTableProtocol (
   return AcpiTable;\r
 }\r
 \r
+\r
+STATIC\r
+VOID\r
+EFIAPI\r
+OnPciEnumerated (\r
+  IN EFI_EVENT Event,\r
+  IN VOID      *Context\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  DEBUG ((EFI_D_INFO, "%a: PCI enumeration complete, installing ACPI tables\n",\r
+    __FUNCTION__));\r
+  Status = InstallAcpiTables (FindAcpiTableProtocol ());\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "%a: InstallAcpiTables: %r\n", __FUNCTION__, Status));\r
+  }\r
+  gBS->CloseEvent (Event);\r
+}\r
+\r
+\r
 EFI_STATUS\r
 EFIAPI\r
 AcpiPlatformEntryPoint (\r
@@ -41,7 +63,54 @@ AcpiPlatformEntryPoint (
   )\r
 {\r
   EFI_STATUS Status;\r
+  VOID       *Interface;\r
+  EFI_EVENT  PciEnumerated;\r
+  VOID       *Registration;\r
+\r
+  //\r
+  // If the platform doesn't support PCI, or PCI enumeration has been disabled,\r
+  // install the tables at once, and let the entry point's return code reflect\r
+  // the full functionality.\r
+  //\r
+  if (PcdGetBool (PcdPciDisableBusEnumeration)) {\r
+    DEBUG ((EFI_D_INFO, "%a: PCI or its enumeration disabled, installing "\r
+      "ACPI tables\n", __FUNCTION__));\r
+    return InstallAcpiTables (FindAcpiTableProtocol ());\r
+  }\r
+\r
+  //\r
+  // Similarly, if PCI enumeration has already completed, install the tables\r
+  // immediately.\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid,\r
+                  NULL /* Registration */, &Interface);\r
+  if (!EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_INFO, "%a: PCI enumeration already complete, "\r
+      "installing ACPI tables\n", __FUNCTION__));\r
+    return InstallAcpiTables (FindAcpiTableProtocol ());\r
+  }\r
+  ASSERT (Status == EFI_NOT_FOUND);\r
+\r
+  //\r
+  // Otherwise, delay installing the ACPI tables until PCI enumeration\r
+  // completes. The entry point's return status will only reflect the callback\r
+  // setup.\r
+  //\r
+  Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, OnPciEnumerated,\r
+                  NULL /* Context */, &PciEnumerated);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = gBS->RegisterProtocolNotify (\r
+                  &gEfiPciEnumerationCompleteProtocolGuid, PciEnumerated,\r
+                  &Registration);\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->CloseEvent (PciEnumerated);\r
+  } else {\r
+    DEBUG ((EFI_D_INFO, "%a: PCI enumeration pending, registered callback\n",\r
+      __FUNCTION__));\r
+  }\r
 \r
-  Status = InstallAcpiTables (FindAcpiTableProtocol ());\r
   return Status;\r
 }\r