本文将mark下pci-pci bridge相关notes。

Overview

For PCI-PCI bridges to pass PCI I/O, PCI Memory or PCI Configuration address space reads and writes across them, they need to know the following:

  • Primary Bus Number
    The bus number immediately upstream of the PCI-PCI Bridge,

  • Secondary Bus Number
    The bus number immediately downstream of the PCI-PCI Bridge,

  • Subordinate Bus Number
    The highest bus number of all of the busses that can be reached downstream of the bridge.

  • PCI I/O and PCI Memory Windows
    The window base and size for PCI I/O address space and PCI Memory address space for all addresses downstream of the PCI-PCI Bridge.

Bus Number

1
2
3
4
5
/* Header type 1 (PCI-to-PCI bridges) */
#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */

The problem is that at the time when you wish to configure any given PCI-PCI bridge you do not know the subordinate bus number for that bridge. You do not know if there are further PCI-PCI bridges downstream and if you did, you do not know what numbers will be assigned to them. The answer is to use a depthwise recursive algorithm and scan each bus for any PCI-PCI bridges assigning them numbers as they are found. As each PCI-PCI bridge is found and its secondary bus numbered, assign it a temporary subordinate number of 0xFF and scan and assign numbers to all PCI-PCI bridges downstream of it.

其实subordinate的计算是基于DFS算法的。

算法详细请参考Configuring PCI-PCI Bridges - Assigning PCI Bus Numbers

PCI I/O and PCI Memory Windows

PCI-PCI bridges only pass a subset of PCI I/O and PCI memory read and write requests downstream. For example, in the following Figure, the PCI-PCI bridge will only pass read and write addresses from PCI bus 0 to PCI bus 1 if they are for PCI I/O or PCI memory addresses owned by either the SCSI or ethernet device; all other PCI I/O and memory addresses are ignored. This filtering stops addresses propogating needlessly throughout the system. To do this, the PCI-PCI bridges must be programmed with a base and limit for PCI I/O and PCI Memory space access that they have to pass from their primary bus onto their secondary bus.

  • The PCI-PCI Bridge
    We now cross the PCI-PCI Bridge and allocate PCI memory there:

    • The Ethernet Device
      This is asking for 0xB0 bytes of both PCI I/O and PCI Memory space. It gets allocated PCI I/O at 0x4000 and PCI Memory at 0x400000. The PCI Memory base is moved to 0x4000B0 and the PCI I/O base to 0x40B0.
    • The SCSI Device
      This is asking for 0x1000 PCI Memory and so it is allocated it at 0x401000 after it has been naturally aligned. The PCI I/O base is still 0x40B0 and the PCI Memory base has been moved to 0x402000.
  • The PCI-PCI Bridge’s PCI I/O and Memory Windows
    We now return to the bridge and set its PCI I/O window at between 0x4000 and 0x40B0 and it’s PCI Memory window at between 0x400000 and 0x402000. This means that the PCI-PCI Bridge will ignore the PCI Memory accesses for the video device and pass them on if they are for the ethernet or scsi devices.


参考资料:

  1. Configuring PCI-PCI Bridges - Assigning PCI Bus Numbers
  2. Allocating PCI I/O and PCI Memory to PCI-PCI Bridges and Devices
  3. https://wiki.osdev.org/PCI
  4. https://tldp.org/LDP/tlk/dd/pci.html