BSD 4_4_Lite2 release
[unix-history] / usr / src / sys / hp300 / hp300 / trap.c
index 9d85ead..f18333b 100644 (file)
@@ -1,44 +1,70 @@
 /*
  * Copyright (c) 1988 University of Utah.
 /*
  * Copyright (c) 1988 University of Utah.
- * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1986, 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * the Systems Programming Group of the University of Utah Computer
  * Science Department.
  *
  *
  * This code is derived from software contributed to Berkeley by
  * the Systems Programming Group of the University of Utah Computer
  * Science Department.
  *
- * %sccs.include.redist.c%
+ * 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.
  *
  *
- * from: Utah $Hdr: trap.c 1.35 91/12/26$
+ * 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.24 (Berkeley) %G%
+ * from: Utah $Hdr: trap.c 1.37 92/12/20$
+ *
+ *     @(#)trap.c      8.7 (Berkeley) 2/19/95
  */
 
  */
 
-#include "param.h"
-#include "systm.h"
-#include "proc.h"
-#include "acct.h"
-#include "kernel.h"
-#include "signalvar.h"
-#include "resourcevar.h"
-#include "syscall.h"
-#include "syslog.h"
-#include "user.h"
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+#include <sys/acct.h>
+#include <sys/kernel.h>
+#include <sys/signalvar.h>
+#include <sys/resourcevar.h>
+#include <sys/syscall.h>
+#include <sys/syslog.h>
+#include <sys/user.h>
 #ifdef KTRACE
 #ifdef KTRACE
-#include "ktrace.h"
+#include <sys/ktrace.h>
 #endif
 
 #endif
 
-#include "../include/psl.h"
-#include "../include/trap.h"
-#include "../include/cpu.h"
-#include "../include/reg.h"
-#include "../include/mtpr.h"
+#include <machine/psl.h>
+#include <machine/trap.h>
+#include <machine/cpu.h>
+#include <machine/reg.h>
+#include <machine/mtpr.h>
 
 
-#include "vm/vm.h"
-#include "vm/pmap.h"
+#include <vm/vm.h>
+#include <vm/pmap.h>
 
 #ifdef HPUXCOMPAT
 
 #ifdef HPUXCOMPAT
-#include "hp/hpux/hpux.h"
+#include <hp/hpux/hpux.h>
 #endif
 
 struct sysent  sysent[];
 #endif
 
 struct sysent  sysent[];
@@ -120,30 +146,30 @@ again:
 #endif
        /* take pending signals */
        while ((sig = CURSIG(p)) != 0)
 #endif
        /* take pending signals */
        while ((sig = CURSIG(p)) != 0)
-               psig(sig);
-       p->p_pri = p->p_usrpri;
+               postsig(sig);
+       p->p_priority = p->p_usrpri;
        if (want_resched) {
                /*
                 * Since we are curproc, clock will normally just change
                 * our priority without moving us from one queue to another
                 * (since the running process is not on a queue.)
        if (want_resched) {
                /*
                 * Since we are curproc, clock will normally just change
                 * our priority without moving us from one queue to another
                 * (since the running process is not on a queue.)
-                * If that happened after we setrq ourselves but before we
-                * swtch()'ed, we might not be on the queue indicated by
-                * our priority.
+                * If that happened after we put ourselves on the run queue
+                * but before we mi_switch()'ed, we might not be on the queue
+                * indicated by our priority.
                 */
                s = splstatclock();
                 */
                s = splstatclock();
-               setrq(p);
+               setrunqueue(p);
                p->p_stats->p_ru.ru_nivcsw++;
                p->p_stats->p_ru.ru_nivcsw++;
-               swtch();
+               mi_switch();
                splx(s);
                while ((sig = CURSIG(p)) != 0)
                splx(s);
                while ((sig = CURSIG(p)) != 0)
-                       psig(sig);
+                       postsig(sig);
        }
 
        /*
         * If profiling, charge system time to the trapped pc.
         */
        }
 
        /*
         * If profiling, charge system time to the trapped pc.
         */
-       if (p->p_flag & SPROFIL) {
+       if (p->p_flag & P_PROFIL) {
                extern int psratio;
 
                addupc_task(p, fp->f_pc,
                extern int psratio;
 
                addupc_task(p, fp->f_pc,
@@ -175,7 +201,7 @@ again:
                }
        }
 #endif
                }
        }
 #endif
-       curpri = p->p_pri;
+       curpriority = p->p_priority;
 }
 
 /*
 }
 
 /*
@@ -190,12 +216,11 @@ trap(type, code, v, frame)
        register unsigned v;
        struct frame frame;
 {
        register unsigned v;
        struct frame frame;
 {
-       register int i;
-       unsigned ucode;
+       extern char fswintr[];
        register struct proc *p;
        register struct proc *p;
+       register int i;
+       u_int ucode;
        u_quad_t sticks;
        u_quad_t sticks;
-       unsigned ncode;
-       extern char fswintr[];
 
        cnt.v_trap++;
        p = curproc;
 
        cnt.v_trap++;
        p = curproc;
@@ -210,7 +235,7 @@ trap(type, code, v, frame)
        default:
 dopanic:
                printf("trap type %d, code = %x, v = %x\n", type, code, v);
        default:
 dopanic:
                printf("trap type %d, code = %x, v = %x\n", type, code, v);
-               regdump(frame.f_regs, 128);
+               regdump(&frame, 128);
                type &= ~T_USER;
                if ((unsigned)type < TRAP_TYPES)
                        panic(trap_type[type]);
                type &= ~T_USER;
                if ((unsigned)type < TRAP_TYPES)
                        panic(trap_type[type]);
@@ -237,18 +262,33 @@ copyfault:
                i = SIGBUS;
                break;
 
                i = SIGBUS;
                break;
 
+#ifdef HP380
+       case T_ADDRERR:
+               /*
+                * Yow!  Looks like we get a kernel exception if the PC
+                * in the RTE frame is odd on a 68040 (not on a 68030).
+                * It comes through as a user exception for access faults
+                * (T_MMUFLT).
+                */
+               if (*(short *)frame.f_pc != 0x4e73)
+                       goto dopanic;
+               /* fall through */
+#endif
+
 #ifdef FPCOPROC
        case T_COPERR:          /* kernel coprocessor violation */
 #endif
        case T_FMTERR|T_USER:   /* do all RTE errors come in as T_USER? */
        case T_FMTERR:          /* ...just in case... */
 #ifdef FPCOPROC
        case T_COPERR:          /* kernel coprocessor violation */
 #endif
        case T_FMTERR|T_USER:   /* do all RTE errors come in as T_USER? */
        case T_FMTERR:          /* ...just in case... */
-       /*
-        * The user has most likely trashed the RTE or FP state info
-        * in the stack frame of a signal handler.
-        */
+               /*
+                * The user has most likely trashed the RTE or FP state info
+                * in the stack frame of a signal handler.
+                */
                type |= T_USER;
                printf("pid %d: kernel %s exception\n", p->p_pid,
                type |= T_USER;
                printf("pid %d: kernel %s exception\n", p->p_pid,
-                      type==T_COPERR ? "coprocessor" : "format");
+                      (type==T_COPERR|T_USER) ? "coprocessor" :
+                      (type==T_ADDRERR|T_USER) ? "RTE address" :
+                      "RTE format");
                p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL;
                i = sigmask(SIGILL);
                p->p_sigignore &= ~i;
                p->p_sigacts->ps_sigact[SIGILL] = SIG_DFL;
                i = sigmask(SIGILL);
                p->p_sigignore &= ~i;
@@ -295,7 +335,7 @@ copyfault:
 
        case T_ILLINST|T_USER:  /* illegal instruction fault */
 #ifdef HPUXCOMPAT
 
        case T_ILLINST|T_USER:  /* illegal instruction fault */
 #ifdef HPUXCOMPAT
