[ARM异常]-ARMV8-aarch64异常和中断处理概念详细介绍

269 篇文章 398 订阅

★★★ 个人博客导读首页—点击此处 ★★★

快速链接:
.
👉👉👉 个人博客笔记导读目录(全部) 👈👈👈

在这里插入图片描述

1、异常和中断的概念

(AArch64 Exception and Interrupt Handling)
异常是指需要特权软件(an exception handler))采取某些操作,以确保系统的平稳运行

中断有时用作异常的同义词。但是对于ARM的术语来说,中断是异步异常,只是异常的一种;

异常是一个事件(而不是分支或跳转指令)导致指令的正常顺序执行被修改。
一个中断是一个异常,它不是由程序执行直接引起的。通常情况下,硬件外部到处理器核心信号中断,如一个按钮被按下

ARM-A架构异常分为两组,同步和异步的。
同步异常类型可以有很多原因,但是它们是以类似的方式处理。
异步异常类型被细分为三个中断:IRQ, FIQ和SError(系统错误)。

2、异常产生的方法:
(1)、Abort :

指令获取失败时生成中止(指令中止)
失败的数据访问(数据中止)
它们可以来自外部记忆系统在内存访问上给出错误响应(指示可能指定的地址与系统中的实际内存不对应)。或者,核心的内存管理单元(MMU)生成中止

在AArch64中,同步中止会导致同步异常。异步中止会导致SError中断异常

(2)、Reset

重置是一种特殊情况,因为它总是有自己的向量以最高的实现异常级别为目标
地址可以从重置向量基地址寄存器中读取RVBAR_ELn,其中n是实现的最高异常级别的数目。
所有的核心都有一个重置输入,并在它们被重置后接受重置异常重置。它是最高优先级的异常,不能被掩盖。这个异常是用来在内核上执行代码来初始化它,在系统通电后向上

(3)、同步异常

• The Supervisor Call (SVC) instruction enables User mode programs
to request an OS service.
• The Hypervisor Call (HVC) instruction enables the guest OS to
request hypervisor services.
• The Secure monitor Call (SMC) instruction enables the Normal

(4)、异步异常(中断)

中断有三种类型,IRQ, FIQ和SError。IRQ和FIQ是与SError相比,一般用途是与外部异步数据中止。所以通常,术语“中断”仅指到IRQ和FIQ。

3、同步异常和异步异常的处理
(1)、处理一个同步异常

Exception Syndrome Register (ESR_ELn)
Fault Address Register (FAR_ELn)
The Exception Link Register (ELR_ELn)

异常综合征寄存器(ESR_ELn)和错误地址寄存器(FAR_ELn)是提供用于向异常处理程序提供有关同步异常原因的信息
ESR_ELn提供异常原因的信息,而FAR_ELn保存所有同步指令和数据中止和对齐错误的错误虚拟地址。

对于实现了EL2 (Hypervisor)或EL3(安全内核)的系统,同步异常通常在当前或更高的异常级别中获取。异步异常可以(如果)),将被路由到更高的异常级别,由Hypervisor或安全程序处理
内核。SCR_EL3寄存器指定哪些异常被路由到EL3,类似地,HCR_EL2指定将哪些异常路由到EL2。有一些单独的位允许独立控制IRQ, FIQ和SError的路由。

(2)、ESR_ELn - 异常综合征寄存器

包含允许异常的信息
处理程序来确定异常的原因。它只针对同步异常进行更新
和SError。它不为IRQ或FIQ更新,因为这些中断处理程序通常获得状态
来自通用中断控制器(GIC)寄存器的信息

(3)、Unallocated instructions

Unallocated instructions cause a Synchronous Abort in AArch64. 该异常产生的原因:
• An instruction opcode that is not allocated.
• An instruction that requires a higher level of privilege than the current Exception level. //比如你在EL1中操作了SCR_EL3寄存器
• An instruction that has been disabled.
• Any instruction when the PSTATE.IL field is set.

(4)、System calls

在这里插入图片描述

4、异常处理

ARMv8-A体系结构有四个异常级别:EL0、EL1、EL2和EL3。处理器执行
只能通过获取异常或从异常返回来在异常级别之间移动。

