/* cpu_asm.s * * This file contains all assembly code for the ARM implementation * of RTEMS. * * 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.OARcorp.com/rtems/license.html. * */ #include /* * Format of ARM Register structure */ .set REG_R0, 0 .set REG_R1, 4 .set REG_R2, 8 .set REG_R3, 12 .set REG_R4, 16 .set REG_R5, 20 .set REG_R6, 24 .set REG_R7, 28 .set REG_R8, 32 .set REG_R9, 36 .set REG_R10, 40 .set REG_FP, 44 .set REG_IP, 48 .set REG_SP, 52 .set REG_LR, 56 .set REG_PC, 60 .set SIZE_REGS, REG_PC + 4 /* * void _CPU_Context_switch( run_context, heir_context ) * * This routine performs a normal non-FP context. * * R0 = run_context R1 = heir_context * */ .globl _CPU_Context_switch _CPU_Context_switch: str r2, [r0, #REG_R2] str r3, [r0, #REG_R3] str r4, [r0, #REG_R4] str r5, [r0, #REG_R5] str r6, [r0, #REG_R6] str r7, [r0, #REG_R7] str r8, [r0, #REG_R8] str r9, [r0, #REG_R9] str r10, [r0, #REG_R10] str sp, [r0, #REG_SP] str lr, [r0, #REG_PC] ldr r2, [r1, #REG_R2] ldr r3, [r1, #REG_R3] ldr r4, [r1, #REG_R4] ldr r5, [r1, #REG_R5] ldr r6, [r1, #REG_R6] ldr r7, [r1, #REG_R7] ldr r8, [r1, #REG_R8] ldr r9, [r1, #REG_R9] ldr r10, [r1, #REG_R10] ldr sp, [r1, #REG_SP] ldr lr, [r1, #REG_PC] mov pc, lr /* * NOTE: May be unnecessary to reload some registers. */ /* * void _CPU_Context_restore( new_context ) * * This routine performs a normal non-FP context. */ .globl _CPU_Context_restore _CPU_Context_restore: ldr r2, [r0, #REG_R2] ldr r3, [r0, #REG_R3] ldr r4, [r0, #REG_R4] ldr r5, [r0, #REG_R5] ldr r6, [r0, #REG_R6] ldr r7, [r0, #REG_R7] ldr r8, [r0, #REG_R8] ldr r9, [r0, #REG_R9] ldr r10, [r0, #REG_R10] ldr sp, [r0, #REG_SP] ldr lr, [r0, #REG_PC] mov pc, lr .globl _Exception_Handler_Undef_Swi _Exception_Handler_Undef_Swi: sub r13,r13,#SIZE_REGS str r0, [r13, #REG_R0] str r1, [r13, #REG_R1] str r2, [r13, #REG_R2] str r3, [r13, #REG_R3] 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 fp, [r13, #REG_FP] str ip, [r13, #REG_IP] 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, =_currentExcHandler ldr lr, =_go_back_1 ldr pc,[r1] /* call handler */ _go_back_1: ldr r0, [r13, #REG_R0] ldr r1, [r13, #REG_R1] ldr r2, [r13, #REG_R2] ldr r3, [r13, #REG_R3] 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 fp, [r13, #REG_FP] ldr ip, [r13, #REG_IP] ldr sp, [r13, #REG_SP] ldr lr, [r13, #REG_LR] add r13,r13,#SIZE_REGS movs pc,r14 /* return */ .globl _Exception_Handler_Abort _Exception_Handler_Abort: sub r13,r13,#SIZE_REGS str r0, [r13, #REG_R0] str r1, [r13, #REG_R1] str r2, [r13, #REG_R2] str r3, [r13, #REG_R3] 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 sp, [r13, #REG_FP] str lr, [r13, #REG_IP] 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 r0, [r13, #REG_R0] ldr r1, [r13, #REG_R1] ldr r2, [r13, #REG_R2] ldr r3, [r13, #REG_R3] 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_FP] ldr lr, [r13, #REG_IP] ldr lr, [r13, #REG_SP] ldr lr, [r13, #REG_LR] add r13,r13,#SIZE_REGS subs pc,r14,#4 /* return */