在PCIe总线中,配置读写请求TLP(Transaction Layer Packet)、Completion(Cpl)和Completion Data (CplD) 报文使用Bus Number、Device Number和Function Number进行路由寻址,而不是像数据读写操作那样使用基于地址的路由,有几个主要的原因:
-
层级结构的设计:
- PCIe总线采用了层级结构的设计,其中每个设备都通过一个唯一的组合来标识:Bus Number、Device Number和Function Number。这种结构可以支持多层级的连接,每个层级都有其唯一的编号。
- Bus Number、Device Number和Function Number的组合提供了一个直接的、唯一的标识,用于在多级拓扑结构中精确定位和路由数据。这种标识方式比简单的基于地址的路由更适合于复杂的PCIe拓扑。
-
效率和可扩展性:
- 使用Bus Number、Device Number和Function Number进行路由可以提高路由的效率和可扩展性。这些数字是在PCIe配置空间中静态地配置的,并且由硬件直接处理,因此可以快速确定数据包的最终目的地。
- 相比之下,基于地址的路由可能需要更多的逻辑和计算,特别是在多级Switch和桥接器的情况下。使用静态的编号可以减少路由决策的复杂性和延迟。
-
标准化和互操作性:
- PCIe标准定义了Bus Number、Device Number和Function Number的使用方式,这种方式在所有符合PCIe标准的设备和主板上都是一致的。这种标准化促进了不同厂商设备之间的互操作性和兼容性,使得不同厂商的设备能够在同一个PCIe总线上协同工作。
综上所述,PCIe总线中配置读写请求TLP、Cpl和CplD报文使用Bus Number、Device Number和Function Number进行路由寻址,是基于其设计的层级结构、路由效率、可扩展性以及标准化和互操作性的考虑。这种设计保证了数据传输的高效性和系统的稳定性,尤其适合复杂的多设备、多级拓扑结构。
在PCIe总线中,基于ID的路由方式主要用于配置读写请求TLP、Cpl和CplD报文,此外Vendor_Defined消息报文也可以使用这种基于ID的路由方式。而在PCI总线中,只有配置读写周期才使用ID进行数据传递。
基于ID的路由方式与基于地址的路由方式有较大的不同,基于ID路由方式的TLP头格式也与基于地址路由方式的头格式不同,其报文格式如图5 6所示。
如上图所示,使用ID路由方式的TLP头,其Byte8~11字段与基于地址路由的TLP不同。基于ID路由的TLP,使用Bus Number、Device Number和Function Number进行路由寻址。从软件的角度上看,PCIe总线与PCI总线兼容,只是在PCIe总线中,每一个PCIe设备使用唯一的PCI设备号,但是每一个设备仍然可以有多个子设备(Function)。
PCIe总线规定,在一个PCI总线域空间中,最多只能有256条PCI总线,因此在一个TLP中,Bus Number由五位组成;而在每一条总线中最多包含32个设备,因此TLP中的Device Number由5位[2]组成;而每一个设备中最多包含8个功能,因此一个TLP的Function Number由3位组成。
配置读写请求TLP是使用“基于ID路由”的一组重要报文,其主要作用是读写PCIe总线的EP、Switch及PCIe桥片的配置寄存器,以完成PCIe总线的配置。在处理器系统上电之后需要进行PCI总线系统的枚举,为PCI总线分配总线号,并设置Switch、PCIe桥片或者EP的配置寄存器,如Limit寄存器组、Base寄存器组、BAR寄存器、Subordinate Bus Number、Secondary Bus Number和Primary Bus Number等一系列配置寄存器。
在上文中我们简单介绍了Limit寄存器组和Base寄存器组的用法,下文将重点描述Subordinate Bus Number、Secondary Bus Number和Primary Bus Number寄存器。Subordinate Bus Number、Secondary Bus Number和Primary Bus Number寄存器在Type 01h配置寄存器中,用来描述PCI-to-PCI桥片的上游及下游总线号。这段寄存器在PCI配置寄存器中的位置如图5 7所示。
与PCI总线中的桥片类似,Primary Bus Number记录PCI-to-PCI桥上游的PCI总线号,Secondary Bus Number记录PCI-to-PCI桥下游的第一个PCI总线号,而Subordinate Bus Number记录PCI-to-PCI桥下游的最后一个PCI总线号。
如图5 5所示,P-P1桥片的Primary Bus Number为0,Secondary Bus Number为1,而Subordinate Bus Number为3。这些总线号,在处理器系统对PCI总线进行枚举时由系统初始化程序设置,从系统初始化程序的角度上看,PCIe总线与PCI总线基本兼容,只是PCIe总线对配置空间进行了一些扩展。
如表5 2所示,RC可以使用Type 00h和Type 01h读写请求TLP,对PCIe设备的配置寄存器进行读写访问,配置读写请求TLP只能由RC发出,配置读写请求TLP使用基于ID的路由方式。
如图5 5所示的例子**,RC首先使用Type 00h配置请求TLP访问在PCI Bus0总线上的设备,PCI Bus0上的所有设备,包括桥片都要监听PCI Bus 0上的配置请求,在本例中只有Switch挂接在PCI Bus0上,实际上是Switch的上游端口与PCI Bus0直接相连。因此Switch的上游端口将接收RC发出的Type 00h配置请求TLP,之后Switch将向RC发出完成报文,结束配置请求。与PCI总线相同,PCIe总线的Type 00h类型配置请求TLP不能够穿越桥片,在图5 5中这类请求只能访问Switch上游端口的配置空间。**
PCI总线是基于共享总线的数据传送方式,在一条PCI总线上可以连接多个PCI Agent设备,其中每一个PCI Agent都提供了一个IDSEL#信号,这个信号与PCI-to-PCI桥片或者HOST主桥的地址线直接相连,PCI总线根据与IDSEL#信号与地址线的连接关系决定相应设备的Device Number。
这与PCIe总线的使用方法不同,**PCIe总线使用“端对端”的连接方式,在PCIe链路只能连接一个下游设备,而这个下游设备的Device Number只能为0。**而只有在Switch的虚拟PCI总线上可以连接多个Device Number不同的端口。
当一个虚拟PCI总线上挂接PCI-to-PCI桥时,系统配置软件将使用Type 01h配置请求TLP访问PCI-PCI桥下游的PCI设备。如图5 5所示,RC可以通过Type 01h配置请求TLP访问P-P2桥片、P-P3桥片,EP1和EP2。
当RC使用Type 01h配置请求TLP,直接访问P-P1桥的下游设备时,首先需要检查该TLP的Bus Number是否为1,如果为1表示该TLP的访问目标在PCI Bus 1总线上,此时PCI-to-PCI桥将这个Type 01h类型的TLP转换为Type 00h类型的TLP,然后推至PCI Bus 1总线,并访问其下的设备。
如果该TLP的Bus Number在P-P1桥片的Secondary Bus Number和Subordinate Bus Number寄存器之间,则P-P1桥片将该Type 01h类型的TLP直接转发到PCI Bus 1上,并不改变该TLP的类型,之后Type 01和类型的TLP将继续检查P-P2和P-P3桥片的配置空间,决定由P-P2还是P-P3接收该TLP。如果TLP的PCI Bus Number为2时,P-P2桥片将接收该TLP,并将该Type 01h类型TLP转换为Type 00h类型的TLP,然后发送给EP1,并由EP1处理该TLP。
上文简要讲述了配置请求TLP使用ID路由方式从上游端口向下游端口的传递规则,但是Vendor_Defined消息报文和Cpl和CplD报文还可能从下游端口向上游端口进行传递。此时PCIe总线处理方法略有不同。下文仍以图5 5为例说明这种情况。
当一个TLP从EP2传送到EP1或者RC时,首先检查P-P3桥片的配置空间,P-P3桥片发现该TLP不是发向自己时,将该TLP推至上游总线,即PCI Bus 1。如果PCI Bus1上P-P1桥片没有认领该TLP,该TLP将继续向P-P2桥片传递,并由这个桥片将TLP转发给合适的EP;如果P-P1桥片认领该TLP,该TLP将继续向上游总线传递,直至RC。
由以上描述可以发现,PCIe总线使用的基于ID的路由方式与PCI总线中配置读写总线事务通过PCI桥的方法较为类似。