Merge changes from NetBSD, up to 3/19/97; undoes some local changes.
authordownsj <downsj@openbsd.org>
Wed, 26 Mar 1997 08:32:36 +0000 (08:32 +0000)
committerdownsj <downsj@openbsd.org>
Wed, 26 Mar 1997 08:32:36 +0000 (08:32 +0000)
Changed to match new arch/m68k code.
genassym.cf is currently just a place holder.

16 files changed:
sys/arch/hp300/DOC/Options
sys/arch/hp300/conf/Makefile.hp300
sys/arch/hp300/conf/files.hp300
sys/arch/hp300/dev/hil.c
sys/arch/hp300/hp300/genassym.c
sys/arch/hp300/hp300/genassym.cf [new file with mode: 0644]
sys/arch/hp300/hp300/hpux_machdep.c
sys/arch/hp300/hp300/locore.s
sys/arch/hp300/hp300/machdep.c
sys/arch/hp300/hp300/mem.c
sys/arch/hp300/hp300/pmap.c
sys/arch/hp300/hp300/trap.c
sys/arch/hp300/hp300/vm_machdep.c
sys/arch/hp300/include/hpux_machdep.h
sys/arch/hp300/include/pmap.h
sys/arch/hp300/include/proc.h

index ff2ef25..04ec092 100644 (file)
@@ -1,4 +1,4 @@
-$OpenBSD: Options,v 1.3 1997/02/04 07:15:22 downsj Exp $
+$OpenBSD: Options,v 1.4 1997/03/26 08:32:36 downsj Exp $
 $NetBSD: Options,v 1.6 1997/01/31 23:01:21 carrel Exp $
 
 Here is a list of hp300 specific kernel compilation options and what they
@@ -79,12 +79,6 @@ COMPAT_HPUX
 COMPAT_OHPUX
        Compile in old 4.2-ish HP-UX (pre-6.0?) compatibility code.
 
-FPCOPROC
-       Compile in code to support the 68881 and above FPU.  Should always
-       be defined, since all supported SPUs have one.  Don't even know if
-       it will compile, much less work,  without this option.  Defined in
-       the prototype makefile (hp300/conf/Makefile.hp300).
-
 DCMSTATS
        Compile in code to collect a variety of transmit/receive statistics
        for the 98642 4-port MUX.
index c853870..631c7ae 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile.hp300,v 1.12 1997/02/03 04:47:06 downsj Exp $
+#      $OpenBSD: Makefile.hp300,v 1.13 1997/03/26 08:32:38 downsj Exp $
 #      $NetBSD: Makefile.hp300,v 1.45 1996/12/01 06:12:30 jonathan Exp $
 
 # Makefile for OpenBSD
@@ -34,7 +34,7 @@ HP300=        ../..
 
 INCLUDES=      -I. -I$S/arch -I$S -nostdinc
 CPPFLAGS=      ${INCLUDES} ${IDENT} ${PARAM} -D_KERNEL \
-               -Dmc68020 -Dhp300 -DFPCOPROC
+               -Dmc68020 -Dhp300
 CWARNFLAGS=    -Werror
 CFLAGS=                ${DEBUG} ${COPTS} ${CWARNFLAGS} -msoft-float
 AFLAGS=                -x assembler-with-cpp -traditional-cpp -D_LOCORE
index 6a3851f..391bb1d 100644 (file)
@@ -1,5 +1,5 @@
-#      $OpenBSD: files.hp300,v 1.7 1997/02/24 01:16:07 downsj Exp $
-#      $NetBSD: files.hp300,v 1.22 1997/01/30 22:11:19 scottr Exp $
+#      $OpenBSD: files.hp300,v 1.8 1997/03/26 08:32:38 downsj Exp $
+#      $NetBSD: files.hp300,v 1.23 1997/03/17 19:46:43 gwr Exp $
 #
 # hp300-specific configuration info
 
@@ -180,8 +180,6 @@ file        arch/hp300/hp300/vm_machdep.c
 file   arch/hp300/hp300/disksubr.c
 file   arch/hp300/dev/dma.c
 
-file   arch/m68k/m68k/copy.s
-
 file   dev/cons.c
 file   dev/cninit.c
 
index fc159f1..8817d39 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: hil.c,v 1.8 1997/01/12 15:12:41 downsj Exp $  */
+/*     $OpenBSD: hil.c,v 1.9 1997/03/26 08:32:39 downsj Exp $  */
 /*     $NetBSD: hil.c,v 1.29 1996/10/14 07:09:41 thorpej Exp $ */
 
 /*
@@ -112,8 +112,8 @@ hilsoftinit(unit, hilbase)
        register int i;
 
        /* XXX ITE interface */
-       extern char *us_keymap, *us_shiftmap, *us_ctrlmap,
-                   *us_ctrlshiftmap, **us_stringmap;
+       extern char us_keymap[], us_shiftmap[], us_ctrlmap[],
+                   us_ctrlshiftmap[], *us_stringmap[];
 
 #ifdef DEBUG
        if (hildebug & HDB_FOLLOW)
@@ -1183,7 +1183,7 @@ kbdcninit()
        u_char lang;
 
        /* XXX from hil_keymaps.c */
-       extern char *us_keymap, *us_shiftmap, *us_ctrlmap;
+       extern char us_keymap[], us_shiftmap[], us_ctrlmap[];
 
        hilkbd_cn_device = h;
 
index 2c94d54..b7dea5e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: genassym.c,v 1.6 1997/02/04 06:21:29 downsj Exp $     */
+/*     $OpenBSD: genassym.c,v 1.7 1997/03/26 08:32:40 downsj Exp $     */
 /*     $NetBSD: genassym.c,v 1.22 1997/02/02 07:53:16 thorpej Exp $    */
 
 /*
@@ -278,9 +278,6 @@ main()
        def("CLKMSB1", CLKMSB1);
        def("CLKMSB3", CLKMSB3);
 
-       /* HP-UX trace bit */
-       def("MDP_TRCB", ffs(MDP_HPUXTRACE) - 1);
-
 #ifdef USELEDS
        /* LEDs */
        def("LED_PULSE", LED_PULSE);
diff --git a/sys/arch/hp300/hp300/genassym.cf b/sys/arch/hp300/hp300/genassym.cf
new file mode 100644 (file)
index 0000000..ff1cfb3
--- /dev/null
@@ -0,0 +1,219 @@
+#      $NetBSD: genassym.cf,v 1.5 1997/03/16 09:40:01 thorpej Exp $
+
+#
+# Copyright (c) 1982, 1990, 1993
+#      The Regents of the University of California.  All rights reserved.
+#
+# 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.
+#
+#      @(#)genassym.c  8.3 (Berkeley) 1/4/94
+#
+
+include <sys/param.h>
+include <sys/buf.h>
+include <sys/map.h>
+include <sys/proc.h>
+include <sys/mbuf.h>
+include <sys/msgbuf.h>
+include <sys/syscall.h>
+include <sys/user.h>
+
+include <vm/vm.h>
+
+include <machine/cpu.h>
+include <machine/psl.h>
+include <machine/reg.h>
+include <machine/pte.h>
+
+include <hp300/hp300/clockreg.h>
+include <hp300/hp300/led.h>
+
+define __XXX_BUG_FODDER        0
+
+# CPU options
+ifdef M68020
+define M68020                  1
+endif
+ifdef M68030
+define M68030                  1
+endif
+ifdef M68040
+define M68040                  1
+endif
+
+# MMU options
+ifdef M68K_MMU_MOTOROLA
+define M68K_MMU_MOTOROLA       1
+endif
+ifdef M68K_MMU_HP
+define M68K_MMU_HP             1
+endif
+
+# values for mmutype
+define MMU_68040               MMU_68040
+define MMU_68030               MMU_68030
+define MMU_HP                  MMU_HP
+define MMU_68851               MMU_68851
+
+# values for cputype
+define CPU_68020               CPU_68020
+define CPU_68030               CPU_68030
+define CPU_68040               CPU_68040
+
+# values for fputype
+define FPU_68881               FPU_68881
+define FPU_68040               FPU_68040
+
+# values for machineid
+define HP_320                  HP_320
+define HP_330                  HP_330
+define HP_350                  HP_350
+define HP_360                  HP_360
+define HP_370                  HP_370
+define HP_340                  HP_340
+define HP_375                  HP_375
+define HP_380                  HP_380
+define HP_433                  HP_433
+
+# values for ectype
+define EC_PHYS                 EC_PHYS
+define EC_NONE                 EC_NONE
+define EC_VIRT                 EC_VIRT
+
+# general constants
+define UPAGES                  UPAGES
+define USPACE                  USPACE
+define NBPG                    NBPG
+define PGSHIFT                 PGSHIFT
+define USRSTACK                USRSTACK
+define MAXADDR                 MAXADDR
+
+# proc fields and values
+define P_FORW                  offsetof(struct proc, p_forw)
+define P_BACK                  offsetof(struct proc, p_back)
+define P_VMSPACE               offsetof(struct proc, p_vmspace)
+define P_ADDR                  offsetof(struct proc, p_addr)
+define P_PRIORITY              offsetof(struct proc, p_priority)
+define P_STAT                  offsetof(struct proc, p_stat)
+define P_WCHAN                 offsetof(struct proc, p_wchan)
+define P_MD_FLAGS              offsetof(struct proc, p_md.md_flags)
+define P_MD_REGS               offsetof(struct proc, p_md.md_regs)
+define SSLEEP                  SSLEEP
+define SRUN                    SRUN
+
+# VM structure fields
+define VM_PMAP                 offsetof(struct vmspace, vm_pmap)
+define PM_STCHG                offsetof(struct pmap, pm_stchanged)
+
+# interrupt/fault metering
+define V_INTR                  offsetof(struct vmmeter, v_intr)
+
+# PSL values (should just include psl.h?)
+define PSL_S                   PSL_S
+define PSL_IPL7                PSL_IPL7
+define PSL_LOWIPL              PSL_LOWIPL
+define PSL_HIGHIPL             PSL_HIGHIPL
+define PSL_USER                PSL_USER
+define SPL1                    PSL_S | PSL_IPL1
+define SPL2                    PSL_S | PSL_IPL2
+define SPL3                    PSL_S | PSL_IPL3
+define SPL4                    PSL_S | PSL_IPL4
+define SPL5                    PSL_S | PSL_IPL5
+define SPL6                    PSL_S | PSL_IPL6
+
+# magic
+define FC_USERD                FC_USERD
+define FC_PURGE                FC_PURGE
+define INTIOBASE               INTIOBASE
+define MMUBASE                 MMUBASE
+define MMUSTAT                 MMUSTAT
+define MMUCMD                  MMUCMD
+define MMUSSTP                 MMUSSTP
+define MMUUSTP                 MMUUSTP
+define MMUTBINVAL              MMUTBINVAL
+define MMU_BERR                MMU_BERR
+define MMU_ENAB                MMU_ENAB
+define MMU_FAULT               MMU_FAULT
+define MMU_CEN                 MMU_CEN
+define MMU_IEN                 MMU_IEN
+define MMU_FPE                 MMU_FPE
+define CACHE_ON                CACHE_ON
+define CACHE_OFF               CACHE_OFF
+define CACHE_CLR               CACHE_CLR
+define IC_CLEAR                IC_CLEAR
+define DC_CLEAR                DC_CLEAR
+
+# pte/ste bits
+define PG_V                    PG_V
+define PG_NV                   PG_NV
+define PG_RO                   PG_RO
+define PG_RW                   PG_RW
+define PG_CI                   PG_CI
+define PG_PROT                 PG_PROT
+define PG_FRAME                PG_FRAME
+define SG_V                    SG_V
+define SG_NV                   SG_NV
+define SG_RW                   SG_RW
+define SG_FRAME                SG_FRAME
+define SG_ISHIFT               SG_ISHIFT
+
+# pcb fields
+define PCB_PS                  offsetof(struct pcb, pcb_ps)
+define PCB_USTP                offsetof(struct pcb, pcb_ustp)
+define PCB_USP                 offsetof(struct pcb, pcb_usp)
+define PCB_REGS                offsetof(struct pcb, pcb_regs)
+define PCB_ONFAULT             offsetof(struct pcb, pcb_onfault)
+define PCB_FPCTX               offsetof(struct pcb, pcb_fpregs)
+define SIZEOF_PCB              sizeof(struct pcb)
+
+# exception frame offset/sizes
+define FR_SP                   offsetof(struct frame, f_regs[15])
+define FR_HW                   offsetof(struct frame, f_sr)
+define FR_ADJ                  offsetof(struct frame, f_stackadj)
+define FR_SIZE                 sizeof(struct trapframe)
+
+# system calls
+define SYS_exit                SYS_exit
+define SYS_execve              SYS_execve
+define SYS_sigreturn           SYS_sigreturn
+
+# errno
+define EFAULT                  EFAULT
+define ENAMETOOLONG            ENAMETOOLONG
+
+# clock registers
+define CLKSR                   CLKSR
+define CLKMSB1                 CLKMSB1
+define CLKMSB3                 CLKMSB3
+
+# LED stuff
+define LED_PULSE               LED_PULSE
+define LED_DISK                LED_DISK
+define LED_LANRCV              LED_LANRCV
+define LED_LANXMT              LED_LANXMT
index 0133d4f..c7cb54e 100644 (file)
@@ -1,8 +1,8 @@
-/*     $OpenBSD: hpux_machdep.c,v 1.3 1997/01/12 15:13:16 downsj Exp $ */
-/*     $NetBSD: hpux_machdep.c,v 1.5 1996/10/14 06:51:50 thorpej Exp $ */
+/*     $OpenBSD: hpux_machdep.c,v 1.4 1997/03/26 08:32:41 downsj Exp $ */
+/*     $NetBSD: hpux_machdep.c,v 1.9 1997/03/16 10:00:45 thorpej Exp $ */
 
 /*
- * Copyright (c) 1995, 1996 Jason R. Thorpe.  All rights reserved.
+ * Copyright (c) 1995, 1996, 1997 Jason R. Thorpe.  All rights reserved.
  * Copyright (c) 1988 University of Utah.
  * Copyright (c) 1990, 1993
  *     The Regents of the University of California.  All rights reserved.
@@ -88,6 +88,8 @@
 
 #include <machine/hpux_machdep.h>
 
+extern short exframesize[];
+
 #define NHIL   1       /* XXX */
 #include "grf.h"
 
@@ -99,10 +101,12 @@ extern     int grfopen __P((dev_t dev, int oflags, int devtype, struct proc *p));
 extern int hilopen __P((dev_t dev, int oflags, int devtype, struct proc *p));
 #endif
 
-static struct {
-       int     machine_id;
-       char    *machine_str;
-} machine_table[] = {
+struct valtostr {
+       int     val;
+       const char *str;
+};
+
+static struct valtostr machine_table[] = {
        { HP_320,       "320" },
        { HP_330,       "330" },        /* includes 318 and 319 */
        { HP_340,       "340" },
@@ -115,18 +119,23 @@ static    struct {
        {     -1,       "3?0" },        /* unknown system (???) */
 };
 
-/* 6.0 and later style context */
-#ifdef M68040
-static char hpux_040context[] =
-    "standalone HP-MC68040 HP-MC68881 HP-MC68020 HP-MC68010 localroot default";
-#endif
-#ifdef FPCOPROC
-static char hpux_context[] =
-    "standalone HP-MC68881 HP-MC68020 HP-MC68010 localroot default";
-#else
-static char hpux_context[] =
-    "standalone HP-MC68020 HP-MC68010 localroot default";
-#endif
+/*
+ * 6.0 and later context.
+ * XXX what are the HP-UX "localroot" semantics?  Should we handle
+ * XXX diskless systems here?
+ */
+static struct valtostr context_table[] = {
+       { FPU_68040,
+    "standalone HP-MC68040 HP-MC68881 HP-MC68020 HP-MC68010 localroot default"
+       },
+       { FPU_68881,
+    "standalone HP-MC68881 HP-MC68020 HP-MC68010 localroot default"
+       },
+       { FPU_NONE,
+    "standalone HP-MC68020 HP-MC68010 localroot default"
+       },
+       { 0, NULL },
+};
 
 #define UOFF(f)                ((int)&((struct user *)0)->f)
 #define HPUOFF(f)      ((int)&((struct hpux_user *)0)->f)
@@ -223,11 +232,11 @@ hpux_cpu_uname(ut)
         * Find the current machine-ID in the table and
         * copy the string into the uname.
         */
-       for (i = 0; machine_table[i].machine_id != -1; ++i)
-               if (machine_table[i].machine_id == machineid)
+       for (i = 0; machine_table[i].val != -1; ++i)
+               if (machine_table[i].val == machineid)
                        break;
 
-       sprintf(ut->machine, "9000/%s", machine_table[i].machine_str);
+       sprintf(ut->machine, "9000/%s", machine_table[i].str);
 }
 
 /*
@@ -303,25 +312,28 @@ hpux_sys_getcontext(p, v, retval)
        register_t *retval; 
 {
        struct hpux_sys_getcontext_args *uap = v;
-       int error = 0;
+       int l, i, error = 0;
        register int len; 
 
-#ifdef M68040
-       if ((machineid == HP_380) || (machineid == HP_433)) {
-               len = min(SCARG(uap, len), sizeof(hpux_040context));
-               if (len)
-                       error = copyout(hpux_040context, SCARG(uap, buf), len);
-               if (error == 0)
-                       *retval = sizeof(hpux_040context);
-               return (error);
+       for (i = 0; context_table[i].str != NULL; i++)
+               if (context_table[i].val == fputype)
+                       break;
+       if (context_table[i].str == NULL) {
+               /*
+                * XXX What else?  It's not like this can happen...
+                */
+               return (EINVAL);
        }
-#endif
-       len = min(SCARG(uap, len), sizeof(hpux_context));
+
+       /* + 1 ... count the terminating \0. */
+       l = strlen(context_table[i].str) + 1;
+       len = min(SCARG(uap, len), l);
+
        if (len)
-               error = copyout(hpux_context, SCARG(uap, buf), (u_int)len);
+               error = copyout(context_table[i].str, SCARG(uap, buf), len);
        if (error == 0)
-               *retval = sizeof(hpux_context);
-       return (error);
+               *retval = l;
+       return (0);
 }
 
 /*
@@ -344,18 +356,17 @@ hpux_to_bsd_uoff(off, isps, p)
        if ((int)off == HPUOFF(hpuxu_ar0))
                return(UOFF(U_ar0)); 
 
+       if (fputype) {
+               /* FP registers from PCB */
+               hp = (struct hpux_fp *)HPUOFF(hpuxu_fp);
+               bp = (struct bsdfp *)UOFF(u_pcb.pcb_fpregs);
 
-#ifdef FPCOPROC
-       /* FP registers from PCB */
-       hp = (struct hpux_fp *)HPUOFF(hpuxu_fp);
-       bp = (struct bsdfp *)UOFF(u_pcb.pcb_fpregs);
-
-       if (off >= hp->hpfp_ctrl && off < &hp->hpfp_ctrl[3])
-               return((int)&bp->ctrl[off - hp->hpfp_ctrl]);
+               if (off >= hp->hpfp_ctrl && off < &hp->hpfp_ctrl[3])
+                       return((int)&bp->ctrl[off - hp->hpfp_ctrl]);
 
-       if (off >= hp->hpfp_reg && off < &hp->hpfp_reg[24])
-               return((int)&bp->reg[off - hp->hpfp_reg]);
-#endif
+               if (off >= hp->hpfp_reg && off < &hp->hpfp_reg[24])
+                       return((int)&bp->reg[off - hp->hpfp_reg]);
+       }
 
        /*
         * Everything else we recognize comes from the kernel stack,
@@ -407,89 +418,372 @@ hpux_to_bsd_uoff(off, isps, p)
        return (-1);
 }
 
+#define        HSS_RTEFRAME    0x01
+#define        HSS_FPSTATE     0x02
+#define        HSS_USERREGS    0x04
+
+struct hpuxsigstate {
+       int     hss_flags;              /* which of the following are valid */
+       struct  frame hss_frame;        /* original exception frame */
+       struct  fpframe hss_fpstate;    /* 68881/68882 state info */
+};
+
 /*
- * Kludge up a uarea dump so that HP-UX debuggers can find out
- * what they need.  IMPORTANT NOTE: we do not EVEN attempt to
- * convert the entire user struct.
+ * WARNING: code in locore.s assumes the layout shown here for hsf_signum
+ * thru hsf_handler so... don't screw with them!
  */
