RISC-V 特权模式:机器模式
本文的内容主要是对 《riscv-privileged.pdf》Machine-Level ISA 章节的归纳与理解。
RISC-V 架构定义了 机器模式(machine mode)。这个模式是每一个标准 RISC-V 处理器必须要实现的模式。
并且这个模式是 RISC-V 架构中拥有最高权限的模式。机器模式可以访问所有其他模式下的控制状态寄存器 (CSR)。
机器模式具备拦截和处理异常的能力。
一. RISC-V 机器模式下的控制状态寄存器(CSR)
下表是对 RISC-V 机器模式下的控制状态寄存器的汇总,我会在表格后面将我觉得比较重要的寄存器拿出来讲一下。
寄存器 | 功能简要说明 |
---|---|
Machine ISA Register (misa) | 用于指示当前处理器所支持的指令集模块。 |
Machine Vendor ID Register (mvendorid) | 用于指示供应商 ID 的寄存器 |
Machine Architecture ID Register (marchid) | 处理器核架构编号 |
Machine Implementation ID Register (mimpid) | 提供了处理器实现版本的唯一编码 |
Hart ID Register (mhartid) | 运行当前代码的硬件线程(hart)的 ID |
Machine Status Registers (mstatus and mstatush) | 机器模式下的状态寄存器 |
Machine Trap-Vector Base-Address Register (mtvec) | 配置发生异常后的入口地址 |
Machine Trap Delegation Registers (medeleg and mideleg) | 机器异常委托寄存器和机器中断委托寄存器 |
Machine Interrupt Registers (mip and mie) | 控制中断使能与查询中断的状态的寄存器 |
Hardware Performance Monitor | 硬件性能监控的CSR寄存器,用于监控CPU的内部运行情况。 |
Machine Counter-Enable Register (mcounteren) | 仅控制计数器的可访问性。读或写这个寄存器的行为不会影响底层计数器。 |
Machine Counter-Inhibit CSR (mcountinhibit) | 控制计数器是否递增 |
Machine Scratch Register (mscratch) | 用于机器模式下临时性的保存某些数据。 |
Machine Exception Program Counter (mepc) | 用于保存进入异常前的指令的 PC 值。 |
Machine Cause Register (mcause) | 用于保存进入异常的原因。 |
Machine Trap Value Register (mtval) | 用于保存进入异常时的地址或者指令 |
1. mhartid
这个寄存器用于指示运行当前代码的硬件线程(Hart)。操作系统 SMP (对称多处理) 时会用到这个寄存器来判断运行当前代码的 Hart 。
Hart :英文全称 hardware thread ,表示一个硬件线程,对软件层面来说,就是一个独立的处理器。但是实际上也有可能它不是完整的独立的一个 CPU 核心。这里我们需要理解一个概念,那就是超线程技术,超线程技术就是将一个处理器运算单元被多个硬件线程复用,每个硬件线程有自己独立的一套通用寄存器等上下文资源。
2. mstatus
下图是机器模式下的状态寄存器。
- SIE: 监管者模式(supervisor mode)的全局中断使能位。
- MIE: 机器模式(machine mode)的全局中断使能位。
- SPIE:用于保存进入异常之前,SIE的值。
- MPIE:用于保存进入异常之前,MIE的值。
- SPP:用于保存进入异常之前,处理器处于那种模式。(只有一位,只能用于保存 S-mode 或者 U-mode 模式)
- MPP:用于保存进入异常之前,处理器处于那种模式。(有两位, U-mode,S-mode,M-mode 都可以保存)
- FS:用于维护或者反映浮点单元状态的位域。这个位域可以用于操作系统上下文切换时对浮点状态的判断。
- XS:用于维护或者反映用户自定义扩展指令单元的状态。这个位域可以用于操作系统上下文切换时对用户自定义扩展指令单元状态的判断。
- SD: 用于反映FS或者XS的位域是否处于脏(dirty)状态。这个位域是 FS,XS 状态的汇总,方便操作系统上下文切换时快速判断(即:是否需要对浮点上下文或者其他扩展指令状态进行保存)。
3. mtvec
配置发生异常后的入口地址。当处理器的程序在执行当中发生了异常,处理器会强行跳转到一个指定的 PC 地址。
这个 PC 地址是由 mtvee 寄存器指定的。
以上描述的过程叫做“陷阱”。
4. medeleg 和 mideleg
- medeleg :异常委托寄存器。
- mideleg:中断委托寄存器。
默认情况下,任何特权级别的所有陷阱都会在机器模式下处理,当然机器模式处理程序可以使用 MRET 指令将陷阱重定向回适当的模式级别。但是为了提高性能,RISC-V 提供了一种硬件机制,那就是异常中断委托机制。有了这个机制后,就不再需要软件程序上使用 MRET 指令将陷阱重定向回想要的模式级别。
medeleg 和 mideleg 寄存器中提供单独的读/写位,来指定某些异常和中断类型可以直接由某一较低的模式来处理。
5. mip 和 mie
- mie:用于控制不同中断类型的使能。
- mip:用于查询中断是否处于等待状态。
6. mscratch
用于机器模式下临时性的保存某些数据。
可以保存指向 硬件线程(hart)的上下文空间的指针,并在进入机器模式陷阱处理程序时与用户寄存器交换。
二. RISC-V 机器模式下的定时器
RISC-V 定义了一个 64 位的实时计数器,这个实时计数器会以恒定的频率递增。我们可以通过 mtime 和 mtimecmp 这两个寄存器来访问它。
- mtime:实时的显示这个计数器的值。
- mtimecmp:定时器比较寄存器。
当 mtime 的值大于或等于 mtimecmp 的值时,定时器中断就会被挂起。(前提是 mie 寄存器中的 MTIE 位被打开使能了)
这个定时器通常被用来做操作系统的滴答定时器。
三. RISC-V 机器模式下的特权指令
1. ECALL
软件程序可以通过 ECALL 指令在不同模式下生成不同的异常,以便可以有选择地委托模式环境来调用异常。
比如:类 unix 操作系统的一个典型用例是将 environment-call-from- u 模式异常委托给 s 模式,而不是其他异常。
2. EBREAK
调试器可以使用 EBREAK 指令将控制权转移回调试环境。它会生成一个断点异常,并且不执行任何其他操作。
3. MRET
MRET 指令是用于处理异常陷阱后返回,每个特权级别有单独的陷阱返回指令。
- MRET:用于机器模式下的返回
- SRET: 用于监管者模式下的返回
4. WFI
等待中断指令(WFI)具备这样的一个功能:即当程序调用 WFI 指令后,当前 hart 会被暂停,直到产生中断。WFI 指令的执行还可以用来通知硬件平台,应该优先将合适的中断路由到这个 hart 。WFI可用于所有模式下。