Module Name:    src
Committed By:   tsutsui
Date:           Fri Jan 31 18:24:03 UTC 2014

Modified Files:
        src/sys/arch/x68k/x68k: locore.s

Log Message:
Move the startup routine to the beginning of the source as other m68k ports.

No particular comments on port-x68k@.


To generate a diff of this commit:
cvs rdiff -u -r1.111 -r1.112 src/sys/arch/x68k/x68k/locore.s

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x68k/x68k/locore.s
diff -u src/sys/arch/x68k/x68k/locore.s:1.111 src/sys/arch/x68k/x68k/locore.s:1.112
--- src/sys/arch/x68k/x68k/locore.s:1.111	Sun Oct 27 02:06:06 2013
+++ src/sys/arch/x68k/x68k/locore.s	Fri Jan 31 18:24:03 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.s,v 1.111 2013/10/27 02:06:06 tsutsui Exp $	*/
+/*	$NetBSD: locore.s,v 1.112 2014/01/31 18:24:03 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1988 University of Utah.
@@ -82,6 +82,278 @@ ASLOCAL(tmpstk)
 	/* NOTREACHED */
 
 /*
+ * Macro to relocate a symbol, used before MMU is enabled.
+ */
+#define	_RELOC(var, ar)	\
+	lea	var,ar;	\
+	addl	%a5,ar
+
+#define	RELOC(var, ar)		_RELOC(_C_LABEL(var), ar)
+#define	ASRELOC(var, ar)	_RELOC(_ASM_LABEL(var), ar)
+
+/*
+ * Initialization
+ *
+ * A4 contains the address of the end of the symtab
+ * A5 contains physical load point from boot
+ * VBR contains zero from ROM.  Exceptions will continue to vector
+ * through ROM until MMU is turned on at which time they will vector
+ * through our table (vectors.s).
+ */
+BSS(lowram,4)
+BSS(esym,4)
+
+GLOBAL(_verspad)
+	.word	0
+GLOBAL(boot_version)
+	.word	X68K_BOOTIF_VERS
+
+ASENTRY_NOPROFILE(start)
+	movw	#PSL_HIGHIPL,%sr	| no interrupts
+
+	addql	#4,%sp
+	movel	%sp@+,%a5		| firstpa
+	movel	%sp@+,%d5		| fphysize -- last page
+	movel	%sp@,%a4		| esym
+
+	RELOC(vectab,%a0)		| set Vector Base Register temporaly
+	movc	%a0,%vbr
+
+#if 0	/* XXX this should be done by the boot loader */
+	RELOC(edata, %a0)		| clear out BSS
+	movl	#_C_LABEL(end)-4,%d0	| (must be <= 256 kB)
+	subl	#_C_LABEL(edata),%d0
+	lsrl	#2,%d0
+1:	clrl	%a0@+
+	dbra	%d0,1b
+#endif
+
+	ASRELOC(tmpstk, %a0)
+	movl	%a0,%sp			| give ourselves a temporary stack
+	RELOC(esym, %a0)
+#if 1
+	movl	%a4,%a0@		| store end of symbol table
+#else
+	clrl	%a0@			| no symbol table, yet
+#endif
+	RELOC(lowram, %a0)
+	movl	%a5,%a0@		| store start of physical memory
+
+	movl	#CACHE_OFF,%d0
+	movc	%d0,%cacr		| clear and disable on-chip cache(s)
+
+/* 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 68020/68040/68060
+	jra	Lstart1			| no, we have 68030
+Lnot68030:
+	bset	#31,%d0			| data cache enable bit
+	movc	%d0,%cacr		|   only exists on 68040/68060
+	movc	%cacr,%d0		| read it back
+	tstl	%d0			| zero?
+	jeq	Lis68020		| yes, we have 68020
+	moveq	#0,%d0			| now turn it back off
+	movec	%d0,%cacr		|   before we access any data
+	.word	0xf4d8			| cinva bc - invalidate caches XXX
+	bset	#30,%d0			| data cache no allocate mode bit
+	movc	%d0,%cacr		|   only exists on 68060
+	movc	%cacr,%d0		| read it back
+	tstl	%d0			| zero?
+	jeq	Lis68040		| yes, we have 68040
+	RELOC(mmutype, %a0)		| no, we have 68060
+	movl	#MMU_68040,%a0@		| with a 68040 compatible MMU
+	RELOC(cputype, %a0)
+	movl	#CPU_68060,%a0@		| and a 68060 CPU
+	jra	Lstart1
+Lis68040:
+	RELOC(mmutype, %a0)
+	movl	#MMU_68040,%a0@		| with a 68040 MMU
+	RELOC(cputype, %a0)
+	movl	#CPU_68040,%a0@		| and a 68040 CPU
+	jra	Lstart1
+Lis68020:
+	RELOC(mmutype, %a0)
+	movl	#MMU_68851,%a0@		| we have PMMU
+	RELOC(cputype, %a0)
+	movl	#CPU_68020,%a0@		| and a 68020 CPU
+
+Lstart1:
+/* initialize source/destination control registers for movs */
+	moveq	#FC_USERD,%d0		| user space
+	movc	%d0,%sfc		|   as source
+	movc	%d0,%dfc		|   and destination of transfers
+/* initialize memory sizes (for pmap_bootstrap) */
+	movl	%d5,%d1			| last page
+	moveq	#PGSHIFT,%d2
+	lsrl	%d2,%d1			| convert to page (click) number
+	RELOC(maxmem, %a0)
+	movl	%d1,%a0@		| save as maxmem
+	movl	%a5,%d0			| lowram value from ROM via boot
+	lsrl	%d2,%d0			| convert to page number
+	subl	%d0,%d1			| compute amount of RAM present
+	RELOC(physmem, %a0)
+	movl	%d1,%a0@		| and physmem
+/* configure kernel and lwp0 VA space so we can get going */
+#if NKSYMS || defined(DDB) || defined(LKM)
+	RELOC(esym,%a0)			| end of static kernel test/data/syms
+	movl	%a0@,%d5
+	jne	Lstart2
+#endif
+	movl	#_C_LABEL(end),%d5	| end of static kernel text/data
+Lstart2:
+	RELOC(setmemrange,%a0)		| call setmemrange()
+	jbsr	%a0@			|  to probe all memory regions
+	addl	#PAGE_SIZE-1,%d5
+	andl	#PG_FRAME,%d5		| round to a page
+	movl	%d5,%a4
+	addl	%a5,%a4			| convert to PA
+	pea	%a5@			| firstpa
+	pea	%a4@			| nextpa
+	RELOC(pmap_bootstrap,%a0)
+	jbsr	%a0@			| pmap_bootstrap(firstpa, nextpa)
+	addql	#8,%sp
+
+/*
+ * Prepare to enable MMU.
+ * Since the kernel is mapped logical == physical, we just turn it on.
+ */
+	RELOC(Sysseg_pa, %a0)		| system segment table addr
+	movl	%a0@,%d1		| read value (a PA)
+	RELOC(mmutype, %a0)
+	cmpl	#MMU_68040,%a0@		| 68040?
+	jne	Lmotommu1		| no, skip
+	.long	0x4e7b1807		| movc d1,srp
+	jra	Lstploaddone
+Lmotommu1:
+	RELOC(protorp, %a0)
+	movl	#0x80000202,%a0@	| nolimit + share global + 4 byte PTEs
+	movl	%d1,%a0@(4)		| + segtable address
+	pmove	%a0@,%srp		| load the supervisor root pointer
+	movl	#0x80000002,%a0@	| reinit upper half for CRP loads
+Lstploaddone:
+	RELOC(mmutype, %a0)
+	cmpl	#MMU_68040,%a0@		| 68040?
+	jne	Lmotommu2		| no, skip
+#include "opt_jupiter.h"
+#ifdef JUPITER
+	/* JUPITER-X: set system register "SUPER" bit */
+	movl	#0x0200a240,%d0		| translate DRAM area transparently
+	.long	0x4e7b0006		| movc d0,dtt0
+	lea	0x00c00000,%a0		| a0: graphic VRAM
+	lea	0x02c00000,%a1		| a1: graphic VRAM ( not JUPITER-X )
+					|     DRAM ( JUPITER-X )
+	movw	%a0@,%d0
+	movw	%d0,%d1
+	notw	%d1
+	movw	%d1,%a1@
+	movw	%d0,%a0@
+	cmpw	%a1@,%d1		| JUPITER-X?
+	jne	Ljupiterdone		| no, skip
+	movl	#0x0100a240,%d0		| to access system register
+	.long	0x4e7b0006		| movc d0,dtt0
+	movb	#0x01,0x01800003	| set "SUPER" bit
+Ljupiterdone:
+#endif /* JUPITER */
+	moveq	#0,%d0			| ensure TT regs are disabled
+	.long	0x4e7b0004		| movc d0,itt0
+	.long	0x4e7b0005		| movc d0,itt1
+	.long	0x4e7b0006		| movc d0,dtt0
+	.long	0x4e7b0007		| movc d0,dtt1
+	.word	0xf4d8			| cinva bc
+	.word	0xf518			| pflusha
+#if PGSHIFT == 13
+	movl	#0xc000,%d0
+#else
+	movl	#0x8000,%d0
+#endif
+	.long	0x4e7b0003		| movc d0,tc
+#ifdef M68060
+	RELOC(cputype, %a0)
+	cmpl	#CPU_68060,%a0@		| 68060?
+	jne	Lnot060cache
+	movl	#1,%d0
+	.long	0x4e7b0808		| movcl d0,pcr
+	movl	#0xa0808000,%d0
+	movc	%d0,%cacr		| enable store buffer, both caches
+	jmp	Lenab1
+Lnot060cache:
+#endif
+	movl	#0x80008000,%d0
+	movc	%d0,%cacr		| turn on both caches
+	jmp	Lenab1
+Lmotommu2:
+	pflusha
+#if PGSHIFT == 13
+	movl	#0x82d08b00,%sp@-	| value to load TC with
+#else
+	movl	#0x82c0aa00,%sp@-	| value to load TC with
+#endif
+	pmove	%sp@,%tc		| load it
+
+/*
+ * Should be running mapped from this point on
+ */
+Lenab1:
+/* set vector base in virtual address */
+	movl	#_C_LABEL(vectab),%d0	| set Vector Base Register
+	movc	%d0,%vbr
+	lea	_ASM_LABEL(tmpstk),%sp	| temporary stack
+/* call final pmap setup */
+	jbsr	_C_LABEL(pmap_bootstrap_finalize)
+/* set kernel stack, user SP */
+	movl	_C_LABEL(lwp0uarea),%a1	| grab lwp0 uarea
+	lea	%a1@(USPACE-4),%sp	| set kernel stack to end of area  
+	movl	#USRSTACK-4,%a2
+	movl	%a2,%usp		| init user SP
+
+/* detect FPU type */
+	jbsr	_C_LABEL(fpu_probe)
+	movl	%d0,_C_LABEL(fputype)
+	tstl	_C_LABEL(fputype)	| Have an FPU?
+	jeq	Lenab2			| No, skip.
+	clrl	%a1@(PCB_FPCTX)		| ensure null FP context
+	movl	%a1,%sp@-
+	jbsr	_C_LABEL(m68881_restore) | restore it (does not kill a1)
+	addql	#4,%sp
+Lenab2:
+	cmpl	#MMU_68040,_C_LABEL(mmutype)	| 68040?
+	jeq	Ltbia040		| yes, cache already on
+	pflusha
+	tstl	_C_LABEL(mmutype)
+	jpl	Lenab3			| 68851 implies no d-cache
+	movl	#CACHE_ON,%d0
+	movc	%d0,%cacr		| clear cache(s)
+	jra	Lenab3
+Ltbia040:
+	.word	0xf518
+Lenab3:
+/* final setup for C code */
+	movl	%d7,_C_LABEL(boothowto)	| save reboot flags
+	movl	%d6,_C_LABEL(bootdev)	|   and boot device
+	jbsr	_C_LABEL(x68k_init)	| additional pre-main initialization
+
+/*
+ * Create a fake exception frame so that cpu_lwp_fork() can copy it.
+ * main() nevers returns; we exit to user mode from a forked process
+ * later on.
+ */
+	clrw	%sp@-			| vector offset/frame type
+	clrl	%sp@-			| PC - filled in by "execve"
+	movw	#PSL_USER,%sp@-		| in user mode
+	clrl	%sp@-			| stack adjust count and padding
+	lea	%sp@(-64),%sp		| construct space for D0-D7/A0-A7
+	lea	_C_LABEL(lwp0),%a0	| save pointer to frame
+	movl	%sp,%a0@(L_MD_REGS)	|   in lwp0.p_md.md_regs
+
+	jra	_C_LABEL(main)		| main()
+
+	PANIC("main() returned")	| Yow!  Main returned!
+	/* NOTREACHED */
+
+/*
  * Trap/interrupt vector routines
  */
 #include <m68k/m68k/trap_subr.s>
