PCIe总线-事物层之TLP请求和完成报文格式介绍(六)

1.概述

TLP报文按照类型,可以大致分为4中类型,分别是IO请求报文、存储器请求报文、配置请求报文、完成报文和消息请求报文。IO请求报文可分为IO读请求(不携带数据)和IO写请求(携带数据)。存储器请求报文可分为存储器读请求(不携带数据)、带锁的存储器读请求(不携带数据)和存储器写请求(携带数据)。配置请求报文可分为配置0读请求(不携带数据)、配置0写请求(携带数据)、配置1读请求(不携带数据)和配置1写请求(携带数据)。完成报文可分为携带数据(带锁和不带锁)、不携带数据(带锁和不带锁)。消息请求可分为携带数据和不携带数据两种类型。

2.IO Requests

在早期的PCI总线中,CPU访问PCI设备的IO地址空间,使用IO请求,而在较新的PCIe总线中,CPU使用memory map方式访问PCIe设备的IO地址空间,很少使用IO请求。为了保持对PCI总线的兼容性,PCIe总线中也保留了IO请求。IO请求可以访问16位和32位IO地址空间,具体位宽根据设备的BAR确定。IO请求TLP报文的格式如下图所示。

IO请求

位域意义
FmtIO请求报文格式。000b = IO Read(3DW without data),010b = IO Write(3DW with data)
TypeIO请求报文类型(00010b)
TCIO请求通常为0,确保IO请求报文不高于任何高优先级的报文
Attr不适用于IO请求,保持为0
TH不适用于IO请求,保持为0
AT不适用于IO请求,保持为0
LengthIO请求的数据长度最大为1DW,所以设置为1
Requester ID发出IO请求Function的BDF
Tag确保一段时间内同一个Function发出的IO请求不重复,通常使用低5位,若使用扩展tag和PF选项,可以扩展到11位,最大允许2048个IO请求不重复
Last DW BEIO请求的数据长度最大为1DW,所以为0
1st DW BE确认1DW数据负载中的有效位,可能同时为0
AddressIO请求读写的地址,低2位为0,地址按DW对齐

3.Memory Requests

存储器请求有3DW和4DW两种报文类型,3DW对应32位地址,4DW对应64位地址。需要注意的是,若存储器请求及其完成报文携带数据,则不能越过4KB地址边界。具体的报文格式如下图所示。

存储器请求

存储器请求的位域意义如下表所示,没有列出的参考TLP通用格式章节。

位域意义
Fmt存储器请求报文格式。000b = Memory Read (3DW w/o data),010b = Memory Write (3DW w/ data),001b = Memory Read (4DW w/o data),011b = Memory Write (4DW w/ data),1xxb = TLP Prefix
Type存储器请求报文类型,00000b = Memory Read or Write,00001b = Memory Read Locked
Address [63:32]存储器请求使用64位地址时,保存高32位地址
Address [31:2]32位地址,低2位为0,地址按DW对齐

4.Configuration Requests

配置请求分为Type0和Type1类型。Type0配置请求可以直接访问PCIe设备。Type1配置请求不能直接访问PCIe设备,需要至少穿越一个PCIe桥,当访问的PCIe设备没有与PCIe桥直接相连时,PCIe桥会直接向下转发Type1配置请求,当访问的PCIe设备与PCIe桥直接相连时,则PCIe桥会将Type1配置请求转换成Type0配置请求,然后转发给PCIe设备。通常情况下,CPU若访问与Host桥相连的PCIe桥或者设备,则发出Type0配置请求,否则需要发出Type1配置请求。配置请求TLP报文格式如下图所示。

配置请求

位域意义
Fmt配置请求报文格式。000b = configuration read (no data),010b = configuration write (with data)
Type配置请求报文类型,00100b = Type 0 Config Request,00101b = Type 1 Config Request
TC配置请求通常为0,确保配置请求报文不高于任何高优先级的报文
Attr不适用于配置请求,保持为0
TH不适用于配置请求,保持为0
AT不适用于配置请求,保持为0
Length配置请求的数据长度最大为1DW,所以设置为1
Requester ID发出配置请求Function的BDF
Tag确保一段时间内同一个Function发出的配置请求不重复,通常使用低5位,若使用扩展tag,可以扩展到8位,最大允许256个配置请求不重复
Last DW BE配置请求的数据长度最大为1DW,所以为0
1st DW BE确认1DW数据负载中的有效位,可能同时为0
Completer ID配置请求访问目标设备的BDF
Ext Register Number配置空间扩展寄存器地址。用于访问PCIe扩展的配置空间。访问配置空间的前256字节,则位0。和Register Number一起组成10位地址,可以访问PCIe扩展的4KB地址空间
Register Number配置空间寄存器地址。用于访问配置空间的前256字节,和Ext Register Number一起组成10位地址,可以访问PCIe扩展的4KB地址空间

