summaryrefslogtreecommitdiffstats
path: root/main/cpu/arm/vectors_arm.S
diff options
context:
space:
mode:
Diffstat (limited to 'main/cpu/arm/vectors_arm.S')
-rw-r--r--main/cpu/arm/vectors_arm.S79
1 files changed, 59 insertions, 20 deletions
diff --git a/main/cpu/arm/vectors_arm.S b/main/cpu/arm/vectors_arm.S
index 54d9ef2..128c4ac 100644
--- a/main/cpu/arm/vectors_arm.S
+++ b/main/cpu/arm/vectors_arm.S
@@ -27,39 +27,78 @@
*
*/
+#define _ASSEMBLY_ 1
+
#include "arm.h"
+#define MORE_CONTEXT_SIZE \
+ (ARM_EXCEPTION_FRAME_SIZE - ARM_EXCEPTION_FRAME_REGISTER_SP_OFFSET)
+
+#define EXCEPTIONSAVE(n) \
+ sub sp, #MORE_CONTEXT_SIZE ; \
+ stmdb sp!, {r0-r12} ; \
+ mov r4, #(n) ; \
+ ; \
+ b save_more_context ; \
+
.global undefined_instruction
+.global software_interrupt
+.global abort_prefetch
+.global abort_data
+.global not_assigned
+.global interrupt_request
+.global fast_interrupt_request
+
undefined_instruction:
-mov r1, #EXCTYPE_UNDEF
-b umon_exception
+EXCEPTIONSAVE(EXCTYPE_UNDEF)
-.global software_interrupt
software_interrupt:
-mov r1, #EXCTYPE_SWI
-b umon_exception
+EXCEPTIONSAVE(EXCTYPE_SWI)
-.global abort_prefetch
abort_prefetch:
-mov r1, #EXCTYPE_ABORTP
-b umon_exception
+EXCEPTIONSAVE(EXCTYPE_ABORTP)
-.global abort_data
abort_data:
-mov r1, #EXCTYPE_ABORTD
-b umon_exception
+EXCEPTIONSAVE(EXCTYPE_ABORTD)
-.global not_assigned
not_assigned:
-mov r1, #EXCTYPE_NOTASSGN
-b umon_exception
+EXCEPTIONSAVE(EXCTYPE_NOTASSGN)
-.global interrupt_request
interrupt_request:
-mov r1, #EXCTYPE_IRQ
-b umon_exception
+EXCEPTIONSAVE(EXCTYPE_IRQ)
-.global fast_interrupt_request
fast_interrupt_request:
-mov r1, #EXCTYPE_FIRQ
-b umon_exception
+EXCEPTIONSAVE(EXCTYPE_FIRQ)
+
+/* This code gratefully taken from RTEMS */
+
+save_more_context:
+ /* Save more context */
+ mov r2, lr
+ mrs r3, spsr
+ mrs r7, cpsr
+ orr r5, r3, #ARM_PSR_I
+ bic r5, #ARM_PSR_T
+ msr cpsr, r5
+ mov r0, sp
+ mov r1, lr
+ msr cpsr, r7
+ mov r5, #0
+ add r6, sp, #ARM_EXCEPTION_FRAME_REGISTER_SP_OFFSET
+ stm r6, {r0-r5}
+
+ /* Argument for high level handler */
+ mov r0, sp
+
+ /* Clear VFP context pointer */
+ add r3, sp, #ARM_EXCEPTION_FRAME_VFP_CONTEXT_OFFSET
+ mov r1, #0
+ str r1, [r3]
+
+ /* Call high level handler */
+ b umon_exception
+
+ /* Just in case */
+twiddle:
+ b twiddle
+