diff options
author | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2009-07-17 15:16:50 +0000 |
---|---|---|
committer | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2009-07-17 15:16:50 +0000 |
commit | 9364cf663fc1dcebcc1b87cc4cec7beae5490031 (patch) | |
tree | a3788a17e3f6a72264a9bde798274805c56d9257 /cpukit/score/cpu/arm/arm_exc_handler_low.S | |
parent | remove obsolete files (diff) | |
download | rtems-9364cf663fc1dcebcc1b87cc4cec7beae5490031.tar.bz2 |
adding lpc24xx BSP parts
Diffstat (limited to 'cpukit/score/cpu/arm/arm_exc_handler_low.S')
-rw-r--r-- | cpukit/score/cpu/arm/arm_exc_handler_low.S | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/cpukit/score/cpu/arm/arm_exc_handler_low.S b/cpukit/score/cpu/arm/arm_exc_handler_low.S new file mode 100644 index 0000000000..b333ef5d6a --- /dev/null +++ b/cpukit/score/cpu/arm/arm_exc_handler_low.S @@ -0,0 +1,176 @@ +/** + * @file + * + * ARM exception support code. + */ + +/* + * $Id$ + * + * Copyright (c) 2007 by Ray Xu, <Rayx.cn@gmail.com> + * Thumb support added. + * + * Copyright (c) 2002 by Advent Networks, Inc. + * Jay Monkman <jmonkman@adventnetworks.com> + * + * COPYRIGHT (c) 2000 Canon Research Centre France SA. + * Emmanuel Raguet, mailto:raguet@crf.canon.fr + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * Moved from file 'cpukit/score/cpu/arm/cpu_asm.S'. + * + */ + +#include <rtems/asm.h> +#include <rtems/score/cpu_asm.h> + +/* + * function declaration macro (start body in ARM mode) + */ +#ifdef __thumb__ + #define FUNC_START_ARM(_name_) \ + .code 16 ;\ + .thumb_func ;\ + .globl _name_ ;\ +_name_: ;\ + bx pc ;\ + .code 32 ;\ +_name_ ## _ARM: +#else + #define FUNC_START_ARM(_name_) \ + .globl _name_; \ +_name_: +#endif + + .text + +/* FIXME: _Exception_Handler_Undef_Swi is untested */ +FUNC_START_ARM(_Exception_Handler_Undef_Swi) +/* FIXME: This should use load and store multiple instructions */ + sub r13,r13,#SIZE_REGS + str r4, [r13, #REG_R4] + str r5, [r13, #REG_R5] + str r6, [r13, #REG_R6] + str r7, [r13, #REG_R7] + str r8, [r13, #REG_R8] + str r9, [r13, #REG_R9] + str r10, [r13, #REG_R10] + str r11, [r13, #REG_R11] + str sp, [r13, #REG_SP] + str lr, [r13, #REG_LR] + mrs r0, cpsr /* read the status */ + and r0, r0,#0x1f /* we keep the mode as exception number */ + str r0, [r13, #REG_PC] /* we store it in a free place */ + mov r0, r13 /* put frame address in r0 (C arg 1) */ + + ldr r1, =SWI_Handler + ldr lr, =_go_back_1 + ldr pc,[r1] /* call handler */ +_go_back_1: + ldr r4, [r13, #REG_R4] + ldr r5, [r13, #REG_R5] + ldr r6, [r13, #REG_R6] + ldr r7, [r13, #REG_R7] + ldr r8, [r13, #REG_R8] + ldr r9, [r13, #REG_R9] + ldr r10, [r13, #REG_R10] + ldr r11, [r13, #REG_R11] + ldr sp, [r13, #REG_SP] + ldr lr, [r13, #REG_LR] + add r13,r13,#SIZE_REGS + movs pc,r14 /* return */ + +/* FIXME: _Exception_Handler_Abort is untested */ +FUNC_START_ARM(_Exception_Handler_Abort) +/* FIXME: This should use load and store multiple instructions */ + sub r13,r13,#SIZE_REGS + str r4, [r13, #REG_R4] + str r5, [r13, #REG_R5] + str r6, [r13, #REG_R6] + str r7, [r13, #REG_R7] + str r8, [r13, #REG_R8] + str r9, [r13, #REG_R9] + str sp, [r13, #REG_R11] + str lr, [r13, #REG_SP] + str lr, [r13, #REG_LR] + mrs r0, cpsr /* read the status */ + and r0, r0,#0x1f /* we keep the mode as exception number */ + str r0, [r13, #REG_PC] /* we store it in a free place */ + mov r0, r13 /* put frame address in ro (C arg 1) */ + + ldr r1, =_currentExcHandler + ldr lr, =_go_back_2 + ldr pc,[r1] /* call handler */ +_go_back_2: + ldr r4, [r13, #REG_R4] + ldr r5, [r13, #REG_R5] + ldr r6, [r13, #REG_R6] + ldr r7, [r13, #REG_R7] + ldr r8, [r13, #REG_R8] + ldr r9, [r13, #REG_R9] + ldr r10, [r13, #REG_R10] + ldr sp, [r13, #REG_R11] + ldr lr, [r13, #REG_SP] + ldr lr, [r13, #REG_LR] + add r13,r13,#SIZE_REGS +#ifdef __thumb__ + subs r11, r14,#4 + bx r11 + nop +#else + subs pc,r14,#4 /* return */ +#endif + +#define ABORT_REGS_OFFS 32-REG_R4 +#define ABORT_SIZE_REGS SIZE_REGS+ABORT_REGS_OFFS + +FUNC_START_ARM(_exc_data_abort) + sub sp, sp, #ABORT_SIZE_REGS /* reserve register frame */ + stmia sp, {r0-r11} + add sp, sp, #ABORT_REGS_OFFS /* the Context_Control structure starts by CPSR, R4, ... */ + + str ip, [sp, #REG_PC] /* store R12 (ip) somewhere, oh hackery, hackery, hack */ + str lr, [sp, #REG_LR] + + mov r1, lr + ldr r0, [r1, #-8] /* r0 = bad instruction */ + mrs r1, spsr /* r1 = spsr */ + mov r2, r13 /* r2 = exception frame of Context_Control type */ +#if defined(__thumb__) + .code 32 + /*arm to thumb*/ + adr r5, to_thumb + 1 + bx r5 + .code 16 +to_thumb: +#endif + bl do_data_abort +#if defined(__thumb__) +/*back to arm*/ + .code 16 +thumb_to_arm: + .align 2 + adr r5, arm_code + bx r5 + nop + .code 32 +arm_code: +#endif + + ldr lr, [sp, #REG_LR] + ldr ip, [sp, #REG_PC] /* restore R12 (ip) */ + + sub sp, sp, #ABORT_REGS_OFFS + ldmia sp, {r0-r11} + add sp, sp, #ABORT_SIZE_REGS +#ifdef __thumb__ + subs r11, r14, #4 /* return to the instruction */ + bx r11 + nop +#else + subs pc, r14, #4 +#endif + /* _AFTER_ the aborted one */ |