[摘要]:本文主要介绍 PCIe 协议中 Bus、Device 和 Function 的基本定义。
PCIe 总线的拓扑结构就像一颗葡萄树:树根相当于 PCIe Root Complex,树干和树枝相当于 PCIe Bus,一整串葡萄相当于 PCIe Device,一颗葡萄相当于 PCIe Function。
只要对每一个树枝、每一个葡萄串、每一颗葡萄进行唯一编号,我们就能精准的定位到每一颗葡萄。
Bus - 总线
PCIe 最多支持 256 个总线编号(Bus Number)。初试总线编号为 0,通常会分配给 Root Complex(其实是分配给 Root Complex 内部的虚拟总线)。
从功能逻辑上来讲,我们可以认为 Root Complex 内部包含了一个 Host/PCI 桥、一个虚拟总线和多个虚拟 P2P 桥。Host/PCI 桥用于 Root Complex 和 CPU 的连接;虚拟总线用于 Root Complex 内部的数据传输;虚拟 P2P 桥用于创建新的总线,以连接外部设备(Switch 或者 Endpoint)。
除了虚拟总线被编号为 0 以外,每个虚拟 P2P 桥还需要被分配设备编号(Device Number)和功能编号(Function Number)。
每一个桥(Bridge)都意味着会产生一条新的总线,每条总线的编号必须是唯一的。
与 Root Complex 类似,Switch 也可以被看作由一条虚拟总线和多个虚拟 P2P 桥组成的。
Device - 设备
PCIe 协议允许每条总线最多连接 32 个设备。鉴于 PCIe 设备之间是端到端(Point-to-Point)连接的,所以除了 Root Complex 和 Switch 内部的虚拟总线之外,其它 PCIe 总线上只能连接 1 个新设备。因此,除了 Root Complex 和 Switch 内部的虚拟设备之外,其他设备的编号都是 0,如下图所示:
Function - 功能
Function 是指 PCIe 设备内部相对独立的功能逻辑,每个 Function 具有完全独立的配置空间(Configuration Space)。例如,在一个 PCIe 设备中可以有多个 Function,其中一个 Function 具备网卡功能,另一个 Function 具备 USB 控制器功能,还有其它的 Function 具备显卡功能。
每个 PCIe 设备都必须包含 Function 0。
当 PCIe 设备包含多个 Function 时,Function 的编号不要求是连续的。例如,某个 PCIe 包含 3 个 Function,那么可以编号为 Function 0、Function 2 和 Function 7。