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