PCIe知识碎片日常记录

PCIe的知识实际上很多并且相对杂,在实际项目应用中并不一定都能够用到。这里会将自己在项目或者学习过程中遇到的有意义的,容易混淆的知识碎片进行记录。【持续更新】

目录

1.[20231206]:message tlp

2.[20231207]:tlp length

3.[20231207]:MPS

4.[20231207]: MRRS

5.[20240104]:PCIe 数据链路层是做什么的?有哪些功能?

6.[20240104]:ECRC vs LCRC

7.PCIe 配置空间 Size 是多少?

8.[20240117]:NCBE(Non-Contiguous Byte Enable)

9.[20240123]:Cannot initiate non-posted requests prior to receiving first CfgWr0.

10.[20240123]:Zero-Length Write/Read

11.[20240202]:Flow Control 初始化流程  

1.[20231206]:message tlp

message TLP包的类型是message,如PME, INTx message中断信息。但是MSI(message signaled interrupt)中断虽然名字有message,但是它的TLP包是Memory Write。 MSIX一样。

2.[20231207]:tlp length

TLP length[9:0]是以DW为单位的,表示payload size有多少DW。1表示1个DW,2表示2DW......以此类推。总共10bit,当全为1时,length = 'd1023,表示1023个DW的payload。而当length=0,即全0时是表示1024个DW的payload

[注]:这里其实就表明了PCIe SPEC协议允许最大的payload可以到达4KB,即1024DW。

3.[20231207]:MPS

Maximum Payload Size (简称MPS)

控制一个TLP可以传输的最大数据长度。作为接收方,必须能处理跟MPS设定大小相同的TLP数据包,作为传输方,不允许创建超过MPS设定的TLP数据包。

 PCIe协议允许最大一个Payload可以到4K,但是规定了在整个传输路径上的所有Device,都必须使用相同的MPS设置,同时不能超过该路径上一个设备的MPS能力值。也就是说,MPS capability高的设备要迁就低的设备。以PCIe SSD来说,插到一块老掉牙的主板上(MPS只有128 Byte),你的Payload size再大,也是没有用的。

该值位于Device Control Register(PCIe capability structure)中,有6个有效值,可以理解为以128Byte为最小单位。

4.[20231207]: MRRS

Maximum Read Request Size(简称MRRS)

在配置阶段,OS的PCIe驱动也会配置另外一个参数maximum read request size,用于控制一个Memory read的最大size,最大4K(以128 Byte为单位)
Read request size是可以大于MPS滴,比如给一个MPS=128 Byte的PCIe SSD发一个512 Byte的read request,PCIe SSD可以通过返回多个4个128 Byte的 Cpld,或者8个64 Byte的Cpld,完成这个request的响应。OS 层面可以通过控制PCIe SSD的maximum read request size参数,平衡多个PCIe SSD之间的吞吐量,避免系统带宽(总共40个lane)被某些个SSD霸占。

 同时,Read request size也对PCIe SSD的Performance有影响,这个size太小,意味着同样的data,需要发送更多的request去获取,而read request的TLP是不带任何data payload的。

5.[20240104]:PCIe 数据链路层是做什么的?有哪些功能?

PCIe 数据链路层/DataLink Layer位于事务层与物理层之间,用以保证数据传输的可靠性。

其主要功能如下:

  • TLP 数据交换。在发送端,数据链路层负责接收事务层发来的 TLP,添加 Sequence Number 及 LCRC 后交给物理层;在接收端,数据链路层负责接收物理层发来的 TLP,数据完整性检测通过后交给事务层。此外,数据链路层负责 TLP 流控。
  • 错误检测及重传。数据链路层基于 ACK/NAK 机制来检测有无 TLP 损坏或丢包,在出现损坏或丢包时通过 Retry 机制请求重传。若发送端长时间等不到相应 TLP 的 ACK,还有 Timeout 机制来保证重传。
  • 链路初始化及电源管理。PCIe 初始化过程中,数据链路层监测 PCIe Link 的 Reset、Active、Disconnected 等状态并传递到事务层。在 LTSSM 跳转到 L0 状态后,数据链路层交换 FC DLLP 进行流控初始化。此外,在允许过程中,PCIe Link 双方的数据链路层交换 PM DLLP 实现功耗管理及电源管理。
     

