PCI+Express体系结构导读笔记(二)-MSI及MSI-X
MSI及MSI-X中断机制
为什么提出这两个概念
在这一篇中讲的原因为: MSI/MSI-X机制的引入解决了传统Line-based Interrupt机制的限制, 包括:
- 无需经过I/O APIC转发中断,直接通过PCI/PCIe Memory Write Transaction向CPU发送中断,效率更高
- 每个PCI Function可以支持分配多个中断向量,满足同一个设备有多个不同中断请求的需要
- 当分配多个中断向量给同1个PCI Function时,提供按中断向量进行屏蔽的功能,更为灵活
在PCI中, MSI/MSI-X为可选功能, PCIe必须要修支持64位的MSI或者MSI-X, 一个PCIe可以同时支持 INT#x/MSI/MSI-X, 但驱动只用启动其中一个, MSI/MSI-X以Capability的形式存在于PCIe中
MSI/MSI-X Capability结构
MSI结构
MSI的结构可以由四种方式组成, 分别为:
- 32位的Message结构
- 64位的Message结构
- 32位带中断的Masking结构
- 64位带中断的Masking结构
MSI报文可以使用32位或者64位的地址, 并且可以使用Masking(掩码)机制使能或禁止某个中断, MSI Capability结构如下:
MSI的Capability ID值为0x05, PCIe设备中每一个Capability结构都有唯一的ID号, Next Pointer指向下一个Capability, 其余各字段的解释如下:
Message Control: 存放当前PCIe设备使用MSI进行中断请求的状态域控制信息, 每一位代表的意思如下表:
Bits 定义 描述 15:9 Reserved 保留,始终为0 8 Per-vector Masking Capable 为1, 则为带中断的Masking, 设备初始化时设置 7 64 bit Address Capable 为1, 则支持64位的地质结构, 为0则支持32位, 设备初始化时设置 6:4 Multiple Message Enable 表示软件分配给当前PCIe设备的中断向量数目, 驱动根据Multiple Message Capable确定这个值, 资源不紧张则相等, 资源紧张可能小于 3:1 Multiple Message Capable 驱动只读, 表示当前PCIe设备可以使用几个中断向量号, 0~5分别代表使用1, 2, 4, 8, 16, 32个中断向量,其余值保留 0 MSI Enable MSI中断机制使能位, 为1且MSI-X的Enable为0, 则使用MSI中断机制, 此时Legacy中断机制被禁止. 如果两个中断机制都禁止, 则使用INT#x中断消息报文发出/结束中断请求 Message Address: 存放MSI存储器写事务的目的地址的低32位, 1~0位始终为0, 不使用
Message Upper Address: 如果为64位, 则该值为MSI存储器写事务的目的地址的高32位
Message Data: 存放MSI报文使用的数据, 不同处理器对该字段的规则不同, 如果Multiple Message Enable不为0(支持多个中断请求), 则PCIe设备可以通过改变该字段的低位数据以发送不同的中断请求
Mask Bits: 由32位组成, 每一位代表一种中断请求, 为1代表该中断被屏蔽, 0代表启用
Pnending Bits: 对于驱动是只读位, 当Mask Bits对应位为1(屏蔽中断)时, 如果 PCIe 设备需要发送对应的中断请求时,Pending Bits 字段的对应位将被 PCIe 设备的内部逻辑置1, 如果Mask bits改写为0后, PCIe设备会发送MSI报文向处理器提交中断请求, 将对应位清0, 在驱动开发中, 有时需要联合使用Mask Bits与Pending Bits防止处理器丢弃中断请求.
MSI-X结构
引入MSI-X的主要原因是因为不需要中断向量号连续, 并且MSI-X支持更多的中断请求, MSI-X主要使用MSI-X Table存放该设备使用的所有 Message Address和 Message Data字段, 这个表格存放在BAR空间中, MSI-X结构如下:
MSI-X的Capability ID为0x11, Next Pointer指向下一个Capability地址, Message Control各bit定义如下:
Bits | 定义 | 描述 |
---|---|---|
15 | MSI-X Enable | 使能位, 是否启用MSI-X |
14 | Function Mask | 为1, 则所有中断被屏蔽, 为0, 则启用所有中断 |
10:0 | Table Size | 代表MSI-X Table的大小, 只读 |
- Table BIR(BAR Indicator Register), 该字段存放的是MSI-X Table在哪个BAR空间, 总共有3位, 0
5分别对应BAR05 - Table Offset, 存放的是MSI-X Table在对应BAR空间中的偏移
- PBA(Pending Bit Array) BIR, 该字段存放Pending Table在哪个BAR空间, 总共有3位, 0
5分别对应BAR05 - PBA Offset,存放的是Pending Table在对应BAR空间中的偏移
MSI-X Table
组成结构如下(DWORD代表32bit), 每一个Entry与一个中断请求对应:
- Msg Addr: MSI-X 存储器写事务的目的地址的低 32 位, 31:2有效, 可读写, 1:0始终为0, 只读,
- Msg Upper Addr: 该字段可读写,存放 MSI-X 存储器写事务的目的地址的高 32 位
- Msg Data: 可读写, 存放MSI-X报文使用的数据
- Vector Control: 只有第0位有效, 其他位保留, 为1 则代表不能使用该Entry提交中断请求, 为0代表可以, 复位时为0, 使用方法与MSI的Mask为类似
Pending Table
组成如下(QWORD代表64bit):
与MSI机制的Pending bits类似, 每一个Entry由64位组成, 一个bit对应一个中断, 在此不多赘述
x86中处理MSI-X中断请求
PCIe设备发出MSI-X中断请求的方法与发出MSI中断请求的方法类似, 都是像 Message Address所在的地址写Message Data字段包含的数据, 只不过Message Address和Message Data在MSI-X中放在了BAR空间. x86需要设置MSI-X Capability结构指向的Message Address和Message Data, 并使能MSI-X Enable位
Message Address与Message Data
x86处理器中, PCIe设备使用的Message Address与Message Data字段与PowerPC处理器(IBM开发的)不同
Message Address
在x86中, Message Address字段仍然保留PCI总线域的地址, 格式如下:
- 31-20, 存放FSB Interrupts存储器空间的基地址, 值位0xFEE
- 19-12, 保存目标CPU的ID号, 如果CPU的ID与该字段相等, 则目标CPU将会接受这个Interrupt Message
- 11-4, 保留
- 3(Redirection Hint Indication), 如果为0, 则表示Interrupt Message将直接发向与Destination ID字段相同的CPU, 如果为1, 则启用中断转发功能
- 2(Destination Mode), 表示在传递优先级低的中断请求时, Destination ID是否被翻译为Logical或者Physical APIC ID, x86处理器中APIC ID有三种模式, 分别为 Physical, Logical和Cluster ID模式
- 1-0, 为0
如果RH为1, DM为0, 则Destination ID使用Physical模式, 如果RH为1, DM为1, 则使用Logical模式, 如果RH为0, 则忽略DM
Message Data
31-16, 保留
15-14, 触发模式, 为0时使用边沿触发方式申请中断, 为1时使用低电平触发方式申请中断, 为2时使用高电平触发方式申请中断
13-11, 保留
10-8, 表示如何处理来自PCIe设备的中断请求, 如下:
值 模式 说明 0b000 Fixed Mode 中断请求将被Destination ID字段指定的CPU处理 0b001 Lowest Priority 中短请求将被优先级最低的CPU处理 0b010 SMI 必须使用边沿触发, Vector必须为0, 中断请求将被Destination ID字段指定的CPU处理 0b100 NMI 必须使用边沿触发, Vector和Trigger字段被忽略, 中断请求将被Destination ID字段指定的CPU处理 0b101 INIT Vector和Trigger字段被忽略, 中断请求将被Destination ID字段指定的CPU处理 0b111 INTR 使用INTR信号传递中断请求并且使用边沿触发, MSI中断信息首先传递给中断控制器, 然后再通过INTR信号传递给CPU 7-0, Vector, 当使用了Fixed Mode或者 Lowest Priority模式时, 如果Vector字段有效, CPU收到中断请求后会使用Vector字段指定的中断向量处理这些中断请求, 当为其他值时, Vector字段无效
驱动程序初始化PCIe设备的MSI
如果PCIe设备支持MSI机制, 则驱动程序需要做以下事情:
- 设置设备MSI Capability结构的Message Address和Message Data字段, 如果设备支持64位地址空间, 则还需要设置Upper Address字段
- 置MSI Capabilities中的MSI Enable位有效, 使能MSI机制