-int
-hpux_dumpu(vp, cred)
-       struct vnode *vp;
-       struct ucred *cred;
+struct hpuxsigframe {
+       int     hsf_signum;                /* signo for handler */
+       int     hsf_code;                  /* additional info for handler */
+       struct  hpuxsigcontext *hsf_scp;   /* context ptr for handler */
+       sig_t   hsf_handler;               /* handler addr for u_sigc */
+       struct  hpuxsigstate hsf_sigstate; /* state of the hardware */
+       struct  hpuxsigcontext hsf_sc;     /* actual context */
+};
+
+#ifdef DEBUG
+int hpuxsigdebug = 0;
+int hpuxsigpid = 0;
+#define SDB_FOLLOW     0x01
+#define SDB_KSTACK     0x02
+#define SDB_FPSTATE    0x04
+#endif
+
+/*
+ * Send an interrupt to process.
+ */
+/* ARGSUSED */
+void
+hpux_sendsig(catcher, sig, mask, code, type, val)
+       sig_t catcher;
+       int sig, mask;
+       u_long code;
+       int type;
+       union sigval val;
 {
-       int error = 0;
-       struct proc *p = curproc;
-       struct hpux_user *faku;
-       struct bsdfp *bp;
-       short *foop;
+       register struct proc *p = curproc;
+       register struct hpuxsigframe *kfp, *fp;
+       register struct frame *frame;
+       register struct sigacts *psp = p->p_sigacts;
+       register short ft;
+       int oonstack, fsize;
+       extern char sigcode[], esigcode[];
+
+       frame = (struct frame *)p->p_md.md_regs;
+       ft = frame->f_format;
+       oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
 
        /*
-        * Make sure there is no mistake about this being a real
-        * user structure.
+        * Allocate and validate space for the signal handler
+        * context. Note that if the stack is in P0 space, the
+        * call to grow() is a nop, and the useracc() check
+        * will fail if the process has not already allocated
+        * the space with a `brk'.
         */
-       faku = (struct hpux_user *)malloc((u_long)ctob(1), M_TEMP, M_WAITOK);
-       bzero((caddr_t)faku, ctob(1));
+       fsize = sizeof(struct hpuxsigframe);
+       if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
+           (psp->ps_sigonstack & sigmask(sig))) {
+               fp = (struct hpuxsigframe *)(psp->ps_sigstk.ss_sp +
+                   psp->ps_sigstk.ss_size - fsize);
+               psp->ps_sigstk.ss_flags |= SS_ONSTACK;
+       } else
+               fp = (struct hpuxsigframe *)(frame->f_regs[SP] - fsize);
+       if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize)) 
+               (void)grow(p, (unsigned)fp);
+
+#ifdef DEBUG
+       if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
+               printf("hpux_sendsig(%d): sig %d ssp %x usp %x scp %x ft %d\n",
+                      p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
+#endif
 
-       /* Fill in the process sizes. */
-       faku->hpuxu_tsize = p->p_vmspace->vm_tsize;
-       faku->hpuxu_dsize = p->p_vmspace->vm_dsize;
-       faku->hpuxu_ssize = p->p_vmspace->vm_ssize;
+       if (useracc((caddr_t)fp, fsize, B_WRITE) == 0) {
+#ifdef DEBUG
+               if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
+                       printf("hpux_sendsig(%d): useracc failed on sig %d\n",
+                              p->p_pid, sig);
+#endif
+               /*
+                * Process has trashed its stack; give it an illegal
+                * instruction to halt it in its tracks.
+                */
+               SIGACTION(p, SIGILL) = SIG_DFL;
+               sig = sigmask(SIGILL);
+               p->p_sigignore &= ~sig;
+               p->p_sigcatch &= ~sig;
+               p->p_sigmask &= ~sig;
+               psignal(p, SIGILL);
+               return;
+       }
+       kfp = (struct hpuxsigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK);
+
+       /* 
+        * Build the argument list for the signal handler.
+        */
+       kfp->hsf_signum = bsdtohpuxsig(sig);
+       kfp->hsf_code = code;
+       kfp->hsf_scp = &fp->hsf_sc;
+       kfp->hsf_handler = catcher;
 
        /*
-        * Fill in the exec header for CDB.
-        * This was saved back in exec().  As far as I can tell CDB
-        * only uses this information to verify that a particular
-        * core file goes with a particular binary.
+        * Save necessary hardware state.  Currently this includes:
+        *      - general registers
+        *      - original exception frame (if not a "normal" frame)
+        *      - FP coprocessor state
         */
-       bcopy((caddr_t)p->p_addr->u_md.md_exec,
-           (caddr_t)&faku->hpuxu_exdata, sizeof (struct hpux_exec));
+       kfp->hsf_sigstate.hss_flags = HSS_USERREGS;
+       bcopy((caddr_t)frame->f_regs,
+           (caddr_t)kfp->hsf_sigstate.hss_frame.f_regs, sizeof frame->f_regs);
+       if (ft >= FMT7) {
+#ifdef DEBUG
+               if (ft > 15 || exframesize[ft] < 0)
+                       panic("hpux_sendsig: bogus frame type");
+#endif
+               kfp->hsf_sigstate.hss_flags |= HSS_RTEFRAME;
+               kfp->hsf_sigstate.hss_frame.f_format = frame->f_format;
+               kfp->hsf_sigstate.hss_frame.f_vector = frame->f_vector;
+               bcopy((caddr_t)&frame->F_u,
+                   (caddr_t)&kfp->hsf_sigstate.hss_frame.F_u, exframesize[ft]);
+
+               /*
+                * Leave an indicator that we need to clean up the kernel
+                * stack.  We do this by setting the "pad word" above the
+                * hardware stack frame to the amount the stack must be
+                * adjusted by.
+                *
+                * N.B. we increment rather than just set f_stackadj in
+                * case we are called from syscall when processing a
+                * sigreturn.  In that case, f_stackadj may be non-zero.
+                */
+               frame->f_stackadj += exframesize[ft];
+               frame->f_format = frame->f_vector = 0;
+#ifdef DEBUG
+               if (hpuxsigdebug & SDB_FOLLOW)
+                       printf("hpux_sendsig(%d): copy out %d of frame %d\n",
+                              p->p_pid, exframesize[ft], ft);
+#endif
+       }
+       if (fputype) {
+               kfp->hsf_sigstate.hss_flags |= HSS_FPSTATE;
+               m68881_save(&kfp->hsf_sigstate.hss_fpstate);
+       }
+
+#ifdef DEBUG
+       if ((hpuxsigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate)
+               printf("hpux_sendsig(%d): copy out FP state (%x) to %x\n",
+                      p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate,
+                      &kfp->sf_state.ss_fpstate);
+#endif
 
        /*
-        * Adjust user's saved registers (on kernel stack) to reflect
-        * HP-UX order.  Note that HP-UX saves the SR as 2 bytes not 4
-        * so we have to move it up.
+        * Build the signal context to be used by hpux_sigreturn.
         */
-       faku->hpuxu_ar0 = p->p_md.md_regs;
-       foop = (short *) p->p_md.md_regs;
-       foop[32] = foop[33];
-       foop[33] = foop[34];
-       foop[34] = foop[35];
+       kfp->hsf_sc.hsc_syscall = 0;            /* XXX */
+       kfp->hsf_sc.hsc_action  = 0;            /* XXX */
+       kfp->hsf_sc.hsc_pad1    = kfp->hsf_sc.hsc_pad2 = 0;
+       kfp->hsf_sc.hsc_onstack = oonstack;
+       kfp->hsf_sc.hsc_mask    = mask;
+       kfp->hsf_sc.hsc_sp      = frame->f_regs[SP];
+       kfp->hsf_sc.hsc_ps      = frame->f_sr;
+       kfp->hsf_sc.hsc_pc      = frame->f_pc;
+
+       /* How amazingly convenient! */
+       kfp->hsf_sc._hsc_pad    = 0;
+       kfp->hsf_sc._hsc_ap     = (int)&fp->hsf_sigstate;
+
+       (void) copyout((caddr_t)kfp, (caddr_t)fp, fsize);
+       frame->f_regs[SP] = (int)fp;
+
+#ifdef DEBUG
+       if (hpuxsigdebug & SDB_FOLLOW) {
+               printf(
+                 "hpux_sendsig(%d): sig %d scp %x fp %x sc_sp %x sc_ap %x\n",
+                  p->p_pid, sig, kfp->sf_scp, fp,
+                  kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap);
+       }
+#endif
 
-#ifdef FPCOPROC
        /*
-        * Copy 68881 registers from our PCB format to HP-UX format
+        * Signal trampoline code is at base of user stack.
         */
-       bp = (struct bsdfp *) &p->p_addr->u_pcb.pcb_fpregs;
-       bcopy((caddr_t)bp->save, (caddr_t)faku->hpuxu_fp.hpfp_save,
-           sizeof(bp->save));
-       bcopy((caddr_t)bp->ctrl, (caddr_t)faku->hpuxu_fp.hpfp_ctrl,
-           sizeof(bp->ctrl));
-       bcopy((caddr_t)bp->reg, (caddr_t)faku->hpuxu_fp.hpfp_reg,
-           sizeof(bp->reg));
+       frame->f_pc = (int)PS_STRINGS - (esigcode - sigcode);
+#ifdef DEBUG
+       if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
+               printf("hpux_sendsig(%d): sig %d returns\n",
+                      p->p_pid, sig);
+#endif
+       free((caddr_t)kfp, M_TEMP);
+}
+
+/*
+ * System call to cleanup state after a signal
+ * has been taken.  Reset signal mask and
+ * stack state from context left by sendsig (above).
+ * Return to previous pc and psl as specified by
+ * context left by sendsig. Check carefully to
+ * make sure that the user has not modified the
+ * psl to gain improper priviledges or to cause
+ * a machine fault.
+ */
+/* ARGSUSED */
+int
+hpux_sys_sigreturn(p, v, retval)
+       struct proc *p;
+       void *v;
+       register_t *retval;
+{
+       struct hpux_sys_sigreturn_args /* {
+               syscallarg(struct hpuxsigcontext *) sigcntxp;
+       } */ *uap = v;
+       register struct hpuxsigcontext *scp;
+       register struct frame *frame;
+       register int rf;
+       struct hpuxsigcontext tsigc;
+       struct hpuxsigstate tstate;
+       int flags;
+
+       scp = SCARG(uap, sigcntxp);
+#ifdef DEBUG
+       if (hpuxsigdebug & SDB_FOLLOW)
+               printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
 #endif
+       if ((int)scp & 1)
+               return (EINVAL);
 
        /*
-        * Slay the dragon
+        * Fetch and test the HP-UX context structure.
+        * We grab it all at once for speed.
         */
-       faku->hpuxu_dragon = -1;
+       if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
+           copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc))
+               return (EINVAL);
+       scp = &tsigc;
+       if ((scp->hsc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0)
+               return (EINVAL);
 
        /*
-        * Dump this artfully constructed page in place of the
-        * user struct page.
+        * Restore the user supplied information
         */
-       error = vn_rdwr(UIO_WRITE, vp, (caddr_t)faku, ctob(1), (off_t)0,
-           UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p);
+       if (scp->hsc_onstack & 01)
+               p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
+       else
+               p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
+       p->p_sigmask = scp->hsc_mask &~ sigcantmask;
+       frame = (struct frame *) p->p_md.md_regs;
+       frame->f_regs[SP] = scp->hsc_sp;
+       frame->f_pc = scp->hsc_pc;
+       frame->f_sr = scp->hsc_ps;
 
        /*
-        * Dump the remaining UPAGES-1 pages normally
-        * XXX Spot the wild guess.
+        * Grab a pointer to the hpuxsigstate.
+        * If zero, the user is probably doing a longjmp.
+        * (This will never happen, really, since HP-UX doesn't
+        * know/care about the state pointer.)
         */
-       if (error == 0)
-               error = vn_rdwr(UIO_WRITE, vp, (caddr_t)p->p_addr + ctob(1),
-                   ctob(UPAGES-1), (off_t)ctob(1), UIO_SYSSPACE,
-                   IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p);
+       if ((rf = scp->_hsc_ap) == 0)
+               return (EJUSTRETURN);
+
+       /*
+        * See if there is anything to do before we go to the
+        * expense of copying in close to 1/2K of data
+        */
+       flags = fuword((caddr_t)rf);
+#ifdef DEBUG
+       if (hpuxsigdebug & SDB_FOLLOW)
+               printf("sigreturn(%d): sc_ap %x flags %x\n",
+                      p->p_pid, rf, flags);
+#endif
+       /*
+        * fuword failed (bogus _hsc_ap value).
+        */
+       if (flags == -1)
+               return (EINVAL);
+       if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
+               return (EJUSTRETURN);
+#ifdef DEBUG
+       if ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid)
+               printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n",
+                      p->p_pid, &flags, scp->sc_sp, SCARG(uap, sigcntxp),
+                      (flags & HSS_RTEFRAME) ? tstate.ss_frame.f_format : -1);
+#endif
+       /*
+        * Restore most of the users registers except for A6 and SP
+        * which were handled above.
+        */
+       if (flags & HSS_USERREGS)
+               bcopy((caddr_t)tstate.hss_frame.f_regs,
+                   (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
+
+       /*
+        * Restore long stack frames.  Note that we do not copy
+        * back the saved SR or PC, they were picked up above from
+        * the sigcontext structure.
+        */
+       if (flags & HSS_RTEFRAME) {
+               register int sz;
+               
+               /* grab frame type and validate */
+               sz = tstate.hss_frame.f_format;
+               if (sz > 15 || (sz = exframesize[sz]) < 0)
+                       return (EINVAL);
+               frame->f_stackadj -= sz;
+               frame->f_format = tstate.hss_frame.f_format;
+               frame->f_vector = tstate.hss_frame.f_vector;
+               bcopy((caddr_t)&tstate.hss_frame.F_u,
+                   (caddr_t)&frame->F_u, sz);
+#ifdef DEBUG
+               if (hpuxsigdebug & SDB_FOLLOW)
+                       printf("sigreturn(%d): copy in %d of frame type %d\n",
+                              p->p_pid, sz, tstate.ss_frame.f_format);
+#endif
+       }
 
-       free((caddr_t)faku, M_TEMP);
+       /*
+        * Finally we restore the original FP context
+        */
+       if (flags & HSS_FPSTATE)
+               m68881_restore(&tstate.hss_fpstate);
+
+#ifdef DEBUG
+       if ((hpuxsigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
+               printf("sigreturn(%d): copied in FP state (%x) at %x\n",
+                      p->p_pid, *(u_int *)&tstate.ss_fpstate,
+                      &tstate.ss_fpstate);
+
+       if ((hpuxsigdebug & SDB_FOLLOW) ||
+           ((hpuxsigdebug & SDB_KSTACK) && p->p_pid == hpuxsigpid))
+               printf("sigreturn(%d): returns\n", p->p_pid);
+#endif
+       return (EJUSTRETURN);
+}
 
-       return (error);
+/*
+ * Set registers on exec.
+ * XXX Should clear registers except sp, pc.
+ */
+void
+hpux_setregs(p, pack, stack, retval)
+       register struct proc *p;
+       struct exec_package *pack;
+       u_long stack;
+       register_t *retval;
+{
+       struct frame *frame = (struct frame *)p->p_md.md_regs;
+
+       frame->f_pc = pack->ep_entry & ~1;
+       frame->f_regs[SP] = stack;
+       frame->f_regs[A2] = (int)PS_STRINGS;
+
+       /* restore a null state frame */
+       p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
+       if (fputype)
+               m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
+
+       p->p_md.md_flags &= ~MDP_HPUXMMAP;
+       frame->f_regs[A0] = 0;  /* not 68010 (bit 31), no FPA (30) */
+       retval[0] = 0;          /* no float card */
+       if (fputype)
+               retval[1] = 1;  /* yes 68881 */
+       else
+               retval[1] = 0;  /* no 68881 */
 }
index befe538..f491e6f 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: locore.s,v 1.12 1997/02/23 21:42:54 downsj Exp $      */
-/*     $NetBSD: locore.s,v 1.63 1997/02/02 07:55:52 thorpej Exp $      */
+/*     $OpenBSD: locore.s,v 1.13 1997/03/26 08:32:41 downsj Exp $      */
+/*     $NetBSD: locore.s,v 1.67 1997/03/16 10:49:43 thorpej Exp $      */
 
 /*
  * Copyright (c) 1997 Theo de Raadt
@@ -74,6 +74,7 @@
  */
 
 #include "assym.h"
+#include <machine/trap.h>
 
 #define MMUADDR(ar)    movl    _MMUbase,ar
 #define CLKADDR(ar)    movl    _CLKbase,ar
@@ -106,663 +107,513 @@ tmpstk:
        .text
 
 /*
- * Do a dump.
- * Called by auto-restart.
- */
-       .globl  _dumpsys
-       .globl  _doadump
-_doadump:
-       jbsr    _dumpsys
-       jbsr    _doboot
-       /*NOTREACHED*/
-
-/*
- * Trap/interrupt vector routines
- */ 
-
-       .globl  _trap, _nofault, _longjmp
-_buserr:
-       /*
-        * XXX TODO: look at the mac68k _buserr and generalize
-        * XXX the saving of the fault address so this routine
-        * XXX can be shared.
-        */
-       tstl    _nofault                | device probe?
-       jeq     Lberr                   | no, handle as usual
-       movl    _nofault,sp@-           | yes,
-       jbsr    _longjmp                |  longjmp(nofault)
-Lberr:
-#if defined(M68040)
-#if defined(M68020) || defined(M68030)
-       cmpl    #MMU_68040,_mmutype     | 68040?
-       jne     _addrerr                | no, skip
-#endif
-       clrl    sp@-                    | stack adjust count
-       moveml  #0xFFFF,sp@-            | save user registers
-       movl    usp,a0                  | save the user SP
-       movl    a0,sp@(FR_SP)           |   in the savearea
-       lea     sp@(FR_HW),a1           | grab base of HW berr frame
-       moveq   #0,d0
-       movw    a1@(12),d0              | grab SSW
-       movl    a1@(20),d1              | and fault VA
-       btst    #11,d0                  | check for mis-aligned access
-       jeq     Lberr2                  | no, skip
-       addl    #3,d1                   | yes, get into next page
-       andl    #PG_FRAME,d1            | and truncate
-Lberr2:
-       movl    d1,sp@-                 | push fault VA
-       movl    d0,sp@-                 | and padded SSW
-       btst    #10,d0                  | ATC bit set?
-       jeq     Lisberr                 | no, must be a real bus error
-       movc    dfc,d1                  | yes, get MMU fault
-       movc    d0,dfc                  | store faulting function code
-       movl    sp@(4),a0               | get faulting address
-       .word   0xf568                  | ptestr a0@
-       movc    d1,dfc
-       .long   0x4e7a0805              | movc mmusr,d0
-       movw    d0,sp@                  | save (ONLY LOW 16 BITS!)
-       jra     Lismerr
-#endif
-_addrerr:
-       clrl    sp@-                    | stack adjust count
-       moveml  #0xFFFF,sp@-            | save user registers
-       movl    usp,a0                  | save the user SP
-       movl    a0,sp@(FR_SP)           |   in the savearea
-       lea     sp@(FR_HW),a1           | grab base of HW berr frame
-#if defined(M68040)
-#if defined(M68020) || defined(M68030)
-       cmpl    #MMU_68040,_mmutype     | 68040?
-       jne     Lbenot040               | no, skip
-#endif
-       movl    a1@(8),sp@-             | yes, push fault address
-       clrl    sp@-                    | no SSW for address fault
-       jra     Lisaerr                 | go deal with it
-Lbenot040:
-#endif
-       moveq   #0,d0
-       movw    a1@(10),d0              | grab SSW for fault processing
-       btst    #12,d0                  | RB set?
-       jeq     LbeX0                   | no, test RC
-       bset    #14,d0                  | yes, must set FB
-       movw    d0,a1@(10)              | for hardware too
-LbeX0:
-       btst    #13,d0                  | RC set?
-       jeq     LbeX1                   | no, skip
-       bset    #15,d0                  | yes, must set FC
-       movw    d0,a1@(10)              | for hardware too
-LbeX1:
-       btst    #8,d0                   | data fault?
-       jeq     Lbe0                    | no, check for hard cases
-       movl    a1@(16),d1              | fault address is as given in frame
-       jra     Lbe10                   | thats it
-Lbe0:
-       btst    #4,a1@(6)               | long (type B) stack frame?
-       jne     Lbe4                    | yes, go handle
-       movl    a1@(2),d1               | no, can use save PC
-       btst    #14,d0                  | FB set?
-       jeq     Lbe3                    | no, try FC
-       addql   #4,d1                   | yes, adjust address
-       jra     Lbe10                   | done
-Lbe3:
-       btst    #15,d0                  | FC set?
-       jeq     Lbe10                   | no, done
-       addql   #2,d1                   | yes, adjust address
-       jra     Lbe10                   | done
-Lbe4:
-       movl    a1@(36),d1              | long format, use stage B address
-       btst    #15,d0                  | FC set?
-       jeq     Lbe10                   | no, all done
-       subql   #2,d1                   | yes, adjust address
-Lbe10:
-       movl    d1,sp@-                 | push fault VA
-       movl    d0,sp@-                 | and padded SSW
-       movw    a1@(6),d0               | get frame format/vector offset
-       andw    #0x0FFF,d0              | clear out frame format
-       cmpw    #12,d0                  | address error vector?
-       jeq     Lisaerr                 | yes, go to it
-#if defined(M68K_MMU_MOTOROLA)
-#if defined(M68K_MMU_HP)
-       tstl    _mmutype                | HP MMU?
-       jeq     Lbehpmmu                | yes, skip
-#endif
-       movl    d1,a0                   | fault address
-       movl    sp@,d0                  | function code from ssw
-       btst    #8,d0                   | data fault?
-       jne     Lbe10a
-       movql   #1,d0                   | user program access FC
-                                       | (we dont separate data/program)
-       btst    #5,a1@                  | supervisor mode?
-       jeq     Lbe10a                  | if no, done
-       movql   #5,d0                   | else supervisor program access
-Lbe10a:
-       ptestr  d0,a0@,#7               | do a table search
-       pmove   psr,sp@                 | save result
-       movb    sp@,d1
-       btst    #2,d1                   | invalid? (incl. limit viol and berr)
-       jeq     Lmightnotbemerr         | no -> wp check
-       btst    #7,d1                   | is it MMU table berr?
-       jeq     Lismerr                 | no, must be fast
-       jra     Lisberr1                | real bus err needs not be fast
-Lmightnotbemerr:
-       btst    #3,d1                   | write protect bit set?
-       jeq     Lisberr1                | no, must be bus error
-       movl    sp@,d0                  | ssw into low word of d0
-       andw    #0xc0,d0                | write protect is set on page:
-       cmpw    #0x40,d0                | was it read cycle?
-       jeq     Lisberr1                | yes, was not WPE, must be bus err
-       jra     Lismerr                 | no, must be mem err
-Lbehpmmu:
-#endif
-#if defined(M68K_MMU_HP)
-       MMUADDR(a0)
-       movl    a0@(MMUSTAT),d0         | read status
-       btst    #3,d0                   | MMU fault?
-       jeq     Lisberr                 | no, just a non-MMU bus error so skip
-       andl    #~MMU_FAULT,a0@(MMUSTAT)| yes, clear fault bits
-       movw    d0,sp@                  | pass MMU stat in upper half of code
-#endif
-Lismerr:
-       movl    #T_MMUFLT,sp@-          | show that we are an MMU fault
-       jra     Ltrapnstkadj            | and deal with it
-Lisaerr:
-       movl    #T_ADDRERR,sp@-         | mark address error
-       jra     Ltrapnstkadj            | and deal with it
-Lisberr1:
-       clrw    sp@                     | re-clear pad word
-Lisberr:
-       movl    #T_BUSERR,sp@-          | mark bus error
-Ltrapnstkadj:
-       jbsr    _trap                   | handle the error
-       lea     sp@(12),sp              | pop value args
-       movl    sp@(FR_SP),a0           | restore user SP
-       movl    a0,usp                  |   from save area
-       movw    sp@(FR_ADJ),d0          | need to adjust stack?
-       jne     Lstkadj                 | yes, go to it
-       moveml  sp@+,#0x7FFF            | no, restore most user regs
-       addql   #8,sp                   | toss SSP and stkadj
-       jra     rei                     | all done
-Lstkadj:
-       lea     sp@(FR_HW),a1           | pointer to HW frame
-       addql   #8,a1                   | source pointer
-       movl    a1,a0                   | source
-       addw    d0,a0                   |  + hole size = dest pointer
-       movl    a1@-,a0@-               | copy
-       movl    a1@-,a0@-               |  8 bytes
-       movl    a0,sp@(FR_SP)           | new SSP
-       moveml  sp@+,#0x7FFF            | restore user registers
-       movl    sp@,sp                  | and our SP
-       jra     rei                     | all done
-
-/*
- * FP exceptions.
- */
-_fpfline:              /* XXXthorpej - candidate for vector patch */
-#if defined(M68040)
-       cmpw    #0x202c,sp@(6)          | format type 2?
-       jne     _illinst                | no, not an FP emulation
-#ifdef FPSP
-       .globl fpsp_unimp
-       jmp     fpsp_unimp              | yes, go handle it
-#else
-       clrl    sp@-                    | stack adjust count
-       moveml  #0xFFFF,sp@-            | save registers
-       moveq   #T_FPEMULI,d0           | denote as FP emulation trap
-       jra     fault                   | do it
-#endif
-#else
-       jra     _illinst
-#endif
-
-_fpunsupp:             /* XXXthorpej - candidate for vector patch */
-#if defined(M68040)
-       cmpl    #MMU_68040,_mmutype     | 68040?
-       jne     _illinst                | no, treat as illinst
-#ifdef FPSP
-       .globl  fpsp_unsupp
-       jmp     fpsp_unsupp             | yes, go handle it
-#else
-       clrl    sp@-                    | stack adjust count
-       moveml  #0xFFFF,sp@-            | save registers
-       moveq   #T_FPEMULD,d0           | denote as FP emulation trap
-       jra     fault                   | do it
-#endif
-#else
-       jra     _illinst
-#endif
-
-/*
- * Handles all other FP coprocessor exceptions.
- * Note that since some FP exceptions generate mid-instruction frames
- * and may cause signal delivery, we need to test for stack adjustment
- * after the trap call.
- */
-       .globl  _fpfault
-_fpfault:
-#ifdef FPCOPROC
-       clrl    sp@-            | stack adjust count
-       moveml  #0xFFFF,sp@-    | save user registers
-       movl    usp,a0          | and save
-       movl    a0,sp@(FR_SP)   |   the user stack pointer
-       clrl    sp@-            | no VA arg
-       movl    _curpcb,a0      | current pcb
-       lea     a0@(PCB_FPCTX),a0 | address of FP savearea
-       fsave   a0@             | save state
-#if defined(M68040) || defined(M68060)
-       /* always null state frame on 68040, 68060 */
-       cmpl    #MMU_68040,_mmutype
-       jle     Lfptnull
-#endif
-       tstb    a0@             | null state frame?
-       jeq     Lfptnull        | yes, safe
-       clrw    d0              | no, need to tweak BIU
-       movb    a0@(1),d0       | get frame size
-       bset    #3,a0@(0,d0:w)  | set exc_pend bit of BIU
-Lfptnull:
-       fmovem  fpsr,sp@-       | push fpsr as code argument
-       frestore a0@            | restore state
-       movl    #T_FPERR,sp@-   | push type arg
-       jra     Ltrapnstkadj    | call trap and deal with stack cleanup
-#else
-       jra     _badtrap        | treat as an unexpected trap
-#endif
-
-/*
- * Coprocessor and format errors can generate mid-instruction stack
- * frames and cause signal delivery hence we need to check for potential
- * stack adjustment.
- */
-_coperr:
-       clrl    sp@-            | stack adjust count
-       moveml  #0xFFFF,sp@-
-       movl    usp,a0          | get and save
-       movl    a0,sp@(FR_SP)   |   the user stack pointer
-       clrl    sp@-            | no VA arg
-       clrl    sp@-            | or code arg
-       movl    #T_COPERR,sp@-  | push trap type
-       jra     Ltrapnstkadj    | call trap and deal with stack adjustments
-
-_fmterr:
-       clrl    sp@-            | stack adjust count
-       moveml  #0xFFFF,sp@-
-       movl    usp,a0          | get and save
-       movl    a0,sp@(FR_SP)   |   the user stack pointer
-       clrl    sp@-            | no VA arg
-       clrl    sp@-            | or code arg
-       movl    #T_FMTERR,sp@-  | push trap type
-       jra     Ltrapnstkadj    | call trap and deal with stack adjustments
-
-/*
- * Other exceptions only cause four and six word stack frame and require
- * no post-trap stack adjustment.
- */
-_illinst:
-       clrl    sp@-
-       moveml  #0xFFFF,sp@-
-       moveq   #T_ILLINST,d0
-       jra     fault
-
-_zerodiv:
-       clrl    sp@-
-       moveml  #0xFFFF,sp@-
-       moveq   #T_ZERODIV,d0
-       jra     fault
-
-_chkinst:
-       clrl    sp@-
-       moveml  #0xFFFF,sp@-
-       moveq   #T_CHKINST,d0
-       jra     fault
-
-_trapvinst:
-       clrl    sp@-
-       moveml  #0xFFFF,sp@-
-       moveq   #T_TRAPVINST,d0
-       jra     fault
-
-_privinst:
-       clrl    sp@-
-       moveml  #0xFFFF,sp@-
-       moveq   #T_PRIVINST,d0
-       jra     fault
-
-       .globl  fault
-fault:
-       movl    usp,a0                  | get and save
-       movl    a0,sp@(FR_SP)           |   the user stack pointer
-       clrl    sp@-                    | no VA arg
-       clrl    sp@-                    | or code arg
-       movl    d0,sp@-                 | push trap type
-       jbsr    _trap                   | handle trap
-       lea     sp@(12),sp              | pop value args
-       movl    sp@(FR_SP),a0           | restore
-       movl    a0,usp                  |   user SP
-       moveml  sp@+,#0x7FFF            | restore most user regs
-       addql   #8,sp                   | pop SP and stack adjust
-       jra     rei                     | all done
-
-       .globl  _straytrap
-_badtrap:
-       moveml  #0xC0C0,sp@-            | save scratch regs
-       movw    sp@(22),sp@-            | push exception vector info
-       clrw    sp@-
-       movl    sp@(22),sp@-            | and PC
-       jbsr    _straytrap              | report
-       addql   #8,sp                   | pop args
-       moveml  sp@+,#0x0303            | restore regs
-       jra     rei                     | all done
-
-       .globl  _syscall
-_trap0:
-       clrl    sp@-                    | stack adjust count
-       moveml  #0xFFFF,sp@-            | save user registers
-       movl    usp,a0                  | save the user SP
-       movl    a0,sp@(FR_SP)           |   in the savearea
-       movl    d0,sp@-                 | push syscall number
-       jbsr    _syscall                | handle it
-       addql   #4,sp                   | pop syscall arg
-       tstl    _astpending
-       jne     Lrei2
-       tstb    _ssir
-       jeq     Ltrap1
-       movw    #SPL1,sr
-       tstb    _ssir
-       jne     Lsir1
-Ltrap1:        
-       movl    sp@(FR_SP),a0           | grab and restore
-       movl    a0,usp                  |   user SP
-       moveml  sp@+,#0x7FFF            | restore most registers
-       addql   #8,sp                   | pop SP and stack adjust
-       rte
-
-/*
- * Routines for traps 1 and 2.  The meaning of the two traps depends
- * on whether we are an HPUX compatible process or a native 4.3 process.
- * Our native 4.3 implementation uses trap 1 as sigreturn() and trap 2
- * as a breakpoint trap.  HPUX uses trap 1 for a breakpoint, so we have
- * to make adjustments so that trap 2 is used for sigreturn.
- */
-_trap1:
-       btst    #MDP_TRCB,mdpflag       | being traced by an HPUX process?
-       jeq     sigreturn               | no, trap1 is sigreturn
-       jra     _trace                  | yes, trap1 is breakpoint
-
-_trap2:
-       btst    #MDP_TRCB,mdpflag       | being traced by an HPUX process?
-       jeq     _trace                  | no, trap2 is breakpoint
-       jra     sigreturn               | yes, trap2 is sigreturn
-
-/*
- * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD)
- *     cachectl(command, addr, length)
- * command in d0, addr in a1, length in d1
- */
-       .globl  _cachectl
-_trap12:
-       movl    d1,sp@-                 | push length
-       movl    a1,sp@-                 | push addr
-       movl    d0,sp@-                 | push command
-       jbsr    _cachectl               | do it
-       lea     sp@(12),sp              | pop args
-       jra     rei                     | all done
-
-/*
- * Trace (single-step) trap.  Kernel-mode is special.
- * User mode traps are simply passed on to trap().
+ * Macro to relocate a symbol, used before MMU is enabled.
  */
-_trace:
-       clrl    sp@-                    | stack adjust count
-       moveml  #0xFFFF,sp@-
-       moveq   #T_TRACE,d0
-       movw    sp@(FR_HW),d1           | get PSW
-       andw    #PSL_S,d1               | from system mode?
-       jne     kbrkpt                  | yes, kernel breakpoint
-       jra     fault                   | no, user-mode fault
+#define        RELOC(var, ar)          \
+       lea     var,ar;         \
+       addl    a5,ar
 
 /*
- * Trap 15 is used for:
- *     - GDB breakpoints (in user programs)
- *     - KGDB breakpoints (in the kernel)
- *     - trace traps for SUN binaries (not fully supported yet)
- * User mode traps are simply passed to trap().
+ * Initialization
+ *
+ * A4 contains the address of the end of the symtab
+ * A5 contains physical load point from boot
+ * VBR contains zero from ROM.  Exceptions will continue to vector
+ * through ROM until MMU is turned on at which time they will vector
+ * through our table (vectors.s).
  */
-_trap15:
-       clrl    sp@-                    | stack adjust count
-       moveml  #0xFFFF,sp@-
-       moveq   #T_TRAP15,d0
-       movw    sp@(FR_HW),d1           | get PSW
-       andw    #PSL_S,d1               | from system mode?
-       jne     kbrkpt                  | yes, kernel breakpoint
-       jra     fault                   | no, user-mode fault
+       .comm   _lowram,4
+       .comm   _esym,4
 
-kbrkpt:        | Kernel-mode breakpoint or trace trap. (d0=trap_type)
-       | Save the system sp rather than the user sp.
-       movw    #PSL_HIGHIPL,sr         | lock out interrupts
-       lea     sp@(FR_SIZE),a6         | Save stack pointer
-       movl    a6,sp@(FR_SP)           |  from before trap
+       .text
+       .globl  _edata
+       .globl  _etext,_end
+       .globl  start
+start:
+       movw    #PSL_HIGHIPL,sr         | no interrupts
+       RELOC(tmpstk, a0)
+       movl    a0,sp                   | give ourselves a temporary stack
+       RELOC(_esym, a0)
+#if 1
+       movl    a4,a0@                  | store end of symbol table
+#else
+       clrl    a0@                     | no symbol table, yet
+#endif
+       RELOC(_lowram, a0)
+       movl    a5,a0@                  | store start of physical memory
+       movl    #CACHE_OFF,d0
+       movc    d0,cacr                 | clear and disable on-chip cache(s)
 
-       | If were are not on tmpstk switch to it.
-       | (so debugger can change the stack pointer)
-       movl    a6,d1
-       cmpl    #tmpstk,d1
-       jls     Lbrkpt2                 | already on tmpstk
-       | Copy frame to the temporary stack
-       movl    sp,a0                   | a0=src
-       lea     tmpstk-96,a1            | a1=dst
-       movl    a1,sp                   | sp=new frame
-       moveq   #FR_SIZE,d1
-Lbrkpt1:
-       movl    a0@+,a1@+
-       subql   #4,d1
-       bgt     Lbrkpt1
+/* check for internal HP-IB in SYSFLAG */
+       btst    #5,0xfffffed2           | internal HP-IB?
+       jeq     Lhaveihpib              | yes, have HP-IB just continue
+       RELOC(_internalhpib, a0)
+       movl    #0,a0@                  | no, clear associated address
+Lhaveihpib:
 
-Lbrkpt2:
-       | Call the trap handler for the kernel debugger.
-       | Do not call trap() to do it, so that we can
-       | set breakpoints in trap() if we want.  We know
-       | the trap type is either T_TRACE or T_BREAKPOINT.
-       | If we have both DDB and KGDB, let KGDB see it first,
-       | because KGDB will just return 0 if not connected.
-       | Save args in d2, a2
-       movl    d0,d2                   | trap type
-       movl    sp,a2                   | frame ptr
-#ifdef KGDB
-       | Let KGDB handle it (if connected)
-       movl    a2,sp@-                 | push frame ptr
-       movl    d2,sp@-                 | push trap type
-       jbsr    _kgdb_trap              | handle the trap
-       addql   #8,sp                   | pop args
-       cmpl    #0,d0                   | did kgdb handle it?
-       jne     Lbrkpt3                 | yes, done
-#endif
-#ifdef DDB
-       | Let DDB handle it
-       movl    a2,sp@-                 | push frame ptr
-       movl    d2,sp@-                 | push trap type
-       jbsr    _kdb_trap               | handle the trap
-       addql   #8,sp                   | pop args
-#if 0  /* not needed on hp300 */
-       cmpl    #0,d0                   | did ddb handle it?
-       jne     Lbrkpt3                 | yes, done
-#endif
-#endif
-       /* Sun 3 drops into PROM here. */
-Lbrkpt3:
-       | The stack pointer may have been modified, or
-       | data below it modified (by kgdb push call),
-       | so push the hardware frame at the current sp
-       | before restoring registers and returning.
+       RELOC(_boothowto, a0)           | save reboot flags
+       movl    d7,a0@
+       RELOC(_bootdev, a0)             |   and boot device
+       movl    d6,a0@
 
-       movl    sp@(FR_SP),a0           | modified sp
-       lea     sp@(FR_SIZE),a1         | end of our frame
-       movl    a1@-,a0@-               | copy 2 longs with
-       movl    a1@-,a0@-               | ... predecrement
-       movl    a0,sp@(FR_SP)           | sp = h/w frame
-       moveml  sp@+,#0x7FFF            | restore all but sp
-       movl    sp@,sp                  | ... and sp
-       rte                             | all done
+       /*
+        * All data registers are now free.  All address registers
+        * except a5 are free.  a5 is used by the RELOC() macro,
+        * and cannot be used until after the MMU is enabled.
+        */
 
-/* Use common m68k sigreturn */
-#include <m68k/m68k/sigreturn.s>
+/* determine our CPU/MMU combo - check for all regardless of kernel config */
+       movl    #INTIOBASE+MMUBASE,a1
+       movl    #0x200,d0               | data freeze bit
+       movc    d0,cacr                 |   only exists on 68030
+       movc    cacr,d0                 | read it back
+       tstl    d0                      | zero?
+       jeq     Lnot68030               | yes, we have 68020/68040
+       RELOC(_mmutype, a0)             | no, we have 68030
+       movl    #MMU_68030,a0@          | set to reflect 68030 PMMU
+       RELOC(_cputype, a0)
+       movl    #CPU_68030,a0@          | and 68030 CPU
+       RELOC(_machineid, a0)
+       movl    #0x80,a1@(MMUCMD)       | set magic cookie
+       movl    a1@(MMUCMD),d0          | read it back
+       btst    #7,d0                   | cookie still on?
+       jeq     Lnot370                 | no, 360 or 375
+       movl    #0,a1@(MMUCMD)          | clear magic cookie
+       movl    a1@(MMUCMD),d0          | read it back
+       btst    #7,d0                   | still on?
+       jeq     Lisa370                 | no, must be a 370
+       movl    #HP_340,a0@             | yes, must be a 340
+       jra     Lstart1
+Lnot370:
+       movl    #HP_360,a0@             | type is at least a 360
+       movl    #0,a1@(MMUCMD)          | clear magic cookie2
+       movl    a1@(MMUCMD),d0          | read it back
+       btst    #16,d0                  | still on?
+       jeq     Lstart1                 | no, must be a 360
+       movl    #HP_375,a0@             | yes, must be a 345/375
+       jra     Lhaspac
+Lisa370:
+       movl    #HP_370,a0@             | set to 370
+Lhaspac:
+       RELOC(_ectype, a0)
+       movl    #EC_PHYS,a0@            | also has a physical address cache
+       jra     Lstart1
+Lnot68030:
+       bset    #31,d0                  | data cache enable bit
+       movc    d0,cacr                 |   only exists on 68040
+       movc    cacr,d0                 | read it back
+       tstl    d0                      | zero?
+       beq     Lis68020                | yes, we have 68020
+       moveq   #0,d0                   | now turn it back off
+       movec   d0,cacr                 |   before we access any data
+       RELOC(_mmutype, a0)
+       movl    #MMU_68040,a0@          | with a 68040 MMU
+       RELOC(_cputype, a0)
+       movl    #CPU_68040,a0@          | and a 68040 CPU
+       RELOC(_fputype, a0)
+       movl    #FPU_68040,a0@          | ...and FPU
+       RELOC(_ectype, a0)
+       movl    #EC_NONE,a0@            | and no cache (for now XXX)
+       RELOC(_machineid, a0)
+       movl    a1@(MMUCMD),d0          | read MMU register
+       lsrl    #8,d0                   | get apparent ID
+       cmpb    #6,d0                   | id == 6?
+       jeq     Lis33mhz                | yes, we have a 433s
+       movl    #HP_380,a0@             | no, we have a 380/425t
+       jra     Lstart1
+Lis33mhz:
+       movl    #HP_433,a0@             | 433s (XXX 425s returns same ID, ugh!)
+       jra     Lstart1
+Lis68020:
+       movl    #1,a1@(MMUCMD)          | a 68020, write HP MMU location
+       movl    a1@(MMUCMD),d0          | read it back
+       btst    #0,d0                   | non-zero?
+       jne     Lishpmmu                | yes, we have HP MMU
+       RELOC(_mmutype, a0)
+       movl    #MMU_68851,a0@          | no, we have PMMU
+       RELOC(_machineid, a0)
+       movl    #HP_330,a0@             | and 330 CPU
+       jra     Lstart1
+Lishpmmu:
+       RELOC(_ectype, a0)              | 320 or 350
+       movl    #EC_VIRT,a0@            | both have a virtual address cache
+       movl    #0x80,a1@(MMUCMD)       | set magic cookie
+       movl    a1@(MMUCMD),d0          | read it back
+       btst    #7,d0                   | cookie still on?
+       jeq     Lis320                  | no, just a 320
+       RELOC(_machineid, a0)
+       movl    #HP_350,a0@             | yes, a 350
+       jra     Lstart1
+Lis320:
+       RELOC(_machineid, a0)
+       movl    #HP_320,a0@
+
+Lstart1:
+       movl    #0,a1@(MMUCMD)          | clear out MMU again
+/* initialize source/destination control registers for movs */
+       moveq   #FC_USERD,d0            | user space
+       movc    d0,sfc                  |   as source
+       movc    d0,dfc                  |   and destination of transfers
+/* initialize memory sizes (for pmap_bootstrap) */
+       movl    #MAXADDR,d1             | last page
+       moveq   #PGSHIFT,d2
+       lsrl    d2,d1                   | convert to page (click) number
+       RELOC(_maxmem, a0)
+       movl    d1,a0@                  | save as maxmem
+       movl    a5,d0                   | lowram value from ROM via boot
+       lsrl    d2,d0                   | convert to page number
+       subl    d0,d1                   | compute amount of RAM present
+       RELOC(_physmem, a0)
+       movl    d1,a0@                  | and physmem
+/* configure kernel and proc0 VA space so we can get going */
+       .globl  _Sysseg, _pmap_bootstrap, _avail_start
+#ifdef DDB
+       RELOC(_esym,a0)                 | end of static kernel test/data/syms
+       movl    a0@,d5
+       jne     Lstart2
+#endif
+       movl    #_end,d5                | end of static kernel text/data
+Lstart2:
+       addl    #NBPG-1,d5
+       andl    #PG_FRAME,d5            | round to a page
+       movl    d5,a4
+       addl    a5,a4                   | convert to PA
+       pea     a5@                     | firstpa
+       pea     a4@                     | nextpa
+       RELOC(_pmap_bootstrap,a0)
+       jbsr    a0@                     | pmap_bootstrap(firstpa, nextpa)
+       addql   #8,sp
 
 /*
- * Interrupt handlers.
- * All device interrupts are auto-vectored.  The CPU provides
- * the vector 0x18+level.  Note we count spurious interrupts, but
- * we don't do anything else with them.
+ * Prepare to enable MMU.
+ * Since the kernel is not mapped logical == physical we must insure
+ * that when the MMU is turned on, all prefetched addresses (including
+ * the PC) are valid.  In order guarentee that, we use the last physical
+ * page (which is conveniently mapped == VA) and load it up with enough
+ * code to defeat the prefetch, then we execute the jump back to here.
+ *
+ * Is this all really necessary, or am I paranoid??
  */
+       RELOC(_Sysseg, a0)              | system segment table addr
+       movl    a0@,d1                  | read value (a KVA)
+       addl    a5,d1                   | convert to PA
+       RELOC(_mmutype, a0)
+       tstl    a0@                     | HP MMU?
+       jeq     Lhpmmu2                 | yes, skip
+       cmpl    #MMU_68040,a0@          | 68040?
+       jne     Lmotommu1               | no, skip
+       .long   0x4e7b1807              | movc d1,srp
+       jra     Lstploaddone
+Lmotommu1:
+       RELOC(_protorp, a0)
+       movl    #0x80000202,a0@         | nolimit + share global + 4 byte PTEs
+       movl    d1,a0@(4)               | + segtable address
+       pmove   a0@,srp                 | load the supervisor root pointer
+       movl    #0x80000002,a0@         | reinit upper half for CRP loads
+       jra     Lstploaddone            | done
+Lhpmmu2:
+       moveq   #PGSHIFT,d2
+       lsrl    d2,d1                   | convert to page frame
+       movl    d1,INTIOBASE+MMUBASE+MMUSSTP | load in sysseg table register
+Lstploaddone:
+       lea     MAXADDR,a2              | PA of last RAM page
+       RELOC(Lhighcode, a1)            | addr of high code
+       RELOC(Lehighcode, a3)           | end addr
+Lcodecopy:
+       movw    a1@+,a2@+               | copy a word
+       cmpl    a3,a1                   | done yet?
+       jcs     Lcodecopy               | no, keep going
+       jmp     MAXADDR                 | go for it!
 
-#define INTERRUPT_SAVEREG      moveml  #0xC0C0,sp@-
-#define INTERRUPT_RESTOREREG   moveml  sp@+,#0x0303
+       /*
+        * BEGIN MMU TRAMPOLINE.  This section of code is not
+        * executed in-place.  It's copied to the last page
+        * of RAM (mapped va == pa) and executed there.
+        */
 
-       /* Externs. */
-       .globl  _hilint, _isrdispatch, _nmihand
-       .globl  _hardclock, _statintr
+Lhighcode:
+       /*
+        * Set up the vector table, and race to get the MMU
+        * enabled.
+        */
+       movl    #_vectab,d0             | set Vector Base Register
+       movc    d0,vbr
 
-_spurintr:     /* Level 0 */
-       addql   #1,_intrcnt+0
-       addql   #1,_cnt+V_INTR
-       jra     rei
+       RELOC(_mmutype, a0)
+       tstl    a0@                     | HP MMU?
+       jeq     Lhpmmu3                 | yes, skip
+       cmpl    #MMU_68040,a0@          | 68040?
+       jne     Lmotommu2               | no, skip
+       movw    #0,INTIOBASE+MMUBASE+MMUCMD+2
+       movw    #MMU_IEN+MMU_CEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD+2
+                                       | enable FPU and caches
+       moveq   #0,d0                   | ensure TT regs are disabled
+       .long   0x4e7b0004              | movc d0,itt0
+       .long   0x4e7b0005              | movc d0,itt1
+       .long   0x4e7b0006              | movc d0,dtt0
+       .long   0x4e7b0007              | movc d0,dtt1
+       .word   0xf4d8                  | cinva bc
+       .word   0xf518                  | pflusha
+       movl    #0x8000,d0
+       .long   0x4e7b0003              | movc d0,tc
+       movl    #0x80008000,d0
+       movc    d0,cacr                 | turn on both caches
+       jmp     Lenab1
+Lmotommu2:
+       movl    #MMU_IEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD
+                                       | enable 68881 and i-cache
+       RELOC(_prototc, a2)
+       movl    #0x82c0aa00,a2@         | value to load TC with
+       pmove   a2@,tc                  | load it
+       jmp     Lenab1
+Lhpmmu3:
+       movl    #0,INTIOBASE+MMUBASE+MMUCMD     | clear external cache
+       movl    #MMU_ENAB,INTIOBASE+MMUBASE+MMUCMD | turn on MMU
+       jmp     Lenab1                          | jmp to mapped code
+Lehighcode:
 
-_lev1intr:     /* Level 1: HIL XXX this needs to go away */
-       INTERRUPT_SAVEREG
-       jbsr    _hilint
-       INTERRUPT_RESTOREREG
-       addql   #1,_intrcnt+4
-       addql   #1,_cnt+V_INTR
-       jra     rei
+       /*
+        * END MMU TRAMPOLINE.  Address register a5 is now free.
+        */
 
-_intrhand:     /* Levels 2 through 5 */
-       INTERRUPT_SAVEREG
-       movw    sp@(22),sp@-            | push exception vector info
-       clrw    sp@-
-       jbsr    _isrdispatch            | call dispatch routine
-       addql   #4,sp
-       INTERRUPT_RESTOREREG
-       jra     rei                     | all done
+/*
+ * Should be running mapped from this point on
+ */
+Lenab1:
+/* select the software page size now */
+       lea     tmpstk,sp               | temporary stack
+       jbsr    _vm_set_page_size       | select software page size
+/* set kernel stack, user SP, and initial pcb */
+       movl    _proc0paddr,a1          | get proc0 pcb addr
+       lea     a1@(USPACE-4),sp        | set kernel stack to end of area
+       lea     _proc0,a2               | initialize proc0.p_addr so that
+       movl    a1,a2@(P_ADDR)          |   we don't deref NULL in trap()
+       movl    #USRSTACK-4,a2
+       movl    a2,usp                  | init user SP
+       movl    a1,_curpcb              | proc0 is running
 
-_lev6intr:     /* Level 6: clock */
-       INTERRUPT_SAVEREG
-       CLKADDR(a0)
-       movb    a0@(CLKSR),d0           | read clock status
-Lclkagain:
-       btst    #0,d0                   | clear timer1 int immediately to
-       jeq     Lnotim1                 |  minimize chance of losing another
-       movpw   a0@(CLKMSB1),d1         |  due to statintr processing delay
-Lnotim1:
-       btst    #2,d0                   | timer3 interrupt?
-       jeq     Lnotim3                 | no, skip statclock
-       movpw   a0@(CLKMSB3),d1         | clear timer3 interrupt
-       addql   #1,_intrcnt+28          | count clock interrupts
-       lea     sp@(16),a1              | a1 = &clockframe
-       movl    d0,sp@-                 | save status
-       movl    a1,sp@-
-       jbsr    _statintr               | statintr(&frame)
-       addql   #4,sp
-       movl    sp@+,d0                 | restore pre-statintr status
-       CLKADDR(a0)
-Lnotim3:
-       btst    #0,d0                   | timer1 interrupt?
-       jeq     Lrecheck                | no, skip hardclock
-       addql   #1,_intrcnt+24          | count hardclock interrupts
-       lea     sp@(16),a1              | a1 = &clockframe
+       tstl    _fputype                | Have an FPU?
+       jeq     Lenab2                  | No, skip.
+       clrl    a1@(PCB_FPCTX)          | ensure null FP context
        movl    a1,sp@-
-#ifdef USELEDS
-       .globl  _ledaddr, _inledcontrol, _ledcontrol, _hz
-       tstl    _ledaddr                | using LEDs?
-       jeq     Lnoled0                 | no, skip this code
-       movl    heartbeat,d0            | get tick count
-       addql   #1,d0                   |  increment
-       movl    _hz,d1
-       addl    #50,d1                  | get the timing a little closer
-       cmpl    #0,beatstatus           | time to slow down?
-       jeq     SlowThrob
-       lsrl    #3,d1                   | fast throb
-SlowThrob:
-       lsrl    #1,d1                   | slow throb
-       cmpl    d0,d1                   | are we there yet?
-       jne     Lnoled1                 | no, nothing to do
-       tstl    _inledcontrol           | already updating LEDs?
-       jne     Lnoled2                 | yes, skip it
-       addl    #1,beatstatus           | incr beat status
-       cmpl    #3,beatstatus           | time to reset?
-       ble     SkipReset
-       movl    #0,beatstatus           | reset the status indicator
-SkipReset:
-       movl    #LED_PULSE,sp@-
-       movl    #LED_DISK+LED_LANRCV+LED_LANXMT,sp@-
-       clrl    sp@-
-       jbsr    _ledcontrol             | toggle pulse, turn all others off
-       lea     sp@(12),sp
-Lnoled2:
-       movql   #0,d0
-Lnoled1:
-       movl    d0,heartbeat
-Lnoled0:
-#endif
-       jbsr    _hardclock              | hardclock(&frame)
+       jbsr    _m68881_restore         | restore it (does not kill a1)
        addql   #4,sp
-       CLKADDR(a0)
-Lrecheck:
-       addql   #1,_cnt+V_INTR          | chalk up another interrupt
-       movb    a0@(CLKSR),d0           | see if anything happened
-       jmi     Lclkagain               |  while we were in hardclock/statintr
-       INTERRUPT_RESTOREREG
-       jra     rei                     | all done
+Lenab2:
+/* flush TLB and turn on caches */
+       jbsr    _TBIA                   | invalidate TLB
+       cmpl    #MMU_68040,_mmutype     | 68040?
+       jeq     Lnocache0               | yes, cache already on
+       movl    #CACHE_ON,d0
+       movc    d0,cacr                 | clear cache(s)
+       tstl    _ectype
+       jeq     Lnocache0
+       MMUADDR(a0)
+       orl     #MMU_CEN,a0@(MMUCMD)    | turn on external cache
+Lnocache0:
+/* Final setup for call to main(). */
+       jbsr    _isrinit                | initialize interrupt handlers
+       jbsr    _hp300_calibrate_delay  | calibrate delay() loop
 
-_lev7intr:     /* Level 7: Parity errors, reset key */
-       addql   #1,_intrcnt+32
-       clrl    sp@-
-       moveml  #0xFFFF,sp@-            | save registers
-       movl    usp,a0                  | and save
-       movl    a0,sp@(FR_SP)           |   the user stack pointer
-       jbsr    _nmihand                | call handler
-       movl    sp@(FR_SP),a0           | restore
+/*
+ * Create a fake exception frame so that cpu_fork() can copy it.
+ * main() nevers returns; we exit to user mode from a forked process
+ * later on.
+ */
+       clrw    sp@-                    | vector offset/frame type
+       clrl    sp@-                    | PC - filled in by "execve"
+       movw    #PSL_USER,sp@-          | in user mode
+       clrl    sp@-                    | stack adjust count and padding
+       lea     sp@(-64),sp             | construct space for D0-D7/A0-A7
+       lea     _proc0,a0               | save pointer to frame
+       movl    sp,a0@(P_MD_REGS)       |   in proc0.p_md.md_regs
+
+       jra     _main                   | main()
+
+       pea     Lmainreturned           | Yow!  Main returned!
+       jbsr    _panic
+       /* NOTREACHED */
+Lmainreturned:
+       .asciz  "main() returned"
+       .even
+
+       .globl  _proc_trampoline
+_proc_trampoline:
+       movl    a3,sp@-
+       jbsr    a2@
+       addql   #4,sp
+       movl    sp@(FR_SP),a0           | grab and load
        movl    a0,usp                  |   user SP
-       moveml  sp@+,#0x7FFF            | and remaining registers
-       addql   #8,sp                   | pop SP and stack adjust
-       jra     rei                     | all done
+       moveml  sp@+,#0x7FFF            | restore most user regs
+       addql   #8,sp                   | toss SP and stack adjust
+       jra     rei                     | and return
+
 
 /*
- * Emulation of VAX REI instruction.
- *
- * This code deals with checking for and servicing ASTs
- * (profiling, scheduling) and software interrupts (network, softclock).
- * We check for ASTs first, just like the VAX.  To avoid excess overhead
- * the T_ASTFLT handling code will also check for software interrupts so we
- * do not have to do it here.  After identifing that we need an AST we
- * drop the IPL to allow device interrupts.
- *
- * This code is complicated by the fact that sendsig may have been called
- * necessitating a stack cleanup.
- */
-       .comm   _ssir,1
-       .globl  _astpending
-       .globl  rei
-rei:
-       tstl    _astpending             | AST pending?
-       jeq     Lchksir                 | no, go check for SIR
-Lrei1:
-       btst    #5,sp@                  | yes, are we returning to user mode?
-       jne     Lchksir                 | no, go check for SIR
-       movw    #PSL_LOWIPL,sr          | lower SPL
-       clrl    sp@-                    | stack adjust
-       moveml  #0xFFFF,sp@-            | save all registers
-       movl    usp,a1                  | including
-       movl    a1,sp@(FR_SP)           |    the users SP
-Lrei2:
-       clrl    sp@-                    | VA == none
-       clrl    sp@-                    | code == none
-       movl    #T_ASTFLT,sp@-          | type == async system trap
-       jbsr    _trap                   | go handle it
+ * Trap/interrupt vector routines
+ */ 
+
+       .globl  _trap, _nofault, _longjmp
+_buserr:
+       /*
+        * XXX TODO: look at the mac68k _buserr and generalize
+        * XXX the saving of the fault address so this routine
+        * XXX can be shared.
+        */
+       tstl    _nofault                | device probe?
+       jeq     Lberr                   | no, handle as usual
+       movl    _nofault,sp@-           | yes,
+       jbsr    _longjmp                |  longjmp(nofault)
+Lberr:
+#if defined(M68040)
+#if defined(M68020) || defined(M68030)
+       cmpl    #MMU_68040,_mmutype     | 68040?
+       jne     _addrerr                | no, skip
+#endif
+       clrl    sp@-                    | stack adjust count
+       moveml  #0xFFFF,sp@-            | save user registers
+       movl    usp,a0                  | save the user SP
+       movl    a0,sp@(FR_SP)           |   in the savearea
+       lea     sp@(FR_HW),a1           | grab base of HW berr frame
+       moveq   #0,d0
+       movw    a1@(12),d0              | grab SSW
+       movl    a1@(20),d1              | and fault VA
+       btst    #11,d0                  | check for mis-aligned access
+       jeq     Lberr2                  | no, skip
+       addl    #3,d1                   | yes, get into next page
+       andl    #PG_FRAME,d1            | and truncate
+Lberr2:
+       movl    d1,sp@-                 | push fault VA
+       movl    d0,sp@-                 | and padded SSW
+       btst    #10,d0                  | ATC bit set?
+       jeq     Lisberr                 | no, must be a real bus error
+       movc    dfc,d1                  | yes, get MMU fault
+       movc    d0,dfc                  | store faulting function code
+       movl    sp@(4),a0               | get faulting address
+       .word   0xf568                  | ptestr a0@
+       movc    d1,dfc
+       .long   0x4e7a0805              | movc mmusr,d0
+       movw    d0,sp@                  | save (ONLY LOW 16 BITS!)
+       jra     Lismerr
+#endif
+_addrerr:
+       clrl    sp@-                    | stack adjust count
+       moveml  #0xFFFF,sp@-            | save user registers
+       movl    usp,a0                  | save the user SP
+       movl    a0,sp@(FR_SP)           |   in the savearea
+       lea     sp@(FR_HW),a1           | grab base of HW berr frame
+#if defined(M68040)
+#if defined(M68020) || defined(M68030)
+       cmpl    #MMU_68040,_mmutype     | 68040?
+       jne     Lbenot040               | no, skip
+#endif
+       movl    a1@(8),sp@-             | yes, push fault address
+       clrl    sp@-                    | no SSW for address fault
+       jra     Lisaerr                 | go deal with it
+Lbenot040:
+#endif
+       moveq   #0,d0
+       movw    a1@(10),d0              | grab SSW for fault processing
+       btst    #12,d0                  | RB set?
+       jeq     LbeX0                   | no, test RC
+       bset    #14,d0                  | yes, must set FB
+       movw    d0,a1@(10)              | for hardware too
+LbeX0:
+       btst    #13,d0                  | RC set?
+       jeq     LbeX1                   | no, skip
+       bset    #15,d0                  | yes, must set FC
+       movw    d0,a1@(10)              | for hardware too
+LbeX1:
+       btst    #8,d0                   | data fault?
+       jeq     Lbe0                    | no, check for hard cases
+       movl    a1@(16),d1              | fault address is as given in frame
+       jra     Lbe10                   | thats it
+Lbe0:
+       btst    #4,a1@(6)               | long (type B) stack frame?
+       jne     Lbe4                    | yes, go handle
+       movl    a1@(2),d1               | no, can use save PC
+       btst    #14,d0                  | FB set?
+       jeq     Lbe3                    | no, try FC
+       addql   #4,d1                   | yes, adjust address
+       jra     Lbe10                   | done
+Lbe3:
+       btst    #15,d0                  | FC set?
+       jeq     Lbe10                   | no, done
+       addql   #2,d1                   | yes, adjust address
+       jra     Lbe10                   | done
+Lbe4:
+       movl    a1@(36),d1              | long format, use stage B address
+       btst    #15,d0                  | FC set?
+       jeq     Lbe10                   | no, all done
+       subql   #2,d1                   | yes, adjust address
+Lbe10:
+       movl    d1,sp@-                 | push fault VA
+       movl    d0,sp@-                 | and padded SSW
+       movw    a1@(6),d0               | get frame format/vector offset
+       andw    #0x0FFF,d0              | clear out frame format
+       cmpw    #12,d0                  | address error vector?
+       jeq     Lisaerr                 | yes, go to it
+#if defined(M68K_MMU_MOTOROLA)
+#if defined(M68K_MMU_HP)
+       tstl    _mmutype                | HP MMU?
+       jeq     Lbehpmmu                | yes, skip
+#endif
+       movl    d1,a0                   | fault address
+       movl    sp@,d0                  | function code from ssw
+       btst    #8,d0                   | data fault?
+       jne     Lbe10a
+       movql   #1,d0                   | user program access FC
+                                       | (we dont separate data/program)
+       btst    #5,a1@                  | supervisor mode?
+       jeq     Lbe10a                  | if no, done
+       movql   #5,d0                   | else supervisor program access
+Lbe10a:
+       ptestr  d0,a0@,#7               | do a table search
+       pmove   psr,sp@                 | save result
+       movb    sp@,d1
+       btst    #2,d1                   | invalid? (incl. limit viol and berr)
+       jeq     Lmightnotbemerr         | no -> wp check
+       btst    #7,d1                   | is it MMU table berr?
+       jeq     Lismerr                 | no, must be fast
+       jra     Lisberr1                | real bus err needs not be fast
+Lmightnotbemerr:
+       btst    #3,d1                   | write protect bit set?
+       jeq     Lisberr1                | no, must be bus error
+       movl    sp@,d0                  | ssw into low word of d0
+       andw    #0xc0,d0                | write protect is set on page:
+       cmpw    #0x40,d0                | was it read cycle?
+       jeq     Lisberr1                | yes, was not WPE, must be bus err
+       jra     Lismerr                 | no, must be mem err
+Lbehpmmu:
+#endif
+#if defined(M68K_MMU_HP)
+       MMUADDR(a0)
+       movl    a0@(MMUSTAT),d0         | read status
+       btst    #3,d0                   | MMU fault?
+       jeq     Lisberr                 | no, just a non-MMU bus error so skip
+       andl    #~MMU_FAULT,a0@(MMUSTAT)| yes, clear fault bits
+       movw    d0,sp@                  | pass MMU stat in upper half of code
+#endif
+Lismerr:
+       movl    #T_MMUFLT,sp@-          | show that we are an MMU fault
+       jra     Ltrapnstkadj            | and deal with it
+Lisaerr:
+       movl    #T_ADDRERR,sp@-         | mark address error
+       jra     Ltrapnstkadj            | and deal with it
+Lisberr1:
+       clrw    sp@                     | re-clear pad word
+Lisberr:
+       movl    #T_BUSERR,sp@-          | mark bus error
+Ltrapnstkadj:
+       jbsr    _trap                   | handle the error
        lea     sp@(12),sp              | pop value args
        movl    sp@(FR_SP),a0           | restore user SP
        movl    a0,usp                  |   from save area
        movw    sp@(FR_ADJ),d0          | need to adjust stack?
-       jne     Laststkadj              | yes, go to it
+       jne     Lstkadj                 | yes, go to it
        moveml  sp@+,#0x7FFF            | no, restore most user regs
-       addql   #8,sp                   | toss SP and stack adjust
-       rte                             | and do real RTE
-Laststkadj:
+       addql   #8,sp                   | toss SSP and stkadj
+       jra     rei                     | all done
+Lstkadj:
        lea     sp@(FR_HW),a1           | pointer to HW frame
        addql   #8,a1                   | source pointer
        movl    a1,a0                   | source
@@ -772,375 +623,517 @@ Laststkadj:
        movl    a0,sp@(FR_SP)           | new SSP
        moveml  sp@+,#0x7FFF            | restore user registers
        movl    sp@,sp                  | and our SP
-       rte                             | and do real RTE
-Lchksir:
-       tstb    _ssir                   | SIR pending?
-       jeq     Ldorte                  | no, all done
-       movl    d0,sp@-                 | need a scratch register
-       movw    sp@(4),d0               | get SR
-       andw    #PSL_IPL7,d0            | mask all but IPL
-       jne     Lnosir                  | came from interrupt, no can do
-       movl    sp@+,d0                 | restore scratch register
-Lgotsir:
-       movw    #SPL1,sr                | prevent others from servicing int
-       tstb    _ssir                   | too late?
-       jeq     Ldorte                  | yes, oh well...
-       clrl    sp@-                    | stack adjust
-       moveml  #0xFFFF,sp@-            | save all registers
-       movl    usp,a1                  | including
-       movl    a1,sp@(FR_SP)           |    the users SP
-Lsir1: 
-       clrl    sp@-                    | VA == none
-       clrl    sp@-                    | code == none
-       movl    #T_SSIR,sp@-            | type == software interrupt
-       jbsr    _trap                   | go handle it
-       lea     sp@(12),sp              | pop value args
-       movl    sp@(FR_SP),a0           | restore
-       movl    a0,usp                  |   user SP
-       moveml  sp@+,#0x7FFF            | and all remaining registers
-       addql   #8,sp                   | pop SP and stack adjust
-       rte
-Lnosir:
-       movl    sp@+,d0                 | restore scratch register
-Ldorte:
-       rte                             | real return
+       jra     rei                     | all done
+
+/*
+ * FP exceptions.
+ */
+_fpfline:              /* XXXthorpej - candidate for vector patch */
+#if defined(M68040)
+       cmpl    #FPU_68040,_fputype     | 68040 FPU?
+       jne     Lfp_unimp               | no, skip FPSP
+       cmpw    #0x202c,sp@(6)          | format type 2?
+       jne     _illinst                | no, not an FP emulation
+Ldofp_unimp:
+#ifdef FPSP
+       .globl fpsp_unimp
+       jmp     fpsp_unimp              | yes, go handle it
+#endif
+Lfp_unimp:
+#endif /* M68040 */
+#ifdef FPU_EMULATE
+       clrl    sp@-                    | stack adjust count
+       moveml  #0xFFFF,sp@-            | save registers
+       moveq   #T_FPEMULI,d0           | denote as FP emulation trap
+       jra     fault                   | do it
+#else
+       jra     _illinst
+#endif
+
+_fpunsupp:             /* XXXthorpej - candidate for vector patch */
+#if defined(M68040)
+       cmpl    #FPU_68040,_fputype     | 68040 FPU?
+       jne     _illinst                | no, treat as illinst
+#ifdef FPSP
+       .globl  fpsp_unsupp
+       jmp     fpsp_unsupp             | yes, go handle it
+#endif
+Lfp_unsupp:
+#endif /* M68040 */
+#ifdef FPU_EMULATE
+       clrl    sp@-                    | stack adjust count
+       moveml  #0xFFFF,sp@-            | save registers
+       moveq   #T_FPEMULD,d0           | denote as FP emulation trap
+       jra     fault                   | do it
+#else
+       jra     _illinst
+#endif
 
 /*
- * Macro to relocate a symbol, used before MMU is enabled.
+ * Handles all other FP coprocessor exceptions.
+ * Note that since some FP exceptions generate mid-instruction frames
+ * and may cause signal delivery, we need to test for stack adjustment
+ * after the trap call.
  */
-#define        RELOC(var, ar)          \
-       lea     var,ar;         \
-       addl    a5,ar
+       .globl  _fpfault
+_fpfault:
+       clrl    sp@-            | stack adjust count
+       moveml  #0xFFFF,sp@-    | save user registers
+       movl    usp,a0          | and save
+       movl    a0,sp@(FR_SP)   |   the user stack pointer
+       clrl    sp@-            | no VA arg
+       movl    _curpcb,a0      | current pcb
+       lea     a0@(PCB_FPCTX),a0 | address of FP savearea
+       fsave   a0@             | save state
+#if defined(M68040) || defined(M68060)
+       /* always null state frame on 68040, 68060 */
+       cmpl    #CPU_68040,_cputype
+       jle     Lfptnull
+#endif
+       tstb    a0@             | null state frame?
+       jeq     Lfptnull        | yes, safe
+       clrw    d0              | no, need to tweak BIU
+       movb    a0@(1),d0       | get frame size
+       bset    #3,a0@(0,d0:w)  | set exc_pend bit of BIU
+Lfptnull:
+       fmovem  fpsr,sp@-       | push fpsr as code argument
+       frestore a0@            | restore state
+       movl    #T_FPERR,sp@-   | push type arg
+       jra     Ltrapnstkadj    | call trap and deal with stack cleanup
 
 /*
- * Initialization
- *
- * A4 contains the address of the end of the symtab
- * A5 contains physical load point from boot
- * VBR contains zero from ROM.  Exceptions will continue to vector
- * through ROM until MMU is turned on at which time they will vector
- * through our table (vectors.s).
+ * Coprocessor and format errors can generate mid-instruction stack
+ * frames and cause signal delivery hence we need to check for potential
+ * stack adjustment.
  */
-       .comm   _lowram,4
-       .comm   _esym,4
+_coperr:
+       clrl    sp@-            | stack adjust count
+       moveml  #0xFFFF,sp@-
+       movl    usp,a0          | get and save
+       movl    a0,sp@(FR_SP)   |   the user stack pointer
+       clrl    sp@-            | no VA arg
+       clrl    sp@-            | or code arg
+       movl    #T_COPERR,sp@-  | push trap type
+       jra     Ltrapnstkadj    | call trap and deal with stack adjustments
 
-       .text
-       .globl  _edata
-       .globl  _etext,_end
-       .globl  start
-start:
-       movw    #PSL_HIGHIPL,sr         | no interrupts
-       RELOC(tmpstk, a0)
-       movl    a0,sp                   | give ourselves a temporary stack
-       RELOC(_esym, a0)
-#if 1
-       movl    a4,a0@                  | store end of symbol table
-#else
-       clrl    a0@                     | no symbol table, yet
-#endif
-       RELOC(_lowram, a0)
-       movl    a5,a0@                  | store start of physical memory
-       movl    #CACHE_OFF,d0
-       movc    d0,cacr                 | clear and disable on-chip cache(s)
+_fmterr:
+       clrl    sp@-            | stack adjust count
+       moveml  #0xFFFF,sp@-
+       movl    usp,a0          | get and save
+       movl    a0,sp@(FR_SP)   |   the user stack pointer
+       clrl    sp@-            | no VA arg
+       clrl    sp@-            | or code arg
+       movl    #T_FMTERR,sp@-  | push trap type
+       jra     Ltrapnstkadj    | call trap and deal with stack adjustments
 
-/* check for internal HP-IB in SYSFLAG */
-       btst    #5,0xfffffed2           | internal HP-IB?
-       jeq     Lhaveihpib              | yes, have HP-IB just continue
-       RELOC(_internalhpib, a0)
-       movl    #0,a0@                  | no, clear associated address
-Lhaveihpib:
+/*
+ * Other exceptions only cause four and six word stack frame and require
+ * no post-trap stack adjustment.
+ */
+_illinst:
+       clrl    sp@-
+       moveml  #0xFFFF,sp@-
+       moveq   #T_ILLINST,d0
+       jra     fault
 
-       RELOC(_boothowto, a0)           | save reboot flags
-       movl    d7,a0@
-       RELOC(_bootdev, a0)             |   and boot device
-       movl    d6,a0@
+_zerodiv:
+       clrl    sp@-
+       moveml  #0xFFFF,sp@-
+       moveq   #T_ZERODIV,d0
+       jra     fault
 
-       /*
-        * All data registers are now free.  All address registers
-        * except a5 are free.  a5 is used by the RELOC() macro,
-        * and cannot be used until after the MMU is enabled.
-        */
+_chkinst:
+       clrl    sp@-
+       moveml  #0xFFFF,sp@-
+       moveq   #T_CHKINST,d0
+       jra     fault
 
-/* determine our CPU/MMU combo - check for all regardless of kernel config */
-       movl    #INTIOBASE+MMUBASE,a1
-       movl    #0x200,d0               | data freeze bit
-       movc    d0,cacr                 |   only exists on 68030
-       movc    cacr,d0                 | read it back
-       tstl    d0                      | zero?
-       jeq     Lnot68030               | yes, we have 68020/68040
-       RELOC(_mmutype, a0)             | no, we have 68030
-       movl    #MMU_68030,a0@          | set to reflect 68030 PMMU
-       RELOC(_cputype, a0)
-       movl    #CPU_68030,a0@          | and 68030 CPU
-       RELOC(_machineid, a0)
-       movl    #0x80,a1@(MMUCMD)       | set magic cookie
-       movl    a1@(MMUCMD),d0          | read it back
-       btst    #7,d0                   | cookie still on?
-       jeq     Lnot370                 | no, 360 or 375
-       movl    #0,a1@(MMUCMD)          | clear magic cookie
-       movl    a1@(MMUCMD),d0          | read it back
-       btst    #7,d0                   | still on?
-       jeq     Lisa370                 | no, must be a 370
-       movl    #HP_340,a0@             | yes, must be a 340
-       jra     Lstart1
-Lnot370:
-       movl    #HP_360,a0@             | type is at least a 360
-       movl    #0,a1@(MMUCMD)          | clear magic cookie2
-       movl    a1@(MMUCMD),d0          | read it back
-       btst    #16,d0                  | still on?
-       jeq     Lstart1                 | no, must be a 360
-       movl    #HP_375,a0@             | yes, must be a 345/375
-       jra     Lhaspac
-Lisa370:
-       movl    #HP_370,a0@             | set to 370
-Lhaspac:
-       RELOC(_ectype, a0)
-       movl    #EC_PHYS,a0@            | also has a physical address cache
-       jra     Lstart1
-Lnot68030:
-       bset    #31,d0                  | data cache enable bit
-       movc    d0,cacr                 |   only exists on 68040
-       movc    cacr,d0                 | read it back
-       tstl    d0                      | zero?
-       beq     Lis68020                | yes, we have 68020
-       moveq   #0,d0                   | now turn it back off
-       movec   d0,cacr                 |   before we access any data
-       RELOC(_mmutype, a0)
-       movl    #MMU_68040,a0@          | with a 68040 MMU
-       RELOC(_cputype, a0)
-       movl    #CPU_68040,a0@          | and a 68040 CPU
-       RELOC(_ectype, a0)
-       movl    #EC_NONE,a0@            | and no cache (for now XXX)
-       RELOC(_machineid, a0)
-       movl    a1@(MMUCMD),d0          | read MMU register
-       lsrl    #8,d0                   | get apparent ID
-       cmpb    #6,d0                   | id == 6?
-       jeq     Lis33mhz                | yes, we have a 433s
-       movl    #HP_380,a0@             | no, we have a 380/425t
-       jra     Lstart1
-Lis33mhz:
-       movl    #HP_433,a0@             | 433s (XXX 425s returns same ID, ugh!)
-       jra     Lstart1
-Lis68020:
-       movl    #1,a1@(MMUCMD)          | a 68020, write HP MMU location
-       movl    a1@(MMUCMD),d0          | read it back
-       btst    #0,d0                   | non-zero?
-       jne     Lishpmmu                | yes, we have HP MMU
-       RELOC(_mmutype, a0)
-       movl    #MMU_68851,a0@          | no, we have PMMU
-       RELOC(_machineid, a0)
-       movl    #HP_330,a0@             | and 330 CPU
-       jra     Lstart1
-Lishpmmu:
-       RELOC(_ectype, a0)              | 320 or 350
-       movl    #EC_VIRT,a0@            | both have a virtual address cache
-       movl    #0x80,a1@(MMUCMD)       | set magic cookie
-       movl    a1@(MMUCMD),d0          | read it back
-       btst    #7,d0                   | cookie still on?
-       jeq     Lis320                  | no, just a 320
-       RELOC(_machineid, a0)
-       movl    #HP_350,a0@             | yes, a 350
-       jra     Lstart1
-Lis320:
-       RELOC(_machineid, a0)
-       movl    #HP_320,a0@
+_trapvinst:
+       clrl    sp@-
+       moveml  #0xFFFF,sp@-
+       moveq   #T_TRAPVINST,d0
+       jra     fault
 
-Lstart1:
-       movl    #0,a1@(MMUCMD)          | clear out MMU again
-/* initialize source/destination control registers for movs */
-       moveq   #FC_USERD,d0            | user space
-       movc    d0,sfc                  |   as source
-       movc    d0,dfc                  |   and destination of transfers
-/* initialize memory sizes (for pmap_bootstrap) */
-       movl    #MAXADDR,d1             | last page
-       moveq   #PGSHIFT,d2
-       lsrl    d2,d1                   | convert to page (click) number
-       RELOC(_maxmem, a0)
-       movl    d1,a0@                  | save as maxmem
-       movl    a5,d0                   | lowram value from ROM via boot
-       lsrl    d2,d0                   | convert to page number
-       subl    d0,d1                   | compute amount of RAM present
-       RELOC(_physmem, a0)
-       movl    d1,a0@                  | and physmem
-/* configure kernel and proc0 VA space so we can get going */
-       .globl  _Sysseg, _pmap_bootstrap, _avail_start
-#ifdef DDB
-       RELOC(_esym,a0)                 | end of static kernel test/data/syms
-       movl    a0@,d5
-       jne     Lstart2
-#endif
-       movl    #_end,d5                | end of static kernel text/data
-Lstart2:
-       addl    #NBPG-1,d5
-       andl    #PG_FRAME,d5            | round to a page
-       movl    d5,a4
-       addl    a5,a4                   | convert to PA
-       pea     a5@                     | firstpa
-       pea     a4@                     | nextpa
-       RELOC(_pmap_bootstrap,a0)
-       jbsr    a0@                     | pmap_bootstrap(firstpa, nextpa)
-       addql   #8,sp
+_privinst:
+       clrl    sp@-
+       moveml  #0xFFFF,sp@-
+       moveq   #T_PRIVINST,d0
+       jra     fault
+
+       .globl  fault
+fault:
+       movl    usp,a0                  | get and save
+       movl    a0,sp@(FR_SP)           |   the user stack pointer
+       clrl    sp@-                    | no VA arg
+       clrl    sp@-                    | or code arg
+       movl    d0,sp@-                 | push trap type
+       jbsr    _trap                   | handle trap
+       lea     sp@(12),sp              | pop value args
+       movl    sp@(FR_SP),a0           | restore
+       movl    a0,usp                  |   user SP
+       moveml  sp@+,#0x7FFF            | restore most user regs
+       addql   #8,sp                   | pop SP and stack adjust
+       jra     rei                     | all done
+
+       .globl  _straytrap
+_badtrap:
+       moveml  #0xC0C0,sp@-            | save scratch regs
+       movw    sp@(22),sp@-            | push exception vector info
+       clrw    sp@-
+       movl    sp@(22),sp@-            | and PC
+       jbsr    _straytrap              | report
+       addql   #8,sp                   | pop args
+       moveml  sp@+,#0x0303            | restore regs
+       jra     rei                     | all done
+
+       .globl  _syscall
+_trap0:
+       clrl    sp@-                    | stack adjust count
+       moveml  #0xFFFF,sp@-            | save user registers
+       movl    usp,a0                  | save the user SP
+       movl    a0,sp@(FR_SP)           |   in the savearea
+       movl    d0,sp@-                 | push syscall number
+       jbsr    _syscall                | handle it
+       addql   #4,sp                   | pop syscall arg
+       tstl    _astpending
+       jne     Lrei2
+       tstb    _ssir
+       jeq     Ltrap1
+       movw    #SPL1,sr
+       tstb    _ssir
+       jne     Lsir1
+Ltrap1:        
+       movl    sp@(FR_SP),a0           | grab and restore
+       movl    a0,usp                  |   user SP
+       moveml  sp@+,#0x7FFF            | restore most registers
+       addql   #8,sp                   | pop SP and stack adjust
+       rte
 
 /*
- * Prepare to enable MMU.
- * Since the kernel is not mapped logical == physical we must insure
- * that when the MMU is turned on, all prefetched addresses (including
- * the PC) are valid.  In order guarentee that, we use the last physical
- * page (which is conveniently mapped == VA) and load it up with enough
- * code to defeat the prefetch, then we execute the jump back to here.
- *
- * Is this all really necessary, or am I paranoid??
+ * Trap 1 - sigreturn
  */
-       RELOC(_Sysseg, a0)              | system segment table addr
-       movl    a0@,d1                  | read value (a KVA)
-       addl    a5,d1                   | convert to PA
-       RELOC(_mmutype, a0)
-       tstl    a0@                     | HP MMU?
-       jeq     Lhpmmu2                 | yes, skip
-       cmpl    #MMU_68040,a0@          | 68040?
-       jne     Lmotommu1               | no, skip
-       .long   0x4e7b1807              | movc d1,srp
-       jra     Lstploaddone
-Lmotommu1:
-       RELOC(_protorp, a0)
-       movl    #0x80000202,a0@         | nolimit + share global + 4 byte PTEs
-       movl    d1,a0@(4)               | + segtable address
-       pmove   a0@,srp                 | load the supervisor root pointer
-       movl    #0x80000002,a0@         | reinit upper half for CRP loads
-       jra     Lstploaddone            | done
-Lhpmmu2:
-       moveq   #PGSHIFT,d2
-       lsrl    d2,d1                   | convert to page frame
-       movl    d1,INTIOBASE+MMUBASE+MMUSSTP | load in sysseg table register
-Lstploaddone:
-       lea     MAXADDR,a2              | PA of last RAM page
-       RELOC(Lhighcode, a1)            | addr of high code
-       RELOC(Lehighcode, a3)           | end addr
-Lcodecopy:
-       movw    a1@+,a2@+               | copy a word
-       cmpl    a3,a1                   | done yet?
-       jcs     Lcodecopy               | no, keep going
-       jmp     MAXADDR                 | go for it!
-
-       /*
-        * BEGIN MMU TRAMPOLINE.  This section of code is not
-        * executed in-place.  It's copied to the last page
-        * of RAM (mapped va == pa) and executed there.
-        */
+_trap1:
+       jra     sigreturn
 
-Lhighcode:
-       /*
-        * Set up the vector table, and race to get the MMU
-        * enabled.
-        */
-       movl    #_vectab,d0             | set Vector Base Register
-       movc    d0,vbr
+/*
+ * Trap 2 - trace trap
+ */
+_trap2:
+       jra     _trace
 
-       RELOC(_mmutype, a0)
-       tstl    a0@                     | HP MMU?
-       jeq     Lhpmmu3                 | yes, skip
-       cmpl    #MMU_68040,a0@          | 68040?
-       jne     Lmotommu2               | no, skip
-       movw    #0,INTIOBASE+MMUBASE+MMUCMD+2
-       movw    #MMU_IEN+MMU_CEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD+2
-                                       | enable FPU and caches
-       moveq   #0,d0                   | ensure TT regs are disabled
-       .long   0x4e7b0004              | movc d0,itt0
-       .long   0x4e7b0005              | movc d0,itt1
-       .long   0x4e7b0006              | movc d0,dtt0
-       .long   0x4e7b0007              | movc d0,dtt1
-       .word   0xf4d8                  | cinva bc
-       .word   0xf518                  | pflusha
-       movl    #0x8000,d0
-       .long   0x4e7b0003              | movc d0,tc
-       movl    #0x80008000,d0
-       movc    d0,cacr                 | turn on both caches
-       jmp     Lenab1
-Lmotommu2:
-       movl    #MMU_IEN+MMU_FPE,INTIOBASE+MMUBASE+MMUCMD
-                                       | enable 68881 and i-cache
-       RELOC(_prototc, a2)
-       movl    #0x82c0aa00,a2@         | value to load TC with
-       pmove   a2@,tc                  | load it
-       jmp     Lenab1
-Lhpmmu3:
-       movl    #0,INTIOBASE+MMUBASE+MMUCMD     | clear external cache
-       movl    #MMU_ENAB,INTIOBASE+MMUBASE+MMUCMD | turn on MMU
-       jmp     Lenab1                          | jmp to mapped code
-Lehighcode:
+/*
+ * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD)
+ *     cachectl(command, addr, length)
+ * command in d0, addr in a1, length in d1
+ */
+       .globl  _cachectl
+_trap12:
+       movl    d1,sp@-                 | push length
+       movl    a1,sp@-                 | push addr
+       movl    d0,sp@-                 | push command
+       jbsr    _cachectl               | do it
+       lea     sp@(12),sp              | pop args
+       jra     rei                     | all done
 
-       /*
-        * END MMU TRAMPOLINE.  Address register a5 is now free.
-        */
+/*
+ * Trace (single-step) trap.  Kernel-mode is special.
+ * User mode traps are simply passed on to trap().
+ */
+_trace:
+       clrl    sp@-                    | stack adjust count
+       moveml  #0xFFFF,sp@-
+       moveq   #T_TRACE,d0
+       movw    sp@(FR_HW),d1           | get PSW
+       andw    #PSL_S,d1               | from system mode?
+       jne     kbrkpt                  | yes, kernel breakpoint
+       jra     fault                   | no, user-mode fault
 
 /*
- * Should be running mapped from this point on
+ * Trap 15 is used for:
+ *     - GDB breakpoints (in user programs)
+ *     - KGDB breakpoints (in the kernel)
+ *     - trace traps for SUN binaries (not fully supported yet)
+ * User mode traps are simply passed to trap().
  */
-Lenab1:
-/* select the software page size now */
-       lea     tmpstk,sp               | temporary stack
-       jbsr    _vm_set_page_size       | select software page size
-/* set kernel stack, user SP, and initial pcb */
-       movl    _proc0paddr,a1          | get proc0 pcb addr
-       lea     a1@(USPACE-4),sp        | set kernel stack to end of area
-       lea     _proc0,a2               | initialize proc0.p_addr so that
-       movl    a1,a2@(P_ADDR)          |   we don't deref NULL in trap()
-       movl    #USRSTACK-4,a2
-       movl    a2,usp                  | init user SP
-       movl    a1,_curpcb              | proc0 is running
-#ifdef FPCOPROC
-       clrl    a1@(PCB_FPCTX)          | ensure null FP context
-       movl    a1,sp@-
-       jbsr    _m68881_restore         | restore it (does not kill a1)
-       addql   #4,sp
+_trap15:
+       clrl    sp@-                    | stack adjust count
+       moveml  #0xFFFF,sp@-
+       moveq   #T_TRAP15,d0
+       movw    sp@(FR_HW),d1           | get PSW
+       andw    #PSL_S,d1               | from system mode?
+       jne     kbrkpt                  | yes, kernel breakpoint
+       jra     fault                   | no, user-mode fault
+
+kbrkpt:        | Kernel-mode breakpoint or trace trap. (d0=trap_type)
+       | Save the system sp rather than the user sp.
+       movw    #PSL_HIGHIPL,sr         | lock out interrupts
+       lea     sp@(FR_SIZE),a6         | Save stack pointer
+       movl    a6,sp@(FR_SP)           |  from before trap
+
+       | If were are not on tmpstk switch to it.
+       | (so debugger can change the stack pointer)
+       movl    a6,d1
+       cmpl    #tmpstk,d1
+       jls     Lbrkpt2                 | already on tmpstk
+       | Copy frame to the temporary stack
+       movl    sp,a0                   | a0=src
+       lea     tmpstk-96,a1            | a1=dst
+       movl    a1,sp                   | sp=new frame
+       moveq   #FR_SIZE,d1
+Lbrkpt1:
+       movl    a0@+,a1@+
+       subql   #4,d1
+       bgt     Lbrkpt1
+
+Lbrkpt2:
+       | Call the trap handler for the kernel debugger.
+       | Do not call trap() to do it, so that we can
+       | set breakpoints in trap() if we want.  We know
+       | the trap type is either T_TRACE or T_BREAKPOINT.
+       | If we have both DDB and KGDB, let KGDB see it first,
+       | because KGDB will just return 0 if not connected.
+       | Save args in d2, a2
+       movl    d0,d2                   | trap type
+       movl    sp,a2                   | frame ptr
+#ifdef KGDB
+       | Let KGDB handle it (if connected)
+       movl    a2,sp@-                 | push frame ptr
+       movl    d2,sp@-                 | push trap type
+       jbsr    _kgdb_trap              | handle the trap
+       addql   #8,sp                   | pop args
+       cmpl    #0,d0                   | did kgdb handle it?
+       jne     Lbrkpt3                 | yes, done
 #endif
-/* flush TLB and turn on caches */
-       jbsr    _TBIA                   | invalidate TLB
-       cmpl    #MMU_68040,_mmutype     | 68040?
-       jeq     Lnocache0               | yes, cache already on
-       movl    #CACHE_ON,d0
-       movc    d0,cacr                 | clear cache(s)
-       tstl    _ectype
-       jeq     Lnocache0
-       MMUADDR(a0)
-       orl     #MMU_CEN,a0@(MMUCMD)    | turn on external cache
-Lnocache0:
-/* Final setup for call to main(). */
-       jbsr    _isrinit                | initialize interrupt handlers
-       jbsr    _hp300_calibrate_delay  | calibrate delay() loop
+#ifdef DDB
+       | Let DDB handle it
+       movl    a2,sp@-                 | push frame ptr
+       movl    d2,sp@-                 | push trap type
+       jbsr    _kdb_trap               | handle the trap
+       addql   #8,sp                   | pop args
+#if 0  /* not needed on hp300 */
+       cmpl    #0,d0                   | did ddb handle it?
+       jne     Lbrkpt3                 | yes, done
+#endif
+#endif
+       /* Sun 3 drops into PROM here. */
+Lbrkpt3:
+       | The stack pointer may have been modified, or
+       | data below it modified (by kgdb push call),
+       | so push the hardware frame at the current sp
+       | before restoring registers and returning.
+
+       movl    sp@(FR_SP),a0           | modified sp
+       lea     sp@(FR_SIZE),a1         | end of our frame
+       movl    a1@-,a0@-               | copy 2 longs with
+       movl    a1@-,a0@-               | ... predecrement
+       movl    a0,sp@(FR_SP)           | sp = h/w frame
+       moveml  sp@+,#0x7FFF            | restore all but sp
+       movl    sp@,sp                  | ... and sp
+       rte                             | all done
+
+/* Use common m68k sigreturn */
+#include <m68k/m68k/sigreturn.s>
 
 /*
- * Create a fake exception frame so that cpu_fork() can copy it.
- * main() nevers returns; we exit to user mode from a forked process
- * later on.
+ * Interrupt handlers.
+ * All device interrupts are auto-vectored.  The CPU provides
+ * the vector 0x18+level.  Note we count spurious interrupts, but
+ * we don't do anything else with them.
  */
-       clrw    sp@-                    | vector offset/frame type
-       clrl    sp@-                    | PC - filled in by "execve"
-       movw    #PSL_USER,sp@-          | in user mode
-       clrl    sp@-                    | stack adjust count and padding
-       lea     sp@(-64),sp             | construct space for D0-D7/A0-A7
-       lea     _proc0,a0               | save pointer to frame
-       movl    sp,a0@(P_MD_REGS)       |   in proc0.p_md.md_regs
 
-       jra     _main                   | main()
+#define INTERRUPT_SAVEREG      moveml  #0xC0C0,sp@-
+#define INTERRUPT_RESTOREREG   moveml  sp@+,#0x0303
 
-       pea     Lmainreturned           | Yow!  Main returned!
-       jbsr    _panic
-       /* NOTREACHED */
-Lmainreturned:
-       .asciz  "main() returned"
-       .even
+       /* Externs. */
+       .globl  _hilint, _isrdispatch, _nmihand
+       .globl  _hardclock, _statintr
 
-       .globl  _proc_trampoline
-_proc_trampoline:
-       movl    a3,sp@-
-       jbsr    a2@
+_spurintr:     /* Level 0 */
+       addql   #1,_intrcnt+0
+       addql   #1,_cnt+V_INTR
+       jra     rei
+
+_lev1intr:     /* Level 1: HIL XXX this needs to go away */
+       INTERRUPT_SAVEREG
+       jbsr    _hilint
+       INTERRUPT_RESTOREREG
+       addql   #1,_intrcnt+4
+       addql   #1,_cnt+V_INTR
+       jra     rei
+
+_intrhand:     /* Levels 2 through 5 */
+       INTERRUPT_SAVEREG
+       movw    sp@(22),sp@-            | push exception vector info
+       clrw    sp@-
+       jbsr    _isrdispatch            | call dispatch routine
        addql   #4,sp
-       movl    sp@(FR_SP),a0           | grab and load
+       INTERRUPT_RESTOREREG
+       jra     rei                     | all done
+
+_lev6intr:     /* Level 6: clock */
+       INTERRUPT_SAVEREG
+       CLKADDR(a0)
+       movb    a0@(CLKSR),d0           | read clock status
+Lclkagain:
+       btst    #0,d0                   | clear timer1 int immediately to
+       jeq     Lnotim1                 |  minimize chance of losing another
+       movpw   a0@(CLKMSB1),d1         |  due to statintr processing delay
+Lnotim1:
+       btst    #2,d0                   | timer3 interrupt?
+       jeq     Lnotim3                 | no, skip statclock
+       movpw   a0@(CLKMSB3),d1         | clear timer3 interrupt
+       addql   #1,_intrcnt+28          | count clock interrupts
+       lea     sp@(16),a1              | a1 = &clockframe
+       movl    d0,sp@-                 | save status
+       movl    a1,sp@-
+       jbsr    _statintr               | statintr(&frame)
+       addql   #4,sp
+       movl    sp@+,d0                 | restore pre-statintr status
+       CLKADDR(a0)
+Lnotim3:
+       btst    #0,d0                   | timer1 interrupt?
+       jeq     Lrecheck                | no, skip hardclock
+       addql   #1,_intrcnt+24          | count hardclock interrupts
+       lea     sp@(16),a1              | a1 = &clockframe
+       movl    a1,sp@-
+#ifdef USELEDS
+       .globl  _ledaddr, _inledcontrol, _ledcontrol, _hz
+       tstl    _ledaddr                | using LEDs?
+       jeq     Lnoled0                 | no, skip this code
+       movl    heartbeat,d0            | get tick count
+       addql   #1,d0                   |  increment
+       movl    _hz,d1
+       addl    #50,d1                  | get the timing a little closer
+       cmpl    #0,beatstatus           | time to slow down?
+       jeq     SlowThrob
+       lsrl    #3,d1                   | fast throb
+SlowThrob:
+       lsrl    #1,d1                   | slow throb
+       cmpl    d0,d1                   | are we there yet?
+       jne     Lnoled1                 | no, nothing to do
+       tstl    _inledcontrol           | already updating LEDs?
+       jne     Lnoled2                 | yes, skip it
+       addl    #1,beatstatus           | incr beat status
+       cmpl    #3,beatstatus           | time to reset?
+       ble     SkipReset
+       movl    #0,beatstatus           | reset the status indicator
+SkipReset:
+       movl    #LED_PULSE,sp@-
+       movl    #LED_DISK+LED_LANRCV+LED_LANXMT,sp@-
+       clrl    sp@-
+       jbsr    _ledcontrol             | toggle pulse, turn all others off
+       lea     sp@(12),sp
+Lnoled2:
+       movql   #0,d0
+Lnoled1:
+       movl    d0,heartbeat
+Lnoled0:
+#endif
+       jbsr    _hardclock              | hardclock(&frame)
+       addql   #4,sp
+       CLKADDR(a0)
+Lrecheck:
+       addql   #1,_cnt+V_INTR          | chalk up another interrupt
+       movb    a0@(CLKSR),d0           | see if anything happened
+       jmi     Lclkagain               |  while we were in hardclock/statintr
+       INTERRUPT_RESTOREREG
+       jra     rei                     | all done
+
+_lev7intr:     /* Level 7: Parity errors, reset key */
+       addql   #1,_intrcnt+32
+       clrl    sp@-
+       moveml  #0xFFFF,sp@-            | save registers
+       movl    usp,a0                  | and save
+       movl    a0,sp@(FR_SP)           |   the user stack pointer
+       jbsr    _nmihand                | call handler
+       movl    sp@(FR_SP),a0           | restore
        movl    a0,usp                  |   user SP
-       moveml  sp@+,#0x7FFF            | restore most user regs
+       moveml  sp@+,#0x7FFF            | and remaining registers
+       addql   #8,sp                   | pop SP and stack adjust
+       jra     rei                     | all done
+
+/*
+ * Emulation of VAX REI instruction.
+ *
+ * This code deals with checking for and servicing ASTs
+ * (profiling, scheduling) and software interrupts (network, softclock).
+ * We check for ASTs first, just like the VAX.  To avoid excess overhead
+ * the T_ASTFLT handling code will also check for software interrupts so we
+ * do not have to do it here.  After identifing that we need an AST we
+ * drop the IPL to allow device interrupts.
+ *
+ * This code is complicated by the fact that sendsig may have been called
+ * necessitating a stack cleanup.
+ */
+       .comm   _ssir,1
+       .globl  _astpending
+       .globl  rei
+rei:
+       tstl    _astpending             | AST pending?
+       jeq     Lchksir                 | no, go check for SIR
+Lrei1:
+       btst    #5,sp@                  | yes, are we returning to user mode?
+       jne     Lchksir                 | no, go check for SIR
+       movw    #PSL_LOWIPL,sr          | lower SPL
+       clrl    sp@-                    | stack adjust
+       moveml  #0xFFFF,sp@-            | save all registers
+       movl    usp,a1                  | including
+       movl    a1,sp@(FR_SP)           |    the users SP
+Lrei2:
+       clrl    sp@-                    | VA == none
+       clrl    sp@-                    | code == none
+       movl    #T_ASTFLT,sp@-          | type == async system trap
+       jbsr    _trap                   | go handle it
+       lea     sp@(12),sp              | pop value args
+       movl    sp@(FR_SP),a0           | restore user SP
+       movl    a0,usp                  |   from save area
+       movw    sp@(FR_ADJ),d0          | need to adjust stack?
+       jne     Laststkadj              | yes, go to it
+       moveml  sp@+,#0x7FFF            | no, restore most user regs
        addql   #8,sp                   | toss SP and stack adjust
-       jra     rei                     | and return
+       rte                             | and do real RTE
+Laststkadj:
+       lea     sp@(FR_HW),a1           | pointer to HW frame
+       addql   #8,a1                   | source pointer
+       movl    a1,a0                   | source
+       addw    d0,a0                   |  + hole size = dest pointer
+       movl    a1@-,a0@-               | copy
+       movl    a1@-,a0@-               |  8 bytes
+       movl    a0,sp@(FR_SP)           | new SSP
+       moveml  sp@+,#0x7FFF            | restore user registers
+       movl    sp@,sp                  | and our SP
+       rte                             | and do real RTE
+Lchksir:
+       tstb    _ssir                   | SIR pending?
+       jeq     Ldorte                  | no, all done
+       movl    d0,sp@-                 | need a scratch register
+       movw    sp@(4),d0               | get SR
+       andw    #PSL_IPL7,d0            | mask all but IPL
+       jne     Lnosir                  | came from interrupt, no can do
+       movl    sp@+,d0                 | restore scratch register
+Lgotsir:
+       movw    #SPL1,sr                | prevent others from servicing int
+       tstb    _ssir                   | too late?
+       jeq     Ldorte                  | yes, oh well...
+       clrl    sp@-                    | stack adjust
+       moveml  #0xFFFF,sp@-            | save all registers
+       movl    usp,a1                  | including
+       movl    a1,sp@(FR_SP)           |    the users SP
+Lsir1: 
+       clrl    sp@-                    | VA == none
+       clrl    sp@-                    | code == none
+       movl    #T_SSIR,sp@-            | type == software interrupt
+       jbsr    _trap                   | go handle it
+       lea     sp@(12),sp              | pop value args
+       movl    sp@(FR_SP),a0           | restore
+       movl    a0,usp                  |   user SP
+       moveml  sp@+,#0x7FFF            | and all remaining registers
+       addql   #8,sp                   | pop SP and stack adjust
+       rte
+Lnosir:
+       movl    sp@+,d0                 | restore scratch register
+Ldorte:
+       rte                             | real return
 
 /*
  * Signal "trampoline" code (18 bytes).  Invoked from RTE setup by sendsig().
@@ -1169,22 +1162,6 @@ _sigcode:
        .align  2
 _esigcode:
 
-/*
- * ..And HPUX versions of the above.  Hardcoded to use trap 2.
- */
-       .globl  _hpux_sigcode, _hpux_esigcode
-       .data
-_hpux_sigcode:
-       movl    sp@(12),a0              | signal handler addr   (4 bytes)
-       jsr     a0@                     | call signal handler   (2 bytes)
-       addql   #4,sp                   | pop signo             (2 bytes)
-       trap    #2                      | special syscall entry (2 bytes)
-       movl    d0,sp@(4)               | save errno            (4 bytes)
-       moveq   #1,d0                   | syscall == exit       (2 bytes)
-       trap    #0                      | exit(errno)           (2 bytes)
-       .align  2
-_hpux_esigcode:
-
 /*
  * Primitives
  */ 
@@ -1192,21 +1169,9 @@ _hpux_esigcode:
 #include <machine/asm.h>
 
 /*
- * non-local gotos
+ * Use common m68k support routines.
  */
-ENTRY(setjmp)
-       movl    sp@(4),a0       | savearea pointer
-       moveml  #0xFCFC,a0@     | save d2-d7/a2-a7
-       movl    sp@,a0@(48)     | and return address
-       moveq   #0,d0           | return 0
-       rts
-
-ENTRY(longjmp)
-       movl    sp@(4),a0
-       moveml  a0@+,#0xFCFC
-       movl    a0@,sp@
-       moveq   #1,d0
-       rts
+#include <m68k/m68k/support.s>
 
 /*
  * The following primitives manipulate the run queues.  _whichqs tells which
@@ -1411,7 +1376,9 @@ Lsw2:
        moveml  #0xFCFC,a1@(PCB_REGS)   | save non-scratch registers
        movl    usp,a2                  | grab USP (a2 has been saved)
        movl    a2,a1@(PCB_USP)         | and save it
-#ifdef FPCOPROC
+
+       tstl    _fputype                | Do we have an FPU?
+       jeq     Lswnofpsave             | No  Then don't attempt save.
        lea     a1@(PCB_FPCTX),a2       | pointer to FP save area
        fsave   a2@                     | save FP state
        tstb    a2@                     | null state frame?
@@ -1419,7 +1386,6 @@ Lsw2:
        fmovem  fp0-fp7,a2@(216)        | save FP general registers
        fmovem  fpcr/fpsr/fpi,a2@(312)  | save FP control registers
 Lswnofpsave:
-#endif
 
 #ifdef DIAGNOSTIC
        tstl    a0@(P_WCHAN)
@@ -1493,7 +1459,9 @@ Lcxswdone:
        moveml  a1@(PCB_REGS),#0xFCFC   | and registers
        movl    a1@(PCB_USP),a0
        movl    a0,usp                  | and USP
-#ifdef FPCOPROC
+
+       tstl    _fputype                | If we don't have an FPU,
+       jeq     Lnofprest               |  don't try to restore it.
        lea     a1@(PCB_FPCTX),a0       | pointer to FP save area
        tstb    a0@                     | null state frame?
        jeq     Lresfprest              | yes, easy
@@ -1510,7 +1478,8 @@ Lresnot040:
        fmovem  a0@(216),fp0-fp7        | restore FP general registers
 Lresfprest:
        frestore a0@                    | restore state
-#endif
+
+Lnofprest:
        movw    a1@(PCB_PS),sr          | no, restore PS
        moveq   #1,d0                   | return 1 (for alternate returns)
        rts
@@ -1525,7 +1494,9 @@ ENTRY(savectx)
        movl    usp,a0                  | grab USP
        movl    a0,a1@(PCB_USP)         | and save it
        moveml  #0xFCFC,a1@(PCB_REGS)   | save non-scratch registers
-#ifdef FPCOPROC
+
+       tstl    _fputype                | Do we have FPU?
+       jeq     Lsvnofpsave             | No?  Then don't save state.
        lea     a1@(PCB_FPCTX),a0       | pointer to FP save area
        fsave   a0@                     | save FP state
        tstb    a0@                     | null state frame?
@@ -1533,7 +1504,6 @@ ENTRY(savectx)
        fmovem  fp0-fp7,a0@(216)        | save FP general registers
        fmovem  fpcr/fpsr/fpi,a0@(312)  | save FP control registers
 Lsvnofpsave:
-#endif
        moveq   #0,d0                   | return 0
        rts
 
@@ -1953,30 +1923,6 @@ ENTRY(spl0)
 Lspldone:
        rts
 
-ENTRY(_insque)
-       movw    sr,d0
-       movw    #PSL_HIGHIPL,sr         | atomic
-       movl    sp@(8),a0               | where to insert (after)
-       movl    sp@(4),a1               | element to insert (e)
-       movl    a0@,a1@                 | e->next = after->next
-       movl    a0,a1@(4)               | e->prev = after
-       movl    a1,a0@                  | after->next = e
-       movl    a1@,a0
-       movl    a1,a0@(4)               | e->next->prev = e
-       movw    d0,sr
-       rts
-
-ENTRY(_remque)
-       movw    sr,d0
-       movw    #PSL_HIGHIPL,sr         | atomic
-       movl    sp@(4),a0               | element to remove (e)
-       movl    a0@,a1
-       movl    a0@(4),a0
-       movl    a0,a1@(4)               | e->next->prev = e->prev
-       movl    a1,a0@                  | e->prev->next = e->next
-       movw    d0,sr
-       rts
-
 /*
  * _delay(u_int N)
  *
@@ -1995,7 +1941,6 @@ L_delay:
        jgt     L_delay
        rts
 
-#ifdef FPCOPROC
 /*
  * Save and restore 68881 state.
  * Pretty awful looking since our assembler does not
@@ -2020,7 +1965,6 @@ ENTRY(m68881_restore)
 Lm68881rdone:
        frestore a0@                    | restore state
        rts
-#endif
 
 /*
  * Handle the nitty-gritty of rebooting the machine.
@@ -2098,7 +2042,8 @@ Lebootcode:
 #undef DOREBOOT
 
        .data
-       .globl  _machineid,_mmutype,_cputype,_ectype,_protorp,_prototc
+       .globl  _machineid,_mmutype,_cputype,_ectype,_fputype
+       .globl  _protorp,_prototc
 _machineid:
        .long   HP_320          | default to 320
 _mmutype:
@@ -2107,6 +2052,8 @@ _cputype:
        .long   CPU_68020       | default to 68020 CPU
 _ectype:
        .long   EC_NONE         | external cache type, default to none
+_fputype:
+       .long   FPU_68881       | default to 68881 FPU
 _protorp:
        .long   0,0             | prototype root pointer
 _prototc:
index e14997b..51dc747 100644 (file)
@@ -1,36 +1,7 @@
-/*     $OpenBSD: machdep.c,v 1.20 1997/02/24 01:16:09 downsj Exp $     */
-/*     $NetBSD: machdep.c,v 1.80 1997/02/02 07:58:49 thorpej Exp $     */
+/*     $OpenBSD: machdep.c,v 1.21 1997/03/26 08:32:43 downsj Exp $     */
+/*     $NetBSD: machdep.c,v 1.83 1997/03/16 09:12:13 thorpej Exp $     */
 
 /*
- * Copyright (c) 1997 Theo de Raadt
- * 
- * 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 under OpenBSD by
- *     Theo de Raadt.
- * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
- *
  * Copyright (c) 1988 University of Utah.
  * Copyright (c) 1982, 1986, 1990, 1993
  *     The Regents of the University of California.  All rights reserved.
@@ -465,11 +436,12 @@ setregs(p, pack, stack, retval)
        frame->f_pc = pack->ep_entry & ~1;
        frame->f_regs[SP] = stack;
        frame->f_regs[A2] = (int)PS_STRINGS;
-#ifdef FPCOPROC
+
        /* restore a null state frame */
        p->p_addr->u_pcb.pcb_fpregs.fpf_null = 0;
-       m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
-#endif
+       if (fputype)
+               m68881_restore(&p->p_addr->u_pcb.pcb_fpregs);
+
 #ifdef COMPAT_SUNOS
        /*
         * SunOS' ld.so does self-modifying code without knowing
@@ -481,24 +453,6 @@ setregs(p, pack, stack, retval)
        else
                p->p_md.md_flags &= ~MDP_UNCACHE_WX;
 #endif
-#ifdef COMPAT_HPUX
-       p->p_md.md_flags &= ~MDP_HPUXMMAP;
-       if (p->p_emul == &emul_hpux) {
-               frame->f_regs[A0] = 0; /* not 68010 (bit 31), no FPA (30) */
-               retval[0] = 0;          /* no float card */
-#ifdef FPCOPROC
-               retval[1] = 1;          /* yes 68881 */
-#else
-               retval[1] = 0;          /* no 68881 */
-#endif
-
-               /* Make sure the trace bit is correct.  Doesn't belong here. */
-               if (p->p_flag & P_TRACED)
-                       p->p_md.md_flags |= MDP_HPUXTRACE;
-               else
-                       p->p_md.md_flags &= ~MDP_HPUXTRACE;
-       }
-#endif
 }
 
 /*
@@ -698,445 +652,6 @@ ledcontrol(ons, offs, togs)
 }
 #endif
 
-#define SS_RTEFRAME    1
-#define SS_FPSTATE     2
-#define SS_USERREGS    4
-
-struct sigstate {
-       int     ss_flags;               /* which of the following are valid */
-       struct  frame ss_frame;         /* original exception frame */
-       struct  fpframe ss_fpstate;     /* 68881/68882 state info */
-};
-
-/*
- * WARNING: code in locore.s assumes the layout shown for sf_signum
- * thru sf_handler so... don't screw with them!
- */
-struct sigframe {
-       int     sf_signum;              /* signo for handler */
-       siginfo_t *sf_sip;              /* pointer to siginfo_t */
-       struct  sigcontext *sf_scp;     /* context ptr for handler */
-       sig_t   sf_handler;             /* handler addr for u_sigc */
-       struct  sigstate sf_state;      /* state of the hardware */
-       struct  sigcontext sf_sc;       /* actual context */
-       siginfo_t sf_si;
-};
-
-#ifdef COMPAT_HPUX
-struct hpuxsigcontext {
-       int     hsc_syscall;
-       char    hsc_action;
-       char    hsc_pad1;
-       char    hsc_pad2;
-       char    hsc_onstack;
-       int     hsc_mask;
-       int     hsc_sp;
-       short   hsc_ps;
-       int     hsc_pc;
-/* the rest aren't part of the context but are included for our convenience */
-       short   hsc_pad;
-       u_int   hsc_magic;              /* XXX sigreturn: cookie */
-       struct  sigcontext *hsc_realsc; /* XXX sigreturn: ptr to BSD context */
-};
-
-/*
- * For an HP-UX process, a partial hpuxsigframe follows the normal sigframe.
- * Tremendous waste of space, but some HP-UX applications (e.g. LCL) need it.
- */
-struct hpuxsigframe {
-       int     hsf_signum;
-       struct  sigcontext *hsf_scp;
-       int     hsf_nothing;
-       struct  hpuxsigcontext hsf_sc;
-       int     hsf_regs[15];
-};
-#endif
-
-#ifdef DEBUG
-int sigdebug = 0;
-int sigpid = 0;
-#define SDB_FOLLOW     0x01
-#define SDB_KSTACK     0x02
-#define SDB_FPSTATE    0x04
-#endif
-
-/*
- * Send an interrupt to process.
- */
-void
-sendsig(catcher, sig, mask, code, type, val)
-       sig_t catcher;
-       int sig, mask;
-       u_long code;
-       int type;
-       union sigval val;
-{
-       register struct proc *p = curproc;
-       register struct sigframe *fp, *kfp;
-       register struct frame *frame;
-       register struct sigacts *psp = p->p_sigacts;
-       register short ft;
-       int oonstack, fsize;
-       extern char sigcode[], esigcode[];
-#ifdef COMPAT_HPUX
-       extern char hpux_sigcode[], hpux_esigcode[];
-#endif
-
-       frame = (struct frame *)p->p_md.md_regs;
-       ft = frame->f_format;
-       oonstack = psp->ps_sigstk.ss_flags & SS_ONSTACK;
-       /*
-        * Allocate and validate space for the signal handler
-        * context. Note that if the stack is in P0 space, the
-        * call to grow() is a nop, and the useracc() check
-        * will fail if the process has not already allocated
-        * the space with a `brk'.
-        */
-#ifdef COMPAT_HPUX
-       if (p->p_emul == &emul_hpux)
-               fsize = sizeof(struct sigframe) + sizeof(struct hpuxsigframe);
-       else
-#endif
-       fsize = sizeof(struct sigframe);
-       if ((psp->ps_flags & SAS_ALTSTACK) && !oonstack &&
-           (psp->ps_sigonstack & sigmask(sig))) {
-               fp = (struct sigframe *)(psp->ps_sigstk.ss_sp +
-                                        psp->ps_sigstk.ss_size - fsize);
-               psp->ps_sigstk.ss_flags |= SS_ONSTACK;
-       } else
-               fp = (struct sigframe *)(frame->f_regs[SP] - fsize);
-       if ((unsigned)fp <= USRSTACK - ctob(p->p_vmspace->vm_ssize)) 
-               (void)grow(p, (unsigned)fp);
-#ifdef DEBUG
-       if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
-               printf("sendsig(%d): sig %d ssp %x usp %x scp %x ft %d\n",
-                      p->p_pid, sig, &oonstack, fp, &fp->sf_sc, ft);
-#endif
-       if (useracc((caddr_t)fp, fsize, B_WRITE) == 0) {
-#ifdef DEBUG
-               if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
-                       printf("sendsig(%d): useracc failed on sig %d\n",
-                              p->p_pid, sig);
-#endif
-               /*
-                * Process has trashed its stack; give it an illegal
-                * instruction to halt it in its tracks.
-                */
-               SIGACTION(p, SIGILL) = SIG_DFL;
-               sig = sigmask(SIGILL);
-               p->p_sigignore &= ~sig;
-               p->p_sigcatch &= ~sig;
-               p->p_sigmask &= ~sig;
-               psignal(p, SIGILL);
-               return;
-       }
-       kfp = (struct sigframe *)malloc((u_long)fsize, M_TEMP, M_WAITOK);
-       /* 
-        * Build the argument list for the signal handler.
-        */
-       kfp->sf_signum = sig;
-       kfp->sf_sip = NULL;
-       kfp->sf_scp = &fp->sf_sc;
-       kfp->sf_handler = catcher;
-
-       /*
-        * Save necessary hardware state.  Currently this includes:
-        *      - general registers
-        *      - original exception frame (if not a "normal" frame)
-        *      - FP coprocessor state
-        */
-       kfp->sf_state.ss_flags = SS_USERREGS;
-       bcopy((caddr_t)frame->f_regs,
-             (caddr_t)kfp->sf_state.ss_frame.f_regs, sizeof frame->f_regs);
-       if (ft >= FMT7) {
-#ifdef DEBUG
-               if (ft > 15 || exframesize[ft] < 0)
-                       panic("sendsig: bogus frame type");
-#endif
-               kfp->sf_state.ss_flags |= SS_RTEFRAME;
-               kfp->sf_state.ss_frame.f_format = frame->f_format;
-               kfp->sf_state.ss_frame.f_vector = frame->f_vector;
-               bcopy((caddr_t)&frame->F_u,
-                     (caddr_t)&kfp->sf_state.ss_frame.F_u, exframesize[ft]);
-               /*
-                * Leave an indicator that we need to clean up the kernel
-                * stack.  We do this by setting the "pad word" above the
-                * hardware stack frame to the amount the stack must be
-                * adjusted by.
-                *
-                * N.B. we increment rather than just set f_stackadj in
-                * case we are called from syscall when processing a
-                * sigreturn.  In that case, f_stackadj may be non-zero.
-                */
-               frame->f_stackadj += exframesize[ft];
-               frame->f_format = frame->f_vector = 0;
-#ifdef DEBUG
-               if (sigdebug & SDB_FOLLOW)
-                       printf("sendsig(%d): copy out %d of frame %d\n",
-                              p->p_pid, exframesize[ft], ft);
-#endif
-       }
-#ifdef FPCOPROC
-       kfp->sf_state.ss_flags |= SS_FPSTATE;
-       m68881_save(&kfp->sf_state.ss_fpstate);
-#ifdef DEBUG
-       if ((sigdebug & SDB_FPSTATE) && *(char *)&kfp->sf_state.ss_fpstate)
-               printf("sendsig(%d): copy out FP state (%x) to %x\n",
-                      p->p_pid, *(u_int *)&kfp->sf_state.ss_fpstate,
-                      &kfp->sf_state.ss_fpstate);
-#endif
-#endif
-       /*
-        * Build the signal context to be used by sigreturn.
-        */
-       kfp->sf_sc.sc_onstack = oonstack;
-       kfp->sf_sc.sc_mask = mask;
-       kfp->sf_sc.sc_sp = frame->f_regs[SP];
-       kfp->sf_sc.sc_fp = frame->f_regs[A6];
-       kfp->sf_sc.sc_ap = (int)&fp->sf_state;
-       kfp->sf_sc.sc_pc = frame->f_pc;
-       kfp->sf_sc.sc_ps = frame->f_sr;
-
-       if (psp->ps_siginfo & sigmask(sig)) {
-               kfp->sf_sip = &fp->sf_si;
-               initsiginfo(&kfp->sf_si, sig, code, type, val);
-       }
-
-#ifdef COMPAT_HPUX
-       /*
-        * Create an HP-UX style sigcontext structure and associated goo
-        */
-       if (p->p_emul == &emul_hpux) {
-               register struct hpuxsigframe *hkfp;
-
-               hkfp = (struct hpuxsigframe *)&kfp[1];
-               hkfp->hsf_signum = bsdtohpuxsig(kfp->sf_signum);
-               hkfp->hsf_scp = (struct sigcontext *)
-                       &((struct hpuxsigframe *)(&fp[1]))->hsf_sc;
-               hkfp->hsf_sc.hsc_syscall = 0;           /* XXX */
-               hkfp->hsf_sc.hsc_action = 0;            /* XXX */
-               hkfp->hsf_sc.hsc_pad1 = hkfp->hsf_sc.hsc_pad2 = 0;
-               hkfp->hsf_sc.hsc_onstack = kfp->sf_sc.sc_onstack;
-               hkfp->hsf_sc.hsc_mask = kfp->sf_sc.sc_mask;
-               hkfp->hsf_sc.hsc_sp = kfp->sf_sc.sc_sp;
-               hkfp->hsf_sc.hsc_ps = kfp->sf_sc.sc_ps;
-               hkfp->hsf_sc.hsc_pc = kfp->sf_sc.sc_pc;
-               hkfp->hsf_sc.hsc_pad = 0;
-               hkfp->hsf_sc.hsc_magic = 0xdeadbeef;
-               hkfp->hsf_sc.hsc_realsc = kfp->sf_scp;
-               bcopy((caddr_t)frame->f_regs, (caddr_t)hkfp->hsf_regs,
-                     sizeof (hkfp->hsf_regs));
-
-               kfp->sf_signum = hkfp->hsf_signum;
-               kfp->sf_scp = hkfp->hsf_scp;
-       }
-#endif
-       /* XXX do not copy out siginfo if not needed */
-       (void) copyout((caddr_t)kfp, (caddr_t)fp, fsize);
-       frame->f_regs[SP] = (int)fp;
-#ifdef DEBUG
-       if (sigdebug & SDB_FOLLOW)
-               printf("sendsig(%d): sig %d scp %x fp %x sc_sp %x sc_ap %x\n",
-                      p->p_pid, sig, kfp->sf_scp, fp,
-                      kfp->sf_sc.sc_sp, kfp->sf_sc.sc_ap);
-#endif
-       /*
-        * Signal trampoline code is at base of user stack.
-        */
-#ifdef COMPAT_HPUX
-       if (p->p_emul == &emul_hpux)
-               frame->f_pc = (int)PS_STRINGS - (hpux_esigcode - hpux_sigcode);
-       else
-#endif
-       frame->f_pc = (int)PS_STRINGS - (esigcode - sigcode);
-#ifdef DEBUG
-       if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
-               printf("sendsig(%d): sig %d returns\n",
-                      p->p_pid, sig);
-#endif
-       free((caddr_t)kfp, M_TEMP);
-}
-
-/*
- * System call to cleanup state after a signal
- * has been taken.  Reset signal mask and
- * stack state from context left by sendsig (above).
- * Return to previous pc and psl as specified by
- * context left by sendsig. Check carefully to
- * make sure that the user has not modified the
- * psl to gain improper priviledges or to cause
- * a machine fault.
- */
-/* ARGSUSED */
-int
-sys_sigreturn(p, v, retval)
-       struct proc *p;
-       void *v;
-       register_t *retval;
-{
-       struct sys_sigreturn_args /* {
-               syscallarg(struct sigcontext *) sigcntxp;
-       } */ *uap = v;
-       register struct sigcontext *scp;
-       register struct frame *frame;
-       register int rf;
-       struct sigcontext tsigc;
-       struct sigstate tstate;
-       int flags;
-
-       scp = SCARG(uap, sigcntxp);
-#ifdef DEBUG
-       if (sigdebug & SDB_FOLLOW)
-               printf("sigreturn: pid %d, scp %x\n", p->p_pid, scp);
-#endif
-       if ((int)scp & 1)
-               return (EINVAL);
-#ifdef COMPAT_HPUX
-       /*
-        * Grab context as an HP-UX style context and determine if it
-        * was one that we contructed in sendsig.
-        */
-       if (p->p_emul == &emul_hpux) {
-               struct hpuxsigcontext *hscp = (struct hpuxsigcontext *)scp;
-               struct hpuxsigcontext htsigc;
-
-               if (useracc((caddr_t)hscp, sizeof (*hscp), B_WRITE) == 0 ||
-                   copyin((caddr_t)hscp, (caddr_t)&htsigc, sizeof htsigc))
-                       return (EINVAL);
-               /*
-                * If not generated by sendsig or we cannot restore the
-                * BSD-style sigcontext, just restore what we can -- state
-                * will be lost, but them's the breaks.
-                */
-               hscp = &htsigc;
-               if (hscp->hsc_magic != 0xdeadbeef ||
-                   (scp = hscp->hsc_realsc) == 0 ||
-                   useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
-                   copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc)) {
-                       if (hscp->hsc_onstack & 01)
-                               p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
-                       else
-                               p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
-                       p->p_sigmask = hscp->hsc_mask &~ sigcantmask;
-                       frame = (struct frame *) p->p_md.md_regs;
-                       frame->f_regs[SP] = hscp->hsc_sp;
-                       frame->f_pc = hscp->hsc_pc;
-                       frame->f_sr = hscp->hsc_ps &~ PSL_USERCLR;
-                       return (EJUSTRETURN);
-               }
-               /*
-                * Otherwise, overlay BSD context with possibly modified
-                * HP-UX values.
-                */
-               tsigc.sc_onstack = hscp->hsc_onstack;
-               tsigc.sc_mask = hscp->hsc_mask;
-               tsigc.sc_sp = hscp->hsc_sp;
-               tsigc.sc_ps = hscp->hsc_ps;
-               tsigc.sc_pc = hscp->hsc_pc;
-       } else
-#endif
-       /*
-        * Test and fetch the context structure.
-        * We grab it all at once for speed.
-        */
-       if (useracc((caddr_t)scp, sizeof (*scp), B_WRITE) == 0 ||
-           copyin((caddr_t)scp, (caddr_t)&tsigc, sizeof tsigc))
-               return (EINVAL);
-       scp = &tsigc;
-       if ((scp->sc_ps & (PSL_MBZ|PSL_IPL|PSL_S)) != 0)
-               return (EINVAL);
-       /*
-        * Restore the user supplied information
-        */
-       if (scp->sc_onstack & 01)
-               p->p_sigacts->ps_sigstk.ss_flags |= SS_ONSTACK;
-       else
-               p->p_sigacts->ps_sigstk.ss_flags &= ~SS_ONSTACK;
-       p->p_sigmask = scp->sc_mask &~ sigcantmask;
-       frame = (struct frame *) p->p_md.md_regs;
-       frame->f_regs[SP] = scp->sc_sp;
-       frame->f_regs[A6] = scp->sc_fp;
-       frame->f_pc = scp->sc_pc;
-       frame->f_sr = scp->sc_ps;
-       /*
-        * Grab pointer to hardware state information.
-        * If zero, the user is probably doing a longjmp.
-        */
-       if ((rf = scp->sc_ap) == 0)
-               return (EJUSTRETURN);
-       /*
-        * See if there is anything to do before we go to the
-        * expense of copying in close to 1/2K of data
-        */
-       flags = fuword((caddr_t)rf);
-#ifdef DEBUG
-       if (sigdebug & SDB_FOLLOW)
-               printf("sigreturn(%d): sc_ap %x flags %x\n",
-                      p->p_pid, rf, flags);
-#endif
-       /*
-        * fuword failed (bogus sc_ap value).
-        */
-       if (flags == -1)
-               return (EINVAL);
-       if (flags == 0 || copyin((caddr_t)rf, (caddr_t)&tstate, sizeof tstate))
-               return (EJUSTRETURN);
-#ifdef DEBUG
-       if ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid)
-               printf("sigreturn(%d): ssp %x usp %x scp %x ft %d\n",
-                      p->p_pid, &flags, scp->sc_sp, SCARG(uap, sigcntxp),
-                      (flags&SS_RTEFRAME) ? tstate.ss_frame.f_format : -1);
-#endif
-       /*
-        * Restore most of the users registers except for A6 and SP
-        * which were handled above.
-        */
-       if (flags & SS_USERREGS)
-               bcopy((caddr_t)tstate.ss_frame.f_regs,
-                     (caddr_t)frame->f_regs, sizeof(frame->f_regs)-2*NBPW);
-       /*
-        * Restore long stack frames.  Note that we do not copy
-        * back the saved SR or PC, they were picked up above from
-        * the sigcontext structure.
-        */
-       if (flags & SS_RTEFRAME) {
-               register int sz;
-               
-               /* grab frame type and validate */
-               sz = tstate.ss_frame.f_format;
-               if (sz > 15 || (sz = exframesize[sz]) < 0)
-                       return (EINVAL);
-               frame->f_stackadj -= sz;
-               frame->f_format = tstate.ss_frame.f_format;
-               frame->f_vector = tstate.ss_frame.f_vector;
-               bcopy((caddr_t)&tstate.ss_frame.F_u, (caddr_t)&frame->F_u, sz);
-#ifdef DEBUG
-               if (sigdebug & SDB_FOLLOW)
-                       printf("sigreturn(%d): copy in %d of frame type %d\n",
-                              p->p_pid, sz, tstate.ss_frame.f_format);
-#endif
-       }
-#ifdef FPCOPROC
-       /*
-        * Finally we restore the original FP context
-        */
-       if (flags & SS_FPSTATE)
-               m68881_restore(&tstate.ss_fpstate);
-#ifdef DEBUG
-       if ((sigdebug & SDB_FPSTATE) && *(char *)&tstate.ss_fpstate)
-               printf("sigreturn(%d): copied in FP state (%x) at %x\n",
-                      p->p_pid, *(u_int *)&tstate.ss_fpstate,
-                      &tstate.ss_fpstate);
-#endif
-#endif
-#ifdef DEBUG
-       if ((sigdebug & SDB_FOLLOW) ||
-           ((sigdebug & SDB_KSTACK) && p->p_pid == sigpid))
-               printf("sigreturn(%d): returns\n", p->p_pid);
-#endif
-       return (EJUSTRETURN);
-}
-
 int    waittime = -1;
 
 void
