RISC-V 特权指令结构
机器模式
机器模式(缩写为 M 模式,M-mode)是 RISC-V 中 hart(hardware thread,硬件线 程)可以执行的最高权限模式。在 M 模式下运行的 hart 对内存,I/O 和一些对于启动和配 置系统来说必要的底层功能有着完全的使用权。因此它是唯一所有标准 RISC-V 处理器都 必须实现的权限模式。实际上简单的 RISC-V 微控制器仅支持 M 模式。
hart 是 硬 件 线 程 (hardware thread)的缩略 形式。 我们用该术语将 它们与大多数程序员熟 悉的软件线程区分开 来。软件线程在 harts 上 进行分时复用。 大多数 处理器核都只有一个 hart。
CSR:控制状态寄存器
机器模式最重要的特性是拦截和处理异常(不寻常的运行时事件)的能力。
RISC-V 将 异常分为两类。
- 同步异常:这类异常在指令执行期间产生
- 如访问了无效的存储器地址
- 执行了具有无效操作码的指令
- 中断:它是与指令流异步的外部事件,比如键盘输入。
为了方便表述与区分,本文接下来的表述按照如下规则
- 异常:异常分两类,其中的同步异常
- 中断:异常分两类,其中的中断
RISC-V 异常和中断的原因

中断时mcause的最高有效位被设置成1,异常时置为0,剩下的位标识了中断或者异常的具体原因。
中断类型(来源)
- 软件中断:软件中断通过向内存映射寄存器中存数来触发,并通常用于由一个 hart 中断另一个 hart(在其他架构中称为处理器间中断机制)。
- 时钟中断:当 hart 的时间比较器(一个名为
mtimecmp的内存映射寄存器)大于实时计数器mtime时,会触发时钟中断。 - 外部中断: 有平台级中断控制器(大多数外部设备连接到这个中断控制器)引发。
机器模式下的异常、中断处理
八个控制状态寄存器(CSR)是机器模式下异常、中断处理的必要部分
mtvec(Machine Trap Vector)它保存发生异常/中断时处理器需要跳转到的地址。- RISC-V 还支持
向量中断,其中处理器跳转到各类异常/中断各自对应的地址,而不是一个统一的入口点。这种寻址消除 了读取和解码mcause的需要,加快了中断处理速度。 将mtval [0]设 置为1可启用此功能; 然后根据异常/中断原因x将PC设置为(mtval-1 + 4x ),而 不 是 通 常 的mtvec。
- RISC-V 还支持
mepc(Machine Exception PC)它指向发生异常/中断的指令。mcause(Machine Exception Cause)它指示发生异常/中断的原因(类型)。mie(Machine Interrupt Enable)它指出处理器当前屏蔽了哪些中断。mip(Machine Interrupt Pending)它列出目前正准备处理的中断(已经到来的中断)。mtval(Machine Trap Value)它保存了陷入(trap)的附加信息:page fault中出错的地址、发生非法指令例外的指令本身,对于其他异常,它的值为 0。mscratch(Machine Scratch)它暂时存放一个字大小的数据。mstatus(Machine Status)它保存全局中断使能,以及许多其他的状态
mstatus

