如果系统里有一个PCIe设备了,我们想对这个PCIe设备的PCIe层进行控制,最常见的方式就是配置这个设备PCIe配置空间的寄存器了。
每个PCIe设备有4K大小的配置空间,前256字节是兼容PCI,所有PCIe设备一致,协议定义了的寄存器内容,后面的就是各个厂商自定义空间。
在linux下对配置空间进行寄存器读写的命令是setpci,具体用法可以看help,上篇文章中提到的lspci命令更多用法也可以看help。
协议里面配置空间header有2种分布,分为Type0和Type1,Type0指的是Endpoint,Type1指Rc以及switch,为什么会有这个差异,可以看到协议里面这两个header最明显的差异在0x10起始的地址。Type0是bar0到bar5,而Type1只有bar0和bar1,其他是一些memory范围和prefetch memory范围。那是因为RC和switch下面都要接设备,而且RC的作用只是发起请求和处理请求,而且RC还可以直接访问内存,switch只转发数据,可以说它们只需要PCIe的功能就可以了,而Endpoint作为网卡有网络报文传输的作用,它不仅仅是一个PCIe设备,还是一个网络设备,网络相关的功能需要映射内存,就是通过bar地址来实现的。
看完header后,我们可以看到还有一些Capability,每个Capability表示这个PCIe设备支持的一个功能,