!
! Program first executed by the Sparc after reset.
!
#define KERNEL
#include <sun4/asm←linkage.h>
#define softcardPageSizeByte 8192
! see "SparcSoftcard.h"
#define trapBaseByte softcardPageSizeByte
! the trap vectors will be located in page 1
#define RESET←TRAP 0
#define OVERFLOW←TRAP 5
#define UNDERFLOW←TRAP 6
#define TRAP𡤃 0x83
#define NB←WINDOWS 7
! Fujitsu implementation
#define INTERRUPT←MASK 0xf00
.seg "text"
.global ←init0 ! Starts here after Reset
.global ←main
.global ←place←trap←vector
←init0: ! First instruction after reset
!
! set CPW and WIM to meaningfull values
!
wr %g0, %g0, %wim ! guaranties that all windows are valid
nop
nop
nop
rd %psr, %g1 !
and %g1, ~0x1f, %g1 ! set CPW to 0.
and %g1, ~0x20, %g1 ! disable traps.
and %g1, ~0x40, %g1 ! reset PS bit.
or %g1, INTERRUPT←MASK, %g1 ! Set PIL Bits (disable interrrupts).
wr %g1, %g0, %psr !
nop
wr %g0, 2, %wim ! mark window #1 invalid (max number of call before overflow)
nop
set 0, %fp ! Indicates End Of Stack.
!
! Temporary sets %sp value near the end of the second page.
! *** DON'T put it in page 0. The mapping is temporary changed by init1.c ***
!
set ( 2 * softcardPageSizeByte ), %sp
sub %sp, MINFRAME, %sp ! decrement sp by one frame
and %sp, ~7, %sp ! round down to 0 modulo 8
!
! Zero bss.
!
.global ta
.global 𡤎nd
set 0, %l0
set 0, %l1
set ta, %l2 ! ta is the start of the bss (double word aligned).
set 𡤎nd, %l3 ! 𡤎nd is the end of the bss
1:
std %l0, [%l2]
add %l2, 8, %l2
subcc %l2, %l3, %g0
bne 1b
nop
!
! Sets all the traps pointers to the debugger entry point.
!
.global debug𡤎ntry
add %g0, %g0, %g1 ! (trap number and loop index)
sethi %hi(debug𡤎ntry), %g2 ! prepare the arguments
or %g2, %lo(debug𡤎ntry), %g2 ! (trap routine address)
trapsloop:
mov %g1, %o0 !
mov %g2, %o1 ! Place the arguments inside the right registers
call ←place←trap←vector
inc %g1 ! inc loop index
subcc %g1, 256, %g0 ! test loop exit
bne trapsloop
nop
!
! Sets the reset trap to the debugger entry point.
!
set RESET←TRAP, %o0 !
sethi %hi(debug𡤎ntry), %o1 ! prepare the arguments for the call
or %o1, %lo(debug𡤎ntry), %o1 !
call place←reset←trap←vector
nop
!
! Sets the trap pointers for window←overflow, window←underflow
! and window←Save𡤊llroutines
!
.global window←overflow
.global window←underflow
.global window←save𡤊ll
set OVERFLOW←TRAP, %o0 !
sethi %hi(window←overflow), %o1 ! prepare the arguments for the call
or %o1, %lo(window←overflow), %o1 !
call ←place←trap←vector
nop
set UNDERFLOW←TRAP, %o0 !
sethi %hi(window←underflow), %o1 ! prepare the arguments for the call
or %o1, %lo(window←underflow), %o1 !
call ←place←trap←vector
nop
set TRAP𡤃, %o0 !
sethi %hi(window←save𡤊ll), %o1 ! prepare the arguments for the call
or %o1, %lo(window←save𡤊ll), %o1 !
call ←place←trap←vector
nop
!
! Set trap base address to trapBaseByte = page 1 ( page 0 will be used as NIL check )
!
set trapBaseByte, %g1
wr %g1, 0, %tbr
nop
nop
nop
!
! Enable traps interrupts are still masked
!
rd %psr, %g1
or %g1, 0x20, %g1 ! set ET bit
wr %g1, 0, %psr
nop
!
! Call a C subroutine to find out the memory size and initialize the map.
! This subroutine returns sparcMemorySizeByte inside %o0.
! All the VM pages from 0 to sparcMemorySizeByte/softcardPageSizeByte - 1 point
! to distinct Real memory pages. The remaining entries of the map point at the
! same place that page 0.
!
.global ←init←map
call ←init←map
nop
mov %o0, %l0 ! save the memory size
mov %o0, %sp ! set SP to its correct value (near sparcMemorySizeByte)
sub %sp, MINFRAME, %sp ! decrement sp by one frame
and %sp, ~7, %sp ! round down to 0 modulo 8
!
! Set the memory size (for subsequent calls to MemEnd() )
!
mov %l0, %o0
call ←SetMemEnd
nop
!
! Set the stack size (for subsequent calls to StackEnd() or HeapEnd() )
!
set 0x100000, %o0 ! arbitrary
call ←SetStackSize
nop
!
! End of assembly code initialization.
!
ba ←init1 ! Jumps to the C init1.c program
nop
!
! leaf subroutine ←place←trap←vector
!
! Places at address trap←number *16 the instruction "b targetress" followed by "nop"
!
! %o0 holds trap←number
! %o1 holds targetress
!
←place←trap←vector:
sethi %hi(self), %o2
or %o2, %lo(self), %o2 ! %o2 holds the address of the instruction "b self"
ld [%o2] , %o3 ! %o3 holds the instruction "b self"
sll %o0, 4, %o0 ! %o0 now holds the low part of the trap vector address
set trapBaseByte, %o4 ! add the trap base address
add %o0, %o4, %o0 ! %o0 now holds the trap vector address
sub %o1, %o0, %o1 ! byte offset of the vector to program location
srl %o1, 2, %o1 ! word offset of the vector to program location
add %o3, %o1, %o3 ! %o3 holds the instruction "b target address"
! DANGEROUS overflow not tested
! Fails to produce the right code if the target is more than 8 MegaBytes away.
st %o3, [%o0] ! store the branch instruction
ld [%o2 + 4] , %o3 ! %o3 holds the instruction "nop"
st %o3, [%o0 + 4] ! store the nop instruction
retl ! return from leaf subroutine
nop
place←reset←trap←vector:
sethi %hi(self), %o2
or %o2, %lo(self), %o2 ! %o2 holds the address of the instruction "b self"
ld [%o2] , %o3 ! %o3 holds the instruction "b self"
sll %o0, 4, %o0 ! %o0 now holds the low part of the trap vector address
set 0, %o4 ! add the trap base address
add %o0, %o4, %o0 ! %o0 now holds the trap vector address
sub %o1, %o0, %o1 ! byte offset of the vector to program location
srl %o1, 2, %o1 ! word offset of the vector to program location
add %o3, %o1, %o3 ! %o3 holds the instruction "b target address"
! DANGEROUS overflow not tested
! Fails to produce the right code if the target is more than 8 MegaBytes away.
st %o3, [%o0] ! store the branch instruction
ld [%o2 + 4] , %o3 ! %o3 holds the instruction "nop"
st %o3, [%o0 + 4] ! store the nop instruction
retl ! return from leaf subroutine
nop
self:
b self ! template for ←place←trap←vector and place←reset←trap←vector
nop ! subroutines. DO NOT REMOVE