1. RSIC-V 特权级特征
特权手册定义了指令集的执行环境
执行环境是程序的运行平台。即相同程序可以在接口相同、实现不同的执行环境中运行。
(1)程序初始状态
(2)存储区的属性和访问状态(系统调用)
(3)程序和执行环境的交互
(4)程序可见的ISA
任何情况下,一个RISCV处理器线程必须运行在某个模式下,而区分这些工作模式的原因是为不同的软件栈部件提供保护。当一个线程试图执行当前模式下不允许的操作,将会产生异常。
三种特权态
执行不被当前特权态允许的操作时会报异常。
- 机器模式(M)
必选项,另外两种可选;权限最高,可以访问任意硬件资源
通常运行bootloader或者firmware等 - 监督模式(S)
若支持该模式,另外两种须均支持;
该模式下可以运行linux等OS kernel - 用户模式(U)
此类系统实现用户和机器模式的区分,从而实现资源保护;
可以运行应用程序
M+U实现一种保护机制,用于系统和用户的隔离。
只有在响应异常和异常返回时才会发生特权级的切换。
响应异常时,要进入的特权级不能降低。
异常返回时,要返回的特权级不会升高。
特权态的切换
在RISC-V中,MRET
、SRET
和URET
分别用于从Machine、Supervisor和User模式中的trap返回,返回之后的特权等级即分别为MPP、SPP和UPP中记录的值。
系统寄存器
- 上电时工作模式切换
上电后(reset),RISC-V架构规定,特权模式复位称为机器模式,机器模式可以通过指令mret转换称为用户模式。
PC复位值由硬件自定义。
2. M模式
1 相关指令
- mret
当异常程序处理完成后,最终要从异常服务程序中退出,并返回主程序。riscv中定义了一组退出指令mret,sret,和uret,对于机器模式,对应mret。注意高等级的特权模式可以执行低等级的xRET指令,即M模式可以执行MRET,SRET和URET
在机器模式下退出异常时候,软件必须使用mret。riscv架构规定,处理器执行完mret指令后,硬件行为如下:
- 停止执行当前程序流,转而从csr寄存器mepc定义的pc地址开始执行。
- 硬件更新csr寄存器机器模式状态寄存器mstatus。mstatus寄存器MIE域被更新为当前MPIE的值。MPIE 域的值则更新为1。
2 CSR寄存器
标识寄存器包括
misa
表示处理器支持得指令集模块,如果读该寄存器返回0,则表示没有实现这个寄存器
MXL: 数据位宽
Extersion:实现了哪些扩展;在软件实现时可根据该寄存器调用哪些库
misa[4] = ~misa[8]
状态寄存器包括:
mstatsus
xPP:保存处理器进入x态之前的特权级
01:S
XS/FS
当FS值为 0 时,表示浮点单元为关闭状态,且如果此时使用浮点指令,将触发异常;若其值为 1 或 2,当执行了浮点指令后,该域会被更新为 3。
RISC-V架构下 FPU Context 的动态保存和恢复 - 极术社区 - 连接开发者与智能计算生态
MPRV: modify privilege,在某个特权级下调整load/store执行的特权状态,0:使用当前特权级的地址转换和保护机制;1:用MPP中的值作为当前状态的地址转换和保护机制
SXL/UXL:S/U态基本整数指令集控制位(00:RV32I/RV32E;10:RV64I)
与异常有关的寄存器包括:
mtvec
异常表基址寄存器,决定异常访问入口
mtval
保存因异常类型而异的信息,供异常处理程序处理异常时使用,包括
发生故障的虚地址
发生故障的指令的编码
自定义的其他编码
mcause
如果出现异常,则硬件将异常编号写到mcause寄存器中。
如果硬件实现需要区分不同的复位类型,那么mcause寄存器的值需要被复位成硬件实现自定义的值;如果硬件实现不需要区分不同的复位类型,那么mcause寄存器的值应复位成0值。
异常原因编码

