BSD 4_4_Lite1 release
[unix-history] / usr / src / sys / luna68k / luna68k / locore.s
index 17d7848..5a4260e 100644 (file)
@@ -1,26 +1,73 @@
 /*
  * Copyright (c) 1988 University of Utah.
  * Copyright (c) 1992 OMRON Corporation.
 /*
  * Copyright (c) 1988 University of Utah.
  * Copyright (c) 1992 OMRON Corporation.
- * Copyright (c) 1980, 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1980, 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * This code is derived from software contributed to Berkeley by
  * the Systems Programming Group of the University of Utah Computer
  * Science Department.
  *
  *
  * This code is derived from software contributed to Berkeley by
  * the Systems Programming Group of the University of Utah Computer
  * Science Department.
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- * from: Utah $Hdr: locore.s 1.62 92/01/20$
- * OMRON: $Id: locore.s,v 1.2 92/06/14 06:16:34 moti Exp $
+ * 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.
  *
  *
- * from: hp300/hp300/locore.s   7.16 (Berkeley) 7/8/92
+ * from: Utah $Hdr: locore.s 1.62 92/01/20$
+ * from: hp300/hp300/locore.s  8.5 (Berkeley) 11/14/93
  *
  *
- *     @(#)locore.s    7.6 (Berkeley) %G%
+ *     @(#)locore.s    8.4 (Berkeley) 12/6/93
  */
 
  */
 
+/*
+ * STACKCHECK enables two types of kernel stack checking:
+ *     1. stack "overflow".  On every clock interrupt we ensure that
+ *        the current kernel stack has not grown into the user struct
+ *        page, i.e. size exceeded UPAGES-1 pages.
+ *     2. stack "underflow".  Before every rte to user mode we ensure
+ *        that we will be exactly at the base of the stack after the
+ *        exception frame has been popped.
+ * Both checks are performed at splclock since they operate on the
+ * global temporary stack.
+ */
+/* #define     STACKCHECK */
+
 #include "assym.s"
 #include <luna68k/luna68k/vectors.s>
 
 #include "assym.s"
 #include <luna68k/luna68k/vectors.s>
 
+/*
+ * Temporary stack for a variety of purposes.
+ * Try and make this the first thing is the data segment so it
+ * is page aligned.  Note that if we overflow here, we run into
+ * our text segment.
+ */
+       .data
+       .space  NBPG
+tmpstk:
+
        .text
 /*
  * This is where we wind up if the kernel jumps to location 0.
        .text
 /*
  * This is where we wind up if the kernel jumps to location 0.
@@ -53,35 +100,73 @@ _doadump:
        .globl  _trap, _nofault, _longjmp
 _buserr:
        tstl    _nofault                | device probe?
        .globl  _trap, _nofault, _longjmp
 _buserr:
        tstl    _nofault                | device probe?
-       jeq     _addrerr                | no, handle as usual
+       jeq     Lberr                   | no, handle as usual
        movl    _nofault,sp@-           | yes,
        jbsr    _longjmp                |  longjmp(nofault)
        movl    _nofault,sp@-           | yes,
        jbsr    _longjmp                |  longjmp(nofault)
+Lberr:
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     _addrerr                | no, skip
+       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:
 _addrerr:
-       clrw    sp@-                    | pad SR to longword
+       clrl    sp@-                    | stack adjust count
        moveml  #0xFFFF,sp@-            | save user registers
        movl    usp,a0                  | save the user SP
        moveml  #0xFFFF,sp@-            | save user registers
        movl    usp,a0                  | save the user SP
-       movl    a0,sp@(60)              |   in the savearea
-       lea     sp@(64),a1              | grab base of HW berr frame
+       movl    a0,sp@(FR_SP)           |   in the savearea
+       lea     sp@(FR_HW),a1           | grab base of HW berr frame
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     Lbenot040               | no, skip
+       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
        moveq   #0,d0
-       movw    a1@(12),d0              | grab SSW for fault processing
+       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
        btst    #12,d0                  | RB set?
        jeq     LbeX0                   | no, test RC
        bset    #14,d0                  | yes, must set FB
-       movw    d0,a1@(12)              | for hardware too
+       movw    d0,a1@(10)              | for hardware too
 LbeX0:
        btst    #13,d0                  | RC set?
        jeq     LbeX1                   | no, skip
        bset    #15,d0                  | yes, must set FC
 LbeX0:
        btst    #13,d0                  | RC set?
        jeq     LbeX1                   | no, skip
        bset    #15,d0                  | yes, must set FC
-       movw    d0,a1@(12)              | for hardware too
+       movw    d0,a1@(10)              | for hardware too
 LbeX1:
        btst    #8,d0                   | data fault?
        jeq     Lbe0                    | no, check for hard cases
 LbeX1:
        btst    #8,d0                   | data fault?
        jeq     Lbe0                    | no, check for hard cases
-       movl    a1@(18),d1              | fault address is as given in frame
+       movl    a1@(16),d1              | fault address is as given in frame
        jra     Lbe10                   | thats it
 Lbe0:
        jra     Lbe10                   | thats it
 Lbe0:
-       btst    #4,a1@(8)               | long (type B) stack frame?
+       btst    #4,a1@(6)               | long (type B) stack frame?
        jne     Lbe4                    | yes, go handle
        jne     Lbe4                    | yes, go handle
-       movl    a1@(4),d1               | no, can use save PC
+       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
        btst    #14,d0                  | FB set?
        jeq     Lbe3                    | no, try FC
        addql   #4,d1                   | yes, adjust address
@@ -92,14 +177,14 @@ Lbe3:
        addql   #2,d1                   | yes, adjust address
        jra     Lbe10                   | done
 Lbe4:
        addql   #2,d1                   | yes, adjust address
        jra     Lbe10                   | done
 Lbe4:
-       movl    a1@(38),d1              | long format, use stage B address
+       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
        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@(8),d0               | get frame format/vector offset
+       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
        andw    #0x0FFF,d0              | clear out frame format
        cmpw    #12,d0                  | address error vector?
        jeq     Lisaerr                 | yes, go to it
@@ -121,21 +206,21 @@ Lisberr:
 Ltrapnstkadj:
        jbsr    _trap                   | handle the error
        lea     sp@(12),sp              | pop value args
 Ltrapnstkadj:
        jbsr    _trap                   | handle the error
        lea     sp@(12),sp              | pop value args
-       movl    sp@(60),a0              | restore user SP
+       movl    sp@(FR_SP),a0           | restore user SP
        movl    a0,usp                  |   from save area
        movl    a0,usp                  |   from save area
-       movw    sp@(64),d0              | need to adjust stack?
+       movw    sp@(FR_ADJ),d0          | need to adjust stack?
        jne     Lstkadj                 | yes, go to it
        moveml  sp@+,#0x7FFF            | no, restore most user regs
        jne     Lstkadj                 | yes, go to it
        moveml  sp@+,#0x7FFF            | no, restore most user regs
-       addql   #6,sp                   | toss SSP and pad
+       addql   #8,sp                   | toss SSP and stkadj
        jra     rei                     | all done
 Lstkadj:
        jra     rei                     | all done
 Lstkadj:
-       lea     sp@(66),a1              | pointer to HW frame
+       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
        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@(60)              | new SSP
+       movl    a0,sp@(FR_SP)           | new SSP
        moveml  sp@+,#0x7FFF            | restore user registers
        movl    sp@,sp                  | and our SP
        jra     rei                     | all done
        moveml  sp@+,#0x7FFF            | restore user registers
        movl    sp@,sp                  | and our SP
        jra     rei                     | all done
@@ -144,10 +229,38 @@ Lstkadj:
  * FP exceptions.
  */
 _fpfline:
  * FP exceptions.
  */
 _fpfline:
+#if defined(LUNA2)
+       cmpw    #0x202c,sp@(6)          | format type 2?
+       jne     _illinst                | no, not an FP emulation
+#ifdef HPFPLIB
+       .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
        jra     _illinst
+#endif
 
 _fpunsupp:
 
 _fpunsupp:
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     _illinst                | no, treat as illinst
+#ifdef HPFPLIB
+       .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
        jra     _illinst
+#endif
 
 /*
  * Handles all other FP coprocessor exceptions.
 
 /*
  * Handles all other FP coprocessor exceptions.
@@ -157,10 +270,10 @@ _fpunsupp:
  */
 _fpfault:
 #ifdef FPCOPROC
  */
 _fpfault:
 #ifdef FPCOPROC
-       clrw    sp@-            | pad SR to longword
+       clrl    sp@-            | stack adjust count
        moveml  #0xFFFF,sp@-    | save user registers
        movl    usp,a0          | and save
        moveml  #0xFFFF,sp@-    | save user registers
        movl    usp,a0          | and save
-       movl    a0,sp@(60)      |   the user stack pointer
+       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
        clrl    sp@-            | no VA arg
        movl    _curpcb,a0      | current pcb
        lea     a0@(PCB_FPCTX),a0 | address of FP savearea
@@ -179,26 +292,57 @@ Lfptnull:
        jra     _badtrap        | treat as an unexpected trap
 #endif
 
        jra     _badtrap        | treat as an unexpected trap
 #endif
 
+#ifdef HPFPLIB
+/*
+ * We wind up here from the 040 FP emulation library after
+ * the exception has been processed.
+ */
+       .globl  _fault
+_fault:
+       subql   #4,sp           | space for rts addr
+       movl    d0,sp@-         | scratch register
+       movw    sp@(14),d0      | get vector offset
+       andl    #0xFFF,d0       | mask out frame type and clear high word
+       cmpl    #0x100,d0       | HP-UX style reschedule trap?
+       jne     Lfault1         | no, skip
+       movl    sp@+,d0         | restore scratch register
+       addql   #4,sp           | pop space
+       jra     Lrei1           | go do AST
+Lfault1:
+       cmpl    #0xC0,d0        | FP exception?
+       jlt     Lfault2         | no, skip
+       movl    sp@+,d0         | yes, backoff
+       addql   #4,sp           |  and prepare for normal trap frame
+       jra     _fpfault        | go to it
+Lfault2:
+       addl    #Lvectab,d0     | convert to vector table offset
+       exg     d0,a0
+       movl    a0@,sp@(4)      | get exception vector and save for rts
+       exg     d0,a0
+       movl    sp@+,d0         |   scratch registers
+       rts                     | return to handler from vectab
+#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:
 /*
  * Coprocessor and format errors can generate mid-instruction stack
  * frames and cause signal delivery hence we need to check for potential
  * stack adjustment.
  */
 _coperr:
-       clrw    sp@-
+       clrl    sp@-            | stack adjust count
        moveml  #0xFFFF,sp@-
        movl    usp,a0          | get and save
        moveml  #0xFFFF,sp@-
        movl    usp,a0          | get and save
-       movl    a0,sp@(60)      |   the user stack pointer
+       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@-            | 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:
-       clrw    sp@-
+       clrl    sp@-            | stack adjust count
        moveml  #0xFFFF,sp@-
        movl    usp,a0          | get and save
        moveml  #0xFFFF,sp@-
        movl    usp,a0          | get and save
-       movl    a0,sp@(60)      |   the user stack pointer
+       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
        clrl    sp@-            | no VA arg
        clrl    sp@-            | or code arg
        movl    #T_FMTERR,sp@-  | push trap type
@@ -209,31 +353,31 @@ _fmterr:
  * no post-trap stack adjustment.
  */
 _illinst:
  * no post-trap stack adjustment.
  */
 _illinst:
-       clrw    sp@-
+       clrl    sp@-
        moveml  #0xFFFF,sp@-
        moveq   #T_ILLINST,d0
        jra     fault
 
 _zerodiv:
        moveml  #0xFFFF,sp@-
        moveq   #T_ILLINST,d0
        jra     fault
 
 _zerodiv:
-       clrw    sp@-
+       clrl    sp@-
        moveml  #0xFFFF,sp@-
        moveq   #T_ZERODIV,d0
        jra     fault
 
 _chkinst:
        moveml  #0xFFFF,sp@-
        moveq   #T_ZERODIV,d0
        jra     fault
 
 _chkinst:
-       clrw    sp@-
+       clrl    sp@-
        moveml  #0xFFFF,sp@-
        moveq   #T_CHKINST,d0
        jra     fault
 
 _trapvinst:
        moveml  #0xFFFF,sp@-
        moveq   #T_CHKINST,d0
        jra     fault
 
 _trapvinst:
-       clrw    sp@-
+       clrl    sp@-
        moveml  #0xFFFF,sp@-
        moveq   #T_TRAPVINST,d0
        jra     fault
 
 _privinst:
        moveml  #0xFFFF,sp@-
        moveq   #T_TRAPVINST,d0
        jra     fault
 
 _privinst:
-       clrw    sp@-
+       clrl    sp@-
        moveml  #0xFFFF,sp@-
        moveq   #T_PRIVINST,d0
        jra     fault
        moveml  #0xFFFF,sp@-
        moveq   #T_PRIVINST,d0
        jra     fault
@@ -241,44 +385,42 @@ _privinst:
        .globl  fault
 fault:
        movl    usp,a0                  | get and save
        .globl  fault
 fault:
        movl    usp,a0                  | get and save
-       movl    a0,sp@(60)              |   the user stack pointer
+       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
        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@(60),a0              | restore
+       movl    sp@(FR_SP),a0           | restore
        movl    a0,usp                  |   user SP
        moveml  sp@+,#0x7FFF            | restore most user regs
        movl    a0,usp                  |   user SP
        moveml  sp@+,#0x7FFF            | restore most user regs
-       addql   #6,sp                   | pop SP and pad word
+       addql   #8,sp                   | pop SP and stack adjust
        jra     rei                     | all done
 
        .globl  _straytrap
 _badtrap:
        jra     rei                     | all done
 
        .globl  _straytrap
 _badtrap:
-       clrw    sp@-                    | pad SR
        moveml  #0xC0C0,sp@-            | save scratch regs
        moveml  #0xC0C0,sp@-            | save scratch regs
-       movw    sp@(24),sp@-            | push exception vector info
+       movw    sp@(22),sp@-            | push exception vector info
        clrw    sp@-
        clrw    sp@-
-       movl    sp@(24),sp@-            | and PC
+       movl    sp@(22),sp@-            | and PC
        jbsr    _straytrap              | report
        addql   #8,sp                   | pop args
        moveml  sp@+,#0x0303            | restore regs
        jbsr    _straytrap              | report
        addql   #8,sp                   | pop args
        moveml  sp@+,#0x0303            | restore regs
-       addql   #2,sp                   | pop padding
        jra     rei                     | all done
 
        .globl  _syscall
 _trap0:
        jra     rei                     | all done
 
        .globl  _syscall
 _trap0:
-       clrw    sp@-                    | pad SR to longword
+       clrl    sp@-                    | stack adjust count
        moveml  #0xFFFF,sp@-            | save user registers
        movl    usp,a0                  | save the user SP
        moveml  #0xFFFF,sp@-            | save user registers
        movl    usp,a0                  | save the user SP
-       movl    a0,sp@(60)              |   in the savearea
+       movl    a0,sp@(FR_SP)           |   in the savearea
        movl    d0,sp@-                 | push syscall number
        jbsr    _syscall                | handle it
        addql   #4,sp                   | pop syscall arg
        movl    d0,sp@-                 | push syscall number
        jbsr    _syscall                | handle it
        addql   #4,sp                   | pop syscall arg
-       movl    sp@(60),a0              | grab and restore
+       movl    sp@(FR_SP),a0           | grab and restore
        movl    a0,usp                  |   user SP
        moveml  sp@+,#0x7FFF            | restore most registers
        movl    a0,usp                  |   user SP
        moveml  sp@+,#0x7FFF            | restore most registers
-       addql   #6,sp                   | pop SSP and align word
+       addql   #8,sp                   | pop SP and stack adjust
        jra     rei                     | all done
 
 /*
        jra     rei                     | all done
 
 /*
@@ -311,13 +453,13 @@ _trap12:
  * We just pass it on and let trap() sort it all out
  */
 _trap15:
  * We just pass it on and let trap() sort it all out
  */
 _trap15:
-       clrw    sp@-
+       clrl    sp@-
        moveml  #0xFFFF,sp@-
 #ifdef KGDB
        moveq   #T_TRAP15,d0
        moveml  #0xFFFF,sp@-
 #ifdef KGDB
        moveq   #T_TRAP15,d0
-       movl    sp@(64),d1              | from user mode?
-       andl    #PSL_S,d1
-       jeq     fault
+       movw    sp@(FR_HW),d1           | get PSW
+       andw    #PSL_S,d1               | from user mode?
+       jeq     fault                   | yes, just a regular fault
        movl    d0,sp@-
        .globl  _kgdb_trap_glue
        jbsr    _kgdb_trap_glue         | returns if no debugger
        movl    d0,sp@-
        .globl  _kgdb_trap_glue
        jbsr    _kgdb_trap_glue         | returns if no debugger
@@ -331,13 +473,13 @@ _trap15:
  * Push the code and treat as a normal fault.
  */
 _trace:
  * Push the code and treat as a normal fault.
  */
 _trace:
-       clrw    sp@-
+       clrl    sp@-
        moveml  #0xFFFF,sp@-
 #ifdef KGDB
        moveq   #T_TRACE,d0
        moveml  #0xFFFF,sp@-
 #ifdef KGDB
        moveq   #T_TRACE,d0
-       movl    sp@(64),d1              | from user mode?
-       andl    #PSL_S,d1
-       jeq     fault
+       movw    sp@(FR_HW),d1           | get SSW
+       andw    #PSL_S,d1               | from user mode?
+       jeq     fault                   | no, regular fault
        movl    d0,sp@-
        jbsr    _kgdb_trap_glue         | returns if no debugger
        addl    #4,sp
        movl    d0,sp@-
        jbsr    _kgdb_trap_glue         | returns if no debugger
        addl    #4,sp
@@ -354,17 +496,17 @@ sigreturn:
        lea     sp@(-84),sp             | leave enough space for largest frame
        movl    sp@(84),sp@             | move up current 8 byte frame
        movl    sp@(88),sp@(4)
        lea     sp@(-84),sp             | leave enough space for largest frame
        movl    sp@(84),sp@             | move up current 8 byte frame
        movl    sp@(88),sp@(4)
-       movw    #84,sp@-                | default: adjust by 84 bytes
+       movl    #84,sp@-                | default: adjust by 84 bytes
        moveml  #0xFFFF,sp@-            | save user registers
        movl    usp,a0                  | save the user SP
        moveml  #0xFFFF,sp@-            | save user registers
        movl    usp,a0                  | save the user SP
-       movl    a0,sp@(60)              |   in the savearea
+       movl    a0,sp@(FR_SP)           |   in the savearea
        movl    #SYS_sigreturn,sp@-     | push syscall number
        jbsr    _syscall                | handle it
        addql   #4,sp                   | pop syscall#
        movl    #SYS_sigreturn,sp@-     | push syscall number
        jbsr    _syscall                | handle it
        addql   #4,sp                   | pop syscall#
-       movl    sp@(60),a0              | grab and restore
+       movl    sp@(FR_SP),a0           | grab and restore
        movl    a0,usp                  |   user SP
        movl    a0,usp                  |   user SP
-       lea     sp@(64),a1              | pointer to HW frame
-       movw    a1@+,d0                 | do we need to adjust the stack?
+       lea     sp@(FR_HW),a1           | pointer to HW frame
+       movw    sp@(FR_ADJ),d0          | do we need to adjust the stack?
        jeq     Lsigr1                  | no, just continue
        moveq   #92,d1                  | total size
        subw    d0,d1                   |  - hole size = frame size
        jeq     Lsigr1                  | no, just continue
        moveq   #92,d1                  | total size
        subw    d0,d1                   |  - hole size = frame size
@@ -377,7 +519,7 @@ Lsigrlp:
        dbf     d1,Lsigrlp              | continue
        movl    a0,a1                   | new HW frame base
 Lsigr1:
        dbf     d1,Lsigrlp              | continue
        movl    a0,a1                   | new HW frame base
 Lsigr1:
-       movl    a1,sp@(60)              | new SP value
+       movl    a1,sp@(FR_SP)           | new SP value
        moveml  sp@+,#0x7FFF            | restore user registers
        movl    sp@,sp                  | and our SP
        jra     rei                     | all done
        moveml  sp@+,#0x7FFF            | restore user registers
        movl    sp@,sp                  | and our SP
        jra     rei                     | all done
@@ -410,21 +552,17 @@ _lev1intr:
 
 _lev2intr:
        addql   #1,_intrcnt+8
 
 _lev2intr:
        addql   #1,_intrcnt+8
-       clrw    sp@-
        moveml  #0xC0C0,sp@-
        jbsr    __scintr        
        moveml  sp@+,#0x0303
        moveml  #0xC0C0,sp@-
        jbsr    __scintr        
        moveml  sp@+,#0x0303
-       addql   #2,sp
        addql   #1,_cnt+V_INTR
        jra     rei
 
 _lev3intr:
        addql   #1,_intrcnt+12
        addql   #1,_cnt+V_INTR
        jra     rei
 
 _lev3intr:
        addql   #1,_intrcnt+12
-       clrw    sp@-
        moveml  #0xC0C0,sp@-
        jbsr    __leintr
        moveml  sp@+,#0x0303
        moveml  #0xC0C0,sp@-
        jbsr    __leintr
        moveml  sp@+,#0x0303
-       addql   #2,sp
        addql   #1,_cnt+V_INTR
        jra     rei
 
        addql   #1,_cnt+V_INTR
        jra     rei
 
@@ -435,42 +573,34 @@ _lev4intr:
 
 _lev6intr:
        addql   #1,_intrcnt+24
 
 _lev6intr:
        addql   #1,_intrcnt+24
-       clrw    sp@-
        moveml  #0xC0C0,sp@-
        moveml  #0xC0C0,sp@-
-       jbsr    _siointr
+       jbsr    __siointr
        moveml  sp@+,#0x0303
        moveml  sp@+,#0x0303
-       addql   #2,sp
        addql   #1,_cnt+V_INTR
        jra     rei
 
 _lev5intr:
        addql   #1,_cnt+V_INTR
        jra     rei
 
 _lev5intr:
-       clrw    sp@-
-       moveml  #0xC0C0,sp@-
-#ifdef DEBUG
-       .globl  _panicstr, _regdump, _panic
-       cmpl    #_kstack+NBPG,sp        | are we still in stack pages?
+#ifdef STACKCHECK
+       .globl  _panicstr,_badkstack
+       cmpl    #_kstack+NBPG,sp        | are we still in stack page?
        jcc     Lstackok                | yes, continue normally
        jcc     Lstackok                | yes, continue normally
-       tstl    _curproc                | if !curproc could have swtch_exit'ed,
+       tstl    _curproc                | if !curproc could have switch_exited,
        jeq     Lstackok                |     might be on tmpstk
        tstl    _panicstr               | have we paniced?
        jne     Lstackok                | yes, do not re-panic
        jeq     Lstackok                |     might be on tmpstk
        tstl    _panicstr               | have we paniced?
        jne     Lstackok                | yes, do not re-panic
-       lea     tmpstk,sp               | no, switch to tmpstk
-       moveml  #0xFFFF,sp@-            | push all registers
-       movl    #Lstkrip,sp@-           | push panic message
-       jbsr    _printf                 | preview
+       movl    sp@(4),tmpstk-4         | no, copy common
+       movl    sp@,tmpstk-8            |  frame info
+       movl    sp,tmpstk-16            | no, save original SP
+       lea     tmpstk-16,sp            | switch to tmpstk
+       moveml  #0xFFFE,sp@-            | push remaining registers
+       movl    #1,sp@-                 | is an overflow
+       jbsr    _badkstack              | badkstack(1, frame)
        addql   #4,sp
        addql   #4,sp
-       movl    sp,a0                   | remember this spot
-       movl    #256,sp@-               | longword count
-       movl    a0,sp@-                 | and reg pointer
-       jbsr    _regdump                | dump core
-       addql   #8,sp                   | pop params
-       movl    #Lstkrip,sp@-           | push panic message
-       jbsr    _panic                  | ES and D
-Lstkrip:
-       .asciz  "k-stack overflow"
-       .even
+       moveml  sp@+,#0x7FFF            | restore most registers
+       movl    sp@,sp                  | and SP
 Lstackok:
 #endif
 Lstackok:
 #endif
+       moveml  #0xC0C0,sp@-
        lea     sp@(16),a1              | a1 = &clockframe
        btst    #CLK_INT,CLOCK_REG      | system-clock intrrupt?
        jeq     Lnottimer               | no, skip hardclock
        lea     sp@(16),a1              | a1 = &clockframe
        btst    #CLK_INT,CLOCK_REG      | system-clock intrrupt?
        jeq     Lnottimer               | no, skip hardclock
@@ -483,21 +613,20 @@ Lstackok:
        addql   #4,sp
 Lnottimer:
        moveml  sp@+,#0x0303            | restore scratch regs
        addql   #4,sp
 Lnottimer:
        moveml  sp@+,#0x0303            | restore scratch regs
-       addql   #2,sp                   | pop pad word
        addql   #1,_cnt+V_INTR          | chalk up another interrupt
        jra     rei                     | all done
 
 _lev7intr:
        addql   #1,_intrcnt+36
        addql   #1,_cnt+V_INTR          | chalk up another interrupt
        jra     rei                     | all done
 
 _lev7intr:
        addql   #1,_intrcnt+36
-       clrw    sp@-                    | pad SR to longword
+       clrl    sp@-                    | pad SR to longword
        moveml  #0xFFFF,sp@-            | save registers
        movl    usp,a0                  | and save
        moveml  #0xFFFF,sp@-            | save registers
        movl    usp,a0                  | and save
-       movl    a0,sp@(60)              |   the user stack pointer
+       movl    a0,sp@(FR_SP)           |   the user stack pointer
        jbsr    _nmihand                | call handler
        jbsr    _nmihand                | call handler
-       movl    sp@(60),a0              | restore
+       movl    sp@(FR_SP),a0           | restore
        movl    a0,usp                  |   user SP
        moveml  sp@+,#0x7FFF            | and remaining registers
        movl    a0,usp                  |   user SP
        moveml  sp@+,#0x7FFF            | and remaining registers
-       addql   #6,sp                   | pop SSP and align word
+       addql   #8,sp                   | pop SSP and align word
        jra     rei                     | all done
 
 /*
        jra     rei                     | all done
 
 /*
@@ -507,7 +636,8 @@ _lev7intr:
  * (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
  * (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.
+ * 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.
  *
  * This code is complicated by the fact that sendsig may have been called
  * necessitating a stack cleanup.
@@ -515,42 +645,51 @@ _lev7intr:
        .comm   _ssir,1
        .globl  _astpending
 rei:
        .comm   _ssir,1
        .globl  _astpending
 rei:
-#ifdef DEBUG
+#ifdef STACKCHECK
        tstl    _panicstr               | have we paniced?
        tstl    _panicstr               | have we paniced?
-       jne     Ldorte                  | yes, do not make matters worse
+       jne     Ldorte1                 | yes, do not make matters worse
 #endif
        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
 #endif
        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
-       clrw    sp@-                    | pad SR to longword
+       movw    #PSL_LOWIPL,sr          | lower SPL
+       clrl    sp@-                    | stack adjust
        moveml  #0xFFFF,sp@-            | save all registers
        movl    usp,a1                  | including
        moveml  #0xFFFF,sp@-            | save all registers
        movl    usp,a1                  | including
-       movl    a1,sp@(60)              |    the users SP
+       movl    a1,sp@(FR_SP)           |    the users SP
        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
        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@(60),a0              | restore user SP
+       movl    sp@(FR_SP),a0           | restore user SP
        movl    a0,usp                  |   from save area
        movl    a0,usp                  |   from save area
-       movw    sp@(64),d0              | need to adjust stack?
+       movw    sp@(FR_ADJ),d0          | need to adjust stack?
        jne     Laststkadj              | yes, go to it
        moveml  sp@+,#0x7FFF            | no, restore most user regs
        jne     Laststkadj              | yes, go to it
        moveml  sp@+,#0x7FFF            | no, restore most user regs
-       addql   #6,sp                   | toss SSP and pad
+       addql   #8,sp                   | toss SP and stack adjust
+#ifdef STACKCHECK
+       jra     Ldorte
+#else
        rte                             | and do real RTE
        rte                             | and do real RTE
+#endif
 Laststkadj:
 Laststkadj:
-       lea     sp@(66),a1              | pointer to HW frame
+       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
        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@(60)              | new SSP
+       movl    a0,sp@(FR_SP)           | new SSP
        moveml  sp@+,#0x7FFF            | restore user registers
        movl    sp@,sp                  | and our SP
        moveml  sp@+,#0x7FFF            | restore user registers
        movl    sp@,sp                  | and our SP
-       rte                             | and return
+#ifdef STACKCHECK
+       jra     Ldorte
+#else
+       rte                             | and do real RTE
+#endif
 Lchksir:
        tstb    _ssir                   | SIR pending?
        jeq     Ldorte                  | no, all done
 Lchksir:
        tstb    _ssir                   | SIR pending?
        jeq     Ldorte                  | no, all done
@@ -563,23 +702,63 @@ Lgotsir:
        movw    #SPL1,sr                | prevent others from servicing int
        tstb    _ssir                   | too late?
        jeq     Ldorte                  | yes, oh well...
        movw    #SPL1,sr                | prevent others from servicing int
        tstb    _ssir                   | too late?
        jeq     Ldorte                  | yes, oh well...
-       clrw    sp@-                    | pad SR to longword
+       clrl    sp@-                    | stack adjust
        moveml  #0xFFFF,sp@-            | save all registers
        movl    usp,a1                  | including
        moveml  #0xFFFF,sp@-            | save all registers
        movl    usp,a1                  | including
-       movl    a1,sp@(60)              |    the users SP
+       movl    a1,sp@(FR_SP)           |    the users SP
        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
        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@(60),a0              | restore
+       movl    sp@(FR_SP),a0           | restore
        movl    a0,usp                  |   user SP
        moveml  sp@+,#0x7FFF            | and all remaining registers
        movl    a0,usp                  |   user SP
        moveml  sp@+,#0x7FFF            | and all remaining registers
-       addql   #6,sp                   | pop SSP and align word
+       addql   #8,sp                   | pop SP and stack adjust
+#ifdef STACKCHECK
+       jra     Ldorte
+#else
        rte
        rte
+#endif
 Lnosir:
        movl    sp@+,d0                 | restore scratch register
 Ldorte:
 Lnosir:
        movl    sp@+,d0                 | restore scratch register
 Ldorte:
+#ifdef STACKCHECK
+       movw    #SPL6,sr                | avoid trouble
+       btst    #5,sp@                  | are we returning to user mode?
+       jne     Ldorte1                 | no, skip it
+       movl    a6,tmpstk-20
+       movl    d0,tmpstk-76
+       moveq   #0,d0
+       movb    sp@(6),d0               | get format/vector
+       lsrl    #3,d0                   | convert to index
+       lea     _exframesize,a6         |  into exframesize
+       addl    d0,a6                   |  to get pointer to correct entry
+       movw    a6@,d0                  | get size for this frame
+       addql   #8,d0                   | adjust for unaccounted for bytes
+       lea     _kstackatbase,a6        | desired stack base
+       subl    d0,a6                   |   - frame size == our stack
+       cmpl    a6,sp                   | are we where we think?
+       jeq     Ldorte2                 | yes, skip it
+       lea     tmpstk,a6               | will be using tmpstk
+       movl    sp@(4),a6@-             | copy common
+       movl    sp@,a6@-                |   frame info
+       clrl    a6@-
+       movl    sp,a6@-                 | save sp
+       subql   #4,a6                   | skip over already saved a6
+       moveml  #0x7FFC,a6@-            | push remaining regs (d0/a6/a7 done)
+       lea     a6@(-4),sp              | switch to tmpstk (skip saved d0)
+       clrl    sp@-                    | is an underflow
+       jbsr    _badkstack              | badkstack(0, frame)
+       addql   #4,sp
+       moveml  sp@+,#0x7FFF            | restore most registers
+       movl    sp@,sp                  | and SP
+       rte
+Ldorte2:
+       movl    tmpstk-76,d0
+       movl    tmpstk-20,a6
+Ldorte1:
+#endif
        rte                             | real return
 
 /*
        rte                             | real return
 
 /*
@@ -613,9 +792,15 @@ start:
        movc    d0,vbr                  | XXXX please remove these 2 lines
 /* 
  * a5 contains parameters address from booter.
        movc    d0,vbr                  | XXXX please remove these 2 lines
 /* 
  * a5 contains parameters address from booter.
- * First, we copy parameters to save area.
- * (Now just save maxmem and so on. Not complete yet.) XXXX
+ * First, we copy whole parameters to Kernel InterFace Field
  */
  */