5.Completions

完成报文用于响应Non‐Posted请求,Non‐Posted请求包括IO读写请求、配置读写请求、原子操作请求和存储器读请求。完成报文可以携带数据也可以不携带数据,Zero-Length读完成报文不携带数据,携带数据的完成报文的数据最大长度不超过MPS,在x86和PowrPC处理器中,一般不超过RCB。完成报文的许多位域和对应的请求报文相同,如TC、Attr、Requester ID和tag,完成报文使用Requester ID路由到发送请求的设备。完成报文TLP格式如下图所示。正常情况下,Completer ID对于发送请求的设备没有意义,但对于完成报文发生错误时,可以通过Completer ID定位发生错误的设备。

完成报文

位域意义
Fmt完成报文格式。000b = Completion without data (Cpl),010b = Completion with data (CplD)
Type完成报文类型(01010b)
TC和请求报文相同
Attr和请求报文相同
TH不适用于完成报文,保持为0
AT不适用于配置请求,保持为0
Length完成报文携带的数据长度,按DW对齐,若真实数据长度没有按DW对齐,则需要借助Lower Address和Byte Count字段描述第一个DW和最后一个DW的有效字节
Completer ID完成报文Function的BDF
Compl. Status(Completion Status Code)完成报文状态。000b = Successful Completion (SC),001b = Unsupported Request (UR),010b = Config Req Retry Status (CRS),100b = Completer abort (CA),其他保留
BCM(Byte Count Modified)用于PCI-X总线发送完成报文的设备,对于PCIe总线无意义
Byte Count一个请求可能需要多个完成报文响应,该字段记录源设备还需要从目标设备接收多少字节数据才能完成全部数据据传输,而且包含当前完成报文携带的数据。若多个完成报文中有一个完成报文的状态不是SC,则终止此次请求。IO和配置请求只需要一个完成报文。0x0表示4096字节,0x1表示1字节,0xFFF表示4095字节
Requester ID和请求Function的BDF相同
Tag和请求Function的tag相同,用来匹配发送的请求,Requester ID和Tag组成的Transaction ID必须和源设备的Transaction ID相同
Lower Address第一读请求完成报文携带数据的起始地址的低7位。当真实数据没有按DW对齐时,需要和Byte Count字段一起用于描述第一个DW和最后一个DW的有效字节(完成报文中没有First DW BE和Last DW BE字段)

如源设备向目标设备发送了存储器读请求,读取长度为128字节。目标设备使用两个完成报文响应此存储器读请求,第一个完成报文的有效数据负载为64字节,则Byte Count为128,第二个完成报文的有效数据负载为64字节,则Byte Count为64。当源设备接收到一个完成报文后,发现还有64字节数据没有接收完毕,则会继续等待下一个完成报文,收到第二个完成报文后才会结束整个存储器读请求,此时和存储器读请求相关的资源都会被释放,如tag、retry buffer。
完成报文有效数据长度由Length字段定义,而Length按DW对齐。这就存在一个问题,当第一个完成报文的开始地址和最后一个完成报文的结束地址没有按DW对齐,而仅凭Length字段又无法区分这种情况。此时需要借助Lower Address和Byte Count来区分这种情况,而Byte Count和Lower Address又和存储器读请求的First DW BE和Last DW BE密切相关。
下图是一个完成报文数据示意图,Length=4DW,Byte Count=10字节,Lower Address=11b。对应的存储器读请求的First DW BE=1000b,Last DW BE=0001b。当源设备收到完成报文后,发现Lower Address=11b,说明有效数据从START的Byte3开始,再根据Byte Count=10,则有效数据的结束地址为START+3的Byte0。

在这里插入图片描述
Lower Address保存了第一个完成报文数据起始地址的低2位,和存储器读请求First DW BE字段密切相关。对应关系如下:

First DW BELower Address[1:0]
000000
xxx100
xx1001
x10010
100011

First DW BE、Last DW BE和Total Byte Count(全部完成报文数据长度之和,也可以理解为第一个完成报文的Byte Count)的对应关系如下:

First DW BELast DW BETotal Byte Count
1xx100004
01x100003
1x1000003
001100002
011000002
110000002
000100001
001000001
010000001
100000001
000000001
xxx11xxxLength * 4
xxx101xx(Length * 4) - 1
xxx1001x(Length * 4) - 2
xxx10001(Length * 4) - 3
xx101xxx(Length * 4) - 1
xx1001xx(Length * 4) - 2
xx10001x(Length * 4) - 3
xx100001(Length * 4) - 4
x1001xxx(Length * 4) - 2
x10001xx(Length * 4) - 3
x100001x(Length * 4) - 4
x1000001(Length * 4) - 5
10001xxx(Length * 4) - 3
100001xx(Length * 4) - 4
1000001x(Length * 4) - 5
10000001(Length * 4) - 6

读请求返回的数据遵循下面的规则:

  1. 一个读请求可能需要多个完成报文响应,所有完成报文传输的数据长度等于读请求的数据长度。
  2. 一个明确的完成报文只能响应一个读请求。
  3. IO和配置读请求数据长度为1DW,因此只有一个完成报文。
  4. 若完成报文的完成状态不是SC,则会终止此次事务。
  5. 若一个读请求需要多个完成报文响应,则完成报文读取的数据地址必须按RCB对齐。RC的RCB为64字节或者128字节,由硬件设置,软件可以通过配置空间读取。
  6. 若一个读请求需要多个完成报文响应,则完成报文读取的数据地址依次增大。

完成报文的接收处理规则:

  1. 若接收方接收到一个没有匹配到读请求的完成报文,则视为非预期的完成报文,当作错误处理。
  2. 若接收方收到的完成报文的完成状态不是SC和CRS时,则作为错误处理,与之相关的读请求缓冲区将被释放。
  3. RC在发出配置请求之后,若收到的完成报文的完成状态是CRS时,则此次配置请求终止。后续的行为由硬件的实现决定,若RC支持处理这种情况,则会在其寄存器定义处理CRS的策略,软件可以读取和设置。处理CRS的策略有以下几种情况:
  4. 若软件不能获取CRS状态,则RC会重发该配置读请求,重发的次数由实现决定。
  5. 若软件能获取CRS状态,则当RC发出PCI_VENDOR_ID配置读请求之后,若收到的完成报文是CRS状态,则RC会将VENDOR_ID的值设置为0x0001,然后返回给软件,软件读到该状态,通常会等待一段时间,再发起PCI_VENDOR_ID读请求。PCI‐SIG保留了VENDOR_ID=0x0001值。对于其他配置读写请求,RC会自动的重发该请求。
  6. CRS状态用于响应配置请求,对于其他类型请求,将视为有缺陷的TLP报文处理。
  7. 若完成报文状态为reserved时,处理行为和完成报文状态为UR时一致。
  8. 若一个读请求需要多个完成报文响应,若有一个完成报文的完成状态不是SC,则此次事务结束,对于错误之前接收到的数据,由实现决定。

6.Message Requests

消息请求通常是直接发向RC或者来自RC的广播报文,其取代了在PCI和PCI-X总线中使用的中断、错误和电源管理边带信号。消息请求类似于posted存储器写请求,无需完成报文响应,但不同的是posted存储器写请求基于地址路由,而消息请求基于地址路由、ID路由和隐式路由,具体的路由方式和消息请求类型有关系。消息请求使用4DW格式,如下图所示。

消息请求

位域意义
Fmt数据包格式。001b = Message Request without data,011b = Message Request with data
Type数据包类型。Bit[4:3]固定为10b,表示消息请求。Bit[2:0]表示消息路由方式。000b = Implicitly Routed to RC (Root Complex),001b = Routed by address,010b = Routed by ID,011b = Implicitly Broadcast from RC,100b = Local‐Terminate at Receiver,101b = Gather & route to RC,0thers = Reserved, treated as Local
TC不适用于消息请求,默认为0
Attr[2]TLP是否使用ID‐based Ordering
TH保留
Attr[1:0]保留
AT不适用于配置请求,保持为0
Length对于消息请求,没有数据保留,默认为0,有数据为1,消息请求最多携带1DW数据
Message Code消息编码。0000 0000b = Unlock Message(Locked Transaction Support),0001 0000b = Latency Tolerance Reporting(LTR),0001 0010b = Optimized Buffer Flush/Fill(OBFF),0001 xxxxb = Power Management Message,0010 0xxxb = INTx Message,0011 00xxb = Error Message,0100 xxxxb = Ignored Messages (related to Hot‐Plug support in spec revision 1.1),0101 0000b = Set Slot Power Message,0111 111xb = Vendor‐Defined Messages。详细信息参考PCIe5.0 Spec Table F-1 Message Code Usage表格
Byte8-11如果使用地址路由,则为64位地址的高32位。如果使用ID路由,Bytes8和Bytes9为target ID,即目标设备的BDF。其他路由方式不使用
Byte12-15如果使用地址路由,则为64位地址的低32位。其他路由方式不使用

下面只介绍INTx消息、电源管理消息和错误消息,其他参考PCIe Spec。

