PCIe系列第三讲、事务层通用 TLP 头结构分析

作者: 叫什么好呢啊 来源:根究FPGA

上一讲说道:“一个完整的TLP由1个或多个TLP Prefix、TLP头、Data Payload和TLP Digest构成”,那么本讲将就谈一谈TLP的头,具体几种事务(存储器读写、配置读写、IO读写、原子操作、消息报文)后面一一分析。

通用TLP头的Fmt和Type字段

Fmt[2:0]字段:
位于帧头字段 0 的位[7:5],是关于事务层帧头长度和该事务链路层包(TLP)是否有数据的标志字段:

  • 3’b000:帧头长 3DW,无数据
  • 3’b001:帧头长 4DW,无数据
  • 3’b010:帧头长 3DW,有数据
  • 3’b011:帧头长 4DW,有数据
  • 3’b100:TLP Prefix
  • 所有的读操作(存储、IO、配置)TLP 都不带数据,而写请求(存储、IO、配置)TLP 带数据,其他 TLP 可能带也可能不带数据。

    Type[4:0]字段:
    Type 的 5 位编码与 Fmt 字段一起用于规定事务类型、帧头长度和是否有数据负载。如果存储器读写 TLP 支持 64 位地址模式时,TLP 头长度为 4DW,否则为 3DW。而完成报文的 TLP 头不含有地址信息,使用的 TLP 头长度为 3DW,其中 Byte4~Byte15 格式与 TLP 类型有关。

    PCIe 总线规范还规定了 MRdLk 报文(锁定存储器读请求),该报文的作用是与 PCI 总线的所操作相兼容,但是 PCIe 总线规范 并不建议用户使用该功能,因为这将极大地影响 PCIe 总线的数据传送效率。


    与 PCI 总线不同,PCIe 总线 规范还定义了 Msg 报文,即消息报文,分别为 Msg 和 MsgD,这两个报文一个不可以传递数据,一个可以传递数据。

    存储器读写操作、IO 读写操作、配置读写操作请求的 type 字段相同,如存储器读写请求的 type 字段都是“5’b0_0000”,此时 PCIe 总线规范使用 Fmt 字段区分读写操作,当 Fmt 是“带数据”的报文一定是“写操作”;当 Fmt 字段是不带数据的报文,一定是“读操作”。
    TC 字段(Transmit Class)

    位于 Byte1 的位[6:4]。

    TC 字段表示当前传输的等级,位宽为 3,即有 8 种传输类型,分别为 TC0~TC7,默认为 0,该字段为 PCIe 的 QoS(Quality of Service)相关。PCIe 使用 TC 字段来区分不同等级的数据传递,而多数 EP 中只含有一个 VC,因此这些 EP 在发送 TLP 时,也仅仅使用 TC0,但是有些对实时性要求较高的 EP 中,含有可以设置 TC 字段的寄存器。

    目前多数处理器系统的 RC 仅支持一个 VC 通路,此时 EP 使用不同 TC 传输意义不大。不同的 TC 使用 PCIe 链路中不同的 VC,而不同的 VC 仲裁机制不同,EP 或者 RC 可以通过调整 TLP 中的 TC 字段,从而调整 TLP 中使用的 VC,从而调整 TLP 的优先级。

    (注:VC:Virtual Channel,虚拟通道,VC0~VC7)
    Attr:

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

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

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

    ID-Ordering 即IDO模型,与数据传送的数据流相关。

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

    Attr[0]:No Snoop Attribute,用于控制是否进行 Cache 一致性处理 1:不进行 cache 一致性操作。PCI 设备对存储器进行 DMA 操作时会进行 Cache 一致性操作,这种“自动的”Cache 一致性行为在某些特殊情况下并不会带来更高的效率。

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

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

    除此之外,当 PCIe 访问的存储空间不是“可 Cache 空间”时,也可以通过设置“No Snoop Attribute”位,避免 FSB 与 Cache 共享一致性操作,从而提高 FSB 的效率。

    “No Snoop Attribute”是 PCIe 总线针对 PCI 不足做出的重要改动。

    翻译一下什么叫做 snoop,一般情况下,内存数据是被 cache 的,但是 cache 是费时的,这就降低了 PCIe 总线的操作效率,所以在面对大批量的内存数据操作时,先使用软件指令保证 cache 与主存储器的一致性,之后再进行 DMA 操作。

    TH字段:

    TH 位于 Byte1 的位 0,表示该 TLP 是否含有 TPH(TLP Processing Hint,TLP 处理信息提示)信息。
    TLP 发送端可以使用 TPH 信息,通知接收端即将访问数据的特性,以便接收端合理地预读和管理数据。

    TD字段:

    TD 位表示 TLP 中的 TLP Digest 是否有效,为 1 表示有效,为 0 表示无效。

    EP字段:

    EP:表示当前 TLP 中的 Data Payload 是否有效。1:有效 0:无效 AT字段:

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

    该字段的主要目的是为了方便多个虚拟主机共享同一个 PCIe 设备。Length字段:

    该字段用来描述 Data Payload 数据有效负载的大小,单位是 DW,PCIe 总线规范中规定一个 TLP 的 Data Payload 的大小在 1B~4096B 之间,PCIe 总线设置 Length 字段的目的是提高总线的传送效率。

    存储器读请求 TLP 中没有 Data Payload 字段,此时使用 Length 字段表示需要读取多少数据。当该字段为 n 时,表示需要获取 n 个 DW,其中 0≤n≤0x3FF,需要注意的是,当 n=0 时,表示数据长度为 1024DW,如果 PCIe 主设备传送的单位小于 1 个 DW 或者传送的数据不足以 DW 为界时需要使用“DE BE”字段。

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

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

    推荐阅读