RISC-V架构异常处理机制

参考《RISC-V架构与嵌入式开发快速入门》

1 进入异常

进入异常时,RISC-V架构规定的硬件行为可以简述如下:
(1)停止执行当前程序流,转而从CSR寄存器mtvec定义的PC地址开始执行。
(2)进入异常不仅会让处理器跳转到上述的PC地址开始执行,还会让硬件同时更新其他几个CSR寄存器,分别是以下4个寄存器,
机器模式异常原因寄存器mcaue (Machine Cause Register)
机器模式异常PC寄存器mepc (Machine Exception Program Counter)
机器模式异常值寄存器mtval (Machine Trap Value Register)
机器模式状态寄存器mstatus (Machine Sauns Register)
下文将分别予以详述。

1.1 从mtvec定义的PC地址开始执行

RISCY架构规定,在处理器的程序执行过程中,一旦遇到异常发生, 则终止当前的程序流,处理器被强行跳转到个新的PC地址。该过程在RISCV的架构中定义为“陷阱(trap)”,宇面含义为“跳入陷阱”,更加准确的意泽为“进入异常”。
RISCV处理器trap后跳入的PC地址由个叫做机器模式异常入口基地址寄存器mtevc(Machine Trp-Vecor Base-Address Register)的CSR寄存器指定,其要点如下。
(1)mtvec寄存器是一个可读可写的 CSR寄存器,因此软件可以编程更改其中的值。
(2) mtvec寄存器的详细格式如图1所示,其中的最低2位是MODE域,高30位是BASE域。


图1:mtvec寄存器的格式

●假设 MODE的值为0,则所有的异常响应时处理器均跳转到BASE值指示的PC地址。
●假设MODE的值为1,则狭义的异常发生时,处理器跳转到BASE值指示的PC地址;狭义的中断发生时,处理器跳转到BASE+4xCAUSE值指示的PC地址。CAUSE的值表示中所对应的异常编号(Exception Code), 如图2所示。譬如机器计时器中断(Machine Timer Interrupt) 的异常编号为7,则其跳转的地址为BASE+4x7=BASE+28 = BASE+0x1C.


图2:mcause寄存器中的Exception Code

1.2 更新CSR寄存器mcause

RISC-V架构规定,在进入异常时,机器模式异常原因寄存器mcause (Machine CauseRegister)被同时更新,以反映当前的异常种类,软件可以通过读此寄存器查询造成异常的具体原因。
mcause寄存器的详细格式如图3所示,其中最高1位为Interrupt域,低31位为异常编号域。此两个域的组合表示值如图2所示,用于指示RISC-V架构定义的12种中断类型和16种异常类型。


图3:mcause寄存器的格式

1.3 更新CSR寄存器mepc

RISC-V架构定义异常的返回地址由机器模式异常PC寄存器mepe (Machine Exception Program Counter)保存。在进入异常时,硬件将白动更新mepc寄存器的值为当前遇到异常的指令PC值(即当前程序的停止执行点)。该寄存器将作为异常的返回地址,在异常结束之后,能够使用它保存的PC值回到之前被停止执行的程序点。
(1)值得注意的是,虽然mope寄存器会在异常发生时自动被硬件更新,但是mcpe寄仔器本身也是一个可读可写的寄存器,因此软件也可以直接写该寄存器以修改其值。
(2)对于狭义的中断和狭义的异常而言,RISV-V 架构定义其返回地址(更新mepc)有些细微差别。
出现中断时,中断返回地址mepc的值被更新为下一条尚未执行的指令。
出现异常时,中断返回地址mepc的值被更新为当前发生异常的指令PC。注意:如果异常由ecall或ebreak产生,由于mepc的值被更新为ecall或ebreak指令自己的PC.因此在异常返回时,如果直接使用mepc保存的PC值作为返回地址,则会再次跳回ecall或者ebreak指令,从而造成死循环(执行ecall或者ebreak 指令导致重新进入异常)。正确的做法是在异常处理程序中软件改变mepc指向下一条指令, 由于现在ecall/ebreak (或c.ebreak) 是4 (或2)字节指令,因此改写设定mepe mepc+4 (或+2)即可。


图4:mepc寄存器的格式

1.4 更新CSR寄存器mtval

RISC-V架构规定,在进入异常时, 硬件将自动更新机器模式异常值寄存器mtval(Machine Trap Value Resiste,以反映引起当前异常的存储器访问地址或者指令编码。
●如果是由存储器 访问造成的异常,替如遭遇硬件断点、取指令、存储器读写造成的异常,则将存储器访间的地址更新到mtval寄存器中。
●如果是由非法指令造成的异常,则将该指令的指令编码更新到mtval 寄存器中。
注意: mtval 寄存器又名mbadadd 寄存器,在某些版本的RISC-V 编译器中仅识别mbadaddr名称。


图5:mtvcal寄存器格式

1.5 更新CSR寄存器mstatus

RISC-V架构规定,在进入异常时,硬件将自动更新机器模式状态寄存器msatut MacbineStatus Register)的某些域。
(1) mstatus寄存器的详细格式如图6所示,其中的MIE域表示在Machine Mode下中断全局使能。


图6 mstatus 寄存器的格式

●当该MIE 域的值为1时,表示机器模式下所有中断的全局打开。
●当该MIE域的值为0时,表示机器模式下所有中断的全局关闭。
(2) RISC-V 架构规定,异常发生时有如下情况。
●MPIE域的值被更新为异常发生前MIE域的值。MPIE域的作用是在异常结束之后,能够使用MPIE的值恢复出异常发生之前的MIE值。
●MIE的值则被更新成为0 (意味着进入异常服务程序后中断被全局关闭,所有的中断都将被屏蔽不响应)。
●MPP的值被更新为异常发生前的模式。MPP域的作用是在异常结束之后,能够使用MPP的值恢复出异常发生之前的工作模式。对于只支持机器模式(Machine ModeOnly)的处理器核,则MPP的值永远为二进制值11.
注意:在此仅介绍“只支持机器模式”的架构,因此对SIE、UIE、SPP、SPIE等不做赞述。对其感兴趣的读者请参考RISC-V“特权架构文档”原文。

2 退出异常

当程序完成异常处理之后, 最终需要从异常服务程序中退出,并返回主程序。RISC-V架构定又了一组专门的退出异常指令(Trap-Return Instruction是)包括MRET、SRET和USET,其中MIRET指令是必备的,而SRET和URET指令仅在支持监督模式和用户模式的处理器中使用。
注意:在此仅介绍“只支持机器模式”的架构,对SRET和URET指令不做赞述。对其感兴趣的读者请参考RISCV“特权架构文档”原文。
在机器模式下退出异常时,软件必须使用MRET指令。RISC-V架构规定,处理器执行MRET指令后的硬件行为如下。
●停止执行当前程序流,转而从CSR寄存器mepe定义的PC地址开始执行。
●执行MRET指令不仅会让处理器跳转到上.述的PC地址开始执行,还会让硬件同时更新CSR寄存器机器模式状态寄有器mstuts (Machine Status Register)。下文将分别予以详述。

2.1 从mepc定义的PC地址开始执行

在上面提及,在进入异常时,mepc 寄存器被同时史新,以反映当时遇到异常的指令的PC值。通过这个机制,意味者MRET指令执行后处理器回到了当时遇到异常的指令的PC地址,从而可以继续执行之前被中止的程序流。

2.2 更新CSR寄存器mstatus

mstatus寄存器的详细格式如图4-4所示。RISCV架构规定,在执行MRET指令后,硬4 31件将自动更新机器模式状态寄存器mstatus (Machine Status Register)的某些域。
RISC-V架构规定,执行MRET指令退出异常时有如下情况。
●mstatus寄存器MIE域的值被更新为当前MPIE的值。
●mstatus寄存器MPIE域的值则被更新为1
在上面提及,在进入异常时,MPIE的值曾经被更新为异常发生前的MIE值。而MRET指令执行后,再次将MIE域的值更新为MPIE的值。通过这个机制,则意味着MRET指令执行后,处理器的MIE值被恢复成异常发生之前的值(假设之前的MIE值为1,则意味着中断被重新全局打开)。

3 RISC-V架构中断定义

硬中断类型
RISC-V架构定义的中断类型分为4种。
●外部中断 (External Interrupt)
●计时器中断(Timer Interupt)
●软件中断(Software Interrupt)
●调试中断 (Debug Interrupt)
下文将分别予以详述。

3.1 外部中断

RISC-V架构定义的外部中断要点如下。
(1)外部中断是指来自于处理器核外部的中断,譬如外部设备UART、 GPIO等产生的中断。
(2) RISC-V架构在机器模式、监督模式和用户模式下均有对应的外部中断。在此仅介绍“只支持机器模式”的架构,因此仅介绍机器模式外部中断。
(3)机器模式外部中断(Machine Extermal Interrupt)的屏蔽由CSR寄存器mie中的MEIE域控制,等待(CPending) 标志则反映在CSR寄存器mip中的MEIP城。后面会了解mip和mip寄存器的更多详情。
(4)机器模式外部中断可以作为处理器核的一个单比特输入信号, 假设处理器需要支持很多个外部中断源,RISC.V 架构定义了一个平台级别中断控制器(Platform Level InterruptCortoler, PLIC) 可用于多个外部中断源的优先级仲裁和派发。
●PLIC 可以将多个外部中断源仲裁为一个单比特的中断信号送入处理器核,处理器核
收到中断进入异常服务程序后,可以通过读PLIC的相关寄存器查看中断源的编号和信息。
● 处理器核在处理完相应的中断服务程序后, 可以通过写PLIC的相关寄有器和具体的外部中断源的寄存器,从而清除中断源(假设中断来源为GPIO,则可通过GPIO模块的中断相关寄存器清除该中断)。
(5)虽然RISC-V架构只明确定义了个机器模式外部中断,同时明确定义可通过PLIC在外部管理众多的外部中断源将其仲裁成为根机器 模式外部中断信号传递给处理器核。但是RISC-V架构也预留了大量的空间供用广扩展其他外部中断类型,如以下3种。
●CSR寄存器mic和mip的高20位可以用丁书展控制其他的日定义中断类型。后面了解mie和mip寄存器的更多详情。
●用户甚至可以自定义若干组新的mie利mip寄存器以支持更多自定义中断类型。
●CSR寄有器mceuase的中断异常编号域为12及以上的值,均可以用于其他自定义中断的异常编号(Excption Code)。因此理论上通过扩展,RISCV架构可以支持无数根白定义的外部中断(xcemal Irrup)信号直按输入给处理器核。后面会了解mcause寄存器的更多详情。

3.2 计时器中断

RISC-V架构定义的计时器中断要点如下。
(1)计时器中断是指来自计时器的中断。
(2) RISC-V整构在机器模式、监督模式和用户模式下均有对应的计时器中断。在此仅介绍“只支持机器模式”的架构,因此仅介绍机器模式计时器中断。
(3)机器模式计时器中断的屏蔽由mie寄存器中的MTIE域控制,等待(Pending)标志则反映在mip寄存器中的MTIP域。
(4)RISCV架构定义了系统平台中必须有一个计时器,并给该计时器定义了两个64位宽的寄存器mtime(如图7所示)和mtimecmp (如图8所示)、mtime高存器用于反映当前计时器的计数值,mtimecmp用于设置计时器的比较值。当mtime中的计数值大于或者等于mtimecmp中设置的比较值时,计时器使会产生时器中断。计时器中断会一直拉高,自到软件重新写mtimecmp商存器的值,使得其比较值大于mtime中的值,从而将计时器中断清除。


图7:mtime寄存器

图8:mtimecmp 寄存器

●值得注意的是,RISC-V架构并没有定义mtime寄存器和mtimecmp寄存器为CSR
寄存器,而是定义其为存储器地址映射(Memory Address Mapped)的系统寄存器,具体的存储器映射(Memory Mapped)地址RISC-V架构并没有规定,而是交由SoC系统集成者实现。
●另一点值得注意的是,RISC-V 架构定义mtime定时器为实时(Rea-Time) 计时器,系统必须以一种恒定的频率作为计时器的时钟。该恒定的时钟频率必须为低速的电源常开的(Always-on)时钟,低速是为了省电:常开是为了提供准确的计时。

3.3 软件中断

RISC-V架构定义的软件中断要点如下。
(1)软件中断是指来自软件自己触发的中断。
(2)由于RISC-V架构在机器模式、监督模式和用户模式均有对应的软件中断。在此仅介绍“只支持机器模式”的架构,因此仅介绍机器模式软件中断(Machine Software Interrupt)。
(3) 机器模式软件中断的屏藏由mie寄存器中的MSIE域控制,等待(Pendig)标志则反映在mip寄存器中的MSIP域。
(4) RISCV架构定义的机器模式软件中断可以通过软件写1至msip寄在器来转发。
注意:msip寄存器和mip寄存器中的MSP域命名不可混滑。凡RISC-V架构并没有定义msip寄存器为CSR寄存器。而是定文其为在储器地址映射的系统寄存器具体的存储器映射地址RISCV架构并没有规定,而是交由SoC系统实现。
(5)当软件写1至msip寄存器触发了软件中断之后。CSR寄存器mip中的MSIP域会置高,反映其等待状态。软件通过写0至msip寄右器来清除该软件中断
3.4###调试中断
除上述三种中断之外,还有一种特殊的中断-调试中断(Debug Interrupt)。此中断专用于实现调试器(Debugger)。

4 中断屏蔽

RISC-V架构的教义上的异常是不可以被屏蔽的,但是狭义上的中断则可以被屏蔽掉,RISC-V 架构也就是说一旦发生狭义上的异常,处理器一定会停止当前操作转向处理异常。但是狭义上的中断则是可以被屏蔽掉,ROSC-V架构定义了CSR寄存器机器模式中断使能寄存器 mie(Machine Interrupt Enable Registers)可以
用于控制中断的屏蔽。
(1) mie寄存器的详细格式如图9所示,其中每一个比特域用于控制每个单独的中断使能。
●MEIE域控制机器模式(Mechine Mode)下外部中断(External Interrupt )的屏蔽。


图9:mie 寄存器格式

●MTIE 域控制机器模式(Machine Mode)下计时器中断(Timer Interrupt )的屏蔽。
●MSIE域控制机器模式(Machine Mode)下软件中断(Software Interrupt)的屏蔽。
(2)软件可以通过写mie寄存器中的值达到屏蔽某些中断的效果。假设MTIE域为被设置成0,则意味着将计时器中断屏蔽,处理器将无法响应计时器中断。
(3)如果处理器只实现了机器模式,则监督模式和用户模式对应的中断使能位(SEIE、UEIE、 STIE、 UTIE、 SSIE 和USIE)无任何意义。
注意:在此仅介绍“只支持机器模式”的架构,因此对SEIEUEIE、STIE、 UTE、SSIE 和USIE等不做赘述。对其感兴趣的读者请参考RISC-V“特权架构文档”原文。
注意:除了对3种中断的分别屏蔽,通过mstatus寄存器中的MIE域还可以全局关闭所有中断。
4.3 RISC -V架构中断定义

5 中断等待

RISC-V架构定义了CSR寄存器机器模式中断等待寄存器mip Mechine Interrupt Pending Registers)可以用于查询中断的等待状态。
(1) mip寄行器的详细格式如图10所示,其中的每一个城用于反映每个单独的中断等待状态(Pending)。
MEIP域反映机器模式(Machine Mode)下的外部中断的等待(Pending) 状态。MTIP域反映机器模式(Machine Mode)下的计时器中断的等待 (Pending) 状态。MSIP域反映机器模式(Machine Mode)下的软件中断的等待(Pendin) 状态。


图10:mip 寄存器格式

(2)如果处理器只实现了机器模式,则mip寄存器中监督模式和用户模式对应的中断等待状态位(SEIP、 UEIP、STIP、 UTIP、 SSIP 和USIP)无任何意义。
注意:在此仅介绍“只支持机器模式”的架构,因此对SEIP、UEIP、STIP、 UTIP、SSIP 和USIP等不做赘述。对其感兴趣的读者请参考RISC-V“特权架构文档”原义。
(3)软件可以通过读mip寄存器中的值达到查询中断状态的效果。
●如果MTIP域的值为1,则表示当前有计时器中断(Timer Interrupt ) 正在等待“Pending"。注意:即便mie省存器中MTIE域的值为0 (被屏蔽),如果计时器中断到来,则MTIP域仍然能够显示为1。
●MSIP和MEIP与MTIP同理。
(4) MEIP/MTIP/MSIP域的属性均为只读,软件无法直接写这些城改变其值。只有这些中断的源头被清除后将中断源撤销,MEIP/MTIP/MSIP 域的值才能相应地归零。譬如MEIP对应的外部中断需要程序进入中断服务程序后配置外部中断源,将其中断搬销。MTIP和MSIP同理。

6 中断优先级与仲裁

对于中断而言,曾经提到多个中断可能存在着优先级仲我的情况。对于RISC-V架构而言,分为如下3种情况。
(1)如果3种中断同时发生,其响应的优先级顺序如下,mcauee 寄存器中将按此优先级顺序选择更新异常编号(Exception Code)的值。
● 外部中断(Extermal Interrupt ) 优先级最高。
●软件中断(Software Interrupt)其次。
●计时器中断(Timer Interrupt )再次。
(2)調试中断比较将殊”只有调试器(Debugger)介入调试时才发生,正常情形下不会发生,因此在此不予讨论。
(3)由于外部中断来自PLIC.而PLIC可以管理数量众多的外部中断源,多个外部中断源之间的优先级和仲裁可通过配置PLIC的寄存器进行管理。

7 中断嵌套

曾经提到多个中断理论上可能存在着中断嵌套的情况。对于RISC-V架构而言。
● 进入异常之后,mstatus资存器中的MIE域将会被硬件自动更新成为0 (意味者中断被全局关闭,从而无法响应新的中断)。
● 退出中断后, MIE城才被硬件自动恢复成中断发生之前的值(通过MPIE域得到),从而再次全局打开中断。
由上可见,一且响应中断进入异常模式后,中断被全局关闭再也无法响应新的中断,因此RISC-V架构定义的硬件机制默认无法支持硬件中断嵌套行为。
如果一定要支持中断嵌套,需要使用软件的方式达到中断嵌套的目的,从理论上来讲,可采用如下方法。
(1)在进入异常之后,软件通过查询mcause寄存器确认这是响应中断造成的异常,并跳入相应的中断服务程序中。在这期间,由于mstatus寄存器中的MIE域被硬件自动更新成为0,因此新的中断都不会被响应。
(2)待程序跳入中断服务程序中后,软件可以强行改写mstatus寄存器的值,而将MIE域的值改为1,意味者将中断再次全局打开。从此时起,处理器将能够再次响应中断。但是在强行打开MIE域之前,需要注意如下事项。
● 假设软件希望屏蔽比其优先级低的中断,而仅允许优先级比它高的新来打断当前中断,那么软件需要通过配置mie寄存器中的MEIE/MTIE/MSIE域,来有选择地屏蔽不同类型的中断。
● 对于PLIC管理的众多外部中断而言,由于其优先级受PLIC控制,假设软件希望屏蔽比其优先级低的中断,而仅允许优先级比它高的新来中断打断当前中断,那么软件需要通过配置PUIC 网值(hrstod备存器的方式来有选择地屏被不同类型的中断,
(3)在中断嵌套的过程中,软件需要注意保存上下文至存储器堆栈中,或者从存储器堆栈中将上下文恢复(与函数嵌套同理)
(4)在中断联套的过程中,软件还需要注意将mepc寄存器,以及为了实现软件中断嵌套被修改的其他CSR寄存器的值保存至存储器堆校中,或者从在储器堆栈中恢复(与函数嵌套同理)。
除此之外,RISC-V 架构也允许用户实现自定义的中断控制器实现硬件中断嵌套功能

C RISC-V 架构的PLIC介绍

C.1 概述

如前所述,RISC-V 架构定义了一个 PLIC用于对多个外部中断源按优先级进行仲裁和分发。PLIC 的逻辑结构如图C-1所示,相关概念如下。


图C-1PLIC 逻辑结构示意图

●PLIC中断目标
●PLIC中断目标的阈值
●PLIC中断源
●PLIC中断源的闸口
●PLIC中断源的编号
●PLIC中断源的优先级
●PLIC中断源的使能
●PLIC中断通知机制
●PLIC中断响应机制
●PLIC中断完成机制
●PLIC中断完整流程
下文将分别予以详述。注意:
图C-1仅为PLIC的逻辑示意图,并非其真正的硬件结构图。处理器设计人员可以采取更高效的硬件设计结构予以实现。
●图C-1中有两个中断目标(Target0和Target1), 但PLIC理论上可以支持一个或者任意多个中断目标。下节将对中断目标予以详述。
●图C-1 中的IP (Interrupt Pending)表示中断源的等待标志寄存器; Priority 表示中断
源的优先级寄存器;中断使能(Interrupt Enable, IE)为中断源对应于中断目标的使能寄存器: Threshold 为中断月标的优先级阙值寄存器: EIP 为发往中断目标的中断信号线。C.2节和C.3节将对各概念及寄存器予以详述。

C.2 PLIC 中断目标

如上一节所述,PLIC理论上可以支持一一个或者任意多个中断目标(Interrupt Target),硬件设计人员可以选择具体的中断目标个数上限。
RISC-V架构规定,PLIC的中断目标通常是RISC-V架构的一个特定模式 下的Hart。但是,理论上PLIC不仅可以用于向RISC-V的Hart发送中断也可以向系统的其他组件发送中断(譬如DMA、DSP等)。
通常情况下,RISC-V架构的Hart 需要进入机器模式(Machtine Mode)响应中断,但是RISC-V架构也运行低级别的工作模式(譬如用户模式)直接响应中断,此特性由CSR寄存mideleg控制。因此对于一个Hart而言,其机器模式可以作为中断目标,还可以有其他模式作为中断目标。
注意: mideleg寄存器只有在支持多和种工作模式的RISC-V处理器中才使用。
如图C-2所示,法PLC服务于3个RISC-V Hart。Hart 0 由M/U两种模式,Hart 1有M/S/U这3种模式,Hart 2有M/S/U这3种模式,因此该PLIC总共有编号0~7共8个中断目标,


图C-2:PLIC中断目标示例

PLIC中断目标之阈值

如图C-1所示,PLIC的每个中断目标均可以设置特定的优先级阔值(Threshold)。只有中断源的优先级高于此阈值,中断才能够被发送给中断目标。有关中断源的优先级概念将在附录C.3.3节予以详述。
中断目标的优先级阈值寄存器应该是存储器地址映射(Memory Address Mapped)的可读可写寄存器,从而软件可以通过编程配置不同的阈值来屏蔽比阈值低优先级的中断源。

C.3 PLIC中断源

如图C-1所示,PLIC理论上可以支持任意多个(具体硬件实现可以选择其支持的上限)中断源(Interrupt Soure)。每个中断源可以是不同的触发类型,譬如电平触发(Level-triggred)或者边沿触发(Edge-triggered等,
PLIC为每个中断源分配了如下功能组件和参数。
●闸口(Gateway) 和IP
●编号(ID)
●优先级(Priority)使能(Enable)

C.3.1 PLIC 中断源之闸口(Gateway) 和IP

如图C-1所示,PLIC 为每个中断源分配了一个闸口(Gateway),每个闸口都有对应的中断等待寄存器,其功能如下。
●闸口将不同触发类型的外部中断转换成统一的内 部中断请求。
●对于同一个中断源而言, 闸口保证一次只发送一 个中断请求 (Interrupt Request),如图C-1所示,中断请求经过闸口发送后,硬件将会自动将对应的IP寄存器置高。
●闸口发这一个中断请求后则启动屏蔽,如果此中断没有被处理完成,则后续的中断将会被闸口屏蔽住。有关中断完成机制,见附录 C.4.3节中的详细介绍。

C.3.2PLIC中断源之编号(ID)

PLIC为每个中断源分配了一个独一无二 的编号(ID)。ID编号0被预留,作为表示“不存在的中断”,因此有效的中断ID从1开始。
譬如,假设某PLIC的硬件实现支持1024个ID,则ID应为0-1023.其中,除了0被预留表示“不存在的中断”之外,编号1~ 1023对应的中断源按口信号线可以用于连接有效的外部中断源。

C.3.3 PLIC 中断源之优先级(Priority)

如图C-1所示,PLIC 的每个中断源均可以设置特定的优先级,其要点如下。
每个中断源的优先级寄存器应该是存储器地址映射的可读可写寄存器,从而使得软件可以对其编程配置不同的优先级。
●PLIC 架构理论上可以支持任意多个优先级,硬件实现时可以选择具体的优先级个数。譬如,假设硬件实现时选择优先级寄存器的有效位为3位,则其可以支持的优先级个数为0~7这8个优先级。
●优先级的数字越大,则表示优先级越高。
●优先级0 意味着“不可能中断”,相当于将此中断源屏蔽。
这是因为PLIC的每个中断目标均可以设置特定的优先级阙值,只有中断源的优先级高于此阈值,中断才能够被发送给中断目标。由于阈值最小也为0,因此中断源的优先级为0则不可能高于任何设定的阙值,即意味着“不可能中断”。

C.3.4 PLIC中断源之中断使能(Enable)

如图C.1所示,PLIC 为每个中断目标的每个中断源均分配了一个中断使能寄存器,其要点如下。
IE寄存器应该是存储器地址映射的可读可写寄存器, 从而使得软件可以对其编程。
●如果E寄存器被编程配置为0,则意味着此中断源对应此中断目标被屏蔽。
●如果E寄存器被编程配置为1,则意味着此中断源对应此中断目标被打开,

C4 PLIC中断处理机制

C.4.1 PLIC 中断通知机制( Notification)

如图C-1所示,对于每个中断目标而言,PLIC对其所有中断源进行仲裁选择的原则如下。
●对于每个中断目标来说,只有满足下列所有条件的中断源才能参与仲裁。
中断源对于该中断目标的使能(IE寄存器)必须为1。
中断源的优先级(优先级寄存器的值)必须大于0。
中断源必须经过了闸口发送(IP 寄存器的值为1)。
●从所有参与仲裁的中断源中选择优先级最高的中断源,作为仲裁结果。如果參与仲裁的多个中断源具有相同的优先级,仲裁时则选择ID数目最小的中断源。
●如果仲裁出的中断源优先级高于中断目标的优先级阅值,则产生最终的中断通知(Notification),否则不产生最终中断通知。
经过仲裁之后,如果对中断目标产生中断通知,则向该中断目标生成根电平触发的中断线。若中断目标是一个RISC-V Hart的M Mode,则该中断线的值将会反映在其CSR寄存器mip中的MEIP域。

C.4.2 PLIC中断响应机制(Claim)

对于每个中断目标而言,如果收到了中断通知,且决定对该中断进行响应,则需要向PLIC发送中断响成(Interrupt Claim)消息。PLIC定义的中断响应机制如下:
●PLIC实现一个存储器地址映射的可读寄存器,中断目标可以通过对此寄存器进行读操作,达到中断响应的目的。作为反馈(Claim Response),此读操作将返回一个ID,表示当前仲裁出的中断源对应的中断ID。中断目标可以通过此ID得知其需要响应的具体外部中断源,如果返回的中断ID为0表示则表示无中断请求。
●PLIC接收到中断响应的寄存器读操作,且返回了中断ID之后,硬件自动将对应中断源的IP寄存器清0。
注意:此中断源的IP寄存器清0后,其他中断源仍可以重新进行仲裁,选出下一个最高优先级的中断源,因此PLIC有可能会继续向该中断目标发送新的中断通知。
●中断目标可以将该中断口标的优先级调值设置到最大,即屛敞掉所有的中断通知但是该中断目标仍然可以对PTIC发送中断响应的寄存器读操作,PLIC 依然会返回当前仲截出的中断源对应的中断ID,

C.4.3PLIC中断完成机制(Completion)

对于中断目标而言,如果彻底完成了某个中断源的中断处理操作,则需要向PLIC发送中断完成(Interupt Completion)消息。PLIC 定义的中断完成机制如下。
●PLIC实现一个存储器地址映射的可写寄存器,中断目标可以通过对此寄存器进行写操作达到中断完成的目的。此写操作需要写入一个中断ID,以通知PLIC完成了此中断源的中断处理操作。
●PLIC 接收到中断完成的寄存器写操作后(写入中断ID),硬件自动将对应中断源的闸口解除屛蔽。只有利口解除屏蔽之后,此中断源才能经过闸口发起下一次中断清求(才能重新将IP寄存器置高)。

C.4.4 PLIC 中断完整流程

综上所述,对于每个中断源的中断而言,如图C-3所示,其完整流程总结如下。


图C-3:中断完整流程

●如果闸口没有被屏蔽, 则中断源经过闸口发起中断请求(Inerupt Request)。 闸口发送一个中断请求后:硬件自动闸口启动屏蔽,后续的中断将会动将其对应的IP会被闸口屏蔽住。
●按照C.4.1节所述的中断仲裁机制,如果经过PLIC硬件的仲裁后选择了该中断源,且其优先级高于中断目标的阈值,PLIC则向中断目标发起中断通知(Interrupt Notification)。
●中断目标收到中断通知后,如果决定响应此中断,则使用软件向PLIC发起中断响应的读操作。作为响应反馈,PLIC返回该中断源的中断ID。同时,硬件自动将其对应的IP寄存器清零。
●中断目标收到中断ID之后,可以通过此ID得知得知其需要响应的具体外部中断源。然后进入该外部中断源对应的具体中断服务程序(Interrupt Service Routine)中进行处理
●将彻成完成 了中断处那之后,中断目标使用软件向PLIC发起“中断完成”的写操作,写入要完成的中断ID。同事,PLIC硬件将对应中断源的闸口解除屏蔽,允许其能发起下一次新的中断请求。

C.5 PLIC寄存器总结

综上所述,PLIC需要支持的若干种存储器地址映射的寄存器如下。
●每个中断源的中断等待 (Interrupt Pending, IP)寄存器(只读)。
●每个中断源的优先级寄存器(可读可写)。
●每个中断目标对应每个中断源的中断使能寄存器(可读可写)。
●每个中断目标的阈值寄存器(可读可写)。
●每个中断目标的中断响应寄存器(可读)。
●每个中断目标的中断完成寄存器(可写)。RISC-V架构文档中并没有对上述寄存器定义明
确的存储器地址,而是交给硬件实现者自定义。因此硬件设计人员可以按照所处SoC系统的不同情况分配具体的存储器映射地址。以SiFive公司开源的Fredorm E310 SoC平台为例,其PLIC的寄存器地址映射表如图C-4


图C-4:Freedom E310 soC平台的PLIC寄存器地址映射表

338 1附录C RISC-V架构的PLIC介绍
注意:
●图C-4为siFive公司开源的Freedom E310 soC中使用的PLIC寄存器地址映射表。
此PLIC的编程模型支持最多1024个ID.则ID为0-1023.其中,除了0被预留表示“不存在的中断”之外,编号1 1023 对应的中断源接口信号线可以用于连接有效的外部中断源。
此PLIC的编程模型支持最多15872个中断目标(Tnget 0~ Target 15871)。
●图C-4中的"soure 1 pioriy" ~“soure 1023 prorty"对应每个中断源的优先级寄存器(可读可写)。虽然每个优先级寄存器对应于一个32位的地址区间(4字节),但是优完级寄存器的有效位可以只有几位(其他位固定为0值)。假改硬件实现优先级寄存器的有效位为了位,则其可以支持的优先级个数为0~7这8个优先级。
●图C-4中的“Starl of pending array”~“End of pending array”对应每个中断源的IP中断等待寄存器(只读)。由于每个中断源的IP仅有一位宽,而每个寄存器对应于一个32位的地址区间(4字节),因此每个寄存器可以包含32个中断源的IP。
按照此规则,譬如"Start of pending aray"寄存器包含中断源0~31的IP寄存器值,其他依次类推。每32个中断源的I被组织在一个寄有器中,总共1024个中断源则需要32个寄存器,其地址为0x0C00 1000~ 0x0C00107C 的32个地址。
●图C-4中的“target 0 enables" 对应每个中断源的中断使能寄存器(可读可写)。与IP寄存器同理,由于每个中断源的IE仅有一位宽,而每个寄存器对应于一个32 位的地址区间(4字节),因此每个寄存器可以包含32个中断源的IE。
按照此规则,对于“target 0”而言,每32个中断源的IE被组织在一个寄存器中,总共1024个中断源,则需要32个寄存器,其地址为0x0C00 2000~ 0x0C00 207C的32个地址区间。
●图C-4 中的“target 1 enables" ~“targe 15871 enabls" 与上述“target 0 eables"同理,每一个“target” 占据32个地址区间。
图C4中的“targt 0 piortry threshold"“target 15871 priority threshold” 对应每个中断日标的阈值寄存器(可读可写)。
虽然每个阅值寄存器对应于一个32位的地址区问(4字节),但是阈值寄存器的有效位个数应该与每个中断源的优先级寄存器有效位个数相同。
●图C-4中的“target 0 claim/complele"" ~“target 15871 claim/comoplete”对应每个中断目标的“中断响应”寄存器和“中断完成”寄存器。
如C.4.2节和C.4.3节中所述,对于每个中断目标而言,由于“中断响应”寄存器为可读,“中断完成”寄存器为可写,因此将其合作为一个寄存器共享同一个地址,成为一个可读可写寄存器。

你可能感兴趣的:(RISC-V架构异常处理机制)