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