PCIE学习系列 三(PCIE中断)

简介

我们知道中断机制带来的优势很多,例如实时响应、节省CPU资源、多任务支持等,中断使系统能够高效地与外部设备进行交互和协作。
在PCIe中有三种中断方式,分别是INTx、MSI、MSI-X,下面将对三种中断类型分别进行描述。

INTx

INTx一般被称为传统(lagacy)中断,它有四根线,分别是通过INTA、INTB、INTC、INTD来上报中断,一个简单的例子如下图所示:
在这里插入图片描述
多数PCI设备仅使用INTA信号,很少使用INTB和INTC信号,而INTD信号更是极少使用。在PCI总线中,PCI设备配置空间的Interrupt Pin寄存器记录该设备究竟使用哪个INTx信号。
一个简单的PCI总线INTx中断处理流程如下:
1、 PCI设备通过INTx边带信号产生中断请求,经过中断控制器(Interrupt Controller,PIC)后,转换为INTR信号,并直接发送至CPU;
2、 CPU收到INTR信号置位后,意识到了中断请求的发生,但是此时并不知道是什么中断请求。于是通过一个特殊的指令来查询中断请求信息,该过程一般被称为中断应答(Interrupt Acknowledge);。
3、 该特殊指令被发送至PIC后,PIC会返回一个8bits的中断向量(Interrupt Vector)值给CPU。该中断向量值与其发送的INTR请求是对应的;
4、 CPU收到来自PIC的中断向量值后,会去其Memory中的中断向量表(Interrupt Table)中查找对应的中断服务程序(Interrupt Service Routines,ISR)在Memory的位置;
5、 然后CPU读取ISR程序,进而处理该中断。

MSI

MSI(Message Signaled Interrupt)与传统的中断方式相比,MSI 提供了更高的灵活性和性能,有以下几个优势:
1、 设备向内存写入数据,然后发起引脚中断,有可能会出现CPU收到中断时,数据还没有达到内存。而使用MSI中断时,产生中断的写不能越过数据的写(PCIE/PCI的transaction order rule可以保证),驱动可以确信所有的数据已经达到内存。
2、 基于引脚的传统中断会被多个设备所共享,中断共享时,如果触发了中断,linux中需要一一调用对应的中断处理函数,这样会有性能上的损失,而MSI不存在共享的问题。
3、 多功能的PCI设备,每一个功能最多只有一个中断引脚,当具体的事件产生时,驱动需要查询设备才能知道是哪一个事件产生,这样会降低中断的处理速度。而一个设备可以支持32个MSI中断,每个中断可以对应特定的功能。

MSI和MSI-X中断都是通过向MSI/MSI-X Capability结构中的Message Address写Message Data的写请求TLP上报中断,可以简单理解为往Message Address写入值 Message Data,此时就会触发中断。需要注意的是这里的Message并不是Tlp的Message类型,MSI本质上是一种Memory Write,Message Address和Message Data依赖处理器体系结构,MSI的结构有以下几种:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
Capability ID:标识当前Capability类型,05h表示MSI功能,其他可参考配置空间中讲解的PCI capability。
Next Capability Pointer:下一个Capability Structure的偏移地址,其值为00h则表示到达Linked List的末尾。
Message Control Register:MSI的格式与支持的功能等信息,如下图所示:
在这里插入图片描述
对该寄存器的具体描述如下:
在这里插入图片描述
在这里插入图片描述
Message Address Register:产生MSI中断需要写的地址,可以看出1:0都必须为0。
在这里插入图片描述
Message Data Register:产生MSI中断需要写的内容,可以看出无论哪种结构,Message Data的长度都为16bit。
在这里插入图片描述
这里Message Address Register 、Message Data Register是Host端驱动配置到PCIe设备端寄存器的。当PCIe设备需要产生一个中断时,则会生成一个Memory Write类型的TLP包,会把Message Address Register、Message Data Register拷贝到TLP对应字段,然后发送给RC,RC收到TLP包并解析,然后通过ITS模块产生LPI中断,最后CPU就能触发对应的中断。(这里我只是简单提到,更详细的可以结合Gic相关的资料看看, armv8架构使用的gic版本一般是Gic_v3或者Gic_v4)生成MSI TLP的规则如下:
No Snoop和Relaxed Ordering bits的值必须为0
TLP长度值必须为01h
First BE必须为1111b
Last BE必须为0000b
在这里插入图片描述
Mask Bits:将相关的中断向量(Interrupt Vector)屏蔽后,该MSI将不会被发送。软件可以通过这种方式来使能或者禁止某些MSI的发送。
Pending Bits:如果相关中断向量没有被屏蔽,此时发生了相关中断请求,这时Pending Bits中的相应bit则会被置位。一旦中断信息被发出,则该bit会立即被清零。

MSI-X

MSI和MSI-X机制的基本原理相同,其中MSI中断机制最多只能支持32个中断请求,而且要求中断向量连续,而MSI-X中断机制可以支持更多的中断请求,而且不要求中断向量连续,这也是最重要的一点。MSI-X在PCIe3.0提出,MSI-X机制对MSI做出了一些升级和改进。

在这里插入图片描述
MSI-X Capability的结构如下:
在这里插入图片描述
Capability ID: Capability结构的ID号,其值为0x11。
在这里插入图片描述
Message Control:存放当前PCIe设备使用MSI-x机制进行中断请求的状态和控制信息,如下所示:
在这里插入图片描述
Table BIR:BAR Indicator Register。该字段存放MSI-X Table所在的位置,PCIe总线规范规定MSI-X Table存放在设备的BAR空间中。该字段表示设备使用BAR0 ~ 5寄存器中的哪个BAR空间存放MSI-X table。
Table Offset: 存放MSI-X Table在相应BAR空间中的偏移。
PBA(Pending Bit Array) BIR:存放Pending Table在PCIe设备的哪个BAR空间中。在通常情况下,Pending Table和MSI-X Table存放在PCIe设备的同一个BAR空间中。
PBA Offset:该字段存放Pending Table在相应BAR空间中的偏移。

总结

PCIe有三种中断,分别为INTx中断,MSI中断,MSI-X中断,在PCI总线中,所有需要提交中断请求的设备,必须能够通过INTx引脚提交中断请求,而MSI机制是一个可选机制。而在PCIe总线中,PCIe设备必须支持MSI或者MSI-X中断请求机制,而可以不支持INTx中断消息,但是对于某个具体的PCIe设备,可能仅支持一种报文。
无论是MSI还是MSI-X,其本质上都是基于Memory Write 的,相对MSI来说MSI-X最主要的升级是中断可以不连续。

猜你喜欢

转载自blog.csdn.net/qq_42208449/article/details/132736957