index 05a49d5..54b8722 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: mem.c,v 1.3 1997/02/10 11:13:31 downsj Exp $  */
-/*     $NetBSD: mem.c,v 1.14 1997/02/02 07:59:41 thorpej Exp $ */
+/*     $OpenBSD: mem.c,v 1.4 1997/03/26 08:32:43 downsj Exp $  */
+/*     $NetBSD: mem.c,v 1.15 1997/03/15 23:30:12 thorpej Exp $ */
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -57,6 +57,7 @@
 #include <vm/vm.h>
 
 extern u_int lowram;
+extern char *extiobase;
 static caddr_t devzeropage;
 
 /*ARGSUSED*/
@@ -117,13 +118,15 @@ mmrw(dev, uio, flags)
 /* minor device 0 is physical memory */
                case 0:
                        v = uio->uio_offset;
-#ifndef DEBUG
-                       /* allow reads only in RAM (except for DEBUG) */
+
+                       /*
+                        * Only allow reads in physical RAM.
+                        */
                        if (v >= 0xFFFFFFFC || v < lowram) {
                                error = EFAULT;
                                goto unlock;
                        }
-#endif
+
                        pmap_enter(pmap_kernel(), (vm_offset_t)vmmap,
                            trunc_page(v), uio->uio_rw == UIO_READ ?
                            VM_PROT_READ : VM_PROT_WRITE, TRUE);
