请教uclinux+arm的IRQ中断处理过程中的问题
各位高手:
大家好!我是一名学习linux的新手.所以还有很多问题要请教大家!急盼大家帮忙!!!
最近,我在学习uclinux+arm的IRQ中断处理过程的源代码中,遇到这么一个问题,百思不得其解.
当IRQ中断发生后,cpu一定会跳到/linux/arch/arm/kernel/entry-armv.S中的vector_IRQ处执行.
vector_IRQ: @
@ save mode specific registers
@
ldr r13, .LCsirq
sub lr, lr, #4
str lr, [r13] @ save lr_IRQ
mrs lr, spsr
str lr, [r13, #4] @ save spsr_IRQ
@
@ now branch to the relevent MODE handling routine
@
mov r13, #I_BIT | MODE_SVC
msr spsr_c, r13 @ switch to SVC_32 mode
and lr, lr, #15
ldr lr, [pc, lr, lsl #2]
movs pc, lr @ Changes mode and branches
.LCtab_irq: .word __irq_usr @ 0 (USR_26 / USR_32)
.word __irq_invalid @ 1 (FIQ_26 / FIQ_32)
.word __irq_invalid @ 2 (IRQ_26 / IRQ_32)
.word __irq_svc @ 3 (SVC_26 / SVC_32)
.word __irq_invalid @ 4
.word __irq_invalid @ 5
.word __irq_invalid @ 6
.word __irq_invalid @ 7
.word __irq_invalid @ 8
.word __irq_invalid @ 9
.word __irq_invalid @ a
.word __irq_invalid @ b
.word __irq_invalid @ c
.word __irq_invalid @ d
.word __irq_invalid @ e
.word __irq_invalid @ f
.align 5
在这里,cpu将根据中断发生前其所处的运行模式来选择哪个子程序执行.我们假设原来在用户模式(usr),则cpu将跳转到__irq_usr出执行.
__irq_usr: sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ save r0 - r12
ldr r4, .LCirq
add r8, sp, #S_PC
ldmia r4, {r5 - r7} @ get saved PC, SPSR
stmia r8, {r5 - r7} @ save pc, psr, old_r0
stmdb r8, {sp, lr}^
alignment_trap r4, r7, __temp_irq
zero_fp
1: get_irqnr_and_base r0, r6, r5, lr @获得优先级最高的中断号到r0
movne r1, sp @将当前堆栈指针赋给r1
adrsvc ne, lr, 1b @通过设置lr,使实现了对中断的串行处理
@
@ routine called with r0 = irq number, r1 = struct pt_regs *
@
bne do_IRQ
mov why, #0
get_current_task tsk
b ret_to_user
问题出在这里:在vector_IRQ最后将mov r13, #I_BIT | MODE_SVC,即r13=#I_BIT | MODE_SVC(常数).而紧接着在__irq_usr中马上又sub sp, sp, #S_FRAME_SIZE,即r13=r13 - #S_FRAME_SIZE.
这样不是将堆栈指针混乱了吗?当嵌套中断发生时,必将因堆栈指针是常数而混乱.除非,sp和r13不是指同一个寄存器,但是又没有进行模式转换呀.这到底是怎么回事?请大家指教!!!!!!!!!!万分感谢!!!!!!急盼!