(Also including the list as I welcome more eyeballs.)
Hi Nico,
Thanks for your pointers.
On Fri, 22 Dec 2023 at 08:55, Nico Huber nico.h@gmx.de wrote:
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().
I came up with the code at the end of this email. However it renders my board so inoperative I had to rescue myself. Can you see any obvious errors in it?
I commented out the timeout part as I thought it was hanging me up. It was not.
Thanks Keith
--------8<--------
void bootblock_mainboard_early_init(void) { nuvoton_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
if (CONFIG(POST_DEVICE_PCI_PCIE)) { /* * Enable PCIe root port 7 (00:1c.6) and the ASM1083 PCIe-PCI bridge behind it * and have it accept I/O cycles. This should allow a POST card in the PCI slot * to receive POST codes. * * Below is copied and modified from device/pci_early.c because CONFIG_PCI_EARLY_BRIDGE * doesn't quite do what we need. */ //int timeout; const int secondary = 3; pci_devfn_t bridge = PCH_PCIE_DEV(6); //pci_devfn_t p2p_bridge = PCI_DEV(secondary_bus, 0, 0);
/* Trigger secondary bus reset and program its bus number. */ pci_s_assert_secondary_reset(bridge); pci_s_deassert_secondary_reset(bridge); pci_s_write_config8(bridge, PCI_SECONDARY_BUS, secondary); pci_s_write_config8(bridge, PCI_SUBORDINATE_BUS, secondary + 1);
u16 reg16;
/* Enable I/O window behind the bridge. * Base = 0x0000 * Limit = 0x0FFF */ pci_s_write_config16(bridge, PCI_IO_BASE, 0x0000); pci_or_config16(bridge, PCI_COMMAND, PCI_COMMAND_IO);
/* Enable subtractive decode (PECR3[SDE]). */ pci_or_config8(bridge, 0xec, 0x01); /* Have to do it in D30F0 too, even though Z77 doesn't natively do PCI. */ pci_or_config32(PCI_DEV(0, 30, 0), 0x4c, (1 << 28));
/* Done with root port. Now do the 1083. */ bridge = PCI_DEV(secondary, 0, 0);
/* for (timeout = 20000; timeout; timeout--) { u32 id = pci_s_read_config32(bridge, PCI_VENDOR_ID); if (id != 0 && id != 0xffffffff && id != 0xffff0001) break; udelay(10); }*/
reg16 = pci_read_config16(bridge, PCI_CLASS_DEVICE);
if (reg16 != 0x0604) /* PCI-PCI Bridge */ return;
/* Trigger secondary bus reset and program its bus number. */ pci_s_assert_secondary_reset(bridge); pci_s_deassert_secondary_reset(bridge); pci_s_write_config8(bridge, PCI_SECONDARY_BUS, secondary + 1); pci_s_write_config8(bridge, PCI_SUBORDINATE_BUS, secondary + 1); /* Set this second bridge to decode the same I/O ports. */ pci_s_write_config16(bridge, PCI_IO_BASE, 0x0000); pci_or_config16(bridge, PCI_COMMAND, PCI_COMMAND_IO); }
}