基于Linux2.6.30.4分析IRQ中断的处理流程。

1.中断入口

/* arch/arm/kenel/entry-armv.S*/
b    vector_irq + stubs_offset

2.vector_irq

vector_stub 宏展开即为vector_irq, 参考Linux异常体系之vector_stub宏解析

/*
 * Interrupt dispatcher
 */
    vector_stub    irq, IRQ_MODE, 4

    .long    __irq_usr            @  0  (USR_26 / USR_32)
    .long    __irq_invalid            @  1  (FIQ_26 / FIQ_32)
    .long    __irq_invalid            @  2  (IRQ_26 / IRQ_32)
    .long    __irq_svc            @  3  (SVC_26 / SVC_32)

3.__irq_user

__irq_usr:
usr_entry      /*3.1*/
kuser_cmpxchg_check

#ifdef CONFIG_TRACE_IRQFLAGS
bl    trace_hardirqs_off          
#endif
get_thread_info tsk     /*3.2*/

#ifdef CONFIG_PREEMPT
/*
*r8<--old preempt_count
*r7<--preempt_count+1
*preempt_count<--r7
*/
ldr    r8, [tsk, #TI_PREEMPT]    @ get preempt count
add    r7, r8, #1    @ increment it
str    r7, [tsk, #TI_PREEMPT]
#endif

irq_handler     /*3.3*/
#ifdef CONFIG_PREEMPT
/*
*r0<--new preempt_count
*preempt<--old preempt_count
*/
ldr    r0, [tsk, #TI_PREEMPT]
str    r8, [tsk, #TI_PREEMPT]
teq    r0, r7
strne    r0, [r0, -r0]
#endif

#ifdef CONFIG_TRACE_IRQFLAGS
bl    trace_hardirqs_on
#endif

mov why, #0
b    ret_to_user    /*3.4*/
UNWIND(.fnend    )
ENDPROC(__irq_usr)

 3.1__user_entry 

.macro    usr_entry
UNWIND(.fnstart    )
UNWIND(.cantunwind    )    @ don't unwind the user space
/* DEFINE(S_FRAME_SIZE,    sizeof(struct pt_regs));*/
sub    sp, sp, #S_FRAME_SIZE    /**/
stmib    sp, {r1 - r12}

ldmia    r0, {r1 - r3}
add    r0, sp, #S_PC    @ here for interlock avoidance
mov    r4, #-1    @ "" "" "" ""

str    r1, [sp]    @ save the "real" r0 copied
@ from the exception stack

@
@ We are now ready to fill in the remaining blanks on the stack:
@
@ r2 - lr_<exception>, already fixed up for correct return/restart
@ r3 - spsr_<exception>
@ r4 - orig_r0 (see pt_regs definition in ptrace.h)
@
@ Also, separately save sp_usr and lr_usr
@
stmia    r0, {r2 - r4}
/*“^”符号表示访问user mode的寄存器*/
stmdb    r0, {sp, lr}^

@
@ Enable the alignment trap while in kernel mode
@
alignment_trap r0

@
@ Clear FP to mark the first stack frame
@
zero_fp
.endm

 这里面用到pt_regs结构保存栈上的数据,8字节对齐

/*
 * This struct defines the way the registers are stored on the
 * stack during a system call.  Note that sizeof(struct pt_regs)
 * has to be a multiple of 8.
 */
struct pt_regs {
    long uregs[18];
};

与之相关的宏定义如下

DEFINE(S_FRAME_SIZE,        sizeof(struct pt_regs));
  
DEFINE(S_R0,            offsetof(struct pt_regs, ARM_r0));
DEFINE(S_R1,            offsetof(struct pt_regs, ARM_r1));
DEFINE(S_R2,            offsetof(struct pt_regs, ARM_r2));
DEFINE(S_R3,            offsetof(struct pt_regs, ARM_r3));
DEFINE(S_R4,            offsetof(struct pt_regs, ARM_r4));
DEFINE(S_R5,            offsetof(struct pt_regs, ARM_r5));
DEFINE(S_R6,            offsetof(struct pt_regs, ARM_r6));
DEFINE(S_R7,            offsetof(struct pt_regs, ARM_r7));
DEFINE(S_R8,            offsetof(struct pt_regs, ARM_r8));
DEFINE(S_R9,            offsetof(struct pt_regs, ARM_r9));
DEFINE(S_R10,            offsetof(struct pt_regs, ARM_r10));
DEFINE(S_FP,            offsetof(struct pt_regs, ARM_fp));
DEFINE(S_IP,            offsetof(struct pt_regs, ARM_ip));
DEFINE(S_SP,            offsetof(struct pt_regs, ARM_sp));
DEFINE(S_LR,            offsetof(struct pt_regs, ARM_lr));
DEFINE(S_PC,            offsetof(struct pt_regs, ARM_pc));
DEFINE(S_PSR,            offsetof(struct pt_regs, ARM_cpsr));
DEFINE(S_OLD_R0,        offsetof(struct pt_regs, ARM_ORIG_r0));

#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]
macos

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-10-29
  • 2021-10-17
  • 2022-12-23
  • 2021-10-11
猜你喜欢
  • 2021-12-13
  • 2021-10-12
  • 2021-06-23
  • 2021-10-29
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案