5.3 存储器、I/O和配置读写请求TLP

本节讲述PCIe总线定义的各类TLP,并详细介绍这些TLP的格式。在这些TLP中,有些格式对于初学者来说较难理解。读者需要建立PCIe总线中与TLP相关的一些基本概念,特别是存储器读写相关的报文格式。在PCIe总线中,存储器读写,I/O读写和配置读写请求TLP由以下几类报文组成。

(1)      存储器读请求TLP和读完成TLP

当PCIe主设备,RC或者EP,访问目标设备的存储器空间时,使用Non-Posted总线事务向目标设备发出存储器读请求TLP,目标设备收到这个存储器读请求TLP后,使用存储器读完成TLP,主动向主设备传递数据。当主设备收到目标设备的存储器读完成TLP后,将完成一次存储器读操作。

(2)      存储器写请求TLP

在PCIe总线中,存储器写使用Posted总线事务。PCIe主设备仅使用存储器写请求TLP即可完成存储器写操作,主设备不需要目标设备的回应报文。

(3)      原子操作请求和完成报文

原子操作由PCIe V2.1总线规范引入,一个完整的原子操作包括原子操作请求和原子操作完成报文组成。原子操作的使用方法与其他Non-Posted总线事务类似,首先PCIe主设备向目标设备发送原子操作请求,之后目标设备向主设备发送原子操作完成报文,结束一次原子操作。有关原子操作的详细说明见第5.3.5节。

(4)      I/O读写请求TLP和读写完成TLP

在PCIe总线中,I/O读写操作使用Non-Posted总线事务,I/O读写TLP都需要完成报文做为回应。只是在I/O写请求的完成报文中不需要“带数据”,而仅含有I/O写请求是否成功的状态信息。

(5)      配置读写请求TLP和配置读写完成TLP

从总线事务的角度上看,配置读写请求操作的过程与I/O读写操作的过程类似。配置读写请求TLP都需要配置读写完成作为应答,从而完成一个完成的配置读写操作。

(6)      消息报文

与PCI总线相比,PCIe总线增加了消息请求事务。PCIe总线使用基于报文的数据传送模式,所有总线事务都是通过报文实现的,PCIe总线取消了一些在PCI总线中存在的边带信号。在PCIe总线中,一些由PCI总线的边带信号完成的工作,如中断请求和电源管理等,在PCIe总线中由消息请求报文实现。

5.3.1 存储器读写请求TLP

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

5.3 存储器、I/O和配置读写请求TLP

在PCIe总线中,存储器写请求TLP使用Posted数据传送方式。而其他与存储器和I/O相关的报文都使用Split方式进行数据传送,这些请求报文需要完成报文,通知发送端之前的数据请求报文已经被处理完毕,有关完成报文的详细说明见第5.3.2节。

存储器读写请求TLP使用地址路由方式进行数据传递,在这类TLP头中包含Address字段,Address字段具有两种地址格式,分别是32位和64位地址。在存储器读写和I/O读写请求的第3和第4个双字中,存放TLP的32或者64位地址。存储器、I/O和原子操作读写请求使用的TLP头较为类似。本节仅介绍存储器、I/O读写使用的TLP头,而在第5.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第一个双字的字节使能位。其对应关系如表5?5所示。

5?5 First和Last DW BE字段

Last DW BE

第3位

为1表示数据Payload的最后一个双字的字节3有效

第2位

为1表示数据Payload的最后一个双字的字节2有效

第1位

为1表示数据Payload的最后一个双字的字节1有效

第0位

为1表示数据Payload的最后一个双字的字节0有效

First DW BE

第3位

为1表示数据Payload的第一个双字的字节3有效

第2位

为1表示数据Payload的第一个双字的字节2有效

第1位

为1表示数据Payload的第一个双字的字节1有效

第0位

为1表示数据Payload的第一个双字的字节0有效

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方式进行存储器写时,目标设备不需要向主设备发送回应报文,因此主设备并不知道这个存储器写是否已经达到目的地。而主设备可以使用“读刷新”操作,向目标设备进行读操作来保证存储器写最终到达目的地。

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

3 Requester ID字段

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

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

对于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字段的格式如图5?9所示。存储器读,I/O和配置读写请求TLP使用Transaction字段的主要目的是使接收端通过分析报文的Transaction ID,确认完成报文的目的地。

5.3 存储器、I/O和配置读写请求TLP

在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位,Tag字段可以由8位组成,此时发送端能够暂存256个报文。

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

PCIe设备在PCI Express Capability结构的Device Control寄存器中,设置了一个Phantom Functions Enable位,。当一个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接收这些报文,以充分利用报文接收流水线,。

PCIe V2.1总线规范还提出了另一种Requester ID格式,即ARI (Alternative Routing-ID Interpretation)格式,除了Requester ID外,在完成报文中使用的Completer ID也可以使用这种格式。ARI格式将ID号分为两个字段,分别为Bus号和Function号,而不使用Device号,ARI格式如图5?10所示。

5.3 存储器、I/O和配置读写请求TLP

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]为“0b00 0000 0001”,表示I/O读写请求TLP最大的数据Payload为1DW,该类TLP不支持突发传送。
  • Last DW[3:0]为“0b0000”。

5.3.2 完成报文

