FIQ为例说明其中断处理流程

描述

1-保存环境

FIQ中断触发时, PE将异常发生时的PSTATE保存到SPSR_EL3将返回地址保存到ELR_EL3(以上是由硬件完成的) ,( pstate可能指CPU忙时的电源管理,也可能是其它的,但是肯定关于此时CPU状态的。)然后跳转到异常向量 表入口处执行中断处理流程

2-执行中断处理流程

fiq_aarch64函数主要由handle_interrupt_exception宏实现,该宏的定义如下:

该函数主要实现了

  • • 1、 异常切换时的上下文保存
  • • 2、运行时栈的切换
  • • 3、 中断处理函数查询
  • • 4、参数设置和跳转功能。

其详细流程如下:

.macro handle_interrupt_exception label
    bl save_gp_pmcr_pauth_regs1)
(1)将通用寄存器(x0x29以及sp_el0),pmcr以及pauth寄存器保存到sp_el3指定的el3栈中

#if ENABLE_PAUTH
    /* Load and program APIAKey firmware key */
    bl pauth_load_bl31_apiakey
#endif

    mrs x0, spsr_el3
    mrs x1, elr_el3
    stp x0, x1, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]2)
    (2)将spsr_el3elr_el3保存到sp_el3指定的el3栈中

    /* Switch to the runtime stack i.e. SP_EL0 */
    ldr x2, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]3)
(3)从el3栈中读取sp_el0栈指针

    mov x20, sp4)
(4)将sp_el3栈指针暂存到x20寄存器中

    msr spsel, #MODE_SP_EL05)
(5)将当前的runtime栈切换为sp_el0

    mov sp, x26)
(6)恢复sp_el0栈的值

    bl plat_ic_get_pending_interrupt_type7)
(7)读取当前中断的中断号,并根据中断号获取中断类型


    cmp x0, #INTR_TYPE_INVAL
    b.eq interrupt_exit_label8)
(8)若中断类型为非法,则直接退出中断处理


    bl get_interrupt_type_handler9)
(9)获取该中断类型对应的处理函数

    cbz x0, interrupt_exit_label10)
(10)若获取处理函数失败,则直接退出中断处理

    mov x21, x011)
(11)将中断类型处理函数指针暂存到x21寄存器中


    mov x0, #INTR_ID_UNAVAILABLE

    /* Set the current security state in the 'flags' parameter */
    mrs x2, scr_el3
    ubfx x1, x2, #0, #112)
(12)设置中断处理函数的输入参数0和参数1


    /* Restore the reference to the 'handle' i.e. SP_EL3 */
    mov x2, x2013)
(13)将sp_el3指针设置中断处理函数的输入参数2


    /* x3 will point to a cookie (not used now) */
    mov x3, xzr14)
(14)设置中断处理函数的输入参数3,该参数始终当前为0


    /* Call the interrupt type handler */
    blr x2115)
(15)跳转到中断处理函数并执行实际的中断处理


interrupt_exit_label:                                              
    /* Return from exception, possibly in a different security state */
    b el3_exit

    .endm

(1)将通用寄存器(x0 – x29以及sp_el0),pmcr以及pauth寄存器保存到sp_el3指定的el3栈中

(2)将spsr_el3和elr_el3保存到sp_el3指定的el3栈中

(3)从el3栈中读取sp_el0栈指针

(4)将sp_el3栈指针暂存到x20寄存器中

(5)将当前的runtime栈切换为sp_el0

(6)恢复sp_el0栈的值

(7)读取当前中断的中断号,并根据中断号获取中断类型

(8)若中断类型为非法,则直接退出中断处理

(9)获取该中断类型对应的处理函数

(10)若获取处理函数失败,则直接退出中断处理

(11)将中断类型处理函数指针暂存到x21寄存器中

(12)设置中断处理函数的输入参数0和参数1

(13)将sp_el3指针设置中断处理函数的输入参数2

(14)设置中断处理函数的输入参数3,该参数始终当前为0

(15)跳转到中断处理函数并执行实际的中断处理

在bl31中实际的中断处理函数有两类,group 0中断和secure group 1中断。 group 0中断由exception handler framework(ehf)管理,该框架实现了对bl31中group 0中断的注册和管理 ,当前sdei框架使用了这种中断类型。

而secure EL1中断一般是bl31为bl32接收并转发给bl32的 ,如optee在bl31中注册了一个secure el1中断处理函数opteed_sel1_interrupt_handler,该函数比较简单,只是执行了异常等级上下文切换,跳转到bl32的fiq异常处理入口,将中断处理转交给bl32。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分