Laszlo, All are good except: can you use EfiCreateProtocolNotifyEvent() exposed by UefiLib?
Regards, Ray >-----Original Message----- >From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Laszlo >Ersek >Sent: Thursday, May 19, 2016 6:13 AM >To: edk2-devel-01 <edk2-de...@ml01.01.org> >Cc: Ni, Ruiyu <ruiyu...@intel.com>; Justen, Jordan L ><jordan.l.jus...@intel.com> >Subject: [edk2] [PATCH] OvmfPkg: prevent 64-bit MMIO BAR degradation if there >is no CSM > >According to edk2 commit > > "MdeModulePkg/PciBus: do not improperly degrade resource" > >and to the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL definition in the >Platform Init 1.4a specification, a platform can provide such a protocol >in order to influence the PCI resource allocation performed by the PCI Bus >driver. > >In particular it is possible instruct the PCI Bus driver, with a >"wildcard" hint, to allocate the 64-bit MMIO BARs of a device in 64-bit >address space, regardless of whether the device features an option ROM. > >(By default, the PCI Bus driver considers an option ROM reason enough for >allocating the 64-bit MMIO BARs in 32-bit address space. It cannot know if >BDS will launch a legacy boot option, and under legacy boot, a legacy BIOS >binary from a combined option ROM could be dispatched, and fail to access >MMIO BARs in 64-bit address space.) > >In platform code we can ascertain whether a CSM is present or not. If not, >then legacy BIOS binaries in option ROMs can't be dispatched, hence the >BAR degradation is detrimental, and we should prevent it. This is expected >to conserve the 32-bit address space for 32-bit MMIO BARs. > >The driver added in this patch could be simplified based on the following >facts: > >- In the Ia32 build, the 64-bit MMIO aperture is always zero-size, hence > the driver will exit immediately. Therefore the driver could be omitted > from the Ia32 build. > >- In the Ia32X64 and X64 builds, the driver could be omitted if CSM_ENABLE > was defined (because in that case the degradation would be justified). > On the other hand, if CSM_ENABLE was undefined, then the driver could be > included, and it could provide the hint unconditionally (without looking > for the Legacy BIOS protocol). > >These short-cuts are not taken because they would increase the differences >between the OVMF DSC/FDF files. If we can manage without extreme >complexity, we should use dynamic logic (vs. build time configuration), >plus keep conditional compilation to a minimum. > >Cc: Jordan Justen <jordan.l.jus...@intel.com> >Cc: Ruiyu Ni <ruiyu...@intel.com> >Contributed-under: TianoCore Contribution Agreement 1.0 >Signed-off-by: Laszlo Ersek <ler...@redhat.com> >--- > >Notes: > This patch will make a difference only when Ray's patch at > <http://thread.gmane.org/gmane.comp.bios.edk2.devel/12290/focus=12292> > is committed. > > OvmfPkg/OvmfPkgIa32.dsc | > 1 + > OvmfPkg/OvmfPkgIa32X64.dsc | > 1 + > OvmfPkg/OvmfPkgX64.dsc | > 1 + > OvmfPkg/OvmfPkgIa32.fdf | > 1 + > OvmfPkg/OvmfPkgIa32X64.fdf | > 1 + > OvmfPkg/OvmfPkgX64.fdf | > 1 + > OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf | > 50 +++ > OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c | > 353 ++++++++++++++++++++ > 8 files changed, 409 insertions(+) > >diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc >index 45569f2875b5..1becb65cd878 100644 >--- a/OvmfPkg/OvmfPkgIa32.dsc >+++ b/OvmfPkg/OvmfPkgIa32.dsc >@@ -552,6 +552,7 @@ [Components] > UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf > UefiCpuPkg/CpuDxe/CpuDxe.inf > PcAtChipsetPkg/8254TimerDxe/8254Timer.inf >+ OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf > MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf { > <LibraryClasses> > PciHostBridgeLib|OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf >diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc >index 05ff1c914455..3d838cdcb125 100644 >--- a/OvmfPkg/OvmfPkgIa32X64.dsc >+++ b/OvmfPkg/OvmfPkgIa32X64.dsc >@@ -561,6 +561,7 @@ [Components.X64] > UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf > UefiCpuPkg/CpuDxe/CpuDxe.inf > PcAtChipsetPkg/8254TimerDxe/8254Timer.inf >+ OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf > MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf { > <LibraryClasses> > PciHostBridgeLib|OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf >diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc >index 54d4413f11f6..16d58bad7865 100644 >--- a/OvmfPkg/OvmfPkgX64.dsc >+++ b/OvmfPkg/OvmfPkgX64.dsc >@@ -559,6 +559,7 @@ [Components] > UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf > UefiCpuPkg/CpuDxe/CpuDxe.inf > PcAtChipsetPkg/8254TimerDxe/8254Timer.inf >+ OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf > MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf { > <LibraryClasses> > PciHostBridgeLib|OvmfPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf >diff --git a/OvmfPkg/OvmfPkgIa32.fdf b/OvmfPkg/OvmfPkgIa32.fdf >index 594e84fd713b..8ab1633f832a 100644 >--- a/OvmfPkg/OvmfPkgIa32.fdf >+++ b/OvmfPkg/OvmfPkgIa32.fdf >@@ -207,6 +207,7 @@ [FV.DXEFV] > INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf > INF UefiCpuPkg/CpuDxe/CpuDxe.inf > INF PcAtChipsetPkg/8254TimerDxe/8254Timer.inf >+INF OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf > INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf > INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > INF PcAtChipsetPkg/KbcResetDxe/Reset.inf >diff --git a/OvmfPkg/OvmfPkgIa32X64.fdf b/OvmfPkg/OvmfPkgIa32X64.fdf >index 36a8f7e279c3..85fead07e957 100644 >--- a/OvmfPkg/OvmfPkgIa32X64.fdf >+++ b/OvmfPkg/OvmfPkgIa32X64.fdf >@@ -207,6 +207,7 @@ [FV.DXEFV] > INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf > INF UefiCpuPkg/CpuDxe/CpuDxe.inf > INF PcAtChipsetPkg/8254TimerDxe/8254Timer.inf >+INF OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf > INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf > INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > INF PcAtChipsetPkg/KbcResetDxe/Reset.inf >diff --git a/OvmfPkg/OvmfPkgX64.fdf b/OvmfPkg/OvmfPkgX64.fdf >index 4b1fa944ad1b..dd5ea30662d6 100644 >--- a/OvmfPkg/OvmfPkgX64.fdf >+++ b/OvmfPkg/OvmfPkgX64.fdf >@@ -207,6 +207,7 @@ [FV.DXEFV] > INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf > INF UefiCpuPkg/CpuDxe/CpuDxe.inf > INF PcAtChipsetPkg/8254TimerDxe/8254Timer.inf >+INF OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf > INF MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf > INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf > INF PcAtChipsetPkg/KbcResetDxe/Reset.inf >diff --git >a/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf >b/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf >new file mode 100644 >index 000000000000..883e45c17436 >--- /dev/null >+++ b/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.inf >@@ -0,0 +1,50 @@ >+## @file >+# A simple DXE_DRIVER that causes the PCI Bus UEFI_DRIVER to allocate 64-bit >+# MMIO BARs above 4 GB, regardless of option ROM availability (as long as a >CSM >+# is not present), conserving 32-bit MMIO aperture for 32-bit BARs. >+# >+# Copyright (C) 2016, Red Hat, Inc. >+# >+# This program and the accompanying materials are licensed and made available >+# under the terms and conditions of the BSD License which accompanies this >+# 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. >+## >+ >+[Defines] >+ INF_VERSION = 0x00010005 >+ BASE_NAME = IncompatiblePciDeviceSupportDxe >+ FILE_GUID = F6697AC4-A776-4EE1-B643-1FEFF2B615BB >+ MODULE_TYPE = DXE_DRIVER >+ VERSION_STRING = 1.0 >+ ENTRY_POINT = DriverInitialize >+ >+[Sources] >+ IncompatiblePciDeviceSupport.c >+ >+[Packages] >+ IntelFrameworkPkg/IntelFrameworkPkg.dec >+ MdeModulePkg/MdeModulePkg.dec >+ MdePkg/MdePkg.dec >+ OvmfPkg/OvmfPkg.dec >+ >+[LibraryClasses] >+ DebugLib >+ MemoryAllocationLib >+ PcdLib >+ UefiBootServicesTableLib >+ UefiDriverEntryPoint >+ >+[Protocols] >+ gEfiIncompatiblePciDeviceSupportProtocolGuid ## SOMETIMES_PRODUCES >+ gEfiLegacyBiosProtocolGuid ## NOTIFY >+ >+[Pcd] >+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration ## CONSUMES >+ gUefiOvmfPkgTokenSpaceGuid.PcdPciMmio64Size ## CONSUMES >+ >+[Depex] >+ TRUE >diff --git >a/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c >b/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c >new file mode 100644 >index 000000000000..b6ff12842c21 >--- /dev/null >+++ b/OvmfPkg/IncompatiblePciDeviceSupportDxe/IncompatiblePciDeviceSupport.c >@@ -0,0 +1,353 @@ >+/** @file >+ A simple DXE_DRIVER that causes the PCI Bus UEFI_DRIVER to allocate 64-bit >+ MMIO BARs above 4 GB, regardless of option ROM availability (as long as a >CSM >+ is not present), conserving 32-bit MMIO aperture for 32-bit BARs. >+ >+ Copyright (C) 2016, Red Hat, Inc. >+ >+ This program and the accompanying materials are licensed and made available >+ under the terms and conditions of the BSD License which accompanies this >+ 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 <IndustryStandard/Acpi10.h> >+#include <IndustryStandard/Pci22.h> >+ >+#include <Library/DebugLib.h> >+#include <Library/MemoryAllocationLib.h> >+#include <Library/PcdLib.h> >+#include <Library/UefiBootServicesTableLib.h> >+ >+#include <Protocol/IncompatiblePciDeviceSupport.h> >+#include <Protocol/LegacyBios.h> >+ >+// >+// The Legacy BIOS protocol has been located. >+// >+STATIC BOOLEAN mLegacyBiosInstalled; >+ >+// >+// The protocol interface this driver produces. >+// >+STATIC EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL >+ >mIncompatiblePciDeviceSupport; >+ >+// >+// Configuration template for the CheckDevice() protocol member function. >+// >+// Refer to Table 20 "ACPI 2.0 & 3.0 QWORD Address Space Descriptor Usage" in >+// the Platform Init 1.4a Spec, Volume 5. >+// >+// This structure is interpreted by the UpdatePciInfo() function in the edk2 >+// PCI Bus UEFI_DRIVER. >+// >+#pragma pack (1) >+typedef struct { >+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR AddressSpaceDesc; >+ EFI_ACPI_END_TAG_DESCRIPTOR EndDesc; >+} MMIO64_PREFERENCE; >+#pragma pack () >+ >+STATIC CONST MMIO64_PREFERENCE mConfiguration = { >+ // >+ // AddressSpaceDesc >+ // >+ { >+ ACPI_ADDRESS_SPACE_DESCRIPTOR, // Desc >+ (UINT16)( // Len >+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - >+ OFFSET_OF ( >+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR, >+ ResType >+ ) >+ ), >+ ACPI_ADDRESS_SPACE_TYPE_MEM, // ResType >+ PCI_ACPI_UNUSED, // GenFlag >+ PCI_ACPI_UNUSED, // SpecificFlag >+ 64, // AddrSpaceGranularity: >+ // aperture selection >hint >+ // for BAR allocation >+ PCI_ACPI_UNUSED, // AddrRangeMin >+ PCI_BAR_OLD_ALIGN, // AddrRangeMax: >+ // no special alignment >+ // for affected BARs >+ PCI_BAR_ALL, // AddrTranslationOffset: >+ // hint covers all >+ // eligible BARs >+ PCI_BAR_NOCHANGE // AddrLen: >+ // use probed BAR size >+ }, >+ // >+ // EndDesc >+ // >+ { >+ ACPI_END_TAG_DESCRIPTOR, // Desc >+ 0 // Checksum: to be ignored >+ } >+}; >+ >+// >+// The CheckDevice() member function has been called. >+// >+STATIC BOOLEAN mCheckDeviceCalled; >+ >+ >+/** >+ Notification callback for Legacy BIOS protocol installation. >+ >+ @param[in] Event Event whose notification function is being invoked. >+ >+ @param[in] Context The pointer to the notification function's context, >which >+ is implementation-dependent. >+**/ >+STATIC >+VOID >+EFIAPI >+LegacyBiosInstalled ( >+ IN EFI_EVENT Event, >+ IN VOID *Context >+ ) >+{ >+ EFI_STATUS Status; >+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; >+ >+ ASSERT (!mCheckDeviceCalled); >+ >+ Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, >+ NULL /* Registration */, (VOID **)&LegacyBios); >+ if (EFI_ERROR (Status)) { >+ return; >+ } >+ >+ mLegacyBiosInstalled = TRUE; >+ >+ // >+ // Close the event and deregister this callback. >+ // >+ Status = gBS->CloseEvent (Event); >+ ASSERT_EFI_ERROR (Status); >+} >+ >+ >+/** >+ Returns a list of ACPI resource descriptors that detail the special resource >+ configuration requirements for an incompatible PCI device. >+ >+ Prior to bus enumeration, the PCI bus driver will look for the presence of >+ the EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL. Only one instance of this >+ protocol can be present in the system. For each PCI device that the PCI bus >+ driver discovers, the PCI bus driver calls this function with the device's >+ vendor ID, device ID, revision ID, subsystem vendor ID, and subsystem device >+ ID. If the VendorId, DeviceId, RevisionId, SubsystemVendorId, or >+ SubsystemDeviceId value is set to (UINTN)-1, that field will be ignored. The >+ ID values that are not (UINTN)-1 will be used to identify the current >device. >+ >+ This function will only return EFI_SUCCESS. However, if the device is an >+ incompatible PCI device, a list of ACPI resource descriptors will be >returned >+ in Configuration. Otherwise, NULL will be returned in Configuration instead. >+ The PCI bus driver does not need to allocate memory for Configuration. >+ However, it is the PCI bus driver's responsibility to free it. The PCI bus >+ driver then can configure this device with the information that is derived >+ from this list of resource nodes, rather than the result of BAR probing. >+ >+ Only the following two resource descriptor types from the ACPI Specification >+ may be used to describe the incompatible PCI device resource requirements: >+ - QWORD Address Space Descriptor (ACPI 2.0, section 6.4.3.5.1; also ACPI >3.0) >+ - End Tag (ACPI 2.0, section 6.4.2.8; also ACPI 3.0) >+ >+ The QWORD Address Space Descriptor can describe memory, I/O, and bus number >+ ranges for dynamic or fixed resources. The configuration of a PCI root >bridge >+ is described with one or more QWORD Address Space Descriptors, followed by >an >+ End Tag. See the ACPI Specification for details on the field values. >+ >+ @param[in] This Pointer to the >+ EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL >+ instance. >+ >+ @param[in] VendorId A unique ID to identify the manufacturer of >+ the PCI device. See the Conventional PCI >+ Specification 3.0 for details. >+ >+ @param[in] DeviceId A unique ID to identify the particular PCI >+ device. See the Conventional PCI >+ Specification 3.0 for details. >+ >+ @param[in] RevisionId A PCI device-specific revision identifier. >+ See the Conventional PCI Specification 3.0 >+ for details. >+ >+ @param[in] SubsystemVendorId Specifies the subsystem vendor ID. See the >+ Conventional PCI Specification 3.0 for >+ details. >+ >+ @param[in] SubsystemDeviceId Specifies the subsystem device ID. See the >+ Conventional PCI Specification 3.0 for >+ details. >+ >+ @param[out] Configuration A list of ACPI resource descriptors that >+ detail the configuration requirement. >+ >+ @retval EFI_SUCCESS The function always returns EFI_SUCCESS. >+**/ >+STATIC >+EFI_STATUS >+EFIAPI >+CheckDevice ( >+ IN EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL *This, >+ IN UINTN VendorId, >+ IN UINTN DeviceId, >+ IN UINTN RevisionId, >+ IN UINTN SubsystemVendorId, >+ IN UINTN SubsystemDeviceId, >+ OUT VOID **Configuration >+ ) >+{ >+ mCheckDeviceCalled = TRUE; >+ >+ // >+ // Unlike the general description of this protocol member suggests, there is >+ // nothing incompatible about the PCI devices that we'll match here. We'll >+ // match all PCI devices, and generate exactly one QWORD Address Space >+ // Descriptor for each. That descriptor will instruct the PCI Bus >UEFI_DRIVER >+ // not to degrade 64-bit MMIO BARs for the device, even if a PCI option ROM >+ // BAR is present on the device. >+ // >+ // The concern captured in the PCI Bus UEFI_DRIVER is that a legacy BIOS >boot >+ // (via a CSM) could dispatch a legacy option ROM on the device, which might >+ // have trouble with MMIO BARs that have been allocated outside of the >32-bit >+ // address space. But, if we don't support legacy option ROMs at all, then >+ // this problem cannot arise. >+ // >+ if (mLegacyBiosInstalled) { >+ // >+ // Don't interfere with resource degradation. >+ // >+ *Configuration = NULL; >+ return EFI_SUCCESS; >+ } >+ >+ // >+ // This member function is mis-specified actually: it is supposed to >allocate >+ // memory, but as specified, it could not return an error status. >Thankfully, >+ // the edk2 PCI Bus UEFI_DRIVER actually handles error codes; see the >+ // UpdatePciInfo() function. >+ // >+ *Configuration = AllocateCopyPool (sizeof mConfiguration, &mConfiguration); >+ if (*Configuration == NULL) { >+ DEBUG ((EFI_D_WARN, >+ "%a: 64-bit MMIO BARs may be degraded for PCI 0x%04x:0x%04x (rev %d)\n", >+ __FUNCTION__, (UINT32)VendorId, (UINT32)DeviceId, (UINT8)RevisionId)); >+ return EFI_OUT_OF_RESOURCES; >+ } >+ return EFI_SUCCESS; >+} >+ >+ >+/** >+ Entry point for this driver. >+ >+ @param[in] ImageHandle Image handle of this driver. >+ @param[in] SystemTable Pointer to SystemTable. >+ >+ @retval EFI_SUCESS Driver has loaded successfully. >+ @retval EFI_UNSUPPORTED PCI resource allocation has been disabled. >+ @retval EFI_UNSUPPORTED There is no 64-bit PCI MMIO aperture. >+ @return Error codes from lower level functions. >+ >+**/ >+EFI_STATUS >+EFIAPI >+DriverInitialize ( >+ IN EFI_HANDLE ImageHandle, >+ IN EFI_SYSTEM_TABLE *SystemTable >+ ) >+{ >+ EFI_STATUS Status; >+ EFI_EVENT Event; >+ VOID *Registration; >+ >+ // >+ // If the PCI Bus driver is not supposed to allocate resources, then it >makes >+ // no sense to install a protocol that influences the resource allocation. >+ // >+ // Similarly, if there is no 64-bit PCI MMIO aperture, then 64-bit MMIO BARs >+ // have to be allocated under 4 GB unconditionally. >+ // >+ if (PcdGetBool (PcdPciDisableBusEnumeration) || >+ PcdGet64 (PcdPciMmio64Size) == 0) { >+ return EFI_UNSUPPORTED; >+ } >+ >+ // >+ // Otherwise, create a protocol notify to see if a CSM is present. (With the >+ // CSM absent, the PCI Bus driver won't have to worry about allocating >64-bit >+ // MMIO BARs in the 32-bit MMIO aperture, for the sake of a legacy BIOS.) >+ // >+ // If the Legacy BIOS Protocol is present at the time of this driver >starting >+ // up, we can mark immediately that the PCI Bus driver should perform the >+ // usual 64-bit MMIO BAR degradation. >+ // >+ // Otherwise, if the Legacy BIOS Protocol is absent at startup, it may be >+ // installed later. However, if it doesn't show up until the first >+ // EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL.CheckDevice() call from the >+ // PCI Bus driver, then it never will: >+ // >+ // 1. The following drivers are dispatched in some unspecified order: >+ // - PCI Host Bridge DXE_DRIVER, >+ // - PCI Bus UEFI_DRIVER, >+ // - this DXE_DRIVER, >+ // - Legacy BIOS DXE_DRIVER. >+ // >+ // 2. The DXE_CORE enters BDS. >+ // >+ // 3. The platform BDS connects the PCI Root Bridge IO instances (produced >by >+ // the PCI Host Bridge DXE_DRIVER). >+ // >+ // 4. The PCI Bus UEFI_DRIVER enumerates resources and calls into this >+ // DXE_DRIVER (CheckDevice()). >+ // >+ // 5. This driver remembers if EFI_LEGACY_BIOS_PROTOCOL has been installed >+ // sometime during step 1 (produced by the Legacy BIOS DXE_DRIVER). >+ // >+ // For breaking this order, the Legacy BIOS DXE_DRIVER would have to install >+ // its protocol after the firmware enters BDS, which cannot happen. >+ // >+ Status = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, >+ LegacyBiosInstalled, NULL /* Context */, &Event); >+ if (EFI_ERROR (Status)) { >+ return Status; >+ } >+ >+ Status = gBS->RegisterProtocolNotify (&gEfiLegacyBiosProtocolGuid, Event, >+ &Registration); >+ if (EFI_ERROR (Status)) { >+ goto CloseEvent; >+ } >+ >+ Status = gBS->SignalEvent (Event); >+ ASSERT_EFI_ERROR (Status); >+ >+ mIncompatiblePciDeviceSupport.CheckDevice = CheckDevice; >+ Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle, >+ &gEfiIncompatiblePciDeviceSupportProtocolGuid, >+ &mIncompatiblePciDeviceSupport, NULL); >+ if (EFI_ERROR (Status)) { >+ goto CloseEvent; >+ } >+ >+ return EFI_SUCCESS; >+ >+CloseEvent: >+ if (!mLegacyBiosInstalled) { >+ EFI_STATUS CloseStatus; >+ >+ CloseStatus = gBS->CloseEvent (Event); >+ ASSERT_EFI_ERROR (CloseStatus); >+ } >+ >+ return Status; >+} >-- >1.8.3.1 > >_______________________________________________ >edk2-devel mailing list >edk2-devel@lists.01.org >https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel