关于 x86 LAPIC 系统上消息信号中断 (MSI) 的问题

Question about Message Signaled Interrupts (MSI) on x86 LAPIC system

您好,我正在编写内核并计划为 PCI 设备使用 MSI 中断。

但是,我对文档也很困惑。

我对MSI的理解如下:

从PCI设备的角度来看:

  1. 文件表明我 需要找到 Capabillty ID = 0x05 来定位 3 个寄存器:消息控制 (MCR)、消息地址 (MAR) 和消息数据 (MDR) 寄存器
  2. MCR 为 MSI 中断提供控制功能,
  3. MAR 提供PCI设备的物理地址 一旦中断发生将写入
  4. MDR 形成将写入物理地址的实际数据

从CPU来看:

  1. 文档显示消息地址寄存器包含 0xFEE 的固定顶部,后面是目标 ID (LAPIC ID) 和其他控制位,如下所示:

  2. 消息数据寄存器将包含以下信息,包括中断向量:


读完所有这些后,我在想如果 APIC_ID 是 0x0h Message Address 是否会与 Local APIC 内存映射冲突?虽然FEE00000~FEE00010的地址是保留的

另外,MDR中的vector number是否对应IDT vector number。换句话说,如果我将 MAR = 0xFEE0000C(目标 ID = 0,使用逻辑 APIC ID)和 MDR = 0x0032(边沿触发,向量 = 50)并启用 MSI 中断,那么一旦设备发出中断 CPU 会相应地 运行 IDT[50] 指向的函数吗?然后我写0h到EOI寄存器就结束了?

最后根据文档说MAR的高32位没有用?有人可以帮忙吗?

非常感谢!

您对如何在 PCI(或 PCIe)设备中检测和编程 MSI 的理解是正确的。* 消息地址控制目标(CPU 中断被发送到),而消息数据包含向量号。对于普通中断,消息数据的所有位都应为 0,但低 8 位除外,其中包含向量。 向量是 IDT 的索引,因此如果消息数据为 0x0032,则中断通过 IDT 的条目 50 传送。**

如果中断消息中的Destination ID为0,则MSI的Message Address与本地APIC的默认地址匹配,但不冲突,因为APIC只能由CPU 并且 MSI 只能由设备写入。

在 x86 平台上,消息地址的高 32 位必须为 0。这可以通过将消息地址的高位部分设置为 0 或通过将设备编程为使用 32 位消息地址 (在这种情况下,不使用上层消息地址寄存器)。 PCI 规范设计用于使用 64 位 MSI 地址的系统,但 x86 系统从不使用消息地址的高 32 位。

通过写入APIC_BASE MSR 重新编程APIC 基地址不会影响用于MSI 的地址范围;它始终是 0xFEExxxxx。


* 您还应该查看 MSI-X 功能,因为某些设备支持 MSI-X 但不支持 MSI。 MSI-X稍微灵活一点,难免会复杂一点。

** 使用 MSI 功能时,消息数据与消息数据寄存器 (MDR) 中的值不完全相同。 MSI 功能允许设备使用多个连续向量。当设备发送中断消息时,它会根据设备内部的中断原因将 MDR 的低位替换为不同的值。