背景
我遇到了一个问题,在32位Linux内核上,我的PCIe驱动程序、多MSI和自定义硬件设备可以完美工作,现在我已经改用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触发;触发中断的双字写入只有在来自设备时才被识别为中断。
CPU可以通过写入本地APIC ICR寄存器以类似的方式启动中断。这只能从内核中完成,而且据我所知,目前还没有允许注入任意中断的内核服务。也许你可以在内核驱动程序中添加一个服务来完成这项工作
ICR的字段与MSI的字段不同,但它们是相似的。比较两者的文档以将其中一个映射到另一个应该很简单。