PCI/PCIe 总线概述(5)—PCIe总线事务层

第5章 PCIe总线的事务层

(2011-08-08 16:19:57)

标签:

杂谈

分类: 浅谈PCIe体系结构

事务层是PCIe总线层次结构的最高层,该层次将接收PCIe设备核心层的数据请求,并将其转换为PCIe总线事务,PCIe总线使用的这些总线事务在TLP头中定义。PCIe总线继承了PCI/PCI-X总线的大多数总线事务,如存储器读写、I/O读写、配置读写总线事务,并增加了Message总线事务和原子操作等总线事务。

本节重点介绍与数据传送密切相关的总线事务,如存储器、I/O、配置读写总线事务。在PCIe总线中,Non-Posted总线事务分两部分进行,首先是发送端向接收端提交总线读写请求,之后接收端再向发送端发送完成(Completion)报文。PCIe总线使用Split传送方式处理所有Non-Posted总线事务,存储器读、I/O读写和配置读写这些Non-Posted总线事务都使用Split传送方式。PCIe的事务层还支持流量控制和虚通路管理等一系列特性,而PCI总线并不支持这些新的特性。

PCIe总线中,不同的总线事务采用的路由方式不相同。PCIe总线继承了PCI总线的地址路由和ID路由方式,并添加了“隐式路由”方式。

PCIe总线使用的数据报文首先在事务层中形成,这个数据报文也被称之为事务层数据报文,即TLPTLP在经过数据链路层时被加上Sequence Number前缀和CRC后缀,然后发向物理层。

数据链路层还可以产生DLLP(Data Link Layer Packet)DLLPTLP没有直接关系,DLLP是产生于数据链路层,终止于数据链路层,并不会传递到事务层。DLLP不是TLP加上前缀和后缀形成的。数据链路层的报文DLLP通过物理层时,需要经过8/10b编码,然后再进行发送。数据的接收过程是发送过程的逆过程,但是在具体实现上,接收过程与发送过程并不完全相同。

5.1 TLP的格式

(2011-08-08 16:21:32)

标签:

杂谈

分类: 浅谈PCIe体系结构

当处理器或者其他PCIe设备访问PCIe设备时,所传送的数据报文首先通过事务层被封装为一个或者多个TLP,之后才能通过PCIe总线的各个层次发送出去。TLP的基本格式如图5‑1所示。

6472c4ccgac8158de66e2&690

一个完整的TLP1个或者多个TLP PrefixTLP头、Data Payload(数据有效负载)TLP Digest组成。TLP头是TLP最重要的标志,不同的TLP其头的定义并不相同。TLP头包含了当前TLP的总线事务类型、路由信息等一系列信息。在一个TLP中,Data Payload的长度可变,最小为0,最大为1024DW

TLP Digest是一个可选项, 一个TLP是否需要TLP DigestTLP头决定。Data Payload也是一个可选项,有些TLP并不需要Data Payload,如存储器读请求、配置和I/O写完成TLP并不需要Data Payload

TLP PrefixPCIe V2.1总线规范引入,分为Local TLP PrefixEP-EP TLP Prefix两类。其中Local TLP Prefix的主要作用是在PCIe链路的两端传递消息,而EP-EP TLP Prefix的主要作用是在发送设备和接收设备之间传递消息。设置TLP Prefix的主要目的是为了扩展TLP头,并以此支持PCIe V2.1规范的一些新的功能。

TLP头由3个或者4个双字(DW)组成。其中第一个双字中保存通用TLP头,其他字段与通用TLP头的Type字段相关。一个通用TLP头由FmtTypeTCLength等字段组成,如图5‑2所示。

6472c4ccgac815e9bdd85&690

如果存储器读写TLP支持64位地址模式时,TLP头的长度为4DW,否则为3DW。而完成报文的TLP头不含有地址信息,使用的TLP头长度为3DW。其中Byte 4~Byte 15的格式与TLP相关,下文将结合具体的TLP介绍这些字段。

5.1.1 通用TLP头的Fmt字段和Type字段

FmtType字段确认当前TLP使用的总线事务,TLP头的大小是由3个双字还是4个双字组成,当前TLP是否包含有效负载。其具体含义如表5‑1所示。

 51 Fmt[1:0]字段

Fmt[2:0]

TLP的格式

0b000

TLP大小为3个双字,不带数据。

0b001

TLP大小为4个双字,不带数据。

0b010

TLP大小为3个双字,带数据。

0b011

TLP大小为4个双字,带数据。

0b100

TLP Prefix

其他

PCIe总线保留

 其中所有读请求TLP都不带数据,而写请求TLP带数据,而其他TLP可能带数据也可能不带数据,如完成报文可能含有数据,也可能仅含有完成标志而并不携带数据。在TLPType字段中存放TLP的类型,即PCIe总线支持的总线事务。该字段共由5位组成,其含义如表5‑2所示。

52 Type[4:0]字段

TLP类型 Fmt[2:0] Type[4:0] 描述
MRd 0b000

0b001

0b0 0000 存储器读请求;TLP头大小为3个或者4个双字,不带数据。
MRdLk 0b000

0b001

0b0 0001 带锁的存储器读请求;TLP头大小为3个或者4个双字,不带数据。
MWr 0b010

0b011

0b0 0000 存储器写请求;TLP头大小为3个或者4个双字,带数据。
IORd 0b000 0b0 0010 IO读请求;TLP头大小为3个双字,不带数据。
IOWr 0b010 0b0 0010 IO写请求;TLP头大小为3个双字,带数据。
CfgRd0 0b000 0b0 0100 配置0读请求;TLP头大小为3个双字,不带数据。
CfgWr0 0b010 0b0 0100 配置0写请求;TLP头大小为3个双字,带数据。
CfgRd1 0b000 0b0 0101 配置1读请求;不带数据。
CfgWr1 0b010 0b0 0101 配置1写请求;带数据。
TCfgRd 0b010 0b1 1011 本书对这两种总线事务不做介绍。
TCfgWr 0b001 0b1 1011
Msg 0b001 0b1 0r2r1r0 消息请求;TLP头大小为4个双字,不带数据。“rrr”字段是消息请求报文的Route字段,下文将详细介绍该字段。
MsgD 0b011 0b1 0r2r1r0 消息请求;TLP头大小为4个双字,带数据。
Cpl 0b000 0b0 1010 完成报文;TLP头大小为3个双字,不带数据。包括存储器、配置和I/O写完成。
CplD 0b010 0b0 1010 带数据的完成报文,TLP头大小为3个双字,包括存储器读、I/O读、配置读和原子操作读完成。
CplLk 0b000 0b0 1011 锁定的完成报文,TLP头大小为3个双字,不带数据。
CplDLk 0b010 0b0 1011 带数据的锁定完成报文,TLP头大小为3个双字,带数据。
FetchAdd 0b010

0b011

0b0 1100 Fetch and Add原子操作。
Swap 0b010

0b011

0b0 1101 Swap原子操作。
CAS 0b010

0b011

0b0 1110 CAS原子操作。
LPrfx 0b100 0b0 L3L2L1L0 Local TLP Prefix
EPrfx 0b100 0b1 E3E2E1E0 End-End TLP Prefix

由上表所示,存储器读和写请求,IO读和写请求,及配置读和写请求的type字段相同,如存储器读和写请求的Type字段都为0b0 0000。此时PCIe总线规范使用Fmt字段区分读写请求,当Fmt字段是“带数据”的报文,一定是“写报文”;当Fmt字段是“不带数据”的报文,一定是“读报文”。

PCIe总线的数据报文传送方式与PCI总线数据传送有类似之处。其中存储器写TLP使用Posted方式进行传送,而其他总线事务使用Non-Posted方式。

PCIe总线规定所有Non-Posted存储器请求使用Split总线方式进行数据传递。当PCIe设备进行存储器读、I/O读写或者配置读写请求时,首先向目标设备发送数据读写请求TLP,当目标设备收到这些读写请求TLP后,将数据和完成信息通过完成报文(Cpl或者CplD)发送给源设备。

其中存储器读、I/O读和配置读需要使用CplD报文,因为目标设备需要将数据传递给源设备;而I/O写和配置写需要使用Cpl报文,因为目标设备不需要将任何数据传递给源设备,但是需要通知源设备,写操作已经完成,数据已经成功地传递给目标设备。

PCIe总线中,进行存储器或者I/O写操作时,数据与数据包头一起传递;而进行存储器或者I/O读操作时,源设备首先向目标设备发送读请求TLP,而目标设备在准备好数据后,向源设备发出完成报文。

PCIe总线规范还定义了MRdLk报文,该报文的主要作用是与PCI总线的锁操作相兼容,但是PCIe总线规范并不建议用户使用这种功能,因为使用这种功能将极大影响PCIe总线的数据传送效率。

PCI总线并不相同,PCIe总线规范定义了Msg报文,即消息报文。分别为MsgMsgD,这两种报文的区别在于一个报文可以传递数据,一个不能传递数据。

PCIe V2.1总线规范还补充了一些总线事务,如FetchAddSwapCASLPrfxEPrfx。其中LPrfxEPrfx总线事务分别与Local TLP PrefixEP-EP TLP Prefix对应。在PCIe总线规范V2.0中,TLP头的大小为1DW,而使用LPrfxEPrfx总线事务可以对TLP头进行扩展,本节不对这些TLP Prefix做进一步介绍。PCIe设备可以使用FetchAddSwapCAS总线事务进行原子操作,本篇将在第5.3.5节详细介绍该类总线事务。

5.1.2 TC字段

TC字段表示当前TLP的传送类型,PCIe总线规定了8种传输类型,分别为TC0TC7,缺省值为TC0,该字段与PCIeQoS相关。PCIe设备使用TC区分不同类型的数据传递,而多数EP中只含有一个VC,因此这些EP在发送TLP时,也仅仅使用TC0,但是有些对实时性要求较高的EP中,含有可以设置TC字段的寄存器。

Intel的高精度声卡控制器(High Definition Audio Controller)的扩展配置空间中含有一个TCSEL寄存器。系统软件可以设置该寄存器,使声卡控制器发出的TLP使用合适的TC。声卡控制器可以使用TC7传送一些对实时性要求较强的控制信息,而使用TC0传送一般的数据信息。在具体实现中,一个EP也可以将控制TC字段的寄存器放入到设备的BAR空间中,而不必和Intel的高精度声卡控制器相同,存放在PCI配置空间中。

目前许多处理器系统的RC仅支持一个VC通路,此时EP使用不同的TC进行传递数据的意义不大。x86处理器的MCH中一般支持两个VC通路,而多数PowerPC处理器仅支持一个VC通路。PLX公司的多数Switch也仅支持两个VC通路。

有些RC,如MPC8572处理器,也能决定其发出TLP使用的TC。在该处理器的PCIe Outbound窗口寄存器(PEXOWARn)中,含有一个TC字段,通过设置该字段可以确定RC发出的TLP使用的TC字段。不同的TC可以使用PCIe链路中的不同VC,而不同的VC的仲裁级别并不相同。EP或者RC通过调整其发出TLPTC字段,可以调整TLP使用的VC,从而调整TLP的优先级。

5.1.3 Attr字段

Attr字段由3位组成,其中第2位表示该TLP是否支持PCIe总线的ID-based Ordering;第1位表示是否支持Relaxed Ordering;而第0位表示该TLP在经过RC到达存储器时,是否需要进行Cache共享一致性处理。Attr字段如图5‑3所示。

6472c4ccgac8166b7d08f&690

一个TLP可以同时支持ID-based OrderingRelaxed Ordering两种位序。Relaxed Ordering最早在PCI-X总线规范中提出,用来提高PCI-X总线的数据传送效率;而ID-based OrderingPCIe V2.1总线规范提出。TLP支持的序如表5‑3所示。

 53 TLP支持的序

Attr[2]

Attr[1]

类型

0

0

缺省序,即强序模型

0

1

PCI-X Relaxed Ordering模型

1

0

ID-Based Ordering(IDO)模型

1

1

同时支持Relaxed OrderingIDO模型

 当使用标准的强序模型时,在数据的整个传送路径中,PCIe设备在处理相同类型的TLP时,如PCIe设备发送两个存储器写TLP时,后面的存储器写TLP必须等待前一个存储器写TLP完成后才能被处理,即便当前报文在传送过程中被阻塞,后一个报文也必须等待。

如果使用Relaxed Ordering模型,后一个存储器写TLP可以穿越前一个存储器写TLP,提前执行,从而提高了PCIe总线的利用率。有时一个PCIe设备发出的TLP,其目的地址并不相同,可能先进入发送队列的TLP,在某种情况下无法发送,但这并不影响后续TLP的发送,因为这两个TLP的目的地址并不相同,发送条件也并不相同。

值得注意的是,在使用PCI总线强序模型时,不同种类的TLP间也可以乱序通过同一条PCIe链路,比如存储器写TLP可以超越存储器读请求TLP提前进行。而PCIe总线支持Relaxed Ordering模型之后,在TLP的传递过程中出现乱序种类更多,但是这些乱序仍然是有条件限制的。在PCIe总线规范中为了避免死锁,还规定了不同报文的传送数据规则,即Ordering Rules

PCIe V2.1总线规范引入了一种新的“序”模型,即IDO(ID-Based Ordering)模型,IDO模型与数据传送的数据流相关,是PCIe V2.1规范引入的序模型。

Attr字段的第0位是“No Snoop Attribute”位。当该位为0时表示当前TLP所传送的数据在通过FSB时,需要与Cache保持一致,这种一致性由FSB通过总线监听自动完成而不需要软件干预;如果为1,表示FSB并不会将TLP中的数据与Cache进行一致,在这种情况下,进行数据传送时,必须使用软件保证Cache的一致性。

PCI总线中没有与这个“No Snoop Attribute”位对应的概念,因此一个PCI设备对存储器进行DMA操作时会进行Cache一致性操作[1]。这种“自动的”Cache一致性行为在某些特殊情况下并不能带来更高的效率。

当一个PCIe设备对存储器进行DMA读操作时,如果传送的数据非常大,比如512MBCache的一致性操作不但不会提高DMA写的效率,反而会降低。因为这个DMA读访问的数据在绝大多数情况下,并不会在Cache中命中,但是FSB依然需要使用Snoop Phase进行总线监听。而处理器在进行Cache一致性操作时仍然需要占用一定的时钟周期,即在Snoop Phase中占用的时钟周期,Snoop PhaseFSB总线事务的一个阶段,如图3‑6所示。

对于这类情况,一个较好的做法是,首先使用软件指令保证Cache与主存储器的一致性,并置“No Snoop Attribute”位为1[2],然后再进行DMA读操作。同理使用这种方法对一段较大的数据区域进行DMA写时,也可以提高效率。

除此之外,当PCIe设备访问的存储器,不是“可Cache空间”时,也可以通过设置“No Snoop Attribute”位,避免FSBCache共享一致性操作,从而提高FSB的效率。“No Snoop Attribute”位是PCIe总线针对PCI总线的不足,所作出的重要改动。

5.1.4 通用TLP头中的其他字段

除了FmtType字段外,通用TLP头还含有以下字段。

1 TH位、TD位和EP

TH位为1表示当前TLP中含有TPH(TLP Processing Hint)信息,TPHPCIe V2.1总线规范引入的一个重要功能。TLP的发送端可以使用TPH信息,通知接收端即将访问数据的特性,以便接收端合理地预读和管理数据,TPH的详细介绍见第5.3.6节。

TD位表示TLP中的TLP Digest是否有效,为1表示有效,为0表示无效。而EP位表示当前TLP中的数据是否有效,为1表示无效,为0表示有效。

2 AT字段

AT字段与PCIe总线的地址转换相关。在一些PCIe设备中设置了ATC(Address Translation Cache)部件,这个部件的主要功能是进行地址转换。只有在支持IOMMU技术的处理器系统中,PCIe设备才能使用该字段。

AT字段可以用作存储器域与PCI总线域之间的地址转换,但是设置这个字段的主要目的是为了方便多个虚拟主机共享同一个PCIe设备。对这个字段有兴趣的读者可以参考Address Translation Sevices规范,这个规范是PCIIO Virtualization规范的重要组成部分。对虚拟化技术有兴趣的读者可以参考清华大学出版社的《系统虚拟化——原理与实现》,以获得基本的关于虚拟化的入门知识。

3 Length字段

Length字段用来描述TLP的有效负载(Data Payload)大小[3]PCIe总线规范规定一个TLPData Payload的大小在1B4096B之间。PCIe总线设置Length字段的目的是提高总线的传送效率。

PCI设备在进行数据传送时,其目标设备并不知道实际的数据传送大小,这在一定程度上影响了PCI总线的数据传送效率。而在PCIe总线中,目标设备可以通过Length字段提前获知源设备需要发送或者请求的数据长度,从而合理地管理接收缓冲,并根据实际情况进行Cache一致性操作。

PCI设备进行DMA写操作,将PCI设备中4KB大小的数据传送到主存储器时,这个PCI设备的DMA控制器将存放传送的目的地址和传送大小,然后启动DMA写操作,将数据写入到主存储器。由于PCI总线是一条共享总线,因此传送4KB大小的数据,可能会使用若干个PCI总线写事务才能完成[4],而每一个PCI总线写事务都不知道DMA控制器何时才能将数据传送完毕。

如果这些总线写事务还通过一系列PCI桥才能到达存储器,在这个路径上的每一个PCI桥也无法预知,何时这个DMA操作才能结束。这种“不可预知”将导致PCI总线的带宽不能被充分利用,而且极易造成PCI桥数据缓冲的浪费。

PCIe总线通过TLPLength字段,可以有效避免PCIe链路带宽的浪费。值得注意的是,Length字段以DW为单位,其最小单位为1DW。如果PCIe主设备传送的单位小于1DW或者传送的数据并不以DW对界时,需要使用字节使能字段,即“DW BE”字段。有关“DW BE”字段的详细说明见第5.3.1节。


[1]PowerPC处理器通过设置Inbound寄存器,也可以避免这个Cache一致性操作。

[2]FSB收到这类TLP后,不进行Cache一致性操作。

[3] 存储器读请求TLP没有DataPayload字段,此时该TLP使用Length字段表示需要读取多少数据。

[4] 当多个PCI设备共享一条PCI总线时,一个设备不会长时间占用PCI总线,这个设备在使用这条PCI总线一定的时间后,将让出PCI总线的使用权。

5.2 TLP的路由

(2011-08-08 16:26:37)

标签:

杂谈

分类: 浅谈PCIe体系结构

TLP的路由是指TLP通过Switch或者PCIe桥片时采用哪条路径,最终到达EP或者RC的方法。PCIe总线一共定义了三种路由方法,分别是基于地址(Address)的路由,基于ID的路由和隐式路由(Implicit)方式。

存储器和I/O读写请求TLP使用基于地址的路由方式,这种方式使用TLP中的Address字段进行路由选径,最终到达目的地。

而配置读写报文、“Vendor_Defined Messages”报文、CplCplD报文使用基于ID的路由方式,这种方式使用PCI总线号[1](Bus Number)进行路由选径。在Switch或者多端口RC的虚拟PCI-PCI桥配置空间中,包含如何使用PCI总线号进行路由选径的信息。

而隐式路由方式主要用于Message报文的传递。在PCIe总线中定义了一系列消息报文,包括“INTx Interrupt Signaling”,“Power Management Messages”和“Error Signal Messages”等报文。在这些报文中,除了“Vendor_Defined Messages”报文,其他所有消息报文都使用隐式路由方式,隐式路由方式是指从下游端口到上游端口进行数据传递的使用路由方式,或者用于RCEP发出广播报文。

5.2.1 基于地址的路由

PCIe总线中,存储器读写和I/O读写TLP使用基于地址的路由方式。PCIe设备使用的地址路由方式与PCI设备使用的地址路由方式类似。只是PCIe设备使用TLP进行数据传送,而PCI设备使用总线周期进行数据传送。使用地址路由方式进行数据传递的TLP格式如第5.3.1节的图5‑8所示,在这类TLP中包含目的设备的地址。

当一个TLP进行数据传递时,可能会经过多级Switch,最终到达目的地。Switch将根据存储器读写和I/O读写请求TLP的目的地址将报文传递到合适的Egress端口上。如图4‑10所示,在一个Switch中包含了多个虚拟PCI-to-PCI桥。在Switch中有几个端口,就包含几个虚拟PCI-to-PCI桥。

在虚拟PCI-to-PCI桥的配置寄存器空间中,包含一个桥片能够接收的物理地址范围。PCIe总线通过这个物理地址范围实现基于地址的路由。这段配置寄存器如图5‑4所示。当系统软件初始化PCI总线时,将合理地设置这些寄存器,之后当TLP通过这些Switch时将根据这些寄存器选择合适的路径。

6472c4ccgac816c0e5258&690.png

上图中的配置寄存器描述了该虚拟PCI-to-PCI桥下游PCI子树使用的三组空间范围,分别为I/O、存储器和可预取的存储器空间,分别用BaseLimit两类寄存器描述,其中Base寄存器表示可访问空间的基地址,Limit寄存器表示可访问空间的大小。TLP使用基于地址的路由时,一定要通过查询这组寄存器之后,再决定传送路径。这组寄存器的使用方法与PCI总线中的PCI桥兼容。

其中TLP从“上游端口发送到下游端口”与“下游端口发送到上游端口”的路由过程略有不同,如图5‑5所示。下文以TLP1~3的发送过程对地址路由过程进行说明。TLP1~3的描述如下。

  • TLP1是一个存储器或者I/O请求TLP,由RC发出,并通过一个Switch发向EP1。存储器和I/O读写请求TLP使用这种地址路由方式。TLP1将从Switch的上游端口传送到下游端口。
  • TLP2是一个存储器或者I/O请求TLP,由EP2发出,并通过一个Switch发向RC。当PCIe设备进行DMA读写操作时,将使用这种地址路由方式。TLP2将从Switch的下游端口传送到上游端口。
  • TLP3是一个存储器或者I/O请求TLP,由一个EP2发出,并通过一个Switch后发送到另外一个EP。在x86处理器系统中,这种用法并不常见。但是在某些大规模处理器系统中,具有这种应用方式。此时TLP3将从Switch的下游端口传送到另外一个下游端口。 

 

6472c4ccgac81716aaca7&690.png

1 TLP1的传送过程

TLP1RC发向EP1时,这个TLP1I/O或者存储器报文,其中TLP1目的地址在EP1BAR空间中。当处理器访问EPBAR空间时,需要使用该类TLP。值得注意的是这个数据报文在通过RC时需要进行地址转换。

TLP1首先通过PCI Bus0发向Switch,并通过SwitchUpstream端口到达P-P1桥片,P-P1桥片首先根据配置寄存器中的LimitBase寄存器决定是否接收TLP1。如果Switch不接收TLP1,则将该TLP作为不支持的请求(Unsupported Request)处理,此时如果TLP1需要回应报文,Switch将发出完成报文,该报文的状态为UR(Unsupported Request)

如果Switch接收TLP1,则表示TLP1所访问的地址在该Switch下游端口所连接的EP或者Switch中,此时SwitchTLP1PCI Bus0推至PCI Bus1中,即穿越P-P1桥片。TLP1到达PCI Bus1后将同时查找P-P2P-P3桥片配置寄存器中的LimitBase寄存器,决定是P-P2还是P-P3桥片接收TLP1。本小节中的例子将使用P-P2桥片接收TLP1,并将TLP1推至PCI Bus2,而PCI Bus2上的EP1将接收TLP1,完成整个地址路由。

2 TLP2的传送过程

TLP2EP2发向RC时,一般来说该TLP将访问处理器系统的主存储器。此时TLP2首先将请求发至P-P3桥片,在P-P3桥片配置寄存器的LimitBase寄存器中当然不会包含TLP2所访问的地址,此时P-P3桥片将TLP2推至PCI Bus1

TLP从“下游端口向上游端口”与“TLP从上游端口向下游端口”进行传递时,桥片的处理机制有所不同,从上游端口向下游端口传递时,如果桥片配置寄存器的LimitBase寄存器包含该TLP的访问地址时,桥片将接收此TLP,否则不接收该TLP。而从下游端口向上游端口传递时,如果桥片配置寄存器的LimitBase寄存器不包含该TLP的访问地址时,桥片将接收该TLP,并将其推至桥片的上游PCI总线。值得注意的是,这两种地址译码方式都属于PCI总线的正向译码。

TLP2到达PCI Bus1时,首先检查在PCI Bus1总线上的P-P2桥片是否可以接收此TLP,如果不能接收则TLP2通过P-P1桥片传递到PCI Bus0,即到达RC

MPC8548处理器中,到达RCTLP首先通过Inbound寄存器进行地址转换,将TLPPCI总线地址转换为处理器的地址,然后访问处理器中相应的存储器空间;对于x86处理器而言,MCH也会完成PCI域地址空间到存储器域地址空间的转换,然后访问处理器中相应的存储器空间。

3 TLP3的传送过程

TLP3的传递方式与TLP2的传递方式有些类似,当TLP3传递到PCI Bus1时,P-P2桥片将接收TLP3,并将TLP3传递到PCI Bus2上的EP1中。由以上叙述可以发现,PCIe总线中基于地址的路由方式与PCI总线上的基于地址的数据传递流程十分相近。TLP3PCI总线域上进行数据传递,因此不需要进行PCI总线域到存储器域的地址转换。

5.2.2 基于ID的路由

PCIe总线中,基于ID的路由方式主要用于配置读写请求TLPCplCplD报文,此外Vendor_Defined消息报文也可以使用这种基于ID的路由方式。而在PCI总线中,只有配置读写周期才使用ID进行数据传递。

基于ID的路由方式与基于地址的路由方式有较大的不同,基于ID路由方式的TLP头格式也与基于地址路由方式的头格式不同,其报文格式如图5‑6所示。

6472c4ccgac817509a72a&690.png

如上图所示,使用ID路由方式的TLP头,其Byte811字段与基于地址路由的TLP不同。基于ID路由的TLP,使用Bus NumberDevice NumberFunction Number进行路由寻址。从软件的角度上看,PCIe总线与PCI总线兼容,只是在PCIe总线中,每一个PCIe设备使用唯一的PCI设备号,但是每一个设备仍然可以有多个子设备(Function)

PCIe总线规定,在一个PCI总线域空间中,最多只能有256PCI总线,因此在一个TLP中,Bus Number由五位组成;而在每一条总线中最多包含32个设备,因此TLP中的Device Number5[2]组成;而每一个设备中最多包含8个功能,因此一个TLPFunction Number3位组成。

配置读写请求TLP是使用“基于ID路由”的一组重要报文,其主要作用是读写PCIe总线的EPSwitchPCIe桥片的配置寄存器,以完成PCIe总线的配置。在处理器系统上电之后需要进行PCI总线系统的枚举,为PCI总线分配总线号,并设置SwitchPCIe桥片或者EP的配置寄存器,如Limit寄存器组、Base寄存器组、BAR寄存器、Subordinate Bus NumberSecondary Bus NumberPrimary Bus Number等一系列配置寄存器。

在上文中我们简单介绍了Limit寄存器组和Base寄存器组的用法,下文将重点描述Subordinate Bus NumberSecondary Bus NumberPrimary Bus Number寄存器。Subordinate Bus NumberSecondary Bus NumberPrimary Bus Number寄存器在Type 01h配置寄存器中,用来描述PCI-to-PCI桥片的上游及下游总线号。这段寄存器在PCI配置寄存器中的位置如图5‑7所示。

6472c4ccgac81783cb5d5&690

PCI总线中的桥片类似,Primary Bus Number记录PCI-to-PCI桥上游的PCI总线号,Secondary Bus Number记录PCI-to-PCI桥下游的第一个PCI总线号,而Subordinate Bus Number记录PCI-to-PCI桥下游的最后一个PCI总线号。

如图5‑5所示,P-P1桥片的Primary Bus Number0Secondary Bus Number1,而Subordinate Bus Number3。这些总线号,在处理器系统对PCI总线进行枚举时由系统初始化程序设置,从系统初始化程序的角度上看,PCIe总线与PCI总线基本兼容,只是PCIe总线对配置空间进行了一些扩展。

如表5‑2所示,RC可以使用Type 00hType 01h读写请求TLP,对PCIe设备的配置寄存器进行读写访问,配置读写请求TLP只能由RC发出,配置读写请求TLP使用基于ID的路由方式。

如图5‑5所示的例子,RC首先使用Type 00h配置请求TLP访问在PCI Bus0总线上的设备,PCI Bus0上的所有设备,包括桥片都要监听PCI Bus 0上的配置请求,在本例中只有Switch挂接在PCI Bus0上,实际上是Switch的上游端口与PCI Bus0直接相连。因此Switch的上游端口将接收RC发出的Type 00h配置请求TLP,之后Switch将向RC发出完成报文,结束配置请求。与PCI总线相同,PCIe总线的Type 00h类型配置请求TLP不能够穿越桥片,在图5‑5中这类请求只能访问Switch上游端口的配置空间。

PCI总线是基于共享总线的数据传送方式,在一条PCI总线上可以连接多个PCI Agent设备,其中每一个PCI Agent都提供了一个IDSEL#信号,这个信号与PCI-to-PCI桥片或者HOST主桥的地址线直接相连,PCI总线根据与IDSEL#信号与地址线的连接关系决定相应设备的Device Number

这与PCIe总线的使用方法不同,PCIe总线使用“端对端”的连接方式,在PCIe链路只能连接一个下游设备,而这个下游设备的Device Number只能为0。而只有在Switch的虚拟PCI总线上可以连接多个Device Number不同的端口。

当一个虚拟PCI总线上挂接PCI-to-PCI桥时,系统配置软件将使用Type 01h配置请求TLP访问PCI-PCI桥下游的PCI设备。如图5‑5所示,RC可以通过Type 01h配置请求TLP访问P-P2桥片、P-P3桥片,EP1EP2

RC使用Type 01h配置请求TLP,直接访问P-P1桥的下游设备时,首先需要检查该TLPBus Number是否为1,如果为1表示该TLP的访问目标在PCI Bus 1总线上,此时PCI-to-PCI桥将这个Type 01h类型的TLP转换为Type 00h类型的TLP,然后推至PCI Bus 1总线,并访问其下的设备。

如果该TLPBus NumberP-P1桥片的Secondary Bus NumberSubordinate Bus Number寄存器之间,则P-P1桥片将该Type 01h类型的TLP直接转发到PCI Bus 1上,并不改变该TLP的类型,之后Type 01和类型的TLP将继续检查P-P2P-P3桥片的配置空间,决定由P-P2还是P-P3接收该TLP。如果TLPPCI Bus Number2时,P-P2桥片将接收该TLP,并将该Type 01h类型TLP转换为Type 00h类型的TLP,然后发送给EP1,并由EP1处理该TLP

上文简要讲述了配置请求TLP使用ID路由方式从上游端口向下游端口的传递规则,但是Vendor_Defined消息报文和CplCplD报文还可能从下游端口向上游端口进行传递。此时PCIe总线处理方法略有不同。下文仍以图5‑5为例说明这种情况。

当一个TLPEP2传送到EP1或者RC时,首先检查P-P3桥片的配置空间,P-P3桥片发现该TLP不是发向自己时,将该TLP推至上游总线,即PCI Bus 1。如果PCI Bus1P-P1桥片没有认领该TLP,该TLP将继续向P-P2桥片传递,并由这个桥片将TLP转发给合适的EP;如果P-P1桥片认领该TLP,该TLP将继续向上游总线传递,直至RC

由以上描述可以发现,PCIe总线使用的基于ID的路由方式与PCI总线中配置读写总线事务通过PCI桥的方法较为类似。

5.2.3 隐式路由

PCIe总线规定消息请求报文使用隐式路由方式。在PCIe总线中,有许多消息是直接发向RC或者来自RC的广播报文,这些报文不使用地址或者ID进行路由,而是使用MsgMsgD报文的Route字段进行路由,这种路由方式被称为隐式路由。

PCIe总线定义了一些用于中断请求、错误状态处理、锁定总线事务、热插拔信号处理和“Vendor_Defined Messages”消息报文。这些消息报文需要使用隐式路由方式进行传递。消息报文的Route字段的含义如表5‑4所示。

54 Route[4:0]字段

Route[2:0] 描述
000 路由到RC
001 使用地址路由
010 使用ID路由
011 来自RC的广播报文
100 本地消息,在接收端结束(Legacy中断消息使用这种报文格式,传递来自PCI总线的中断报文)
101 用于PCIe电源管理(PME_TO_Ack报文使用)
110~111 保留

 由上表所示,使用隐式路由方式的TLP,其Route字段为“000”,“011”,“100”或者“101”。当一个报文使用隐式路由向EP发送时,EP将对Route字段进行检查,如果这个报文是“来自RC的广播报文”,或者是“本地报文”,EP将接收此报文。

如果Switch收到一条使用隐式路由的TLP时,将根据报文Route字段的不同而分别处理。如果Switch的上游端口接收了一条来自RC的广播消息,则将该报文发向所有的下游端口;如果Switch接收了一条来自下游端口发向RC的消息报文时,Switch将此报文直接转发到上游端口,直至RC;如果Switch接收了一条使用隐式路由方式的本地消息报文,则Switch接收并终结此报文,不再上传或下推。

如果RC收到一个使用隐式路由的TLP时,将根据报文Route字段而分别处理这些TLP。如果该Route字段为0b0000b101RC将接收该TLP,并作相应的处理;如果为0b100RC将接收该TLP,并结束该TLP报文的传递。


[1] PCIe总线实际上使用Transaction ID进行ID路由,有关Transaction ID的详细说明见第6.3.1节。

[2] PCIe链路采用端到端的通信方式,每一个链路只能挂接一个设备,因此在多数情况下,使用3位描述Device Number是多余的,因此PCIe总线提出了ARI格式,该格式的详细描述见第6.3.1节。

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

(2011-08-08 16:32:33)

标签:

杂谈

分类: 浅谈PCIe体系结构

本节讲述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所示。

6472c4ccg77a68ca17701&690

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

55 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并没有实际意义。

6472c4ccgac8180d9ccec&690

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

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

6472c4ccgac81847a26f3&690

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机制相关的一些报文。

6472c4ccgac81897e5083&690

完成报文“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所示。

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

6472c4ccgac818dcbaf40&690

配置请求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字段。

6472c4ccgac8195de20c6&690

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

  • INTx中断消息报文(INTx Interrupt Signaling)
  • 电源管理消息报文(Power Management)
  • 错误消息报文(Error Signaling)
  • 锁定事务消息报文(Locked Transaction Support)
  • 插槽电源限制消息报文(Slot Power Limit Support)
  • Vendor-Defined Messages

5.4 TLP中与数据负载相关的参数

(2011-08-09 11:36:53)

标签:

杂谈

分类: 浅谈PCIe体系结构

PCIe总线中,有些TLP含有Data Payload,如存储器写请求、存储器读完成TLP等。在PCIe总线中,TLP含有的Data Payload大小与Max_Payload_SizeMax_Read_Request_SizeRCB参数相关。下文将分别介绍这些参数的使用。

5.4.1 Max_Payload_Size参数

PCIe总线规定在TLP报文中,数据有效负载的最大值为4KB,但是PCIe设备并不一定能够发送这么大的数据报文。PCIe设备含有“Max_Payload_Size”和“Max_Payload_Size Supported”参数,这两个参数分别在Device Capability寄存器和Device Control寄存器中定义。

Max_Payload_Size Supported”参数存放在一个PCIe设备中,TLP有效负载的最大值,该参数由PCIe设备的硬件逻辑确定,系统软件不能改写该参数。而Max_Payload_Size参数存放PCIe设备实际使用的,TLP有效负载的最大值。该参数由PCIe链路两端的设备协商决定,是PCIe设备进行数据传送时,实际使用的参数。

PCIe设备发送数据报文时,使用Max_Payload_Size参数决定TLP的最大有效负载。当PCIe设备的所传送的数据大小超过Max_Payload_Size参数时,这段数据将被分割为多个TLP进行发送。当PCIe设备接收TLP时,该TLP的最大有效负载也不能超过Max_Payload_Size参数,如果接收的TLP,其Length字段超过Max_Payload_Size参数,该PCIe设备将认为该TLP非法。

RC或者EP在发送存储器读完成TLP时,这个存储器读完成TLP的最大Payload也不能超过Max_Payload_Size参数,如果超过该参数,PCIe设备需要发送多个读完成报文。值得注意的是,这些读完成报文需要满足RCB参数的要求,有关RCB参数的详细说明见下文。

在实际应用中,尽管有些PCIe设备的Max_Payload_Size Supported参数可以为256B512B1024B或者更高,但是如果PCIe链路的对端设备可以支持的Max_Payload_Size参数为128B时,系统软件将使用对端设备的Max_Payload_Size Supported参数,初始化该设备的Max_Payload_Size参数,即选用PCIe链路两端最小的Max_Payload_Size Supported参数初始化Max_Payload_Size参数。

在多数x86处理器系统的MCH或者ICH中,Max_Payload_Size Supported参数为128B。这也意味着在x86处理器中,与MCH或者ICH直接相连的PCIe设备进行DMA读写时,数据的有效负载不能超过128B。而在PowerPC处理器系统中,该参数大多为256B

目前在大多数EP中,Max_Payload_Size Supported参数不大于512B,因为在大多数处理器系统的RC中,Max_Payload_Size Supported参数也不大于512B。因此即便EP支持较大的Max_Payload_Size Supported参数,并不会提高数据传送效率。

Max_Payload_Size参数的大小与PCIe链路的传送效率成正比,该参数越大,PCIe链路带宽的利用率越高,该参数越小,PCIe链路带宽的利用率越低。

PCIe总线规范规定,对于实时性要求较高的PCIe设备,Max_Payload_Size参数不应设置过大,因此这个参数有时会低于PCIe链路允许使用的最大值。

5.4.2 Max_Read_Request_Size参数

Max_Read_Request_Size参数由PCIe设备决定,该参数规定了PCIe设备一次能从目标设备读取多少数据。

Max_Read_Request_Size参数在Device Control寄存器中定义。该参数与存储器读请求TLPLength字段相关,其中Length字段不能大于Max_Read_Request_Size参数。在存储器读请求TLP中,Length字段表示需要从目标设备读取多少数据。

值得注意的是,Max_Read_Request_Size参数与Max_Payload_Size参数间没有直接联系,Max_Payload_Size参数仅与存储器写请求和存储器读完成报文相关。

PCIe总线规定存储器读请求,其读取的数据长度不能超过Max_Read_Request_Size参数,即存储器读TLP中的Length字段不能大于这个参数。如果一次存储器读操作需要读取的数据范围大于Max_Read_Request_Size参数时,该PCIe设备需要向目标设备发送多个存储器读请求TLP

PCIe总线规定Max_Read_Request_Size参数的最大值为4KB,但是系统软件需要根据硬件特性决定该参数的值。因为PCIe总线规定EP在进行存储器读请求时,需要具有足够大的缓冲接收来自目标设备的数据。

如果一个EPMax_Read_Request_Size参数被设置为4KB,而且这个EP每发出一个4KB大小存储器读请求时,EP都需要准备一个4KB大小的缓冲[1]。这对于绝大多数EP,这都是一个相当苛刻的条件。为此在实际设计中,一个EP会对Max_Read_Request_Size参数的大小进行限制。

5.4.3 RCB参数

RCB位在Link Control寄存器中定义。RCB位决定了RCB参数的值,在PCIe总线中,RCB参数的大小为64B或者128B,如果一个PCIe设备没有设置RCB的大小[2],则RCRCB参数缺省值为64B,而其他PCIe设备的RCB参数的缺省值为128BPCIe总线规定RCRCB参数的值为64B或者128B,其他PCIe设备的RCB参数为128B

PCIe总线中,一个存储器读请求TLP可能收到目标设备发出的多个完成报文后,才能完成一次存储器读操作。因为在PCIe总线中,一个存储器读请求最多可以请求4KB大小的数据报文,而目标设备可能会使用多个存储器读完成TLP才能将数据传递完毕。

当一个EPRC或者其他EP读取数据时,这个EP首先向RC或者其他EP发送存储器读请求TLP;之后由RC或者其他EP发送存储器读完成TLP,将数据传递给这个EP

如果存储器读完成报文所传递数据的地址范围没有跨越RCB参数的边界,那么数据发送端只能使用一个存储器完成报文将数据传递给请求方,否则可以使用多个存储器读完成TLP

假定一个EP向地址范围为0xFFFF-0000~0xFFFF-0010这段区域进行DMA读操作,RC收到这个存储器读请求TLP后,将组织存储器读完成TLP,由于这段区域并没有跨越RCB边界,因此RC只能使用一个存储器读完成TLP完成数据传递。

如果存储器读完成报文所传递数据的地址范围跨越了RCB边界,那么数据发送端(目标设备)可以使用一个或者多个完成报文进行数据传递。数据发送端使用多个存储器读完成报文完成数据传递时,需要遵循以下原则。

  • 第一个完成报文所传送的数据,其起始地址与要求的起始地址相同。其结束地址或者为要求的结束地址(使用一个完成报文传递所有数据),或者为RCB参数的整数倍(使用多个完成报文传递数据)
  • 最后一个完成报文的起始地址或者为要求的起始地址(使用一个完成报文传递所有数据),或者为RCB参数的整数倍(使用多个完成报文传递数据)。其结束地址必须为要求的结束地址。
  • 中间的完成报文的起始地址和结束地址必须为RCB参数的整数倍。

RC或者EP需要使用多个存储器读完成报文将0xFFFE-FFF0~0xFFFF-00C7之间的数据发送给数据请求方时,可以将这些完成报文按照表5‑9方式组织。

 59 存储器读完成报文的拆分方法

方式1 方式2 方式3
0xFFFE-FFF0~0xFFFE-FFFF 0xFFFE-FFF0~0xFFFE-FFFF 0xFFFE-FFF0~0xFFFE-FFFF
0xFFFF-0000~0xFFFF-003F 0xFFFF-0000~0xFFFF-007F 0xFFFF-0000~0xFFFF-00C7
0xFFFF-0040~0xFFFF-007F 0xFFFF-0080~0xFFFF-00C7  
0xFFFF-0080~0xFFFF-00BF    
0xFFFF-00C0~0xFFFF-00C7    

 上表提供的方式仅供参考,目标设备还可以使用其他拆分方法发送存储器读完成TLPPCIe总线使用多个完成报文实现一次数据读请求的主要原因是考虑Cache行长度和流量控制。在多数x86处理器系统中,存储器读完成报文的数据长度为一个Cache行,即一次传送64B。除此之外,较短的数据完成报文占用流量控制的资源较少,而且可以有效避免数据拥塞。

5.5 小结

本章重点介绍PCIe总线的事务层。在PCIe总线层次结构中,事务层最易理解,同时也与系统软件直接相关。


[1] 这是流量控制Infinite FC Unit的要求,详见第9.3.2节。

[2] 有些PCIe设备可能没有Link Control寄存器。

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google photo

You are commenting using your Google account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s