PCIE手札 - 者旨於陽

时间:2024-02-20 09:21:16

PCIE手札

PCIE兼容了大部分PCI总线的特性,区别在于使用串行差分总线代替了并行总线,并实现了协议分层。PCIE的带宽与LANE数量和时钟频率相关,时钟频率支持2.5G和5G,Lane支持x1/x2/x4/x8/x12/x16/x32,每个Lane由一对差分信号组成。

 

1、PCIE总线拓扑结构


PCIE总线拓扑结构主要由RC(Root Complex)、SW(Switch)和EP(Endpoint)组成,通过总线号、设备号唯一标识每个PCIE设备,每个设备拥有1~8个功能号。根据PCIE协议规范定义,一个PCIE总线拓扑结构中,最多支持256级总线,每条总线上最多挂载32个PCIE设备,SW可以理解为一种特殊的PCIE设备。每个SW代表一级Bus,挂载在该SW下的所有PCIE设备(包括SW和EP)都属于这一级Bus。这样,通过总线号、设备号、功能号就可以匹配到指定的功能设备。

 

1.1、Root Complex(RC)

CPU连接到根聚合体(Root Complex),RC负责完成CPU地址域和PCIE总线域的转换,并且实现各种总线的聚合。将一部分CPU地址映射到内存,一部分地址映射到相应的相应的PCIE设备。

1)Root Complex是I/O层次结构的根节点,用来连接CPU/Memory子系统到I/O子系统,相当于PCI总线结构中的主桥(北桥)。

2)一个Root Complex可以支持一个或者多个PCI Express Ports,每个端口表示一个独立的I/O层次结构域,每个I/O层次结构域由一个单独的Endpoint组成或者由一个或者多个Switch组件和Endpoints组成。

3)I/O层次结构域通过Root Complex进行P2P对等网络传输是可选功能,实现方式也是独立的。

4)Root Complex作为Requester时,支持组包configuration request、I/O request和locked request

 

1.2、Endpoint

Endpoint是PCIE体系结构的根节点,可以作为传输的请求方(Requester)或者结束方(Completer)。Endpoint可以分为Legacy Endpoint、PCIE Endpoint和Root Complex Integrated Endpoint三种。传统端点设备支持I/O传输、锁定传输,不需要支持64位寻址;PCIE端点不需要支持I/O或者锁定传输,必须支持64位寻址。

Endpoint是指只具有上游端口(即指向Root Complex或者Switch的端口)的一个具体的PCIE设备。

 

1.3、Switch

Switch由多个虚拟PCI-to-PCI Bridge设备组成,用于多设备互连,实现路由寻址转发、仲裁等功能。它包含以下特性:

1)一个Switch由至少两个PCI-to-PCI Bridges组成

2)Switch使用PCI桥的机制实现数据传输,如基于地址的路由机制

3)Swtich必须支持在任意端口之间传输任意类型的TLP(Transaction Layer Packet)

4)Swtich必须支持Locked Request,但是下游端口作为发起方时,发起的Locked Request不需要支持

5)每一个使能的Swtich Port必须遵循流控协议(Flow Control)

6)Swtich不可以将TLP数据包分割成多个小数据包进行传输

7)当同一个VC(Virtual Channel)发生竞态时,Swtich的Ingress Ports(inbound Link)之间的仲裁机制通过round robin或者weighted round robin算法实现

 

1.4、PCIE设备枚举

由前述可知,PCIE总线系统中,通过Bus号和Device号唯一标识PCIE设备,通过Function号唯一标识PCIE设备的功能。

Bus号和Device号是PCIE初始化时进行PCIE设备枚举产生的,而Function号是通过硬件编码设置的,这是因为不同的拓扑结构下,PCIE设备在拓扑网络中的位置不是固定的,而每个PCIE设备支持的功能是可以确定的。

PCIE设备枚举就是在PCIE总线初始化的过程中,使用深度优先算法动态检测PCIE总线拓扑网络结构,为每一个PCIE设备(包括SW和EP)确定Bus号和Device号。

PCIE设备枚举主要基于以下几点因素实现:

1)每个PCIE设备至少支持一个Function(最多支持8个Function),而且第一个Function号必须为0,其他Function号可以不连续编址。每一个Function均包含一组PCIE配置空间,PCIE配置空间的前64字节为PCIE配置空间头部信息,EP支持Type 0格式的头部信息,RC和SW支持Type 1格式的头部信息。

 可以看到,Device ID和Vendor ID的字段是一致的,用来标识厂家ID和设备ID。PCIE协议规定Device ID和Vendor ID的取值不能为0xFFFF,当RC发起configure read操作时,如果总线上不存在对应的PCIE设备(Bus/Dev/Fun号不匹配)时,就会返回0xFFFF,由此确定PCIE设备是否存在。

2)RC的Bus号通过硬件编码为0,因此PCIE设备枚举从Bus 0, Device 0, Function 0开始,首先扫描RC下挂载的PCIE设备(每个PCIE设备必须支持Fun 0,所以只有Dev号是不确定的),由此确定Device号(每个Bus下最多可以挂载32个PCIE设备,由此确定了Device号边界)。

3)当确定某个PCIE设备存在时,则通过PCIE配置空间头的Header Type字段确定该PCIE设备是SW还是EP,如果是EP,是一个多功能设备还是单功能设备(支持多少个Function)

4)如果步骤3检测到SW,则扫描下一级总线(Bus号递增,Bus号取值范围为0~255,由此确定的Bus号的边界),根据递归的深度设置0x18字段的Primary Bus Number(上级Bus号)、Secondary Bus Number(下游Bus号,同一层次)、Subordinate Bus Number(当前Bus下最远的Bus号);如果为多功能EP,则继续枚举Function(Function号递增)

根据上述步骤,完成PCIE设备枚举,为每个PCIE设备确定Bus号和Device号,并检测到每一个PCIE设备支持的Function号。

 

2、PCIE分层协议

PCIE分层协议分为三层——传输层、数据链路层和物理层,每一个协议层根据传输方向分为inbound和outbound两部分。

PCIE使用packet的形式传输数据,packet在传输层和数据链路层组包。类似于网络协议,每一层均添加额外的信息标识。

 

2.1、传输层

传输层负责组包和解包TLPs(Transaction Layer Packets),TLP可以是读数据包、写数据包或者特定事件。传输层也负责TLP流控。

TLP就是用户和PCIE IP核交互的接口。

TLP分为应答型和非应答型,每个TLP必须有一个特定的标识(Transaction ID)。 

PCIE设备有四种地址空间——Memory,I/O,Configuration,Message地址空间,对应四种传输类型,传输层支持不同传输类型TLP的寻址——TLP路由

 

2.1.1、TLP routing (TLP路由)

首先,我们知道ARM是统一编址,即ARM的物理地址空间是内存地址空间和I/O地址空间统一编制形成的。PCIE总线拓扑网络中使用Bus号和Device号给PCIE设备编址,进一步通过Function号给每个PCIE设备的具体功能编址,每个PCIE功能设备有四种地址空间(配置空间是确定的,其他地址空间是独立的还是共享待商榷)。

RC负责CPU域的物理地址空间和PCIE总线域的地址转换。

某种意义上讲,PCIE总线的核心就是实现CPU对PCIE设备的四种地址空间进行直接读写,即实现地址映射机制。CPU通过RC发起读写请求,RC负责产生TLP,传输层(RC+SW)负责TLP路由。

有三种TLP路由机制——基于地址路由、基于ID路由和隐式路由。

 

 

2.1.2、ATU(Address Translation Unit)

TLP的FMT和Type字段定义了四种传输类型,TLP路由就是基于这两个字段识别请求类型,从而采用不同的TLP路由机制。

ATU(地址转换单元)负责实现TLP路由,即进行CPU域的物理地址和PCIE域的总线地址(Bus/Device/Function或者BAR)之间的转换。

如果PCIE总线上发起访问对应CPU域物理地址的请求,将通过ATU生成TLP,TLP中的地址就是ATU转换后的地址。ATU中必须配置TLP类型,如上所述,不同的TLP类型的TLP路由策略是不一样的,而路由策略直接影响到地址转换。

Configuration请求,基于ID的路由地址被解析成“总线号+设备号+功能号+偏移”,访问的是PCIE设备4KB配置空间。

I/O请求或者Memory请求,基于地址的路由,通过和PCIE总线上各个PCIE设备的BAR地址空间范围比较来确认所请求的物理地址落在哪个PCIE设备的BAR空间上,然后进行相应的读写操作。

Message请求,基于ID或者Implicit路由。

 

2.1.3、BAR(Base Address Register)

每个PCIE设备的内存地址空间都是从0开始编址,当一个PCIE控制器同时接入多个PCIE设备时,需要确保PCIE总线上每一个PCIE设备的内存地址空间彼此独立,所以需要分别配置BAR(Base Address Register),从而避免PCIE设备发生物理地址冲突。

BAR在PCIE设备配置地址空间特定字段设置。

 

2.2、数据链路层

数据链路层负责链路管理、数据完整性校验和纠正。

下行方向,数据链路层接收传输层TLP数据包,添加TLP序列号和CRC校验码,然后发送给物理层;上行方向校验TLP数据包完整性,然后发送给传输层。

一旦检测到TLP数据包错误,数据链路层负责请求TLP重传直到接收到完整的TLP数据包,或者检测到链路异常。

数据链路层自己也会产生和处理链路管理数据包,称为DLLP(Data Link Layer Packet)。

 

2.3、物理层

物理层负责端口管理,包括驱动能力和数据缓冲区、串并转换、PLL和阻抗匹配电路。它负责把数据链路层下发的数据包转换成串行数据、并在PCI Express Link(每个Link包含至少1个Lane)之间以一定的速率和带宽进行传输。

 

3、PCIE地址空间

3.1、PCIE内存地址空间

PCIE设备内存地址空间位于PCIE设备上,用于进行大块数据存放和交换,如内存、显存、扩展ROM、设备缓冲区等。

PCIE设备内存地址空间设置好BAR(Base Address Register)后,物理地址就能在Linux内核中通过ioremap映射到内核虚拟地址空间,通过readb/writeb/readl/writel等IO访问接口读写。


3.2、PCIE I/O地址空间

为了访问I/O设备而设立,一般用于查询和控制设备的工作状态以及少量数据交换。

访问外部设备寄存器的地址空间?


3.3、PCIE配置地址空间

PCIE设备通过配置地址空间向系统提供设备自身的基本信息,每个PCIE设备都有自己的配置地址空间,由PCIE规范定义统一的格式。

PCIE设备配置地址空间实质上是一段特殊的I/O地址空间,可以为PCIE内存地址空间和PCIE I/O地址空间分配物理地址基地址,即BAR(Base Address Register)。

 

参考文献

1、DWC_pcie_reference

2、PCI_Express_Base_Rev_2.0_20Dec06a

3、Xilinx PCI Express

4、PCI Express System Architecture