PCIe总线支持Split传送方式,目标设备使用完成报文向源设备主动发送数据。完成报文使用ID路由方式,由TLP Predix、报文头和Data Payload组成,但是在某些完成报文可以不含有Data Payload,如I/O或者配置写完成和Zero-Length读完成报文。在PCIe总线中,有一下几类数据请求需要收到完成报文之后,才能完成整个数据传送过程,完成报文格式如图5?11所示。

  • 所有的数据读请求,包括存储器、I/O读请求、配置读请求和原子操作请求。当一个PCIe设备发出这些数据请求报文后,必须收到目标设备的完成报文后,才能结束一次数据传送。这一类完成报文必须包含Data Payload。
  • 所有的Non-Posted数据写请求,包括I/O和配置写请求。当一个PCIe设备发出这些数据请求报文后,必须收到目标设备的完成报文后,才能结束数据传送。但是这一类完成报文不包含数据,仅包含应答信息。
  • 与ATS机制相关的一些报文。
5.3 存储器、I/O和配置读写请求TLP

完成报文“Byte 0”中的大部分字段与“存储器,I/O、配置请求报文”的对应字段的含义相同。完成报文一次最多能够传送的报文大小不能超过Max_Payload_Size参数。在多数处理器中,完成报文中包含的数据在一个Cache行之内,完成报文使用RCB参数来处理数据对界,RCB参数的大小与处理器系统的Cache行长度和DDR-SDRAM的一次突发传送长度相关,这些参数的详细描述见第5.4.3节。在x86和PowerPC处理器中,一个存储器读完成报文一般不超过RCB参数。

1 Requester ID和Tag字段

完成报文使用ID路由方式,ID路由方式详见第5.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字段。

2 Completer ID字段

Completer ID字段的含义与Requester ID字段较为相似,只是该字段存放“发送完成报文”的PCIe设备的ID号。PCIe设备进行数据请求时需要在TLP字段中包含Requester ID字段;而使用完成报文结束数据请求时,需要提供Completer ID字段。

3 Status字段

Status字段保存当前完成报文的完成状态,表示当前TLP是正确地将数据传递给数据请求端;还是在数据传递过程中出现错误;或者要求数据请求方进行重试。PCIe总线规定了几类完成状态,如表5?6所示。

5?6 Status字段

Status[2:0]

描述

0b000

SC(Sucessful Completion),正常结束

0b001

UR(Unsupported Request),不支持的数据请求

0b010

CRS(Configuration Request Retry Status),要求数据请求方进行重试。当RC对一个PCIe目标设备发起配置请求时,如果该目标设备没有准备好,可以向RC发出CRS完成报文,当RC收到这类报文时,不能结束本次配置请求,必须择时重新发送配置请求

0b100

CA(Completion Abort),数据夭折。表示目标设备无法完成本次数据请求

其他

保留

4 BCM位与Byte Count字段

BCM(Byte Count Modified)字段由PCI-X设备设置。PCI-X设备也支持Split Transaction传送方式,当PCI-X设备进行存储器读请求时,目标设备不一定一次就能将所有数据传递给源设备。此时目标设备在进行第一次数据传送时,需要设置Byte Count字段和BCM位。

BCM位表示Byte Count字段是否被更改,该位仅对PCI-X设备有效,而PCIe设备不能操纵BCM位,只有PCI-X设备或者PCIe-to-PCI-X桥可以改变该位。本节对此位不做进一步介绍,对此位感兴趣的读者可以参考PCI-X Addendum to the PCI Local Bus Specification, Revision 2.0。

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的有效数据为64B,而Byte Count字段为128;第2个存储器读完成TLP中的有效数据为64B,而Byte Count字段也为64。当数据请求端接收完毕第1个存储器读完成TLP后,发现还有64B的数据没有接收完毕,此时必须等待下一个存储器读完成TLP。等到数据请求端收齐所有数据后,才能结束整个存储器读请求。

目标设备发出的第2个读完成TLP中的有效数据为64B,而Byte Count字段为64,当数据请求端接收完毕这个读完成TLP后,将完成一个完整的存储器读过程,从而可以释放这个存储器读过程使用的Tag资源。存储器读请求的完成报文的拆分方式较为复杂,Byte Count字段的设置也相对较为复杂。

5 Lower Address字段

如果当前完成报文为存储器读完成TLP,该字段存放在存储器读完成TLP中第一个数据所对应地址的最低位。值得注意的是,在完成报文中,并不存在First DW BE和Last DW BE字段,因此接收端必须使用存储器读完成TLP的Low Address字段,识别一个TLP中包含数据的起始地址。

5.3.3 配置读写请求TLP

配置读写请求TLP由RC发起,用来访问PCIe设备的配置空间。配置请求报文使用基于ID的路由方式。PCIe总线也支持两种配置请求报文,分别为Type 00h和Type 01h配置请求。配置请求TLP的格式如图5?12所示。

5.3 存储器、I/O和配置读写请求TLP

配置请求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字段根据配置读写请求的大小设置。

5.3.4 消息请求报文

在PCIe总线中,多数消息报文使用隐式路由方式,其格式如图5?13所示。其中Byte 0字段为通用TLP头,而Byte 4的第3字节中存放Message Code字段。

5.3 存储器、I/O和配置读写请求TLP

PCIe总线规定了以下几类消息报文。

  • INTx中断消息报文(INTx Interrupt Signaling)。
  • 电源管理消息报文(Power Management)。
  • 错误消息报文(Error Signaling)。
  • 锁定事务消息报文(Locked Transaction Support)。
  • 插槽电源限制消息报文(Slot Power Limit Support)。
  • Vendor-Defined Messages。
上一篇:海思hi3518 opencv测试


下一篇:useful urls