1 /* $NetBSD: locore.s,v 1.189 2025/12/04 02:55:24 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1982, 1990 The Regents of the University of California. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * the Systems Programming Group of the University of Utah Computer 10 * Science Department. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37 /*- 38 * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, 39 * Michael L. Finch, Bradley A. Grantham, and 40 * Lawrence A. Kesteloot 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. All advertising materials mentioning features or use of this software 52 * must display the following acknowledgement: 53 * This product includes software developed by the Alice Group. 54 * 4. The names of the Alice Group or any of its members may not be used 55 * to endorse or promote products derived from this software without 56 * specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR 59 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 60 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 61 * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT, 62 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 63 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 64 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 65 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 66 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 67 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 68 * 69 */ 70 71 /* 72 * from: Utah $Hdr: locore.s 1.58 91/04/22$ 73 * 74 * @(#)locore.s 7.11 (Berkeley) 5/9/91 75 */ 76 77 #include "opt_compat_netbsd.h" 78 #include "opt_compat_sunos.h" 79 #include "opt_ddb.h" 80 #include "opt_fpu_emulate.h" 81 #include "opt_kgdb.h" 82 #include "opt_lockdebug.h" 83 #include "opt_fpsp.h" 84 #include "opt_m68k_arch.h" 85 86 #include "assym.h" 87 88 #include <machine/asm.h> 89 #include <machine/trap.h> 90 91 /* 92 * This is for kvm_mkdb, and should be the address of the beginning 93 * of the kernel text segment (not necessarily the same as kernbase). 94 */ 95 .text 96 GLOBAL(kernel_text) 97 98 #include <mac68k/mac68k/vectors.s> 99 #include <mac68k/mac68k/macglobals.s> 100 101 /* 102 * Initialization 103 */ 104 105 .data 106 | Scratch memory. Careful when messing with these... 107 ASLOCAL(longscratch) 108 .long 0 109 ASLOCAL(longscratch2) 110 .long 0 111 ASLOCAL(pte_tmp) | for get_pte() 112 .long 0 113 GLOBAL(macos_crp1) 114 .long 0 115 GLOBAL(macos_crp2) 116 .long 0 117 GLOBAL(macos_tc) 118 .long 0 119 GLOBAL(macos_tt0) 120 .long 0 121 GLOBAL(macos_tt1) 122 .long 0 123 GLOBAL(bletch) 124 .long 0 125 126 BSS(esym,4) 127 128 ASENTRY_NOPROFILE(start) 129 movw #PSL_HIGHIPL,%sr | no interrupts. ever. 130 lea _ASM_LABEL(tmpstk),%sp | give ourselves a temporary stack 131 132 movl #CACHE_OFF,%d0 133 movc %d0,%cacr | clear and disable on-chip cache(s) 134 135 /* 136 * Some parameters provided by MacOS 137 * 138 * LAK: This section is the new way to pass information from the booter 139 * to the kernel. At A1 there is an environment variable which has 140 * a bunch of stuff in ascii format, "VAR=value\0VAR=value\0\0". 141 */ 142 movl %a1,%sp@- | Address of buffer 143 movl %d4,%sp@- | Some flags... (mostly not used) 144 jbsr _C_LABEL(getenvvars) | Parse the environment buffer 145 addql #8,%sp 146 147 /* Determine MMU/MPU from what we can test empirically */ 148 movl #0x200,%d0 | data freeze bit 149 movc %d0,%cacr | only exists on 68030 150 movc %cacr,%d0 | read it back 151 tstl %d0 | zero? 152 jeq Lnot68030 | yes, we have 68020/68040 153 154 movl #CACHE_OFF,%d0 | disable and clear both caches 155 movc %d0,%cacr 156 lea _C_LABEL(mmutype),%a0 | no, we have 68030 157 movl #MMU_68030,%a0@ | set to reflect 68030 PMMU 158 lea _C_LABEL(cputype),%a0 159 movl #CPU_68030,%a0@ | and 68030 MPU 160 jra Lstart1 161 162 Lnot68030: 163 bset #31,%d0 | data cache enable bit 164 movc %d0,%cacr | only exists on 68040 165 movc %cacr,%d0 | read it back 166 tstl %d0 | zero? 167 beq Lis68020 | yes, we have 68020 168 169 movql #CACHE40_OFF,%d0 | now turn it back off 170 movc %d0,%cacr | before we access any data 171 .word 0xf4f8 | cpusha bc ;push and invalidate caches 172 lea _C_LABEL(mmutype),%a0 173 movl #MMU_68040,%a0@ | Reflect 68040 MMU 174 lea _C_LABEL(cputype),%a0 175 movl #CPU_68040,%a0@ | and 68040 MPU 176 jra Lstart1 177 178 Lis68020: 179 movl #CACHE_OFF,%d0 | disable and clear cache 180 movc %d0,%cacr 181 lea _C_LABEL(mmutype),%a0 | Must be 68020+68851 182 movl #MMU_68851,%a0@ | Reflect 68851 PMMU 183 lea _C_LABEL(cputype),%a0 184 movl #CPU_68020,%a0@ | and 68020 MPU 185 186 Lstart1: 187 /* 188 * Now that we know what CPU we have, initialize the address error 189 * and bus error handlers in the vector table: 190 * 191 * vectab+8 bus error 192 * vectab+12 address error 193 */ 194 lea _C_LABEL(cputype),%a0 195 lea _C_LABEL(vectab),%a2 196 #if defined(M68040) 197 cmpl #CPU_68040,%a0@ | 68040? 198 jne 1f | no, skip 199 movl #_C_LABEL(buserr40),%a2@(8) 200 movl #_C_LABEL(addrerr4060),%a2@(12) 201 jra Lstart2 202 1: 203 #endif 204 #if defined(M68020) || defined(M68030) 205 cmpl #CPU_68040,%a0@ | 68040? 206 jeq 1f | yes, skip 207 movl #_C_LABEL(busaddrerr2030),%a2@(8) 208 movl #_C_LABEL(busaddrerr2030),%a2@(12) 209 jra Lstart2 210 1: 211 #endif 212 /* Config botch; no hope. */ 213 movl _C_LABEL(MacOSROMBase),%a1 | Load MacOS ROMBase 214 jra Ldoboot1 215 216 Lstart2: 217 jbsr _C_LABEL(setmachdep) | Set some machine-dep stuff 218 jbsr _C_LABEL(consinit) | XXX Should only be if graybar on 219 220 /* 221 * Figure out MacOS mappings and bootstrap NetBSD 222 */ 223 lea _C_LABEL(macos_tc),%a0 | get current %TC 224 cmpl #MMU_68040,_C_LABEL(mmutype) | check to see if 68040 225 jeq Lget040TC 226 227 pmove %tc,%a0@ 228 jra Lstart3 229 230 Lget040TC: 231 #if 0 232 movl _C_LABEL(current_mac_model),%a1 | if an AV Mac, save current 233 cmpl #MACH_CLASSAV,%a1@(CPUINFO_CLASS) | %TC so internal video will 234 jne LnotAV | get configured 235 #endif 236 .long 0x4e7a0003 | movc %tc,%d0 237 jra LsaveTC 238 LnotAV: 239 movql #0,%d0 | otherwise, 240 .long 0x4e7b0003 | movc %d0,%tc ;Disable MMU 241 LsaveTC: 242 movl %d0,%a0@ 243 244 Lstart3: 245 movl %a0@,%sp@- | get Mac OS mapping, relocate video, 246 jbsr _C_LABEL(bootstrap_mac68k) | bootstrap pmap, et al. 247 addql #4,%sp 248 249 /* 250 * Set up the vector table, and race to get the MMU 251 * enabled. 252 */ 253 movl #_C_LABEL(vectab),%d0 | set Vector Base Register 254 movc %d0,%vbr 255 256 movl _C_LABEL(Sysseg_pa),%a1 | system segment table PA 257 cmpl #MMU_68040,_C_LABEL(mmutype) 258 jne Lenablepre040MMU | if not 040, skip 259 260 movql #0,%d0 261 .long 0x4e7b0003 | movc %d0,%tc ;Disable MMU 262 .long 0x4e7b0004 | movc %d0,%itt0 ;Disable itt0 263 .long 0x4e7b0005 | movc %d0,%itt1 ;Disable itt1 264 .long 0x4e7b0006 | movc %d0,%dtt0 ;Disable dtt0 265 .long 0x4e7b0007 | movc %d0,%dtt1 ;Disable dtt1 266 movl %a1,%d1 267 .word 0xf518 | pflusha 268 .long 0x4e7b1807 | movc %d1,%srp 269 270 #if defined(DJMEMCMAX) 271 movl %a3,%sp@- 272 cmpl #MACH_MACC610,_C_LABEL(machineid) 273 jeq Ldjmemc610 274 cmpl #MACH_MACQ610,_C_LABEL(machineid) 275 jeq Ldjmemc610 276 cmpl #MACH_MACC650,_C_LABEL(machineid) 277 jeq Ldjmemccfg 278 cmpl #MACH_MACQ650,_C_LABEL(machineid) 279 jeq Ldjmemccfg 280 cmpl #MACH_MACQ800,_C_LABEL(machineid) 281 jeq Ldjmemccfg 282 283 jra Lnodjmemc 284 285 Ldjmemccfg: 286 movl #0x50f0e00c,%a0 287 movl %a0@,%d0 | determine where RAM SIMMs start 288 andl #0x000000FF,%d0 289 addl #0x10,%d0 | bank 3 start 290 addl #0x10,%d0 | bank 4 start 291 292 movl #0x50f0e014,%a0 293 movl %d0,%a0@+ | bank 4 294 addl #0x10,%d0 295 movl %d0,%a0@+ | bank 5 296 addl #0x10,%d0 297 298 movl %d0,%a0@+ | bank 6 299 addl #0x10,%d0 300 movl %d0,%a0@+ | bank 7 301 addl #0x10,%d0 302 movl %d0,%a0@+ | bank 8 303 addl #0x10,%d0 304 movl %d0,%a0@+ | bank 9 305 addl #0x10,%d0 306 jra Ldjmemctop 307 308 Ldjmemc610: 309 movl #0x50f0e00c,%a0 310 movl %a0@,%d0 | determine where RAM SIMMs start 311 andl #0x000000FF,%d0 312 addl #0x10,%d0 | bank 3 start 313 314 movl #0x50f0e014,%a0 315 movl %d0,%a0@+ | bank 4 316 addl #0x10,%d0 317 movl %d0,%a0@+ | bank 5 318 movl %d0,%a0@+ | bank 6 319 addl #0x10,%d0 320 movl %d0,%a0@+ | bank 7 321 movl %d0,%a0@+ | bank 8 322 addl #0x10,%d0 323 movl %d0,%a0@+ | bank 9 324 325 Ldjmemctop: 326 movl #0x50F0E02C,%a0 327 movl %d0,%a0@ | memtop 328 329 | preserve ~512KB beyond 4MB just in case 330 movl #0x400000,%a0 331 movl #0x9000000,%a2 332 movl #0xFFFF,%d0 333 L1stbankcopy1: 334 movl %a0@+,%a2@+ 335 dbra %d0,L1stbankcopy1 336 movl #0xFFFF,%d0 337 L1stbankcopy2: 338 movl %a0@+,%a2@+ 339 dbra %d0,L1stbankcopy2 340 341 lea _ASM_LABEL(Lsetup1stbank),%a0 342 movl #0x8800000,%a2 | Pick a location that should be in bank 4 343 movl #0x64,%d0 344 Ldjcopy: 345 movl %a0@+,%a2@+ 346 dbra %d0,Ldjcopy 347 348 movl #0x8800000,%a0 349 lea _ASM_LABEL(Ldjmemcdone),%a2 350 jmp %a0@ 351 352 Lsetup1stbank: 353 | now configure banks 2 & 3 354 movl #0x50f0e00c,%a0 355 movl %a0@,%d0 | determine where RAM SIMMs start 356 andl #0x000000FF,%d0 357 movl %d0,%a0@+ 358 addl #0x10,%d0 | bank 3 start 359 movl %d0,%a0@ 360 361 | and return to where we came from. 362 jmp %a2@ 363 364 Ldjmemcdone: 365 movl #0x400000,%a2 366 movl #0x9000000,%a0 367 movl #0xFFFF,%d0 368 Lcopyback1: 369 movl %a0@+,%a2@+ 370 dbra %d0,Lcopyback1 371 movl #0xFFFF,%d0 372 Lcopyback2: 373 movl %a0@+,%a2@+ 374 dbra %d0,Lcopyback2 375 376 Lnodjmemc: 377 movl %sp@+,%a3 378 #endif 379 380 movl #MMU40_TCR_BITS,%d0 381 .long 0x4e7b0003 | movc %d0,%tc ;Enable MMU 382 movl #CACHE40_ON,%d0 383 movc %d0,%cacr | turn on both caches 384 jra Lloaddone 385 386 Lenablepre040MMU: 387 tstl _C_LABEL(mmutype) | TTx instructions will break 68851 388 jgt LnokillTT 389 390 lea _ASM_LABEL(longscratch),%a0 | disable TTx registers on 68030 391 movl #0,%a0@ 392 .long 0xf0100800 | movl %a0@,%tt0 393 .long 0xf0100c00 | movl %a0@,%tt1 394 395 LnokillTT: 396 #if defined(M68020) || defined(M68030) 397 lea _C_LABEL(protorp),%a0 398 movl %a1,%a0@(4) | segtable address 399 pmove %a0@,%srp | load the supervisor root pointer 400 pflusha 401 lea _ASM_LABEL(longscratch),%a2 402 movl #MMU51_TCR_BITS,%a2@ | value to load %TC with 403 pmove %a2@,%tc | load it 404 #endif /* M68020 || M68030 */ 405 406 Lloaddone: 407 408 /* 409 * Should be running mapped from this point on 410 */ 411 lea _ASM_LABEL(tmpstk),%sp | temporary stack 412 /* phase 2 of pmap setup, returns pointer to lwp0 uarea in %a0 */ 413 jbsr _C_LABEL(pmap_bootstrap2) 414 /* set kernel stack, user SP, lwp0, and initial pcb */ 415 lea %a0@(USPACE-4),%sp | set kernel stack to end of area 416 movl #USRSTACK-4,%a2 417 movl %a2,%usp | init %USP 418 419 /* flush TLB and turn on caches */ 420 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 421 jeq Ltbia040 | yes, cache already on 422 pflusha 423 movl #CACHE_ON,%d0 424 movc %d0,%cacr | clear cache(s) 425 #ifdef __notyet__ 426 tstl _C_LABEL(ectype) 427 jeq Lnocache0 428 | Enable external cache here 429 #endif 430 jra Lnocache0 431 432 Ltbia040: 433 .word 0xf518 | pflusha 434 435 Lnocache0: 436 /* Final setup for call to main(). */ 437 jbsr _C_LABEL(mac68k_init) 438 439 /* 440 * Create a fake exception frame so that cpu_lwp_fork() can copy it. 441 * main() nevers returns; we exit to user mode from a forked process 442 * later on. 443 */ 444 clrw %sp@- | vector offset/frame type 445 clrl %sp@- | PC - filled in by "execve" 446 movw #PSL_USER,%sp@- | in user mode 447 clrl %sp@- | stack adjust count and padding 448 lea %sp@(-64),%sp | construct space for D0-D7/A0-A7 449 lea _C_LABEL(lwp0),%a0 | save pointer to frame 450 movl %sp,%a0@(L_MD_REGS) | in lwp0.l_md.md_regs 451 452 jra _C_LABEL(main) | main() 453 PANIC("main() returned") 454 /* NOTREACHED */ 455 456 /* 457 * Trap/interrupt vector routines 458 */ 459 #include <m68k/m68k/trap_subr.s> 460 461 /* 462 * Use common m68k bus error and address error handlers. 463 */ 464 .data 465 GLOBAL(mac68k_a2_fromfault) 466 .long 0 467 GLOBAL(m68k_fault_addr) 468 .long 0 469 470 #include <m68k/m68k/busaddrerr.s> 471 472 /* 473 * FP exceptions. 474 */ 475 ENTRY_NOPROFILE(fpfline) 476 #if defined(M68040) 477 cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? 478 jne Lfp_unimp | no, skip FPSP 479 cmpw #0x202c,%sp@(6) | format type 2? 480 jne _C_LABEL(illinst) | no, not an FP emulation 481 Ldofp_unimp: 482 #ifdef FPSP 483 jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it 484 #endif 485 Lfp_unimp: 486 #endif /* M68040 */ 487 #ifdef FPU_EMULATE 488 clrl %sp@- | stack adjust count 489 moveml #0xFFFF,%sp@- | save registers 490 moveq #T_FPEMULI,%d0 | denote as FP emulation trap 491 jra _ASM_LABEL(fault) | do it 492 #else 493 jra _C_LABEL(illinst) 494 #endif 495 496 ENTRY_NOPROFILE(fpunsupp) 497 #if defined(M68040) 498 cmpl #FPU_68040,_C_LABEL(fputype) | 68040 FPU? 499 jne _C_LABEL(illinst) | no, treat as illinst 500 #ifdef FPSP 501 jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it 502 #endif 503 Lfp_unsupp: 504 #endif /* M68040 */ 505 #ifdef FPU_EMULATE 506 clrl %sp@- | stack adjust count 507 moveml #0xFFFF,%sp@- | save registers 508 moveq #T_FPEMULD,%d0 | denote as FP emulation trap 509 jra _ASM_LABEL(fault) | do it 510 #else 511 jra _C_LABEL(illinst) 512 #endif 513 514 /* 515 * Handles all other FP coprocessor exceptions. 516 * Note that since some FP exceptions generate mid-instruction frames 517 * and may cause signal delivery, we need to test for stack adjustment 518 * after the trap call. 519 */ 520 ENTRY_NOPROFILE(fpfault) 521 clrl %sp@- | stack adjust count 522 moveml #0xFFFF,%sp@- | save user registers 523 movl %usp,%a0 | and save 524 movl %a0,%sp@(FR_SP) | the user stack pointer 525 clrl %sp@- | no VA arg 526 movl _C_LABEL(curpcb),%a0 | current pcb 527 lea %a0@(PCB_FPCTX),%a0 | address of FP savearea 528 fsave %a0@ | save state 529 #if defined(M68040) || defined(M68060) 530 /* always null state frame on 68040, 68060 */ 531 cmpl #FPU_68040,_C_LABEL(fputype) 532 jge Lfptnull 533 #endif 534 tstb %a0@ | null state frame? 535 jeq Lfptnull | yes, safe 536 clrw %d0 | no, need to tweak BIU 537 movb %a0@(1),%d0 | get frame size 538 bset #3,%a0@(0,%d0:w) | set exc_pend bit of BIU 539 Lfptnull: 540 fmovem %fpsr,%sp@- | push %fpsr as code argument 541 frestore %a0@ | restore state 542 movl #T_FPERR,%sp@- | push type arg 543 jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup 544 545 /* 546 * Other exceptions only cause four and six word stack frame and require 547 * no post-trap stack adjustment. 548 */ 549 550 ENTRY_NOPROFILE(badtrap) 551 moveml #0xC0C0,%sp@- | save scratch regs 552 movw %sp@(22),%sp@- | push exception vector info 553 clrw %sp@- 554 movl %sp@(22),%sp@- | and PC 555 jbsr _C_LABEL(straytrap) | report 556 addql #8,%sp | pop args 557 moveml %sp@+,#0x0303 | restore regs 558 jra _ASM_LABEL(rei) | all done 559 560 ENTRY_NOPROFILE(trap0) 561 clrl %sp@- | pad SR to longword 562 moveml #0xFFFF,%sp@- | save user registers 563 movl %usp,%a0 | save %USP 564 movl %a0,%sp@(FR_SP) | in the savearea 565 movl %d0,%sp@- | push syscall number 566 jbsr _C_LABEL(syscall) | handle it 567 addql #4,%sp | pop syscall arg 568 tstl _C_LABEL(astpending) 569 jne .Lrei2 570 tstb _C_LABEL(ssir) 571 jeq .Ltrap1 572 movw #SPL1,%sr 573 tstb _C_LABEL(ssir) 574 jne .Lsir1 575 .Ltrap1: 576 movl %sp@(FR_SP),%a0 | grab and restore 577 movl %a0,%usp | %USP 578 moveml %sp@+,#0x7FFF | restore most registers 579 addql #8,%sp | pop SSP and align word 580 rte 581 582 /* 583 * Trap 12 is the entry point for the cachectl "syscall" (both HP-UX & BSD) 584 * cachectl(command, addr, length) 585 * command in %d0, addr in %a1, length in %d1 586 */ 587 ENTRY_NOPROFILE(trap12) 588 movl _C_LABEL(curlwp),%a0 589 movl %a0@(L_PROC),%sp@- | push proc pointer 590 movl %d1,%sp@- | push length 591 movl %a1,%sp@- | push addr 592 movl %d0,%sp@- | push command 593 jbsr _C_LABEL(cachectl1) | do it 594 lea %sp@(16),%sp | pop args 595 jra _ASM_LABEL(rei) | all done 596 597 /* 598 * Trace (single-step) trap. Kernel-mode is special. 599 * User mode traps are simply passed on to trap(). 600 */ 601 ENTRY_NOPROFILE(trace) 602 clrl %sp@- | stack adjust count 603 moveml #0xFFFF,%sp@- 604 moveq #T_TRACE,%d0 605 606 | Check PSW and see what happen. 607 | T=0 S=0 (should not happen) 608 | T=1 S=0 trace trap from user mode 609 | T=0 S=1 trace trap on a trap instruction 610 | T=1 S=1 trace trap from system mode (kernel breakpoint) 611 612 movw %sp@(FR_HW),%d1 | get PSW 613 notw %d1 | XXX no support for T0 on 680[234]0 614 andw #PSL_TS,%d1 | from system mode (T=1, S=1)? 615 jeq Lkbrkpt | yes, kernel breakpoint 616 jra _ASM_LABEL(fault) | no, user-mode fault 617 618 /* 619 * Trap 15 is used for: 620 * - GDB breakpoints (in user programs) 621 * - KGDB breakpoints (in the kernel) 622 * - trace traps for SUN binaries (not fully supported yet) 623 * User mode traps are simply passed to trap(). 624 */ 625 ENTRY_NOPROFILE(trap15) 626 clrl %sp@- | stack adjust count 627 moveml #0xFFFF,%sp@- 628 moveq #T_TRAP15,%d0 629 movw %sp@(FR_HW),%d1 | get PSW 630 andw #PSL_S,%d1 | from system mode? 631 jne Lkbrkpt | yes, kernel breakpoint 632 jra _ASM_LABEL(fault) | no, user-mode fault 633 634 Lkbrkpt: | Kernel-mode breakpoint or trace trap. (%d0=trap_type) 635 | Save the system %sp rather than the user %usp. 636 movw #PSL_HIGHIPL,%sr | lock out interrupts 637 lea %sp@(FR_SIZE),%a6 | Save stack pointer 638 movl %a6,%sp@(FR_SP) | from before trap 639 640 | If were are not on tmpstk switch to it. 641 | (so debugger can change the stack pointer) 642 movl %a6,%d1 643 cmpl #_ASM_LABEL(tmpstk),%d1 644 jls Lbrkpt2 | already on tmpstk 645 | Copy frame to the temporary stack 646 movl %sp,%a0 | %a0=src 647 lea _ASM_LABEL(tmpstk)-96,%a1 | %a1=dst 648 movl %a1,%sp | %sp=new frame 649 moveq #FR_SIZE,%d1 650 Lbrkpt1: 651 movl %a0@+,%a1@+ 652 subql #4,%d1 653 bgt Lbrkpt1 654 655 Lbrkpt2: 656 | Call the trap handler for the kernel debugger. 657 | Do not call trap() to do it, so that we can 658 | set breakpoints in trap() if we want. We know 659 | the trap type is either T_TRACE or T_BREAKPOINT. 660 | If we have both DDB and KGDB, let KGDB see it first, 661 | because KGDB will just return 0 if not connected. 662 | Save args in %d2, %a2 663 movl %d0,%d2 | trap type 664 movl %sp,%a2 | frame ptr 665 #ifdef KGDB 666 | Let KGDB handle it (if connected) 667 movl %a2,%sp@- | push frame ptr 668 movl %d2,%sp@- | push trap type 669 jbsr _C_LABEL(kgdb_trap) | handle the trap 670 addql #8,%sp | pop args 671 cmpl #0,%d0 | did kgdb handle it? 672 jne Lbrkpt3 | yes, done 673 #endif 674 #ifdef DDB 675 | Let DDB handle it 676 movl %a2,%sp@- | push frame ptr 677 movl %d2,%sp@- | push trap type 678 jbsr _C_LABEL(kdb_trap) | handle the trap 679 addql #8,%sp | pop args 680 #if 0 /* not needed on hp300 */ 681 cmpl #0,%d0 | did ddb handle it? 682 jne Lbrkpt3 | yes, done 683 #endif 684 #endif 685 /* Sun 3 drops into PROM here. */ 686 Lbrkpt3: 687 | The stack pointer may have been modified, or 688 | data below it modified (by kgdb push call), 689 | so push the hardware frame at the current %sp 690 | before restoring registers and returning. 691 692 movl %sp@(FR_SP),%a0 | modified %sp 693 lea %sp@(FR_SIZE),%a1 | end of our frame 694 movl %a1@-,%a0@- | copy 2 longs with 695 movl %a1@-,%a0@- | ... predecrement 696 movl %a0,%sp@(FR_SP) | %sp = h/w frame 697 moveml %sp@+,#0x7FFF | restore all but %sp 698 movl %sp@,%sp | ... and %sp 699 rte | all done 700 701 /* 702 * Interrupt handlers. 703 * 704 * Most 68k-based Macintosh computers 705 * 706 * Level 0: Spurious: ignored 707 * Level 1: VIA1 (clock, ADB) 708 * Level 2: VIA2 (NuBus, SCSI) 709 * Level 3: 710 * Level 4: Serial (SCC) 711 * Level 5: 712 * Level 6: 713 * Level 7: Non-maskable: parity errors, RESET button 714 * 715 * On the Q700, Q900 and Q950 in "A/UX mode": this should become: 716 * 717 * Level 0: Spurious: ignored 718 * Level 1: Software 719 * Level 2: VIA2 (except ethernet, sound) 720 * Level 3: Ethernet 721 * Level 4: Serial (SCC) 722 * Level 5: Sound 723 * Level 6: VIA1 724 * Level 7: NMIs: parity errors, RESET button, YANCC error 725 * 726 * On the 660AV and 840AV: 727 * 728 * Level 0: Spurious: ignored 729 * Level 1: VIA1 (clock, ADB) 730 * Level 2: VIA2 (NuBus, SCSI) 731 * Level 3: PSC device interrupt 732 * Level 4: PSC DMA and serial 733 * Level 5: ??? 734 * Level 6: ??? 735 * Level 7: NMIs: parity errors?, RESET button 736 */ 737 738 ENTRY_NOPROFILE(spurintr) 739 addql #1,_C_LABEL(intrcnt)+0 740 INTERRUPT_SAVEREG 741 CPUINFO_INCREMENT(CI_NINTR) 742 INTERRUPT_RESTOREREG 743 jra _ASM_LABEL(rei) 744 745 ENTRY_NOPROFILE(intrhand) 746 INTERRUPT_SAVEREG 747 jbsr _C_LABEL(intr_dispatch) | call dispatch routine 748 INTERRUPT_RESTOREREG 749 jra _ASM_LABEL(rei) | all done 750 751 ENTRY_NOPROFILE(lev7intr) 752 addql #1,_C_LABEL(intrcnt)+16 753 clrl %sp@- | pad %SR to longword 754 moveml #0xFFFF,%sp@- | save registers 755 movl %usp,%a0 | and save 756 movl %a0,%sp@(FR_SP) | the user stack pointer 757 jbsr _C_LABEL(nmihand) | call handler 758 movl %sp@(FR_SP),%a0 | restore 759 movl %a0,%usp | %USP 760 moveml %sp@+,#0x7FFF | and remaining registers 761 addql #8,%sp | pop SSP and align word 762 jra _ASM_LABEL(rei) 763 764 /* 765 * We could tweak rtclock_intr and gain 12 cycles on the 020 and 030 by 766 * saving the status register directly to the stack, but this would lose 767 * badly on the 040. Aligning the stack takes 10 more cycles than this 768 * code does, so it's a good compromise. 769 * 770 * A pointer to the clockframe is passed as an argument in the usual 771 * fashion. 772 */ 773 ENTRY_NOPROFILE(rtclock_intr) 774 movl %sp@(4),%a1 | stash pointer to clockframe 775 movl %d2,%sp@- | save %d2 776 movw %sr,%d2 | save SPL 777 | raise SPL to splclock() 778 movw _C_LABEL(ipl2psl_table)+IPL_CLOCK*2,%sr 779 movl %a1,%sp@- | push pointer to clockframe 780 jbsr _C_LABEL(hardclock) | call generic clock int routine 781 addql #4,%sp | pop param 782 jbsr _C_LABEL(mrg_VBLQueue) | give programs in the VBLqueue a chance 783 addql #1,_C_LABEL(intrcnt)+32 | record a clock interrupt 784 INTERRUPT_SAVEREG 785 CPUINFO_INCREMENT(CI_NINTR) 786 INTERRUPT_RESTOREREG 787 movw %d2,%sr | restore SPL 788 movl %sp@+,%d2 | restore %d2 789 rts | go back from whence we came 790 791 /* 792 * Emulation of VAX REI instruction. 793 * 794 * This code deals with checking for and servicing ASTs 795 * (profiling, scheduling) and software interrupts (network, softclock). 796 * We check for ASTs first, just like the VAX. To avoid excess overhead 797 * the T_ASTFLT handling code will also check for software interrupts so we 798 * do not have to do it here. After identifying that we need an AST we 799 * drop the IPL to allow device interrupts. 800 * 801 * This code is complicated by the fact that sendsig may have been called 802 * necessitating a stack cleanup. 803 */ 804 805 ASENTRY_NOPROFILE(rei) 806 tstl _C_LABEL(astpending) | AST pending? 807 jeq .Lchksir | no, go check for SIR 808 .Lrei1: 809 btst #5,%sp@ | yes, are we returning to user mode? 810 jne .Lchksir | no, go check for SIR 811 movw #PSL_LOWIPL,%sr | lower SPL 812 clrl %sp@- | stack adjust 813 moveml #0xFFFF,%sp@- | save all registers 814 movl %usp,%a1 | including 815 movl %a1,%sp@(FR_SP) | %USP 816 .Lrei2: 817 clrl %sp@- | VA == none 818 clrl %sp@- | code == none 819 movl #T_ASTFLT,%sp@- | type == async system trap 820 pea %sp@(12) | fp == address of trap frame 821 jbsr _C_LABEL(trap) | go handle it 822 lea %sp@(16),%sp | pop value args 823 movl %sp@(FR_SP),%a0 | restore %USP 824 movl %a0,%usp | from save area 825 movw %sp@(FR_ADJ),%d0 | need to adjust stack? 826 jne .Laststkadj | yes, go to it 827 moveml %sp@+,#0x7FFF | no, restore most user regs 828 addql #8,%sp | toss %SP and stack adjust 829 rte | and do real RTE 830 .Laststkadj: 831 lea %sp@(FR_HW),%a1 | pointer to HW frame 832 addql #8,%a1 | source pointer 833 movl %a1,%a0 | source 834 addw %d0,%a0 | + hole size = dest pointer 835 movl %a1@-,%a0@- | copy 836 movl %a1@-,%a0@- | 8 bytes 837 movl %a0,%sp@(FR_SP) | new SSP 838 moveml %sp@+,#0x7FFF | restore user registers 839 movl %sp@,%sp | and our %SP 840 rte | and do real RTE 841 .Lchksir: 842 tstb _C_LABEL(ssir) | SIR pending? 843 jeq .Ldorte | no, all done 844 movl %d0,%sp@- | need a scratch register 845 movw %sp@(4),%d0 | get SR 846 andw #PSL_IPL7,%d0 | mask all but IPL 847 jne .Lnosir | came from interrupt, no can do 848 movl %sp@+,%d0 | restore scratch register 849 .Lgotsir: 850 movw #SPL1,%sr | prevent others from servicing int 851 tstb _C_LABEL(ssir) | too late? 852 jeq .Ldorte | yes, oh well... 853 clrl %sp@- | stack adjust 854 moveml #0xFFFF,%sp@- | save all registers 855 movl %usp,%a1 | including 856 movl %a1,%sp@(FR_SP) | %USP 857 .Lsir1: 858 clrl %sp@- | VA == none 859 clrl %sp@- | code == none 860 movl #T_SSIR,%sp@- | type == software interrupt 861 pea %sp@(12) | fp == address of trap frame 862 jbsr _C_LABEL(trap) | go handle it 863 lea %sp@(16),%sp | pop value args 864 movl %sp@(FR_SP),%a0 | restore 865 movl %a0,%usp | %USP 866 moveml %sp@+,#0x7FFF | and all remaining registers 867 addql #8,%sp | pop %SP and stack adjust 868 rte 869 .Lnosir: 870 movl %sp@+,%d0 | restore scratch register 871 .Ldorte: 872 rte | real return 873 874 /* 875 * Primitives 876 */ 877 878 /* 879 * Use common m68k process/lwp switch and context save subroutines. 880 */ 881 #define FPCOPROC /* XXX: Temp. Reqd. */ 882 #include <m68k/m68k/switch_subr.s> 883 884 #if defined(M68040) 885 ENTRY(suline) 886 movl %sp@(4),%a0 | address to write 887 movl _C_LABEL(curpcb),%a1 | current pcb 888 movl #Lslerr,%a1@(PCB_ONFAULT) | where to return to on a fault 889 movl %sp@(8),%a1 | address of line 890 movl %a1@+,%d0 | get lword 891 movsl %d0,%a0@+ | put lword 892 nop | sync 893 movl %a1@+,%d0 | get lword 894 movsl %d0,%a0@+ | put lword 895 nop | sync 896 movl %a1@+,%d0 | get lword 897 movsl %d0,%a0@+ | put lword 898 nop | sync 899 movl %a1@+,%d0 | get lword 900 movsl %d0,%a0@+ | put lword 901 nop | sync 902 moveq #0,%d0 | indicate no fault 903 jra Lsldone 904 Lslerr: 905 moveq #-1,%d0 906 Lsldone: 907 movl _C_LABEL(curpcb),%a1 | current pcb 908 clrl %a1@(PCB_ONFAULT) | clear fault address 909 rts 910 #endif 911 912 ENTRY(ecacheon) 913 rts 914 915 ENTRY(ecacheoff) 916 rts 917 918 /* 919 * Set processor priority level calls. Most are implemented with 920 * inline asm expansions. However, spl0 requires special handling 921 * as we need to check for our emulated software interrupts. 922 */ 923 924 ALTENTRY(splnone, _spl0) 925 ENTRY(spl0) 926 moveq #0,%d0 927 movw %sr,%d0 | get old SR for return 928 movw #PSL_LOWIPL,%sr | restore new SR 929 tstb _C_LABEL(ssir) | software interrupt pending? 930 jeq .Lspldone | no, all done 931 subql #4,%sp | make room for RTE frame 932 movl %sp@(4),%sp@(2) | position return address 933 clrw %sp@(6) | set frame type 0 934 movw #PSL_LOWIPL,%sp@ | and new SR 935 jra .Lgotsir | go handle it 936 .Lspldone: 937 rts 938 939 /* 940 * delay() - delay for a specified number of microseconds 941 * _delay() - calibrator helper for delay() 942 * 943 * Notice that delay_factor is scaled up by a factor of 128 to avoid loss 944 * of precision for small delays. As a result of this we need to avoid 945 * overflow. 946 * 947 * The branch target for the loops must be aligned on a half-line (8-byte) 948 * boundary to minimize cache effects. This guarantees both that there 949 * will be no prefetch stalls due to cache line burst operations and that 950 * the loops will run from a single cache half-line. 951 */ 952 .align 8 | align to half-line boundary 953 | (use nop instructions if necessary!) 954 ALTENTRY(_delay, _delay) 955 ENTRY(delay) 956 movl %sp@(4),%d0 | get microseconds to delay 957 cmpl #0x40000,%d0 | is it a "large" delay? 958 bls .Ldelayshort | no, normal calculation 959 movql #0x7f,%d1 | adjust for scaled multiplier (to 960 addl %d1,%d0 | avoid overflow) 961 lsrl #7,%d0 962 mulul _C_LABEL(delay_factor),%d0 | calculate number of loop iterations 963 bra .Ldelaysetup | go do it! 964 .Ldelayshort: 965 mulul _C_LABEL(delay_factor),%d0 | calculate number of loop iterations 966 lsrl #7,%d0 | adjust for scaled multiplier 967 .Ldelaysetup: 968 jeq .Ldelayexit | bail out if nothing to do 969 movql #0,%d1 | put bits 15-0 in %d1 for the 970 movw %d0,%d1 | inner loop, and move bits 971 movw #0,%d0 | 31-16 to the low-order word 972 subql #1,%d1 | of %d0 for the outer loop 973 swap %d0 974 .Ldelay: 975 tstl _C_LABEL(delay_flag) | this never changes for delay()! 976 dbeq %d1,.Ldelay | (used only for timing purposes) 977 dbeq %d0,.Ldelay 978 addqw #1,%d1 | adjust end count and 979 swap %d0 | return the longword result 980 orl %d1,%d0 981 .Ldelayexit: 982 rts 983 984 /* 985 * Handle the nitty-gritty of rebooting the machine. 986 * Basically we just turn off the MMU and jump to the appropriate ROM routine. 987 * Note that we must be running in an address range that is mapped one-to-one 988 * logical to physical so that the PC is still valid immediately after the MMU 989 * is turned off. We have conveniently mapped the last page of physical 990 * memory this way. 991 */ 992 ENTRY_NOPROFILE(doboot) 993 #if defined(M68040) 994 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 995 jeq Lnocache5 | yes, skip 996 #endif 997 movl #CACHE_OFF,%d0 998 movc %d0,%cacr | disable on-chip cache(s) 999 Lnocache5: 1000 movl _C_LABEL(last_page),%a0 | last page of physical memory 1001 lea Lbootcode,%a1 | start of boot code 1002 lea Lebootcode,%a3 | end of boot code 1003 Lbootcopy: 1004 movw %a1@+,%a0@+ | copy a word 1005 cmpl %a3,%a1 | done yet? 1006 jcs Lbootcopy | no, keep going 1007 #if defined(M68040) 1008 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 1009 jne LmotommuE | no, skip 1010 .word 0xf4f8 | cpusha bc 1011 LmotommuE: 1012 #endif 1013 movl _C_LABEL(last_page),%a0 1014 jmp %a0@ | jump to last page 1015 1016 Lbootcode: 1017 lea %a0@(0x800),%sp | physical %SP in case of NMI 1018 movl _C_LABEL(MacOSROMBase),%a1 | Load MacOS ROMBase 1019 1020 #if defined(M68040) 1021 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 1022 jne LmotommuF | no, skip 1023 movl #0,%d0 1024 movc %d0,%cacr | caches off 1025 .long 0x4e7b0003 | movc %d0,%tc (disable MMU) 1026 jra Ldoboot1 1027 LmotommuF: 1028 #endif 1029 lea _ASM_LABEL(longscratch),%a3 1030 movl #0,%a3@ | value for pmove to %TC (turn off MMU) 1031 pmove %a3@,%tc | disable MMU 1032 1033 Ldoboot1: 1034 lea %a1@(0x90),%a1 | offset of ROM reset routine 1035 jmp %a1@ | and jump to ROM to reset machine 1036 Lebootcode: 1037 1038 /* 1039 * u_long ptest040(void *addr, u_int fc); 1040 * 1041 * ptest040() does an 040 PTESTR (addr) and returns the 040 MMUSR iff 1042 * translation is enabled. This allows us to find the physical address 1043 * corresponding to a MacOS logical address for get_physical(). 1044 * sar 01-oct-1996 1045 */ 1046 ENTRY_NOPROFILE(ptest040) 1047 #if defined(M68040) 1048 .long 0x4e7a0003 | movc %tc,%d0 1049 andw #0x8000,%d0 1050 jeq Lget_phys1 | MMU is disabled 1051 movc %dfc,%d1 | Save %DFC 1052 movl %sp@(8),%d0 | Set FC for ptestr 1053 movc %d0,%dfc 1054 movl %sp@(4),%a0 | logical address to look up 1055 .word 0xf568 | ptestr (%a0) 1056 .long 0x4e7a0805 | movc %mmusr,%d0 1057 movc %d1,%dfc | Restore %DFC 1058 rts 1059 Lget_phys1: 1060 #endif 1061 movql #0,%d0 | return failure 1062 rts 1063 1064 /* 1065 * LAK: (7/24/94) This routine was added so that the 1066 * C routine that runs at startup can figure out how MacOS 1067 * had mapped memory. We want to keep the same mapping so 1068 * that when we set our MMU pointer, the PC doesn't point 1069 * in the middle of nowhere. 1070 * 1071 * long get_pte(void *addr, unsigned long pte[2], unsigned short *psr) 1072 * 1073 * Takes "addr" and looks it up in the current MMU pages. Puts 1074 * the PTE of that address in "pte" and the result of the 1075 * search in "psr". "pte" should be 2 longs in case it is 1076 * a long-format entry. 1077 * 1078 * One possible problem here is that setting the TT register 1079 * may screw something up if we access user data space in a 1080 * called function or in an interrupt service routine. 1081 * 1082 * Returns -1 on error, 0 if pte is a short-format pte, or 1083 * 1 if pte is a long-format pte. 1084 * 1085 * Be sure to only call this routine if the MMU is enabled. This 1086 * routine is probably more general than it needs to be -- it 1087 * could simply return the physical address (replacing 1088 * get_physical() in machdep). 1089 * 1090 * "gas" does not understand the %tt0 register, so we must hand- 1091 * assemble the instructions. 1092 */ 1093 ENTRY_NOPROFILE(get_pte) 1094 subql #4,%sp | make temporary space 1095 1096 lea _ASM_LABEL(longscratch),%a0 1097 movl #MAC68K_TT_GET_PTE,%a0@ | See pmap.h 1098 .long 0xf0100800 | pmove %a0@,%tt0 1099 1100 movl %sp@(8),%a0 | logical address to look up 1101 movl #0,%a1 | clear in case of failure 1102 ptestr #FC_USERD,%a0@,#7,%a1 | search for logical address 1103 pmove %psr,%sp@ | store processor status register 1104 movw %sp@,%d1 1105 movl %sp@(16),%a0 | where to store the %psr 1106 movw %d1,%a0@ | send back to caller 1107 andw #0xc400,%d1 | if bus error, exceeded limit, or invalid 1108 jne get_pte_fail1 | leave now 1109 tstl %a1 | check address we got back 1110 jeq get_pte_fail2 | if 0, then was not set -- fail 1111 1112 movl %a1,%d0 1113 movl %d0,_ASM_LABEL(pte_tmp) | save for later 1114 1115 | send first long back to user 1116 movl %sp@(12),%a0 | address of where to put pte 1117 movsl %a1@,%d0 | 1118 movl %d0,%a0@ | first long 1119 1120 andl #3,%d0 | dt bits of pte 1121 cmpl #1,%d0 | should be 1 if page descriptor 1122 jne get_pte_fail3 | if not, get out now 1123 1124 movl %sp@(16),%a0 | addr of stored %psr 1125 movw %a0@,%d0 | get %psr again 1126 andw #7,%d0 | number of levels it found 1127 addw #-1,%d0 | find previous level 1128 movl %sp@(8),%a0 | logical address to look up 1129 movl #0,%a1 | clear in case of failure 1130 1131 cmpl #0,%d0 1132 jeq pte_level_zero 1133 cmpl #1,%d0 1134 jeq pte_level_one 1135 cmpl #2,%d0 1136 jeq pte_level_two 1137 cmpl #3,%d0 1138 jeq pte_level_three 1139 cmpl #4,%d0 1140 jeq pte_level_four 1141 cmpl #5,%d0 1142 jeq pte_level_five 1143 cmpl #6,%d0 1144 jeq pte_level_six 1145 jra get_pte_fail4 | really should have been one of these... 1146 1147 pte_level_zero: 1148 | must get CRP to get length of entries at first level 1149 lea _ASM_LABEL(longscratch),%a0 | space for two longs 1150 pmove %crp,%a0@ | save root pointer 1151 movl %a0@,%d0 | load high long 1152 jra pte_got_parent 1153 pte_level_one: 1154 ptestr #FC_USERD,%a0@,#1,%a1 | search for logical address 1155 pmove %psr,%sp@ | store processor status register 1156 movw %sp@,%d1 1157 jra pte_got_it 1158 pte_level_two: 1159 ptestr #FC_USERD,%a0@,#2,%a1 | search for logical address 1160 pmove %psr,%sp@ | store processor status register 1161 movw %sp@,%d1 1162 jra pte_got_it 1163 pte_level_three: 1164 ptestr #FC_USERD,%a0@,#3,%a1 | search for logical address 1165 pmove %psr,%sp@ | store processor status register 1166 movw %sp@,%d1 1167 jra pte_got_it 1168 pte_level_four: 1169 ptestr #FC_USERD,%a0@,#4,%a1 | search for logical address 1170 pmove %psr,%sp@ | store processor status register 1171 movw %sp@,%d1 1172 jra pte_got_it 1173 pte_level_five: 1174 ptestr #FC_USERD,%a0@,#5,%a1 | search for logical address 1175 pmove %psr,%sp@ | store processor status register 1176 movw %sp@,%d1 1177 jra pte_got_it 1178 pte_level_six: 1179 ptestr #FC_USERD,%a0@,#6,%a1 | search for logical address 1180 pmove %psr,%sp@ | store processor status register 1181 movw %sp@,%d1 1182 1183 pte_got_it: 1184 andw #0xc400,%d1 | if bus error, exceeded limit, or invalid 1185 jne get_pte_fail5 | leave now 1186 tstl %a1 | check address we got back 1187 jeq get_pte_fail6 | if 0, then was not set -- fail 1188 1189 movsl %a1@,%d0 | get pte of parent 1190 movl %d0,_C_LABEL(macos_tt0) | XXX for later analysis (kill me) 1191 pte_got_parent: 1192 andl #3,%d0 | dt bits of pte 1193 cmpl #2,%d0 | child is short-format descriptor 1194 jeq short_format 1195 cmpl #3,%d0 | child is long-format descriptor 1196 jne get_pte_fail7 1197 1198 | long_format -- we must go back, change the tt, and get the 1199 | second long. The reason we didn't do this in the first place 1200 | is that the first long might have been the last long of RAM. 1201 1202 movl _ASM_LABEL(pte_tmp),%a1 | get address of our original pte 1203 addql #4,%a1 | address of ite second long 1204 1205 | send second long back to user 1206 movl %sp@(12),%a0 | address of where to put pte 1207 movsl %a1@,%d0 | 1208 movl %d0,%a0@(4) | write in second long 1209 1210 movql #1,%d0 | return long-format 1211 jra get_pte_success 1212 1213 short_format: 1214 movql #0,%d0 | return short-format 1215 jra get_pte_success 1216 1217 get_pte_fail: 1218 movql #-1,%d0 | return failure 1219 1220 get_pte_success: 1221 lea _ASM_LABEL(longscratch),%a0 | disable tt 1222 movl #0,%a0@ 1223 .long 0xf0100800 | pmove %a0@,%tt0 1224 1225 addql #4,%sp | return temporary space 1226 rts 1227 1228 get_pte_fail1: 1229 jbsr _C_LABEL(printstar) 1230 jra get_pte_fail 1231 get_pte_fail2: 1232 jbsr _C_LABEL(printstar) 1233 jbsr _C_LABEL(printstar) 1234 jra get_pte_fail 1235 get_pte_fail3: 1236 jbsr _C_LABEL(printstar) 1237 jbsr _C_LABEL(printstar) 1238 jbsr _C_LABEL(printstar) 1239 jra get_pte_fail 1240 get_pte_fail4: 1241 jbsr _C_LABEL(printstar) 1242 jbsr _C_LABEL(printstar) 1243 jbsr _C_LABEL(printstar) 1244 jbsr _C_LABEL(printstar) 1245 jra get_pte_fail 1246 get_pte_fail5: 1247 jbsr _C_LABEL(printstar) 1248 jbsr _C_LABEL(printstar) 1249 jbsr _C_LABEL(printstar) 1250 jbsr _C_LABEL(printstar) 1251 jbsr _C_LABEL(printstar) 1252 jra get_pte_fail 1253 get_pte_fail6: 1254 jbsr _C_LABEL(printstar) 1255 jbsr _C_LABEL(printstar) 1256 jbsr _C_LABEL(printstar) 1257 jbsr _C_LABEL(printstar) 1258 jbsr _C_LABEL(printstar) 1259 jbsr _C_LABEL(printstar) 1260 jra get_pte_fail 1261 get_pte_fail7: 1262 jbsr _C_LABEL(printstar) 1263 jbsr _C_LABEL(printstar) 1264 jbsr _C_LABEL(printstar) 1265 jbsr _C_LABEL(printstar) 1266 jbsr _C_LABEL(printstar) 1267 jbsr _C_LABEL(printstar) 1268 jbsr _C_LABEL(printstar) 1269 jra get_pte_fail 1270 get_pte_fail8: 1271 jbsr _C_LABEL(printstar) 1272 jbsr _C_LABEL(printstar) 1273 jbsr _C_LABEL(printstar) 1274 jbsr _C_LABEL(printstar) 1275 jbsr _C_LABEL(printstar) 1276 jbsr _C_LABEL(printstar) 1277 jbsr _C_LABEL(printstar) 1278 jbsr _C_LABEL(printstar) 1279 jra get_pte_fail 1280 get_pte_fail9: 1281 jbsr _C_LABEL(printstar) 1282 jbsr _C_LABEL(printstar) 1283 jbsr _C_LABEL(printstar) 1284 jbsr _C_LABEL(printstar) 1285 jbsr _C_LABEL(printstar) 1286 jbsr _C_LABEL(printstar) 1287 jbsr _C_LABEL(printstar) 1288 jbsr _C_LABEL(printstar) 1289 jbsr _C_LABEL(printstar) 1290 jra get_pte_fail 1291 get_pte_fail10: 1292 jbsr _C_LABEL(printstar) 1293 jbsr _C_LABEL(printstar) 1294 jbsr _C_LABEL(printstar) 1295 jbsr _C_LABEL(printstar) 1296 jbsr _C_LABEL(printstar) 1297 jbsr _C_LABEL(printstar) 1298 jbsr _C_LABEL(printstar) 1299 jbsr _C_LABEL(printstar) 1300 jbsr _C_LABEL(printstar) 1301 jbsr _C_LABEL(printstar) 1302 jra get_pte_fail 1303 1304 /* 1305 * Misc. global variables. 1306 */ 1307 .data 1308 GLOBAL(sanity_check) 1309 .long 0x18621862 | this is our stack overflow checker. 1310 1311 .space 4 * PAGE_SIZE 1312 .align 4 1313 ASLOCAL(tmpstk) 1314 1315 GLOBAL(machineid) 1316 .long 0 | default to 320 1317 1318 GLOBAL(mmutype) 1319 .long MMU_68851 | default to 68851 PMMU 1320 1321 GLOBAL(cputype) 1322 .long CPU_68020 | default to 68020 CPU 1323 1324 #ifdef __notyet__ 1325 GLOBAL(ectype) 1326 .long EC_NONE | external cache type, default to none 1327 #endif 1328 1329 GLOBAL(fputype) 1330 .long FPU_68882 | default to 68882 FPU 1331 1332 GLOBAL(intiolimit) 1333 .long 0 | KVA of end of internal IO space 1334 1335 GLOBAL(load_addr) 1336 .long 0 | Physical address of kernel 1337 1338 ASLOCAL(lastpage) 1339 .long 0 | LAK: to store the addr of last page in mem 1340 1341 GLOBAL(MacOSROMBase) 1342 .long 0x40800000 1343 GLOBAL(mac68k_vrsrc_cnt) 1344 .long 0 1345 GLOBAL(mac68k_vrsrc_vec) 1346 .word 0, 0, 0, 0, 0, 0 1347 1348 #ifdef DEBUG 1349 ASGLOBAL(fulltflush) 1350 .long 0 1351 1352 ASGLOBAL(fullcflush) 1353 .long 0 1354 #endif 1355 1356 /* interrupt counters -- leave some space for overriding the names */ 1357 1358 GLOBAL(intrnames) 1359 .asciz "spur " 1360 .asciz "via1 " 1361 .asciz "via2 " 1362 .asciz "unused1 " 1363 .asciz "scc " 1364 .asciz "unused2 " 1365 .asciz "unused3 " 1366 .asciz "nmi " 1367 .asciz "clock " 1368 GLOBAL(eintrnames) 1369 .even 1370 1371 GLOBAL(intrcnt) 1372 .long 0,0,0,0,0,0,0,0,0 1373 GLOBAL(eintrcnt) 1374