/* SPDX-License-Identifier: BSD-2-Clause */ /* * 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. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #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 */