从u-boot理解armv7异常处理

    说到异常,就会想起不正常情况。异常确实是CPU处理非正常流程的一种手段。这里要说的是中断也是一种异常,而且ARMV7KH 定义了两种中断异常,irq与fiq。中断是我们熟知的,中断向量表跟异常向量表是什么关系呢。当外设发生中断时,通知中断控制器,中断控制器只是向CPU CORE发送了IRQ,也就是说在CORE看来所有中断只能称为IRQ异常。下面理一下armv7在异常处理上的设置。

1、armv7异常向量


从上面我们可以知道armv7支持7种异常。上面表要注意data abort与irq之间隔了一个向量,是一个没有使用的异常向量。

  (1)、复位(RESET)
    a、当处理器复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行,包括系统加电和系统复位。
    b、通过设置PC跳转到复位中断向量处执行称为软复位。
    (2)、未定义的指令
    当ARM处理器或者是系统中的协处理器认为当前指令未定义时,产生未定义的指令异常中断,可以通过改异常中断机制仿真浮点向量运算。
    (3)、软件中断
    这是一个由用户定义的中断指令(SWI)。该异常由执行SWI指令产生,可用于用户模式下的程序调用特权操作指令。在实时操作系统中可以通过该机制实现系统功能调用。
    (4)、指令与取终止(Prefech Abort)
    如果处理器预取的指令的地址不存在,或者该地址不允许当前指令访问,当被预取的指令执行时,处理器产生指令预取终止异常中断。
    (5)、数据访问终止(DATAABORT)
    如果数据访问指令的目标地址不存在,或者该地址不允许当前指令访问,处理器产生数据访问终止异常中断。
    (6)、外部中断请求(IRQ)
    当处理器的外部中断请求引脚有效,而且CPSR的寄存器的I控制位被清除时,处理器产生外部中断请求异常中断。系统中个外设通过该异常中断请求处理服务。
    (7)、快速中断请求(FIQ)
    当处理器的外部快速中断请求引脚有效,而且CPSR的F控制位被清除时,处理器产生外部中断请求异常中断。

2、异常向量表与异常响应

当相应的异常发生时,CPU跳到一个固定的地址去执行指定程序。这个通常由称为异常向量表来实现。异常向量来实现。向量表的定义如下图所示:


armv7实现向量表时用的是一个word,4个字节的空间,这里放指令的话也只能放下一条arm指令。所以这里要想实现更多处理只能放一条跳转指令。但是图中是一条ldr指令,给CPU直接赋值。那么如果这条跳转执行的话,我们如果在异常处理完成之后返回呢。这里要明白,在异常发生时,硬件做的事及软件要做的事。

硬件在异常发生时可能会伴随着模式的切换,关于ARMV7的几中模式看下面图。


在这里只要看到不同模式,采用了寄存组分组技术,也就说不同模式使用了不同的寄存器。那么要CPU要完成异常处理完成后再次回到异常发生的地方需要做那些事情呢。

1)硬件首先把发生异常模式的当前PC+4,也就是在发生模式切换时,把当前模式的下一条指令地址保存到该模式的lr寄存器。从上图可以看出,在各模式PC指令是一样的,但是lr寄存器使用不同寄存器。

2)将cpsr的值复制到异常模式的spsr.

3)将cpsr设置成对应的异常工作模式。

4)设置PC指针为为异常向量表相应地址去执行。

而软件要做的事是:

1)切换SP指针到对应的模式栈,也就是不同模式采用不同的栈。

2)在当前模式栈中保存共用寄存器。

看一下uboot代码中irq的处理:


3、中断与异常处理

中断是异常处理的子集。当我们给外设绑定一个中断号的处理程序时,其实是引发的IRQ异常,然后由do_irq中实现了二级向量表,实现各中断处理的。


4、异常栈的建立

关于各异常的建立是在运行时建立的,这个解释起来要使用gd这个全局结构与uboot内存布局。有兴趣可以参考一下board_init_f

这个函数,异常模式的栈就是在这里建立的。

5、异常向表的地址设置问题,这个表是可以放在高地址,也可以入在低地址空间的。放在高地址还是放在低地址是由CP15的SCTRL控制,如图所示:


v=0:低地址。

v=1:高地址。

那么具体放在高地什么位置是由c12的vbar寄存器指出。


这部分uboot代码如下所示:


猜你喜欢

转载自blog.csdn.net/benjorsun/article/details/80351595
今日推荐