device/pci_device.c: Add way to limit max bus numbers
By default this limits PCI buses to CONFIG_MMCONF_BUS_NUMBER. Some platforms have multiple PCI root busses (e.g. xeon_sp), where bus numbers are limited. This provides a basic check. On some platforms it looks like programming 0xff to the subordinate bus number confuses and hangs the hardware. Change-Id: I0582b156df1a5f76119a3687886c4d58f2d3ad6f Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/c/coreboot/+/59395 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Jonathan Zhang <jonzhang@fb.com> Reviewed-by: David Hendricks <david.hendricks@gmail.com>
This commit is contained in:
parent
306bd40939
commit
20d25779c8
|
@ -1532,6 +1532,18 @@ static void pci_bridge_route(struct bus *link, scan_state state)
|
||||||
if (state == PCI_ROUTE_SCAN) {
|
if (state == PCI_ROUTE_SCAN) {
|
||||||
link->secondary = parent->subordinate + 1;
|
link->secondary = parent->subordinate + 1;
|
||||||
link->subordinate = link->secondary + dev->hotplug_buses;
|
link->subordinate = link->secondary + dev->hotplug_buses;
|
||||||
|
link->max_subordinate = parent->max_subordinate
|
||||||
|
? parent->max_subordinate
|
||||||
|
: (CONFIG_ECAM_MMCONF_BUS_NUMBER - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (link->secondary > link->max_subordinate)
|
||||||
|
die("%s: No more busses available!\n", __func__);
|
||||||
|
|
||||||
|
/* This ought to only happen with hotplug buses. */
|
||||||
|
if (link->subordinate > link->max_subordinate) {
|
||||||
|
printk(BIOS_WARNING, "%s: Limiting subordinate busses\n", __func__);
|
||||||
|
link->subordinate = link->max_subordinate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == PCI_ROUTE_CLOSE) {
|
if (state == PCI_ROUTE_CLOSE) {
|
||||||
|
@ -1541,7 +1553,7 @@ static void pci_bridge_route(struct bus *link, scan_state state)
|
||||||
} else if (state == PCI_ROUTE_SCAN) {
|
} else if (state == PCI_ROUTE_SCAN) {
|
||||||
primary = parent->secondary;
|
primary = parent->secondary;
|
||||||
secondary = link->secondary;
|
secondary = link->secondary;
|
||||||
subordinate = 0xff; /* MAX PCI_BUS number here */
|
subordinate = link->max_subordinate;
|
||||||
} else if (state == PCI_ROUTE_FINAL) {
|
} else if (state == PCI_ROUTE_FINAL) {
|
||||||
primary = parent->secondary;
|
primary = parent->secondary;
|
||||||
secondary = link->secondary;
|
secondary = link->secondary;
|
||||||
|
|
|
@ -85,7 +85,8 @@ struct bus {
|
||||||
uint16_t bridge_cmd; /* Bridge command register */
|
uint16_t bridge_cmd; /* Bridge command register */
|
||||||
unsigned char link_num; /* The index of this link */
|
unsigned char link_num; /* The index of this link */
|
||||||
uint16_t secondary; /* secondary bus number */
|
uint16_t secondary; /* secondary bus number */
|
||||||
uint16_t subordinate; /* max subordinate bus number */
|
uint16_t subordinate; /* subordinate bus number */
|
||||||
|
uint16_t max_subordinate; /* max subordinate bus number */
|
||||||
unsigned char cap; /* PCi capability offset */
|
unsigned char cap; /* PCi capability offset */
|
||||||
uint32_t hcdn_reg; /* For HyperTransport link */
|
uint32_t hcdn_reg; /* For HyperTransport link */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue