[SeaBIOS] [PATCH v2 5/6] pci: fix bridge ressource allocation.

Gerd Hoffmann kraxel at redhat.com
Wed Feb 29 12:45:09 CET 2012


The patch changes the bridge ressource allocation:  Unused memory
windows are disabled:  If none of the devices connected to the bridge
has -- say -- I/O bars, then the I/O memory window is turned off.  This
implies that bridges without devices don't get any ressources assigned.
The pci bridge spec wants us behave that way (figured while looking at
drivers/pci/setup-bus.c in the linux kernel source tree).

Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
---
 src/pciinit.c |   43 +++++++++++++++++++++++++++++++++----------
 1 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/src/pciinit.c b/src/pciinit.c
index 33b9bf7..a03e17c 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -457,6 +457,8 @@ static void pci_bios_check_devices(struct pci_bus *busses)
         for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
             u64 limit = (type == PCI_REGION_TYPE_IO) ?
                 PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
+            if (s->r[type].sum == 0)
+                continue;
             s->r[type].size = s->r[type].sum;
             if (s->r[type].size < limit)
                 s->r[type].size = limit;
@@ -505,6 +507,8 @@ static void pci_bios_init_bus_bases(struct pci_bus *bus)
     int type, i;
 
     for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
+        if (bus->r[type].sum == 0)
+            continue;
         dprintf(1, "  type %s max %llx sum %llx base %llx\n",
                 region_type_name[type], bus->r[type].max,
                 bus->r[type].sum, bus->r[type].base);
@@ -522,9 +526,10 @@ static void pci_bios_init_bus_bases(struct pci_bus *bus)
     }
 }
 
-static u32 pci_bios_bus_get_addr(struct pci_bus *bus, int type, u32 size)
+static u64 pci_bios_bus_get_addr(struct pci_bus *bus, int type, u64 size)
 {
-    u32 index, addr;
+    u32 index;
+    u64 addr;
 
     index = pci_size_to_index(size, type);
     addr = bus->r[type].bases[index];
@@ -552,30 +557,48 @@ static void pci_bios_map_devices(struct pci_bus *busses)
         struct pci_bus *parent = &busses[pci_bdf_to_bus(bdf)];
         int type;
         for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
+            if (s->r[type].sum == 0)
+                continue;
             s->r[type].base = pci_bios_bus_get_addr(
                 parent, type, s->r[type].size);
         }
         dprintf(1, "PCI: init bases bus %d (secondary)\n", secondary_bus);
         pci_bios_init_bus_bases(s);
 
-        u64 base = s->r[PCI_REGION_TYPE_IO].base;
-        u64 limit = base + s->r[PCI_REGION_TYPE_IO].size - 1;
+        u64 base, limit;
+        if (s->r[PCI_REGION_TYPE_IO].sum) {
+            base = s->r[PCI_REGION_TYPE_IO].base;
+            limit = base + s->r[PCI_REGION_TYPE_IO].size - 1;
+        } else {
+            base = PCI_BRIDGE_IO_MIN;
+            limit = 0;
+        }
         pci_config_writeb(bdf, PCI_IO_BASE, base >> PCI_IO_SHIFT);
         pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0);
         pci_config_writeb(bdf, PCI_IO_LIMIT, limit >> PCI_IO_SHIFT);
         pci_config_writew(bdf, PCI_IO_LIMIT_UPPER16, 0);
 
-        base = s->r[PCI_REGION_TYPE_MEM].base;
-        limit = base + s->r[PCI_REGION_TYPE_MEM].size - 1;
+        if (s->r[PCI_REGION_TYPE_MEM].sum) {
+            base = s->r[PCI_REGION_TYPE_MEM].base;
+            limit = base + s->r[PCI_REGION_TYPE_MEM].size - 1;
+        } else {
+            base = PCI_BRIDGE_MEM_MIN;
+            limit = 0;
+        }
         pci_config_writew(bdf, PCI_MEMORY_BASE, base >> PCI_MEMORY_SHIFT);
         pci_config_writew(bdf, PCI_MEMORY_LIMIT, limit >> PCI_MEMORY_SHIFT);
 
-        base = s->r[PCI_REGION_TYPE_PREFMEM].base;
-        limit = base + s->r[PCI_REGION_TYPE_PREFMEM].size - 1;
+        if (s->r[PCI_REGION_TYPE_PREFMEM].sum) {
+            base = s->r[PCI_REGION_TYPE_PREFMEM].base;
+            limit = base + s->r[PCI_REGION_TYPE_PREFMEM].size - 1;
+        } else {
+            base = PCI_BRIDGE_MEM_MIN;
+            limit = 0;
+        }
         pci_config_writew(bdf, PCI_PREF_MEMORY_BASE, base >> PCI_PREF_MEMORY_SHIFT);
         pci_config_writew(bdf, PCI_PREF_MEMORY_LIMIT, limit >> PCI_PREF_MEMORY_SHIFT);
-        pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, 0);
-        pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, 0);
+        pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, base >> 32);
+        pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, base >> 32);
     }
 
     // Map regions on each device.
-- 
1.7.1




More information about the SeaBIOS mailing list