[SeaBIOS] [PATCH v2 5/6] pci: fix bridge ressource allocation.
Gerd Hoffmann
kraxel at redhat.com
Wed Feb 29 12:45:09 CET 2012
The patch changes the bridge ressource allocation: Unused memory
windows are disabled: If none of the devices connected to the bridge
has -- say -- I/O bars, then the I/O memory window is turned off. This
implies that bridges without devices don't get any ressources assigned.
The pci bridge spec wants us behave that way (figured while looking at
drivers/pci/setup-bus.c in the linux kernel source tree).
Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
---
src/pciinit.c | 43 +++++++++++++++++++++++++++++++++----------
1 files changed, 33 insertions(+), 10 deletions(-)
diff --git a/src/pciinit.c b/src/pciinit.c
index 33b9bf7..a03e17c 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -457,6 +457,8 @@ static void pci_bios_check_devices(struct pci_bus *busses)
for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
u64 limit = (type == PCI_REGION_TYPE_IO) ?
PCI_BRIDGE_IO_MIN : PCI_BRIDGE_MEM_MIN;
+ if (s->r[type].sum == 0)
+ continue;
s->r[type].size = s->r[type].sum;
if (s->r[type].size < limit)
s->r[type].size = limit;
@@ -505,6 +507,8 @@ static void pci_bios_init_bus_bases(struct pci_bus *bus)
int type, i;
for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
+ if (bus->r[type].sum == 0)
+ continue;
dprintf(1, " type %s max %llx sum %llx base %llx\n",
region_type_name[type], bus->r[type].max,
bus->r[type].sum, bus->r[type].base);
@@ -522,9 +526,10 @@ static void pci_bios_init_bus_bases(struct pci_bus *bus)
}
}
-static u32 pci_bios_bus_get_addr(struct pci_bus *bus, int type, u32 size)
+static u64 pci_bios_bus_get_addr(struct pci_bus *bus, int type, u64 size)
{
- u32 index, addr;
+ u32 index;
+ u64 addr;
index = pci_size_to_index(size, type);
addr = bus->r[type].bases[index];
@@ -552,30 +557,48 @@ static void pci_bios_map_devices(struct pci_bus *busses)
struct pci_bus *parent = &busses[pci_bdf_to_bus(bdf)];
int type;
for (type = 0; type < PCI_REGION_TYPE_COUNT; type++) {
+ if (s->r[type].sum == 0)
+ continue;
s->r[type].base = pci_bios_bus_get_addr(
parent, type, s->r[type].size);
}
dprintf(1, "PCI: init bases bus %d (secondary)\n", secondary_bus);
pci_bios_init_bus_bases(s);
- u64 base = s->r[PCI_REGION_TYPE_IO].base;
- u64 limit = base + s->r[PCI_REGION_TYPE_IO].size - 1;
+ u64 base, limit;
+ if (s->r[PCI_REGION_TYPE_IO].sum) {
+ base = s->r[PCI_REGION_TYPE_IO].base;
+ limit = base + s->r[PCI_REGION_TYPE_IO].size - 1;
+ } else {
+ base = PCI_BRIDGE_IO_MIN;
+ limit = 0;
+ }
pci_config_writeb(bdf, PCI_IO_BASE, base >> PCI_IO_SHIFT);
pci_config_writew(bdf, PCI_IO_BASE_UPPER16, 0);
pci_config_writeb(bdf, PCI_IO_LIMIT, limit >> PCI_IO_SHIFT);
pci_config_writew(bdf, PCI_IO_LIMIT_UPPER16, 0);
- base = s->r[PCI_REGION_TYPE_MEM].base;
- limit = base + s->r[PCI_REGION_TYPE_MEM].size - 1;
+ if (s->r[PCI_REGION_TYPE_MEM].sum) {
+ base = s->r[PCI_REGION_TYPE_MEM].base;
+ limit = base + s->r[PCI_REGION_TYPE_MEM].size - 1;
+ } else {
+ base = PCI_BRIDGE_MEM_MIN;
+ limit = 0;
+ }
pci_config_writew(bdf, PCI_MEMORY_BASE, base >> PCI_MEMORY_SHIFT);
pci_config_writew(bdf, PCI_MEMORY_LIMIT, limit >> PCI_MEMORY_SHIFT);
- base = s->r[PCI_REGION_TYPE_PREFMEM].base;
- limit = base + s->r[PCI_REGION_TYPE_PREFMEM].size - 1;
+ if (s->r[PCI_REGION_TYPE_PREFMEM].sum) {
+ base = s->r[PCI_REGION_TYPE_PREFMEM].base;
+ limit = base + s->r[PCI_REGION_TYPE_PREFMEM].size - 1;
+ } else {
+ base = PCI_BRIDGE_MEM_MIN;
+ limit = 0;
+ }
pci_config_writew(bdf, PCI_PREF_MEMORY_BASE, base >> PCI_PREF_MEMORY_SHIFT);
pci_config_writew(bdf, PCI_PREF_MEMORY_LIMIT, limit >> PCI_PREF_MEMORY_SHIFT);
- pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, 0);
- pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, 0);
+ pci_config_writel(bdf, PCI_PREF_BASE_UPPER32, base >> 32);
+ pci_config_writel(bdf, PCI_PREF_LIMIT_UPPER32, base >> 32);
}
// Map regions on each device.
--
1.7.1
More information about the SeaBIOS
mailing list