本文将更偏向于具体编程实现的角度来介绍MSI-X,阅读本文需要有PCI总线以及MSI的基本前置知识。

MSI-X是PCI总线设备的一种中断方式,直接将中断投递到处理器核心的Local APIC。它与MSI的区别在于,MSI-X属于是对MSI中断的扩展,他们的区别在于,MSI的话,只有32个中断向量,且必须连续,MSI-X可以有2048个,可以不连续。

并且,MSI和MSI-X是互斥的,也就是说,对于某个pci设备而言,它要么启用MSI,要么启用MSI-X,不能同时启用二者。并且,有的PCI设备同时支持了二者,你可以选择启用其中的任意一种。

MSI-X Capability list 介绍

MSI-X Capability的结构

CapabilityID

其中,DWORD0的低8bit为ID,若该部分的值为0x11,则表明当前链表结点为MSI-X Capability List

查看设备是否支持MSI-X

可以通过遍历PCI Config Space的Capability指针指向的链表,寻找CapabilityID为0x11的链表项,则为MSI-X的Capability空间,说明该设备支持MSI-X

Next Pointer

该部分为指向下一个Capability List的指针。这个指针的值指的是下一个List item在PCI配置空间中的偏移量。

Message Control

Message Control部分的bit分布

MSI-X Enable

若当前位为1,且MSI Enable为0,那么,当前function将被允许使用MSI-X来进行中断请求。

当设备被reset之后,当前bit为0,默认是不开启MSI-X中断的

Function Mask

如当前位为1,则与该function相关的所有中断向量将会被屏蔽。若当前位为0,则当前function的每个中断向量的屏蔽情况由每个向量的单独的mask bit决定。

Table Size

表明了MSI-X表的大小,这个部分是只读的。并且,这里它是“N-1”表示法的,举个例子,比如这里读到3,那么说明Table大小为4.

Table BIR

这个字段位于DWORD1的低3bits,表示哪个BAR寄存器中存储了MSI-X Table的地址,我们需要把对应的地址映射到虚拟内存之中。

它与具体的BAR寄存器具有以下映射关系:

BIR Value对应的BAR寄存器寄存器偏移量
0BAR00x10
1BAR10x14
2BAR20x18
3BAR30x1c
4BAR40x20
5BAR50x24

再回头看pci标准中的header的结构,我们可以发现,对于PCI-to-PCI bridge,BIR的值只能选择0和1,因为bridge的其他部分都被用作了特殊用途。只有General device的是6个BAR都可用的。

Table Offset

该部分位于DWORD1,

MSI-X Table起始地址 = 在BIR中指定的BAR中存储的基地址+Table Offset

需要注意的是Table Offset是8bytes对齐的,它总共32bit,也就是说,把DWORD1的值读取出来,然后mask掉BIR,得到的就是Table Offset了。

Pending bit BIR

该字段位于DWORD2中。它与上面的BIR类似,只不过它是用于指出Pending bit的基地址是存放在哪个寄存器之中。我们需要把对应的地址映射到虚拟内存之中。

Pending bit Offset

这部分与上面的Table Offset类似,只不过涉及到的是MSI-X PBA

MSI-X Table

MSI-X Table中描述了该function的MSI-X中断向量。结构如下图所示:

MSi-X Table Structure

MSI-X表由最大2048个表项组成,每个表项占16bytes,最大占用32KB。

Message Address

消息地址是4字节对齐的。

Message Data

该字段指定了当中断发生时,用于驱动在Message Address上所进行的内存事务的数据,其中[3:0]bits被用于内存事务的数据阶段的assert。这一点和MSI的有些相像。但是不同的是,function不会修改Message data的低位。

Vector Control

这个字段位于DWORD3,只使用了第0bit,作为vector的mask bit,若被置位,那么这个function将不能使用这个表项来发送MSI-X中断。然而,需要注意的是:如果其他表项也使用了相同的中断向量号,他们仍然能被用来发送中断消息。

MSI-X PBA Table

上面提到的Pending bits table,里边每个表项是64bits,每个bit对应了MSI-X Table中的一个表项。一旦对应的表项有中断产生,那么对应的pending bit就会被控制器置位。需要注意的是,系统软件不应该向pending bits写入数据,否则将产生未定义的结果。

在下文中,我们将介绍如何配置MSI-X中断。

转载请注明来源:https://longjin666.cn/?p=1496

欢迎关注我的公众号“灯珑”,让我们一起了解更多的事物~

你也可能喜欢

发表评论