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