A flowed text. Please apply another [10/12] in this series.
On Tue, 2012-04-24 at 18:23 +1200, Alexey Korolev wrote: > Do not store pci region stats - instead calulate the > sum and alignment on demand. > > Signed-off-by: Alexey Korolev <alexey.koro...@endace.com> > --- > src/pciinit.c | 57 > +++++++++++++++++++++++++++++++++++---------------------- > 1 files changed, 35 insertions(+), 22 deletions(-) > > diff --git a/src/pciinit.c b/src/pciinit.c > index 0d66dbe..a6cf98b 100644 > --- a/src/pciinit.c > +++ b/src/pciinit.c > @@ -40,8 +40,6 @@ struct pci_region_entry { > }; > > struct pci_region { > - /* pci region stats */ > - u64 sum, align; > /* pci region assignments */ > u64 base; > struct pci_region_entry *list; > @@ -369,6 +367,25 @@ static int pci_bios_bridge_region_is64(struct > pci_region *r, > return 1; > } > > +static u64 pci_region_align(struct pci_region *r) > +{ > + if (!r->list) > + return 1; > + // The first entry in the sorted list has the largest alignment > + return r->list->align; > +} > + > +static u64 pci_region_sum(struct pci_region *r) > +{ > + struct pci_region_entry *entry = r->list; > + u64 sum = 0; > + while (entry) { > + sum += entry->size; > + entry = entry->next; > + } > + return sum; > +} > + > static struct pci_region_entry * > pci_region_create_entry(struct pci_bus *bus, struct pci_device *dev, > int bar, u64 size, u64 align, int type, int > is64) > @@ -394,10 +411,6 @@ pci_region_create_entry(struct pci_bus *bus, struct > pci_device *dev, > } > entry->next = *pprev; > *pprev = entry; > - > - bus->r[type].sum += size; > - if (bus->r[type].align < align) > - bus->r[type].align = align; > return entry; > } > > @@ -446,9 +459,9 @@ static int pci_bios_check_devices(struct pci_bus > *busses) > for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) { > u64 align = (type == PCI_REGION_TYPE_IO) ? > PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN; > - if (s->r[type].align > align) > - align = s->r[type].align; > - u64 size = ALIGN(s->r[type].sum, align); > + if (pci_region_align(&s->r[type]) > align) > + align = pci_region_align(&s->r[type]); > + u64 size = ALIGN(pci_region_sum(&s->r[type]), align); > int is64 = pci_bios_bridge_region_is64(&s->r[type], > s->bus_dev, type); > // entry->bar is -1 if the entry represents a bridge region > @@ -464,26 +477,26 @@ static int pci_bios_check_devices(struct pci_bus > *busses) > return 0; > } > > -#define ROOT_BASE(top, sum, align) ALIGN_DOWN((top)-(sum),(align) ?: 1) > - > // Setup region bases (given the regions' size and alignment) > static void pci_bios_init_root_regions(struct pci_bus *bus) > { > - u64 start = BUILD_PCIMEM_START; > - u64 end = BUILD_PCIMEM_END; > - > bus->r[PCI_REGION_TYPE_IO].base = 0xc000; > > - int reg1 = PCI_REGION_TYPE_PREFMEM, reg2 = PCI_REGION_TYPE_MEM; > - if (bus->r[reg1].align < bus->r[reg2].align) { > + struct pci_region *r_end = &bus->r[PCI_REGION_TYPE_PREFMEM]; > + struct pci_region *r_start = &bus->r[PCI_REGION_TYPE_MEM]; > + > + if (pci_region_align(r_start) < pci_region_align(r_end)) { > // Swap regions to improve alignment. > - reg1 = PCI_REGION_TYPE_MEM; > - reg2 = PCI_REGION_TYPE_PREFMEM; > + r_end = r_start; > + r_start = &bus->r[PCI_REGION_TYPE_PREFMEM]; > } > - bus->r[reg2].base = ROOT_BASE(end, bus->r[reg2].sum, > bus->r[reg2].align); > - bus->r[reg1].base = ROOT_BASE(bus->r[reg2].base, bus->r[reg1].sum > - , bus->r[reg1].align); > - if (bus->r[reg1].base < start) > + r_end->base = ALIGN_DOWN((BUILD_PCIMEM_END - > pci_region_sum(r_end)), > + pci_region_align(r_end)); > + r_start->base = ALIGN_DOWN((r_end->base - pci_region_sum(r_start)), > + pci_region_align(r_start)); > + > + if ((r_start->base < BUILD_PCIMEM_START) || > + (r_start->base > BUILD_PCIMEM_END)) > // Memory range requested is larger than available. > panic("PCI: out of address space\n"); > }