IMSIC
RISC-V AIA 文档 第三章 Incoming MSI Controller (IMSIC)
传入 MSI 控制器(IMSIC)是一个可选的 RISC-V 硬件组件,与 hart 紧密相连,每个 hart 有一个 IMSIC。IMSIC 接收并记录 Hart 的传入消息信号中断 (MSI),并在有待处理并使能的中断时向 Hart 发出信号。
IMSIC 在机器地址空间中有一个或多个内存映射寄存器,用于接收 MSI。除了这些内存映射寄存器外,软件与 IMSIC 的交互主要通过附加 hart 的几个 RISC-V CSR。
1、中断文件和中断标识
【在 RISC-V 系统中,MSI 不仅会被定向到特定 hart,而且会被定向到特定 hart 的特定特权级,如 M 或 S 级别。此外,当 hart 实现了 H 扩展时,IMSIC 可以选择允许 MSI 定向到 VS 级的特定虚拟 hart。】
【对于每个特权级和每个可向其发送 MSI 的虚拟 hart,hart 的 IMSIC 都包含一个单独的中断文件(interrupt file)】。假定一个 hart 实现了 S 模式,那么它的 IMSIC 至少有两个中断文件,一个用于 M,另一个用于 S。如果 Hart 还实现了 H 扩展,其 IMSIC 可能会有额外的中断文件,用于虚拟 Hart,即访客中断文件(guest interrupt files)。【IMSIC 为虚拟机提供的访客中断文件数量正好是 GEILEN,即 RISC-V Privileged Architecture 为 H 扩展定义的受支持的访客外部中断数量】。
【每个独立的中断文件主要由两个大小相同的比特数组组成,一个数组用于记录已到达但尚未服务的 MSI(interrupt-pending bits),另一个数组用于指定 hart 当前能接受的中断(interrupt-enable bits)】。这两个数组中的每个位都对应不同的中断标识号,不同来源的 MSI 可通过该标识号在中断文件中进行区分。【由于 IMSIC 是 hart 的外部中断控制器,因此中断文件的中断标识将成为所附 hart 外部中断的次要标识(minor identities)】。
次要标识,参考下表理解(仅外部中断需要次要标识):
中断文件支持的中断标识数(以及每个数组中的有效位数)是 64 的倍数的一个小数,最小为 63,最大为 2047。
【当中断文件支持 N 个不同的中断标识时,有效标识号介于 1 和 N 之间。在此范围内的标识号表示中断文件已实现;在此范围外的标识号表示未实现。0 永远不是有效的中断标识。】
【IMSIC 硬件不认为一个中断文件的中断标识号与另一个中断文件的中断标识号有任何联系】。软件通常会为不同中断文件的不同 MSI 源分配相同的中断标识号,而不会在不同中断文件之间进行协调。因此,【系统中可单独区分的 MSI 信号源总数可能是单个中断文件的中断标识数乘以系统中所有中断文件总数的乘积】。
系统中的所有中断文件并不一定大小相同(实现的中断标识数量相同)。【对于给定的 hart,访客外部中断的中断文件大小必须全部相同,但 M级 和 S级 的中断文件大小可能与访客外部中断的中断文件不同,也可能彼此不同。同样,不同 Hart 的中断文件也可能大小不同】。
平台可为软件提供配置 IMSIC 中中断文件数量和/或其大小的方法,例如允许用 M级 的较小中断文件换取 S级 的较大中断文件,反之亦然。任何此类可配置性都超出了本规范的范围。不过,建议只赋予 M级 改变 IMSIC 中中断文件数量和大小的权力。
2、MSI encoding
既定标准(特别是 PCI 和 PCIe 标准)规定,来自设备的单个消息信号中断 (MSI) 采取设备自然对齐 32 位写入的形式,地址和值均由软件在设备(或设备控制器)上配置。根据设备或控制器所符合的标准版本,地址可能被限制在低 4 GB(32 位)范围内,而写入的值可能被限制在 16 位范围内,高 16 位始终为零。
【当 RISC-V Hart 具有 IMSIC 时,来自设备的 MSI 通常会直接发送到由软件选择来处理中断的单个 Hart】(可能是基于某种中断亲和性策略)。【MSI 将通过存在于接收单元 IMSIC 中的相应中断文件定向到特定权限级别或特定虚拟单元】。MSI 写地址是与目标中断文件物理连接的特定字长寄存器的物理地址。MSI 写入数据只是该中断文件中待处理中断的标识号(最终成为连接 hart 的外部中断的次要标识)。
【注意】通过在设备上配置 MSI 的地址和数据,系统软件可完全控制:(a) 接收特定设备中断的 Hart,(b) 目标特权级或虚拟 Hart,以及 © 在目标中断文件中代表 MSI 的标识号。要素 a 和 b 由 MSI 地址所针对的中断文件决定,而要素 c 则由 MSI 数据传达。
**在实现 H 扩展且设备由客户操作系统直接管理时,设备的 MSI 地址最初是客户物理地址,因为它们是由客户操作系统在设备上配置的。这些客户地址必须由 IOMMU 转换,IOMMU 由 hypervisor 配置,以便将这些 MSI 重定向到中断文件,用于正确的客户外部中断。**有关此主题的更多信息,请参阅第 8 章。
3、Interrupt priorities
在单个中断文件中,中断优先级直接由中断标识号决定。标识号越小,优先级越高。
由于 MSI 使软件能够完全控制中断文件中标识号的分配,因此软件可以自由选择反映中断所需的相对优先级的标识号。
确实,如果中断文件包含分配给每个中断标识的优先级编号数组,那么软件可以更动态地调整中断优先级。 然而,我们认为这种额外的灵活性不会经常被利用,不足以证明额外的硬件费用是合理的。 事实上,对于当前使用 MSI 的许多系统来说,软件的常见做法是完全忽略中断优先级并表现得好像所有中断都具有相同的优先级。
一个中断文件的最低标识号被赋予了最高优先级,而不是相反的顺序,因为只有最高优先级的中断才可能需要仔细管理优先级顺序,而在所有系统中保证存在的是低标识号,即 1 到 63(或者 1 到 255)。例如,一个中断文件中优先级最高的中断(可能是时间最紧迫的中断)总是标识号 1。如果优先级顺序颠倒,最高优先级的中断在不同的机器上就会有不同的标识号,这取决于中断文件实现了多少个标识。如果软件能够为最高优先级的中断分配固定的标识号,那么中断优先级顺序与自然数顺序相反所带来的任何不适都是值得的。
4、Reset and revealed state
重置 IMSIC 后,其中断文件的所有状态都会变得有效和一致,但其他状态未作说明,M级 和 S级 中断文件的 eidelivery 寄存器除外,具体说明见第 3.8.1 节。
如果 IMSIC 中包含 S级 中断文件,且所附 hart 上的软件启用了先前禁用的 S 模式(例如,通过将 CSR misa 的 S 位从 0 改为 1),则 S 级 中断文件的所有状态均有效且一致,但未指定其他状态。同样,如果 IMSIC 中包含访客中断文件,而所连接的 hart 上的软件启用了先前禁用的 H 扩展(例如,将 misa 的 H 位从 0 改为 1),则 IMSIC 访客中断文件的所有状态都有效且一致,但在其他方面未指定。
5、Memory region for an interrupt file
【IMSIC 中的每个中断文件都有一个或两个内存映射 32 位寄存器,用于接收 MSI 写入】。这些内存映射寄存器位于中断文件物理地址空间中自然对齐的 4-KiB 区域(页)内,即每个中断文件一个页。
一个中断文件内存区域的布局为:
offset size register name
0x000 4 bytes seteipnum_le
0x004 4 bytes seteipnum_be
中断文件 4-KiB 内存区域中的所有其他字节都是保留字节,必须以只读 0 的方式执行。
中断文件的内存区域中仅支持自然对齐的 32 位简单读取和写入。 对只读字节的写入将被忽略。 对于其他形式的访问(其他大小、未对齐的访问或 AMO),IMSIC 实现最好应该报告访问故障或总线错误,但必须忽略该访问。
【如果 i 是已实现的中断标识号,则以小端字节顺序将值 i 写入 seteipnum_le(按数字设置外部中断挂起位,小端)会导致中断 i 的挂起位设置为 1】。 如果写入的值不是以小端字节顺序实现的中断标识号,则对 seteipnum_le 的写入将被忽略。
对于支持大端字节顺序的系统,如果 i 是已实现的中断标识号,则以大端字节顺序将值 i 写入 seteipnum_be (按数字设置外部中断挂起位,大端) 会导致 中断 i 挂起位设置为 1。 如果写入的值不是按大端字节顺序实现的中断标识号,则对 seteipnum_be 的写入将被忽略。 仅支持小端字节顺序的系统可能会选择忽略对 seteipnum_be 的所有写入。
【在大多数系统中,seteipnum_le 是指向此中断文件的 MSI 的写入端口】。 对于主要为大端字节顺序构建的系统,seteipnum_be 可以用作从某些设备定向到此中断文件的 MSI 的写入端口。
在所有情况下,读取 seteipnum_le 或 seteipnum_be 都会返回零。
当不被忽略时,对中断文件内存区域的写入保证最终会反映在中断文件中,但不一定立即反映。 对于单个中断文件,对其内存区域进行多次写入(存储)的效果尽管任意延迟,但始终以与 RISC-V 非特权 ISA 定义的存储的全局内存顺序相同的顺序发生。
6、多个中断文件的内存区域排布
如上一节所述,IMSIC 实现的每个中断文件都有自己的内存区域,正好占用一个 4-KiB 的机器地址空间页。在可行的情况下,所有 IMSIC 的 M级中断文件的内存页应一起位于地址空间的一部分,而所有 S级 和访客中断文件的内存页同样应一起位于地址空间的另一部分,具体规则如下:
将 M级 中断文件与地址空间中的其他中断文件分开的主要原因是,实施物理内存保护(PMP)的 Harts 只需使用一个 PMP 表项,就能向所有 S级 和访客级中断文件授予 S级 访问权限。如果将 M级 中断文件的内存页与权限较低的中断文件的内存页交错排列,那么向所有 非M级 中断文件授予 S级 访问权限所需的 PMP 表项数量可能与系统中的 Harts 数量相当。
如果机器的结构要求将 Harts 细分为若干组,每组在地址空间中各占一部分,那么最好的办法是将每组 Harts 的 M级 中断文件分别放在一起,同样地,将每组 Harts 的 S级 和访客级中断文件分别放在一起。下文将进一步讨论这种情况。
系统可能会在地址空间中将中断组划分为若干组,因为每组都存在于单独的芯片(或多芯片模块中的芯片组)上,将多个芯片的地址空间编织在一起是不切实际的。在这种情况下,对所有 非M级 中断文件授予 S级 访问权限,每个组只需一个 PMP 表项。
…
7、IMSIC 关于外部中断的 CSR
【软件主要通过第 2 章介绍的 CSR 访问 Hart 的 IMSIC】。【每个可接收中断的权限级别都有一套独立的 CSR】。【M级 CSR 与 IMSIC 的 M级 中断文件交互,而如果执行了 S模式,则 S级 CSR 与 IMSIC 的 S级中断文件交互。当 IMSIC 具有访客中断文件时,VS CSR 与单个访客中断文件交互,访客中断文件由 CSR hstatus 的 VGEIN 字段选择】。
对于 M级,相关的 CSR 包括 miselect、mireg 和 mtopei。在实现 S模式时,S 级 CSR 的集合与机器级的一致:siselect、sireg 和 stopei。而在实现了 H 扩展时,有三个相应的 VS CSR:vsiselect、vsireg 和 vstopei。
如第 2 章所述,【寄存器 miselect 和 mireg 提供了对其他 M级 寄存器的间接访问】。同样,S级 寄存器 siselect 和 sireg 以及 VS 级寄存器 vsiselect 和 vsireg 也是如此。【在每种情况下,*iselect CSR(miselect、siselect 或 vsiselect)的值范围为 0x70-0xFF,选择相应 IMSIC 中断文件的寄存器,即 M级 中断文件(miselect)、S级 中断文件(siselect)或访客中断文件(vsiselect)】。
每个级别的中断文件作用相同。*对于给定特权级,iselect CSR 的值在 0x70-0xFF 范围内,可选择相应中断文件的这些寄存器:
0x70 eidelivery
0x72 eithreshold
0x80 eip0
0x81 eip1
... ...
0xBF eip63
0xC0 eie0
0xC1 eie1
... ...
0xFF eie63
寄存器编号 0x71 和 0x73-0x7F 为预留值。当 *iselect CSR 具有其中一个值时,从匹配的 *ireg CSR(mireg、sireg 或 vsireg)读取将返回 0,写入 *ireg CSR 将被忽略。(对于 vsiselect 和 vsireg,所有访问都取决于 hstatus.VGEIN 是否为客户中断文件的有效编号)。
寄存器 eip0 至 eip63 包含所有已实现的中断标识的待处理位,统称为 eip 数组。寄存器 eie0 至 eie63 包含相同中断标识的使能位,统称为 eie 数组。
间接访问的中断文件寄存器和 CSR mtopei、stopei 和 vstopei 将在接下来的两节中详细介绍。
8、间接访问中断文件寄存器
本节介绍通过 *iselect CSR(miselect、siselect 或 vsiselect)及其伙伴 *ireg CSR(mireg、sireg 或 vsireg)间接访问中断文件的寄存器。这些间接访问的宽度始终是当前的 XLEN,RV32 代码为 32 位,RV64 代码为 64 位。
8.1、外部中断传递使能寄存器 (eidelivery)
【eidelivery 是一个 WARL 寄存器,用于控制中断文件中的中断是否从 IMSIC 发送到所连接的 hart,以便在 hart 的 mip 或 hgeip CSR 中显示为待处理外部中断】。寄存器 eidelivery 也可选择支持将 PLIC(平台级中断控制器)或 APLIC(高级 PLIC)的中断直接发送到所连接的 hart。目前为 eidelivery 定义了三种可能的值:
0 = 禁用中断传送
1 = 启用来自中断文件的中断传送
0x40000000 = 启用从 PLIC 或 APLIC 发送中断(可选)
如果 eidelivery 支持值为 0x40000000,则系统中的特定 PLIC 或 APLIC 可充当连接的 hart 的备用外部中断控制器,其特权级与该中断文件相同。当 eidelivery 值为 0x40000000 时,中断文件的功能与 eidelivery 值为 0 时相同,PLIC 或 APLIC 将取代中断文件,为 hart 提供该特权级的待处理外部中断。
访客中断文件不支持用于 eidelivery 的值 0x40000000。
如果支持该值,则 Reset 将 eidelivery 初始化为 0x40000000; 否则,复位后 eidelivery 具有未指定的有效值(0 或 1)。
8.2、External interrupt enable threshold register (eithreshold)
【eithreshold 是一个 WLRL 寄存器,它确定允许从该中断文件向连接的 hart 发出中断信号的最小中断优先级(最大中断标识号)】。 如果 N 是该中断文件的最大实现中断标识号,则 eithreshold 必须能够保存 0 到 N 之间的所有值(含 0 和 N)。
当 eithreshold 为非零值 P 时,无论 eie 数组中相应中断使能位的设置如何,中断标识 P 及以上的中断标识都不参与触发中断,就像这些中断标识未被启用一样。当 eithreshold 值为零时,所有已启用的中断标识都会参与中断文件的触发中断。
8.3、外部中断待处理寄存器 (eip0–eip63)
当 XLEN = 32 时,寄存器 eip[k] 包含标识号为 k × 32 到 k × 32 + 31 的中断的挂起位。对于在该范围内实现的中断标识 i,中断 i 的挂起位为 bit (i mod 32) 的 eip[k]。
**当 XLEN = 64 时,奇数寄存器 eip1、eip3、…eip63 不存在。**在这种情况下,如果 *iselect CSR 是 0x81-0xBF 范围内的奇数值,试图访问匹配的 *ireg CSR 会引发非法指令异常,除非在 VS 模式下进行,否则会引发虚拟指令异常。对于偶数 k,寄存器 eipk 包含标识号为 k × 32 至 k × 32 + 63 的中断的待处理位。对于该范围内已执行的中断标识 i,中断 i 的待处理位是寄存器 eipk 的位(i mod 64)。
有效 eipk 寄存器中与支持的中断标识不对应的位位置(如 eip0 的第 0 位)为只读 0。
8.4、外部中断使能寄存器 (eie0–eie63)
当 XLEN = 32 时,寄存器 eie[k] 包含标识号为 k × 32 到 k × 32 + 31 的中断的使能位。对于在该范围内实现的中断标识 i,中断 i 的使能位为 bit (i mod 32) 的eie[k]。
**当 XLEN = 64 时,奇数寄存器 eie1、eie3、…eie63 不存在。**在这种情况下,如果 *iselect CSR 是 0xC1-0xFF 范围内的奇数值,试图访问匹配的 *ireg CSR 会引发非法指令异常,除非在 VS 模式下进行,否则会引发虚拟指令异常。对于偶数 k,寄存器 eiek 包含身份号为 k × 32 至 k × 32 + 63 的中断的使能位。对于该范围内已执行的中断标识 i,中断 i 的使能位是寄存器 eiek 的位(i mod 64)。
有效 eiek 寄存器中与支持的中断标识不对应的位位置(如 eie0 的第 0 位)为只读 0。
9、Top 外部中断 CSRs (mtopei, stopei, vstopei)
CSR mtopei 直接与 IMSIC 的 M级 中断文件交互。 如果实现了 S 模式,CSR stopei 直接与 S级 中断文件交互。【如果实现了 H扩展 并且 hstatus 的字段 VGEIN 是已实现的访客中断文件的编号,则 vstopei 与所选访客中断文件进行交互】。
*topei CSR(mtopei、stopei 或 vstopei)的值指示中断文件当前最高优先级的 pending-and-enabled 的中断,如果 eithreshold 不为零,该中断也超过其 eithreshold 寄存器指定的优先级阈值。标识号较低的中断具有较高的优先级。
如果在中断文件的 eip 数组中没有待处理且在 eie 数组中也没有使能的中断,或者如果 eithreshold 不为零,且没有 pending-and-enabled 的中断的标识号小于 eithreshold 的值,则读取 *topei CSR 的结果为零。 否则,读取 *topei 返回的值具有以下格式:
bits 26:16 Interrupt identity
bits 10:0 Interrupt priority (same as identity)
所有其他位均为零。
*topei CSR 中报告的中断标识是 hart 上外部中断的次要标识。
对 *topei CSR 的写入会清除中断文件中的 pending 位,从而获得所报告的中断标识。写入的值将被忽略;相反,寄存器的当前可读值将决定哪个中断 pending 位被清除。**具体来说,【当写入 topei CSR 时,如果寄存器值 26:16 位的中断标识为 i,那么中断文件中中断 i 的待定位将被清零。当 topei CSR 的值为零时,对寄存器的写入不起作用】。
如果通过一条 CSR 指令(CSRRW、CSRRS 或 CSRRC)同时读写 *topei CSR,则读取返回的值表示被清零的 pending 位。
10、Interrupt delivery and handling
IMSIC 的中断文件向连接的 hart 提供外部中断信号,每个中断文件一个中断信号。来自 M级 中断文件的中断信号在 CSR mip 中显示为位 MEIP,而来自 S级 中断文件的中断信号在 mip 和 sip 中显示为位 SEIP。来自任何访客中断文件的中断信号在 hypervisor 的 CSR hgeip 中显示为 active bits。
当中断文件的 eidelivery 寄存器禁用中断发送(eidelivery = 0)时,来自中断文件的中断信号将保持非有效(假)状态。启用中断文件的中断传送(eidelivery = 1)后,如果仅当中断文件有一个 pending-and-enabled 的中断,且该中断也超过了 eithreshold 指定的优先级阈值(如果不为零)时,其中断信号才会被确认。
仅用于通过IMSIC 进行外部中断的陷阱处理程序可大致编写如下:
save processor registers
i = read CSR mtopei or stopei, and write simultaneously to claim the interrupt
i = i>>16
call the interrupt handler for external interrupt i (minor identity)
restore processor registers
return from trap
第二步中 mtopei 或 stopei 的组合读写可以通过单个 CSRRW 机器指令完成:
csrrw rd , mtopei/stopei, x0
其中 rd 是值 i 的目标寄存器。