6.1.INTx Interrupt Messages

PCIe总线使用MSI或MSI-X中断机制,但为了兼容PCI总线,保留了传统的INTx中断。传统的INTx中断有4根中断信号线连接中断控制器,使用电平触发中断,有Assert和Deassert过程,而PCIe总线没有中断信号线,只能使用数据包模拟中断,而数据包模拟中断类似于边沿触发中断。因此PCIe总线使用两个消息请求模拟INTx中断,第一个消息Assert中断,第二个消息Deassert中断。

INTx MessageMessage CodeRouting(Type[2:0])
Assert_INTA0010 0000b100b = Local‐Terminate at Receiver
Assert_INTB0010 0001b100b = Local‐Terminate at Receiver
Assert_INTC0010 0010b100b = Local‐Terminate at Receiver
Assert_INTD0010 0011b100b = Local‐Terminate at Receiver
Deassert_INTA0010 0000b100b = Local‐Terminate at Receiver
Deassert_INTB0010 0001b100b = Local‐Terminate at Receiver
Deassert_INTC0010 0010b100b = Local‐Terminate at Receiver
Deassert_INTD0010 0011b100b = Local‐Terminate at Receiver

使用INTx消息的规则:

  1. INTx消息没有数据负载,Length保留,默认为0。
  2. INTx消息由上行口发送。对于接收到的数据包检查这一规则是可选的,如果检测,不符合规范的INTx消息会被视为错误的TLP报文。
  3. INTx消息默认使用传输类型TC0,接收端必须检查该字段,若违反该规则,则会被视为错误的TLP报文。
  4. 连接链路两端的设备必须跟踪四个INTx中断的当前状态。如果某个中断的逻辑状态在上行端口处发生变化,则必须发送相应的INTx消息。
  5. 当Command寄存器中的中断禁止位被设置为1时,INTx中断将被关闭。
  6. 设备产生中断后,上行端口将发送INTx消息,若设备的中断此时被禁止,则上行端口将发送Deassert_INTx消息。
  7. Switch必须独立的跟踪每个下行口的四个INTx中断状态,并将这些状态合并到上行口。
  8. RC必须独立跟踪四个INTx中断状态,并以特定于实现的方式将它们转换成系统中断。
  9. INTx消息的路由类型为Local‐Terminate at Receiver,这允许Switch在需要的时候重新映射中断。

6.2.Power Management Messages

PCIe总线兼容PCI总线的电源管理规范,并添加了基于硬件的链路层电源管理。电源管理消息用于传递电源管理信息。

Power Management MessageMessage CodeRouting(Type[2:0])
PM_Active_State_Nak0001 0100b100b = Local‐Terminate at Receiver
PM_PME0001 1000b000b - Implicitly Routed to RC
PM_Turn_Off0001 1001b011b - Implicitly Broadcast from RC
PME_TO_Ack0001 1011b101b - Gather & route to RC

使用电源管理消息的规则:

  1. 电源管理消息没有数据负载,Length保留,默认为0。
  2. 电源管理消息默认使用传输类型TC0,接收端必须检查该字段,若违反该规则,则会被视为错误的TLP报文。
  3. 当下行端口收到链路对端设备将链路电源状态切换到L1的请求时,但下行端口不允许切换时,将发送PM_Active_State_Nak消息报文。
  4. 当设备请求电源管理事件时,其上行端口将会发送PM_PME消息报文。
  5. PM_Turn_Off消息会发送到下游的所有EP。
  6. PM_Turn_Off消息由EP发送到上游,对于有多个下行端口的Swtich,需要等待所有下行端口收到PM_Turn_Off消息后才会转发到上游。

6.3.Error Messages

当PCIe设备检测到错误时,会向其上游发送错误消息。错误消息使用隐式路由,最终会到达RC。软件可以通过错误消息TLP的Requester ID确定发生错误的设备。

Error MessageMessage CodeRouting(Type[2:0])
ERR_COR (Correctable)0011 0000b000b - Implicitly Routed to RC
ERR_NONFATAL (Uncorrectable, Non‐fatal)0011 0001b000b - Implicitly Routed to RC
ERR_FATAL (Uncorrectable, Fatal)0011 0011b000b - Implicitly Routed to RC

使用错误消息的规则:

  1. 错误消息没有数据负载,Length保留,默认为0。
  2. 错误消息默认使用传输类型TC0,接收端必须检查该字段,若违反该规则,则会被视为错误的TLP报文。
  3. RC会将错误消息转换为系统特定的事件,以通知软件处理。

参考资料

  1. PCIEXPRESS体系结构导读
  2. PCI Express technology 3.0
  3. PCI Express® Base Specification Revision 5.0 Version 1.0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值