我正在尝试为我的 RV32I 内核实现一个简单的中断控制器。我相信我了解在 RISC-V 中应该如何处理中断,以及 CSR 寄存器在该过程中的作用。
RISC-V 定义了三种中断源:外部、软件和定时器。我了解计时器和外部中断是如何产生的。但是,我不明白如何或什么会产生软件中断。指令?一系列指令?也许实现定义的标志?我不知道。
任何人都可以举一个例子和软件中断的解释,最好是相关的汇编代码,如果它是相关的?
提前致谢!
您正在寻找的是来自 mip csr 的 SSIP 和 USIP 位。
通过向 sip 寄存器中的主管软件中断挂起 (SSIP) 位写入 1,在当前 hart 上触发主管级软件中断。可以通过将 0 写入 sip 中的 SSIP 位来清除挂起的主管级软件中断。当 sie 寄存器中的 SSIE 位清零时,主管级软件中断被禁用。
通过向 sip 寄存器中的用户软件中断挂起 (USIP) 位写入 1,在当前 hart 上触发用户级软件中断。挂起的用户级软件中断可以通过向 sip 中的 USIP 位写入 0 来清除。当 sie 寄存器中的 USIE 位清零时,用户级软件中断被禁用。
您可以在The RISC-V Instruction Set Manual Volume II: Privileged Architecture
V20190608 中找到此信息。
软件中断是由(用户)程序执行引起的。
软件中断可能发生在ecall
——相当于syscall
MIPS 上;这是用户程序对操作系统服务的请求,它以一种可控的方式跨越了权限边界。
软件中断也可能来自非法或格式错误的内存操作,lw
即sw
.
查看表 3.6、4.1 上的异常列表(这里我只显示第二半;注意 ecall 出现在前半):
第一种是由于在程序计数器中放置了错误的值(例如奇数),这可能是由跳转寄存器或堆栈损坏的返回引起的。
接下来允许程序计数器引用未映射的地址,即未标记为可执行的页面。
断点通常由软件在调试期间使用。
加载访问错误是指使用加载或存储到未映射或以其他方式受保护的地址。
原子操作有自己的异常编号(不知道为什么)。
最后,它们可能是由特权模式(U、S、H、M)之间的切换引起的