mstatus.MIE 置 1 时才会产生中断。
mstatus.PMIE 它在异常/中断发生后保存 MIE 的旧值
mie
每个中断在控制状态寄存器 mie 中都有自己的使能位。这些位在 mie 中的位置对应于图[[RISC-V 异常和中断的原因.png]]。例如,mie[7]=1 对应于 M 模式中的时钟中断打开。
注意:中断可以被屏蔽,但是异常不能被屏蔽
mip
与 mie 有着相同的布局,并且指示当前待处理的中断。
三者相互配合
mstatus.MIE=1 打开接收中断的总开关 = 1mie[7]= 1 接收时钟中断mip[7]= 1 当前待处理的中断刚好有时钟中断
则可以处理机器的时钟中断。mstatus[MIE] & mie[7] & mip[7] ≠ 0
当一个hart 发生异常、中断时
硬件会自动经历如下的状态转换:
- 异常指令的
PC被保存在mepc中,PC被设置为mtvec。- 对于同步异常:
pepc指向导致异常的指令。 - 对于中断:它指向中断处理后应该恢复执行的位置。(这个由软件设置)
- 对于同步异常:
- 根据异常/中断源来设置
mcause寄存器。 - 将
mtval设置为出错的地址或者其他适用于特定异常的信息。 - 将
mstatus中的MIE位置置零以禁用中断,并把先前的MIE值保留到MPIE中。 - 发生异常之前的权限模式保留在
mstatus的MPP域中,再把权限模式更改为M。(如果处理器仅实现 M 模式,则有效地跳过这个步骤)。
处理中
为避免覆盖整数寄存器中的内容,异常/中断处理程序先在最开始用 mscratch 和整数寄存器(例如 a0)中的值交换。通常,软件会让 mscratch 包含指向附加临时内存空间的指针,处理程序用该指针来保存其主体中将会用到的整数寄存器。在主体执行之 后,中断程序会恢复它保存到内存中的寄存器,然后再次使用 mscratch 和 a0 交换, 将两个寄存器恢复到它们在发生异常之前的值。
返回
- 使用
mret指令返回,mret将PC设置为mepc - 将
mstatus的MPIE域复制到MIE来恢复之前的中断使能设置 - 并将权限模式设置为
mstatus的MPP域中的值
委托
默认情况下,发生所有异常(不论在什么权限模式下)的时候,控制权都会被移交到 M 模式的异常处理程序。但是 Unix 系统中的大多数例外都应该进行 S 模式下的系统调 用。M 模式的异常处理程序可以将异常重新导向 S 模式,但这些额外的操作会减慢大多数 异常的处理速度。因此,RISC-V 提供了一种异常委托机制。通过该机制可以选择性地将中断和同步异常交给 S 模式处理,而完全绕过 M 模式。
委托中断
mideleg(Machine Interrupt Delegation,机器中断委托)CSR控制将哪些中断委托给 S模式
与 mip 和 mie 一样,mideleg 中的每个位对应于”异常/中断原因图“相同的中断。例如, mideleg[5]对应于 S 模式的时钟中断,如果把它置位,S 模式的时钟中断将会移交 S 模式 的异常处理程序,而不是 M 模式的异常处理程序。
屏蔽委托的中断
委托给 S 模式的任何中断都可以被 S 模式的sieCSR屏蔽。
sie(Supervisor Interrupt Enable,监管者中断使能)和 sip(Supervisor Interrupt Pending,监管者中断待处理)CSR 是 S 模式的控制状态寄存器,他们是 mie 和 mip 的子集。它们有着和 M 模式下相同的布局,但在 sie 和 sip 中只有与由 mideleg 委托的中断对应的位才能读写。那些没有被委派 的中断对应的位始终为零。
委托异常
M 模式还可以通过 medeleg CSR 将同步异常委托给 S 模式
medeleg[15]便会把 store page fault(store 过程中出现的缺页)委托给 S 模式。
基于页面的虚拟内存
S 模式提供了一种传统的虚拟内存系统,它将内存划分为固定大小的页来进行地址转 换和对内存内容的保护。启用分页的时候,大多数地址(包括 load 和 store 的有效地址和 PC 中的地址)都是虚拟地址。要访问物理内存,它们必须被转换为真正的物理地址,这通 过遍历一种称为页表的多叉树实现。 RISC-V 的分页方案以 SvX 的模式命名,其中 X 是以位为单位的虚拟地址的长度。RV64 支持多种分页方案,但我们只介绍最受欢迎的一种,Sv39。

