[SeaBIOS] [PATCH] Add ability to track PCI paths and add to build_pci_path().

Kevin O'Connor kevin at koconnor.net
Mon Jan 10 06:52:31 CET 2011


Improve device path descriptions of devices on PCI buses.
---
 src/boot.c |   17 ++++++++++++-----
 src/pci.c  |   29 +++++++++++++++++++++++++++++
 src/pci.h  |    5 +++++
 src/post.c |    1 +
 4 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/src/boot.c b/src/boot.c
index b59794e..05fb3dd 100644
--- a/src/boot.c
+++ b/src/boot.c
@@ -99,13 +99,20 @@ build_pci_path(char *buf, int max, const char *devname, int bdf)
 {
     // Build the string path of a bdf - for example: /pci at i0cf8/isa at 1,2
     char *p = buf;
-    int bus = pci_bdf_to_bus(bdf);
-    if (bus)
-        // XXX - this isn't the correct path syntax
-        p += snprintf(p, max, "/bus%x", bus);
+    int parent = pci_bdf_to_bus(bdf);
+    if (PCIpaths)
+        parent = PCIpaths[parent];
+    int parentdev = parent & 0xffff;
+    if (parent & PP_PCIBRIDGE) {
+        p = build_pci_path(p, max, "pci-bridge", parentdev);
+    } else {
+        if (parentdev)
+            p += snprintf(p, max, "/pci-root@%x", parentdev);
+        p += snprintf(p, buf+max-p, "%s", FW_PCI_DOMAIN);
+    }
 
     int dev = pci_bdf_to_dev(bdf), fn = pci_bdf_to_fn(bdf);
-    p += snprintf(p, buf+max-p, "%s/%s@%x", FW_PCI_DOMAIN, devname, dev);
+    p += snprintf(p, buf+max-p, "/%s@%x", devname, dev);
     if (fn)
         p += snprintf(p, buf+max-p, ",%x", fn);
     return p;
diff --git a/src/pci.c b/src/pci.c
index 5237f19..45f210d 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -185,6 +185,35 @@ pci_find_class(u16 classid)
     return -1;
 }
 
+int *PCIpaths;
+
+// Build the PCI path designations.
+void
+pci_path_setup(void)
+{
+    PCIpaths = malloc_tmp(sizeof(*PCIpaths) * 256);
+    if (!PCIpaths)
+        return;
+    memset(PCIpaths, 0, sizeof(PCIpaths));
+
+    int roots = 0;
+    int bdf, max;
+    foreachpci(bdf, max) {
+        int bus = pci_bdf_to_bus(bdf);
+        if (! PCIpaths[bus])
+            PCIpaths[bus] = (roots++) | PP_ROOT;
+
+        // Check if found device is a bridge.
+        u32 v = pci_config_readb(bdf, PCI_HEADER_TYPE);
+        v &= 0x7f;
+        if (v == PCI_HEADER_TYPE_BRIDGE || v == PCI_HEADER_TYPE_CARDBUS) {
+            v = pci_config_readl(bdf, PCI_PRIMARY_BUS);
+            int childbus = (v >> 8) & 0xff;
+            PCIpaths[childbus] = bdf | PP_PCIBRIDGE;
+        }
+    }
+}
+
 int pci_init_device(const struct pci_device_id *ids, u16 bdf, void *arg)
 {
     u16 vendor_id = pci_config_readw(bdf, PCI_VENDOR_ID);
diff --git a/src/pci.h b/src/pci.h
index 46af207..9869a26 100644
--- a/src/pci.h
+++ b/src/pci.h
@@ -47,6 +47,11 @@ int pci_find_vga(void);
 int pci_find_device(u16 vendid, u16 devid);
 int pci_find_class(u16 classid);
 
+#define PP_ROOT      (1<<17)
+#define PP_PCIBRIDGE (1<<18)
+extern int *PCIpaths;
+void pci_path_setup(void);
+
 int pci_next(int bdf, int *pmax);
 #define foreachpci(BDF, MAX)                    \
     for (MAX=0x0100, BDF=pci_next(0, &MAX)      \
diff --git a/src/post.c b/src/post.c
index efcfc85..7d2b5f2 100644
--- a/src/post.c
+++ b/src/post.c
@@ -217,6 +217,7 @@ maininit(void)
 
     // Initialize pci
     pci_setup();
+    pci_path_setup();
     smm_init();
 
     // Initialize internal tables
-- 
1.7.3.4




More information about the SeaBIOS mailing list