PCIe 基础知识

参考:Linux PCI驱动框架分析(二)

PCIe设备与数据结构

PCIe在Linux driver中被抽象为各种数据结构,PCIe Host bridge被抽象为struct pci_host_bridge;PCIe bus被抽象为struct pci_bus; PCIe switch 和PCIe endpoint被抽象为struct pci_dev.

PCIe 配置空间 

PCIe配置空间分为兼容配置空间和扩展配置空间。

兼容配置空间: PCIe配置空间完整保留了PCI总线的配置空间,大小256Byte,前面的64Byte位配置头,分为Type0Type1.Type0表示Endpoint, Type1表示Bridge. 紧接着的192BytePCI Capability.对于PCIe必须实现下面的Capability structures:

        •  PCI Express Capability

        •  Power Management

        •  MSI and/or MSI-X

配置空间格式如图:

 扩展配置空间:PCIe将配置空间扩展到4KB,用于支持PCIe总线中的新功能

CPU读Endpoint配置空间流程如下:

        • CPU产生memory requestIO request.

        • RCCPU request转换为配置读写请求.

        • 根据BDF查找设备(如右图从bus4,device0, fun0 reg0读取2Bytes); Bridge检查请求的BDF中的Bus号是否与自己的下一级总线号相等,相等则将Type1转换为Type0发给下一级(Endpoint);不相等,但在自己下级总线号和最后一级总线号之间,则将Type1请求发给下一级总线;如果没在自己下级总线号和最后一级总线号之间,则该桥认为这一请求和自己无关,忽略.

        备注:PCIe Spec规定只有RC有权限发起配置请求,且配置请求的路由只能采用BDF;传统PCI设备使用IO间接寻址访问;PCIe设备使用Memory-mapped访问

PCIe设备枚举

BDF(Bus, Device, Function)是PCIe总线中每个功能独一无二的标识符.

Bus: 占用8,PCIe总线最多支持256个子总线, Bus0总是分配给Root Complex.

Device: 占用5,即每个子总线最多支持32个设备

Function: 占用3,即每个设备最多支持8个功能. 每个设备必须有Fun0,其他可选.