6.[20240104]:ECRC vs LCRC

TL层的TLP报文有个ECRC,而DLL层对TLP会加上序列号和LCRC。两个CRC有何不同呢?

ECRC,End-to-End CRC,由事务层生成及解析,是可选的,是 TLP 的组成部分,Size 4B,位于 Data Payload 之后。ECRC 始于 Requester,终于 Completer,不会被 Switch 等中间节点修改。ECRC 错误是不可纠正错误,若 Switch 发现 ECRC 出错,其记录错误并继续转发;若 Completer 发现 ECRC 出错,则上报错误请求系统处理。

  LCRC,Link CRC,由数据链路层生成及解析,是必选的,Size 4B,添加在 TLP 之后。LCRC 始于 PCIe 链路的发送端数据链路层,终于 PCIe 链路的接收端数据链路层,途径 Switch 时需要进行校验并重新进行计算填充。LCRC 是可纠正错误,若接收端检测到 LCRC 出错,其请求重发该 TLP。

7.PCIe 配置空间 Size 是多少?

  PCI 设备的配置空间为 256B,PCIe 设备的增强配置空间为 4KB。PCIe 4KB 配置空间的前 256B 空间即 PCI 的配置空间。对于最大支持 256 Bus * 32 Device * 8 Function 的 PCIe 设备,其内存需要给该 PCIe 设备预留 4KB*256*32*8=256MB 作为配置空间。

8.[20240117]:NCBE(Non-Contiguous Byte Enable)

以上是spec中对于NCBE的原话。另外,TLP中feild开看,Address 字段低 2b 无效(默认 00b),Data Payload 为 DW 地址对齐。这一rule在VIP的constraint约束中也明确写了出来。

  •  Length = 1 DW,FBE 可以不连续(NCBE),LBE必须为0000。
    • FBE可以为:1010b, 0101b, 1001b, 1011b, 1101b
  • Length = 1 QW 且地址 QW 对齐,FBE 及 LBE 均可以不连续。(1 QW = 2 DW)
  • Length = 1 QW 但地址非 QW 对齐,或 Length ≥ 3 DW,FBE 与 LBE 之间的 1 必须连续。比如 FBE=1100b & LBE=0011b,比如 FBE=1000b & LBE=0111b。

实际,如果length=2DW/1QW,且非QW对齐,即bit2!=0【下面address[29:0]对应TLP中的address[31:2]】,FBE和LBE只可以取下面的值对。

9.[20240123]:Cannot initiate non-posted requests prior to receiving first CfgWr0.

这是从CDNS VIP里报出来的错误,意思是在收到第一笔CfgWr0 traffic之前不能发送non-posted request,如MRd_32。实际是因为没有做枚举,device还不知道自己的BDF或者说requesterID,因此不能发送traffic。这里CfgWr0也默认是frontdoor进行枚举寄存器配置。

