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
|
||||
@ -23,6 +23,7 @@ file arch/sh3/sh3/pmap.c
|
||||
file arch/sh3/sh3/process_machdep.c
|
||||
file arch/sh3/sh3/sh3_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/cache.c
|
||||
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.
|
||||
@ -59,6 +59,8 @@ struct mdlwp {
|
||||
#define MDP_USEDFPU 0x0001 /* has used the FPU */
|
||||
|
||||
struct mdproc {
|
||||
void (*md_syscall)(struct lwp *, struct trapframe *);
|
||||
|
||||
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.
|
||||
@ -66,6 +66,7 @@ typedef volatile unsigned char __cpu_simple_lock_t;
|
||||
|
||||
#define __HAVE_AST_PERPROC
|
||||
#define __HAVE_GENERIC_SOFT_INTERRUPTS
|
||||
#define __HAVE_SYSCALL_INTERN
|
||||
|
||||
#if defined(_KERNEL)
|
||||
#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.
|
||||
@ -79,7 +79,7 @@
|
||||
*/
|
||||
|
||||
#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_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 tlb_exception(struct lwp *, struct trapframe *, uint32_t);
|
||||
void syscall(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;
|
||||
goto trapsignal;
|
||||
} else {
|
||||
syscall(l, tf);
|
||||
(*l->l_proc->p_md.md_syscall)(l, tf);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -259,146 +258,6 @@ general_exception(struct lwp *l, struct trapframe *tf, uint32_t va)
|
||||
/*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):
|
||||
|
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