文章目录

  • PCIe基础
  • 拓扑
  • 配置空间
  • 兼容PCI协议
  • Memory & I/O地址空间
  • 参考


PCIe基础

PCI Express,简称PCI-E,官方简称PCIe,是计算机总线的一个重要分支,它沿用既有的PCI编程概念及信号标准,并且构建了更加高速的串行通信系统标准。目前这一标准由PCI-SIG组织制定和维护。

PCI设备枚举 bios pcie设备_PCIe总线


拓扑

PCI设备枚举 bios pcie设备_寄存器_02


配置空间

在 PCI Express (PCIe) 中,设备被分为两种类型:Type 0 设备和 Type 1 设备。Type 0 设备和 Type 1 设备的区别在于它们的配置空间结构不同。

Type 0 设备是指普通的 PCIe 设备(RC和EP)。Type 0 设备的配置空间只包含一个配置空间头部,用于描述设备的基本信息,如 Vendor ID、Device ID、Class Code、Subclass Code 等等。Type 0 设备可以有多个 BAR(Base Address Registers),用于描述设备的地址空间信息。

Type 1 设备是指 PCIe-to-PCI/PCI-X Bridge,它们可以将一个 PCIe 总线转换成一个或多个 PCI 总线,从而使 PCIe 总线上的 PCIe 设备可以与 PCI 总线上的 PCI 设备进行通信。Type 1 设备的配置空间包含一个配置空间头部和一个或多个 PCI-to-PCI Bridge (P2P) 或 CardBus Bridge (CB) 头部。Type 1 设备的每个 PCI-to-PCI Bridge (P2P) 或 CardBus Bridge (CB) 头部描述一个转换的 PCI 总线。Type 1 设备还有多个 BAR,其中每个 BAR 描述一个转换的 PCI 总线上的地址空间。

PCI设备枚举 bios pcie设备_寄存器_03


PCIe Type 0配置空间(RC与EP设备)

PCI设备枚举 bios pcie设备_PCIe总线_04


PCIe Type 1 配置空间(网桥设备)


兼容PCI协议

PCIe总线 是 PCI总线 的升级版,因此 PCIe 设备的配置空间需要兼容 PCI 协议,以确保与老式 PCI 设备的兼容性和互操作性。

  1. PCIe兼容PCI配置空间格式:

PCIe 设备的配置空间必须使用与 PCI 相同的格式,包括配置空间头部和配置空间寄存器。

  1. 兼容PCI配置空间寄存器

PCIe 设备的配置空间寄存器必须包括与 PCI 相同的寄存器,包括 Vendor IDDevice IDClass CodeSubclass CodeHeader TypeBase Address Registers 等。这些寄存器在 PCIe 设备中的定义必须与 PCI 相同,以确保与 PCI 设备的兼容性和互操作性。

  1. 兼容PCI配置空间头部

PCIe 设备的配置空间头部必须兼容 PCI 头部格式,包括 Header TypeCache Line SizeLatency TimerInterrupt PinInterrupt Line 等字段。PCIe 设备必须使用 Type 0 或 Type 1 头部格式,并根据需要使用 PCI-to-PCI Bridge (P2P)CardBus Bridge (CB) 头部格式。

  1. 兼容PCI配置空间的访问方式

PCIe 设备的配置空间必须使用与 PCI 相同的访问方法,包括使用 I/O 空间或内存空间访问配置空间。PCIe 设备的配置空间访问必须遵循 PCI 总线协议的要求和规范,以确保与 PCI 设备的兼容性和互操作性。

PCI设备枚举 bios pcie设备_寄存器_05


兼容PCI配置空间

PCI设备枚举 bios pcie设备_PCIe总线_06

PCI Device Classes (ucw.cz) 可用于查询设备类型。


Memory & I/O地址空间

在PCIe总线中,可以访问PCIe设备的两种类型的地址空间,分别为Memory空间和I/O空间,Memory空间是一种物理地址空间,可用于访问系统内存,在PCIe总线中,Memory空间通常用于访问设备的配置寄存器和DMA缓冲区。I/O空间是一种虚拟地址空间,用于访问设备的寄存器和控制器。以进行数据传输和控制操作。

PCIe 总线将 Memory 地址空间和 I/O 地址空间分别映射到总线地址空间中的不同区域。Memory地址空间通常映射到系统内存地址空间中的一部分,由操作系统和设备驱动程序来管理和分配。I/O 地址空间则映射到总线地址空间中的一段固定区域,通常为 64KB 的大小。设备可以访问 I/O 地址空间中的寄存器和控制器。

在设备驱动程序中,可以使用 inb()outb()inw()outw()inl()outl() 等函数来读取和写入 I/O 空间中的数据。这些函数分别用于读取和写入单字节、双字节和四字节数据,可以根据具体需求来选择适当的函数。需要注意的是,访问 I/O 空间时需要使用 ioread*()iowrite*() 等内核函数来确保访问的正确性和安全性。