• NXP i.MX8系列平台开发讲解 - 3.10 Linux PCIe资源分配与访问(二)


    目录

    1. PCIe BFD

    2. PCIe 配置空间

    2.1 PCIe 配置空间访问

    PCIe I/O访问方法

    PCIe MMIO访问方法

    3. PCIe BAR相关

    4. PCIe Capbility

    5. PCIe 操作


    本文将重点讲解PCIe的资源访问相关内容,对于PCIe资源访问是从Host 端老看可以对PCIe进行配置与访问的资源主要包括以下相关类目

    • BDF:BUS Devices Function

    • 配置空间

    • BAR

    • Capability

    • MSI/MSI-X

    • DMA

    1. PCIe BFD

    PCIe总线中的每一个功能都需要需要对应一个唯一的标识符,这个标识符就是这里提到的BDF,全称英文为Bus,Device,Function;

    BUS:总线号【8位】,最多通过配置软件分配256个总线号,初始总线号为0,通常都是由硬件分配给Root Complex。在分配总线号时候,当发现网桥时候,软件就给新的总线分配一个唯一并且大于网桥所在的总线号,一旦新的总线号分配成功,软件就继续扫描当前总线上更多的桥之前寻找新总线上的桥,这也是我们称为的“深度优先搜索”

    Device:设备号【5位】,PCIe允许在单个PCI总线上最多32个设备号;

    Function:功能号【3位】,最大值也就是可以定义8个Function,Fucntion 号也就是每个Device功能,这些功能可能包括硬盘接口,显示接口,以太网控制器,USB控制器。对于多功能的设备无需按照顺序实现。每个Function也有自己的配置地址,用于设置关联的资源;

    对于BUS分配的规则如图:

    图中对于BUS号的分配,遵循深度优先的方式,从Root Complex开始分配BUS0,Virtual P2P下端分配了BUS1,在此遇到了一个桥设备,对于桥设备总线定义了BUS2,继续往下分配了BUS3,也就是看到图中最左下端位置,分配完毕后,往右边继续分配了BUS4,依次类推。

    思考:

    对于Device和Fuction是如何分配?

    这里就不在采用何种深度优先去分配,而是设备本身就分配好的了。

    每个设备的BDF信息存在哪里?

    BDF是不存储在Device中,而是在逻辑上存在,在程序中,放在协议中去传输。

    查看BUS总线相关,可以采用lspci -tv

    2. PCIe 配置空间

    PCIe设备都有自己独立的一段配置空间,该部分空间是这个设备的。在系统中需要对这个设备分配一段内容空间,CPU访问这段内容空间就是访问此设备的配置空间,设备在出厂时,对于PCIe的配置空间都是默认值的。

    配置空间特点:

    设备端实现的一组特别的寄存器;

    软件和设备交互的接口,软件可以用来控制设备和查看设备的状态;

    每个设备的Fuction对应一个配置空间,而不是每个设备只有一个配置空间;

    配置空间大小:

    在PCI定义了256字节,但是在PCIe已经扩展到了4K,如图0x00~0xFFF;

    组成结构:

    头部数据:64字节(0x00~0x40)

    Capability Structure:192字节

    PCIe扩展空间:4096~256字节

    PCIe与PCI的配置空间的区别联系:

    在PCIe 配置空间中可以看到PCI相关,PCIe的发展是兼容PCI,每个设备的配置空间的256字节是PCI空间,后面的4~256字节是PCIE扩展空间。目前PCIe的配置空间为4K,PCIE一共支持256条Bus,32个Dev,8个Fun。 因此在满负载的情况下,共需内存大小 = 4k * 256 328 = 256K Bytes = 256M,这个256M的内存空间是为PCIE设备准备的空间系统不可用,这也是你的内存条实际可用的总是会小于标称的主要原因之一。对于PCIe配置空间有两种类型,主要通过Header Type进行区分

    PCIe 标准配置空间分两种Type 0 和Type1

    Type 0 主要是针对PCI的endpoint设备;

    type 1 主要是针对PCI bridge, switch。

    PCIe中配置空间头部信息根据Type0/1 不一样,可以看到

    2.1 PCIe 配置空间访问

    Pcie 配置空间的访问方法目前有两种,一种是IO, 还有一种是MIMO访问

    • PCIe I/O访问方法

    I/O访问,定义了两个IO寄存器用来访问设备的配置空间:

    CONFIG_ADDRESS

    CONFIG_DATA

    写入数据到配置空间:地址寄存器写入BDF和register;数据寄存器写入数据,完成写入

    从配置空间读取数据:地址寄存器写入BDF和register;然后从数据寄存器读取数据,完成读取;

    • PCIe MMIO访问方法

    MIMO方法:IO端口只能访问256(2^6)字节的配置空间,PCIe的配置空间扩展到4K,IO端口的无法访问到扩展的配置空间,所以定义了这么一段MMIO空间来配置访问空间,大小256M,空间地址范围查看如下

    hywel@ubuntu:~$ grep MMCONFIG -i /proc/iomem 
      00000000-00000000 : PCI MMCONFIG 0000 [bus 00-7f]

    读写操作:

    1. # 读取
    2. hywel@ubuntu:~$ lspci -xxx
    3. 00:00.0 Host bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (rev 01)
    4. 00: 86 80 90 71 06 00 00 02 01 00 00 06 00 00 00 00
    5. 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    6. 20: 00 00 00 00 00 00 00 00 00 00 00 00 ad 15 76 19
    7. 30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    8. # 省略很多
    9. # ...
    10. 00:07.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)
    11. 00: 86 80 11 71 05 00 80 02 01 8a 01 01 00 40 00 00
    12. 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    13. 20: 61 10 00 00 00 00 00 00 00 00 00 00 ad 15 76 19
    14. 30: 00 00 00 00 00 00 00 00 00 00 00 00 ff 00 00 00
    15. # 读取
    16. hywel@ubuntu:~$ lspci -s 00:07.1 VENDOR_ID
    17. # 写入。。注意当前是什么设备,有时候写完后不正常了
    18. hywel@ubuntu:~$ lspci -s 00.07.1 VENDOR_ID=0X111

    3. PCIe BAR相关

    PCIe BAR(Base Address Register) 基地址寄存器

    BAR的存在的意义是什么:

    设备内部使用RAM或者寄存器实现一些功能,有时候需要让外部来访问,比如网卡的队列描述符,DMA控制器等等,需要让Host来操作才能写入,或者GPU的显存RAM需要Host传输,然后才能GPU渲染计算;

    这些内部的RAM或者寄存器被Host访问,就需要Host统一寻址,也就是统一映射到Host物理地址空间;

    BAR里面写入的值,为了Host映射设备内部的RAM或者寄存器而分配的地址;

    BAR如何分配

    Host软件读取设备BAR的个数和大小,开始向BAR写入1,再读取,如果返回0,则没有;

    Host软件为设备的每一个BAR,进行分配统一物理地址空间,然后把基地址写入BAR;

    后面Host软件访问设备的RAM或者寄存器,就通过BAR里面的值加上偏移方向;

    4. PCIe Capbility

    PCIe Capbility是兼容PCI的Capbility,从PCIe的配置文件分布看到里面在地址空间0x40~0xff作为PCI的Capbility空间,PCIe的Capbility是在扩展部分存在。Capbility作为表示设备的能力,同时会提供设备状态额反应设备状态的功能。

    遍历标准的Capbility:地址范围(0x40~0xff),头部组成,Nex Capability指向下一个Capability ID,这样就形成了一个单向链表;

    遍历PCIe的Capability:地址范围(0x100~0xfff),0x100放第一个扩展的Capability

    Capability示例

    lspci -s 00:07.1 vxxxx|less

    5. PCIe 操作

    PCIe 设备可以发起操作主要分为两种DMA和interuput

    DMA

    Host无需参与数据传输,把数据从一个端点的数据传到另外一个端点,此过程完全不需要CPU的参与;

    MDA底层寓意:完全不需要CPU暗语的memory类型的TLP包传输;

    Interuput

    PCIe支持两种中断,

    INTx message: 模拟INTx,可选支持

    MSI : Message Signaled Interuput中断,必须支持

  • 相关阅读:
    计算机毕业设计Java电影周边产品查找系统(源码+系统+mysql数据库+lw文档)
    Matplotlib的一些常规操作
    Windows搭建minio存储
    C# .Net AOP 演进历史POP OOP 代码细节篇
    普通话水平测试考试命题自拟-(背诵版)
    java 企业工程管理系统软件源码+Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis
    【AI】Deepstream入门(2)Ubuntu20.04安装Deepstream
    MybatisPlus学习 条件构造器Wrapper方法详解
    Node+koa之目录优化和sequelize的使用(五)
    测试用例的优化与整理:确保软件质量的关键步骤
  • 原文地址:https://blog.csdn.net/zalebool/article/details/138225784