1 处理机制概述

相对于ARMv7中的异常向量表(Exception Vector Table),ARMv8异常处理机制更为复杂,涉及处理器的异常等级(Exception Levels, ELn)、运行状态(Execution States)和安全模式(Secure Mode)。

这种特性意味着我们在描述异常时需要说明异常是在什么异常等级下发生的,返回时处理器的异常等级、运行状态和安全模式发生了什么变化,比如“在当前异常等级下发生Sync异常,异常等级从EL2切换到EL1,使处理器的运行状态从AArch64转到AArch32”。

ARMv8共有4个异常等级ELn(n=0,1,2,3),EL3最高,EL2最低。复位处理(Reset Handler)和异常向量表分开,支持为每个异常等级提供独立的异常向量表和栈指针寄存器(Stack Pointer,SP)。异常等级只能在复位、异常发生和退出时变更,且进入异常不能降低异常等级、退出异常不能提升异常等级。


2 异常向量表

ARMv8的异常向量表也有固定的区域划分,不过更大——单张异常向量表起始地址0x800字节对齐,内部每段0x80字节对齐,如图2-1。
图2-1 ARMv8异常向量表的结构

上图只是一个异常等级的异常向量表,一般来说需要为EL3、EL2和EL1各提供一张异常向量表。不同异常等级ELn的异常向量表起始地址可以通过寄存器VBAR_ELn(n=1,2,3)设置。

向量表可分为两部分,偏移地址0x000-0x400的用于相应当前异常等级的异常,偏移地址0x400-0x780的向量用于接收低一等级的异常。比如EL2的异常向量表,这部分就用于处理EL1的异常。

ARMv8提供了4个堆栈指针寄存器,不同异常等级ELn(n=1,2,3)可通过寄存器SPSel选择SP_ELn或者EL0作为堆栈指针,这将决定在当前异常等级下发生异常时PC跳转的位置。比如当前异常等级(假设为EL2)下发生IRQ中断,如果当前选择的堆栈指针为SP0,PC就会跳转到异常向量表的0x080偏移位置,如果当前选择的堆栈为SP_EL2,PC就会跳转到异常向量表的偏移地址0x280处。

值得一提的是,堆栈指针寄存器的使用和ARMv7没啥差别。向SPSel值选择了当前异常等级的堆栈指针后,SP寄存器和选定的SP_ELn会产生关联,二者的值会保持一致。同步机制还没有在手册里看到,暂且可以认为SP是引用了SP_ELn的值。

此外,习惯上用后缀t表示当前异常等级选择的堆栈是SP_EL0,比如SP_EL1t,用后缀h表示选择的是ELn,比如SP_EL1h。


3 异常处理

处于AArch64运行状态的ARMv8处理器根据异常的类型、发生异常的异常等级、当前使用的堆栈指针(SP in use)、寄存器组的状态(state of the register file)。

3.1 Taken 和 Return
Taken关乎异常的处理,Return关乎异常的返回。
Taken指的是处理器对异常的响应(Responds),即因异常做出动作。Taken from描述异常的来源,指处理器在Taken发生前一刻的状态。Taken to则描述异常的去向,指的是处理器在Taken发生后一刻的状态。
在异常处理的语境下,Return指的是,额,使用异常返回指令(Exception return instruction)触发的动作?Return form描述异常从何退出,指的是Return前处理器的状态。Return to描述异常退出结果,指的是Return后处理器的状态。

3.2 异常处理入口
产生异常的指令有HVC/SMC/SVC。
如果异常taken to一个使用AArch64运行状态的异常等级ELn,那么处理器在将PC跳转到异常向量表的对应位置前,将执行以下动作:
 将Taken from的PSTATE保存到SPSR_ELn寄存器
 将优先返回地址(preferred exception return address)保存到ELR_ELn寄存器
 配置Taken to的PSTATE寄存器
 如果是Synchronous或者SError异常,异常综合信息写入ESR_ELn寄存器
 跳转到异常向量表对应位置
