RISC-V异常处理流程概述(2):异常处理机制

news2024/9/24 9:24:39

RISC-V异常处理流程概述(2):异常处理机制

    • 一、异常处理流程和异常委托
      • 1.1 异常处理流程
      • 1.2 异常委托
    • 二、RISC-V异常处理中软件相关内容
      • 2.1 异常处理准备工作
      • 2.2 异常处理函数
      • 2.3 Opensbi系统调用的注册

一、异常处理流程和异常委托

1.1 异常处理流程

发生异常时,首先需要执行 trap 流程:

  • 切换到对应的特权模式以处理该 trap。检查 medeleg 寄存器中的相应位,以判断是直接 trap 进 S 模式还是 M 模式。
  • 设置 [m/s]status 中的 xPP,xPIE,xIE 等字段。

并设置相关 CSR 的值:

  • 将 [m/s]epc 设为导致异常的指令对应的 PC 值。
  • 在 [m/s]tval 中存储有关的信息。
  • 设置 [m/s]cause寄存器的值。 随后读出 [m/s]tvec 中的值,并根据这个值跳转到 trap 处理程序。

在这里插入图片描述
这里不过多分析异常处理过程中硬件寄存器的变化,需要注意的是,在执行异常处理程序时,会进行上下文环境的切换和保存,在执行完异常处理程序后,会通过【m/s】ret指令来退出异常处理程序,接下来会进行恢复异常前程序流的相关操作,最终会跳转到【m/s】pec中保存的地址执行

1.2 异常委托

在默认的情况下,无论在什么模式下发生异常,都会将控制权交到M模式的异常处理程序,但是Linux系统多数异常都在S模式下进行系统调用。此时,会将M 模式的异常处理程序可以将异常重新导向 S 模式,但这些额外的操作会减慢大多数异常的处理速度。因此,RISC-V 提供了一种异常委托机制。通过该机制可以选择性地将异常交给 S 模式处理,而完全绕过 M 模式。

这种委托机制的实现主要通过:medeleg(Machine Exception Delegation,机器同步异常委托)和 mideleg(Machine Interrupt Delegation,机器中断委托)分别控制将哪些同步异常和中断委托给 S 模式,mret 指令则将 trap 交给其它特权模式处理。

委托给 S 模式的任何异常都可以被 S 模式屏蔽。sie(Supervisor Interrupt Enable,监管者中断使能)和 sip(Supervisor Interrupt Pending,监管者中断待处理)是 S 模式的控制状态寄存器,它们是 mie 和 mip 的子集。它们有着和 M 模式下相同的布局,但在 sie 和 sip 中只有由 mideleg 委托的中断对应的位才能读写,那些没有被委派的中断对应的位始终为 0。

注:发生异常时控制权都不会移交给权限更低的模式。在 M 模式下发生的异常总是在 M 模式下处理。在 S 模式下发生的异常,根据具体的委派设置,可能由 M 模式或 S 模式处理,但永远不会由 U 模式处理。

二、RISC-V异常处理中软件相关内容

2.1 异常处理准备工作

这里需要特殊强调的是异常处理构建的相关内容:
这里会将a4寄存器中的值存储到CSR_MTVEC这个状态寄存器,也就是异常处理程序的的入口;如果遇到异常、中断时,硬件会自动找到_trap_handler

	/* Setup trap handler */
	la	a4, _trap_handler
#if __riscv_xlen == 32
	csrr	a5, CSR_MISA
	srli	a5, a5, ('H' - 'A')
	andi	a5, a5, 0x1
	beq	a5, zero, _skip_trap_handler_rv32_hyp
	la	a4, _trap_handler_rv32_hyp
#endif
	csrw	CSR_MTVEC, a4

	.section .entry, "ax", %progbits
	.align 3
	.globl _trap_handler
_trap_handler:
	TRAP_SAVE_AND_SETUP_SP_T0

	TRAP_SAVE_MEPC_MSTATUS 0

	TRAP_SAVE_GENERAL_REGS_EXCEPT_SP_T0

	TRAP_CALL_C_ROUTINE

	TRAP_RESTORE_GENERAL_REGS_EXCEPT_SP_T0

	TRAP_RESTORE_MEPC_MSTATUS 0

	TRAP_RESTORE_SP_T0

	mret

