系列文章目录
PCI Express 体系结构导读摘录(一)
PCI Express 体系结构导读摘录(二)
PCI Express 体系结构导读摘录(三)
文章目录
第 6 章 PCIe 总线的事务层
事务层是 PCIe 总线层次结构的最高层, 该层次将接收 PCIe 设备核心层的数据请求, 并 将其转换为 PCIe 总线事务, PCIe 总线使用的这些总线事务在 TLP(Transaction Layer Packet) 头中定义。 PCIe 总线继承 了 PCI / PCI-X 总线的大多数总线事务, 如存储器读写、 I / O 读写、 配置读写总线事务, 并增 加了 Message 总线事务和原子操作等总线事务。
本节重点介绍与数据传送密切相关的总线事务, 如存储器、 I / O、 配置读写总线事务。 在 PCIe 总线中, Non-Posted 总线事务分两部分进行, 首先是发送端向接收端提交总线读写 请求, 之后接收端再向发送端发送完成 ( Completion) 报文。 PCIe 总线使用 Split 传送方式处理所有 Non-Posted 总线事务, 存储器读、 I / O 读写和配置读写这些 Non-Posted 总线事务都 使用 Split 传送方式。 PCIe 的事务层还支持流量控制和虚通路管理等一系列特性, 而 PCI 总 线并不支持这些新的特性。
在 PCIe 总线中, 不同的总线事务采用的路由方式不相同。 PCIe 总线继承了 PCI 总线的地址路由和 ID 路由方式, 并添加了 “隐式路由” 方式。
PCIe 总线使用的数据报文首先在事务层中形成, 这个数据报文也称为事务层数据报文, 即 TLP。 TLP(Transaction Layer Packet) 在经过数据链路层时被加上 Sequence Number 前缀和 CRC 后缀, 然后发向物理层。
数据链路层还可以产生 DLLP ( Data Link Layer Packet) 。 DLLP 和 TLP 没有直接关系。 DLLP 是产生于数据链路层, 终止于数据链路层, 并不会传递到事务层。 DLLP 不是 TLP 加 上前缀和后缀形成的。 数据链路层的报文 DLLP 通过物理层时, 需要经过 8 / 10b 编码, 然后 再进行发送。 而数据的接收过程是发送过程的逆过程。
6. 1 TLP(Transaction Layer Packet) 的格式
当处理器或者其他 PCIe 设备访问 PCIe 设备时, 所传送的数据报文首先通过事务层被封 装为一个或者多个 TLP, 之后才能通过 PCIe 总线的各个层次发送出去。 TLP 的基本格式如 图 6-1 所示。
一个完整的 TLP 由 1 个或者多个 TLP Prefix、 TLP 头、 Data Payload (数据有效负载) 和 TLP Digest 组成。 TLP 头是 TLP 最重要的标志, 不同的 TLP 其头的定义并不相同。 TLP 头包含了当前 TLP 的总线事务类型、 路由信息等一系列信息。 在一个 TLP 中, Data Payload 的长度可变, 最小为 0, 最大为 1024DW 。
TLP Digest 是一个可选项, 一个 TLP 是否需要 TLP Digest 由 TLP 头决定。 Data Payload 也 是一个可选项, 有些 TLP 并不需要 Data Payload, 如存储器读请求、 配置和 I / O 写完成 TLP 并不需要 Data Payload。
TLP Prefix 由 PCIe V2. 1 总线规范引入, 分为 Local TLP Prefix 和 EP-EP TLP Prefix 两类。 其中 Local TLP Prefix 的主要作用是在 PCIe 链路的两端传递消息, 而 EP-EP TLP Prefix 的主 要作用是在发送设备和接收设备之间传递消息。 设置 TLP Prefix 的主要目的是为了扩展 TLP 头, 并以此支持 PCIe V2. 1 规范的一些新的功能。
TLP 头由 3 个或者 4 个双字 (DW) 组成。 其中第一个双字中保存通用 TLP 头, 其他字段与通用 TLP 头的 Type 字段相关。 一个通用 TLP 头由 Fmt、 Type、 TC、 Length 等字段组成, 如图 6-2 所示。
如果存储器读写 TLP 支持 64 位地址模式时, TLP 头的长度为 4DW, 否则为 3DW。 而完 成报文的 TLP 头不含有地址信息, 使用的 TLP 头长度为 3DW。 其中 Byte 4 ~ Byte 15 的格式 与 TLP 相关, 下文将结合具体的 TLP 介绍这些字段。
6. 1. 1 通用 TLP 头的 Fmt 字段和 Type 字段
Fmt 和 Type 字段确认当前 TLP 使用的总线事务, TLP 头的大小是由 3 个双字还是 4 个双字组成, 当前 TLP 是否包含有效负载。 其具体含义如表 6-1 所示。
其中所有读请求 TLP 都不带数据, 而写请求 TLP 带数据, 而其他 TLP 可能带数据也可能不带数据, 如完成报文可能含有数据, 也可能仅含有完成标志而并不携带数据。 在 TLP 的 Type 字段中存放 TLP 的类型, 即 PCIe 总线支持的总线事务。 该字段共由 5 位组成, 其含义如表 6-2 所示。
存储器读和写请求, IO 读和写请求, 及配置读和写请求的 type 字段相同, 如存储器读和写请求的 Type 字段都为 0b0 0000。 此时 PCIe 总线规范使用 Fmt 字段区分读写请求, 当 Fmt 字段是 “带数据” 的报文, 一定是 “写报文” ; 当 Fmt 字段是 “不带数据” 的报文, 一 定是 “读报文” 。
PCIe 总线的数据报文传送方式与 PCI 总线数据传送有类似之处。 其中存储器写 TLP 使用 Posted 方式进行传送, 而其他总线事务使用 Non-Posted 方式。
PCIe 总线规定所有 Non-Posted 存储器请求使用 Split 总线方式进行数据传递。 当 PCIe 设备进行存储器读、 I / O 读写或者配置读写请求时, 首先向目标设备发送数据读写请求 TLP, 当目标设备收到这些读写请求 TLP 后, 将数据和完成信息通过完成报文 ( Cpl 或者 CplD) 发送给源设备。
其中存储器读、 I / O 读和配置读需要使用 CplD 报文, 因为目标设备需要将数据传递给 源设备; 而 I / O 写和配置写需要使用 Cpl 报文, 因为目标设备不需要将任何数据传递给源设 备, 但是需要通知源设备, 写操作已经完成, 数据已经成功地传递给目标设备。
在 PCIe 总线中, 进行存储器或者 I / O 写操作时, 数据与数据包头一起传递; 而进行存 储器或者 I / O 读操作时, 源设备首先向目标设备发送读请求 TLP, 而目标设备在准备好数据 后, 向源设备发出完成报文。
与 PCI 总线不同, PCIe 总线规范定义了 Msg 报文, 即消息报文, 分别为 Msg 和 MsgD。 这两种报文的区别在于一个报文可以传递数据, 一个不能传递数据。
PCIe V2. 1 总线规范还补充了一些总线事务, 如 FetchAdd、 Swap、 CAS、 LPrfx 和 EPrfx。 其中 LPrfx 和 EPrfx 总线事务分别与 Local TLP Prefix 和 EP-EP TLP Prefix 对应。 在 PCIe 总线 规范 V2. 0 中, TLP 头的大小为 1DW, 而使用 LPrfx 和 EPrfx 总线事务可以对 TLP 头进行扩 展, 本节不对这些 TLP Prefix 做进一步介绍。 PCIe 设备可以使用 FetchAdd、 Swap 和 CAS 总 线事务进行原子操作, 第 6. 3. 5 节将详细介绍该类总线事务。
6. 1. 2 TC 字段
TC 字段表示当前 TLP 的传送类型, PCIe 总线规定了 8 种传输类型, 分别为 TC0 ~ TC7, 缺省值为 TC0, 该字段与 PCIe 的 QoS(Quality of Service,服务质量) 相关。 PCIe 设备使用 TC 区分不同类型的数据传递, 而多数 EP 中只含有一个 VC, 因此这些 EP 在发送 TLP 时, 也仅仅使用 TC0, 但是有些对实 时性要求较高的 EP 中, 含有可以设置 TC 字段的寄存器。
6. 1. 3 Attr 字段
Attr 字段由 3 位组成, 其中第 2 位表示该 TLP 是否支持 PCIe 总线的 ID-based Ordering; 图 6-3 Attr 字段格式第 1 位表示是否支持 Relaxed Ordering; 而第 0 位表示该 TLP 在经过 RC 到达存储器时, 是否需要进行 Cache 共享一致性处理。 Attr 字段如图 6-3 所示。
一个 TLP 可以同时支持 ID-based Ordering 和 Relaxed Orde- ring 两种位序。 Relaxed Ordering 最早在 PCI-X 总线规范中提出, 用来提高 PCI-X 总线的数据传送效率; 而 ID-based Orde- ring 由 PCIe V2. 1 总线规范提出。 TLP 支持的序如表 6-3 所示。
当使用标准的强序模型时, 在数据的整个传送路径中, PCIe 设备在处理相同类型的 TLP 时, 如 PCIe 设备发送两个存储器写 TLP 时, 后面的存储器写 TLP 必须等待前一个存 储器写 TLP 完成后才能被处理, 即便当前报文在传送过程中被阻塞, 后一个报文也必须 等待。
如果使用 Relaxed Ordering 模型, 后一个存储器写 TLP 可以穿越前一个存储器写 TLP, 提前执行, 从而提高了 PCIe 总线的利用率。 有时一个 PCIe 设备发出的 TLP, 其目的地址并 不相同, 可能先进入发送队列的 TLP, 在某种情况下无法发送, 但这并不影响后续 TLP 的发 送, 因为这两个 TLP 的目的地址并不相同, 发送条件也并不相同。
Attr 字段的第 0 位是 “No Snoop Attribute” 位。 当该位为 0 时表示当前 TLP 所传送的数 据在通过 FSB 时, 需要与 Cache 保持一致, 这种一致性由 FSB 通过总线监听自动完成而不 需要软件干预; 如果为 1, 表示 FSB 并不会将 TLP 中的数据与 Cache 进行一致, 在这种情况 下, 进行数据传送时, 必须使用软件保证 Cache 的一致性。
6. 1. 4 通用 TLP 头中的其他字段
除了 Fmt 和 Type 字段外, 通用 TLP 头还含有以下字段。
-
TH 位、 TD 位和 EP 位
TH 位为 1 表示当前 TLP 中含有 TPH (TLP Processing Hint) 信息, TPH 是 PCIe V2. 1 总 线规范引入的一个重要功能。 TLP 的发送端可以使用 TPH 信息, 通知接收端即将访问数据 的特性, 以便接收端合理地预读和管理数据, TPH 的详细介绍见第 6. 3. 6 节。
TD 位表示 TLP 中的 TLP Digest 是否有效, 为 1 表示有效, 为 0 表示无效。 而 EP 位表示 当前 TLP 中的数据是否有效, 为 1 表示无效, 为 0 表示有效。 -
AT 字段
AT 字段与 PCIe 总线的地址转换相关。 在一些 PCIe 设备中设置了 ATC (Address Translation Cache) 部件, 这个部件的主要功能是进行地址转换。 只有在支持 IOMMU 技术的处理器 系统中, PCIe 设备才能使用该字段。 -
Length 字段
Length 字段用来描述 TLP 的有效负载 (Data Payload) 大小 。 PCIe 总线规范规定一个 TLP 的 Data Payload 的大小在 0 ~ 4096 B 之间。 PCIe 总线设置 Length 字段的目的是提高总线的传送效率。
6. 2 TLP 的路由
TLP 的路由是指 TLP 通过 Switch 或者 PCIe 桥片时采用哪条路径, 最终到达 EP 或者 RC 的方法。 PCIe 总线一共定义了三种路由方法, 分别是基于地址 (Address) 的路由, 基于 ID 的路由和隐式路由 ( Implicit) 方式。
存储器和 I / O 读写请求 TLP 使用基于地址的路由方式, 这种方式使用 TLP 中的 Address 字段进行路由选径, 最终到达目的地。
而配置读写报文、 “Vendor_Defined Messages” 报文、 Cpl 和 CplD 报文使用基于 ID 的路 由方式, 这种方式使用 PCI 总线号 ( Bus Number) 进行路由选径。 在 Switch 或者多端口 RC 的虚拟 PCI-to-PCI 桥配置空间中, 包含如何使用 PCI 总线号进行路由选径的信息。
而隐式路由方式主要用于 Message 报文的传递。 在 PCIe 总线中定义了一系列消息报文, 包括 “ INTx Interrupt Signaling” , “ Power Management Messages” 和 “ Error Signal Messages” 等报文。 在这些报文中, 除了 “Vendor_Defined Messages” 报文, 其他所有消息报文都使用隐式路由方式, 隐式路由方式是指从下游端口到上游端口进行数据传递的使用路由方式, 或者用于 RC 向 EP 发出广播报文。
6. 2. 1 基于地址的路由
在 PCIe 总线中, 存储器读写和 I / O 读写 TLP 使用基于地址的路由方式。 PCIe 设备使用的地址路由方式与 PCI 设备使用的地址路由方式类似。 只是 PCIe 设备使用 TLP 进行数据传 送, 而 PCI 设备使用总线周期进行数据传送。 使用地址路由方式进行数据传递的 TLP 格式如第 6. 3. 1 节的图 6-8 所示, 在这类 TLP 中包含目的设备的地址。
当一个 TLP 进行数据传递时, 可能会经过多级 Switch, 最终到达目的地。 Switch 将根据存储器读写和 I / O 读写请求 TLP 的目的地址将报文传递到合适的 Egress 端口上。 如图 4-10 所示, 在一个 Switch 中包含了多个虚拟 PCI-to-PCI 桥。 在 Switch 中有几个端口, 就包含几个 虚拟 PCI-to-PCI 桥。
图 6-4 中的配置寄存器描述了该虚拟 PCI-to-PCI 桥下游 PCI 子树使用的三组空间范围, 分别为 I / O、 存储器和可预取的存储器空间, 分别用 Base 和 Limit 两类寄存器描述, 其中 Base 寄存器表示可访问空间的基地址, Limit 寄存器表示可访问空间的大小。 TLP 使用基于 地址的路由时, 一定要通过查询这组寄存器之后, 再决定传送路径。 这组寄存器的使用方法与 PCI 总线中的 PCI 桥兼容。
6. 2. 2 基于 ID 的路由
在 PCIe 总线中, 基于 ID 的路由方式主要用于配置读写请求 TLP、 Cpl 和 CplD 报文, 此 外 Vendor_Defined 消息报文也可以使用这种基于 ID 的路由方式。 而在 PCI 总线中, 只有配置读写周期才使用 ID 进行数据传递。
基于 ID 的路由方式与基于地址的路由方式有较大的不同, 基于 ID 路由方式的 TLP 头格式也与基于地址路由方式的头格式不同, 其报文格式如图 6-6 所示。
使用 ID 路由方式的 TLP 头, 其 Byte8 ~ Byte11 字段与基于地址路由的 TLP 不同。 基于 ID 路由的 TLP, 使用 Bus Number、 Device Number 和 Function Number 进行路由寻址。 从软件 的角度来看, PCIe 总线与 PCI 总线兼容, 只是在 PCIe 总线中, 每一个 PCIe 设备使用唯一的 PCI 设备号, 但是每一个设备仍然可以有多个子设备 (Function) 。
PCIe 总线规定, 在一个 PCI 总线域空间中, 最多只能有 256 条 PCI 总线, 因此在一个 TLP 中, Bus Number 由 8 位组成; 而在每一条总线中最多包含 32 个设备, 因此 TLP 中的 Device Number 由 5 位组成; 而每一个设备中最多包含 8 个功能, 因此一个 TLP 的 Function Number 由 3 位组成。
配置读写请求 TLP 是使用 “基于 ID 路由” 的一组重要报文, 其主要作用是读写 PCIe 总线的 EP、 Switch 及 PCIe 桥片的配置寄存器, 以完成 PCIe 总线的配置。 在处理器系统上电之后需要进行 PCI 总线系统的枚举, 为 PCI 总线分配总线号, 并设置 Switch、 PCIe 桥片或者 EP 的配置寄存器, 如 Limit 寄存器组、 Base 寄存器组、 BAR 寄存器、 Subordinate Bus Number、 Secondary Bus Number 和 Primary Bus Number 等一系列配置寄存器。
在上文中我们简单介绍了 Limit 寄存器组和 Base 寄存器组的用法, 下文将重点描述 Subordinate Bus Number(下级总线号)、 Secondary Bus Number 和 Primary Bus Number 寄存器。 Subordinate Bus Number、 Secondary Bus Number 和 Primary Bus Number 寄存器在 Type 01h 配置寄存器中, 用来描述 PCI-to-PCI 桥片的上游及下游总线号。 这段寄存器在 PCI 配置寄存器中的位置如所图 6-7 示。
与 PCI 总线中的桥片类似, Primary Bus Number 记录 PCI-to-PCI 桥上游的 PCI 总线号, Secondary Bus Number 记录 PCI-to-PCI 桥下游的第一个 PCI 总线号, 而 Subordinate Bus Num- ber 记录 PCI-to-PCI 桥下游的最后一个 PCI 总线号。
如 图 6-5 所示, P-P1 桥片的 Primary Bus Number 为 0, Secondary Bus Number 为 1, 而 Subordinate Bus Number 为 3。 这些总线号, 在处理器系统对 PCI 总线进行枚举时由系统初始化程序设置, 从系统初始化程序的角度来看, PCIe 总线与 PCI 总线基本兼容, 只是 PCIe 总线对配置空间进行了一些扩展。
在如 表 6-2 所示中, RC 可以使用 Type 00h 和 Type 01h 读写请求 TLP(Transaction Layer Packet) , 对 PCIe 设备的配置寄存器进行读写访问, 配置读写请求 TLP 只能由 RC 发出, 配置读写请求 TLP 使用基于 ID 的路由方式。
在如 图 6-5 所示的例子中, RC 首先使用 Type 00h 配置请求 TLP 访问在 PCI Bus0 总线上的设备, PCI Bus0 上的所有设备, 包括桥片都要监听 PCI Bus 0 上的配置请求, 在本例中只有 Switch 挂接在 PCI Bus0 上, 实际上是 Switch 的上游端口与 PCI Bus0 直接相连。 因此 Switch 的上游端口将接收 RC 发出的 Type 00h 配置请求 TLP, 之后 Switch 将向 RC 发出完成报文, 结束配置请求。 与 PCI 总线相同, PCIe 总线的 Type 00h 类型配置请求 TLP 不能够穿越桥片, 在图 6-5 中这类请求只能访问 Switch 上游端口的配置空间。
PCIe 总线使用 “端对端” 的连接方式, PCIe 链路只能连接一个下游设备, 而这个下游设备的 Device Number 只能为 0。 而只有在 Switch 的虚拟 PCI 总线上可以连接多个 Device Number 不同的端口。
当一个虚拟 PCI 总线上挂接 PCI-to-PCI 桥时, 系统配置软件将使用 Type 01h 配置请求 TLP 访问 PCI-PCI 桥下游的 PCI 设备。 如 图 6-5 所示, RC 可以通过 Type 01h 配置请求 TLP 访问 P-P2 桥片、 P-P3 桥片, EP1 和 EP2。
上文简要讲述了配置请求 TLP 使用 ID 路由方式从上游端口向下游端口的传递规则, 但 是 Vendor_Defined 消息报文和 Cpl 和 CplD 报文还可能从下游端口向上游端口进行传递。 此 时 PCIe 总线处理方法略有不同。 下文仍以 图 6-5 为例说明这种情况。
当一个 TLP 从 EP2 传送到 EP1 或者 RC 时, 首先检查 P-P3 桥片的配置空间, P-P3 桥片 发现该 TLP 不是发向自己时, 将该 TLP 推至上游总线, 即 PCI Bus 1。 如果 PCI Bus1 上 P-P1 桥片没有认领该 TLP, 该 TLP 将继续向 P-P2 桥片传递, 并由这个桥片将 TLP 转发给合适的 EP; 如果 P-P1 桥片认领该 TLP, 该 TLP 将继续向上游总线传递, 直至 RC。
6. 2. 3 隐式路由
PCIe 总线规定消息请求报文使用隐式路由方式。 在 PCIe 总线中, 有许多消息是直接发向 RC 或者来自 RC 的广播报文, 这些报文不使用地址或者 ID 进行路由, 而是使用 Msg 和 MsgD 报文的 Route 字段进行路由, 这种路由方式称为隐式路由。
PCIe 总线定义了一些用于中断请求、 错误状态处理、 锁定总线事务、 热插拔信号处理和 “Vendor_Defined Messages” 消息报文。 这些消息报文需要使用隐式路由方式进行传递。 消息报文的 Route 字段的含义如表 6-4 所示。
路由字段见表 6-2 中 Msg 消息的 Type 字段 。
使用隐式路由方式的 TLP, 其 Route 字段为 “000” , “011” , “100” 或者 “101” 。 当一 个报文使用隐式路由向 EP 发送时, EP 将对 Route 字段进行检查, 如果这个报文是 “来自 RC 的广播报文” , 或者是 “本地报文” , EP 将接收此报文。
如果 Switch 收到一条使用隐式路由的 TLP 时, 将根据报文 Route 字段的不同而分别处 理。 如果 Switch 的上游端口接收了一条来自 RC 的广播消息, 则将该报文发向所有的下游端口; 如果 Switch 接收了一条来自下游端口发向 RC 的消息报文时, Switch 将此报文直接转发到上游端口, 直至 RC; 如果 Switch 接收了一条使用隐式路由方式的本地消息报文, 则 Switch 接收并终结此报文, 不再上传或下推。
6. 3 存储器、 I / O 和配置读写请求 TLP
在 PCIe 总线中, 存储器读写, I / O 读写和配置读写请求 TLP 由以下几类报文组成。
- 存储器读请求 TLP 和读完成 TLP
当 PCIe 主设备, RC 或者 EP, 访问目标设备的存储器空间时, 使用 Non-Posted 总线事 务向目标设备发出存储器读请求 TLP, 目标设备收到这个存储器读请求 TLP 后, 使用存储器读完成 TLP, 主动向主设备传递数据。 当主设备收到目标设备的存储器读完成 TLP 后, 将完成一次 DMA 读操作。 - 存储器写请求 TLP
在 PCIe 总线中, 存储器写使用 Posted 总线事务。 PCIe 主设备仅使用存储器写请求 TLP 即可完成 DMA 写操作, 主设备不需要目标设备的回应报文。 - 原子操作请求和完成报文
原子操作由 PCIe V2. 1 总线规范引入, 一个完整的原子操作由原子操作请求和原子操作 完成报文组成。 原子操作的使用方法与其他 Non-Posted 总线事务类似, 首先 PCIe 主设备向 目标设备发送原子操作请求, 之后目标设备向主设备发送原子操作完成报文, 结束一次原子 操作。 有关原子操作的详细说明见第 6. 3. 5 节。 - I / O 读写请求 TLP 和读写完成 TLP
在 PCIe 总线中, I / O 读写操作使用 Non-Posted 总线事务, I / O 读写 TLP 都需要完成报文做为回应。 只是在 I / O 写请求的完成报文中不需要 “带数据” , 而仅含有 I / O 写请求是否成 功的状态信息。 - 配置读写请求 TLP 和配置读写完成 TLP
从总线事务的角度上看, 配置读写请求操作的过程与 I / O 读写操作的过程类似。 配置读 写请求 TLP 都需要配置读写完成作为应答, 从而完成一个完成的配置读写操作。 - 消息报文
与 PCI 总线相比, PCIe 总线增加了消息请求事务。 PCIe 总线使用基于报文的数据传送 模式, 所有总线事务都是通过报文实现的, PCIe 总线取消了一些在 PCI 总线中存在的边带信号。 在 PCIe 总线中, 一些由 PCI 总线的边带信号完成的工作, 如中断请求和电源管理等, 在 PCIe 总线中由消息请求报文实现。
6. 3. 1 存储器读写请求 TLP
存储器读写请求 TLP 的格式如图 6-8 所示。
在 PCIe 总线中, 存储器写请求 TLP 使用 Posted 数据传送方式。 而其他与存储器和 I / O 相关的报文都使用 Split 方式进行数据传送, 这些请求报文需要完成报文, 通知发送端之前的数据请求报文已经处理完毕, 有关完成报文的详细说明见第 6. 3. 2 节。
存储器读写请求 TLP 使用地址路由方式进行数据传递, 在这类 TLP 头中包含 Address 字段, Address 字段具有两种地址格式, 分别是 32 位和 64 位地址。 在存储器读写和 I / O 读写请求的第 3 和第 4 个双字中, 存放 TLP 的 32 或者 64 位地址。 存储器、 I / O 和原子操作读写 请求使用的 TLP 头较为类似。 本节仅介绍存储器、 I / O 读写使用的 TLP 头, 而在第 6. 3. 5 节 详细介绍原子操作。
-
Length 字段
在存储器读请求 TLP 中并不包含 Data Payload, 在该报文中, Length 字段表示需要从目标设备数据区域读取的数据长度; 而在存储器写 TLP 中, Length 字段表示当前报文的 Data Payload 长度。
Length 字段的最小单位为 DW。 当该字段为 n 时, 表示需要获得的数据长度或者当前报 文的数据长度为 n 个 DW, 其中 0≤n≤0x3FF。 值得注意的是, 当 n 等于 0 时, 表示数据长 度为 1024 个 DW。
-
DW BE 字段
PCIe 总线以字节为基本单位进行数据传递, 但是 Length 字段以 DW 为最小单位。 为此 TLP 使用 Last DW BE 和 First DW BE 这两个字段进行字节使能, 使得在一个 TLP 中, 有效数据以字节为单位。
这两个 DW BE 字段各由 4 位组成, 其中 Last DW BE 字段的每一位对应数据 Payload 最后一个双字的字节使能位; 而 First DW BE 字段的每一位对应数据 Payload 第一个双字的字节使能位。 其对应关系如表 6-5 所示。
Last DW BE 和 First DW BE 这两个字段的使用规则如下。- 如果传送的数据长度在一个对界的双字 (DW) 之内, 则 Last DW BE 字段为 0b0000, 而 First DW BE 的对应位置 1; 如果数据长度超过 1DW, Last DW BE 字段一定不能为 0b0000。 PCIe 总线使用 Last DW BE 字段为 0b0000 表示所传送的数据在一个对界的 DW 之内。
- 如果传送的数据长度超过 1DW, 则 First DW BE 字段至少有一个位使能。 不能出现 First DW BE 为 0b0000 的情况。
- 如果传送的数据长度大于等于 3DW, 则在 First DW BE 和 Last DW BE 字段中不能出 现不连续的置 1 位。
- 如果传送的数据长度在 1DW 之内时, 在 First DW BE 字段中允许有不连续的置 1 位。 此时 PCIe 总线允许在 TLP 中传送 1 个 DW 的第 1, 3 字节或者第 0, 2 字节。
- 如果传送的数据长度在 2DW 之内时, 则 First DW BE 字段和 Last DW BE 字段允许有 不连续的置 1 位。
值得注意的是, 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 链路的利用率。
在 PCIe 总线中, 使用 Posted 方式进行存储器写时, 目标设备不需要向主设备发送回应 报文, 因此主设备并不知道这个存储器写是否已经达到目的地。 而主设备可以使用 “读刷 新” 操作, 向目标设备进行读操作来保证存储器写最终到达目的地。 有关 “读刷新” 的详 细说明及实现原理见第 11 章。
-
Requester ID 字段
Requester ID 字段包含 “生成这个 TLP 报文” 的 PCIe 设备的总线号 ( Bus Number) 、 设 备号 (Device Number) 和功能号 (Function Number) , 其格式如 图 6-9 所示。 对于存储器写请求 TLP, Requester ID 字段并不是必须的, 因为目标设备收到存储器写请求 TLP 后, 不需 要完成报文作为应答, 因此 Requester ID 字段对于存储器写请求 TLP 并没有实际意义。
对于 Non-Posted 数据请求, 目标设备需要使用完成报文做为回应。 在这个完成报文中, 需要使用源设备的 Requester ID 字段。 因此在 Non-Posted 数据请求 TLP 中, 如存储器读请求、 I / O 和配置读写请求 TLP, 必须使用 Requester ID 字段。
存储器, I / O 读请求 TLP 中含有 Requester ID 和 Tag 字段。 在 PCIe 总线中 Requester ID 和 Tag 字段合称为 Transaction ID, Transaction ID 字段的格式如 图 6-9 所示。 存储器读, I / O 和配置读写请求 TLP 使用 Transaction 字段的主要目的是使接收端通过分析报文的 Transaction ID, 确认完成报文的目的地。
在 PCIe 总线中, 所有 Non-Posted 数据请求都需要完成报文作为应答, 才能结束一次完 整的数据传递。 一个源设备在发送 Non-Posted 数据请求之后, 如果并没有收到目标设备回送 的完成报文, TLP 报文的发送端需要保存这个 Non-Posted 数据请求, 此时该设备使用的 Transaction ID (Tag 字段) 不能被再次使用, 直到一次数据传送结束, 即数据发送端收齐与该 TLP 对应的所有完成报文。
在同一个时间段内, PCIe 设备发出的每一个 Non-Posted 数据请求 TLP, 其 Transaction ID 必须是唯一的。 即在同一时间段内, 在当前 PCI 总线域中不能存在两个或者两个以上的存储 器读请求 TLP, 其 Transaction ID 完全相同。
源设备发送 Non-Posted 数据请求后, 在没有获得全部完成报文之前, 不能释放这个 Transaction ID 占用的资源。 在同一个 PCIe 设备发送的 TLP 中, 其 Requester ID 字段是相同的, 因此 PCIe 设备的设计者所能管理的资源是 Tag 字段。 PCIe 设备的设计者需要合理地管 理 Tag 资源, 以保证数据传送的正确性。
PCIe 设备在发送 Non-Posted 数据请求时, 需要暂存这些 Non-Posted 数据请求。 其中 Tag 字段的长度决定了发送端能够暂存多少个同类型的 TLP, 如果 Tag 字段长度为 5, 发送端能够暂存 32 个报文; 如果 PCIe 设备使能了 Extended Tag 位 (该位的详细描述见第 4. 3. 2 节) , Tag 字段可以由 8 位组成, 此时发送端能够暂存 256 个报文。
与 PCI 总线相比, PCIe 总线的数据传送延时较长, 而为了弥补这个传送延时, PCIe 设备通常使用流水线技术。 此时 PCIe 设备必须能够连续发送多个存储器读请求报文, 随后 RC 也将连续回送多个存储器读完成报文, 在 PCIe 设备的实现中, 需要保证能够源源不断地从 RC 接收这些报文, 以充分利用报文接收流水线, 有关这部分内容详见第 12. 4. 3 节。
PCIe V2. 1 总线规范还提出了另一种 Requester ID 格式, 即 ARI ( Alternative Routing-ID Interpretation) 格式, 除了 Requester ID 外, 在完成报文中使用的 Completer ID 也可以使用这种格式。 ARI 格式将 ID 号分为两个字段, 分别为 Bus 号和 Function 号, 而不使用 Device 号, ARI 格式如图 6-10 所示。
PCIe 总线引入 ARI 格式的依据是在一个 PCIe 链路上仅可能存在一个 PCIe 设备, 因而 其 Device 号一定为 0。 在多数 PCIe 设备中, Requester ID 和 Completion ID 包含的 Device 号是没有意义的。 使用 ARI 格式时, 一个 PCIe 设备最多可以支持 256 个 Function, 而传统的 PCIe 设备最多只能支持 8 个 Function。
-
I / O 读写请求 TLP 的规则
I / O 读写请求与存储器读写请求 TLP 的格式基本类似, 只是 I / O 读写请求 TLP 只能使用 32 位地址模式和基于地址的路由方式, 而且 I / O 读写请求 TLP 只能使用 Non-Posted 方式进 行传递。 PCIe 总线并不建议 PCIe 设备支持 I / O 地址空间, 但是 Switch 和 RC 需要具备接收和发送 I / O 请求报文的能力, 因为许多老的 PCI 设备依然使用 I / O 地址空间, 这些 PCI 设备 可以通过 PCIe 桥连接到 PCIe 总线中。 因此虽然支持 I / O 读写请求的 PCIe 设备极少, 但是 在 PCIe 体系结构中, 依然需要支持 PCI 总线域的 I / O 地址空间。
与存储器读写请求 TLP 不同, I / O 读写请求 TLP 的某些字段必须为以下值。- TC [2∶ 0] 必须为 0, I / O 请求报文使用的 TC 标签只能为 0。
- TH 和 Attr2 位保留, 而 Attr [1∶ 0] 必须为 “0b00” , 这表示 I / O 请求报文必须使用 PCI 总线的强序数据传送模式, 而且在传送过程中, 硬件保证其传送的数据与 Cache 保持一致, 实际上 I / O 地址空间都是不可 Cache 的。
- AT [1∶ 0] 必须为 “0b00” , 表示不支持地址转换, 因此在虚拟化技术中, 并不处理 PCI 总线域中的 I / O 空间。
- Length [9∶ 0] 为 “0b00 0000 0001” , 表示 I / O 读写请求 TLP 最大的数据 Payload 为 1DW, 该类 TLP 不支持突发传送。
- Last DW [3∶ 0] 为 “0b0000” 。
6. 3. 2 完成报文
PCIe 总线支持 Split 传送方式, 目标设备使用完成报文向源设备主动发送数据。 完成报 文使用 ID 路由方式, 由 TLP Predix、 报文头和 Data Payload 组成, 但是某些完成报文可以不含有 Data Payload, 如 I / O 或者配置写完成和 Zero-Length 读完成报文。 在 PCIe 总线中, 有以 下几类数据请求需要收到完成报文之后, 才能完成整个数据传送过程, 完成报文格式如图 6-11 所示。
- 所有的数据读请求, 包括存储器、 I / O 读请求、 配置读请求和原子操作请求。 当一个 PCIe 设备发出这些数据请求报文后, 必须收到目标设备的完成报文后, 才能结束一次数据传送。 这一类完成报文必须包含 Data Payload。
- 所有的 Non-Posted 数据写请求, 包括 I / O 和配置写请求。 当一个 PCIe 设备发出这些数据请求报文后, 必须收到目标设备的完成报文后, 才能结束数据传送。 但是这一类完成报文不包含数据, 仅包含应答信息。
- 与 ATS 机制相关的一些报文, 详见第 13. 2 节。
完成报文 “Byte 0” 中的大部分字段与 “存储器, I / O、 配置请求报文” 的对应字段的 含义相同。 完成报文一次最多能够传送的报文大小不能超过 Max_Payload_Size 参数。 在多数 处理器中, 完成报文中包含的数据在一个 Cache 行之内, 完成报文使用 RCB 参数来处理数 据对界, RCB 参数的大小与处理器系统的 Cache 行长度和 DDR-SDRAM 的一次突发传送长度 相关, 这些参数的详细描述见第 6. 4. 3 节。 在 x86 和 PowerPC 处理器中, 一个存储器读完成 报文一般不超过 RCB 参数。
-
Requester ID 和 Tag 字段
完成报文使用 ID 路由方式, ID 路由方式详见第 6. 2. 2 节。 完成报文头的长度为 3DW, 完成报文头中包含 Transaction ID 信息, 由 Requester ID 和 Tag 字段组成, 这个 ID 必须与源设备发送的数据请求报文的 Transaction ID 对应, 完成报文使用 Transaction ID 进行 ID 路由, 并将数据发送给源设备。
当 PCIe 设备收到存储器读、 I / O 读写或者配置读写请求 TLP 时, 需要首先保存这些报 文的 Transaction ID, 之后当该设备准备好完成报文后, 将完成报文的 Requester ID 和 Tag 字段赋值为之前保存的 Transaction ID 字段。
-
Completer ID 字段
Completer ID 字段的含义与 Requester ID 字段较为相似, 只是该字段存放 “发送完成报文” 的 PCIe 设备的 ID 号。 PCIe 设备进行数据请求时需要在 TLP 字段中包含 Requester ID 字 段; 而使用完成报文结束数据请求时, 需要提供 Completer ID 字段。
-
Status 字段
Status 字段保存当前完成报文的完成状态, 表示当前 TLP 是正确地将数据传递给数据请 求端; 还是在数据传递过程中出现错误; 或者要求数据请求方进行重试。 PCIe 总线规定了 几类完成状态, 如表 6-6 所示。
-
BCM 位与 Byte Count 字段
BCM ( Byte Count Modified) 字段由 PCI-X 设备设置。
Byte Count 字段记录源设备还需要从目标设备中获得多少字节的数据就能完成全部数据传递, 当前 TLP 中的有效负载也被 Byte Count 字段统计在内。 该字段由 12 位组成。 该字段为 0b0000- 0000- 0001 表示还剩一个字节, 为 0b1111-1111-1111 表示还剩 4095 个字节, 而为 0b0000- 0000- 0000 表示还剩 4096 个字节。 除了存储器读请求的完成报文外, 大多数完成报文的 Byte Count 字段为 4。
如一个源设备向目标设备发送一个 “读取 128B 的存储器读请求 TLP” , 而目标设备收 到这个读请求 TLP 后, 可能使用两个存储器读完成 TLP 传递数据。 其中第 1 个存储器读完成 TLP 的有效数据为 64 B, 而 Byte Count 字段为 128; 第 2 个存储器读完成 TLP 中的有效数 据为 64 B, 而 Byte Count 字段也为 64。 当数据请求端接收完毕第 1 个存储器读完成 TLP 后, 发现还有 64 B 的数据没有接收完毕, 此时必须等待下一个存储器读完成 TLP。 等到数据请 求端收齐所有数据后, 才能结束整个存储器读请求。
目标设备发出的第 2 个读完成 TLP 中的有效数据为 64B, 而 Byte Count 字段为 64, 当数 据请求端接收完毕这个读完成 TLP 后, 将完成一个完整的存储器读过程, 从而可以释放这 个存储器读过程使用的 Tag 资源。 -
Lower Address 字段
如果当前完成报文为存储器读完成 TLP, 该字段存放在存储器读完成 TLP 中第一个数据 所对应地址的最低位。 值得注意的是, 在完成报文中, 并不存在 First DW BE 和 Last DW BE 字段, 因此接收端必须使用存储器读完成 TLP 的 Low Address 字段, 识别一个 TLP 中包含数 据的起始地址。 第 12. 2. 2 节将详细介绍该字段的作用。
6. 3. 3 配置读写请求 TLP
配置读写请求 TLP 由 RC 发起, 用来访问 PCIe 设备的配置空间。 配置请求报文使用基于 ID 的路由方式。 PCIe 总线也支持两种配置请求报文, 分别为 Type 00h 和 Type 01h 配置请求。 配置请求 TLP 的格式如图 6-12 所示。
配置请求 TLP 的第 4 ~ 7 字节与存储器请求 TLP 类似。 而第 8 ~ 11 字节的 Bus、 Device 和 Function Number 中存放该 TLP 访问的目标设备的相应的号码, 而 Ext Register 和 Reigister Number 存放寄存器号。 配置请求报文的其他字段必须为以下值。
- TC [2∶ 0] 必须为 0, I / O 请求报文的传送类型 (TC) 只能为 0。
- TH 位为保留位; Attr2 位为保留, 而 Attr [1∶ 0] 必须为 “00b” , 这表示 I / O 请求报文使用 PCI 总线的强序数据传送模式; AT [1∶ 0] 必须为 “0b00” , 表示不进行地址转换。
- Length [9∶ 0] 为 “0b00 0000 0001” , 表示配置读写请求最大 Payload 为 1DW。
- Last DW BE 字段为 “0b0000” 。 而 First DW BE 字段根据配置读写请求的大小设置。
6. 3. 4 消息请求报文
在 PCIe 总线中, 多数消息报文使用隐式路由方式, 其格式如图 6-13 所示。 其中 Byte 0 字段为通用 TLP 头, 而 Byte 4 的第 3 字节中存放 Message Code 字段。
PCIe 总线规定了以下几类消息报文。
- INTx 中断消息报文 ( INTx Interrupt Signaling) 。
- 电源管理消息报文 (Power Management) 。
- 错误消息报文 (Error Signaling) 。
- 锁定事务消息报文 (Locked Transaction Support) 。
- 插槽电源限制消息报文 ( slot power limit support) 。
- 供应商定义的消息。
-
INTx 中断消息报文
PCIe 总线推荐设备使用 MSI 或者 MSI-X 机制提交中断请求, 但是 MSI 中断机制并不是由 PCIe 总线首先提出的, 在 PCI 总线中就已经存在这种中断请求机制。
在 PCIe 总线中, PCIe 设备可以使用 Legacy 中断方式提交中断请求, 此时需要使用 INTx 中断消息报文向 RC 通知中断事件。 除此之外在 PCIe 体系结构中仍然存在 PCI 设备, 这些设备可能使用 INTx 信号提交中断请求。
例如在 PCIe 桥片上挂接的 PCI 设备可能并不支持 MSI 中断机制, 因此需要使用 INTx 中断信号提交中断请求, 此时 PCIe 桥需要将 INTx 信号转换为 INTx 中断消息报文, 并向 RC 提交中断请求。 在 PCIe 总线中, 共有 8 种 INTx 中断消息报文, 见表 6-7。
-
错误消息报文
在第 4. 3. 3 节中简要介绍了 AER Capability 结构。 如果 PCIe 设备支持 AER Capability 结 构, 当 PCIe 设备出现某种错误时, 将向 RC 或者 RC Event Collector 发送错误消息报文, 之 后 RC 或者 RC Event Collector 将根据错误类型分别进行处理。
PCIe 总线规范定义了两大类错误类型, 分别是可恢复错误 ( Correctable Errors) 和不可恢复错误 (Uncorrectable Errors) , 不可恢复错误又细分为致命错误 ( Fatal) 和非致命错误 (Nonfatal) 。 当 PCIe 设备出现这些错误时, 将使用 ERR_COR、ERR_NONFATAL 和 ERR_FATAL 错误消息报文向 RC 或者 RC Event Collector 发送错误消息报文。
6. 3. 5 PCIe 总线的原子操作
PCIe V2. 1 总线规范引入原子操作的概念, 原子操作仅能在存储器访问中使用。 其中 RC 和 EP 可以作为原子操作的请求者和接收者, 而 Switch 和多端口 RC 支持原子操作的转 发。 PCIe 总线支持三类原子操作, 分别是 EP-to-EP, EP-to-RC 和 RC-to-EP 的原子操作。
PCIe 设备使用一次原子操作可以实现之前需要多次数据操作才能完成的数据交换任务, 除此之外 PCIe 设备使用原子操作还可以避免使用带锁的 PCIe 总线事务。 原子操作的基本过 程如下所示。
- 源设备向目标设备发送原子操作请求 TLP。 原子操作请求 TLP 使用 Non-Posted 方式进行数据传递, 且使用基于地址的路由方式。
- 当目标设备收到这个原子操作请求 TLP 之后, 将从这个 TLP 指定的存储器空间中读取原始数据。
- 目标设备将 “原始数据” 与 “原子操作请求 TLP 中包含的操作数” 进行某种规定的运算后产生一个新的数据。 这一过程不可被其他总线事务中断, PCIe 设备保证这一过程为原子操作。 这个步骤对于原子操作至关重要, 也是原子操作的实现要点。
- 当上述原子操作执行完毕后, 目标设备使用原子操作完成报文向源设备传送数据, 并将这个新的数据写入目标设备的存储器空间中。 原子操作完成报文与存储器读完成的传递方式类似。
由以上分析, 可以发现所谓原子操作是指 PCIe 设备 “读取原始数据” 、 “运算” 和 “产生新的数据” 这三个过程不可被其他操作打断。 这三个过程将在目标设备中一次完成, 并由目标设备的硬件逻辑保证这三个过程不会被其他 TLP 干扰。
由上文所述, 一个完整的原子操作由原子操作请求 TLP 和完成 TLP 组成。 其中原子操作请求 TLP 的报文头与存储器请求 TLP 类似, 如 图 6-8 所示。 原子操作请求 TLP 具有 Data Payload 字段, 在 Data Payload 中包含原子操作请求 TLP 使用的操作数。
目前, PCIe 总线共支持 3 种原子操作, 分别为 FetchAdd、 Swap 和 CAS 原子操作。 不同的原子操作使用的操作数个数并不相同, 其中 FetchAdd 和 Swap 原子操作使用一个操作数,而 CAS 原子操作使用两个操作数。
-
FetchAdd 操作
FetchAdd 操作支持 32b 或者 64b 的操作数。 如果该 TLP 的 Length 字段为 1DW 时, 操作 数的长度为 32b; 如果该 TLP 的 Length 字段为 2DW 时, 操作数的长度为 64b。 FetchAdd 操作的执行过程如下所示。
(1) PCIe 设备从 TLP 的指定 PCI 总线地址中获得原始数据。
(2) 将原始数据与 TLP 中的操作数相加, 并得到一个新的数据。 相加的结果忽略进位与溢出位。
(3) 将这个新的数据写入 TLP 指定的 PCI 总线地址中。
(4) 使用完成报文返回指定 PCI 总线地址中的原始数据。 -
Swap 总线事务
Swap 操作也支持 32b 或者 64b 的操作数, 其原则与 FetchAdd 操作完全一致。 Swap 操作的执行过程如下所示。
(1) PCIe 设备从 TLP 指定的 PCI 总线地址中读取原始数据。
(2) 将 TLP 中的操作数写入 TLP 指定的 PCI 总线地址。
(3) 使用完成报文返回 PCI 总线地址中的原始数据。 -
CAS 总线事务
CAS 操作支持 32b、 64b 或者 128b 的操作数。 如果该 TLP 的 Length 字段为 2DW 时, 操 作数的长度为 32b; 如果该 TLP 的 Length 字段为 4DW 时, 操作数的长度为 64b; 如果该 TLP 的 Length 字段为 8DW 时, 操作数的长度为 128b。 CAS 总线事务含有两个操作数, 分别为 “Compare” 和 “ Swap” 。 CAS 操作的执行过程如下所示。
(1) PCIe 设备从 TLP 指定的 PCI 总线地址中获得原始数据。
(2) 将原始数据与 “Compare” 操作数进行比较。
(3) 如果结果相等, 则将 “ Swap” 操作数写入 TLP 指定的位置。
(4) 使用完成报文返回 PCI 总线地址中的原始数据。
智能设备之间以及智能设备与处理器之间如果需要使用 “ Spin Lock” 操作时, 可以使用 CAS 原子操作实现。 值得注意的是, 在 x86 处理器的指令集中, 也含有 CAS 类指令, 该 指令是实现 “ Spin Lock” 的基础。 但是在处理器系统中使用的 “ Spin Lock” 操作与智能设 备使用的 “ Spin Lock” 操作在实现上有所不同。
6. 3. 6 TLP Processing Hint
当 TLP 的 TH 位为 1 时, 表示在当前 TLP 中包含 Processing Hint 字段, PH 字段由 PCIe V2. 1 总线规范引入。 该字段的引入可以使目标设备根据源设备对数据的使用情况, 合理地 安排数据缓冲, 从而降低 PCIe 设备的访问延时, 并最大化地利用 PCIe 设备中的数据缓冲。
Processing Hint 字段的产生与智能设备的大量涌现密切相关。 在智能设备中, 含有一个 运算能力相当强的处理器。 智能设备与处理器之间的数据交换, 实质上等效于两个处理器系 统之间的数据传递。 有些智能设备, 如在显卡中使用的 GPU ( Graphic Processing Unit) 和 GP-GPU (Gerneral Purpose GPU) 的处理能力甚至超过多数通用处理器。 智能设备与处理器 系统可以采用图 6-14 所示的拓扑结构连接。
在这种处理器系统中, 内部互连网络处于核心地位, 上图所示的网络是一个理想的全互 连结构。 在这种互连结构中, 处理器、 存储器和智能设备与网络节点相连。 在这种结构中, 在网络节点上连接的设备都含有一个处理器, 包括存储器。
6. 4 TLP 中与数据负载相关的参数
在 PCIe 总线中, 有些 TLP 含有 Data Payload, 如存储器写请求、 存储器读完成 TLP 等。 在 PCIe 总线中, TLP 含有的 Data Payload 大小与 Max_Payload_Size、 Max_Read_Request_Size 和 RCB 参数相关。 下面将分别介绍这些参数的使用。
6. 4. 1 Max_Payload_Size 参数
PCIe 总线规定在 TLP 报文中, 数据有效负载的最大值为 4 KB, 但是 PCIe 设备并不一定能够发送这么大的数据报文。 PCIe 设备含有 “ Max_Payload_Size” 和 “ Max_Payload_Size Supported” 参数, 这两个参数分别在 Device Capability 寄存器和 Device Control 寄存器中定 义, 这两个寄存器在 PCI Express Capability 结构中的位置见第 4. 3. 2 节。
“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 非法。
6. 4. 2 Max_Read_Request_Size 参数
Max_Read_Request_Size 参数由 PCIe 设备决定, 该参数规定了 PCIe 设备一次能从目标设备读取多少数据。
Max_Read_Request_Size 参数在 Device Control 寄存器中定义, 详见第 4. 3. 2 节。 该参数与存储器读请求 TLP 的 Length 字段相关, 其中 Length 字段不能大于 Max_Read_Request_Size 参数。 在存储器读请求 TLP 中, Length 字段表示需要从目标设备读取多少数据。
6. 4. 3 RCB 参数
RCB 位在 Link Control 寄存器中定义, 见第 4. 3. 2 节。 RCB 位决定了 RCB 参数的值, 在 PCIe 总线中, RCB 参数的大小为 64 B 或者 128 B, 如果一个 PCIe 设备没有设置 RCB 的大小 , 则 RC 的 RCB 参数缺省值为 64 B, 而其他 PCIe 设备的 RCB 参数的缺省值为 128 B。 PCIe 总线规定 RC 的 RCB 参数的值为 64 B 或者 128 B, 其他 PCIe 设备的 RCB 参 数为 128 B。
6. 5 小结
本章重点介绍 PCIe 总线的事务层。 在 PCIe 总线层次结构中, 事务层最易理解, 同时也 与系统软件直接相关。 但是事务层的知识较为琐碎, 在第 12 章将结合一个 EP 的设计实例, 进一步说明 PCIe 总线事务层的具体实现机制。
☆