BSD 4_4 release
[unix-history] / usr / src / sys / tahoe / tahoe / trap.c
index ad9021b..4c81cc7 100644 (file)
@@ -1,24 +1,28 @@
-/*     trap.c  1.4     86/01/09        */
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)trap.c      7.11 (Berkeley) 12/16/90
+ */
 
 
-#include "../tahoe/psl.h"
-#include "../tahoe/reg.h"
-#include "../tahoe/pte.h"
-#include "../tahoe/mtpr.h"
+#include "sys/param.h"
+#include "sys/systm.h"
+#include "sys/user.h"
+#include "sys/proc.h"
+#include "sys/seg.h"
+#include "sys/acct.h"
+#include "sys/kernel.h"
 
 
-#include "param.h"
-#include "systm.h"
-#include "dir.h"
-#include "user.h"
-#include "proc.h"
-#include "seg.h"
-#include "acct.h"
-#include "kernel.h"
-#define        SYSCALLTRACE
-#ifdef SYSCALLTRACE
-#include "../sys/syscalls.c"
+#include "../include/psl.h"
+#include "../include/reg.h"
+#include "../include/pte.h"
+#include "../include/mtpr.h"
+#ifdef KTRACE
+#include "sys/ktrace.h"
 #endif
 
 #endif
 
-#include "../tahoe/trap.h"
+#include "../include/trap.h"
 
 #define        USER    040             /* user-mode flag added to type */
 
 
 #define        USER    040             /* user-mode flag added to type */
 
@@ -43,19 +47,21 @@ char        *trap_type[] = {
        "Alignment fault",                      /* T_ALIGNFLT */
        "Kernel stack not valid",               /* T_KSPNOTVAL */
        "Bus error",                            /* T_BUSERR */
        "Alignment fault",                      /* T_ALIGNFLT */
        "Kernel stack not valid",               /* T_KSPNOTVAL */
        "Bus error",                            /* T_BUSERR */
+       "Kernel debugger request",              /* T_KDBTRAP */
 };
 };
-#define        TRAP_TYPES      (sizeof (trap_type) / sizeof (trap_type[0]))
+int    TRAP_TYPES = sizeof (trap_type) / sizeof (trap_type[0]);
 
 /*
  * Called from the trap handler when a processor trap occurs.
  */
 /*ARGSUSED*/
 trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
 
 /*
  * Called from the trap handler when a processor trap occurs.
  */
 /*ARGSUSED*/
 trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