10.[20240123]:Zero-Length Write/Read

  • Zero-Length Write
    • A Memory Write Request of 1 DW with no bytes enabled, 即Memory Write 类型tlp中只有1DW的data,且length字段为1,并且tlp header中的First DW BE[3:0] 和Last DW BE[3:0]均为0。
    • Zero-Length Write has no effect at the Completer unless otherwise specified. 正常情况下Zero-Length Write不会对完成者造成任何影响,除非特别指定。例如:正常情况下,一颗芯片中的PCIe作为endpoint,收到Zero-Length Write时,此Zero-Length Write不会改写当前tlp中addr对应的寄存器(or RAM)的数值,也不会产生对应地址的写脉冲,更不会应该此写操作造成芯片功能的变化。A Memory Write 通常在特定的协议中去使用,已达到额外的效果,例如LN protocol。

  • Zero-Length Read

    • A Memory Read Request of 1 DW with no bytes enabled。即Memory Read 类型tlp中且length字段为1,并且tlp header中的First DW BE[3:0] 和Last DW BE[3:0]均为0。

    • Zero-Length Read may be used by devices as a type of flush Request. For a Requester, the flush semantic allows a device to ensure that previously issued Posted Writes have been completed at their PCI Express destination. To be effective in all cases, the address for the zero-length Read must target the same device as the Posted Writes that are being flushed. One recommended approach is using the same address as one of the Posted Writes being flushed.【Zero-Length Read 通常作为一种刷新操作,用于确保之前发起的Posted Writes已经被completer完成了。假设master在T0时刻已经发起mem_write(addrA),T1时刻发起zero_mem_rd(addA),T3时刻master收到对应的cpld。此时在T3时刻,master就知道了mem_write(addrA)已经被slave正确执行了。】

    •  If a Read Request of 1 DW specifies that no bytes are enabled to be read (First DW BE[3:0] field = 0000b), the corresponding Completion must specify a Length of 1 DW, and include a data payload of 1 DW.The contents of the data payload within the Completion packet is unspecified and may be any value。即对应cpl的长度必须指定为1DW,且必须包含1DW的data payload,并且data的数值没有要求,可以是任意值

11.[20240202]:Flow Control 初始化流程  

PCIe 流控初始化发生于物理层 LinkUp=1 之后、数据链路层 DLCMSM=DL_Init 状态时。

PCIe 流控初始化先后分为两个阶段:

FC_Init1 阶段: PCIe 设备先后重复发送 InitFC1-P、InitFC1-NP、InitFC1-Cpl 这 3 笔 FC DLLP 到对端设备,至少每 34us 发送一次,告知其 Rx Buffer 的 Size。直到接收到对端发来的 InitFC1 DLLP 之后才停止发送,并把对端的 Buffer Size 保存起来。
FC_Init2 阶段: PCIe 设备先后重复发送 InitFC2-P、InitFC2-NP、InitFC2-Cpl。此时的 FC DLLP 中不携带初始化 Credit 信息。
【由此可知:InitFC2 期间发送的 InitFC2 DLLP 不携带 Credit 信息,仅用以确认流控初始化是否成功。InitFC1 期间不能发送 TLP,InitFC2 期间可以。】

12.[20240223]:BDF再识

  • Bus - 总线

PCIe最多支持256个总线编号(Bus Number).BUS0通常会分配给Root Complex(其实是分配给RC内部的虚拟总线)。

从功能逻辑上来讲,我们可以认为 Root Complex 内部包含了一个 Host/PCI 桥、一个虚拟总线和多个虚拟 P2P 桥。Host/PCI 桥用于 Root Complex 和 CPU 的连接;虚拟总线用于 Root Complex 内部的数据传输;虚拟 P2P 桥用于创建新的总线,以连接外部设备(Switch 或者 Endpoint)。

  • Device - 设备 

PCIe 协议允许每条总线最多连接 32 个设备。鉴于 PCIe 设备之间是端到端(Point-to-Point)连接的,所以除了 Root Complex 和 Switch 内部的虚拟总线之外,其它 PCIe 总线上只能连接 1 个新设备。因此,除了 Root Complex 和 Switch 内部的虚拟设备之外,其他设备的编号都是 0,如下图所示:

  • Function - 功能 
  • Function 是指 PCIe 设备内部相对独立的功能逻辑,每个 Function 具有完全独立的配置空间(Configuration Space)。

例如,在一个 PCIe 设备中可以有多个 Function,其中一个 Function 具备网卡功能,另一个 Function 具备 USB 控制器功能,还有其它的 Function 具备显卡功能。

  • 每个 PCIe 设备都必须包含 Function 0。
  • 当 PCIe 设备包含多个 Function 时,Function 的编号不要求是连续的。