+
+       movl    #KIFF_SIZE,sp@-         | KIFF size
+       pea     _KernInter              | KIFF address
+       pea     a5@                     | bootor's KIFF address
+       jbsr    _bcopy
+       lea     sp@(12),sp              | pop value args
+
        movl    a5@(KI_MAXADDR),d0      | maxaddr
        moveq   #PGSHIFT,d1
        lsrl    d1,d0                   | convert to page (click) number
        movl    a5@(KI_MAXADDR),d0      | maxaddr
        moveq   #PGSHIFT,d1
        lsrl    d1,d0                   | convert to page (click) number
@@ -626,6 +811,28 @@ start:
        movl    #CACHE_OFF,d0
        movc    d0,cacr                 | clear and disable on-chip cache(s)
 
        movl    #CACHE_OFF,d0
        movc    d0,cacr                 | clear and disable on-chip cache(s)
 
+#if defined(LUNA2)
+/* determine our CPU/MMU combo - check for all regardless of kernel config */
+       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 68040(LUNA2)
+       movl    #1,_machineid           | no, must be a LUNA-I
+       movl    #-1,_mmutype            | set to reflect 68030 PMMU
+       jra     Lstart1
+Lnot68030:
+       movl    #2,_machineid           | must be a LUNA-II
+       movl    #-2,_mmutype            | set to reflect 68040 MMU
+#ifdef HPFPLIB
+       movl    #3,_processor           | HP-UX style processor id
+#endif
+Lstart1:
+#endif
+/* set 60 to hz, when running LUNA-I */
+       .globl  _modify_clock_param
+       jbsr    _modify_clock_param
+
 /* initialize source/destination control registers for movs */
        moveq   #FC_USERD,d0            | user space
        movc    d0,sfc                  |   as source
 /* initialize source/destination control registers for movs */
        moveq   #FC_USERD,d0            | user space
        movc    d0,sfc                  |   as source
@@ -634,10 +841,7 @@ start:
 /*
  * LUNA  PIO initialization.
  */
 /*
  * LUNA  PIO initialization.
  */
-       movb    #PIO_MODED,PIO0_CTL     | read dipswitch
-       movb    PIO0_B,d0               | dipsw-2 (from portB)
-       lsll    #8,d0
-       movb    PIO0_A,d0               | dipsw-1 (from portA)
+       movw    PIO0_A,d0               | dipsw-1,2 (from port A&B)
        movw    d0,_dipswitch
 
 /* configure kernel and proc0 VA space so we can get going */
        movw    d0,_dipswitch
 
 /* configure kernel and proc0 VA space so we can get going */
@@ -654,25 +858,48 @@ start:
 /*
  * Prepare to enable MMU.
  */
 /*
  * Prepare to enable MMU.
  */
-       movl    _Sysseg,a1              | system segment table addr read value (a KVA)
+       movl    _Sysseg,d1              | system segment table addr read value (a KVA)
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     Lmotommu1               | no, skip
+       
+       .long   0x4e7b1807              | movc d1,srp
+/* we must set tt-registers here */
+       movl    #0x403FA040,d0          | tt0 for LUNA2 0x40000000-0x7fffffff
+       .long   0x4e7b0004              | movc d0,itt0
+       .long   0x4e7b0006              | movc d0,dtt0
+       movl    #0x807FA040,d0          | tt1 for LUNA2 0x80000000-0xffffffff
+       .long   0x4e7b0005              | movc d0,itt1
+       .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
+Lmotommu1:
+#endif
        lea     _protorp,a0
        movl    #0x80000202,a0@         | nolimit + share global + 4 byte PTEs
        lea     _protorp,a0
        movl    #0x80000202,a0@         | nolimit + share global + 4 byte PTEs
-       movl    a1,a0@(4)               | + segtable address
+       movl    d1,a0@(4)               | + segtable address
        pmove   a0@,srp                 | load the supervisor root pointer
        movl    #0x80000002,a0@         | reinit upper half for CRP loads
 /* we must set tt-registers here */
        pmove   a0@,srp                 | load the supervisor root pointer
        movl    #0x80000002,a0@         | reinit upper half for CRP loads
 /* we must set tt-registers here */
-       lea     _protott0,a0
+       lea     _protott0,a0            | tt0 for LUNA1 0x40000000-0x7fffffff
        .word   0xf010                  | pmove a0@,mmutt0
        .word   0x0800
        .word   0xf010                  | pmove a0@,mmutt0
        .word   0x0800
-       lea     _protott1,a0
+       lea     _protott1,a0            | tt1 for LUNA1 0x80000000-0xffffffff
        .word   0xf010                  | pmove a0@,mmutt1
        .word   0x0c00
        .word   0xf010                  | pmove a0@,mmutt1
        .word   0x0c00
+       lea     _mapping_tc,a2
        movl    #0x82c0aa00,a2@         | value to load TC with
        pmove   a2@,tc                  | load it
 
 /*
  * Should be running mapped from this point on
  */
        movl    #0x82c0aa00,a2@         | value to load TC with
        pmove   a2@,tc                  | load it
 
 /*
  * Should be running mapped from this point on
  */
+Lenab1:
 #ifdef FPCOPROC
 /* fpp check */
        movl    a1,sp@-
 #ifdef FPCOPROC
 /* fpp check */
        movl    a1,sp@-
@@ -683,12 +910,6 @@ start:
 /* select the software page size now */
        lea     tmpstk,sp               | temporary stack
        jbsr    _vm_set_page_size       | select software page size
 /* select the software page size now */
        lea     tmpstk,sp               | temporary stack
        jbsr    _vm_set_page_size       | select software page size
-#ifdef BOOTDEBUG
-       movl    a5,sp@-                 | phys load address (assumes VA 0)
-       movl    a4,sp@-                 | first available PA
-       jbsr    _Opmap_bootstrap        | sync up pmap module
-       addql   #8,sp
-#endif
 /* set kernel stack, user SP, and initial pcb */
        lea     _kstack,a1              | proc0 kernel stack
        lea     a1@(UPAGES*NBPG-4),sp   | set kernel stack to end of area
 /* set kernel stack, user SP, and initial pcb */
        lea     _kstack,a1              | proc0 kernel stack
        lea     a1@(UPAGES*NBPG-4),sp   | set kernel stack to end of area
@@ -696,7 +917,6 @@ start:
        movl    a2,usp                  | init user SP
        movl    _proc0paddr,a1          | get proc0 pcb addr
        movl    a1,_curpcb              | proc0 is running
        movl    a2,usp                  | init user SP
        movl    _proc0paddr,a1          | get proc0 pcb addr
        movl    a1,_curpcb              | proc0 is running
-       clrw    a1@(PCB_FLAGS)          | clear flags
 #ifdef FPCOPROC
        clrl    a1@(PCB_FPCTX)          | ensure null FP context
        movl    a1,sp@-
 #ifdef FPCOPROC
        clrl    a1@(PCB_FPCTX)          | ensure null FP context
        movl    a1,sp@-
@@ -705,21 +925,48 @@ start:
 #endif
 /* flush TLB and turn on caches */
        jbsr    _TBIA                   | invalidate TLB
 #endif
 /* flush TLB and turn on caches */
        jbsr    _TBIA                   | invalidate TLB
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jeq     Lnocache0               | yes, cache already on
+#endif
        movl    #CACHE_ON,d0
        movc    d0,cacr                 | clear cache(s)
        movl    #CACHE_ON,d0
        movc    d0,cacr                 | clear cache(s)
+Lnocache0:
 /* final setup for C code */
        movw    #PSL_LOWIPL,sr          | lower SPL
        movl    d7,_boothowto           | save reboot flags
        movl    d6,_bootdev             |   and boot device
 /* final setup for C code */
        movw    #PSL_LOWIPL,sr          | lower SPL
        movl    d7,_boothowto           | save reboot flags
        movl    d6,_bootdev             |   and boot device
-       jbsr    _main                   | call main()
-
-/* proc[1] == init now running here;
- * create a null exception frame and return to user mode in icode
+/*
+ * Create a fake exception frame that returns to user mode,
+ * make space for the rest of a fake saved register set, and
+ * pass the first available RAM and a pointer to the register
+ * set to "main()".  "main()" will call "icode()", which fakes
+ * an "execve()" system call, which is why we need to do that
+ * ("main()" sets "u.u_ar0" to point to the register set).
+ * When "main()" returns, we're running in process 1 and have
+ * successfully faked the "execve()".  We load up the registers from
+ * that set; the "rte" loads the PC and PSR, which jumps to "init".
  */
  */
-       clrw    sp@-                    | vector offset/frame type
-       clrl    sp@-                    | return to icode location 0
-       movw    #PSL_USER,sp@-          | in user mode
-       rte
+       clrw    sp@-                    | vector offset/frame type
+       clrl    sp@-                    | PC - filled in by "execve"
+       movw    #PSL_USER,sp@-          | in user mode
+       clrw    sp@-                    | pad SR to longword
+       lea     sp@(-64),sp             | construct space for D0-D7/A0-A7
+       pea     sp@                     | addr of space for D0
+       jbsr    _main                   | main(firstaddr, r0)
+       addql   #4,sp                   | pop args
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     Lnoflush                | no, skip
+       .word   0xf478                  | cpusha dc
+       .word   0xf498                  | cinva ic
+Lnoflush:
+#endif
+       movl    sp@(60),a0              | grab and load
+       movl    a0,usp                  |   user SP
+       moveml  sp@+,#0x7FFF            | load most registers (all but SSP)
+       addql   #6,sp                   | pop SSP and align word
+       rte
 
 /*
  * Signal "trampoline" code (18 bytes).  Invoked from RTE setup by sendsig().
 
 /*
  * Signal "trampoline" code (18 bytes).  Invoked from RTE setup by sendsig().
@@ -735,12 +982,13 @@ start:
  *                     .
  *     scp+0-> beginning of signal context frame
  */
  *                     .
  *     scp+0-> beginning of signal context frame
  */
-       .globl  _sigcode, _esigcode
+       .globl  _sigcode, _esigcode, _sigcodetrap
        .data
 _sigcode:
        movl    sp@(12),a0              | signal handler addr   (4 bytes)
        jsr     a0@                     | call signal handler   (2 bytes)
        addql   #4,sp                   | pop signo             (2 bytes)
        .data
 _sigcode:
        movl    sp@(12),a0              | signal handler addr   (4 bytes)
        jsr     a0@                     | call signal handler   (2 bytes)
        addql   #4,sp                   | pop signo             (2 bytes)
