summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2018-06-09 08:25:03 +0300
committerKyösti Mälkki <kyosti.malkki@gmail.com>2018-06-14 07:59:05 +0000
commit1dc5ce31ced5baee363f6d30049ca418ce414866 (patch)
tree7b49e7ceed093073e1c434c77401bb6c0469037f
parent3414f6035b5af0ef004742f0ba91fbad266a6162 (diff)
downloadcoreboot-1dc5ce31ced5baee363f6d30049ca418ce414866.tar.xz
coreinfo: Skip unpopulated PCI functions
Per PCI specification, function 0 must be present, so functions 1 to 7 can be skipped in this case. For a device that is not multi-function, it may not decode function number in the hardware at all. To avoid registering such a device eight times, skip scanning functions 1 to 7. Without the latter fix, a single-function PCI bridge may call pci_scan_bus() second time and secondary side devices would get appended second time in the array devices[]. At that point, quicksort() apparently hits an infinite recursion loop. Since pci_scan_bus() is called in part of the early modules->init() sequence early in main(), the errors here left coreinfo payload completely silent when PCI module was built-in on affected system. Terminal screen was cleared, though. Change-Id: Ifc6622f050b98afb7196de0cc3a863c4cdfa6c94 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/26990 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Nico Huber <nico.h@gmx.de>
-rw-r--r--payloads/coreinfo/pci_module.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/payloads/coreinfo/pci_module.c b/payloads/coreinfo/pci_module.c
index f79d543d5e..9f10b12703 100644
--- a/payloads/coreinfo/pci_module.c
+++ b/payloads/coreinfo/pci_module.c
@@ -183,8 +183,14 @@ static void pci_scan_bus(int bus)
/* Nobody home. */
if (val == 0xffffffff || val == 0x00000000 ||
- val == 0x0000ffff || val == 0xffff0000)
+ val == 0x0000ffff || val == 0xffff0000) {
+
+ /* If function 0 is not present, no need
+ * to test other functions. */
+ if (func == 0)
+ func = 8;
continue;
+ }
/* FIXME: Remove this arbitrary limitation. */
if (devices_index >= MAX_PCI_DEVICES)
@@ -197,7 +203,11 @@ static void pci_scan_bus(int bus)
/* If this is a bridge, then follow it. */
hdr = pci_read_config8(dev, REG_HEADER_TYPE);
- hdr &= 0x7f;
+
+ if ((func == 0) && !(hdr & HEADER_TYPE_MULTIFUNCTION))
+ func = 8;
+
+ hdr &= ~HEADER_TYPE_MULTIFUNCTION;
if (hdr == HEADER_TYPE_BRIDGE ||
hdr == HEADER_TYPE_CARDBUS) {
unsigned int busses;