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. --- c/src/exec/score/cpu/arm/ChangeLog | 11 ++ c/src/exec/score/cpu/arm/Makefile.am | 1 + c/src/exec/score/cpu/arm/cpu.c | 187 +++++++++++++++++-------- c/src/exec/score/cpu/arm/cpu_asm.S | 119 +++++++++------- c/src/exec/score/cpu/arm/rtems/score/arm.h | 34 +++-- c/src/exec/score/cpu/arm/rtems/score/cpu.h | 103 +++++++++----- c/src/exec/score/cpu/arm/rtems/score/cpu_asm.h | 76 ++++------ cpukit/score/cpu/arm/ChangeLog | 11 ++ cpukit/score/cpu/arm/Makefile.am | 1 + cpukit/score/cpu/arm/cpu.c | 187 +++++++++++++++++-------- cpukit/score/cpu/arm/cpu_asm.S | 119 +++++++++------- cpukit/score/cpu/arm/rtems/score/arm.h | 34 +++-- cpukit/score/cpu/arm/rtems/score/cpu.h | 103 +++++++++----- cpukit/score/cpu/arm/rtems/score/cpu_asm.h | 76 ++++------ 14 files changed, 648 insertions(+), 414 deletions(-) diff --git a/c/src/exec/score/cpu/arm/ChangeLog b/c/src/exec/score/cpu/arm/ChangeLog index e3499a1546..8b946f1ad2 100644 --- a/c/src/exec/score/cpu/arm/ChangeLog +++ b/c/src/exec/score/cpu/arm/ChangeLog @@ -1,3 +1,14 @@ +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. + 2002-07-05 Joel Sherrill * rtems/score/cpu.h: Filled in something that was marked XXX. diff --git a/c/src/exec/score/cpu/arm/Makefile.am b/c/src/exec/score/cpu/arm/Makefile.am index fea8733ff3..03e6e36ebf 100644 --- a/c/src/exec/score/cpu/arm/Makefile.am +++ b/c/src/exec/score/cpu/arm/Makefile.am @@ -26,6 +26,7 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE) $(include_HEADERS:%=$(PROJECT_INCLUDE)/%) include_rtems_scoredir = $(includedir)/rtems/score include_rtems_score_HEADERS = \ rtems/score/cpu.h \ + rtems/score/cpu_asm.h \ rtems/score/arm.h \ rtems/score/types.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score \ diff --git a/c/src/exec/score/cpu/arm/cpu.c b/c/src/exec/score/cpu/arm/cpu.c index ec2a8f5e5c..3ae3f5828a 100644 --- a/c/src/exec/score/cpu/arm/cpu.c +++ b/c/src/exec/score/cpu/arm/cpu.c @@ -5,6 +5,9 @@ * COPYRIGHT (c) 2000 Canon Research Centre France SA. * Emmanuel Raguet, mailto:raguet@crf.canon.fr * + * Copyright (c) 2002 Advent Networks, Inc + * Jay Monkman + * * 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. @@ -25,30 +28,32 @@ * * INPUT PARAMETERS: * cpu_table - CPU table to initialize - * thread_dispatch - address of disptaching routine + * thread_dispatch - address of ISR disptaching routine (unused) + * */ - void _CPU_Initialize( rtems_cpu_table *cpu_table, void (*thread_dispatch) /* ignored on this CPU */ ) { - _CPU_Table = *cpu_table; + _CPU_Table = *cpu_table; } -/*PAGE +/* * - * _CPU_ISR_Get_level + * _CPU_ISR_Get_level - returns the current interrupt level */ unsigned32 _CPU_ISR_Get_level( void ) { - /* - * This routine returns the current interrupt level. - */ - - return 0; + unsigned32 reg; + + asm volatile ("mrs %0, cpsr \n" \ + "and %0, %0, #0xc0 \n" \ + : "=r" (reg)); + + return reg; } /* @@ -59,28 +64,48 @@ unsigned32 _CPU_ISR_Get_level( void ) * * Input parameters: * vector - interrupt vector number - * old_handler - former ISR for this vector number * new_handler - replacement ISR for this vector number + * old_handler - pointer to store former ISR for this vector number + * + * FIXME: This vector scheme should be changed to allow FIQ to be + * handled better. I'd like to be able to put VectorTable + * elsewhere - JTM + * * * Output parameters: NONE * */ - void _CPU_ISR_install_vector( unsigned32 vector, proc_ptr new_handler, proc_ptr *old_handler ) { - /* pointer on the redirection table in RAM */ - long *VectorTable = (long *)(MAX_EXCEPTIONS * 4); - - if (old_handler != NULL) - old_handler = *(proc_ptr *)(VectorTable + vector); - *(VectorTable + vector) = (long)new_handler ; + /* pointer on the redirection table in RAM */ + long *VectorTable = (long *)(MAX_EXCEPTIONS * 4); + + if (old_handler != NULL) { + old_handler = *(proc_ptr *)(VectorTable + vector); + } + + *(VectorTable + vector) = (long)new_handler ; } +void _CPU_Context_Initialize( + Context_Control *the_context, + unsigned32 *stack_base, + unsigned32 size, + unsigned32 new_level, + void *entry_point, + boolean is_fp +) +{ + the_context->register_sp = ((unsigned32)(stack_base)) + (size) ; + the_context->register_pc = (entry_point); + the_context->register_cpsr = (new_level | 0x13); +} + /*PAGE * * _CPU_Install_interrupt_stack @@ -88,6 +113,32 @@ void _CPU_ISR_install_vector( void _CPU_Install_interrupt_stack( void ) { +/* FIXME: do something here */ +#if 0 + extern unsigned long _fiq_stack; + extern unsigned long _fiq_stack_size; + extern unsigned long _irq_stack; + extern unsigned long _irq_stack_size; + extern unsigned long _abt_stack; + extern unsigned long _abt_stack_size; + unsigned long *ptr; + int i; + + ptr = &_fiq_stack; + for (i = 0; i < ((int)&_fiq_stack_size/4); i++) { + ptr[i] = 0x13131313; + } + + ptr = &_irq_stack; + for (i = 0; i < ((int)&_irq_stack_size/4); i++) { + ptr[i] = 0xf0f0f0f0; + } + + ptr = &_abt_stack; + for (i = 0; i < ((int)&_abt_stack_size/4); i++) { + ptr[i] = 0x55555555; + } +#endif } /*PAGE @@ -110,60 +161,82 @@ void _CPU_Install_interrupt_stack( void ) void _CPU_Thread_Idle_body( void ) { - while(1); + while(1); /* FIXME: finish this */ /* insert your "halt" instruction here */ ; } void _defaultExcHandler (CPU_Exception_frame *ctx) { - printk("----------------------------------------------------------\n"); - printk("Exception %d caught at PC %x by thread %d\n", - ctx->register_pc, ctx->register_lr - 4, - _Thread_Executing->Object.id); - printk("----------------------------------------------------------\n"); - printk("Processor execution context at time of the fault was :\n"); - printk("----------------------------------------------------------\n"); - printk(" r0 = %x r1 = %x r2 = %x r3 = %x\n", - ctx->register_r0, ctx->register_r1, ctx->register_r2, ctx->register_r3); - printk(" r4 = %x r5 = %x r6 = %x r7 = %x\n", - ctx->register_r4, ctx->register_r5, ctx->register_r6, ctx->register_r7); - printk(" r8 = %x r9 = %x r10 = %x\n", - ctx->register_r8, ctx->register_r9, ctx->register_r10); - printk(" fp = %x ip = %x sp = %x pc = %x\n", - ctx->register_fp, ctx->register_ip, ctx->register_sp, ctx->register_lr - 4); - printk("----------------------------------------------------------\n"); - - if (_ISR_Nest_level > 0) { - /* - * In this case we shall not delete the task interrupted as - * it has nothing to do with the fault. We cannot return either - * because the eip points to the faulty instruction so... - */ - printk("Exception while executing ISR!!!. System locked\n"); - while(1); - } - else { - printk(" ************ FAULTY THREAD WILL BE DELETED **************\n"); - rtems_task_delete(_Thread_Executing->Object.id); - } + printk("\n\r"); + printk("----------------------------------------------------------\n\r"); + printk("Exception 0x%x caught at PC 0x%x by thread %d\n", + ctx->register_pc, ctx->register_lr - 4, + _Thread_Executing->Object.id); + printk("----------------------------------------------------------\n\r"); + printk("Processor execution context at time of the fault was :\n\r"); + printk("----------------------------------------------------------\n\r"); + printk(" r0 = %8x r1 = %8x r2 = %8x r3 = %8x\n\r", + ctx->register_r0, ctx->register_r1, + ctx->register_r2, ctx->register_r3); + printk(" r4 = %8x r5 = %8x r6 = %8x r7 = %8x\n\r", + ctx->register_r4, ctx->register_r5, + ctx->register_r6, ctx->register_r7); + printk(" r8 = %8x r9 = %8x r10 = %8x\n\r", + ctx->register_r8, ctx->register_r9, ctx->register_r10); + printk(" fp = %8x ip = %8x sp = %8x pc = %8x\n\r", + ctx->register_fp, ctx->register_ip, + ctx->register_sp, ctx->register_lr - 4); + printk("----------------------------------------------------------\n\r"); + + if (_ISR_Nest_level > 0) { + /* + * In this case we shall not delete the task interrupted as + * it has nothing to do with the fault. We cannot return either + * because the eip points to the faulty instruction so... + */ + printk("Exception while executing ISR!!!. System locked\n\r"); + while(1); + } + else { + printk("*********** FAULTY THREAD WILL BE DELETED **************\n\r"); + rtems_task_delete(_Thread_Executing->Object.id); + } } cpuExcHandlerType _currentExcHandler = _defaultExcHandler; extern void _Exception_Handler_Undef_Swi(); extern void _Exception_Handler_Abort(); - +/* FIXME: put comments here */ void rtems_exception_init_mngt() { - ISR_Level level; + ISR_Level level; _CPU_ISR_Disable(level); - _CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF, _Exception_Handler_Undef_Swi, NULL); - _CPU_ISR_install_vector(ARM_EXCEPTION_SWI, _Exception_Handler_Undef_Swi, NULL); - _CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT, _Exception_Handler_Abort , NULL); - _CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT, _Exception_Handler_Abort , NULL); - _CPU_ISR_install_vector(ARM_EXCEPTION_FIQ, _Exception_Handler_Abort , NULL); - _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _Exception_Handler_Abort , NULL); + _CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF, + _Exception_Handler_Undef_Swi, + NULL); + + _CPU_ISR_install_vector(ARM_EXCEPTION_SWI, + _Exception_Handler_Undef_Swi, + NULL); + + _CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT, + _Exception_Handler_Abort, + NULL); + + _CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT, + _Exception_Handler_Abort, + NULL); + + _CPU_ISR_install_vector(ARM_EXCEPTION_FIQ, + _Exception_Handler_Abort, + NULL); + + _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, + _Exception_Handler_Abort, + NULL); + _CPU_ISR_Enable(level); } diff --git a/c/src/exec/score/cpu/arm/cpu_asm.S b/c/src/exec/score/cpu/arm/cpu_asm.S index dfe6212923..60c638d80a 100644 --- a/c/src/exec/score/cpu/arm/cpu_asm.S +++ b/c/src/exec/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 */ - diff --git a/c/src/exec/score/cpu/arm/rtems/score/arm.h b/c/src/exec/score/cpu/arm/rtems/score/arm.h index 7994d7150b..05aed89892 100644 --- a/c/src/exec/score/cpu/arm/rtems/score/arm.h +++ b/c/src/exec/score/cpu/arm/rtems/score/arm.h @@ -1,12 +1,13 @@ -/* no_cpu.h - * - * This file is an example (i.e. "no CPU") of the file which is - * created for each CPU family port of RTEMS. +/* + * $Id$ * * * COPYRIGHT (c) 2000 Canon Research Centre France SA. * Emmanuel Raguet, mailto:raguet@crf.canon.fr * + * Copyright (c) 2002 Advent Networks, Inc. + * Jay Monkman + * * 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. @@ -28,16 +29,23 @@ extern "C" { * dependent features are present in a particular member * of the family. */ - -#if defined(__arm__) - -#define CPU_MODEL_NAME "arm" -#define ARM_HAS_FPU 0 - +#if defined(__arm9__) +# define CPU_MODEL_NAME "arm9" +# define ARM_HAS_FPU 0 +#elif defined(__arm9tdmi__) +# define CPU_MODEL_NAME "arm9tdmi" +# define ARM_HAS_FPU 0 +#elif defined(__arm7__) +# define CPU_MODEL_NAME "arm7" +# define ARM_HAS_FPU 0 +#elif defined(__arm7tdmi__) +# define CPU_MODEL_NAME "arm7tdmi" +# define ARM_HAS_FPU 0 +#elif defined(__arm__) +# define CPU_MODEL_NAME "unknown ARM" +# define ARM_HAS_FPU 0 #else - -#error "Unsupported CPU Model" - +# error "Unsupported CPU Model" #endif /* diff --git a/c/src/exec/score/cpu/arm/rtems/score/cpu.h b/c/src/exec/score/cpu/arm/rtems/score/cpu.h index 8e4afea4ed..7074d0022e 100644 --- a/c/src/exec/score/cpu/arm/rtems/score/cpu.h +++ b/c/src/exec/score/cpu/arm/rtems/score/cpu.h @@ -1,8 +1,10 @@ -/* cpu.h - * - * This include file contains information pertaining to the arm +/* + * This include file contains information pertaining to the ARM * processor. * + * COPYRIGHT (c) 2002 Advent Networks, Inc. + * Jay Monkman + * * COPYRIGHT (c) 2000 Canon Research Centre France SA. * Emmanuel Raguet, mailto:raguet@crf.canon.fr * @@ -10,8 +12,10 @@ * found in the file LICENSE in this distribution or at * http://www.OARcorp.com/rtems/license.html. * + * $Id$ */ +/* FIXME: finish commenting/cleaning up this file */ #ifndef __CPU_h #define __CPU_h @@ -43,7 +47,7 @@ extern "C" { * one subroutine call is avoided entirely.] */ -#define CPU_INLINE_ENABLE_DISPATCH FALSE +#define CPU_INLINE_ENABLE_DISPATCH TRUE /* * Should the body of the search loops in _Thread_queue_Enqueue_priority @@ -63,7 +67,7 @@ extern "C" { * necessary to strike a balance when setting this parameter. */ -#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE +#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE /* * Does RTEMS manage a dedicated interrupt stack in software? @@ -99,14 +103,14 @@ extern "C" { * * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE. * - * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and + * Only one of CPU_HAS_SOFTWARE_INTERRU * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is * possible that both are FALSE for a particular CPU. Although it * is unclear what that would imply about the interrupt processing * procedure on that CPU. */ -#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE +#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE /* * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager? @@ -118,7 +122,7 @@ extern "C" { * or CPU_INSTALL_HARDWARE_INTERRUPT_STACK is TRUE. */ -#define CPU_ALLOCATE_INTERRUPT_STACK FALSE +#define CPU_ALLOCATE_INTERRUPT_STACK TRUE /* * Does the RTEMS invoke the user's ISR with the vector number and @@ -273,8 +277,8 @@ extern "C" { */ #define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE -#define CPU_BIG_ENDIAN TRUE -#define CPU_LITTLE_ENDIAN FALSE +#define CPU_BIG_ENDIAN FALSE +#define CPU_LITTLE_ENDIAN TRUE /* * The following defines the number of bits actually used in the @@ -282,7 +286,7 @@ extern "C" { * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level(). */ -#define CPU_MODES_INTERRUPT_MASK 0x00000001 +#define CPU_MODES_INTERRUPT_MASK 0x000000c0 /* * Processor defined structures @@ -345,6 +349,7 @@ typedef struct { unsigned32 register_sp; unsigned32 register_lr; unsigned32 register_pc; + unsigned32 register_cpsr; } Context_Control; typedef struct { @@ -476,14 +481,14 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * that a "reasonable" small application should not have any problems. */ -#define CPU_STACK_MINIMUM_SIZE (1024*4) +#define CPU_STACK_MINIMUM_SIZE (1024*16) /* * CPU's worst alignment requirement for data types on a byte boundary. This * alignment does not take into account the requirements for the stack. */ -#define CPU_ALIGNMENT 8 +#define CPU_ALIGNMENT 4 /* * This number corresponds to the byte alignment requirement for the @@ -522,7 +527,7 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT. */ -#define CPU_STACK_ALIGNMENT 32 +#define CPU_STACK_ALIGNMENT 4 /* ISR handler macros */ @@ -537,14 +542,16 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * level is returned in _level. */ -#define _CPU_ISR_Disable( _level ) \ - { \ - (_level) = 0; \ - asm volatile ("MRS r0, cpsr \n" \ - "ORR r0, r0, #0xc0 \n" \ - "MSR cpsr, r0 \n" \ - : : : "r0"); \ - } +#define _CPU_ISR_Disable( _level ) \ + do { \ + int reg; \ + asm volatile ("MRS %0, cpsr \n" \ + "ORR %1, %0, #0xc0 \n" \ + "MSR cpsr, %1 \n" \ + "AND %0, %0, #0xc0 \n" \ + : "=r" (_level), "=r" (reg) \ + : "0" (_level), "1" (reg)); \ + } while (0) /* * Enable interrupts to the previous level (returned by _CPU_ISR_Disable). @@ -552,14 +559,17 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * _level is not modified. */ -#define _CPU_ISR_Enable( _level ) \ - { \ - asm volatile ("MRS r0, cpsr \n" \ - "AND r0, r0, #0xFFFFFF3F \n" \ - "MSR cpsr, r0 \n" \ - : : : "r0" ); \ - } - +#define _CPU_ISR_Enable( _level ) \ + do { \ + int reg; \ + asm volatile ("MRS %0, cpsr \n" \ + "BIC %0, %0, #0xc0 \n" \ + "ORR %0, %0, %2 \n" \ + "MSR cpsr, %0 \n" \ + : "=r" (reg) \ + : "0" (reg), "r" (_level)); \ + } while (0) + /* * This temporarily restores the interrupt to _level before immediately * disabling them again. This is used to divide long RTEMS critical @@ -567,8 +577,17 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * modified. */ -#define _CPU_ISR_Flash( _isr_cookie ) \ +#define _CPU_ISR_Flash( _level ) \ { \ + int reg1; \ + int reg2; \ + asm volatile ("MRS %0, cpsr \n" \ + "BIC %1, %0, #0xc0 \n" \ + "ORR %1, %1, %4 \n" \ + "MSR cpsr, %1 \n" \ + "MSR cpsr, %0 \n" \ + : "=r" (reg1), "=r" (reg2) \ + : "0" (reg1), "1" (reg2), "r" (_level)); \ } /* @@ -586,8 +605,16 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); #define _CPU_ISR_Set_level( new_level ) \ { \ + int reg; \ + asm volatile ("MRS %0, cpsr \n" \ + "BIC %0, %0, #0xc0 \n" \ + "ORR %0, %0, %2 \n" \ + "MSR cpsr_c, %0 \n" \ + : "=r" (reg) \ + : "0" (reg), "r" (new_level)); \ } + unsigned32 _CPU_ISR_Get_level( void ); /* end of ISR handler macros */ @@ -615,12 +642,14 @@ unsigned32 _CPU_ISR_Get_level( void ); * where the PSR contains an enable FPU bit. */ -#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \ - _isr, _entry_point, _is_fp ) \ - { \ - (_the_context)->register_sp = ((unsigned32)(_stack_base)) + (_size) ; \ - (_the_context)->register_pc = (_entry_point); \ - } +void _CPU_Context_Initialize( + Context_Control *the_context, + unsigned32 *stack_base, + unsigned32 size, + unsigned32 new_level, + void *entry_point, + boolean is_fp +); /* * This routine is responsible for somehow restarting the currently diff --git a/c/src/exec/score/cpu/arm/rtems/score/cpu_asm.h b/c/src/exec/score/cpu/arm/rtems/score/cpu_asm.h index d3342afcd0..2c13347578 100644 --- a/c/src/exec/score/cpu/arm/rtems/score/cpu_asm.h +++ b/c/src/exec/score/cpu/arm/rtems/score/cpu_asm.h @@ -1,69 +1,41 @@ /* - * cpu_asm.h + * $Id$ * - * Very loose template for an include file for the cpu_asm.? file - * if it is implemented as a ".S" file (preprocessed by cpp) instead - * of a ".s" file (preprocessed by gm4 or gasp). - * - * COPYRIGHT (c) 2000 Canon Research Centre France SA. - * Emmanuel Raguet, mailto:raguet@crf.canon.fr + * Copyright (c) 2002 by Advent Networks, Inc. + * Jay Monkman * * 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. * + * This file is the include file for cpu_asm.S + * * */ #ifndef __CPU_ASM_h #define __CPU_ASM_h -/* pull in the generated offsets */ - -#include - -/* - * Hardware General Registers - */ - -/* put something here */ - -/* - * Hardware Floating Point Registers - */ - -/* put something here */ - -/* - * Hardware Control Registers - */ - -/* put something here */ -/* - * Calling Convention - */ - -/* put something here */ - -/* - * Temporary registers - */ +/* Registers saved in context switch: */ +.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_R11, 44 +.set REG_R12, 48 +.set REG_SP, 52 +.set REG_LR, 56 +.set REG_PC, 60 +.set REG_CPSR, 64 +.set SIZE_REGS, REG_CPSR + 4 -/* put something here */ - -/* - * Floating Point Registers - SW Conventions - */ - -/* put something here */ - -/* - * Temporary floating point registers - */ - -/* put something here */ #endif - -/* end of file */ diff --git a/cpukit/score/cpu/arm/ChangeLog b/cpukit/score/cpu/arm/ChangeLog index e3499a1546..8b946f1ad2 100644 --- a/cpukit/score/cpu/arm/ChangeLog +++ b/cpukit/score/cpu/arm/ChangeLog @@ -1,3 +1,14 @@ +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. + 2002-07-05 Joel Sherrill * rtems/score/cpu.h: Filled in something that was marked XXX. diff --git a/cpukit/score/cpu/arm/Makefile.am b/cpukit/score/cpu/arm/Makefile.am index fea8733ff3..03e6e36ebf 100644 --- a/cpukit/score/cpu/arm/Makefile.am +++ b/cpukit/score/cpu/arm/Makefile.am @@ -26,6 +26,7 @@ PREINSTALL_FILES = $(PROJECT_INCLUDE) $(include_HEADERS:%=$(PROJECT_INCLUDE)/%) include_rtems_scoredir = $(includedir)/rtems/score include_rtems_score_HEADERS = \ rtems/score/cpu.h \ + rtems/score/cpu_asm.h \ rtems/score/arm.h \ rtems/score/types.h PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score \ diff --git a/cpukit/score/cpu/arm/cpu.c b/cpukit/score/cpu/arm/cpu.c index ec2a8f5e5c..3ae3f5828a 100644 --- a/cpukit/score/cpu/arm/cpu.c +++ b/cpukit/score/cpu/arm/cpu.c @@ -5,6 +5,9 @@ * COPYRIGHT (c) 2000 Canon Research Centre France SA. * Emmanuel Raguet, mailto:raguet@crf.canon.fr * + * Copyright (c) 2002 Advent Networks, Inc + * Jay Monkman + * * 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. @@ -25,30 +28,32 @@ * * INPUT PARAMETERS: * cpu_table - CPU table to initialize - * thread_dispatch - address of disptaching routine + * thread_dispatch - address of ISR disptaching routine (unused) + * */ - void _CPU_Initialize( rtems_cpu_table *cpu_table, void (*thread_dispatch) /* ignored on this CPU */ ) { - _CPU_Table = *cpu_table; + _CPU_Table = *cpu_table; } -/*PAGE +/* * - * _CPU_ISR_Get_level + * _CPU_ISR_Get_level - returns the current interrupt level */ unsigned32 _CPU_ISR_Get_level( void ) { - /* - * This routine returns the current interrupt level. - */ - - return 0; + unsigned32 reg; + + asm volatile ("mrs %0, cpsr \n" \ + "and %0, %0, #0xc0 \n" \ + : "=r" (reg)); + + return reg; } /* @@ -59,28 +64,48 @@ unsigned32 _CPU_ISR_Get_level( void ) * * Input parameters: * vector - interrupt vector number - * old_handler - former ISR for this vector number * new_handler - replacement ISR for this vector number + * old_handler - pointer to store former ISR for this vector number + * + * FIXME: This vector scheme should be changed to allow FIQ to be + * handled better. I'd like to be able to put VectorTable + * elsewhere - JTM + * * * Output parameters: NONE * */ - void _CPU_ISR_install_vector( unsigned32 vector, proc_ptr new_handler, proc_ptr *old_handler ) { - /* pointer on the redirection table in RAM */ - long *VectorTable = (long *)(MAX_EXCEPTIONS * 4); - - if (old_handler != NULL) - old_handler = *(proc_ptr *)(VectorTable + vector); - *(VectorTable + vector) = (long)new_handler ; + /* pointer on the redirection table in RAM */ + long *VectorTable = (long *)(MAX_EXCEPTIONS * 4); + + if (old_handler != NULL) { + old_handler = *(proc_ptr *)(VectorTable + vector); + } + + *(VectorTable + vector) = (long)new_handler ; } +void _CPU_Context_Initialize( + Context_Control *the_context, + unsigned32 *stack_base, + unsigned32 size, + unsigned32 new_level, + void *entry_point, + boolean is_fp +) +{ + the_context->register_sp = ((unsigned32)(stack_base)) + (size) ; + the_context->register_pc = (entry_point); + the_context->register_cpsr = (new_level | 0x13); +} + /*PAGE * * _CPU_Install_interrupt_stack @@ -88,6 +113,32 @@ void _CPU_ISR_install_vector( void _CPU_Install_interrupt_stack( void ) { +/* FIXME: do something here */ +#if 0 + extern unsigned long _fiq_stack; + extern unsigned long _fiq_stack_size; + extern unsigned long _irq_stack; + extern unsigned long _irq_stack_size; + extern unsigned long _abt_stack; + extern unsigned long _abt_stack_size; + unsigned long *ptr; + int i; + + ptr = &_fiq_stack; + for (i = 0; i < ((int)&_fiq_stack_size/4); i++) { + ptr[i] = 0x13131313; + } + + ptr = &_irq_stack; + for (i = 0; i < ((int)&_irq_stack_size/4); i++) { + ptr[i] = 0xf0f0f0f0; + } + + ptr = &_abt_stack; + for (i = 0; i < ((int)&_abt_stack_size/4); i++) { + ptr[i] = 0x55555555; + } +#endif } /*PAGE @@ -110,60 +161,82 @@ void _CPU_Install_interrupt_stack( void ) void _CPU_Thread_Idle_body( void ) { - while(1); + while(1); /* FIXME: finish this */ /* insert your "halt" instruction here */ ; } void _defaultExcHandler (CPU_Exception_frame *ctx) { - printk("----------------------------------------------------------\n"); - printk("Exception %d caught at PC %x by thread %d\n", - ctx->register_pc, ctx->register_lr - 4, - _Thread_Executing->Object.id); - printk("----------------------------------------------------------\n"); - printk("Processor execution context at time of the fault was :\n"); - printk("----------------------------------------------------------\n"); - printk(" r0 = %x r1 = %x r2 = %x r3 = %x\n", - ctx->register_r0, ctx->register_r1, ctx->register_r2, ctx->register_r3); - printk(" r4 = %x r5 = %x r6 = %x r7 = %x\n", - ctx->register_r4, ctx->register_r5, ctx->register_r6, ctx->register_r7); - printk(" r8 = %x r9 = %x r10 = %x\n", - ctx->register_r8, ctx->register_r9, ctx->register_r10); - printk(" fp = %x ip = %x sp = %x pc = %x\n", - ctx->register_fp, ctx->register_ip, ctx->register_sp, ctx->register_lr - 4); - printk("----------------------------------------------------------\n"); - - if (_ISR_Nest_level > 0) { - /* - * In this case we shall not delete the task interrupted as - * it has nothing to do with the fault. We cannot return either - * because the eip points to the faulty instruction so... - */ - printk("Exception while executing ISR!!!. System locked\n"); - while(1); - } - else { - printk(" ************ FAULTY THREAD WILL BE DELETED **************\n"); - rtems_task_delete(_Thread_Executing->Object.id); - } + printk("\n\r"); + printk("----------------------------------------------------------\n\r"); + printk("Exception 0x%x caught at PC 0x%x by thread %d\n", + ctx->register_pc, ctx->register_lr - 4, + _Thread_Executing->Object.id); + printk("----------------------------------------------------------\n\r"); + printk("Processor execution context at time of the fault was :\n\r"); + printk("----------------------------------------------------------\n\r"); + printk(" r0 = %8x r1 = %8x r2 = %8x r3 = %8x\n\r", + ctx->register_r0, ctx->register_r1, + ctx->register_r2, ctx->register_r3); + printk(" r4 = %8x r5 = %8x r6 = %8x r7 = %8x\n\r", + ctx->register_r4, ctx->register_r5, + ctx->register_r6, ctx->register_r7); + printk(" r8 = %8x r9 = %8x r10 = %8x\n\r", + ctx->register_r8, ctx->register_r9, ctx->register_r10); + printk(" fp = %8x ip = %8x sp = %8x pc = %8x\n\r", + ctx->register_fp, ctx->register_ip, + ctx->register_sp, ctx->register_lr - 4); + printk("----------------------------------------------------------\n\r"); + + if (_ISR_Nest_level > 0) { + /* + * In this case we shall not delete the task interrupted as + * it has nothing to do with the fault. We cannot return either + * because the eip points to the faulty instruction so... + */ + printk("Exception while executing ISR!!!. System locked\n\r"); + while(1); + } + else { + printk("*********** FAULTY THREAD WILL BE DELETED **************\n\r"); + rtems_task_delete(_Thread_Executing->Object.id); + } } cpuExcHandlerType _currentExcHandler = _defaultExcHandler; extern void _Exception_Handler_Undef_Swi(); extern void _Exception_Handler_Abort(); - +/* FIXME: put comments here */ void rtems_exception_init_mngt() { - ISR_Level level; + ISR_Level level; _CPU_ISR_Disable(level); - _CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF, _Exception_Handler_Undef_Swi, NULL); - _CPU_ISR_install_vector(ARM_EXCEPTION_SWI, _Exception_Handler_Undef_Swi, NULL); - _CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT, _Exception_Handler_Abort , NULL); - _CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT, _Exception_Handler_Abort , NULL); - _CPU_ISR_install_vector(ARM_EXCEPTION_FIQ, _Exception_Handler_Abort , NULL); - _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, _Exception_Handler_Abort , NULL); + _CPU_ISR_install_vector(ARM_EXCEPTION_UNDEF, + _Exception_Handler_Undef_Swi, + NULL); + + _CPU_ISR_install_vector(ARM_EXCEPTION_SWI, + _Exception_Handler_Undef_Swi, + NULL); + + _CPU_ISR_install_vector(ARM_EXCEPTION_PREF_ABORT, + _Exception_Handler_Abort, + NULL); + + _CPU_ISR_install_vector(ARM_EXCEPTION_DATA_ABORT, + _Exception_Handler_Abort, + NULL); + + _CPU_ISR_install_vector(ARM_EXCEPTION_FIQ, + _Exception_Handler_Abort, + NULL); + + _CPU_ISR_install_vector(ARM_EXCEPTION_IRQ, + _Exception_Handler_Abort, + NULL); + _CPU_ISR_Enable(level); } 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 */ - diff --git a/cpukit/score/cpu/arm/rtems/score/arm.h b/cpukit/score/cpu/arm/rtems/score/arm.h index 7994d7150b..05aed89892 100644 --- a/cpukit/score/cpu/arm/rtems/score/arm.h +++ b/cpukit/score/cpu/arm/rtems/score/arm.h @@ -1,12 +1,13 @@ -/* no_cpu.h - * - * This file is an example (i.e. "no CPU") of the file which is - * created for each CPU family port of RTEMS. +/* + * $Id$ * * * COPYRIGHT (c) 2000 Canon Research Centre France SA. * Emmanuel Raguet, mailto:raguet@crf.canon.fr * + * Copyright (c) 2002 Advent Networks, Inc. + * Jay Monkman + * * 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. @@ -28,16 +29,23 @@ extern "C" { * dependent features are present in a particular member * of the family. */ - -#if defined(__arm__) - -#define CPU_MODEL_NAME "arm" -#define ARM_HAS_FPU 0 - +#if defined(__arm9__) +# define CPU_MODEL_NAME "arm9" +# define ARM_HAS_FPU 0 +#elif defined(__arm9tdmi__) +# define CPU_MODEL_NAME "arm9tdmi" +# define ARM_HAS_FPU 0 +#elif defined(__arm7__) +# define CPU_MODEL_NAME "arm7" +# define ARM_HAS_FPU 0 +#elif defined(__arm7tdmi__) +# define CPU_MODEL_NAME "arm7tdmi" +# define ARM_HAS_FPU 0 +#elif defined(__arm__) +# define CPU_MODEL_NAME "unknown ARM" +# define ARM_HAS_FPU 0 #else - -#error "Unsupported CPU Model" - +# error "Unsupported CPU Model" #endif /* diff --git a/cpukit/score/cpu/arm/rtems/score/cpu.h b/cpukit/score/cpu/arm/rtems/score/cpu.h index 8e4afea4ed..7074d0022e 100644 --- a/cpukit/score/cpu/arm/rtems/score/cpu.h +++ b/cpukit/score/cpu/arm/rtems/score/cpu.h @@ -1,8 +1,10 @@ -/* cpu.h - * - * This include file contains information pertaining to the arm +/* + * This include file contains information pertaining to the ARM * processor. * + * COPYRIGHT (c) 2002 Advent Networks, Inc. + * Jay Monkman + * * COPYRIGHT (c) 2000 Canon Research Centre France SA. * Emmanuel Raguet, mailto:raguet@crf.canon.fr * @@ -10,8 +12,10 @@ * found in the file LICENSE in this distribution or at * http://www.OARcorp.com/rtems/license.html. * + * $Id$ */ +/* FIXME: finish commenting/cleaning up this file */ #ifndef __CPU_h #define __CPU_h @@ -43,7 +47,7 @@ extern "C" { * one subroutine call is avoided entirely.] */ -#define CPU_INLINE_ENABLE_DISPATCH FALSE +#define CPU_INLINE_ENABLE_DISPATCH TRUE /* * Should the body of the search loops in _Thread_queue_Enqueue_priority @@ -63,7 +67,7 @@ extern "C" { * necessary to strike a balance when setting this parameter. */ -#define CPU_UNROLL_ENQUEUE_PRIORITY FALSE +#define CPU_UNROLL_ENQUEUE_PRIORITY TRUE /* * Does RTEMS manage a dedicated interrupt stack in software? @@ -99,14 +103,14 @@ extern "C" { * * If this is TRUE, CPU_ALLOCATE_INTERRUPT_STACK should also be TRUE. * - * Only one of CPU_HAS_SOFTWARE_INTERRUPT_STACK and + * Only one of CPU_HAS_SOFTWARE_INTERRU * CPU_HAS_HARDWARE_INTERRUPT_STACK should be set to TRUE. It is * possible that both are FALSE for a particular CPU. Although it * is unclear what that would imply about the interrupt processing * procedure on that CPU. */ -#define CPU_HAS_HARDWARE_INTERRUPT_STACK FALSE +#define CPU_HAS_HARDWARE_INTERRUPT_STACK TRUE /* * Does RTEMS allocate a dedicated interrupt stack in the Interrupt Manager? @@ -118,7 +122,7 @@ extern "C" { * or CPU_INSTALL_HARDWARE_INTERRUPT_STACK is TRUE. */ -#define CPU_ALLOCATE_INTERRUPT_STACK FALSE +#define CPU_ALLOCATE_INTERRUPT_STACK TRUE /* * Does the RTEMS invoke the user's ISR with the vector number and @@ -273,8 +277,8 @@ extern "C" { */ #define CPU_HAS_OWN_HOST_TO_NETWORK_ROUTINES FALSE -#define CPU_BIG_ENDIAN TRUE -#define CPU_LITTLE_ENDIAN FALSE +#define CPU_BIG_ENDIAN FALSE +#define CPU_LITTLE_ENDIAN TRUE /* * The following defines the number of bits actually used in the @@ -282,7 +286,7 @@ extern "C" { * CPU interrupt levels is defined by the routine _CPU_ISR_Set_level(). */ -#define CPU_MODES_INTERRUPT_MASK 0x00000001 +#define CPU_MODES_INTERRUPT_MASK 0x000000c0 /* * Processor defined structures @@ -345,6 +349,7 @@ typedef struct { unsigned32 register_sp; unsigned32 register_lr; unsigned32 register_pc; + unsigned32 register_cpsr; } Context_Control; typedef struct { @@ -476,14 +481,14 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * that a "reasonable" small application should not have any problems. */ -#define CPU_STACK_MINIMUM_SIZE (1024*4) +#define CPU_STACK_MINIMUM_SIZE (1024*16) /* * CPU's worst alignment requirement for data types on a byte boundary. This * alignment does not take into account the requirements for the stack. */ -#define CPU_ALIGNMENT 8 +#define CPU_ALIGNMENT 4 /* * This number corresponds to the byte alignment requirement for the @@ -522,7 +527,7 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * NOTE: This must be a power of 2 either 0 or greater than CPU_ALIGNMENT. */ -#define CPU_STACK_ALIGNMENT 32 +#define CPU_STACK_ALIGNMENT 4 /* ISR handler macros */ @@ -537,14 +542,16 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * level is returned in _level. */ -#define _CPU_ISR_Disable( _level ) \ - { \ - (_level) = 0; \ - asm volatile ("MRS r0, cpsr \n" \ - "ORR r0, r0, #0xc0 \n" \ - "MSR cpsr, r0 \n" \ - : : : "r0"); \ - } +#define _CPU_ISR_Disable( _level ) \ + do { \ + int reg; \ + asm volatile ("MRS %0, cpsr \n" \ + "ORR %1, %0, #0xc0 \n" \ + "MSR cpsr, %1 \n" \ + "AND %0, %0, #0xc0 \n" \ + : "=r" (_level), "=r" (reg) \ + : "0" (_level), "1" (reg)); \ + } while (0) /* * Enable interrupts to the previous level (returned by _CPU_ISR_Disable). @@ -552,14 +559,17 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * _level is not modified. */ -#define _CPU_ISR_Enable( _level ) \ - { \ - asm volatile ("MRS r0, cpsr \n" \ - "AND r0, r0, #0xFFFFFF3F \n" \ - "MSR cpsr, r0 \n" \ - : : : "r0" ); \ - } - +#define _CPU_ISR_Enable( _level ) \ + do { \ + int reg; \ + asm volatile ("MRS %0, cpsr \n" \ + "BIC %0, %0, #0xc0 \n" \ + "ORR %0, %0, %2 \n" \ + "MSR cpsr, %0 \n" \ + : "=r" (reg) \ + : "0" (reg), "r" (_level)); \ + } while (0) + /* * This temporarily restores the interrupt to _level before immediately * disabling them again. This is used to divide long RTEMS critical @@ -567,8 +577,17 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); * modified. */ -#define _CPU_ISR_Flash( _isr_cookie ) \ +#define _CPU_ISR_Flash( _level ) \ { \ + int reg1; \ + int reg2; \ + asm volatile ("MRS %0, cpsr \n" \ + "BIC %1, %0, #0xc0 \n" \ + "ORR %1, %1, %4 \n" \ + "MSR cpsr, %1 \n" \ + "MSR cpsr, %0 \n" \ + : "=r" (reg1), "=r" (reg2) \ + : "0" (reg1), "1" (reg2), "r" (_level)); \ } /* @@ -586,8 +605,16 @@ SCORE_EXTERN void (*_CPU_Thread_dispatch_pointer)(); #define _CPU_ISR_Set_level( new_level ) \ { \ + int reg; \ + asm volatile ("MRS %0, cpsr \n" \ + "BIC %0, %0, #0xc0 \n" \ + "ORR %0, %0, %2 \n" \ + "MSR cpsr_c, %0 \n" \ + : "=r" (reg) \ + : "0" (reg), "r" (new_level)); \ } + unsigned32 _CPU_ISR_Get_level( void ); /* end of ISR handler macros */ @@ -615,12 +642,14 @@ unsigned32 _CPU_ISR_Get_level( void ); * where the PSR contains an enable FPU bit. */ -#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \ - _isr, _entry_point, _is_fp ) \ - { \ - (_the_context)->register_sp = ((unsigned32)(_stack_base)) + (_size) ; \ - (_the_context)->register_pc = (_entry_point); \ - } +void _CPU_Context_Initialize( + Context_Control *the_context, + unsigned32 *stack_base, + unsigned32 size, + unsigned32 new_level, + void *entry_point, + boolean is_fp +); /* * This routine is responsible for somehow restarting the currently diff --git a/cpukit/score/cpu/arm/rtems/score/cpu_asm.h b/cpukit/score/cpu/arm/rtems/score/cpu_asm.h index d3342afcd0..2c13347578 100644 --- a/cpukit/score/cpu/arm/rtems/score/cpu_asm.h +++ b/cpukit/score/cpu/arm/rtems/score/cpu_asm.h @@ -1,69 +1,41 @@ /* - * cpu_asm.h + * $Id$ * - * Very loose template for an include file for the cpu_asm.? file - * if it is implemented as a ".S" file (preprocessed by cpp) instead - * of a ".s" file (preprocessed by gm4 or gasp). - * - * COPYRIGHT (c) 2000 Canon Research Centre France SA. - * Emmanuel Raguet, mailto:raguet@crf.canon.fr + * Copyright (c) 2002 by Advent Networks, Inc. + * Jay Monkman * * 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. * + * This file is the include file for cpu_asm.S + * * */ #ifndef __CPU_ASM_h #define __CPU_ASM_h -/* pull in the generated offsets */ - -#include - -/* - * Hardware General Registers - */ - -/* put something here */ - -/* - * Hardware Floating Point Registers - */ - -/* put something here */ - -/* - * Hardware Control Registers - */ - -/* put something here */ -/* - * Calling Convention - */ - -/* put something here */ - -/* - * Temporary registers - */ +/* Registers saved in context switch: */ +.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_R11, 44 +.set REG_R12, 48 +.set REG_SP, 52 +.set REG_LR, 56 +.set REG_PC, 60 +.set REG_CPSR, 64 +.set SIZE_REGS, REG_CPSR + 4 -/* put something here */ - -/* - * Floating Point Registers - SW Conventions - */ - -/* put something here */ - -/* - * Temporary floating point registers - */ - -/* put something here */ #endif - -/* end of file */ -- cgit v1.2.3