文章目录

  • 控制流 (Control Flow)和Trap
  • RISC-V Trap处理中涉及的寄存器
    • mtvec (Machine Trap-Vector Base-Address)
    • mepc (Machine Exception Program Counter)
    • mcause (Machine Cause)
    • mstatus (Machine Status)
    • 中断与异常含义
  • RISC-V Trap处理流程
    • Top Half(Trap发生时,Hart自动执行流)
    • Bottom Half(软件需要做的事情)
    • 退出 trap:编程调用 MRET 指令

控制流 (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_INTERNALcsrr a0, mcausecsrr a1, mepcbge a0, x0, synchronous_exceptionasynchronous_interrupt:store_x a1, 0( sp )                 /* Asynchronous interrupt so save unmodified exception return address. */load_x sp, xISRStackTop             /* Switch to ISR stack. */j handle_interruptsynchronous_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_exceptionhandle_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, 1slli 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_handlerportUPDATE_MTIMER_COMPARE_REGISTERcall xTaskIncrementTickbeqz a0, processed_source       /* Don't switch context if incrementing tick didn't unblock a task. */call vTaskSwitchContextj processed_source#endif /* portasmHAS_MTIME */application_interrupt_handler:call freertos_risc_v_application_interrupt_handlerj processed_sourcehandle_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 vTaskSwitchContextj processed_sourceapplication_exception_handler:call freertos_risc_v_application_exception_handlerj processed_source                  /* No other exceptions handled yet. */processed_source:portcontextRESTORE_CONTEXT
/*-----------------------------------------------------------*/

【RISC-V】Trap和Exception相关推荐

  1. RISC V (RV32+RV64) 架构 整体介绍

    文章目录 riscv 市场 芯片介绍 软件介绍 开发板介绍 PC介绍 riscv 架构 编程模型(指令集/寄存器/ABI/SBI) 运行状态 指令集 寄存器 riscv32和riscv64两者的区别 ...

  2. 计组学习笔记2(RISC v版)

    指令集解释 (规定:R[r]表示通用寄存器r的内容,M[addr]表示存储单元addr的内容,SEXT[imm]表示对imm进行符号扩展,ZEXT[imm]表示对imm进行零扩展) 整数运算类 -U型 ...

  3. 安装Ubuntu RISC V toolchain失败(网速、git配置原因)

    git获取大容量工程出错:RPC failed: curl GnuTLS recv error : Decryption has failed. error: RPC failed; curl 56 ...

  4. XV6 lab3:Trap

    Lab3:Traps 参考文章: 6.S081 & 操作系统内核 操作系统MIT6.S081:Lab4->Trap Xv6操作系统的系统调用通过 trampoline 来实现用户空间和内 ...

  5. python--raise Exception

    def printError(v):if v:passelse:raise Exception('Not exiests `V`.')

  6. XV6实验(2020)

    XV6实验记录(2020) 环境搭建 参考连接 Lab guidance (mit.edu) 6.S081 / Fall 2020 (mit.edu) xv6 book中文版 Lab1:Xv6 and ...

  7. RISC-V 指令学习笔记(基于CH32V103)

    文章目录 RISC-V 指令学习笔记(基于CH32V103) 一.指令结构分类 二.寄存器功能 三.加载存储指令 四.算数运算指令 五.移位指令 六.逻辑操作指令 七.跳转指令 7.1 条件跳转 7. ...

  8. GPU指令集技术分析

    GPU指令集技术分析 本文将两篇文章整理了一下. 参考文章链接如下: https://zhuanlan.zhihu.com/p/391238629 https://zhuanlan.zhihu.com ...

  9. Java 线程池(ThreadPoolExecutor)原理分析与使用

    ThreadPoolExecutor原理概述 在我们的开发中"池"的概念并不罕见,有数据库连接池.线程池.对象池.常量池等等.下面我们主要针对线程池来一步一步揭开线程池的面纱. 使 ...

最新文章

  1. canvas绘制闹钟-方法1
  2. 网站内链优化中有哪些常见的形式?
  3. java的注释规范_Java代码注释规范
  4. Python的字符串操作和Unicode
  5. 《Python Cookbook(第3版)中文版》——1.5 实现优先级队列
  6. entity framework 删除数据库出现错误的解决方法--最土但是很有效的方法
  7. Hadoop安装部署的三种模式总结
  8. Java项目框架搭建系列(Java学习路线)-博客提纲
  9. 对数及对比度拉伸变换
  10. 笔记本电脑也是一种微型计算机,计算机一级试题 很权威的哦
  11. 遗传算法(GA)学习 || 原理、本质、代码、例题
  12. java 数组与arraylist_java的数组和arraylist
  13. 奥利给!有了这么豪横的指南,还愁不会逛 GitHub?!
  14. IoTSharp 已支持国产松果时序数据库PinusDB
  15. 操作系统笔记(6):RR轮转调度算法
  16. mathematica--求偏导
  17. 住在宝马对面的苦逼程序员
  18. 为什么要使用UTF-8?
  19. win10企业版永久激活2017怎么用
  20. WiFi大师终极版本4.0.3源码已经上线,全新的系统、全新的功能!

热门文章

  1. 一个产品经理的自述:我在腾讯工作的这一年
  2. 希腊罗马神话和《圣经》中的英语典故
  3. java后端系统学习总结 03_java Web基础学习
  4. 转载:80,90后需要提前领悟的至高心法
  5. 乐嘉版 人物性格,红黄蓝绿
  6. 数据库的行格式ROW_FORMAT
  7. Oracle varchar2 4000
  8. 让DIV子元素超出部分隐藏
  9. 由浅入深玩转华为WLAN—19 漫游系列(6)不同AC之间AP漫游的概述以及二三层漫游处理过程
  10. Java编写太阳升起,描写早晨太阳升起的句子