PCI-E配置MSI中断流程解析
在传统的pci中断体系中,每一个pci总线上的设备被分配一个特定的中断号,然后当设备需要中断cpu时,设备直接发出int信号,然后在cpu的inta引脚拉低的时候将自己的中断号放在数据总线上,一切都要设备自己负责,这一切的缘由一部分就是因为pci的并行性,实现事务很复杂,而pcie是串行的,很容易定义协议包,因此很容易就实现了由root complex代理中断的功能,因此设备也就可以动态的分配独占的中断号了,因为中断号的分配完全是软件解决的,而不再像传统pci那样是硬件解决的了,软件的最大特点就是其灵活性,因此pcie更适合大量设备的环境,中断处理程序再也不需要大量遍历共享中断号的设备来确定中断源了。
在调试PCI-E的MSI中断前,需要先保证将传统中断调通,然后再调试这个。MSI中断究其本质,就是一个存储器读写事件。将MSI Address设置为内存中的某个地址(可以为64位),产生MSI中断时,中断源会在MSI Address所在的地址写入MSI Data。也就是说,如果有四条MSI中断线,就会依次写入Data、Data+1、Data+2、Data+3在内存中,依次来区分中断源设备。
设备端的定义
设备在自己的配置空间定义了自己的Capabilities list. 如果该设备支持MSI中断,在此capabilities list其中必定有一个节点的Capabilities ID=0x5D(0x5D 表明是MSI中断节点,其位置由设备自定义)

主控制器
1> 主控制器的工作是扫描到该设备后顺藤摸瓜,沿着Capabilities List找到MSI中断节点.

2> 主控制器给设备上的Address Register和data register俩寄存器赋值(以MPC8548E为例,该值是中断控制器的MSI中断寄存器定义决定);
设备
MSI中断, 本质上是一个内存写事务,该事务的payload部分都由MSI Capabilities 寄存器的值组成。

The key points here are:
1> Device prepare the capabilities list and the MSI node
2> Controller assign a value to the address register, which is inside the MSI capability node, and the value assigned is the kernel virtual address of the MSI interrupt description register inside the interrupt controller.
3> As well, the value assigned to the data register is defined by the MSI registers inside the interrupt controller.
Capabilites list 指针位于config space的 0x34 偏移量处,它是所有capabilities 节点的根节点。

和传统中断在系统初始化扫描PCI bus tree时就已自动为设备分配好中断号不同,MSI中断是在设备驱动程序初始化时调用pci_enable_msi() kernel API 时才分配中断号的。所以如果使用传统中断,在设备驱动程序中直接调用request_irq(pDev->irq, handler,...) 注册设备中断处理函数即可。而使用MSI中断的话,需先调用pci_enable_msi() 初始化设备MSI 结构,分配MSI中断号,并替换INTx中断号,再调用request_irq(pDev->irq, handler,...) 注册设备中断处理函数。除了卸载中断处理函数需要相应地调用pci_diable_msi()外,其他的处理完全相同。下面的Linux 内核代码详细描述了这一过程:
- int pci_enable_msi(struct pci_dev* dev)
- {
- int status;
- status = pci_msi_check_device(dev, 1, PCI_CAP_ID_MSI);
- if (status)
- return status;
- WARN_ON(!!dev->msi_enabled);
- if (dev->msix_enabled) {
- dev_info(&dev->dev, "can't enable MSI "
- "(MSI-X already enabled)\n");
- return -EINVAL;
- }
- status = msi_capability_init(dev);//此函数会配置设备MSI结构并分配替换MSI中断号
- }
- static int msi_capability_init(struct pci_dev *dev)
- {
- struct msi_desc *entry;
- int pos, ret;
- u16 control;
- ......
- msi_set_enable(dev, 0);
- pci_intx_for_msi(dev, 0);// disable INTx interrupts
- msi_set_enable(dev, 1);
- dev->msi_enabled = 1;
- dev->irq = entry->irq;
- return 0;
- }
PCI-E配置MSI中断流程解析的更多相关文章
- SpringBoot启动流程解析
写在前面: 由于该系统是底层系统,以微服务形式对外暴露dubbo服务,所以本流程中SpringBoot不基于jetty或者tomcat等容器启动方式发布服务,而是以执行程序方式启动来发布(参考下图ke ...
- EDKII Build Process:EDKII项目源码的配置、编译流程[三]
<EDKII Build Process:EDKII项目源码的配置.编译流程[3]>博文目录: 3. EDKII Build Process(EDKII项目源码的配置.编译流程) -> ...
- Django生命周期 URL ----> CBV 源码解析-------------- 及rest_framework APIView 源码流程解析
一.一个请求来到Django 的生命周期 FBV 不讨论 CBV: 请求被代理转发到uwsgi: 开始Django的流程: 首先经过中间件process_request (session等) 然后 ...
- HBase - 数据写入流程解析
本文由 网易云发布. 作者:范欣欣 本篇文章仅限内部分享,如需转载,请联系网易获取授权. 众所周知,HBase默认适用于写多读少的应用,正是依赖于它相当出色的写入性能:一个100台RS的集群可以轻松 ...
- EurekaClient自动装配及启动流程解析
在上篇文章中,我们简单介绍了EurekaServer自动装配及启动流程解析,本篇文章则继续研究EurekaClient的相关代码 老规矩,先看spring.factories文件,其中引入了一个配置类 ...
- Session (简介、、相关方法、流程解析、登录验证)
Session简介 Session的由来 Cookie虽然在一定程度上解决了"保持状态"的需求,但是由于Cookie本身最大支持4096字节,以及Cookie本身保存在客户端,可能 ...
- Java开发学习(二十三)----SpringMVC入门案例、工作流程解析及设置bean加载控制
一.SpringMVC概述 SpringMVC是隶属于Spring框架的一部分,主要是用来进行Web开发,是对Servlet进行了封装.SpringMVC是处于Web层的框架,所以其主要的作用就是用来 ...
- TCP/IP协议三次握手与四次握手流程解析
原文链接地址:http://www.2cto.com/net/201310/251896.html TCP/IP协议三次握手与四次握手流程解析 TCP/IP协议的详细信息参看<TCP/IP协议详 ...
- SSL/TLS算法流程解析
SSL/TLS 早已不是陌生的词汇,然而其原理及细则却不是太容易记住.本文将试图通过一些简单图示呈现其流程原理,希望读者有所收获. 一.相关版本 Version Source Description ...
随机推荐
- apr-util的安装
下载软件 下载链接: http://pan.baidu.com/s/1o6sOwgM http://pan.baidu.com/s/1hqIdcA4 ########安装apr######### ta ...
- [Cpp] 面向对象程序设计 C++
初始化列表(包括成员对象初始化) 初始化列表 ( 推荐 ) : 可以初始化任何类型的数据, 不管是不是普通类型还是对象,都建议用. 不再需要在构造器中赋值了, 而且初始化列表比构造函数要早执行. ...
- CF 570D. Tree Requests [dsu on tree]
传送门 题意: 一棵树,询问某棵子树指定深度的点能否构成回文 当然不用dsu on tree也可以做 dsu on tree的话,维护当前每一个深度每种字母出现次数和字母数,我直接用了二进制.... ...
- 让XtraMessageBox按钮显示中文
需要定义一个继承子Localizer的类,然后重写GetLocalizedString public class MessboxClass : Localizer { public override ...
- bind,apply,call区别总结
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- Java生产者消费者
简单的生产者.消费者,一个数据缓冲区,一个或者多个生产者把数据放入缓冲区.一个或者多个消费者将数据从缓冲区取走.该缓冲区是一个数据共享,必须进行同步处理,如果缓冲区是满的,生产者将不能放数据,同理如果 ...
- java处理json与对象的转化 递归
整个类是一个case,总结了我在使用java处理json的时候遇到的问题,还有级联关系的对象如何遍历,json和对象之间的转换! 对于对象json转换中遇到的问题我参考了一篇博客,http://blo ...
- CENTOS6.6下mysql5.7.11带boost和不带boost的源码安装
本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn Mysql5.7版本更新后有很多变化,比如json等,连安装都有变化 ...
- Socket网络通信之数据传递
Socket通信的步骤: 1.创建ServerSocket和Socket 2.打开连接到Socket的输入/输出流 3.按照协议对Socket进行读/写操作 4.关闭输入输出流.关闭Socket 服务 ...
- dcoker实战,使用docker部署NodeJs应用
docker简介 docker是一个开源的应用容器引擎,可以为我们提供安全.可移植.可重复的自动化部署的方式.docker采用虚拟化的技术来虚拟化出应用程序的运行环境.如上图一样.docker就像 ...