From 4f0b287a4aa0d948d61f5c2ef1915c4db24f30e9 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 17 Jul 2002 17:14:31 +0000 Subject: 2002-07-17 Jay Monkman * rtems/score/cpu_asm.h: Enhanced to include register offsets. * Makefile.am: Install rtems/score/cpu_asm.h. * cpu.c: Significantly enhanced including the implementation of _CPU_ISR_Get_level. * cpu_asm.S: Improved behavior of context switch and interrupt dispatching. * rtems/score/arm.h: Improved the CPU model name determination. * rtems/score/cpu.h: Improved interrupt disable/enable functions. --- cpukit/score/cpu/arm/cpu_asm.S | 119 ++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 48 deletions(-) (limited to 'cpukit/score/cpu/arm/cpu_asm.S') diff --git a/cpukit/score/cpu/arm/cpu_asm.S b/cpukit/score/cpu/arm/cpu_asm.S index dfe6212923..60c638d80a 100644 --- a/cpukit/score/cpu/arm/cpu_asm.S +++ b/cpukit/score/cpu/arm/cpu_asm.S @@ -1,8 +1,12 @@ -/* cpu_asm.s +/* + * $Id$ * * This file contains all assembly code for the ARM implementation * of RTEMS. * + * Copyright (c) 2002 by Advent Networks, Inc. + * Jay Monkman + * * COPYRIGHT (c) 2000 Canon Research Centre France SA. * Emmanuel Raguet, mailto:raguet@crf.canon.fr * @@ -13,41 +17,33 @@ */ #include +#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 ) + * void _CPU_Context_restore( run_context, heir_context ) * * This routine performs a normal non-FP context. * - * R0 = run_context R1 = heir_context - * + * R0 = run_context R1 = heir_context + * + * This function copies the current registers to where r0 points, then + * restores the ones from where r1 points. + * + * + * NOTE: The function should be able to only save/restore the registers + * that would be saved by a C function since the others have already + * been saved. + * + * It should also be able to use the stm/ldm instructions. + * */ .globl _CPU_Context_switch - _CPU_Context_switch: +/* FIXME: This should use load and store multiple instructions */ +/* Start saving context */ str r2, [r0, #REG_R2] str r3, [r0, #REG_R3] str r4, [r0, #REG_R4] @@ -57,9 +53,21 @@ _CPU_Context_switch: str r8, [r0, #REG_R8] str r9, [r0, #REG_R9] str r10, [r0, #REG_R10] + + str r11, [r0, #REG_R11] + str r12, [r0, #REG_R12] + str sp, [r0, #REG_SP] - str lr, [r0, #REG_PC] + str lr, [r0, #REG_PC] /* save LR at PC's location */ + mrs r2, cpsr + str r2, [r0, #REG_CPSR] + +/* Start restoring context */ + + ldr r2, [r1, #REG_CPSR] + msr cpsr, r2 + ldr r2, [r1, #REG_R2] ldr r3, [r1, #REG_R3] ldr r4, [r1, #REG_R4] @@ -68,25 +76,34 @@ _CPU_Context_switch: ldr r7, [r1, #REG_R7] ldr r8, [r1, #REG_R8] ldr r9, [r1, #REG_R9] - ldr r10, [r1, #REG_R10] + ldr r10, [r1, #REG_R10] + ldr r11, [r1, #REG_R11] + ldr r12, [r1, #REG_R12] + ldr sp, [r1, #REG_SP] - ldr lr, [r1, #REG_PC] + 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. + * This function copies the restores the registers from where r0 points. + * It must match _CPU_Context_switch() + * + * NOTE: The function should be able to only save/restore the registers + * that would be saved by a C function since the others have already + * been saved. + * + * It should also be able to use the stm/ldm instructions. + * */ .globl _CPU_Context_restore - _CPU_Context_restore: +/* FIXME: This should use load and store multiple instructions */ + ldr r2, [r0, #REG_CPSR] + msr cpsr, r2 - ldr r2, [r0, #REG_R2] + ldr r2, [r0, #REG_R2] ldr r3, [r0, #REG_R3] ldr r4, [r0, #REG_R4] ldr r5, [r0, #REG_R5] @@ -94,14 +111,19 @@ _CPU_Context_restore: ldr r7, [r0, #REG_R7] ldr r8, [r0, #REG_R8] ldr r9, [r0, #REG_R9] - ldr r10, [r0, #REG_R10] + ldr r10, [r0, #REG_R10] + ldr r11, [r1, #REG_R11] + ldr r12, [r1, #REG_R12] + ldr sp, [r0, #REG_SP] ldr lr, [r0, #REG_PC] mov pc, lr +/* FIXME: _Exception_Handler_Undef_Swi is untested */ .globl _Exception_Handler_Undef_Swi _Exception_Handler_Undef_Swi: +/* FIXME: This should use load and store multiple instructions */ sub r13,r13,#SIZE_REGS str r0, [r13, #REG_R0] str r1, [r13, #REG_R1] @@ -114,8 +136,8 @@ _Exception_Handler_Undef_Swi: 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 r11, [r13, #REG_R11] + str r12, [r13, #REG_R12] str sp, [r13, #REG_SP] str lr, [r13, #REG_LR] mrs r0, cpsr /* read the status */ @@ -123,7 +145,7 @@ _Exception_Handler_Undef_Swi: 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 r1, =SWI_Handler ldr lr, =_go_back_1 ldr pc,[r1] /* call handler */ _go_back_1: @@ -138,15 +160,17 @@ _go_back_1: 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 r11, [r13, #REG_R11] + ldr r12, [r13, #REG_R12] ldr sp, [r13, #REG_SP] ldr lr, [r13, #REG_LR] add r13,r13,#SIZE_REGS - movs pc,r14 /* return */ - + movs pc,r14 /* return */ + +/* FIXME: _Exception_Handler_Abort is untested */ .globl _Exception_Handler_Abort _Exception_Handler_Abort: +/* FIXME: This should use load and store multiple instructions */ sub r13,r13,#SIZE_REGS str r0, [r13, #REG_R0] str r1, [r13, #REG_R1] @@ -159,8 +183,8 @@ _Exception_Handler_Abort: 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 sp, [r13, #REG_R11] + str lr, [r13, #REG_R12] str lr, [r13, #REG_SP] str lr, [r13, #REG_LR] mrs r0, cpsr /* read the status */ @@ -183,11 +207,10 @@ _go_back_2: 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 sp, [r13, #REG_R11] + ldr lr, [r13, #REG_R12] ldr lr, [r13, #REG_SP] ldr lr, [r13, #REG_LR] add r13,r13,#SIZE_REGS subs pc,r14,#4 /* return */ - -- cgit v1.2.3