【问题标题】:How can I get the corresponding MSI message in an interrupt?如何在中断中获取相应的 MSI 消息?
【发布时间】:2013-05-14 18:49:20
【问题描述】:
我们在 PCIe 卡上使用 FPGA。我能够保留适当的资源并且 MSI 中断正确触发。我的问题是从以下方面辨别中断源:我的 Linux 驱动程序只接收来自 FPGA 的不同中断源的单个 MSI 中断。因此,FPGA 人员通过总线发送 MSI 消息中编码的原因。
问题:
- 是否有可能访问此消息以便从我的 ISR 中的此帧中获取信息? (我知道我总是可以检查 FPGA 的中断状态寄存器,但是使用 MSI 消息会更优雅,并且可以避免额外的总线访问。)
- 如果 1 不可能,切换到 MSI-X 是否可以解决此问题,以便我可以直接获取信息? (我知道 MSI-X 是首选解决方案,但 FPGA 的人指定了 MSI)
感谢您的帮助!
【问题讨论】:
标签:
linux
driver
interrupt
pci-e
【解决方案1】:
希望您现在已经得到了您需要的答案,但我将尝试根据我对 Windows 驱动程序中的 MSI 的理解做出贡献,因为它是 PCIe 2.2 标准行为并且不应该有所不同。我正在编写一个 Windows PCIe 驱动程序来处理源自配置为 pcie 端点的 TI DM8168 的 MSI 中断。
当 FPGA 设备发出常规(非 msi-x)MSI 中断信号时,它实际上并没有发送“消息”,即必须填充数据结构并将其传输到某处。 MSI 是通过让 FPGA 将某个数据字值写入一个特定的内存位置来实现的,该内存位置通过 PCIe 在主机和设备之间共享。必须写入的特定内存位置和数据值由主机的总线管理器选择,它不能只是任意值。
总线管理器在 PCIe 配置空间中设置指向 MSI 内存位置的指针和要使用的特定预定义数据值,以便设备和主机都可以看到它们。 MSI 内存位置是物理总线地址,因此必须将其转换为设备和主机上的虚拟地址空间。
常规(非 msi-x)MSI 可以支持的最大消息数必须是 2 的整数幂,最大值为 32(即 1、2、4、8、16、32)。例如,如果 FPGA 支持 8 条消息,那么它将复制数据值(来自 PCIe 配置空间)并设置最低 3 位来指示 MessageID 编号(0-7),然后将这个新值写入 MSI 指针位置.如果 FPGA 支持 16 条消息,那么它必须修改数据值的低 4 位以指示消息 ID 号(0-15)。数据值的高位不得更改。
在您的 ISR 的接收端,您检查相同的最低位以查看哪个 MSI 已发出信号。没有与 MSI 本身相关的其他数据或 ACK;任何进一步的数据都是特定于实现的,必须从您和硬件团队商定的内存位置或寄存器中读取。在 Windows WDF 框架驱动程序中,此 MessageID 值已被屏蔽并作为参数提供给 EvtInterruptIsr 回调函数。我确定它在 linux 中是不同的。
我的回复有点晚了,但对于像我过去几周那样跨过这个话题的其他人来说,它可能在未来有用。