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报文的格式如下图所示。
位域 | 意义 |
---|---|
Fmt | IO请求报文格式。000b = IO Read(3DW without data),010b = IO Write(3DW with data) |
Type | IO请求报文类型(00010b) |
TC | IO请求通常为0,确保IO请求报文不干扰任何高优先级的报文 |
Attr | 不适用于IO请求,保持为0 |
TH | 不适用于IO请求,保持为0 |
AT | 不适用于IO请求,保持为0 |
Length | IO请求的数据长度最大为1DW,所以设置为1 |
Requester ID | 发出IO请求Function的BDF |
Tag | 确保一段时间内同一个Function发出的IO请求不重复,通常使用低5位,若使用扩展tag和PF选项,可以扩展到11位,最大允许2048个IO请求不重复 |
Last DW BE | IO请求的数据长度最大为1DW,所以为0 |
1st DW BE | 确认1DW数据负载中的有效位,可能同时为0 |
Address | IO请求读写的地址,低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 | 完成报文状态。000b = Successful Completion (SC),001b = Unsupported Request (UR),010b = Config Req Retry Status (CRS),100b = Completer abort (CA),其他保留 |
Compl. Status(Completion Status Code) | 完成报文Function的BDF |
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字段) |
读请求返回的数据遵循下面的规则:
- 一个读请求可能需要多个完成报文响应,所有完成报文传输的数据长度等于读请求的数据长度。
- 一个明确的完成报文只能响应一个读请求。
- IO和配置读请求数据长度为1DW,因此只有一个完成报文。
- 若完成报文的完成状态不是SC,则会终止此次事务。
- 若一个读请求需要多个完成报文响应,则完成报文读取的数据地址必须按RCB对齐。RC的RCB为64字节或者128字节,由硬件设置,软件可以通过配置空间读取。
- 若一个读请求需要多个完成报文响应,则完成报文读取的数据地址依次增大。
完成报文的接收处理规则:
- 若接收方接收到一个没有匹配到读请求的完成报文,则视为非预期的完成报文,当作错误处理。
- 若接收方收到的完成报文的完成状态不是SC和CRS时,则作为错误处理,与之相关的读请求缓冲区将被释放。
- RC在发出配置请求之后,若收到的完成报文的完成状态是CRS时,则此次配置请求终止。后续的行为由硬件的实现决定,若RC支持处理这种情况,则会在其寄存器定义处理CRS的策略,软件可以读取和设置。处理CRS的策略有以下几种情况:
- 若软件不能获取CRS状态,则RC会重发该配置读请求,重发的次数由实现决定。
- 若软件能获取CRS状态,则当RC发出PCI_VENDOR_ID配置读请求之后,若收到的完成报文是CRS状态,则RC会将VENDOR_ID的值设置为0x0001,然后返回给软件,软件读到该状态,通常会等待一段时间,再发起PCI_VENDOR_ID读请求。PCI‐SIG保留了VENDOR_ID=0x0001值。对于其他配置读写请求,RC会自动的重发该请求。
- CRS状态用于响应配置请求,对于其他类型请求,将视为有缺陷的TLP报文处理。
- 若完成报文状态为reserved时,处理行为和完成报文状态为UR时一致。
- 若一个读请求需要多个完成报文响应,若有一个完成报文的完成状态不是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 Message | Message Code | Routing(Type[2:0]) |
---|---|---|
Assert_INTA | 0010 0000b | 100b = Local‐Terminate at Receiver |
Assert_INTB | 0010 0001b | 100b = Local‐Terminate at Receiver |
Assert_INTC | 0010 0010b | 100b = Local‐Terminate at Receiver |
Assert_INTD | 0010 0011b | 100b = Local‐Terminate at Receiver |
Deassert_INTA | 0010 0000b | 100b = Local‐Terminate at Receiver |
Deassert_INTB | 0010 0001b | 100b = Local‐Terminate at Receiver |
Deassert_INTC | 0010 0010b | 100b = Local‐Terminate at Receiver |
Deassert_INTD | 0010 0011b | 100b = Local‐Terminate at Receiver |
使用INTx消息的规则:
- INTx消息没有数据负载,Length保留,默认为0。
- INTx消息由上行口发送。对于接收到的数据包检查这一规则是可选的,如果检测,不符合规范的INTx消息会被视为错误的TLP报文。
- INTx消息默认使用传输类型TC0,接收端必须检查该字段,若违反该规则,则会被视为错误的TLP报文。
- 连接链路两端的设备必须跟踪四个INTx中断的当前状态。如果某个中断的逻辑状态在上行端口处发生变化,则必须发送相应的INTx消息。
- 当Command寄存器中的中断禁止位被设置为1时,INTx中断将被关闭。
- 设备产生中断后,上行端口将发送INTx消息,若设备的中断此时被禁止,则上行端口将发送Deassert_INTx消息。
- Switch必须独立的跟踪每个下行口的四个INTx中断状态,并将这些状态合并到上行口。
- RC必须独立跟踪四个INTx中断状态,并以特定于实现的方式将它们转换成系统中断。
- INTx消息的路由类型为Local‐Terminate at Receiver,这允许Switch在需要的时候重新映射中断。
6.2.Power Management Messages
PCIe总线兼容PCI总线的电源管理规范,并添加了基于硬件的链路层电源管理。电源管理消息用于传递电源管理信息。
Power Management Message | Message Code | Routing(Type[2:0]) |
---|---|---|
PM_Active_State_Nak | 0001 0100b | 100b = Local‐Terminate at Receiver |
PM_PME | 0001 1000b | 000b - Implicitly Routed to RC |
PM_Turn_Off | 0001 1001b | 011b - Implicitly Broadcast from RC |
PME_TO_Ack | 0001 1011b | 101b - Gather & route to RC |
使用电源管理消息的规则:
- 电源管理消息没有数据负载,Length保留,默认为0。
- 电源管理消息默认使用传输类型TC0,接收端必须检查该字段,若违反该规则,则会被视为错误的TLP报文。
- 当下行端口收到链路对端设备将链路电源状态切换到L1的请求时,但下行端口不允许切换时,将发送PM_Active_State_Nak消息报文。
- 当设备请求电源管理事件时,其上行端口将会发送PM_PME消息报文。
- PM_Turn_Off消息会发送到下游的所有EP。
- PM_Turn_Off消息由EP发送到上游,对于有多个下行端口的Swtich,需要等待所有下行端口收到PM_Turn_Off消息后才会转发到上游。
6.3.Error Messages
当PCIe设备检测到错误时,会向其上游发送错误消息。错误消息使用隐式路由,最终会到达RC。软件可以通过错误消息TLP的Requester ID确定发生错误的设备。
Error Message | Message Code | Routing(Type[2:0]) |
---|---|---|
ERR_COR (Correctable) | 0011 0000b | 000b - Implicitly Routed to RC |
ERR_NONFATAL (Uncorrectable, Non‐fatal) | 0011 0001b | 000b - Implicitly Routed to RC |
ERR_FATAL (Uncorrectable, Fatal) | 0011 0011b | 000b - Implicitly Routed to RC |
使用错误消息的规则:
- 错误消息没有数据负载,Length保留,默认为0。
- 错误消息默认使用传输类型TC0,接收端必须检查该字段,若违反该规则,则会被视为错误的TLP报文。
- RC会将错误消息转换为系统特定的事件,以通知软件处理。
参考资料
- PCIEXPRESS体系结构导读
- PCI Express technology 3.0
- PCI Express® Base Specification Revision 5.0 Version 1.0