我们知道由PCIe训练器仿真的协议层PCIe RC 是用来测试用户开发的EP,市场上大多数公司是开发各类PCIe 外设的,不论GPU,AI加速卡,DPU,网卡,SSD主控芯片,等等,所有需要PCIe 6.0训练器仿真RC的场景多,PCI SIG进行CTS测试也是以测试外设为主;但是PCIe 训练器仿真的EP则专门用来测试用户开发的RC设备,一般情况是各类CPU,当然也包括PCIe Switch的RC端(连接下行EP外设的部分)。
SerialTek PCIe 6.0协议分析仪的训练器Tester(也叫Exerciser)功能支持设置成仿真RC或者EP。有用户问如果设置成EP来测试他们开发的CPU的时候,CPU是否可以在初始化过程中会扫描到这个仿真的EP device并且给它分配一个BDF(Bus: Device. Function)呢?这个就要了解BDF扫描机制是如何在系统里面实现的,我们今天先简单讲一下 PCIe 枚举里 BDF 的实现细节,再给你一个尽量贴近工程实际、尤其适合“CPU + PCIe协议仿真的 EP”场景的回答。
先上答案:
SerialTek公司的PCIe 6.0训练器在设置成EP emulation的时候是可以被CPU正确识别到BDF的,该设备在业内不同的主机系统里面都正确通过PCIe枚举的过程验证并且获得BDF分配,该仿真的EP和正常的PCIe EP device没有什么特别不同的地方。
这么说吧,如果这个仿真的 Endpoint 最终被 CPU/Root Complex 成功枚举到,CPU 在初始化扫描过程中就会“看到”并给它分配一个 BDF。但要注意,BDF 通常不是 Endpoint 自己预先决定并上报给 CPU 的固定号码,而是 Root Complex / 固件 / 操作系统在枚举过程中分配和记录的地址。Linux 文档里也直接把设备地址写成 domain:bus:device.function 这种形式,并明确这是系统里的 PCI 设备地址表示法。
我们上面这个场景里可以这样理解:
1)CPU 会不会“扫描到”这个 FPGA EP 的 BDF?会,但更准确地说是:CPU/RC 在扫描配置空间时发现了这个设备,然后给它安排了一个 BDF,并在后续访问中按这个 BDF 去访问它。前提是链路先起来,LTSSM 至少走到能正常进行配置访问的状态,并且 FPGA 这边把一个合法的 PCIe 配置空间端点行为模拟出来了,比如 Vendor ID / Device ID、Header Type、BAR、Class Code 等基本字段能被正确读到。Linux 内核文档也说明了 PCI 设备是通过总线上的配置与资源模型被内核识别和管理的。
2)BDF 到底是什么?BDF = Bus / Device / Function。 通常写成:
bb:dd.f
如果把 PCI domain 也带上,Linux 常写成:
dddd:bb:dd.f
例如 0000:17:00.0,其中 Linux 文档明确说明前面的部分可表示 PCI domain 和 bus,而后面的目录对应某个 slot/function 设备。
它本质上是配置访问地址,不是设备内部某个永久烧录的“身份证号”。
3)BDF 一般是怎么实现出来的?核心在 PCIe 枚举(enumeration)。
大致过程是:
device number、 functionnumber 发起配置读;bus/device/function 记录;所以:
4)PCIe协议分析仪的RC/EP仿真都是通过设备内部的高端FPGA实现的,在 FPGA 仿真 Endpoint 时,哪些东西是 FPGA 自己决定的,哪些不是?一般来说:
FPGA / EP 自己决定的:
不是 FPGA 自己最终决定的:
也就是说,FPGA 提供“我是什么设备”的配置空间内容;系统决定“你在这台机器里住哪个地址号”。 有些 SoC/PCIe EP 控制器会提供“PCIe gadget”一类接口,让你配置 vendorid、deviceid、BAR 大小等,但这不等于你能直接指定最终 BDF。Linux 文档里这类 EP gadget 接口就体现了这一点:可配置的是设备属性,而不是最终系统分配给它的完整 BDF。
5)那 CPU 初始化时,是“先知道 BDF”,还是“先发现设备再形成 BDF”?更贴近真实实现的说法是:先按候选的 bus/device/function 地址去探测配置空间,读到有效设备后,这个地址就成为该设备的 BDF。
所以从软件视角看,像是在“扫描 BDF”; 从设备视角看,是“系统在一堆可能地址里探测,发现你后把那个地址作为你的 BDF”。
6)这个 BDF 是不是每次开机都固定?不一定。 Linux 内核参数文档就明确提醒,PCI 的 bus/device/function 地址可能会因为插入新硬件、主板固件变化、或者内核参数变化而改变。
因此:
7)结合你这个“CPU + FPGA 仿真 EP”的场景,最实用的结论如果你的 FPGA Endpoint 仿真是正常的,那么 CPU 初始化时通常会:
00:01.0、 01:00.0 之类。但如果下面任一项有问题,CPU 就可能根本“看不到”这个 BDF:
0xFFFF;8)一句话总结BDF 不是 FPGA Endpoint 预先“报给 CPU”的固定编号,而是 CPU/Root Complex 在 PCIe 枚举过程中,根据系统拓扑和配置访问结果,为这个被发现的 Endpoint 确定并使用的地址。
链接: https://pan.baidu.com/s/1R-tJEqwBlzBaDR0WLuMU0Q?pwd=9av3 提取码: 9av3
如果你有其任何关于PCIe5&6.0, CXL, NVMe/NVMoF, NAND, DDR5/LPDDR5以及UFS测试方面的我问题想咨询,请访问:访问www.saniffer.cn / www.saniffer.com 访问我们的相关测试工具和产品;或者添加点击左下角“阅读原文”留言,或者saniffer公众号留言,致电021-50807071 / 13127856862,sales@saniffer.com。