QEMU裸机开发之S模式定时器中断
在本章节中我们来学习如何在s模式下使用定时器中断,我们首先将上一章节中的ecall调用定义为更新定时器比较寄存器的调用,因为在s模式我们是不能访问定时器比较寄存器的,所以只能发起ecall调用到m模式去访问。在m模式下对s模式下的ecall异常处理如下所示。
case ECALL_FROM_SMODE: timer_set(timer_get() + TIMER_CLK_RATE); csr_clear(mip, SIP_STIP); csr_set(mie, MIE_MTIE); break;
- 先更新比较寄存器以在1s后产生定时器中断。
- 然后将s模式的定时器中断状态位置0,不然会一直产生定时器中断。
- 接着使能m模式下的定时器中断使能位,以让m模式可以处理定时器中断。
当产生定时器中断后,首先会进入m模式下的定时器中断处理,如下所示。
case M_TIMER_INT: csr_clear(mie, MIE_MTIE); csr_set(mip, SIP_STIP); //timer_set(timer_get() + TIMER_CLK_RATE); // raise a supervisor software interrupt. //sip_set(SIP_SSIP); break;
- 首先关闭m模式下的定时器中断使能位,也就是m模式不再处理定时器中断。
- 然后将s模式的定时器中断状态位置1,这样在退出m模式中断处理后,会立马进入s模式的中断处理,然后就可以在s模式下处理定时器中断了。
在s模式下的定时器中断处理也很简单,就是再次发起ecall以便设置新的定时器比较值,如下所示。
case S_TIMER_INT: RISCV_ECALL_0(0); break;
这样就再次进入m模式进行s模式定时器中断状态清除和重新使能m模式下定时器中断,这个在上面已经说过了。m模式下的异常和定时器中断处理逻辑参考自OpenSBI源码。
在命令行执行“make qemu”,通过打印信息可以看到先在m模式下处理定时器中断,然后在s模式下处理定时器中断,最后通过ecall重新设置定时器比较值,如下所示。
ewenbin@gewenbin-virtual-machine:~/Desktop/qemu_test/lesson11$ make qemu riscv64-unknown-elf-gcc -Wall -Werror -O -fno-omit-frame-pointer -ggdb -mcmodel=medany -ffreestanding -fno-common -nostdlib -mno-relax -I. -fno-stack-protector -fno-pie -no-pie -c -o trap.o trap.c riscv64-unknown-elf-gcc -Wall -Werror -O -fno-omit-frame-pointer -ggdb -mcmodel=medany -ffreestanding -fno-common -nostdlib -mno-relax -I. -fno-stack-protector -fno-pie -no-pie -c -o clint.o clint.c riscv64-unknown-elf-ld -z max-page-size=4096 -T kernel.ld -o kernelimage entry.o start.o uart.o trap.o clint.o riscv64-unknown-elf-objdump -S kernelimage > kernel.asm riscv64-unknown-elf-objdump -t kernelimage | sed '1,/SYMBOL TABLE/d; s/ .* / /; /^$/d' > kernel.sym qemu-system-riscv64 -machine virt -bios none -kernel kernelimage -m 128M -smp 1 -nographic start 79. main 45. Exception : Environment call from S-mode. Interrupt : Machine timer interrupt. Interrupt : Supervisor timer interrupt. Exception : Environment call from S-mode. Interrupt : Machine timer interrupt. Interrupt : Supervisor timer interrupt. Exception : Environment call from S-mode.
工程源码:链接:https://pan.baidu.com/s/1TnTYr7mywdKj5bxpdmWnyA,提取码:q772,见lesson11。
评论