diff options
Diffstat (limited to 'cpukit/score/cpu/sparc64/sparc64-syscall.S')
-rw-r--r-- | cpukit/score/cpu/sparc64/sparc64-syscall.S | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/cpukit/score/cpu/sparc64/sparc64-syscall.S b/cpukit/score/cpu/sparc64/sparc64-syscall.S new file mode 100644 index 0000000000..ffd6e8538d --- /dev/null +++ b/cpukit/score/cpu/sparc64/sparc64-syscall.S @@ -0,0 +1,126 @@ +/* + * systrap.S + * + * This file contains emulated system calls using software trap 0. + * The following calls are supported: + * + * + SYS_exit (halt) + * + SYS_irqdis (disable interrupts) + * + SYS_irqset (set interrupt level) + * + * COPYRIGHT (c) 2010. Gedare Bloom. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include <rtems/asm.h> +#include "sparc64-syscall.h" + + +.seg "text" +/* + * system call + * + * On entry: + * g4[AG | GL=1] = tstate (from trap table) + * g2[AG | GL=1] = trap vector # (256) + * g3[AG | GL=1] = address of SYM(syscall) + * g4[AG | GL-1] = system call id + * if arch = sun4v: + * We need to back to GL-1 to read the system call id. + * on sun4u: + * We need to go back to the normal globals to read the system call id. + * + * First thing is to return to the previous set of globals, so + * that the system call id can be read. The syscall code needs + * to re-read tstate. + * + * syscall should only ever be entered by ta 0 being called explicitly + * by a function that knows what is happening. This means the syscall + * code can safely use any scratch registers and the %o registers. + */ + + +PUBLIC(syscall) + + + SYM(syscall): + mov %g0, %g4 ! clear %g4 at this GL +#if defined (SUN4U) + rdpr %pstate, %g1 + andn %g1, SPARC_PSTATE_AG_MASK, %g1 + wrpr %g1, %g0, %pstate ! go to regular globals +#elif defined (SUN4V) + rdpr %gl, %g1 + dec %g1 + wrpr %g0, %g1, %gl ! go back to GL = GL - 1 +#endif + + subcc %g4, 2, %g0 + bne 3f + rdpr %tstate, %g5 ! re-read tstate, use delay slot + + ! syscall 2, disable interrupts + rdpr %pil, %g1 + and %g5, SPARC_TSTATE_IE_MASK, %o0 + or %o0, %g1, %o0 ! return TSTATE_IE | PIL + wrpr %g0, 0xf, %pil ! set PIL to 15 + andn %g5, SPARC_TSTATE_IE_MASK, %g1 + wrpr %g0, %g1, %tstate ! disable interrupts in trap state + ba,a 9f + + 3: ! syscall 3, enable interrupts + subcc %g4, 3, %g0 + bne 1f + and %o0, 0xf, %g1 + wrpr %g0, %g1, %pil ! restore PIL +! and %o0, SPARC_TSTATE_IE_MASK, %g1 +! or %g5, %g1, %g1 ! restore saved IE + or %g5, SPARC_TSTATE_IE_MASK, %g1 ! restore IE (safe?) + wrpr %g0, %g1, %tstate + ba,a 9f + + 1: + ba,a 1b ! spin. taking a trap here -> htrap + + 9: ! leave + mov 0, %g4 ! clear %g4 + DONE + +PUBLIC(sparc_disable_interrupts) + + SYM(sparc_disable_interrupts): + mov SYS_irqdis, %g4 + ta 0 +#if 0 + rdpr %pstate, %g5 + rdpr %pil, %g1 + and %g5, SPARC_PSTATE_IE_MASK, %o0 + or %o0, %g1, %o0 ! return PSTATE_IE | PIL + wrpr %g0, 0xf, %pil ! set PIL to 15 + andn %g5, SPARC_PSTATE_IE_MASK, %g1 + wrpr %g0, %g1, %pstate ! disable interrupts +#endif + retl + nop + +PUBLIC(sparc_enable_interrupts) + + SYM(sparc_enable_interrupts): + mov SYS_irqen, %g4 + ta 0 +#if 0 + rdpr %pstate, %g5 + and %o0, 0xf, %g1 + wrpr %g0, %g1, %pil ! restore PIL + and %o0, SPARC_PSTATE_IE_MASK, %g1 + or %g5, %g1, %g1 ! restore saved IE +! or %g5, SPARC_PSTATE_IE_MASK, %g1 ! set IE regardless of old (safe?) + wrpr %g0, %g1, %pstate +#endif + retl + nop + + /* end of file */ |