mepc
保存发生异常的指令地址,或被中断打断没有提交的地址
发生自陷时,执行ECALL时,保存的是ECALL的地址,因此返回时应是 mepc+4
发生故障时,保存产生故障的地址
mip/mie
保存每一个中断的
pending/enable
medeleg/mideleg
同步异常代理寄存器/中断代理寄存器,由S态代理M态处理异常
定时器寄存器包括:
mtime/mtimecmp
性能监测寄存器包括
计算程序执行的IPC,性能分析优化
mcycle
时钟周期计数器
minstret
提交指令数计数器
3. S模式
1 相关指令
- SRET
S模式下使用sret指令返回原先指令的下一条指令
2 CSR寄存器
状态控制寄存器:
sstatus
S模式下保存和控制当前线程的操作状态,是mstatus的子集。
SPP:sret执行后即将返回的特权态
0:用户态
1:S态
- SIE:使能或失能S
- 模式下CPU的所有中断
与虚存系统相关的寄存器:
satp
PPN:根页表得物理页号
ASID: 地址空间标识
MODE:选择是否使用虚实地址转换,0:disable 1: enable
stvec
当发生异常进入S态时,被用于生成异常表访问地址的异常表基址寄存器
sepc
当发生异常进入S态时,保存发生异常的指令的地址或被中断打断没有提交的指令的地址
stval
4. 异常
4.1 控制流改变事件
为了响应处理器状态的改变而导致的控制流的突然变化,控制流的改变被定义为一个事件,可能和当前指令执行相关或无关。
异常处理流程
下图来源于国防科技大学微处理器设计课程:
以M态、U态机器举例说明:
当发生异常时,机器进入M态,硬件会将异常指令的pc保存在mepc中,异常信息保存在mtval中,判断是什么异常并将异常编码写入到mcause中,再根据mtvec的值计算出对应异常处理程序的入口(异常表),pc跳转到该入口。
异常表是软件的概念,通常是一堆跳转指令,可以指定异常发生时程序跳转的地址,该地址通常保存的是跳转指令,执行该指令会跳转到该异常的处理程序,基址寄存器和异常编号一起生成的异常表的地址
当自陷或可恢复的故障等异常处理结束时,软件执行mret指令,pc会被设为mepc的值,恢复现场,继续执行。
4.2 同步异常和异步异常
通常把同步异常叫做异常,异步异常叫中断。
同步异常
异常的类型:自陷,故障,中止。
自陷
执行一条指令时故意发生的异常,是程序主动的
总是返回现场的下一条指令
例如系统调用
故障
可修复的
总是返回异常发生现场的当前指令。
例如缺页异常
中止
无法恢复的错,例如内存的奇偶校验错(在可靠性要求较高的场景需要恢复)
中断
即异步异常,由4.1节的定义,终端是与执行指令无关的控制流改变事件。响应中断的时间点是不一定的,中断返回总是返回到现场的下一条指令。
外部中断
定时器中断:
OS在分时复用时会使用定时器中断划分时间片。
软件中断:
调试中断
5. 虚拟内存系统
SV32
虚拟地址和物理地址的转换
一级页表转换:
1)根据请求的虚拟地址VA求一级页表项PTE1的物理地址:PTE1_addr = VA[31:22] << 2 + stap[21:0]
2)获取存储器中PTE1值:PTE1 = Mem[PTE1_addr]
3)获取物理地址PA:PA = { PTE1[31:20], VA[21:12], VA[11:0] }
二级页表转换:
1)获取PTE1的过程和一级页表一样
2)求二级页表项PTE2的物理地址:PTE2_addr = VA[21:12] << 2 + PTE1[31:12] << 12
3)获取存储器中PTE2值:PTE2 = Mem[PTE2_addr]
4)获取物理地址PA:PA = { PTE2[31:20], PTE2 [21:12], VA[11:0] }
页表项PTE
V等于0表示缺页故障
X/W/R状态控制位的编码:
三者全为0表示指向下一级页表