Changeset a51b352 in rtems


Ignore:
Timestamp:
May 30, 2015, 3:48:27 PM (4 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
b88d346f
Parents:
335e5ca
git-author:
Sebastian Huber <sebastian.huber@…> (05/30/15 15:48:27)
git-committer:
Sebastian Huber <sebastian.huber@…> (06/09/15 07:05:50)
Message:

sparc: Add SPARC_USE_SAFE_FP_SUPPORT

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.

Update #2270.

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/shared/irq_asm.S

    r335e5ca ra51b352  
    2525#include <rtems/score/percpu.h>
    2626#include <bspopts.h>
     27
     28#if SPARC_HAS_FPU == 1 && defined(SPARC_USE_SAFE_FP_SUPPORT)
     29  #define FP_FRAME_OFFSET_FO_F1 (CPU_MINIMUM_STACK_FRAME_SIZE + 0)
     30  #define FP_FRAME_OFFSET_F2_F3 (FP_FRAME_OFFSET_FO_F1 + 8)
     31  #define FP_FRAME_OFFSET_F4_F5 (FP_FRAME_OFFSET_F2_F3 + 8)
     32  #define FP_FRAME_OFFSET_F6_F7 (FP_FRAME_OFFSET_F4_F5 + 8)
     33  #define FP_FRAME_OFFSET_F8_F9 (FP_FRAME_OFFSET_F6_F7 + 8)
     34  #define FP_FRAME_OFFSET_F1O_F11 (FP_FRAME_OFFSET_F8_F9 + 8)
     35  #define FP_FRAME_OFFSET_F12_F13 (FP_FRAME_OFFSET_F1O_F11 + 8)
     36  #define FP_FRAME_OFFSET_F14_F15 (FP_FRAME_OFFSET_F12_F13 + 8)
     37  #define FP_FRAME_OFFSET_F16_F17 (FP_FRAME_OFFSET_F14_F15 + 8)
     38  #define FP_FRAME_OFFSET_F18_F19 (FP_FRAME_OFFSET_F16_F17 + 8)
     39  #define FP_FRAME_OFFSET_F2O_F21 (FP_FRAME_OFFSET_F18_F19 + 8)
     40  #define FP_FRAME_OFFSET_F22_F23 (FP_FRAME_OFFSET_F2O_F21 + 8)
     41  #define FP_FRAME_OFFSET_F24_F25 (FP_FRAME_OFFSET_F22_F23 + 8)
     42  #define FP_FRAME_OFFSET_F26_F27 (FP_FRAME_OFFSET_F24_F25 + 8)
     43  #define FP_FRAME_OFFSET_F28_F29 (FP_FRAME_OFFSET_F26_F27 + 8)
     44  #define FP_FRAME_OFFSET_F3O_F31 (FP_FRAME_OFFSET_F28_F29 + 8)
     45  #define FP_FRAME_OFFSET_FSR (FP_FRAME_OFFSET_F3O_F31 + 8)
     46  #define FP_FRAME_SIZE (FP_FRAME_OFFSET_FSR + 8)
     47#endif
    2748
    2849/*
     
    614635        nop
    615636isr_dispatch:
     637
     638#if SPARC_HAS_FPU == 1 && defined(SPARC_USE_SAFE_FP_SUPPORT)
     639        /* Test if we interrupted a floating point thread (PSR[EF] == 1) */
     640        andcc   %l0, %l5, %g0
     641        be      non_fp_thread_dispatch
     642         nop
     643
     644        /*
     645         * Yes, this is a floating point thread, then save the floating point
     646         * context to a new stack frame.  Then do the thread dispatch.
     647         * Post-switch actions (e.g. signal handlers) and context switch
     648         * extensions may safely use the floating point unit.
     649         */
     650        sub     %sp, FP_FRAME_SIZE, %sp
     651        std     %f0, [%sp + FP_FRAME_OFFSET_FO_F1]
     652        std     %f2, [%sp + FP_FRAME_OFFSET_F2_F3]
     653        std     %f4, [%sp + FP_FRAME_OFFSET_F4_F5]
     654        std     %f6, [%sp + FP_FRAME_OFFSET_F6_F7]
     655        std     %f8, [%sp + FP_FRAME_OFFSET_F8_F9]
     656        std     %f10, [%sp + FP_FRAME_OFFSET_F1O_F11]
     657        std     %f12, [%sp + FP_FRAME_OFFSET_F12_F13]
     658        std     %f14, [%sp + FP_FRAME_OFFSET_F14_F15]
     659        std     %f16, [%sp + FP_FRAME_OFFSET_F16_F17]
     660        std     %f18, [%sp + FP_FRAME_OFFSET_F18_F19]
     661        std     %f20, [%sp + FP_FRAME_OFFSET_F2O_F21]
     662        std     %f22, [%sp + FP_FRAME_OFFSET_F22_F23]
     663        std     %f24, [%sp + FP_FRAME_OFFSET_F24_F25]
     664        std     %f26, [%sp + FP_FRAME_OFFSET_F26_F27]
     665        std     %f28, [%sp + FP_FRAME_OFFSET_F28_F29]
     666        std     %f30, [%sp + FP_FRAME_OFFSET_F3O_F31]
     667        call    SYM(_Thread_Dispatch), 0
     668         st     %fsr, [%sp + FP_FRAME_OFFSET_FSR]
     669
     670        /*
     671         * Restore the floating point context from stack frame and release the
     672         * stack frame.
     673         */
     674        ldd     [%sp + FP_FRAME_OFFSET_FO_F1], %f0
     675        ldd     [%sp + FP_FRAME_OFFSET_F2_F3], %f2
     676        ldd     [%sp + FP_FRAME_OFFSET_F4_F5], %f4
     677        ldd     [%sp + FP_FRAME_OFFSET_F6_F7], %f6
     678        ldd     [%sp + FP_FRAME_OFFSET_F8_F9], %f8
     679        ldd     [%sp + FP_FRAME_OFFSET_F1O_F11], %f10
     680        ldd     [%sp + FP_FRAME_OFFSET_F12_F13], %f12
     681        ldd     [%sp + FP_FRAME_OFFSET_F14_F15], %f14
     682        ldd     [%sp + FP_FRAME_OFFSET_F16_F17], %f16
     683        ldd     [%sp + FP_FRAME_OFFSET_F18_F19], %f18
     684        ldd     [%sp + FP_FRAME_OFFSET_F2O_F21], %f20
     685        ldd     [%sp + FP_FRAME_OFFSET_F22_F23], %f22
     686        ldd     [%sp + FP_FRAME_OFFSET_F24_F25], %f24
     687        ldd     [%sp + FP_FRAME_OFFSET_F26_F27], %f26
     688        ldd     [%sp + FP_FRAME_OFFSET_F28_F29], %f28
     689        ldd     [%sp + FP_FRAME_OFFSET_F3O_F31], %f30
     690        ld      [%sp + FP_FRAME_OFFSET_FSR], %fsr
     691        ba      thread_dispatch_done
     692         add    %sp, FP_FRAME_SIZE, %sp
     693
     694non_fp_thread_dispatch:
     695#endif
     696
    616697        call    SYM(_Thread_Dispatch), 0
    617698         nop
     699
     700#if SPARC_HAS_FPU == 1 && defined(SPARC_USE_SAFE_FP_SUPPORT)
     701thread_dispatch_done:
     702#endif
    618703
    619704        /*
  • cpukit/score/cpu/sparc/cpu.c

    r335e5ca ra51b352  
    132132void _CPU_Initialize(void)
    133133{
    134 #if (SPARC_HAS_FPU == 1)
     134#if (SPARC_HAS_FPU == 1) && !defined(SPARC_USE_SAFE_FP_SUPPORT)
    135135  Context_Control_fp *pointer;
    136136  uint32_t            psr;
  • cpukit/score/cpu/sparc/cpu_asm.S

    r335e5ca ra51b352  
    2727#include <rtems/system.h>
    2828
    29 #if (SPARC_HAS_FPU == 1)
     29#if (SPARC_HAS_FPU == 1) && !defined(SPARC_USE_SAFE_FP_SUPPORT)
    3030
    3131/*
  • cpukit/score/cpu/sparc/rtems/score/cpu.h

    r335e5ca ra51b352  
    2929/* conditional compilation parameters */
    3030
     31#if defined(RTEMS_SMP)
     32  /*
     33   * The SPARC ABI is a bit special with respect to the floating point context.
     34   * The complete floating point context is volatile.  Thus from an ABI point
     35   * of view nothing needs to be saved and restored during a context switch.
     36   * Instead the floating point context must be saved and restored during
     37   * interrupt processing.  Historically the deferred floating point switch is
     38   * used for SPARC and the complete floating point context is saved and
     39   * restored during a context switch to the new floating point unit owner.
     40   * This is a bit dangerous since post-switch actions (e.g. signal handlers)
     41   * and context switch extensions may silently corrupt the floating point
     42   * context.  The floating point unit is disabled for interrupt handlers.
     43   * Thus in case an interrupt handler uses the floating point unit then this
     44   * will result in a trap.
     45   *
     46   * On SMP configurations the deferred floating point switch is not
     47   * supported in principle.  So use here a safe floating point support.  Safe
     48   * means that the volatile floating point context is saved and restored
     49   * around a thread dispatch issued during interrupt processing.  Thus
     50   * post-switch actions and context switch extensions may safely use the
     51   * floating point unit.
     52   */
     53  #define SPARC_USE_SAFE_FP_SUPPORT
     54#endif
     55
    3156/**
    3257 * Should the calls to _Thread_Enable_dispatch be inlined?
     
    103128 * This is set based upon the multilib settings.
    104129 */
    105 #if ( SPARC_HAS_FPU == 1 )
     130#if ( SPARC_HAS_FPU == 1 ) && !defined(SPARC_USE_SAFE_FP_SUPPORT)
    106131  #define CPU_HARDWARE_FP     TRUE
    107132#else
     
    153178 * it is safe to defer floating point context switches.
    154179 */
    155 #if defined(RTEMS_SMP)
     180#if defined(SPARC_USE_SAFE_FP_SUPPORT)
    156181  #define CPU_USE_DEFERRED_FP_SWITCH FALSE
    157182#else
Note: See TracChangeset for help on using the changeset viewer.