ARMv8-AArch64 的异常处理模型详解之异常向量表vector tables

这篇具有很好参考价值的文章主要介绍了ARMv8-AArch64 的异常处理模型详解之异常向量表vector tables。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一,AArch64 异常向量表

 二,栈指针以及SP寄存器的选择

三,从异常返回


 

一,AArch64 异常向量表

异常向量表(vector tables)是一组存放于普通内存(normal memory)空间的,用于处理不同类型异常的指令(exception handler)。

当异常发生时,处理器需要跳转到对应的异常处理器(exception handler)来处理异常。异常处理器充当调度代码,识别异常的原因,然后调用相关的处理程序代码(异常处理子程序)来处理异常。

  • exception vector:在内存中存储异常处理器(exception handler)的位置称为异常向量。
  • exception vector tables :异常向量统一存放的区域称为异常向量表。
每个异常级别都有它自己的向量表,其基地址由它自己的向量基地址寄存器(Vector Base Address Register) VBAR_EL<x>定义,其中<x>为1、2或3。需要注意的是,没有针对EL0的向量表,因为异常永远不会在EL0中被处理。VBAR的值需要由软件进行初始化,它们在reset后的值是未定义的。
所有的向量表都使用相同的格式,对不同的异常类型和异常来源,有着不同的异常处理器(异常向量) ,并且,针对每种异常类型,在距离向量基地址的固定偏移量处(0x80)都有一个异常向量。
异常向量的区分和选择取决于如下因素:
  • 异常的类型,比如有(SError, FIQ, IRQ以及同步异常)。
  • 当前异常等级以及目标异常等级(The Exception levels the exception is being taken from and to)。
  • 当前支持的执行状态(AArch32或者AArch64)
  • 所使用的栈指针寄存器(SP_EL0还是SP_ELx)

下表为AArch64的异常向量表格式:

Address

Exception type

Description

VBAR_ELn + 0x000

Synchronous

Current EL with SP0

+ 0x080

IRQ/vIRQ

+ 0x100

FIQ/vFIQ

+ 0x180

SError/vSError

+ 0x200

Synchronous

Current EL with SPx

+ 0x280

IRQ/vIRQ

+ 0x300

FIQ/vFIQ

+ 0x380

SError/vSError

+ 0x400

Synchronous

Lower EL using AArch64

+ 0x480

IRQ/vIRQ

+ 0x500

FIQ/vFIQ

+ 0x580

SError/vSError

+ 0x600

Synchronous

Lower EL using AArch32

+ 0x680

IRQ/vIRQ

+ 0x700

FIQ/vFIQ

+ 0x780

SError/vSError

从这张表我们可以知道,这些向量被分为两组,每一组又被分为两个子组: 

  • 异常等级有变化(准确来说是异常等级提高,从低等级进入到更高等级,Exception from Lower EL)
    • 低等级是AArch32状态
    • 低等级是AArch64状态
  • 异常等级无变化
    • 异常使用SP_ELx。
    • 异常使用SP_EL0。

在VBAR_ELn 的向量基地址已知的情况下,当发生异常时,处理器可以根据当前的状态以及异常的类型,找到对应的异常向量进行异常处理。

如下图所示,为一个简单的异常处理流程图,当异常发生时,处理器会跳到对应异常向量中,首先将易失寄存器,也就是当前处理器的寄存器上下文保存到栈中。然后调用针对当前异常类型的异常处理函数进行处理。在异常处理完之后,再将之前保存在栈中的寄存器上下文恢复。最后执行ERET指令,从异常中返回。

AArch64的异常向量有32 个word的空间(128 bytes),可以存放32条指令,可以用于栈操作(寄存器上下文的压栈以及出栈)、调用特定异常处理函数以及ERET指令。

ARMv8-AArch64 的异常处理模型详解之异常向量表vector tables,ARM,arm开发,异常处理,异常向量表,ARMv8,arm

 

 二,栈指针以及SP寄存器的选择

 在上节中提到过异常向量的选择因素中有一项所使用的栈指针寄存器(SP_EL0还是SP_ELx)。当处理器执行在AArch64状态下时,ARM架构允许软件为当前的异常等级选择栈指针寄存器:

  • SP_EL0(需要配置PSTATE的SP)。
  • SP_ELx,x为当前的异常等级(默认情况)。

比如处理器当前处于EL1,默认情况下是使用SP_EL1作为当前的SP寄存器,但是也可以配置成使用SP_EL0。基于此配置,异常向量也被多分成了两组(使用SP_EL0还是SP_ELx)。

当异常发生时,默认情况下,会自动使用目标异常等级的SP_ELx作为栈指针寄存器。但是栈指针寄存器的选择可以通过配置PSTATE来实现,另外必须遵守如下规则:

  • 如果当前处于EL0,则处理器使用EL0的栈指针寄存器:SP_EL0。
  • 如果处于EL1,EL2或者EL3时,处理器使用的栈指针寄存器受到PSTATE.SP位控制
    • ​​​​​​​​​​​​​​如果PSTATE.SP=0,则处理器使用SP_EL0。
    • 如果PSTATE.SP=1(默认情况下为1,在warm reset后,SP也为1),则处理器使用SP_ELx。

 为什么会有SP_EL0和SP_ELx的选择配置呢?

主要是因为EL0是应用层,一般的应用程序都在EL0上运行,因此给SP_EL0分配的栈空间一般都非常大。如果异常处理时有比较大的栈空间需求,SP_EL0是更好的选择,软件可以通过设置PSTATE.SP=0,让其他异常等级上的程序工作使用SP_EL0。

三,从异常返回

当异常处理完成后,处理器需要恢复到异常发生前的状态,需要:

  • 恢复所有的之前压入栈的寄存器上下文。
  • 执行ERET指令。

ERET指令主要干了两件事:

  • SPSR_EL<x>寄存器里的值恢复到PSTATE。
  • 将ELR_EL<x>里保存的地址恢复到PC寄存器,相当于处理器跳转到ELR_EL<x>中的地址。

SPSR_EL<x>和ELR_EL<x>的x是目标异常等级,也就是(taken to和returned from的异常等级),SPSR_EL<x>寄存器里也同样保存着执行状态控制bit,如果想要改变处理器的执行状态,其中一个方法就是在ERET指令之前,将想要的执行状态(AArch32或者AArch64)提前写入SPSR_ELx。需要注意的是,写入SPSR_ELx的执行状态需要和SCR_EL3.RW 或者HCR_EL2.RW配置相对应,不然会产生非法的异常返回。

ERET主要是将SPSR_EL<x>和ELR_EL<x>的值更新到PSTATE和PC寄存器,为了让处理器不会进入未定义的状态,这两个更新操作是原子性的(不会被打断),而且对处理器来说是不可见的。

下图是ERET指令的伪代码,通过对伪代码进行分析,可以知道,虽然ERET的两个更新操作是原子性的,但是也有先后顺序:先更新SPSR,再更新PC 。

ARMv8-AArch64 的异常处理模型详解之异常向量表vector tables,ARM,arm开发,异常处理,异常向量表,ARMv8,armARMv8-AArch64 的异常处理模型详解之异常向量表vector tables,ARM,arm开发,异常处理,异常向量表,ARMv8,arm

ARMv8-AArch64 的异常处理模型详解之异常向量表vector tables,ARM,arm开发,异常处理,异常向量表,ARMv8,arm 

 ARMv8-AArch64 的异常处理模型详解之异常向量表vector tables,ARM,arm开发,异常处理,异常向量表,ARMv8,arm

ARMv8-AArch64 的异常处理模型详解之异常向量表vector tables,ARM,arm开发,异常处理,异常向量表,ARMv8,arm 

 对于ELR的使用,有一点要特别注意:ELR中保存的地址与异常类型有关。

  • 对于同步的异常服务调用指令,比如SVC、HVC以及SMC。假设执行了SMC指令进入到EL3,ELR_EL3中保存的是SMC的下一条指令。
  • 对于其他的同步异常,ELR保存的是产生异常的那条指令的地址。
  • 对于异步异常,ELR中保存的是当异常发生时,第一条还没有被执行完成的指令的地址。

当然异常处理程序软件也可以再适当的时候修改ELR寄存器里的内容,确保处理器在ERET指令后能回到正确的程序流中。

下图是ARMv7的各类型异常的首选异常返回地址:

ARMv8-AArch64 的异常处理模型详解之异常向量表vector tables,ARM,arm开发,异常处理,异常向量表,ARMv8,arm文章来源地址https://www.toymoban.com/news/detail-835297.html

