SVN r16411 delayed ACPI table installation until PCI enumeration was complete, because on QEMU the ACPI-related fw_cfg files should only be downloaded after PCI enumeration.
However, InitializeXen() in "OvmfPkg/PlatformPei/Xen.c" sets PcdPciDisableBusEnumeration to TRUE. This causes PciBusDriverBindingStart() in "MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.c" to set gFullEnumeration to FALSE, which in turn makes PciEnumerator() in "MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c" branch to PciEnumeratorLight(). The installation of EFI_PCI_ENUMERATION_COMPLETE_PROTOCOL at the end of PciEnumerator() is not reached. Which means that starting with SVN r16411, AcpiPlatformDxe is never dispatched on Xen. This patch replaces the EFI_PCI_ENUMERATION_COMPLETE_PROTOCOL depex with a matching protocol registration callback for the PCI enumeration enabled (ie. QEMU) case. When PCI enumeration is disabled (ie. when running on Xen), AcpiPlatformDxe doesn't wait for EFI_PCI_ENUMERATION_COMPLETE_PROTOCOL. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <ler...@redhat.com> --- OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf | 4 +- OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c | 84 +++++++++++++++++++++++------ 2 files changed, 72 insertions(+), 16 deletions(-) diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf index 53292bf..6b2c9d2 100644 --- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf +++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -56,16 +56,18 @@ [Protocols] gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiPciEnumerationCompleteProtocolGuid # PROTOCOL SOMETIMES_CONSUMED [Guids] gEfiXenInfoGuid [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiTableStorageFile + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration gUefiCpuPkgTokenSpaceGuid.PcdCpuLocalApicBaseAddress gPcAtChipsetPkgTokenSpaceGuid.Pcd8259LegacyModeEdgeLevel gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress [Depex] - gEfiAcpiTableProtocolGuid AND gEfiPciEnumerationCompleteProtocolGuid + gEfiAcpiTableProtocolGuid diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c index 11f0ca8..9823eba 100644 --- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c +++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatform.c @@ -12,6 +12,7 @@ **/ +#include <Protocol/PciEnumerationComplete.h> #include "AcpiPlatform.h" EFI_STATUS @@ -221,6 +222,47 @@ FindAcpiTablesInFv ( return EFI_SUCCESS; } +STATIC +EFI_STATUS +EFIAPI +InstallTables ( + VOID + ) +{ + EFI_STATUS Status; + EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, + NULL /* Registration */, (VOID **)&AcpiTable); + if (EFI_ERROR (Status)) { + return EFI_ABORTED; + } + + if (XenDetected ()) { + Status = InstallXenTables (AcpiTable); + } else { + Status = InstallAllQemuLinkedTables (AcpiTable); + } + + if (EFI_ERROR (Status)) { + Status = FindAcpiTablesInFv (AcpiTable); + } + + return Status; +} + +STATIC +VOID +EFIAPI +OnPciEnumerated ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + InstallTables (); + gBS->CloseEvent (Event); +} + /** Entrypoint of Acpi Platform driver. @@ -239,31 +281,43 @@ AcpiPlatformEntryPoint ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; - EFI_ACPI_TABLE_PROTOCOL *AcpiTable; + EFI_STATUS Status; + VOID *Interface; + EFI_EVENT PciEnumerated; + VOID *Registration; // - // Find the AcpiTable protocol + // If PCI enumeration has been disabled, or it has already completed, install + // the tables at once, and let the entry point's return code reflect the full + // functionality. // - Status = gBS->LocateProtocol ( - &gEfiAcpiTableProtocolGuid, - NULL, - (VOID**)&AcpiTable - ); - if (EFI_ERROR (Status)) { - return EFI_ABORTED; + if (PcdGetBool (PcdPciDisableBusEnumeration)) { + return InstallTables (); } - if (XenDetected ()) { - Status = InstallXenTables (AcpiTable); - } else { - Status = InstallAllQemuLinkedTables (AcpiTable); + Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, + NULL /* Registration */, &Interface); + if (!EFI_ERROR (Status)) { + return InstallTables (); } + ASSERT (Status == EFI_NOT_FOUND); + // + // Otherwise, delay the installation until PCI enumeration is complete. 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)) { - Status = FindAcpiTablesInFv (AcpiTable); + return Status; } + Status = gBS->RegisterProtocolNotify ( + &gEfiPciEnumerationCompleteProtocolGuid, PciEnumerated, + &Registration); + if (EFI_ERROR (Status)) { + gBS->CloseEvent (PciEnumerated); + } return Status; } -- 1.8.3.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel