/* ARM System Developer's Guide, Chapter 9 Section 1 (y. 2004-2008) (page 323) */ .data und_msg: .string "Undefined Instruction" swi_msg: .string "Hello. I am the sample SWI handler! =)" prefetch_abt_msg: .string "Prefetch Abort" data_abt_msg: .string "Data Abort @ " irq_msg: .string "IRQ" fiq_msg: .string "FIQ" .text .balign 32 .global vectab vectab: ldr pc, =panic ldr pc, =und_handler ldr pc, =swi_handler ldr pc, =prefetch_abt_handler ldr pc, =data_abt_handler nop ldr pc, =irq_handler ldr pc, =fiq_handler und_handler: stmfd sp!, {lr} ldr r0, =und_msg bl printkl ldmfd sp!, {pc}^ swi_handler: stmfd sp!, {r0-r12, lr} /* Get SWI number to pass to c_swi_handler */ ldr r10, [lr, #-4] and r10, #0x00ffffff mov r0, r10 mov r1, sp mrs r2, spsr stmfd sp!, {r2} bl c_swi_handler ldmfd sp!, {r2} msr spsr_cxsf, r2 ldmfd sp!, {r0-r12, pc}^ // TODO: untested prefetch_abt_handler: sub lr, #4 stmfd sp!, {lr} ldr r0, =prefetch_abt_msg bl printkl ldmfd sp!, {pc}^ data_abt_handler: sub lr, #8 stmfd sp!, {lr} ldr r0, =data_abt_msg bl printk ldmfd sp!, {r0} bl itoa bl printkl b panic ldmfd sp!, {pc}^ irq_handler: // mask FIQ (IRQ already masked by hardware when entering IRQ mode) cpsid f // Prepare return address and store context on stack sub lr, #0x4 stmfd sp!, {r0-r12, lr} // Acknoweledge interrupt ldr r10, =0x01c8200c // IAR ldr r0, [r10] push {r0} // Complex handlers in C++ bl c_irq_handler // Send End of Interrupt pop {r0} ldr r10, =0x01c82010 // EOIR address mov r1, #1023 // check for spurious interrupt cmp r0, r1 strne r0, [r10] // ack interrupt only if not spurious (see GICC_EOIR) // Reload context from stack // and also restore CPSR from SPSR (that caret) ldmfd sp!, {r0-r12, pc}^ // TODO: untested fiq_handler: stmfd sp!, {lr} ldr r0, =fiq_msg bl printkl ldmfd sp!, {pc}^