summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/shared
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/sparc/shared')
-rw-r--r--c/src/lib/libbsp/sparc/shared/irq_asm.S54
-rw-r--r--c/src/lib/libbsp/sparc/shared/start/start.S15
2 files changed, 60 insertions, 9 deletions
diff --git a/c/src/lib/libbsp/sparc/shared/irq_asm.S b/c/src/lib/libbsp/sparc/shared/irq_asm.S
index 1d76e7e728..7d0312b7e4 100644
--- a/c/src/lib/libbsp/sparc/shared/irq_asm.S
+++ b/c/src/lib/libbsp/sparc/shared/irq_asm.S
@@ -7,7 +7,7 @@
* COPYRIGHT (c) 1989-2011.
* On-Line Applications Research Corporation (OAR).
*
- * Copyright (c) 2014, 2016 embedded brains GmbH
+ * Copyright (c) 2014, 2017 embedded brains GmbH
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -218,7 +218,17 @@ done_flushing:
! The next load is in a delay slot, which is all right
#endif
+#if defined(SPARC_USE_LAZY_FP_SWITCH)
+ ld [%g6 + SPARC_PER_CPU_FP_OWNER_OFFSET], %g2
+#endif
ld [%o1 + PSR_OFFSET], %g1 ! g1 = heir psr with traps enabled
+#if defined(SPARC_USE_LAZY_FP_SWITCH)
+ sethi %hi(SPARC_PSR_EF_MASK), %g5
+ cmp %g2, %g0
+ bne,a .Lclear_psr_ef_done
+ andn %g1, %g5, %g1 ! g1 = heir psr w/o PSR[EF]
+.Lclear_psr_ef_done:
+#endif
andn %g1, SPARC_PSR_CWP_MASK, %g1 ! g1 = heir psr w/o cwp
or %g1, %g3, %g1 ! g1 = heir psr with cwp
mov %g1, %psr ! restore status register and
@@ -583,7 +593,7 @@ pil_fixed:
nop ! delay slot
#endif
-#if SPARC_HAS_FPU == 1
+#if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
mov %l0, %g1 ! PSR[EF] value of interrupted context
ta SPARC_SWTRAP_IRQDIS_FP ! **** DISABLE INTERRUPTS ****
#else
@@ -652,10 +662,38 @@ isr_dispatch:
mov 0, %o1 ! ISR level for _Thread_Do_dispatch()
-#if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
+#if defined(SPARC_USE_LAZY_FP_SWITCH)
/* Test if we interrupted a floating point thread (PSR[EF] == 1) */
andcc %l0, %l5, %g0
- be non_fp_thread_dispatch
+ be .Lnon_fp_thread_dispatch
+ ld [%g6 + PER_CPU_OFFSET_EXECUTING], %l6
+
+ /* Set new floating point unit owner to executing thread */
+ st %l6, [%g6 + SPARC_PER_CPU_FP_OWNER_OFFSET]
+
+ call SYM(_Thread_Do_dispatch)
+ mov %g6, %o0
+
+ /*
+ * If we are still the floating point unit owner, then reset the
+ * floating point unit owner to NULL, otherwise clear PSR[EF] in the
+ * interrupt frame and let the FP disabled system call do the floating
+ * point context save/restore.
+ */
+ ld [%g6 + SPARC_PER_CPU_FP_OWNER_OFFSET], %l7
+ cmp %l6, %l7
+ bne .Ldisable_fp
+ andn %l0, %l5, %l0
+ ba .Lthread_dispatch_done
+ st %g0, [%g6 + SPARC_PER_CPU_FP_OWNER_OFFSET]
+.Ldisable_fp:
+ ba .Lthread_dispatch_done
+ st %l0, [%fp + ISF_PSR_OFFSET]
+.Lnon_fp_thread_dispatch:
+#elif defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
+ /* Test if we interrupted a floating point thread (PSR[EF] == 1) */
+ andcc %l0, %l5, %g0
+ be .Lnon_fp_thread_dispatch
nop
/*
@@ -722,17 +760,17 @@ isr_dispatch:
ldd [%sp + FP_FRAME_OFFSET_F28_F29], %f28
ldd [%sp + FP_FRAME_OFFSET_F3O_F31], %f30
ld [%sp + FP_FRAME_OFFSET_FSR], %fsr
- ba thread_dispatch_done
+ ba .Lthread_dispatch_done
add %sp, FP_FRAME_SIZE, %sp
-non_fp_thread_dispatch:
+.Lnon_fp_thread_dispatch:
#endif
call SYM(_Thread_Do_dispatch)
mov %g6, %o0
-#if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
-thread_dispatch_done:
+#if SPARC_HAS_FPU == 1
+.Lthread_dispatch_done:
#endif
ta SPARC_SWTRAP_IRQDIS ! **** DISABLE INTERRUPTS ****
diff --git a/c/src/lib/libbsp/sparc/shared/start/start.S b/c/src/lib/libbsp/sparc/shared/start/start.S
index 3b9f841223..64498c6110 100644
--- a/c/src/lib/libbsp/sparc/shared/start/start.S
+++ b/c/src/lib/libbsp/sparc/shared/start/start.S
@@ -35,6 +35,15 @@
/*
* System call optimized trap table entry
*/
+#define FPDIS_TRAP(_handler) \
+ mov %psr, %l0 ; \
+ sethi %hi(_handler), %l4 ; \
+ jmp %l4+%lo(_handler); \
+ sethi %hi(SPARC_PSR_EF_MASK), %l3
+
+/*
+ * System call optimized trap table entry
+ */
#define IRQDIS_TRAP(_handler) \
mov %psr, %l0 ; \
sethi %hi(_handler), %l4 ; \
@@ -100,7 +109,11 @@ SYM(trap_table):
! exception
BAD_TRAP; ! 02 illegal instruction
BAD_TRAP; ! 03 privileged instruction
+#if defined(SPARC_USE_LAZY_FP_SWITCH)
+ FPDIS_TRAP(SYM(syscall_lazy_fp_switch)); ! 04 fp disabled
+#else
BAD_TRAP; ! 04 fp disabled
+#endif
WOTRAP(5, SYM(window_overflow_trap_handler)); ! 05 window overflow
WUTRAP(6, SYM(window_underflow_trap_handler));! 06 window underflow
BAD_TRAP; ! 07 memory address not aligned
@@ -209,7 +222,7 @@ SYM(CLOCK_SPEED):
*/
IRQDIS_TRAP(SYM(syscall_irqdis)); ! 89 IRQ Disable syscall trap
IRQEN_TRAP(SYM(syscall_irqen)); ! 8A IRQ Enable syscall trap
-#if SPARC_HAS_FPU == 1
+#if defined(SPARC_USE_SYNCHRONOUS_FP_SWITCH)
IRQDIS_TRAP(SYM(syscall_irqdis_fp)); ! 8B IRQ disable
! and set PSR[EF] syscall trap
#else