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]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.