-       unsigned type, code;
+       unsigned type, code;    /* kdb assumes these are *not* registers */
 {
        int r0, r1;             /* must reserve space */
        register int *locr0 = ((int *)&psl)-PS;
        register int i;
 {
        int r0, r1;             /* must reserve space */
        register int *locr0 = ((int *)&psl)-PS;
        register int i;
+       unsigned ucode = code;
        register struct proc *p;
        struct timeval syst;
 
        register struct proc *p;
        struct timeval syst;
 
@@ -70,6 +76,10 @@ trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
        switch (type) {
 
        default:
        switch (type) {
 
        default:
+#ifdef KADB
+               if (kdb_trap(&psl))
+                       return;
+#endif
                printf("trap type %d, code = %x, pc = %x\n", type, code, pc);
                type &= ~USER;
                if (type < TRAP_TYPES && trap_type[type])
                printf("trap type %d, code = %x, pc = %x\n", type, code, pc);
                type &= ~USER;
                if (type < TRAP_TYPES && trap_type[type])
@@ -86,7 +96,7 @@ trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
        case T_RESADFLT + USER:         /* reserved addressing fault */
        case T_RESOPFLT + USER:         /* resereved operand fault */
        case T_ALIGNFLT + USER:         /* unaligned data fault */
        case T_RESADFLT + USER:         /* reserved addressing fault */
        case T_RESOPFLT + USER:         /* resereved operand fault */
        case T_ALIGNFLT + USER:         /* unaligned data fault */
-               u.u_code = type &~ USER;
+               ucode = type &~ USER;
                i = SIGILL;
                break;
 
                i = SIGILL;
                break;
 
@@ -100,7 +110,6 @@ trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
                goto out;
 
        case T_ARITHTRAP + USER:
                goto out;
 
        case T_ARITHTRAP + USER:
-               u.u_code = code;
                i = SIGFPE;
                break;
 
                i = SIGFPE;
                break;
 
@@ -120,9 +129,7 @@ trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
 
        case T_PAGEFLT:                 /* allow page faults in kernel mode */
        case T_PAGEFLT + USER:          /* page fault */
 
        case T_PAGEFLT:                 /* allow page faults in kernel mode */
        case T_PAGEFLT + USER:          /* page fault */
-               i = u.u_error;
                pagein(code, 0);
                pagein(code, 0);
-               u.u_error = i;
                if (type == T_PAGEFLT)
                        return;
                goto out;
                if (type == T_PAGEFLT)
                        return;
                goto out;
@@ -133,6 +140,9 @@ trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
                i = SIGTRAP;
                break;
 
                i = SIGTRAP;
                break;
 
+#ifdef notdef
+       /* THIS CODE IS BOGUS- delete? (KSP not valid is unrecoverable)
+          And what does KSPNOTVAL in user-mode mean? */
        /*
         * For T_KSPNOTVAL and T_BUSERR, can not allow spl to
         * drop to 0 as clock could go off and we would end up
        /*
         * For T_KSPNOTVAL and T_BUSERR, can not allow spl to
         * drop to 0 as clock could go off and we would end up
@@ -148,20 +158,21 @@ trap(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
                /* fall thru... */
        case T_KSPNOTVAL + USER:
                printf("pid %d: ksp not valid\n", u.u_procp->p_pid);
                /* fall thru... */
        case T_KSPNOTVAL + USER:
                printf("pid %d: ksp not valid\n", u.u_procp->p_pid);
+panic("ksp not valid - 2");
                /* must insure valid kernel stack pointer? */
                psignal(u.u_procp, SIGKILL);
                return;
                /* must insure valid kernel stack pointer? */
                psignal(u.u_procp, SIGKILL);
                return;
+#endif
 
        case T_BUSERR + USER:
 
        case T_BUSERR + USER:
-               u.u_code = code;
-               psignal(u.u_procp, SIGBUS);
-               return;
+               i = SIGBUS;
+               break;
        }
        }
-       psignal(u.u_procp, i);
+       trapsignal(i, ucode);
 out:
        p = u.u_procp;
 out:
        p = u.u_procp;
-       if (p->p_cursig || ISSIG(p))
-               psig();
+       if (i = CURSIG(p))
+               psig(i);
        p->p_pri = p->p_usrpri;
        if (runrun) {
                /*
        p->p_pri = p->p_usrpri;
        if (runrun) {
                /*
@@ -172,10 +183,12 @@ out:
                 * swtch()'ed, we might not be on the queue indicated by
                 * our priority.
                 */
                 * swtch()'ed, we might not be on the queue indicated by
                 * our priority.
                 */
-               (void) spl8();
+               (void) splclock();
                setrq(p);
                u.u_ru.ru_nivcsw++;
                swtch();
                setrq(p);
                u.u_ru.ru_nivcsw++;
                swtch();
+               if (i = CURSIG(p))
+                       psig(i);
        }
        if (u.u_prof.pr_scale) {
                int ticks;
        }
        if (u.u_prof.pr_scale) {
                int ticks;
@@ -189,10 +202,6 @@ out:
        curpri = p->p_pri;
 }
 
        curpri = p->p_pri;
 }
 
-#ifdef SYSCALLTRACE
-int    syscalltrace = 0;
-#endif
-
 /*
  * Called from locore when a system call occurs
  */
 /*
  * Called from locore when a system call occurs
  */
@@ -205,9 +214,13 @@ syscall(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
        register caddr_t params;
        register int i;
        register struct sysent *callp;
        register caddr_t params;
        register int i;
        register struct sysent *callp;
-       register struct proc *p;
+       register struct proc *p = u.u_procp;
        struct timeval syst;
        struct timeval syst;
-       int opc;
+       int error, opc;
+       struct args {
+               int i[8];
+       } args;
+       int rval[2];
 
 #ifdef lint
        r0 = 0; r0 = r0; r1 = 0; r1 = r1;
 
 #ifdef lint
        r0 = 0; r0 = r0; r1 = 0; r1 = r1;
@@ -216,12 +229,7 @@ syscall(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
        if (!USERMODE(locr0[PS]))
                panic("syscall");
        u.u_ar0 = locr0;
        if (!USERMODE(locr0[PS]))
                panic("syscall");
        u.u_ar0 = locr0;
-       if (code == 139) {                      /* 4.2 COMPATIBILTY XXX */
-               osigcleanup();                  /* 4.2 COMPATIBILTY XXX */
-               goto done;                      /* 4.2 COMPATIBILTY XXX */
-       }
        params = (caddr_t)locr0[FP] + NBPW;
        params = (caddr_t)locr0[FP] + NBPW;
-       u.u_error = 0;
 /* BEGIN GROT */
        /*
         * Try to reconstruct pc, assuming code
 /* BEGIN GROT */
        /*
         * Try to reconstruct pc, assuming code
@@ -237,63 +245,53 @@ syscall(sp, type, hfs, accmst, acclst, dbl, code, pc, psl)
                }
        }
 /* END GROT */
                }
        }
 /* END GROT */
-       callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
-       if (callp == sysent) {
-               i = fuword(params);
+       if (code == 0) {                        /* indir */
+               code = fuword(params);
                params += NBPW;
                params += NBPW;
-               callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
        }
        }
+       if (code >= nsysent)
+               callp = &sysent[0];             /* indir (illegal) */
+       else
+               callp = &sysent[code];
        if ((i = callp->sy_narg * sizeof (int)) &&
        if ((i = callp->sy_narg * sizeof (int)) &&
-           (u.u_error = copyin(params, (caddr_t)u.u_arg, (u_int)i)) != 0) {
-               locr0[R0] = u.u_error;
+           (error = copyin(params, (caddr_t)&args, (u_int)i)) != 0) {
+               locr0[R0] = error;
                locr0[PS] |= PSL_C;     /* carry bit */
                locr0[PS] |= PSL_C;     /* carry bit */
+#ifdef KTRACE
+               if (KTRPOINT(p, KTR_SYSCALL))
+                       ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
+#endif
                goto done;
        }
                goto done;
        }
-       u.u_r.r_val1 = 0;
-       u.u_r.r_val2 = locr0[R1];
-       if (setjmp(&u.u_qsave)) {
-               if (u.u_error == 0 && u.u_eosys != RESTARTSYS)
-                       u.u_error = EINTR;
-       } else {
-               u.u_eosys = NORMALRETURN;
-#ifdef SYSCALLTRACE
-               if (syscalltrace) {
-                       register int i;
-                       char *cp;
-
-                       if (code >= nsysent)
-                               printf("0x%x", code);
-                       else
-                               printf("%s", syscallnames[code]);
-                       cp = "(";
-                       for (i= 0; i < callp->sy_narg; i++) {
-                               printf("%s%x", cp, u.u_arg[i]);
-                               cp = ", ";
-                       }
-                       if (i)
-                               putchar(')', 0);
-                       putchar('\n', 0);
-               }
+#ifdef KTRACE
+       if (KTRPOINT(p, KTR_SYSCALL))
+               ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
 #endif
 #endif
-               (*callp->sy_call)();
-       }
-       if (u.u_eosys == NORMALRETURN) {
-               if (u.u_error) {
-                       locr0[R0] = u.u_error;
+       rval[0] = 0;
+       rval[1] = locr0[R1];
+       error = (*callp->sy_call)(u.u_procp, &args, rval);
+       if (error == ERESTART)
+               pc = opc;
+       else if (error != EJUSTRETURN) {
+               if (error) {
+                       locr0[R0] = error;
                        locr0[PS] |= PSL_C;     /* carry bit */
                } else {
                        locr0[PS] &= ~PSL_C;    /* clear carry bit */
                        locr0[PS] |= PSL_C;     /* carry bit */
                } else {
                        locr0[PS] &= ~PSL_C;    /* clear carry bit */
-                       locr0[R0] = u.u_r.r_val1;
-                       locr0[R1] = u.u_r.r_val2;
+                       locr0[R0] = rval[0];
+                       locr0[R1] = rval[1];
                }
                }
-       } else if (u.u_eosys == RESTARTSYS)
-               pc = opc;
-       /* else if (u.u_eosys == JUSTRETURN) */
+       }
+       /* else if (error == EJUSTRETURN) */
                /* nothing to do */
 done:
                /* nothing to do */
 done:
+       /*
+        * Reinitialize proc pointer `p' as it may be different
+        * if this is a child returning from fork syscall.
+        */
        p = u.u_procp;
        p = u.u_procp;
-       if (p->p_cursig || ISSIG(p))
-               psig();
+       if (i = CURSIG(p))
+               psig(i);
        p->p_pri = p->p_usrpri;
        if (runrun) {
                /*
        p->p_pri = p->p_usrpri;
        if (runrun) {
                /*
@@ -304,10 +302,12 @@ done:
                 * swtch()'ed, we might not be on the queue indicated by
                 * our priority.
                 */
                 * swtch()'ed, we might not be on the queue indicated by
                 * our priority.
                 */
-               (void) spl8();
+               (void) splclock();
                setrq(p);
                u.u_ru.ru_nivcsw++;
                swtch();
                setrq(p);
                u.u_ru.ru_nivcsw++;
                swtch();
+               if (i = CURSIG(p))
+                       psig(i);
        }
        if (u.u_prof.pr_scale) {
                int ticks;
        }
        if (u.u_prof.pr_scale) {
                int ticks;
@@ -319,27 +319,8 @@ done:
                        addupc(locr0[PC], &u.u_prof, ticks);
        }
        curpri = p->p_pri;
                        addupc(locr0[PC], &u.u_prof, ticks);
        }
        curpri = p->p_pri;
-}
-
-/*
- * nonexistent system call-- signal process (may want to handle it)
- * flag error if process won't see signal immediately
- * Q: should we do that all the time ??
- */
-nosys()
-{
-
-       if (u.u_signal[SIGSYS] == SIG_IGN || u.u_signal[SIGSYS] == SIG_HOLD)
-               u.u_error = EINVAL;
-       psignal(u.u_procp, SIGSYS);
-}
-
-#ifdef notdef
-/*
- * Ignored system call
- */
-nullsys()
-{
-
-}
+#ifdef KTRACE
+       if (KTRPOINT(p, KTR_SYSRET))
+               ktrsysret(p->p_tracep, code, error, rval[0]);
 #endif
 #endif
+}