PCIe-BAR空间的访问和配置

前文:

        几乎所有的设备中都有能够让软件访问的内部寄存器或是存储空间位置。这些内部位置有可能用来控制设备的行为、报告设备的状态,或者可能用来保持住设备要进行处理的数据。这意味着这些内部位置需要是可寻址的(addressable)。软件必须可以执行一个带有地址的读或者写操作,以此来访问目标设备内相应的内部位置。为了让这种方式可行,这些内部位置都需要被分配地址,并且所分配的地址也都必须是系统所支持的地址空间。

        PCIe支持三个地址空间,与PCI中的三个地址空间完全相同:

        配置空间(Configuration)

        内存地址空间(Memory)

        IO地址空间(IO)

        前文中配置空间是由PCI引入的,软件通过配置空间就可以用一种标准化的方法来对设备的状态进行控制和检查。PCIe对PCI软件具有向后兼容性,所以PCIe中仍然支持配置空间。尽管配置空间出现的意义是来放置和保持一些标准化的结构(PCI-defined Header、Capability Structure能力结构等等),但是PCIe设备也会经常的将一些设备特定(device-specific)的寄存器映射到设备自身的配置空间中。在这种情况下,映射到配置空间的设备特定寄存器常用来作为控制寄存器(control)、状态寄存器(status)或者指针寄存器(pointer),而不是用来存储数据。

        此外,一个系统中的每个设备对地址空间的数量和类型可能都有不同的要求。如一个设备可能有256byte大小的内部寄存器/存储需要通过IO地址空间来访问,而另一个设备中可能有16KB的内部寄存器/存储需要通过MMIO来访问。基于PCI的设备不允许自己来决定哪些地址可以用来访问它们内部的位置,做这些决定是系统软件负责的工作(例如BIOS和操作系统内核)。因此设备必须为系统软件提供一个途径用来确定设备对地址空间的需求。一旦软件知道了设备对地址空间的需求是什么样的,并假设这个需求是可以被满足的,软件就会给对应的设备分配一段可用的地址范围和相应的地址空间类型(IO、NP-MMIO、P-MMIO)。这些都是通过配置空间Header中的基地址寄存器BARs(Base Address Registers)来完成的

1.1. PCIe地址空间类型
  • 配置空间:标准化访问设备配置信息(如PCIe头、能力结构),支持设备发现和初始化。通过特定机制(如Intel的CONFIG_ADDRESS/CONFIG_DATA)访问。

  • 内存地址空间(MMIO):将设备寄存器/内存映射到系统内存地址,分为:

    • 可预取(Prefetchable):读无副作用,允许预取和写合并,提升性能。

    • 不可预取(Non-Prefetchable):读可能有副作用(如状态寄存器读后自动清零),需严格按序访问。

  • IO地址空间:传统x86架构的端口IO(PIO),PCIe不推荐使用,仅为兼容性保留。

1.2. 基地址寄存器(BARs)
  • 作用:设备通过BAR向系统声明地址需求,系统分配基地址后写入BAR,形成设备寄存器的访问入口。

  • 结构

    • Type 0 Header(端点设备EP):6个32位BAR,最多请求6个独立地址区域。

    • Type 1 Header(桥设备,如Switch端口、RC):2个BAR,用于下游总线配置。

  • BAR编程流程

    1. 探测需求:系统向BAR写入全1,读取返回值确定地址空间类型(低4位)和大小(掩码计算)。

    2. 分配地址:根据系统资源,分配合适基地址写入BAR高位。

  • 示例:若BAR0读回值为0xFFFF0001,最低位为1表示请求IO空间,掩码0xFFFF0000说明需16位对齐,大

你可能感兴趣的:(pcie,高速串行总线,fpga开发)