| 标志位 | 说明 |
|---|---|
| V | 决定了该页表项的其余部分是否有效(V = 1 时有效) 。若 V = 0,则任何遍历到此页表项的虚址转换操作都会导致页错误。 |
| R、W 和 X | 位分别表示此页是否可以读取、写入和执行。如果这三个位都是 0,V=1 那么这个页表项是指向下一级页表的指针,否则它是页表树的一个叶节点。 |
| U | 位表示该页是否是用户页面。若 U = 0,则 U 模式不能访问此页面,但 S 模式 可以。若 U = 1,则 U 模式下能访问这个页面 。 |
| G | 表示这个映射是否对所有虚址空间有效,硬件可以用这个信息来提高地址转换的性能。这一位通常只用于属于操作系统的页面 |
| A | 位表示自从上次 A 位被清除以来,该页面是否被访问过。 |
| D | 位表示自从上次清除 D 位以来页面是否被弄脏(例如被写入)。 |
| RSW | 域留给操作系统使用,它会被硬件忽略。 |
| PNN | PPN 域包含物理页号,这是物理地址的一部分。若这个页表项是一个叶节点,那 么 PPN 是转换后物理地址的一部分。否则 PPN 给出下一节页表的地址。 |
操作系统依赖于 A 位和 D 位来决定将哪些页面 交换到辅存。定期清除 A 位有助于 OS 判断哪 些页面是最近最少使用 的。 置上 D 位表示换 出该页面的成本更高, 因为它必须写回辅存。
一个叫 satp(Supervisor Address Translation and Protection,监管者地址转换和保护) 的 S 模式控制状态寄存器控制了分页系统。satp 有三个域。Mode域可以开启分页并选择页表级数。ASID(Address Space Identifier, 地址空间标识符)域是可选的,它可以用来降低上下文切换的开销。最后,PPN 字段保存 了根页表的物理地址,它以 4 KiB 的页面大小为单位。通常 M 模式的程序在第一次进入 S 模式之前会把零写入 satp 以禁用分页,然后 S 模式的程序在初始化页表以后会再次进行 satp 寄存器的写操

