[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/6] Redesign of pciinit.c (take 2)
From: |
Alexey Korolev |
Subject: |
[Qemu-devel] [PATCH 2/6] Redesign of pciinit.c (take 2) |
Date: |
Tue, 13 Mar 2012 17:45:19 +1300 |
Added pci_region_entry structure and list operations to pciinit.c
List is filled with entries during pci_check_devices.
List is used just for printing space allocation if we were using lists.
Next step will resource allocation using mapping functions.
Signed-off-by: Alexey Korolev <address@hidden>
---
src/pciinit.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 101 insertions(+), 3 deletions(-)
diff --git a/src/pciinit.c b/src/pciinit.c
index 9f3fdd4..2bf5473 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -31,6 +31,20 @@ static const char *region_type_name[] = {
[ PCI_REGION_TYPE_PREFMEM ] = "prefmem",
};
+struct pci_bus;
+struct pci_region_entry {
+ struct pci_device *dev;
+ int bar;
+ u32 base;
+ u32 size;
+ int is64bit;
+ enum pci_region_type type;
+ struct pci_bus *this_bus;
+ struct pci_bus *parent_bus;
+ struct pci_region_entry *next;
+ struct pci_region_entry **pprev;
+};
+
struct pci_bus {
struct {
/* pci region stats */
@@ -41,6 +55,7 @@ struct pci_bus {
/* 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;
};
@@ -352,6 +367,31 @@ pci_bios_get_bar(struct pci_device *pci, int bar, u32
*val, u32 *size)
*size = (~(*val & mask)) + 1;
}
+/****************************************************************
+ * Build topology and calculate size of entries
+ ****************************************************************/
+
+struct pci_region_entry *
+pci_region_create_entry(struct pci_bus *bus, struct pci_device *dev,
+ u32 size, int type, int is64bit)
+{
+ struct pci_region_entry *entry= malloc_tmp(sizeof(*entry));
+ if (!entry) {
+ warn_noalloc();
+ return NULL;
+ }
+ memset(entry, 0, sizeof(*entry));
+
+ entry->dev = dev;
+ entry->type = type;
+ entry->is64bit = is64bit;
+ entry->size = size;
+
+ 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;
@@ -364,9 +404,10 @@ static void pci_bios_bus_reserve(struct pci_bus *bus, int
type, u32 size)
bus->r[type].max = size;
}
-static void pci_bios_check_devices(struct pci_bus *busses)
+static int pci_bios_check_devices(struct pci_bus *busses)
{
dprintf(1, "PCI: check devices\n");
+ struct pci_region_entry *entry;
// Calculate resources needed for regular (non-bus) devices.
struct pci_device *pci;
@@ -378,10 +419,15 @@ static void pci_bios_check_devices(struct pci_bus *busses)
struct pci_bus *bus = &busses[pci_bdf_to_bus(pci->bdf)];
int i;
for (i = 0; i < PCI_NUM_REGIONS; i++) {
- u32 val, size;
+ u32 val, size, min_size;
+ int 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);
+ size = (size > min_size) ? size : min_size;
pci_bios_bus_reserve(bus, pci_addr_to_type(val), size);
pci->bars[i].addr = val;
@@ -390,6 +436,11 @@ static void pci_bios_check_devices(struct pci_bus *busses)
(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);
+ if (!entry)
+ return -1;
+ entry->bar = i;
+
if (pci->bars[i].is64)
i++;
}
@@ -411,6 +462,11 @@ static void pci_bios_check_devices(struct pci_bus *busses)
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)
+ return -1;
+ entry->this_bus = s;
}
dprintf(1, "PCI: secondary bus %d sizes: io %x, mem %x, prefmem %x\n",
secondary_bus,
@@ -418,6 +474,7 @@ static void pci_bios_check_devices(struct pci_bus *busses)
s->r[PCI_REGION_TYPE_MEM].size,
s->r[PCI_REGION_TYPE_PREFMEM].size);
}
+ return 0;
}
#define ROOT_BASE(top, sum, max) ALIGN_DOWN((top)-(sum),(max) ?: 1)
@@ -553,6 +610,44 @@ static void pci_bios_map_devices(struct pci_bus *busses)
}
}
+static void pci_region_dump_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",
+ entry->dev->secondary_bus, entry->size, entry->base,
+ region_type_name[entry->type]);
+ }
+}
+
+static void pci_bios_dump_devices(struct pci_bus *busses)
+{
+ struct pci_region_entry *entry, *next;
+
+ int bus;
+ for (bus = 0; bus<=MaxPCIBus; bus++) {
+ int type;
+ for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
+ u32 size;
+ for (size = busses[bus].r[type].max; size > 0; size >>= 1) {
+ list_foreach_entry_safe(busses[bus].r[type].list,
+ next, entry) {
+ if (size == entry->size) {
+ entry->base = busses[bus].r[type].base;
+ busses[bus].r[type].base += size;
+ pci_region_dump_one_entry(entry);
+ list_del(entry);
+ free(entry);
+ }
+ }
+ }
+ }
+ }
+}
/****************************************************************
* Main setup code
@@ -588,13 +683,16 @@ pci_setup(void)
return;
}
memset(busses, 0, sizeof(*busses) * (MaxPCIBus + 1));
- pci_bios_check_devices(busses);
+ if (pci_bios_check_devices(busses))
+ return;
+
if (pci_bios_init_root_regions(&busses[0], start, end) != 0) {
panic("PCI: out of address space\n");
}
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
[Qemu-devel] [PATCH 3/6] Switch from array based approach to lists of pci_region_entries, Alexey Korolev, 2012/03/13
[Qemu-devel] [PATCH 4/6] Delete array based resource assignment code., Alexey Korolev, 2012/03/13
[Qemu-devel] [PATCH 5/6] Get rid of size element of pci_bus->r structure, Alexey Korolev, 2012/03/13
[Qemu-devel] [PATCH 6/6] Use linked lists in pmm.c and stack.c, Alexey Korolev, 2012/03/13