From bc5fc7a6f4623848fabba8dcb325db3d731d9f4a Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 12 Oct 2001 17:40:22 +0000 Subject: 2001-10-12 Alexandra Kossovsky * cpu.c, rtems/score/cpu.h, rtems/score/sh.h: Modified to support SH4. Reviewed by Ralf Corsepius who did the original SH port. --- c/src/exec/score/cpu/sh/ChangeLog | 6 +++ c/src/exec/score/cpu/sh/cpu.c | 25 +++++++++++ c/src/exec/score/cpu/sh/rtems/score/cpu.h | 61 ++++++++++++++++++++++++--- c/src/exec/score/cpu/sh/rtems/score/sh.h | 70 ++++++++++++++++++++++++++----- cpukit/score/cpu/sh/ChangeLog | 6 +++ cpukit/score/cpu/sh/cpu.c | 25 +++++++++++ cpukit/score/cpu/sh/rtems/score/cpu.h | 61 ++++++++++++++++++++++++--- cpukit/score/cpu/sh/rtems/score/sh.h | 70 ++++++++++++++++++++++++++----- 8 files changed, 292 insertions(+), 32 deletions(-) diff --git a/c/src/exec/score/cpu/sh/ChangeLog b/c/src/exec/score/cpu/sh/ChangeLog index b536b0d6a8..e743a074bc 100644 --- a/c/src/exec/score/cpu/sh/ChangeLog +++ b/c/src/exec/score/cpu/sh/ChangeLog @@ -1,3 +1,9 @@ +2001-10-12 Alexandra Kossovsky + + * cpu.c, rtems/score/cpu.h, rtems/score/sh.h: Modified to + support SH4. Reviewed by Ralf Corsepius + who did the original SH port. + 2001-10-11 Ralf Corsepius * .cvsignore: Add autom4te.cache for autoconf > 2.52. diff --git a/c/src/exec/score/cpu/sh/cpu.c b/c/src/exec/score/cpu/sh/cpu.c index eaebb46ac7..b63be7c4c2 100644 --- a/c/src/exec/score/cpu/sh/cpu.c +++ b/c/src/exec/score/cpu/sh/cpu.c @@ -29,6 +29,10 @@ #include #include +/* FIXME: This should not be here */ +#if defined(__SH4__) +#include +#endif /* referenced in start.S */ extern proc_ptr vectab[] ; @@ -75,6 +79,14 @@ void _CPU_Initialize( */ /* FP context initialization support goes here */ + /* FIXME: When not to use SH4_FPSCR_PR ? */ +#ifdef __SH4__ + _CPU_Null_fp_context.fpscr = SH4_FPSCR_DN | SH4_FPSCR_RM | SH4_FPSCR_PR; +#endif +#ifdef __SH3E__ + /* FIXME: Wild guess :) */ + _CPU_Null_fp_context.fpscr = SH4_FPSCR_DN | SH4_FPSCR_RM; +#endif _CPU_Table = *cpu_table; @@ -151,6 +163,7 @@ void _CPU_ISR_install_raw_handler( * */ +#if defined(sh1) || defined(sh2) void _CPU_ISR_install_vector( unsigned32 vector, proc_ptr new_handler, @@ -230,6 +243,18 @@ void _CPU_Context_Initialize( int _is_fp ) { _the_context->r15 = (unsigned32*) ((unsigned32) (_stack_base) + (_size) ); +#if defined(__sh1__) || defined(__sh2__) _the_context->sr = (_isr << 4) & 0x00f0 ; +#else + _the_context->sr = SH4_SR_MD | ((_isr << 4) & 0x00f0); +#endif _the_context->pr = (unsigned32*) _entry_point ; + + +#if 0 && SH_HAS_FPU + /* Disable FPU if it is non-fp task */ + if(!_is_fp) + _the_context->sr |= SH4_SR_FD; +#endif } + diff --git a/c/src/exec/score/cpu/sh/rtems/score/cpu.h b/c/src/exec/score/cpu/sh/rtems/score/cpu.h index 601276f45e..16777170db 100644 --- a/c/src/exec/score/cpu/sh/rtems/score/cpu.h +++ b/c/src/exec/score/cpu/sh/rtems/score/cpu.h @@ -34,6 +34,9 @@ extern "C" { #ifndef ASM #include #endif +#if 0 && defined(__SH4__) +#include +#endif /* conditional compilation parameters */ @@ -131,8 +134,13 @@ extern "C" { * an i387 and wish to leave floating point support out of RTEMS. */ -#define CPU_HARDWARE_FP FALSE -#define CPU_SOFTWARE_FP FALSE +#if SH_HAS_FPU +/* FIXME: What about CPU_SOFTWARE_FP ? */ +#define CPU_HARDWARE_FP TRUE +#else +#define CPU_SOFTWARE_FP FALSE +#define CPU_HARDWARE_FP FALSE +#endif /* * Are all tasks RTEMS_FLOATING_POINT tasks implicitly? @@ -150,7 +158,11 @@ extern "C" { * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well. */ +#if SH_HAS_FPU +#define CPU_ALL_TASKS_ARE_FP TRUE +#else #define CPU_ALL_TASKS_ARE_FP FALSE +#endif /* * Should the IDLE task have a floating point context? @@ -164,7 +176,11 @@ extern "C" { * must be saved as part of the preemption. */ +#if SH_HAS_FPU +#define CPU_IDLE_TASK_IS_FP TRUE +#else #define CPU_IDLE_TASK_IS_FP FALSE +#endif /* * Should the saving of the floating point registers be deferred @@ -192,7 +208,14 @@ extern "C" { * be saved or restored. */ -#define CPU_USE_DEFERRED_FP_SWITCH TRUE +#if SH_HAS_FPU +#define CPU_USE_DEFERRED_FP_SWITCH FALSE +#else +/* FIXME: Is this needed? + * Only here for backward compatibility with previous versions + */ +#define CPU_USE_DEFERRED_FP_SWITCH TRUE +#endif /* * Does this port provide a CPU dependent IDLE task implementation? @@ -355,6 +378,20 @@ typedef struct { } Context_Control; typedef struct { +#if SH_HAS_FPU +#ifdef SH4_USE_X_REGISTERS + union { + float f[16]; + double d[8]; + } x; +#endif + union { + float f[16]; + double d[8]; + } r; + float fpul; /* fp communication register */ + unsigned32 fpscr; /* fp control register */ +#endif /* SH_HAS_FPU */ } Context_Control_fp; typedef struct { @@ -400,9 +437,9 @@ typedef struct { * _CPU_Context_Initialize. */ -/* +#if SH_HAS_FPU SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context; -*/ +#endif /* * On some CPUs, RTEMS supports a software managed interrupt stack. @@ -478,8 +515,12 @@ SCORE_EXTERN void CPU_delay( unsigned32 microseconds ); * CPU's worst alignment requirement for data types on a byte boundary. This * alignment does not take into account the requirements for the stack. */ - +#if defined(__SH4__) +/* FIXME: sh3 and SH3E? */ +#define CPU_ALIGNMENT 8 +#else #define CPU_ALIGNMENT 4 +#endif /* * This number corresponds to the byte alignment requirement for the @@ -654,8 +695,15 @@ SCORE_EXTERN void _CPU_Context_Initialize( * SH1, SH2, SH3 have no FPU, but the SH3e and SH4 have. */ +#if SH_HAS_FPU +#define _CPU_Context_Initialize_fp( _destination ) \ + do { \ + *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context;\ + } while(0) +#else #define _CPU_Context_Initialize_fp( _destination ) \ { } +#endif /* end of Context handler macros */ @@ -678,6 +726,7 @@ SCORE_EXTERN void _CPU_Context_Initialize( #define _CPU_Fatal_halt( _error)\ { \ asm volatile("mov.l %0,r0"::"m" (_error)); \ + asm volatile("mov #1, r4"); \ asm volatile("trapa #34"); \ } #endif diff --git a/c/src/exec/score/cpu/sh/rtems/score/sh.h b/c/src/exec/score/cpu/sh/rtems/score/sh.h index 2834ea6c64..1ad5b564f4 100644 --- a/c/src/exec/score/cpu/sh/rtems/score/sh.h +++ b/c/src/exec/score/cpu/sh/rtems/score/sh.h @@ -38,30 +38,40 @@ extern "C" { * It does this by setting variables to indicate which implementation * dependent features are present in a particular member of the family. */ - -#if defined(rtems_multilib) /* * Figure out all CPU Model Feature Flags based upon compiler * predefines. */ -#define CPU_MODEL_NAME "rtems_multilib" -#define SH_HAS_FPU 0 -#define SH_HAS_SEPARATE_STACKS 1 +#if defined(__SH3E__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) +/* + * Define this if you want to use XD-registers. + * Then this registers will be saved/restored on context switch. + * ! They will not be saved/restored on interrupts! + */ +#define SH4_USE_X_REGISTERS 0 + +#if defined(__LITTLE_ENDIAN__) +#define SH_HAS_FPU 1 #else +/* FIXME: Context_Control_fp does not support big endian */ +#warning FPU not supported +#define SH_HAS_FPU 0 +#endif -#if defined(__sh1__) || defined(__sh2__) || defined(__sh3__) -#define SH_HAS_FPU 0 +#elif defined(__sh1__) || defined(__sh2__) || defined(__sh3__) +#define SH_HAS_FPU 0 #else -#define SH_HAS_FPU 1 +#warning Cannot detect FPU support, assuming no FPU +#define SH_HAS_FPU 0 #endif /* this should not be here */ +#ifndef CPU_MODEL_NAME #define CPU_MODEL_NAME "SH-Multilib" - -#endif /* multilib */ +#endif /* * If the following macro is set to 0 there will be no software irq stack @@ -79,6 +89,8 @@ extern "C" { #ifndef ASM +#if defined(__sh1__) || defined(__sh2__) + /* * Mask for disabling interrupts */ @@ -111,6 +123,44 @@ extern "C" { "nop\n\t" \ : : "r" (SH_IRQDIS_VALUE), "r" (_level) ); +#else + +#define SH_IRQDIS_MASK 0xf0 + +#define sh_disable_interrupts( _level ) \ + asm volatile ( \ + "stc sr,%0\n\t" \ + "mov %0,r5\n\t" \ + "or %1,r5\n\t" \ + "ldc r5,sr\n\t"\ + : "=&r" (_level ) \ + : "r" (SH_IRQDIS_MASK) \ + : "r5" ); + +#define sh_enable_interrupts( _level ) \ + asm volatile( "ldc %0,sr\n\t" \ + "nop\n\t" \ + :: "r" (_level) ); + +/* + * This temporarily restores the interrupt to _level before immediately + * disabling them again. This is used to divide long RTEMS critical + * sections into two or more parts. The parameter _level is not + * modified. + */ + +#define sh_flash_interrupts( _level ) \ + asm volatile( \ + "stc sr,r5\n\t" \ + "ldc %1,sr\n\t" \ + "nop\n\t" \ + "or %0,r5\n\t" \ + "ldc r5,sr\n\t" \ + "nop\n\t" \ + : : "r" (SH_IRQDIS_MASK), "r" (_level) : "r5"); + +#endif + #define sh_get_interrupt_level( _level ) \ { \ register unsigned32 _tmpsr ; \ diff --git a/cpukit/score/cpu/sh/ChangeLog b/cpukit/score/cpu/sh/ChangeLog index b536b0d6a8..e743a074bc 100644 --- a/cpukit/score/cpu/sh/ChangeLog +++ b/cpukit/score/cpu/sh/ChangeLog @@ -1,3 +1,9 @@ +2001-10-12 Alexandra Kossovsky + + * cpu.c, rtems/score/cpu.h, rtems/score/sh.h: Modified to + support SH4. Reviewed by Ralf Corsepius + who did the original SH port. + 2001-10-11 Ralf Corsepius * .cvsignore: Add autom4te.cache for autoconf > 2.52. diff --git a/cpukit/score/cpu/sh/cpu.c b/cpukit/score/cpu/sh/cpu.c index eaebb46ac7..b63be7c4c2 100644 --- a/cpukit/score/cpu/sh/cpu.c +++ b/cpukit/score/cpu/sh/cpu.c @@ -29,6 +29,10 @@ #include #include +/* FIXME: This should not be here */ +#if defined(__SH4__) +#include +#endif /* referenced in start.S */ extern proc_ptr vectab[] ; @@ -75,6 +79,14 @@ void _CPU_Initialize( */ /* FP context initialization support goes here */ + /* FIXME: When not to use SH4_FPSCR_PR ? */ +#ifdef __SH4__ + _CPU_Null_fp_context.fpscr = SH4_FPSCR_DN | SH4_FPSCR_RM | SH4_FPSCR_PR; +#endif +#ifdef __SH3E__ + /* FIXME: Wild guess :) */ + _CPU_Null_fp_context.fpscr = SH4_FPSCR_DN | SH4_FPSCR_RM; +#endif _CPU_Table = *cpu_table; @@ -151,6 +163,7 @@ void _CPU_ISR_install_raw_handler( * */ +#if defined(sh1) || defined(sh2) void _CPU_ISR_install_vector( unsigned32 vector, proc_ptr new_handler, @@ -230,6 +243,18 @@ void _CPU_Context_Initialize( int _is_fp ) { _the_context->r15 = (unsigned32*) ((unsigned32) (_stack_base) + (_size) ); +#if defined(__sh1__) || defined(__sh2__) _the_context->sr = (_isr << 4) & 0x00f0 ; +#else + _the_context->sr = SH4_SR_MD | ((_isr << 4) & 0x00f0); +#endif _the_context->pr = (unsigned32*) _entry_point ; + + +#if 0 && SH_HAS_FPU + /* Disable FPU if it is non-fp task */ + if(!_is_fp) + _the_context->sr |= SH4_SR_FD; +#endif } + diff --git a/cpukit/score/cpu/sh/rtems/score/cpu.h b/cpukit/score/cpu/sh/rtems/score/cpu.h index 601276f45e..16777170db 100644 --- a/cpukit/score/cpu/sh/rtems/score/cpu.h +++ b/cpukit/score/cpu/sh/rtems/score/cpu.h @@ -34,6 +34,9 @@ extern "C" { #ifndef ASM #include #endif +#if 0 && defined(__SH4__) +#include +#endif /* conditional compilation parameters */ @@ -131,8 +134,13 @@ extern "C" { * an i387 and wish to leave floating point support out of RTEMS. */ -#define CPU_HARDWARE_FP FALSE -#define CPU_SOFTWARE_FP FALSE +#if SH_HAS_FPU +/* FIXME: What about CPU_SOFTWARE_FP ? */ +#define CPU_HARDWARE_FP TRUE +#else +#define CPU_SOFTWARE_FP FALSE +#define CPU_HARDWARE_FP FALSE +#endif /* * Are all tasks RTEMS_FLOATING_POINT tasks implicitly? @@ -150,7 +158,11 @@ extern "C" { * If CPU_HARDWARE_FP is FALSE, then this should be FALSE as well. */ +#if SH_HAS_FPU +#define CPU_ALL_TASKS_ARE_FP TRUE +#else #define CPU_ALL_TASKS_ARE_FP FALSE +#endif /* * Should the IDLE task have a floating point context? @@ -164,7 +176,11 @@ extern "C" { * must be saved as part of the preemption. */ +#if SH_HAS_FPU +#define CPU_IDLE_TASK_IS_FP TRUE +#else #define CPU_IDLE_TASK_IS_FP FALSE +#endif /* * Should the saving of the floating point registers be deferred @@ -192,7 +208,14 @@ extern "C" { * be saved or restored. */ -#define CPU_USE_DEFERRED_FP_SWITCH TRUE +#if SH_HAS_FPU +#define CPU_USE_DEFERRED_FP_SWITCH FALSE +#else +/* FIXME: Is this needed? + * Only here for backward compatibility with previous versions + */ +#define CPU_USE_DEFERRED_FP_SWITCH TRUE +#endif /* * Does this port provide a CPU dependent IDLE task implementation? @@ -355,6 +378,20 @@ typedef struct { } Context_Control; typedef struct { +#if SH_HAS_FPU +#ifdef SH4_USE_X_REGISTERS + union { + float f[16]; + double d[8]; + } x; +#endif + union { + float f[16]; + double d[8]; + } r; + float fpul; /* fp communication register */ + unsigned32 fpscr; /* fp control register */ +#endif /* SH_HAS_FPU */ } Context_Control_fp; typedef struct { @@ -400,9 +437,9 @@ typedef struct { * _CPU_Context_Initialize. */ -/* +#if SH_HAS_FPU SCORE_EXTERN Context_Control_fp _CPU_Null_fp_context; -*/ +#endif /* * On some CPUs, RTEMS supports a software managed interrupt stack. @@ -478,8 +515,12 @@ SCORE_EXTERN void CPU_delay( unsigned32 microseconds ); * CPU's worst alignment requirement for data types on a byte boundary. This * alignment does not take into account the requirements for the stack. */ - +#if defined(__SH4__) +/* FIXME: sh3 and SH3E? */ +#define CPU_ALIGNMENT 8 +#else #define CPU_ALIGNMENT 4 +#endif /* * This number corresponds to the byte alignment requirement for the @@ -654,8 +695,15 @@ SCORE_EXTERN void _CPU_Context_Initialize( * SH1, SH2, SH3 have no FPU, but the SH3e and SH4 have. */ +#if SH_HAS_FPU +#define _CPU_Context_Initialize_fp( _destination ) \ + do { \ + *((Context_Control_fp *) *((void **) _destination)) = _CPU_Null_fp_context;\ + } while(0) +#else #define _CPU_Context_Initialize_fp( _destination ) \ { } +#endif /* end of Context handler macros */ @@ -678,6 +726,7 @@ SCORE_EXTERN void _CPU_Context_Initialize( #define _CPU_Fatal_halt( _error)\ { \ asm volatile("mov.l %0,r0"::"m" (_error)); \ + asm volatile("mov #1, r4"); \ asm volatile("trapa #34"); \ } #endif diff --git a/cpukit/score/cpu/sh/rtems/score/sh.h b/cpukit/score/cpu/sh/rtems/score/sh.h index 2834ea6c64..1ad5b564f4 100644 --- a/cpukit/score/cpu/sh/rtems/score/sh.h +++ b/cpukit/score/cpu/sh/rtems/score/sh.h @@ -38,30 +38,40 @@ extern "C" { * It does this by setting variables to indicate which implementation * dependent features are present in a particular member of the family. */ - -#if defined(rtems_multilib) /* * Figure out all CPU Model Feature Flags based upon compiler * predefines. */ -#define CPU_MODEL_NAME "rtems_multilib" -#define SH_HAS_FPU 0 -#define SH_HAS_SEPARATE_STACKS 1 +#if defined(__SH3E__) || defined(__SH4__) || defined(__SH4_SINGLE_ONLY__) +/* + * Define this if you want to use XD-registers. + * Then this registers will be saved/restored on context switch. + * ! They will not be saved/restored on interrupts! + */ +#define SH4_USE_X_REGISTERS 0 + +#if defined(__LITTLE_ENDIAN__) +#define SH_HAS_FPU 1 #else +/* FIXME: Context_Control_fp does not support big endian */ +#warning FPU not supported +#define SH_HAS_FPU 0 +#endif -#if defined(__sh1__) || defined(__sh2__) || defined(__sh3__) -#define SH_HAS_FPU 0 +#elif defined(__sh1__) || defined(__sh2__) || defined(__sh3__) +#define SH_HAS_FPU 0 #else -#define SH_HAS_FPU 1 +#warning Cannot detect FPU support, assuming no FPU +#define SH_HAS_FPU 0 #endif /* this should not be here */ +#ifndef CPU_MODEL_NAME #define CPU_MODEL_NAME "SH-Multilib" - -#endif /* multilib */ +#endif /* * If the following macro is set to 0 there will be no software irq stack @@ -79,6 +89,8 @@ extern "C" { #ifndef ASM +#if defined(__sh1__) || defined(__sh2__) + /* * Mask for disabling interrupts */ @@ -111,6 +123,44 @@ extern "C" { "nop\n\t" \ : : "r" (SH_IRQDIS_VALUE), "r" (_level) ); +#else + +#define SH_IRQDIS_MASK 0xf0 + +#define sh_disable_interrupts( _level ) \ + asm volatile ( \ + "stc sr,%0\n\t" \ + "mov %0,r5\n\t" \ + "or %1,r5\n\t" \ + "ldc r5,sr\n\t"\ + : "=&r" (_level ) \ + : "r" (SH_IRQDIS_MASK) \ + : "r5" ); + +#define sh_enable_interrupts( _level ) \ + asm volatile( "ldc %0,sr\n\t" \ + "nop\n\t" \ + :: "r" (_level) ); + +/* + * This temporarily restores the interrupt to _level before immediately + * disabling them again. This is used to divide long RTEMS critical + * sections into two or more parts. The parameter _level is not + * modified. + */ + +#define sh_flash_interrupts( _level ) \ + asm volatile( \ + "stc sr,r5\n\t" \ + "ldc %1,sr\n\t" \ + "nop\n\t" \ + "or %0,r5\n\t" \ + "ldc r5,sr\n\t" \ + "nop\n\t" \ + : : "r" (SH_IRQDIS_MASK), "r" (_level) : "r5"); + +#endif + #define sh_get_interrupt_level( _level ) \ { \ register unsigned32 _tmpsr ; \ -- cgit v1.2.3