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