+_sigcodetrap:
        trap    #1                      | special syscall entry (2 bytes)
        movl    d0,sp@(4)               | save errno            (4 bytes)
        moveq   #1,d0                   | syscall == exit       (2 bytes)
        trap    #1                      | special syscall entry (2 bytes)
        movl    d0,sp@(4)               | save errno            (4 bytes)
        moveq   #1,d0                   | syscall == exit       (2 bytes)
@@ -748,55 +996,72 @@ _sigcode:
        .align  2
 _esigcode:
 
        .align  2
 _esigcode:
 
-/*
- * Icode is copied out to process 1 to exec init.
- * If the exec fails, process 1 exits.
- */
-       .globl  _icode,_szicode
-       .text
-_icode:
-       clrl    sp@-
-       pea     pc@((argv-.)+2)
-       pea     pc@((init-.)+2)
-       clrl    sp@-
-       moveq   #SYS_execve,d0
-       trap    #0
-       moveq   #SYS_exit,d0
-       trap    #0
-init:
-       .asciz  "/sbin/init"
-       .even
-argv:
-       .long   init+6-_icode           | argv[0] = "init" ("/sbin/init" + 6)
-       .long   eicode-_icode           | argv[1] follows icode after copyout
-       .long   0
-eicode:
-
-_szicode:
-       .long   _szicode-_icode
-
 /*
  * Primitives
  */ 
 
 /*
  * Primitives
  */ 
 
+#ifdef __STDC__
+#define EXPORT(name)           .globl _ ## name; _ ## name:
+#else
+#define EXPORT(name)           .globl _/**/name; _/**/name:
+#endif
 #ifdef GPROF
 #ifdef GPROF
-#define        ENTRY(name) \
-       .globl _/**/name; _/**/name: link a6,#0; jbsr mcount; unlk a6
-#define ALTENTRY(name, rname) \
-       ENTRY(name); jra rname+12
+#if __GNUC__ >= 2
+#define                ENTRY(name)             EXPORT(name) link a6,\#0; jbsr mcount; unlk a6
 #else
 #else
-#define        ENTRY(name) \
-       .globl _/**/name; _/**/name:
-#define ALTENTRY(name, rname) \
-       .globl _/**/name; _/**/name:
+#define                ENTRY(name)             EXPORT(name) link a6,#0; jbsr mcount; unlk a6
 #endif
 #endif
+#define ALTENTRY(name, rname) ENTRY(name); jra rname+12
+#else
+#define                ENTRY(name)             EXPORT(name)
+#define ALTENTRY(name, rname)          ENTRY(name)
+#endif
+
+/*
+ * For gcc2
+ */
+ENTRY(__main)
+       rts
+
+/*
+ * copypage(fromaddr, toaddr)
+ *
+ * Optimized version of bcopy for a single page-aligned NBPG byte copy.
+ */
+ENTRY(copypage)
+       movl    sp@(4),a0               | source address
+       movl    sp@(8),a1               | destination address
+       movl    #NBPG/32,d0             | number of 32 byte chunks
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     Lmlloop                 | no, use movl
+Lm16loop:
+       .long   0xf6209000              | move16 a0@+,a1@+
+       .long   0xf6209000              | move16 a0@+,a1@+
+       subql   #1,d0
+       jne     Lm16loop
+       rts
+#endif
+Lmlloop:
+       movl    a0@+,a1@+
+       movl    a0@+,a1@+
+       movl    a0@+,a1@+
+       movl    a0@+,a1@+
+       movl    a0@+,a1@+
+       movl    a0@+,a1@+
+       movl    a0@+,a1@+
+       movl    a0@+,a1@+
+       subql   #1,d0
+       jne     Lmlloop
+       rts
 
 /*
  * copyinstr(fromaddr, toaddr, maxlength, &lencopied)
  *
  * Copy a null terminated string from the user address space into
  * the kernel address space.
 
 /*
  * copyinstr(fromaddr, toaddr, maxlength, &lencopied)
  *
  * Copy a null terminated string from the user address space into
  * the kernel address space.
- * NOTE: maxlength must be < 64K
+ *
+ * NOTE: maxlength must be < 64K (due to use of DBcc)
  */
 ENTRY(copyinstr)
        movl    _curpcb,a0              | current pcb
  */
 ENTRY(copyinstr)
        movl    _curpcb,a0              | current pcb
@@ -878,7 +1143,8 @@ Lcosflt2:
  *
  * Copy a null terminated string from one point to another in
  * the kernel address space.
  *
  * Copy a null terminated string from one point to another in
  * the kernel address space.
- * NOTE: maxlength must be < 64K
+ *
+ * NOTE: maxlength must be < 64K (due to use of DBcc)
  */
 ENTRY(copystr)
        movl    sp@(4),a0               | a0 = fromaddr
  */
 ENTRY(copystr)
        movl    sp@(4),a0               | a0 = fromaddr
@@ -909,116 +1175,122 @@ Lcsflt2:
        jra     Lcsdone 
 
 /* 
        jra     Lcsdone 
 
 /* 
- * Copyin(from, to, len)
+ * Copyin(from_user, to_kernel, len)
+ * Copyout(from_kernel, to_user, len)
+ *
+ * Copy specified amount of data between kernel and user space.
  *
  *
- * Copy specified amount of data from user space into the kernel.
- * NOTE: len must be < 64K
+ * XXX both use the DBcc instruction which has 16-bit limitation so only
+ * 64k units can be copied, where "unit" is either a byte or a longword
+ * depending on alignment.  To be safe, assume it can copy at most
+ * 64k bytes.  Don't make MAXBSIZE or MAXPHYS larger than 64k without
+ * fixing this code!
  */
 ENTRY(copyin)
  */
 ENTRY(copyin)
+       movl    sp@(12),d0              | get size
+#ifdef MAPPEDCOPY
+       .globl  _mappedcopysize,_mappedcopyin
+       cmpl    _mappedcopysize,d0      | size >= mappedcopysize
+       jcc     _mappedcopyin           | yes, go do it the new way
+#endif
        movl    d2,sp@-                 | scratch register
        movl    _curpcb,a0              | current pcb
        movl    #Lciflt,a0@(PCB_ONFAULT) | set up to catch faults
        movl    d2,sp@-                 | scratch register
        movl    _curpcb,a0              | current pcb
        movl    #Lciflt,a0@(PCB_ONFAULT) | set up to catch faults
-       movl    sp@(16),d2              | check count
+       tstl    d0                      | check count
        jlt     Lciflt                  | negative, error
        jeq     Lcidone                 | zero, done
        movl    sp@(8),a0               | src address
        movl    sp@(12),a1              | dest address
        jlt     Lciflt                  | negative, error
        jeq     Lcidone                 | zero, done
        movl    sp@(8),a0               | src address
        movl    sp@(12),a1              | dest address
-       movl    a0,d0
-       btst    #0,d0                   | src address odd?
+       movl    a0,d2
+       btst    #0,d2                   | src address odd?
        jeq     Lcieven                 | no, go check dest
        movsb   a0@+,d1                 | yes, get a byte
        nop
        movb    d1,a1@+                 | put a byte
        jeq     Lcieven                 | no, go check dest
        movsb   a0@+,d1                 | yes, get a byte
        nop
        movb    d1,a1@+                 | put a byte
-       subql   #1,d2                   | adjust count
+       subql   #1,d0                   | adjust count
        jeq     Lcidone                 | exit if done
 Lcieven:
        jeq     Lcidone                 | exit if done
 Lcieven:
-       movl    a1,d0
-       btst    #0,d0                   | dest address odd?
-       jne     Lcibyte                 | yes, must copy by bytes
-       movl    d2,d0                   | no, get count
-       lsrl    #2,d0                   | convert to longwords
-       jeq     Lcibyte                 | no longwords, copy bytes
-       subql   #1,d0                   | set up for dbf
+       movl    a1,d2
+       btst    #0,d2                   | dest address odd?
+       jne     Lcibloop                | yes, must copy by bytes
+       movl    d0,d2                   | no, get count
+       lsrl    #2,d2                   | convert to longwords
+       jeq     Lcibloop                | no longwords, copy bytes
 Lcilloop:
        movsl   a0@+,d1                 | get a long
        nop
        movl    d1,a1@+                 | put a long
 Lcilloop:
        movsl   a0@+,d1                 | get a long
        nop
        movl    d1,a1@+                 | put a long
-       dbf     d0,Lcilloop             | til done
-       andl    #3,d2                   | what remains
+       subql   #1,d2
+       jne     Lcilloop                | til done
+       andl    #3,d0                   | what remains
        jeq     Lcidone                 | all done
        jeq     Lcidone                 | all done
-Lcibyte:
-       subql   #1,d2                   | set up for dbf
 Lcibloop:
        movsb   a0@+,d1                 | get a byte
        nop
        movb    d1,a1@+                 | put a byte
 Lcibloop:
        movsb   a0@+,d1                 | get a byte
        nop
        movb    d1,a1@+                 | put a byte
-       dbf     d2,Lcibloop             | til done
+       subql   #1,d0
+       jne     Lcibloop                | til done
 Lcidone:
 Lcidone:
-       moveq   #0,d0                   | success
-Lciexit:
        movl    _curpcb,a0              | current pcb
        clrl    a0@(PCB_ONFAULT)        | clear fault catcher
        movl    sp@+,d2                 | restore scratch reg
        rts
 Lciflt:
        moveq   #EFAULT,d0              | got a fault
        movl    _curpcb,a0              | current pcb
        clrl    a0@(PCB_ONFAULT)        | clear fault catcher
        movl    sp@+,d2                 | restore scratch reg
        rts
 Lciflt:
        moveq   #EFAULT,d0              | got a fault
-       jra     Lciexit
+       jra     Lcidone
 
 
-/* 
- * Copyout(from, to, len)
- *
- * Copy specified amount of data from kernel to the user space
- * NOTE: len must be < 64K
- */
 ENTRY(copyout)
 ENTRY(copyout)
+       movl    sp@(12),d0              | get size
+#ifdef MAPPEDCOPY
+       .globl  _mappedcopysize,_mappedcopyout
+       cmpl    _mappedcopysize,d0      | size >= mappedcopysize
+       jcc     _mappedcopyout          | yes, go do it the new way
+#endif
        movl    d2,sp@-                 | scratch register
        movl    _curpcb,a0              | current pcb
        movl    #Lcoflt,a0@(PCB_ONFAULT) | catch faults
        movl    d2,sp@-                 | scratch register
        movl    _curpcb,a0              | current pcb
        movl    #Lcoflt,a0@(PCB_ONFAULT) | catch faults
-       movl    sp@(16),d2              | check count
+       tstl    d0                      | check count
        jlt     Lcoflt                  | negative, error
        jeq     Lcodone                 | zero, done
        movl    sp@(8),a0               | src address
        movl    sp@(12),a1              | dest address
        jlt     Lcoflt                  | negative, error
        jeq     Lcodone                 | zero, done
        movl    sp@(8),a0               | src address
        movl    sp@(12),a1              | dest address
-       movl    a0,d0
-       btst    #0,d0                   | src address odd?
+       movl    a0,d2
+       btst    #0,d2                   | src address odd?
        jeq     Lcoeven                 | no, go check dest
        movb    a0@+,d1                 | yes, get a byte
        movsb   d1,a1@+                 | put a byte
        nop
        jeq     Lcoeven                 | no, go check dest
        movb    a0@+,d1                 | yes, get a byte
        movsb   d1,a1@+                 | put a byte
        nop
-       subql   #1,d2                   | adjust count
+       subql   #1,d0                   | adjust count
        jeq     Lcodone                 | exit if done
 Lcoeven:
        jeq     Lcodone                 | exit if done
 Lcoeven:
-       movl    a1,d0
-       btst    #0,d0                   | dest address odd?
-       jne     Lcobyte                 | yes, must copy by bytes
-       movl    d2,d0                   | no, get count
-       lsrl    #2,d0                   | convert to longwords
-       jeq     Lcobyte                 | no longwords, copy bytes
-       subql   #1,d0                   | set up for dbf
+       movl    a1,d2
+       btst    #0,d2                   | dest address odd?
+       jne     Lcobloop                | yes, must copy by bytes
+       movl    d0,d2                   | no, get count
+       lsrl    #2,d2                   | convert to longwords
+       jeq     Lcobloop                | no longwords, copy bytes
 Lcolloop:
        movl    a0@+,d1                 | get a long
        movsl   d1,a1@+                 | put a long
        nop
 Lcolloop:
        movl    a0@+,d1                 | get a long
        movsl   d1,a1@+                 | put a long
        nop
-       dbf     d0,Lcolloop             | til done
-       andl    #3,d2                   | what remains
+       subql   #1,d2
+       jne     Lcolloop                | til done
+       andl    #3,d0                   | what remains
        jeq     Lcodone                 | all done
        jeq     Lcodone                 | all done
-Lcobyte:
-       subql   #1,d2                   | set up for dbf
 Lcobloop:
        movb    a0@+,d1                 | get a byte
        movsb   d1,a1@+                 | put a byte
        nop
 Lcobloop:
        movb    a0@+,d1                 | get a byte
        movsb   d1,a1@+                 | put a byte
        nop
-       dbf     d2,Lcobloop             | til done
+       subql   #1,d0
+       jne     Lcobloop                | til done
 Lcodone:
 Lcodone:
-       moveq   #0,d0                   | success
-Lcoexit:
        movl    _curpcb,a0              | current pcb
        clrl    a0@(PCB_ONFAULT)        | clear fault catcher
        movl    sp@+,d2                 | restore scratch reg
        rts
 Lcoflt:
        moveq   #EFAULT,d0              | got a fault
        movl    _curpcb,a0              | current pcb
        clrl    a0@(PCB_ONFAULT)        | clear fault catcher
        movl    sp@+,d2                 | restore scratch reg
        rts
 Lcoflt:
        moveq   #EFAULT,d0              | got a fault
-       jra     Lcoexit
+       jra     Lcodone
 
 /*
  * non-local gotos
 
 /*
  * non-local gotos
@@ -1030,15 +1302,6 @@ ENTRY(setjmp)
        moveq   #0,d0           | return 0
        rts
 
        moveq   #0,d0           | return 0
        rts
 
-ENTRY(qsetjmp)
-       movl    sp@(4),a0       | savearea pointer
-       lea     a0@(40),a0      | skip regs we do not save
-       movl    a6,a0@+         | save FP
-       movl    sp,a0@+         | save SP
-       movl    sp@,a0@         | and return address
-       moveq   #0,d0           | return 0
-       rts
-
 ENTRY(longjmp)
        movl    sp@(4),a0
        moveml  a0@+,#0xFCFC
 ENTRY(longjmp)
        movl    sp@(4),a0
        moveml  a0@+,#0xFCFC
@@ -1047,12 +1310,11 @@ ENTRY(longjmp)
        rts
 
 /*
        rts
 
 /*
- * The following primitives manipulate the run queues.
- * _whichqs tells which of the 32 queues _qs
- * have processes in them.  Setrq puts processes into queues, Remrq
- * removes them from queues.  The running process is on no queue,
- * other processes are on a queue related to p->p_pri, divided by 4
- * actually to shrink the 0-127 range of priorities into the 32 available
+ * The following primitives manipulate the run queues.  _whichqs tells which
+ * of the 32 queues _qs have processes in them.  Setrunqueue puts processes
+ * into queues, Remrq removes them from queues.  The running process is on
+ * no queue, other processes are on a queue related to p->p_priority, divided
+ * by 4 actually to shrink the 0-127 range of priorities into the 32 available
  * queues.
  */
 
  * queues.
  */
 
@@ -1060,35 +1322,35 @@ ENTRY(longjmp)
        .globl  _curproc,_want_resched
 
 /*
        .globl  _curproc,_want_resched
 
 /*
- * Setrq(p)
+ * Setrunqueue(p)
  *
  * Call should be made at spl6(), and p->p_stat should be SRUN
  */
  *
  * Call should be made at spl6(), and p->p_stat should be SRUN
  */
-ENTRY(setrq)
+ENTRY(setrunqueue)
        movl    sp@(4),a0
        movl    sp@(4),a0
-       tstl    a0@(P_RLINK)
+       tstl    a0@(P_BACK)
        jeq     Lset1
        movl    #Lset2,sp@-
        jbsr    _panic
 Lset1:
        clrl    d0
        jeq     Lset1
        movl    #Lset2,sp@-
        jbsr    _panic
 Lset1:
        clrl    d0
-       movb    a0@(P_PRI),d0
+       movb    a0@(P_PRIORITY),d0
        lsrb    #2,d0
        movl    _whichqs,d1
        bset    d0,d1
        movl    d1,_whichqs
        lslb    #3,d0
        addl    #_qs,d0
        lsrb    #2,d0
        movl    _whichqs,d1
        bset    d0,d1
        movl    d1,_whichqs
        lslb    #3,d0
        addl    #_qs,d0
-       movl    d0,a0@(P_LINK)
+       movl    d0,a0@(P_FORW)
        movl    d0,a1
        movl    d0,a1
-       movl    a1@(P_RLINK),a0@(P_RLINK)
-       movl    a0,a1@(P_RLINK)
-       movl    a0@(P_RLINK),a1
-       movl    a0,a1@(P_LINK)
+       movl    a1@(P_BACK),a0@(P_BACK)
+       movl    a0,a1@(P_BACK)
+       movl    a0@(P_BACK),a1
+       movl    a0,a1@(P_FORW)
        rts
 
 Lset2:
        rts
 
 Lset2:
-       .asciz  "setrq"
+       .asciz  "setrunqueue"
        .even
 
 /*
        .even
 
 /*
@@ -1099,7 +1361,7 @@ Lset2:
 ENTRY(remrq)
        movl    sp@(4),a0
        clrl    d0
 ENTRY(remrq)
        movl    sp@(4),a0
        clrl    d0
-       movb    a0@(P_PRI),d0
+       movb    a0@(P_PRIORITY),d0
        lsrb    #2,d0
        movl    _whichqs,d1
        bclr    d0,d1
        lsrb    #2,d0
        movl    _whichqs,d1
        bclr    d0,d1
@@ -1108,27 +1370,27 @@ ENTRY(remrq)
        jbsr    _panic
 Lrem1:
        movl    d1,_whichqs
        jbsr    _panic
 Lrem1:
        movl    d1,_whichqs
-       movl    a0@(P_LINK),a1
-       movl    a0@(P_RLINK),a1@(P_RLINK)
-       movl    a0@(P_RLINK),a1
-       movl    a0@(P_LINK),a1@(P_LINK)
+       movl    a0@(P_FORW),a1
+       movl    a0@(P_BACK),a1@(P_BACK)
+       movl    a0@(P_BACK),a1
+       movl    a0@(P_FORW),a1@(P_FORW)
        movl    #_qs,a1
        movl    d0,d1
        lslb    #3,d1
        addl    d1,a1
        movl    #_qs,a1
        movl    d0,d1
        lslb    #3,d1
        addl    d1,a1
-       cmpl    a1@(P_LINK),a1
+       cmpl    a1@(P_FORW),a1
        jeq     Lrem2
        movl    _whichqs,d1
        bset    d0,d1
        movl    d1,_whichqs
 Lrem2:
        jeq     Lrem2
        movl    _whichqs,d1
        bset    d0,d1
        movl    d1,_whichqs
 Lrem2:
-       clrl    a0@(P_RLINK)
+       clrl    a0@(P_BACK)
        rts
 
 Lrem3:
        .asciz  "remrq"
 Lsw0:
        rts
 
 Lrem3:
        .asciz  "remrq"
 Lsw0:
-       .asciz  "swtch"
+       .asciz  "switch"
        .even
 
        .globl  _curpcb
        .even
 
        .globl  _curpcb
@@ -1137,35 +1399,34 @@ Lsw0:
 _masterpaddr:                  | XXX compatibility (debuggers)
 _curpcb:
        .long   0
 _masterpaddr:                  | XXX compatibility (debuggers)
 _curpcb:
        .long   0
-pcbflag:
-       .byte   0               | copy of pcb_flags low byte
+mdpflag:
+       .byte   0               | copy of proc md_flags low byte
        .align  2
        .comm   nullpcb,SIZEOF_PCB
        .text
 
 /*
        .align  2
        .comm   nullpcb,SIZEOF_PCB
        .text
 
 /*
- * At exit of a process, do a swtch for the last time.
+ * At exit of a process, do a switch for the last time.
  * The mapping of the pcb at p->p_addr has already been deleted,
  * and the memory for the pcb+stack has been freed.
  * The ipl is high enough to prevent the memory from being reallocated.
  */
  * The mapping of the pcb at p->p_addr has already been deleted,
  * and the memory for the pcb+stack has been freed.
  * The ipl is high enough to prevent the memory from being reallocated.
  */
-ENTRY(swtch_exit)
+ENTRY(switch_exit)
        movl    #nullpcb,_curpcb        | save state into garbage pcb
        lea     tmpstk,sp               | goto a tmp stack
        movl    #nullpcb,_curpcb        | save state into garbage pcb
        lea     tmpstk,sp               | goto a tmp stack
-       jra     _cpu_swtch
+       jra     _cpu_switch
 
 /*
 
 /*
- * When no processes are on the runq, Swtch branches to idle
+ * When no processes are on the runq, Swtch branches to Idle
  * to wait for something to come ready.
  */
  * to wait for something to come ready.
  */
-       .globl  Idle
-Lidle:
+       .globl  idle
+idle:
        stop    #PSL_LOWIPL
 Idle:
        stop    #PSL_LOWIPL
 Idle:
-idle:
        movw    #PSL_HIGHIPL,sr
        tstl    _whichqs
        movw    #PSL_HIGHIPL,sr
        tstl    _whichqs
-       jeq     Lidle
+       jeq     idle
        movw    #PSL_LOWIPL,sr
        jra     Lsw1
 
        movw    #PSL_LOWIPL,sr
        jra     Lsw1
 
@@ -1175,7 +1436,7 @@ Lbadsw:
        /*NOTREACHED*/
 
 /*
        /*NOTREACHED*/
 
 /*
- * cpu_swtch()
+ * cpu_switch()
  *
  * NOTE: On the mc68851 (318/319/330) we attempt to avoid flushing the
  * entire ATC.  The effort involved in selective flushing may not be
  *
  * NOTE: On the mc68851 (318/319/330) we attempt to avoid flushing the
  * entire ATC.  The effort involved in selective flushing may not be
@@ -1185,7 +1446,7 @@ Lbadsw:
  * user's PTEs have been changed (formerly denoted by the SPTECHG p_flag
  * bit).  For now, we just always flush the full ATC.
  */
  * user's PTEs have been changed (formerly denoted by the SPTECHG p_flag
  * bit).  For now, we just always flush the full ATC.
  */
-ENTRY(cpu_swtch)
+ENTRY(cpu_switch)
        movl    _curpcb,a0              | current pcb
        movw    sr,a0@(PCB_PS)          | save sr before changing ipl
 #ifdef notyet
        movl    _curpcb,a0              | current pcb
        movw    sr,a0@(PCB_PS)          | save sr before changing ipl
 #ifdef notyet
@@ -1208,7 +1469,7 @@ Lswchk:
        addqb   #1,d0
        cmpb    #32,d0
        jne     Lswchk
        addqb   #1,d0
        cmpb    #32,d0
        jne     Lswchk
-       jra     idle
+       jra     Idle
 Lswfnd:
        movw    #PSL_HIGHIPL,sr         | lock out interrupts
        movl    a0@,d1                  | and check again...
 Lswfnd:
        movw    #PSL_HIGHIPL,sr         | lock out interrupts
        movl    a0@,d1                  | and check again...
@@ -1229,13 +1490,13 @@ Lswok:
        lslb    #3,d1                   | convert queue number to index
        addl    #_qs,d1                 | locate queue (q)
        movl    d1,a1
        lslb    #3,d1                   | convert queue number to index
        addl    #_qs,d1                 | locate queue (q)
        movl    d1,a1
-       cmpl    a1@(P_LINK),a1          | anyone on queue?
+       cmpl    a1@(P_FORW),a1          | anyone on queue?
        jeq     Lbadsw                  | no, panic
        jeq     Lbadsw                  | no, panic
-       movl    a1@(P_LINK),a0                  | p = q->p_link
-       movl    a0@(P_LINK),a1@(P_LINK)         | q->p_link = p->p_link
-       movl    a0@(P_LINK),a1                  | q = p->p_link
-       movl    a0@(P_RLINK),a1@(P_RLINK)       | q->p_rlink = p->p_rlink
-       cmpl    a0@(P_LINK),d1          | anyone left on queue?
+       movl    a1@(P_FORW),a0          | p = q->p_forw
+       movl    a0@(P_FORW),a1@(P_FORW) | q->p_forw = p->p_forw
+       movl    a0@(P_FORW),a1          | q = p->p_forw
+       movl    a0@(P_BACK),a1@(P_BACK) | q->p_back = p->p_back
+       cmpl    a0@(P_FORW),d1          | anyone left on queue?
        jeq     Lsw2                    | no, skip
        movl    _whichqs,d1
        bset    d0,d1                   | yes, reset bit
        jeq     Lsw2                    | no, skip
        movl    _whichqs,d1
        bset    d0,d1                   | yes, reset bit
@@ -1271,10 +1532,10 @@ Lswnofpsave:
        cmpb    #SRUN,a0@(P_STAT)
        jne     Lbadsw
 #endif
        cmpb    #SRUN,a0@(P_STAT)
        jne     Lbadsw
 #endif
-       clrl    a0@(P_RLINK)            | clear back link
+       clrl    a0@(P_BACK)             | clear back link
+       movb    a0@(P_MDFLAG+3),mdpflag | low byte of p_md.md_flags
        movl    a0@(P_ADDR),a1          | get p_addr
        movl    a1,_curpcb
        movl    a0@(P_ADDR),a1          | get p_addr
        movl    a1,_curpcb
-       movb    a1@(PCB_FLAGS+1),pcbflag | copy of pcb_flags low byte
 
        /* see if pmap_activate needs to be called; should remove this */
        movl    a0@(P_VMSPACE),a0       | vmspace = p->p_vmspace
 
        /* see if pmap_activate needs to be called; should remove this */
        movl    a0@(P_VMSPACE),a0       | vmspace = p->p_vmspace
@@ -1310,6 +1571,17 @@ Lres1:
        orl     #PG_RW+PG_V,d1          | ensure valid and writable
        movl    d1,a2@+                 | load it up
        dbf     d0,Lres1                | til done
        orl     #PG_RW+PG_V,d1          | ensure valid and writable
        movl    d1,a2@+                 | load it up
        dbf     d0,Lres1                | til done
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     Lres1a                  | no, skip
+       .word   0xf518                  | yes, pflusha
+       movl    a1@(PCB_USTP),d0        | get USTP
+       moveq   #PGSHIFT,d1
+       lsll    d1,d0                   | convert to addr
+       .long   0x4e7b0806              | movc d0,urp
+       jra     Lcxswdone
+Lres1a:
+#endif
        movl    #CACHE_CLR,d0
        movc    d0,cacr                 | invalidate cache(s)
        pflusha                         | flush entire TLB
        movl    #CACHE_CLR,d0
        movc    d0,cacr                 | invalidate cache(s)
        pflusha                         | flush entire TLB
@@ -1319,6 +1591,7 @@ Lres1:
        lea     _protorp,a0             | CRP prototype
        movl    d0,a0@(4)               | stash USTP
        pmove   a0@,crp                 | load new user root pointer
        lea     _protorp,a0             | CRP prototype
        movl    d0,a0@(4)               | stash USTP
        pmove   a0@,crp                 | load new user root pointer
+Lcxswdone:
        moveml  a1@(PCB_REGS),#0xFCFC   | and registers
        movl    a1@(PCB_USP),a0
        movl    a0,usp                  | and USP
        moveml  a1@(PCB_REGS),#0xFCFC   | and registers
        movl    a1@(PCB_USP),a0
        movl    a0,usp                  | and USP
@@ -1326,6 +1599,13 @@ Lres1:
        lea     a1@(PCB_FPCTX),a0       | pointer to FP save area
        tstb    a0@                     | null state frame?
        jeq     Lresfprest              | yes, easy
        lea     a1@(PCB_FPCTX),a0       | pointer to FP save area
        tstb    a0@                     | null state frame?
        jeq     Lresfprest              | yes, easy
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     Lresnot040              | no, skip
+       clrl    sp@-                    | yes...
+       frestore sp@+                   | ...magic!
+Lresnot040:
+#endif
        fmovem  a0@(312),fpcr/fpsr/fpi  | restore FP control registers
        fmovem  a0@(216),fp0-fp7        | restore FP general registers
 Lresfprest:
        fmovem  a0@(312),fpcr/fpsr/fpi  | restore FP control registers
        fmovem  a0@(216),fp0-fp7        | restore FP general registers
 Lresfprest:
@@ -1338,7 +1618,7 @@ Lresfprest:
 /*
  * savectx(pcb, altreturn)
  * Update pcb, saving current processor state and arranging
 /*
  * savectx(pcb, altreturn)
  * Update pcb, saving current processor state and arranging
- * for alternate return ala longjmp in swtch if altreturn is true.
+ * for alternate return ala longjmp in switch if altreturn is true.
  */
 ENTRY(savectx)
        movl    sp@(4),a1
  */
 ENTRY(savectx)
        movl    sp@(4),a1
@@ -1432,6 +1712,13 @@ ENTRY(suiword)
        movsl   d0,a0@                  | do write to user space
        nop
        moveq   #0,d0                   | indicate no fault
        movsl   d0,a0@                  | do write to user space
        nop
        moveq   #0,d0                   | indicate no fault
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     Lsuicpurge              | no, skip
+       .word   0xf498                  | cinva ic (XXX overkill)
+       jra     Lfsdone
+Lsuicpurge:
+#endif
        movl    #IC_CLEAR,d1
        movc    d1,cacr                 | invalidate i-cache
        jra     Lfsdone
        movl    #IC_CLEAR,d1
        movc    d1,cacr                 | invalidate i-cache
        jra     Lfsdone
@@ -1477,11 +1764,46 @@ ENTRY(subyte)
        moveq   #0,d0                   | indicate no fault
        jra     Lfsdone
 
        moveq   #0,d0                   | indicate no fault
        jra     Lfsdone
 
+#if defined(LUNA2)
+ENTRY(suline)
+       movl    sp@(4),a0               | address to write
+       movl    _curpcb,a1              | current pcb
+       movl    #Lslerr,a1@(PCB_ONFAULT) | where to return to on a fault
+       movl    sp@(8),a1               | address of line
+       movl    a1@+,d0                 | get lword
+       movsl   d0,a0@+                 | put lword
+       nop                             | sync
+       movl    a1@+,d0                 | get lword
+       movsl   d0,a0@+                 | put lword
+       nop                             | sync
+       movl    a1@+,d0                 | get lword
+       movsl   d0,a0@+                 | put lword
+       nop                             | sync
+       movl    a1@+,d0                 | get lword
+       movsl   d0,a0@+                 | put lword
+       nop                             | sync
+       moveq   #0,d0                   | indicate no fault
+       jra     Lsldone
+Lslerr:
+       moveq   #-1,d0
+Lsldone:
+       movl    _curpcb,a1              | current pcb
+       clrl    a1@(PCB_ONFAULT)        | clear fault address
+       rts
+#endif
+
 /*
  * Invalidate entire TLB.
  */
 ENTRY(TBIA)
 __TBIA:
 /*
  * Invalidate entire TLB.
  */
 ENTRY(TBIA)
 __TBIA:
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     Lmotommu3               | no, skip
+       .word   0xf518                  | yes, pflusha
+       rts
+Lmotommu3:
+#endif
        pflusha                         | flush entire TLB
        movl    #DC_CLEAR,d0
        movc    d0,cacr                 | invalidate on-chip d-cache
        pflusha                         | flush entire TLB
        movl    #DC_CLEAR,d0
        movc    d0,cacr                 | invalidate on-chip d-cache
@@ -1495,7 +1817,21 @@ ENTRY(TBIS)
        tstl    fulltflush              | being conservative?
        jne     __TBIA                  | yes, flush entire TLB
 #endif
        tstl    fulltflush              | being conservative?
        jne     __TBIA                  | yes, flush entire TLB
 #endif
