基于 PCI Express Base Specification 整理,涵盖事务层 (Transaction Layer)、数据链路层 (Data Link Layer) 和物理层 (Physical Layer) 的报文格式。目录1. PCIe 三层架构概述1.1 PCIe 四种地址空间2. TLP 事务层报文2.1 通用 TLP 头部格式DW0:Fmt/Type/TC/Attr/TH/TD/EP/AT/LengthDW1 及其他字段:ReqID/Tag/BE/Status/ByteCount2.2 Fmt 与 Type 编码表2.3 各类型 TLP 头部详解2.4 TLP Prefix2.5 TLP Digest (ECRC)2.6 TLP 大小限制与对齐规则3. DLLP 数据链路层报文3.1 DLLP 通用格式3.2 DLLP 类型编码4. Ordered Sets 物理层报文5. 流量控制机制6. 关键字段说明7. 典型事务交互示例7.1 NPU DMA 事务7.2 MMIO 寄存器访问7.3 配置空间枚举7.4 消息与中断1. PCIe 三层架构概述PCIe 采用分层的报文传输架构,每一层在发送端封装上一层的数据,在接收端解封装:┌─────────────────────────────────────────────┐ │ Device Core │ │ ┌───────────────────────────────────────┐ │ │ │ Transaction Layer (事务层) │ │ │ │ ─ TLP 组装 / 拆解 │ │ │ │ ─ 事务排序、流量控制 │ │ │ └───────────┬───────────────────────────┘ │ │ │ TLP │ │ ┌───────────▼───────────────────────────┐ │ │ │ Data Link Layer (数据链路层) │ │ │ │ ─ Sequence Number / LCRC 附加 │ │ │ │ ─ DLLP 生成 (Ack/Nak, 流控) │ │ │ │ ─ 重传机制 │ │ │ └───────────┬───────────────────────────┘ │ │ │ │ │ ┌───────────▼───────────────────────────┐ │ │ │ Physical Layer (物理层) │ │ │ │ ─ 8b/10b 或 128b/130b 编码 │ │ │ │ ─ Ordered Sets (TS1/TS2, SKP 等) │ │ │ │ ─ Lane 绑定与去偏移 │ │ │ └───────────────────────────────────────┘ │ └─────────────────────────────────────────────┘层数据单元主要功能Transaction LayerTLP (Transaction Layer Packet)读写请求、完成、消息Data Link LayerDLLP (Data Link Layer Packet)应答/重传、流控信用、电源管理Physical LayerOrdered Sets / PLP链路训练、时钟补偿、电气空闲1.1 PCIe 四种地址空间PCIe 协议定义了四种地址空间,每种对应不同的 TLP 事务类型和路由方式。理解这四类空间是理解 TLP Type 编码的前提。┌───────────────────────────────────────────────────────────────────┐ │ PCIe 四种地址空间 │ ├──────────────┬──────────────┬──────────┬──────────────────────────┤ │ 地址空间 │ TLP Type │ 路由方式 │ 用途 │ ├──────────────┼──────────────┼──────────┼──────────────────────────┤ │ Memory │ MRd / MWr │ 地址路由 │ MMIO 寄存器访问、DMA 数据 │ │ │ AtomicOp │ │ 搬移、GPU 显存访问 │ ├──────────────┼──────────────┼──────────┼──────────────────────────┤ │ I/O │ IORd / IOWr │ 地址路由 │ 遗留 PCI 设备的 I/O BAR │ │ │ (已废弃) │ │ 原生 PCIe 设备不使用 │ ├──────────────┼──────────────┼──────────┼──────────────────────────┤ │Configuration │CfgRd / CfgWr │ ID 路由 │ 设备枚举 (Bus/Dev/Func) │ │ │(Type0/Type1) │ │ BAR 配置、Capability 操作 │ ├──────────────┼──────────────┼──────────┼──────────────────────────┤ │ Message │ Msg / MsgD │ 隐式路由 │ 中断 (MSI/MSI-X)、错误 │ │ │ │ (按类型) │ 上报、PME、电源管理 │ └──────────────┴──────────────┴──────────┴──────────────────────────┘Memory 空间是 PCIe 的主力。所有设备寄存器都通过 MMIO 映射到系统物理地址空间,CPU 用load/store指令即可访问,RC 自动将内存地址空间的访问翻译为 MRd/MWr TLP。DMA 引擎、GPU 的大批量数据搬移同样走 Memory 事务。它使用地址路由——Switch 根据 TLP 中的目标地址查 Base/Limit 寄存器决定往哪个下游端口转发。I/O 空间继承自 PCI 时代。传统 PCI 设备可以申请 I/O BAR,x86 上通过inb/outb等专用 I/O 指令访问。PCIe 规范已明确要求原生 PCIe 设备不使用 I/O BAR,I/O TLP 仅保留用于桥接老式 PCI/PCI-X 设备。它同样走地址路由,但地址空间是独立的 16-bit I/O 端口空间而非内存地址空间。Configuration 空间是 PCIe 设备枚举的根基。它不靠地址路由,而是靠ID 路由——按 Bus/Device/Function 编号逐级转发。这就决定了它不能被 Memory 事务取代:Switch 看不懂 Memory 地址里的 BDF 编号,但 Configuration TLP 的头部里有显式的 Bus Number 字段。Type 0 发给目标 Endpoint,Type 1 用于跨 Switch 的配置访问(到达目标总线时由 Switch 转为 Type 0)。Message 空间是 PCIe 的设计亮点之一。PCI 总线有很多独立的物理边带信号线——中断(INTA#)、系统错误(SERR#)、电源管理事件(PME#)——PCIe 没有这些引脚,因此把这些信号全部编码为 Message TLP,直接在数据通路上传输(带内消息)。Message 的隐式路由是它不能被 Memory 取代的关键:根据 Message Code,Switch 自动知道这个 TLP 应该发往 Root Complex、广播到所有设备、还是本地终止,不需要目标地址。核心结论:I/O 事务被 Memory(MMIO)取代,但 Configuration 和 Message 各自保留了 Memory 无法替代的路由机制。2. TLP 事务层报文TLP 是 PCIe 协议的核心,承载所有内存读写、I/O、配置空间访问和消息事务。TLP 封装过程┌── 事务层 (Transaction Layer) ─┐ 发送端: Data ──► [TLP Header] + Data + [ECRC] │ ▼ ┌────── 数据链路层 (Data Link Layer) ────────┐ 链路层不加 Header, Seq# │ TLP Header │ Data │ ECRC │ LCRC 只加 Seq# 前缀和 2B └────────── 整个 TLP ────────────┘ 4B LCRC 后缀 │ ▼ ┌───────────── 物理层 (Physical Layer) ────────────┐ STP │ Seq# │ TLP Header │ Data │ ECRC │ LCRC │ END 1B 2B 1B 接收端: 各层反向解封装,逐层校验 Seq# / LCRC / ECRC 链路层查 LCRC → 错了发 Nak 重传 事务层查 ECRC → 错了上报错误封装元素添加层大小作用TLP Header事务层3 DW (12B) 或 4 DW (16B)事务类型、地址、路由信息ECRC事务层1 DW (4B),可选端到端完整性(跨 Switch 不变)Seq#数据链路层2BAck/Nak 重传机制的序列号LCRC数据链路层4B链路完整性,逐跳校验STP / END物理层各 1B帧定界(K-code 控制字符)2.1 通用 TLP 头部格式TLP 头部有3-DW (12 字节)和4-DW (16 字节)两种长度,由 Fmt 字段选择。3-DW Header (32-bit 地址): Byte 0 1 2 3 ┌─────────┬────────┬─────────┬─────────┐ │R Fmt Typ│TH TD EP│ AT │ Len│R TC Attr│ DW 0 ├─────────┴────────┴─────────┴─────────┤ │ Requester-specific │ DW 1 (Requester ID / Tag / Last DW BE / 1st DW BE) ├──────────────────────────────────────┤ │ Address [31:2] │ DW 2 (32-bit 地址) └──────────────────────────────────────┘ 4-DW Header (64-bit 地址): Byte 0 1 2 3 ┌─────────┬─────────┬─────────┬─────────┐ │R Fmt Typ│TH TD EP │ AT │ Len│R TC Attr│ DW 0 ├─────────┴─────────┴─────────┴─────────┤ │ Requester-specific │ DW 1 (Requester ID / Tag / Last DW BE / 1st DW BE) ├───────────────────────────────────────┤ │ Address [63:32] │ DW 2 (地址高 32 位) ├───────────────────────────────────────┤ │ Address [31:2] │ DW 3 (地址低 32 位) └───────────────────────────────────────┘字节序:PCIe 采用小端序(little-endian)。每个 DW 内,Byte 0(bits 7:0)最先在链路上发出,Byte 3 最后。每个字节内 bit 0(LSB)先发。图中从左到右 = 线上传输顺序。TLP Header 字段总览DW 0(Byte 0 先发 ──────────────────────────────────────────► Byte 3 最后发,小端序): ┌──┬────┬─────────┬──┬──┬──┬──┬──────┬──┬──────┬──┬───────┬──────────┐ │R │Fmt │ Type │TH│TD│EP│R │ AT │R │ TC │R │ Attr │ Reserved │ │1 │ 2 │ 5 │1 │1 │1 │1 │ 2 │1 │ 3 │1 │ 3 │ 8 │ │7 │6:5 │ 4:0 │15│14│13│12│11:10 │23│22:20 │19│18:16 │ [31:24] │ └──┴────┴─────────┴──┴──┴──┴──┴──────┴──┴──────┴──┴───────┴──────────┘ Byte 0 [7:0] Byte 1 [15:8] Byte 2 [23:16] Byte 3 [31:24] DW 1 (请求 TLP): ┌────────────────────┬──────────────────────┬──────────────────────┐ │ Requester ID │ Tag │ Last BE │ First BE │ │ [31:16] │ [15:8] │ [7:4] │ [3:0] │ └────────────────────┴──────────────────────┴──────────────────────┘ DW 1 (Completion TLP): ┌────────────────────┬───────┬──────────┬──────────────────────────┐ │ Completer ID │Status │ BCM │ Byte Count │ │ [31:16] │[15:13]│ [12] │ [11:0] │ └────────────────────┴───────┴──────────┴──────────────────────────┘ DW 1 (Message TLP): ┌────────────────────┬──────────────────────┬──────────────────────┐ │ Requester ID │ Tag │ Message Code │ │ [31:16] │ [15:8] │ [7:0] │ └────────────────────┴──────────────────────┴──────────────────────┘ DW 2-3: 地址 / 路由信息 (取决于事务类型和 Fmt) 字段速查: Fmt[6:5] 头部长度 + 有无数据 AT[11:10] IOMMU 地址翻译类型 Type[4:0] 事务类型 TC[22:20] 服务质量优先级 TH[15] 预取提示 Attr[18:16] NoSnoop / RelaxedOrd / IDO TD[14] ECRC 存在标志 Len[9:0] 数据负载长度 (DW) EP[13] 数据已损坏标记字段所属位宽位置一句话作用DW0 Byte 0(先发)FmtDW02[6:5]头部长度 + 有无数据TypeDW05[4:0]事务类型(MRd/MWr/Cfg/Msg/Cpl…)DW0 Byte 1THDW01[15]数据处理提示(预取/缓存策略)TDDW01[14]尾部是否有 ECRC