diff options
Diffstat (limited to '')
-rw-r--r-- | cpukit/score/cpu/sparc/cpu.c | 2 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/cpu_asm.S | 2 | ||||
-rw-r--r-- | cpukit/score/cpu/sparc/rtems/score/cpu.h | 29 |
3 files changed, 29 insertions, 4 deletions
diff --git a/cpukit/score/cpu/sparc/cpu.c b/cpukit/score/cpu/sparc/cpu.c index bab0040058..569b6f8ec8 100644 --- a/cpukit/score/cpu/sparc/cpu.c +++ b/cpukit/score/cpu/sparc/cpu.c @@ -131,7 +131,7 @@ RTEMS_STATIC_ASSERT( void _CPU_Initialize(void) { -#if (SPARC_HAS_FPU == 1) +#if (SPARC_HAS_FPU == 1) && !defined(SPARC_USE_SAFE_FP_SUPPORT) Context_Control_fp *pointer; uint32_t psr; diff --git a/cpukit/score/cpu/sparc/cpu_asm.S b/cpukit/score/cpu/sparc/cpu_asm.S index 3fa0532c86..4e683dae0d 100644 --- a/cpukit/score/cpu/sparc/cpu_asm.S +++ b/cpukit/score/cpu/sparc/cpu_asm.S @@ -26,7 +26,7 @@ #include <rtems/asm.h> #include <rtems/system.h> -#if (SPARC_HAS_FPU == 1) +#if (SPARC_HAS_FPU == 1) && !defined(SPARC_USE_SAFE_FP_SUPPORT) /* * void _CPU_Context_save_fp( diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h index 02891b0438..d35846521e 100644 --- a/cpukit/score/cpu/sparc/rtems/score/cpu.h +++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h @@ -28,6 +28,31 @@ extern "C" { /* conditional compilation parameters */ +#if defined(RTEMS_SMP) + /* + * The SPARC ABI is a bit special with respect to the floating point context. + * The complete floating point context is volatile. Thus from an ABI point + * of view nothing needs to be saved and restored during a context switch. + * Instead the floating point context must be saved and restored during + * interrupt processing. Historically the deferred floating point switch is + * used for SPARC and the complete floating point context is saved and + * restored during a context switch to the new floating point unit owner. + * This is a bit dangerous since post-switch actions (e.g. signal handlers) + * and context switch extensions may silently corrupt the floating point + * context. The floating point unit is disabled for interrupt handlers. + * Thus in case an interrupt handler uses the floating point unit then this + * will result in a trap. + * + * On SMP configurations the deferred floating point switch is not + * supported in principle. So use here a safe floating point support. Safe + * means that the volatile floating point context is saved and restored + * around a thread dispatch issued during interrupt processing. Thus + * post-switch actions and context switch extensions may safely use the + * floating point unit. + */ + #define SPARC_USE_SAFE_FP_SUPPORT +#endif + /** * Should the calls to _Thread_Enable_dispatch be inlined? * @@ -102,7 +127,7 @@ extern "C" { * * This is set based upon the multilib settings. */ -#if ( SPARC_HAS_FPU == 1 ) +#if ( SPARC_HAS_FPU == 1 ) && !defined(SPARC_USE_SAFE_FP_SUPPORT) #define CPU_HARDWARE_FP TRUE #else #define CPU_HARDWARE_FP FALSE @@ -152,7 +177,7 @@ extern "C" { * On the SPARC, we can disable the FPU for integer only tasks so * it is safe to defer floating point context switches. */ -#if defined(RTEMS_SMP) +#if defined(SPARC_USE_SAFE_FP_SUPPORT) #define CPU_USE_DEFERRED_FP_SWITCH FALSE #else #define CPU_USE_DEFERRED_FP_SWITCH TRUE |