广义异常分类
riscv 的异常(广义的异常)包括
狭义的异常
取指令访问到非法的地址空间
读写数据访问地址属性出错
取指令地址非对齐
非法指令错误
执行调试断点指令(ebreak)
狭义的中断
精确异常 : 外部中断(由PLIC综合出来的一个bit线)
非精确异常:
读写存储器出错
狭义异常分为以下几种
illegal instruction
breakpoint
狭义中断分为以下几种
三个模式下的 软中断
三个模式下的 timer 中断
三个模式下的 外部中断
debugint
广义异常的发生
狭义异常分为以下几种
illegal instruction
breakpoint
软件执行 ebreak 指令 可能会进入
狭义中断分为以下几种
三个模式下的 软中断
软件执行 写1 到 msip 寄存器 会进入
三个模式下的 timer 中断
mtime(会变化的值,类似于mcycle)中的计数值大于等于 mtimecmp(固定值)中的值 , 会进入
三个模式下的 外部中断
PLIC将多个PLIC外部的中断源仲裁为一个单比特的中断信号送入处理器核 , 会进入
debugint
多个狭义中断同时发生,按以下顺序发生
1. 外部中断
2. 软中断
3. timer中断
广义异常处理流程
0. 广义异常发生
1. halt
2. 设置 CSR
mcause
mepc
mtval
mstatus
3. 设置PC
分两种情况
针对 mevec的MODE为0 , PC设置 为 单一入口 trap_entry
针对 mtvec的MODE为1 , PC设置 为 trap_entery . BASE+4*(1) ... BASE+4*(编号)
4. resume request
5. 开始执行软件代码
针对中断要 清 pending
对于异常要根据 异常指令 , 控制 mepc+=2 或 mepc+=4
6. 执行mret
7. halt
8. 恢复CSR
mcause
mepc
mtval
mstatus
9. 设置PC
PC=mepc
10. resume request
11. 开始执行软件代码
狭义异常的编程
狭义异常的发生不可屏蔽
狭义中断的编程
狭义中断的发生 可通过 clear mstatus 中的 MIE 屏蔽
狭义中断中的 外部中断的发生 可通过 clear mie 的 MEIE 屏蔽
不管 是否屏蔽 , 只要 外部中断 出现(不是发生), 就会将 mip 的 MEIP 域 set
怎么清除 MEIP?
machine mode ext interrupt flow
device -> plic -> MIE(MEIE) -> MSTATUS(MIE)
config1 config2 config3 config4
config1 是要确保 device 能产生中断
config2 是能确保 中断号 为 5 的 中断 能够正确配置(优先级,feature),而且能够enable
config3 是能够确保 MIE 的 MEIE bit 能够enable
config4 是能够确保 MSTATUS 的 MIE bit 能够 enable
如果四个config 都能够 确保,那么肯定会产生中断 ,但是中断函数的进入是另一回事
狭义中断中的 timer 中断的发生 可通过 clear mie 的 MTIE 屏蔽
不管 是否屏蔽 , 只要 timer中断 出现(不是发生), 就会将 mip 的 MTIP 域 set
怎么清除 MTIP?
machine mode mtimer interrupt flow
mtimer -> MIE(MTIE) -> MSTATUS(MIE)
config1 config2 config3
config1 是确保 mtimer 能够中断(只需要设置比较寄存器即可)
config2 是能够确保 MIE 的 MTIE bit 能够enable
config3 是能够确保 MSTATUS 的 MIE bit 能够 enable
狭义中断中的 软 中断的发生 可通过 clear mie 的 MSIE 屏蔽
不管 是否屏蔽 , 只要 软中断 出现(不是发生), 就会将 mip 的 MSIP 域 set
怎么清除 MSIP?
machine mode mtimer interrupt flow
plic_sw -> MIE(MSIE) -> MSTATUS(MIE)
config1 config2 config3
config1 是确保 plic_sw 能够中断
config2 是能够确保 MIE 的 MSIE bit 能够enable
config3 是能够确保 MSTATUS 的 MIE bit 能够 enable