Operating system 在监控模式下不会触发外部中断
我正在写一个玩具内核来学习操作系统。我的目标是RISC-V机器(Operating system 在监控模式下不会触发外部中断,operating-system,interrupt,riscv,Operating System,Interrupt,Riscv,我正在写一个玩具内核来学习操作系统。我的目标是RISC-V机器(virtinqemu)。我尝试将中断委托给主管模式,但我不知道为什么它不起作用 根据我在特权体系结构手册中所读的内容,我需要在mieCSR中为主管启用异常,并在mideleg和medelegCSR中设置我要委派的异常位。但这样做不会在外部中断挂起时引发任何异常 软件中断工作,它们在S模式下被触发和接收,但外部中断甚至没有触发(甚至在M模式下也没有) 为了了解发生了什么,我尝试使用gdb并观察mip寄存器的变化。 我用机器的UART0
virt
inqemu
)。我尝试将中断委托给主管模式,但我不知道为什么它不起作用
根据我在特权体系结构手册中所读的内容,我需要在mie
CSR中为主管启用异常,并在mideleg
和medeleg
CSR中设置我要委派的异常位。但这样做不会在外部中断挂起时引发任何异常
软件中断工作,它们在S模式下被触发和接收,但外部中断甚至没有触发(甚至在M模式下也没有)
为了了解发生了什么,我尝试使用gdb
并观察mip
寄存器的变化。
我用机器的UART0端口触发中断(通过按下键盘上的一个键),下面是发生的情况
按一个键在mip中设置一个位,暂停执行。以下是相关CSR的状态:
(gdb) p /x $sip
$3 = 0x200
(gdb) p /x $sie
$4 = 0x222
(gdb) p /x $mstatus
$5 = 0xaa
(gdb) p /x $mideleg
$6 = 0x666
(gdb) p /x $medeleg
$7 = 0xb0bfff
(gdb) p /x $scause
$8 = 0x0
(gdb) p /x $stval
$9 = 0x0
因此,设置了SEIP(管理器外部中断挂起)位,但不触发任何内容。如果我接着继续执行,我最终会触发一个页面错误或一条非法指令,因为这些都是软件中断并被执行
如果我试图在监控模式下运行wfi
指令,同样的情况也会发生,因此机器将卡在wfi
指令上
我是做错了什么,还是做错了?
如果这个问题缺少细节,请告诉我,我会修改它
编辑:virt机器所基于的板上似乎有一个用于Hart 0的SiFive E51处理器,它根本不支持监控模式,当然我在引导加载程序中使用了这个Hart
但是,为什么即使文件明确说明模拟器仅实现M和U模式,模拟器仍允许此hart上的监控模式?为什么同步异常仍然被委托到S模式
谢谢关于virt
RISC-V机器的精确性
将Hart 0更改为Hart 1作为我的主核心并没有改变问题
通过打印misa
和mimp
csr,我现在可以判断virt
机器的所有内核都具有相同的misa
并实现监控模式。因此,该机器不是基于FU53平台架构,它只是使用与PLIC相同的全局中断系统
但PLIC内存映射与FU53不同,FU53没有Hart 0的S模式全局中断内存映射寄存器。因此,我用来启用S模式全局中断的地址不是好的
在这个文件中:您可以找到常数,用于计算设置时要使用的正确PLIC地址
我仍然不完全理解为什么设置了mip
中的挂起位,但现在它可以工作了
tl;博士
这就是进入S模式时使其工作的状态。警察信息中心地址是罪魁祸首
mstatus: MPIE = 1, SIE = 1, MPP = 01
mie : MEIE = MTIE = MSIE = SEIE = STIE = SSIE = 1 (mie=0xaaa)
mideleg: 0x222
medeleg: 0xb0bfff (which is set when writing 0xffffffff to it)
PLIC:
- *0x0C00_2080 (Hart 0 S-mode enable) = 0x400 (enable UART0)
- *0x0C00_0028 (Interrupt number 10 priority) = 1
- *0x0C20_1000 (Hart 0 S-mode threshold) = 0