问题描述
背景
我遇到一个问题,即在32位Linux内核上,具有多MSI和自定义硬件设备的PCIe驱动程序可以完美运行,现在我移至64位iMX8MM CPU且MSI中断不再触发。驱动程序正确注册了中断,没有任何错误,我可以查看cat /proc/interrupts
的输出,并查看为我的驱动程序列出的所有MSI向量及其中断计数,该计数为零。有网桥,但是/sys/bus/pci/devices/<address>/msi_bus
有1
,因此已启用。 lspci -vv
中的所有内容按顺序排列,并且CONFIG_PCI_MSI
已应用于内核。我能够在PCIe设备上读取和写入内存缓冲区,因此通信正常进行,只是无法触发MSI中断。这与在32位CPU上运行的驱动程序代码完全相同,可以正常工作,并在新的64位CPU上重新编译。
问题
如何强制系统上的MSI中断以查看Linux是否会选择它并执行我的代码?从lspci -vv
中,我可以看到MSI地址,并且知道要写入的MSI向量值。那么,我该在系统上哪里写呢?我研究了/dev/mem
和其他可以希望做一个echo 0x1 > <address>
或其他命令行功能的地方,以编写一个值并触发它。我在哪里/如何写以触发特定的MSI中断?
解决方法
MSI不能由CPU触发;触发中断的dword写操作仅在来自设备时才被识别为中断。
CPU可以通过写入本地APIC ICR寄存器以类似方式启动中断。这只能从内核完成,据我所知,没有现有的内核服务允许注入任意中断。也许您可以将服务添加到内核驱动程序中。 (请注意,作为临时调试工具,将其留在驱动程序中非常不合适。)
ICR的字段与MSI的字段不同,但它们是相似的。比较两者的文档以将它们相互映射应该很简单。