@@ -141,6 +144,17 @@ mmrw(dev, uio, flags)
                        if (!kernacc((caddr_t)v, c,
                            uio->uio_rw == UIO_READ ? B_READ : B_WRITE))
                                return (EFAULT);
+
+                       /*
+                        * Don't allow reading intio or dio
+                        * device space.  This could lead to
+                        * corruption of device registers.
+                        */
+                       if (ISIIOVA(v) ||
+                           ((caddr_t)v >= extiobase &&
+                           (caddr_t)v < (extiobase + (EIOMAPSIZE * NBPG))))
+                               return (EFAULT);
+
                        error = uiomove((caddr_t)v, c, uio);
                        continue;
 
@@ -159,19 +173,11 @@ mmrw(dev, uio, flags)
                        /*
                         * On the first call, allocate and zero a page
                         * of memory for use with /dev/zero.
-                        *
-                        * XXX on the hp300 we already know where there
-                        * is a global zeroed page, the null segment table.
                         */
                        if (devzeropage == NULL) {
-#if CLBYTES == NBPG
-                               extern caddr_t Segtabzero;
-                               devzeropage = Segtabzero;
-#else
                                devzeropage = (caddr_t)
                                    malloc(CLBYTES, M_TEMP, M_WAITOK);
                                bzero(devzeropage, CLBYTES);
-#endif
                        }
                        c = min(iov->iov_len, CLBYTES);
                        error = uiomove(devzeropage, c, uio);
