MSI_MSIX中断总结文档.docx_msi中断-嵌入式文档类资源-CSDN下载
MSI/MSIX中断的总结
- MSI
1.1 MSI Capability 结构体描述
所有的能够产生中断的PCIe设备functions都必须支持MSI和MSIX其中至少1种。如下表 1-1所示的MSI capability结构体, 每个支持MSI的设备function必须实现它自己的MSI capability结构体。一个设备function不允许有超过一个MSI capability结构体,但是允许同时有MSI capability和MSIX capability。
31 16 | 15 8 | 7 0 | |
Message Control | Next Capability Pointer | Capability ID | pointer |
Message Address | Pointer+4 | ||
Extended Message Data(如果有) | Message Data | pointer+8 |
表 1-1 MSI capability结构体 (32位消息地址)
31 16 | 15 8 | 7 0 | |
Message Control | Next Capability Pointer | Capability ID | pointer |
Message Address | pointer+4 | ||
Message upper Address | pointer+8 | ||
Extended Message Data(如果有) | Message Data | pointer+c |
表 1-2 MSI capability结构体 (64位消息地址)
31 16 | 15 8 | 7 0 | |
Message Control | Next Capability Pointer | Capability ID | pointer |
Message Address | Pointer+4 | ||
Extended Message Data(如果有) | Message Data | pointer+8 | |
Mask Bits | pointer+c | ||
Pending Bits | pointer+10 |
表 1-3 MSI capability结构体 (32位消息地址和PVM)
31 16 | 15 8 | 7 0 | |
Message Control | Next Capability Pointer | Capability ID | pointer |
Message Address | Pointer+4 | ||
Message upper Address | Pointer+8 | ||
Extended Message Data(如果有) | Message Data | pointer+c | |
Mask Bits | Pointer10 | ||
Pending Bits | pointer+14 |
表 1-4 MSI capability结构体 (64位消息地址和PVM)
为了发起一个请求服务,设备function需要填写Message Data寄存器的内容(如果使能了扩展message data的话,还需要填写扩展message data的值)到message Address(如果是64位的message address,还应包括高32位地址)所指定的地址。
对Message Address寄存器所存的地址做读操作时会产生未定义的结果。
一个function支持实现 表1-1到表1-4 四种MSI capability结构体种的一种。这个取决于支持哪个可选的特性。一个legacy EP 必须支持32位或者64位的Message Address。一个PCIe EP必须支持64位的Message Address版本的MSI capability结构体。Message Control寄存器用来显示function的能力特性并提供系统软件控制。下面描述每个具体的域段。
- MSI capability Header (偏移 00h) 目标
MSI capability 结构体通过MSI capability header将自己登记到PCI配置空间的capability 列表中的。
15 8 | 7 0 |
Next Capability Pointer | Capability ID |
表 1-5 MSI capability Header
位域 | 寄存器名 | 描述 | HOST属性 |
7 : 0 | Capability ID | 表示MSI capability的ID。对于MSI来说,这个域值必须是05H,表示这个capability结构体是MSI capability 结构体 | |
15 :8 | Next Capability Pointer | 下一个capability的地址或者是00h(表示它后面没有capability了) |
表 1-6 MSI capability Header
- MSI的消息控制寄存器 (偏移 02h)
这个寄存器提供关于MSI的系统软件控制。MSI使能默认是关闭的。如果MSI和MSIX都没有使能,function请求服务使用INTx中断(如果支持的话)。系统软件可以通过设置这个寄存器的bit 0为1来使能MSI。系统软件允许被改变消息控制寄存器的RW位域。但是设备驱动不允许修改消息控制寄存器的RW位和位域。
15 9 | 8 | 7 | 6 4 | 3 1 | 0 |
保留 | 每个向量掩码能力 | 64位地址能力 | 多消息使能 | 多消息能力 | 使能 |
表 1
位域 | 位域名 | 描述 | Host属性 |
0 | MSI使能 | 如果设置了这个位,并且MSIX使能开关关闭,function允许使用MSI并且禁止使用INTx.系统配置软件写这个位1来使能MSI。 | RW |
3 : 1 | 多消息能力 | 系统软件读这个域段来决定请求的向量集。请求的向量个数必须是2的幂对齐(例如,如果一个function需要3个向量,它通过初始化这个域段的值为010b来请求4个向量)。编码对应的向量个数如下: 000b 1 001b 2 010b 4 011b 8 100b 16 101b 32 其它 保留 | RO |
6 :4 | 多消息使能 | 软件来写这个域段来决定请求的向量的个数。请求的向量个数必须是2的幂对齐(例如,如果一个function需要3个向量,它通过初始化这个域段的值为010b来请求4个向量)。编码对应的向量个数如下: 000b 1 001b 2 010b 4 011b 8 100b 16 101b 32 其它 保留 | RO |
7 | 64位地址能力 | 如果置1,则表示function能够发送一个64位地址的消息地址。对于PCIe设备来说,这个位必须置1。 | RO |
8 | Per-vector掩码能力 | 如果设置位1,表示function支持每个向量的掩码。对于PF或者VF,该位必须置1 | |
9 | 扩展消息数据能力 | 如果设置为1,function有能力提供扩展消息数据。 | RO |
10 | 扩展消息数据使能 | 如果设置为1,function被使能来提供扩展消息数据 | RW/RO |
表1-7 MSI的消息控制寄存器
- MSI的消息地址寄存器 (偏移 04h)
31 2 | 1 0 |
消息地址(4字节对齐) | 保留(读返回0) |
表1-7 MSI的消息地址寄存器
- MSI的消息高32位地址寄存器 (偏移 08h)
这个寄存器只有在支持64位消息地址的时候才有效(消息控制寄存器的bit7置1支持64位地址)。对于PCIe-ep来说,这个设计必须的,对于非PCIe-ep的其它的function是可选的。
- MSI的数据寄存器 (偏移 08h或者0Ch)
Data是32位的长度(16位的data+ 16位的扩展data)
系统指定的消息数据。
如果MSI控制寄存器里面的消息使能位置1了,function设备发送一个DW的内存写,这个写tlp报文的4个字节的payload就是data的值。
多消息使能域段决定了data的可修改的低位的值。这个值决定了系统软件可分配的向量。例如,一个多消息使能编码是010b表示这个function设备已经分配了4个向量并且允许修改消息数据的位1和位0(一个function修改了消息数据的低位来生成分配的向量,生成完后可将这个MSI报文发给host)。如果多消息使能位是000b,那么这个function设备不允许修改消息数据。
- MSI的掩码寄存器 (偏移 0Ch或者10h)
这个寄存器是可选的。只有在per-vector 掩码能力被置1后才有效。
掩码位域和pending位域使软件能够禁止或者延时消息的发送。MSI的向量编号是0 – N-1。N是软件分配的向量个数,每个向量被相应地掩码位和pending位关联起来。
多消息能力域段指定了有多少个向量被实现了。所有的没有实现的掩码和pending位被保留。
- MSI的pending寄存器(偏移10h 或者 14h)
这个寄存器是可选的。
2.MSIX
2.1 MSIX Capability 结构体描述
MSIX capability结构体说明如下图。每个function不允许有多个MSIX capability结构体,但是一个function允许同时有一个MSIX和一个MSI结构体。
对比MSI结构体直接包含function的向量对应的所有的控制/状态信息。MSIX结构体则是指向了一个MSIX表结构体和一个MSIX pending bits 数组结构体(PBA)。这两个结构体都存在于memory空间。
每个结构体可以通过function的一个BAR空间或者通过一个加强的分配capability的入口来映射。Bar指示器寄存器(BIR)用来指示是哪一个BAR(或者BEI当使用加强分配功能的时候)。一个8字节的偏移表明从BAR空间的相对基地址多远的地方开始映射。BAR允许是32位的bar空间或者64位的bar空间。但是必须是mem类型的bar空间。一个function允许将这两个结构体映射到一个相同的bar,或者映射到不同的bar。
MSIX表结构体, 一般包含多个入口(entry)。每个entry由消息地址、消息高32位地址、消息data、和向量控制域组成。每个entry能够描述一个唯一的向量。
Pending bits 数组(PBA)结构体,包含function的pending位域,由多个打包好的QWORD组成。最后一个QWORD不需要全部填充。
- MSIX的capability结构体
表 2-1 MSIX capability结构体
- MSIX的表结构体
表 2-2 MSIX 表结构体
- MSIX的PBA结构体
表 2-3 MSIX的PBA结构体
一个function设备通过执行一个4字节的内存写事务来向host发起一个MSI中断请求服务。这个写事务的4字节的内容来源于表结构体的entry的消息data域。Entry的高32位地址和32位消息地址组成这个这个事务要发往的目的地。对这个地址读会产生未定义的结果。
用来存放MSIX表或者MSIX PBA的BAR或者enhanced allocation capability里的entry也可以映射一些与MSIX无关的地址空间。在这些地址空间必须不能与MSIX结构体所在的地址空间共享任何4KB对齐的地址范围里的同一地址空间。MSIX表和PBA可以共存在一个4KB对齐的地址范围,但是他们所在的空间不能重合。
- 专用BARs和地址范围隔离
为了使系统软件能够映射MSIX结构体到不同的处理器页表来提供访问控制的能力。建议一个function专门将MSIX表和PBA分离开。或者在他们之间提供一个最小的隔离地址范围。
如果不能够获得专门的分开的BAR空间来分别存放表和PBA, 建议function专门使用一个单独的BAR来存放MSIX和PBA。
如果不能够获得一个专门的BAR,建议一个function使用8KB对齐的地址范围来隔离MSIX结构体和非MSIX结构体。
例如:如果一个BAR需要映射2KB的地址空间到 一个包含有128个entry的MSIX表,16字节来存放PBA(总共128位),并且还有64字节的与MSIX无关的寄存器,下面是一个可接受的实现 :
BAR请求总共8KB地址空间。映射第一个64字节来存放非MSIX的寄存器。在偏移4KB的地方映射表,在偏移6KB的地方映射PBA。
对于共享的BAR来说,一个较好的实现是:请求总共16KB的地址空间。映射前64字节来存放非MSIX的寄存器。在偏移8KB的地方映射MSIX表,在偏移12KB的地方映射PBA。
- 在读/写内存中的MSIX内存空间结构体
为了简单性和灵活性,MSIX表和PBA结构体可以被定义在设备的一块通用目的的读/写内存空间。为了实现这个目的,所有包含的区域没有哪一处要求是只读的,但是在对齐和长度大小方面有限制。
对于MSIX表和PBA的所有访问,软件必须使用DWORD对齐挥着QWORD对齐的事务;否则将会产生未定义的结果。
MSIX表入口和PBA都是从0到N -1 编号,N-1由MSIX控制寄存器中的table size域的大小决定。对于一个给定的任意的表的entry,它的起始地址可以通过下面的公式计算:
entry_start_address = table_base + K * 16
对于相关联的pending位K,用于QWORD访问的地址和在QWORD里面的位的编号可以通过下面的公式计算:
QWORD address = PBA_base + (K / 64) * 8
QWORD bit# = K % 64
软件选择读使用QWORD访问来读取pending位K,可以使用如下公式:
DWORD address = PBA_base + (K / 32) * 4
DWORD bit# = K / 32
- MSIX capability 头(偏移00h)
MSIX capability 结构体通过MSIX capability header将自己登记到PCI配置空间的capability 列表中的。
15 8 | 7 0 |
Next Capability Pointer | Capability ID |
表 2-4 MSIX capability Header
描述同1.1.1
MSIX的Capability ID 是0x11。
- MSIX 的消息控制寄存器(偏移04h)
默认的,MSIX是禁止的,如果MSI和MSIX都禁止了,那么function的请求服务将会由INTx来执行(如果支持INTx功能的话)。系统软件可以通过设置这个寄存器的bit 15来使能MSIX。系统软件可以修改消息控制寄存器的读写域段,设备驱动不允许修改消息控制寄存器的RW域段(HOST可以改,slave不允许改RW区域)。
表 2-5 MSIX的消息控制寄存器
bit位置 | 寄存器域名 | 描述 | 属性 |
10:0 | Table size | 系统软件读取这个域来决定MSIX的表的size N,例如,返回值00000000011b表示表的大小是4。 | RO |
13:11 | 保留 | 读返回0,写没有影响 | 保留 |
14 | Function mask | 如果设置了这个总的mask开关,那么与这个function相关联的所有的向量都会被mask,而不管它的每个位的mask如何设置。 | RW |
15 | MSIX enable | 同MSI enable,优先级较高 | RW |
- MSIX 的消表偏移/表BIR寄存器(偏移04h)
bit位置 | 寄存器域名 | 描述 | 属性 |
2:0 | 表BIR | BIR用来指示是哪一个BAR,或者BEI(用来指示是哪一个entry) 对于32位的bar 0 --- 10h 1 --- 14h 2 --- 18h 3 --- 1ch 4 --- 20h 5 --- 24h 6 --- 保留 对于64位的BAR来说,表BIR指示低32位。对于type1类型的function, BIR的值2到5是保留的。(type1配置空间只有BAR0、BAR1) | RO |
31:3 | 表偏移 | 相对BAR地址的偏移。Bit 5:3被设置为0来保证偏移地址是32位对齐的。 | RO |
- MSIX 的PBA偏移/PBA_BIR 寄存器(偏移08h)
bit位置 | 寄存器域名 | 描述 | 属性 |
2:0 | PBA BIR | BIR用来指示是哪一个BAR,或者BEI(用来指示是哪一个entry)用来映射function的MSIX PBA到内存空间。 对于64位的BAR来说,表BIR指示低32位。对于type1类型的function, BIR的值2到5是保留的。(type1配置空间只有BAR0、BAR1) | RO |
31:3 | PBA偏移 | 相对BAR地址的偏移。Bit 5:3被设置为0来保证偏移地址是32位对齐的。 | RO |
- MSIX表入口的消息地址寄存器
32位的message address, 最低两位固定为0来满足32位地址对齐。
- MSIX表入口的消息高32位地址寄存器
32位的地址
- MSIX表入口的消息data寄存器
32位的data,由系统指定消息data的值。对于MSIX消息,MSIX表entry里面的data的内容指明了内存写事务里的32位的负载的值。所有的4个字节的使能被设置。与MSI消息使用的message data不同的是, MSIX的data的低位不能被function修改。
- MSIX的向量控制寄存器
如果一个function实现了一个TPH请求capability结构体和一个MSIX capability 结构体,那么这个function可以有选择性地使用向量控制寄存器来存储一个steer tag.
bit位置 | 寄存器域名 | 描述 | 属性 |
0 | Mask 位 | 每个位的mask开关,默认的置1,表示mask。当这个位被mask了,function将会禁止使用MSIX表entry来发送一个消息,但是其他entry不受影响。其他entry也可以发送相同的向量号消息。 | RW |
15:1 | 保留 | 现在必须是0,将来扩展使用 | RW或者保留 |
23:16 | ST lower | 如果function实现一个TPH请求capability结构体,并且ST表的位置指示值是10b,那么这个域包含ST的低8位并且必须是RW的。 否则,保留为将来扩展使用。 | |
31:24 | ST upper | 如果function实现了一个TPH请求capability结构体,并且ST表位置 指示值是10b, 并且扩展的TPH请求支持位被设置了,那么这个域包含ST的高8位并且必须是RW的。 否则,RW/保留。 |
- MSIX的PBA入口的pending bits寄存器
64位的Pending Bits。
对pending bits里面设置了的每个位,function有一个关联MSIX表entry的pending 消息。
对于没有关联MSIX表entry的位则保留。默认的,保留的pending位必须是0。
软件不能写这个寄存器,只能读。
- Host端软件实现
3.1 MSI的软件实现
Package文件中含有软件的实现。