一、故事前传
之前我们讲了对PCIe的一些基础概念作了一个宏观的介绍,了解了PCIe是一种封装分层协议(packet-based layered protocol),主要包括事务层(Transaction layer), 数据链路层(Data link layer)和物理层(Physical layer)。
较为详细解释请见之前的文章:
1. PCIe技术概述;
2.0 PCIe Transaction layer事务层概述;
2.1 PCIe Transaction layer事务层TLP的前世今生;
2.2 PCIe Transaction layer事务层TLP事务处理方式解析。
二、事务层TLP结构解析
经过之前文章的介绍,我们可以知道,PCIe总线在事务层中利用TLP (Transaction Layer Packet) 进行数据传输。那么,TLP具体长什么样子呢?又有哪些关键内容?这个就是我们本文的重点。
TLP主要包括三个部分:Header, Data Payload和ECRC(End to End CRC).
Header: 内容来自于Device Core。大小一般为3或者4个DWs(12-16bytes)。每个类型TLP中Header格式不尽相同,但是包含的信息大致相同。
Data: 内容也来自Device Core。大小为1~1024 DWs。
Digest/ECRC: 这部根据Header和Data内容计算得到。ECRC可以选择性的附加。如果附加在TLP之后,大小一般为1DW。
我们先介绍一下Header的结构和内容:
以一个通用的4DWs TLP Header为例,如下图。
接下来,我们针对上面Header的内容进一步解析:
Fmt[2:0](Format): 3 bits, Byte0 Bit7:5, 具体含义如下:
Type[4:0]: 5 bits, Byte0 Bit4:0, 详细定义如下:
这里需要提一下,通常情况下Type[4:0]与Fmt[2:0]合起来定义具体的TLP事务类型,如下表:
举个例子:
Fmt[2:0]=001, 代表Header长度为4DWs, 并且no data传输;
Type[4:0]=00000, 代表Memory Request;
那么合起来就是,Memory Read Request(MRd).
TC[2:0](Trafic Class): 3bits, Byte1 Bit6:4, 总共定义了8个等级Trafic Class.
Traffic Class顾名思义可以理解为交通等级。比如在生活中我们遇到救护车或者消防车时,由于救护车和救护车是跟时间赛跑,那么交通等级就高,一般的私家车(可以认为没有交通等级)就必须给救护车和消防车让行!可能这个类比不是很恰当,不过大致意思是这样的~
Attr[0](Attributes): 1 bit, Byte1 Bit2, 这个bit的功能就是是否对TLP进行排序(IDO, ID-based Ordering)。
TH[0](TLP Processing Hints): 1 bit, Byte1 Bit0, 如果TH=1, 就代表在TLP中添加了TLP处理提示,可以告知系统以更有效的措施处理这个TLP。
TD[0](TLP Digest): 1 bit, Byte2 Bit7, 如果TD=1,就代表TLP里面包含了ECRC(End-to-End CRC)。
EP[0](Poisoned Data): 1 bit, Byte2 Bit6, 如果EP=1,就代表TLP传输的数据有误。
Attr[1:0](Attributes): 2 bits, Byte2 Bit5:4,
bit5=1代表enable PCI-X Relaxed Ordering功能;
bit4=1代表这个TLP没有主机缓存一致性的问题,不需要缓存窥探措施;
扩展:
缓存一致性: 也就是说只有一块一级缓存,所有处理器都必须共用它。在每一个指令周期,只有一个幸运的CPU能通过一级缓存做内存操作,运行它的指令。
窥探(Snoop): 窥探的思想是,缓存不仅仅在做内存传输的时候才和总线打交道,而是不停地在窥探总线上发生的数据交换,跟踪其他缓存在做什么。所以当一个缓存代表它所属的处理器去读写内存时,其他处理器都会得到通知,它们以此来使自己的缓存保持同步。只要某个处理器一写内存,其他处理器马上就知道这块内存在它们自己的缓存中对应的段已经失效。
AT[1:0](Address Type): 2 bits, Byte2 Bit3:2, 这两bits针对Memory和AtomicOp请求声明存储地址类型的。
Length[9:0]: TLP传输的长度,已DW为单位,最大1024 DWs.
此外,为了区分Requester与Completer之间的事务类型, PCIe Spec定义了一个事务描述块(Transaction Descriptor Fields). 下图中5个红色区域合起来就称为一个事务描述块。
Transaction ID包含了Request ID和Tag:内容有Request Device具体的位置(Bus/Device/Function)。主要是用于Requester发出事务的完成TLP回报。