需要注意的是:

  • When the processor moves from a higher to a lower Exception level, the Execution state can
    stay the same, or it can switch from AArch64 to AArch32.
  • When moving from a lower to a higher Exception level, the Execution state can stay the same
    or switch from AArch32 to AArch64
    也就是说,如果高级别的level为aarch32,那么低级别的level一定得为aarch32
    如果高级别的level为aarch64,那么低级别的level一可以为aarch32或aarch64

当一个异常发生时, the processor自动执行了如下动作:

  1. The SPSR_ELn is updated (where n is the Exception level where the exception is taken), to
    store the PSTATE information that is required to correctly return at the end of the exception.
  2. PSTATE is updated to reflect the new processor status (and this can mean that the
    Exception level is raised, or it can stay the same).
  3. The address to return to at the end of the exception is stored in ELR_ELn.
    The _ELn suffix on register names denotes that there are multiple copies of these registers
    existing at different Exception levels. This means, for example, that SPSR_EL1 is a different
    physical register to SPSR_EL2.
    在这里插入图片描述

而我们在异常处理中,又会调用下一级的函数来干活,图形也就如下所示:

在这里插入图片描述

当异常处理完成后,processor由高级别返回低级别时,使用ERET指令返回

4、异常向量表

每个异常级别都有自己的一套向量表,这些表的基地址分别写在VBAR_EL3, VBAR_EL2 and VBAR_EL1系统寄存器中.
向量表中的每个条目有16 instructions long(0x80字节)(在ARMv7-A和AArch32中,每个条目只有4个字节)。这意味着在AArch64中顶层处理程序可以直接在向量中,而不是跳转到其它地址处执行.

VBAR_ELn执行的每个table中,定义了16个entries,具体走哪一个entry是由下面几个因素决定的:
• The type of exception (SError, FIQ, IRQ, or Synchronous)
• If the exception is being taken at the same Exception level, the stack pointer to be used (SP0 or SPn).
• If the exception is being taken at a lower Exception level, the Execution state of the next lower level (AArch64 or AArch32).

一张经典的向量表,如下所示:
在这里插入图片描述

举一个超级简单的例子:
kernel code执行在EL1,这时来了一个IRQ,该中断没有配置到hypervisor和secure environment中,所以它的处理仅仅是在kernel中完成,程序跳转到VBAR_EL1+0x280,栈使用sp_el1(将SPSel设置程sp_el1)

5、异常返回

软件必须告诉处理器何时从异常中返回。这是通过代码完成的使用ERET指令。这将从SPSR_ELn中恢复异常前的PSTATE并返回通过从ELR_ELn恢复PC,将程序执行返回到原始位置。
在A64指令集中,使用寄存器X30(与RET指令一起)返回子例程

ELR_ELn寄存器用于存储来自异常的返回地址。它的价值寄存器是自动写入的入口异常,并被写入到PC作为其中之一执行用于从异常中返回的ERET指令的效果。

除了SPSR和ELR寄存器之外,每个异常级别都有自己专用的堆栈指针登记。它们是SP_EL0、SP_EL1、SP_EL2和SP_EL3。这些寄存器用来指向专用的栈。堆栈可以,例如,用来存储寄存器被损坏异常处理程序,使它们可以在返回之前恢复到原来的值原始代码

处理程序代码可以从使用SP_ELn切换到使用SP_EL0。例如,SP_EL1可能指向存储小堆栈的内存块,内核可以始终保证该小堆栈是有效的。SP_EL0可能指向较大的内核任务堆栈. 但不能保证不发生溢出。这切换通过写入SPSel寄存器来控制。

6、PSTATE

在这里插入图片描述
在这里插入图片描述

当前processor的状态保存在PSTATE,当异常到来时,PSTATE的值会自动保存在SPSR中。 aarch64中由三个SPSR : SPSR_EL3, SPSR_EL2, and SPSR_EL1
例如,如果发生了一个异常target到EL1,那么当前处理器的状态会自动保存到SPSR_EL1中;

在这里插入图片描述

7、中断的处理流程

在这里插入图片描述
在这里插入图片描述


  • 0
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码改变世界ctw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值