1/* $NetBSD: locore.s,v 1.112 2018/12/19 13:57:46 maxv Exp $ */ 2 3/* 4 * Copyright (c) 1988 University of Utah. 5 * Copyright (c) 1980, 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 * from: Utah $Hdr: locore.s 1.58 91/04/22$ 37 * 38 * @(#)locore.s 7.11 (Berkeley) 5/9/91 39 */ 40 41/* 42 * 43 * Original (hp300) Author: unknown, maybe Mike Hibler? 44 * Amiga author: Markus Wild 45 * Atari Modifications: Leo Weppelman 46 */ 47 48#include "opt_compat_netbsd.h" 49#include "opt_compat_sunos.h" 50#include "opt_ddb.h" 51#include "opt_fpsp.h" 52#include "opt_kgdb.h" 53#include "opt_lockdebug.h" 54#include "opt_mbtype.h" 55#include "opt_m68k_arch.h" 56 57#include "kbd.h" 58#include "ncrscsi.h" 59#include "zs.h" 60 61#include "assym.h" 62#include <machine/asm.h> 63 64/* 65 * This is for kvm_mkdb, and should be the address of the beginning 66 * of the kernel text segment (not necessarily the same as kernbase). 67 */ 68 .text 69 GLOBAL(kernel_text) 70 71/* 72 * Clear & skip page zero, it will not be mapped 73 */ 74 .fill PAGE_SIZE/4,4,0 75 76#include <atari/atari/vectors.s> 77 78 .text 79 .even 80/* 81 * Do a dump. 82 * Called by auto-restart. 83 */ 84ENTRY_NOPROFILE(doadump) 85 jbsr _C_LABEL(dumpsys) 86 jbsr _C_LABEL(doboot) 87 /*NOTREACHED*/ 88 89/* 90 * Trap/interrupt vector routines 91 */ 92#include <m68k/m68k/trap_subr.s> 93 94#if defined(M68040) || defined(M68060) 95ENTRY_NOPROFILE(addrerr4060) 96 clrl %sp@- | stack adjust count 97 moveml #0xFFFF,%sp@- | save user registers 98 movl %usp,%a0 | save the user SP 99 movl %a0,%sp@(FR_SP) | in the savearea 100 movl %sp@(FR_HW+8),%sp@- 101 clrl %sp@- | dummy code 102 movl #T_ADDRERR,%sp@- | mark address error 103 jra _ASM_LABEL(faultstkadj) | and deal with it 104#endif /* defined(M68040) || defined(M68060) */ 105 106#if defined(M68060) 107ENTRY_NOPROFILE(buserr60) 108 clrl %sp@- | stack adjust count 109 moveml #0xFFFF,%sp@- | save user registers 110 movl %usp,%a0 | save the user SP 111 movl %a0,%sp@(FR_SP) | in the savearea 112 movel %sp@(FR_HW+12),%d0 | FSLW 113 btst #2,%d0 | branch prediction error? 114 jeq Lnobpe 115 movc %cacr,%d2 116 orl #IC60_CABC,%d2 | clear all branch cache entries 117 movc %d2,%cacr 118 movl %d0,%d1 119 addql #1,L60bpe 120 andl #0x7ffd,%d1 121 jeq _ASM_LABEL(faultstkadjnotrap2) 122Lnobpe: 123| we need to adjust for misaligned addresses 124 movl %sp@(FR_HW+8),%d1 | grab VA 125 btst #27,%d0 | check for mis-aligned access 126 jeq Lberr3 | no, skip 127 addl #28,%d1 | yes, get into next page 128 | operand case: 3, 129 | instruction case: 4+12+12 130 andl #PG_FRAME,%d1 | and truncate 131Lberr3: 132 movl %d1,%sp@- 133 movl %d0,%sp@- | code is FSLW now. 134 andw #0x1f80,%d0 135 jeq Lisberr 136 movl #T_MMUFLT,%sp@- | show that we are an MMU fault 137 jra _ASM_LABEL(faultstkadj) | and deal with it 138#endif /* defined(M68060) */ 139 140#if defined(M68040) 141ENTRY_NOPROFILE(buserr40) 142 clrl %sp@- | stack adjust count 143 moveml #0xFFFF,%sp@- | save user registers 144 movl %usp,%a0 | save the user SP 145 movl %a0,%sp@(FR_SP) | in the savearea 146 movl %sp@(FR_HW+20),%d1 | get fault address 147 moveq #0,%d0 148 movw %sp@(FR_HW+12),%d0 | get SSW 149 btst #11,%d0 | check for mis-aligned 150 jeq Lbe1stpg | no skip 151 addl #3,%d1 | get into next page 152 andl #PG_FRAME,%d1 | and truncate 153Lbe1stpg: 154 movl %d1,%sp@- | pass fault address. 155 movl %d0,%sp@- | pass SSW as code 156 btst #10,%d0 | test ATC 157 jeq Lisberr | it is a bus error 158 movl #T_MMUFLT,%sp@- | show that we are an MMU fault 159 jra _ASM_LABEL(faultstkadj) | and deal with it 160#endif /* defined(M68040) */ 161 162#if defined(M68020) || defined(M68030) 163ENTRY_NOPROFILE(buserr2030) 164ENTRY_NOPROFILE(addrerr2030) 165 clrl %sp@- | stack adjust count 166 moveml #0xFFFF,%sp@- | save user registers 167 movl %usp,%a0 | save the user SP 168 movl %a0,%sp@(FR_SP) | in the savearea 169 moveq #0,%d0 170 movw %sp@(FR_HW+10),%d0 | grab SSW for fault processing 171 btst #12,%d0 | RB set? 172 jeq LbeX0 | no, test RC 173 bset #14,%d0 | yes, must set FB 174 movw %d0,%sp@(FR_HW+10) | for hardware too 175LbeX0: 176 btst #13,%d0 | RC set? 177 jeq LbeX1 | no, skip 178 bset #15,%d0 | yes, must set FC 179 movw %d0,%sp@(FR_HW+10) | for hardware too 180LbeX1: 181 btst #8,%d0 | data fault? 182 jeq Lbe0 | no, check for hard cases 183 movl %sp@(FR_HW+16),%d1 | fault address is as given in frame 184 jra Lbe10 | thats it 185Lbe0: 186 btst #4,%sp@(FR_HW+6) | long (type B) stack frame? 187 jne Lbe4 | yes, go handle 188 movl %sp@(FR_HW+2),%d1 | no, can use save PC 189 btst #14,%d0 | FB set? 190 jeq Lbe3 | no, try FC 191 addql #4,%d1 | yes, adjust address 192 jra Lbe10 | done 193Lbe3: 194 btst #15,%d0 | FC set? 195 jeq Lbe10 | no, done 196 addql #2,%d1 | yes, adjust address 197 jra Lbe10 | done 198Lbe4: 199 movl %sp@(FR_HW+36),%d1 | long format, use stage B address 200 btst #15,%d0 | FC set? 201 jeq Lbe10 | no, all done 202 subql #2,%d1 | yes, adjust address 203Lbe10: 204 movl %d1,%sp@- | push fault VA 205 movl %d0,%sp@- | and padded SSW 206 movw %sp@(FR_HW+8+6),%d0 | get frame format/vector offset 207 andw #0x0FFF,%d0 | clear out frame format 208 cmpw #12,%d0 | address error vector? 209 jeq Lisaerr | yes, go to it 210 movl %d1,%a0 | fault address 211 movl %sp@,%d0 | function code from ssw 212 btst #8,%d0 | data fault? 213 jne Lbe10a 214 movql #1,%d0 | user program access FC 215 | (we do not separate data/program) 216 btst #5,%sp@(FR_HW+8) | supervisor mode? 217 jeq Lbe10a | if no, done 218 movql #5,%d0 | else supervisor program access 219Lbe10a: 220 ptestr %d0,%a0@,#7 | do a table search 221 pmove %psr,%sp@ | save result 222 movb %sp@,%d1 223 btst #2,%d1 | invalid (incl. limit viol. and berr)? 224 jeq Lmightnotbemerr | no -> wp check 225 btst #7,%d1 | is it MMU table berr? 226 jeq Lismerr | no, must be fast 227 jra Lisberr1 | real bus err needs not be fast. 228Lmightnotbemerr: 229 btst #3,%d1 | write protect bit set? 230 jeq Lisberr1 | no: must be bus error 231 movl %sp@,%d0 | ssw into low word of d0 232 andw #0xc0,%d0 | Write protect is set on page: 233 cmpw #0x40,%d0 | was it read cycle? 234 jeq Lisberr1 | yes, was not WPE, must be bus err 235Lismerr: 236 movl #T_MMUFLT,%sp@- | show that we are an MMU fault 237 jra _ASM_LABEL(faultstkadj) | and deal with it 238Lisaerr: 239 movl #T_ADDRERR,%sp@- | mark address error 240 jra _ASM_LABEL(faultstkadj) | and deal with it 241Lisberr1: 242 clrw %sp@ | re-clear pad word 243#endif /* !(defined(M68020) || defined(M68030)) */ 244 245Lisberr: | also used by M68040/60 246 tstl _C_LABEL(nofault) | device probe? 247 jeq LberrIsProbe | no, handle as usual 248 movl _C_LABEL(nofault),%sp@- | yes, 249 jbsr _C_LABEL(longjmp) | longjmp(nofault) 250 /* NOTREACHED */ 251LberrIsProbe: 252 movl #T_BUSERR,%sp@- | mark bus error 253 jra _ASM_LABEL(faultstkadj) | and deal with it 254 255 /* 256 * This is where the default vectors end-up! 257 * At the time of the 'machine-type' probes, it seems necessary 258 * that the 'nofault' test is done first. Because the MMU is not 259 * yet setup at this point, the real fault handlers sometimes 260 * misinterpret the cause of the fault. 261 */ 262ENTRY_NOPROFILE(buserr) 263ENTRY_NOPROFILE(addrerr) 264 tstl _C_LABEL(nofault) | device probe? 265 jeq 1f | no, halt... 266 movl _C_LABEL(nofault),%sp@- | yes, 267 jbsr _C_LABEL(longjmp) | longjmp(nofault) 268 /* NOTREACHED */ 2691: 270 jra _C_LABEL(badtrap) | only catch probes! 271 272/* 273 * FP exceptions. 274 */ 275ENTRY_NOPROFILE(fpfline) 276 cmpl #MMU_68040,_C_LABEL(mmutype) 277 jne fpfline_not40 | not a 040 FPU, do 6888? emulation 278 cmpw #0x202c,%sp@(6) | format type 2? 279 jne _C_LABEL(illinst) | no, not an FP emulation 280#ifdef FPSP 281 jmp _ASM_LABEL(fpsp_unimp) | yes, go handle it 282#endif 283fpfline_not40: 284 clrl %sp@- | stack adjust count 285 moveml #0xFFFF,%sp@- | save registers 286 moveq #T_FPEMULI,%d0 | denote as FP emulation trap 287 jra _ASM_LABEL(fault) | do it 288 289ENTRY_NOPROFILE(fpunsupp) 290 cmpl #MMU_68040,_C_LABEL(mmutype) 291 jne fpunsupp_not40 | not a 040 FPU, try 6888? 292#ifdef FPSP 293 jmp _ASM_LABEL(fpsp_unsupp) | yes, go handle it 294#endif 295fpunsupp_not40: 296 clrl %sp@- | stack adjust count 297 moveml #0xFFFF,%sp@- | save registers 298 moveq #T_FPEMULD,%d0 | denote as FP emulation trap 299 jra _ASM_LABEL(fault) | do it 300 301/* 302 * Handles all other FP coprocessor exceptions. 303 * Note that since some FP exceptions generate mid-instruction frames 304 * and may cause signal delivery, we need to test for stack adjustment 305 * after the trap call. 306 */ 307ENTRY_NOPROFILE(fpfault) 308 clrl %sp@- | stack adjust count 309 moveml #0xFFFF,%sp@- | save user registers 310 movl %usp,%a0 | and save 311 movl %a0,%sp@(FR_SP) | the user stack pointer 312 clrl %sp@- | no VA arg 313 movl _C_LABEL(curpcb),%a0 | current pcb 314 lea %a0@(PCB_FPCTX),%a0 | address of FP savearea 315 fsave %a0@ | save state 316 317#if defined(M68040) || defined(M68060) 318#ifdef notdef /* XXX: Can't use this while we don't have the cputype */ 319 movb _C_LABEL(cputype), %d0 320 andb #(ATARI_68040|ATARI_68060), %d0 321 jne Lfptnull 322#else 323 cmpb #0x41,%a0@ | is it the 68040 FPU-frame format? 324 jeq Lfptnull | yes, safe 325#endif /* notdef */ 326#endif /* defined(M68040) || defined(M68060) */ 327 328 tstb %a0@ | null state frame? 329 jeq Lfptnull | yes, safe 330 clrw %d0 | no, need to tweak BIU 331 movb %a0@(1),%d0 | get frame size 332 bset #3,%a0@(0,%d0:w) | set exc_pend bit of BIU 333Lfptnull: 334 fmovem %fpsr,%sp@- | push fpsr as code argument 335 frestore %a0@ | restore state 336 movl #T_FPERR,%sp@- | push type arg 337 jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup 338 339/* 340 * Other exceptions only cause four and six word stack frame and require 341 * no post-trap stack adjustment. 342 */ 343 344ENTRY_NOPROFILE(intr_glue) 345 addql #1,_C_LABEL(idepth) 346 INTERRUPT_SAVEREG 347 jbsr _C_LABEL(intr_dispatch) | handle interrupt 348 INTERRUPT_RESTOREREG 349 subql #1,_C_LABEL(idepth) 350 jra _ASM_LABEL(rei) 351 352ENTRY_NOPROFILE(lev2intr) 353 rte | HBL, can't be turned off on Falcon! 354 355ENTRY_NOPROFILE(lev4intr) | VBL interrupt 356#ifdef FALCON_VIDEO 357 tstl _C_LABEL(falcon_needs_vbl) 358 jne 1f | Yes, go service a VBL-request 359 rte | Nothing to do. 3601: 361 addql #1,_C_LABEL(idepth) 362 INTERRUPT_SAVEREG 363 jbsr _C_LABEL(falcon_display_switch) 364 INTERRUPT_RESTOREREG 365 subql #1,_C_LABEL(idepth) 366#endif /* FALCON_VIDEO */ 367 rte 368 369ENTRY_NOPROFILE(lev5intr) 370ENTRY_NOPROFILE(lev6intr) 371 372#ifdef _MILANHW_ 373 /* XXX 374 * Need to find better places to define these (Leo) 375 */ 376#define PLX_PCICR 0x4204 377#define PLX_CNTRL 0x42ec 378#define PLX_DMCFGA 0x42ac 379 addql #1,_C_LABEL(idepth) 380 moveml %d0-%d2/%a0-%a1,%sp@- 381 movw %sp@(20),%sp@- | push previous SR value 382 clrw %sp@- | padded to longword 383 movl _C_LABEL(stio_addr),%a0 | get KVA of ST-IO area 384 movew #0xffff,%a0@(PLX_PCICR) | clear PCI_SR error bits 385 movel %a0@(PLX_CNTRL),%d0 | Change PCI command code from 386 andw #0xf0ff,%d0 387 movw %sr,%d2 | Block interrupts for now 388 oriw #0x0700,%sr 389 movl %d0,%a0@(PLX_CNTRL) 390 movq #0,%d1 | clear upper bits 391 | Read any (uncached!) PCI address 392 | to fetch vector number 393 movl _C_LABEL(pci_mem_uncached),%a1 394 movb %a1@,%d1 395 orw #0x0600,%d0 | Change PCI command code back 396 movel %d0,%a0@(PLX_CNTRL) | to Read Cycle 397 movew %d2,%sr | Re-enable interrupts 398 movel %d1,%sp@- | Call handler 399 jbsr _C_LABEL(milan_isa_intr) 400 addql #8,%sp 401 moveml %sp@+,%d0-%d2/%a0-%a1 402 subql #1,_C_LABEL(idepth) 403 jra _ASM_LABEL(rei) 404 405/* 406 * Support functions for reading and writing the Milan PCI config space. 407 * Of interest: 408 * - We need exclusive access to the PLX9080 during config space 409 * access, hence the splhigh(). 410 * - The 'confread' function shortcircuits the NMI to make probes to 411 * unexplored pci-config space possible. 412 */ 413ENTRY(milan_pci_confread) 414 movl %sp@(4),%d0 | get tag and regno 415 bset #31,%d0 | add config space flag 416 andl #~3,%d0 | access type 0 417 movl _C_LABEL(stio_addr),%a0 | get KVA of ST-IO area 418 movw %sr,%d1 | goto splhigh 419 oriw #0x0700,%sr 420 movb #1,_ASM_LABEL(plx_nonmi)| no NMI interrupts please! 421 movl %d0,%a0@(PLX_DMCFGA) | write tag to the config register 422 movl _C_LABEL(pci_io_addr),%a1 423 movl %a1@,%d0 | fetch value 424 movl #0,%a0@(PLX_DMCFGA) | back to normal PCI access 425 426 | Make sure the C-function can peek 427 movw %a0@(PLX_PCICR),_C_LABEL(plx_status) | at the access results. 428 429 movw #0xf900,%a0@(PLX_PCICR) | Clear potential error bits 430 movb #0, _ASM_LABEL(plx_nonmi) 431 movw %d1,%sr | splx 432 rts 433 434ENTRY(milan_pci_confwrite) 435 movl %sp@(4),%d0 | get tag and regno 436 bset #31,%d0 | add config space flag 437 andl #~3,%d0 | access type 0 438 movl _C_LABEL(stio_addr),%a0 | get KVA of ST-IO area 439 movw %sr,%d1 | goto splhigh 440 oriw #0x0700,%sr 441 movl %d0,%a0@(PLX_DMCFGA) | write tag to the config register 442 movl _C_LABEL(pci_io_addr),%a1 443 movl %sp@(8),%a1@ | write value 444 movl #0,%a0@(PLX_DMCFGA) | back to normal PCI access 445 movw %d1,%sr | splx 446 rts 447 448ENTRY_NOPROFILE(lev7intr) 449 tstl _ASM_LABEL(plx_nonmi) | milan_conf_read shortcut 450 jne 1f | .... get out immediately 451 INTERRUPT_SAVEREG 452 movl _C_LABEL(stio_addr),%a0 | get KVA of ST-IO area 453 movw %a0@(PLX_PCICR),_C_LABEL(plx_status) 454 movw #0xf900,%a0@(PLX_PCICR) | Clear error bits 455 jbsr _C_LABEL(nmihandler) | notify... 456 INTERRUPT_RESTOREREG 457 addql #1,_C_LABEL(intrcnt)+28 | add another nmi interrupt 4581: 459 rte | all done 460#endif /* _MILANHW_ */ 461 462ENTRY_NOPROFILE(lev3intr) 463ENTRY_NOPROFILE(badtrap) 464 addql #1,_C_LABEL(idepth) 465 INTERRUPT_SAVEREG 466 movw %sp@(22),%sp@- | push exception vector info 467 clrw %sp@- 468 movl %sp@(22),%sp@- | and PC 469 jbsr _C_LABEL(straytrap) | report 470 addql #8,%sp | pop args 471 INTERRUPT_RESTOREREG | restore regs 472 subql #1,_C_LABEL(idepth) 473 jra _ASM_LABEL(rei) | all done 474 475ENTRY_NOPROFILE(badmfpint) 476 addql #1,_C_LABEL(idepth) 477 INTERRUPT_SAVEREG | save scratch regs 478 movw %sp@(22),%sp@- | push exception vector info 479 clrw %sp@- 480 movl %sp@(22),%sp@- | and PC 481 jbsr _C_LABEL(straymfpint) | report 482 addql #8,%sp | pop args 483 INTERRUPT_RESTOREREG | restore regs 484 subql #1,_C_LABEL(idepth) 485 jra _ASM_LABEL(rei) | all done 486 487ENTRY_NOPROFILE(trap0) 488 clrl %sp@- | stack adjust count 489 moveml #0xFFFF,%sp@- | save user registers 490 movl %usp,%a0 | save the user SP 491 movl %a0,%sp@(FR_SP) | in the savearea 492 movl %d0,%sp@- | push syscall number 493 jbsr _C_LABEL(syscall) | handle it 494 addql #4,%sp | pop syscall arg 495 movl %sp@(FR_SP),%a0 | grab and restore 496 movl %a0,%usp | user SP 497 moveml %sp@+,#0x7FFF | restore most registers 498 addql #8,%sp | pop SP and stack adjust 499 jra _ASM_LABEL(rei) | all done 500 501/* 502 * Trap 12 is the entry point for the cachectl "syscall" 503 * cachectl(command, addr, length) 504 * command in d0, addr in a1, length in d1 505 */ 506ENTRY_NOPROFILE(trap12) 507 movl _C_LABEL(curlwp),%a0 508 movl %a0@(L_PROC),%sp@- | push curproc pointer 509 movl %d1,%sp@- | push length 510 movl %a1,%sp@- | push addr 511 movl %d0,%sp@- | push command 512 jbsr _C_LABEL(cachectl1) | do it 513 lea %sp@(16),%sp | pop args 514 jra _ASM_LABEL(rei) | all done 515 516/* 517 * Trace (single-step) trap. Kernel-mode is special. 518 * User mode traps are simply passed on to trap(). 519 */ 520ENTRY_NOPROFILE(trace) 521 clrl %sp@- | stack adjust count 522 moveml #0xFFFF,%sp@- 523 moveq #T_TRACE,%d0 524 525 | Check PSW and see what happen. 526 | T=0 S=0 (should not happen) 527 | T=1 S=0 trace trap from user mode 528 | T=0 S=1 trace trap on a trap instruction 529 | T=1 S=1 trace trap from system mode (kernel breakpoint) 530 531 movw %sp@(FR_HW),%d1 | get PSW 532 notw %d1 | XXX no support for T0 on 680[234]0 533 andw #PSL_TS,%d1 | from system mode (T=1, S=1)? 534 jeq Lkbrkpt | yes, kernel breakpoint 535 jra _ASM_LABEL(fault) | no, user-mode fault 536 537/* 538 * Trap 15 is used for: 539 * - GDB breakpoints (in user programs) 540 * - KGDB breakpoints (in the kernel) 541 * - trace traps for SUN binaries (not fully supported yet) 542 * User mode traps are simply passed to trap(). 543 */ 544ENTRY_NOPROFILE(trap15) 545 clrl %sp@- 546 moveml #0xFFFF,%sp@- 547 moveq #T_TRAP15,%d0 548 movw %sp@(FR_HW),%d1 | get PSW 549 andw #PSL_S,%d1 | from system mode? 550 jne Lkbrkpt | yes, kernel breakpoint 551 jra _ASM_LABEL(fault) | no, user-mode fault 552 553Lkbrkpt: 554 | Kernel-mode breakpoint or trace trap. (d0=trap_type) 555 | Save the system sp rather than the user sp. 556 movw #PSL_HIGHIPL,%sr | lock out interrupts 557 lea %sp@(FR_SIZE),%a6 | Save stack pointer 558 movl %a6,%sp@(FR_SP) | from before trap 559 560 | If were are not on tmpstk switch to it. 561 | (so debugger can change the stack pointer) 562 movl %a6,%d1 563 cmpl #_ASM_LABEL(tmpstk),%d1 564 jls Lbrkpt2 | already on tmpstk 565 | Copy frame to the temporary stack 566 movl %sp,%a0 | a0=src 567 lea _ASM_LABEL(tmpstk)-96,%a1 | a1=dst 568 movl %a1,%sp | sp=new frame 569 moveq #FR_SIZE,%d1 570Lbrkpt1: 571 movl %a0@+,%a1@+ 572 subql #4,%d1 573 bgt Lbrkpt1 574 575Lbrkpt2: 576 | Call the trap handler for the kernel debugger. 577 | Do not call trap() to do it, so that we can 578 | set breakpoints in trap() if we want. We know 579 | the trap type is either T_TRACE or T_BREAKPOINT. 580 | If we have both DDB and KGDB, let KGDB see it first, 581 | because KGDB will just return 0 if not connected. 582 | Save args in d2, a2 583 movl %d0,%d2 | trap type 584 movl %sp,%a2 | frame ptr 585#ifdef KGDB 586 | Let KGDB handle it (if connected) 587 movl %a2,%sp@- | push frame ptr 588 movl %d2,%sp@- | push trap type 589 jbsr _C_LABEL(kgdb_trap) | handle the trap 590 addql #8,%sp | pop args 591 cmpl #0,%d0 | did kgdb handle it? 592 jne Lbrkpt3 | yes, done 593#endif 594#ifdef DDB 595 | Let DDB handle it 596 movl %a2,%sp@- | push frame ptr 597 movl %d2,%sp@- | push trap type 598 jbsr _C_LABEL(kdb_trap) | handle the trap 599 addql #8,%sp | pop args 600#if 0 /* not needed on atari */ 601 cmpl #0,%d0 | did ddb handle it? 602 jne Lbrkpt3 | yes, done 603#endif 604#endif 605 /* Sun 3 drops into PROM here. */ 606Lbrkpt3: 607 | The stack pointer may have been modified, or 608 | data below it modified (by kgdb push call), 609 | so push the hardware frame at the current sp 610 | before restoring registers and returning. 611 612 movl %sp@(FR_SP),%a0 | modified sp 613 lea %sp@(FR_SIZE),%a1 | end of our frame 614 movl %a1@-,%a0@- | copy 2 longs with 615 movl %a1@-,%a0@- | ... predecrement 616 movl %a0,%sp@(FR_SP) | sp = h/w frame 617 moveml %sp@+,#0x7FFF | restore all but sp 618 movl %sp@,%sp | ... and sp 619 rte | all done 620 621/* Use common m68k sigreturn */ 622#include <m68k/m68k/sigreturn.s> 623 624/* 625 * Interrupt handlers. 626 * 627 * Level 0: Spurious: ignored. 628 * Level 1: softint 629 * Level 2: HBL 630 * Level 3: not used 631 * Level 4: not used 632 * Level 5: SCC (not used) 633 * Level 6: MFP1/MFP2 (not used -> autovectored) 634 * Level 7: Non-maskable: shouldn't be possible. ignore. 635 */ 636 637/* Provide a generic interrupt dispatcher, only handle hardclock (int6) 638 * specially, to improve performance 639 */ 640 641ENTRY_NOPROFILE(spurintr) 642 addql #1,_C_LABEL(intrcnt)+0 643 INTERRUPT_SAVEREG | save scratch registers 644 CPUINFO_INCREMENT(CI_NINTR) 645 INTERRUPT_RESTOREREG | restore scratch regs 646 jra _ASM_LABEL(rei) 647 648 /* MFP timer A handler --- System clock --- */ 649ASENTRY_NOPROFILE(mfp_tima) 650 addql #1,_C_LABEL(idepth) 651 INTERRUPT_SAVEREG | save scratch registers 652 movl %sp,%sp@- | push pointer to clockframe 653 jbsr _C_LABEL(hardclock) | call generic clock int routine 654 addql #4,%sp | pop params 655 addql #1,_C_LABEL(intrcnt_user)+52 656 | add another system clock interrupt 657 CPUINFO_INCREMENT(CI_NINTR) 658 INTERRUPT_RESTOREREG | restore scratch regs 659 subql #1,_C_LABEL(idepth) 660 jra _ASM_LABEL(rei) | all done 661 662#ifdef STATCLOCK 663 /* MFP timer C handler --- Stat/Prof clock --- */ 664ASENTRY_NOPROFILE(mfp_timc) 665 addql #1,_C_LABEL(idepth) 666 INTERRUPT_SAVEREG | save scratch registers 667 jbsr _C_LABEL(statintr) | call statistics clock handler 668 addql #1,_C_LABEL(intrcnt)+36 | add another stat clock interrupt 669 CPUINFO_INCREMENT(CI_NINTR) 670 INTERRUPT_RESTOREREG | restore scratch regs 671 subql #1,_C_LABEL(idepth) 672 jra _ASM_LABEL(rei) | all done 673#endif /* STATCLOCK */ 674 675#if NKBD > 0 676 /* MFP ACIA handler --- keyboard/midi --- */ 677ASENTRY_NOPROFILE(mfp_kbd) 678 addql #1,_C_LABEL(idepth) 679 addql #1,_C_LABEL(intrcnt)+8 | add another kbd/mouse interrupt 680 681 INTERRUPT_SAVEREG | save scratch registers 682 movw %sp@(16),%sp@- | push previous SR value 683 clrw %sp@- | padded to longword 684 jbsr _C_LABEL(kbdintr) | handle interrupt 685 addql #4,%sp | pop SR 686 CPUINFO_INCREMENT(CI_NINTR) 687 INTERRUPT_RESTOREREG | restore scratch regs 688 subql #1,_C_LABEL(idepth) 689 jra _ASM_LABEL(rei) 690#endif /* NKBD */ 691 692#if NNCRSCSI > 0 693 /* MFP2 SCSI DMA handler --- NCR5380 --- */ 694ASENTRY_NOPROFILE(mfp2_5380dm) 695 addql #1,_C_LABEL(idepth) 696 addql #1,_C_LABEL(intrcnt)+24 | add another 5380-DMA interrupt 697 698 INTERRUPT_SAVEREG | save scratch registers 699 movw %sp@(16),%sp@- | push previous SR value 700 clrw %sp@- | padded to longword 701 jbsr _C_LABEL(scsi_dma) | handle interrupt 702 addql #4,%sp | pop SR 703 CPUINFO_INCREMENT(CI_NINTR) 704 INTERRUPT_RESTOREREG | restore scratch regs 705 subql #1,_C_LABEL(idepth) 706 jra _ASM_LABEL(rei) 707 708 /* MFP2 SCSI handler --- NCR5380 --- */ 709ASENTRY_NOPROFILE(mfp2_5380) 710 addql #1,_C_LABEL(idepth) 711 addql #1,_C_LABEL(intrcnt)+20 | add another 5380-SCSI interrupt 712 713 INTERRUPT_SAVEREG | save scratch registers 714 movw %sp@(16),%sp@- | push previous SR value 715 clrw %sp@- | padded to longword 716 jbsr _C_LABEL(scsi_ctrl) | handle interrupt 717 addql #4,%sp | pop SR 718 CPUINFO_INCREMENT(CI_NINTR) 719 INTERRUPT_RESTOREREG | restore scratch regs 720 subql #1,_C_LABEL(idepth) 721 jra _ASM_LABEL(rei) 722#endif /* NNCRSCSI > 0 */ 723 724#ifdef _ATARIHW_ 725 /* Level 1 (Software) interrupt handler */ 726ENTRY_NOPROFILE(lev1intr) 727 addql #1,_C_LABEL(idepth) 728 INTERRUPT_SAVEREG | save scratch registers 729 movl _C_LABEL(stio_addr),%a0 | get KVA of ST-IO area 730 moveb #0, %a0@(SCU_SOFTINT) | Turn off software interrupt 731 addql #1,_C_LABEL(intrcnt)+16 | add another software interrupt 732 jbsr _C_LABEL(nullop) | XXX handle software interrupts 733 CPUINFO_INCREMENT(CI_NINTR) 734 INTERRUPT_RESTOREREG 735 subql #1,_C_LABEL(idepth) 736 jra _ASM_LABEL(rei) 737 738 /* 739 * Should never occur, except when special hardware modification 740 * is installed. In this case, one expects to be dropped into 741 * the debugger. 742 */ 743ENTRY_NOPROFILE(lev7intr) 744#ifdef DDB 745 /* 746 * Note that the nmi has to be turned off while handling it because 747 * the hardware modification has no de-bouncing logic.... 748 */ 749 addql #1,_C_LABEL(idepth) 750 movl %a0, %sp@- | save a0 751 movl _C_LABEL(stio_addr),%a0 | get KVA of ST-IO area 752 movb %a0@(SCU_SYSMASK),%sp@- | save current sysmask 753 movb #0, %a0@(SCU_SYSMASK) | disable all interrupts 754 trap #15 | drop into the debugger 755 movb %sp@+, %a0@(SCU_SYSMASK)| restore sysmask 756 movl %sp@+, %a0 | restore a0 757 subql #1,_C_LABEL(idepth) 758#endif 759 addql #1,_C_LABEL(intrcnt)+28 | add another nmi interrupt 760 rte | all done 761 762#endif /* _ATARIHW_ */ 763 764 765/* 766 * Emulation of VAX REI instruction. 767 * 768 * This code deals with checking for and servicing ASTs 769 * (profiling, scheduling) and software interrupts (network, softclock). 770 * We check for ASTs first, just like the VAX. To avoid excess overhead 771 * the T_ASTFLT handling code will also check for software interrupts so we 772 * do not have to do it here. After identifing that we need an AST we 773 * drop the IPL to allow device interrupts. 774 * 775 * This code is complicated by the fact that sendsig may have been called 776 * necessitating a stack cleanup. A cleanup should only be needed at this 777 * point for coprocessor mid-instruction frames (type 9), but we also test 778 * for bus error frames (type 10 and 11). 779 */ 780ASENTRY_NOPROFILE(rei) 781#ifdef DEBUG 782 tstl _C_LABEL(panicstr) | have we paniced? 783 jne Ldorte | yes, do not make matters worse 784#endif 785 tstl _C_LABEL(astpending) | AST pending? 786 jeq Lchksir | no, go check for SIR 787Lrei1: 788 btst #5,%sp@ | yes, are we returning to user mode? 789 jne Lchksir | no, go check for SIR 790 movw #PSL_LOWIPL,%sr | lower SPL 791 clrl %sp@- | stack adjust 792 moveml #0xFFFF,%sp@- | save all registers 793 movl %usp,%a1 | including 794 movl %a1,%sp@(FR_SP) | the users SP 795 clrl %sp@- | VA == none 796 clrl %sp@- | code == none 797 movl #T_ASTFLT,%sp@- | type == async system trap 798 pea %sp@(12) | fp == address of trap frame 799 jbsr _C_LABEL(trap) | go handle it 800 lea %sp@(16),%sp | pop value args 801 movl %sp@(FR_SP),%a0 | restore user SP 802 movl %a0,%usp | from save area 803 movw %sp@(FR_ADJ),%d0 | need to adjust stack? 804 jne Laststkadj | yes, go to it 805 moveml %sp@+,#0x7FFF | no, restore most user regs 806 addql #8,%sp | toss SP and stack adjust 807 rte | and do real RTE 808Laststkadj: 809 lea %sp@(FR_HW),%a1 | pointer to HW frame 810 addql #8,%a1 | source pointer 811 movl %a1,%a0 | source 812 addw %d0,%a0 | + hole size = dest pointer 813 movl %a1@-,%a0@- | copy 814 movl %a1@-,%a0@- | 8 bytes 815 movl %a0,%sp@(FR_SP) | new SSP 816 moveml %sp@+,#0x7FFF | restore user registers 817 movl %sp@,%sp | and our SP 818 rte | and do real RTE 819Lchksir: 820 tstb _C_LABEL(ssir) | SIR pending? 821 jeq Ldorte | no, all done 822 movl %d0,%sp@- | need a scratch register 823 movw %sp@(4),%d0 | get SR 824 andw #PSL_IPL7,%d0 | mask all but IPL 825 jne Lnosir | came from interrupt, no can do 826 movl %sp@+,%d0 | restore scratch register 827Lgotsir: 828 movw #SPL1,%sr | prevent others from servicing int 829 tstb _C_LABEL(ssir) | too late? 830 jeq Ldorte | yes, oh well... 831 clrl %sp@- | stack adjust 832 moveml #0xFFFF,%sp@- | save all registers 833 movl %usp,%a1 | including 834 movl %a1,%sp@(FR_SP) | the users SP 835 clrl %sp@- | VA == none 836 clrl %sp@- | code == none 837 movl #T_SSIR,%sp@- | type == software interrupt 838 pea %sp@(12) | fp == address of trap frame 839 jbsr _C_LABEL(trap) | go handle it 840 lea %sp@(16),%sp | pop value args 841 movl %sp@(FR_SP),%a0 | restore 842 movl %a0,%usp | user SP 843 moveml %sp@+,#0x7FFF | and all remaining registers 844 addql #8,%sp | pop SP and stack adjust 845 rte 846Lnosir: 847 movl %sp@+,%d0 | restore scratch register 848Ldorte: 849 rte | real return 850 851/* 852 * Initialization 853 * 854 * A5 contains physical load point from boot 855 * exceptions vector thru our table, that's bad.. just hope nothing exceptional 856 * happens till we had time to initialize ourselves.. 857 */ 858 BSS(lowram,4) 859 BSS(esym,4) 860 861 .globl _C_LABEL(edata) 862 .globl _C_LABEL(etext),_C_LABEL(end) 863 864GLOBAL(bootversion) 865 .word 0x0003 | Glues kernel/installboot/loadbsd 866 | and other bootcode together. 867ASENTRY_NOPROFILE(start) 868 movw #PSL_HIGHIPL,%sr | No interrupts 869 870 /* 871 * a0 = start of loaded kernel 872 * a1 = value of esym 873 * d0 = fastmem size 874 * d1 = stmem size 875 * d2 = cputype 876 * d3 = boothowto 877 * d4 = size of loaded kernel 878 */ 879 movl #8,%a5 | Addresses 0-8 are mapped to ROM on the 880 addql #8,%a0 | atari ST. We cannot set these. 881 subl #8,%d4 882 883 /* 884 * Copy until end of kernel relocation code. 885 */ 886Lstart0: 887 movl %a0@+,%a5@+ 888 subl #4, %d4 889 cmpl #Lstart3,%a5 890 jle Lstart0 891 /* 892 * Enter kernel at destination address and continue copy 893 * Make sure that the jump is absolute (by adding ':l') otherwise 894 * the assembler tries to use a pc-relative jump. 895 * Which is definitely not what is needed at this point! 896 */ 897 jmp Lstart2:l 898Lstart2: 899 movl %a0@+,%a5@+ | copy the rest of the kernel 900 subl #4, %d4 901 jcc Lstart2 902Lstart3: 903 904 lea _ASM_LABEL(tmpstk),%sp | give ourselves a temporary stack 905 906 /* 907 * save the passed parameters. `prepass' them on the stack for 908 * later catch by _start_c 909 */ 910 movl %a1,%sp@- | pass address of _esym 911 movl %d1,%sp@- | pass stmem-size 912 movl %d0,%sp@- | pass fastmem-size 913 movl %d5,%sp@- | pass fastmem_start 914 movl %d2,%sp@- | pass machine id 915 movl %d3,_C_LABEL(boothowto) | save reboot flags 916 917 918 /* 919 * Set cputype and mmutype dependent on the machine-id passed 920 * in from the loader. Also make sure that all caches are cleared. 921 */ 922 movl #ATARI_68030,%d1 | 68030 type from loader 923 andl %d2,%d1 924 jeq Ltestfor020 | Not an 68030, try 68020 925 movl #MMU_68030,_C_LABEL(mmutype) | Use 68030 MMU 926 movl #CPU_68030,_C_LABEL(cputype) | and a 68030 CPU 927 movl #CACHE_OFF,%d0 | 68020/030 cache clear 928 jra Lend_cpuset | skip to init. 929Ltestfor020: 930 movl #ATARI_68020,%d1 | 68020 type from loader 931 andl %d2,%d1 932 jeq Ltestfor040 933 movl #MMU_68851,_C_LABEL(mmutype) | Assume 68851 with 68020 934 movl #CPU_68020,_C_LABEL(cputype) | and a 68020 CPU 935 movl #CACHE_OFF,%d0 | 68020/030 cache clear 936 jra Lend_cpuset | skip to init. 937Ltestfor040: 938 movl #CACHE_OFF,%d0 | 68020/030 cache 939 movl #ATARI_68040,%d1 940 andl %d2,%d1 941 jeq Ltestfor060 942 movl #MMU_68040,_C_LABEL(mmutype) | Use a 68040 MMU 943 movl #CPU_68040,_C_LABEL(cputype) | and a 68040 CPU 944 .word 0xf4f8 | cpusha bc - push&inval caches 945 movl #CACHE40_OFF,%d0 | 68040 cache disable 946 jra Lend_cpuset | skip to init. 947Ltestfor060: 948 movl #ATARI_68060,%d1 949 andl %d2,%d1 950 jeq Lend_cpuset 951 movl #MMU_68040,_C_LABEL(mmutype) | Use a 68040 MMU 952 movl #CPU_68060,_C_LABEL(cputype) | and a 68060 CPU 953 .word 0xf4f8 | cpusha bc - push&inval caches 954 movl #CACHE40_OFF,%d0 | 68040 cache disable 955 orl #IC60_CABC,%d0 | and clear 060 branch cache 956 957Lend_cpuset: 958 movc %d0,%cacr | clear and disable on-chip cache(s) 959 movl #_C_LABEL(vectab),%a0 | set address of vector table 960 movc %a0,%vbr 961 962 /* 963 * Initialize source/destination control registers for movs 964 */ 965 moveq #FC_USERD,%d0 | user space 966 movc %d0,%sfc | as source 967 movc %d0,%dfc | and destination of transfers 968 969 /* 970 * let the C function initialize everything and enable the MMU 971 */ 972 jsr _C_LABEL(start_c) 973 974 /* 975 * set kernel stack, user SP 976 */ 977 movl _C_LABEL(lwp0uarea),%a1 | grab lwp0 uarea 978 lea %a1@(USPACE-4),%sp | set kernel stack to end of area 979 movl #USRSTACK-4,%a2 980 movl %a2,%usp | init user SP 981 movl %a2,%a1@(PCB_USP) | and save it 982 clrw %a1@(PCB_FLAGS) | clear flags 983 984 /* flush TLB and turn on caches */ 985 jbsr _C_LABEL(_TBIA) | invalidate TLB 986 movl #CACHE_ON,%d0 987 cmpl #MMU_68040,_C_LABEL(mmutype) 988 jne Lcacheon 989 /* is this needed? MLH */ 990 .word 0xf4f8 | cpusha bc - push & invalidate caches 991 movl #CACHE40_ON,%d0 992#ifdef M68060 993 cmpl #CPU_68060,_C_LABEL(cputype) 994 jne Lcacheon 995 movl #CACHE60_ON,%d0 996#endif 997Lcacheon: 998 movc %d0,%cacr | clear cache(s) 999 1000 /* 1001 * Final setup for C code 1002 */ 1003 movw #PSL_LOWIPL,%sr | lower SPL 1004 1005#ifdef notdef 1006 movl %d6,_C_LABEL(bootdev) | and boot device 1007#endif 1008 1009 /* 1010 * Create a fake exception frame that returns to user mode, 1011 * make space for the rest of a fake saved register set, and 1012 * pass a pointer to the register set to "main()". 1013 * "main()" will call "icode()", which fakes 1014 * an "execve()" system call, which is why we need to do that 1015 * ("main()" sets "u.u_ar0" to point to the register set). 1016 * When "main()" returns, we're running in process 1 and have 1017 * successfully faked the "execve()". We load up the registers from 1018 * that set; the "rte" loads the PC and PSR, which jumps to "init". 1019 */ 1020 movl #0,%a6 | make DDB stack_trace() work 1021 clrw %sp@- | vector offset/frame type 1022 clrl %sp@- | PC - filled in by "execve" 1023 movw #PSL_USER,%sp@- | in user mode 1024 clrl %sp@- | stack adjust count 1025 lea %sp@(-64),%sp | construct space for D0-D7/A0-A7 1026 lea _C_LABEL(lwp0),%a0 | lwp0 in a0 1027 movl %sp,%a0@(L_MD_REGS) | save frame for lwp0 1028 movl %usp,%a1 1029 movl %a1,%sp@(FR_SP) | save user stack pointer in frame 1030 pea %sp@ | addr of space for D0 1031 jbsr _C_LABEL(main) | main(r0) 1032 addql #4,%sp | pop args 1033 cmpl #MMU_68040,_C_LABEL(mmutype) 1034 jne Lnoflush | Not an 68040, skip flush 1035 .word 0xf478 | cpusha dc 1036 .word 0xf498 | cinva ic 1037Lnoflush: 1038 movl %sp@(FR_SP),%a0 | grab and load 1039 movl %a0,%usp | user SP 1040 moveml %sp@+,#0x7FFF | load most registers (all but SSP) 1041 addql #8,%sp | pop SSP and stack adjust count 1042 rte 1043 1044/* 1045 * Use common m68k sigcode. 1046 */ 1047#include <m68k/m68k/sigcode.s> 1048#ifdef COMPAT_SUNOS 1049#include <m68k/m68k/sunos_sigcode.s> 1050#endif 1051 1052/* 1053 * Primitives 1054 */ 1055 1056/* 1057 * Use common m68k support routines. 1058 */ 1059#include <m68k/m68k/support.s> 1060 1061/* 1062 * update profiling information for the user 1063 * addupc(pc, &u.u_prof, ticks) 1064 */ 1065ENTRY(addupc) 1066 movl %a2,%sp@- | scratch register 1067 movl %sp@(12),%a2 | get &u.u_prof 1068 movl %sp@(8),%d0 | get user pc 1069 subl %a2@(8),%d0 | pc -= pr->pr_off 1070 jlt Lauexit | less than 0, skip it 1071 movl %a2@(12),%d1 | get pr->pr_scale 1072 lsrl #1,%d0 | pc /= 2 1073 lsrl #1,%d1 | scale /= 2 1074 mulul %d1,%d0 | pc /= scale 1075 moveq #14,%d1 1076 lsrl %d1,%d0 | pc >>= 14 1077 bclr #0,%d0 | pc &= ~1 1078 cmpl %a2@(4),%d0 | too big for buffer? 1079 jge Lauexit | yes, screw it 1080 addl %a2@,%d0 | no, add base 1081 movl %d0,%sp@- | push address 1082 jbsr _C_LABEL(fusword) | grab old value 1083 movl %sp@+,%a0 | grab address back 1084 cmpl #-1,%d0 | access ok 1085 jeq Lauerror | no, skip out 1086 addw %sp@(18),%d0 | add tick to current value 1087 movl %d0,%sp@- | push value 1088 movl %a0,%sp@- | push address 1089 jbsr _C_LABEL(susword) | write back new value 1090 addql #8,%sp | pop params 1091 tstl %d0 | fault? 1092 jeq Lauexit | no, all done 1093Lauerror: 1094 clrl %a2@(12) | clear scale (turn off prof) 1095Lauexit: 1096 movl %sp@+,%a2 | restore scratch reg 1097 rts 1098 1099/* 1100 * non-local gotos 1101 */ 1102ENTRY(qsetjmp) 1103 movl %sp@(4),%a0 | savearea pointer 1104 lea %a0@(40),%a0 | skip regs we do not save 1105 movl %a6,%a0@+ | save FP 1106 movl %sp,%a0@+ | save SP 1107 movl %sp@,%a0@ | and return address 1108 moveq #0,%d0 | return 0 1109 rts 1110 1111/* 1112 * Use common m68k process/lwp switch and context save subroutines. 1113 */ 1114#define FPCOPROC 1115#include <m68k/m68k/switch_subr.s> 1116 1117 1118#if defined(M68040) 1119ENTRY(suline) 1120 movl %sp@(4),%a0 | address to write 1121 movl _C_LABEL(curpcb),%a1 | current pcb 1122 movl #Lslerr,%a1@(PCB_ONFAULT) | where to return to on a fault 1123 movl %sp@(8),%a1 | address of line 1124 movl %a1@+,%d0 | get lword 1125 movsl %d0,%a0@+ | put lword 1126 nop | sync 1127 movl %a1@+,%d0 | get lword 1128 movsl %d0,%a0@+ | put lword 1129 nop | sync 1130 movl %a1@+,%d0 | get lword 1131 movsl %d0,%a0@+ | put lword 1132 nop | sync 1133 movl %a1@+,%d0 | get lword 1134 movsl %d0,%a0@+ | put lword 1135 nop | sync 1136 moveq #0,%d0 | indicate no fault 1137 jra Lsldone 1138Lslerr: 1139 moveq #-1,%d0 1140Lsldone: 1141 movl _C_LABEL(curpcb),%a1 | current pcb 1142 clrl %a1@(PCB_ONFAULT) | clear fault address 1143 rts 1144#endif /* defined(M68040) */ 1145 1146ENTRY(ecacheon) 1147 rts 1148 1149ENTRY(ecacheoff) 1150 rts 1151 1152/* 1153 * Get callers current SP value. 1154 * Note that simply taking the address of a local variable in a C function 1155 * doesn't work because callee saved registers may be outside the stack frame 1156 * defined by A6 (e.g. GCC generated code). 1157 */ 1158ENTRY_NOPROFILE(getsp) 1159 movl %sp,%d0 | get current SP 1160 addql #4,%d0 | compensate for return address 1161 rts 1162 1163/* 1164 * Check out a virtual address to see if it's okay to write to. 1165 * 1166 * probeva(va, fc) 1167 * 1168 */ 1169ENTRY(probeva) 1170 movl %sp@(8),%d0 1171 movec %d0,%dfc 1172 movl %sp@(4),%a0 1173 .word 0xf548 | ptestw (a0) 1174 moveq #FC_USERD,%d0 | restore DFC to user space 1175 movc %d0,%dfc 1176 .word 0x4e7a,0x0805 | movec MMUSR,d0 1177 rts 1178 1179/* 1180 * Load a new user segment table pointer. 1181 */ 1182ENTRY(loadustp) 1183 movl %sp@(4),%d0 | new USTP 1184 moveq #PGSHIFT,%d1 1185 lsll %d1,%d0 | convert to addr 1186#if defined(M68060) 1187 cmpl #CPU_68060,_C_LABEL(cputype) | 68060? 1188 jeq Lldustp060 | yes, skip 1189#endif 1190 cmpl #MMU_68040,_C_LABEL(mmutype) | 68040? 1191 jeq Lldustp040 | yes, skip 1192 pflusha | flush entire TLB 1193 lea _C_LABEL(protorp),%a0 | CRP prototype 1194 movl %d0,%a0@(4) | stash USTP 1195 pmove %a0@,%crp | load root pointer 1196 movl #CACHE_CLR,%d0 1197 movc %d0,%cacr | invalidate on-chip d-cache 1198 rts 1199#if defined(M68060) 1200Lldustp060: 1201 movc %cacr,%d1 1202 orl #IC60_CUBC,%d1 | clear user branch cache entries 1203 movc %d1,%cacr 1204#endif 1205Lldustp040: 1206 .word 0xf518 | pflusha 1207 .word 0x4e7b,0x0806 | movec d0,URP 1208 rts 1209 1210/* 1211 * Flush any hardware context associated with given USTP. 1212 * Only does something for HP330 where we must flush RPT 1213 * and ATC entries in PMMU. 1214 */ 1215ENTRY(flushustp) 1216#if defined(M68060) 1217 cmpl #CPU_68060,_C_LABEL(cputype) 1218 jeq Lflustp060 | A 060 needs special treatment 1219#endif 1220 cmpl #MMU_68040,_C_LABEL(mmutype) 1221 jeq Lnot68851 1222 tstl _C_LABEL(mmutype) | 68851 PMMU? 1223 jle Lnot68851 | no, nothing to do 1224 movl %sp@(4),%d0 | get USTP to flush 1225 moveq #PGSHIFT,%d1 1226 lsll %d1,%d0 | convert to address 1227 movl %d0,_C_LABEL(protorp)+4 | stash USTP 1228 pflushr _C_LABEL(protorp) | flush RPT/TLB entries 1229Lnot68851: 1230 rts 1231#if defined(M68060) 1232Lflustp060: 1233 movc %cacr,%d1 1234 orl IC60_CUBC,%d1 | clear user branch cache entries 1235 movc %d1,%cacr 1236 rts 1237#endif 1238 1239ENTRY(ploadw) 1240 movl %sp@(4),%a0 | address to load 1241 cmpl #MMU_68040,_C_LABEL(mmutype) 1242 jeq Lploadw040 1243 ploadw #1,%a0@ | pre-load translation 1244Lploadw040: | should 68040 do a ptest? 1245 rts 1246 1247/* 1248 * Set processor priority level calls. Most are implemented with 1249 * inline asm expansions. However, spl0 requires special handling 1250 * as we need to check for our emulated software interrupts. 1251 */ 1252 1253ENTRY(spl0) 1254 moveq #0,%d0 1255 movw %sr,%d0 | get old SR for return 1256 movw #PSL_LOWIPL,%sr | restore new SR 1257 tstb _C_LABEL(ssir) | software interrupt pending? 1258 jeq Lspldone | no, all done 1259 subql #4,%sp | make room for RTE frame 1260 movl %sp@(4),%sp@(2) | position return address 1261 clrw %sp@(6) | set frame type 0 1262 movw #PSL_LOWIPL,%sp@ | and new SR 1263 jra Lgotsir | go handle it 1264Lspldone: 1265 rts 1266 1267/* 1268 * Handle the nitty-gritty of rebooting the machine. 1269 * 1270 */ 1271ENTRY_NOPROFILE(doboot) 1272 movl #CACHE_OFF,%d0 1273 cmpl #MMU_68040,_C_LABEL(mmutype) | is it 68040? 1274 jne Ldoboot0 1275 .word 0xf4f8 | cpusha bc - push and inval caches 1276 nop 1277 movl #CACHE40_OFF,%d0 1278Ldoboot0: 1279 movc %d0,%cacr | disable on-chip cache(s) 1280 1281 movw #0x2700,%sr | cut off any interrupts 1282 1283 /* 1284 * Clear first 2k of ST-memory. We start clearing at address 0x8 1285 * because the lower 8 bytes are mapped to ROM. 1286 * This makes sure that the machine will 'cold-boot'. 1287 */ 1288 movl _C_LABEL(page_zero),%a0 1289 addl #0x8,%a0 1290 movl #512,%d0 1291Ldb1: 1292 clrl %a0@+ 1293 dbra %d0,Ldb1 1294 1295 lea Ldoreboot,%a1 | a1 = start of copy range 1296 lea Ldorebootend,%a2 | a2 = end of copy range 1297 movl _C_LABEL(page_zero),%a0 | a0 = virtual base for page zero 1298 addl %a1,%a0 | + offset of Ldoreboot 1299Ldb2: | Do the copy 1300 movl %a1@+,%a0@+ 1301 cmpl %a2,%a1 1302 jle Ldb2 1303 1304 /* 1305 * Ok, turn off MMU.. 1306 */ 1307Ldoreboot: 1308 cmpl #MMU_68040,_C_LABEL(mmutype) 1309 jeq Lmmuoff040 | Go turn off 68040 MMU 1310 lea _ASM_LABEL(zero),%a0 1311 pmove %a0@,%tc | Turn off MMU 1312 lea _ASM_LABEL(nullrp),%a0 1313 pmove %a0@,%crp | Invalidate CPU root pointer 1314 pmove %a0@,%srp | and the Supervisor root pointer 1315 jra Ldoboot1 | Ok, continue with actual reboot 1316Lmmuoff040: 1317 movl #0,%d0 1318 .word 0x4e7b,0x0003 | movc d0,TC 1319 .word 0x4e7b,0x0806 | movc d0,URP 1320 .word 0x4e7b,0x0807 | movc d0,SRP 1321 1322Ldoboot1: 1323 movl #0, %a0 1324 movc %a0,%vbr 1325 movl %a0@(4), %a0 | fetch reset-vector 1326 jmp %a0@ | jump through it 1327 /* NOTREACHED */ 1328 1329/* A do-nothing MMU root pointer (includes the following long as well) */ 1330 1331ASLOCAL(nullrp) 1332 .long 0x7fff0001 1333ASLOCAL(zero) 1334 .long 0 1335Ldorebootend: 1336 1337 .data 1338 .p2align 2 1339 .space PAGE_SIZE 1340ASLOCAL(tmpstk) 1341GLOBAL(protorp) 1342 .long 0x80000002,0 | prototype root pointer 1343 1344#ifdef M68060 /* XXX */ 1345L60iem: .long 0 1346L60fpiem: .long 0 1347L60fpdem: .long 0 1348L60fpeaem: .long 0 1349L60bpe: .long 0 1350#endif 1351#ifdef DEBUG 1352 1353ASLOCAL(fulltflush) 1354 .long 0 1355ASLOCAL(fullcflush) 1356 .long 0 1357GLOBAL(timebomb) 1358 .long 0 1359#endif 1360ASLOCAL(plx_nonmi) 1361 .long 0 1362GLOBAL(plx_status) 1363 .long 0 1364 1365/* interrupt counters & names */ 1366#include <atari/atari/intrcnt.h> 1367