@@ -211,11 +217,9 @@ mmmmap(dev, off, prot)
         */
        if (minor(dev) != 0)
                return (-1);
+
        /*
         * Allow access only in RAM.
-        *
-        * XXX could be extended to allow access to IO space but must
-        * be very careful.
         */
        if ((unsigned)off < lowram || (unsigned)off >= 0xFFFFFFFC)
                return (-1);
index dbf0777..9bb24ab 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: pmap.c,v 1.5 1997/02/24 01:16:09 downsj Exp $ */
-/*     $NetBSD: pmap.c,v 1.28 1997/02/02 08:01:32 thorpej Exp $        */
+/*     $OpenBSD: pmap.c,v 1.6 1997/03/26 08:32:44 downsj Exp $ */
+/*     $NetBSD: pmap.c,v 1.30 1997/03/18 14:13:55 mycroft Exp $        */
 
 /* 
  * Copyright (c) 1991, 1993
@@ -908,8 +908,7 @@ pmap_remove(pmap, sva, eva)
         *      2. if it is a user mapping not for the current process,
         *         it won't be there
         */
-       if (pmap_aliasmask &&
-           (pmap == pmap_kernel() || pmap != curproc->p_vmspace->vm_map.pmap))
+       if (pmap_aliasmask && !active_user_pmap(pmap))
                needcflush = FALSE;
 #ifdef DEBUG
        if (pmap_aliasmask && (pmapvacflush & PVF_REMOVE)) {
@@ -2008,8 +2007,7 @@ pmap_remove_mapping(pmap, va, pte, flags)
                 * flush the VAC.  Note that the kernel side was flushed
                 * above so we don't worry about non-CI kernel mappings.
                 */
-               if (pmap == curproc->p_vmspace->vm_map.pmap &&
-                   !pmap_pte_ci(pte)) {
+               if (active_user_pmap(pmap) && !pmap_pte_ci(pte)) {
                        DCIU();
 #ifdef PMAPSTATS
                        remove_stats.uflushes++;
@@ -2186,8 +2184,7 @@ pmap_remove_mapping(pmap, va, pte, flags)
                                 * pointer for current process so
                                 * update now to reload hardware.
                                 */
-                               if (curproc != NULL &&
-                                   ptpmap == curproc->p_vmspace->vm_map.pmap)
+                               if (active_user_pmap(ptpmap))
                                        PMAP_ACTIVATE(ptpmap,
                                            &curproc->p_addr->u_pcb, 1);
                        }
@@ -2431,7 +2428,7 @@ pmap_enter_ptpage(pmap, va)
                 * XXX may have changed segment table pointer for current
                 * process so update now to reload hardware.
                 */
-               if (pmap == curproc->p_vmspace->vm_map.pmap)
+               if (active_user_pmap(pmap))
                        PMAP_ACTIVATE(pmap, &curproc->p_addr->u_pcb, 1);
 #ifdef DEBUG
                if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB))
