/** * @file olimex_exception_catch.S * * @section descr File description * * ARM exceptions catching. Default behavior has been choosen to * help debugging. * * @section copyright Copyright * * Trampoline OS * * Trampoline is copyright (c) IRCCyN 2005+ * Copyright ESEO for function and data structures documentation and ARM port * Trampoline is protected by the French intellectual property law. * * This software is distributed under the Lesser GNU Public Licence * * @section infos File informations * * $Date$ * $Rev$ * $Author$ * $URL$ */ #include "../tpl_asm_definitions.h" .set prefetch_abort, 1 .set data_abort, 2 .set undefined_instruction, 3 .set unused, 4 #define OS_START_SEC_VAR #include "tpl_as_memmap.h" /* containts the address of the instruction which caused exception (abort, * pfabord, undef) */ .global faulty_instruction faulty_instruction: .word 0 /* contains the CPSR value at the time of the fault (abord, pfabord, undef) */ .global saved_psr saved_psr: .word 0 /* contains the stack pointer at the time of the fault */ .global interrupted_stack_pointer interrupted_stack_pointer: .word 0 #define OS_STOP_SEC_VAR #include "tpl_as_memmap.h" #define OS_START_LTORG #include "tpl_as_memmap.h" #define OS_STOP_LTORG #include "tpl_as_memmap.h" #define OS_START_SEC_CODE #include "tpl_as_memmap.h" /* this macro locks interrupts before hanging down in a loop */ .macro lock_interrupts stmfd sp!, {r0} mrs r0, cpsr orr r0, #(CPSR_FIQ_LOCKED | CPSR_IRQ_LOCKED) msr cpsr_c, r0 ldmfd sp!, {r0} .endm /* this macro decodes some informations about an exception (abort, undef) */ .macro decode_exception exception_type stmfd sp!, {r0, r1, r2} /* get the faulty PC */ .if (\exception_type == data_abort) sub r0, lr, #8 .else sub r0, lr, #4 .endif ldr r1, =faulty_instruction str r0, [r1] /* get the faulty CPSR */ mrs r0, spsr ldr r1, =saved_psr str r0, [r1] /* get stack pointer from faulty mode */ mrs r0, cpsr /* save current mode */ mrs r1, spsr and r1, r1, #0x1f bic r2, r0, #0x1f orr r2, r2, r1 msr cpsr, r2 ldr r1, =interrupted_stack_pointer str sp, [r1] msr cpsr, r0 ldmfd sp!, {r0, r1, r2} .endm .global primary_undefined_instruction_handler primary_undefined_instruction_handler: lock_interrupts decode_exception undefined_instruction b . .global primary_prefetch_abort_handler primary_prefetch_abort_handler: lock_interrupts decode_exception prefetch_abort b . .global primary_data_abort_handler primary_data_abort_handler: lock_interrupts decode_exception data_abort b . .global primary_unused_handler primary_unused_handler: lock_interrupts decode_exception unused b . /* FIQ not defined in this port version */ .global tpl_primary_fiq_handler tpl_primary_fiq_handler: subs pc, lr, #4 #define OS_STOP_SEC_CODE #include "tpl_as_memmap.h" #define OS_START_LTORG #include "tpl_as_memmap.h" #define OS_STOP_LTORG #include "tpl_as_memmap.h" /* End of file olimx_exception_catch.S */