summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/arm/arm_exc_handler_low.S
diff options
context:
space:
mode:
authorThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2009-07-17 15:16:50 +0000
committerThomas Doerfler <Thomas.Doerfler@embedded-brains.de>2009-07-17 15:16:50 +0000
commit9364cf663fc1dcebcc1b87cc4cec7beae5490031 (patch)
treea3788a17e3f6a72264a9bde798274805c56d9257 /cpukit/score/cpu/arm/arm_exc_handler_low.S
parentremove obsolete files (diff)
downloadrtems-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.S176
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 */