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@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();