Home | History | Annotate | Line # | Download | only in boot
locore.S revision 1.9.4.1
      1 /*	$NetBSD: locore.S,v 1.9.4.1 2014/05/18 17:45:15 rmind Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1992 OMRON Corporation.
      5  *
      6  * This code is derived from software contributed to Berkeley by
      7  * OMRON Corporation.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *	This product includes software developed by the University of
     20  *	California, Berkeley and its contributors.
     21  * 4. Neither the name of the University nor the names of its contributors
     22  *    may be used to endorse or promote products derived from this software
     23  *    without specific prior written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     35  * SUCH DAMAGE.
     36  *
     37  *	@(#)locore.s	8.1 (Berkeley) 6/10/93
     38  */
     39 /*
     40  * Copyright (c) 1990, 1993
     41  *	The Regents of the University of California.  All rights reserved.
     42  *
     43  * This code is derived from software contributed to Berkeley by
     44  * OMRON Corporation.
     45  *
     46  * Redistribution and use in source and binary forms, with or without
     47  * modification, are permitted provided that the following conditions
     48  * are met:
     49  * 1. Redistributions of source code must retain the above copyright
     50  *    notice, this list of conditions and the following disclaimer.
     51  * 2. Redistributions in binary form must reproduce the above copyright
     52  *    notice, this list of conditions and the following disclaimer in the
     53  *    documentation and/or other materials provided with the distribution.
     54  * 3. Neither the name of the University nor the names of its contributors
     55  *    may be used to endorse or promote products derived from this software
     56  *    without specific prior written permission.
     57  *
     58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     68  * SUCH DAMAGE.
     69  *
     70  *	@(#)locore.s	8.1 (Berkeley) 6/10/93
     71  */
     72 
     73 /* For _C_LABEL() and friends. */
     74 #include <m68k/asm.h>
     75 
     76 #define	T_BUSERR	0
     77 #define	T_ADDRERR	1
     78 #define	T_ILLINST	2
     79 #define	T_ZERODIV	3
     80 #define	T_CHKINST	4
     81 #define	T_TRAPVINST	5
     82 #define	T_PRIVINST	6
     83 #define	T_MMUFLT	8
     84 #define	T_FMTERR	10
     85 #define	T_FPERR		11
     86 #define	T_COPERR	12
     87 
     88 #define	PSL_LOWIPL	0x2000		/* PSL_S | PSL_IPL0 */
     89 #define	PSL_HIGHIPL	0x2700		/* PSL_S | PSL_IPL7 */
     90 
     91 #define	SPL1		0x2100		/* PSL_S | PSL_IPL1 */
     92 #define	SPL2		0x2200		/* PSL_S | PSL_IPL2 */
     93 #define	SPL3		0x2300		/* PSL_S | PSL_IPL3 */
     94 #define	SPL4		0x2400		/* PSL_S | PSL_IPL4 */
     95 #define	SPL5		0x2500		/* PSL_S | PSL_IPL5 */
     96 #define	SPL6		0x2600		/* PSL_S | PSL_IPL6 */
     97 
     98 #define	CLOCK_REG	0x63000000
     99 #define	CLK_CLR		1
    100 
    101 #define	ILLGINST	16
    102 #define	NMIVEC		124
    103 #define	EVTRAPF		188
    104 
    105 	.text
    106 
    107 ASENTRY_NOPROFILE(start)
    108 ASGLOBAL(Reset)
    109 	jmp _C_LABEL(start1)	/* 0: NOT USED (reset PC) */
    110 	.word	0		/* 1: NOT USED (reset PC) */
    111 	VECTOR(buserr)		/* 2: bus error */
    112 	VECTOR(addrerr)		/* 3: address error */
    113 	VECTOR(illinst)		/* 4: illegal instruction */
    114 	VECTOR(zerodiv)		/* 5: zero divide */
    115 	VECTOR(chkinst)		/* 6: CHK instruction */
    116 	VECTOR(trapvinst)	/* 7: TRAPV instruction */
    117 	VECTOR(privinst)	/* 8: privilege violation */
    118 	VECTOR(badtrap)		/* 9: trace */
    119 	VECTOR(illinst)		/* 10: line 1010 emulator */
    120 	VECTOR(illinst)		/* 11: line 1111 emulator */
    121 	VECTOR(badtrap)		/* 12: unassigned, reserved */
    122 	VECTOR(coperr)		/* 13: coprocessor protocol violation */
    123 	VECTOR(fmterr)		/* 14: format error */
    124 	VECTOR(badtrap)		/* 15: uninitialized interrupt vector */
    125 	VECTOR(badtrap)		/* 16: unassigned, reserved */
    126 	VECTOR(badtrap)		/* 17: unassigned, reserved */
    127 	VECTOR(badtrap)		/* 18: unassigned, reserved */
    128 	VECTOR(badtrap)		/* 19: unassigned, reserved */
    129 	VECTOR(badtrap)		/* 20: unassigned, reserved */
    130 	VECTOR(badtrap)		/* 21: unassigned, reserved */
    131 	VECTOR(badtrap)		/* 22: unassigned, reserved */
    132 	VECTOR(badtrap)		/* 23: unassigned, reserved */
    133 	VECTOR(badtrap)		/* 24: unassigned, reserved */
    134 	VECTOR(badtrap)		/* 25: unassigned, reserved */
    135 	VECTOR(lev2intr)	/* 26: level 2 interrupt autovector */
    136 	VECTOR(lev3intr)	/* 27: level 3 interrupt autovector */
    137 	VECTOR(badtrap)		/* 28: level 4 interrupt autovector */
    138 	VECTOR(lev5intr)	/* 29: level 5 interrupt autovector */
    139 	VECTOR(lev6intr)	/* 30: level 6 interrupt autovector */
    140 	VECTOR(badtrap)		/* 31: level 7 interrupt autovector */
    141 	VECTOR(illinst)		/* 32: syscalls */
    142 	VECTOR(illinst)		/* 33: sigreturn syscall or breakpoint */
    143 	VECTOR(illinst)		/* 34: breakpoint or sigreturn syscall */
    144 	VECTOR(illinst)		/* 35: TRAP instruction vector */
    145 	VECTOR(illinst)		/* 36: TRAP instruction vector */
    146 	VECTOR(illinst)		/* 37: TRAP instruction vector */
    147 	VECTOR(illinst)		/* 38: TRAP instruction vector */
    148 	VECTOR(illinst)		/* 39: TRAP instruction vector */
    149 	VECTOR(illinst)		/* 40: TRAP instruction vector */
    150 	VECTOR(illinst)		/* 41: TRAP instruction vector */
    151 	VECTOR(illinst)		/* 42: TRAP instruction vector */
    152 	VECTOR(illinst)		/* 43: TRAP instruction vector */
    153 	VECTOR(illinst)		/* 44: TRAP instruction vector */
    154 	VECTOR(illinst)		/* 45: TRAP instruction vector */
    155 	VECTOR(illinst)		/* 45: TRAP instruction vector */
    156 	VECTOR(illinst)		/* 47: TRAP instruction vector */
    157 	VECTOR(fptrap)		/* 48: FPCP branch/set on unordered cond */
    158 	VECTOR(fptrap)		/* 49: FPCP inexact result */
    159 	VECTOR(fptrap)		/* 50: FPCP divide by zero */
    160 	VECTOR(fptrap)		/* 51: FPCP underflow */
    161 	VECTOR(fptrap)		/* 52: FPCP operand error */
    162 	VECTOR(fptrap)		/* 53: FPCP overflow */
    163 	VECTOR(fptrap)		/* 54: FPCP signalling NAN */
    164 
    165 	VECTOR(badtrap)		/* 55: unassigned, reserved */
    166 	VECTOR(badtrap)		/* 56: unassigned, reserved */
    167 	VECTOR(badtrap)		/* 57: unassigned, reserved */
    168 	VECTOR(badtrap)		/* 58: unassigned, reserved */
    169 	VECTOR(badtrap)		/* 59: unassigned, reserved */
    170 	VECTOR(badtrap)		/* 60: unassigned, reserved */
    171 	VECTOR(badtrap)		/* 61: unassigned, reserved */
    172 	VECTOR(badtrap)		/* 62: unassigned, reserved */
    173 	VECTOR(badtrap)		/* 63: unassigned, reserved */
    174 #define BADTRAP16       \
    175 	VECTOR(badtrap) ; VECTOR(badtrap) ; \
    176 	VECTOR(badtrap) ; VECTOR(badtrap) ; \
    177 	VECTOR(badtrap) ; VECTOR(badtrap) ; \
    178 	VECTOR(badtrap) ; VECTOR(badtrap) ; \
    179 	VECTOR(badtrap) ; VECTOR(badtrap) ; \
    180 	VECTOR(badtrap) ; VECTOR(badtrap) ; \
    181 	VECTOR(badtrap) ; VECTOR(badtrap) ; \
    182 	VECTOR(badtrap) ; VECTOR(badtrap)
    183 
    184 	BADTRAP16		/* 64-255: user interrupt vectors */
    185 	BADTRAP16		/* 64-255: user interrupt vectors */
    186 	BADTRAP16		/* 64-255: user interrupt vectors */
    187 	BADTRAP16		/* 64-255: user interrupt vectors */
    188 	BADTRAP16		/* 64-255: user interrupt vectors */
    189 	BADTRAP16		/* 64-255: user interrupt vectors */
    190 	BADTRAP16		/* 64-255: user interrupt vectors */
    191 	BADTRAP16		/* 64-255: user interrupt vectors */
    192 	BADTRAP16		/* 64-255: user interrupt vectors */
    193 	BADTRAP16		/* 64-255: user interrupt vectors */
    194 	BADTRAP16		/* 64-255: user interrupt vectors */
    195 	BADTRAP16		/* 64-255: user interrupt vectors */
    196 
    197 
    198 	STACK = 0x800000
    199 	DIPSW = 0x49000000
    200 
    201 ASENTRY_NOPROFILE(start1)
    202 	movw	#PSL_HIGHIPL,%sr	| no interrupts
    203 	movl	#STACK,%sp		| set SP
    204 
    205 	movl	#_C_LABEL(prgcore), %a2	| save program address
    206 	movl	#_ASM_LABEL(Reset), %a2@+	| save start of core
    207 	movl	#_C_LABEL(end),  %a2@+	| save end of core
    208 	movl	#STACK, %a2@		| save initial stack addr
    209 
    210 /* clear BSS area */
    211 	movl	#_C_LABEL(edata),%a2	| start of BSS
    212 	movl	#_C_LABEL(end),%a3	| end
    213 Lbssclr:
    214 	clrb	%a2@+			| clear BSS
    215 	cmpl	%a2,%a3			| done?
    216 	bne	Lbssclr			| no, keep going
    217 
    218 /* save address to goto ROM monitor */
    219 	movec	%vbr,%a0		| ROM vbr to %a0
    220 	movl	%a0@(NMIVEC),%d0	| restore NMIVEC
    221 	movl	#_ASM_LABEL(gotoROM),%a0	| save to _gotoROM
    222 	movl	%d0,%a0@		|
    223 	movl	#_ASM_LABEL(Reset),%a0	| BP vbr to %a0
    224 	movl	#_C_LABEL(exit),%a0@(NMIVEC)	| save address
    225 
    226 
    227 /* switch vector tabel */
    228 	movec	%vbr,%a0
    229 	movl	%a0@(ILLGINST),%sp@-	| save ILLINST vector for BrkPtr
    230 	movl	%a0@(EVTRAPF),%sp@-
    231 
    232 	movl	#_ASM_LABEL(Reset),%a0
    233 	movl	%sp@+,%a0@(EVTRAPF)
    234 	movl	%sp@+,%a0@(ILLGINST)	| restore ILLINST vector
    235 	movec	%a0,%vbr
    236 
    237 	movl	#DIPSW,%a0
    238 	movw	%a0@,%d0
    239 	lsrl	#8,%d0
    240 	andl	#0xFF,%d0
    241 	movl	%d0,_C_LABEL(dipsw1)
    242 	movw	%a0@,%d0
    243 	andl	#0xFF,%d0
    244 	movl	%d0,_C_LABEL(dipsw2)
    245 
    246 /* determine our CPU */
    247 
    248 	/* XXX should be generated via assym.h */
    249 	CACHE_OFF = 0x0808
    250 	DC_FREEZE = 0x0200
    251 	CPU_68030 = 1
    252 	CPU_68040 = 2
    253 
    254 	movl	#CACHE_OFF,%d0
    255 	movc	%d0,%cacr		| clear and disable on-chip cache(s)
    256 	movl	#DC_FREEZE,%d0		| data freeze bit
    257 	movc	%d0,%cacr		|   only exists on 68030
    258 	movc	%cacr,%d0		| read it back
    259 	tstl	%d0			| zero?
    260 	jeq	Lnot68030		| yes, we have 68040
    261 	movl	#CPU_68030,%d0
    262 	jra	Lstart0
    263 Lnot68030:
    264 	movl	#CPU_68040,%d0
    265 Lstart0:
    266 	movl	%d0,_C_LABEL(cputype)
    267 
    268 /* final setup for C code */
    269 	movw	#PSL_LOWIPL,%sr		| no interrupts
    270 	jsr	_C_LABEL(main)		| lets go
    271 	jsr	start
    272 
    273 /*
    274  * exit to ROM monitor
    275  */
    276 
    277 	ROM_VBR = 0
    278 
    279 ENTRY_NOPROFILE(exit)
    280 GLOBAL(_rtt)
    281 	movw	#PSL_HIGHIPL,%sr	| no interrupts
    282 	movl	#ROM_VBR,%a0
    283 	movec	%a0,%vbr
    284 	movl	#_ASM_LABEL(gotoROM),%a0
    285 	movl	%a0@,%a1
    286 	jmp	%a1@
    287 
    288 /*
    289  * Trap/interrupt vector routines
    290  */
    291 
    292 ENTRY_NOPROFILE(buserr)
    293 	tstl	_C_LABEL(nofault)	| device probe?
    294 	jeq	_C_LABEL(addrerr)	| no, handle as usual
    295 	movl	_C_LABEL(nofault),%sp@-	| yes,
    296 	jbsr	_C_LABEL(longjmp)	|  longjmp(nofault)
    297 ENTRY_NOPROFILE(addrerr)
    298 	clrw	%sp@-			| pad SR to longword
    299 	moveml	#0xFFFF,%sp@-		| save user registers
    300 	movl	%usp,%a0		| save the user SP
    301 	movl	%a0,%sp@(60)		|   in the savearea
    302 	lea	%sp@(64),%a1		| grab base of HW berr frame
    303 	movw	%a1@(12),%d0		| grab SSW for fault processing
    304 	btst	#12,%d0			| RB set?
    305 	jeq	LbeX0			| no, test RC
    306 	bset	#14,%d0			| yes, must set FB
    307 	movw	%d0,%a1@(12)		| for hardware too
    308 LbeX0:
    309 	btst	#13,%d0			| RC set?
    310 	jeq	LbeX1			| no, skip
    311 	bset	#15,%d0			| yes, must set FC
    312 	movw	%d0,%a1@(12)		| for hardware too
    313 LbeX1:
    314 	btst	#8,%d0			| data fault?
    315 	jeq	Lbe0			| no, check for hard cases
    316 	movl	%a1@(18),%d1		| fault address is as given in frame
    317 	jra	Lbe10			| thats it
    318 Lbe0:
    319 	btst	#4,%a1@(8)		| long (type B) stack frame?
    320 	jne	Lbe4			| yes, go handle
    321 	movl	%a1@(4),%d1		| no, can use save PC
    322 	btst	#14,%d0			| FB set?
    323 	jeq	Lbe3			| no, try FC
    324 	addql	#4,%d1			| yes, adjust address
    325 	jra	Lbe10			| done
    326 Lbe3:
    327 	btst	#15,%d0			| FC set?
    328 	jeq	Lbe10			| no, done
    329 	addql	#2,%d1			| yes, adjust address
    330 	jra	Lbe10			| done
    331 Lbe4:
    332 	movl	%a1@(38),%d1		| long format, use stage B address
    333 	btst	#15,%d0			| FC set?
    334 	jeq	Lbe10			| no, all done
    335 	subql	#2,%d1			| yes, adjust address
    336 Lbe10:
    337 	movl	%d1,%sp@-		| push fault VA
    338 	movw	%d0,%sp@-		| and SSW
    339 	clrw	%sp@-			|   padded to longword
    340 	movw	%a1@(8),%d0		| get frame format/vector offset
    341 	andw	#0x0FFF,%d0		| clear out frame format
    342 	cmpw	#12,%d0			| address error vector?
    343 	jeq	Lisaerr			| yes, go to it
    344 #if 0
    345 	movl	%d1,%a0			| fault address
    346 	.long	0xf0109e11		| ptestr #1,%a0@,#7
    347 	.long	0xf0176200		| pmove %psr,%sp@
    348 	btst	#7,%sp@			| bus error bit set?
    349 	jeq	Lismerr			| no, must be MMU fault
    350 	clrw	%sp@			| yes, re-clear pad word
    351 #endif
    352 	jra	Lisberr			| and process as normal bus error
    353 Lismerr:
    354 	movl	#T_MMUFLT,%sp@-		| show that we are an MMU fault
    355 	jra	Lbexit			| and deal with it
    356 Lisaerr:
    357 	movl	#T_ADDRERR,%sp@-	| mark address error
    358 	jra	Lbexit			| and deal with it
    359 Lisberr:
    360 	movl	#T_BUSERR,%sp@-		| mark bus error
    361 Lbexit:
    362 	jbsr	_C_LABEL(trap)		| handle the error
    363 	lea	%sp@(12),%sp		| pop value args
    364 	movl	%sp@(60),%a0		| restore user SP
    365 	movl	%a0,%usp		|   from save area
    366 	moveml	%sp@+,#0x7FFF		| restore most user regs
    367 	addql	#4,%sp			| toss SSP
    368 	tstw	%sp@+			| do we need to clean up stack?
    369 	jeq	_ASM_LABEL(rei)		| no, just continue
    370 	btst	#7,%sp@(6)		| type 9/10/11 frame?
    371 	jeq	_ASM_LABEL(rei)		| no, nothing to do
    372 	btst	#5,%sp@(6)		| type 9?
    373 	jne	Lbex1			| no, skip
    374 	movw	%sp@,%sp@(12)		| yes, push down SR
    375 	movl	%sp@(2),%sp@(14)	| and PC
    376 	clrw	%sp@(18)		| and mark as type 0 frame
    377 	lea	%sp@(12),%sp		| clean the excess
    378 	jra	_ASM_LABEL(rei)		| all done
    379 Lbex1:
    380 	btst	#4,%sp@(6)		| type 10?
    381 	jne	Lbex2			| no, skip
    382 	movw	%sp@,%sp@(24)		| yes, push down SR
    383 	movl	%sp@(2),%sp@(26)	| and PC
    384 	clrw	%sp@(30)		| and mark as type 0 frame
    385 	lea	%sp@(24),%sp		| clean the excess
    386 	jra	_ASM_LABEL(rei)		| all done
    387 Lbex2:
    388 	movw	%sp@,%sp@(84)		| type 11, push down SR
    389 	movl	%sp@(2),%sp@(86)	| and PC
    390 	clrw	%sp@(90)		| and mark as type 0 frame
    391 	lea	%sp@(84),%sp		| clean the excess
    392 	jra	_ASM_LABEL(rei)		| all done
    393 
    394 ENTRY_NOPROFILE(illinst)
    395 	clrw	%sp@-
    396 	moveml	#0xFFFF,%sp@-
    397 	moveq	#T_ILLINST,%d0
    398 	jra	_C_LABEL(fault)
    399 
    400 ENTRY_NOPROFILE(zerodiv)
    401 	clrw	%sp@-
    402 	moveml	#0xFFFF,%sp@-
    403 	moveq	#T_ZERODIV,%d0
    404 	jra	_C_LABEL(fault)
    405 
    406 ENTRY_NOPROFILE(chkinst)
    407 	clrw	%sp@-
    408 	moveml	#0xFFFF,%sp@-
    409 	moveq	#T_CHKINST,%d0
    410 	jra	_C_LABEL(fault)
    411 
    412 ENTRY_NOPROFILE(trapvinst)
    413 	clrw	%sp@-
    414 	moveml	#0xFFFF,%sp@-
    415 	moveq	#T_TRAPVINST,%d0
    416 	jra	_C_LABEL(fault)
    417 
    418 ENTRY_NOPROFILE(privinst)
    419 	clrw	%sp@-
    420 	moveml	#0xFFFF,%sp@-
    421 	moveq	#T_PRIVINST,%d0
    422 	jra	_C_LABEL(fault)
    423 
    424 ENTRY_NOPROFILE(coperr)
    425 	clrw	%sp@-
    426 	moveml	#0xFFFF,%sp@-
    427 	moveq	#T_COPERR,%d0
    428 	jra	_C_LABEL(fault)
    429 
    430 ENTRY_NOPROFILE(fmterr)
    431 	clrw	%sp@-
    432 	moveml	#0xFFFF,%sp@-
    433 	moveq	#T_FMTERR,%d0
    434 	jra	_C_LABEL(fault)
    435 
    436 ENTRY_NOPROFILE(fptrap)
    437 #ifdef FPCOPROC
    438 	clrw	%sp@-		| pad SR to longword
    439 	moveml	#0xFFFF,%sp@-	| save user registers
    440 	movl	%usp,%a0	| and save
    441 	movl	%a0,%sp@(60)	|   the user stack pointer
    442 	clrl	%sp@-		| no VA arg
    443 #if 0
    444 	lea	_u+PCB_FPCTX,%a0	| address of FP savearea
    445 	.word	0xf310		| fsave %a0@
    446 	tstb	%a0@		| null state frame?
    447 	jeq	Lfptnull	| yes, safe
    448 	clrw	%d0		| no, need to tweak BIU
    449 	movb	a0@(1),d0	| get frame size
    450 	bset	#3,%a0@(0,%d0:w)	| set exc_pend bit of BIU
    451 Lfptnull:
    452 	.word	0xf227,0xa800	| fmovem %fpsr,%sp@- (code arg)
    453 	.word	0xf350		| frestore %a0@
    454 #else
    455 	clrl	%sp@-		| push dummy FPSR
    456 #endif
    457 	movl	#T_FPERR,%sp@-	| push type arg
    458 	jbsr	_C_LABEL(trap)	| call trap
    459 	lea	%sp@(12),%sp	| pop value args
    460 	movl	%sp@(60),%a0	| restore
    461 	movl	%a0,%usp	|   user SP
    462 	moveml	%sp@+,#0x7FFF	| and remaining user registers
    463 	addql	#6,%sp		| pop SSP and align word
    464 	jra	_ASM_LABEL(rei)	| all done
    465 #else
    466 	jra	_C_LABEL(badtrap)	| treat as an unexpected trap
    467 #endif
    468 
    469 ENTRY_NOPROFILE(fault)
    470 	movl	%usp,%a0	| get and save
    471 	movl	%a0,%sp@(60)	|   the user stack pointer
    472 	clrl	%sp@-		| no VA arg
    473 	clrl	%sp@-		| or code arg
    474 	movl	%d0,%sp@-	| push trap type
    475 	jbsr	_C_LABEL(trap)	| handle trap
    476 	lea	%sp@(12),%sp	| pop value args
    477 	movl	%sp@(60),%a0	| restore
    478 	movl	%a0,%usp	|   user SP
    479 	moveml	%sp@+,#0x7FFF	| restore most user regs
    480 	addql	#6,%sp		| pop SP and pad word
    481 	jra	_ASM_LABEL(rei)	| all done
    482 
    483 ENTRY_NOPROFILE(badtrap)
    484 	clrw	%sp@-
    485 	moveml	#0xC0C0,%sp@-
    486 	movw	%sp@(24),%sp@-
    487 	clrw	%sp@-
    488 	jbsr	_C_LABEL(straytrap)
    489 	addql	#4,%sp
    490 	moveml	%sp@+,#0x0303
    491 	addql	#2,%sp
    492 	jra	_ASM_LABEL(rei)
    493 
    494 /*
    495  * Interrupt handlers.
    496  * All device interrupts are auto-vectored.  Most can be configured
    497  * to interrupt in the range IPL2 to IPL6.  Here are our assignments:
    498  *
    499  *	Level 0:
    500  *	Level 1:
    501  *	Level 2:	SCSI SPC
    502  *	Level 3:	LANCE Ethernet
    503  *	Level 4:
    504  *	Level 5:	System Clock
    505  *	Level 6:	Internal SIO used uPD7201A
    506  *	Level 7:	NMI: Abort Key (Dispatched vector to ROM monitor)
    507  */
    508 
    509 ENTRY_NOPROFILE(lev2intr)
    510 	clrw	%sp@-
    511 	moveml	#0xC0C0,%sp@-
    512 	jbsr	_C_LABEL(scintr)
    513 	moveml	%sp@+,#0x0303
    514 	addql	#2,%sp
    515 	jra	_ASM_LABEL(rei)
    516 
    517 ENTRY_NOPROFILE(lev3intr)
    518 	clrw	%sp@-
    519 	moveml	#0xC0C0,%sp@-
    520 	jbsr	_C_LABEL(lance_intr)
    521 	moveml	%sp@+,#0x0303
    522 	addql	#2,%sp
    523 	jra	_ASM_LABEL(rei)
    524 
    525 ENTRY_NOPROFILE(lev5intr)
    526 	clrw	%sp@-			| push pad word
    527 	moveml	#0xC0C0,%sp@-		| save scratch regs
    528 	movl	#CLOCK_REG,%a0		| get clock CR addr
    529 	movb	#CLK_CLR,%a0@		| reset system clock
    530 	lea	%sp@(16),%a1		| get pointer to PS
    531 	movl	%a1@,%sp@-		| push padded PS
    532 	movl	%a1@(4),%sp@-		| push PC
    533 	jbsr	_C_LABEL(hardclock)	| call generic clock int routine
    534 	addql	#8,%sp			| pop params
    535 	moveml	%sp@+,#0x0303		| restore scratch regs
    536 	addql	#2,%sp			| pop pad word
    537 	jra	_ASM_LABEL(rei)		| all done
    538 
    539 ENTRY_NOPROFILE(hardclock)
    540 	addql	#1,_C_LABEL(tick)
    541 	rts
    542 
    543 BSS(tick,4)
    544 
    545 ENTRY_NOPROFILE(lev6intr)
    546 	clrw	%sp@-
    547 	moveml	#0xC0C0,%sp@-
    548 	jbsr	_C_LABEL(_siointr)
    549 	moveml	%sp@+,#0x0303
    550 	addql	#2,%sp
    551 	jra	_ASM_LABEL(rei)
    552 
    553 
    554 /*
    555  * Emulation of VAX REI instruction.
    556  *
    557  * This code deals with checking for and servicing ASTs
    558  * (profiling, scheduling) and software interrupts (network, softclock).
    559  * We check for ASTs first, just like the VAX.  To avoid excess overhead
    560  * the T_ASTFLT handling code will also check for software interrupts so we
    561  * do not have to do it here.
    562  *
    563  * This code is complicated by the fact that sendsig may have been called
    564  * necessitating a stack cleanup.  A cleanup should only be needed at this
    565  * point for coprocessor mid-instruction frames (type 9), but we also test
    566  * for bus error frames (type 10 and 11).
    567  */
    568 #if 0
    569 	.comm	_ssir,1
    570 ASENTRY_NOPROFILE(rei)
    571 #ifdef DEBUG
    572 	tstl	_C_LABEL(panicstr)		| have we paniced?
    573 	jne	Ldorte			| yes, do not make matters worse
    574 #endif
    575 	btst	#PCB_ASTB,_u+PCB_FLAGS+1| AST pending?
    576 	jeq	Lchksir			| no, go check for SIR
    577 	btst	#5,%sp@			| yes, are we returning to user mode?
    578 	jne	Lchksir			| no, go check for SIR
    579 	clrw	%sp@-			| pad SR to longword
    580 	moveml	#0xFFFF,%sp@-		| save all registers
    581 	movl	%usp,%a1		| including
    582 	movl	%a1,%sp@(60)		|    the users SP
    583 	clrl	%sp@-			| VA == none
    584 	clrl	%sp@-			| code == none
    585 	movl	#T_ASTFLT,%sp@-		| type == async system trap
    586 	jbsr	_C_LABEL(trap)		| go handle it
    587 	lea	%sp@(12),%sp		| pop value args
    588 	movl	%sp@(60),%a0		| restore
    589 	movl	%a0,%usp		|   user SP
    590 	moveml	%sp@+,#0x7FFF		| and all remaining registers
    591 	addql	#4,%sp			| toss SSP
    592 	tstw	%sp@+			| do we need to clean up stack?
    593 	jeq	Ldorte			| no, just continue
    594 	btst	#7,%sp@(6)		| type 9/10/11 frame?
    595 	jeq	Ldorte			| no, nothing to do
    596 	btst	#5,%sp@(6)		| type 9?
    597 	jne	Last1			| no, skip
    598 	movw	%sp@,%sp@(12)		| yes, push down SR
    599 	movl	%sp@(2),%sp@(14)	| and PC
    600 	clrw	%sp@(18)		| and mark as type 0 frame
    601 	lea	%sp@(12),%sp		| clean the excess
    602 	jra	Ldorte			| all done
    603 Last1:
    604 	btst	#4,%sp@(6)		| type 10?
    605 	jne	Last2			| no, skip
    606 	movw	%sp@,%sp@(24)		| yes, push down SR
    607 	movl	%sp@(2),%sp@(26)	| and PC
    608 	clrw	%sp@(30)		| and mark as type 0 frame
    609 	lea	%sp@(24),%sp		| clean the excess
    610 	jra	Ldorte			| all done
    611 Last2:
    612 	movw	%sp@,%sp@(84)		| type 11, push down SR
    613 	movl	%sp@(2),%sp@(86)	| and PC
    614 	clrw	%sp@(90)		| and mark as type 0 frame
    615 	lea	%sp@(84),%sp		| clean the excess
    616 	jra	Ldorte			| all done
    617 Lchksir:
    618 	tstb	_ssir			| SIR pending?
    619 	jeq	Ldorte			| no, all done
    620 	movl	%d0,%sp@-		| need a scratch register
    621 	movw	%sp@(4),%d0		| get SR
    622 	andw	#PSL_IPL7,%d0		| mask all but IPL
    623 	jne	Lnosir			| came from interrupt, no can do
    624 	movl	%sp@+,%d0		| restore scratch register
    625 Lgotsir:
    626 	movw	#SPL1,%sr		| prevent others from servicing int
    627 	tstb	_ssir			| too late?
    628 	jeq	Ldorte			| yes, oh well...
    629 	clrw	%sp@-			| pad SR to longword
    630 	moveml	#0xFFFF,%sp@-		| save all registers
    631 	movl	%usp,%a1		| including
    632 	movl	%a1,%sp@(60)		|    the users SP
    633 	clrl	%sp@-			| VA == none
    634 	clrl	%sp@-			| code == none
    635 	movl	#T_SSIR,%sp@-		| type == software interrupt
    636 	jbsr	_trap			| go handle it
    637 	lea	%sp@(12),%sp		| pop value args
    638 	movl	%sp@(60),%a0		| restore
    639 	movl	%a0,%usp		|   user SP
    640 	moveml	%sp@+,#0x7FFF		| and all remaining registers
    641 	addql	#6,%sp			| pop SSP and align word
    642 	rte
    643 Lnosir:
    644 	movl	%sp@+,%d0		| restore scratch register
    645 Ldorte:
    646 #else
    647 ASENTRY_NOPROFILE(rei)			| dummy Entry of rei
    648 #endif
    649 	rte				| real return
    650 
    651 /*
    652  * non-local gotos
    653  */
    654 ALTENTRY(savectx, _setjmp)
    655 ENTRY(setjmp)
    656 	movl	%sp@(4),%a0	| savearea pointer
    657 	moveml	#0xFCFC,%a0@	| save d2-d7/a2-a7
    658 	movl	%sp@,%a0@(48)	| and return address
    659 	moveq	#0,%d0		| return 0
    660 	rts
    661 
    662 ENTRY(qsetjmp)
    663 	movl	%sp@(4),%a0	| savearea pointer
    664 	lea	%a0@(40),%a0	| skip regs we do not save
    665 	movl	%a6,%a0@+		| save FP
    666 	movl	%sp,%a0@+		| save SP
    667 	movl	%sp@,%a0@		| and return address
    668 	moveq	#0,%d0		| return 0
    669 	rts
    670 
    671 ENTRY(longjmp)
    672 	movl	%sp@(4),%a0
    673 	moveml	%a0@+,#0xFCFC
    674 	movl	%a0@,%sp@
    675 	moveq	#1,%d0
    676 	rts
    677 
    678 ENTRY_NOPROFILE(getsfc)
    679 	movc	%sfc,%d0
    680 	rts
    681 ENTRY_NOPROFILE(getdfc)
    682 	movc	%dfc,%d0
    683 	rts
    684 
    685 /*
    686  * Set processor priority level calls.  Most could (should) be replaced
    687  * by inline asm expansions.  However, SPL0 and SPLX require special
    688  * handling.  If we are returning to the base processor priority (SPL0)
    689  * we need to check for our emulated software interrupts.
    690  */
    691 
    692 ENTRY(spl0)
    693 	moveq	#0,%d0
    694 	movw	%sr,%d0			| get old SR for return
    695 	movw	#PSL_LOWIPL,%sr		| restore new SR
    696 |	jra	Lsplsir
    697 	rts
    698 
    699 ENTRY(splx)
    700 	moveq	#0,%d0
    701 	movw	%sr,%d0			| get current SR for return
    702 	movw	%sp@(6),%d1		| get new value
    703 	movw	%d1,%sr			| restore new SR
    704 |	andw	#PSL_IPL7,%d1		| mask all but PSL_IPL
    705 |	jne	Lspldone		| non-zero, all done
    706 |Lsplsir:
    707 |	tstb	_ssir			| software interrupt pending?
    708 |	jeq	Lspldone		| no, all done
    709 |	subql	#4,%sp			| make room for RTE frame
    710 |	movl	%sp@(4),%sp@(2)		| position return address
    711 |	clrw	%sp@(6)			| set frame type 0
    712 |	movw	#PSL_LOWIPL,%sp@	| and new SR
    713 |	jra	Lgotsir			| go handle it
    714 |Lspldone:
    715 	rts
    716 
    717 ENTRY(spl1)
    718 	moveq	#0,%d0
    719 	movw	%sr,%d0
    720 	movw	#SPL1,%sr
    721 	rts
    722 
    723 ALTENTRY(splscsi, _spl2)
    724 ENTRY(spl2)
    725 	moveq	#0,%d0
    726 	movw	%sr,%d0
    727 	movw	#SPL2,%sr
    728 	rts
    729 
    730 ENTRY(spl3)
    731 	moveq	#0,%d0
    732 	movw	%sr,%d0
    733 	movw	#SPL3,%sr
    734 	rts
    735 
    736 ENTRY(spl4)
    737 	moveq	#0,%d0
    738 	movw	%sr,%d0
    739 	movw	#SPL4,%sr
    740 	rts
    741 
    742 ENTRY(spl5)
    743 	moveq	#0,%d0
    744 	movw	%sr,%d0
    745 	movw	#SPL5,%sr
    746 	rts
    747 
    748 ENTRY(spl6)
    749 	moveq	#0,%d0
    750 	movw	%sr,%d0
    751 	movw	#SPL6,%sr
    752 	rts
    753 
    754 ALTENTRY(splhigh, _spl7)
    755 ENTRY(spl7)
    756 	moveq	#0,%d0
    757 	movw	%sr,%d0
    758 	movw	#PSL_HIGHIPL,%sr
    759 	rts
    760 
    761 
    762 	.data
    763 
    764 /*
    765  * Memory Information Field for secondary booter memory allocator
    766  */
    767 
    768 GLOBAL(prgcore)
    769 	.long	0
    770 	.long	0
    771 	.long	0
    772 
    773 ASLOCAL(gotoROM)
    774 	.long	0
    775 
    776 GLOBAL(dipsw1)
    777 	.long	0
    778 
    779 GLOBAL(dipsw2)
    780 	.long	0
    781 
    782 GLOBAL(cputype)
    783 	.long	CPU_68030
    784