1/*	$NetBSD: locore.S,v 1.15 2022/03/16 20:31:01 andvar 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(exit)		/* 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/* clear BSS area */
206	movl	#_C_LABEL(edata),%a2	| start of BSS
207	movl	#_C_LABEL(end),%a3	| end
208Lbssclr:
209	clrb	%a2@+			| clear BSS
210	cmpl	%a2,%a3			| done?
211	bne	Lbssclr			| no, keep going
212
213/* save address to goto ROM monitor */
214	movec	%vbr,%a0		| save ROM vbr
215	movl	%a0,_ASM_LABEL(romvbr)
216	movl	#_ASM_LABEL(Reset),%a0	| BP vbr to %a0
217/* copy ROM vectors */
218	movl	%a0@(ILLGINST),_ASM_LABEL(Reset) + ILLGINST
219	movl	%a0@(EVTRAPF),_ASM_LABEL(Reset) + EVTRAPF
220	movec	%a0,%vbr
221
222	movw	DIPSW,%d0
223	clrl	%d1
224	movw	%d0,%d1
225	lsrl	#8,%d1
226	movl	%d1,_C_LABEL(dipsw1)
227	movb	%d0,%d1
228	movl	%d1,_C_LABEL(dipsw2)
229
230/* determine our CPU */
231
232	/* XXX should be generated via assym.h */
233	CACHE_OFF = 0x0808
234	DC_FREEZE = 0x0200
235	CPU_68030 = 1
236	CPU_68040 = 2
237
238	movl	#CACHE_OFF,%d0
239	movc	%d0,%cacr		| clear and disable on-chip cache(s)
240	movl	#DC_FREEZE,%d0		| data freeze bit
241	movc	%d0,%cacr		|   only exists on 68030
242	movc	%cacr,%d0		| read it back
243	tstl	%d0			| zero?
244	jeq	Lnot68030		| yes, we have 68040
245	movl	#CPU_68030,%d0
246	jra	Lstart0
247Lnot68030:
248	movl	#CPU_68040,%d0
249Lstart0:
250	movl	%d0,_C_LABEL(cputype)
251
252/* final setup for C code */
253	movw	#PSL_LOWIPL,%sr		| enable interrupts
254	jsr	_C_LABEL(main)		| lets go
255	jsr	start
256
257/*
258 * exit to ROM monitor
259 */
260ENTRY_NOPROFILE(exit)
261GLOBAL(_rtt)
262	movw	#PSL_HIGHIPL,%sr	| no interrupts
263	movl	_ASM_LABEL(romvbr),%a0
264	movec	%a0,%vbr
265	movl	%a0@(NMIVEC),%a1
266	jmp	%a1@
267
268/*
269 * Trap/interrupt vector routines
270 */
271
272ENTRY_NOPROFILE(buserr)
273	tstl	_C_LABEL(nofault)	| device probe?
274	jeq	_C_LABEL(addrerr)	| no, handle as usual
275	movl	_C_LABEL(nofault),%sp@-	| yes,
276	jbsr	_C_LABEL(longjmp)	|  longjmp(nofault)
277ENTRY_NOPROFILE(addrerr)
278	clrw	%sp@-			| pad SR to longword
279	moveml	#0xFFFF,%sp@-		| save user registers
280	movl	%usp,%a0		| save the user SP
281	movl	%a0,%sp@(60)		|   in the savearea
282	lea	%sp@(64),%a1		| grab base of HW berr frame
283	movw	%a1@(12),%d0		| grab SSW for fault processing
284	btst	#12,%d0			| RB set?
285	jeq	LbeX0			| no, test RC
286	bset	#14,%d0			| yes, must set FB
287	movw	%d0,%a1@(12)		| for hardware too
288LbeX0:
289	btst	#13,%d0			| RC set?
290	jeq	LbeX1			| no, skip
291	bset	#15,%d0			| yes, must set FC
292	movw	%d0,%a1@(12)		| for hardware too
293LbeX1:
294	btst	#8,%d0			| data fault?
295	jeq	Lbe0			| no, check for hard cases
296	movl	%a1@(18),%d1		| fault address is as given in frame
297	jra	Lbe10			| thats it
298Lbe0:
299	btst	#4,%a1@(8)		| long (type B) stack frame?
300	jne	Lbe4			| yes, go handle
301	movl	%a1@(4),%d1		| no, can use save PC
302	btst	#14,%d0			| FB set?
303	jeq	Lbe3			| no, try FC
304	addql	#4,%d1			| yes, adjust address
305	jra	Lbe10			| done
306Lbe3:
307	btst	#15,%d0			| FC set?
308	jeq	Lbe10			| no, done
309	addql	#2,%d1			| yes, adjust address
310	jra	Lbe10			| done
311Lbe4:
312	movl	%a1@(38),%d1		| long format, use stage B address
313	btst	#15,%d0			| FC set?
314	jeq	Lbe10			| no, all done
315	subql	#2,%d1			| yes, adjust address
316Lbe10:
317	movl	%d1,%sp@-		| push fault VA
318	movw	%d0,%sp@-		| and SSW
319	clrw	%sp@-			|   padded to longword
320	movw	%a1@(8),%d0		| get frame format/vector offset
321	andw	#0x0FFF,%d0		| clear out frame format
322	cmpw	#12,%d0			| address error vector?
323	jeq	Lisaerr			| yes, go to it
324#if 0
325	movl	%d1,%a0			| fault address
326	.long	0xf0109e11		| ptestr #1,%a0@,#7
327	.long	0xf0176200		| pmove %psr,%sp@
328	btst	#7,%sp@			| bus error bit set?
329	jeq	Lismerr			| no, must be MMU fault
330	clrw	%sp@			| yes, re-clear pad word
331#endif
332	jra	Lisberr			| and process as normal bus error
333Lismerr:
334	movl	#T_MMUFLT,%sp@-		| show that we are an MMU fault
335	jra	Lbexit			| and deal with it
336Lisaerr:
337	movl	#T_ADDRERR,%sp@-	| mark address error
338	jra	Lbexit			| and deal with it
339Lisberr:
340	movl	#T_BUSERR,%sp@-		| mark bus error
341Lbexit:
342	jbsr	_C_LABEL(trap)		| handle the error
343	lea	%sp@(12),%sp		| pop value args
344	movl	%sp@(60),%a0		| restore user SP
345	movl	%a0,%usp		|   from save area
346	moveml	%sp@+,#0x7FFF		| restore most user regs
347	addql	#4,%sp			| toss SSP
348	tstw	%sp@+			| do we need to clean up stack?
349	jeq	_ASM_LABEL(rei)		| no, just continue
350	btst	#7,%sp@(6)		| type 9/10/11 frame?
351	jeq	_ASM_LABEL(rei)		| no, nothing to do
352	btst	#5,%sp@(6)		| type 9?
353	jne	Lbex1			| no, skip
354	movw	%sp@,%sp@(12)		| yes, push down SR
355	movl	%sp@(2),%sp@(14)	| and PC
356	clrw	%sp@(18)		| and mark as type 0 frame
357	lea	%sp@(12),%sp		| clean the excess
358	jra	_ASM_LABEL(rei)		| all done
359Lbex1:
360	btst	#4,%sp@(6)		| type 10?
361	jne	Lbex2			| no, skip
362	movw	%sp@,%sp@(24)		| yes, push down SR
363	movl	%sp@(2),%sp@(26)	| and PC
364	clrw	%sp@(30)		| and mark as type 0 frame
365	lea	%sp@(24),%sp		| clean the excess
366	jra	_ASM_LABEL(rei)		| all done
367Lbex2:
368	movw	%sp@,%sp@(84)		| type 11, push down SR
369	movl	%sp@(2),%sp@(86)	| and PC
370	clrw	%sp@(90)		| and mark as type 0 frame
371	lea	%sp@(84),%sp		| clean the excess
372	jra	_ASM_LABEL(rei)		| all done
373
374ENTRY_NOPROFILE(illinst)
375	clrw	%sp@-
376	moveml	#0xFFFF,%sp@-
377	moveq	#T_ILLINST,%d0
378	jra	_C_LABEL(fault)
379
380ENTRY_NOPROFILE(zerodiv)
381	clrw	%sp@-
382	moveml	#0xFFFF,%sp@-
383	moveq	#T_ZERODIV,%d0
384	jra	_C_LABEL(fault)
385
386ENTRY_NOPROFILE(chkinst)
387	clrw	%sp@-
388	moveml	#0xFFFF,%sp@-
389	moveq	#T_CHKINST,%d0
390	jra	_C_LABEL(fault)
391
392ENTRY_NOPROFILE(trapvinst)
393	clrw	%sp@-
394	moveml	#0xFFFF,%sp@-
395	moveq	#T_TRAPVINST,%d0
396	jra	_C_LABEL(fault)
397
398ENTRY_NOPROFILE(privinst)
399	clrw	%sp@-
400	moveml	#0xFFFF,%sp@-
401	moveq	#T_PRIVINST,%d0
402	jra	_C_LABEL(fault)
403
404ENTRY_NOPROFILE(coperr)
405	clrw	%sp@-
406	moveml	#0xFFFF,%sp@-
407	moveq	#T_COPERR,%d0
408	jra	_C_LABEL(fault)
409
410ENTRY_NOPROFILE(fmterr)
411	clrw	%sp@-
412	moveml	#0xFFFF,%sp@-
413	moveq	#T_FMTERR,%d0
414	jra	_C_LABEL(fault)
415
416ENTRY_NOPROFILE(fptrap)
417#ifdef FPCOPROC
418	clrw	%sp@-		| pad SR to longword
419	moveml	#0xFFFF,%sp@-	| save user registers
420	movl	%usp,%a0	| and save
421	movl	%a0,%sp@(60)	|   the user stack pointer
422	clrl	%sp@-		| no VA arg
423#if 0
424	lea	_u+PCB_FPCTX,%a0	| address of FP savearea
425	.word	0xf310		| fsave %a0@
426	tstb	%a0@		| null state frame?
427	jeq	Lfptnull	| yes, safe
428	clrw	%d0		| no, need to tweak BIU
429	movb	a0@(1),d0	| get frame size
430	bset	#3,%a0@(0,%d0:w)	| set exc_pend bit of BIU
431Lfptnull:
432	.word	0xf227,0xa800	| fmovem %fpsr,%sp@- (code arg)
433	.word	0xf350		| frestore %a0@
434#else
435	clrl	%sp@-		| push dummy FPSR
436#endif
437	movl	#T_FPERR,%sp@-	| push type arg
438	jbsr	_C_LABEL(trap)	| call trap
439	lea	%sp@(12),%sp	| pop value args
440	movl	%sp@(60),%a0	| restore
441	movl	%a0,%usp	|   user SP
442	moveml	%sp@+,#0x7FFF	| and remaining user registers
443	addql	#6,%sp		| pop SSP and align word
444	jra	_ASM_LABEL(rei)	| all done
445#else
446	jra	_C_LABEL(badtrap)	| treat as an unexpected trap
447#endif
448
449ENTRY_NOPROFILE(fault)
450	movl	%usp,%a0	| get and save
451	movl	%a0,%sp@(60)	|   the user stack pointer
452	clrl	%sp@-		| no VA arg
453	clrl	%sp@-		| or code arg
454	movl	%d0,%sp@-	| push trap type
455	jbsr	_C_LABEL(trap)	| handle trap
456	lea	%sp@(12),%sp	| pop value args
457	movl	%sp@(60),%a0	| restore
458	movl	%a0,%usp	|   user SP
459	moveml	%sp@+,#0x7FFF	| restore most user regs
460	addql	#6,%sp		| pop SP and pad word
461	jra	_ASM_LABEL(rei)	| all done
462
463ENTRY_NOPROFILE(badtrap)
464	clrw	%sp@-
465	moveml	#0xC0C0,%sp@-
466	movw	%sp@(24),%sp@-
467	clrw	%sp@-
468	jbsr	_C_LABEL(straytrap)
469	addql	#4,%sp
470	moveml	%sp@+,#0x0303
471	addql	#2,%sp
472	jra	_ASM_LABEL(rei)
473
474/*
475 * Interrupt handlers.
476 * All device interrupts are auto-vectored.  Most can be configured
477 * to interrupt in the range IPL2 to IPL6.  Here are our assignments:
478 *
479 *	Level 0:
480 *	Level 1:
481 *	Level 2:	SCSI SPC
482 *	Level 3:	LANCE Ethernet
483 *	Level 4:
484 *	Level 5:	System Clock
485 *	Level 6:	Internal SIO used uPD7201A
486 *	Level 7:	NMI: Abort Key (Dispatched vector to ROM monitor)
487 */
488
489ENTRY_NOPROFILE(lev2intr)
490	clrw	%sp@-
491	moveml	#0xC0C0,%sp@-
492	jbsr	_C_LABEL(scintr)
493	moveml	%sp@+,#0x0303
494	addql	#2,%sp
495	jra	_ASM_LABEL(rei)
496
497ENTRY_NOPROFILE(lev3intr)
498	clrw	%sp@-
499	moveml	#0xC0C0,%sp@-
500	jbsr	_C_LABEL(lance_intr)
501	moveml	%sp@+,#0x0303
502	addql	#2,%sp
503	jra	_ASM_LABEL(rei)
504
505ENTRY_NOPROFILE(lev5intr)
506	clrw	%sp@-			| push pad word
507	moveml	#0xC0C0,%sp@-		| save scratch regs
508	movl	#CLOCK_REG,%a0		| get clock CR addr
509	movb	#CLK_CLR,%a0@		| reset system clock
510	lea	%sp@(16),%a1		| get pointer to PS
511	movl	%a1@,%sp@-		| push padded PS
512	movl	%a1@(4),%sp@-		| push PC
513	jbsr	_C_LABEL(hardclock)	| call generic clock int routine
514	addql	#8,%sp			| pop params
515	moveml	%sp@+,#0x0303		| restore scratch regs
516	addql	#2,%sp			| pop pad word
517	jra	_ASM_LABEL(rei)		| all done
518
519ENTRY_NOPROFILE(hardclock)
520	addql	#1,_C_LABEL(tick)
521	rts
522
523BSS(tick,4)
524
525ENTRY_NOPROFILE(lev6intr)
526	clrw	%sp@-
527	moveml	#0xC0C0,%sp@-
528	jbsr	_C_LABEL(_siointr)
529	moveml	%sp@+,#0x0303
530	addql	#2,%sp
531	jra	_ASM_LABEL(rei)
532
533
534/*
535 * Emulation of VAX REI instruction.
536 *
537 * This code deals with checking for and servicing ASTs
538 * (profiling, scheduling) and software interrupts (network, softclock).
539 * We check for ASTs first, just like the VAX.  To avoid excess overhead
540 * the T_ASTFLT handling code will also check for software interrupts so we
541 * do not have to do it here.
542 *
543 * This code is complicated by the fact that sendsig may have been called
544 * necessitating a stack cleanup.  A cleanup should only be needed at this
545 * point for coprocessor mid-instruction frames (type 9), but we also test
546 * for bus error frames (type 10 and 11).
547 */
548#if 0
549	.comm	_ssir,1
550ASENTRY_NOPROFILE(rei)
551#ifdef DEBUG
552	tstl	_C_LABEL(panicstr)		| have we panicked?
553	jne	Ldorte			| yes, do not make matters worse
554#endif
555	btst	#PCB_ASTB,_u+PCB_FLAGS+1| AST pending?
556	jeq	Lchksir			| no, go check for SIR
557	btst	#5,%sp@			| yes, are we returning to user mode?
558	jne	Lchksir			| no, go check for SIR
559	clrw	%sp@-			| pad SR to longword
560	moveml	#0xFFFF,%sp@-		| save all registers
561	movl	%usp,%a1		| including
562	movl	%a1,%sp@(60)		|    the users SP
563	clrl	%sp@-			| VA == none
564	clrl	%sp@-			| code == none
565	movl	#T_ASTFLT,%sp@-		| type == async system trap
566	jbsr	_C_LABEL(trap)		| go handle it
567	lea	%sp@(12),%sp		| pop value args
568	movl	%sp@(60),%a0		| restore
569	movl	%a0,%usp		|   user SP
570	moveml	%sp@+,#0x7FFF		| and all remaining registers
571	addql	#4,%sp			| toss SSP
572	tstw	%sp@+			| do we need to clean up stack?
573	jeq	Ldorte			| no, just continue
574	btst	#7,%sp@(6)		| type 9/10/11 frame?
575	jeq	Ldorte			| no, nothing to do
576	btst	#5,%sp@(6)		| type 9?
577	jne	Last1			| no, skip
578	movw	%sp@,%sp@(12)		| yes, push down SR
579	movl	%sp@(2),%sp@(14)	| and PC
580	clrw	%sp@(18)		| and mark as type 0 frame
581	lea	%sp@(12),%sp		| clean the excess
582	jra	Ldorte			| all done
583Last1:
584	btst	#4,%sp@(6)		| type 10?
585	jne	Last2			| no, skip
586	movw	%sp@,%sp@(24)		| yes, push down SR
587	movl	%sp@(2),%sp@(26)	| and PC
588	clrw	%sp@(30)		| and mark as type 0 frame
589	lea	%sp@(24),%sp		| clean the excess
590	jra	Ldorte			| all done
591Last2:
592	movw	%sp@,%sp@(84)		| type 11, push down SR
593	movl	%sp@(2),%sp@(86)	| and PC
594	clrw	%sp@(90)		| and mark as type 0 frame
595	lea	%sp@(84),%sp		| clean the excess
596	jra	Ldorte			| all done
597Lchksir:
598	tstb	_ssir			| SIR pending?
599	jeq	Ldorte			| no, all done
600	movl	%d0,%sp@-		| need a scratch register
601	movw	%sp@(4),%d0		| get SR
602	andw	#PSL_IPL7,%d0		| mask all but IPL
603	jne	Lnosir			| came from interrupt, no can do
604	movl	%sp@+,%d0		| restore scratch register
605Lgotsir:
606	movw	#SPL1,%sr		| prevent others from servicing int
607	tstb	_ssir			| too late?
608	jeq	Ldorte			| yes, oh well...
609	clrw	%sp@-			| pad SR to longword
610	moveml	#0xFFFF,%sp@-		| save all registers
611	movl	%usp,%a1		| including
612	movl	%a1,%sp@(60)		|    the users SP
613	clrl	%sp@-			| VA == none
614	clrl	%sp@-			| code == none
615	movl	#T_SSIR,%sp@-		| type == software interrupt
616	jbsr	_trap			| go handle it
617	lea	%sp@(12),%sp		| pop value args
618	movl	%sp@(60),%a0		| restore
619	movl	%a0,%usp		|   user SP
620	moveml	%sp@+,#0x7FFF		| and all remaining registers
621	addql	#6,%sp			| pop SSP and align word
622	rte
623Lnosir:
624	movl	%sp@+,%d0		| restore scratch register
625Ldorte:
626#else
627ASENTRY_NOPROFILE(rei)			| dummy Entry of rei
628#endif
629	rte				| real return
630
631/*
632 * non-local gotos
633 */
634ALTENTRY(savectx, _setjmp)
635ENTRY(setjmp)
636	movl	%sp@(4),%a0	| savearea pointer
637	moveml	#0xFCFC,%a0@	| save d2-d7/a2-a7
638	movl	%sp@,%a0@(48)	| and return address
639	moveq	#0,%d0		| return 0
640	rts
641
642ENTRY(qsetjmp)
643	movl	%sp@(4),%a0	| savearea pointer
644	lea	%a0@(40),%a0	| skip regs we do not save
645	movl	%a6,%a0@+		| save FP
646	movl	%sp,%a0@+		| save SP
647	movl	%sp@,%a0@		| and return address
648	moveq	#0,%d0		| return 0
649	rts
650
651ENTRY(longjmp)
652	movl	%sp@(4),%a0
653	moveml	%a0@+,#0xFCFC
654	movl	%a0@,%sp@
655	moveq	#1,%d0
656	rts
657
658ENTRY_NOPROFILE(getsfc)
659	movc	%sfc,%d0
660	rts
661ENTRY_NOPROFILE(getdfc)
662	movc	%dfc,%d0
663	rts
664
665/*
666 * Set processor priority level calls.  Most could (should) be replaced
667 * by inline asm expansions.  However, SPL0 and SPLX require special
668 * handling.  If we are returning to the base processor priority (SPL0)
669 * we need to check for our emulated software interrupts.
670 */
671
672ENTRY(spl0)
673	moveq	#0,%d0
674	movw	%sr,%d0			| get old SR for return
675	movw	#PSL_LOWIPL,%sr		| restore new SR
676|	jra	Lsplsir
677	rts
678
679ENTRY(splx)
680	moveq	#0,%d0
681	movw	%sr,%d0			| get current SR for return
682	movw	%sp@(6),%d1		| get new value
683	movw	%d1,%sr			| restore new SR
684|	andw	#PSL_IPL7,%d1		| mask all but PSL_IPL
685|	jne	Lspldone		| non-zero, all done
686|Lsplsir:
687|	tstb	_ssir			| software interrupt pending?
688|	jeq	Lspldone		| no, all done
689|	subql	#4,%sp			| make room for RTE frame
690|	movl	%sp@(4),%sp@(2)		| position return address
691|	clrw	%sp@(6)			| set frame type 0
692|	movw	#PSL_LOWIPL,%sp@	| and new SR
693|	jra	Lgotsir			| go handle it
694|Lspldone:
695	rts
696
697ENTRY(spl1)
698	moveq	#0,%d0
699	movw	%sr,%d0
700	movw	#SPL1,%sr
701	rts
702
703ALTENTRY(splscsi, _spl2)
704ENTRY(spl2)
705	moveq	#0,%d0
706	movw	%sr,%d0
707	movw	#SPL2,%sr
708	rts
709
710ENTRY(spl3)
711	moveq	#0,%d0
712	movw	%sr,%d0
713	movw	#SPL3,%sr
714	rts
715
716ENTRY(spl4)
717	moveq	#0,%d0
718	movw	%sr,%d0
719	movw	#SPL4,%sr
720	rts
721
722ENTRY(spl5)
723	moveq	#0,%d0
724	movw	%sr,%d0
725	movw	#SPL5,%sr
726	rts
727
728ENTRY(spl6)
729	moveq	#0,%d0
730	movw	%sr,%d0
731	movw	#SPL6,%sr
732	rts
733
734ALTENTRY(splhigh, _spl7)
735ENTRY(spl7)
736	moveq	#0,%d0
737	movw	%sr,%d0
738	movw	#PSL_HIGHIPL,%sr
739	rts
740
741
742	.data
743
744/*
745 * Memory Information Field for secondary booter memory allocator
746 */
747
748ASLOCAL(romvbr)
749	.long	0
750
751GLOBAL(dipsw1)
752	.long	0
753
754GLOBAL(dipsw2)
755	.long	0
756
757GLOBAL(cputype)
758	.long	CPU_68030
759