5.3 存储器、I/O和配置读写请求TLP 分类: 浅谈PCI-E 2013-07-22 16:28 413人阅读 评论(0) 收藏

本节讲述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个双字中,存放TLP32或者64位地址。存储器、I/O和原子操作读写请求使用的TLP头较为类似。本节仅介绍存储器、I/O读写使用的TLP头,而在第5.3.5节详细介绍原子操作。

1 Length字段

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

Length字段的最小单位为DW。当该字段为n时,表示需要获得的数据长度或者当前报文的数据长度为nDW,其中0?n?0x3FF。值得注意的是,当n等于0时,表示数据长度为1024DW

2 DW BE字段

PCIe总线以字节为基本单位进行数据传递,但是Length字段以DW为最小单位。为此TLP使用Last DW BEFirst DW BE这两个字段进行字节使能,使得在一个TLP中,有效数据以字节为单位。

这两个DW BE字段各由4位组成,其中Last DW BE字段的每一位对应数据Payload最后一个双字的字节使能位;而First DW BE字段的每一位对应数据Payload第一个双字的字节使能位。其对应关系如5?5所示。

5?5 FirstLast 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 BEFirst DW BE这两个字段的使用规则如下。

  • 如果传送的数据长度在一个对界的双字(DW)之内,则Last DW BE字段为0b0000,而First DW BE的对应位置1;如果数据长度超过1DWLast DW BE字段一定不能为0b0000PCIe总线使用Last DW BE字段为0b0000表示所传送的数据在一个对界的DW之内。
  • 如果传送的数据长度超过1DW,则First DW BE字段至少有一个位使能。不能出现First DW BE0b0000的情况。
  • 如果传送的数据长度大于等于3DW,则在First DW BELast DW BE字段中不能出现不连续的置1位。
  • 如果传送的数据长度在1DW之内时,在First DW BE字段中允许有不连续的置1位。此时PCIe总线允许在TLP中传送1DW的第13字节或者第02字节。
  • 如果传送的数据长度为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表示需要获得的数据长度为1024DW

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所示。对于存储器写请求TLPRequester ID字段并不是必须的,因为目标设备收到存储器写请求TLP后,不需要完成报文作为应答,因此Requester ID字段对于存储器写请求TLP并没有实际意义。

但是PCIe总线规范并没有明确说明存储器写请求TLP究竟需不需要Requester ID字段,为此IC设计者依然需要将存储器写TLPRequester 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 IDTag字段。在PCIe总线中Requester IDTag字段合称为Transaction IDTransaction 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设备可能只包含1Function。因此PCIe设备还可以使用Function号扩展Tag字段,从而扩展“暂存TLP报文”的数目。

PCIe设备在PCI Express Capability结构的Device Control寄存器中,设置了一个Phantom Functions Enable位,。当一个PCIe设备仅支持一个Function时,Phantom Functions Enable位可以被设置为1,此时PCIe设备可以使用Requester IDFunction 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 IDCompletion ID包含的Device号是没有意义的。使用ARI格式时,一个PCIe设备最多可以支持256Function,而传统的PCIe设备最多只能支持8Function

4 I/O读写请求TLP的规则

I/O读写请求与存储器读写请求TLP的格式基本类似,只是I/O读写请求TLP只能使用32位地址模式和基于地址的路由方式,而且I/O读写请求TLP只能使用Non-Posted方式进行传递。PCIe总线并不建议PCIe设备支持I/O地址空间,但是SwitchRC需要具备接收和发送I/O请求报文的能力,因为许多老的PCI设备依然使用I/O地址空间,这些PCI设备可以通过PCIe桥连接到PCIe总线中。因此虽然支持I/O读写请求的PCIe设备极少,但是在PCIe体系结构中,依然需要支持PCI总线域的I/O地址空间。

与存储器读写请求TLP不同,I/O读写请求TLP的某些字段必须为以下值。

  • TC[2:0]必须为0I/O请求报文使用的TC标签只能为0
  • THAttr2位保留,而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最大的数据Payload1DW,该类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节。在x86PowerPC处理器中,一个存储器读完成报文一般不超过RCB参数。

1 Requester IDTag字段

完成报文使用ID路由方式,ID路由方式详见第5.2.2节。完成报文头的长度为3DW,完成报文头中包含Transaction ID信息,由Requester IDTag字段组成,这个ID必须与源设备发送的数据请求报文的Transaction ID对应,完成报文使用Transaction ID进行ID路由,并将数据发送给源设备。

PCIe设备收到存储器读、I/O读写或者配置读写请求TLP时,需要首先保存这些报文的Transaction ID,之后当该设备准备好完成报文后,将完成报文的Requester IDTag字段赋值为之前保存的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 BELast DW BE字段,因此接收端必须使用存储器读完成TLPLow Address字段,识别一个TLP中包含数据的起始地址。

5.3.3 配置读写请求TLP

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

5.3 存储器、I/O和配置读写请求TLP - 毛毛虫 - 毛毛虫的刻薄

配置请求TLP的第4~7字节与存储器请求TLP类似。而第8~11字节的BusDeviceFunction Number中存放该TLP访问的目标设备的相应的号码,而Ext RegisterReigister Number存放寄存器号。配置请求报文的其他字段必须为以下值。

  • TC[2:0]必须为0I/O请求报文的传送类型(TC)只能为0
  • TH位为保留位;Attr2位为保留,而Attr[1:0]必须为“00b”,这表示I/O请求报文使用PCI总线的强序数据传送模式;AT[1:0]必须为“0b00”,表示不进行地址转换。
  • Length[9:0]为“0b00 0000 0001”,表示配置读写请求最大Payload1DW
  • 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

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2013-07-22 16:28  毛毛虫的薄刻  阅读(1154)  评论(0编辑  收藏  举报