msix中断实现原理
根据中断的上报方式区分,PCIE设备有两种方式向处理器提交中断请求:
INTx引脚:和其他外设中断请求一样,通过改变中断请求线电平的方式向处理器提交中断请求,INTx属于边带信号,不在PCIE协议处理的范围内;
MSI/MSI-X:PCIE设备独有的,基于TLP消息报文,通过存储器写请求TLP向处理器提交中断请求,MSI/MSI-x中断基于TLP消息报文,可以更加合理地处理PCIe总线的”序”;
MSI/MSI-X中断基于MSI/MSI-X Capability结构实现,都是通过向MSI/MSI-X Capability结构中的Message Address写Message Data的存储器写请求TLP报文上报中断,Message Address和Message Data依赖处理器体系结构:
比如,PowerPC处理器MSI/MSI-X Capability结构中的Message Address是MPIC中断控制器的MSIIR寄存器地址,Message Data里面的值是写入MSIIR寄存器的值;那么MSI/MSI-X中断请求报文就是将Message Data里面的值写入MSIIR寄存器,从而向MPIC中断控制器提交中断,然后,由MPIC中断控制器将中断转发给处理器,然后处理器通过中断响应周期从MPIC中断控制器的ACK寄存器中获得中断向量;
MSIIR各字段含义如下:
Bits |
定义 |
描述 |
27~31 |
IBS |
该字段用来选择MSIR0~MSIR7寄存器的对应位。0b00000对应SH0;0b00001对应SH1;0b00010对应SH2;以此类推0b11111对应SH31; |
24~26 |
SRS |
该字段用来选择MSIR0~MSIR7寄存器。0b000对应MSIR0;0b001对应MSIR1;0b010对应MSIR2;以此类推0b111对应MSIR7。 |
0~24 |
保留。 |
其中,MSIR0~MSIR7的每个bit表示一个中断;
又比如x86处理器,与PowerPC处理器不同,x86处理器使用FSB Interrupts Message总线事务转发MSI/MSI-X中断请求,直接将中断提交给处理器,不经过中断控制器,因此,MSI/MSI-X Capability结构中的Message Address存放的是FSB Interrupts存储器空间的基地址;
如下图是x86处理器中Message Address和Message Data字段的格式,里面包含了CPU的ID号Destination ID以及中断向量号Vector;
MSI/MSI-X中断TLP报文到达RC时,发现TLP的目的地址在FSB Interrupts存储器空间中,则将PCIe总线的存储器写请求转换为Interrupt Message总线事务,并在FSB总线上广播,FSB总线上的CPU根据消息中CPU的ID号选择是否接收这个Interrupt Message总线事务,并进入中断状态,之后CPU直接从总线事务中获得中断向量号,执行相应的中断服务例程,而不需要从APIC中断控制器读取中断向量号。
MSI Capability结构:
MSI Capability寄存器的结构如上图所示,包括Message Control、Message Address、Message Data、Mask Bits以及Pending Bits这几个主要字段;
Message Control字段,存放当前PCIe设备使用MSI机制进行中断请求的状态与控制信息,比如MSI中断个数、MSI ENABLE等;
Mask Bits可以用来屏蔽和使能中断,共32bit,每个bit控制一个中断,因此一个PCIe设备最多支持32个MSI中断;
MSI Capability寄存器存放在PCIe的配置空间里面;
MSI-X Capability结构:
MSI-X Capability结构如上图所示,功能与MSI类似;与MSI Capability寄存器不同的是,MSI-X结构中将Message Address、Message Data、Mask Bits放在MSI-X Table里面,并且每一个MSI-X中断有独立的Message Address、Message Data、Mask Bits,封装在MSI-X Table的一个个entry里面,对应的Pending信息存放在Pending Table里面,如下图;
MSI-X Table和Pending Table是存放在BAR空间里面的,因此大小没有限制,也就是一个PCIe设备可以支持无限多MSI-X中断,并且每个中断号可以不用连续;
MSI中断使用方法:
/* * int pci_enable_msi(struct pci_dev *dev) */ 首先,调用pci_enable_msi使能msi中断,在这个函数里面,会根据处理器体系结构初始化MSI Capability寄存器,并且分配中断号保存在pci_dev->irq中; 然后,使用request_irq函数即可注册中断处理函数;
MSI-X中断使用方法:
/* * int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries, int minvec, int maxvec) */ 首先,调用pci_enable_msix_range使能msix中断,这个函数里面会根据处理器体系结构初始化MSI-X Capability寄存器,并且分配中断号保存在entries->vector; 然后,使用request_irq函数注册中断处理函数即可;
今天的文章PCI LAN_pcie中断分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/83441.html