1 1.78 thorpej /* $NetBSD: locore.s,v 1.78 2024/01/17 12:33:51 thorpej Exp $ */ 2 1.1 gwr 3 1.1 gwr /* 4 1.62 rmind * Copyright (c) 1988 University of Utah. 5 1.1 gwr * Copyright (c) 1980, 1990, 1993 6 1.1 gwr * The Regents of the University of California. All rights reserved. 7 1.52 agc * 8 1.52 agc * This code is derived from software contributed to Berkeley by 9 1.52 agc * the Systems Programming Group of the University of Utah Computer 10 1.52 agc * Science Department. 11 1.52 agc * 12 1.52 agc * Redistribution and use in source and binary forms, with or without 13 1.52 agc * modification, are permitted provided that the following conditions 14 1.52 agc * are met: 15 1.52 agc * 1. Redistributions of source code must retain the above copyright 16 1.52 agc * notice, this list of conditions and the following disclaimer. 17 1.52 agc * 2. Redistributions in binary form must reproduce the above copyright 18 1.52 agc * notice, this list of conditions and the following disclaimer in the 19 1.52 agc * documentation and/or other materials provided with the distribution. 20 1.52 agc * 3. Neither the name of the University nor the names of its contributors 21 1.52 agc * may be used to endorse or promote products derived from this software 22 1.52 agc * without specific prior written permission. 23 1.52 agc * 24 1.52 agc * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 1.52 agc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 1.52 agc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 1.52 agc * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 1.52 agc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 1.52 agc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 1.52 agc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 1.52 agc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 1.52 agc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 1.52 agc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 1.52 agc * SUCH DAMAGE. 35 1.52 agc * 36 1.52 agc * from: Utah $Hdr: locore.s 1.66 92/12/22$ 37 1.52 agc * @(#)locore.s 8.6 (Berkeley) 5/27/94 38 1.52 agc */ 39 1.1 gwr 40 1.29 thorpej #include "opt_compat_netbsd.h" 41 1.35 christos #include "opt_compat_sunos.h" 42 1.47 lukem #include "opt_kgdb.h" 43 1.42 thorpej #include "opt_lockdebug.h" 44 1.27 gwr 45 1.1 gwr #include "assym.h" 46 1.17 thorpej #include <machine/asm.h> 47 1.1 gwr #include <machine/trap.h> 48 1.1 gwr 49 1.1 gwr | Remember this is a fun project! 50 1.1 gwr 51 1.1 gwr .data 52 1.19 jeremy GLOBAL(mon_crp) 53 1.1 gwr .long 0,0 54 1.1 gwr 55 1.1 gwr | This is for kvm_mkdb, and should be the address of the beginning 56 1.1 gwr | of the kernel text segment (not necessarily the same as kernbase). 57 1.1 gwr .text 58 1.19 jeremy GLOBAL(kernel_text) 59 1.1 gwr 60 1.1 gwr | This is the entry point, as well as the end of the temporary stack 61 1.1 gwr | used during process switch (one 8K page ending at start) 62 1.19 jeremy ASGLOBAL(tmpstk) 63 1.20 gwr ASGLOBAL(start) 64 1.19 jeremy 65 1.1 gwr | The first step, after disabling interrupts, is to map enough of the kernel 66 1.1 gwr | into high virtual address space so that we can use position dependent code. 67 1.1 gwr | This is a tricky task on the sun3x because the MMU is already enabled and 68 1.1 gwr | the ROM monitor provides no indication of where the root MMU table is mapped. 69 1.1 gwr | Therefore we must use one of the 68030's 'transparent translation' registers 70 1.1 gwr | to define a range in the address space where the MMU translation is 71 1.1 gwr | turned off. Once this is complete we can modify the MMU table directly 72 1.1 gwr | without the need for it to be mapped into virtual memory. 73 1.1 gwr | All code must be position independent until otherwise noted, as the 74 1.1 gwr | boot loader has loaded us into low memory but all the symbols in this 75 1.1 gwr | code have been linked high. 76 1.45 chs movw #PSL_HIGHIPL,%sr | no interrupts 77 1.61 tsutsui movl #KERNBASE3X,%a5 | for vtop conversion 78 1.45 chs lea _C_LABEL(mon_crp),%a0 | where to store the CRP 79 1.45 chs subl %a5,%a0 80 1.1 gwr | Note: borrowing mon_crp for tt0 setup... 81 1.45 chs movl #0x3F8107,%a0@ | map the low 1GB v=p with the 82 1.14 jeremy .long 0xf0100800 | transparent translation reg0 83 1.14 jeremy | [ pmove a0@, tt0 ] 84 1.1 gwr | In order to map the kernel into high memory we will copy the root table 85 1.1 gwr | entry which maps the 16 megabytes of memory starting at 0x0 into the 86 1.1 gwr | entry which maps the 16 megabytes starting at KERNBASE. 87 1.45 chs pmove %crp,%a0@ | Get monitor CPU root pointer 88 1.45 chs movl %a0@(4),%a1 | 2nd word is PA of level A table 89 1.1 gwr 90 1.45 chs movl %a1,%a0 | compute the descriptor address 91 1.45 chs addl #0x3e0,%a1 | for VA starting at KERNBASE 92 1.45 chs movl %a0@,%a1@ | copy descriptor type 93 1.45 chs movl %a0@(4),%a1@(4) | copy physical address 94 1.1 gwr 95 1.1 gwr | Kernel is now double mapped at zero and KERNBASE. 96 1.1 gwr | Force a long jump to the relocated code (high VA). 97 1.45 chs movl #IC_CLEAR,%d0 | Flush the I-cache 98 1.45 chs movc %d0,%cacr 99 1.1 gwr jmp L_high_code:l | long jump 100 1.1 gwr 101 1.1 gwr L_high_code: 102 1.1 gwr | We are now running in the correctly relocated kernel, so 103 1.1 gwr | we are no longer restricted to position-independent code. 104 1.1 gwr | It is handy to leave transparent translation enabled while 105 1.20 gwr | for the low 1GB while _bootstrap() is doing its thing. 106 1.1 gwr 107 1.1 gwr | Do bootstrap stuff needed before main() gets called. 108 1.1 gwr | Our boot loader leaves a copy of the kernel's exec header 109 1.1 gwr | just before the start of the kernel text segment, so the 110 1.1 gwr | kernel can sanity-check the DDB symbols at [end...esym]. 111 1.20 gwr | Pass the struct exec at tmpstk-32 to _bootstrap(). 112 1.7 gwr | Also, make sure the initial frame pointer is zero so that 113 1.7 gwr | the backtrace algorithm used by KGDB terminates nicely. 114 1.45 chs lea _ASM_LABEL(tmpstk)-32,%sp 115 1.45 chs movl #0,%a6 116 1.26 gwr jsr _C_LABEL(_bootstrap) | See locore2.c 117 1.1 gwr 118 1.1 gwr | Now turn off the transparent translation of the low 1GB. 119 1.1 gwr | (this also flushes the ATC) 120 1.45 chs clrl %sp@- 121 1.14 jeremy .long 0xf0170800 | pmove sp@,tt0 122 1.45 chs addql #4,%sp 123 1.1 gwr 124 1.20 gwr | Now that _bootstrap() is done using the PROM functions, 125 1.1 gwr | we can safely set the sfc/dfc to something != FC_CONTROL 126 1.45 chs moveq #FC_USERD,%d0 | make movs access "user data" 127 1.45 chs movc %d0,%sfc | space for copyin/copyout 128 1.45 chs movc %d0,%dfc 129 1.1 gwr 130 1.1 gwr | Setup process zero user/kernel stacks. 131 1.58 matt lea _C_LABEL(lwp0),%a0 | get lwp0 132 1.59 rmind movl %a0@(L_PCB),%a1 | XXXuvm_lwp_getuarea 133 1.45 chs lea %a1@(USPACE-4),%sp | set SSP to last word 134 1.61 tsutsui movl #USRSTACK3X-4,%a2 135 1.45 chs movl %a2,%usp | init user SP 136 1.1 gwr 137 1.20 gwr | Note curpcb was already set in _bootstrap(). 138 1.1 gwr | Will do fpu initialization during autoconfig (see fpu.c) 139 1.1 gwr | The interrupt vector table and stack are now ready. 140 1.1 gwr | Interrupts will be enabled later, AFTER autoconfiguration 141 1.1 gwr | is finished, to avoid spurrious interrupts. 142 1.1 gwr 143 1.1 gwr /* 144 1.60 skrll * Create a fake exception frame so that cpu_lwp_fork() can copy it. 145 1.49 chs * main() nevers returns; we exit to user mode from a forked process 146 1.49 chs * later on. 147 1.1 gwr */ 148 1.45 chs clrw %sp@- | tf_format,tf_vector 149 1.45 chs clrl %sp@- | tf_pc (filled in later) 150 1.45 chs movw #PSL_USER,%sp@- | tf_sr for user mode 151 1.45 chs clrl %sp@- | tf_stackadj 152 1.45 chs lea %sp@(-64),%sp | tf_regs[16] 153 1.58 matt movl %a1,%a0@(L_MD_REGS) | lwp0.l_md.md_regs = trapframe 154 1.19 jeremy jbsr _C_LABEL(main) | main(&trapframe) 155 1.49 chs PANIC("main() returned") 156 1.1 gwr 157 1.1 gwr | That is all the assembly startup code we need on the sun3x! 158 1.1 gwr | The rest of this is like the hp300/locore.s where possible. 159 1.1 gwr 160 1.1 gwr /* 161 1.1 gwr * Trap/interrupt vector routines 162 1.1 gwr */ 163 1.17 thorpej #include <m68k/m68k/trap_subr.s> 164 1.1 gwr 165 1.19 jeremy GLOBAL(buserr) 166 1.19 jeremy tstl _C_LABEL(nofault) | device probe? 167 1.19 jeremy jeq _C_LABEL(addrerr) | no, handle as usual 168 1.45 chs movl _C_LABEL(nofault),%sp@- | yes, 169 1.19 jeremy jbsr _C_LABEL(longjmp) | longjmp(nofault) 170 1.19 jeremy GLOBAL(addrerr) 171 1.45 chs clrl %sp@- | stack adjust count 172 1.45 chs moveml #0xFFFF,%sp@- | save user registers 173 1.45 chs movl %usp,%a0 | save the user SP 174 1.45 chs movl %a0,%sp@(FR_SP) | in the savearea 175 1.45 chs lea %sp@(FR_HW),%a1 | grab base of HW berr frame 176 1.45 chs moveq #0,%d0 177 1.45 chs movw %a1@(10),%d0 | grab SSW for fault processing 178 1.45 chs btst #12,%d0 | RB set? 179 1.1 gwr jeq LbeX0 | no, test RC 180 1.45 chs bset #14,%d0 | yes, must set FB 181 1.45 chs movw %d0,%a1@(10) | for hardware too 182 1.1 gwr LbeX0: 183 1.45 chs btst #13,%d0 | RC set? 184 1.1 gwr jeq LbeX1 | no, skip 185 1.45 chs bset #15,%d0 | yes, must set FC 186 1.45 chs movw %d0,%a1@(10) | for hardware too 187 1.1 gwr LbeX1: 188 1.45 chs btst #8,%d0 | data fault? 189 1.1 gwr jeq Lbe0 | no, check for hard cases 190 1.45 chs movl %a1@(16),%d1 | fault address is as given in frame 191 1.1 gwr jra Lbe10 | thats it 192 1.1 gwr Lbe0: 193 1.45 chs btst #4,%a1@(6) | long (type B) stack frame? 194 1.1 gwr jne Lbe4 | yes, go handle 195 1.45 chs movl %a1@(2),%d1 | no, can use save PC 196 1.45 chs btst #14,%d0 | FB set? 197 1.1 gwr jeq Lbe3 | no, try FC 198 1.45 chs addql #4,%d1 | yes, adjust address 199 1.1 gwr jra Lbe10 | done 200 1.1 gwr Lbe3: 201 1.45 chs btst #15,%d0 | FC set? 202 1.1 gwr jeq Lbe10 | no, done 203 1.45 chs addql #2,%d1 | yes, adjust address 204 1.1 gwr jra Lbe10 | done 205 1.1 gwr Lbe4: 206 1.45 chs movl %a1@(36),%d1 | long format, use stage B address 207 1.45 chs btst #15,%d0 | FC set? 208 1.1 gwr jeq Lbe10 | no, all done 209 1.45 chs subql #2,%d1 | yes, adjust address 210 1.1 gwr Lbe10: 211 1.45 chs movl %d1,%sp@- | push fault VA 212 1.45 chs movl %d0,%sp@- | and padded SSW 213 1.45 chs movw %a1@(6),%d0 | get frame format/vector offset 214 1.45 chs andw #0x0FFF,%d0 | clear out frame format 215 1.45 chs cmpw #12,%d0 | address error vector? 216 1.1 gwr jeq Lisaerr | yes, go to it 217 1.1 gwr 218 1.1 gwr /* MMU-specific code to determine reason for bus error. */ 219 1.45 chs movl %d1,%a0 | fault address 220 1.45 chs movl %sp@,%d0 | function code from ssw 221 1.45 chs btst #8,%d0 | data fault? 222 1.1 gwr jne Lbe10a 223 1.45 chs movql #1,%d0 | user program access FC 224 1.1 gwr | (we dont separate data/program) 225 1.45 chs btst #5,%a1@ | supervisor mode? 226 1.1 gwr jeq Lbe10a | if no, done 227 1.45 chs movql #5,%d0 | else supervisor program access 228 1.1 gwr Lbe10a: 229 1.45 chs ptestr %d0,%a0@,#7 | do a table search 230 1.45 chs pmove %psr,%sp@ | save result 231 1.45 chs movb %sp@,%d1 232 1.45 chs btst #2,%d1 | invalid? (incl. limit viol and berr) 233 1.1 gwr jeq Lmightnotbemerr | no -> wp check 234 1.45 chs btst #7,%d1 | is it MMU table berr? 235 1.1 gwr jeq Lismerr | no, must be fast 236 1.1 gwr jra Lisberr1 | real bus err needs not be fast 237 1.1 gwr Lmightnotbemerr: 238 1.45 chs btst #3,%d1 | write protect bit set? 239 1.1 gwr jeq Lisberr1 | no, must be bus error 240 1.45 chs movl %sp@,%d0 | ssw into low word of d0 241 1.45 chs andw #0xc0,%d0 | write protect is set on page: 242 1.45 chs cmpw #0x40,%d0 | was it read cycle? 243 1.1 gwr jeq Lisberr1 | yes, was not WPE, must be bus err 244 1.1 gwr /* End of MMU-specific bus error code. */ 245 1.1 gwr 246 1.1 gwr Lismerr: 247 1.45 chs movl #T_MMUFLT,%sp@- | show that we are an MMU fault 248 1.17 thorpej jra _ASM_LABEL(faultstkadj) | and deal with it 249 1.1 gwr Lisaerr: 250 1.45 chs movl #T_ADDRERR,%sp@- | mark address error 251 1.17 thorpej jra _ASM_LABEL(faultstkadj) | and deal with it 252 1.1 gwr Lisberr1: 253 1.45 chs clrw %sp@ | re-clear pad word 254 1.1 gwr Lisberr: 255 1.45 chs movl #T_BUSERR,%sp@- | mark bus error 256 1.17 thorpej jra _ASM_LABEL(faultstkadj) | and deal with it 257 1.1 gwr 258 1.1 gwr /* 259 1.1 gwr * FP exceptions. 260 1.1 gwr */ 261 1.19 jeremy GLOBAL(fpfline) 262 1.45 chs clrl %sp@- | stack adjust count 263 1.45 chs moveml #0xFFFF,%sp@- | save registers 264 1.45 chs moveq #T_FPEMULI,%d0 | denote as FP emulation trap 265 1.19 jeremy jra _ASM_LABEL(fault) | do it 266 1.1 gwr 267 1.19 jeremy GLOBAL(fpunsupp) 268 1.45 chs clrl %sp@- | stack adjust count 269 1.45 chs moveml #0xFFFF,%sp@- | save registers 270 1.45 chs moveq #T_FPEMULD,%d0 | denote as FP emulation trap 271 1.19 jeremy jra _ASM_LABEL(fault) | do it 272 1.1 gwr 273 1.1 gwr /* 274 1.1 gwr * Handles all other FP coprocessor exceptions. 275 1.1 gwr * Note that since some FP exceptions generate mid-instruction frames 276 1.1 gwr * and may cause signal delivery, we need to test for stack adjustment 277 1.1 gwr * after the trap call. 278 1.1 gwr */ 279 1.19 jeremy GLOBAL(fpfault) 280 1.45 chs clrl %sp@- | stack adjust count 281 1.45 chs moveml #0xFFFF,%sp@- | save user registers 282 1.45 chs movl %usp,%a0 | and save 283 1.45 chs movl %a0,%sp@(FR_SP) | the user stack pointer 284 1.45 chs clrl %sp@- | no VA arg 285 1.45 chs movl _C_LABEL(curpcb),%a0 | current pcb 286 1.45 chs lea %a0@(PCB_FPCTX),%a0 | address of FP savearea 287 1.45 chs fsave %a0@ | save state 288 1.45 chs tstb %a0@ | null state frame? 289 1.1 gwr jeq Lfptnull | yes, safe 290 1.45 chs clrw %d0 | no, need to tweak BIU 291 1.45 chs movb %a0@(1),%d0 | get frame size 292 1.45 chs bset #3,%a0@(0,%d0:w) | set exc_pend bit of BIU 293 1.1 gwr Lfptnull: 294 1.45 chs fmovem %fpsr,%sp@- | push fpsr as code argument 295 1.45 chs frestore %a0@ | restore state 296 1.45 chs movl #T_FPERR,%sp@- | push type arg 297 1.17 thorpej jra _ASM_LABEL(faultstkadj) | call trap and deal with stack cleanup 298 1.1 gwr 299 1.1 gwr /* 300 1.1 gwr * Other exceptions only cause four and six word stack frame and require 301 1.1 gwr * no post-trap stack adjustment. 302 1.1 gwr */ 303 1.19 jeremy GLOBAL(badtrap) 304 1.45 chs clrl %sp@- | stack adjust count 305 1.45 chs moveml #0xFFFF,%sp@- | save std frame regs 306 1.19 jeremy jbsr _C_LABEL(straytrap) | report 307 1.45 chs moveml %sp@+,#0xFFFF | restore regs 308 1.45 chs addql #4,%sp | stack adjust count 309 1.19 jeremy jra _ASM_LABEL(rei) | all done 310 1.1 gwr 311 1.1 gwr /* 312 1.1 gwr * Trap 0 is for system calls 313 1.1 gwr */ 314 1.19 jeremy GLOBAL(trap0) 315 1.45 chs clrl %sp@- | stack adjust count 316 1.45 chs moveml #0xFFFF,%sp@- | save user registers 317 1.45 chs movl %usp,%a0 | save the user SP 318 1.45 chs movl %a0,%sp@(FR_SP) | in the savearea 319 1.45 chs movl %d0,%sp@- | push syscall number 320 1.19 jeremy jbsr _C_LABEL(syscall) | handle it 321 1.45 chs addql #4,%sp | pop syscall arg 322 1.45 chs movl %sp@(FR_SP),%a0 | grab and restore 323 1.45 chs movl %a0,%usp | user SP 324 1.45 chs moveml %sp@+,#0x7FFF | restore most registers 325 1.45 chs addql #8,%sp | pop SP and stack adjust 326 1.19 jeremy jra _ASM_LABEL(rei) | all done 327 1.11 gwr 328 1.11 gwr /* 329 1.11 gwr * Trap 12 is the entry point for the cachectl "syscall" 330 1.11 gwr * cachectl(command, addr, length) 331 1.11 gwr * command in d0, addr in a1, length in d1 332 1.11 gwr */ 333 1.19 jeremy GLOBAL(trap12) 334 1.51 thorpej movl _C_LABEL(curlwp),%a0 335 1.51 thorpej movl %a0@(L_PROC),%sp@- | push curproc pointer 336 1.45 chs movl %d1,%sp@- | push length 337 1.45 chs movl %a1,%sp@- | push addr 338 1.45 chs movl %d0,%sp@- | push command 339 1.32 is jbsr _C_LABEL(cachectl1) | do it 340 1.45 chs lea %sp@(16),%sp | pop args 341 1.19 jeremy jra _ASM_LABEL(rei) | all done 342 1.1 gwr 343 1.1 gwr /* 344 1.1 gwr * Trace (single-step) trap. Kernel-mode is special. 345 1.1 gwr * User mode traps are simply passed on to trap(). 346 1.1 gwr */ 347 1.19 jeremy GLOBAL(trace) 348 1.45 chs clrl %sp@- | stack adjust count 349 1.45 chs moveml #0xFFFF,%sp@- 350 1.45 chs moveq #T_TRACE,%d0 351 1.37 itohy 352 1.37 itohy | Check PSW and see what happen. 353 1.37 itohy | T=0 S=0 (should not happen) 354 1.37 itohy | T=1 S=0 trace trap from user mode 355 1.37 itohy | T=0 S=1 trace trap on a trap instruction 356 1.37 itohy | T=1 S=1 trace trap from system mode (kernel breakpoint) 357 1.37 itohy 358 1.45 chs movw %sp@(FR_HW),%d1 | get PSW 359 1.45 chs notw %d1 | XXX no support for T0 on 680[234]0 360 1.45 chs andw #PSL_TS,%d1 | from system mode (T=1, S=1)? 361 1.37 itohy jeq _ASM_LABEL(kbrkpt) | yes, kernel brkpt 362 1.19 jeremy jra _ASM_LABEL(fault) | no, user-mode fault 363 1.1 gwr 364 1.1 gwr /* 365 1.1 gwr * Trap 15 is used for: 366 1.1 gwr * - GDB breakpoints (in user programs) 367 1.1 gwr * - KGDB breakpoints (in the kernel) 368 1.1 gwr * - trace traps for SUN binaries (not fully supported yet) 369 1.11 gwr * User mode traps are simply passed to trap(). 370 1.1 gwr */ 371 1.19 jeremy GLOBAL(trap15) 372 1.45 chs clrl %sp@- | stack adjust count 373 1.45 chs moveml #0xFFFF,%sp@- 374 1.45 chs moveq #T_TRAP15,%d0 375 1.45 chs btst #5,%sp@(FR_HW) | was supervisor mode? 376 1.19 jeremy jne _ASM_LABEL(kbrkpt) | yes, kernel brkpt 377 1.19 jeremy jra _ASM_LABEL(fault) | no, user-mode fault 378 1.1 gwr 379 1.19 jeremy ASLOCAL(kbrkpt) 380 1.45 chs | Kernel-mode breakpoint or trace trap. (%d0=trap_type) 381 1.1 gwr | Save the system sp rather than the user sp. 382 1.45 chs movw #PSL_HIGHIPL,%sr | lock out interrupts 383 1.45 chs lea %sp@(FR_SIZE),%a6 | Save stack pointer 384 1.45 chs movl %a6,%sp@(FR_SP) | from before trap 385 1.1 gwr 386 1.1 gwr | If we are not on tmpstk switch to it. 387 1.1 gwr | (so debugger can change the stack pointer) 388 1.45 chs movl %a6,%d1 389 1.45 chs cmpl #_ASM_LABEL(tmpstk),%d1 390 1.1 gwr jls Lbrkpt2 | already on tmpstk 391 1.1 gwr | Copy frame to the temporary stack 392 1.45 chs movl %sp,%a0 | %a0=src 393 1.45 chs lea _ASM_LABEL(tmpstk)-96,%a1 | %a1=dst 394 1.45 chs movl %a1,%sp | sp=new frame 395 1.45 chs moveq #FR_SIZE,%d1 396 1.1 gwr Lbrkpt1: 397 1.45 chs movl %a0@+,%a1@+ 398 1.45 chs subql #4,%d1 399 1.1 gwr bgt Lbrkpt1 400 1.1 gwr 401 1.1 gwr Lbrkpt2: 402 1.11 gwr | Call the trap handler for the kernel debugger. 403 1.6 gwr | Do not call trap() to handle it, so that we can 404 1.1 gwr | set breakpoints in trap() if we want. We know 405 1.1 gwr | the trap type is either T_TRACE or T_BREAKPOINT. 406 1.45 chs movl %d0,%sp@- | push trap type 407 1.19 jeremy jbsr _C_LABEL(trap_kdebug) 408 1.45 chs addql #4,%sp | pop args 409 1.6 gwr 410 1.1 gwr | The stack pointer may have been modified, or 411 1.1 gwr | data below it modified (by kgdb push call), 412 1.1 gwr | so push the hardware frame at the current sp 413 1.1 gwr | before restoring registers and returning. 414 1.45 chs movl %sp@(FR_SP),%a0 | modified sp 415 1.45 chs lea %sp@(FR_SIZE),%a1 | end of our frame 416 1.45 chs movl %a1@-,%a0@- | copy 2 longs with 417 1.45 chs movl %a1@-,%a0@- | ... predecrement 418 1.45 chs movl %a0,%sp@(FR_SP) | sp = h/w frame 419 1.45 chs moveml %sp@+,#0x7FFF | restore all but sp 420 1.45 chs movl %sp@,%sp | ... and sp 421 1.1 gwr rte | all done 422 1.1 gwr 423 1.1 gwr /* 424 1.1 gwr * Interrupt handlers. Most are auto-vectored, 425 1.1 gwr * and hard-wired the same way on all sun3 models. 426 1.1 gwr * Format in the stack is: 427 1.45 chs * %d0,%d1,%a0,%a1, sr, pc, vo 428 1.1 gwr */ 429 1.1 gwr 430 1.1 gwr /* clock: see clock.c */ 431 1.46 kleink #ifdef __ELF__ 432 1.46 kleink .align 4 433 1.46 kleink #else 434 1.1 gwr .align 2 435 1.46 kleink #endif 436 1.19 jeremy GLOBAL(_isr_clock) 437 1.1 gwr INTERRUPT_SAVEREG 438 1.19 jeremy jbsr _C_LABEL(clock_intr) 439 1.65 christos INTERRUPT_RESTOREREG 440 1.19 jeremy jra _ASM_LABEL(rei) 441 1.1 gwr 442 1.1 gwr /* 443 1.1 gwr * Emulation of VAX REI instruction. 444 1.1 gwr * 445 1.1 gwr * This code is (mostly) un-altered from the hp300 code, 446 1.1 gwr * except that sun machines do not need a simulated SIR 447 1.1 gwr * because they have a real software interrupt register. 448 1.1 gwr * 449 1.1 gwr * This code deals with checking for and servicing ASTs 450 1.1 gwr * (profiling, scheduling) and software interrupts (network, softclock). 451 1.1 gwr * We check for ASTs first, just like the VAX. To avoid excess overhead 452 1.1 gwr * the T_ASTFLT handling code will also check for software interrupts so we 453 1.1 gwr * do not have to do it here. After identifying that we need an AST we 454 1.1 gwr * drop the IPL to allow device interrupts. 455 1.1 gwr * 456 1.1 gwr * This code is complicated by the fact that sendsig may have been called 457 1.1 gwr * necessitating a stack cleanup. 458 1.1 gwr */ 459 1.1 gwr 460 1.19 jeremy ASGLOBAL(rei) 461 1.1 gwr #ifdef DIAGNOSTIC 462 1.69 andvar tstl _C_LABEL(panicstr) | have we panicked? 463 1.1 gwr jne Ldorte | yes, do not make matters worse 464 1.1 gwr #endif 465 1.19 jeremy tstl _C_LABEL(astpending) | AST pending? 466 1.1 gwr jeq Ldorte | no, done 467 1.1 gwr Lrei1: 468 1.45 chs btst #5,%sp@ | yes, are we returning to user mode? 469 1.1 gwr jne Ldorte | no, done 470 1.45 chs movw #PSL_LOWIPL,%sr | lower SPL 471 1.45 chs clrl %sp@- | stack adjust 472 1.45 chs moveml #0xFFFF,%sp@- | save all registers 473 1.45 chs movl %usp,%a1 | including 474 1.45 chs movl %a1,%sp@(FR_SP) | the users SP 475 1.45 chs clrl %sp@- | VA == none 476 1.45 chs clrl %sp@- | code == none 477 1.45 chs movl #T_ASTFLT,%sp@- | type == async system trap 478 1.56 tsutsui pea %sp@(12) | fp == address of trap frame 479 1.19 jeremy jbsr _C_LABEL(trap) | go handle it 480 1.56 tsutsui lea %sp@(16),%sp | pop value args 481 1.45 chs movl %sp@(FR_SP),%a0 | restore user SP 482 1.45 chs movl %a0,%usp | from save area 483 1.45 chs movw %sp@(FR_ADJ),%d0 | need to adjust stack? 484 1.1 gwr jne Laststkadj | yes, go to it 485 1.45 chs moveml %sp@+,#0x7FFF | no, restore most user regs 486 1.45 chs addql #8,%sp | toss SP and stack adjust 487 1.1 gwr rte | and do real RTE 488 1.1 gwr Laststkadj: 489 1.45 chs lea %sp@(FR_HW),%a1 | pointer to HW frame 490 1.45 chs addql #8,%a1 | source pointer 491 1.45 chs movl %a1,%a0 | source 492 1.45 chs addw %d0,%a0 | + hole size = dest pointer 493 1.45 chs movl %a1@-,%a0@- | copy 494 1.45 chs movl %a1@-,%a0@- | 8 bytes 495 1.45 chs movl %a0,%sp@(FR_SP) | new SSP 496 1.45 chs moveml %sp@+,#0x7FFF | restore user registers 497 1.45 chs movl %sp@,%sp | and our SP 498 1.1 gwr Ldorte: 499 1.1 gwr rte | real return 500 1.1 gwr 501 1.1 gwr /* 502 1.1 gwr * Initialization is at the beginning of this file, because the 503 1.1 gwr * kernel entry point needs to be at zero for compatibility with 504 1.1 gwr * the Sun boot loader. This works on Sun machines because the 505 1.1 gwr * interrupt vector table for reset is NOT at address zero. 506 1.1 gwr * (The MMU has a "boot" bit that forces access to the PROM) 507 1.1 gwr */ 508 1.1 gwr 509 1.1 gwr /* 510 1.1 gwr * Primitives 511 1.1 gwr */ 512 1.1 gwr 513 1.1 gwr /* 514 1.51 thorpej * Use common m68k process/lwp switch and context save subroutines. 515 1.1 gwr */ 516 1.51 thorpej #define FPCOPROC /* XXX: Temp. Reqd. */ 517 1.51 thorpej #include <m68k/m68k/switch_subr.s> 518 1.1 gwr 519 1.1 gwr 520 1.20 gwr /* suline() */ 521 1.1 gwr 522 1.1 gwr #ifdef DEBUG 523 1.1 gwr .data 524 1.19 jeremy ASGLOBAL(fulltflush) 525 1.1 gwr .long 0 526 1.19 jeremy ASGLOBAL(fullcflush) 527 1.1 gwr .long 0 528 1.1 gwr .text 529 1.1 gwr #endif 530 1.1 gwr 531 1.1 gwr ENTRY(ecacheon) 532 1.1 gwr rts 533 1.1 gwr 534 1.1 gwr ENTRY(ecacheoff) 535 1.1 gwr rts 536 1.1 gwr 537 1.1 gwr /* 538 1.1 gwr * Load a new CPU Root Pointer (CRP) into the MMU. 539 1.2 gwr * void loadcrp(struct mmu_rootptr *); 540 1.1 gwr */ 541 1.1 gwr ENTRY(loadcrp) 542 1.45 chs movl %sp@(4),%a0 | arg1: &CRP 543 1.45 chs movl #CACHE_CLR,%d0 544 1.45 chs movc %d0,%cacr | invalidate cache(s) 545 1.1 gwr pflusha | flush entire TLB 546 1.45 chs pmove %a0@,%crp | load new user root pointer 547 1.45 chs rts 548 1.45 chs 549 1.45 chs ENTRY(getcrp) 550 1.45 chs movl %sp@(4),%a0 | arg1: &crp 551 1.45 chs pmove %crp,%a0@ | *crpp = %crp 552 1.10 gwr rts 553 1.10 gwr 554 1.10 gwr /* 555 1.10 gwr * Get the physical address of the PTE for a given VA. 556 1.10 gwr */ 557 1.10 gwr ENTRY(ptest_addr) 558 1.45 chs movl %sp@(4),%a1 | VA 559 1.45 chs ptestr #5,%a1@,#7,%a0 | %a0 = addr of PTE 560 1.48 scw movl %a0,%d0 | Result in %d0 (not a pointer return) 561 1.1 gwr rts 562 1.1 gwr 563 1.1 gwr /* 564 1.1 gwr * _delay(unsigned N) 565 1.1 gwr * Delay for at least (N/256) microseconds. 566 1.1 gwr * This routine depends on the variable: delay_divisor 567 1.1 gwr * which should be set based on the CPU clock rate. 568 1.26 gwr * XXX: Currently this is set based on the CPU model, 569 1.26 gwr * XXX: but this should be determined at run time... 570 1.1 gwr */ 571 1.19 jeremy GLOBAL(_delay) 572 1.45 chs | %d0 = arg = (usecs << 8) 573 1.45 chs movl %sp@(4),%d0 574 1.45 chs | %d1 = delay_divisor; 575 1.45 chs movl _C_LABEL(delay_divisor),%d1 576 1.36 thorpej jra L_delay /* Jump into the loop! */ 577 1.36 thorpej 578 1.36 thorpej /* 579 1.36 thorpej * Align the branch target of the loop to a half-line (8-byte) 580 1.36 thorpej * boundary to minimize cache effects. This guarantees both 581 1.36 thorpej * that there will be no prefetch stalls due to cache line burst 582 1.36 thorpej * operations and that the loop will run from a single cache 583 1.36 thorpej * half-line. 584 1.36 thorpej */ 585 1.46 kleink #ifdef __ELF__ 586 1.36 thorpej .align 8 587 1.46 kleink #else 588 1.46 kleink .align 3 589 1.46 kleink #endif 590 1.1 gwr L_delay: 591 1.45 chs subl %d1,%d0 592 1.1 gwr jgt L_delay 593 1.1 gwr rts 594 1.1 gwr 595 1.1 gwr | Define some addresses, mostly so DDB can print useful info. 596 1.24 gwr | Not using _C_LABEL() here because these symbols are never 597 1.24 gwr | referenced by any C code, and if the leading underscore 598 1.24 gwr | ever goes away, these lines turn into syntax errors... 599 1.61 tsutsui .set _KERNBASE3X,KERNBASE3X 600 1.26 gwr .set _MONSTART,SUN3X_MONSTART 601 1.26 gwr .set _PROM_BASE,SUN3X_PROM_BASE 602 1.26 gwr .set _MONEND,SUN3X_MONEND 603 1.1 gwr 604 1.1 gwr |The end! 605