summaryrefslogtreecommitdiffstats
path: root/cpukit/score
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cpukit/score/cpu/sparc/cpu.c2
-rw-r--r--cpukit/score/cpu/sparc/cpu_asm.S2
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/cpu.h29
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