[PATCH v2 1/2] score: Add Thread_Control::is_fp

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Jun 3 08:10:52 UTC 2015


Store the floating-point unit property in the thread control block
regardless of the CPU_HARDWARE_FP and CPU_SOFTWARE_FP settings.  Make
sure the floating-point unit is only enabled for the corresponding
multilibs.  This helps targets which have a volatile only floating point
context like SPARC for example.
---
 c/src/lib/libcpu/powerpc/new-exceptions/cpu.c | 18 +-----------------
 cpukit/posix/src/pthreadcreate.c              |  6 +-----
 cpukit/score/cpu/mips/cpu.c                   | 12 ++++++++++--
 cpukit/score/include/rtems/score/thread.h     |  2 ++
 cpukit/score/src/threadinitialize.c           |  1 +
 cpukit/score/src/threadloadenv.c              |  7 ++-----
 6 files changed, 17 insertions(+), 29 deletions(-)

diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/cpu.c b/c/src/lib/libcpu/powerpc/new-exceptions/cpu.c
index 0b0527e..1e564f7 100644
--- a/c/src/lib/libcpu/powerpc/new-exceptions/cpu.c
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/cpu.c
@@ -98,8 +98,6 @@ void _CPU_Context_Initialize(
   }
 
 #ifdef PPC_MULTILIB_FPU
-  msr_value |= MSR_FP;
-#else
   /*
    *  The FP bit of the MSR should only be enabled if this is a floating
    *  point task.  Unfortunately, the vfprintf_r routine in newlib
@@ -108,21 +106,7 @@ void _CPU_Context_Initialize(
    *  of vfprintf.c will be required to avoid this behavior.  At this
    *  time (7 July 1997), this restructuring is not being done.
    */
-
-  /* Make sure integer tasks have no FPU access in order to
-   * catch violations. Gcc may implicitely use the FPU and
-   * data corruption may happen.
-   * Since we set the_contex->msr using our current MSR,
-   * we must make sure MSR_FP is off if (!is_fp)...
-   * Unfortunately, this means that users of vfprintf_r have to use FP
-   * tasks or fix vfprintf. Furthermore, users of int-only tasks
-   * must prevent gcc from using the FPU (currently -msoft-float is the
-   * only way...)
-   */
-  if ( is_fp )
-    msr_value |= PPC_MSR_FP;
-  else
-    msr_value &= ~PPC_MSR_FP;
+  msr_value |= MSR_FP;
 #endif
 
 #ifdef PPC_MULTILIB_ALTIVEC
diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c
index c448c42..498242c 100644
--- a/cpukit/posix/src/pthreadcreate.c
+++ b/cpukit/posix/src/pthreadcreate.c
@@ -155,11 +155,7 @@ int pthread_create(
    *  Currently all POSIX threads are floating point if the hardware
    *  supports it.
    */
-  #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
-    is_fp = true;
-  #else
-    is_fp = false;
-  #endif
+  is_fp = true;
 
   /*
    *  Allocate the thread control block.
diff --git a/cpukit/score/cpu/mips/cpu.c b/cpukit/score/cpu/mips/cpu.c
index fffee5e..cb6c664 100644
--- a/cpukit/score/cpu/mips/cpu.c
+++ b/cpukit/score/cpu/mips/cpu.c
@@ -179,6 +179,7 @@ void _CPU_Context_Initialize(
 {
   uintptr_t             stack_tmp;
   __MIPS_REGISTER_TYPE  intlvl = new_level & 0xff;
+  __MIPS_REGISTER_TYPE  c0_sr;
 
   stack_tmp  = (uintptr_t)stack_base;
   stack_tmp += ((size) - CPU_STACK_ALIGNMENT);
@@ -187,11 +188,18 @@ void _CPU_Context_Initialize(
   the_context->sp = (__MIPS_REGISTER_TYPE) stack_tmp;
   the_context->fp = (__MIPS_REGISTER_TYPE) stack_tmp;
   the_context->ra = (__MIPS_REGISTER_TYPE) (uintptr_t)entry_point;
-  the_context->c0_sr =
+
+  c0_sr =
     ((intlvl==0)? (mips_interrupt_mask() | 0x300 | _INTON):
       ( ((intlvl<<9) & mips_interrupt_mask()) | 0x300 |
       ((intlvl & 1)?_INTON:0)) ) |
-      SR_CU0 | ((is_fp)?SR_CU1:0) | _EXTRABITS;
+      SR_CU0 | _EXTRABITS;
+#if MIPS_HAS_FPU == 1
+  if ( is_fp ) {
+    c0_sr |= SR_CU1;
+  }
+#endif
+  the_context->c0_sr = c0_sr;
 }
 /*
  *  _CPU_Internal_threads_Idle_thread_body
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 39fcb17..c69646b 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -750,6 +750,8 @@ struct Thread_Control_struct {
 #endif
   /** This field is true if the thread is preemptible. */
   bool                                  is_preemptible;
+  /** This field is true if the thread uses the floating point unit. */
+  bool                                  is_fp;
 
   /**
    * @brief Scheduler related control.
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index 2133d74..a09693a 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -159,6 +159,7 @@ bool _Thread_Initialize(
    *  General initialization
    */
 
+  the_thread->is_fp                  = is_fp;
   the_thread->Start.isr_level        = isr_level;
   the_thread->Start.is_preemptible   = is_preemptible;
   the_thread->Start.budget_algorithm = budget_algorithm;
diff --git a/cpukit/score/src/threadloadenv.c b/cpukit/score/src/threadloadenv.c
index c84e2b4..43564af 100644
--- a/cpukit/score/src/threadloadenv.c
+++ b/cpukit/score/src/threadloadenv.c
@@ -25,17 +25,14 @@ void _Thread_Load_environment(
   Thread_Control *the_thread
 )
 {
-  bool is_fp;
   uint32_t isr_level;
 
 #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE )
   if ( the_thread->Start.fp_context ) {
     the_thread->fp_context = the_thread->Start.fp_context;
     _Context_Initialize_fp( &the_thread->fp_context );
-    is_fp = true;
-  } else
+  }
 #endif
-    is_fp = false;
 
   the_thread->is_preemptible   = the_thread->Start.is_preemptible;
   the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
@@ -58,7 +55,7 @@ void _Thread_Load_environment(
     the_thread->Start.Initial_stack.size,
     isr_level,
     _Thread_Handler,
-    is_fp,
+    the_thread->is_fp,
     the_thread->Start.tls_area
   );
 
-- 
1.8.4.5



More information about the devel mailing list