Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/usermode Implement a working(!) syscall! well, it c...



details:   https://anonhg.NetBSD.org/src/rev/2bcc41d5aabb
branches:  trunk
changeset: 769412:2bcc41d5aabb
user:      reinoud <reinoud%NetBSD.org@localhost>
date:      Thu Sep 08 19:38:59 2011 +0000

description:
Implement a working(!) syscall! well, it can call a number of syscalls without
dying ;)

diffstat:

 sys/arch/usermode/include/machdep.h  |  10 +++-
 sys/arch/usermode/usermode/machdep.c |  93 ++++++++++++++++++++++++++++++++++-
 sys/arch/usermode/usermode/syscall.c |  72 +++++++++++++++++----------
 sys/arch/usermode/usermode/trap.c    |  14 +++--
 4 files changed, 150 insertions(+), 39 deletions(-)

diffs (truncated from 320 to 300 lines):

diff -r 134e63f1eba3 -r 2bcc41d5aabb sys/arch/usermode/include/machdep.h
--- a/sys/arch/usermode/include/machdep.h       Thu Sep 08 19:37:01 2011 +0000
+++ b/sys/arch/usermode/include/machdep.h       Thu Sep 08 19:38:59 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.h,v 1.1 2011/09/08 15:11:42 reinoud Exp $ */
+/* $NetBSD: machdep.h,v 1.2 2011/09/08 19:38:59 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Reinoud Zandijk <reinoud%netbsd.org@localhost>
@@ -26,6 +26,12 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-int    md_check_syscall_opcode(void *ptr);
+int    md_syscall_check_opcode(void *ptr);
+void   md_syscall_get_syscallnumber(ucontext_t *ucp, uint32_t *code);
+int    md_syscall_getargs(lwp_t *l, ucontext_t *ucp, int nargs, int argsize,
+               register_t *args);
+void   md_syscall_set_returnargs(lwp_t *l, ucontext_t *ucp, register_t *rval);
+void   md_syscall_inc_pc(ucontext_t *ucp);
+
 void   syscall(void);
 
diff -r 134e63f1eba3 -r 2bcc41d5aabb sys/arch/usermode/usermode/machdep.c
--- a/sys/arch/usermode/usermode/machdep.c      Thu Sep 08 19:37:01 2011 +0000
+++ b/sys/arch/usermode/usermode/machdep.c      Thu Sep 08 19:38:59 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.26 2011/09/08 15:10:59 reinoud Exp $ */
+/* $NetBSD: machdep.c,v 1.27 2011/09/08 19:39:00 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Reinoud Zandijk <reinoud%netbsd.org@localhost>
@@ -32,7 +32,7 @@
 #include "opt_urkelvisor.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.26 2011/09/08 15:10:59 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.27 2011/09/08 19:39:00 reinoud Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -214,13 +214,78 @@
 #endif
 }
 
+void
+md_syscall_get_syscallnumber(ucontext_t *ucp, uint32_t *code)
+{
+       uint *reg = (int *) &ucp->uc_mcontext;
+
+       *code = reg[11];                        /* EAX */
+}
 
 int
-md_check_syscall_opcode(void *ptr)
+md_syscall_getargs(lwp_t *l, ucontext_t *ucp, int nargs, int argsize,
+       register_t *args)
 {
-//     uint8_t  *p8;
+       uint *reg = (int *) &ucp->uc_mcontext;
+       register_t *sp = (register_t *) reg[17];/* ESP */
+       int ret;
+       uint i;
+
+       i = 0;
+#if 0
+       reg = (int *) &ucp->uc_mcontext;
+       /* register dump before call */
+       const char *name[] = {"GS", "FS", "ES", "DS", "EDI", "ESI", "EBP", "ESP",
+               "EBX", "EDX", "ECX", "EAX", "TRAPNO", "ERR", "EIP", "CS", "EFL",
+               "UESP", "SS"};
+
+       for (i =0; i < 19; i++)
+               printf("reg[%02d] (%6s) = %"PRIx32"\n", i, name[i], reg[i]);
+       printf("\n");
+#endif
+
+       ret = copyin(sp + 1, args, argsize);
+
+#if 0
+       for (i = 0; i < nargs+4; i++)
+               printf("stack[%02d] = %"PRIx32"\n", i, (uint) sp[i]);
+#endif
+#if 0
+       for (i = 0; i < nargs; i++)
+               printf("arg[%02d] = %"PRIx32"\n", i, (uint) args[i]);
+       printf("\n");
+#endif
+
+       return ret;
+}
+
+void
+md_syscall_set_returnargs(lwp_t *l, ucontext_t *ucp, register_t *rval)
+{
+       uint *reg = (int *) &ucp->uc_mcontext;
+
+       /* set return parameters */
+       reg[11] = rval[0];      /* EAX */
+       reg[ 9] = rval[1];      /* EDX */
+
+#if 0
+       uint i;
+       reg = (int *) &ucp->uc_mcontext;
+       /* register dump before call */
+       const char *name[] = {"GS", "FS", "ES", "DS", "EDI", "ESI", "EBP", "ESP",
+               "EBX", "EDX", "ECX", "EAX", "TRAPNO", "ERR", "EIP", "CS", "EFL",
+               "UESP", "SS"};
+
+       for (i =0; i < 19; i++)
+               printf("reg[%02d] (%6s) = %"PRIx32"\n", i, name[i], reg[i]);
+#endif
+
+}
+
+int
+md_syscall_check_opcode(void *ptr)
+{
        uint16_t *p16;
-//     uint32_t *p32;
 
        /* undefined instruction */
        p16 = (uint16_t *) ptr;
@@ -233,6 +298,24 @@
        return 0;
 }
 
+void
+md_syscall_inc_pc(ucontext_t *ucp)
+{
+       uint *reg = (int *) &ucp->uc_mcontext;
+       uint16_t *p16;
+
+       /* advance program counter */
+       p16 = (uint16_t *) reg[14];
+       if (*p16 == 0xff0f)
+               reg[14] += 2;   /* EIP */
+       if (*p16 == 0xff0b)
+               reg[14] += 2;   /* EIP */
+
+       /* TODO int $80 and sysenter */
+
+       printf("jump back to %p\n", (void *) reg[14]);
+}
+
 
 #else
 #      error setregs() not yet ported to this architecture
diff -r 134e63f1eba3 -r 2bcc41d5aabb sys/arch/usermode/usermode/syscall.c
--- a/sys/arch/usermode/usermode/syscall.c      Thu Sep 08 19:37:01 2011 +0000
+++ b/sys/arch/usermode/usermode/syscall.c      Thu Sep 08 19:38:59 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: syscall.c,v 1.7 2011/09/08 14:49:42 reinoud Exp $ */
+/* $NetBSD: syscall.c,v 1.8 2011/09/08 19:39:00 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.7 2011/09/08 14:49:42 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.8 2011/09/08 19:39:00 reinoud Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -43,8 +43,8 @@
 #include <sys/userret.h>
 #include <machine/pcb.h>
 #include <machine/thunk.h>
+#include <machine/machdep.h>
 
-extern void syscall(void);
 
 void userret(struct lwp *l);
 
@@ -73,39 +73,59 @@
 syscall(void)
 {      
        lwp_t *l = curlwp;
+       const struct proc * const p = l->l_proc;
+       const struct sysent *callp;
        struct pcb *pcb = lwp_getpcb(l);
        ucontext_t *ucp = &pcb->pcb_userland_ucp;
-       uint *reg, i;
-
-       l = curlwp;
+       register_t copyargs[2+SYS_MAXSYSARGS];
+       register_t *args;
+       register_t rval[2];
+       uint32_t code;
+       uint nargs, argsize;
+       int error;
 
-       printf("syscall called for lwp %p!\n", l);
-       reg = (int *) &ucp->uc_mcontext;
-#if 1
-       /* register dump before call */
-       const char *name[] = {"GS", "FS", "ES", "DS", "EDI", "ESI", "EBP", "ESP",
-               "EBX", "EDX", "ECX", "EAX", "TRAPNO", "ERR", "EIP", "CS", "EFL",
-               "UESP", "SS"};
-
-       for (i =0; i < 19; i++)
-               printf("reg[%02d] (%6s) = %"PRIx32"\n", i, name[i], reg[i]);
-#endif
+//     printf("syscall called for lwp %p!\n", l);
 
        /* system call accounting */
        curcpu()->ci_data.cpu_nsyscall++;
+       LWP_CACHE_CREDS(l, l->l_proc);
 
        /* XXX do we want do do emulation? */
-       LWP_CACHE_CREDS(l, l->l_proc);
-       /* TODO issue!! */
+       md_syscall_get_syscallnumber(ucp, &code);
+       code &= (SYS_NSYSENT -1);
+
+       callp   = p->p_emul->e_sysent + code;
+       nargs   = callp->sy_narg;
+       argsize = callp->sy_argsize;
+
+       printf("syscall no. %d, ", code);
+       printf("nargs %d, argsize %d =>  ", nargs, argsize);
+
+       args  = copyargs;
+       rval[0] = rval[1] = 0;
+       error = md_syscall_getargs(l, ucp, nargs, argsize, args);
+       if (!error) 
+               error = (*callp->sy_call)(l, args, rval);
 
-       printf("syscall no. %d\n", reg[11]);
-/* skip instruction */
-reg[14] += 2;
+       printf("error = %d, rval[0] = %"PRIx32", retval[1] = %"PRIx32"\n",
+               error, (uint) rval[0], (uint) rval[1]);
+       switch (error) {
+       default:
+               rval[0] = error;
+//             rval[1] = 0;
+               /* fall trough */
+       case 0:
+               md_syscall_set_returnargs(l, ucp, rval);
+               /* fall trough */
+       case EJUSTRETURN:
+               md_syscall_inc_pc(ucp);
+               break;
+       case ERESTART:
+               /* nothing to do */
+               break;
+       }
 
-/* retval */
-reg[11] = 0;
-       printf("end of syscall : return to userland\n");
+//     printf("end of syscall : return to userland\n");
        userret(l);
-printf("jump back to %p\n", (void *) reg[14]);
 }
 
diff -r 134e63f1eba3 -r 2bcc41d5aabb sys/arch/usermode/usermode/trap.c
--- a/sys/arch/usermode/usermode/trap.c Thu Sep 08 19:37:01 2011 +0000
+++ b/sys/arch/usermode/usermode/trap.c Thu Sep 08 19:38:59 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.36 2011/09/08 15:13:27 reinoud Exp $ */
+/* $NetBSD: trap.c,v 1.37 2011/09/08 19:39:00 reinoud Exp $ */
 
 /*-
  * Copyright (c) 2011 Reinoud Zandijk <reinoud%netbsd.org@localhost>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.36 2011/09/08 15:13:27 reinoud Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.37 2011/09/08 19:39:00 reinoud Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -218,7 +218,7 @@
                                recurse--;
                                return;
                        }
-                       panic("should deliver a trap to the process");
+                       panic("%s: should deliver a trap to the process", __func__);
                        /* XXX HOWTO see arm/arm/syscall.c illegal instruction signal */
                }
 
@@ -239,12 +239,14 @@
        struct pcb *pcb;
        vaddr_t va;
 
+       va = 0;
+
        if (info->si_signo == SIGILL) {
                l = curlwp;
                p = l->l_proc;
                pcb = lwp_getpcb(l);
 
-#if 1
+#if 0
                va = (vaddr_t) info->si_addr;



Home | Main Index | Thread Index | Old Index