Linux驱动——PCI

Linux驱动——PCI

小狼@http://blog.csdn.net/xiaolangyangyang


Linux驱动——PCI_第1张图片

Linux驱动——PCI_第2张图片

Linux驱动——PCI_第3张图片

PCI设备枚举过程:

PC系统中BIOSOS均实现了枚举过程,linux可通过内核PCI access mode配置选择使用OS还是BIOS进行枚举,嵌入式系统中枚举过程由linux驱动实现)

1PCI控制器是通过读取配置空间寄存器的VID检测是否存在bridgedevice,读取值为0xFF则为空;

2PCI控制器在bus上(从bus0-device0-func0开始)扫描bridge,如果有bridge,则初始化该配置空间,写入bus num到该配置空间寄存器,再跳转到对应的bus上扫描下一级bridge注意:该处写入bus号到硬件后,访问对应的下一级bridge才有效,其跳转就是读取对应的地址偏移的配置寄存器);

3CPU最初只能扫描到bus0上的bridgedevice,初始化其下的bridge配置寄存器后(写入bus num),才能正常扫描对应的下一级bus

4、递归式扫描整个配置寄存器形成树状结构;

5、依次在所有的bus上扫描device,通过向BAR空间写0xFFFFFFFF,读取BAR值确定BAR地址空间sizetype,一个func包括6BAR空间,每个有效的BAR都需要分配物理地址;

6、系统分配物理空间地址(该地址即为PCI空间映射到MEM空间的物理地址)写到BAR寄存器高bit位,这样在CPU访问到该部分物理空间地址时,就落入到了RC空间。

PCI MEM/IO映射过程:

(由Linux driver实现)

        Linux驱动申请虚拟地址将BAR寄存器分配的物理地址进行MEM or IO映射,CPU发出一个物理地址,落入分配给RC的空间,这个地址进入PCIE的调度体系,就可以从RC开始,变成PCIE自己的消息(TLP)。

NVMe协议:

NVMe协议是基于PCIe接口的一种SDD标准协议,其在PCIe上支持65536个命令队列,MessageDatacore)支持乱序,支持的接口如下:

1message:用于传输命令,命令可变数据长度(512b2Mb),一般只有一个message接口;

2datacore):用于传输数据,一般有多个data接口。

PCI设备驱动程序:

        左边主要涉及的是PCI总线驱动,那么PCI设备驱动是什么呢。PCI设备驱动是通过PCI总线桥梁连接的硬件设备的驱动,例如基于PCI总线的网卡设备。以下代码是一个典型的PCI设备代码框架:

Linux驱动——PCI_第4张图片

疑难问答:

1、在枚举之前访问左右的配置空间是什么效果?
        枚举之前,没有将bus num写入配置寄存器,只能访问到root bridge下的全部配置寄存器,其他配置寄存器读出来全是0。
        例如root bridge下挂载有3个bridge,分别是B_A、B_B、B_C,每个bridge下挂载一个dev,分别是D_A、D_B、D_C,这时读取bus 0下的配置寄存器,能读到B_A、B_B、B_C,但是在任何bus下都读不到D_A、D_B、D_C。
        把B_A的bus num写1后,就能读取到bus 1下的D_A;
        把B_B的bus num写2后,才能读取到bus 2下的D_B;
        把B_C的bus num写3后,才能读取到bus 2下的D_C。

2、写入BAR寄存器的地址是什么地址?
        写入BAR寄存器的地址是PCI空间地址,CPU要访问这个地址,就得有MEM空间到PCI空间的地址映射,各平台映射关系如下(一般为一一映射关系):
        X86:一一映射关系,只要CPU向某个物理地址写数据,bridge都能获取,如果是BAR地址,就会将该数据经bridge传到PCI;
        powerPC:Outbound和Inbound寄存器组;
        ARM:AXI总线传递数据,ARM使用ECAM的方式访问pcie配置空间,BAR空间也是吗?

3、怎么读写配置寄存器?

       X86:PCIe配置寄存器与MEM独立编址,使用CFG_ADDR、CFG_DATA寄存器读写;
       ARM ECAM映射:ECAM把PCIe配置寄存器映射到MEM空间,统一编址;
       ARM硬件支持:硬件直接将PCIe配置寄存器分配到MEM空间,统一编址。

Linux驱动——PCI_第5张图片

 4、PCI空间与MEM空间怎么映射?

       X86:一一对应映射;
       ARM/PowerPc;使用Outbound和Inbound寄存器组进行映射配置。


 Linux Kernel核心中文手册-Chapter6-PCI

必看:原来PCIe技术原理这么简单!

PCI BAR设置过程

PCIe设备枚举
PCI设备BAR空间的初始化

RISCV Platform Spec之PCIe

从cpu角度理解PCIe

从cpu角度理解PCIe续集

你可能感兴趣的:(Linux内核,linux)