-
-/*
- *************************************************************************
- *
- * Interrupt handling
- *
- *************************************************************************
- */
-
-@
-@ IRQ stack frame.
-@
-#define S_FRAME_SIZE 72
-
-#define S_OLD_R0 68
-#define S_PSR 64
-#define S_PC 60
-#define S_LR 56
-#define S_SP 52
-
-#define S_IP 48
-#define S_FP 44
-#define S_R10 40
-#define S_R9 36
-#define S_R8 32
-#define S_R7 28
-#define S_R6 24
-#define S_R5 20
-#define S_R4 16
-#define S_R3 12
-#define S_R2 8
-#define S_R1 4
-#define S_R0 0
-
-#define MODE_SVC 0x13
-#define I_BIT 0x80
-
-/*
- * use bad_save_user_regs for abort/prefetch/undef/swi ...
- * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
- */
-
- .macro bad_save_user_regs
- sub sp, sp, #S_FRAME_SIZE
- stmia sp, {r0 - r12} @ Calling r0-r12
-#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
- ldr r2, _armboot_start
- sub r2, r2, #(CONFIG_STACKSIZE)
- sub r2, r2, #(CONFIG_SYS_MALLOC_LEN)
- /* set base 2 words into abort stack */
- sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)
-#else
- ldr r2, IRQ_STACK_START_IN
-#endif
- ldmia r2, {r2 - r3} @ get pc, cpsr
- add r0, sp, #S_FRAME_SIZE @ restore sp_SVC
-
- add r5, sp, #S_SP
- mov r1, lr
- stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
- mov r0, sp
- .endm
-
- .macro irq_save_user_regs
- sub sp, sp, #S_FRAME_SIZE
- stmia sp, {r0 - r12} @ Calling r0-r12
- add r7, sp, #S_PC
- stmdb r7, {sp, lr}^ @ Calling SP, LR
- str lr, [r7, #0] @ Save calling PC
- mrs r6, spsr
- str r6, [r7, #4] @ Save CPSR
- str r0, [r7, #8] @ Save OLD_R0
- mov r0, sp
- .endm
-
- .macro irq_restore_user_regs
- ldmia sp, {r0 - lr}^ @ Calling r0 - lr
- mov r0, r0
- ldr lr, [sp, #S_PC] @ Get PC
- add sp, sp, #S_FRAME_SIZE
- /* return & move spsr_svc into cpsr */
- subs pc, lr, #4
- .endm
-
- .macro get_bad_stack
-#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
- ldr r13, _armboot_start @ setup our mode stack
- sub r13, r13, #(CONFIG_STACKSIZE)
- sub r13, r13, #(CONFIG_SYS_MALLOC_LEN)
- /* reserve a couple spots in abort stack */
- sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8)
-#else
- ldr r13, IRQ_STACK_START_IN @ setup our mode stack
-#endif
-
- str lr, [r13] @ save caller lr / spsr
- mrs lr, spsr
- str lr, [r13, #4]
-
- mov r13, #MODE_SVC @ prepare SVC-Mode
- @ msr spsr_c, r13
- msr spsr, r13
- mov lr, pc
- movs pc, lr
- .endm
-
- .macro get_irq_stack @ setup IRQ stack
- ldr sp, IRQ_STACK_START
- .endm
-
- .macro get_fiq_stack @ setup FIQ stack
- ldr sp, FIQ_STACK_START
- .endm
-
-/*
- * exception handlers
- */
- .align 5
-undefined_instruction:
- get_bad_stack
- bad_save_user_regs
- bl do_undefined_instruction
-
- .align 5
-software_interrupt:
- get_bad_stack
- bad_save_user_regs
- bl do_software_interrupt
-
- .align 5
-prefetch_abort:
- get_bad_stack
- bad_save_user_regs
- bl do_prefetch_abort
-
- .align 5
-data_abort:
- get_bad_stack
- bad_save_user_regs
- bl do_data_abort
-
- .align 5
-not_used:
- get_bad_stack
- bad_save_user_regs
- bl do_not_used
-
-#ifdef CONFIG_USE_IRQ
-
- .align 5
-irq:
- get_irq_stack
- irq_save_user_regs
- bl do_irq
- irq_restore_user_regs
-
- .align 5
-fiq:
- get_fiq_stack
- /* someone ought to write a more effiction fiq_save_user_regs */
- irq_save_user_regs
- bl do_fiq
- irq_restore_user_regs
-
-#else
-
- .align 5
-irq:
- get_bad_stack
- bad_save_user_regs
- bl do_irq
-
- .align 5
-fiq:
- get_bad_stack
- bad_save_user_regs
- bl do_fiq
-
-#endif