[SeaBIOS] [PATCH 3/6] Switch from array based approach to lists of pci_region_entries

Alexey Korolev alexey.korolev at endace.com
Tue Mar 13 05:58:50 CET 2012


Now we use the list of pci_region_entries instead of arrays of bases.
In this patch in addition to dumping resource allocations using
pci_region_entry, we add actual PCI resource assignment.

Note: I commented old code and split patches 3/6 and 4/6 just for
better patch readability. 

Signed-off-by: Alexey Korolev <alexey.korolev at endace.com>
---
 src/pciinit.c |  106 +++++++++++++++++++++++++--------------------------------
 1 files changed, 46 insertions(+), 60 deletions(-)

diff --git a/src/pciinit.c b/src/pciinit.c
index 2bf5473..f766a75 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -12,9 +12,8 @@
 #include "pci_regs.h" // PCI_COMMAND
 #include "xen.h" // usingXen
 
-#define PCI_IO_INDEX_SHIFT 2
-#define PCI_MEM_INDEX_SHIFT 12
-
+#define PCI_DEV_IO_MINSIZE        0x4
+#define PCI_DEV_MEM_MINSIZE    0x1000
 #define PCI_BRIDGE_IO_MIN      0x1000
 #define PCI_BRIDGE_MEM_MIN   0x100000
 
