PCIe 基础知识
建立完整的知识框架
拓扑结构
PCIe采用层次化的树形拓扑结构,由Root Complex(根复合体)、Switch(交换器)、Bridge(桥接器)和Endpoint(终端设备)组成。
总线号分配示例
Root Complex (Bus 0)
├── Root Port 0 → Switch A (Bus 1)
│ ├── Downstream Port 0 → GPU (Bus 2)
│ ├── Downstream Port 1 → NVMe SSD (Bus 3)
│ └── Downstream Port 2 → Switch C (Bus 4)
│ └── Endpoint (Bus 4-Sub)
└── Root Port 1 → Switch B (Bus 5)
├── Downstream Port 0 → 网卡 (Bus 6)
└── Downstream Port 1 → AI加速卡 (Bus 7)
Root Complex (RC)
Root Complex是PCIe层次结构的根节点,连接CPU/内存子系统和PCIe域。它负责:
- 发起配置访问
- 处理来自Endpoint的内存请求
- 管理中断路由
- 提供时钟和电源管理
Switch
Switch是多端口设备,用于扩展PCIe拓扑:
- 一个上游端口连接RC或其他Switch
- 多个下游端口连接Endpoint或下游Switch
- 执行路由功能,转发TLP
Endpoint
Endpoint是终端设备,可以是:
- Legacy Endpoint:传统PCI设备
- PCIe Endpoint:原生PCIe设备
- 支持Memory、I/O、配置事务
传统 PCI 采用共享总线架构,所有设备分时使用同一条总线,存在三个根本问题:
1. 带宽瓶颈:所有设备共享一条总线的带宽,设备越多每个设备分到的带宽越少。
2. 时钟频率受限:共享总线需要满足所有设备的最差时序约束,无法提升频率。PCI 最高 66MHz,PCIe Gen1 就达到 2.5GHz。
3. 扩展性差:增加设备会增加总线负载电容,信号完整性恶化。
PCIe 采用点对点(Point-to-Point)架构:每个设备独享一条 Link,带宽不共享;Link 是独立的串行差分对,时钟频率可以远高于并行总线;需要更多设备时通过 Switch 扩展,每个下游端口又是一条独立的点对点 Link。
这个设计权衡的代价是:需要 Switch 芯片来扩展拓扑,增加了硬件成本和延迟。但换来的带宽提升和扩展灵活性远超这个代价。
协议分层模型
PCIe协议采用分层架构:发送方自上而下逐层封装,接收方自下而上逐层解析,两侧的同层之间构成对等协议——每层只与对端的同层"对话"。
一个 TLP 是如何被逐层"套上"开销的
发送方向下每经过一层,就多封装一层开销;接收方向上则逐层校验、剥离。下图是一个 Memory Write TLP 的完整封装结构:
接收方向完全相反:物理层先剥离帧符号并解码,数据链路层校验 LCRC / 序列号(失败则触发 Nak 重传),最后事务层解析 Header。
事务类型
PCIe定义了多种事务类型,满足不同的访问需求。
| 类型 | 读写 | 地址空间 | 用途 |
|---|---|---|---|
| Memory | Rd/Wr | Memory空间 | 大块数据传输,最常用 |
| I/O | Rd/Wr | I/O空间 | 传统设备兼容 |
| Configuration | Rd/Wr | 配置空间 | 设备枚举和配置 |
| Message | 仅写 | 无地址 | 中断、错误报告 |
Memory事务详解
Memory事务是最常用的事务类型,支持大块数据的高效传输。
Memory Read (MRd)
- 请求者发起读请求
- 指定地址、长度、标签
- 完成者返回CplD(带数据的完成包)
- 支持拆分事务
Memory Write (MWr)
- 请求者发送数据和地址
- Posted事务,无需完成包
- 提高写入效率
- 可选原子操作
地址路由方式
延伸阅读:PCIe Switch 专题——Switch 的路由机制、总线号分配与端口仲裁的完整展开。
流量控制
PCIe采用基于信用的流量控制机制,防止发送方淹没接收方。
※ 图中计数为初始信用值示例,实际数值由接收方在链路训练后通告。
信用生命周期:以 PH 信用为例(初始 10 个)
信用类型
| 信用类型 | 用途 | 单位 |
|---|---|---|
| PH (Posted Header) | Posted请求头缓存 | Header个数 |
| PB (Posted Data) | Posted数据缓存 | 数据单元(4DW) |
| NPH (Non-Posted Header) | Non-Posted请求头缓存 | Header个数 |
| NPD (Non-Posted Data) | Non-Posted数据缓存 | 数据单元 |
| CplH (Completion Header) | 完成包头缓存 | Header个数 |
| CplD (Completion Data) | 完成数据缓存 | 数据单元 |
在串行点对点链路上,发送方无法知道接收方的缓冲区状态。如果发送方持续发送,接收方缓冲区溢出后会丢包,而丢包重传的开销极大。
PCIe 选择信用机制而非停等协议(发一个等确认再发下一个),原因是:
1. 流水线效率:信用机制允许发送方在未收到确认前继续发送多个 TLP,充分利用链路带宽。停等协议在长链路下效率极低。
2. 细粒度控制:将信用分为 Header 和 Data 两类,因为接收方需要为 Header 和 Data 分配不同大小的缓冲区。一个 64B 的 Memory Write 消耗 1 个 Header 信用和若干 Data 信用。
3. 多 VC 独立管理:每个虚拟通道(VC)有独立的信用池,避免一个低优先级流量堵死高优先级流量。
代价是:发送方需要维护 6 类 × N 个 VC 的信用计数器,硬件复杂度增加。但对于高速串行链路来说,这是值得的。
中断机制
PCIe支持多种中断方式,从传统的INTx到现代的MSI/MSI-X。
INTx (传统中断)
与传统PCI兼容,使用INTA#/INTB#/INTC#/INTD#信号线。
- 支持4条中断线
- 多个设备可共享中断线
- 需要中断控制器仲裁
- 性能较低,现代设备很少使用
MSI (消息信号中断)
通过Memory Write TLP发送中断消息,无需专用信号线。
- 支持1-32个中断向量
- 每个向量可独立配置目标CPU
- 避免中断共享,提高性能
- 适用于大多数设备
MSI消息格式:
┌─────────────────────────────────┐
│ Address: 0xFEExxxxx │
│ Data: Vector | CPU ID | etc │
└─────────────────────────────────┘
MSI-X (增强型MSI)
MSI的增强版本,支持更多向量和更灵活的配置。
- 支持最多2048个向量
- 每个向量独立地址/数据
- 向量配置存储在设备内存
- 支持动态向量掩码
适用于高性能设备:NVMe SSD、高速网卡等
延伸阅读:软硬件架构全景图中的中断路径——INTx 与 MSI/MSI-X 在系统硬件中如何经 IO-APIC / LAPIC 送达 CPU。
错误处理
PCIe定义了完善的错误检测、报告和恢复机制:错误分为可纠正与不可纠正(非致命/致命)两大类,由 AER(高级错误报告)能力结构记录并通过中断通知软件。完整内容见专页: