QEMU裸机开发之M模式中断设置
1. CSR寄存器操作
从本章节开始我们需要对CSR相关寄存器设置,所以将这些寄存器的读写访问封装成一些接口定义在“csr.h”中,这些接口基本都参考自xv6,如下所示。
2. 中断初始化
在可以使用中断和异常处理之前,需要进行一些设置,所以需要在“start.c”中添加中断初始化代码,如下所示。
#include "uart.h" #include "csr.h" // in kernel.ld. extern char __stack_start[]; // in entry.S. void machine_trap_entry(void); static void machine_trap_init(void) { //this stack is used for machine_trap_entry in entry.S mscratch_set((unsigned long)(__stack_start + 4096 * 2)); // set the machine-mode trap handler. mtvec_set((unsigned long)machine_trap_entry); // enable machine-mode interrupts. mstatus_set(mstatus_get() | MSTATUS_MIE); // enable machine-mode timer and soft interrupts. mie_set(mie_get() | MIE_MTIE | MIE_MSIE); } void start(void) { printf("%s %d.\r\n", __func__, __LINE__); machine_trap_init(); }
首先设置了m模式下的中断栈地址,“__stack_start”是定义在链接脚本中的,这个地址往上第二个4KB空间就是m模式中断和异常栈,RISCV架构不像arm那样每个模式都有自己的sp寄存器,所以先将栈地址保存在“mscratch”寄存器中,在实际发生中断和异常时,“mscratch”中保存的值会被软件取出并赋值给sp寄存器。
“mtvec_set”设置了中断和异常的处理地址,这个和arm架构后来提供的中断基址设置寄存器功能类似。通过“mstatus_set”使能了m模式的中断总使能位,类似arm中cpsr中的“F”位,这样cpu才能响应和处理中断。最后通过“mie_set”使能了定时器和核间中断,在本系列裸机学习中我们不关注中断控制器中断,所以这里只使能了这两个中断。
在初始化好了中断之后,我们还需要实现中断处理函数,这个在下一小节讲解。
3.中断处理
3.1 中断入口
在“entry.S”中,我们需要实现m模式中断和异常处理的入口,如下所示。
# # machine-mode trap entry. # .globl machine_trap_entry .align 4 machine_trap_entry: # mscratch holds mmode trap stack address, # swap current sp and mmode trap stack address csrrw sp, mscratch, sp // call the C trap handler in trap.c call machine_trap # restore old sp value csrrw sp, mscratch, sp mret
“machine_trap_entry”处理裸机也很简单,就是从“mscratch”中将事先保存的中断栈地址设置到sp寄存器中,然后调用c函数“machine_trap”进行具体的中断处理,结束后再恢复sp寄存器,最后通过“mret”指令退出中断处理函数。RISCV不像arm架构不会自动切换使用中断栈,所以这些工作都交给了软件开发者,另外这里简化了处理工作,在实际的系统中断处理函数中还需要保存通用寄存器等,这里为了说明中断基本处理原理,省去了这些操作。
3.2 中断C函数处理
m模式中断和异常c函数放在“trap.c”中,如下所示。
#include "uart.h" // interrupts and exceptions from kernel code go here via machine_trap_entry. void machine_trap(void) { printf("%s %d.\r\n", __func__, __LINE__); }
这里目前只添加了一条打印,用于表明确实进入了中断处理。
4. 测试
由于需要触发中断才能测试中断处理是不是真的被执行了,所以本章节只是准备好这些设置和处理,在下一章节中,通过核间中断来一起验证和测试。
5. 工程源码
链接:https://pan.baidu.com/s/1TnTYr7mywdKj5bxpdmWnyA,提取码:q772,见lesson3。
评论