2

您好我正在编写一个内核并计划对 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,消息地址是否会与本地 APIC 内存映射冲突?虽然 FEE00000~FEE00010 的地址是保留的。

另外,MDR中的向量编号是否与IDT向量编号相对应。换句话说,如果我设置 MAR = 0xFEE0000C (Destination ID = 0, Using logical APIC ID) and MDR = 0x0032 (edge trigger, Vector = 50) 并启用 MSI 中断,那么一旦设备发出中断 CPU 就会相应地运行IDT[50]指向的函数?之后我将 0h 写入 EOI 寄存器以结束它?

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

非常感谢!

4

1 回答 1

3

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

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

在 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 的低位替换为不同的值。

于 2019-10-04T07:31:20.710 回答