index a2f7185..74deb73 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: trap.c,v 1.8 1997/02/21 06:07:25 deraadt Exp $        */
-/*     $NetBSD: trap.c,v 1.47 1996/10/14 20:06:31 thorpej Exp $        */
+/*     $OpenBSD: trap.c,v 1.9 1997/03/26 08:32:45 downsj Exp $ */
+/*     $NetBSD: trap.c,v 1.48 1997/03/15 23:34:32 thorpej Exp $        */
 
 /*
  * Copyright (c) 1997 Theo de Raadt
@@ -373,9 +373,7 @@ trap(type, code, v, frame)
                i = SIGBUS;
                break;
 
-#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... */
        /*
@@ -396,7 +394,6 @@ trap(type, code, v, frame)
                v = frame.f_pc;
                break;
 
-#ifdef FPCOPROC
        case T_COPERR|T_USER:   /* user coprocessor violation */
        /* What is a proper response here? */
                typ = FPE_FLTINV;
@@ -419,7 +416,6 @@ trap(type, code, v, frame)
                i = SIGFPE;
                v = frame.f_pc;
                break;
-#endif
 
 #ifdef M68040
        case T_FPEMULI|T_USER:  /* unimplemented FP instuction */
index 3c82ed9..e22fbf4 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: vm_machdep.c,v 1.7 1997/02/10 11:13:34 downsj Exp $   */
-/*     $NetBSD: vm_machdep.c,v 1.31 1997/02/02 08:03:06 thorpej Exp $  */
+/*     $OpenBSD: vm_machdep.c,v 1.8 1997/03/26 08:32:45 downsj Exp $   */
+/*     $NetBSD: vm_machdep.c,v 1.34 1997/03/16 09:59:40 thorpej Exp $  */
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -79,7 +79,7 @@ cpu_fork(p1, p2)
        extern struct pcb *curpcb;
        extern void proc_trampoline(), child_return();
 
-       p2->p_md.md_flags = p1->p_md.md_flags & ~MDP_HPUXTRACE;
+       p2->p_md.md_flags = p1->p_md.md_flags;
 
        /* Sync curpcb (which is presumably p1's PCB) and copy it to p2. */
        savectx(curpcb);
@@ -149,18 +149,6 @@ cpu_coredump(p, vp, cred, chdr)
        struct coreseg cseg;
        int error;
 
-#ifdef COMPAT_HPUX
-       extern struct emul emul_hpux;
-
-       /*
-        * If we loaded from an HP-UX format binary file we dump enough
-        * of an HP-UX style user struct so that the HP-UX debuggers can
-        * grok it.
-        */
-       if (p->p_emul == &emul_hpux)
-               return (hpux_dumpu(vp, cred));
-#endif
-
        CORE_SETMAGIC(*chdr, COREMAGIC, MID_M68K, 0);
        chdr->c_hdrsize = ALIGN(sizeof(*chdr));
        chdr->c_seghdrsize = ALIGN(sizeof(cseg));
@@ -171,10 +159,15 @@ cpu_coredump(p, vp, cred, chdr)
        if (error)
                return error;
 
-       /* Save floating point registers. */
-       error = process_read_fpregs(p, &md_core.freg);
-       if (error)
-               return error;
+       if (fputype) {
+               /* Save floating point registers. */
+               error = process_read_fpregs(p, &md_core.freg);
+               if (error)
+                       return error;
+       } else {
+               /* Make sure these are clear. */
+               bzero((caddr_t)&md_core.freg, sizeof(md_core.freg));
+       }
 
        CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_M68K, CORE_CPU);
        cseg.c_addr = 0;
