Implement syscall_intern for sh3.
This commit is contained in:
parent
f5546fc71e
commit
51d0cd96db
@ -1,4 +1,4 @@
|
|||||||
# $NetBSD: files.sh3,v 1.30 2003/07/27 01:19:31 thorpej Exp $
|
# $NetBSD: files.sh3,v 1.31 2005/07/10 22:27:20 uwe Exp $
|
||||||
#
|
#
|
||||||
|
|
||||||
defflag opt_cputype.h SH3 SH4
|
defflag opt_cputype.h SH3 SH4
|
||||||
@ -23,6 +23,7 @@ file arch/sh3/sh3/pmap.c
|
|||||||
file arch/sh3/sh3/process_machdep.c
|
file arch/sh3/sh3/process_machdep.c
|
||||||
file arch/sh3/sh3/sh3_machdep.c
|
file arch/sh3/sh3/sh3_machdep.c
|
||||||
file arch/sh3/sh3/sys_machdep.c
|
file arch/sh3/sh3/sys_machdep.c
|
||||||
|
file arch/sh3/sh3/syscall.c
|
||||||
file arch/sh3/sh3/vm_machdep.c
|
file arch/sh3/sh3/vm_machdep.c
|
||||||
file arch/sh3/sh3/cache.c
|
file arch/sh3/sh3/cache.c
|
||||||
file arch/sh3/sh3/cache_sh3.c sh3
|
file arch/sh3/sh3/cache_sh3.c sh3
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: proc.h,v 1.8 2005/07/10 16:21:01 uwe Exp $ */
|
/* $NetBSD: proc.h,v 1.9 2005/07/10 22:27:20 uwe Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
|
||||||
@ -59,6 +59,8 @@ struct mdlwp {
|
|||||||
#define MDP_USEDFPU 0x0001 /* has used the FPU */
|
#define MDP_USEDFPU 0x0001 /* has used the FPU */
|
||||||
|
|
||||||
struct mdproc {
|
struct mdproc {
|
||||||
|
void (*md_syscall)(struct lwp *, struct trapframe *);
|
||||||
|
|
||||||
volatile int md_astpending; /* AST pending on return to userland */
|
volatile int md_astpending; /* AST pending on return to userland */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: types.h,v 1.20 2005/07/10 16:24:29 uwe Exp $ */
|
/* $NetBSD: types.h,v 1.21 2005/07/10 22:27:20 uwe Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1990 The Regents of the University of California.
|
* Copyright (c) 1990 The Regents of the University of California.
|
||||||
@ -66,6 +66,7 @@ typedef volatile unsigned char __cpu_simple_lock_t;
|
|||||||
|
|
||||||
#define __HAVE_AST_PERPROC
|
#define __HAVE_AST_PERPROC
|
||||||
#define __HAVE_GENERIC_SOFT_INTERRUPTS
|
#define __HAVE_GENERIC_SOFT_INTERRUPTS
|
||||||
|
#define __HAVE_SYSCALL_INTERN
|
||||||
|
|
||||||
#if defined(_KERNEL)
|
#if defined(_KERNEL)
|
||||||
#define __HAVE_RAS
|
#define __HAVE_RAS
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: exception.c,v 1.21 2005/07/01 18:01:45 christos Exp $ */
|
/* $NetBSD: exception.c,v 1.22 2005/07/10 22:27:20 uwe Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
|
||||||
@ -79,7 +79,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: exception.c,v 1.21 2005/07/01 18:01:45 christos Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: exception.c,v 1.22 2005/07/10 22:27:20 uwe Exp $");
|
||||||
|
|
||||||
#include "opt_ddb.h"
|
#include "opt_ddb.h"
|
||||||
#include "opt_kgdb.h"
|
#include "opt_kgdb.h"
|
||||||
@ -140,7 +140,6 @@ const int exp_types = sizeof exp_type / sizeof exp_type[0];
|
|||||||
|
|
||||||
void general_exception(struct lwp *, struct trapframe *, uint32_t);
|
void general_exception(struct lwp *, struct trapframe *, uint32_t);
|
||||||
void tlb_exception(struct lwp *, struct trapframe *, uint32_t);
|
void tlb_exception(struct lwp *, struct trapframe *, uint32_t);
|
||||||
void syscall(struct lwp *, struct trapframe *);
|
|
||||||
void ast(struct lwp *, struct trapframe *);
|
void ast(struct lwp *, struct trapframe *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -177,7 +176,7 @@ general_exception(struct lwp *l, struct trapframe *tf, uint32_t va)
|
|||||||
ksi.ksi_addr = (void *)tf->tf_spc;
|
ksi.ksi_addr = (void *)tf->tf_spc;
|
||||||
goto trapsignal;
|
goto trapsignal;
|
||||||
} else {
|
} else {
|
||||||
syscall(l, tf);
|
(*l->l_proc->p_md.md_syscall)(l, tf);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -259,146 +258,6 @@ general_exception(struct lwp *l, struct trapframe *tf, uint32_t va)
|
|||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* void syscall(struct lwp *l, struct trapframe *tf):
|
|
||||||
* l ... curlwp when exception occur.
|
|
||||||
* tf ... full user context.
|
|
||||||
* System call request from POSIX system call gate interface to kernel.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
syscall(struct lwp *l, struct trapframe *tf)
|
|
||||||
{
|
|
||||||
struct proc *p = l->l_proc;
|
|
||||||
caddr_t params;
|
|
||||||
const struct sysent *callp;
|
|
||||||
int error, opc, nsys;
|
|
||||||
size_t argsize;
|
|
||||||
register_t code, args[8], rval[2], ocode;
|
|
||||||
|
|
||||||
uvmexp.syscalls++;
|
|
||||||
|
|
||||||
opc = tf->tf_spc;
|
|
||||||
ocode = code = tf->tf_r0;
|
|
||||||
|
|
||||||
nsys = p->p_emul->e_nsysent;
|
|
||||||
callp = p->p_emul->e_sysent;
|
|
||||||
|
|
||||||
params = (caddr_t)tf->tf_r15;
|
|
||||||
|
|
||||||
switch (code) {
|
|
||||||
case SYS_syscall:
|
|
||||||
/*
|
|
||||||
* Code is first argument, followed by actual args.
|
|
||||||
*/
|
|
||||||
code = tf->tf_r4; /* fuword(params); */
|
|
||||||
/* params += sizeof(int); */
|
|
||||||
break;
|
|
||||||
case SYS___syscall:
|
|
||||||
/*
|
|
||||||
* Like syscall, but code is a quad, so as to maintain
|
|
||||||
* quad alignment for the rest of the arguments.
|
|
||||||
*/
|
|
||||||
if (callp != sysent)
|
|
||||||
break;
|
|
||||||
/* fuword(params + _QUAD_LOWWORD * sizeof(int)); */
|
|
||||||
#if _BYTE_ORDER == BIG_ENDIAN
|
|
||||||
code = tf->tf_r5;
|
|
||||||
#else
|
|
||||||
code = tf->tf_r4;
|
|
||||||
#endif
|
|
||||||
/* params += sizeof(quad_t); */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (code < 0 || code >= nsys)
|
|
||||||
callp += p->p_emul->e_nosys; /* illegal */
|
|
||||||
else
|
|
||||||
callp += code;
|
|
||||||
argsize = callp->sy_argsize;
|
|
||||||
|
|
||||||
if (ocode == SYS_syscall) {
|
|
||||||
if (argsize) {
|
|
||||||
args[0] = tf->tf_r5;
|
|
||||||
args[1] = tf->tf_r6;
|
|
||||||
args[2] = tf->tf_r7;
|
|
||||||
if (argsize > 3 * sizeof(int)) {
|
|
||||||
argsize -= 3 * sizeof(int);
|
|
||||||
error = copyin(params, (caddr_t)&args[3],
|
|
||||||
argsize);
|
|
||||||
} else
|
|
||||||
error = 0;
|
|
||||||
} else
|
|
||||||
error = 0;
|
|
||||||
}
|
|
||||||
else if (ocode == SYS___syscall) {
|
|
||||||
if (argsize) {
|
|
||||||
args[0] = tf->tf_r6;
|
|
||||||
args[1] = tf->tf_r7;
|
|
||||||
if (argsize > 2 * sizeof(int)) {
|
|
||||||
argsize -= 2 * sizeof(int);
|
|
||||||
error = copyin(params, (caddr_t)&args[2],
|
|
||||||
argsize);
|
|
||||||
} else
|
|
||||||
error = 0;
|
|
||||||
} else
|
|
||||||
error = 0;
|
|
||||||
} else {
|
|
||||||
if (argsize) {
|
|
||||||
args[0] = tf->tf_r4;
|
|
||||||
args[1] = tf->tf_r5;
|
|
||||||
args[2] = tf->tf_r6;
|
|
||||||
args[3] = tf->tf_r7;
|
|
||||||
if (argsize > 4 * sizeof(int)) {
|
|
||||||
argsize -= 4 * sizeof(int);
|
|
||||||
error = copyin(params, (caddr_t)&args[4],
|
|
||||||
argsize);
|
|
||||||
} else
|
|
||||||
error = 0;
|
|
||||||
} else
|
|
||||||
error = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
goto bad;
|
|
||||||
|
|
||||||
if ((error = trace_enter(l, code, code, NULL, args)) != 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
rval[0] = 0;
|
|
||||||
rval[1] = tf->tf_r1;
|
|
||||||
error = (*callp->sy_call)(l, args, rval);
|
|
||||||
out:
|
|
||||||
switch (error) {
|
|
||||||
case 0:
|
|
||||||
tf->tf_r0 = rval[0];
|
|
||||||
tf->tf_r1 = rval[1];
|
|
||||||
tf->tf_ssr |= PSL_TBIT; /* T bit */
|
|
||||||
|
|
||||||
break;
|
|
||||||
case ERESTART:
|
|
||||||
/* 2 = TRAPA instruction size */
|
|
||||||
tf->tf_spc = opc - 2;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case EJUSTRETURN:
|
|
||||||
/* nothing to do */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
bad:
|
|
||||||
if (p->p_emul->e_errno)
|
|
||||||
error = p->p_emul->e_errno[error];
|
|
||||||
tf->tf_r0 = error;
|
|
||||||
tf->tf_ssr &= ~PSL_TBIT; /* T bit */
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
trace_exit(l, code, args, rval, error);
|
|
||||||
|
|
||||||
userret(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void tlb_exception(struct lwp *l, struct trapframe *tf, uint32_t va):
|
* void tlb_exception(struct lwp *l, struct trapframe *tf, uint32_t va):
|
||||||
|
402
sys/arch/sh3/sh3/syscall.c
Normal file
402
sys/arch/sh3/sh3/syscall.c
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
/* $NetBSD: syscall.c,v 1.1 2005/07/10 22:27:20 uwe Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
|
||||||
|
* Copyright (c) 1990 The Regents of the University of California.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* the University of Utah, and William Jolitz.
|
||||||
|
*
|
||||||
|
* 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. Neither the name of the University 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 REGENTS 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 REGENTS 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.
|
||||||
|
*
|
||||||
|
* @(#)trap.c 7.4 (Berkeley) 5/13/91
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1995 Charles M. Hannum. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* the University of Utah, and William Jolitz.
|
||||||
|
*
|
||||||
|
* 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 University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
|
||||||
|
*
|
||||||
|
* @(#)trap.c 7.4 (Berkeley) 5/13/91
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SH3 Trap and System call handling
|
||||||
|
*
|
||||||
|
* T.Horiuchi 1998.06.8
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "opt_ktrace.h"
|
||||||
|
#include "opt_syscall_debug.h"
|
||||||
|
#include "opt_systrace.h"
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/sa.h>
|
||||||
|
#include <sys/savar.h>
|
||||||
|
#ifdef KTRACE
|
||||||
|
#include <sys/ktrace.h>
|
||||||
|
#endif
|
||||||
|
#ifdef SYSTRACE
|
||||||
|
#include <sys/systrace.h>
|
||||||
|
#endif
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
#include <sh3/userret.h>
|
||||||
|
|
||||||
|
#include <uvm/uvm_extern.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void syscall_plain(struct lwp *, struct trapframe *);
|
||||||
|
#if defined(KTRACE) || defined(SYSTRACE)
|
||||||
|
static void syscall_fancy(struct lwp *, struct trapframe *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
syscall_intern(struct proc *p)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef KTRACE
|
||||||
|
if (p->p_traceflag & (KTRFAC_SYSCALL | KTRFAC_SYSRET)) {
|
||||||
|
p->p_md.md_syscall = syscall_fancy;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef SYSTRACE
|
||||||
|
if (ISSET(p->p_flag, P_SYSTRACE)) {
|
||||||
|
p->p_md.md_syscall = syscall_fancy;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
p->p_md.md_syscall = syscall_plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* System call request from POSIX system call gate interface to kernel.
|
||||||
|
* l ... curlwp when trap occurs.
|
||||||
|
* tf ... full user context.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
syscall_plain(struct lwp *l, struct trapframe *tf)
|
||||||
|
{
|
||||||
|
struct proc *p = l->l_proc;
|
||||||
|
caddr_t params;
|
||||||
|
const struct sysent *callp;
|
||||||
|
int error, opc, nsys;
|
||||||
|
size_t argsize;
|
||||||
|
register_t code, args[8], rval[2], ocode;
|
||||||
|
|
||||||
|
uvmexp.syscalls++;
|
||||||
|
|
||||||
|
opc = tf->tf_spc;
|
||||||
|
ocode = code = tf->tf_r0;
|
||||||
|
|
||||||
|
nsys = p->p_emul->e_nsysent;
|
||||||
|
callp = p->p_emul->e_sysent;
|
||||||
|
|
||||||
|
params = (caddr_t)tf->tf_r15;
|
||||||
|
|
||||||
|
switch (code) {
|
||||||
|
case SYS_syscall:
|
||||||
|
/*
|
||||||
|
* Code is first argument, followed by actual args.
|
||||||
|
*/
|
||||||
|
code = tf->tf_r4; /* fuword(params); */
|
||||||
|
/* params += sizeof(int); */
|
||||||
|
break;
|
||||||
|
case SYS___syscall:
|
||||||
|
/*
|
||||||
|
* Like syscall, but code is a quad, so as to maintain
|
||||||
|
* quad alignment for the rest of the arguments.
|
||||||
|
*/
|
||||||
|
if (callp != sysent)
|
||||||
|
break;
|
||||||
|
/* fuword(params + _QUAD_LOWWORD * sizeof(int)); */
|
||||||
|
#if _BYTE_ORDER == BIG_ENDIAN
|
||||||
|
code = tf->tf_r5;
|
||||||
|
#else
|
||||||
|
code = tf->tf_r4;
|
||||||
|
#endif
|
||||||
|
/* params += sizeof(quad_t); */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (code < 0 || code >= nsys)
|
||||||
|
callp += p->p_emul->e_nosys; /* illegal */
|
||||||
|
else
|
||||||
|
callp += code;
|
||||||
|
argsize = callp->sy_argsize;
|
||||||
|
|
||||||
|
if (ocode == SYS_syscall) {
|
||||||
|
if (argsize) {
|
||||||
|
args[0] = tf->tf_r5;
|
||||||
|
args[1] = tf->tf_r6;
|
||||||
|
args[2] = tf->tf_r7;
|
||||||
|
if (argsize > 3 * sizeof(int)) {
|
||||||
|
argsize -= 3 * sizeof(int);
|
||||||
|
error = copyin(params, (caddr_t)&args[3],
|
||||||
|
argsize);
|
||||||
|
} else
|
||||||
|
error = 0;
|
||||||
|
} else
|
||||||
|
error = 0;
|
||||||
|
}
|
||||||
|
else if (ocode == SYS___syscall) {
|
||||||
|
if (argsize) {
|
||||||
|
args[0] = tf->tf_r6;
|
||||||
|
args[1] = tf->tf_r7;
|
||||||
|
if (argsize > 2 * sizeof(int)) {
|
||||||
|
argsize -= 2 * sizeof(int);
|
||||||
|
error = copyin(params, (caddr_t)&args[2],
|
||||||
|
argsize);
|
||||||
|
} else
|
||||||
|
error = 0;
|
||||||
|
} else
|
||||||
|
error = 0;
|
||||||
|
} else {
|
||||||
|
if (argsize) {
|
||||||
|
args[0] = tf->tf_r4;
|
||||||
|
args[1] = tf->tf_r5;
|
||||||
|
args[2] = tf->tf_r6;
|
||||||
|
args[3] = tf->tf_r7;
|
||||||
|
if (argsize > 4 * sizeof(int)) {
|
||||||
|
argsize -= 4 * sizeof(int);
|
||||||
|
error = copyin(params, (caddr_t)&args[4],
|
||||||
|
argsize);
|
||||||
|
} else
|
||||||
|
error = 0;
|
||||||
|
} else
|
||||||
|
error = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
rval[0] = 0;
|
||||||
|
rval[1] = tf->tf_r1;
|
||||||
|
error = (*callp->sy_call)(l, args, rval);
|
||||||
|
|
||||||
|
switch (error) {
|
||||||
|
case 0:
|
||||||
|
tf->tf_r0 = rval[0];
|
||||||
|
tf->tf_r1 = rval[1];
|
||||||
|
tf->tf_ssr |= PSL_TBIT; /* T bit */
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ERESTART:
|
||||||
|
/* 2 = TRAPA instruction size */
|
||||||
|
tf->tf_spc = opc - 2;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EJUSTRETURN:
|
||||||
|
/* nothing to do */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bad:
|
||||||
|
if (p->p_emul->e_errno)
|
||||||
|
error = p->p_emul->e_errno[error];
|
||||||
|
tf->tf_r0 = error;
|
||||||
|
tf->tf_ssr &= ~PSL_TBIT; /* T bit */
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
userret(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(KTRACE) || defined(SYSTRACE)
|
||||||
|
/*
|
||||||
|
* Like syscall_plain but with trace_enter/trace_exit.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
syscall_fancy(struct lwp *l, struct trapframe *tf)
|
||||||
|
{
|
||||||
|
struct proc *p = l->l_proc;
|
||||||
|
caddr_t params;
|
||||||
|
const struct sysent *callp;
|
||||||
|
int error, opc, nsys;
|
||||||
|
size_t argsize;
|
||||||
|
register_t code, args[8], rval[2], ocode;
|
||||||
|
|
||||||
|
uvmexp.syscalls++;
|
||||||
|
|
||||||
|
opc = tf->tf_spc;
|
||||||
|
ocode = code = tf->tf_r0;
|
||||||
|
|
||||||
|
nsys = p->p_emul->e_nsysent;
|
||||||
|
callp = p->p_emul->e_sysent;
|
||||||
|
|
||||||
|
params = (caddr_t)tf->tf_r15;
|
||||||
|
|
||||||
|
switch (code) {
|
||||||
|
case SYS_syscall:
|
||||||
|
/*
|
||||||
|
* Code is first argument, followed by actual args.
|
||||||
|
*/
|
||||||
|
code = tf->tf_r4; /* fuword(params); */
|
||||||
|
/* params += sizeof(int); */
|
||||||
|
break;
|
||||||
|
case SYS___syscall:
|
||||||
|
/*
|
||||||
|
* Like syscall, but code is a quad, so as to maintain
|
||||||
|
* quad alignment for the rest of the arguments.
|
||||||
|
*/
|
||||||
|
if (callp != sysent)
|
||||||
|
break;
|
||||||
|
/* fuword(params + _QUAD_LOWWORD * sizeof(int)); */
|
||||||
|
#if _BYTE_ORDER == BIG_ENDIAN
|
||||||
|
code = tf->tf_r5;
|
||||||
|
#else
|
||||||
|
code = tf->tf_r4;
|
||||||
|
#endif
|
||||||
|
/* params += sizeof(quad_t); */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (code < 0 || code >= nsys)
|
||||||
|
callp += p->p_emul->e_nosys; /* illegal */
|
||||||
|
else
|
||||||
|
callp += code;
|
||||||
|
argsize = callp->sy_argsize;
|
||||||
|
|
||||||
|
if (ocode == SYS_syscall) {
|
||||||
|
if (argsize) {
|
||||||
|
args[0] = tf->tf_r5;
|
||||||
|
args[1] = tf->tf_r6;
|
||||||
|
args[2] = tf->tf_r7;
|
||||||
|
if (argsize > 3 * sizeof(int)) {
|
||||||
|
argsize -= 3 * sizeof(int);
|
||||||
|
error = copyin(params, (caddr_t)&args[3],
|
||||||
|
argsize);
|
||||||
|
} else
|
||||||
|
error = 0;
|
||||||
|
} else
|
||||||
|
error = 0;
|
||||||
|
}
|
||||||
|
else if (ocode == SYS___syscall) {
|
||||||
|
if (argsize) {
|
||||||
|
args[0] = tf->tf_r6;
|
||||||
|
args[1] = tf->tf_r7;
|
||||||
|
if (argsize > 2 * sizeof(int)) {
|
||||||
|
argsize -= 2 * sizeof(int);
|
||||||
|
error = copyin(params, (caddr_t)&args[2],
|
||||||
|
argsize);
|
||||||
|
} else
|
||||||
|
error = 0;
|
||||||
|
} else
|
||||||
|
error = 0;
|
||||||
|
} else {
|
||||||
|
if (argsize) {
|
||||||
|
args[0] = tf->tf_r4;
|
||||||
|
args[1] = tf->tf_r5;
|
||||||
|
args[2] = tf->tf_r6;
|
||||||
|
args[3] = tf->tf_r7;
|
||||||
|
if (argsize > 4 * sizeof(int)) {
|
||||||
|
argsize -= 4 * sizeof(int);
|
||||||
|
error = copyin(params, (caddr_t)&args[4],
|
||||||
|
argsize);
|
||||||
|
} else
|
||||||
|
error = 0;
|
||||||
|
} else
|
||||||
|
error = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
if ((error = trace_enter(l, code, code, NULL, args)) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
rval[0] = 0;
|
||||||
|
rval[1] = tf->tf_r1;
|
||||||
|
error = (*callp->sy_call)(l, args, rval);
|
||||||
|
out:
|
||||||
|
switch (error) {
|
||||||
|
case 0:
|
||||||
|
tf->tf_r0 = rval[0];
|
||||||
|
tf->tf_r1 = rval[1];
|
||||||
|
tf->tf_ssr |= PSL_TBIT; /* T bit */
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ERESTART:
|
||||||
|
/* 2 = TRAPA instruction size */
|
||||||
|
tf->tf_spc = opc - 2;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EJUSTRETURN:
|
||||||
|
/* nothing to do */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bad:
|
||||||
|
if (p->p_emul->e_errno)
|
||||||
|
error = p->p_emul->e_errno[error];
|
||||||
|
tf->tf_r0 = error;
|
||||||
|
tf->tf_ssr &= ~PSL_TBIT; /* T bit */
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
trace_exit(l, code, args, rval, error);
|
||||||
|
|
||||||
|
userret(l);
|
||||||
|
}
|
||||||
|
#endif /* KTRACE || SYSTRACE */
|
Loading…
Reference in New Issue
Block a user