@@ -242,689 +514,417 @@ Lisaerr:
 	movl	#T_ADDRERR,%sp@-	| mark address error
 	jra	_ASM_LABEL(faultstkadj)	| and deal with it
 Lisberr1:
-	clrw	%sp@			| re-clear pad word
-Lisberr:
-	movl	#T_BUSERR,%sp@-		| mark bus error
-	jra	_ASM_LABEL(faultstkadj)	| and deal with it
-
-/*
- * FP exceptions.
- */
-#include "opt_fpu_emulate.h"
-ENTRY_NOPROFILE(fpfline)
-#if defined(M68040)
-	cmpl	#FPU_68040,_C_LABEL(fputype) | 68040 FPU?
-	jne	Lfp_unimp		| no, skip FPSP
-	cmpw	#0x202c,%sp@(6)		| format type 2?
-	jne	_C_LABEL(illinst)	| no, not an FP emulation
-#ifdef FPSP
-	jmp	_ASM_LABEL(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	_ASM_LABEL(fault)	| do it
-#endif
-Lfp_unimp:
-#endif
-#ifdef FPU_EMULATE
-	clrl	%sp@-			| stack adjust count
-	moveml	#0xFFFF,%sp@-		| save registers
-	moveq	#T_FPEMULD,%d0		| denote as FP emulation trap
-	jra	_ASM_LABEL(fault)	| do it
-#else
-	jra	_C_LABEL(illinst)
-#endif
-
-ENTRY_NOPROFILE(fpunsupp)
-#if defined(M68040)
-	cmpl	#FPU_68040,_C_LABEL(fputype) | 68040?
-	jne	Lfp_unsupp		| no, skip FPSP
-#ifdef FPSP
-	jmp	_ASM_LABEL(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	_ASM_LABEL(fault)	| do it
-#endif
-Lfp_unsupp:
-#endif
-#ifdef FPU_EMULATE
-	clrl	%sp@-			| stack adjust count
-	moveml	#0xFFFF,%sp@-		| save registers
-	moveq	#T_FPEMULD,%d0		| denote as FP emulation trap
-	jra	_ASM_LABEL(fault)	| do it
-#else
-	jra	_C_LABEL(illinst)
-#endif
-
-/*
- * Handles all other FP coprocessor exceptions.
- * Note that since some FP exceptions generate mid-instruction frames
- * and may cause signal delivery, we need to test for stack adjustment
- * after the trap call.
- */
-ENTRY_NOPROFILE(fpfault)
-	clrl	%sp@-		| stack adjust count
-	moveml	#0xFFFF,%sp@-	| save user registers
-	movl	%usp,%a0	| and save
-	movl	%a0,%sp@(FR_SP)	|   the user stack pointer
-	clrl	%sp@-		| no VA arg
-	movl	_C_LABEL(curpcb),%a0 | current pcb
-	lea	%a0@(PCB_FPCTX),%a0 | address of FP savearea
-	fsave	%a0@		| save state
-#if defined(M68040) || defined(M68060)
-	/* always null state frame on 68040, 68060 */
-	cmpl	#FPU_68040,_C_LABEL(fputype)
-	jge	Lfptnull
-#endif
-	tstb	%a0@		| null state frame?
-	jeq	Lfptnull	| yes, safe
-	clrw	%d0		| no, need to tweak BIU
-	movb	%a0@(1),%d0	| get frame size
-	bset	#3,%a0@(0,%d0:w) | set exc_pend bit of BIU
-Lfptnull:
-	fmovem	%fpsr,%sp@-	| push fpsr as code argument
-	frestore %a0@		| restore state
-	movl	#T_FPERR,%sp@-	| push type arg
-	jra	_ASM_LABEL(faultstkadj)	| call trap and deal with stack cleanup
-
-/*
- * Other exceptions only cause four and six word stack frame and require
- * no post-trap stack adjustment.
- */
-
-ENTRY_NOPROFILE(badtrap)
-	moveml	#0xC0C0,%sp@-		| save scratch regs
-	movw	%sp@(22),%sp@-		| push exception vector info
-	clrw	%sp@-
-	movl	%sp@(22),%sp@-		| and PC
-	jbsr	_C_LABEL(straytrap)	| report
-	addql	#8,%sp			| pop args
-	moveml	%sp@+,#0x0303		| restore regs
-	jra	_ASM_LABEL(rei)		| all done
-
-ENTRY_NOPROFILE(trap0)
-	clrl	%sp@-			| stack adjust count
-	moveml	#0xFFFF,%sp@-		| save user registers
-	movl	%usp,%a0		| save the user SP
-	movl	%a0,%sp@(FR_SP)		|   in the savearea
-	movl	%d0,%sp@-		| push syscall number
-	jbsr	_C_LABEL(syscall)	| handle it
-	addql	#4,%sp			| pop syscall arg
-	tstl	_C_LABEL(astpending)
-	jne	Lrei2
-	tstb	_C_LABEL(ssir)
-	jeq	Ltrap1
-	movw	#SPL1,%sr
-	tstb	_C_LABEL(ssir)
-	jne	Lsir1
-Ltrap1:
-	movl	%sp@(FR_SP),%a0		| grab and restore
-	movl	%a0,%usp		|   user SP
-	moveml	%sp@+,#0x7FFF		| restore most registers
-	addql	#8,%sp			| pop SP and stack adjust
-	rte
-
-/*
- * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD)
- *	cachectl(command, addr, length)
- * command in d0, addr in a1, length in d1
- */
-ENTRY_NOPROFILE(trap12)
-	movl	_C_LABEL(curlwp),%a0
-	movl	%a0@(L_PROC),%sp@-	| push curproc pointer
-	movl	%d1,%sp@-		| push length
-	movl	%a1,%sp@-		| push addr
-	movl	%d0,%sp@-		| push command
-	jbsr	_C_LABEL(cachectl1)	| do it
-	lea	%sp@(16),%sp		| pop args
-	jra	_ASM_LABEL(rei)		| all done
-
-/*
- * Trace (single-step) trap.  Kernel-mode is special.
- * User mode traps are simply passed on to trap().
- */
-ENTRY_NOPROFILE(trace)
-	clrl	%sp@-			| stack adjust count
-	moveml	#0xFFFF,%sp@-
-	moveq	#T_TRACE,%d0
-
-	| Check PSW and see what happen.
-	|   T=0 S=0	(should not happen)
-	|   T=1 S=0	trace trap from user mode
-	|   T=0 S=1	trace trap on a trap instruction
-	|   T=1 S=1	trace trap from system mode (kernel breakpoint)
-
-	movw	%sp@(FR_HW),%d1		| get PSW
-	notw	%d1			| XXX no support for T0 on 680[234]0
-	andw	#PSL_TS,%d1		| from system mode (T=1, S=1)?
-	jeq	Lkbrkpt			| yes, kernel breakpoint
-	jra	_ASM_LABEL(fault)	| no, user-mode fault
-
-/*
- * Trap 15 is used for:
- *	- GDB breakpoints (in user programs)
- *	- KGDB breakpoints (in the kernel)
- *	- trace traps for SUN binaries (not fully supported yet)
- * User mode traps are simply passed to trap().
- */
-ENTRY_NOPROFILE(trap15)
-	clrl	%sp@-			| stack adjust count
-	moveml	#0xFFFF,%sp@-
-	moveq	#T_TRAP15,%d0
-	movw	%sp@(FR_HW),%d1		| get PSW
-	andw	#PSL_S,%d1		| from system mode?
-	jne	Lkbrkpt			| yes, kernel breakpoint
-	jra	_ASM_LABEL(fault)	| no, user-mode fault
-
-Lkbrkpt: | Kernel-mode breakpoint or trace trap. (d0=trap_type)
-	| Save the system sp rather than the user sp.
-	movw	#PSL_HIGHIPL,%sr	| lock out interrupts
-	lea	%sp@(FR_SIZE),%a6	| Save stack pointer
-	movl	%a6,%sp@(FR_SP)		|  from before trap
-
-	| If were are not on tmpstk switch to it.
-	| (so debugger can change the stack pointer)
-	movl	%a6,%d1
-	cmpl	#_ASM_LABEL(tmpstk),%d1
-	jls	Lbrkpt2			| already on tmpstk
-	| Copy frame to the temporary stack
-	movl	%sp,%a0			| a0=src
-	lea	_ASM_LABEL(tmpstk)-96,%a1 | a1=dst
-	movl	%a1,%sp			| sp=new frame
-	moveq	#FR_SIZE,%d1
-Lbrkpt1:
-	movl	%a0@+,%a1@+
-	subql	#4,%d1
-	jgt	Lbrkpt1
-
-Lbrkpt2:
-	| Call the trap handler for the kernel debugger.
-	| Do not call trap() to do it, so that we can
-	| set breakpoints in trap() if we want.  We know
-	| the trap type is either T_TRACE or T_BREAKPOINT.
-	| If we have both DDB and KGDB, let KGDB see it first,
-	| because KGDB will just return 0 if not connected.
-	| Save args in d2, a2
-	movl	%d0,%d2			| trap type
-	movl	%sp,%a2			| frame ptr
-#ifdef KGDB
-	| Let KGDB handle it (if connected)
-	movl	%a2,%sp@-		| push frame ptr
-	movl	%d2,%sp@-		| push trap type
-	jbsr	_C_LABEL(kgdb_trap)	| handle the trap
-	addql	#8,%sp			| pop args
-	cmpl	#0,%d0			| did kgdb handle it?
-	jne	Lbrkpt3			| yes, done
-#endif
-#ifdef DDB
-	| Let DDB handle it
-	movl	%a2,%sp@-		| push frame ptr
-	movl	%d2,%sp@-		| push trap type
-	jbsr	_C_LABEL(kdb_trap)	| handle the trap
-	addql	#8,%sp			| pop args
-#if 0	/* not needed on hp300 */
-	cmpl	#0,%d0			| did ddb handle it?
-	jne	Lbrkpt3			| yes, done
-#endif
-#endif
-	/* Sun 3 drops into PROM here. */
-Lbrkpt3:
-	| The stack pointer may have been modified, or
-	| data below it modified (by kgdb push call),
-	| so push the hardware frame at the current sp
-	| before restoring registers and returning.
-
-	movl	%sp@(FR_SP),%a0		| modified sp
-	lea	%sp@(FR_SIZE),%a1	| end of our frame
-	movl	%a1@-,%a0@-		| copy 2 longs with
-	movl	%a1@-,%a0@-		| ... predecrement
-	movl	%a0,%sp@(FR_SP)		| sp = h/w frame
-	moveml	%sp@+,#0x7FFF		| restore all but sp
-	movl	%sp@,%sp		| ... and sp
-	rte				| all done
-
-/* Use common m68k sigreturn */
-#include <m68k/m68k/sigreturn.s>
+	clrw	%sp@			| re-clear pad word
+Lisberr:
+	movl	#T_BUSERR,%sp@-		| mark bus error
+	jra	_ASM_LABEL(faultstkadj)	| and deal with it
 
 /*
- * Provide a generic interrupt dispatcher, only handle hardclock (int6)
- * specially, to improve performance
+ * FP exceptions.
  */
+#include "opt_fpu_emulate.h"
+ENTRY_NOPROFILE(fpfline)
+#if defined(M68040)
+	cmpl	#FPU_68040,_C_LABEL(fputype) | 68040 FPU?
+	jne	Lfp_unimp		| no, skip FPSP
+	cmpw	#0x202c,%sp@(6)		| format type 2?
+	jne	_C_LABEL(illinst)	| no, not an FP emulation
+#ifdef FPSP
+	jmp	_ASM_LABEL(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	_ASM_LABEL(fault)	| do it
+#endif
+Lfp_unimp:
+#endif
+#ifdef FPU_EMULATE
+	clrl	%sp@-			| stack adjust count
+	moveml	#0xFFFF,%sp@-		| save registers
+	moveq	#T_FPEMULD,%d0		| denote as FP emulation trap
+	jra	_ASM_LABEL(fault)	| do it
+#else
+	jra	_C_LABEL(illinst)
+#endif
 
-ENTRY_NOPROFILE(spurintr)	/* level 0 */
-	addql	#1,_C_LABEL(intrcnt)+0
-	INTERRUPT_SAVEREG
-	CPUINFO_INCREMENT(CI_NINTR)
-	INTERRUPT_RESTOREREG
-	rte				| XXX mfpcure (x680x0 hardware bug)
-
-ENTRY_NOPROFILE(kbdtimer)
-	rte
-
-ENTRY_NOPROFILE(intiotrap)
-	addql	#1,_C_LABEL(idepth)
-	INTERRUPT_SAVEREG
-	pea	%sp@(16-(FR_HW))	| XXX
-	jbsr	_C_LABEL(intio_intr)
-	addql	#4,%sp
-	CPUINFO_INCREMENT(CI_NINTR)
-	INTERRUPT_RESTOREREG
-	subql	#1,_C_LABEL(idepth)
-	jra	rei
-
-ENTRY_NOPROFILE(lev1intr)
-ENTRY_NOPROFILE(lev2intr)
-ENTRY_NOPROFILE(lev3intr)
-ENTRY_NOPROFILE(lev4intr)
-ENTRY_NOPROFILE(lev5intr)
-ENTRY_NOPROFILE(lev6intr)
-	addql	#1,_C_LABEL(idepth)
-	INTERRUPT_SAVEREG
-Lnotdma:
-	lea	_C_LABEL(intrcnt),%a0
-	movw	%sp@(22),%d0		| use vector offset
-	andw	#0xfff,%d0		|   sans frame type
-	addql	#1,%a0@(-0x60,%d0:w)	|     to increment apropos counter
-	movw	%sr,%sp@-		| push current SR value
-	clrw	%sp@-			|    padded to longword
-	jbsr	_C_LABEL(intrhand)	| handle interrupt
-	addql	#4,%sp			| pop SR
-	CPUINFO_INCREMENT(CI_NINTR)
-	INTERRUPT_RESTOREREG
-	subql	#1,_C_LABEL(idepth)
-	jra	_ASM_LABEL(rei)
-
-ENTRY_NOPROFILE(timertrap)
-	addql	#1,_C_LABEL(idepth)
-	INTERRUPT_SAVEREG		| save scratch registers
-	addql	#1,_C_LABEL(intrcnt)+32	| count hardclock interrupts
-	lea	%sp@(16),%a1		| a1 = &clockframe
-	movl	%a1,%sp@-
-	jbsr	_C_LABEL(hardclock)	| hardclock(&frame)
-	addql	#4,%sp
-	CPUINFO_INCREMENT(CI_NINTR)	| chalk up another interrupt
-	INTERRUPT_RESTOREREG		| restore scratch registers
-	subql	#1,_C_LABEL(idepth)
-	jra	_ASM_LABEL(rei)		| all done
-
-ENTRY_NOPROFILE(lev7intr)
-	addql	#1,_C_LABEL(idepth)
-	addql	#1,_C_LABEL(intrcnt)+28
-	clrl	%sp@-
+ENTRY_NOPROFILE(fpunsupp)
+#if defined(M68040)
+	cmpl	#FPU_68040,_C_LABEL(fputype) | 68040?
+	jne	Lfp_unsupp		| no, skip FPSP
+#ifdef FPSP
+	jmp	_ASM_LABEL(fpsp_unsupp)	| yes, go handle it
+#else
+	clrl	%sp@-			| stack adjust count
 	moveml	#0xFFFF,%sp@-		| save registers
-	movl	%usp,%a0		| and save
-	movl	%a0,%sp@(FR_SP)		|   the user stack pointer
-	jbsr	_C_LABEL(nmihand)	| call handler
-	movl	%sp@(FR_SP),%a0		| restore
-	movl	%a0,%usp		|   user SP
-	moveml	%sp@+,#0x7FFF		| and remaining registers
-	addql	#8,%sp			| pop SP and stack adjust
-	subql	#1,_C_LABEL(idepth)
-	jra	_ASM_LABEL(rei)		| all done
+	moveq	#T_FPEMULD,%d0		| denote as FP emulation trap
+	jra	_ASM_LABEL(fault)	| do it
+#endif
+Lfp_unsupp:
+#endif
+#ifdef FPU_EMULATE
+	clrl	%sp@-			| stack adjust count
+	moveml	#0xFFFF,%sp@-		| save registers
+	moveq	#T_FPEMULD,%d0		| denote as FP emulation trap
+	jra	_ASM_LABEL(fault)	| do it
+#else
+	jra	_C_LABEL(illinst)
+#endif
 
 /*
- * floppy ejection trap
+ * Handles all other FP coprocessor exceptions.
+ * Note that since some FP exceptions generate mid-instruction frames
+ * and may cause signal delivery, we need to test for stack adjustment
+ * after the trap call.
  */
-
-ENTRY_NOPROFILE(fdeject)
-	jra	_ASM_LABEL(rei)
+ENTRY_NOPROFILE(fpfault)
+	clrl	%sp@-		| stack adjust count
+	moveml	#0xFFFF,%sp@-	| save user registers
+	movl	%usp,%a0	| and save
+	movl	%a0,%sp@(FR_SP)	|   the user stack pointer
+	clrl	%sp@-		| no VA arg
+	movl	_C_LABEL(curpcb),%a0 | current pcb
+	lea	%a0@(PCB_FPCTX),%a0 | address of FP savearea
+	fsave	%a0@		| save state
+#if defined(M68040) || defined(M68060)
+	/* always null state frame on 68040, 68060 */
+	cmpl	#FPU_68040,_C_LABEL(fputype)
+	jge	Lfptnull
+#endif
+	tstb	%a0@		| null state frame?
+	jeq	Lfptnull	| yes, safe
+	clrw	%d0		| no, need to tweak BIU
+	movb	%a0@(1),%d0	| get frame size
+	bset	#3,%a0@(0,%d0:w) | set exc_pend bit of BIU
+Lfptnull:
+	fmovem	%fpsr,%sp@-	| push fpsr as code argument
+	frestore %a0@		| restore state
+	movl	#T_FPERR,%sp@-	| push type arg
+	jra	_ASM_LABEL(faultstkadj)	| call trap and deal with stack cleanup
 
 /*
- * Emulation of VAX REI instruction.
- *
- * This code deals with checking for and servicing ASTs
- * (profiling, scheduling) and software interrupts (network, softclock).
- * We check for ASTs first, just like the VAX.  To avoid excess overhead
- * the T_ASTFLT handling code will also check for software interrupts so we
- * do not have to do it here.  After identifing that we need an AST we
- * drop the IPL to allow device interrupts.
- *
- * This code is complicated by the fact that sendsig may have been called
- * necessitating a stack cleanup.
+ * Other exceptions only cause four and six word stack frame and require
+ * no post-trap stack adjustment.
  */
-ASENTRY_NOPROFILE(rei)
-	tstl	_C_LABEL(astpending)	| AST pending?
-	jeq	Lchksir			| no, go check for SIR
-Lrei1:
-	btst	#5,%sp@			| yes, are we returning to user mode?
-	jne	Lchksir			| no, go check for SIR
-	movw	#PSL_LOWIPL,%sr		| lower SPL
-	clrl	%sp@-			| stack adjust
-	moveml	#0xFFFF,%sp@-		| save all registers
-	movl	%usp,%a1		| including
-	movl	%a1,%sp@(FR_SP)		|    the users SP
-Lrei2:
-	clrl	%sp@-			| VA == none
-	clrl	%sp@-			| code == none
-	movl	#T_ASTFLT,%sp@-		| type == async system trap
-	pea	%sp@(12)		| fp = trap frame address
-	jbsr	_C_LABEL(trap)		| go handle it
-	lea	%sp@(16),%sp		| pop value args
-	movl	%sp@(FR_SP),%a0		| restore user SP
-	movl	%a0,%usp		|   from save area
-	movw	%sp@(FR_ADJ),%d0	| need to adjust stack?
-	jne	Laststkadj		| yes, go to it
-	moveml	%sp@+,#0x7FFF		| no, restore most user regs
-	addql	#8,%sp			| toss SP and stack adjust
-	rte				| and do real RTE
-Laststkadj:
-	lea	%sp@(FR_HW),%a1		| pointer to HW frame
-	addql	#8,%a1			| source pointer
-	movl	%a1,%a0			| source
-	addw	%d0,%a0			|  + hole size = dest pointer
-	movl	%a1@-,%a0@-		| copy
-	movl	%a1@-,%a0@-		|  8 bytes
-	movl	%a0,%sp@(FR_SP)		| new SSP
-	moveml	%sp@+,#0x7FFF		| restore user registers
-	movl	%sp@,%sp		| and our SP
-	rte				| and do real RTE
-Lchksir:
-	tstb	_C_LABEL(ssir)		| SIR pending?
-	jeq	Ldorte			| no, all done
-	movl	%d0,%sp@-		| need a scratch register
-	movw	%sp@(4),%d0		| get SR
-	andw	#PSL_IPL7,%d0		| mask all but IPL
-	jne	Lnosir			| came from interrupt, no can do
-	movl	%sp@+,%d0		| restore scratch register
-Lgotsir:
-	movw	#SPL1,%sr		| prevent others from servicing int
-	tstb	_C_LABEL(ssir)		| too late?
-	jeq	Ldorte			| yes, oh well...
-	clrl	%sp@-			| stack adjust
-	moveml	#0xFFFF,%sp@-		| save all registers
-	movl	%usp,%a1		| including
-	movl	%a1,%sp@(FR_SP)		|    the users SP
-Lsir1:
-	clrl	%sp@-			| VA == none
-	clrl	%sp@-			| code == none
-	movl	#T_SSIR,%sp@-		| type == software interrupt
-	pea	%sp@(12)		| fp = trap frame address
-	jbsr	_C_LABEL(trap)		| go handle it
-	lea	%sp@(16),%sp		| pop value args
-	movl	%sp@(FR_SP),%a0		| restore
+
+ENTRY_NOPROFILE(badtrap)
+	moveml	#0xC0C0,%sp@-		| save scratch regs
+	movw	%sp@(22),%sp@-		| push exception vector info
+	clrw	%sp@-
+	movl	%sp@(22),%sp@-		| and PC
+	jbsr	_C_LABEL(straytrap)	| report
+	addql	#8,%sp			| pop args
+	moveml	%sp@+,#0x0303		| restore regs
+	jra	_ASM_LABEL(rei)		| all done
+
+ENTRY_NOPROFILE(trap0)
+	clrl	%sp@-			| stack adjust count
+	moveml	#0xFFFF,%sp@-		| save user registers
+	movl	%usp,%a0		| save the user SP
+	movl	%a0,%sp@(FR_SP)		|   in the savearea
+	movl	%d0,%sp@-		| push syscall number
+	jbsr	_C_LABEL(syscall)	| handle it
+	addql	#4,%sp			| pop syscall arg
+	tstl	_C_LABEL(astpending)
+	jne	Lrei2
+	tstb	_C_LABEL(ssir)
+	jeq	Ltrap1
+	movw	#SPL1,%sr
+	tstb	_C_LABEL(ssir)
+	jne	Lsir1
+Ltrap1:
+	movl	%sp@(FR_SP),%a0		| grab and restore
 	movl	%a0,%usp		|   user SP
-	moveml	%sp@+,#0x7FFF		| and all remaining registers
+	moveml	%sp@+,#0x7FFF		| restore most registers
 	addql	#8,%sp			| pop SP and stack adjust
 	rte
-Lnosir:
-	movl	%sp@+,%d0		| restore scratch register
-Ldorte:
-	rte				| real return
 
 /*
- * Macro to relocate a symbol, used before MMU is enabled.
+ * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD)
+ *	cachectl(command, addr, length)
+ * command in d0, addr in a1, length in d1
  */
-#define	_RELOC(var, ar)	\
-	lea	var,ar;	\
-	addl	%a5,ar
-
-#define	RELOC(var, ar)		_RELOC(_C_LABEL(var), ar)
-#define	ASRELOC(var, ar)	_RELOC(_ASM_LABEL(var), ar)
+ENTRY_NOPROFILE(trap12)
+	movl	_C_LABEL(curlwp),%a0
+	movl	%a0@(L_PROC),%sp@-	| push curproc pointer
+	movl	%d1,%sp@-		| push length
+	movl	%a1,%sp@-		| push addr
+	movl	%d0,%sp@-		| push command
+	jbsr	_C_LABEL(cachectl1)	| do it
+	lea	%sp@(16),%sp		| pop args
+	jra	_ASM_LABEL(rei)		| all done
 
 /*
- * Initialization
- *
- * A4 contains the address of the end of the symtab
- * A5 contains physical load point from boot
- * VBR contains zero from ROM.  Exceptions will continue to vector
- * through ROM until MMU is turned on at which time they will vector
- * through our table (vectors.s).
+ * Trace (single-step) trap.  Kernel-mode is special.
+ * User mode traps are simply passed on to trap().
  */
-BSS(lowram,4)
-BSS(esym,4)
-
-GLOBAL(_verspad)
-	.word	0
-GLOBAL(boot_version)
-	.word	X68K_BOOTIF_VERS
-
-ASENTRY_NOPROFILE(start)
-	movw	#PSL_HIGHIPL,%sr	| no interrupts
-
-	addql	#4,%sp
-	movel	%sp@+,%a5		| firstpa
-	movel	%sp@+,%d5		| fphysize -- last page
-	movel	%sp@,%a4		| esym
-
-	RELOC(vectab,%a0)		| set Vector Base Register temporaly
-	movc	%a0,%vbr
+ENTRY_NOPROFILE(trace)
+	clrl	%sp@-			| stack adjust count
+	moveml	#0xFFFF,%sp@-
+	moveq	#T_TRACE,%d0
 
-#if 0	/* XXX this should be done by the boot loader */
-	RELOC(edata, %a0)		| clear out BSS
-	movl	#_C_LABEL(end)-4,%d0	| (must be <= 256 kB)
-	subl	#_C_LABEL(edata),%d0
-	lsrl	#2,%d0
-1:	clrl	%a0@+
-	dbra	%d0,1b
-#endif
+	| Check PSW and see what happen.
+	|   T=0 S=0	(should not happen)
+	|   T=1 S=0	trace trap from user mode
+	|   T=0 S=1	trace trap on a trap instruction
+	|   T=1 S=1	trace trap from system mode (kernel breakpoint)
 
-	ASRELOC(tmpstk, %a0)
-	movl	%a0,%sp			| give ourselves a temporary stack
-	RELOC(esym, %a0)
-#if 1
-	movl	%a4,%a0@		| store end of symbol table
-#else
-	clrl	%a0@			| no symbol table, yet
-#endif
-	RELOC(lowram, %a0)
-	movl	%a5,%a0@		| store start of physical memory
+	movw	%sp@(FR_HW),%d1		| get PSW
+	notw	%d1			| XXX no support for T0 on 680[234]0
+	andw	#PSL_TS,%d1		| from system mode (T=1, S=1)?
+	jeq	Lkbrkpt			| yes, kernel breakpoint
+	jra	_ASM_LABEL(fault)	| no, user-mode fault
 
-	movl	#CACHE_OFF,%d0
-	movc	%d0,%cacr		| clear and disable on-chip cache(s)
+/*
+ * Trap 15 is used for:
+ *	- GDB breakpoints (in user programs)
+ *	- KGDB breakpoints (in the kernel)
+ *	- trace traps for SUN binaries (not fully supported yet)
+ * User mode traps are simply passed to trap().
+ */
+ENTRY_NOPROFILE(trap15)
+	clrl	%sp@-			| stack adjust count
+	moveml	#0xFFFF,%sp@-
+	moveq	#T_TRAP15,%d0
+	movw	%sp@(FR_HW),%d1		| get PSW
+	andw	#PSL_S,%d1		| from system mode?
+	jne	Lkbrkpt			| yes, kernel breakpoint
+	jra	_ASM_LABEL(fault)	| no, user-mode fault
 
-/* 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 68020/68040/68060
-	jra	Lstart1			| no, we have 68030
-Lnot68030:
-	bset	#31,%d0			| data cache enable bit
-	movc	%d0,%cacr		|   only exists on 68040/68060
-	movc	%cacr,%d0		| read it back
-	tstl	%d0			| zero?
-	jeq	Lis68020		| yes, we have 68020
-	moveq	#0,%d0			| now turn it back off
-	movec	%d0,%cacr		|   before we access any data
-	.word	0xf4d8			| cinva bc - invalidate caches XXX
-	bset	#30,%d0			| data cache no allocate mode bit
-	movc	%d0,%cacr		|   only exists on 68060
-	movc	%cacr,%d0		| read it back
-	tstl	%d0			| zero?
-	jeq	Lis68040		| yes, we have 68040
-	RELOC(mmutype, %a0)		| no, we have 68060
-	movl	#MMU_68040,%a0@		| with a 68040 compatible MMU
-	RELOC(cputype, %a0)
-	movl	#CPU_68060,%a0@		| and a 68060 CPU
-	jra	Lstart1
-Lis68040:
-	RELOC(mmutype, %a0)
-	movl	#MMU_68040,%a0@		| with a 68040 MMU
-	RELOC(cputype, %a0)
-	movl	#CPU_68040,%a0@		| and a 68040 CPU
-	jra	Lstart1
-Lis68020:
-	RELOC(mmutype, %a0)
-	movl	#MMU_68851,%a0@		| we have PMMU
-	RELOC(cputype, %a0)
-	movl	#CPU_68020,%a0@		| and a 68020 CPU
+Lkbrkpt: | Kernel-mode breakpoint or trace trap. (d0=trap_type)
+	| Save the system sp rather than the user sp.
+	movw	#PSL_HIGHIPL,%sr	| lock out interrupts
+	lea	%sp@(FR_SIZE),%a6	| Save stack pointer
+	movl	%a6,%sp@(FR_SP)		|  from before trap
 
-Lstart1:
-/* initialize source/destination control registers for movs */
-	moveq	#FC_USERD,%d0		| user space
-	movc	%d0,%sfc		|   as source
-	movc	%d0,%dfc		|   and destination of transfers
-/* initialize memory sizes (for pmap_bootstrap) */
-	movl	%d5,%d1			| last page
-	moveq	#PGSHIFT,%d2
-	lsrl	%d2,%d1			| convert to page (click) number
-	RELOC(maxmem, %a0)
-	movl	%d1,%a0@		| save as maxmem
-	movl	%a5,%d0			| lowram value from ROM via boot
-	lsrl	%d2,%d0			| convert to page number
-	subl	%d0,%d1			| compute amount of RAM present
-	RELOC(physmem, %a0)
-	movl	%d1,%a0@		| and physmem
-/* configure kernel and lwp0 VA space so we can get going */
-#if NKSYMS || defined(DDB) || defined(LKM)
-	RELOC(esym,%a0)			| end of static kernel test/data/syms
-	movl	%a0@,%d5
-	jne	Lstart2
-#endif
-	movl	#_C_LABEL(end),%d5	| end of static kernel text/data
-Lstart2:
-	RELOC(setmemrange,%a0)		| call setmemrange()
-	jbsr	%a0@			|  to probe all memory regions
-	addl	#PAGE_SIZE-1,%d5
-	andl	#PG_FRAME,%d5		| round to a page
-	movl	%d5,%a4
-	addl	%a5,%a4			| convert to PA
-	pea	%a5@			| firstpa
-	pea	%a4@			| nextpa
-	RELOC(pmap_bootstrap,%a0)
-	jbsr	%a0@			| pmap_bootstrap(firstpa, nextpa)
-	addql	#8,%sp
+	| If were are not on tmpstk switch to it.
+	| (so debugger can change the stack pointer)
+	movl	%a6,%d1
+	cmpl	#_ASM_LABEL(tmpstk),%d1
+	jls	Lbrkpt2			| already on tmpstk
+	| Copy frame to the temporary stack
+	movl	%sp,%a0			| a0=src
+	lea	_ASM_LABEL(tmpstk)-96,%a1 | a1=dst
+	movl	%a1,%sp			| sp=new frame
+	moveq	#FR_SIZE,%d1
+Lbrkpt1:
+	movl	%a0@+,%a1@+
+	subql	#4,%d1
+	jgt	Lbrkpt1
 
-/*
- * Prepare to enable MMU.
- * Since the kernel is mapped logical == physical, we just turn it on.
- */
-	RELOC(Sysseg_pa, %a0)		| system segment table addr
-	movl	%a0@,%d1		| read value (a PA)
-	RELOC(mmutype, %a0)
-	cmpl	#MMU_68040,%a0@		| 68040?
-	jne	Lmotommu1		| no, skip
-	.long	0x4e7b1807		| movc d1,srp
-	jra	Lstploaddone
-Lmotommu1:
-	RELOC(protorp, %a0)
-	movl	#0x80000202,%a0@	| nolimit + share global + 4 byte PTEs
-	movl	%d1,%a0@(4)		| + segtable address
-	pmove	%a0@,%srp		| load the supervisor root pointer
-	movl	#0x80000002,%a0@	| reinit upper half for CRP loads
-Lstploaddone:
-	RELOC(mmutype, %a0)
-	cmpl	#MMU_68040,%a0@		| 68040?
-	jne	Lmotommu2		| no, skip
-#include "opt_jupiter.h"
-#ifdef JUPITER
-	/* JUPITER-X: set system register "SUPER" bit */
-	movl	#0x0200a240,%d0		| translate DRAM area transparently
-	.long	0x4e7b0006		| movc d0,dtt0
-	lea	0x00c00000,%a0		| a0: graphic VRAM
-	lea	0x02c00000,%a1		| a1: graphic VRAM ( not JUPITER-X )
-					|     DRAM ( JUPITER-X )
-	movw	%a0@,%d0
-	movw	%d0,%d1
-	notw	%d1
-	movw	%d1,%a1@
-	movw	%d0,%a0@
-	cmpw	%a1@,%d1		| JUPITER-X?
-	jne	Ljupiterdone		| no, skip
-	movl	#0x0100a240,%d0		| to access system register
-	.long	0x4e7b0006		| movc d0,dtt0
-	movb	#0x01,0x01800003	| set "SUPER" bit
-Ljupiterdone:
-#endif /* JUPITER */
-	moveq	#0,%d0			| ensure TT regs are disabled
-	.long	0x4e7b0004		| movc d0,itt0
-	.long	0x4e7b0005		| movc d0,itt1
-	.long	0x4e7b0006		| movc d0,dtt0
-	.long	0x4e7b0007		| movc d0,dtt1
-	.word	0xf4d8			| cinva bc
-	.word	0xf518			| pflusha
-#if PGSHIFT == 13
-	movl	#0xc000,%d0
-#else
-	movl	#0x8000,%d0
+Lbrkpt2:
+	| Call the trap handler for the kernel debugger.
+	| Do not call trap() to do it, so that we can
+	| set breakpoints in trap() if we want.  We know
+	| the trap type is either T_TRACE or T_BREAKPOINT.
+	| If we have both DDB and KGDB, let KGDB see it first,
+	| because KGDB will just return 0 if not connected.
+	| Save args in d2, a2
+	movl	%d0,%d2			| trap type
+	movl	%sp,%a2			| frame ptr
+#ifdef KGDB
+	| Let KGDB handle it (if connected)
+	movl	%a2,%sp@-		| push frame ptr
+	movl	%d2,%sp@-		| push trap type
+	jbsr	_C_LABEL(kgdb_trap)	| handle the trap
+	addql	#8,%sp			| pop args
+	cmpl	#0,%d0			| did kgdb handle it?
+	jne	Lbrkpt3			| yes, done
 #endif
-	.long	0x4e7b0003		| movc d0,tc
-#ifdef M68060
-	RELOC(cputype, %a0)
-	cmpl	#CPU_68060,%a0@		| 68060?
-	jne	Lnot060cache
-	movl	#1,%d0
-	.long	0x4e7b0808		| movcl d0,pcr
-	movl	#0xa0808000,%d0
-	movc	%d0,%cacr		| enable store buffer, both caches
-	jmp	Lenab1
-Lnot060cache:
+#ifdef DDB
+	| Let DDB handle it
+	movl	%a2,%sp@-		| push frame ptr
+	movl	%d2,%sp@-		| push trap type
+	jbsr	_C_LABEL(kdb_trap)	| handle the trap
+	addql	#8,%sp			| pop args
+#if 0	/* not needed on hp300 */
+	cmpl	#0,%d0			| did ddb handle it?
+	jne	Lbrkpt3			| yes, done
 #endif
-	movl	#0x80008000,%d0
-	movc	%d0,%cacr		| turn on both caches
-	jmp	Lenab1
-Lmotommu2:
-	pflusha
-#if PGSHIFT == 13
-	movl	#0x82d08b00,%sp@-	| value to load TC with
-#else
-	movl	#0x82c0aa00,%sp@-	| value to load TC with
 #endif
-	pmove	%sp@,%tc		| load it
+	/* Sun 3 drops into PROM here. */
+Lbrkpt3:
+	| The stack pointer may have been modified, or
+	| data below it modified (by kgdb push call),
+	| so push the hardware frame at the current sp
+	| before restoring registers and returning.
+
+	movl	%sp@(FR_SP),%a0		| modified sp
+	lea	%sp@(FR_SIZE),%a1	| end of our frame
+	movl	%a1@-,%a0@-		| copy 2 longs with
+	movl	%a1@-,%a0@-		| ... predecrement
+	movl	%a0,%sp@(FR_SP)		| sp = h/w frame
+	moveml	%sp@+,#0x7FFF		| restore all but sp
+	movl	%sp@,%sp		| ... and sp
+	rte				| all done
+
+/* Use common m68k sigreturn */
+#include <m68k/m68k/sigreturn.s>
 
 /*
- * Should be running mapped from this point on
+ * Provide a generic interrupt dispatcher, only handle hardclock (int6)
+ * specially, to improve performance
  */
-Lenab1:
-/* set vector base in virtual address */
-	movl	#_C_LABEL(vectab),%d0	| set Vector Base Register
-	movc	%d0,%vbr
-	lea	_ASM_LABEL(tmpstk),%sp	| temporary stack
-/* call final pmap setup */
-	jbsr	_C_LABEL(pmap_bootstrap_finalize)
-/* set kernel stack, user SP */
-	movl	_C_LABEL(lwp0uarea),%a1	| grab lwp0 uarea
-	lea	%a1@(USPACE-4),%sp	| set kernel stack to end of area  
-	movl	#USRSTACK-4,%a2
-	movl	%a2,%usp		| init user SP
 
-/* detect FPU type */
-	jbsr	_C_LABEL(fpu_probe)
-	movl	%d0,_C_LABEL(fputype)
-	tstl	_C_LABEL(fputype)	| Have an FPU?
-	jeq	Lenab2			| No, skip.
-	clrl	%a1@(PCB_FPCTX)		| ensure null FP context
+ENTRY_NOPROFILE(spurintr)	/* level 0 */
+	addql	#1,_C_LABEL(intrcnt)+0
+	INTERRUPT_SAVEREG
+	CPUINFO_INCREMENT(CI_NINTR)
+	INTERRUPT_RESTOREREG
+	rte				| XXX mfpcure (x680x0 hardware bug)
+
+ENTRY_NOPROFILE(kbdtimer)
+	rte
+
+ENTRY_NOPROFILE(intiotrap)
+	addql	#1,_C_LABEL(idepth)
+	INTERRUPT_SAVEREG
+	pea	%sp@(16-(FR_HW))	| XXX
+	jbsr	_C_LABEL(intio_intr)
+	addql	#4,%sp
+	CPUINFO_INCREMENT(CI_NINTR)
+	INTERRUPT_RESTOREREG
+	subql	#1,_C_LABEL(idepth)
+	jra	rei
+
+ENTRY_NOPROFILE(lev1intr)
+ENTRY_NOPROFILE(lev2intr)
+ENTRY_NOPROFILE(lev3intr)
+ENTRY_NOPROFILE(lev4intr)
+ENTRY_NOPROFILE(lev5intr)
+ENTRY_NOPROFILE(lev6intr)
+	addql	#1,_C_LABEL(idepth)
+	INTERRUPT_SAVEREG
+Lnotdma:
+	lea	_C_LABEL(intrcnt),%a0
+	movw	%sp@(22),%d0		| use vector offset
+	andw	#0xfff,%d0		|   sans frame type
+	addql	#1,%a0@(-0x60,%d0:w)	|     to increment apropos counter
+	movw	%sr,%sp@-		| push current SR value
+	clrw	%sp@-			|    padded to longword
+	jbsr	_C_LABEL(intrhand)	| handle interrupt
+	addql	#4,%sp			| pop SR
+	CPUINFO_INCREMENT(CI_NINTR)
+	INTERRUPT_RESTOREREG
+	subql	#1,_C_LABEL(idepth)
+	jra	_ASM_LABEL(rei)
+
+ENTRY_NOPROFILE(timertrap)
+	addql	#1,_C_LABEL(idepth)
+	INTERRUPT_SAVEREG		| save scratch registers
+	addql	#1,_C_LABEL(intrcnt)+32	| count hardclock interrupts
+	lea	%sp@(16),%a1		| a1 = &clockframe
 	movl	%a1,%sp@-
-	jbsr	_C_LABEL(m68881_restore) | restore it (does not kill a1)
+	jbsr	_C_LABEL(hardclock)	| hardclock(&frame)
 	addql	#4,%sp
-Lenab2:
-	cmpl	#MMU_68040,_C_LABEL(mmutype)	| 68040?
-	jeq	Ltbia040		| yes, cache already on
-	pflusha
-	tstl	_C_LABEL(mmutype)
-	jpl	Lenab3			| 68851 implies no d-cache
-	movl	#CACHE_ON,%d0
-	movc	%d0,%cacr		| clear cache(s)
-	jra	Lenab3
-Ltbia040:
-	.word	0xf518
-Lenab3:
-/* final setup for C code */
-	movl	%d7,_C_LABEL(boothowto)	| save reboot flags
-	movl	%d6,_C_LABEL(bootdev)	|   and boot device
-	jbsr	_C_LABEL(x68k_init)	| additional pre-main initialization
+	CPUINFO_INCREMENT(CI_NINTR)	| chalk up another interrupt
+	INTERRUPT_RESTOREREG		| restore scratch registers
+	subql	#1,_C_LABEL(idepth)
+	jra	_ASM_LABEL(rei)		| all done
+
+ENTRY_NOPROFILE(lev7intr)
+	addql	#1,_C_LABEL(idepth)
+	addql	#1,_C_LABEL(intrcnt)+28
+	clrl	%sp@-
+	moveml	#0xFFFF,%sp@-		| save registers
+	movl	%usp,%a0		| and save
+	movl	%a0,%sp@(FR_SP)		|   the user stack pointer
+	jbsr	_C_LABEL(nmihand)	| call handler
+	movl	%sp@(FR_SP),%a0		| restore
+	movl	%a0,%usp		|   user SP
+	moveml	%sp@+,#0x7FFF		| and remaining registers
+	addql	#8,%sp			| pop SP and stack adjust
+	subql	#1,_C_LABEL(idepth)
+	jra	_ASM_LABEL(rei)		| all done
 
 /*
- * Create a fake exception frame so that cpu_lwp_fork() can copy it.
- * main() nevers returns; we exit to user mode from a forked process
- * later on.
+ * floppy ejection trap
  */
-	clrw	%sp@-			| vector offset/frame type
-	clrl	%sp@-			| PC - filled in by "execve"
-	movw	#PSL_USER,%sp@-		| in user mode
-	clrl	%sp@-			| stack adjust count and padding
-	lea	%sp@(-64),%sp		| construct space for D0-D7/A0-A7
-	lea	_C_LABEL(lwp0),%a0	| save pointer to frame
-	movl	%sp,%a0@(L_MD_REGS)	|   in lwp0.p_md.md_regs
 
-	jra	_C_LABEL(main)		| main()
+ENTRY_NOPROFILE(fdeject)
+	jra	_ASM_LABEL(rei)
 
-	PANIC("main() returned")	| Yow!  Main returned!
-	/* NOTREACHED */
+/*
+ * Emulation of VAX REI instruction.
+ *
+ * This code deals with checking for and servicing ASTs
+ * (profiling, scheduling) and software interrupts (network, softclock).
+ * We check for ASTs first, just like the VAX.  To avoid excess overhead
+ * the T_ASTFLT handling code will also check for software interrupts so we
+ * do not have to do it here.  After identifing that we need an AST we
+ * drop the IPL to allow device interrupts.
+ *
+ * This code is complicated by the fact that sendsig may have been called
+ * necessitating a stack cleanup.
+ */
+ASENTRY_NOPROFILE(rei)
+	tstl	_C_LABEL(astpending)	| AST pending?
+	jeq	Lchksir			| no, go check for SIR
+Lrei1:
+	btst	#5,%sp@			| yes, are we returning to user mode?
+	jne	Lchksir			| no, go check for SIR
+	movw	#PSL_LOWIPL,%sr		| lower SPL
+	clrl	%sp@-			| stack adjust
+	moveml	#0xFFFF,%sp@-		| save all registers
+	movl	%usp,%a1		| including
+	movl	%a1,%sp@(FR_SP)		|    the users SP
+Lrei2:
+	clrl	%sp@-			| VA == none
+	clrl	%sp@-			| code == none
+	movl	#T_ASTFLT,%sp@-		| type == async system trap
+	pea	%sp@(12)		| fp = trap frame address
+	jbsr	_C_LABEL(trap)		| go handle it
+	lea	%sp@(16),%sp		| pop value args
+	movl	%sp@(FR_SP),%a0		| restore user SP
+	movl	%a0,%usp		|   from save area
+	movw	%sp@(FR_ADJ),%d0	| need to adjust stack?
+	jne	Laststkadj		| yes, go to it
+	moveml	%sp@+,#0x7FFF		| no, restore most user regs
+	addql	#8,%sp			| toss SP and stack adjust
+	rte				| and do real RTE
+Laststkadj:
+	lea	%sp@(FR_HW),%a1		| pointer to HW frame
+	addql	#8,%a1			| source pointer
+	movl	%a1,%a0			| source
+	addw	%d0,%a0			|  + hole size = dest pointer
+	movl	%a1@-,%a0@-		| copy
+	movl	%a1@-,%a0@-		|  8 bytes
+	movl	%a0,%sp@(FR_SP)		| new SSP
+	moveml	%sp@+,#0x7FFF		| restore user registers
+	movl	%sp@,%sp		| and our SP
+	rte				| and do real RTE
+Lchksir:
+	tstb	_C_LABEL(ssir)		| SIR pending?
+	jeq	Ldorte			| no, all done
+	movl	%d0,%sp@-		| need a scratch register
+	movw	%sp@(4),%d0		| get SR
+	andw	#PSL_IPL7,%d0		| mask all but IPL
+	jne	Lnosir			| came from interrupt, no can do
+	movl	%sp@+,%d0		| restore scratch register
+Lgotsir:
+	movw	#SPL1,%sr		| prevent others from servicing int
+	tstb	_C_LABEL(ssir)		| too late?
+	jeq	Ldorte			| yes, oh well...
+	clrl	%sp@-			| stack adjust
+	moveml	#0xFFFF,%sp@-		| save all registers
+	movl	%usp,%a1		| including
+	movl	%a1,%sp@(FR_SP)		|    the users SP
+Lsir1:
+	clrl	%sp@-			| VA == none
+	clrl	%sp@-			| code == none
+	movl	#T_SSIR,%sp@-		| type == software interrupt
+	pea	%sp@(12)		| fp = trap frame address
+	jbsr	_C_LABEL(trap)		| go handle it
+	lea	%sp@(16),%sp		| pop value args
+	movl	%sp@(FR_SP),%a0		| restore
+	movl	%a0,%usp		|   user SP
+	moveml	%sp@+,#0x7FFF		| and all remaining registers
+	addql	#8,%sp			| pop SP and stack adjust
+	rte
+Lnosir:
+	movl	%sp@+,%d0		| restore scratch register
+Ldorte:
+	rte				| real return
 
 /*
  * Use common m68k sigcode.

Reply via email to