PCIe Spec V5.0阅读笔记(二)Transaction Layer Overview(1)

写在前面:本系列文章是个人在阅读PCIe SpecV5.0时个人做的一些笔记,其主要是在记录PCIe Spec知识点的基础上,分享一些自己的想法以及其中一些知识点的原理,并非完全正确,仅作参考。但是对于初学者建议可以先看一下《PCIe体系结构导读》,之后再阅读Spec会更容易理解。Spec在主页的资源里可以下载

由于Spec的第二章内容过多,于是分几篇介绍,本篇主要介绍事务层:

目录

1.Overview

1.1地址空间、事务类型和用

1.1.1 Memory事务

1.1.2 I/O事务

1.1.3 Configuration事务

1.1.4 Message事务

1.2 Packet格式

2.事务层协议

2.1Common Packet Header Fields

2.2 TLPs with Data Payloads - Rules

2.3 TLP Digest Rules

2.4 Routing and Addressing Rules

2.4.1 基于地址的路由

2.4.1 基于ID的路由

2.5 First/Last DW Byte Enables Rules


1.Overview

有几个事务层的关键点:

  • A pipelined full Split-Transaction protocol
  • Mechanisms for differentiating the ordering and processing requirements of Transaction Layer Packets (TLPs)
  • Credit-based flow control 
  • Optional support for data poisoning and end-to-end data integrity detection.

主要是事务拆分、排序、流控以及数据错误检测。

1.1地址空间、事务类型和用

地址空间共有Memory、I/O、Configuration以及Message四种,分别对应不同的事务和用途。

1.1.1 Memory事务

Memory事务包含以下类型:

  • 读请求/读完成
  • 写请求
  • 原子操作请求/完成

其中读写请求很容易理解,就是对对应目标设备进行Memory读写访问,读请求往往伴随着读完成,即向某一设备的地址发起读请求TLP包后,目标设备接收到该包然后将数据准备后通过带有Payload的完成包CPLD返回给源设备。而写请求只需将数据写入目标即可,不需要返回包。原子操作在后续会有详细介绍。

Memory事务采用两种地址形式:

  • 32bit地址
  • 64bit地址
1.1.2 I/O事务

PCIe支持I/O Space是为了兼容以前的设备,未来可能会弃用。

其包括以下两种类型:

  • 读请求/读完成
  • 写请求/写完成

我们可以发现,在I/O事务中,即使是写请求,也要有完成包回复

I/O事务采用32bit地址。

1.1.3 Configuration事务

Configuration事务主要用来访问设备中对应Function的配置寄存器,其类型有:

  • 读请求/读完成
  • 写请求/写完成
1.1.4 Message事务

Message用于支持设备之间的带内通信,除了Spec中介绍的几种Message,同时还支持厂家自定义的Message,但是各厂家之间不同的Message的兼容性并不保证。

1.2 Packet格式

下图是Packet的格式,包含一个或多个(可选)TLP Prefix、1个HeaderDataPayload(部分Packet有)以及Digest校验(可选)。

根据数据包的类型,TLP的Header中会包含以下字段(只是部分字段,后续有完整字段介绍):

  • Format of the packet :指示Header的长度以及是否携带数据

  • Type of the packet: 指示事务类型,比如Memory读写请求等

  • ** Length for any associated data**:Payload部分长度,以DW(4字节)为单位

  • Transaction Descriptor, including:

    Transaction ID

    Attributes

    Traffic Class

  • Address/routing information:地址/路由信息

  • Byte Enables:字节使能

  • Message encoding

  • Completion status:完成状态

2.事务层协议

2.1Common Packet Header Fields

下图是所有TLP Header都具有的字段:

  • Fmt字段代表Header的长度及是否带有数据,详见下表:

  • Type字段代表事务包类型,通常配合Fmt共同作用:

  • Length字段代表Payload部分长度:

    需要注意,这一字段0代表的是1024DW即4096字节,这也是一般Max_Payload_Size设置的大小。

关于其他部分字段,会在后续详细介绍。

2.2 TLPs with Data Payloads - Rules

  • Length的单位是DW

  • 所有Message TLP的Length字段是保留的,除了那些明确指明长度的TLP包

  • TLP发送侧产生的TLP包的Payload部分长度不允许超过Device控制寄存器中设置的Max_Payload_Size(以DW为单位)的大小

  • 接收侧接收到的TLP包中的Length字段指示的长度不能超过接收侧Device控制寄存器中设置的Max_Payload_Size(以DW为单位)的大小

    接收侧在接收到数据包后要进行检查,如果Length字段指示的长度和实际TLP包中Payload部分的数据长度不符合则该TLP包格式错误

  • 对于带有数据的TLP包,其Length部分指示的长度必须和实际部分匹配

  • Length字段只指示Data部分长度,不包含Digest校验部分长度

2.3 TLP Digest Rules

  • 所有TLP包中的TD字段指示在TLP包的尾部是否有ECRC(end-to-end CRC)存在

    如果TD字段和尾部实际上Digest是否存在不对应将会进行错误报告

  • 如果是中间级或末端的PCIe接收设备不支持ECRC检查,则要忽略掉TLP Digest

2.4 Routing and Addressing Rules

一共有三种主要的TLP路由机制:基于地址的路由、基于ID的路由和隐式路由

这里先只介绍地址路由和ID路由,隐式路由在后续会介绍。

2.4.1 基于地址的路由
  • 地址路由用于Memory和I/O请求;

  • 使用32bit64bit两种地址格式

    两种地址格式对应的TLP包的Header下图所示:

    我们可以发现,对于64bit地址路由的情况,其TLP包Header的长度是4DW;对于32bit地址情况其TLP包Header长度为3DW

  • 对于Memory读、Memory写以及原子请求,Address Type(AT)字段的含义如下表:

    00:指其中的地址没有被转换(在PCIe中有多个域如PCIe域、存储器域等),TA(Translation Agent)会将其当作物理地址/虚拟地址;

    01:在完成包中会使用TA将请求中的地址转换后的结果,这个值只对显示的转换请求有意义。如果TA接收到AT为01Memory读之外的其他Memory请求时,将会发出UR(Unsupported Request不支持)信号。

    10:表示其中的地址已经被ATC进行转换,如果允许与SourceID有关的函数允许向系统内存提供物理地址,TA将不会转换这个地址。如果不允许提供,则将其是做UR。

    11:当TLP包中的AT为11时,TA将发出UR信号。

    对于其他类型的TLP部分,除非明确说明,其AT字段均保留

  • 如果TH字段被设置,则图中地址最低为的2bitPH对应的内容如下:

  • Memory读、Memory写以及原子请求可以使用32bit/64bit中的一种

    对于低于4 GB的地址,请求者必须使用32位格式。如果接收到寻址低于4GB的64位格式请求(即地址的高位32位均为0),则不指定接收器的行为。

  • I/O读写请求使用32bit格式

2.4.1 基于ID的路由
  • ID路由用于配置请求(Configuration Request)、基于ID路由的Message完成包

    需要注意的是这里说的完成包不只是配置请求的完成包,而是所有请求对应的Completion

  • ID路由使用总线、设备和功能号(如适用)来指定TLP的目的地

    首先说明以下ARI,Alternative Routing-ID Interpretation。可替换的Routing ID,意味着这是一种要把Routing ID的部分或全部替换掉的机制。Routing ID一般包括Bus号(8bit)、Device号(5bit)、Function号(3bit),对于PCIe链路来讲一个链路只会挂在一个设备,Device Num恒为0,显然对于5bit有点浪费,并且Function号不够用,因此将Device号替换掉。

    (1)对于非ARI路由设备,Bus号(8bit)、Device号(5bit)、Function号(3bit)在TLP包中所处位置如下图所示:

(2)对于ARI路由设备,Bus号(8bit)、Function号(8bit)在TLP包中所处位置如下图所示:

2.5 First/Last DW Byte Enables Rules

Memory, I/O, and Configuration Requests几种TLP包中包含字节使能字段,ByteEnable位于TLP Header中的Byte7,位置如下图所示:

First DW Byte Enable指示Payload中第一个DW哪些字节有效;Last DW Byte Enable指示Payload的最后一个DW哪些字节有效。哪一bit为1则对应的字节有效。

对应关系图如下:

一定需要注意,BE(Byte Enable)随着bit位的增大其对应的Byte索引也在增大,下面以First DW Byte Enable: 0100b,Last DW Byte Enable:1000b举例看看实际是对应哪部分字节有效(橙色背景部分为有效字节):

此外需要注意的是,当Memory Read请求中的TH被置位时,ByteEnable被重新定义为ST[7:0](具体后面会介绍),这个时候就意味着希望该读请求最终返回的每个字节都必须是有效的。

First/Last DW Byte Enable的一些规则如下:

  • 如果TLP包中Length字段表示的长度大于1DW,那么First DW Byte Enable字段一定不能为0000b

  • 如果TLP包中Length字段表示的长度等于1DW,那么Last DW Byte Enable字段一定为0000b

  • 如果TLP包中Length字段表示的长度大于1DW,那么Last DW Byte Enable字段一定不能为0000b

  • 对于长度为1 DW的所有请求,在First DW BE字段中允许使用非连续字节使能,比如1010b、0101b、1001b、1011b、1101b

  • 对于Length长度为2 DW(1 QW=2DW=8字节)的四字(QW)对齐内存请求两个字节使能都允许非连续字节使能

    在这里我们先说一下地址对齐,地址对齐是指发起读写时,起始地址是存储单元大小的整数倍,比如对于32字节的存储对齐要求,起始地址为4的倍数

    在本规则中,要求四字对齐即8字节对齐,其起始地址假设为0X00,下一个存储单元的地址为0X08,那么长度为2DW的TLP包则不会超出本次存储单元的范围即0-0X08,这种情况下允许First DW Byte Enable和Last DW Byte Enable可以非连续字节使能,比如:

    First DW Byte Enable: 1010b,Last DW Byte Enable:1001b

  • 所有长度为2 DW(1 QW)的非QW对齐内存请求和长度为3 DW或更长的内存请求必须只使能第一个最后一个DW之间数据连续的字节

    这就意味着First DW Byte Enable和Last DW Byte Enable所指示的字节必须与中间所有的数据字节在地址上连续。比如: First DW Byte Enable: 1100b,Last DW Byte Enable:0011b

    First DW Byte Enable: 1000b,Last DW Byte Enable:0111b

    下面是第一个例子对应的图:

    我们可以发现,Payload中所有的字节都是连续的。

    需要注意的是连续性,而不是First DW Byte Enable和Last DW Byte Enable的互补性,因为实际上传输的字节并不是都有效,这也是Byte Enable的作用。满足互补性的并不一定就满足连续性的规则,举一个例子:First DW Byte Enable: 0110b,Last DW Byte Enable:1001b,见下图:

    这种情况是不符合规则的,我们可以看到数据的中间部分Byte 3、Byte N-3、Byte N-1和其他旁边的有效数据是断开,也就是有效数据中间嵌入了无用数据,不符合连续性规则。

  • 允许长度为1 DW的写请求不使能字节(Zero-Length Write),这对Completer没有影响,除非另有说明。

    这种Zero-Length Write会有专门的用途。

  • 如果1 DW的读请求指定First DW be[3:0]字段=0000b(Zero-Length Read),则相应的Completer必须指定1 DW的长度,并包含1 DW的数据有效载荷。

    完成数据包中的数据有效负载的内容未指定,可以是任何值。

    设备可以将未启用字节的1 DW内存读请求或“Zero-Length Read”用作一种刷新请求,可以让设备确保之前Posted Writes已在其PCI Express目标设备上完成。如何实现呢?就是在发送一个Post Write后,发送一个采用相同地址的Zero-Length Read包,因为Post Write没有完成包,因此不知道何时能写完,但是Read操作有Completion,因此通过在写之后发送一个Read操作。同时这也和PCIe的order有关,因为如果Read可以超越Write到达目标设备的话,就无法确保是否Write已经完成,只有当Write完成后才处理Read才能够保证我们想要的确认结果。Order会在后续进行介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值