是否可以找到与特定中断相关的MSI功能结构的位置?具体来说,我需要知道写入时触发该中断的PCI地址。
可以使用pci_alloc_irq_vectors(9)函数轻松地初始化MSI中断,但这仅提供了irq编号,而没有引用功能结构。
作为参考,本文档中描述了功能结构:https://pcisig.com/sites/default/files/specification_documents/msi-x_ecn.pdf
答案 0 :(得分:1)
听起来您希望自己能够写入该值并生成中断。这不是MSI的真正工作方式(尽管仍有可能)。使用MSI(或MSI-X),您基本上是在对PCI设备进行编程,使其具有一个地址,该地址应在该设备上生成数据,并在发生中断时将数据值写入该设备。
不能保证AFAIK可以通过写地址自己触发相同的中断。尽管如此,MSI中给出的地址通常仍是由中断控制器(通常实现为PCI设备本身)控制的地址空间内的位置,并且数据值告诉中断控制器触发哪个中断。因此,很可能您可以将相同的值写入相同的物理内存地址,从而产生相同的中断。
无论如何,假设您知道哪个PCI设备正在生成中断,则可以查找MSI功能结构,因此可以读取其编程内容。这很简单。
PCI功能(随设备而异)被组织到设备配置空间内的链表中。列表的开头始终由设备配置空间中偏移量0x34处的字节给出。该字节值为您提供了第一个功能数据结构空间内的偏移量。
每个功能由一个字节的能力类型ID,一个字节的“下一个功能”指针,以及该功能特定的变长数据组成。因此,从偏移量0x34开始,您可以跳过这些功能。
要在任何Linux机器上查看此操作的实际效果,可以运行lspci
。赋予它-v
标志(可以重复获取越来越多的细节)给您带注释的配置空间视图。您还可以添加-xxxx
以获取配置空间的完整十六进制转储,因此您可以自己遵循功能链。 (顺便说一句,您需要使用sudo
运行它以获取所有功能详细信息。)
内核中有一些接口将为您完成此操作:您可以使用pci_find_capability
查找所需功能的偏移量。当然,您也可以自己找到功能,方法是从pci_read_config_byte
开始,偏移量为0x34,然后按照列表进行操作。
一旦找到MSI功能,就可以根据上面引用的文档来解释其内容。您将使用pci_read_config_byte
(/ word
/ dword
)访问功能数据结构的各个部分。