summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/sparc/syscall/syscall.S
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-11-22 10:13:27 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-11-28 16:08:43 +0100
commit6a1b9e41521fffc0abc82cb4426fc0e4ca8ca17e (patch)
tree55facda04d71966fbffe36c1c1b6de7d8dbf547d /c/src/lib/libcpu/sparc/syscall/syscall.S
parentscore: Fix thread queue context initialization (diff)
downloadrtems-6a1b9e41521fffc0abc82cb4426fc0e4ca8ca17e.tar.bz2
sparc: Optimize _ISR_Handler()
Use _Thread_Do_dispatch() instead of _Thread_Dispatch(). Restore the PSR[EF] state of the interrupted context via new system call syscall_irqdis_fp in case floating-point support is enabled.
Diffstat (limited to 'c/src/lib/libcpu/sparc/syscall/syscall.S')
-rw-r--r--c/src/lib/libcpu/sparc/syscall/syscall.S37
1 files changed, 37 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/sparc/syscall/syscall.S b/c/src/lib/libcpu/sparc/syscall/syscall.S
index 64c4805af6..d00aa03876 100644
--- a/c/src/lib/libcpu/sparc/syscall/syscall.S
+++ b/c/src/lib/libcpu/sparc/syscall/syscall.S
@@ -95,6 +95,43 @@ SYM(syscall_irqen):
jmp %l2 ! Return to after TA 10.
rett %l2 + 4
+#if SPARC_HAS_FPU == 1
+ /*
+ * system call - Interrupt disable and set PSR[EF] according to caller
+ * specified %g1
+ *
+ * On entry:
+ *
+ * g1 = the desired PSR[EF] value (from caller)
+ * l0 = psr (from trap table)
+ * l1 = pc
+ * l2 = npc
+ * l3 = psr | SPARC_PSR_PIL_MASK
+ *
+ * On exit:
+ * g1 = old psr (to user)
+ */
+
+.align 32 ! Align to 32-byte cache-line
+ PUBLIC(syscall_irqdis_fp)
+
+SYM(syscall_irqdis_fp):
+ /*
+ * 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), %l4
+
+ andn %l3, %l4, %l3 ! Clear PSR[EF]
+ and %g1, %l4, %g1 ! Select PSR[EF] only from %g1
+ or %l3, %g1, %l3 ! Set PSR[EF] according to %g1
+ mov %l3, %psr ! Set PSR. Write delay 3 instr
+ or %l0, SPARC_PSR_ET_MASK, %g1 ! return old PSR with ET=1
+ nop ! PSR write delay
+ jmp %l2 ! Return to after TA 9.
+ rett %l2 + 4
+#endif
+
#if defined(RTEMS_PARAVIRT)
PUBLIC(_SPARC_Get_PSR)