Separate out syscall() out into three parts:

swi_handler() does stuff that all SWIs will need, then calls
   curproc->p_emul->e_syscall.
  syscall() handles native NetBSD system calls.
  linux_syscall() handles Linux system calls.
This commit is contained in:
bjh21 2002-01-17 17:26:03 +00:00
parent 16ee93eb67
commit 0598bbd10f
5 changed files with 186 additions and 34 deletions

View File

@ -0,0 +1,160 @@
/* $NetBSD: linux_syscall.c,v 1.1 2002/01/17 17:26:03 bjh21 Exp $ */
/*-
* Copyright (c) 2000 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 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.
*
* ARMLinux emulation: syscall entry handling
*/
#include "opt_ktrace.h"
#include "opt_syscall_debug.h"
#include <sys/param.h>
__RCSID("$NetBSD: linux_syscall.c,v 1.1 2002/01/17 17:26:03 bjh21 Exp $");
#include <sys/device.h>
#include <sys/errno.h>
#include <sys/kernel.h>
#include <sys/reboot.h>
#include <sys/signalvar.h>
#include <sys/systm.h>
#include <sys/user.h>
#ifdef KTRACE
#include <sys/ktrace.h>
#endif
#include <uvm/uvm_extern.h>
#include <machine/cpu.h>
#include <machine/frame.h>
#include <machine/pcb.h>
#include <arm/swi.h>
#include <compat/linux/common/linux_errno.h>
#include <compat/linux/linux_syscall.h>
void
linux_syscall(trapframe_t *frame, struct proc *p, u_int32_t insn)
{
const struct sysent *callp;
int code, error;
u_int nargs;
register_t *args, rval[2];
code = insn & (LINUX_SYS_NSYSENT - 1);
/* Linux passes all arguments in order in registers, which is nice. */
args = &frame->tf_r0;
callp = p->p_emul->e_sysent + code;
nargs = callp->sy_argsize / sizeof(register_t);
#ifdef SYSCALL_DEBUG
scdebug_call(p, code, args);
#endif
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSCALL))
ktrsyscall(p, code, nargs * sizeof(register_t), args);
#endif
rval[0] = 0;
rval[1] = 0;
error = (*callp->sy_call)(p, args, rval);
switch (error) {
case 0:
frame->tf_r0 = rval[0];
break;
case ERESTART:
/* Reconstruct the pc to point at the swi. */
frame->tf_pc -= INSN_SIZE;
break;
case EJUSTRETURN:
/* nothing to do */
break;
default:
error = native_to_linux_errno[error];
frame->tf_r0 = error;
break;
}
#ifdef SYSCALL_DEBUG
scdebug_ret(p, code, error, rval);
#endif
userret(p);
#ifdef KTRACE
if (KTRPOINT(p, KTR_SYSRET))
ktrsysret(p, code, error, rval[0]);
#endif
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: syscall.c,v 1.4 2002/01/14 23:14:33 bjh21 Exp $ */
/* $NetBSD: syscall.c,v 1.5 2002/01/17 17:26:03 bjh21 Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -76,13 +76,12 @@
* Created : 09/11/94
*/
#include "opt_compat_linux.h"
#include "opt_ktrace.h"
#include "opt_syscall_debug.h"
#include <sys/param.h>
__RCSID("$NetBSD: syscall.c,v 1.4 2002/01/14 23:14:33 bjh21 Exp $");
__RCSID("$NetBSD: syscall.c,v 1.5 2002/01/17 17:26:03 bjh21 Exp $");
#include <sys/device.h>
#include <sys/errno.h>
@ -112,17 +111,11 @@ struct evcnt arm700bugcount =
EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "cpu", "arm700swibug");
#endif
#define MAXARGS 8
void
syscall(trapframe_t *frame)
swi_handler(trapframe_t *frame)
{
const struct sysent *callp;
struct proc *p;
u_int32_t insn;
int code, error;
u_int nap, nargs;
register_t *ap, *args, copyargs[MAXARGS], rval[2];
/*
* Enable interrupts if they were enabled before the exception.
@ -148,7 +141,6 @@ syscall(trapframe_t *frame)
insn = *(u_int32_t *)((frame->tf_r15 & R15_PC) - INSN_SIZE);
#endif
uvmexp.syscalls++;
p = curproc;
p->p_addr->u_pcb.pcb_tf = frame;
@ -183,8 +175,25 @@ syscall(trapframe_t *frame)
}
#endif /* CPU_ARM7 */
uvmexp.syscalls++;
(*(void(*)(struct trapframe *, struct proc *, u_int32_t))
(p->p_emul->e_syscall))(frame, p, insn);
}
#define MAXARGS 8
void
syscall(struct trapframe *frame, struct proc *p, u_int32_t insn)
{
const struct sysent *callp;
int code, error;
u_int nap, nargs;
register_t *ap, *args, copyargs[MAXARGS], rval[2];
switch (insn & SWI_OS_MASK) { /* Which OS is the SWI from? */
case SWI_OS_ARM: /* ARM-defined SWIs */
code = insn & 0x00ffffff;
switch (code) {
case SWI_IMB:
case SWI_IMBrange:
@ -205,11 +214,6 @@ syscall(trapframe_t *frame)
case SWI_OS_NETBSD: /* New official NetBSD range. */
nap = 4;
break;
#ifdef COMPAT_LINUX
case SWI_OS_LINUX:
nap = 8;
break;
#endif
default:
/* Undefined so illegal instruction */
trapsignal(p, SIGILL, insn);
@ -228,11 +232,6 @@ syscall(trapframe_t *frame)
nap--;
break;
case SYS___syscall:
#if 0
if (!(p->p_emul->e_flags & EMUL_HAS_SYS___syscall))
break;
#endif
code = ap[_QUAD_LOWWORD];
ap += 2;
nap -= 2;

View File

@ -1,4 +1,4 @@
/* $NetBSD: exception.S,v 1.4 2002/01/14 23:21:06 bjh21 Exp $ */
/* $NetBSD: exception.S,v 1.5 2002/01/17 17:26:04 bjh21 Exp $ */
/*
* Copyright (c) 1994-1997 Mark Brinicombe.
@ -129,7 +129,7 @@ ASENTRY_NP(swi_entry)
mov r0, sp /* Pass the frame to any function */
bl _C_LABEL(syscall) /* It's a syscall ! */
bl _C_LABEL(swi_handler) /* It's a SWI ! */
ldr r5, Lastpending /* Get address of astpending */
mrs r4, cpsr_all /* Get CPSR */

View File

@ -1,4 +1,4 @@
# $NetBSD: files.arm,v 1.51 2002/01/14 23:14:33 bjh21 Exp $
# $NetBSD: files.arm,v 1.52 2002/01/17 17:26:04 bjh21 Exp $
# temporary define to allow easy moving to ../arch/arm/arm32
defflag ARM32
@ -103,4 +103,5 @@ include "compat/ossaudio/files.ossaudio"
include "compat/linux/files.linux"
include "compat/linux/arch/arm/files.linux_arm"
file arch/arm/arm/linux_sigcode.S compat_linux
file arch/arm/arm/linux_syscall.c compat_linux
file arch/arm/arm/linux_trap.c compat_linux

View File

@ -1,4 +1,4 @@
/* $NetBSD: except.c,v 1.40 2002/01/12 20:02:15 bjh21 Exp $ */
/* $NetBSD: except.c,v 1.41 2002/01/17 17:26:05 bjh21 Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000 Ben Harris
* All rights reserved.
@ -32,7 +32,7 @@
#include <sys/param.h>
__KERNEL_RCSID(0, "$NetBSD: except.c,v 1.40 2002/01/12 20:02:15 bjh21 Exp $");
__KERNEL_RCSID(0, "$NetBSD: except.c,v 1.41 2002/01/17 17:26:05 bjh21 Exp $");
#include "opt_cputypes.h"
#include "opt_ddb.h"
@ -93,14 +93,6 @@ checkvectors()
#endif
void
swi_handler(struct trapframe *tf)
{
/* XXX The type of e_syscall is all wrong. */
(*(void (*)(struct trapframe *))(curproc->p_emul->e_syscall))(tf);
}
void
prefetch_abort_handler(struct trapframe *tf)
{