上述Taken to的PSTATE配置遵循以下规则:
 PSTATE.EL 设置为ELn。
 PSTATE.{D, A, I, F, SP, TCO} 设置为 1
 PSTATE.SSBS 设置为 SCTLR_ELn.DSSBS 的值
 PSTATE.{IL, nRw, UAO} 设置为 0
 PSTATE.BTYPE 设置为 0b00
 PSTATE.SS 根据v8手册Chapter D2 AArch64 Self-hosted Debug中的规则设置
 对于以下任何一种情况,PSTATE.PAN 设置为 1:
—— 目标异常级别为 EL1并且SCTLR_EL1为 0
—— Taken from EL0,Taken to AArch64状态且打开安全模式的EL2,HCR_EL2.{TGE, E2H}是{1, 1},并且SCTLR_EL2.SPAN是0.
 PSTATE.ALLINT 设置为SCTLR_ELx.SPINTMASK的值取反

3.3 退出异常
退出异常的指令有ERET/ERETAA/ERETAB,异常等级EL0不支持异常退出指令。退出时切换到的目标异常等级可通过当前异常等级ELn的SPSR_ELn设置。

图3-3-1 通过SPSR_ELn选择Target EL

下面是从EL3切换到EL1的例程

.global _el3_to_el1
.type _el3_to_el1, "function"
_el3_to_el1:// Initialize the SCTLR_EL1 register before entering EL1MSR SCTLR_EL1, XZR// Determine the EL1 Execution stateMRS X0, SCR_EL3ORR X0, X0, #(1<<10) // RW, EL2 Execution state is AArch64// Determine the EL1 Security ModeAND X0, X0, #0xFFFFFFFFFFFFFFFE // NS, EL1 is Secure worldMSR SCR_EL3, x0MOV X0, #0b00101MSR SPSR_EL3, X0 // M[4:0]=01001 EL1h, must match SCR_EL3.RW// Determine EL2 entry.ADR X0, el2_entryMSR ELR_EL3, X0ERET

3.4 异常等级切换
ARMv8有EL3、EL2、EL1、EL0共四个异常等级,用户可通过产生或退出异常切换异常等级。切换异常等级需注意配置目标异常等级的栈指针寄存器、运行状态和安全模式。

EL0,EL1有安全模式和非安全模式的区别。 EL2是虚拟机管理级别并且只有非安全模式。 EL3是最高优先级并且只存在安全模式。
此外,EL3直接切换到EL1只能选择安全模式,因此EL3切换到EL1只有两个路径,一种是EL3(S)->EL2(NS)->EL1(S),另一种是EL3(S)->EL1(S)。


4 相关的指令和寄存器

4.1 ERET
4.2 SCR_EL3
4.3 SPSR_ELn.DAIF
4.4 ELR_ELn
4.5 SCTLR_EL2
4.6 HCR_EL2
4.7 ELR


5 架构相关的补充信息

要想真正理解ARMv8的异常处理机制,就需要理解ARMv8架构的特性,概要地说,至少需要通过阅读指令集手册理解以下几个概念。

5.1 运行状态
5.2 安全模式
5.3 Warm Reset

6 参考

  1. Application Note Bare-metal Boot Code for ARMv8-A Processors Version 1.0 Non-Confidential Arm® Architecture Reference Manual for A-profile architecture
  2. Arm® Architecture Reference Manual for A-profile architecture
  3. Github仓库 WaterCutter/pickArm

