summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/sparc/syscall
diff options
context:
space:
mode:
authorDaniel Hellstrom <daniel@gaisler.com>2014-12-03 11:35:52 +0100
committerDaniel Hellstrom <daniel@gaisler.com>2014-12-04 12:51:11 +0100
commitdff1803cfbec3775fff1b9c34cc707c05494dc3b (patch)
treedbb8850d94b30f8388f9e3df9a68fc6c99855f74 /c/src/lib/libcpu/sparc/syscall
parentpc386 bsp fix for default mode (diff)
downloadrtems-dff1803cfbec3775fff1b9c34cc707c05494dc3b.tar.bz2
SPARC: optimize IRQ enable & disable
* Coding style cleanups. * Use OS reserved trap 0x89 for IRQ Disable * Use OS reserved trap 0x8A for IRQ Enable * Add to SPARC CPU supplement documentation This will result in faster Disable/Enable code since the system trap handler does not need to decode which function the user wants. Besides the IRQ disable/enabled can now be inline which avoids the caller to take into account that o0-o7+g1-g4 registers are destroyed by trap handler. It was also possible to reduce the interrupt trap handler by five instructions due to this.
Diffstat (limited to 'c/src/lib/libcpu/sparc/syscall')
-rw-r--r--c/src/lib/libcpu/sparc/syscall/syscall.S118
-rw-r--r--c/src/lib/libcpu/sparc/syscall/syscall.h2
2 files changed, 65 insertions, 55 deletions
diff --git a/c/src/lib/libcpu/sparc/syscall/syscall.S b/c/src/lib/libcpu/sparc/syscall/syscall.S
index 9ce7fa54ef..64c4805af6 100644
--- a/c/src/lib/libcpu/sparc/syscall/syscall.S
+++ b/c/src/lib/libcpu/sparc/syscall/syscall.S
@@ -19,69 +19,81 @@
#include <rtems/asm.h>
#include "syscall.h"
- .seg "text"
- /*
- * system call
- *
- * On entry:
- *
- * l0 = psr (from trap table)
- * l1 = pc
- * l2 = npc
- * g1 = system call id
- *
- * System Call 1 (exit):
- * g2 = additional exit code 1
- * g3 = additional exit code 2
- */
-
-.align 32 ! Align to 32-byte cache-line
- PUBLIC(syscall)
+ .seg "text"
+ /*
+ * system call - halt
+ *
+ * On entry:
+ *
+ * l0 = psr (from trap table)
+ * l1 = pc
+ * l2 = npc
+ * g1 = system call id (1)
+ *
+ * System Call 1 (exit):
+ * g2 = additional exit code 1
+ * g3 = additional exit code 2
+ */
+
+ PUBLIC(syscall)
SYM(syscall):
+ ta 0 ! syscall 1, halt with %g1,%g2,%g3 info
- ! "subcc, %g1, 3, %g0" done in trap table
- bne 2f ! syscall 3? enable interrupt
- and %i0, SPARC_PSR_PIL_MASK, %l4
- andn %l0, SPARC_PSR_PIL_MASK, %l5
- wr %l4, %l5, %psr ! Update PSR according to syscall 3
-1: ! leave, with 3 inst PSR-write delay
- mov 0, %g1 ! clear %g1
- or %l0, SPARC_PSR_ET_MASK, %i0 ! return old psr with ET=1. No
- ! effect on syscall 3
- jmpl %l2, %g0
- rett %l2 + 4
-
-2: or %l0, 0x0f00, %l4 ! set PIL=15
- subcc %g1, 2, %g0 ! syscall 2? disable interrupts
- beq,a 1b ! Annul delay-slot for syscall 1
- mov %l4, %psr ! Update PSR according to Syscall 2
- ta 0 ! syscall 1 (not 2 or 3), halt
-
- PUBLIC(sparc_disable_interrupts)
+ PUBLIC(sparc_syscall_exit)
-SYM(sparc_disable_interrupts):
-
- mov SYS_irqdis, %g1
- retl
- ta 0
+SYM(sparc_syscall_exit):
- PUBLIC(sparc_enable_interrupts)
+ mov SYS_exit, %g1
+ mov %o0, %g2 ! Additional exit code 1
+ mov %o1, %g3 ! Additional exit code 2
+ ta SPARC_SWTRAP_SYSCALL
+
+ /*
+ * system call - Interrupt Disable
+ *
+ * On entry:
+ *
+ * l0 = psr (from trap table)
+ * l1 = pc
+ * l2 = npc
+ * l3 = psr | SPARC_PSR_PIL_MASK
+ *
+ * On exit:
+ * g1 = old psr (to user)
+ */
-SYM(sparc_enable_interrupts):
+.align 32 ! Align to 32-byte cache-line
+ PUBLIC(syscall_irqdis)
- mov SYS_irqen, %g1
- retl
- ta 0
+SYM(syscall_irqdis):
+ 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
- PUBLIC(sparc_syscall_exit)
+ /*
+ * system call - Interrupt Enable
+ *
+ * On entry:
+ *
+ * l0 = psr (from trap table)
+ * l1 = pc
+ * l2 = npc
+ * l3 = psr & ~0x0f00
+ * g1 = new PIL to write (from user)
+ */
-SYM(sparc_syscall_exit):
+.align 32 ! Align to 32-byte cache-line
+ PUBLIC(syscall_irqen)
- mov SYS_exit, %g1
- mov %o0, %g2 ! Additional exit code 1
- mov %o1, %g3 ! Additional exit code 2
- ta 0
+SYM(syscall_irqen):
+ and %g1, SPARC_PSR_PIL_MASK, %l4 ! %l4 = (%g1 & 0xf00)
+ wr %l3, %l4, %psr ! PSR = (PSR & ~0xf00) ^ %l4
+ nop; nop ! PSR write delay;
+ jmp %l2 ! Return to after TA 10.
+ rett %l2 + 4
#if defined(RTEMS_PARAVIRT)
diff --git a/c/src/lib/libcpu/sparc/syscall/syscall.h b/c/src/lib/libcpu/sparc/syscall/syscall.h
index 9af3560267..2f20886840 100644
--- a/c/src/lib/libcpu/sparc/syscall/syscall.h
+++ b/c/src/lib/libcpu/sparc/syscall/syscall.h
@@ -1,3 +1 @@
#define SYS_exit 1
-#define SYS_irqdis 2
-#define SYS_irqen 3