RISC V的中断和异常机制
特权模式
RISC-V定义了三种特权模式,通过不同的模式组合可以实现不同的系统
-
机器模式
M模式是硬件线程(hart)可执行的最高权限模式,可以访问所有资源和内存,具有启动和配置系统等系统底层支撑功能(必须实现),嵌入式系统一般只支持M模式
-
用户模式
只能执行各类普通指令,不能执行特权指令。在U模式下,当系统异常时将自动跳转到M模式下执行异常处理程序。也可通过自陷指令ecall陷入M模式并通过mret特权指令返回U模式
-
监督模式
S模式支持存储保护,操作系统内核运行在该模式下。S模式下的程序无法使用M模式的CSR和相应的特权指令,但可以使用特有特权指令如sret
RISV-V模式位:00->U模式;01->S模式;11->M模式
M模式的异常处理程序可将异常转发给S模式,但会降低处理效率,因此存在mideleg(Machine Interrupt delegation)CSR控制将哪些中断委托给S模式
通过配置mstatus或sstatus并使用mret、sret向低特权级切换,通过ecall向高特权级切换
异常和中断类型
RISC-V上中断CPU中程序正常执行的情况包含异常和中断两大类
异常
-
故障:
引起故障的指令启动后、执行结束前被检测到的一类异常事件。例如指令译码时遇到非法操作符;取指令或数据时发生缺页;执行整数除法指令时发现除数为0。这类异常因为无法通过异常处理程序恢复,因此不能回到原断点继续执行,必须终止整个进程
-
自陷:
事先在程序中用一条特殊指令或设定特殊控制标志来人为设置陷阱,当执行到满足条件的自陷指令时,根据不同的陷阱类型进行相应的处理,自陷异常处理结束后,将返回到自陷指令的下一条指令执行
-
终止:
若发生控制器故障、访问DRAM或SRAM时发生校验错误等情况时,程序将无法继续执行并终止发生问题的进程,这类异常是随机发生的,无法确定发生异常的是哪条指令
中断
程序执行过程中,若外设完成任务或发生某些特殊事件,会向CPU发送中断请求。通常,每条指令结束后,CPU都会主动查询有没有中断请求,若有,则将下一条指令地址作为返回地址保存,然后跳转到相应的中断服务程序执行,结束后回到断点继续执行
-
外部:
外部中断指的是来自处理器核外的外部设备的中断请求,S模式和M模式下的外部中断编号分别为9和11。RISV-V架构定义了一个平台级中断控制器(PLIC)用于多个外部中断源请求信号的汇总和优先级仲裁并向处理器发送中断信号
-
计时器:
在M模式下,系统需要给计时器定义两个64位宽的和主存统一编址的储存器映射寄存器mtime和mtimecmp,mtime是计时器当前值,而mtimecmp则是设定好的比较值,当mtime中的值大于mtimecmp时则产生M模式计时器中断,对应编号为7。S模式下对应编号为5
-
软件:
S模式和M模式下分别为1和3,。在M模式下,通过定义主存统一编址的储存器映射寄存器msip并在该寄存器中写1来触发。软件中断通常用于由一个hart中断另一个hart
-
调试:
由远端主机向处理器发送调试中断请求信号
控制状态寄存器
控制状态寄存器(CSR)是处理器核内部的寄存器,使用独立的12位地址编码,独立于主存地址空间统一编址和5位通用寄存器编码空间,在64位架构下编码地址为8字节,32位编码地址为4字节
在32位M模式下,与异常、中断相关的包含以下CSR寄存器:
-
mstatus
M模式下的状态寄存器,包含20多个字段,其中MIE为全局中断使能位,同理对于U、S模式则有UIE、SIE;MPIE用于保留中断、异常前的全局中断使能位;MPP用于保存中断、异常前的特权模式
-
mcause
M模式下的原因寄存器,mcause包含两个字段,分别为Interrupt和Execption Code(也称为CAUSE值)位,各种异常/中断的编号如下表所示
-
mtvec
M模式下的异常/中断处理程序入口地址寄存器,包含30位BASE字段和2位MODE字段,若MODE=00,则直接跳转到BASE,若为01,则跳转到BASE+CAUSEx4的地址
-
mepc
M模式下的异常/中断返回地址,异常的返回位置为发生异常的指令或自陷指令的地址,因此自陷类异常需将mepc改为下一条指令的地址避免程序无法继续执行
-
mtval
M模式下的异常值寄存器,记录与当前异常有关的辅助信息,如储存器访问出错的地址或非法指令的编码
-
mie
M模式下的中断使能寄存器,MMIE、MTIE和MSIE字段分别对应外部中断、计时器中断和软件中断的使能位(需要mstatus.MIE为1才会工作)
-
mip
M模式下的中断等待状态,包含MEIP、MTIP和MSIP字段
异常/中断编号:
Interrupt | Execption Code | Description |
---|---|---|
1 | 1 | S模式软件中断 |
1 | 3 | M模式软件中断 |
1 | 5 | S模式计时器中断 |
1 | 7 | M模式计时器中断 |
1 | 9 | S模式外部中断 |
1 | 11 | M模式外部中断 |
0 | 0 | 指令地址未对齐 |
0 | 1 | 取指令故障 |
0 | 2 | 非法指令 |
0 | 3 | 调试断点ebreak |
0 | 4 | Load地址未对齐 |
0 | 5 | Load访存故障 |
0 | 6 | Store/AMO地址未对齐 |
0 | 7 | Store/AMO访存故障 |
0 | 8 | U模式下ecall指令 |
0 | 9 | S模式下ecall指令 |
0 | 10 | reserved |
0 | 11 | M模式下ecall指令 |
0 | 12 | 取指令缺页故障 |
0 | 13 | Load缺页故障 |
0 | 14 | reserved |
0 | 15 | Store/AMO缺页故障 |
处理过程
硬件响应阶段
M模式下的异常/中断响应主要包含以下工作:
- 修改mcause、mepc、mtval这几个CSR,
- 修改mstatus中的相关内容,储存中断前的全局中断状态位和特权模式信息(MIE、MPP),将MIE设置为0
- 将mtvec中的地址送入PC,跳转到中断/异常处理程序
软件处理阶段
M模式下的中断/异常处理程序包含以下工作:
- 对现场的上下文进行保存
- 通过查询mcause中的异常/中断编号跳转到具体的异常/中断处理子程序
- 程序结束时恢复现场,mret回到被中断程序的断点出继续执行,mret会修改mstatus中的MIE字段为MPIE中的值,并将MPIE修改成1,将特权模式设置为MPP中的模式编码,并将MPP设置为00,最后从mepc取值送入PC