在 RISC-V-Reader-Chinese-v2p1.pdf 中
RISC-V 中实现精确例外:保证异常之前的所有指令都完整地执行了,而后续的指令都没有开始执行(或等同于没有执行)
所有 RISC-V 系统的共同问题是如何处理异常和屏蔽中断,这是下一节的主题。
RISC-V 将 异常分为两类。
一类是同步异常
这类异常在指令执行期间产生,如访问了无效的存储器地址或执行了具有无效操作码的指令时
另一类是中断
它是与指令流异步的外部事件,比如鼠标的单击
两种异常都会导致
1. 设置 mcause(或scause)
2. pc 被 置位 异常向量表的地址
M模式下发生的异常
同步异常分类
可参考 mcause 下的 mcause[xlen-1] 为 0 时 的 mcause[xlen-2:0] 时的值
在 M 模式运行期间可能发生的同步例外有五种:
⚫ 访问错误异常 当物理内存的地址不支持访问类型时发生(例如尝试写入 ROM)。
⚫ 断点异常 在执行 ebreak 指令,或者地址或数据与调试触发器匹配时发生。
⚫ 环境调用异常 在执行 ecall 指令时发生。
⚫ 非法指令异常 在译码阶段发现无效操作码时发生。
⚫ 非对齐地址异常 在有效地址不能被访问大小整除时发生,例如地址为 0x12 的 amoadd.w。
中断分类
可参考 mcause 下的 mcause[xlen-1] 为 1 时 的 mcause[xlen-2:0] 时的值
有三种标准的中断源:
软件
软件中断通过向内存映射寄存器中存数来触发,并通常用于由一个 hart 中断另一个 hart(在其他架构中称为处理器间中断机
制)。
时钟
当实时计数器 mtime 大于 hart 的时间比较器(一个名为 mtimecmp 的内存映射寄存器)时,会触发时钟中断。
外部来源
外部中断由平台级中断控制器(大多数外部设备连接到这个中断控制器)引发。
不同的硬件平台具有不同的内存映射并且需要中断控制器的不同特性,因此用于发出和消除这些中断的机制因平台而异。
异常后进入的模式 M模式
当一个 hart 发生异常时,硬件自动经历如下的状态转换:
⚫ 异常指令的 PC 被保存在 mepc 中,PC 被设置为 mtvec。(对于同步异常,mepc
指向导致异常的指令;对于中断,它指向中断处理后应该恢复执行的位置。)
⚫ 根据异常来源设置 mcause(如图 10.3 所示),并将 mtval 设置为出错的地址或
者其它适用于特定异常的信息字。
⚫ 把控制状态寄存器 mstatus 中的 MIE 位置零以禁用中断,并把先前的 MIE 值保
留到 MPIE 中。
⚫ 发生异常之前的权限模式保留在 mstatus 的 MPP 域中,再把权限模式更改为
M。图 10.5 显示了 MPP 域的编码(如果处理器仅实现 M 模式,则有效地跳过这
个步骤)。
当一个 hart 发生异常时,硬件自动经历如上的状态转换后,软件可做以下动作 // 注意 , 软件 异常入口 由 mtvec 决定, 可设置单入口和向量入口
1. 读 "M 模式 异常处理寄存器" , 并做相应的处理
2. 调用 mret 指令,返回异常前状态
异常处理寄存器
八个控制状态寄存器(CSR)是机器模式下异常处理的必要部分:
⚫ mtvec(Machine Trap Vector)它保存发生异常时处理器需要跳转到的地址。
⚫ mepc(Machine Exception PC)它指向发生异常的指令。
⚫ mcause(Machine Exception Cause)它指示发生异常的种类。
⚫ mie(Machine Interrupt Enable)它指出处理器目前能处理和必须忽略的中断。
⚫ mip(Machine Interrupt Pending)它列出目前正准备处理的中断。
⚫ mtval(Machine Trap Value)它保存了陷入(trap)的附加信息:地址例外中出错的地址、发生非法指令例外的指令本身,对于其他异常,它的值为 0。
⚫ mscratch(Machine Scratch)它暂时存放一个字大小的数据。
⚫ mstatus(Machine Status)它保存全局中断使能,以及许多其他的状态,
S 模式下发生的异常
同步异常分类 同 M模式
中断分类 同 M模式
异常后进入的模式 S模式或M模式
默认情况下,发生所有异常(不论在什么权限模式下)的时候,控制权都会被移交到
M 模式的异常处理程序。但是 Unix 系统中的大多数例外都应该进行 S 模式下的系统调
用。M 模式的异常处理程序可以将异常重新导向 S 模式,但这些额外的操作会减慢大多数
异常的处理速度。因此,RISC-V 提供了一种异常委托机制。通过该机制可以选择性地将中
断和同步异常交给 S 模式处理,而完全绕过 M 模式。
mideleg(Machine Interrupt Delegation,机器中断委托)CSR 控制将哪些中断委托给 S
模式。与 mip 和 mie 一样,mideleg 中的每个位对应于图 10.3 中相同的异常。例如,
mideleg[5]对应于 S 模式的时钟中断,如果把它置位,S 模式的时钟中断将会移交 S 模式
的异常处理程序,而不是 M 模式的异常处理程序。
委托给 S 模式的任何中断都可以被 S 模式的软件屏蔽。sie(Supervisor Interrupt
Enable,监管者中断使能)和 sip(Supervisor Interrupt Pending,监管者中断待处理)CSR
是 S 模式的控制状态寄存器,他们是 mie 和 mip 的子集。它们有着和 M 模式下相同的布
局,但在 sie 和 sip 中只有与由 mideleg 委托的中断对应的位才能读写。那些没有被委派
的中断对应的位始终为零。
M 模式还可以通过 medeleg CSR 将同步异常委托给 S 模式。该机制类似于刚才提到
的中断委托,但 medeleg 中的位对应的不再是中断,而是图 10.3 中的同步异常编码。例
如,置上 medeleg[15]便会把 store page fault(store 过程中出现的缺页)委托给 S 模式。
请注意,无论委派设置是怎样的,发生异常时控制权都不会移交给权限更低的模式。
在 M 模式下发生的异常总是在 M 模式下处理。
-----------------------------------------------------------------------------------------
在 S 模式下发生的异常,根据具体的委派设置,可能由 M 模式或 S 模式处理,但永远不会由 U 模式处理。
这里只讲述 S模式 处理的情况
-----------------------------------------------------------------------------------------
S 模式处理例外的行为已和 M 模式非常相似。如果 hart 接受了异常并且把它委派给了
S 模式,则硬件会原子地经历几个类似的状态转换,其中用到了 S 模式而不是 M 模式的
CSR:
⚫ 发生例外的指令的 PC 被存入 sepc,且 PC 被设置为 stvec。
⚫ scause 按图 10.3 根据异常类型设置,stval 被设置成出错的地址或者其它特定异
常的信息字。
⚫ 把 sstatus CSR 中的 SIE 置零,屏蔽中断,且 SIE 之前的值被保存在 SPIE 中。
⚫ 发生例外时的权限模式被保存在 sstatus 的 SPP 域,然后设置当前模式为 S 模
式。
当一个 hart 发生异常时,硬件自动经历如上的状态转换后,软件可做以下动作 // 注意 , 软件 异常入口 由 stvec 决定, 可设置单入口和向量入口
1. 读 "S模式的 异常处理寄存器" , 并做相应的处理
2. 调用 sret 指令,返回异常前状态
异常处理寄存器 S模式下的CSR 或 M模式下的CSR
S 模式有几个异常处理 CSR:sepc、stvec、scause、sscratch、stval 和 sstatus,它
们执行与 10.2 中描述的 M 模式 CSR 相同的功能。
U 模式下发生的异常
同步异常分类 同M模式
中断分类 同M模式
异常后进入的模式 S模式或M模式
请注意,无论委派设置是怎样的,发生异常时控制权都不会移交给权限更低的模式。
在 M 模式下发生的异常总是在 M 模式下处理。在 S 模式下发生的异常,根据具体的委派
设置,可能由 M 模式或 S 模式处理,但永远不会由 U 模式处理。
异常处理寄存器 S模式下的CSR 或 M模式下的CSR
freertos
freertos 全程代码运行在 M-mode 下 , 所以 只存在
在 M-mode 下发生异常, 且 target 异常等级 是 M-mode
RISC-V-Qemu-virt_GCC 中 只有 2种 异常
1.同步异常
ecall
2.中断
machine timer