[edk2,wave,1,v2,5/6] OvmfPkg: AcpiPlatformDxe: when PCI is enabled, wait for Platform BDS's cue

Message ID 1458744370-10318-6-git-send-email-lersek@redhat.com
State New
Headers show

Commit Message

Laszlo Ersek March 23, 2016, 2:46 p.m.
This patch doesn't change the behavior of AcpiPlatformDxe when
PcdPciDisableBusEnumeration is TRUE -- that is, when the driver runs on
Xen (OvmfPkg and ArmVirtPkg both), or when the driver runs on QEMU as part
of ArmVirtPkg but no PCI host bridge was found by VirtFdtDxe. In these
cases the driver continues to install the ACPI tables immediately.

However, when PcdPciDisableBusEnumeration is FALSE (i.e., when the driver
runs on QEMU as part of OVMF, or as part of ArmVirtPkg and VirtFdtDxe
finds a PCI host bridge), we now delay the ACPI table download from QEMU.
We wait until the Platform BDS tells us that root bridges have been
connected, and PciIo instances are available.

The explanation is in the patch titled

  OvmfPkg: introduce gRootBridgesConnectedEventGroupGuid

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Jordan Justen <jordan.l.justen@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>

---

Notes:
    v2:
    - replace protocol with event group [Jordan]

 OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf          |  2 +-
 OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf |  4 +-
 OvmfPkg/AcpiPlatformDxe/EntryPoint.c                 | 48 ++++++--------------
 3 files changed, 18 insertions(+), 36 deletions(-)

-- 
1.8.3.1


_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Patch

diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
index 055f3ad0ee0f..8e98053994eb 100644
--- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
+++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -53,18 +53,18 @@  [LibraryClasses]
   MemoryAllocationLib
   BaseLib
   DxeServicesTableLib
   OrderedCollectionLib
 
 [Protocols]
   gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
-  gEfiPciEnumerationCompleteProtocolGuid        # PROTOCOL SOMETIMES_CONSUMED
 
 [Guids]
   gEfiXenInfoGuid
+  gRootBridgesConnectedEventGroupGuid
 
 [Pcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile
   gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
   gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress
   gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel
   gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
diff --git a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf
index 22ce165852f9..c073b2a47ec6 100644
--- a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf
+++ b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf
@@ -43,14 +43,16 @@  [LibraryClasses]
   OrderedCollectionLib
   QemuFwCfgLib
   UefiBootServicesTableLib
   UefiDriverEntryPoint
 
 [Protocols]
   gEfiAcpiTableProtocolGuid                     # PROTOCOL ALWAYS_CONSUMED
-  gEfiPciEnumerationCompleteProtocolGuid        # PROTOCOL SOMETIMES_CONSUMED
+
+[Guids]
+  gRootBridgesConnectedEventGroupGuid
 
 [Pcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
 
 [Depex]
   gEfiAcpiTableProtocolGuid
diff --git a/OvmfPkg/AcpiPlatformDxe/EntryPoint.c b/OvmfPkg/AcpiPlatformDxe/EntryPoint.c
index d713b0d44b1b..1bfd31a0371a 100644
--- a/OvmfPkg/AcpiPlatformDxe/EntryPoint.c
+++ b/OvmfPkg/AcpiPlatformDxe/EntryPoint.c
@@ -9,15 +9,15 @@ 
   distribution.  The full text of the license may be found at
   http://opensource.org/licenses/bsd-license.php
 
   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/
 
-#include <Protocol/PciEnumerationComplete.h>
+#include <Guid/RootBridgesConnectedEventGroup.h>
 #include "AcpiPlatform.h"
 
 STATIC
 EFI_ACPI_TABLE_PROTOCOL *
 FindAcpiTableProtocol (
   VOID
   )
@@ -34,22 +34,23 @@  FindAcpiTableProtocol (
   return AcpiTable;
 }
 
 
 STATIC
 VOID
 EFIAPI
-OnPciEnumerated (
+OnRootBridgesConnected (
   IN EFI_EVENT Event,
   IN VOID      *Context
   )
 {
   EFI_STATUS Status;
 
-  DEBUG ((EFI_D_INFO, "%a: PCI enumeration complete, installing ACPI tables\n",
+  DEBUG ((EFI_D_INFO,
+    "%a: root bridges have been connected, installing ACPI tables\n",
     __FUNCTION__));
   Status = InstallAcpiTables (FindAcpiTableProtocol ());
   if (EFI_ERROR (Status)) {
     DEBUG ((EFI_D_ERROR, "%a: InstallAcpiTables: %r\n", __FUNCTION__, Status));
   }
   gBS->CloseEvent (Event);
 }
@@ -59,58 +60,37 @@  EFI_STATUS
 EFIAPI
 AcpiPlatformEntryPoint (
   IN EFI_HANDLE         ImageHandle,
   IN EFI_SYSTEM_TABLE   *SystemTable
   )
 {
   EFI_STATUS Status;
-  VOID       *Interface;
-  EFI_EVENT  PciEnumerated;
-  VOID       *Registration;
+  EFI_EVENT  RootBridgesConnected;
 
   //
   // If the platform doesn't support PCI, or PCI enumeration has been disabled,
   // install the tables at once, and let the entry point's return code reflect
   // the full functionality.
   //
   if (PcdGetBool (PcdPciDisableBusEnumeration)) {
     DEBUG ((EFI_D_INFO, "%a: PCI or its enumeration disabled, installing "
       "ACPI tables\n", __FUNCTION__));
     return InstallAcpiTables (FindAcpiTableProtocol ());
   }
 
   //
-  // Similarly, if PCI enumeration has already completed, install the tables
-  // immediately.
+  // Otherwise, delay installing the ACPI tables until root bridges are
+  // connected. The entry point's return status will only reflect the callback
+  // setup. (Note that we're a DXE_DRIVER; our entry point function is invoked
+  // strictly before BDS is entered and can connect the root bridges.)
   //
-  Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid,
-                  NULL /* Registration */, &Interface);
+  Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
+                  OnRootBridgesConnected, NULL /* Context */,
+                  &gRootBridgesConnectedEventGroupGuid, &RootBridgesConnected);
   if (!EFI_ERROR (Status)) {
-    DEBUG ((EFI_D_INFO, "%a: PCI enumeration already complete, "
-      "installing ACPI tables\n", __FUNCTION__));
-    return InstallAcpiTables (FindAcpiTableProtocol ());
-  }
-  ASSERT (Status == EFI_NOT_FOUND);
-
-  //
-  // Otherwise, delay installing the ACPI tables until PCI enumeration
-  // completes. The entry point's return status will only reflect the callback
-  // setup.
-  //
-  Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, OnPciEnumerated,
-                  NULL /* Context */, &PciEnumerated);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  Status = gBS->RegisterProtocolNotify (
-                  &gEfiPciEnumerationCompleteProtocolGuid, PciEnumerated,
-                  &Registration);
-  if (EFI_ERROR (Status)) {
-    gBS->CloseEvent (PciEnumerated);
-  } else {
-    DEBUG ((EFI_D_INFO, "%a: PCI enumeration pending, registered callback\n",
+    DEBUG ((EFI_D_INFO,
+      "%a: waiting for root bridges to be connected, registered callback\n",
       __FUNCTION__));
   }
 
   return Status;
 }