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