PCIe学习笔记之MSI/MSI-x中断及代码分析

本文基于linux 5.7.0, 平台是arm64

1. MSI/MSI-X概述

PCIe有三种中断,分别为INTx中断,MSI中断,MSI-X中断,其中INTx是可选的,MSI/MSI-X是必须实现的。

1.1 什么是MSI中断?

MSI, message signal interrupt, 是PCI设备通过写一个特定消息到特定地址,从而触发一个CPU中断。特定消息指的是PCIe总线中的Memory Write TLP, 特定地址一般存放在MSI capability中。

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

1.2 什么是MSI-X中断?

MSI-x是MSI的扩展和增强。MSI有它自身的局限性,MSI最多支持32个中断,且要求中断向量连续, 而MSI-x没有这个限制,且支持的中断数量更多。此外,MSI-X的中断向量信息并不直接存储在capability中,而是在一块特殊Memory中.

MSI和MSI-X的规格对比:

MSI MSI-X
中断向量数 32 2048
中断号约束 必须连续 可以随意分配
MSI信息存放 capability寄存器 MSI-X Table(BAR空间)

总之,PCIe设备在提交MSI中断请求时,都是向MSI/MSI-X Capability结构中的Message Address的地址写Message Data数据,从而组成一个存储器写TLP,向处理器提交中断请求。

在arm64中,MSI/MSI-X对应的是LPI中断, 在之前的文章【ARM GICv3 ITS介绍及代码分析】有介绍过,外设通过写GITS_TRANSLATER寄存器,可以发起LPI中断, 所以相应的,如果在没有使能SMMU时,MSI的message address指的就是ITS_TRANSLATER的地址。

2. MSI/MSI-X capability

2.1 MSI capability

MSI Capability的ID为5, 共有四种组成方式,分别是32和64位的Message结构,32位和64位带中断Masking的结构。
以带bit mask的capability register为例:
在这里插入图片描述

Capability ID :记录msi capability的ID号,固定为0x5.
next pointer: 指向下一个新的Capability寄存器的地址.
Message Control Register: 存放当前PCIe设备使用MSI机制进行中断请求的状态和控制信息
在这里插入图片描述
MSI enable控制MSI是否使能,Multiple Message Capable表示设备能够支持的中断向量数量, Multi Message enable表示实际使用的中断向量数量, 64bit Address Capable表示使用32bit格式还是64bit格式。

Message Address Register: 当MSI enable时,保存中断控制器种接收MSI消息的地址。
Message Data Register: 当MSI enable时,保存MSI报文的数据。
Mask Bits: 可选,Mask Bits字段由32位组成,其中每一位对应一种MSI中断请求。
Pending Bits: 可选,需要与Mask bits配合使用, 可以防止中断丢失。当Mask bits为1的时候,设备发送的MSI中断请求并不会发出,会将pending bits置为1,当mask bits变为0时,MSI会成功发出,pending位会被清除。

2.2 MSI-X capability

MSI-x的capability寄存器结构和MSI有一些差异:
在这里插入图片描述
Capability ID:记载MSI-X Capability结构的ID号,其值为0x11
Message Control: 存放当前PCIe设备使用MSI-x机制进行中断请求的状态和控制信息
在这里插入图片描述
MSI-x enable,控制MSI-x的中断使能 ;
Function Mask,是中断请求的全局Mask位,如果该位为1,该设备所有的中断请求都将被屏蔽;如果该位为0,则由Per Vector Mask位,决定是否屏蔽相应的中断请求。Per Vector Mask位在MSI-X Table中定义;
Table Size, 存放MSI-X table的大小
Table BIR:BAR Indicator Register。该字段存放MSI-X Table所在的位置,PCIe总线规范规定MSI-X Table存放在设备的BAR空间中。该字段表示设备使用BAR0 ~ 5寄存器中的哪个空间存放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空间中的偏移。

通过Table BIR和Table offset知道了MSI-Xtable在哪一个bar中以及在bar中的偏移,就可以找到对应的MSI-X table。
查找过程如下:
在这里插入图片描述
查找到的MSI-X table结构:
在这里插入图片描述
MSI-X Table由多个Entry组成,其中每个Entry与一个中断请求对应。
除了msg data和msg addr外,还有一个vector control的参数,表示PCIe设备是否能够使用该Entry提交中断请求, 类似MSI的mask位。

3. 确认设备的MSI/MSI-X capability

lspci -v可以查看设备支持的capability, 如果有MSI或者MSI-x或者message signal interrupt的描述,并且这些描述后面都有一个enable的flag, “+”表示enable,"-"表示disable。

[root@localhost linux]# lspci -s 00:16.0 -v
00:16.0 PCI bridge: VMware PCI Express Root Port (rev 01) (prog-if 00 [Normal decode])
	Flags: bus master, fast devsel, latency 0, IRQ 32
	Bus: primary=00, secondary=0b, subordinate=0b, sec-latency=0
	I/O behind bridge: 00005000-00005fff
	Memory behind bridge
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值