Hi Keith,
On 22.12.23 08:53, Keith Hui wrote:
My board has a PCI-PCI bridge on bus:device.func 3:0.0 (so bus 3, this will be important) that services the PCI slot. After applying [1] to have the PCH send port 80 data to PCI as I specified in Kconfig, I still don't get any POST code... and not over LPC either, so I know my patch works.
Now I think I may need to enable CONFIG_EARLY_PCI_BRIDGE. Problem is the bridge has to be a device on bus 0.
you'll have to enable all bridges on the path to your PCI device. Starting with the bridge on bus 0. Note that all bus numbers except bus 0 are decided by software. The EARLY_PCI_BRIDGE code is currently not prepared for this. You'll have to * configure more than one bus (repeat what the code currently does) * configure PCI_SUBORDINATE_BUS everywhere to the highest bus number * configure a port I/O range (code currently assumes MMIO) (I don't think there's a simple port 80h switch for PCI bridges, but could be wrong)
The code currently sets bus 15 (as a comment suggests, this is an arbitrary number >0). For your case with the P8Z77-M, the procedure could look like this:
For 00:1c.6: * PCI_SECONDARY_BUS => 15 * PCI_SUBORDINATE_BUS => 16
For 0f:00.0: * PCI_SECONDARY_BUS => 16 * PCI_SUBORDINATE_BUS => 16
For both bridges: * PCI_IO_BASE => 0x00 * PCI_IO_LIMIT => 0x00 (lower bits are implied to be 1s) * PCI_IO_BASE_UPPER16 => 0x00 (registers only exist if indicated * PCI_IO_LIMIT_UPPER16 => 0x00 by PCI_IO_BASE[0..3] == 0x01) * PCI_COMMAND => PCI_COMMAND_IO
Then your device should show up as 10:00.0 (if the board uses 00 as slot number), in case you need to configure something there. That's usually done in pci_early_device_probe().
It's probably not too much work to refactor the code to support multiple bridges in a generic way. For instance, by allowing CONFIG_EARLY_PCI_BRIDGE_DEVICE and _FUNCTION to be comma- separated lists (having two arrays is a bit ugly, though...):
unsigned int bus = 0; const unsigned int max_subordinate = 255; unsigned int bridge_devs[] = { CONFIG_EARLY_PCI_BRIDGE_DEVICES }; unsigned int bridge_funcs[] = { CONFIG_EARLY_PCI_BRIDGE_FUNCTIONS }; _Static_assert (ARRAY_SIZE(bridge_devs) == ARRAY_SIZE(bridge_funcs));
for (int i = 0; i < ARRAY_SIZE(bridge_devs); ++i, ++bus) { const pci_devfn_t bridge = PCI_DEV(bus, bridge_devs[i], bridge_funcs[i]); const unsigned int secondary_bus = bus + 1; /* do thing for each bridge */ }
/* pci_early_device_probe() etc. */
Hope that helps, Nico