当前位置:网站首页>【RISC-V】Trap和Exception
【RISC-V】Trap和Exception
2022-08-04 11:28:00 【佳大先生】
文章目录
控制流 (Control Flow)和Trap
- 控制流(Control Flow)
- branch(条件分支指令), jump (无条件跳转指令),由程序正常自主控制的流程
- 异常控制流 (Exceptional Control Flow,简称 ECP, 又称Trap)
- 不在程序的控制范围之内
- exception
- interrupt
RISC-V Trap处理中涉及的寄存器
八个控制状态寄存器(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)它保存全局中断使能,以及许多其他的状态,如图
mtvec (Machine Trap-Vector Base-Address)
- BASE: trap入口函数的及地址,必须保证四字节对其
- MODE: 进一步用于控制入口函数的地址配置方式
- Direct: 所有的exception和interrupt发生后pc都跳转到BASE指定的地址处。其实就是一个中断处理函数。
- Vectored: exception处理方式同Direct;但interrupt的入口地址以数组方式排列。其实就是多向量指向不同的中断处理函数。
mepc (Machine Exception Program Counter)
- 当trap发生时,pc会被替换为mtvec设定的地址,同时hart会设置mepc为当前指令或者下一条指令的地址(如果是异常则设置当前指令,如果是中断则设置下一条指令的地址),当我们需要退出trap时可以调用特殊的mret指令,该指令会将mepc中的值恢复到pc中(实现返回的效果)。
- 在处理trap的程序中我们可以修改mepc的值达到改变mret返回地址的目的。
mcause (Machine Cause)
- 当trap发生时,hart会设置该寄存器通知我们trap发生的原因。
- 最高位Interrupt为1时标识了当前trap为interrupt,否则是exception。通过此标识能快速分辨发生了中断还是异常。
- 剩余的Exception Code用于标识具体的interrupt或者exception的种类。
- WLRL(Write/Read Only Legal Values)
mstatus (Machine Status)
- MIE: 分别用于打开(1)或者关闭(0) M/S/U模式下的全局中断。当trap发生时,hart会自动将MIE设置为0。
- MPIE: 当trap发生时用于保存trap发生之前的MIE值。
- MPP: 当trap发生时用于保存trap发生之前的权限级别值。M/S/U三种模式用两个bit表示。
中断与异常含义
RISC-V Trap处理流程
Trap初始化(设置入口地址等)-> Trap的Top Half(硬件处理过程)-> Trap的Bottom Half(软件逻辑部分)-> 从Trap返回
Top Half(Trap发生时,Hart自动执行流)
- 先把 mstatus 的MIE值复制到MPIE中,清除 mstatus 中的MIE标志位,效果是中断被禁止。(这就是硬件上不支持中断嵌套,但可以手动将中断再次打开实现中断嵌套)
- 设置 mepc,同时PC被设置为 mtvec。(需要注意的是,对于 exception, mepc 指向导致异常的指令;对于 interrupt,它指向被中断的指令的下一条指令。)
- 根据 trap 的种类设置 mcausem,并根据需要为 mtval 设置附加信息。
- 将 trap发生之前的权限模式保存在 mstatus 的 MPP 域中,再把 hart 权限模式更改为M(也就是说无论在任何 Level 下触发 trap, hart首先切换到 Machine 模式)
Bottom Half(软件需要做的事情)
- 保存(save) 当前控制流的上下文信息,是指保存x1~x31寄存器的值。(利用 mscratch)
- 调用C语言的trap handler
- 中断C程序执行完毕之后从trap handler函数返回,mepc的值可能需要调整。
- 恢复 (restore)上下文的信息。
- 执行 MRET指令返回到trap之前的状态。
退出 trap:编程调用 MRET 指令
- 针对不同权限级别下有各自退出trap的返回指令xRET (x=M/S/U)
- 以在M模式下指令mret指令为例,会执行开中断(mstatus.MIE = mstatus.MPIE; mstatus.MPIE = 1),然后返回进入trap之前的指令,如果是中断的话返回进入trap之前的下一条指令。(pc = mepc)
portASM.S
/*-----------------------------------------------------------*/
.section .text.freertos_risc_v_trap_handler
.align 8
freertos_risc_v_trap_handler:
portcontextSAVE_CONTEXT_INTERNAL
csrr a0, mcause
csrr a1, mepc
bge a0, x0, synchronous_exception
asynchronous_interrupt:
store_x a1, 0( sp ) /* Asynchronous interrupt so save unmodified exception return address. */
load_x sp, xISRStackTop /* Switch to ISR stack. */
j handle_interrupt
synchronous_exception:
addi a1, a1, 4 /* Synchronous so update exception return address to the instruction after the instruction that generated the exeption. */
store_x a1, 0( sp ) /* Save updated exception return address. */
load_x sp, xISRStackTop /* Switch to ISR stack. */
j handle_exception
handle_interrupt:
#if( portasmHAS_MTIME != 0 )
test_if_mtimer: /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */
addi t0, x0, 1
slli t0, t0, __riscv_xlen - 1 /* LSB is already set, shift into MSB. Shift 31 on 32-bit or 63 on 64-bit cores. */
addi t1, t0, 7 /* 0x8000[]0007 == machine timer interrupt. */
bne a0, t1, application_interrupt_handler
portUPDATE_MTIMER_COMPARE_REGISTER
call xTaskIncrementTick
beqz a0, processed_source /* Don't switch context if incrementing tick didn't unblock a task. */
call vTaskSwitchContext
j processed_source
#endif /* portasmHAS_MTIME */
application_interrupt_handler:
call freertos_risc_v_application_interrupt_handler
j processed_source
handle_exception:
/* a0 contains mcause. */
li t0, 11 /* 11 == environment call. */
bne a0, t0, application_exception_handler /* Not an M environment call, so some other exception. */
call vTaskSwitchContext
j processed_source
application_exception_handler:
call freertos_risc_v_application_exception_handler
j processed_source /* No other exceptions handled yet. */
processed_source:
portcontextRESTORE_CONTEXT
/*-----------------------------------------------------------*/
边栏推荐
- mongo-导出数据到mysql
- Win11怎么重装显卡驱动程序?Win11显卡驱动怎么卸载重装?
- Disc burning steps
- Leetcode——利用先序遍历特性完成114. 二叉树展开为链表
- 揭秘交换机市场内幕,“准工业级”猫腻你中招了吗?
- Doing Homework HDU - 1074
- Leetcode刷题——543. 二叉树的直径、617. 合并二叉树(递归解决)
- *iframe*
- datax oracle to oracle离线json文件
- [Flight Control Development Advanced Course 7] Crazy Shell Open Source Formation UAV - Formation Flight
猜你喜欢
ECCV 2022 | 清华&腾讯AI Lab提出REALY: 重新思考3D人脸重建的评估方法
数据库表列类型;DML_添加数据;DDL_修改,删除数据库表
强烈推荐一款优秀且通用的后台管理系统
今天15:00 | CVPR 2022 论文分享精彩继续
中电金信技术实践|分布式事务简说
iMeta | German National Cancer Center Gu Zuguang published a complex heatmap visualization method
复盘:经典的HR面试问题,这些问题可以挖掘你个人的素质,看看你是否合适合我们部门
Advanced transcriptome analysis and R data visualization hot registration (2022.10)
Win11文件类型怎么改?Win11修改文件后缀的方法
化繁为简!阿里新产亿级流量系统设计核心原理高级笔记(终极版)
随机推荐
cat /proc/kallsyms found that the kernel symbol table values are all 0
POJ1094Sorting It All Out题解
Disc burning steps
强烈推荐一款优秀且通用的后台管理系统
小程序实战(三) - head组件的封装与使用
bitset的基本用法
MTBF是什么意思?交换机做MTBF有什么要求?MTTF、MTBF和MTTR的区别是什么?
将博客搬至CSDN
A topic of map
Camunda overall architecture and related concepts
请 AI 画家弄了个 logo,网友热议:画得非常好,下次别画了!
Mysql数据类型
六石编程学:编程中的直线思维与自然思维
Leetcode brush questions - binary search tree related topics (98. Verify binary search tree, 235. The nearest common ancestor of binary search tree, 1038. From binary search tree to bigger sum tree, 5
知网网站地址更换
ping的原理
Mysql——》类型转换符binary
傅里叶级数与傅里叶变换学习
国际原子能机构总干事警告称扎波罗热核电站安全形势已“完全失控”
opencv------图片转化为视频