Re: Is there a way to enable a PCI-PCI bridge on bus 3 early?
Nico Huber via coreboot <[email protected]>
| Newsgroups | gmane.linux.bios |
|---|---|
| Message-ID | <[email protected]> |
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
_______________________________________________
coreboot mailing list -- [email protected]
To unsubscribe send an email to [email protected]