065、PCIE配置地址路由:从一次诡异的设备丢失说起
上周调试一块自研的PCIe扩展卡,系统启动时设备时有时无。lspci命令的输出像在玩捉迷藏——有时能看到设备,有时只剩空气。更诡异的是,当设备“隐身”时,配置空间读回来的全是0xFF。这种问题往往指向配置地址路由的底层机制出了问题。
配置事务的三种路由方式
PCIe配置请求不像内存访问那样简单。它需要一套专门的寻址机制来定位总线上的设备,这就是配置地址路由。路由方式取决于请求的目标地址:
总线/设备/功能号(BDF)路由是最经典的方式。每个PCIe设备都有唯一的BDF标识:8位总线号、5位设备号、3位功能号。系统软件通过遍历总线来发现设备时,用的就是这种路由。比如BDF(0x01, 0x05, 0x00)表示总线1上的设备5、功能0。
ID路由主要用于消息事务,但在某些配置场景下也会涉及。它使用16位的厂商ID和16位的设备ID来匹配目标,适合在设备驱动已经加载但BDF可能变化的场景。
隐式路由则专用于根复合体到端点设备的广播或定向消息,比如电源管理、错误信号等系统级通信。
配置空间访问的硬件实现
配置周期在PCIe链路上被封装成TLP(事务层包)。关键之处在于:CPU发出的配置读写请求,必须通过根复合体转换成对应的TLP格式。