-               if (p->p_flag & SHPUX) {
+               if (p->p_md.md_flags & MDP_HPUX) {
                        ucode = HPUX_ILL_ILLINST_TRAP;
                        i = SIGILL;
                        break;
                        ucode = HPUX_ILL_ILLINST_TRAP;
                        i = SIGILL;
                        break;
@@ -304,7 +344,7 @@ copyfault:
 #endif
        case T_PRIVINST|T_USER: /* privileged instruction fault */
 #ifdef HPUXCOMPAT
 #endif
        case T_PRIVINST|T_USER: /* privileged instruction fault */
 #ifdef HPUXCOMPAT
-               if (p->p_flag & SHPUX)
+               if (p->p_md.md_flags & MDP_HPUX)
                        ucode = HPUX_ILL_PRIV_TRAP;
                else
 #endif
                        ucode = HPUX_ILL_PRIV_TRAP;
                else
 #endif
@@ -314,7 +354,7 @@ copyfault:
 
        case T_ZERODIV|T_USER:  /* Divide by zero */
 #ifdef HPUXCOMPAT
 
        case T_ZERODIV|T_USER:  /* Divide by zero */
 #ifdef HPUXCOMPAT
-               if (p->p_flag & SHPUX)
+               if (p->p_md.md_flags & MDP_HPUX)
                        ucode = HPUX_FPE_INTDIV_TRAP;
                else
 #endif
                        ucode = HPUX_FPE_INTDIV_TRAP;
                else
 #endif
@@ -324,7 +364,7 @@ copyfault:
 
        case T_CHKINST|T_USER:  /* CHK instruction trap */
 #ifdef HPUXCOMPAT
 
        case T_CHKINST|T_USER:  /* CHK instruction trap */
 #ifdef HPUXCOMPAT
-               if (p->p_flag & SHPUX) {
+               if (p->p_md.md_flags & MDP_HPUX) {
                        /* handled differently under hp-ux */
                        i = SIGILL;
                        ucode = HPUX_ILL_CHK_TRAP;
                        /* handled differently under hp-ux */
                        i = SIGILL;
                        ucode = HPUX_ILL_CHK_TRAP;
@@ -337,7 +377,7 @@ copyfault:
 
        case T_TRAPVINST|T_USER:        /* TRAPV instruction trap */
 #ifdef HPUXCOMPAT
 
        case T_TRAPVINST|T_USER:        /* TRAPV instruction trap */
 #ifdef HPUXCOMPAT
-               if (p->p_flag & SHPUX) {
+               if (p->p_md.md_flags & MDP_HPUX) {
                        /* handled differently under hp-ux */
                        i = SIGILL;
                        ucode = HPUX_ILL_TRAPV_TRAP;
                        /* handled differently under hp-ux */
                        i = SIGILL;
                        ucode = HPUX_ILL_TRAPV_TRAP;
@@ -408,8 +448,8 @@ copyfault:
                        return;
                }
                spl0();
                        return;
                }
                spl0();
-               if (p->p_flag & SOWEUPC) {
-                       p->p_flag &= ~SOWEUPC;
+               if (p->p_flag & P_OWEUPC) {
+                       p->p_flag &= ~P_OWEUPC;
                        ADDUPROF(p);
                }
                goto out;
                        ADDUPROF(p);
                }
                goto out;
@@ -460,6 +500,19 @@ copyfault:
                        printf("trap: bad kernel access at %x\n", v);
                        goto dopanic;
                }
                        printf("trap: bad kernel access at %x\n", v);
                        goto dopanic;
                }
+#endif
+#ifdef HPUXCOMPAT
+               if (ISHPMMADDR(va)) {
+                       vm_offset_t bva;
+
+                       rv = pmap_mapmulti(map->pmap, va);
+                       if (rv != KERN_SUCCESS) {
+                               bva = HPMMBASEADDR(va);
+                               rv = vm_fault(map, bva, ftype, FALSE);
+                               if (rv == KERN_SUCCESS)
+                                       (void) pmap_mapmulti(map->pmap, va);
+                       }
+               } else
 #endif
                rv = vm_fault(map, va, ftype, FALSE);
 #ifdef DEBUG
 #endif
                rv = vm_fault(map, va, ftype, FALSE);
 #ifdef DEBUG
@@ -824,27 +877,6 @@ dumpwb(num, s, a, d)
                printf("%x, current value %x", pa, fuword((caddr_t)a));
        printf("\n");
 }
                printf("%x, current value %x", pa, fuword((caddr_t)a));
        printf("\n");
 }
-
-#ifdef HPFPLIB
-fppanic(frame)
-       struct fppanicframe {
-               int     fpsaveframe;
-               int     regs[16];
-               int     fpregs[8*3];
-               int     fpcregs[3];
-               int     hole[5];
-               int     oa6;
-               short   sr;
-               int     pc;
-               short   vector;
-       } frame;
-{
-       printf("FP exception: pid %d(%s): no busy frame, ft=%x pc=%x vec=%x\n",
-              curproc->p_pid, curproc->p_comm,
-              frame.fpsaveframe, frame.pc, frame.vector);
-       panic("bad FP exception");
-}
-#endif
 #endif
 #endif
 
 #endif
 #endif
 
@@ -858,7 +890,7 @@ syscall(code, frame)
        register caddr_t params;
        register struct sysent *callp;
        register struct proc *p;
        register caddr_t params;
        register struct sysent *callp;
        register struct proc *p;
