1/* $NetBSD: locore.s,v 1.46 2024/01/17 12:33:49 thorpej Exp $ */ 2 3/* 4 * Copyright (c) 1980, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * the Systems Programming Group of the University of Utah Computer 9 * Science Department. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. 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 * from: Utah $Hdr: locore.s 1.66 92/12/22$ 36 * 37 * @(#)locore.s 8.6 (Berkeley) 5/27/94 38 */ 39 40/* 41 * Copyright (c) 1994, 1995 Gordon W. Ross 42 * Copyright (c) 1988 University of Utah. 43 * 44 * This code is derived from software contributed to Berkeley by 45 * the Systems Programming Group of the University of Utah Computer 46 * Science Department. 47 * 48 * Redistribution and use in source and binary forms, with or without 49 * modification, are permitted provided that the following conditions 50 * are met: 51 * 1. Redistributions of source code must retain the above copyright 52 * notice, this list of conditions and the following disclaimer. 53 * 2. Redistributions in binary form must reproduce the above copyright 54 * notice, this list of conditions and the following disclaimer in the 55 * documentation and/or other materials provided with the distribution. 56 * 3. All advertising materials mentioning features or use of this software 57 * must display the following acknowledgement: 58 * This product includes software developed by the University of 59 * California, Berkeley and its contributors. 60 * 4. Neither the name of the University nor the names of its contributors 61 * may be used to endorse or promote products derived from this software 62 * without specific prior written permission. 63 * 64 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 65 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 66 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 67 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 68 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 69 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 70 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 71 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 72 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 73 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 74 * SUCH DAMAGE. 75 * 76 * from: Utah $Hdr: locore.s 1.66 92/12/22$ 77 * 78 * @(#)locore.s 8.6 (Berkeley) 5/27/94 79 */ 80 81#include "opt_compat_netbsd.h" 82#include "opt_compat_sunos.h" 83#include "opt_ddb.h" 84#include "opt_fpsp.h" 85#include "opt_fpu_emulate.h" 86#include "opt_m68k_arch.h" 87 88#include "ksyms.h" 89#include "assym.h" 90#include <machine/asm.h> 91#include <machine/trap.h> 92 93/* 94 * This is for kvm_mkdb, and should be the address of the beginning 95 * of the kernel text segment (not necessarily the same as kernbase). 96 */ 97 .text 98GLOBAL(kernel_text) 99 100/* 101 * Temporary stack for a variety of purposes. 102 * Try and make this the first thing is the data segment so it 103 * is page aligned. Note that if we overflow here, we run into 104 * our text segment. 105 */ 106 .data 107 .space PAGE_SIZE 108ASLOCAL(tmpstk) 109 110 .text 111/* 112 * Macro to relocate a symbol, used before MMU is enabled. 113 */ 114#define _RELOC(var, ar) \ 115 lea var-KERNBASE,ar; \ 116 addl %a5,ar 117 118#define RELOC(var, ar) _RELOC(_C_LABEL(var), ar) 119#define ASRELOC(var, ar) _RELOC(_ASM_LABEL(var), ar) 120 121/* 122 * Initialization 123 * 124 * A4 contains the address of the end of the symtab 125 * A5 contains physical load point from boot 126 * VBR contains zero from ROM. Exceptions will continue to vector 127 * through ROM until MMU is turned on at which time they will vector 128 * through our table (vectors.s). 129 */ 130 131BSS(lowram,4) 132BSS(esym,4) 133 134 .text 135ASENTRY_NOPROFILE(start) 136 movw #PSL_HIGHIPL, %sr | no interrupts 137 movl #CACHE_OFF, %d0 138 movc %d0, %cacr | clear and disable on-chip cache(s) 139 140 /* XXX fixed load address */ 141 movl #0x20100000, %a5 142 143 movl #0x20000000, %a0 144 RELOC(edata, %a1) 1451: 146 movl %a5@+, %a0@+ 147 cmpl %a5, %a1 148 bne 1b 149 150 movl #0x20000000, %a5 151 152 ASRELOC(tmpstk, %a0) 153 movl %a0, %sp | give ourselves a temporary stack 154 155 RELOC(edata, %a0) 156 RELOC(end, %a1) 1572: 158 clrb %a0@+ 159 cmpl %a0, %a1 160 bne 2b 161 162 RELOC(esym, %a0) 163#if 0 164 movl %a4, %a0@ | store end of symbol table 165#else 166 clrl %a0@ | no symbol table, yet 167#endif 168 169 RELOC(lowram, %a0) 170 movl %a5, %a0@ | store start of physical memory 171 172#if 0 173 RELOC(boothowto, %a0) | save reboot flags 174 movl %d7, %a0@ 175 RELOC(bootdev, %a0) | and boot device 176 movl %d6, %a0@ 177#endif 178 179 /* 180 * All data registers are now free. All address registers 181 * except a5 are free. a5 is used by the RELOC() macro, 182 * and cannot be used until after the MMU is enabled. 183 */ 184 185/* determine our CPU/MMU combo - check for all regardless of kernel config */ 186 movl #0x200,%d0 | data freeze bit 187 movc %d0,%cacr | only exists on 68030 188 movc %cacr,%d0 | read it back 189 tstl %d0 | zero? 190 jeq Lnot68030 | yes, we have 68020/68040 191 RELOC(mmutype, %a0) | no, we have 68030 192 movl #MMU_68030,%a0@ | set to reflect 68030 PMMU 193 RELOC(cputype, %a0) 194 movl #CPU_68030,%a0@ | and 68030 CPU 195 jra Lstart1 196Lnot68030: 197 bset #31,%d0 | data cache enable bit 198 movc %d0,%cacr | only exists on 68040 199 movc %cacr,%d0 | read it back 200 tstl %d0 | zero? 201 beq Lis68020 | yes, we have 68020 202 moveq #0,%d0 | now turn it back off 203 movec %d0,%cacr | before we access any data 204 RELOC(mmutype, %a0) 205 movl #MMU_68040,%a0@ | with a 68040 MMU 206 RELOC(cputype, %a0) 207 movl #CPU_68040,%a0@ | and a 68040 CPU 208 RELOC(fputype, %a0) 209 movl #FPU_68040,%a0@ | ...and FPU 210 jra Lstart1 211Lis68020: 212 /* impossible */ 213 214Lstart1: 215 216/* initialize source/destination control registers for movs */ 217 moveq #FC_USERD,%d0 | user space 218 movc %d0,%sfc | as source 219 movc %d0,%dfc | and destination of transfers 220 221/* initialize memory size (for pmap_bootstrap) */ 222 movl 0x5c00ac00, %d0 223 andb #0x60, %d0 224 jne Lnot8M 225 movl #0x20800000, %d1 | memory end, 8M 226 jra Lmemok 227Lnot8M: 228 cmpb #0x20, %d0 229 jne Lunkmem 230 movl #0x22000000, %d1 | memory end, 32M 231 jra Lmemok 232Lunkmem: 233 /* ??? */ 234 movl #0x20400000, %d1 | memory end, assume at least 4M 235 236Lmemok: 237 moveq #PGSHIFT,%d2 238 lsrl %d2,%d1 | convert to page (click) number 239 movl %a5,%d0 | lowram value from ROM via boot 240 lsrl %d2,%d0 | convert to page number 241 subl %d0,%d1 | compute amount of RAM present 242 RELOC(physmem, %a0) 243 movl %d1,%a0@ | and physmem 244/* configure kernel and lwp0 VA space so we can get going */ 245 .globl _Sysseg_pa, _pmap_bootstrap, _avail_start 246#if NKSYMS || defined(DDB) || defined(MODULAR) 247 RELOC(esym,%a0) | end of static kernel test/data/syms 248 movl %a0@,%d5 249 jne Lstart2 250#endif 251 movl #_C_LABEL(end),%d5 | end of static kernel text/data 252Lstart2: 253 addl #PAGE_SIZE-1,%d5 254 andl #PG_FRAME,%d5 | round to a page 255 movl %d5,%a4 256 addl %a5,%a4 | convert to PA 257 subl #KERNBASE, %a4 258 pea %a5@ | firstpa 259 pea %a4@ | nextpa 260 RELOC(pmap_bootstrap,%a0) 261 jbsr %a0@ | pmap_bootstrap(firstpa, nextpa) 262 addql #8,%sp 263 264/* 265 * Prepare to enable MMU. 266 */ 267 RELOC(Sysseg_pa, %a0) | system segment table addr 268 movl %a0@,%d1 | read value (a PA) 269 subl #KERNBASE, %d1 270 271 RELOC(mmutype, %a0) 272 cmpl #MMU_68040,%a0@ | 68040? 273 jne Lmotommu1 | no, skip 274 .long 0x4e7b1807 | movc d1,srp 275 jra Lstploaddone 276Lmotommu1: 277#ifdef M68030 278 RELOC(protorp, %a0) 279 movl %d1,%a0@(4) | segtable address 280 pmove %a0@,%srp | load the supervisor root pointer 281#endif /* M68030 */ 282Lstploaddone: 283 284 RELOC(mmutype, %a0) 285 cmpl #MMU_68040,%a0@ | 68040? 286 jne Lmotommu2 | no, skip 287 288 movel #0x2000c000, %d0 | double map RAM 289 .long 0x4e7b0004 | movc d0,itt0 290 .long 0x4e7b0006 | movc d0,dtt0 291 moveq #0, %d0 | ensure TT regs are disabled 292 .long 0x4e7b0005 | movc d0,itt1 293 .long 0x4e7b0007 | movc d0,dtt1 294 295 .word 0xf4d8 | cinva bc 296 .word 0xf518 | pflusha 297 298 movl #MMU40_TCR_BITS, %d0 299 .long 0x4e7b0003 | movc d0,tc 300 movl #0x80008000, %d0 301 movc %d0, %cacr | turn on both caches 302 303 jmp Lenab1:l | avoid pc-relative 304Lmotommu2: 305 /* XXX do TT here */ 306 pflusha 307 RELOC(prototc, %a2) 308 movl #MMU51_TCR_BITS,%a2@ | value to load TC with 309 pmove %a2@,%tc | load it 310 jmp Lenab1 311 312/* 313 * Should be running mapped from this point on 314 */ 315Lenab1: 316 .word 0xf4d8 | cinva bc 317 .word 0xf518 | pflusha 318 nop 319 nop 320 nop 321 nop 322 nop 323 moveq #0,%d0 | ensure TT regs are disabled 324 .long 0x4e7b0004 | movc d0,itt0 325 .long 0x4e7b0005 | movc d0,itt1 326 .long 0x4e7b0006 | movc d0,dtt0 327 .long 0x4e7b0007 | movc d0,dtt1 328 329 lea _ASM_LABEL(tmpstk),%sp | re-load temporary stack 330 jbsr _C_LABEL(vec_init) | initialize vector table 331/* call final pmap setup */ 332 jbsr _C_LABEL(pmap_bootstrap_finalize) 333/* set kernel stack, user SP */ 334 movl _C_LABEL(lwp0uarea),%a1 | get lwp0 uarea 335 lea %a1@(USPACE-4),%sp | set kernel stack to end of area 336 movl #USRSTACK-4,%a2 337 movl %a2,%usp | init user SP 338 339 tstl _C_LABEL(fputype) | Have an FPU? 340 jeq Lenab2 | No, skip. 341 clrl %a1@(PCB_FPCTX) | ensure null FP context 342 movl %a1,%sp@- 343 jbsr _C_LABEL(m68881_restore) | restore it (does not kill a1) 344 addql #4,%sp 345Lenab2: 346 347/* flush TLB and turn on caches */ 348 jbsr _C_LABEL(_TBIA) | invalidate TLB 349 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 350 jeq Lnocache0 | yes, cache already on 351 movl #CACHE_ON,%d0 352 movc %d0,%cacr | clear cache(s) 353Lnocache0: 354 355/* Final setup for call to main(). */ 356 jbsr _C_LABEL(fic_init) 357 358/* 359 * Create a fake exception frame so that cpu_lwp_fork() can copy it. 360 * main() nevers returns; we exit to user mode from a forked process 361 * later on. 362 */ 363 clrw %sp@- | vector offset/frame type 364 clrl %sp@- | PC - filled in by "execve" 365 movw #PSL_USER,%sp@- | in user mode 366 clrl %sp@- | stack adjust count and padding 367 lea %sp@(-64),%sp | construct space for D0-D7/A0-A7 368 lea _C_LABEL(lwp0),%a0 | save pointer to frame 369 movl %sp,%a0@(L_MD_REGS) | in lwp0.l_md.md_regs 370 371 jra _C_LABEL(main) | main() 372 373 pea Lmainreturned | Yow! Main returned! 374 jbsr _C_LABEL(panic) 375 /* NOTREACHED */ 376Lmainreturned: 377 .asciz "main() returned" 378 .even 379 380/* 381 * Trap/interrupt vector routines 382 */ 383#include <m68k/m68k/trap_subr.s> 384 385/* 386 * Use common m68k bus error and address error handlers. 387 */ 388#include <m68k/m68k/busaddrerr.s> 389 390/* 391 * FP exceptions. 392 */ 393ENTRY_NOPROFILE(fpfline) 394#if defined(M68040) 395 cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? 396 jne Lfp_unimp | no, skip FPSP 397 cmpw #0x202c,%sp@(6) | format type 2? 398 jne _C_LABEL(illinst) | no, not an FP emulation 399Ldofp_unimp: 400#ifdef FPSP 401#if 0 402 addl #1, _C_LABEL(evcnt_fpsp_unimp)+EVCNT_COUNT 403#endif 404 jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it 405#endif 406Lfp_unimp: 407#endif /* M68040 */ 408#ifdef FPU_EMULATE 409 clrl %sp@- | stack adjust count 410 moveml #0xFFFF,%sp@- | save registers 411 moveq #T_FPEMULI,%d0 | denote as FP emulation trap 412 jra _ASM_LABEL(fault) | do it 413#else 414 jra _C_LABEL(illinst) 415#endif 416 417ENTRY_NOPROFILE(fpunsupp) 418#if defined(M68040) 419 cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? 420 jne _C_LABEL(illinst) | no, treat as illinst 421#ifdef FPSP 422#if 0 423 addl #1, _C_LABEL(evcnt_fpsp_unsupp)+EVCNT_COUNT 424#endif 425 jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it 426#endif 427Lfp_unsupp: 428#endif /* M68040 */ 429#ifdef FPU_EMULATE 430 clrl %sp@- | stack adjust count 431 moveml #0xFFFF,%sp@- | save registers 432 moveq #T_FPEMULD,%d0 | denote as FP emulation trap 433 jra _ASM_LABEL(fault) | do it 434#else 435 jra _C_LABEL(illinst) 436#endif 437 438/* 439 * Handles all other FP coprocessor exceptions. 440 * Note that since some FP exceptions generate mid-instruction frames 441 * and may cause signal delivery, we need to test for stack adjustment 442 * after the trap call. 443 */ 444ENTRY_NOPROFILE(fpfault) 445 clrl %sp@- | stack adjust count 446 moveml #0xFFFF,%sp@- | save user registers 447 movl %usp,%a0 | and save 448 movl %a0,%sp@(FR_SP) | the user stack pointer 449 clrl %sp@- | no VA arg 450 movl _C_LABEL(curpcb),%a0 | current pcb 451 lea %a0@(PCB_FPCTX),%a0 | address of FP savearea 452 fsave %a0@ | save state 453#if defined(M68040) || defined(M68060) 454 /* always null state frame on 68040, 68060 */ 455 cmpl #FPU_68040,_C_LABEL(fputype) 456 jge Lfptnull 457#endif 458 tstb %a0@ | null state frame? 459 jeq Lfptnull | yes, safe 460 clrw %d0 | no, need to tweak BIU 461 movb %a0@(1),%d0 | get frame size 462 bset #3,%a0@(0,%d0:w) | set exc_pend bit of BIU 463Lfptnull: 464 fmovem %fpsr,%sp@- | push %fpsr as code argument 465 frestore %a0@ | restore state 466 movl #T_FPERR,%sp@- | push type arg 467 jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup 468 469 470ENTRY_NOPROFILE(badtrap) 471 moveml #0xC0C0,%sp@- | save scratch regs 472 movw %sp@(22),%sp@- | push exception vector info 473 clrw %sp@- 474 movl %sp@(22),%sp@- | and PC 475 jbsr _C_LABEL(straytrap) | report 476 addql #8,%sp | pop args 477 moveml %sp@+,#0x0303 | restore regs 478 jra _ASM_LABEL(rei) | all done 479 480ENTRY_NOPROFILE(trap0) 481 clrl %sp@- | stack adjust count 482 moveml #0xFFFF,%sp@- | save user registers 483 movl %usp,%a0 | save the user SP 484 movl %a0,%sp@(FR_SP) | in the savearea 485 movl %d0,%sp@- | push syscall number 486 jbsr _C_LABEL(syscall) | handle it 487 addql #4,%sp | pop syscall arg 488 tstl _C_LABEL(astpending) 489 jne Lrei2 490 tstb _C_LABEL(ssir) 491 jeq Ltrap1 492 movw #SPL1,%sr 493 tstb _C_LABEL(ssir) 494 jne Lsir1 495Ltrap1: 496 movl %sp@(FR_SP),%a0 | grab and restore 497 movl %a0,%usp | user SP 498 moveml %sp@+,#0x7FFF | restore most registers 499 addql #8,%sp | pop SP and stack adjust 500 rte 501 502/* 503 * Trap 12 is the entry point for the cachectl "syscall" (both HPUX & BSD) 504 * cachectl(command, addr, length) 505 * command in d0, addr in a1, length in d1 506 */ 507ENTRY_NOPROFILE(trap12) 508 movl _C_LABEL(curlwp),%a0 509 movl %a0@(L_PROC),%sp@- | push current proc pointer 510 movl %d1,%sp@- | push length 511 movl %a1,%sp@- | push addr 512 movl %d0,%sp@- | push command 513 jbsr _C_LABEL(cachectl1) | do it 514 lea %sp@(16),%sp | pop args 515 jra _ASM_LABEL(rei) | all done 516 517/* 518 * Trace (single-step) trap. Kernel-mode is special. 519 * User mode traps are simply passed on to trap(). 520 */ 521ENTRY_NOPROFILE(trace) 522 clrl %sp@- | stack adjust count 523 moveml #0xFFFF,%sp@- 524 moveq #T_TRACE,%d0 525 526 | Check PSW and see what happen. 527 | T=0 S=0 (should not happen) 528 | T=1 S=0 trace trap from user mode 529 | T=0 S=1 trace trap on a trap instruction 530 | T=1 S=1 trace trap from system mode (kernel breakpoint) 531 532 movw %sp@(FR_HW),%d1 | get PSW 533 notw %d1 | XXX no support for T0 on 680[234]0 534 andw #PSL_TS,%d1 | from system mode (T=1, S=1)? 535 jeq Lkbrkpt | yes, kernel breakpoint 536 jra _ASM_LABEL(fault) | no, user-mode fault 537 538 539/* 540 * Trap 15 is used for: 541 * - GDB breakpoints (in user programs) 542 * - KGDB breakpoints (in the kernel) 543 * - trace traps for SUN binaries (not fully supported yet) 544 * User mode traps are simply passed to trap(). 545 */ 546ENTRY_NOPROFILE(trap15) 547 clrl %sp@- | stack adjust count 548 moveml #0xFFFF,%sp@- 549 moveq #T_TRAP15,%d0 550 movw %sp@(FR_HW),%d1 | get PSW 551 andw #PSL_S,%d1 | from system mode? 552 jne Lkbrkpt | yes, kernel breakpoint 553 jra _ASM_LABEL(fault) | no, user-mode fault 554 555Lkbrkpt: | Kernel-mode breakpoint or trace trap. (%d0=trap_type) 556 | Save the system sp rather than the user sp. 557 movw #PSL_HIGHIPL,%sr | lock out interrupts 558 lea %sp@(FR_SIZE),%a6 | Save stack pointer 559 movl %a6,%sp@(FR_SP) | from before trap 560 561 | If were are not on tmpstk switch to it. 562 | (so debugger can change the stack pointer) 563 movl %a6,%d1 564 cmpl #_ASM_LABEL(tmpstk),%d1 565 jls Lbrkpt2 | already on tmpstk 566 | Copy frame to the temporary stack 567 movl %sp,%a0 | %a0=src 568 lea _ASM_LABEL(tmpstk)-96,%a1 | a1=dst 569 movl %a1,%sp | %sp=new frame 570 moveq #FR_SIZE,%d1 571Lbrkpt1: 572 movl %a0@+,%a1@+ 573 subql #4,%d1 574 bgt Lbrkpt1 575 576Lbrkpt2: 577 | Call the trap handler for the kernel debugger. 578 | Do not call trap() to do it, so that we can 579 | set breakpoints in trap() if we want. We know 580 | the trap type is either T_TRACE or T_BREAKPOINT. 581 movl %d0,%sp@- | push trap type 582 jbsr _C_LABEL(trap_kdebug) 583 addql #4,%sp | pop args 584 585 | The stack pointer may have been modified, or 586 | data below it modified (by kgdb push call), 587 | so push the hardware frame at the current sp 588 | before restoring registers and returning. 589 590 movl %sp@(FR_SP),%a0 | modified %sp 591 lea %sp@(FR_SIZE),%a1 | end of our frame 592 movl %a1@-,%a0@- | copy 2 longs with 593 movl %a1@-,%a0@- | ... predecrement 594 movl %a0,%sp@(FR_SP) | %sp = h/w frame 595 moveml %sp@+,#0x7FFF | restore all but %sp 596 movl %sp@,%sp | ... and %sp 597 rte | all done 598 599/* 600 * Interrupt handlers. 601 */ 602 603ENTRY_NOPROFILE(lev6intr) /* Level 6: clock */ 604 INTERRUPT_SAVEREG 605 /* XXX */ 606 movl _C_LABEL(clockbase), %a0 607 movl %a0@, %d0 608 movl %d0, %a0@ 609 btst #2, %d0 610 jeq 1f 611 addql #1,_C_LABEL(m68k_intr_evcnt)+CLOCK_INTRCNT 612 lea %sp@(0), %a1 | a1 = &clockframe 613 movl %a1, %sp@- 614 jbsr _C_LABEL(hardclock) | hardclock(&frame) 615 addql #4, %sp 616 jra 2f 6171: 618 movl %d0, %sp@- 619 jbsr _C_LABEL(otherclock) 620 addql #4, %sp 6212: 622 INTERRUPT_RESTOREREG 623 jra _ASM_LABEL(rei) | all done 624 625ENTRY_NOPROFILE(lev7intr) /* level 7: parity errors, reset key */ 626 addql #1,_C_LABEL(m68k_intr_evcnt)+NMI_INTRCNT 627 clrl %sp@- 628 moveml #0xFFFF,%sp@- | save registers 629 movl %usp,%a0 | and save 630 movl %a0,%sp@(FR_SP) | the user stack pointer 631 jbsr _C_LABEL(nmihand) | call handler 632 movl %sp@(FR_SP),%a0 | restore 633 movl %a0,%usp | user SP 634 moveml %sp@+,#0x7FFF | and remaining registers 635 addql #8,%sp | pop SP and stack adjust 636 jra _ASM_LABEL(rei) | all done 637 638/* 639 * Emulation of VAX REI instruction. 640 * 641 * This code deals with checking for and servicing ASTs 642 * (profiling, scheduling) and software interrupts (network, softclock). 643 * We check for ASTs first, just like the VAX. To avoid excess overhead 644 * the T_ASTFLT handling code will also check for software interrupts so we 645 * do not have to do it here. After identifying that we need an AST we 646 * drop the IPL to allow device interrupts. 647 * 648 * This code is complicated by the fact that sendsig may have been called 649 * necessitating a stack cleanup. 650 */ 651BSS(ssir,1) 652 653ASENTRY_NOPROFILE(rei) 654 tstl _C_LABEL(astpending) | AST pending? 655 jeq Lchksir | no, go check for SIR 656Lrei1: 657 btst #5,%sp@ | yes, are we returning to user mode? 658 jne Lchksir | no, go check for SIR 659 movw #PSL_LOWIPL,%sr | lower SPL 660 clrl %sp@- | stack adjust 661 moveml #0xFFFF,%sp@- | save all registers 662 movl %usp,%a1 | including 663 movl %a1,%sp@(FR_SP) | the users SP 664Lrei2: 665 clrl %sp@- | VA == none 666 clrl %sp@- | code == none 667 movl #T_ASTFLT,%sp@- | type == async system trap 668 pea %sp@(12) | fp == address of trap frame 669 jbsr _C_LABEL(trap) | go handle it 670 lea %sp@(16),%sp | pop value args 671 movl %sp@(FR_SP),%a0 | restore user SP 672 movl %a0,%usp | from save area 673 movw %sp@(FR_ADJ),%d0 | need to adjust stack? 674 jne Laststkadj | yes, go to it 675 moveml %sp@+,#0x7FFF | no, restore most user regs 676 addql #8,%sp | toss SP and stack adjust 677 rte | and do real RTE 678Laststkadj: 679 lea %sp@(FR_HW),%a1 | pointer to HW frame 680 addql #8,%a1 | source pointer 681 movl %a1,%a0 | source 682 addw %d0,%a0 | + hole size = dest pointer 683 movl %a1@-,%a0@- | copy 684 movl %a1@-,%a0@- | 8 bytes 685 movl %a0,%sp@(FR_SP) | new SSP 686 moveml %sp@+,#0x7FFF | restore user registers 687 movl %sp@,%sp | and our SP 688 rte | and do real RTE 689Lchksir: 690 tstb _C_LABEL(ssir) | SIR pending? 691 jeq Ldorte | no, all done 692 movl %d0,%sp@- | need a scratch register 693 movw %sp@(4),%d0 | get SR 694 andw #PSL_IPL7,%d0 | mask all but IPL 695 jne Lnosir | came from interrupt, no can do 696 movl %sp@+,%d0 | restore scratch register 697Lgotsir: 698 movw #SPL1,%sr | prevent others from servicing int 699 tstb _C_LABEL(ssir) | too late? 700 jeq Ldorte | yes, oh well... 701 clrl %sp@- | stack adjust 702 moveml #0xFFFF,%sp@- | save all registers 703 movl %usp,%a1 | including 704 movl %a1,%sp@(FR_SP) | the users SP 705Lsir1: 706 clrl %sp@- | VA == none 707 clrl %sp@- | code == none 708 movl #T_SSIR,%sp@- | type == software interrupt 709 pea %sp@(12) | fp == address of trap frame 710 jbsr _C_LABEL(trap) | go handle it 711 lea %sp@(16),%sp | pop value args 712 movl %sp@(FR_SP),%a0 | restore 713 movl %a0,%usp | user SP 714 moveml %sp@+,#0x7FFF | and all remaining registers 715 addql #8,%sp | pop SP and stack adjust 716 rte 717Lnosir: 718 movl %sp@+,%d0 | restore scratch register 719Ldorte: 720 rte | real return 721 722/* 723 * Primitives 724 */ 725 726/* 727 * Use common m68k process/lwp switch and context save subroutines. 728 */ 729#define FPCOPROC /* XXX: Temporarily required */ 730#include <m68k/m68k/switch_subr.s> 731 732 733#if defined(M68040) 734ENTRY(suline) 735 movl %sp@(4),%a0 | address to write 736 movl _C_LABEL(curpcb),%a1 | current pcb 737 movl #Lslerr,%a1@(PCB_ONFAULT) | where to return to on a fault 738 movl %sp@(8),%a1 | address of line 739 movl %a1@+,%d0 | get lword 740 movsl %d0,%a0@+ | put lword 741 nop | sync 742 movl %a1@+,%d0 | get lword 743 movsl %d0,%a0@+ | put lword 744 nop | sync 745 movl %a1@+,%d0 | get lword 746 movsl %d0,%a0@+ | put lword 747 nop | sync 748 movl %a1@+,%d0 | get lword 749 movsl %d0,%a0@+ | put lword 750 nop | sync 751 moveq #0,%d0 | indicate no fault 752 jra Lsldone 753Lslerr: 754 moveq #-1,%d0 755Lsldone: 756 movl _C_LABEL(curpcb),%a1 | current pcb 757 clrl %a1@(PCB_ONFAULT) | clear fault address 758 rts 759#endif 760 761/* 762 * Set processor priority level calls. Most are implemented with 763 * inline asm expansions. However, spl0 requires special handling 764 * as we need to check for our emulated software interrupts. 765 */ 766 767ENTRY(spl0) 768 moveq #0,%d0 769 movw %sr,%d0 | get old SR for return 770 movw #PSL_LOWIPL,%sr | restore new SR 771 tstb _C_LABEL(ssir) | software interrupt pending? 772 jeq Lspldone | no, all done 773 subql #4,%sp | make room for RTE frame 774 movl %sp@(4),%sp@(2) | position return address 775 clrw %sp@(6) | set frame type 0 776 movw #PSL_LOWIPL,%sp@ | and new SR 777 jra Lgotsir | go handle it 778Lspldone: 779 rts 780 781/* 782 * _delay(u_int N) 783 * 784 * Delay for at least (N/256) microseconds. 785 * This routine depends on the variable: delay_divisor 786 * which should be set based on the CPU clock rate. 787 */ 788ENTRY_NOPROFILE(_delay) 789 | d0 = arg = (usecs << 8) 790 movl %sp@(4),%d0 791 | d1 = delay_divisor 792 movl _C_LABEL(delay_divisor),%d1 793L_delay: 794 subl %d1,%d0 795 jgt L_delay 796 rts 797 798ENTRY_NOPROFILE(doboot) 799 movl #0x5c00c060, %d0 | want phys addressing 800 .long 0x4e7b0006 | movc d0,dtt0 801 movl #1, 0x5c00b800 | reset 802 stop #0x2700 | paranoia 803 804 .data 805GLOBAL(mmutype) 806 .long MMU_HP | default to HP MMU 807GLOBAL(cputype) 808 .long CPU_68020 | default to 68020 CPU 809GLOBAL(fputype) 810 .long FPU_68881 | default to 68881 FPU 811GLOBAL(prototc) 812 .long 0 | prototype translation control 813 814#ifdef DEBUG 815 .globl fulltflush, fullcflush 816fulltflush: 817 .long 0 818fullcflush: 819 .long 0 820#endif 821