文章目录
- PCIe中断机制:INTx / MSI / MSI-X
- 1. PCIe中断演进
- 2. INTx中断(传统中断)
- 2.1 信号线
- 2.2 特点
- 2.3 配置与使用
- 3. MSI(Message Signaled Interrupt)
- 3.1 工作原理
- 3.2 MSI Capability结构
- 3.3 MSI配置流程
- 3.4 多向量MSI
- 4. MSI-X(扩展MSI)
- 4.1 为什么需要MSI-X
- 4.2 MSI-X Capability
- 4.3 MSI-X Table结构
- 4.4 MSI vs MSI-X对比
- 5. 中断路由流程
- 5.1 INTx路由
- 5.2 MSI/MSI-X路由
- 6. 实际应用
- 6.1 NVMe SSD中断
- 6.2 PCIe网卡
- 6.3 DMA控制器中断
- 7. 中断编程要点
PCIe中断机制:INTx / MSI / MSI-X
1. PCIe中断演进
PCIe从传统中断演进到消息中断,共有三种中断方式:
| 中断类型 | 说明 | 引入版本 | 优点 |
|---|---|---|---|
| INTx | 传统边带中断信号 | PCIe兼容PCI | 简单,无需配置 |
| MSI | 带地址和数据的Memory Write | PCIe 1.0 | 节省引脚,支持多向量 |
| MSI-X | 扩展MSI,支持更多向量 | PCIe 3.0 | 最多2048个向量,表独立寻址 |
2. INTx中断(传统中断)
2.1 信号线
PCIe用带内消息替代传统边带中断线:
| PCI中断 | PCIe消息 | 说明 |
|---|---|---|
| INTA# | Assert_INTA | 中断声明 |
| INTB# | Assert_INTB | — |
| INTC# | Assert_INTC | — |
| INTD# | Assert_INTD | — |
| INTA#~INTD# | Deassert_INTx | 中断解除 |
2.2 特点
- 带内消息:在数据通道上传送,不需要额外引脚
- 共享中断:多个设备可共享同一INTx
- 边沿触发:消息声明+解除机制
- 虚拟线:Switch内部路由INTx消息
2.3 配置与使用
Command Register: [10] INTx Disable = 0 (启用INTx) Status Register: [3] Interrupt Status (读取可清除)3. MSI(Message Signaled Interrupt)
3.1 工作原理
MSI通过一个Memory Write TLP向预设地址写入预设数据,触发CPU中断:
设备 ──MWr(TLP)──> CPU中断控制器 Addr: 预设MSI地址 Data: 中断向量号3.2 MSI Capability结构
┌───────────────────────────────────────┐ │ Cap ID / Next Ptr / Message Control │ ├───────────────────────────────────────┤ │ Message Address (RC分配的MSI地址) │ ├───────────────────────────────────────┤ │ Message Data │ ├───────────────────────────────────────┤ │ Mask Bits (可选) │ ├───────────────────────────────────────┤ │ Pending Bits (可选) │ └───────────────────────────────────────┘3.3 MSI配置流程
- 读取MSI Capability的Message Control
- 确定支持的最大向量数(2/4/8/16/32)
- 从系统分配MSI Address
- 分配MSI Data(向量号)
- 使能MSI(设置MSI Enable位)
3.4 多向量MSI
CPU发起多个Memory Read请求,每个请求分配一个向量号:
向量0: MSI Addr + MSI Data[0] → CPU Core 0 向量1: MSI Addr + MSI Data[1] → CPU Core 1 ...4. MSI-X(扩展MSI)
4.1 为什么需要MSI-X
MSI的局限:
- 向量地址必须连续(同一地址+不同数据)
- 2048个向量限制(MSI最多32个)
MSI-X优势:
- 每个向量独立地址(表BIR + Offset)
- 最多2048个向量
- 向量可动态修改
4.2 MSI-X Capability
┌──────────────────────────────────────┐ │ Cap ID / Next Ptr / Message Control │ ├──────────────────────────────────────┤ │ MSI-X Table BIR (哪个BAR映射表) │ ├──────────────────────────────────────┤ │ MSI-X Table Offset (表起始偏移) │ ├──────────────────────────────────────┤ │ Pending BIR / Pending Offset │ └──────────────────────────────────────┘4.3 MSI-X Table结构
| 字段 | 位宽 | 说明 |
|---|---|---|
| Msg Addr[31:2] | 30bit | 中断地址(4B对齐) |
| Msg Upper Addr | 32bit | 高32位地址 |
| Msg Data | 16bit | 中断数据 |
| Vector Control | 16bit | Mask位 |
4.4 MSI vs MSI-X对比
| 特性 | MSI | MSI-X |
|---|---|---|
| 最大向量数 | 32 | 2048 |
| 向量地址 | 连续(同一Addr+不同Data) | 独立(表BIR+Offset) |
| 引入版本 | PCIe 1.0 | PCIe 3.0 |
| 中断共享 | 较差 | 好(每个设备独立向量) |
| 动态修改 | 否 | 是(可修改表项) |
5. 中断路由流程
5.1 INTx路由
EP设备 → Assert_INTA消息 → Switch → RC → RC将INTx转换为CPU中断向量 → CPU中断控制器 → 中断处理程序5.2 MSI/MSI-X路由
EP设备 → IMWr(Memory Write) → RC → CPU中断控制器 → 中断向量号 → CPU中断处理程序(直接定位到具体设备向量)6. 实际应用
6.1 NVMe SSD中断
NVMe使用MSI-X实现多队列:
- 每个I/O Queue Pair对应一个MSI-X向量
- 提交队列Doorbell → NVMe处理 → MSI-X通知CPU
6.2 PCIe网卡
网卡MSI-X配置:
- Tx完成向量:数据发送完成通知
- Rx完成向量:数据接收完成通知
- 管理向量:异常/错误通知
6.3 DMA控制器中断
DMA完成/异常通过MSI-X上报:
- Channel 0 Done vector
- Channel 0 Abort vector
- All Channels Done vector
- Transfer Error vector
7. 中断编程要点
// Linux MSI-X申请示例ret=pci_alloc_irq_vectors(dev,1,nvecs,PCI_IRQ_MSIX);if(ret<0){// 失败,尝试MSIret=pci_alloc_irq_vectors(dev,1,1,PCI_IRQ_MSI);}// 为每个向量申请中断for(i=0;i<nvecs;i++){irq=pci_irq_vector(dev,i);request_irq(irq,handler,0,name,data);}