2020/07/20
中断:
相关寄存器:
sepc:记录触发中断的指令地址
scause:记录中断具体原因。
stval:记录中断所需要的其他信息,例如缺页异常中导致缺页的虚拟地址
stvec:
MODE:
0:直接跳到base运行
1:跳到BASE+4*cause进行处理流程
BASE
sstatus:状态位控制全局中断。
sie:控制具体类型中断使能。
sip:记录各种具体类型中断是否已经触发。
相关指令:
ecall:S态进入M态,请求底层os服务。
sret:内核态返回用户态,pc设为sepc。(如果需要返回后一条指令,则需要提前修改sepc)
ebreak:触发断点。
mret:机器态返回内核态,同时PC设为mepc。
相关操作:
-
同时读写的原子操作,将指定 CSR 的值写入
dst
,同时将src
的值写入 CSR。 -
csrr dst, csr
(CSR Read) 仅读取一个 CSR 寄存器。 -
csrw csr, src
(CSR Write) 仅写入一个 CSR 寄存器。 -
csrc(i) csr, rs1
(CSR Clear) 将 CSR 寄存器中指定的位清零,csrc
使用通用寄存器作为 mask,csrci
则使用立即数。 -
csrs(i) csr, rs1
(CSR Set) 将 CSR 寄存器中指定的位置 1,csrc
使用通用寄存器作为 mask,csrci
则使用立即数。保存上下文:
第一步:把原先的寄存器信息压栈。
第二步:保存CSR,压栈:
# 取出 CSR 并保存
csrr s1, sstatus
csrr s2, sepc
SAVE s1, 32
SAVE s2, 33
第三步:调用中断,传入参数:(handle_interrput是需要写的中断处理函数)
# 调用 handle_interrupt,传入参数
# context: &mut Context
mv a0, sp
# scause: Scause
csrr a1, scause
# stval: usize
csrr a2, stval
jal handle_interrupt
.globl __restore
第四步:恢复CSR和通用寄存器。
完成了时钟中断,lab1实验算是圆满,其中实验指导出现了几处问题,比如../interrupt的路径问题,但是通过查看源码也得到了解决。
废了九牛二虎之力,lab2也只完成了一小部分。
但是更加深刻理解了rust工程的逻辑,知道了buddy_system的算法原理,
经宇神点拨,决定去重看一下《rust编程之道》第十章。