Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/alpha/alpha Do the fast/slow path separation, a la ...



details:   https://anonhg.NetBSD.org/src/rev/9f0dbe545f86
branches:  trunk
changeset: 500531:9f0dbe545f86
user:      mycroft <mycroft%NetBSD.org@localhost>
date:      Wed Dec 13 07:53:58 2000 +0000

description:
Do the fast/slow path separation, a la x86.

diffstat:

 sys/arch/alpha/alpha/osf1_syscall.c |  110 +++++++++++++++++++++++++++++++++-
 sys/arch/alpha/alpha/syscall.c      |  113 ++++++++++++++++++++++++++++++++++-
 2 files changed, 213 insertions(+), 10 deletions(-)

diffs (291 lines):

diff -r 22562ca25d1e -r 9f0dbe545f86 sys/arch/alpha/alpha/osf1_syscall.c
--- a/sys/arch/alpha/alpha/osf1_syscall.c       Wed Dec 13 07:50:48 2000 +0000
+++ b/sys/arch/alpha/alpha/osf1_syscall.c       Wed Dec 13 07:53:58 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: osf1_syscall.c,v 1.1 2000/12/13 03:16:37 mycroft Exp $ */
+/* $NetBSD: osf1_syscall.c,v 1.2 2000/12/13 07:53:58 mycroft Exp $ */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -99,7 +99,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: osf1_syscall.c,v 1.1 2000/12/13 03:16:37 mycroft Exp $");
+__KERNEL_RCSID(0, "$NetBSD: osf1_syscall.c,v 1.2 2000/12/13 07:53:58 mycroft Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -123,14 +123,20 @@
 
 void   userret __P((struct proc *));
 void   osf1_syscall_intern __P((struct proc *));
-void   osf1_syscall __P((struct proc *, u_int64_t, struct trapframe *));
+void   osf1_syscall_plain __P((struct proc *, u_int64_t, struct trapframe *));
+void   osf1_syscall_fancy __P((struct proc *, u_int64_t, struct trapframe *));
 
 void
 osf1_syscall_intern(p)
        struct proc *p;
 {
 
-       p->p_md.md_syscall = osf1_syscall;
+#ifdef KTRACE
+       if (p->p_traceflag & (KTRFAC_SYSCALL | KTRFAC_SYSRET))
+               p->p_md.md_syscall = osf1_syscall_fancy;
+       else
+#endif
+               p->p_md.md_syscall = osf1_syscall_plain;
 }
 
 /*
@@ -147,7 +153,101 @@
  * a3, and v0 from the frame before returning to the user process.
  */
 void
-osf1_syscall(p, code, framep)
+osf1_syscall_plain(p, code, framep)
+       struct proc *p;
+       u_int64_t code;
+       struct trapframe *framep;
+{
+       const struct sysent *callp;
+       int error;
+       u_int64_t rval[2];
+       u_int64_t *args, copyargs[10];                          /* XXX */
+       u_int hidden, nargs;
+
+       KERNEL_PROC_LOCK(p);
+
+       uvmexp.syscalls++;
+       p->p_md.md_tf = framep;
+
+       callp = p->p_emul->e_sysent;
+
+       switch (code) {
+       case OSF1_SYS_syscall:
+               /* OSF/1 syscall() */
+               code = framep->tf_regs[FRAME_A0];
+               hidden = 1;
+               break;
+       default:
+               hidden = 0;
+               break;
+       }
+
+       code &= (OSF1_SYS_NSYSENT - 1);
+       callp += code;
+
+       nargs = callp->sy_narg + hidden;
+       switch (nargs) {
+       default:
+               error = copyin((caddr_t)alpha_pal_rdusp(), &copyargs[6],
+                   (nargs - 6) * sizeof(u_int64_t));
+               if (error)
+                       goto bad;
+       case 6: 
+               copyargs[5] = framep->tf_regs[FRAME_A5];
+       case 5: 
+               copyargs[4] = framep->tf_regs[FRAME_A4];
+       case 4: 
+               copyargs[3] = framep->tf_regs[FRAME_A3];
+               copyargs[2] = framep->tf_regs[FRAME_A2];
+               copyargs[1] = framep->tf_regs[FRAME_A1];
+               copyargs[0] = framep->tf_regs[FRAME_A0];
+               args = copyargs;
+               break;
+       case 3: 
+       case 2: 
+       case 1: 
+       case 0:
+               args = &framep->tf_regs[FRAME_A0];
+               break;
+       }
+       args += hidden;
+
+#ifdef SYSCALL_DEBUG
+       scdebug_call(p, code, args);
+#endif
+
+       rval[0] = 0;
+       rval[1] = 0;
+       error = (*callp->sy_call)(p, args, rval);
+
+       switch (error) {
+       case 0:
+               framep->tf_regs[FRAME_V0] = rval[0];
+               framep->tf_regs[FRAME_A4] = rval[1];
+               framep->tf_regs[FRAME_A3] = 0;
+               break;
+       case ERESTART:
+               framep->tf_regs[FRAME_PC] -= 4;
+               break;
+       case EJUSTRETURN:
+               break;
+       default:
+       bad:
+               error = osf1_errno_rxlist[error];
+               framep->tf_regs[FRAME_V0] = error;
+               framep->tf_regs[FRAME_A3] = 1;
+               break;
+       }
+
+#ifdef SYSCALL_DEBUG
+       scdebug_ret(p, code, error, rval);
+#endif
+       KERNEL_PROC_UNLOCK(p);
+       userret(p);
+}
+
+void
+osf1_syscall_fancy(p, code, framep)
        struct proc *p;
        u_int64_t code;
        struct trapframe *framep;
diff -r 22562ca25d1e -r 9f0dbe545f86 sys/arch/alpha/alpha/syscall.c
--- a/sys/arch/alpha/alpha/syscall.c    Wed Dec 13 07:50:48 2000 +0000
+++ b/sys/arch/alpha/alpha/syscall.c    Wed Dec 13 07:53:58 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: syscall.c,v 1.1 2000/12/13 03:16:37 mycroft Exp $ */
+/* $NetBSD: syscall.c,v 1.2 2000/12/13 07:53:58 mycroft Exp $ */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -99,7 +99,7 @@
 
 #include <sys/cdefs.h>                 /* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.1 2000/12/13 03:16:37 mycroft Exp $");
+__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.2 2000/12/13 07:53:58 mycroft Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -119,14 +119,20 @@
 
 void   userret __P((struct proc *));
 void   syscall_intern __P((struct proc *));
-void   syscall __P((struct proc *, u_int64_t, struct trapframe *));
+void   syscall_plain __P((struct proc *, u_int64_t, struct trapframe *));
+void   syscall_fancy __P((struct proc *, u_int64_t, struct trapframe *));
 
 void
 syscall_intern(p)
        struct proc *p;
 {
 
-       p->p_md.md_syscall = syscall;
+#ifdef KTRACE
+       if (p->p_traceflag & (KTRFAC_SYSCALL | KTRFAC_SYSRET))
+               p->p_md.md_syscall = syscall_fancy;
+       else
+#endif
+               p->p_md.md_syscall = syscall_plain;
 }
 
 /*
@@ -143,7 +149,104 @@
  * a3, and v0 from the frame before returning to the user process.
  */
 void
-syscall(p, code, framep)
+syscall_plain(p, code, framep)
+       struct proc *p;
+       u_int64_t code;
+       struct trapframe *framep;
+{
+       const struct sysent *callp;
+       int error;
+       u_int64_t rval[2];
+       u_int64_t *args, copyargs[10];                          /* XXX */
+       u_int hidden, nargs;
+
+       KERNEL_PROC_LOCK(p);
+
+       uvmexp.syscalls++;
+       p->p_md.md_tf = framep;
+
+       callp = p->p_emul->e_sysent;
+
+       switch (code) {
+       case SYS_syscall:
+       case SYS___syscall:
+               /*
+                * syscall() and __syscall() are handled the same on
+                * the alpha, as everything is 64-bit aligned, anyway.
+                */
+               code = framep->tf_regs[FRAME_A0];
+               hidden = 1;
+               break;
+       default:
+               hidden = 0;
+               break;
+       }
+
+       code &= (SYS_NSYSENT - 1);
+       callp += code;
+
+       nargs = callp->sy_narg + hidden;
+       switch (nargs) {
+       default:
+               error = copyin((caddr_t)alpha_pal_rdusp(), &copyargs[6],
+                   (nargs - 6) * sizeof(u_int64_t));
+               if (error)
+                       goto bad;
+       case 6: 
+               copyargs[5] = framep->tf_regs[FRAME_A5];
+       case 5: 
+               copyargs[4] = framep->tf_regs[FRAME_A4];
+       case 4: 
+               copyargs[3] = framep->tf_regs[FRAME_A3];
+               copyargs[2] = framep->tf_regs[FRAME_A2];
+               copyargs[1] = framep->tf_regs[FRAME_A1];
+               copyargs[0] = framep->tf_regs[FRAME_A0];
+               args = copyargs;
+               break;
+       case 3: 
+       case 2: 
+       case 1: 
+       case 0:
+               args = &framep->tf_regs[FRAME_A0];
+               break;
+       }
+       args += hidden;
+
+#ifdef SYSCALL_DEBUG
+       scdebug_call(p, code, args);
+#endif
+
+       rval[0] = 0;
+       rval[1] = 0;
+       error = (*callp->sy_call)(p, args, rval);
+
+       switch (error) {
+       case 0:
+               framep->tf_regs[FRAME_V0] = rval[0];
+               framep->tf_regs[FRAME_A4] = rval[1];
+               framep->tf_regs[FRAME_A3] = 0;
+               break;
+       case ERESTART:
+               framep->tf_regs[FRAME_PC] -= 4;
+               break;
+       case EJUSTRETURN:
+               break;
+       default:
+       bad:
+               framep->tf_regs[FRAME_V0] = error;
+               framep->tf_regs[FRAME_A3] = 1;
+               break;
+       }
+
+#ifdef SYSCALL_DEBUG
+       scdebug_ret(p, code, error, rval);
+#endif
+       KERNEL_PROC_UNLOCK(p);
+       userret(p);
+}
+
+void
+syscall_fancy(p, code, framep)
        struct proc *p;
        u_int64_t code;
        struct trapframe *framep;



Home | Main Index | Thread Index | Old Index