首页 > 其他分享 >RISCV AIA (五) APLIC

RISCV AIA (五) APLIC

时间:2024-07-12 10:55:13浏览次数:19  
标签:APLIC RISCV 中断 MSI 寄存器 hart AIA pending

 APLIC

在RISC-V系统中,PLIC 处理外部中断是通过线中断而非MSI(message signal interrupt) 的方式,当系统的hart不具有IMSIC时,hart本身不支持MSI,因此所有的外部中断必须通过 PLIC。即使hart具有IMSIC,且大多数的中断使用 MSI 的方式,但有些设备还是以线中断的方式发出。特别是对于不需要在系统中启动总线事务的设备,支持MSI的成本较高,因此使用线中断时成本较低的选择。与MSI不同,当前计算机平台普遍支持线中断。这也是许多商用设备或控制器选择线中断而非MSI的另一个原因,除非实现像PCIe那样规定MSI的标准。

Advanced PLIC(以下简称 APLIC) 不向下兼容,也就是说不与RISCV PLIC兼容。完整的AIA架构是需要APLIC这个组件的。只要向 hart 发送 interrupt 是使用 wire interrupt 而不是 MSI,就可以使用 PLIC 建立一个可行的系统。不过,假设系统中不需要支持MSI,使用原有的PLIC也是可行的。

在不包含IMSIC的系统中,只会有一个PLIC或者APLIC,作为系统的外部中断控制器,将中断发送到每一个hart中。APLIC与每个hart之间采用独享的中断线连接,每个特权等级都对应一根中断线。

在包含IMSIC的系统中,IMSIC作为每个hart的外部中断控制器,其只接收MSI中断。在这种情况下,APLIC角色发生变化,不再充当hart的外部中断控制器,其作用为将线中断转换丞MSI中断发送到IMSIC中。当 hart具有支持IMSIC时,系统可能包含多个APLIC,用于将wire interrupt转换为MSI,每个APLIC对应一组外设。

中断源与中断标识

一个APLIC支持固定数量的中断源,这些中断源分别对应APLIC模块的物理中断线输入。通常,每个中断源的输入线都会连接一个设备或是设备控制器的输出中断线。对于电平触发的中断,可以将多个外设的中断线相或接入到APLIC的输入中断线上。当APLIC的输入中断线固定设置为0或者1,则该中断源通常配置为Detached模式。

每个APLIC的interrupt source都有一个唯一标识号(ID),范围为1到N,其中N是APLIC的源总数。0表示不是APLIC的有效中断标识号。APLIC可以支持的最大interrupt source为1023。

当 APLIC 将中断直接传递给 harts(不是将中断当作 MSI 转发)时,APLIC是该harts的外部中断控制器,并且APLIC的interrupt ID直接成为该中断的minor ID,并附带软件配置的优先级。

当APLIC通过MSI转发中断时,软件会为每个中断源的MSI配置一个新的interrupt ID。因此,在这种情况下,APLIC interrupt ID只区分APLIC的诸多输入interrupt,到IMSIC时就会使用软件配置的interrupt ID。

Interrupt domain

APLIC支持一个或多个interrupt domain,每个domain分别对应一组hart的某一特权等级(machine或者supervisor level),可以触发组内hart的对应特权等级的中断。每个domain都有各自的物理地址内存映射的控制区域,控制一个完整独立的APLIC。

下图是一个最简单的系统,只有一个hart并且不支持S mode,只有一个machine level的interrupt domain。

下图为SMP系统基本架构,其中hart支持S mode,并且具有多个hart,在这种情况下,APLIC通常会为supervisor level提供一个独立的interrupt domain,此interrupt domain允许操作系统直接在S态处理接收到的中断,避免调用M mode来处理中断,提高处理中断的效率。

APLIC的中断域是一个树状结构,根域总对应的是machine level。输入的线中断首先进入根中断域。每个中断域会有选择地将部分中断源进行委托给子中断域。需要注意的是不论在哪一个中断域,某一中断源的ID都是固定且一致的。对于根以下的中断域,未委托到该中断域的中断源对于该域来说表现为未实现。

下图显示了三个中断域的结构,两个在M level,一个在S level。当结合 PMP(physical memory protection,物理内存保护)使用时,允许软件在M level专门为hart 0(也就是 main hart)建立一个独立空间。

APLIC 的 interrupt domain 层次结构(hierarchy)须满足以下规则:

•      root domain为 M level。

•      S level 的interrupt domain的parent为M level interrupt domain。

•      每个interrupt domain都是用同样的方法送给hart,不论是线中断还是MSI,而不是通过hart之间混合的方式。

当一个RISC-V hart的外部中断控制器是APLIC而非IMSIC时,在每个特权级别,该hart只能位于此APLIC的一个中断域内。

当IMSIC作为RISC-V hart的外部中断控制器时,在每个特权级别,该hat可能位于多个APLIC中断域中(这些中断域在同一个APLIC),并且还有可能从多个不同APLIC接收MSI(每个APLIC可能对应一组外设)。

平台可以提供给软件一组接口来配置给定的APLIC的中断域结构,这不在本规范的讨论范围内,但是这种配置权限只能在Machine level下进行。

Hart index

一个中断域内的每个hart都有唯一的index,范围为0到 2^14 - 1 (= 16,383)。该index可能和RISC-V特权架构下的HART ID没有任何关系。对于相同一组的hart,两个不同的中断域可能使用完全不同的index。但是,如果APLIC的中断域通过MSI转发中断,那么APLIC的所有M level中断域的index需要相同。

单个中断域的组成

APLIC 实现的每个中断域都有自己独立的控制接口,该接口的访问地址为物理地址空间的内存映射,允许通过 PMP(physical memory protection,物理内存保护)和基于页表的地址转换,访问每个中断域。每个中断域的控制接口一致。

在大多数情况,每个中断域对软件来说,都好像是一个root domain,在结构中看不到它上一层的中断域。

对于APLIC的每个中断源,中断域具有以下组件:

  • 中断源配置。用来确认一个特定的中断源在该中断域内是否有效,如果有效,需要指定该中断源的类型,如电平触发还是边沿触发。如果该中断源在该域内无效,则需要配置委托到哪一个子中断域。
  • 中断pending和enable位。对于无效的中断源,则只读0。如果有效,pending位表示对应的中断已经到达但还未投递给hart,而enable位表示对应的中断允许投递给hart。
  • 目标选择。对于有效的中断源,用来选择投递的目标hart以及该中断的优先级(direct mode)或者interrupt identity(MSI mode)。

中断域的内存映射空间

对于APLIC实现的每一个中断域,都存在一个独享的内存映射的控制区域,用来处理该中断域的中断。该控制区域大小是由4KB的倍数,并与4KB地址边界对齐。最小的有效控制区域是16KB。一个中断域的控制区域由一组32bit位宽的寄存器组成,前16KB的寄存器如下图所示。

从偏移量 0x4000 开始,interrupt domain 的控制区域可以选择具有interrupt delivery control (IDC) 结构,每个hart都对应一个IDC 结构。IDC 结构只有在直接向 harts 传递 interrupt 时使用,而不是由 MSI 转发时使用。每个 IDC 结构为 32 字节,并定义如下:

IDC 结构是连续打包的,每个结构 32 字节,因此从 interrupt domain 控制区域的开头到其第二个 IDC 结构(hart index=1)的偏移量为 0x4020;第三个 IDC 结构(hart index=2)的偏移量为 0x4040 以此类推。

除了前16 KB中的缓存器和上面列出的用于 IDC 结构的缓存器外,interrupt domain 控制区域中的其他 byte 都被保留的,并且为 read only 0。中断域的控制区域只支持32bit对齐的访问。

Domain configuration (domaincfg)

domaincfg定义如下:

IE(Interrupt Eable)位指示所在中断域的所有有效中断源的全局使能标志。只有IE=1时,pending和enable同时置位的中断才会投递到目标hart。

DM(Delivery Mode)位表示中断的投递方式,其定义如下:

直接投递方式是指中断按优先级排列并由APLIC本身直接向Hart发出信号。MSI投递方式是指APLIC将中断以MSI的方式发送到hart,由hart中的IMSIC进一步处理。

如果中断域中的hart具有IMSIC,除非其对应的IMSIC的interrupt file的eidelivery支持0x4000_0000,否则将DM置0的效果等同于堆IE置0。

BE (big-Endian),它确定 interrupt domain 的寄存器byte的顺序, 如果BE = 0,表示byte顺序为little-endian,如果 BE = 1,表示为big-endian。(在现今主流的 CPU 中,最常见的字节顺序有两种,分别是 Big-Endian 与 Little-Endian,Big-Endian 是指数据放进内存中的时候,最高位的字节会放在最低的内存地址上,而 Little-Endian 则是刚好相反,它会把最高位的字节放在最高的内存地址上。)

在系统重置时,domaincfg 中的所有可写位都被初始化为零,包括 IE。

​​​​​​​Source configurations  (sourcecfg[1]–sourcecfg[1023])

Sourcecfg用来控制中断源的类型以及它的委托情况。当 source i未实现(该中断源无效),或出现在该中断域中未实现时(没有委托到该中断域),sourcecfg[i] 为只读零。在parent domain,如果中断源i未被委托到当前这个域(child domain),然后在其parent domain中通过配置sourcecfg委托到该域(child domain),则该child domain的sourcecfg会保持为0直到被写入有效的值(如SM)。

Sourcecfg的bit10简写为D,D=1表示当前这个domain是parent domain,该中断源会委托到他的child domain,具体委托到哪一个child domain,bit9:0指示委托到的child domain index(如果该parent domain包含C个child domain,则child domain index的范围为1-C)。

如果一个中断域不存在child domain,D只能为0,表示不进行委托,此时bit9:0的含义发生变化,用来指示中断源i是否有效以及其对应的中断类型。

当1、D=1或者2、D=0且SM=0,该中断源在当前的中断域内都是无效的。只要中断源是无效的,则对对应的pending、enable和target读请求,都会返回0。如果 source i 从 inactive 模式更改为 active 模式,则 pending bit 和 enable bit 还是保持零。

