QEMU provides an fw_cfg file called "etc/extra-pci-roots", containing a little-endian UINT64 value that exposes the number of extra root buses. We can use this value to terminate the scan as soon as we find the last extra root bus.
Cc: Jordan Justen <jordan.l.jus...@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek <ler...@redhat.com> Regression-tested-by: Gabriel Somlo <so...@cmu.edu> --- Notes: v2: - %Lu is available now in format strings, for printing UINT64 values in decimal OvmfPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf | 2 ++ OvmfPkg/PciHostBridgeDxe/PciHostBridge.c | 22 +++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf b/OvmfPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf index 40f4c3c..ca760b5 100644 --- a/OvmfPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf +++ b/OvmfPkg/PciHostBridgeDxe/PciHostBridgeDxe.inf @@ -26,6 +26,7 @@ [Defines] [Packages] MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec [LibraryClasses] UefiDriverEntryPoint @@ -39,6 +40,7 @@ [LibraryClasses] DevicePathLib IoLib PciLib + QemuFwCfgLib [Sources] PciHostBridge.c diff --git a/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c b/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c index 3486644..efef2ed 100644 --- a/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c +++ b/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c @@ -15,6 +15,8 @@ **/ +#include <Library/QemuFwCfgLib.h> + #include "PciHostBridge.h" STATIC @@ -207,6 +209,9 @@ InitializePciHostBridge ( ) { EFI_STATUS Status; + FIRMWARE_CONFIG_ITEM FwCfgItem; + UINTN FwCfgSize; + UINT64 ExtraRootBridgesLeft; UINTN LastRootBridgeNumber; UINTN RootBridgeNumber; PCI_HOST_BRIDGE_INSTANCE *HostBridge; @@ -237,6 +242,20 @@ InitializePciHostBridge ( } // + // QEMU provides the number of extra root buses, shortening the exhaustive + // search below. If there is no hint, the feature is missing. + // + Status = QemuFwCfgFindFile ("etc/extra-pci-roots", &FwCfgItem, &FwCfgSize); + if (EFI_ERROR (Status) || FwCfgSize != sizeof ExtraRootBridgesLeft) { + ExtraRootBridgesLeft = 0; + } else { + QemuFwCfgSelectItem (FwCfgItem); + QemuFwCfgReadBytes (FwCfgSize, &ExtraRootBridgesLeft); + DEBUG ((EFI_D_INFO, "%a: %Lu extra root buses reported by QEMU\n", + __FUNCTION__, ExtraRootBridgesLeft)); + } + + // // The "main" root bus is always there. // LastRootBridgeNumber = 0; @@ -247,7 +266,7 @@ InitializePciHostBridge ( // alive. // for (RootBridgeNumber = 1; - RootBridgeNumber < 256; + RootBridgeNumber < 256 && ExtraRootBridgesLeft > 0; ++RootBridgeNumber) { UINTN Device; @@ -271,6 +290,7 @@ InitializePciHostBridge ( } InsertTailList (&HostBridge->Head, &RootBus->Link); LastRootBridgeNumber = RootBridgeNumber; + --ExtraRootBridgesLeft; } } -- 1.8.3.1 ------------------------------------------------------------------------------ Don't Limit Your Business. Reach for the Cloud. GigeNET's Cloud Solutions provide you with the tools and support that you need to offload your IT needs and focus on growing your business. Configured For All Businesses. Start Your Cloud Today. https://www.gigenetcloud.com/ _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel