0. 序
在2之前,先记录一下riscv异常处理的机制。
1. 异常定义
2. 异常相关的CSR
主要有这几个mstatus, mepc, mtvec, mcause, mie, mip, mscratch, mtval。这是以m模式为例,因此寄存器带有m前缀(否则为s前缀)。其中mie指定哪些中断需要屏蔽,mip保存哪些中断等待被接收。mtvec指令指定异常处理程序的位置。如果mtvec的第一位为1,则异步中断跳转到mtvec+4*mcause的位置(我怎么觉得64位应该是8*mcause?)。
当异常发生时,处理器在mstatus的mpp字段填写异常发生时的运行模式,而mpie字段填写异常发生时中断使能(是否有禁止中断,由mstatus的mie字段指定),然后将mie字段置0(即禁止中断)。因此前面两个步骤相当于在保存之前的PSW。
mepc会保存导致异常的指令或者中断后需要执行的下一条指令的pc值。这一步相当于在保存之前的PC。mcause保存异常号。
和x86不同的是,处理器不会自动切换栈,因此需要一个mscratch寄存器来临时保存通用寄存器的值。
3. 异常相关指令
ecall环境调用,程序主动触发8或9或11号异常(取决于当前运行模式)。mret或者sret指令,用于从异常中返回,语义是:将运行模式修改为mstatus的mpp字段,将中断使能修改为mstatus的mpie字段,将pc值修改为mepc指定的值(恢复之前的运行环境)。
4. 异常的代理
默认情况下,在任何运行模式下引发的异常,处理器默认都会切换到M模式,可以由medeleg,mideleg分别指定异常,中断的代理,若寄存器的相应位置1,表明该异常或者中断由S模式进行处理(当指定异常触发时,处理器将切换到S模式而不是M模式)。
5. 关键词
riscv异常处理。