locore.S revision 1.11.30.1 1 /* $NetBSD: locore.S,v 1.11.30.1 2019/06/10 22:06:26 christos 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(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
201 ASENTRY_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
208 Lbssclr:
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
247 Lnot68030:
248 movl #CPU_68040,%d0
249 Lstart0:
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 */
260 ENTRY_NOPROFILE(exit)
261 GLOBAL(_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
272 ENTRY_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)
277 ENTRY_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
288 LbeX0:
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
293 LbeX1:
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
298 Lbe0:
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
306 Lbe3:
307 btst #15,%d0 | FC set?
308 jeq Lbe10 | no, done
309 addql #2,%d1 | yes, adjust address
310 jra Lbe10 | done
311 Lbe4:
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
316 Lbe10:
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
333 Lismerr:
334 movl #T_MMUFLT,%sp@- | show that we are an MMU fault
335 jra Lbexit | and deal with it
336 Lisaerr:
337 movl #T_ADDRERR,%sp@- | mark address error
338 jra Lbexit | and deal with it
339 Lisberr:
340 movl #T_BUSERR,%sp@- | mark bus error
341 Lbexit:
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
359 Lbex1:
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
367 Lbex2:
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
374 ENTRY_NOPROFILE(illinst)
375 clrw %sp@-
376 moveml #0xFFFF,%sp@-
377 moveq #T_ILLINST,%d0
378 jra _C_LABEL(fault)
379
380 ENTRY_NOPROFILE(zerodiv)
381 clrw %sp@-
382 moveml #0xFFFF,%sp@-
383 moveq #T_ZERODIV,%d0
384 jra _C_LABEL(fault)
385
386 ENTRY_NOPROFILE(chkinst)
387 clrw %sp@-
388 moveml #0xFFFF,%sp@-
389 moveq #T_CHKINST,%d0
390 jra _C_LABEL(fault)
391
392 ENTRY_NOPROFILE(trapvinst)
393 clrw %sp@-
394 moveml #0xFFFF,%sp@-
395 moveq #T_TRAPVINST,%d0
396 jra _C_LABEL(fault)
397
398 ENTRY_NOPROFILE(privinst)
399 clrw %sp@-
400 moveml #0xFFFF,%sp@-
401 moveq #T_PRIVINST,%d0
402 jra _C_LABEL(fault)
403
404 ENTRY_NOPROFILE(coperr)
405 clrw %sp@-
406 moveml #0xFFFF,%sp@-
407 moveq #T_COPERR,%d0
408 jra _C_LABEL(fault)
409
410 ENTRY_NOPROFILE(fmterr)
411 clrw %sp@-
412 moveml #0xFFFF,%sp@-
413 moveq #T_FMTERR,%d0
414 jra _C_LABEL(fault)
415
416 ENTRY_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
431 Lfptnull:
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
449 ENTRY_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
463 ENTRY_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
489 ENTRY_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
497 ENTRY_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
505 ENTRY_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
519 ENTRY_NOPROFILE(hardclock)
520 addql #1,_C_LABEL(tick)
521 rts
522
523 BSS(tick,4)
524
525 ENTRY_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
550 ASENTRY_NOPROFILE(rei)
551 #ifdef DEBUG
552 tstl _C_LABEL(panicstr) | have we paniced?
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
583 Last1:
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
591 Last2:
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
597 Lchksir:
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
605 Lgotsir:
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
623 Lnosir:
624 movl %sp@+,%d0 | restore scratch register
625 Ldorte:
626 #else
627 ASENTRY_NOPROFILE(rei) | dummy Entry of rei
628 #endif
629 rte | real return
630
631 /*
632 * non-local gotos
633 */
634 ALTENTRY(savectx, _setjmp)
635 ENTRY(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
642 ENTRY(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
651 ENTRY(longjmp)
652 movl %sp@(4),%a0
653 moveml %a0@+,#0xFCFC
654 movl %a0@,%sp@
655 moveq #1,%d0
656 rts
657
658 ENTRY_NOPROFILE(getsfc)
659 movc %sfc,%d0
660 rts
661 ENTRY_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
672 ENTRY(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
679 ENTRY(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
697 ENTRY(spl1)
698 moveq #0,%d0
699 movw %sr,%d0
700 movw #SPL1,%sr
701 rts
702
703 ALTENTRY(splscsi, _spl2)
704 ENTRY(spl2)
705 moveq #0,%d0
706 movw %sr,%d0
707 movw #SPL2,%sr
708 rts
709
710 ENTRY(spl3)
711 moveq #0,%d0
712 movw %sr,%d0
713 movw #SPL3,%sr
714 rts
715
716 ENTRY(spl4)
717 moveq #0,%d0
718 movw %sr,%d0
719 movw #SPL4,%sr
720 rts
721
722 ENTRY(spl5)
723 moveq #0,%d0
724 movw %sr,%d0
725 movw #SPL5,%sr
726 rts
727
728 ENTRY(spl6)
729 moveq #0,%d0
730 movw %sr,%d0
731 movw #SPL6,%sr
732 rts
733
734 ALTENTRY(splhigh, _spl7)
735 ENTRY(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
748 ASLOCAL(romvbr)
749 .long 0
750
751 GLOBAL(dipsw1)
752 .long 0
753
754 GLOBAL(dipsw2)
755 .long 0
756
757 GLOBAL(cputype)
758 .long CPU_68030
759