@@ -48,38 +47,14 @@ struct pci_region_entry {
 struct pci_bus {
     struct {
         /* pci region stats */
-        u32 count[32 - PCI_MEM_INDEX_SHIFT];
         u32 sum, max;
-        /* seconday bus region sizes */
         u32 size;
-        /* pci region assignments */
-        u32 bases[32 - PCI_MEM_INDEX_SHIFT];
         u32 base;
         struct pci_region_entry *list;
     } r[PCI_REGION_TYPE_COUNT];
     struct pci_device *bus_dev;
 };
 
-static int pci_size_to_index(u32 size, enum pci_region_type type)
-{
-    int index = __fls(size);
-    int shift = (type == PCI_REGION_TYPE_IO) ?
-        PCI_IO_INDEX_SHIFT : PCI_MEM_INDEX_SHIFT;
-
-    if (index < shift)
-        index = shift;
-    index -= shift;
-    return index;
-}
-
-static u32 pci_index_to_size(int index, enum pci_region_type type)
-{
-    int shift = (type == PCI_REGION_TYPE_IO) ?
-        PCI_IO_INDEX_SHIFT : PCI_MEM_INDEX_SHIFT;
-
-    return 0x1 << (index + shift);
-}
-
 static enum pci_region_type pci_addr_to_type(u32 addr)
 {
     if (addr & PCI_BASE_ADDRESS_SPACE_IO)
@@ -389,19 +364,10 @@ pci_region_create_entry(struct pci_bus *bus, struct pci_device *dev,
 
     list_add_head(&bus->r[type].list, entry);
     entry->parent_bus = bus;
-    return entry;
-}
-
-static void pci_bios_bus_reserve(struct pci_bus *bus, int type, u32 size)
-{
-    u32 index;
-
-    index = pci_size_to_index(size, type);
-    size = pci_index_to_size(index, type);
-    bus->r[type].count[index]++;
     bus->r[type].sum += size;
     if (bus->r[type].max < size)
         bus->r[type].max = size;
+    return entry;
 }
 
 static int pci_bios_check_devices(struct pci_bus *busses)
@@ -420,28 +386,24 @@ static int pci_bios_check_devices(struct pci_bus *busses)
         int i;
         for (i = 0; i < PCI_NUM_REGIONS; i++) {
             u32 val, size, min_size;                       entry->dev->bdf, entry->bar, entry->size, entry->base,
                       region_type_name[entry->type]);
-    } else {
-        entry->this_bus->r[entry->type].base = entry->base;
-        dprintf(1, "Secondary bus %d\t\tsize\t0x%08x\tbase 0x%x type %s\n",
+
+        pci_set_io_region_addr(entry->dev, entry->bar, entry->base);
+        if (entry->is64bit)
+            pci_set_io_region_addr(entry->dev, entry->bar + 1, 0);
+        return;
-            int type;
+            int is64, type;
             pci_bios_get_bar(pci, i, &val, &size);
             if (val == 0)
                 continue;
             type = pci_addr_to_type(val);
-            min_size = (type == PCI_REGION_TYPE_IO) ? (1<<PCI_IO_INDEX_SHIFT):
-                     (1<<PCI_MEM_INDEX_SHIFT);
+            min_size = (type == PCI_REGION_TYPE_IO) ? PCI_DEV_IO_MINSIZE:
+                     PCI_DEV_MEM_MINSIZE;
             size = (size > min_size) ? size : min_size;
 
-            pci_bios_bus_reserve(bus, pci_addr_to_type(val), size);
-            pci->bars[i].addr = val;
-            pci->bars[i].size = size;
-            pci->bars[i].is64 = (!(val & PCI_BASE_ADDRESS_SPACE_IO) &&
-                                 (val & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
-                                 == PCI_BASE_ADDRESS_MEM_TYPE_64);
-
-            entry = pci_region_create_entry(bus, pci, size, type, pci->bars[i].is64);
+            is64 = (!(val & PCI_BASE_ADDRESS_SPACE_IO) &&
+                      (val & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
+                       == PCI_BASE_ADDRESS_MEM_TYPE_64);
+            entry = pci_region_create_entry(bus, pci, size, type, is64);
             if (!entry)
                 return -1;
             entry->bar = i;
 
-            if (pci->bars[i].is64)
+            if (is64)
                 i++;
         }
     }
@@ -461,7 +423,6 @@ static int pci_bios_check_devices(struct pci_bus *busses)
             if (s->r[type].size < limit)
                 s->r[type].size = limit;
             s->r[type].size = pci_size_roundup(s->r[type].size);
-            pci_bios_bus_reserve(parent, type, s->r[type].size);
             entry = pci_region_create_entry(parent, s->bus_dev,
                                             s->r[type].size, type, 0);
             if (!entry)
@@ -503,7 +464,7 @@ static int pci_bios_init_root_regions(struct pci_bus *bus, u32 start, u32 end)
 /****************************************************************
  * BAR assignment
  ****************************************************************/
-
+/*
 static void pci_bios_init_bus_bases(struct pci_bus *bus)
 {
     u32 base, newbase, size;
@@ -609,22 +570,48 @@ static void pci_bios_map_devices(struct pci_bus *busses)
         }
     }
 }
-
-static void pci_region_dump_one_entry(struct pci_region_entry *entry)
+*/
+static void pci_region_map_one_entry(struct pci_region_entry *entry)
 {
     if (!entry->this_bus ) {
         dprintf(1, "PCI: bdf %d bar %d\tsize\t0x%08x\tbase 0x%x type %s\n",
                       entry->dev->bdf, entry->bar, entry->size, entry->base,
                       region_type_name[entry->type]);
-    } else {
-        entry->this_bus->r[entry->type].base = entry->base;
-        dprintf(1, "Secondary bus %d\t\tsize\t0x%08x\tbase 0x%x type %s\n",
+
+        pci_set_io_region_addr(entry->dev, entry->bar, entry->base);
+        if (entry->is64bit)
+            pci_set_io_region_addr(entry->dev, entry->bar + 1, 0);
+        return;
+    }
+
+    entry->this_bus->r[entry->type].base = entry->base;
+    dprintf(1, "PCI-2-PCI bus %d\t\tsize\t0x%08x\tbase 0x%x type %s\n",
                   entry->dev->secondary_bus, entry->size, entry->base,
                   region_type_name[entry->type]);
-   }
+
+    u16 bdf = entry->dev->bdf;
+    u32 base = entry->base;
+    u32 limit = entry->base + entry->size - 1;
+    if (entry->type == PCI_REGION_TYPE_IO) {
+        pci_config_writeb(bdf, PCI_IO_BASE, base >> 8);
+        pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0);
+        pci_config_writeb(bdf, PCI_IO_LIMIT, limit >> 8);
+        pci_config_writew(bdf, PCI_IO_LIMIT_UPPER16, 0);
+    }
+    if (entry->type == PCI_REGION_TYPE_MEM) {
+        pci_config_writew(bdf, PCI_MEMORY_BASE, base >> 16);
+        pci_config_writew(bdf, PCI_MEMORY_LIMIT, limit >> 16);
+    }
+    if (entry->type == PCI_REGION_TYPE_PREFMEM) {
+        pci_config_writew(bdf, PCI_PREF_MEMORY_BASE, base >> 16);
+        pci_config_writew(bdf, PCI_PREF_MEMORY_LIMIT, limit >> 16);
+        pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, 0);
+        pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, 0);
+    }
+    return;
 }
 
-static void pci_bios_dump_devices(struct pci_bus *busses)
+static void pci_bios_map_devices(struct pci_bus *busses)
 {
     struct pci_region_entry *entry, *next;
 
@@ -639,7 +626,7 @@ static void pci_bios_dump_devices(struct pci_bus *busses)
                         if (size == entry->size) {
                             entry->base = busses[bus].r[type].base;
                             busses[bus].r[type].base += size;
-                            pci_region_dump_one_entry(entry);
+                            pci_region_map_one_entry(entry);
                             list_del(entry);
                             free(entry);
                     }
@@ -692,7 +679,6 @@ pci_setup(void)
 
     dprintf(1, "=== PCI new allocation pass #2 ===\n");
     pci_bios_map_devices(busses);
-    pci_bios_dump_devices(busses);
 
     pci_bios_init_devices();
 
-- 
1.7.5.4





More information about the SeaBIOS mailing list