建立excption_stack空间,如所示M模式下的异常,则从SP指针开始构建;若不是M模式进入异常,则需要从TP指针开始构建,TP的值为MSCRARCH(这个寄存器会在非M模式下记录M模式下栈帧地址)

.macro	TRAP_SAVE_AND_SETUP_SP_T0
	/* Swap TP and MSCRATCH */
	csrrw	tp, CSR_MSCRATCH, tp

	/* Save T0 in scratch space */
	REG_S	t0, SBI_SCRATCH_TMP0_OFFSET(tp)

	/*
	 * Set T0 to appropriate exception stack
	 *
	 * Came_From_M_Mode = ((MSTATUS.MPP < PRV_M) ? 1 : 0) - 1;
	 * Exception_Stack = TP ^ (Came_From_M_Mode & (SP ^ TP))
	 *
	 * Came_From_M_Mode = 0    ==>    Exception_Stack = TP
	 * Came_From_M_Mode = -1   ==>    Exception_Stack = SP
	 */
	csrr	t0, CSR_MSTATUS
	srl	t0, t0, MSTATUS_MPP_SHIFT
	and	t0, t0, PRV_M
	slti	t0, t0, PRV_M
	add	t0, t0, -1
	xor	sp, sp, tp
	and	t0, t0, sp
	xor	sp, sp, tp
	xor	t0, tp, t0

	/* Save original SP on exception stack */
	REG_S	sp, (SBI_TRAP_REGS_OFFSET(sp) - SBI_TRAP_REGS_SIZE)(t0)

	/* Set SP to exception stack and make room for trap registers */
	add	sp, t0, -(SBI_TRAP_REGS_SIZE)

	/* Restore T0 from scratch space */
	REG_L	t0, SBI_SCRATCH_TMP0_OFFSET(tp)

	/* Save T0 on stack */
	REG_S	t0, SBI_TRAP_REGS_OFFSET(t0)(sp)

	/* Swap TP and MSCRATCH */
	csrrw	tp, CSR_MSCRATCH, tp
.endm

TRAP_CALL_C_ROUTINE前面的宏流程用于状态的保存,TRAP_CALL_C_ROUTINE则会调用到C阶段,进入真正的异常处理程序:

.macro	TRAP_CALL_C_ROUTINE
	/* Call C routine */
	add	a0, sp, zero
	call	sbi_trap_handler
.endm

下面将调用到sbi_trap_handler进行真正的异常处理函数。

2.2 异常处理函数

当Linux中发起ecall调用后,OpenSBI相关服务出发过程如下,主要分为以下几个阶段

  • 上一节中讲到,在fw_base.S汇编阶段注册了M mode的trap handler,也就是sbi_trap_handler
  • 在sbi_trap_handler中处理各种mcause,首先判断中断原因是否为外部设备中断(timer,ipi),若不是则会根据不同的异常类型比如illegal instructions,Misaligned load & store,S and M mode ecall等等
//lib/sbi_trap.c
/**
 * Handle trap/interrupt
 *
 * This function is called by firmware linked to OpenSBI
 * library for handling trap/interrupt. It expects the
 * following:
 * 1. The 'mscratch' CSR is pointing to sbi_scratch of current HART
 * 2. The 'mcause' CSR is having exception/interrupt cause
 * 3. The 'mtval' CSR is having additional trap information
 * 4. The 'mtval2' CSR is having additional trap information
 * 5. The 'mtinst' CSR is having decoded trap instruction
 * 6. Stack pointer (SP) is setup for current HART
 * 7. Interrupts are disabled in MSTATUS CSR
 *
 * @param regs pointer to register state
 */
