diff --git a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf index 0ba703dcec..055f3ad0ee 100644 --- a/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf +++ b/OvmfPkg/AcpiPlatformDxe/AcpiPlatformDxe.inf @@ -57,16 +57,17 @@ [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/EntryPoint.c b/OvmfPkg/AcpiPlatformDxe/EntryPoint.c index d782b610bd..d713b0d44b 100644 --- a/OvmfPkg/AcpiPlatformDxe/EntryPoint.c +++ b/OvmfPkg/AcpiPlatformDxe/EntryPoint.c @@ -13,6 +13,7 @@ WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ +#include #include "AcpiPlatform.h" STATIC @@ -33,6 +34,27 @@ FindAcpiTableProtocol ( return AcpiTable; } + +STATIC +VOID +EFIAPI +OnPciEnumerated ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + DEBUG ((EFI_D_INFO, "%a: PCI enumeration complete, 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); +} + + EFI_STATUS EFIAPI AcpiPlatformEntryPoint ( @@ -41,7 +63,54 @@ AcpiPlatformEntryPoint ( ) { EFI_STATUS Status; + VOID *Interface; + EFI_EVENT PciEnumerated; + VOID *Registration; + + // + // 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. + // + Status = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, + NULL /* Registration */, &Interface); + 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", + __FUNCTION__)); + } - Status = InstallAcpiTables (FindAcpiTableProtocol ()); return Status; } diff --git a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf index 13c8009ed2..22ce165852 100644 --- a/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf +++ b/OvmfPkg/AcpiPlatformDxe/QemuFwCfgAcpiPlatformDxe.inf @@ -33,6 +33,7 @@ [Packages] MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec OvmfPkg/OvmfPkg.dec [LibraryClasses] @@ -46,9 +47,10 @@ [Protocols] gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiPciEnumerationCompleteProtocolGuid # PROTOCOL SOMETIMES_CONSUMED + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration [Depex] gEfiAcpiTableProtocolGuid - -[Depex.IA32, Depex.X64] - gEfiPciEnumerationCompleteProtocolGuid