diff options
Diffstat (limited to 'main/cpu/arm/vectors_arm.S')
-rw-r--r-- | main/cpu/arm/vectors_arm.S | 79 |
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 + |