前一段时间有好友要我多写一些PCIe相关的,这里试着从PCIe的TLP报文开始。PCIe是我的本行,准确来说应该是PCIe AP RX,主要是如何与系统总线进行配合,接触较多的就是TLP报文,但是对DL/PHY了解很少。我想按照自己的理解,介绍TLP报文的各个域段和相关处理,如何将PCIe报文与系统进行配合,并非协议的直接描述。
01 TLP简介
TLP,Transaction Layer Packet,是PCIe数据传输/信息交互的基础报文。PCIe两侧系统使用TLP报文进行交互,将读写请求和数据打包为TLP报文后,再进行发送。
从地址属性来看,TLP报文可以分为Memory、I/O、配置和Message报文。其中,Memory报文又可以分为读写请求和原子操作,I/O操作包括读写请求,配置请求实现RC对配置空间的访问,Message用于不同设备之间进行信息传递。Memory写请求和Message不需要对端返回响应,称为Posted Request,其余请求是需要响应的,称为Non-posted Request。
如下是协议内对TLP报文的通用描述,包括Prefix、Header、Data和Digest,其中Digest是ECRC,对TLP报文的校验。一般场景使用TLP报文,几乎只会关注Header和Data,很少使用到Prefixs。
在做PCIe接口与系统配合的分析时,我觉得需要考虑的报文格式如下所示,以Memory操作为例,存在TPH和PASID Prefix,然后才是header的各个域段,其次是数据,图中数据部分被省略。Prefix使用的较少,我认为PASID的需求会多一些,TPH Prefix的需求可能有限。本文先对TLP报文的各域段做简要描述,后续在基于每个域段做详细的说明,如何与系统进行配合,主要还是个人的理解。需注意TLP报文header通常使用大端的描述方式,Byte0置于高位。
02 域段简介
- Fmt/Type
Fmt用于描述TLP格式,按长度分为3DW和4DW,再分为带数据和不带数据,另外Prefix需使用单独的Fmt编码。Type用于描述TLP类型,包括Memory/IO读写操作、配置操作、Message报文、CPL完成报文、原子操作,另外还有Prefix相关的Type编码。
对TLP的报文解析,Fmt/Type是入口,然后是基于其编码做不同的解析处理。 - Tag/T8/T9
该域段统称为Tag,总共10bit,其中bit8/bit9与Tag[7:0]分散在Header的不同位置。Tag主要用于标记Non-posted request,也即需返回Completion的报文。除了做协议相关的检查外,在处理NP请求时,直接原样返回Tag域段即可。 - TC
Traffic Class,基于该3bit信号,可将操作请求报文分类至8种类型,分别是0-7。结合VC机制,将不同TC的报文配置分发至不同的VC,可实现不同业务流量的QoS处理,我理解主要就是链路带宽的优先级和分配处理,包括switch的调度逻辑。该机制需硬件支持,单独为每个VC预留Credit Buffer。一般来说,实现TC0和VC0即可,通过上层实现QoS处理,无需在PCIe传输层实现。需注意的是,不同TC的报文,是不能保证Ordering的。 - IDO/RO/NoSnp
统称为Attributes Field,如下所示。IDO和RO是与Transaction Ordering相关,NoSnoop是与Cache一致性相关。Attr域段是作为hints,用于报文的优化处理,提升性能。在PCIe的IP和使用中,Ordering是需要特别注意的点,涉及到数据一致性和性能问题。对于NoSnoop域段,指示是否可用硬件一致性提升其性能,置位后则不能使用Snoop,性能可能较低。
- TPH
涉及域段包括TP、PH和Steering Tag,其中ST最大支持16bit,低8bit位于header,读写请求存在差异,高8bit使用TPH Prefix。TPH也是属于Hints信息,用于描述host和device的访问行为,基于该信息做一些优化提升,ST信号是对该hints做更详细的分类。在Host侧,可考虑将TH置位的报文分配到Cache内,ST可用于表示隶属于哪个CPU的Cache,提高CPU访问报文数据的性能。 - AT
Address Type,与Address Translation Service(ATS)相关。Device侧若没有使用物理地址访问Host,则需要在host侧转换为物理地址后,才能访问系统,这会增加延时。ATS机制可以将地址转换置于Device侧,转换为物理地址后再发送至Host,降低延时,不过也带来了一些问题。ATS将页表关系缓存到device侧,该缓存称为ATC。AT表示当前请求地址为Untranslated/Translated,或者指示当前请求为Translation Request,即请求获取页表关系。 - Length
报文长度,单位DW,对于带数据的报文,0是表示最大长度1024DW,实际可以发出的最大长度由MPS和MRRS控制。在RX方向,需结合地址信号,将报文切分为多个操作再发送至系统,对于读报文还需考虑如何生成CPL;在TX方向,对于大块数据搬运,尽可能按128或256Byte地址对齐的方式进行切分,而不是仅仅根据MPS/MRRS进行处理。 - Requester ID
发出该请求的设备的BDF。在PCIe系统内,每一个设备均有其特有的BDF Number,发出请求时均需携带该BDF作为Requester ID。基于SR-IOV,一个物理设备可以虚拟化为多个虚拟设备,每个虚拟设备均有其特有的BDF。若Host侧开启虚拟化之后,设备使用的可能是虚拟地址,而该ID是作为转换地址逻辑的输入。 - PASID Prefix
PASID,Process Address Space ID,与Requester ID共同定义了当前操作所属的地址域,且该地址域可与Host侧的用户进程共享,再依托于IOMMU/SMMU,实现用户进程与硬件进行直接交互。Intel的Scalable IOV有关于PASID的详细描述,个人感觉基于SIOV实现虚拟化比SR-IOV高效得多,SR-IOV应该被淘汰。但是,当前的设备基本不支持PASID,均是基于SRIOV提供虚拟化支持。 - Last BE/First BE
指示请求的第一个DW和最后一个DW的有效数据。若请求长度非1DW或2DW,该请求必须是连续的访问请求,不支持空洞存在。将AXI写操作转换为TLP报文,需检查其wstrb信号,若存在空洞的情况,需切分为多个操作进行处理。对于1dw或2dw且地址对齐的,允许存在非连续的访问。对于读请求,该域段可用于指示TPH的ST。 - Address
报文请求的地址信号,支持32bit和64bit两种格式,注意低2bit需基于First BE确定。个人感觉该信号是TLP最难分析的,主要是需识别该信号属于哪一个地址域,使用的是物理地址还是虚拟地址,又是如何支持设备虚拟化的,EP模式为何需要Address Translation。
03 小结
以上对TLP报文各个域段做了简介,实际上很多域段都可以扩展描述,涉及内容较多,后续再逐步展开描述。
- End -
作者:芯工阿文
原文链接:芯工阿文
推荐阅读
更多IC设计技术干货请关注IC设计技术专栏。