赞
踩
目录
异常向量表(vector tables)是一组存放于普通内存(normal memory)空间的,用于处理不同类型异常的指令(exception handler)。
当异常发生时,处理器需要跳转到对应的异常处理器(exception handler)来处理异常。异常处理器充当调度代码,识别异常的原因,然后调用相关的处理程序代码(异常处理子程序)来处理异常。
下表为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 |
从这张表我们可以知道,这些向量被分为两组,每一组又被分为两个子组:
在VBAR_ELn 的向量基地址已知的情况下,当发生异常时,处理器可以根据当前的状态以及异常的类型,找到对应的异常向量进行异常处理。
如下图所示,为一个简单的异常处理流程图,当异常发生时,处理器会跳到对应异常向量中,首先将易失寄存器,也就是当前处理器的寄存器上下文保存到栈中。然后调用针对当前异常类型的异常处理函数进行处理。在异常处理完之后,再将之前保存在栈中的寄存器上下文恢复。最后执行ERET指令,从异常中返回。
AArch64的异常向量有32 个word的空间(128 bytes),可以存放32条指令,可以用于栈操作(寄存器上下文的压栈以及出栈)、调用特定异常处理函数以及ERET指令。
在上节中提到过异常向量的选择因素中有一项所使用的栈指针寄存器(SP_EL0还是SP_ELx)。当处理器执行在AArch64状态下时,ARM架构允许软件为当前的异常等级选择栈指针寄存器:
比如处理器当前处于EL1,默认情况下是使用SP_EL1作为当前的SP寄存器,但是也可以配置成使用SP_EL0。基于此配置,异常向量也被多分成了两组(使用SP_EL0还是SP_ELx)。
当异常发生时,默认情况下,会自动使用目标异常等级的SP_ELx作为栈指针寄存器。但是栈指针寄存器的选择可以通过配置PSTATE来实现,另外必须遵守如下规则:
为什么会有SP_EL0和SP_ELx的选择配置呢?
主要是因为EL0是应用层,一般的应用程序都在EL0上运行,因此给SP_EL0分配的栈空间一般都非常大。如果异常处理时有比较大的栈空间需求,SP_EL0是更好的选择,软件可以通过设置PSTATE.SP=0,让其他异常等级上的程序工作使用SP_EL0。
当异常处理完成后,处理器需要恢复到异常发生前的状态,需要:
ERET指令主要干了两件事:
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 。
对于ELR的使用,有一点要特别注意:ELR中保存的地址与异常类型有关。
当然异常处理程序软件也可以再适当的时候修改ELR寄存器里的内容,确保处理器在ERET指令后能回到正确的程序流中。
下图是ARMv7的各类型异常的首选异常返回地址:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。