locore.S revision 1.7 1 /* $NetBSD: locore.S,v 1.7 2013/01/20 03:40:55 tsutsui 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:
503 * Level 4:
504 * Level 5: System Clock
505 * Level 6: Internal SIO used uPD7201A
506 * Level 7: Non-maskable: 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 ENTRY_NOPROFILE(hardclock)
539 rts
540
541 ENTRY_NOPROFILE(lev6intr)
542 clrw %sp@-
543 moveml #0xC0C0,%sp@-
544 jbsr _C_LABEL(_siointr)
545 moveml %sp@+,#0x0303
546 addql #2,%sp
547 jra _ASM_LABEL(rei)
548
549
550 /*
551 * Emulation of VAX REI instruction.
552 *
553 * This code deals with checking for and servicing ASTs
554 * (profiling, scheduling) and software interrupts (network, softclock).
555 * We check for ASTs first, just like the VAX. To avoid excess overhead
556 * the T_ASTFLT handling code will also check for software interrupts so we
557 * do not have to do it here.
558 *
559 * This code is complicated by the fact that sendsig may have been called
560 * necessitating a stack cleanup. A cleanup should only be needed at this
561 * point for coprocessor mid-instruction frames (type 9), but we also test
562 * for bus error frames (type 10 and 11).
563 */
564 #if 0
565 .comm _ssir,1
566 ASENTRY_NOPROFILE(rei)
567 #ifdef DEBUG
568 tstl _C_LABEL(panicstr) | have we paniced?
569 jne Ldorte | yes, do not make matters worse
570 #endif
571 btst #PCB_ASTB,_u+PCB_FLAGS+1| AST pending?
572 jeq Lchksir | no, go check for SIR
573 btst #5,%sp@ | yes, are we returning to user mode?
574 jne Lchksir | no, go check for SIR
575 clrw %sp@- | pad SR to longword
576 moveml #0xFFFF,%sp@- | save all registers
577 movl %usp,%a1 | including
578 movl %a1,%sp@(60) | the users SP
579 clrl %sp@- | VA == none
580 clrl %sp@- | code == none
581 movl #T_ASTFLT,%sp@- | type == async system trap
582 jbsr _C_LABEL(trap) | go handle it
583 lea %sp@(12),%sp | pop value args
584 movl %sp@(60),%a0 | restore
585 movl %a0,%usp | user SP
586 moveml %sp@+,#0x7FFF | and all remaining registers
587 addql #4,%sp | toss SSP
588 tstw %sp@+ | do we need to clean up stack?
589 jeq Ldorte | no, just continue
590 btst #7,%sp@(6) | type 9/10/11 frame?
591 jeq Ldorte | no, nothing to do
592 btst #5,%sp@(6) | type 9?
593 jne Last1 | no, skip
594 movw %sp@,%sp@(12) | yes, push down SR
595 movl %sp@(2),%sp@(14) | and PC
596 clrw %sp@(18) | and mark as type 0 frame
597 lea %sp@(12),%sp | clean the excess
598 jra Ldorte | all done
599 Last1:
600 btst #4,%sp@(6) | type 10?
601 jne Last2 | no, skip
602 movw %sp@,%sp@(24) | yes, push down SR
603 movl %sp@(2),%sp@(26) | and PC
604 clrw %sp@(30) | and mark as type 0 frame
605 lea %sp@(24),%sp | clean the excess
606 jra Ldorte | all done
607 Last2:
608 movw %sp@,%sp@(84) | type 11, push down SR
609 movl %sp@(2),%sp@(86) | and PC
610 clrw %sp@(90) | and mark as type 0 frame
611 lea %sp@(84),%sp | clean the excess
612 jra Ldorte | all done
613 Lchksir:
614 tstb _ssir | SIR pending?
615 jeq Ldorte | no, all done
616 movl %d0,%sp@- | need a scratch register
617 movw %sp@(4),%d0 | get SR
618 andw #PSL_IPL7,%d0 | mask all but IPL
619 jne Lnosir | came from interrupt, no can do
620 movl %sp@+,%d0 | restore scratch register
621 Lgotsir:
622 movw #SPL1,%sr | prevent others from servicing int
623 tstb _ssir | too late?
624 jeq Ldorte | yes, oh well...
625 clrw %sp@- | pad SR to longword
626 moveml #0xFFFF,%sp@- | save all registers
627 movl %usp,%a1 | including
628 movl %a1,%sp@(60) | the users SP
629 clrl %sp@- | VA == none
630 clrl %sp@- | code == none
631 movl #T_SSIR,%sp@- | type == software interrupt
632 jbsr _trap | go handle it
633 lea %sp@(12),%sp | pop value args
634 movl %sp@(60),%a0 | restore
635 movl %a0,%usp | user SP
636 moveml %sp@+,#0x7FFF | and all remaining registers
637 addql #6,%sp | pop SSP and align word
638 rte
639 Lnosir:
640 movl %sp@+,%d0 | restore scratch register
641 Ldorte:
642 #else
643 ASENTRY_NOPROFILE(rei) | dummy Entry of rei
644 #endif
645 rte | real return
646
647 /*
648 * non-local gotos
649 */
650 ALTENTRY(savectx, _setjmp)
651 ENTRY(setjmp)
652 movl %sp@(4),%a0 | savearea pointer
653 moveml #0xFCFC,%a0@ | save d2-d7/a2-a7
654 movl %sp@,%a0@(48) | and return address
655 moveq #0,%d0 | return 0
656 rts
657
658 ENTRY(qsetjmp)
659 movl %sp@(4),%a0 | savearea pointer
660 lea %a0@(40),%a0 | skip regs we do not save
661 movl %a6,%a0@+ | save FP
662 movl %sp,%a0@+ | save SP
663 movl %sp@,%a0@ | and return address
664 moveq #0,%d0 | return 0
665 rts
666
667 ENTRY(longjmp)
668 movl %sp@(4),%a0
669 moveml %a0@+,#0xFCFC
670 movl %a0@,%sp@
671 moveq #1,%d0
672 rts
673
674 ENTRY_NOPROFILE(getsfc)
675 movc %sfc,%d0
676 rts
677 ENTRY_NOPROFILE(getdfc)
678 movc %dfc,%d0
679 rts
680
681 /*
682 * Set processor priority level calls. Most could (should) be replaced
683 * by inline asm expansions. However, SPL0 and SPLX require special
684 * handling. If we are returning to the base processor priority (SPL0)
685 * we need to check for our emulated software interrupts.
686 */
687
688 ENTRY(spl0)
689 moveq #0,%d0
690 movw %sr,%d0 | get old SR for return
691 movw #PSL_LOWIPL,%sr | restore new SR
692 | jra Lsplsir
693 rts
694
695 ENTRY(splx)
696 moveq #0,%d0
697 movw %sr,%d0 | get current SR for return
698 movw %sp@(6),%d1 | get new value
699 movw %d1,%sr | restore new SR
700 | andw #PSL_IPL7,%d1 | mask all but PSL_IPL
701 | jne Lspldone | non-zero, all done
702 |Lsplsir:
703 | tstb _ssir | software interrupt pending?
704 | jeq Lspldone | no, all done
705 | subql #4,%sp | make room for RTE frame
706 | movl %sp@(4),%sp@(2) | position return address
707 | clrw %sp@(6) | set frame type 0
708 | movw #PSL_LOWIPL,%sp@ | and new SR
709 | jra Lgotsir | go handle it
710 |Lspldone:
711 rts
712
713 ENTRY(spl1)
714 moveq #0,%d0
715 movw %sr,%d0
716 movw #SPL1,%sr
717 rts
718
719 ALTENTRY(splscsi, _spl2)
720 ENTRY(spl2)
721 moveq #0,%d0
722 movw %sr,%d0
723 movw #SPL2,%sr
724 rts
725
726 ENTRY(spl3)
727 moveq #0,%d0
728 movw %sr,%d0
729 movw #SPL3,%sr
730 rts
731
732 ENTRY(spl4)
733 moveq #0,%d0
734 movw %sr,%d0
735 movw #SPL4,%sr
736 rts
737
738 ENTRY(spl5)
739 moveq #0,%d0
740 movw %sr,%d0
741 movw #SPL5,%sr
742 rts
743
744 ENTRY(spl6)
745 moveq #0,%d0
746 movw %sr,%d0
747 movw #SPL6,%sr
748 rts
749
750 ALTENTRY(splhigh, _spl7)
751 ENTRY(spl7)
752 moveq #0,%d0
753 movw %sr,%d0
754 movw #PSL_HIGHIPL,%sr
755 rts
756
757
758 .data
759
760 /*
761 * Memory Infomation Field for secondary booter memory allocator
762 */
763
764 GLOBAL(prgcore)
765 .long 0
766 .long 0
767 .long 0
768
769 ASLOCAL(gotoROM)
770 .long 0
771
772 GLOBAL(dipsw1)
773 .long 0
774
775 GLOBAL(dipsw2)
776 .long 0
777
778 GLOBAL(cputype)
779 .long CPU_68030
780