void sbi_trap_handler(struct sbi_trap_regs *regs)
{
   
	int rc = SBI_ENOTSUPP;
	const char *msg = "trap handler failed";
	ulong mcause = csr_read(CSR_MCAUSE);
	ulong mtval = csr_read(CSR_MTVAL), mtval2 = 0, mtinst = 0;
	struct sbi_trap_info trap;

	if (misa_extension('H')) {
   
		mtval2 = csr_read(CSR_MTVAL2);
		mtinst = csr_read(CSR_MTINST);
	}

	if (mcause & (1UL << (__riscv_xlen - 1))) {
   
		mcause &= ~(1UL << (__riscv_xlen - 1));
		switch (mcause) {
   
		case IRQ_M_TIMER:
			sbi_timer_process();
			break;
		case IRQ_M_SOFT:
			sbi_ipi_process();
			break;
		default:
			msg = "unhandled external interrupt";
			goto trap_error;
		};
		return;
	}

	switch (mcause) {
   
	case CAUSE_ILLEGAL_INSTRUCTION:
		rc  = sbi_illegal_insn_handler(mtval, regs);
		msg = "illegal instruction handler failed";
		break;
	case CAUSE_MISALIGNED_LOAD:
		rc = sbi_misaligned_load_handler(mtval, mtval2, mtinst, regs)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1915263.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

软件工程(下)

目录 需求工程 概述 需求获取 分层 获取方法 项目管理维度 需求开发---需求分析 UML&#xff08;统一建模语言&#xff09;&#xff1a;平台无关、语言无关 UML 41视图 需求的定义、验证、跟踪、变更 需求定义 需求验证 需求跟踪 需求变更管理 软件系统建模 软件…

.NET周刊【7月第1期 2024-07-07】

国内文章 学习.NET 8 MiniApis入门 https://www.cnblogs.com/hejiale010426/p/18280441 MiniApis是ASP.NET Core中的轻量级框架&#xff0c;用最少的代码和配置创建HTTP API。其特点包括简洁明了、性能卓越、灵活多变、易于学习使用&#xff0c;并与ASP.NET Core生态系统完美…

深入了解java锁升级可以应对各种疑难问题

对于java锁升级&#xff0c;很多人都停留在比较浅层的表面理解&#xff0c;一定程度下也许够用&#xff0c;但如果学习其中的细节&#xff0c;我们更好地理解多线程并发时各种疑难问题的应对方式&#xff01; 因此我将锁升级过程中可能涉及的大部分细节或者疑问都整合成了一篇…

01MFC建立单个文件类型——画线

文章目录 选择模式初始化文件作用解析各初始化文件解析类导向创建鼠标按键按下抬起操作函数添加一个变量记录起始位置注意事项代码实现效果图虚实/颜色线选择模式 初始化文件作用解析 运行: 各初始化文件解析 MFC(Microsoft Foundation Classes)是一个C++类库,用于在Win…

fm足球经理Football Manager 2022 for mac 下载安装包

《Football Manager 2022》&#xff08;足球经理2022&#xff09;是一款由Sports Interactive开发并由SEGA发行的足球管理模拟游戏。这款游戏让玩家扮演足球俱乐部的 manager&#xff08;经理&#xff09;&#xff0c;负责球队的所有管理工作&#xff0c;包括战术制定、球员转会…

美业收银系统怎么选?哪些功能实用?美业门店管理系统|拓客系统

选择美业会员系统时&#xff0c;你可以考虑以下几个方面的功能来确定哪些对你最实用&#xff1a; 1.会员管理&#xff1a; 系统应该能够轻松管理会员资料、积分、消费记录等信息&#xff0c;以便更好地了解客户需求并提供个性化服务。 2.促销与营销工具&#xff1a; 包括发…

RS NGP804 直流电源

直流电源 R&S NGP804 -借助四核功率提升效率- R&SNGP800 直流电源系列共有五种不同型号&#xff0c;功率为 400 W 或 800 W&#xff0c;可在多种操作条件下提供最大功率。该电源系列具有两个或四个 200 W 输出通道&#xff0c;每通道的输出电压和电流可达 64 V 及 …

C++入门基础篇(下)

目录 6.引用 6.1 引用的特性 6.2 const引用 7.指针和引用的关系 8.内联函数 9.nullptr 6.引用 引⽤不是新定义⼀个变量&#xff0c;⽽是给已存在变量取了⼀个别名&#xff0c;编译器不会为引⽤变量开辟内存空间&#xff0c; 它和它引⽤的变量共⽤同⼀块内存空间。比如&a…

Java毕业设计 基于SSM vue图书管理系统小程序 微信小程序

Java毕业设计 基于SSM vue图书管理系统小程序 微信小程序 SSM 图书管理系统小程序 功能介绍 用户 登录 注册 首页 图片轮播 图书信息推荐 图书详情 赞 踩 评论 收藏 系统公告 公告详情 用户信息修改 我的待还 图书归还 催还提醒 我的收藏管理 意见反馈 管理员 登录 个人中心…

JAVA--SpringCloud

SpringCloud基础 为什么需要spring cloud 单体结构--Monolith 首先请回想一下我们所开发的服务是什么样子的。通常情况下&#xff0c;这个服务所对应的代码由多个项目&#xff08;模块&#xff09;所组成&#xff0c;各个项目会根据自身所提供功能的不同具有一个明确的边界。…

Mosh|初学者SQL教程第二弹

using子句(如果匹配的两个字段在两个表中的名字相同可以使用&#xff09; 多条件使用using 自然连接&#xff08; NATURAL JOIN&#xff09;&#xff0c;它意味着让搜索引擎基于共同列自行去尝试join&#xff0c;可能会出现意想不到的结果&#xff0c;不要轻易尝试 交叉连接&am…

DNS 杂谈

一、定义 DNS&#xff08;Domain Name System&#xff09;&#xff0c;域名系统&#xff0c;该系统记录域名和Ip地址的相互映射关系。用户访问互联网时&#xff0c;通过域名地址得到对应的IP地址&#xff0c;这个过程称为域名解析。DNS运行于UDP协议之上&#xff0c;使用的端口…

HomeAssistant HAOS安装HACS集成

1. HAOS安装HACS集成 1.1 手动安装HACS 下载HACS压缩包 加载项安装samba&#xff0c;可能需要特殊网络环境不然非常慢 配置->加载项->加载项商店-> 搜索samba&#xff0c;并安装&#xff0c;配置用户名密码 Samba配置完成之后,如果启动不起来就需要重启HomeAssis…

图文讲解IDEA如何导入JDBC驱动包

前言 学习JDBC编程,势必要学会如何导入驱动包,这里笔者用图文的方式来介绍 视频版本在这里 50秒教你怎么导入驱动包然后进行JDBC编程的学习_哔哩哔哩_bilibili 忘记录音频了,大伙凑合着看 下载驱动包 https://mvnrepository.com/artifact/mysql/mysql-connector-java 去中…

SpringCloud代码实战

项目结构 实例实现功能:实现通过id查询用户的订单信息 OrderCommon&#xff1a;公共的一些模块类型&#xff0c;此处为一个user对象 Eureka-Service:配置Eureka的启动类&#xff0c;服务端 Order-Service:提供查询功能的服务端 Order-Client:查询的客户端 OrderCommon代码…

C++类与对象-基础篇

目录 一、什么是类 1.1 语法定义 1.2 访问限定符 1.3 类域 二、类的实例化 2.1 什么是实例化 2.2 类的大小 三、this指针 3.1 引入 3.2 this指针的使用 一、什么是类 1.1 语法定义 class 类名 {}; 说明 类似于C语言中的结构体&#xff0c;括号后分号不能丢类内成员可…

类型“RouteRecordName”上不存在属性“includes”。 类型“symbol”上不存在属性“includes”

确定 route.name 运行时是 字符串&#xff0c;强制转换 为字符串。 removeRoute(id: string) { this.dynamRoute this.dynamRoute.filter(route > !(route.name as string).includes(id)) localStorage.setItem(dynamRoute, JSON.stringify(this.dynamRoute)) delete this.t…

[leetcode] shortest-subarray-with-sum-at-least-k 和至少为 K 的最短子数组

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int shortestSubarray(vector<int>& nums, int k) {int n nums.size();vector<long> preSumArr(n 1);for (int i 0; i < n; i) {preSumArr[i 1] preSumArr[i] nums[i];}int res n…

【服务器】在Linux查看运行的Python程序,并找到特定的Python程序

在Linux查看运行的Python程序并找到特定的Python程序 写在最前面1. 使用ps命令查看所有Python进程查看详细信息 2. 使用pgrep命令查找Python进程ID 3. 使用top或htop命令使用top命令使用htop命令 4. 使用lsof命令查找Python进程打开的文件 5. 使用nvidia-smi命令查看GPU使用情况…

九、函数递归

——————————————————————————————————————————— 目录 1、递归是什么&#xff1f; 1.1、递归的思想 1.2、递归的限制条件 2、递归举例 2.1、举例1&#xff1a;求n的阶乘 2.1.1、分析和代码实现 2.2.1分析和代码实现 3、递归与…