-       int error, opc, numsys, s;
+       int error, opc, numsys;
        u_int argsize;
        struct args {
                int i[8];
        u_int argsize;
        struct args {
                int i[8];
@@ -878,7 +910,7 @@ syscall(code, frame)
        p->p_md.md_regs = frame.f_regs;
        opc = frame.f_pc - 2;
 #ifdef HPUXCOMPAT
        p->p_md.md_regs = frame.f_regs;
        opc = frame.f_pc - 2;
 #ifdef HPUXCOMPAT
-       if (p->p_flag & SHPUX)
+       if (p->p_md.md_flags & MDP_HPUX)
                callp = hpuxsysent, numsys = hpuxnsysent;
        else
 #endif
                callp = hpuxsysent, numsys = hpuxnsysent;
        else
 #endif
@@ -886,21 +918,28 @@ syscall(code, frame)
        params = (caddr_t)frame.f_regs[SP] + sizeof(int);
        switch (code) {
 
        params = (caddr_t)frame.f_regs[SP] + sizeof(int);
        switch (code) {
 
-       case SYS_indir:
+       case SYS_syscall:
                /*
                 * Code is first argument, followed by actual args.
                 */
                code = fuword(params);
                params += sizeof(int);
                /*
                 * Code is first argument, followed by actual args.
                 */
                code = fuword(params);
                params += sizeof(int);
+               /*
+                * XXX sigreturn requires special stack manipulation
+                * that is only done if entered via the sigreturn
+                * trap.  Cannot allow it here so make sure we fail.
+                */
+               if (code == SYS_sigreturn)
+                       code = numsys;
                break;
 
                break;
 
-       case SYS___indir:
+       case SYS___syscall:
                /*
                /*
-                * Like indir, but code is a quad, so as to maintain
+                * Like syscall, but code is a quad, so as to maintain
                 * quad alignment for the rest of the arguments.
                 */
 #ifdef HPUXCOMPAT
                 * quad alignment for the rest of the arguments.
                 */
 #ifdef HPUXCOMPAT
-               if (p->p_flag & SHPUX)
+               if (p->p_md.md_flags & MDP_HPUX)
                        break;
 #endif
                code = fuword(params + _QUAD_LOWWORD * sizeof(int));
                        break;
 #endif
                code = fuword(params + _QUAD_LOWWORD * sizeof(int));
@@ -914,25 +953,25 @@ syscall(code, frame)
        if (code < numsys)
                callp += code;
        else
        if (code < numsys)
                callp += code;
        else
-               callp += SYS_indir;     /* => nosys */
-       argsize = callp->sy_narg * sizeof(int);
+               callp += SYS_syscall;   /* => nosys */
+       argsize = callp->sy_argsize;
        if (argsize && (error = copyin(params, (caddr_t)&args, argsize))) {
 #ifdef KTRACE
                if (KTRPOINT(p, KTR_SYSCALL))
        if (argsize && (error = copyin(params, (caddr_t)&args, argsize))) {
 #ifdef KTRACE
                if (KTRPOINT(p, KTR_SYSCALL))
-                       ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
+                       ktrsyscall(p->p_tracep, code, argsize, args.i);
 #endif
                goto bad;
        }
 #ifdef KTRACE
        if (KTRPOINT(p, KTR_SYSCALL))
 #endif
                goto bad;
        }
 #ifdef KTRACE
        if (KTRPOINT(p, KTR_SYSCALL))
-               ktrsyscall(p->p_tracep, code, callp->sy_narg, args.i);
+               ktrsyscall(p->p_tracep, code, argsize, args.i);
 #endif
        rval[0] = 0;
        rval[1] = frame.f_regs[D1];
 #ifdef HPUXCOMPAT
        /* debug kludge */
        if (callp->sy_call == notimp)
 #endif
        rval[0] = 0;
        rval[1] = frame.f_regs[D1];
 #ifdef HPUXCOMPAT
        /* debug kludge */
        if (callp->sy_call == notimp)
-               error = notimp(p, args.i, rval, code, callp->sy_narg);
+               error = notimp(p, args.i, rval, code, argsize);
        else
 #endif
                error = (*callp->sy_call)(p, &args, rval);
        else
 #endif
                error = (*callp->sy_call)(p, &args, rval);
@@ -959,7 +998,7 @@ syscall(code, frame)
        default:
        bad:
 #ifdef HPUXCOMPAT
        default:
        bad:
 #ifdef HPUXCOMPAT
-               if (p->p_flag & SHPUX)
+               if (p->p_md.md_flags & MDP_HPUX)
                        error = bsdtohpuxerrno(error);
 #endif
                frame.f_regs[D0] = error;
                        error = bsdtohpuxerrno(error);
 #endif
                frame.f_regs[D0] = error;