diff options
Diffstat (limited to 'OvmfPkg/AcpiPlatformDxe/EntryPoint.c')
-rw-r--r-- | OvmfPkg/AcpiPlatformDxe/EntryPoint.c | 71 |
1 files changed, 70 insertions, 1 deletions
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 <Protocol/PciEnumerationComplete.h>
#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;
}
|