PCI相关(5)- PCIe总线事务-TLP报文

4.3 存储器、I/O 和配置读写请求 TLP

在 PCIe 总线中,存储器读写,I/O读写和配置读写请求TLP 由以下几类报文组成。

  1. 存储器读请求 TLP 和读完成 TLP

当 PCIe 主设备,RC 或者 EP,访问目标设备的存储器空间时,使用 Non-Posted 总线事务向目标设备发出存储器读请求 TLP,目标设备收到这个存储器读请求 TLP 后,使用存储器读完成 TLP,主动向主设备传递数据。当主设备收到目标设备的存储器读完成 TLP 后,将完成一次存储器读操作。

  1. 存储器写请求 TLP

在 PCIe 总线中,存储器写使用 Posted 总线事务。PCIe 主设备仅使用存储器写请求 TLP即可完成存储器写操作,主设备不需要目标设备的回应报文。

  1. 原子操作请求和完成报文

原子操作由 PCIe V2.1总线规范引入,一个完整的原子操作包括原子操作请求和原子操作完成报文组成。原子操作的使用方法与其他 Non-Posted 总线事务类似,首先 PCIe 主设备向目标设备发送原子操作请求,之后目标设备向主设备发送原子操作完成报文,结束一次原子操作。有关原子操作的详细说明见第5.3.5节。

  1. I/O 读写请求 TLP 和读写完成 TLP

在 PCIe 总线中,I/O 读写操作使用 Non-Posted 总线事务,I/O 读写 TLP 都需要完成报文做为回应。只是在 I/O 写请求的完成报文中不需要“带数据”,而仅含有 I/O 写请求是否成功的状态信息。

  1. 配置读写请求 TLP 和配置读写完成 TLP

从总线事务的角度上看,配置读写请求操作的过程与 I/O 读写操作的过程类似。配置读写请求 TLP 都需要配置读写完成作为应答,从而完成一个完成的配置读写操作。

  1. 消息报文

与 PCI 总线相比,PCIe 总线增加了消息请求事务。PCIe 总线使用基于报文的数据传送模式,所有总线事务都是通过报文实现的,PCIe 总线取消了一些在 PCI 总线中存在的边带信号。在 PCIe 总线中,一些由 PCI 总线的边带信号完成的工作,如中断请求和电源管理等,在 PCIe 总线中由消息请求报文实现。

4.3.1 存储器读写请求 TLP

存储器读写请求 TLP 的格式如下图

 

在 PCIe 总线中,存储器写请求 TLP 使用 Posted 数据传送方式。而其他与存储器和 I/O相关的报文都使用 Split 方式进行数据传送,这些请求报文需要完成报文,存储器读写请求 TLP 使用地址路由方式进行数据传递

(1)Length段

在存储器读请求 TLP 中并不包含 Data Payload,在该报文中,Length 字段表示需要从目标设备数据区域读取的数据长度;而在存储器写 TLP 中,Length 字段表示当前报文的 DataPayload 长度。

Length 字段的最小单位为 DW。当该字段为 n 时,表示需要获得的数据长度或者当前报文的数据长度为 n 个 DW,其中0£n£0x3FF。值得注意的是,当 n 等于0时,表示数据长度为1024个 DW。

(2)DW BE 字段

PCIe 总线以字节为基本单位进行数据传递,但是 Length 字段以 DW 为最小单位。为此TLP 使用 Last DW BE 和 First DW BE 这两个字段进行字节使能,使得在一个 TLP 中,有效数据以字节为单位。

这两个 DW BE 字段各由4位组成,其中 Last DW BE 字段的每一位对应数据 Payload 最后一个双字的字节使能位;而 First DW BE 字段的每一位对应数据 Payload 第一个双字的字节使能位。其对应关系如下图所示。

 

值得注意的是,PCIe 总线支持一种特殊的读操作,即“Zero-Length”读请求。此时Length 字段的长度为1DW,而 First DW BE 字段和 Last DW BE 字段都为0b0000,即所有字节都不使能。此时与这个存储器读请求 TLP 对应的读完成 TLP 中不包含有效数据。再次提醒读者注意“Zero-Length”读请求使用的 Length 字段为1,而不是为0,为0表示需要获得的数据长度为1024个 DW。

