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>
This commit is contained in:
Kyösti Mälkki 2018-06-09 08:25:03 +03:00
parent 3414f6035b
commit 1dc5ce31ce
1 changed files with 12 additions and 2 deletions

View File

@ -183,8 +183,14 @@ static void pci_scan_bus(int bus)
/* Nobody home. */ /* Nobody home. */
if (val == 0xffffffff || val == 0x00000000 || 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; continue;
}
/* FIXME: Remove this arbitrary limitation. */ /* FIXME: Remove this arbitrary limitation. */
if (devices_index >= MAX_PCI_DEVICES) 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. */ /* If this is a bridge, then follow it. */
hdr = pci_read_config8(dev, REG_HEADER_TYPE); 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 || if (hdr == HEADER_TYPE_BRIDGE ||
hdr == HEADER_TYPE_CARDBUS) { hdr == HEADER_TYPE_CARDBUS) {
unsigned int busses; unsigned int busses;