Init
This commit is contained in:
73
sys/boot/sun4c/Makefile
Normal file
73
sys/boot/sun4c/Makefile
Normal file
@@ -0,0 +1,73 @@
|
||||
#
|
||||
# @(#)Makefile 1.1 94/10/31 SMI
|
||||
#
|
||||
# Makefile for /boot, boot blocks, and related stand-alone programs
|
||||
|
||||
ARCH= sun4c
|
||||
MACH= sparc
|
||||
ARCHDIR= ../$(ARCH)
|
||||
MACHDIR= ../$(MACH)
|
||||
ARCHOBJ= conf.o trap.o stubs.o
|
||||
ARCHOPTS= -DSUN4C_60 $(ARCHDEFS)
|
||||
ARCHDEFS= $(LIBPROMCPPOPTS)
|
||||
ARCHLIBS= $(LIBPROM)
|
||||
#
|
||||
# LOAD is the text segment start for booted user programs.
|
||||
# It is also used by srt0.s for the initial stack.
|
||||
#
|
||||
LOAD= 4000
|
||||
#
|
||||
# BRELOC is the text segment start for final stage (2nd or 3rd stage) boots.
|
||||
# Note that this must be higher than the kernel's edata and should be
|
||||
# higher than the kernel's bss so the bss can be cleared.
|
||||
#
|
||||
BRELOC= 300000
|
||||
#
|
||||
# BBRELOC is the text segment start for boot blocks.
|
||||
# Note that this must be higher than boot's edata and should be
|
||||
# higher than boot's bss so the bss can be cleared.
|
||||
#
|
||||
BBRELOC= 340000
|
||||
|
||||
BOOTBLOCKS= bootopen
|
||||
|
||||
ALL= boot.$(ARCH) $(BOOTBLOCKS) installboot
|
||||
|
||||
all: $(ALL)
|
||||
|
||||
include ../boot/Makefile.com
|
||||
|
||||
# Special rules for sun4c, which uses a.out executables as its boot programs.
|
||||
boot.$(ARCH): boot
|
||||
cp $? $@; strip $@
|
||||
|
||||
# Rules for arch-dependent .c files
|
||||
$$(LIB)(%.o): $(ARCHDIR)/%.c
|
||||
$(CC) $(CFLAGS) -DLOAD=0x4000 -c $<
|
||||
@ $(AR) $(ARFLAGS) $(LIB) $% ; $(RM) $%
|
||||
|
||||
# Rules for arch-dependent .s files
|
||||
$$(LIB)(%.o): $(ARCHDIR)/%.s
|
||||
@ $(RM) tmp.c tmp.i $%
|
||||
cp $< tmp.c
|
||||
/lib/cpp -P -DBOOTBLOCK -DLOCORE $(CPPOPTS) $(BOOTOPT) -DLOAD=0x$(LOAD) tmp.c > tmp.s
|
||||
$(AS) -P -Q tmp.s -o $%
|
||||
@ $(AR) $(ARFLAGS) $(LIB) $%
|
||||
@ $(RM) tmp.c tmp.i tmp.s $%
|
||||
|
||||
# Standalone start-off.
|
||||
SRTOPT= -DLOCORE -DLOAD=0x$(LOAD)
|
||||
srt0xx.o:= SRTOPT += -DBOOTBLOCK
|
||||
|
||||
srt0.o srt0xx.o: $(ARCHDIR)/srt0.S
|
||||
cc -c $(CFLAGS) $(SRTOPT) $(BOOTOPT) -o $@ $(ARCHDIR)/srt0.S
|
||||
|
||||
install_mdec:
|
||||
install bootopen $(BOOTBLKDIR)/rawboot
|
||||
$(RM) $(BOOTBLKDIR)/bootsd $(BOOTBLKDIR)/bootfd
|
||||
ln $(BOOTBLKDIR)/rawboot $(BOOTBLKDIR)/bootsd
|
||||
ln $(BOOTBLKDIR)/rawboot $(BOOTBLKDIR)/bootfd
|
||||
# HACK - see bugid 1041421
|
||||
echo "DUMMY sun4c tpboot file to get around suninstall bug in 4.1" > $(STANDDIR)/tpboot.sun4c
|
||||
echo "tpboot is now OBSOLETE for sun4c, but 4.1 suninstall expects it" >> $(STANDDIR)/tpboot.sun4c
|
||||
chmod 644 $(STANDDIR)/tpboot.sun4c
|
||||
50
sys/boot/sun4c/conf.c
Normal file
50
sys/boot/sun4c/conf.c
Normal file
@@ -0,0 +1,50 @@
|
||||
#if !defined(lint) && !defined(BOOTBLOCK)
|
||||
static char sccsid[] = "@(#)conf.c 1.1 94/10/31 SMI";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 Sun Microsystems, Inc.
|
||||
*
|
||||
* Configuration table for standalone I/O system.
|
||||
*
|
||||
* This file contains the character and block device lists
|
||||
* for drivers supported by the boot program. Note that tpboot and copy
|
||||
* use a different link order, so that the devsw[] list in
|
||||
* the standalone library (libsa.a) supersedes this one.
|
||||
*
|
||||
* The open boot proms initialize these tables at run time, not statically,
|
||||
* so they're just empty slots. Be sure to leave enough room for all
|
||||
* possible devices; these really ought to be linked lists, but you know...
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "boot/conf.h"
|
||||
|
||||
/*
|
||||
* The device table
|
||||
*
|
||||
* This table lists all the nfs devices. It is searched by
|
||||
* etherinit() to parse the device specification.
|
||||
*/
|
||||
|
||||
struct boottab *(devsw[8]) = {
|
||||
(struct boottab *)0,
|
||||
};
|
||||
|
||||
/*
|
||||
* This table lists all the ufs devices.
|
||||
*
|
||||
* Beware: in the following table, the entries must appear
|
||||
* in the slot corresponding to their major device number.
|
||||
* This is because other routines index into this table
|
||||
* using the major() of the dev_t returned by getblockdev.
|
||||
*/
|
||||
|
||||
struct bdevlist bdevlist[8] = {
|
||||
"", 0, 0,
|
||||
};
|
||||
|
||||
struct ndevlist ndevlist[8] = {
|
||||
0, 0,
|
||||
};
|
||||
|
||||
274
sys/boot/sun4c/srt0.S
Normal file
274
sys/boot/sun4c/srt0.S
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* srt0.s - standalone startup code
|
||||
* .seg "data"
|
||||
* .asciz "@(#)srt0.S 94/10/31 1.1 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, _npmgrps
|
||||
.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 libc
|
||||
exitbuf:
|
||||
.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 call
|
||||
1:
|
||||
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 program
|
||||
2:
|
||||
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
|
||||
nop
|
||||
|
||||
jmpstart:
|
||||
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
|
||||
call _l14enable ! turn on level 14 interrupts
|
||||
nop
|
||||
!
|
||||
! 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, %o1
|
||||
out:
|
||||
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
|
||||
nop
|
||||
1:
|
||||
set exitbuf, %o0
|
||||
call __longjmp
|
||||
mov 1, %o1
|
||||
out:
|
||||
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
|
||||
nop
|
||||
no_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
|
||||
nop
|
||||
leave_cache_off:
|
||||
ret
|
||||
restore
|
||||
|
||||
init_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
|
||||
nop
|
||||
1:
|
||||
ret
|
||||
restore
|
||||
|
||||
#endif VAC
|
||||
99
sys/boot/sun4c/stubs.s
Normal file
99
sys/boot/sun4c/stubs.s
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* .seg "data"
|
||||
* .asciz "@(#)stubs.s 1.1 94/10/31 SMI"
|
||||
* Copyright (c) 1988 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <machine/asm_linkage.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/psl.h>
|
||||
|
||||
#define SYS_mountroot 0x0
|
||||
#define SYS_exitto 0x1
|
||||
#define SYS_read 0x3
|
||||
#define SYS_open 0x5
|
||||
#define SYS_close 0x6
|
||||
#define SYS_reopen 0x7
|
||||
#define SYS_lseek 0x13
|
||||
|
||||
.text
|
||||
.seg "text"
|
||||
.align 4
|
||||
|
||||
ENTRY(mountroot)
|
||||
save %sp, -SA(MINFRAME), %sp
|
||||
mov %i2, %o3
|
||||
mov %i1, %o2
|
||||
mov %i0, %o1
|
||||
mov SYS_mountroot, %o0
|
||||
t 0;
|
||||
mov %o0, %i0
|
||||
ret
|
||||
restore
|
||||
|
||||
ENTRY(exitto)
|
||||
save %sp, -SA(MINFRAME), %sp
|
||||
mov %i2, %o3
|
||||
mov %i1, %o2
|
||||
mov %i0, %o1
|
||||
mov SYS_exitto, %o0
|
||||
t 0;
|
||||
call __exitto ! __exitto(go2) must be
|
||||
mov %i0, %o0 ! on this side of the trap
|
||||
ret
|
||||
restore
|
||||
|
||||
ENTRY(open)
|
||||
save %sp, -SA(MINFRAME), %sp
|
||||
mov %i2, %o3
|
||||
mov %i1, %o2
|
||||
mov %i0, %o1
|
||||
mov SYS_open, %o0
|
||||
t 0
|
||||
mov %o0, %i0
|
||||
ret
|
||||
restore
|
||||
|
||||
ENTRY(read)
|
||||
save %sp, -SA(MINFRAME), %sp
|
||||
mov %i2, %o3
|
||||
mov %i1, %o2
|
||||
mov %i0, %o1
|
||||
mov SYS_read, %o0
|
||||
t 0
|
||||
mov %o0, %i0
|
||||
ret
|
||||
restore
|
||||
|
||||
ENTRY(close)
|
||||
save %sp, -SA(MINFRAME), %sp
|
||||
mov %i2, %o3
|
||||
mov %i1, %o2
|
||||
mov %i0, %o1
|
||||
mov SYS_close, %o0
|
||||
t 0
|
||||
mov %o0, %i0
|
||||
ret
|
||||
restore
|
||||
|
||||
ENTRY(reopen)
|
||||
save %sp, -SA(MINFRAME), %sp
|
||||
mov %i2, %o3
|
||||
mov %i1, %o2
|
||||
mov %i0, %o1
|
||||
mov SYS_reopen, %o0
|
||||
t 0
|
||||
mov %o0, %i0
|
||||
ret
|
||||
restore
|
||||
|
||||
ENTRY(lseek)
|
||||
save %sp, -SA(MINFRAME), %sp
|
||||
mov %i2, %o3
|
||||
mov %i1, %o2
|
||||
mov %i0, %o1
|
||||
mov SYS_lseek, %o0
|
||||
t 0
|
||||
mov %o0,%i0
|
||||
ret
|
||||
restore
|
||||
|
||||
75
sys/boot/sun4c/trap.s
Normal file
75
sys/boot/sun4c/trap.s
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* .seg "data"
|
||||
* .asciz "@(#)trap.s 1.1 94/10/31 SMI"
|
||||
* Copyright (c) 1986 by Sun Microsystems, Inc.
|
||||
*/
|
||||
#include <machine/asm_linkage.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/psl.h>
|
||||
|
||||
/*
|
||||
* Make sure the vector for 'trap #0' is installed. Kadb in particular
|
||||
* depends on this.
|
||||
*
|
||||
* set_vec(vbr)
|
||||
* int vbr;
|
||||
*/
|
||||
ENTRY(set_vec)
|
||||
bclr 0xfff, %o0 ! set tt field to 0x80 for trap #0
|
||||
or %o0, 0x800, %o0
|
||||
set trap_0, %o1
|
||||
ldd [%o1], %o2 ! copy prototype to trap table
|
||||
std %o2, [%o0]
|
||||
ldd [%o1 + 8], %o2
|
||||
std %o2, [%o0 + 8]
|
||||
mov %psr, %o0 ! enable traps
|
||||
or %o0, PSR_ET, %o0
|
||||
mov %o0, %psr
|
||||
nop
|
||||
retl
|
||||
mov %g0, %o0
|
||||
|
||||
.align 8
|
||||
trap_0: sethi %hi(systrap), %l7
|
||||
or %l7, %lo(systrap), %l7
|
||||
jmp %l7
|
||||
mov %psr, %l0
|
||||
.align 4
|
||||
|
||||
/*
|
||||
* System call handler. We get here after a 't 0' instruction, so we're
|
||||
* trapped somewhere in a syscall stub. We won't rett directly back to the
|
||||
* caller; instead we'll make it look like we simply called syscall().
|
||||
* Syscall()'s return will pass control back to the stub right after
|
||||
* the trap instruction.
|
||||
*/
|
||||
systrap:
|
||||
!
|
||||
! When we enter:
|
||||
! %i0 : syscall code
|
||||
! %i1 : arg 0
|
||||
! %i2 : arg 1
|
||||
! %i3 : arg 2
|
||||
! %l1 : trapped %pc
|
||||
! %l2 : trapped %npc
|
||||
!
|
||||
! Decrement the return address so the system call returns to the right place.
|
||||
!
|
||||
sub %l1, 4, %i7
|
||||
!
|
||||
! Push the args, then leave room for a window overflow. This must be
|
||||
! based on CALLER'S current stack pointer (our frame pointer), not our
|
||||
! current sp, since we want out of this window.
|
||||
!
|
||||
st %i1, [%fp + 0]
|
||||
st %i2, [%fp + 4]
|
||||
st %i3, [%fp + 8]
|
||||
mov %fp, %i1
|
||||
add %fp, -SA(MINFRAME), %fp
|
||||
!
|
||||
! Set up addresses so that when we leave the trap control passes to syscall().
|
||||
!
|
||||
set _syscall, %l1
|
||||
add %l1, 4, %l2
|
||||
jmp %l1
|
||||
rett %l2
|
||||
Reference in New Issue
Block a user