到了这里,关于ARMv8-AArch64 的异常处理模型详解之异常向量表vector tables的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ARMV8-aarch64的虚拟内存(mmutlbcache)介绍-概念扫盲

    🔥 博客主页 : 小羊失眠啦. 🎥 系列专栏 : 《C语言》 《数据结构》 《C++》 《Linux》 《Cpolar》 ❤️ 感谢大家点赞👍收藏⭐评论✍️ 思考: 1、cache的entry里都是有什么? 2、TLB的entry里都是有什么? 3、MMU操作的页表中的entry中都是有什么? L1和L3表中的entry中分别都是有什么

    2024年03月12日
    浏览(53)
  • ARMv8的异常等级(Exception Level)以及执行状态(AArch64/AArch32)

    目录 1,异常等级(Exception Level) 2,Execution states,执行状态 AArch64的异常等级 AArch32的异常等级: 3,异常等级切换  4,执行状态切换(AArch64 = AArch32) 5,状态切换后的寄存器状态 Registers at AArch32 PSTATE at AArch32 6,指令集的切换:Switching between the instruction sets 在ARMv8中,存在

    2024年02月13日
    浏览(52)
  • 交叉编译----宿主机x86 ubuntu 64位-目标机ARMv8 aarch64

    1.交叉编译是什么,为什么要交叉编译 编译:在一个平台上生成在该平台上的可执行代码 交叉编译:在一个平台上生成在另一个平台上的可执行代码 交叉编译的例子:如51单片机的可执行代码(hex文件)是在集成环境keil上面编译完成的,我们只需要将编译好的可执行代码下

    2024年02月15日
    浏览(42)
  • Yocto系列讲解[技巧篇]92 - armv8 aarch64兼容armv7 32位程序运行环境

    By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力!

    2024年01月24日
    浏览(57)
  • 如何在armv6 armv7 armv8(aarch64)嵌入式板子上面安装nginx服务器,支持H265码流

    为什么要在板子瑞芯微rv1126核心板上面安装nginx服务器,是因为我的项目需要用到拉到连接在板子上面的摄像头,由于是摄像头是直连摄像头的只能通过板子上面的wifi热点设备,先连接这个热点才能获取到这个网络摄像头,那么就需要板子做一个推流的服务器让摄像头的画面

    2024年02月15日
    浏览(47)
  • 带wiringPi库的交叉编译 ---宿主机x86Ubuntu,目标机ARMv8 aarch64(香橙派)

    带wiringPi库的交叉编译如何进行 先交叉编译wiringPi库,编译出的库适合香橙派,这时候交叉编译可执行程序的平台和链接库的格式也是正确的 ,然后通过-I和-L来指定链接的wiringPi库的头文件和库的位置,但是现在还没有学习过,后面学了补上 此时如果把wiringPi库拿到Ubuntu上进

    2024年02月15日
    浏览(43)
  • 【ARMv8 异常模型入门及渐进 1 -- 处理器运行模式及EL3/EL2/EL1学习】

    下篇文章:ARMv8 异常模型入门及渐进 2 - 通用寄存器介绍 在ARM v7架构中的ARM核用 PL 的方式定义执行等级。在ARMv8中ARM核的执行等级划分如下图所示。 表 1-1 ARM v8中一个ARM core 运行时可能具有两种状态:分别为 secure world normal world。 两种状态下都有其对应的 EL0 , EL1 。 而 EL3 是

    2024年02月15日
    浏览(48)
  • 浅析ARMv8体系结构:异常处理机制

    异常处理指的是处理器在运行过程中发生了外部事件,导致处理器需要中断当前执行流程转而去处理异常事件的一种机制。在Intel处理器的术语中,中断与异常被分开来描述,但在ARMv8体系结构中,异常和中断统一被称为异常处理。 在ARMv8体系结构中,广义上的异常可以分成同

    2024年02月09日
    浏览(48)
  • Armv8-R AArch32 architecture概念学习

    该博客主要为个人学习,通过阅读官网手册整理而来(个人觉得阅读官网的英文文档非常有助于理解各个IP特性)。若有不对之处请参考 参考文档 ,以官网文档为准。 阅读该文章,可以先查看AArch64 Exception Model学习,再来看该文章会非常简单 该体系结构只有AArch32执行状态。

    2024年01月21日
    浏览(63)
  • ARMv8 - 安全机制 - 异常等级

    ARMv8架构处理器有一套异常等级(Exception level)机制,分成4个等级(EL0 ~ EL3)。 处理器运行时会处于其中的某个等级并且可以进行等级切换。 每个异常等级都拥有一些自己版本的特殊寄存器,例如:system ctrl 寄存器(sctlr_el1,sctlr_el2 …),程序状态寄存器(SPSR_EL1,SPSR_EL

    2024年02月13日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包