目录

1. PCIe 总线概述

2. PCIe 拓扑结构

3. PCIe 分层结构

4. PCIe 事务层类型

5. PCIe 配置和地址空间


1. PCIe 总线概述

PCIe(Peripheral Component Interconnect Express)是一种用于连接计算机内部硬件设备的高速串行总线。它是在PCI(Peripheral Component Interconnect)总线的基础上发展而来的。PCI总线是在1992年由Intel推出的,以取代ISA(Industry Standard Architecture)总线。PCI总线使用并行传输,速度相对较慢,最高只能达到133MB/s。

为了满足高速数据传输的需求,PCIe总线于2003年问世。PCIe总线采用串行传输技术,通过使用多个信道并行发送数据来提高传输速度。它最初的速度为2.5GB/s,后来发展到8GB/s、16GB/s、32GB/s等多种速度级别。

链接速度X 1X 2X 4X 8
Gen1带宽(GB/s)0.5124
Gen2带宽(GB/s)1248
Gen3带宽(GB/s)24816
Gen4带宽(GB/s)481632

当用较多的数据位对原始数据进行编码时,有效数据传输量低于实际传输的数据位数。例如:PCIe串行总线采用10位数据对8位数据进行编码(附加位可能用于时钟编码、误码检测等冗余位)。数据速率通常用每秒传输的数据位,具体指的是编码后的串行比特率,每秒吉比特(GT/s)和每秒兆比特(MT/s)。例如,2.5 GT/s指的是2.5 Gbit/s串行数据速率。

吞吐量表示未编码的带宽(没有8b/10b、128b/130b或242B/256B编码的开销)。PCIe 1.0每通道2.5 GT/s的传输速率意味着2.5 Gbit/s的串行比特率。在8b/10b编码之前,对应的吞吐量为2.5Gbit/s x8/10= 2.0 Gbit/s。

PCIe版本推出年份Line codeTransfe rate per lane单向Throughput per lane(X1 lane)
1.02003NRZ 8b/10b2.5 GT/s2.5GT/s × 8/10 ÷ 8= 0.250 GB/s
2.02007NRZ 8b/10b5.0 GT/s5.0 GT/s × 8/10 ÷ 8= 0.500 GB/s
3.02010NRZ 128b/130b8.0 GT/s8.0 GT/s × 128/130 ÷ 8= 0.985 GB/s
4.02017NRZ 128b/130b16.0 GT/s16.0 GT/s × 128/130 ÷ 8= 1.969 GB/s
5.02019NRZ 128b/130b32.0 GT/s32.0 GT/s × 128/130 ÷ 8= 3.938 GB/s

PCIe链路表示两个组件之间的双单工连接通道。基本的PCIe链路由两对低电压差分信号对组成:一对用于发送,另一对用于接收。

2. PCIe 拓扑结构

PCIe采用的树形拓扑结构,RC(Root Complex)是树的根或主干;PCI采用的是总线型拓扑结构,一条PCI总线上挂着若干个PCI终端设备或PCI桥设备。

PCIe Endpoint,就是PCIe终端设备,比如PCIe SSD、PCIe网卡等。

PCIe Switch,用于扩展链路提供更多的端口连接Endpoint。Switch扩展了PCIe端口,靠近RC的那个端口,称为上游端口(Upstream Poat),而分出来的其他端口,称为下游端口(Downstream Port)。

注:RC是指PCI Express Root Complex,作为PCIe架构的核心组件,其作用是控制每个PCIe设备之间的通信。PCIe RC是一个设备,其主要任务是管理PCIe总线上的所有端点设备。它负责生成和分发PCIe事务,以及传输和接收数据包。此外,PCIe RC还能进行地址转换和流量控制,确保各个设备能够高效地进行数据传输。

3. PCIe 分层结构

PCIe定义了三层结构:事务层、数据链路层、物理层。每层职责各不相同,但下层总是为上层服务的。

事务层(Transaction Layer):负责创建或解析TLP包、流量控制、QoS、事务排序等。

数据链路层(Data Link Layer):负责创建或解析DLLP包、Ack/Nak协议(链路层检错和纠错)、流控、电源管理等。

物理层(Physical Layer):负责处理所有的Packet数据物理传输,发送端数据分发到各个Lane传输(Stripe),接收端把各个Lane上的数据汇总起来(De-stripe),每个Lane上加扰(Scramble,目的是让0和1分布均匀,去除信道的电磁干扰EMI)和去扰(De-scramble),以及8/10或者128/130编码解码等。

PCIe各层功能细节图。

4. PCIe 事务层类型

PCIe事务层分为四种不同的类型(Memory、IO、Configuration、Message),分别用于访问内存空间、IO空间、配置空间,这三种请求在PCI或者PCI-X时代就有了,Message请求是PCIe新加的。

PCI或者PCI-X时代,像中断、错误以及电源管理相关信息,都是通过边带信号进行传输的,但PCIe干掉了这些边带信号线,所有的通信都是走带内信号,即通过Packet传输相应的Message信息。

设备的物理空间,可以通过内存映射的方式到主机的主存。新的PCIe设备(区别于Legacy PCIe设备)只支持内存映射,之所以还存在访问IO空间的TLP,完全是为了兼容老设备。

这四种事务层请求,还可分为两种类型的TLP,分别为Posted TLP和Non-Posted TLP。如果发送的TLP不需要对方回应答包,称之为Posted TLP;如果发送的TLP需要对方回应答包,称之为Non-Posted TLP。

5. PCIe 配置和地址空间

PCIe配置空间是PCI Express(PCIe)设备的寄存器集合,用于管理设备的配置和初始化。这些寄存器包含设备的ID、设备状态、中断号、资源分配和其他配置信息。

