xref: /netbsd-src/sys/arch/luna68k/stand/boot/locore.S (revision 1580a27b92f58fcdcb23fdfbc04a7c2b54a0b7c8)
1/*	$NetBSD: locore.S,v 1.11 2014/03/24 10:46:58 martin 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
107ASENTRY_NOPROFILE(start)
108ASGLOBAL(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
201ASENTRY_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
213Lbssclr:
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
263Lnot68030:
264	movl	#CPU_68040,%d0
265Lstart0:
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
279ENTRY_NOPROFILE(exit)
280GLOBAL(_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
292ENTRY_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)
297ENTRY_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
308LbeX0:
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
313LbeX1:
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
318Lbe0:
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
326Lbe3:
327	btst	#15,%d0			| FC set?
328	jeq	Lbe10			| no, done
329	addql	#2,%d1			| yes, adjust address
330	jra	Lbe10			| done
331Lbe4:
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
336Lbe10:
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
353Lismerr:
354	movl	#T_MMUFLT,%sp@-		| show that we are an MMU fault
355	jra	Lbexit			| and deal with it
356Lisaerr:
357	movl	#T_ADDRERR,%sp@-	| mark address error
358	jra	Lbexit			| and deal with it
359Lisberr:
360	movl	#T_BUSERR,%sp@-		| mark bus error
361Lbexit:
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
379Lbex1:
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
387Lbex2:
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
394ENTRY_NOPROFILE(illinst)
395	clrw	%sp@-
396	moveml	#0xFFFF,%sp@-
397	moveq	#T_ILLINST,%d0
398	jra	_C_LABEL(fault)
399
400ENTRY_NOPROFILE(zerodiv)
401	clrw	%sp@-
402	moveml	#0xFFFF,%sp@-
403	moveq	#T_ZERODIV,%d0
404	jra	_C_LABEL(fault)
405
406ENTRY_NOPROFILE(chkinst)
407	clrw	%sp@-
408	moveml	#0xFFFF,%sp@-
409	moveq	#T_CHKINST,%d0
410	jra	_C_LABEL(fault)
411
412ENTRY_NOPROFILE(trapvinst)
413	clrw	%sp@-
414	moveml	#0xFFFF,%sp@-
415	moveq	#T_TRAPVINST,%d0
416	jra	_C_LABEL(fault)
417
418ENTRY_NOPROFILE(privinst)
419	clrw	%sp@-
420	moveml	#0xFFFF,%sp@-
421	moveq	#T_PRIVINST,%d0
422	jra	_C_LABEL(fault)
423
424ENTRY_NOPROFILE(coperr)
425	clrw	%sp@-
426	moveml	#0xFFFF,%sp@-
427	moveq	#T_COPERR,%d0
428	jra	_C_LABEL(fault)
429
430ENTRY_NOPROFILE(fmterr)
431	clrw	%sp@-
432	moveml	#0xFFFF,%sp@-
433	moveq	#T_FMTERR,%d0
434	jra	_C_LABEL(fault)
435
436ENTRY_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
451Lfptnull:
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
469ENTRY_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
483ENTRY_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
509ENTRY_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
517ENTRY_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
525ENTRY_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
539ENTRY_NOPROFILE(hardclock)
540	addql	#1,_C_LABEL(tick)
541	rts
542
543BSS(tick,4)
544
545ENTRY_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
570ASENTRY_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
603Last1:
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
611Last2:
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
617Lchksir:
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
625Lgotsir:
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
643Lnosir:
644	movl	%sp@+,%d0		| restore scratch register
645Ldorte:
646#else
647ASENTRY_NOPROFILE(rei)			| dummy Entry of rei
648#endif
649	rte				| real return
650
651/*
652 * non-local gotos
653 */
654ALTENTRY(savectx, _setjmp)
655ENTRY(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
662ENTRY(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
671ENTRY(longjmp)
672	movl	%sp@(4),%a0
673	moveml	%a0@+,#0xFCFC
674	movl	%a0@,%sp@
675	moveq	#1,%d0
676	rts
677
678ENTRY_NOPROFILE(getsfc)
679	movc	%sfc,%d0
680	rts
681ENTRY_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
692ENTRY(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
699ENTRY(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
717ENTRY(spl1)
718	moveq	#0,%d0
719	movw	%sr,%d0
720	movw	#SPL1,%sr
721	rts
722
723ALTENTRY(splscsi, _spl2)
724ENTRY(spl2)
725	moveq	#0,%d0
726	movw	%sr,%d0
727	movw	#SPL2,%sr
728	rts
729
730ENTRY(spl3)
731	moveq	#0,%d0
732	movw	%sr,%d0
733	movw	#SPL3,%sr
734	rts
735
736ENTRY(spl4)
737	moveq	#0,%d0
738	movw	%sr,%d0
739	movw	#SPL4,%sr
740	rts
741
742ENTRY(spl5)
743	moveq	#0,%d0
744	movw	%sr,%d0
745	movw	#SPL5,%sr
746	rts
747
748ENTRY(spl6)
749	moveq	#0,%d0
750	movw	%sr,%d0
751	movw	#SPL6,%sr
752	rts
753
754ALTENTRY(splhigh, _spl7)
755ENTRY(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
768GLOBAL(prgcore)
769	.long	0
770	.long	0
771	.long	0
772
773ASLOCAL(gotoROM)
774	.long	0
775
776GLOBAL(dipsw1)
777	.long	0
778
779GLOBAL(dipsw2)
780	.long	0
781
782GLOBAL(cputype)
783	.long	CPU_68030
784