背景
笔者3年多Linux PCIe驱动开发与PCIe芯片验证经验,当前已经不专门搞PCIe,故做一个回顾与小结,希望后面不太清楚时能回头来看看。
建链问题
PCIe的拓扑和Linux的PCIe ID
PCIe的建链问题比较常见,由于各种厂商定位PCIe的方式方法不同,这里我们只介绍协议的方式 如何判断当前链路状态。在介绍建链前需要补充一下PCIe设备如何查看ID。Linux系统下通过以下命令,可以查到当前 PCIe 的拓扑图。
lspci –vt
下图是执行该命令后某个编译服务器的部分拓扑截图。关键信息是各个设备的ID即DBDF(Domain,Bus,Deivce,Function)号,识别到ID后才能针对某个设备做精确的查询和控制。
图中有个IEP设备就是0000:00:00.0, 这里的几个域的含义是第一个0000是domain域基本上都是0,第二个00是Bus总线号,第三个00是Device 设备号,第四个0是Function 功能号。这个RCiEP(Root Complex Integrated Endpoint)设备是Intel CPU自带的内部的模块,我们不需要关注,我们需要关注的是RP(Root Port)和EP(Endpoint),这里是借这个设备说明一下如何查看PCIe 设备的DBDF号,图中红字也有说明。
这个图里面能看到有3 RP,即00:01.0, 00:02.0, 00:03.0。同时也能看到00:02.0下挂了一个EP,但这个EP有两个PF(Physical Function),一个是02:00.0 WX7100 一个是02:00.1 RX580。同时00:03.0 下挂了一个EP,这个EP只有一个PF 03:00.0 NVMe SSD
自此,该拓扑解析完成,目前看到有3个RP 2个EP,且有个EP有2个PF,还有1个RCiEP。
注:绝大部分场景下,设备都在一个domain域内,所以lspci工具使用时通常会省略domain域,即domain默认值为0。
查看当前PCIe建链状态
当我们已经知道拓扑后,我们就知道哪个设备挂载哪个RP下了。假设我们有个设