RISC-V 与中断相关的寄存器和指令
[info] 回顾:RISC-V 中的机器态(Machine Mode,机器模式,M 模式)
- 是 RISC-V 中的最高权限模式,一些底层操作的指令只能由机器态进行使用。
- 是所有标准 RISC-V 处理器都必须实现的模式。
- 默认所有中断实际上是交给机器态处理的,但是为了实现更多功能,机器态会将某些中断交由内核态处理。这些异常也正是我们编写操作系统所需要实现的。
回顾:RISC-V 中的内核态(Supervisor Mode,内核模式,S 模式)
- 通常为操作系统使用,可以访问一些 supervisor 级别的寄存器,通过这些寄存器对中断和虚拟内存映射进行管理。
- Unix 系统中,大部分的中断都是内核态的系统调用。机器态可以通过异常委托机制(Machine Interrupt Delegation)将一部分中断设置为不经过机器态,直接由内核态处理
在实验中,我们主要关心的就是内核态可以使用的一些特权指令和寄存器。其中关于中断的会在本章用到,而关于内存映射的部分将会在第三部分用到。
与中断相关的寄存器
在内核态和机器态中,RISC-V 设计了一些 CSR(Control and Status Registers)寄存器用来保存控制信息。目前我们关心的是其中涉及到控制中断的寄存器。
发生中断时,硬件自动填写的寄存器
sepc
即 Exception Program Counter,用来记录触发中断的指令的地址。和我们之前学的 MIPS 32 系统不同,RISC-V 中不需要考虑延迟槽的问题。但是 RISC-V 中的指令不定长,如果中断处理需要恢复到异常指令后一条指令进行执行,就需要正确判断将
pc
寄存器加上多少字节。scause
记录中断是否是硬件中断,以及具体的中断原因。stval
scause
不足以存下中断所有的必须信息。例如缺页异常,就会将stval
设置成需要访问但是不在内存中的地址,以便于操作系统将这个地址所在的页面加载进来。
指导硬件处理中断的寄存器
stvec
设置内核态中断处理流程的入口地址。存储了一个基址 BASE 和模式 MODE:MODE 为 0 表示 Direct 模式,即遇到中断便跳转至 BASE 进行执行。
MODE 为 1 表示 Vectored 模式,此时 BASE 应当指向一个向量,存有不同处理流程的地址,遇到中断会跳转至
BASE + 4 * cause
进行处理流程。
sstatus
具有许多状态位,控制全局中断使能等。sie
即 Supervisor Interrupt Enable,用来控制具体类型中断的使能,例如其中的 STIE 控制时钟中断使能。sip
即 Supervisor Interrupt Pending,和sie
相对应,记录每种中断是否被触发。仅当sie
和sip
的对应位都为 1 时,意味着开中断且已发生中断,这时中断最终触发。
sscratch
(这个寄存器的用处会在实现线程时起到作用,目前仅了解即可)
在用户态,sscratch
保存内核栈的地址;在内核态,sscratch
的值为 0。
为了能够执行内核态的中断处理流程,仅有一个入口地址是不够的。中断处理流程很可能需要使用栈,而程序当前的用户栈是不安全的。因此,我们还需要一个预设的安全的栈空间,存放在这里。
在内核态中,sp
可以认为是一个安全的栈空间,sscratch
便不需要保存任何值。此时将其设为 0,可以在遇到中断时通过 sscratch
中的值判断中断前程序是否处于内核态。
与中断相关的指令
进入和退出中断
ecall
触发中断,进入更高一层的中断处理流程之中。用户态进行系统调用进入内核态中断处理流程,内核态进行 SBI 调用进入机器态中断处理流程,使用的都是这条指令。sret
从内核态返回用户态,同时将pc
的值设置为sepc
。(如果需要返回到sepc
后一条指令,就需要在sret
之前修改sepc
的值)ebreak
触发一个断点。mret
从机器态返回内核态,同时将pc
的值设置为mepc
。
操作 CSR
只有一系列特殊的指令(CSR Instruction)可以读写 CSR。尽管所有模式都可以使用这些指令,用户态只能只读的访问某几个寄存器。
为了让操作 CSR 的指令不被干扰,许多 CSR 指令都是结合了读写的原子操作。不过在实验中,我们只用到几个简单的指令。
csrrw dst, csr, src
(CSR Read Write)
同时读写的原子操作,将指定 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
则使用立即数。
了解更多
RISC-V 官方文档:
CSR 寄存器(Chapter 4,p59)
https://content.riscv.org/wp-content/uploads/2017/05/riscv-privileged-v1.10.pdfCSR 指令(Section 2.8,p33)
https://content.riscv.org/wp-content/uploads/2017/05/riscv-spec-v2.2.pdf