参考:《PCIe-Multicast(组播)实现》
传统 PCIe系统局限于单目标传送 ,这种传输模式以主机为中心 ,使得主机在给定的时间,在某一时刻主机只能与众多子设备中的一个进行通讯 。
现在越来越多的应用需要同时向多个子设备发送数据,也许主机也不只是一个,甚至一个子设备也需要向主机向其他子设备发送数据 ,PCIE multicast应运而生。
组播是指同时像多个目标或者组发送信息,他允许每一个主机在某个时间可以和多个子设备进行通讯,同时向多个子设备发送相同的数据包,组播相比于传统的传送模式效率上大大提高,因此在工程实现中得到广泛的应用 。
PCIe Multicast的组播功能,实现在Switch上。例如 PEX8749、PEX8796等。
组播允许软件同时将相同的数据写入一组多个目标。PEX 8796的内存写入TLP被寻址到MC地址范围(MC BAR),并且启用了多播后,PEX 8796会自动生成并发送原始副本到一个或多个目标端口的TLP(称为MC复制TLP)。 MC地址空间是分为MC组(MCG),使用MC基址和MC索引位置定义。每PEX 8796端口可以通过选择属于MCG来选择接收MC Copy TLP。相应的MC接收位。如果需要,可以使用“全部阻止”来阻止MC TLP。MC覆盖栏可用于将原始MC TLP的地址替换为单播地址空间,如果端点不支持MC。
PCIE组播实现依赖于对 PCIe Multicast Capability结构的设置。PCIeMulitcastCapability 结构如下:
通过设置 MC Control寄存器和 MC BaseAddress寄存器我们把组地址空间划分为基于基地址的 N 组地址空间,每个组地址空 间大小为 2^MC_Index_Position。
触发 PCIe_Multicast条件为 :
在这个前提下组播会被激发 ,如果接收的设备 MC_Receive_bit与组播的 group匹配 ,该设备就能接到组播的 TLP。
某系统主机通过 pcie switch连接3个设备,在地址映射中我们可 以看到有四个PCIe端口,假设Port0为 up_stream_port,Port1、2、3为 设备端 ,地址 map如下 :
Port 0:F7800000 ~ F7AFFFFF
Port 1:F7A00000 ~ F7AFFFFF
Port 2:F7900000 ~ F79FFFFF
Port 3:F7800000 ~ F78FFFFF
按如下 设置设定 :
JD4000 总共19个芯片(3536*6 + 3519*12 + 6678),pci下的树形结构如下:
lspci -t -vxxx
-[0000:00]-+-00.0 Intel Corporation Sky Lake Host Bridge/DRAM Registers
+-01.0-[01-14]----00.0-[02-14]--+-04.0-[03]----00.0 Device 19e5:3536
| +-05.0-[04]----00.0 Device 19e5:3536
| +-06.0-[05]----00.0 Device 19e5:3536
| +-07.0-[06]----00.0 Device 19e5:3536
| +-08.0-[07]----00.0 Device 19e5:3519
| +-09.0-[08]----00.0 Device 19e5:3519
| +-0a.0-[09]----00.0 Device 19e5:3519
| +-0b.0-[0a]----00.0 Device 19e5:3519
| +-0c.0-[0b]----00.0 Device 19e5:3519
| +-0d.0-[0c]----00.0 Device 19e5:3519
| +-0e.0-[0d]----00.0 Device 19e5:3519
| +-0f.0-[0e]----00.0 Device 19e5:3519
| +-10.0-[0f]----00.0 Device 19e5:3519
| +-11.0-[10]----00.0 Device 19e5:3519
| +-12.0-[11]----00.0 Device 19e5:3536
| +-14.0-[12]----00.0 Device 19e5:3519
| +-15.0-[13]----00.0 Device 19e5:3519
| \-16.0-[14]----00.0 Device 19e5:3536
即有20个PCI桥片,01:00.0为02:04.0~02:16.0等桥片的上游。
简单点来说,在00:01.0 PCI bridge上的地址map大小为1536M.
地址映射中可以看到总共有18个端口。
BUS PORT BAR
02:16.0 22 0x2058000000-0x205bffffff 0x205c000000-0x205fffffff
02:15.0 21 0x2054000000-0x2057ffffff
02:14.0 20 0x2050000000-0x2053ffffff
02:12.0 18 0x2048000000-0x204bffffff 0x204c000000-0x204fffffff
02:11.0 17 0x2044000000-0x2047ffffff
02:10.0 16 0x2040000000-0x2043ffffff
02:07.0 7 0x2018000000-0x201bffffff 0x201c000000-0x201fffffff
02:0e.0 14 0x2038000000-0x203bffffff
02:0f.0 15 0x203c000000-0x203fffffff
02:06.0 6 0x2010000000-0x2013ffffff 0x2014000000-0x2017ffffff
02:0c.0 12 0x2030000000-0x2033ffffff
02:0d.0 13 0x2034000000-0x2037ffffff
02:05.0 5 0x2008000000-0x200bffffff 0x200c000000-0x200fffffff
02:0a.0 10 0x2028000000-0x202bffffff
02:0b.0 11 0x202c000000-0x202fffffff
02:04.0 4 0x2000000000-0x2003ffffff 0x2004000000-0x2007ffffff
02:09.0 9 0x2024000000-0x2027ffffff
粗略的,可以将整个00:01.0 PCI bridge上的地址map大小分为24块。(12*3519 + 6*3536*2)
每块map地址的大小都为64M大小(1536M / 24)。
按如下 设置设定 ,通过setpci设置相关组播寄存器:
每个端口MC_Control_Capability寄存器为 0x8017803F,24 group
setpci -s 01:00.0 0x334.l=0x8017803F
每个端口的 MC_Base_address寄存器 设为 0x00000020 0000001A,基地址为 0x0000002000000000,组地址大小为 64MB。
setpci -s 01:00.0 0x338.l=0x0000001A
setpci -s 01:00.0 0x33C.l=0x00000020
每个端口的 MC_Receive寄存器设为0x1FFFFFF(24个端口)。如此设置每个下行端口都能收到主机发出的 TLP。
setpci -s 01:00.0 0x340.l=0x1FFFFFF
setpci -s 01:00.0 0x344.l=0x0