清除TLB缓存
所有现代的处理器都用地 址转换缓存(通常称为 TLB,全称为 Translation Lookaside Buffer)来减少这种开销。为了 降低这个缓存本身的开销,大多数处理器不会让它时刻与页表保持一致。这意味着如果操 作系统修改了页表,那么这个缓存会变得陈旧而不可用。S 模式添加了另一条指令来解决 这个问题。这条sfence.vma 会通知处理器,软件可能已经修改了页表,于是处理器可以 相应地刷新转换缓存。它需要两个可选的参数,这样可以缩小缓存刷新的范围。一个位于 rs1,它指示了页表哪个虚址对应的转换被修改了;另一个位于 rs2,它给出了被修改页表 的进程的地址空间标识符(ASID)。如果两者都是 x0,便会刷新整个转换缓存。
特权指令:
mret: machine-mode trap returnsret: supervisor-mode trap returnsfence.vma: supervisor-mode fence.virtual memory addreeewfi: wait for interruptcsrr,读取一个 CSR 的值到通用寄存器。如:csrr t0, mstatus,读取mstatus的值到t0中。csrw,把一个通用寄存器中的值写入 CSR 中。如:csrw mstatus, t0,将t0的值写入mstatus。csrs,把 CSR 中指定的 bit 置 1。如:csrsi mstatus, (1 << 2),将mstatus的右起第 3 位置 1。csrc,把 CSR 中指定的 bit 置 0。如:csrci mstatus, (1 << 2),将mstatus的右起第 3 位置 0。csrrw,读取一个 CSR 的值到通用寄存器,然后把另一个值写入该 CSR。如:csrrw t0, mstatus, t0,将mstatus的值与t0的值交换。csrrs,读取一个 CSR 的值到通用寄存器,然后把该 CSR 中指定的 bit 置 1。csrrc,读取一个 CSR 的值到通用寄存器,然后把该 CSR 中指定的 bit 置 0。
RISC-V 特权指令结构的更多相关文章
- RV32I基础整数指令集
RV32I是32位基础整数指令集,它支持32位寻址空间,支持字节地址访问,仅支持小端格式(little-endian,高地址高位,低地址地位),寄存器也是32位整数寄存器.RV32I指令集的目的是尽量 ...
- 计算机系统6-> 计组与体系结构3 | MIPS指令集(中)| MIPS汇编指令与机器表示
上一篇计算机系统5-> 计组与体系结构2 | MIPS指令集(上)| 指令系统从顶层讲解了一个指令集 / 指令系统应当具备哪些特征和工作原理.这一篇就聚焦MIPS指令集(MIPS32),看看其汇 ...
- 一文读懂UGC:互联网上的生态秘密
转载自近乎: UGC(User- Generated Content)用户原创生产内容,它是相对于PGC(Professionally-produced Content)专业生产内容的一种内容来源,简 ...
- SoC的Testbench中的简易bus_monitor(加入print函数)
SoC的Testbench中的简易bus_monitor(加入print函数) 主要思路 向固定地址写信息 使用工具链将C写的print/printf函数编译成hex文件 在testbench中创建b ...
- SoC编译HEX脚本(基于RISC-V的SoC)
SoC编译HEX脚本(基于RISC-V的SoC) 脚本使用 ./compile hello 脚本:设置RISC-V工具链riscv_set_env ############## RISC-V #### ...
- ARM概论(Advanced RISC Machines)
简介 ARM7是32 位通用微处理器ARM(Advanced RISC Machines)家族中的一员,具有比较低的电源消耗和良好的性价比, 基于(精简指令)RISC结构,指令集和相关的译码机制与微程 ...
- Linux IPC System V 信号量
模型 #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> ftok() //获取key ...
- Linux IPC System V 消息队列
模型 #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> ftok() //获取key ...
- Docker使用-v挂载主机目录到容器后出现Permission denied
1. 在挂载主机目录的到容器后,操作挂载的目录出现权限问题: # 将主机上的/data/share/master目录挂载到容器的/opt/share目录docker run -it --name=ma ...
随机推荐
- Linux上天之路(十八)之自动化部署
pexpect Pexpect 是 Don Libes 的 Expect 语言的一个 Python 实现,是一个用来启动子程序,并使用正则表达式对程序输出做出特定响应,以此实现与其自动交互的 Pyth ...
- 使用swagger生成API文档
有时候一份清晰明了的接口文档能够极大地提高前后端双方的沟通效率和开发效率.本文将介绍如何使用swagger生成接口文档. swagger介绍 Swagger本质上是一种用于描述使用JSON表示的RES ...
- SRC(不定期更新)
主域名收集 响应包 Content-Security-Policy-Report-Only
- JDK8 一文搞定👍
! https://zhuanlan.zhihu.com/p/442182870 Java8 新特性 学习来源于 B站 尚硅谷yyds Java学习源码 2021/11/22 距离,过年还有 57 天 ...
- 性能优化-使用双buffer实现无锁队列
借助本文,实现一种在"读多写一"场景下的无锁实现方式 在我们的工作中,多线程编程是一件太稀松平常的事.在多线程环境下操作一个变量或者一块缓存,如果不对其操作加以限制,轻则变量值或者 ...
- STC8H开发(六): SPI驱动ADXL345三轴加速度检测模块
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...
- AXAJ基础知识学习
AXAJ基础知识学习 博客首页 Ajax简介 ajxa全称是Asynchronous Javascript And XML ,就是异步的JS 和XML 通过Ajax可以再浏览器中向服务器发送异步请求, ...
- atan2(y,x)和pow(x,y)
atan2(y,x): 函数atan2(y, x)是4象限反正切,求的是y/x的反正切,其返回值为[-π,+π]之间的一个数.它的取值不仅取决于正切值y/x,还取决于点 (x, y) 落入哪个象限: ...
- gin框架中图形验证码的生成和验证
功能和验证码使用原理 本案例中没有使用redis作为缓存,而是使用的内存存储方法 github链接地址 下载命令 go get github.com/mojocn/base64Captcha 请求处理 ...
- Web播放器
web视频播放器的使用及遇到的问题记录 TcPlayer播放器(腾讯Web超级播放器) https://cloud.tencent.com/document/product/881/20207 Ste ...