“Zero-Length”读请求的引入是为了实现“读刷新”操作,该操作的主要目的是为了确保之前使用 Posted 方式所传送的数据,到达最终的目的地,与“Zero-Length”读对应的读完成报文中不含有负载,从而提高了 PCIe 链路的利用率。

(3)Requester ID 字段

Requester ID 字段包含“生成这个 TLP 报文”的 PCIe 设备的总线号(Bus Number)、设备号(Device Number)和功能号(Function Number),对于存储器写请求 TLP,Requester ID 字段并不是必须的

但是 PCIe 总线规范并没有明确说明存储器写请求 TLP 究竟需不需要 Requester ID 字段,为此 IC 设计者依然需要将存储器写 TLP 的 Requester ID 字段置为有效。

对于 Non-Posted 数据请求,目标设备需要使用完成报文做为回应。在这个完成报文中,需要使用源设备的 Requester ID 字段。因此在 Non-Posted 数据请求 TLP 中,如存储器读请求、I/O 和配置读写请求 TLP,必须使用 Requester ID 字段。

(4)I/O 读写请求 TLP 的规则

I/O 读写请求 TLP 只能使用32位地址模式和基于地址的路由方式且只能使用 Non-Posted 方式进行传递。PCIe 总线并不建议 PCIe 设备支持 I/O 地址空间,但是 Switch 和 RC 需要具备接收和发送 I/O 请求报文的能力,为了兼容一些较老的pci设备。

 

4.3.2 完成报文

PCIe 总线支持 Split 传送方式,目标设备使用完成报文向源设备主动发送数据。完成报文使用 ID 路由方式,由 TLP Predix、报文头和 Data Payload 组成,但是在某些完成报文可以不含有 Data Payload,如 I/O 或者配置写完成和 Zero-Length 读完成报文。

所有的数据读请求,包括存储器、I/O 读请求、配置读请求和原子操作请求。当一个PCIe 设备发出这些数据请求报文后,必须收到目标设备的完成报文后,才能结束一次数据传送。这一类完成报文必须包含 Data Payload。完成报文格式如下图

 

(1)Requester ID 和 Tag 字段

完成报文使用 ID 路由方式。完成报文头的长度为3DW,完成报文头中包含 Transaction ID 信息,由 Requester ID 和 Tag 字段组成,这个 ID 必须与源设备发送的数据请求报文的 Transaction ID 对应,完成报文使用 Transaction ID 进行ID 路由,并将数据发送给源设备。

当 PCIe 设备收到存储器读、I/O 读写或者配置读写请求 TLP 时,需要首先保存这些报文的 Transaction ID,之后当该设备准备好完成报文后,将完成报文的 Requester ID 和 Tag字段赋值为之前保存的 Transaction ID 字段。

(2)Completer ID 字段

Completer ID 字段的含义与 Requester ID 字段较为相似,只是该字段存放“发送完成报文”的 PCIe 设备的 ID 号。PCIe 设备进行数据请求时需要在 TLP 字段中包含 Requester ID字段;而使用完成报文结束数据请求时,需要提供 Completer ID 字段。

(3)Status 字段

Status 字段保存当前完成报文的完成状态,表示当前 TLP 是正确地将数据传递给数据请求端;还是在数据传递过程中出现错误;或者要求数据请求方进行重试。PCIe 总线规定了几类完成状态,如下图所示。

 

(4)BCM 位与 Byte Count 字段

BCM(Byte Count Modified)字段由 PCI-X 设备设置。PCI-X 设备也支持 Split Transaction 传送方式,当 PCI-X 设备进行存储器读请求时,目标设备不一定一次就能将所有数据传递给源设备。此时目标设备在进行第一次数据传送时,需要设置 Byte Count 字段 和 BCM 位。

BCM 位表示 Byte Count 字段是否被更改,该位仅对 PCI-X 设备有效,而 PCIe 设备不能操纵 BCM 位,只有 PCI-X 设备或者 PCIe-to-PCI-X 桥可以改变该位。

Byte Count 字段记录源设备还需要从目标设备中,获得多少字节的数据就能完成全部数据传递,当前 TLP 中的有效负载也被 Byte Count 字段统计在内。该字段由12位组成。该字段为0b0000-0000-0001表示还剩一个字节,为0b1111-1111-1111表示还剩4095个字节,而为0b0000-0000-0000表示还剩4096个字节。除了存储器读请求的完成报文外,大多数完成报文的 Byte Count 字段为4。

