linux arm 异常及中断处理过程 1 --- entry-armv.S  (注释)

内核版本  3.10.90 

arch\arm\kernel\entry-armv.S 

/*
 * Interrupt handling.
 */
    .macro    irq_handler
#ifdef CONFIG_MULTI_IRQ_HANDLER
    ldr    r1, =handle_arch_irq
    mov    r0, sp  /* 通过 svc_entry 或 usr_entry 保存后,sp 指向栈顶
                 * 已入栈的结构为 struct pt_regs ,
                 * 从而以 r0 传递中断回调函数的入参为  struct pt_regs *
                 */
    adr    lr, BSYM(9997f)
    ldr    pc, [r1]
#else
    arch_irq_handler_default
#endif
9997:
    .endm

    .macro    pabt_helper
    @ PABORT handler takes pt_regs in r2, fault address in r4 and psr in r5
#ifdef MULTI_PABORT
    ldr    ip, .LCprocfns
    mov    lr, pc
    ldr    pc, [ip, #PROCESSOR_PABT_FUNC]
#else
    bl    CPU_PABORT_HANDLER  /* 在 arch\arm\include\asm\glue-df.h 里定义 
                             * #define CPU_PABORT_HANDLER v7_pabort
                             * v7_pabort --> 
                             *   arch\arm\mm\fault.c  里的:
                             *  do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
                             */
#endif
    .endm

    .macro    dabt_helper

    @
    @ Call the processor-specific abort handler:
    @
    @  r2 - pt_regs
    @  r4 - aborted context pc
    @  r5 - aborted context psr
    @
    @ The abort handler must return the aborted address in r0, and
    @ the fault status register in r1.  r9 must be preserved.
    @
#ifdef MULTI_DABORT
    ldr    ip, .LCprocfns
    mov    lr, pc
    ldr    pc, [ip, #PROCESSOR_DABT_FUNC]
#else
    bl    CPU_DABORT_HANDLER  /* 在 arch\arm\include\asm\glue-df.h 里定义
                             * #define CPU_DABORT_HANDLER v7_early_abort
                             * 在 arch\arm\mm\abort-ev7.S 里 ENTRY(v7_early_abort) --> do_DataAbort
                             * 在 arch\arm\mm\fault.c  里:
                             * do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
                             */
#endif
    .endm

#ifdef CONFIG_KPROBES
    .section    .kprobes.text,"ax",%progbits
#else
    .text
#endif

/*
 * Invalid mode handlers
 */
    .macro    inv_entry, reason
    sub    sp, sp, #S_FRAME_SIZE
 ARM(    stmib    sp, {r1 - lr}        )
 THUMB(    stmia    sp, {r0 - r12}        )
 THUMB(    str    sp, [sp, #S_SP]        )
 THUMB(    str    lr, [sp, #S_LR]        )
    mov    r1, #\reason
    .endm

__pabt_invalid:
    inv_entry BAD_PREFETCH
    b    common_invalid
ENDPROC(__pabt_invalid)

__dabt_invalid:
    inv_entry BAD_DATA
    b    common_invalid
ENDPROC(__dabt_invalid)

__irq_invalid:
    inv_entry BAD_IRQ
    b    common_invalid
ENDPROC(__irq_invalid)

__und_invalid:
    inv_entry BAD_UNDEFINSTR

    @
    @ XXX fall through to common_invalid
    @

@
@ common_invalid - generic code for failed exception (re-entrant version of handlers)
@
common_invalid:
    zero_fp

    ldmia    r0, {r4 - r6}
    add    r0, sp, #S_PC        @ here for interlock avoidance
    mov    r7, #-1            @  ""   ""    ""        ""
    str    r4, [sp]        @ save preserved r0
    stmia    r0, {r5 - r7}        @ lr_<exception>,
                    @ cpsr_<exception>, "old_r0"

    mov    r0, sp
    b    bad_mode
ENDPROC(__und_invalid)

/*
 * SVC mode handlers
 */

#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5)
#define SPFIX(code...) code
#else
#define SPFIX(code...)
#endif

    .macro    svc_entry, stack_hole=0
 UNWIND(.fnstart        )
 UNWIND(.save {r0 - pc}        )
    sub    sp, sp, #(S_FRAME_SIZE + \stack_hole - 4) /* 相当于一次性入栈: 
                                                  * 在 arch\arm\kernel\asm-offsets.c 里,定义为:
                                                  *  DEFINE(S_FRAME_SIZE,        sizeof(struct pt_regs)); 即为18
                                                  * 此时的 sp 指向的是 sp_svc
                                                  *  当 stack_hole 为 0 时,表示入栈的大小为 18*4 - 4,
                                                  * 并不是完整的入栈 struct pt_regs ( 与 usr_entry 不相同 )
                                                  * 因为暂时不用 保存 ARM_r0 的值
                                                  * sp 指向了 ARM_r1
                                                  * 在 ptrace.h 里有:
                                                  * #define ARM_cpsr    uregs[16]
                                                  * #define ARM_pc        uregs[15]
                                                  * #define ARM_lr        uregs[14]
                                                  * #define ARM_sp        uregs[13]
                                                  * #define ARM_ip        uregs[12]
                                                  * #define ARM_fp        uregs[11]
                                                  * #define ARM_r10        uregs[10]
                                                  * #define ARM_r9        uregs[9]
                                                  * #define ARM_r8        uregs[8]
                                                  * #define ARM_r7        uregs[7]
                                                  * #define ARM_r6        uregs[6]
                                                  * #define ARM_r5        uregs[5]
                                                  * #define ARM_r4        uregs[4]
                                                  * #define ARM_r3        uregs[3]
                                                  * #define ARM_r2        uregs[2]
                                                  * #define ARM_r1        uregs[1]
                                                  * #define ARM_r0        uregs[0]
                                                  * #define ARM_ORIG_r0    uregs[17]
                                                  */
#ifdef CONFIG_THUMB2_KERNEL
 SPFIX(    str    r0, [sp]    )    @ temporarily saved
 SPFIX(    mov    r0, sp        )
 SPFIX(    tst    r0, #4        )    @ test original stack alignment
 SPFIX(    ldr    r0, [sp]    )    @ restored
#else
 SPFIX(    tst    sp, #4        )
#endif
 SPFIX(    subeq    sp, sp, #4    )
    stmia    sp, {r1 - r12} /* 入栈 r1 --- r12 ,到 ARM_r1 --- ARM_ip (uregs[12])
                            */

    ldmia    r0, {r3 - r5}   /* r0 指向的是对应异常模式下的栈 sp
                             * 在 .macro    vector_stub, name, mode, correction=0
                             * 入栈的是 r0, lr_<exception> (parent PC) and spsr_<exception>
             

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值