📄 srt0.s
字号:
/* * srt0.s - standalone startup code * .seg "data" * .asciz "@(#)srt0.S 1.1 92/07/30 SMI" * Copyright (c) 1986-1990 Sun Microsystems, Inc. */ .seg "text" .align 4#include <machine/asm_linkage.h>#include <machine/param.h>#include <machine/reg.h>#include <machine/psl.h>#include <machine/trap.h>#include <machine/mmu.h>#include <mon/idprom.h>/* * param.h defines VAC, DELAY, and CDELAY * if we are compiling for the bootblock undef VAC * to save on code size */#ifdef BOOTBLOCK#undef VAC#endif/* * Initial interrupt priority and how to get there. */#define PSR_PIL_SHIFT 8#define PSR_PIL_INIT (13 << PSR_PIL_SHIFT)/* * The following variables are machine-dependent and are set in fiximp. */ .seg "data" .global _Cpudelay, _nwindows .global _vac, _vac_size, _vac_linesize, _segmask/* * The following variables are more or less machine-independent * (or are set outside of fiximp). */ .global _romp_romp: .word 0 .global _cpudelay ! old macros:_cpudelay: ! shift right amount to scale (n << 4) .word 0 ! worst case value (25 Mhz)idp: .word 0 ! room for idprom format & mach type .word 0 .global _environ_environ: .word 0 ! satisfy references from libcexitbuf: .skip 5*4 ! (jump_buf)exitbuf for _exit routine .seg "text" .align 8 .global _our_die_routine .global _end .global _edata .global __setjmp .global __longjmp .global _main .global __exit .global __exitto .global _start_start:#ifdef BOOTBLOCK .global _begin, _bootb, _bbsize, _bbchecksum b,a _begin_bootb:! should be NBLKENTRIES (64), see installboot.c .skip 64*4 ! room for boot_tab_bbsize: .word 0_bbchecksum: .word 0_begin:#endif BOOTBLOCK! Each standalone program is responsible for its own stack. Our strategy! is that each program which uses this runtime code creates a stack just! below its relocation address. Previous windows may (and probably do)! have frames allocated on the prior stack; leave them alone. Starting with! this window, allocate our own stack frames for our windows. (Overflows! or a window flush would then pass seamlessly from our stack to the old.)! RESTRICTION: A program running at some relocation address must not exec! another which will run at the very same address: the stacks would collide.! This is currently not a problem, as all standalone programs (boot, copy,! kadb, unix, et al.) run at different, carefully chosen addresses...which! is, of course, a crock.!! Careful: don't touch %o0 until the save, since it holds the romp! for Forth PROMs.! set _start, %o1 save %o1, -SA(MINFRAME), %sp acall: call 1f ! get the current pc into o7 ! (where _start is currently located) sethi %hi(acall), %o3 ! relocated address of call1: sub %o7,acall-_start,%o0 ! address where _start is in memory or %o3, %lo(acall), %o3 ! relocated address of call cmp %o3, %o7 be jmpstart .empty ! next instruction ok in delay slot set _edata+4, %o2 ! end of program, inclusive, except bss set _start, %o1 ! beginning of program sub %o2, %o1, %o2 ! size of program2: ldd [%o0], %o4 ! relocate program inc 8, %o0 ! bcopy std %o4, [%o1] deccc 8, %o2 bg 2b inc 8, %o1 set jmpstart, %l0 ! now that it is relocated, jump to it jmp %l0 nopjmpstart: set _romp, %o0 ! Stash the romp we've been saving st %i0, [%o0] /* * Set the machine-dependent variables. * Most of the work gets done in fiximp(), but we need to * set nwindows here as there's no property for it. (XXX) * * Play fast and loose with the CWP. Do everything here with * interrupts disabled, and don't write in any local registers. * Since we're dorking with the psr anyway, set up the * interrupt levels and enable traps while we're at it. * (Then we can do nifty things like call C functions.) */ mov %psr, %o0 /* * Set the psr into a known state: * supervisor mode, interrupt level >= 13, traps enabled */ andn %o0, PSR_PIL, %g1 set PSR_S|PSR_PIL_INIT|PSR_ET, %o1 or %g1, %o1, %g1 ! new psr is ready to go /* * Temporarily go to window 0 to ferret out nwindows. */ andn %o0, PSR_CWP, %g2 ! CWP = 0 mov %wim, %g3 mov %g0, %wim mov %g2, %psr ! we're in window 0 now nop; nop; nop save ! decrement cwp, wraparound to NW-1 mov %psr, %g2 mov %g1, %psr ! get back... mov %g3, %wim ! ...and put back wim and %g2, PSR_CWP, %g2 ! mask off NW-1 inc %g2 ! %g2 = nwindows sethi %hi(_nwindows), %g1 st %g2, [%g1 + %lo(_nwindows)] set _edata, %o0 ! beginning of bss set _end+4, %o1 ! end of bss call _bzero ! zero the bss sub %o1, %o0, %o1 ! size of bss call _fiximp nop#ifdef VAC call init_cache nop#endif!! Mark this spot.! sethi %hi(exitbuf), %o0 call __setjmp or %o0, %lo(exitbuf), %o0 tst %o0 ! returned 1: we exit now. bnz out nop call _main mov 0, %o0 ! delay slot! Fall through...!! __exit means exit NOW. We may be arbitrarily deep in the windows, so longjmp.!#ifndef VAC__exit: set exitbuf, %o0 call __longjmp mov 1, %o1out: ret ! ret to prom restore__exitto: save %sp, -SA(MINFRAME), %sp set _romp, %o0 ! pass the romp to the callee set _our_die_routine, %o2 ! pass our release func to callee clr %o1 ! Clear DVEC jmpl %i0, %o7 ! call thru register ld [%o0], %o0 ret restore#else !VAC__exit: save %sp, -SA(MINFRAME), %sp set _vac, %o0 ! check vac flag ld [%o0], %o0 tst %o0 bz 1f call _turnoff_cache nop1: set exitbuf, %o0 call __longjmp mov 1, %o1out: ret restore__exitto: save %sp, -SA(MINFRAME), %sp ! ! turn off the cache if it's currently on ! set _vac, %o0 ! check vac flag ld [%o0], %o0 tst %o0 bz no_cache nop call _turnoff_cache nopno_cache: set _romp, %o0 ! pass the romp to the callee set _our_die_routine, %o2 ! pass our release func to callee jmpl %i0, %o7 ! call thru register ld [%o0], %o0 set _vac, %o0 ! check vac flag ld [%o0], %o0 tst %o0 bz leave_cache_off nop call _turnon_cache nopleave_cache_off: ret restoreinit_cache: save %sp, -SA(MINFRAME), %sp set _vac, %o0 ! check vac flag ld [%o0], %o0 tst %o0 bz 1f .empty set _start, %o0 ! this doesn't get the stack sethi %hi(_end), %o1 call _cache_prog ! clear the NC bits for prog's pages or %o1, %lo(_end), %o1 call _turnon_cache nop1: ret restore#endif VAC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -