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