RISCV基础开发(十六)

gewenbin
gewenbin
gewenbin
188
文章
15
评论
2021年8月21日15:09:27 评论 687

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。

gewenbin
  • 本文由 发表于 2021年8月21日15:09:27
  • 转载请务必保留本文链接:http://www.databusworld.cn/10546.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: