summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu/arm/arm_exc_abort.S
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/cpu/arm/arm_exc_abort.S')
-rw-r--r--cpukit/score/cpu/arm/arm_exc_abort.S123
1 files changed, 123 insertions, 0 deletions
diff --git a/cpukit/score/cpu/arm/arm_exc_abort.S b/cpukit/score/cpu/arm/arm_exc_abort.S
new file mode 100644
index 0000000000..906dcbb9f1
--- /dev/null
+++ b/cpukit/score/cpu/arm/arm_exc_abort.S
@@ -0,0 +1,123 @@
+/**
+ * @file
+ *
+ * @ingroup arm
+ *
+ * @brief ARM data and prefetch abort exception prologue and epilogue.
+ */
+
+/*
+ * Copyright (c) 2009
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * D-82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * 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.
+ */
+
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
+
+.extern rtems_fatal_error_occurred
+
+.globl arm_exc_data_abort_set_handler
+.globl arm_exc_data_abort
+
+.globl arm_exc_prefetch_abort_set_handler
+.globl arm_exc_prefetch_abort
+
+.section ".bss"
+
+data_abort_handler:
+.long 0
+
+prefetch_abort_handler:
+.long 0
+
+.section ".text"
+
+#ifdef __thumb__
+ .thumb_func
+#endif
+
+arm_exc_data_abort_set_handler:
+ ldr r1, =data_abort_handler
+ str r0, [r1]
+ bx lr
+
+#ifdef __thumb__
+ .thumb_func
+#endif
+
+arm_exc_prefetch_abort_set_handler:
+ ldr r1, =prefetch_abort_handler
+ str r0, [r1]
+ bx lr
+
+.arm
+
+arm_exc_prefetch_abort:
+
+ /* Save context and load handler */
+ sub sp, #16
+ stmdb sp!, {r0-r12}
+ ldr r6, =prefetch_abort_handler
+
+ b save_more_context
+
+arm_exc_data_abort:
+
+ /* Save context and load handler */
+ sub sp, #16
+ stmdb sp!, {r0-r12}
+ ldr r6, =data_abort_handler
+
+save_more_context:
+
+ /* Save more context */
+ mov r2, lr
+ mrs r3, spsr
+ mrs r4, cpsr
+ orr r5, r3, #ARM_PSR_I
+ bic r5, #ARM_PSR_T
+ msr cpsr, r5
+ mov r0, sp
+ mov r1, lr
+ msr cpsr, r4
+ add r5, sp, #68
+ stmdb r5!, {r0-r3}
+
+ /* Call high level handler */
+ ldr r2, [r6]
+ cmp r2, #0
+ ldreq r2, =rtems_fatal_error_occurred
+ movne r0, sp
+ moveq r0, #0xaa
+#ifndef __thumb__
+ mov lr, pc
+ bx r2
+#else /* __thumb__ */
+ SWITCH_FROM_ARM_TO_THUMB r1
+ bl call_handler
+ SWITCH_FROM_THUMB_TO_ARM
+#endif /* __thumb__ */
+
+ /* Restore context */
+ ldmia r5!, {r0-r3}
+ mov lr, r2
+ msr spsr, r3
+ ldmia sp!, {r0-r12}
+ add sp, #16
+
+ /* Return from interrupt */
+ subs pc, lr, #8
+
+#ifdef __thumb__
+.thumb
+call_handler:
+ bx r2
+#endif /* __thumb__ */