-
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     Lmotommu4               | no, skip
+       movl    sp@(4),a0
+       movc    dfc,d1
+       moveq   #1,d0                   | user space
+       movc    d0,dfc
+       .word   0xf508                  | pflush a0@
+       moveq   #5,d0                   | super space
+       movc    d0,dfc
+       .word   0xf508                  | pflush a0@
+       movc    d1,dfc
+       rts
+Lmotommu4:
+#endif
        movl    sp@(4),a0               | get addr to flush
        pflush  #0,#0,a0@               | flush address from both sides
        movl    #DC_CLEAR,d0
        movl    sp@(4),a0               | get addr to flush
        pflush  #0,#0,a0@               | flush address from both sides
        movl    #DC_CLEAR,d0
@@ -1509,6 +1845,13 @@ ENTRY(TBIAS)
 #ifdef DEBUG
        tstl    fulltflush              | being conservative?
        jne     __TBIA                  | yes, flush everything
 #ifdef DEBUG
        tstl    fulltflush              | being conservative?
        jne     __TBIA                  | yes, flush everything
+#endif
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     Lmotommu5               | no, skip
+       .word   0xf518                  | yes, pflusha (for now) XXX
+       rts
+Lmotommu5:
 #endif
        pflush #4,#4                    | flush supervisor TLB entries
        movl    #DC_CLEAR,d0
 #endif
        pflush #4,#4                    | flush supervisor TLB entries
        movl    #DC_CLEAR,d0
@@ -1522,6 +1865,13 @@ ENTRY(TBIAU)
 #ifdef DEBUG
        tstl    fulltflush              | being conservative?
        jne     __TBIA                  | yes, flush everything
 #ifdef DEBUG
        tstl    fulltflush              | being conservative?
        jne     __TBIA                  | yes, flush everything
+#endif
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     Lmotommu6               | no, skip
+       .word   0xf518                  | yes, pflusha (for now) XXX
+       rts
+Lmotommu6:
 #endif
        pflush  #0,#4                   | flush user TLB entries
        movl    #DC_CLEAR,d0
 #endif
        pflush  #0,#4                   | flush user TLB entries
        movl    #DC_CLEAR,d0
@@ -1532,15 +1882,110 @@ ENTRY(TBIAU)
  * Invalidate instruction cache
  */
 ENTRY(ICIA)
  * Invalidate instruction cache
  */
 ENTRY(ICIA)
+#if defined(LUNA2)
+ENTRY(ICPA)
+       cmpl    #-2,_mmutype            | 68040
+       jne     Lmotommu7               | no, skip
+       .word   0xf498                  | cinva ic
+       rts
+Lmotommu7:
+#endif
        movl    #IC_CLEAR,d0
        movc    d0,cacr                 | invalidate i-cache
        rts
 
        movl    #IC_CLEAR,d0
        movc    d0,cacr                 | invalidate i-cache
        rts
 
+/*
+ * Invalidate data cache.
+ * NOTE: we do not flush 68030 on-chip cache as there are no aliasing
+ * problems with DC_WA.  The only cases we have to worry about are context
+ * switch and TLB changes, both of which are handled "in-line" in resume
+ * and TBI*.
+ */
+ENTRY(DCIA)
+__DCIA:
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040
+       jne     Lmotommu8               | no, skip
+       /* XXX implement */
+       rts
+Lmotommu8:
+#endif
+       rts
+
+ENTRY(DCIS)
+__DCIS:
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040
+       jne     Lmotommu9               | no, skip
+       /* XXX implement */
+       rts
+Lmotommu9:
+#endif
+       rts
+
+ENTRY(DCIU)
+__DCIU:
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040
+       jne     LmotommuA               | no, skip
+       /* XXX implement */
+       rts
+LmotommuA:
+#endif
+       rts
+
+#if defined(LUNA2)
+ENTRY(ICPL)
+       movl    sp@(4),a0               | address
+       .word   0xf488                  | cinvl ic,a0@
+       rts
+ENTRY(ICPP)
+       movl    sp@(4),a0               | address
+       .word   0xf490                  | cinvp ic,a0@
+       rts
+ENTRY(DCPL)
+       movl    sp@(4),a0               | address
+       .word   0xf448                  | cinvl dc,a0@
+       rts
+ENTRY(DCPP)
+       movl    sp@(4),a0               | address
+       .word   0xf450                  | cinvp dc,a0@
+       rts
+ENTRY(DCPA)
+       .word   0xf458                  | cinva dc
+       rts
+ENTRY(DCFL)
+       movl    sp@(4),a0               | address
+       .word   0xf468                  | cpushl dc,a0@
+       rts
+ENTRY(DCFP)
+       movl    sp@(4),a0               | address
+       .word   0xf470                  | cpushp dc,a0@
+       rts
+#endif
+
 ENTRY(PCIA)
 ENTRY(PCIA)
+#if defined(LUNA2)
+ENTRY(DCFA)
+       cmpl    #-2,_mmutype            | 68040
+       jne     LmotommuB               | no, skip
+       .word   0xf478                  | cpusha dc
+       rts
+LmotommuB:
+#endif
        movl    #DC_CLEAR,d0
        movc    d0,cacr                 | invalidate on-chip d-cache
        rts
 
        movl    #DC_CLEAR,d0
        movc    d0,cacr                 | invalidate on-chip d-cache
        rts
 
+#if 0 /****************************************************************/
+/* external cache control */
+ENTRY(ecacheon)
+       rts
+
+ENTRY(ecacheoff)
+       rts
+#endif /****************************************************************/
+
 /*
  * Get callers current SP value.
  * Note that simply taking the address of a local variable in a C function
 /*
  * Get callers current SP value.
  * Note that simply taking the address of a local variable in a C function
@@ -1568,6 +2013,13 @@ ENTRY(loadustp)
        movl    sp@(4),d0               | new USTP
        moveq   #PGSHIFT,d1
        lsll    d1,d0                   | convert to addr
        movl    sp@(4),d0               | new USTP
        moveq   #PGSHIFT,d1
        lsll    d1,d0                   | convert to addr
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     LmotommuC               | no, skip
+       .long   0x4e7b0806              | movc d0,urp
+       rts
+LmotommuC:
+#endif
        lea     _protorp,a0             | CRP prototype
        movl    d0,a0@(4)               | stash USTP
        pmove   a0@,crp                 | load root pointer
        lea     _protorp,a0             | CRP prototype
        movl    d0,a0@(4)               | stash USTP
        pmove   a0@,crp                 | load root pointer
@@ -1916,6 +2368,30 @@ _fpvec:  movl    a0,a2@(FLINE_VEC)       | restore vectors
 _doboot:
        movl    #0x41000004,a0
        movl    a0@,a1                  | get PROM restart entry address
 _doboot:
        movl    #0x41000004,a0
        movl    a0@,a1                  | get PROM restart entry address
+#if defined(LUNA2)
+       cmpl    #-2,_mmutype            | 68040?
+       jne     LmotommuF               | no, skip
+
+       movw    #PSL_HIGHIPL,sr         | no interrupts
+
+       movl    #0x41000000,a0
+       movl    a0@,d0
+       movc    d0,isp                  | set ISP
+
+       .word   0xf4f8                  | cpusha bc
+       movl    #0,d0
+       movc    d0,cacr                 | caches off
+       movql   #0,d0
+       .long   0x4e7b0004              | movc d0,itt0
+       .long   0x4e7b0005              | movc d0,itt1
+       .long   0x4e7b0006              | movc d0,dtt0
+       .long   0x4e7b0007              | movc d0,dtt1
+
+       .long   0x4e7b0003              | movc d0,tc
+
+       jmp     a1@                     | goto REBOOT
+LmotommuF:
+#endif
        movl    #CACHE_OFF,d0
        movc    d0,cacr                 | disable on-chip cache(s)
        movl    #_tcroff,a0             | value for pmove to TC (turn off MMU)
        movl    #CACHE_OFF,d0
        movc    d0,cacr                 | disable on-chip cache(s)
        movl    #_tcroff,a0             | value for pmove to TC (turn off MMU)
@@ -1923,15 +2399,20 @@ _doboot:
        jmp     a1@                     | goto REBOOT
 
        .data
        jmp     a1@                     | goto REBOOT
 
        .data
-       .space  NBPG
-tmpstk:
+       .globl  _machineid,_mmutype
+_machineid:
+       .long   1               | default to LUNA-I
+_mmutype:
+       .long   -1              | default to 68030 PMMU
        .globl  _protorp,_protott0,_protott1
 _protorp:
        .long   0,0             | prototype root pointer
 _protott0:
        .globl  _protorp,_protott0,_protott1
 _protorp:
        .long   0,0             | prototype root pointer
 _protott0:
-       .long   0x807F8543      | prototype tt0 register (for kernel)
+       .long   0x403f8543      | tt0 (for LUNA1 kernel 0x40000000-0x7fffffff)
 _protott1:
 _protott1:
-       .long   0               | prototype tt0 register (for user)
+       .long   0x807F8543      | tt1 (for LUNA1 kernel 0x80000000-0xffffffff)
+_mapping_tc:
+       .long   0
        .globl  _cold
 _cold:
        .long   1               | cold start flag
        .globl  _cold
 _cold:
        .long   1               | cold start flag
@@ -1957,15 +2438,36 @@ _clock_on:
        .globl  _dipswitch
 _dipswitch:
        .word   0               | dipsw(front panel) value
        .globl  _dipswitch
 _dipswitch:
        .word   0               | dipsw(front panel) value
+       .globl  _KernInter
+_KernInter:                    | Kernel InterFace Field
+       .space  KIFF_SIZE
 #ifdef DEBUG
        .globl  fulltflush, fullcflush
 fulltflush:
        .long   0
 fullcflush:
        .long   0
 #ifdef DEBUG
        .globl  fulltflush, fullcflush
 fulltflush:
        .long   0
 fullcflush:
        .long   0
-       .globl  timebomb
-timebomb:
+#endif
+#ifdef HPFPLIB
+/*
+ * Undefined symbols from hpux_float.o:
+ *
+ * kdb_printf: A kernel debugger print routine, we just use printf instead.
+ * processor:  HP-UX equiv. of machineid, set to 3 if it is a 68040.
+ * u:          Ye ole u-area.  The code wants to grab the first longword
+ *             indirect off of that and clear the 0x40000 bit there.
+ *             Oddly enough this was incorrect even in HP-UX!
+ * runrun:     Old name for want_resched.
+ */
+       .globl  _kdb_printf,_processor,_u,_runrun
+_kdb_printf:
+       .long   _printf
+_processor:
+       .long   0
+_u:
+       .long   .+4
        .long   0
        .long   0
+       .set    _runrun,_want_resched
 #endif
 /* interrupt counters */
        .globl  _intrcnt,_eintrcnt,_intrnames,_eintrnames
 #endif
 /* interrupt counters */
        .globl  _intrcnt,_eintrcnt,_intrnames,_eintrnames