枚举算法:深度优先(depth-first-search

         1. Bus number 0开始;以BDF=0:0:0读设备A的配置空间寄存器vendor IDdevice ID

        2. 设备AVendor IDdevice ID有效,继续读设备A的配置空间寄存器header type,判断设备C是桥设备还是endpoint,该示例为桥设备,桥设备则初始化设备A配置空间寄存器Primary bus=0Secondary bus=1Subordinate bus=255

        3. 以BDF=1:0:0读设备C的配置空间寄存器vendor IDdevice ID

        4. 设备Cvendor IDdevice ID有效,继续读设备C配置空间寄存器header type,判断设备C桥设备还是endpoint,该示例为桥设备,桥设备则初始化设备C配置空间寄存器Primary bus=1Secondary bus=2Subordinate bus=255

        5. 以BDF=2:0:0读设备D的配置空间寄存器vendor IDdevice ID

        6. 设备Dvendor IDdevice ID有效,继续读设备D配置空间寄存器header type判断设备D桥设备还是endpoint,该示例为桥设备,桥设备则初始化设备D配置空间寄存器Primary bus=2Secondary bus=3Subordinate bus=255

        7. 以BDF=3:0:0设备的配置空间寄存器vendor IDdevice ID,设备的vendor IDdevice ID有效,继续读设备的配置空间寄存器header type判断设备是桥设备还是endpoint,该示例endpoint,继续读设备的配置空间判断时single-function设备还是multi-function设备

        8. 7中的设备为multi-function,然后以BDF=3:0:1设备的配置空间寄存器vendor IDdevice ID,设备的vendor IDdevice ID有效,然后做一些初始化操作

        9. Bus3的设备遍历结束之后,发现桥设备D下最大的bus number3,则将设备D的配置空间寄存器Subordinate bus=3

        10. Bus3遍历结束后,回到Bus2,以BDF=2:1:0读设备E,和步骤5类似

        11. 步骤11和步骤6类似,步骤12和步骤7类似,步骤13&14&15和步骤9类似

下图为枚举完成后的BDF,以及bus编号

PCIe设备枚举的软件实现

        1. 设备的扫描从pci_scan_root_bus_bridge开始,首先需要先向系统注册一个host bridge,在注册的过程中需要创建一个root bus,也就是bus 0,在pci_register_host_bridge函数中,主要是一系列的初始化和注册工作,此外还为总线分配资源,包括地址空间等

        2. pci_scan_child_bus开始,从bus 0向下扫描并添加设备,这个过程由pci_scan_child_bus_extend来完成

        3. 从pci_scan_child_bus_extend的流程可以看出,主要有两大块

                • PCI设备扫描,从循环也能看出来,每条总线支持32个设备,每个设备支持8个功能,扫描完设备后将设备注册进系统,pci_scan_device的过程中会去读取PCI设备的配置空间,获取BAR的相关信息;

                • PCI桥设备扫描,PCI桥是用于连接上一级PCI总线和下一级PCI总线的,当发现有下一级总线时,创建子结构,并再次调用pci_scan_child_bus_extend的函数来扫描下一级的总线,从这个过程看,就是一个递归过程

以RK3568为例,枚举完成后的topology如图:

各种数据结构之前的关系为:

 PCIe地址空间

PCIe地址空间包含三类:Cofiguration配置空间;Memory空间;IO空间 

: PCIe spec规定,IO地址空间只为兼容早期的PCI设备,在新设计中应当使用MMIO(Memory Mapped IO),设备中的内部存储和寄存器都统一映射到存储地址空间(Memory Address Space)

每个PCIe设备(endpoint、bridge)都包含一个配置空间(4k), 对于endpoint设备配置空间header为Type0,包含6个32位的BAR(Base Address Register)寄存器,对于bridge设备配置空间header为Type1,包含2个32位的BAR寄存器。通过BAR寄存器可以分别映射PCIe的memory空间和IO空间到系统的设备地址空间和系统的IO空间中。

QCOM QCS8250 PCIe地址空间

reg = <0x60100000 0x10000>表示配置空间

ranges: <local_addr cpu_addr size>

        • local_addr:字节数由所在节点的#address-cells决定; 此处为3,local_addr的第一个数字右移24位与0x03作与表示地址空间类型,

                (0x01000000>>24)&0x3==0x01表示IO地址空间;

                (0x02000000>>24)&0x3==0x02(32) or 0x03(64)表示MEM地址空间.

        • cpu_addr:字节数由父节点的#address-cells决定

        • size:字节数由所在节点的#size-cells决定

上述ranges的含义为:

PCIe IO地址空间0x60200000---0x602FFFFF映射到CPU地址空间0x60200000---0x602FFFFFsize:1MB

PCIe MEM地址空间0x60300000---0x63FFFFFF映射到CPU地址空间0x60300000---0x63FFFFFFsize:61MB

: bus-rangeranges地址信息加入到(struct pci_host_bridge)bridge->windows链表中管理

BARs寄存器初始化流程

32Endpoint设备请求2MB NP-MMIO示例

        1. BAR[0:3]:只读位,含义如下:

                bit0:0 = Memory request;1 = IO request

                bit[1:2]: 00 = 32-bit decoding; 10 = 64-bit decoding

                bit[3]: 0 = non-prefetchable; 1= prefetchable

        2. 软件写全1到BAR寄存器,然后读回BAR寄存器的值,2的最低可写位次方就是BAR空间需要的大小,此处最低可写位为21,则BAR大小2^21=2MB

        3. 系统为设备分配2MB的地址空间,然后将其实地址写入到BAR寄存器中,此处写到BAR寄存器的值为0x60400000

CPU写该endpoint BAR0寄存器示意图如下:

  • 8
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值