例如,某个 PCIe 包含 3 个 Function,那么可以编号为 Function 0、Function 2 和 Function 7。

13.[20240223]:Unused Base and Limit Registers in BAR space

有些时候,并不会同时用到 P-MMIO、NP-MMIO、IO 三种地址空间。实际上,PCIe 协议并不建议 IO 地址空间。
​当某种类型的地址空间没有被 Endpoint 使用时,它所对应的 Switch 的 Base 和 Limit 该怎么配置?没办法它们配置成全 0,因为 Base 的低地址位总是0s,而 Limit 的低地址为总是 Fs,在把 Base 和 Limit 的其他位设置为 0 的时候,Base 和 Limit 的低地址位就会构成有效的地址段。因此,在这种情况下,需要把 Base 寄存器配置成比 Limit 寄存器更高的地址。例如,IO 地址空间未被使用时,可以把对应的 Base 设置为 F0h,Limit 设置为 00h。鉴于 Base 高于 Limit,此时 Switch 就会察觉到这一个非法的配置,继而认为 IO 地址段并未被使用。

14.[20240223]: PCIe配置空间--Command 寄存器 

 在type0和type1 header中Command寄存器位置如下所示

Command寄存器结构如下:

 

对于 PCIe,只有 Bit 0/1/2/6/8/10 是有效的,其他必须配置为 0 。

  • IO Space Enable
    • 该位用于控制设别如何响应 I/O 空间的访问请求。
    • 该位为 0 时,设备不会响应 I/O 空间访问请求。
    • 该位为 1 时,设备正常响应 I/O 空间访问请求。
    • 复位后,默认为 0 。
  • Memory Space Enable
    • 该位用于控制设别如何响应 Memory 空间的访问请求。
    • 该位为 0 时,设备不会响应 Memory 空间访问请求。
    • 该位为 1 时,设备正常响应 Memory 空间访问请求。
    • 复位后,默认为 0 。
  • Bus Master Enable
    • Endpoint
      • 该位决定了设备能否发出 Memory 读写请求、I/O 读写请求。
      • 该位为 1 时,允许设备发出 Memory 读写请求、I/O 读写请求。
      • 该位为 0 时,不允许设备发出 Memory 读写请求、I/O 读写请求。
      • MSI/MSI-X 中断消息属于 Memory 写请求,因此该位为 0 时,设备无法产生 MSI 或 MSI-X 中断消息。
      • 除了 Memory 读写请求和 I/O 读写请求,其他类型的请求不受该位控制。
      • 默认值为 0。
    • Root Port & Switch
      • 该位决定了设备能否将 Memory 读写请求和 I/O 读写请求转发至上游方向(Upstream Direction)。
      • 该位为 0 时,Root Port 或者 Switch 的 Downsteam 端口收到 Memory 请求和 I/O 请求后,应该按照 Unsupported Requests(UR)处理。对于收到的 Non-Posted 请求,应该向 Requester 发送一个 UR Completion 状态位置位的 Completion。
      • 该位并不会影响 Completion 的转发。
      • 除了 Memory 读写请求和 I/O 读写请求,其他类型的请求不受该位控制。
      • 默认值为 0。
  • Parity Error Response
    • 该位决定了是否使用 status 寄存器的 Master Data Parity Error 位对 Poisoned TLP 进行记录。
    • 该位为 1时,如果有 Poisoned TLP,则将 status 寄存器的 Master Data Parity Error 位设置为 1。
  • SERR# Enable
    • 对于 Endpoint,该位为 1 时,设备可以向 Root Complex 发送 ERR_FATAL 和 ERR_NONFATAL 错误消息。
    • 对于 Switch,该位为 1 时,设备可以将 ERR_FATAL 和 ERR_NONFATAL 错误消息转发到上游总线。
    • ERR_COR 消息不受该位控制。
  • Interrupt Disable
    • 该位用于控制设备能否产生 INTx 中断。
    • 该位为 1 时,不允许设备产生 INTx 中断。
    • 默认值为 0。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值