PCIe Multicast组播功能实现

参考:《PCIe-Multicast(组播)实现》

PCIe组播概念

传统 PCIe系统局限于单目标传送 ,这种传输模式以主机为中心 ,使得主机在给定的时间,在某一时刻主机只能与众多子设备中的一个进行通讯 。

现在越来越多的应用需要同时向多个子设备发送数据,也许主机也不只是一个,甚至一个子设备也需要向主机向其他子设备发送数据 ,PCIE multicast应运而生。

组播是指同时像多个目标或者组发送信息,他允许每一个主机在某个时间可以和多个子设备进行通讯,同时向多个子设备发送相同的数据包,组播相比于传统的传送模式效率上大大提高,因此在工程实现中得到广泛的应用 。

PCIe Multicast的组播功能,实现在Switch上。例如 PEX8749、PEX8796等。

PCIe组播实现

组播允许软件同时将相同的数据写入一组多个目标。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 结构如下:

  • PCIe_Extended_Capability_Header:包含了extend_capability_ID,版本以及下一个 capability 偏移量。
  • MC_Control_and_Capability 寄存器:bit31为 multicast_enable_bit;Bit30-22:保留为0;Bit21-16 multicast_groups数量设置,用户可以根据需要定义组播的组数 ,值为0时表示只有一组,值为N时 group=N+I;Bit15.bit0为capability设置,厂商设定,不能修改。
  • MC_Base_Address寄存器 :Bit 63-l2:播基地址;Bit 11-6:保留为 0;Bit 5-0:Index_ position组播 memory空间,Memeory大小为 2 Index_Posiztion.Index_ position<12无效 。
  • MC_Receive寄存器 :Bit 63-0,每个位对应一个组播组用于接收数据,例如 bit3设置为1,表明该设备要接受第3组播组数据。
  • MC_block_All寄存器 :Bit63-0,每个位对应一个组,用于屏蔽数据,例如bit3设置为1,对于该设备所有来自第3组数据要被屏蔽。
  • MC_Block_untransated寄存器 :Bit 63-0,每个位对应一个组,用于屏蔽包含非透明地址的数据包 ,例如 bit3设置为1,对于该设备所有来自第3组数据要被屏蔽 。
  • MC_OVERLAY_BAR 寄存器 :该寄存器用于改变组播TLP中访问地址,Bit5-0,重定位访问地址空 间大小,如果该值小于6,地址改变机制无效;Bit63-6:重定向的地址 ,例如原TLP中访问地址是0x2000,如果重向地址设为0x1000,设备接收到这个TLP会把访问地址改为0x1000。

PCIe组播访问条件

通过设置 MC Control寄存器和 MC BaseAddress寄存器我们把组地址空间划分为基于基地址的 N 组地址空间,每个组地址空 间大小为 2^MC_Index_Position。

触发 PCIe_Multicast条件为 :

  1. MC_Enable被设置。
  2. TLP是一个写请求 。
  3. 目标地址落在组播地址范围 。

在这个前提下组播会被激发 ,如果接收的设备 MC_Receive_bit与组播的 group匹配 ,该设备就能接到组播的 TLP。

PCIe组播示例

某系统主机通过 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

按如下 设置设定 :

  1. 每个端口MC_Control_Capability寄存器为 0x8002803F,3 groups。
  2. 每个端口的 MC Baseaddress寄存器 设为 0x7800014,基地址为 0x7800000,组地址大小为 1MB。
  3. 每个端口的 MC Receive寄存器设为0x7。如此设置每个下行端口都能收到主机发出的 TLP。

PCIe组播实践

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

猜你喜欢

转载自blog.csdn.net/Ivan804638781/article/details/104964108
今日推荐