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.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <ler...@redhat.com>
---
 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 @@
 
 [Packages]
   MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
 
 [LibraryClasses]
   UefiDriverEntryPoint
@@ -39,6 +40,7 @@
   DevicePathLib
   IoLib
   PciLib
+  QemuFwCfgLib
 
 [Sources]
   PciHostBridge.c
diff --git a/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c 
b/OvmfPkg/PciHostBridgeDxe/PciHostBridge.c
index 3486644..b2e3816 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: 0x%Lx 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


------------------------------------------------------------------------------
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to