/* $OpenBSD: syscall.c,v 1.28 2023/12/13 15:57:22 miod Exp $ */ /* $NetBSD: syscall.c,v 1.24 2003/11/14 19:03:17 scw Exp $ */ /*- * Copyright (c) 2000, 2003 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Charles M. Hannum. * * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. */ /* * Copyright (c) 1994-1998 Mark Brinicombe. * Copyright (c) 1994 Brini. * All rights reserved. * * This code is derived from software written for Brini by Mark Brinicombe * * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Mark Brinicombe * for the NetBSD Project. * 4. The name of the company nor the name of the author may be used to * endorse or promote products derived from this software without specific * prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. * * syscall entry handling * * Created : 09/11/94 */ #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAXARGS 8 void swi_handler(trapframe_t *frame) { struct proc *p = curproc; const struct sysent *callp = sysent; int code, error; u_int nap = 4, nargs; register_t *ap, *args, copyargs[MAXARGS], rval[2]; uvmexp.syscalls++; /* Before enabling interrupts, save FPU state */ vfp_save(); enable_interrupts(PSR_I); p->p_addr->u_pcb.pcb_tf = frame; /* Skip over speculation-blocking barrier. */ frame->tf_pc += 8; ap = &frame->tf_r0; code = frame->tf_r12; // XXX out of range stays on syscall0, which we assume is enosys if (code > 0 && code < SYS_MAXSYSCALL) callp += code; nargs = callp->sy_argsize / sizeof(register_t); if (nargs <= nap) { args = ap; } else { KASSERT(nargs <= MAXARGS); memcpy(copyargs, ap, nap * sizeof(register_t)); if ((error = copyin((void *)frame->tf_usr_sp, copyargs + nap, (nargs - nap) * sizeof(register_t)))) goto bad; args = copyargs; } rval[0] = 0; rval[1] = frame->tf_r1; error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: frame->tf_r0 = rval[0]; frame->tf_r1 = rval[1]; frame->tf_spsr &= ~PSR_C; /* carry bit */ break; case ERESTART: /* * Reconstruct the pc to point at the swi. */ frame->tf_pc -= 12; break; case EJUSTRETURN: /* nothing to do */ break; default: bad: frame->tf_r0 = error; frame->tf_spsr |= PSR_C; /* carry bit */ break; } mi_syscall_return(p, code, error, rval); } void child_return(void *arg) { struct proc *p = arg; struct trapframe *frame = p->p_addr->u_pcb.pcb_tf; frame->tf_r0 = 0; frame->tf_spsr &= ~PSR_C; /* carry bit */ KERNEL_UNLOCK(); mi_child_return(p); }