(5)Lower Address 字段

如果当前完成报文为存储器读完成 TLP,该字段存放在存储器读完成 TLP 中第一个数据所对应地址的最低位。值得注意的是,在完成报文中,并不存在 First DW BE 和 Last DW BE字段,因此接收端必须使用存储器读完成 TLP 的 Low Address 字段,识别一个 TLP 中包含数据的起始地址。

4.3.3 配置读写请求 TLP

配置读写请求 TLP 由 RC 发起,用来访问 PCIe 设备的配置空间。配置请求报文使用基于ID 的路由方式。PCIe 总线也支持两种配置请求报文,分别为 Type 00h 和 Type 01h 配置请求。配置请求 TLP 的格式如下图。

 

4.3.4 消息请求报文

在 PCIe 总线中,多数消息报文使用隐式路由方式,其格式如下图

 

PCIe 总线规定了以下几类消息报文。

INTx 中断消息报文(INTx Interrupt Signaling)。

电源管理消息报文(Power Management)。

错误消息报文(Error Signaling)。

锁定事务消息报文(Locked Transaction Support)。

插槽电源限制消息报文(Slot Power Limit Support)。

Vendor-Defined Messages。

 

4.4 TLP 中与数据负载相关的参数

在 PCIe 总线中,有些 TLP 含有 Data Payload,如存储器写请求、存储器读完成 TLP 等。在 PCIe 总线中,TLP 含有的 Data Payload 大小与 Max_Payload_Size、Max_Read_Request_Size和 RCB 参数相关。

(1)Max_Payload_Size 参数

PCIe 总线规定在 TLP 报文中,数据有效负载的最大值为4KB,但是 PCIe 设备并不一定能够发送这么大的数据报文。PCIe 设备含有“Max_Payload_Size”和“Max_Payload_SizeSupported”参数,这两个参数分别在 Device Capability 寄存器和 Device Control 寄存器中定义。

“Max_Payload_Size Supported”参数存放在一个 PCIe 设备中,TLP 有效负载的最大值,该参数由 PCIe 设备的硬件逻辑确定,系统软件不能改写该参数。而 Max_Payload_Size参数存放 PCIe 设备实际使用的TLP 有效负载的最大值。该参数由 PCIe 链路两端的设备协商决定,是 PCIe 设备进行数据传送时,实际使用的参数。

PCIe 设备发送数据报文时,使用 Max_Payload_Size 参数决定 TLP 的最大有效负载。当PCIe 设备的所传送的数据大小超过 Max_Payload_Size 参数时,这段数据将被分割为多个 TLP进行发送。

当 PCIe 设备接收 TLP 时,该 TLP 的最大有效负载也不能超过 Max_Payload_Size参数,如果接收的 TLP,其Length 字段超过 Max_Payload_Size 参数,该 PCIe 设备将认为该 TLP 非法。

RC 或者 EP 在发送存储器读完成 TLP 时,这个存储器读完成 TLP 的最大 Payload 也不能超过 Max_Payload_Size 参数,如果超过该参数,PCIe 设备需要发送多个读完成报文。值得注意的是,这些读完成报文需要满足 RCB 参数的要求,有关 RCB 参数的详细说明见下文。

在实际应用中,尽管有些 PCIe 设备的 Max_Payload_Size Supported 参数可以为256B、512B、1024B 或者更高,但是如果 PCIe 链路的对端设备可以支持的 Max_Payload_Size 参数为128B 时,系统软件将使用对端设备的 Max_Payload_Size Supported 参数,初始化该设备的 Max_Payload_Size 参数,即选用 PCIe 链路两端最小的 Max_Payload_Size Supported 参数初始化 Max_Payload_Size 参数。

Max_Payload_Size 参数的大小与 PCIe 链路的传送效率成正比,该参数越大,PCIe链路带宽的利用率越高,该参数越小,PCIe 链路带宽的利用率越低。

PCIe 总线规范规定,对于实时性要求较高的 PCIe 设备,Max_Payload_Size 参数不应设置过大,因此这个参数有时会低于 PCIe 链路允许使用的最大值。

(2)Max_Read_Request_Size 参数

Max_Read_Request_Size 参数由 PCIe 设备决定,该参数规定了 PCIe 设备一次能从目标设备读取多少数据。

Max_Read_Request_Size 参数在 Device Control 寄存器中定义。该参数与存储器读请求 TLP 的 Length 字段相关,其中 Length 字段不能大于 Max_Read_Request_Size 参数。在存储器读请求 TLP 中,Length 字段表示需要从目标设备读取多少数据。值得注意的是,Max_Read_Request_Size 参数与 Max_Payload_Size 参数间没有直接联系,Max_Payload_Size 参数仅与存储器写请求和存储器读完成报文相关。

PCIe 总线规定存储器读请求,其读取的数据长度不能超过 Max_Read_Request_Size 参数,即存储器读 TLP 中的 Length 字段不能大于这个参数。如果一次存储器读操作需要读取的数据范围大于 Max_Read_Request_Size 参数时,该 PCIe 设备需要向目标设备发送多个存储器读请求 TLP。

PCIe 总线规定 Max_Read_Request_Size 参数的最大值为4KB,但是系统软件需要根据硬件特性决定该参数的值。因为 PCIe 总线规定 EP 在进行存储器读请求时,需要具有足够大的缓冲接收来自目标设备的数据。

如果一个 EP 的 Max_Read_Request_Size 参数被设置为4KB,而且这个 EP 每发出一个4KB大小存储器读请求时,EP 都需要准备一个4KB 大小的缓冲[1]。这对于绝大多数 EP,这都是一个相当苛刻的条件。为此在实际设计中,一个 EP 会对 Max_Read_Request_Size 参数的大小进行限制。

(3)RCB 参数

RCB 位在 Link Control 寄存器中定义。RCB 位决定了 RCB 参数的值,在 PCIe 总线中,RCB 参数的大小为64B 或者128B,如果一个 PCIe 设备没有设置 RCB 的大小,则 RC 的 RCB参数缺省值为64B,而其他 PCIe 设备的 RCB 参数的缺省值为128B。PCIe 总线规定 RC 的 RCB参数的值为64B 或者128B,其他 PCIe 设备的 RCB 参数为128B。

在 PCIe 总线中,一个存储器读请求 TLP 可能收到目标设备发出的多个完成报文后,才能完成一次存储器读操作。因为在 PCIe 总线中,一个存储器读请求最多可以请求4KB 大小的数据报文,而目标设备可能会使用多个存储器读完成 TLP 才能将数据传递完毕。

当一个 EP 向 RC 或者其他 EP 读取数据时,这个 EP 首先向 RC 或者其他 EP 发送存储器读请求 TLP;之后由 RC 或者其他 EP 发送存储器读完成 TLP,将数据传递给这个 EP。如果存储器读完成报文所传递数据的地址范围没有跨越 RCB 参数的边界,那么数据发送端只能使用一个存储器完成报文将数据传递给请求方,否则可以使用多个存储器读完成TLP。

假定一个 EP 向地址范围为0xFFFF-0000~0xFFFF-0010这段区域进行 DMA 读操作,RC 收到这个存储器读请求 TLP 后,将组织存储器读完成 TLP,由于这段区域并没有跨越 RCB 边界,因此 RC 只能使用一个存储器读完成 TLP 完成数据传递。

如果存储器读完成报文所传递数据的地址范围跨越了 RCB 边界,那么数据发送端(目标设备)可以使用一个或者多个完成报文进行数据传递。数据发送端使用多个存储器读完成报文完成数据传递时,需要遵循以下原则。

第一个完成报文所传送的数据,其起始地址与要求的起始地址相同。其结束地址或者为要求的结束地址(使用一个完成报文传递所有数据),或者为 RCB 参数的整数倍(使用多个完成报文传递数据)。

最后一个完成报文的起始地址或者为要求的起始地址(使用一个完成报文传递所有数据),或者为 RCB 参数的整数倍(使用多个完成报文传递数据)。其结束地址必须为要求的结束地址。

中间的完成报文的起始地址和结束地址必须为 RCB 参数的整数倍。当 RC 或者 EP 需要使用多个存储器读完成报文将0xFFFE-FFF0~0xFFFF-00C7之间的数据发送给数据请求方时,可以将这些完成报文如下图。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值