! ! Program first executed by the Sparc after reset. ! #define KERNEL #include #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_3 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 _edata .global _end set 0, %l0 set 0, %l1 set _edata, %l2 ! _edata is the start of the bss (double word aligned). set _end, %l3 ! _end 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_entry add %g0, %g0, %g1 ! (trap number and loop index) sethi %hi(debug_entry), %g2 ! prepare the arguments or %g2, %lo(debug_entry), %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_entry), %o1 ! prepare the arguments for the call or %o1, %lo(debug_entry), %o1 ! call place_reset_trap_vector nop ! ! Sets the trap pointers for window_overflow, window_underflow ! and window_Save_allroutines ! .global window_overflow .global window_underflow .global window_save_all 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_3, %o0 ! sethi %hi(window_save_all), %o1 ! prepare the arguments for the call or %o1, %lo(window_save_all), %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 target_address" followed by "nop" ! ! %o0 holds trap_number ! %o1 holds target_address ! _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 JJ4JJJJ!J)J,JJJJJJJJ J*J JJ.JJJ'JJJJJJJJJJJJFJ$JJJJJFJ%JJJJJFJ$JJJJJUJJJJJJJJJJ*JJJJ!JJJJJJKJ;JQJPJJJJJJJJJ.JIJ2J.JJJ:JJJ JJJJJIJJJJJJJJ&JJJ-JJJJ$JJXJJJJJJJJLJ8JLJ4J=JDJDJJDJJJNJJ1J8J1JJ*JJJJJLJ8JLJ,J=JDJDJJDJJJNJJ1J8J1JJ*JJJNJ(JJ\~