PCIe设备在启动后会被系统BIOS扫描,BIOS会读取设备的ID和配置空间来确定设备的类型、属性和资源需求。系统BIOS会将这些信息存储在系统内存中,以便操作系统加载设备驱动程序并分配资源。设备驱动程序可以通过访问PCIe配置空间来初始化设备、配置传输特性和通知系统中断信息。

每个PCIe设备都有这样一段空间,主机软件可以通过读取它获得该设备的信息,也可以通过它来配置该设备,这段空间称为PCIe的配置空间。PCIe设备的配置空间是协议规定好的,每一个字段放什么内容,都是有定义的。

配置空间就是一系列寄存器的集合,从PCI时代开始,就有的64Byte的Header和192Byte的Capability数据结构。由于PCIe功能比较强大,配置空间由PCI时代的256Byte扩展成了4KB。为了兼容PCI设备,前256Byte内容和结构保持不变。

配置空间中有个比较重要的BAR(Base Address Register),对Endpoint Cfg(Type0)提供最多6个BAR,而对Switch(Type1)来说只有2个。

CPU只能直接访问主机内存(Memory)空间(或者IO空间),不能直接对PCIe等外设进行操作。CPU如果想访问某个设备的空间,由于它不能亲自跟那些PCIe外设打交道,因此叫RC去办。比如,如果CPU想读取PCIe外设的数据,先叫RC通过TLP把数据从PCIe外设读到主机内存,然后CPU从主机内存读数据;如果CPU要往外设写数据,则先把数据在内存中准备好,然后叫RC通过TLP写入到PCIe设备。

具体实现就是上电的时候,系统把PCIe设备开放的空间(系统软件可见)映射到内存地址空间,CPU要访问该PCIe设备空间,只需访问对应的内存地址空间。一个PCIe设备,可能有若干个内部空间需要映射到内存空间,设备出厂时这些空间的大小和属性都写在Configuration BAR寄存器里面,上电后系统软件读取这些BAR,分别为其分配对应的系统内存地址空间,并把相应的内存基地址写回到BAR(BAR的地址其实就是PCI总线域的地址,CPU访问的是存储器域的地址,CPU访问PCIe设备时,需要把PCI总线域地址转换成存储器域的地址)。

6. PCIe 设备内存空间映射

PCIe设备可以通过在系统内存空间中分配一段地址范围,实现内存映射。下面是具体步骤:

  • 设备向系统发送请求,申请一段连续的内存空间。
  • 系统为设备分配一段合适的内存空间,并返回这段内存空间的物理地址。
  • 设备通过MMIO(Memory-Mapped I/O)方式将自己的寄存器映射到这段内存空间中,这样设备的寄存器就可以通过对这段内存空间的访问来进行控制。
  • 设备可以通过DMA(Direct Memory Access)方式,将数据传输到这段内存空间中,或者从这段内存空间中读取数据。

需要注意的是,设备需要遵守一定的规范,如PCIe规范中定义的BAR(Base Address Register)寄存器,来描述设备所需的内存空间大小和内存映射的起始地址等信息。同时,系统也需要对设备进行相应的配置,来确保内存映射正常工作。

概念补充:

1. 系统是如何检测PCIe设备的存在?

当PCIe设备被插入主板上的PCIe插槽时,主板的BIOS会扫描系统中的硬件,并通过PCIe总线来探测新插入的设备。BIOS会向设备发送一系列的命令,例如读取设备的ID号、配置信息等。如果设备能够正确地响应这些命令并返回正确的信息,则说明设备已成功连接到系统中。

2. non-prefetchable和prefetchable的区别?

Non-prefetchable和Prefetchable是PCI总线的术语。PCI总线包括多个设备和主机之间的通信。以下是它们的区别:

  1. Non-prefetchable: 指的是设备可以访问的存储区域,但是不能预取数据。这种存储区域的访问速度通常比Prefetchable存储区域稍慢。

  2. Prefetchable: 指的是设备可以访问和预取数据的存储区域。这种存储区域的访问速度通常比Non-prefetchable存储区域稍快。

总的来说,Prefetchable存储区域比Non-prefetchable存储区域更适合用于大数据传输。而且,如果设备能够预取,它可以在主机需要数据之前将数据缓存起来,提高系统性能。

对于PCIe设备,系统软件分配映射空间的步骤如下:

  1. 上电时,系统软件首先会读取PCIe设备的BAR0,得到数据BAR0初始化出厂数据;
  2. 然后系统软件往该BAR0写入全1,BAR寄存器有些bit是只读的,是PCIe设备出厂前就固化好的bit,写全1进去,如果值保持不变,就说明这些bit是厂家固化好的,这些固化好的bit提供了这块内部空间的一些信息;
  3. 如果低12位没变,表明该设备空间大小是4KB(2的12次方字节),其中低4bit表明了该存储空间的属性(IO映射还是内存映射?32bit地址还是64bit地址?能否预取?);
  4. 系统根据这些信息,在系统内存空间找到这样一块地方来映射这4KB空间,并把分配的基地址写入到BAR0中。
  5. PCIe设备至少有一个配置空间,系统软件依次读取BAR1…BAR5,完成所有内部空间的映射,第2步往BAR寄存器写入全1,如果读回来的BAR寄存器值还是全为1,则这块空间无效。

PCIe MMIO(Memory-Mapped I/O)指的是PCI Express(PCIe)总线上的内存映射I/O(MMIO),用于在计算机系统中进行高速数据传输的接口。PCIe MMIO是一种虚拟内存空间,用于映射I/O设备内部的寄存器,使其可以通过内存地址直接访问。

7. PCIe 设备内存空间映射Trace分析