index 35dc017..7c6f14f 100644 (file)
@@ -1,8 +1,8 @@
-/*     $OpenBSD: hpux_machdep.h,v 1.3 1997/01/12 15:13:36 downsj Exp $ */
-/*     $NetBSD: hpux_machdep.h,v 1.3 1996/02/28 01:05:57 thorpej Exp $ */
+/*     $OpenBSD: hpux_machdep.h,v 1.4 1997/03/26 08:32:46 downsj Exp $ */
+/*     $NetBSD: hpux_machdep.h,v 1.6 1997/03/16 10:02:40 thorpej Exp $ */
 
 /*-
- * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
 #ifndef _MACHINE_HPUX_MACHDEP_H_
 #define _MACHINE_HPUX_MACHDEP_H_
 
+/*    
+ * Information pushed on stack when a signal is delivered.
+ * This is used by the kernel to restore state following
+ * execution of the signal handler.  It is also made available
+ * to the handler to allow it to restore state properly if
+ * a non-standard exit is performed. 
+ */
+struct hpuxsigcontext {
+       int     hsc_syscall;            /* ??? (syscall number?) */
+       char    hsc_action;             /* ??? */
+       char    hsc_pad1;
+       char    hsc_pad2;
+       char    hsc_onstack;            /* sigstack state to restore */
+       int     hsc_mask;               /* signal mask to restore */
+       int     hsc_sp;                 /* sp to restore */
+       short   hsc_ps;                 /* psl to restore */
+       int     hsc_pc;                 /* pc to restore */
+
+       /*
+        * The following are not actually used by HP-UX.  They exist
+        * for the convenience of the compatibility code.
+        */
+       short   _hsc_pad;
+       int     _hsc_ap;                /* pointer to hpuxsigstate */
+};
+
 int    hpux_cpu_makecmds __P((struct proc *, struct exec_package *));
 int    hpux_cpu_vmcmd __P((struct proc *, struct exec_vmcmd *));
 void   hpux_cpu_bsd_to_hpux_stat __P((struct stat *, struct hpux_stat *));
 void   hpux_cpu_uname __P((struct hpux_utsname *));
 int    hpux_cpu_sysconf_arch __P((void));
 int    hpux_to_bsd_uoff __P((int *, int *, struct proc *));
-int    hpux_dumpu __P((struct vnode *, struct ucred *));
+
+void   hpux_sendsig __P((sig_t, int, int, u_long, int, union sigval));
+void   hpux_setregs __P((struct proc *, struct exec_package *,
+           u_long, register_t *));
 
 #endif /* ! _MACHINE_HPUX_MACHDEP_H_ */
index 3637780..a90af0d 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: pmap.h,v 1.3 1997/01/12 15:13:39 downsj Exp $ */
-/*     $NetBSD: pmap.h,v 1.10 1995/12/11 17:09:23 thorpej Exp $        */
+/*     $OpenBSD: pmap.h,v 1.4 1997/03/26 08:32:46 downsj Exp $ */
+/*     $NetBSD: pmap.h,v 1.12 1997/03/18 16:39:30 mycroft Exp $        */
 
 /* 
  * Copyright (c) 1987 Carnegie-Mellon University
@@ -142,6 +142,9 @@ extern struct pmap  kernel_pmap_store;
 #define pmap_kernel()  (&kernel_pmap_store)
 #define        active_pmap(pm) \
        ((pm) == pmap_kernel() || (pm) == curproc->p_vmspace->vm_map.pmap)
+#define        active_user_pmap(pm) \
+       (curproc && \
+        (pm) != pmap_kernel() && (pm) == curproc->p_vmspace->vm_map.pmap)
 
 extern struct pv_entry *pv_table;      /* array of entries, one per page */
 
index 11c46e2..6403782 100644 (file)
@@ -1,5 +1,5 @@
-/*     $OpenBSD: proc.h,v 1.3 1997/02/24 01:16:11 downsj Exp $ */
-/*     $NetBSD: proc.h,v 1.6 1994/10/26 07:26:35 cgd Exp $     */
+/*     $OpenBSD: proc.h,v 1.4 1997/03/26 08:32:47 downsj Exp $ */
+/*     $NetBSD: proc.h,v 1.7 1997/03/16 09:41:36 thorpej Exp $ */
 
 /*
  * Copyright (c) 1991, 1993
@@ -47,7 +47,6 @@ struct mdproc {
 /* md_flags */
 #define MDP_STACKADJ   0x0002  /* frame SP adjusted; undo when syscall does ERE
 START */
-#define        MDP_HPUXTRACE   0x0004  /* being traced by HP-UX process */
 #define        MDP_HPUXMMAP    0x0008  /* VA space is multiply mapped */
 #define MDP_CCBDATA    0x0010  /* copyback caching of data (68040) */
 #define MDP_CCBSTACK   0x0020  /* copyback caching of stack (68040) */