首页 理论教育PCIExpress体系结构导读|存储器读写请求TLP解析

PCIExpress体系结构导读|存储器读写请求TLP解析

【摘要】:存储器读写请求TLP的格式如图6-8所示。在存储器读写和I/O读写请求的第3和第4个双字中,存放TLP的32或者64位地址。存储器、I/O和原子操作读写请求使用的TLP头较为类似。此时与这个存储器读请求TLP对应的读完成TLP中不包含有效数据。

存储器读写请求TLP的格式如图6-8所示。

978-7-111-29822-9-Part02-58.jpg

图6-8 存储器和I/O读写请求TLP头格式

在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节详细介绍原子操作。

1.Length字段

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

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第一个双字的字节使能位。其对应关系如表6-5所示。

表6-5 First和Last DW BE字段

978-7-111-29822-9-Part02-59.jpg

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章。

在PCIe总线中,标准的存储器读请求也可以完成同样的刷新操作。但是“Zero-Length”读请求与这种读请求相比,其完成报文不需要“Data Payload”,因此在一定程度上提高了PCIe总线的效率。如果一个存储器读请求TLP报文的TH位为1时,DW BE字段将被重新定义为ST[7∶0]字段,有关ST字段的详细说明见第6.3.6节。

3.Requester ID字段

Requester ID字段包含“生成这个TLP报文”的PCIe设备的总线号(Bus Number)、设备号(Device Number)和功能号(Function Number),其格式如图6-9所示。对于存储器写请求TLP,Requester ID字段并不是必须的,因为目标设备收到存储器写请求TLP后,不需要完成报文作为应答,因此Requester ID字段对于存储器写请求TLP并没有实际意义。

但是PCIe总线规范并没有明确说明存储器写请求TLP究竟需不需要Requester ID字段,为此IC设计者依然需要将存储器写TLP的Requester ID字段置为有效。值得注意的是,如果一个存储器写请求TLP报文的TH位为1时,Tag字段将被重新定义为ST[7∶0]字段,有关ST字段的详细说明见第6.3.6节。(www.chuimin.cn)

对于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,确认完成报文的目的地。

978-7-111-29822-9-Part02-60.jpg

图6-9 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个报文。

通过Tag字段的长度,可以发现每个PCIe设备最多可以暂存256个同类型的Non-Posted报文。但是在多数情况下,一个PCIe设备可能只包含1个Function。因此PCIe设备还可以使用Function号扩展Tag字段,从而扩展“暂存TLP报文”的数目。

PCIe设备在PCI Express Capability结构的Device Control寄存器中,设置了一个Phantom Functions Enable位,该位的详细说明见第4.3.2节。当一个PCIe设备仅支持一个Function时,Phantom Functions Enable位可以被设置为1,此时PCIe设备可以使用Requester ID的Function Number字段对Tag字段进一步扩展,此时一个PCIe设备最多可以支持2048个同类型的数据请求。

由以上分析可以发现,一个PCIe设备最多可以支持2048个存储器读数据请求,基本上可以满足绝大多数需要。但是在某些特殊应用场合,PCIe设备即使可以暂存2048个存储器读请求,也并不足够。

与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所示。

978-7-111-29822-9-Part02-61.jpg

图6-10 ARI格式

PCIe总线引入ARI格式的依据是在一个PCIe链路上仅可能存在一个PCIe设备,因而其Device号一定为0。在多数PCIe设备中,Requester ID和Completion ID包含的Device号是没有意义的。使用ARI格式时,一个PCIe设备最多可以支持256个Function,而传统的PCIe设备最多只能支持8个Function。

4.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]为“0b0000000001”,表示I/O读写请求TLP最大的数据Payload为1DW,该类TLP不支持突发传送。

●Last DW[3∶0]为“0b0000”。