drivers - 从 MSI 能力结构中读取地址
问题描述
是否可以找到与特定中断关联的 MSI 能力结构的位置?具体来说,我需要知道写入时触发该中断的 PCI 地址。
可以使用 pci_alloc_irq_vectors(9) 函数轻松初始化 MSI 中断,但这只是提供了 irq 编号并且没有对能力结构的引用。
作为参考,本文档中描述了能力结构:https ://pcisig.com/sites/default/files/specification_documents/msi-x_ecn.pdf
解决方案
听起来您希望能够自己编写该值并生成中断。这并不是 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
) 访问能力数据结构的各个部分。
推荐阅读
- javascript - SocketIO- 具有空值的对象键未在客户端中显示
- .net - 错误 ADB0020: Mono.AndroidTools.IncompatibleCpuAbiExceptiopn: 该包不支持此设备的 CPU 架构
- javascript - 圆形进度条 - CSS/JS
- amazon-web-services - 我们可以使用 Amazon Elasticsearch Service 和 log4Net 在 MVC 应用程序中存储应用程序日志吗
- python - 将我的 python 会话转换为颤动会话
- python - 如何根据令牌数量批处理 tf 数据集?
- iis - 应该使用什么代码为 IIS 10 中的字符编码设置服务器 http 标头?
- c++ - 我的包装库 .dll 是否依赖于我链接的外部 .lib 文件?
- excel - 我正在尝试使用 Cypress 工具将一些数据写入 Excel 文件,但出现错误
- python-3.x - Django主键问题