ARMv8 AArch64异常处理机制概览相关推荐

  1. Go语言的错误异常处理机制及其应用

    一.背景 在日常编写golang程序或阅读别人的golang代码时,我们总会看到如下的一堆代码块: xx, err = func(xx) if err != nil {//do sth. to tac ...

  2. recover 没有捕获异常_GO语言异常处理机制panic和recover分析

    本文实例分析了GO语言异常处理机制panic和recover.分享给大家供大家参考.具体如下: Golang 有2个内置的函数 panic() 和 recover(),用以报告和捕获运行时发生的程序错 ...

  3. 异常处理器详解 Java多线程异常处理机制 多线程中篇(四)

    在Thread中有异常处理器相关的方法 在ThreadGroup中也有相关的异常处理方法 示例 未检查异常 对于未检查异常,将会直接宕掉,主线程则继续运行,程序会继续运行 在主线程中能不能捕获呢? 我 ...

  4. java异常详细讲解_Java异常处理机制的详细讲解和使用技巧

    一起学习 1. 异常机制 1.1 异常机制是指当程序出现错误后,程序如何处理.具体来说,异常机制提供了程序退出的安全通道.当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器. 1.2 ...

  5. java提供两种处理异常的机制_浅析Java异常处理机制

    关于异常处理的文章已有相当的篇幅,本文简单总结了Java的异常处理机制,并结合代码分析了一些异常处理的最佳实践,对异常的性能开销进行了简单分析. 博客另一篇文章<[译]Java异常处理的最佳实践 ...

  6. java异常处理机制详解

    java异常处理机制详解 参考文章: (1)java异常处理机制详解 (2)https://www.cnblogs.com/vaejava/articles/6668809.html 备忘一下.

  7. 【Java面试题】21 Java中的异常处理机制的简单原理和应用。

    [Java面试题]21 Java中的异常处理机制的简单原理和应用. 参考文章: (1)[Java面试题]21 Java中的异常处理机制的简单原理和应用. (2)https://www.cnblogs. ...

  8. SpringMVC异常处理机制详解[附带源码分析]

    SpringMVC异常处理机制详解[附带源码分析] 参考文章: (1)SpringMVC异常处理机制详解[附带源码分析] (2)https://www.cnblogs.com/fangjian0423 ...

  9. c语言c2182是什么错误,C语言中一种更优雅的异常处理机制

    上一篇文章对C语言中的goto语句进行了较深入的阐述,实际上goto语句是面向过程与面向结构化程序语言中,进行异常处理编程的最原始的支持形式.后来为了更好地.更方便地支持异常处理编程机制,使得程序员在 ...

  10. Laravel 5.5 的错误异常处理机制以及应用实例

    一.前言 我们在开发项目中,难免会因为逻辑上的失误而报错,这些报错的展现形式也就是框架封装好的异常处理机制.在项目上线之前,我们还可以根据框架提供的报错信息来锁定错误代码的位置.但是项目上线之后我们是 ...

最新文章

  1. vue父子组件写法,数据传递,顺便封装 element-ui的弹窗组建
  2. 海蜘蛛如何手工升级到最新版
  3. Python中的ThreadLocal变量
  4. BZOJ 1786 DP
  5. Python:序列化
  6. 9月20日云栖精选夜读 | 如何轻松搞定数据科学面试:Python&R语言篇
  7. [文摘]Eclipse中如何批量替换
  8. 使用Lazy对构造进行重构后比较
  9. 如何制作通讯录vcf_【教程】刷机或更换手机后快速导入通讯录的方法
  10. C++ 返回值优化(RVO,Return Value Optimization)
  11. 合并pdf文件最简单的方法
  12. springboot启动报错@Bean definition illegally overridden by existing bean definition
  13. 成本要素****没有被分配到成本组件结构01中的成本组件
  14. 在自己电脑上调试微信公众号后台程序:附工具
  15. macbook电脑如何通过ssh连接群晖nas?
  16. excel手机版_微软开发于手机端的办公软件!
  17. BasicRF学习心得
  18. Saiku3.1构建过程(暂时不包含Saiku-UI)
  19. C++的继承和派生(一)父类和派生类(子类)的介绍以及派生类的访问控制
  20. 去掉所有的空格、回车换行符

热门文章

  1. java 忽略字母大小写判断相等
  2. 【WEB前端|H5实例】QQ修改密码页面模仿/js+css+html实现密码验证/必须包含数字字符字母两种组合/不含非法字符/密码强度验证/不能是最近使用过的密码/密码输入框实时监控
  3. 科研热点|2022年CCF会士评选结果揭晓~
  4. 巨人网络总裁史玉柱简介
  5. 厦大C语言上机 1365 小明的自娱自乐
  6. Cadence使用中遇到的错误及解决办法(更新)
  7. 易灵思FIFO操作指南
  8. hive-学习微博日志分析
  9. 宝宝为什么见生人就哭
  10. 有什么可以测试耳机性能的软件吗,耳机音质测试软件有哪些