Hi again, and a happy new year!
On 03.01.24 05:44, Keith Hui wrote:
/* Trigger secondary bus reset and program its bus number. */ pci_s_assert_secondary_reset(bridge); pci_s_deassert_secondary_reset(bridge);
I don't think this is actually necessary as everything should be reset already. The actual procedure is more involved. There should be a delay between assertion and de-assertion.
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);
One thing I didn't consider, this will conflict with all the other legacy I/O ports (e.g. RTC, UART). And it's not necessary, as...
/* Enable subtractive decode (PECR3[SDE]). */ pci_or_config8(bridge, 0xec, 0x01);
...this should actually suffice for the root port. I didn't know Intel implemented this. But given that they did, it's the best option for your case. I don't know if you also have to set the PCI_COMMAND_IO bit. If you do, set PCI_IO_BASE to 0x00ff (which disables it to avoid conflicts by positive decoding).
/* 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));
But you should never enable this for more than one device on a given bus. If your port 80 sink is behind the root port, don't do this for the legacy PCI bridge.
/* 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);
You should clear the PCI_SECONDARY_BUS registers afterwards as the current early-PCI code does. This is to avoid conflicts with coreboot's later PCI enumeration. Start with PCI_DEV(secondary, 0, 0), then the root port.
Hope this helps, Nico