当中断源配置成Detached模式,对应的线中断输入会被忽略。但是它的setip和setipnum寄存器都可以进行置位。

​​​​​​​ Machine MSI address configuration (mmsiaddrcfg and mmsiaddrcfgh)

对于machine level的中断域,寄存器mmsiaddrcfg和mmsiaddrcfgh将提供传出的MSI地址参数。

如果APLIC的中断域没有支持MSI投递模式,则此两个寄存器没有作用。对于支持MSI的APLIC,在根中断域需要实现这两个寄存器,对于其他的Machine level的中断域可以选择性的支持,对于Supervisor level的中断域不能实现这两个寄存器,且只读0。对于根中断域,这个寄存器的属性是只写,而对于其他的Machine level的中断域,这两个寄存器的属性是只读。

mmisaddrcfg格式如下:

mmsiaddrcfgh格式如下:

Mmsiaddrcfgh的其他bit保留且只读0。

mmsiaddrcfgh(high base PPN) 以及 mmsiaddrcfg(low base PPN) 连接成一个44 bit的物理页基地址(PPN base)。

当在mmsiaddrcfgh的bit L被设为1时,则mmsiaddrcfg和mmsiaddrcfgh被锁住,并且忽略对该寄存器的写入,使其寄存器只可读。当L = 1时,mmsiaddrcfg和mmsiaddrcfgh中的其他字段可以选择全部读为零。在此情况下,当根中断域首次设置 L,且其他bit为非0时,他们的值会在APLIC内部保留,但如果读取mmsiaddrcfg和mmsiaddrcfgh将不可再见到这些值。

如果smiaddrcfg和smsiaddrcfgh也被实现的话,将mmsiaddrcfgh.L设置为1也会锁定smsiaddrcfg和smsiaddrcfgh。

对于根中断域,L在系统复位时初始化微0或者1,由APLIC的具体实现决定。如果L初始化为1,则mmsiaddrcfg的其他域被硬件置为常数,或者APLIC有其他的标准之外的方式确定MSI写入的地址。在此情况下,mmsiaddrcfg和mmsiaddrcfgh的值可能为0x0和0x80000000。

对于非根中断域的其他Machine level的中断域,如果实现了这两个寄存器,则L常置为0,其他位置那么是根中断域mmsiaddrcfg和mmsiaddrcfgh的拷贝,要么是全0.

​​​​​​​Supervisor MSI address configuration

对于M level,smsiaddrcfg和smsiaddrcfgh可以选择S level所使用的参数,用来写入传出MSI的地址参数。

如果一个中断域实现了mmsiaddrcfg和mmsiaddrcfgh,并且APLIC具有S level的中断域,则该域也会实现smsiaddrcfg和smsiaddrcfgh。

与mmsiaddrcfg和mmsiaddrcfgh类似,smsiaddrcfg和smsiaddrcfgh在根中断域的属性是只写,在其他的M level的中断域的属性是只读。

当smisadrcfg实现时,具有以下格式

以及当smsiadrcfgh实现时,具有以下格式:

smsiaddrcfgh(high base PPN) 以及smsiaddrcfg(low base PPN) 连接成一个44 bit的物理页基地址(PPN base)。

如果一个域中的mmisaddrcfgh的L bit被设为1时,则smisaddrcfg和smsiaddrcfgh与mmisaddrcfg和 mmisaddrcfgh一起被锁定为只读。

​​​​​​​Set interrupt-pending bits (setip[0]–setip[31])

读取或写入setip[k]可以修改中断源k*32 到 k*32+31的pending位。对于该范围内所实现的中断源i,它的 pending bit位于 (i mod 32)的位置。读取setip会返回相对应的中断源的pending位,假设该中断源并未实现,则读取setip相对应的位置为 0。

在写入setip寄存器时,对于写入的32位值中为1的每一位,如果该位位置是有效的中断源(active interrupt source),则该源的pending位将设置为1。

​​​​​​​Set interrupt-pending bit by number (setipnum)

如果i是一个中断域中的有效中断源标识,则将i写到setipnum会让对应pending位置1。如果i不是该中断域中的有效中断源标识,则忽略 setipnum 的写入。对该寄存器的读请求都会返回0。

​​​​​​​Rectified inputs, clear interrupt-pending bits (in_clrip[0]–in_clrip[31])

读取in_clrip[k]返回中断源k*32 到 k*32+31的校正输入值,而写入in_clrip[k]会修改同一个中断源的pending位。读取寄存器in_clrip会返回相对应的中断源的校正输入值,假设该中断源并未实现(超出了中断编号的范围),则读取in_clrip相对应的位置为 0。

在写入setip寄存器时,对于写入的32位值中为1的每一位,如果该位位置是有效的中断源(active interrupt source),则该源的pending位将被清零。

​​​​​​​Clear interrupt-pending bit by number (clripnum)

如果i是一个中断域中的有效中断源标识,则将i写到clripnum会让对应pending位置1。如果i不是该中断域中的有效中断源标识,则忽略 clripnum 的写入。对该寄存器的读请求都会返回0。

​​​​​​​Set interrupt-enable bits (setie[0]–setie[31])

读取或写入setie[k]可以修改中断源k*32 到 k*32+31的enable位。对于该范围内所实现的中断源i,它的 enable bit位于 (i mod 32)的位置。读取setie会返回相对应的中断源的pending位,假设该中断源并未实现,则读取setie相对应的位置为 0。

在写入setie寄存器时,对于写入的32位值中为1的每一位,如果该位位置是有效的中断源(active interrupt source),则该源的enable位将设置为1。

​​​​​​​Set interrupt-enable bit by number (setienum)

如果i是一个中断域中的有效中断源标识,则将i写到setienum会让对应pending位置1。如果i不是该中断域中的有效中断源标识,则忽略 setipnum 的写入。对该寄存器的读请求都会返回0。

​​​​​​​Clear interrupt-enable bits (clrie[0]–clrie[31])

写入clrie[k]可以修改中断源k*32到k*32+31的enable位。对于该范围内所实现的中断源i,它的 enable bit位于 (i mod 32)的位置。

在写入clrie寄存器时,对于写入的32位值中为1的每一位,如果该位位置是有效的中断源(active interrupt source),则该源的enable位将设置为0。

​​​​​​​Clear interrupt-enable bit by number (clrienum)

如果i是一个中断域中的有效中断源标识,则将i写到clrienum会让对应pending位置1。如果i不是该中断域中的有效中断源标识,则忽略 clripnum 的写入。对该寄存器的读请求都会返回0。

​​​​​​​Set interrupt-pending bit by number, little-endian (setipnum_le)

寄存器setipnum_le的作用与setipnum相同,只是字节顺序固定为小端格式。对于只有大端格式且 domaincfg BE为1的系统,不需要实现 setipnum_le,此时该寄存器相其他保留的寄存器一样只读为0。

setipnum_le可用于MSI的写入端口。

​​​​​​​Set interrupt-pending bit by number, big-endian (setipnum_be)

寄存器setipnum_be的作用与setipnum相同,只是字节顺序固定为大端格式。对于只有小端格式且 domaincfg BE为0的系统,不需要实现 setipnum_be,此时该寄存器相其他保留的寄存器一样只读为0。

setipnum_be可用于MSI的写入端口。

​​​​​​​Generate MSI (genmsi)

当中断域配置为MSI传送模式 (domaincfg.DM = 1) 时,寄存器genmsi可用于APLIC发送临时的MSI到hart。该功能的主要目的是帮助在hart到APLIC寄存器的写入和从APLIC到hart的MSI传输之间建立临时的已知顺序。(genmsi的作用类似域fence,一种多个MSI的保序操作)

出于其他目的,将MSI发送到hart通常最好直接写入hart的 IMSIC(detached模式下,对pending和enable置位),而不是使用APLIC作为中介。应尽量减少genmsi寄存器的使用,以避免它成为瓶颈。

寄存器genmsi 具有以下格式:

所有其他寄存器位均被保留并读为零。

Busy位通常为0(即为假),但写入genmsi会导致Busy变为1(即为真,表示软件不会直接对busy位置位),表明临时MSI正在等待处理。Hart Index字段指定目标Hart,EIID(外部中断标识)指定MSI的数据值。字段Hart Index和EIID具有与target寄存器(在下一小节4.5.16中描述)中相同的格式和行为。对于M level中断域,临时MSI被发送到M level的目标 hart,而对于S level中断域,临时 MSI 被发送到S level的目标hart。

APLIC应以最小的延迟发送待处理的临时MSI。一旦它离开APLIC并且APLIC能够接受另一个对genmsi的新写入而产生的临时MSI,Bus​​y将恢复为false。之前从该APLIC发送到同一HART的所有MSI必须在HART的IMSIC上可见,然后临时MSI在HART的IMSIC上变得可见(保序的具体解释,将临时MSI的之前的MSI传输与之后的MSI的传输保证严格的顺序)。

当Busy为true时,对genmsi的写入将被忽略。

临时MSI不受该中断域的domaincfg寄存器的IE位影响。即使domaincfg.IE = 0,也会发送临时MSI。

当中断域配置为直接传递模式(domaincfg.DM = 0)时,寄存器genmsi为只读零。

​​​​​​​Interrupt targets (target[1]-target[1023])

如果中断源i在此中断域中为inactive,则寄存器target[i]为只读零。如果源i处于active状态,则target[i]确定中断源的目标hart。target[i]的准确解释取决于寄存器domaincfg的字段DM配置的传递模式。

如果更改了domaincfg.DM,则中断域内所有active的中断源的target寄存器将在为新传送模式定义的所有字段中获取未指定的值。(言外之意是,中断投递方式发生变化后,target寄存器的所有字段会变得无意义,等软件重新对该寄存器进行置位)

对于活动中断源i,如果域配置为直接传递模式 (domaincfg.DM = 0),则寄存器target[i]具有以下格式:

所有其他寄存器位均被保留并读为零。

Hart Index是一个WLRL字段,指定该中断源将传送到的Hart。

IPRIO(中断优先级)字段指定中断源的优先级编号。该字段是IPRIOLEN位宽的无符号整数,其中IPRIOLEN是给定APLIC的常量参数,范围为1到 8。IPRIO 只允许使用值1到2^IPRIOLEN - 1,而不是0。对target寄存器的写入会将IPRIO设置为写入的32位值中的位 (IPRIOLEN - 1):0,除非这些位全部为0,在这种情况下,优先级编号将设置为 1。(如果 IPRIOLEN = 1,这些规则会导致IPRIO实际上为只读,值为1。)

较小的优先级编号表示较高的优先级。当中断源具有相同的优先级编号时,标识编号最低的中断源具有最高优先级。

中断优先级被编码为整数,数字越小表示优先级越高,以匹配IMSIC对优先级的编码。

对于活动中断源i,如果域配置为MSI传递模式 (domaincfg.DM = 1),则寄存器target[i]具有以下格式:

位11被保留并读为零。

Hart Index字段指定该中断源将传送到的Hart。

如果中断域处于S level,并且该域的hart实现了RISC-V特权架构的H扩展,则Guest Index是一个 WLRL 字段,必须能够保存0到GEILEN范围内的所有整数值。(参数 GEILEN 由特权架构的H扩展定义。)否则,字段Guest Index为只读零。对于S level中断域,非零的Guest Index是将MSI发送到的目标Hart的guset interrupt file的编号。当Guest Index为0时,来自S level中断域的MSI将转发到S level的目标hart。对于M level中断域,Guest Index为只读零,并且MSI始终在机器级转发到目标hart。

寄存器target[i]的Hart Index和Guest Index字段共同确定为中断源i转发的MSI的地址。剩余字段 EIID(外部中断标识)指定MSI的数据值,最终成为目标hart处外部中断的次要标识。

如果中断域的hart具有实现N个不同中断标识的 IMSC 中断文件(第3.1节),则 EIID 是 k 位无符号整数字段,其中⌈log2 N ⌉ ≤ k ≤ 11(即EIID的位宽能足够指示N个中断标识)。因此EIID能够保存至少值0到N。对target寄存器的写入,其bit10:0赋值给EIID。

​​​​​​​Reset

APLIC复位后,其所有状态都变得有效且一致,但未指定,但以下情况除外:

  • 每个中断域的domaincfg寄存器(第 4.5.1 节);
  • 可能是机器级中断域MSI地址配置寄存器(第4.5.3 和4.5.4 节);
  • 每个中断域的genmsi寄存器的Busy位(如果存在)(第 4.5.15 节)。

对中断pending位的置位或清零

尝试通过写入中断域控制区域中的寄存器来设置或清除中断源的pending位可能会成功,也可能不会成功,具体取决于相应的中断源模式、中断域的中断投递模式以及中断源校正输入的状态值(第4.5.2节中定义)。下面列举了针对给定的中断源源模式设置或清除pending位时的所有情况。

如果源模式为“Detached”:

  • 仅通过对setip或setipnum寄存器执行相关写入操作将挂起位设置为1。
  • 当在APLIC处请求中断或由MSI转发中断,或者通过对in_clrip寄存器或clripnum进行相关写入时,将清除pending位。

如果源模式为Edge1或Edge0:

  • 通过校正输入值从低到高的跳变,或者通过对setip或setipnum寄存器进行相应写入,将pending位设置为1。
  • 当在APLIC处请求中断或由MSI转发中断,或者通过对in_clrip寄存器或clripnum进行相关写入时,将清除pending位。

如果源模式为Level1或Level0并且中断域配置为直接投递模式(domaincfg.DM = 0):

  • 只要校正后的输入值为高电平,pending位就会设置为1。无法通过写入setip或setipnum寄存器来设置pending位。
  • 只要校正后的输入值为低电平,pending位就会被清除。pending位不能通过 APLIC 处的中断声明来清除,也不能通过写入in_clrip寄存器或clripnum来清除。

如果源模式为Level1或Level0并且中断域配置为MSI投递模式(domaincfg.DM = 1):

  • 通过校正输入值中从低到高的跳变将pending位设置为1。当经校正的输入值为1时,也可以通过setip或setipnum寄存器的相应写入来设置pending位。
  • 只要校正后的输入值为低电平,或者通过对in_clrip寄存器或clripnum进行相关写入,就会清除pending位。

当中断域处于直接投递模式时,电平触发的中断源的pending位始终只是整流输入值的副本。即使在MSI传送模式下,当校正输入值为0时,电平触发的中断源的pending位也不会被设置 (= 1)。

除上述规则外,如第4.5.2节中所述,对sourcecfg寄存器的写入还可导致源的中断挂起位设置为1。

APLIC的中断直接投递方式

当中断域处于直接投递模式 (domaincfg.DM = 0) 时,中断通过每个hart的唯一信号(通常是专用中断线)从APLIC传递到hart。在这种情况下,中断域的内存映射控制区域在末尾包含一组中断传送控制 (IDC) 结构,每个hart都会对应一个IDC结构。第一个IDC结构是该中断域内索引为0的hart;第二个是该中断域索引为1hart;依次类推。

​​​​​​​Interrupt delivery control (IDC) structure

每个IDC结构都是32字节(对齐到 32 字节地址边界)并具有以下定义的寄存器:

如果IDC结构针对的特定hart对于中断域中的任何实际hart都无效,则这些寄存器可以选择全部为只读零。否则,寄存器将在下面单独描述。

特定的APLIC可能被构建为支持最大数量的hart,而无需完全了解系统在每个中断域中使用的hart索引号集。在这种情况下,对于未使用的hart索引号,APLIC可能具有在APLIC内起作用的IDC结构(不是只读零),但只是不连接到任何物理 hart。

Interrupt delivery enable (idelivery)

idelivery是一个WARL寄存器,用于控制是否将中断传递到对应的hart,以便它们在hart的mip CSR中显示为待处理中断。当前仅为 idelivery 定义了两个值:

如果IDC结构用于不存在的hart(即,对在中断域中的任何实际hart,该hart索引都是无效的),则即使将idelivery设置为1也不会将中断传送到任何hart。

Interrupt force (iforce)

iforce是一个可用于测试的WARL 寄存器。仅允许使用值0和1。只要domaincfg的IE字段为1并且通idelivery寄存器使能到hart的中断传送,设置iforce = 1 就会强制向相应的hart 发出中断。当topi为0时,这会为hart创建一个虚假的外部中断。

当读取寄存器claimi返回中断标识为0(表示虚假中断)时iforce将自动清零。

Interrupt enable threshold (ithreshold)

ithreshold是一个WLRL寄存器,用于确定向相应hart发送中断信号的最小中断优先级(即最大优先级编号)。寄存器ithreshold精确实现 IPRIOLEN 位,因此能够覆盖从0到2^IPRIOLEN − 1的所有优先级编号。

当ithreshold为非零值P时,无论其中断源的enable位是否置位,优先级编号为P及更高的中断源不会向 hart 发送中断信号,就好像这些中断源未使能一样。当ithreshold为零时,所有enable=1的中断源都可以向hart发出中断信号。

Top interrupt (topi)

topi是一个只读寄存器,其值指示当前针对此hart的最高优先级的pending和enable的中断,该中断也超过由 ithreshold 指定的优先级阈值(如果不为0)。

如果没有针对此hart的中断pending和enable置位,或者如果 ithreshold 不为零并且没有针对此hart的挂起且启用的中断的优先级编号小于 ithreshold 的值,则 topi 的读取返回零。否则,从 topi 读取返回的值具有以下格式:

所有其他位位置均为零。

topi中报告的中断标识是目标hart处的外部中断的次要标识。

对topi的写入将被忽略。

Claim top interrupt (claimi)

寄存器claimi与topi具有相同的值。当该值不为零时,读取claimi 会清除该值对应的中断标识的pending位。请参阅第4.7节,了解读取claimi时清除pending位的确切时间。

从claimi读取返回零值的同时会将iforce寄存器设置为0。

对claimi的写入将被忽略。

​​​​​​​ 中断投递和处理

当配置中断域以使APLIC直接向HART传送中断时(domaincfg的字段DM为零),APLIC在对应中断域的特权级别为该域的所有HART提供外部中断信号,只要以下一个条件满足:(a) hart没有IMSIC,或 (b) 相关IMSIC中断文件的eidelivery寄存器设置为0x40000000(第3.8.1节)。对于M level,来自APLIC的中断信号在每个hart的mip CSR中显示为位MEIP(achine External Interrupt-Pending)。对于S level,中断信号在每个hart的mip sip CSR中显示为 SEIP 位(supervisor External Interrupt-Pending)。每个中断信号可以任意延迟从APLIC传输到对应的hart。

在APLIC,发送至hart的每个中断信号均源自寄存器domaincfg的IE字段以及该域的内存映射控制区域中 hart IDC结构的当前状态。如果domaincfg.IE = 0或通过idelivery寄存器禁用到hart的中断传送(idelivery = 0),则中断信号将保持无效状态。当domaincfg.IE = 1并且中断投递被使能(idelivery = 1)时,只要寄存器iforce或topi不为零,中断信号就会被置位。

由于APLIC和hart之间的通信可能存在延迟,因此可能会发生外部中断陷阱被捕获(hart侧的MEIP或SEIP置位),但当实际发生对claimi寄存器的读取时,没有该hart中断enable和pending的情况。在这种情况下,claimi返回的中断标识为0,从而导致来自APLIC的表现为虚假中断。便携式软件必须做好应对 APLIC 上可能出现的虚假中断的准备,这种情况可以安全地被忽略,而且应该很少见。出于测试目的,可以通过将IDC结构的iforce寄存器设置为1来触发Hart的虚假中断。

仅用于通过APLIC进行外部中断的陷阱处理程序可大致编写如下:

​​​​​​​Interrupt forwarding by MSIs

在MSI投递模式(domaincfg.DM = 1)下,中断域通过MSI将中断转发到目标hart。

仅当中断源对应的pending位和enable位都为1并且寄存器domaincfg的IE字段也为1时,才会为特定中断源发送MSI。如果发送MSI,则源的中断pending位将被清除。

​​​​​​​MSI的地址和数据

要通过MSI转发中断,APLIC必须知道每个hart的MSI目标地址。对于任何给定的系统,这些地址都是固定的,并且如果可能的话应该硬连线到APLIC中。然而,某些 APLIC 实现可能要求软件提供MSI目标地址。在这种情况下,根中断域的寄存器mmsiadrcfg、mmsiadrcfgh、smsiadrcfg和smsiadrcfgh(第4.5.3节和4.5.4节)可用于配置所有中断域的MSI地址。或者,MSI 地址可以通过本标准之外的某些自定义方式进行配置。如果 MSI 目标地址必须由软件配置,则只能在系统重置后不久的适当特权执行模式下完成此操作,通常仅一次。

对于M level中断域,如果 MSI 目标地址由 mmsiadrcfg 和 mmsiadrcfgh 确定,则根据这些寄存器和寄存器 target[i]的Hart Index字段计算中断源i的传出MSI的地址,如下所示:

其中,<< k和 >> k表示左移和右移k位,“&”表示按位逻辑“与”,竖线“|”表示按位逻辑“或”。假设遵循第3.6节的建议在物理地址空间中IMSIC中断文件的排布,值g旨在表示hart组的编号(如果 HHXW = 0,则始终为零),而h是目标hart在该组内的编号。用第3.6节的术语表示,HHXW = j、LHXW = k、HHXS = E − 24、LHXS = C − 12 和 Base PPN = A>>12。

对于S level中断域,如果MSI目标地址由根域的配置寄存器(smsiadrcfg等)确定,则要构造中断源i的MSI地址,需要使用寄存器 target[i]中的Hart索引(存放的S域的hart index)必须首先转换为M level域的同一hart的索引号。 (不同域的hart index通常相同,但也可能不同。)然后,使用此M level的hart 索引以及来自smsiaddrcfg和smsiaddrcfgh的Base PPN和LHXS值以及其他字段(HHXW、LHXW、HHXS)来计算MSI的地址。其中,Guest Index来自target[i],如下所示:

用第3.6节的术语表示,HHXW = j、LHXW = k、HHXS = E − 24、LHXS = D − 12 和 Base PPN = B>>12。

MSI的数据取自target[i]的EIID字段,0扩展到32位。无论域的domaincfg寄存器的BE字段如何,MSI的32位数据始终以小端字节顺序写入。

​​​​​​​对电平触发中断源的特别考虑

如果MSI转发的是电平触发中断源,APLIC就会清除中断源的pending位,然后忽略该源的线中断输入,直到该输入被清零。发送MSI时清除pending位显然是必要的,以避免同一中断从APLIC到目标hart的持续重复MSI传输。然而,在中断服务例程处理了该中断源后,传入的中断线可能会因其他原因在APLIC处保持有效状态,尽管APLI 处的中断pending位已被清除,并且在没有软件干预的情况下将保持这种状态。如果中断服务例程随后退出而不采取进一步操作,则该位置的中断线输入可能永远都不会被中断控制器处理。

为了避免以这种方式丢弃中断,电平触发中断的中断服务例程可以在退出之前执行以下操作之一:

第一个选项是通过读取APLIC的in_clrip寄存器中的相应内容来测试进入APLIC的中断线是否仍然有效。如果传入中断仍然有效,则可以重复中断服务例程的主体,以在再次测试中断线是否有效之前查找并解决额外的中断原因。一旦观察到传入线路未断言,中断服务例程就可以安全退出,因为任何新的中断断言都将导致pending位被置位,并将新的MSI发送到 hart。

第二个选项是中断服务例程在退出之前将中断的APLIC源标识号写入域的setipnum寄存器。如果该中断源仍有效,则这将导致中断的pending位再次设置为1,但如果该中断源不再有效,则中断的pending位不再置位。

​​​​​​​​​​​​​​同步hart和APLIC之间的交互

当APLIC向hart发送MSI时,在hart的IMSIC处观察到MSI之前,会存在不确定的传输延迟。因此,在通过写入APLIC寄存器来更改APLIC的配置后,harts可能会在写入APLIC寄存器之前不确定的时间内持续查看从APLIC到达的MSI。

有时有必要知道何时不再有这些迟到的MSI到达。例如,如果一个hart将被关闭(“断电”),则所有指向它的中断都必须重定向到其他hart,这可能涉及重新配置一个或多个APLIC。即使在重新配置APLIC之后,在确定不再有MSI发送给它之前,hart仍然无法安全关闭。

genmsi寄存器(第4.5.15节)的存在是为了允许软件确定所有早期MSI何时到达 hart。为了将genmsi 用于此目的,软件可以在每个hart的IMSIC中断文件中专用一个外部中断标识,仅用于APLIC同步。假设有多个 hart,APLIC的genmsi寄存器也应该受到标准互斥锁的保护。然后可以使用以下序列在APLIC和特定HART 之间进行同步:

1. 在hart的IMSIC处,清除专门用于APLIC同步的特定次要中断标识的pending位。

2. 获取APLIC的genmsi寄存器的共享锁。

3. 写入genmsi,生成一个MSI给hart,中断标识为i。

4. 重复读取genmsi,直到Busy 位为假。

5. 释放genmsi 的锁。

6. 重复读取hart IMSIC上次要中断标识 i 的pending位,直到发现该位已设置。

步骤 4 和 6 的循环通常预计会很快成功,通常是在第一次或第二次尝试时。当此序列完成时,来自 APLIC 的所有早期 MSI 也必须已到达 hart 的 IMIC。

标签:APLIC,RISCV,中断,MSI,寄存器,hart,AIA,pending
From: https://blog.csdn.net/weixin_53899594/article/details/140371013

相关文章

  • aiops时代, 10分钟学会用AIAnsbile去调试ansible任务
    AIAnsible:aiansible地址:https://github.com/sunnycloudy/aiansible调试ansible,用ai自动注释,自动分析报错,自动给出建议技术问答:qq群:937374915ai提示效果/example:默认是中文版,中文版效果:!如果要设置成英文版:exportAIANSIBLE_LANG=EN或在aiansible中用......
  • 【会议征稿,ACM出版】2024年第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024,7
    2024第四届人工智能、自动化与高性能计算国际会议(AIAHPC2024)将于2024年7月19-21日在中国·珠海召开。本次会议主要围绕“人工智能、自动化与高性能计算”的最新研究展开,旨在荟聚世界各地该领域的专家、学者、研究人员及相关从业人员,分享研究成果,探索热点问题,交流新的经......
  • RISCV
    RISCVriscv通用寄存器riscv通用寄存器寄存器调用名字用途x0zero常数0x1ra返回地址x2sp栈指针x3gp全局指针x4tp线程指针x5-x7t0-t2临时存储x8s0/fp保存用寄存器/帧指针(配合栈指针界定一个函数的栈)x9s1保存用寄存器x10-x11a0-a1函数参数/返回值x12-x17a2-a7函数参数x......
  • 2024年人工智能、算法与自动化工程国际学术会议(ICAIAAE 2024)
    【会议简介】   2024年人工智能、算法与自动化工程国际学术会议将汇聚来自世界各地的顶尖学者,共同探讨人工智能、算法与自动化工程领域的尖端技术和发展趋势。会议将围绕深度学习、机器学习算法和自动化系统设计等多个主题展开,展示最新的研究成果,推动技术创新和产业应......
  • AIAB BDC弹窗选择 标准程序处理
    TYPES:BEGINOFGTY_S_POSTAB."BeginofS2IINCLUDESTRUCTUREAIMTV.TYPES:OBJNRLIKEANLA-OBJNR,"merkerco-objektZAEHLLIKESY-TABIX,"......
  • [AIAgent]白菜GPT支撑AutoGen开发示例
    AutoGen示例说明AIAgnet仅限GPT4支持,请完成一次请求Token不可预估,请留意费用消耗。免费会员GPT4配额,很可能不足以支撑完成DEMO演示,建议付费会员测试体验。部分示例代码参考AutoGen官方文档,重点验证白菜GPT对AutoGen的支撑能力,详细代码说明,请参考官方文档。所有示例代码均在......
  • Book-Riscv-XV6-Chap1
    操作系统接口–阅读xv6-riscv-bookXv6的时钟周期:定时器芯片两次中断之间的时间xv6作为一个简单的操作系统,利用一个“内核kernel”向其他运行中的程序提供服务的特殊程序,这个内核相当于连接了硬件和运行程序。每一个正在运行的程序可以称为进程,都拥有子集的包含指令、数据、......
  • riscv linker relaxations 是什么
    什么是linkerrelaxations由于链接时携带一些符号地址信息,可以执行一些编译时难以或者不大可能实现的优化。LinkerRelaxtion与传统编译时期的优化是不一样的,此优化发生在链接时。通常情况下,在链接时,改变代码的执行序列是有风险的,因为语义信息此时会丢失,链接器看到也仅是字节流......
  • riscv gnu编译器
    官网https://github.com/riscv-collab/riscv-gnu-toolchain编译器基于RISC-V交叉编译器包括32bit和64bit两种类型,其中每种类型又包括裸机版本(newlib)和动态链接库版本(linuxglibc)newlib./configure--prefix=/opt/riscvmakeglibc#默认仅支持64位target./configure--......
  • 学习riscv(1)安装tinyriscv的工具链
    因为毕设是CPU的低功耗设计,所以开始看cpu,打算还是先从这个tinyriscv学起,昨天把环境下好了,第一步是用git去clone代码,这个首先要下载git,然后在目标文件夹鼠标右键,选择“opengitbushhere”,再输入项目的url,就可以了。方法不难。b站有详细教程接下来是安装工具,我用的是wind......