I am missing something. When an interrupt happens, it disables floating point. Where does fp get re-enabled afterward?
On Fri, May 29, 2015 at 8:54 AM, Sebastian Huber <sebastian.hu...@embedded-brains.de> wrote: > From: Alexander Krutwig <alexander.krut...@embedded-brains.de> > > Update #2270. > --- > c/src/lib/libbsp/sparc/shared/irq_asm.S | 30 ++++++++++++++++++++++++++++++ > cpukit/score/cpu/sparc/cpu.c | 8 ++++++++ > cpukit/score/cpu/sparc/rtems/score/cpu.h | 25 ++++++++++++++++++++++++- > 3 files changed, 62 insertions(+), 1 deletion(-) > > diff --git a/c/src/lib/libbsp/sparc/shared/irq_asm.S > b/c/src/lib/libbsp/sparc/shared/irq_asm.S > index eef144f..8e1dc1f 100644 > --- a/c/src/lib/libbsp/sparc/shared/irq_asm.S > +++ b/c/src/lib/libbsp/sparc/shared/irq_asm.S > @@ -423,6 +423,14 @@ dont_do_the_window: > add %l6, 1, %l6 > st %l6, [%g6 + PER_CPU_THREAD_DISPATCH_DISABLE_LEVEL] > > +#if SPARC_HAS_FPU == 1 > + /* > + * We cannot use an intermediate value for operations with the > PSR[EF] > + * bit since they use a 13-bit sign extension and PSR[EF] is bit 12. > + */ > + sethi %hi(SPARC_PSR_EF_MASK), %l5 > +#endif > + > /* > * If ISR nest level was zero (now 1), then switch stack. > */ > @@ -441,6 +449,19 @@ dont_do_the_window: > > ld [%g6 + PER_CPU_INTERRUPT_STACK_HIGH], %sp > > +#if SPARC_HAS_FPU == 1 > + /* > + * Test if the interrupted thread uses the floating point unit > + * (PSR[EF] == 1). In case it uses the floating point unit, then > store > + * the floating point status register. This has the side-effect that > + * all pending floating point operations complete before the store > + * completes. > + */ > + andcc %l0, %l5, %g0 > + bne,a dont_switch_stacks > + st %fsr, [%g6 + SPARC_PER_CPU_FSR_OFFSET] > +#endif > + > dont_switch_stacks: > /* > * Make sure we have a place on the stack for the window overflow > @@ -471,6 +492,15 @@ dont_switch_stacks: > dont_fix_pil: > or %g5, SPARC_PSR_PIL_MASK, %g5 > pil_fixed: > + > +#if SPARC_HAS_FPU == 1 > + /* > + * Clear the PSR[EF] bit of the interrupted context to ensure that > + * interrupt service routines cannot corrupt the floating point > context. > + */ > + andn %g5, %l5, %g5 > +#endif > + > wr %g5, SPARC_PSR_ET_MASK, %psr ! **** ENABLE TRAPS **** > > /* > diff --git a/cpukit/score/cpu/sparc/cpu.c b/cpukit/score/cpu/sparc/cpu.c > index f96d1ea..ee64b1e 100644 > --- a/cpukit/score/cpu/sparc/cpu.c > +++ b/cpukit/score/cpu/sparc/cpu.c > @@ -29,6 +29,14 @@ RTEMS_STATIC_ASSERT( > SPARC_PER_CPU_ISR_DISPATCH_DISABLE > ); > > +#if SPARC_HAS_FPU == 1 > + RTEMS_STATIC_ASSERT( > + offsetof( Per_CPU_Control, cpu_per_cpu.fsr) > + == SPARC_PER_CPU_FSR_OFFSET, > + SPARC_PER_CPU_FSR_OFFSET > + ); > +#endif > + > #define SPARC_ASSERT_OFFSET(field, off) \ > RTEMS_STATIC_ASSERT( \ > offsetof(Context_Control, field) == off ## _OFFSET, \ > diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h > b/cpukit/score/cpu/sparc/rtems/score/cpu.h > index 5d5f1e4..02891b0 100644 > --- a/cpukit/score/cpu/sparc/rtems/score/cpu.h > +++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h > @@ -341,7 +341,11 @@ typedef struct { > /** This defines the size of the minimum stack frame. */ > #define CPU_MINIMUM_STACK_FRAME_SIZE 0x60 > > -#define CPU_PER_CPU_CONTROL_SIZE 4 > +#if ( SPARC_HAS_FPU == 1 ) > + #define CPU_PER_CPU_CONTROL_SIZE 8 > +#else > + #define CPU_PER_CPU_CONTROL_SIZE 4 > +#endif > > /** > * @brief Offset of the CPU_Per_CPU_control::isr_dispatch_disable field > @@ -349,6 +353,14 @@ typedef struct { > */ > #define SPARC_PER_CPU_ISR_DISPATCH_DISABLE 0 > > +#if ( SPARC_HAS_FPU == 1 ) > + /** > + * @brief Offset of the CPU_Per_CPU_control::fsr field relative to the > + * Per_CPU_Control begin. > + */ > + #define SPARC_PER_CPU_FSR_OFFSET 4 > +#endif > + > /** > * @defgroup Contexts SPARC Context Structures > * > @@ -380,6 +392,17 @@ typedef struct { > * attempts on a previously interrupted thread's stack. > */ > uint32_t isr_dispatch_disable; > + > +#if ( SPARC_HAS_FPU == 1 ) > + /** > + * @brief Memory location to store the FSR register during interrupt > + * processing. > + * > + * This is a write-only field. The FSR is written to force a completion of > + * floating point operations in progress. > + */ > + uint32_t fsr; > +#endif > } CPU_Per_CPU_control; > > /** > -- > 1.8.4.5 > > _______________________________________________ > devel mailing list > devel@rtems.org > http://lists.rtems.org/mailman/listinfo/devel _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel