! ! traps.s Takes care of traps routines. ! #define KERNEL #include #define INTERRUPT_MASK 0xf00 #define NB_WINDOWS 7 ! Fujitsu implementation !********************************************************************** ! ! Debugger entry point. Dumps the registers, ! enables traps and jumps to the C debbuger. ! !********************************************************************** .seg "text" .global debug_entry debug_entry: mov %y, %l4 ! mov %psr, %l5 ! mov %wim,%l6 ! Moves %y, %psr, %wim and %tbr into locals mov %tbr, %l7 ! ! ! If current window is invalid then make it valid ! allowed to use the only 2 remaining registers %l0 and %l3 ! set 1, %l0 sll %l0, %l5, %l0 ! creates the current window position pattern and %l0, %l6, %l0 ! compare with %wim tst %l0 be debug1 ! if window valid nothing to do. nop ! Make window valid wr %g0, 0, %wim ! IMPORTANT otherwise restore will fail in some cases save %g0, %g0, %g0 ! go to the next window and don't add anything SAVE_WINDOW (%sp) ! writes the registers on the memory stack restore %g0, %g0, %g0 ! go back to the trap window ! moves the invalid bit in the %wim and %l6, ((1 << NB_WINDOWS) - 1), %l0 srl %l0, 1, %l0 ! tst %l0 ! Rotates the low order bits of %l0 left bne debug2 ! nop ! set (1 << (NB_WINDOWS - 1)), %l0 ! <- Implementation dependant debug2: ! wr %l0, 0, %wim ! writes back the new %wim debug1: ! ! Set interrupt level to 0xF in order to avoid recursively taking interrupts ! rd %psr, %l0 or %l0, INTERRUPT_MASK, %l0 ! set PIL bits wr %l0, 0, %psr nop ! nop ! Wait for %psr to settle nop ! ! ! ReEnable traps ! rd %psr, %l0 or %l0, 0x20, %l0 ! set ET bit wr %l0, 0, %psr nop ! nop ! Wait for %psr to settle nop ! sub %fp, (24 * 4), %sp ! leave room for the globals also ! ! store global registers on the stack ! std %g0, [%fp - (8-0) *4] std %g2, [%fp - (8-2) *4] std %g4, [%fp - (8-4) *4] std %g6, [%fp - (8-6) *4] ! ! Push everything on the stack ! set NB_WINDOWS, %g1 debug3: save %sp, - 64, %sp dec %g1 tst %g1 bne debug3 nop set NB_WINDOWS, %g1 debug4: restore %g0, %g0, %g0 dec %g1 tst %g1 bne debug4 nop ! ! Multiway branch to the different interrupt routines ! (will join back at label returnFromTrap) ! srl %l7, 4, %l0 ! and %l0, 0xff, %l0 ! Trap number into %l0 subcc %l0, 0x13, %g0 ! be SparcToSparcInt ! SparcToSparc Interrupt level nop ! subcc %l0, 0x14, %g0 ! be IOPToSparcInt ! IOPToSparc Interrupt level nop ! subcc %l0, 0x17, %g0 ! be MesaToSparcInt ! MesaToSparc Interrupt level nop ! subcc %l0, 0x18, %g0 ! be PeriphAInt ! PeriphA Interrupt level nop ! subcc %l0, 0x1b, %g0 ! be PeriphBInt ! PeriphB Interrupt level nop ! subcc %l0, 0x1c, %g0 ! be PeriphCInt ! PeriphC Interrupt level nop ! subcc %l0, 0x17, %g0 ! be AbortInt ! Abort Interrupt level nop ! SparcToSparcInt: IOPToSparcInt: MesaToSparcInt: PeriphCInt: AbortInt: ! *** TO BE CLEANED *** ! Prepares to enter the C debugger ! Clear the SparcToSparcInterrupt state bit and reset PIL to 0 ! .global _SparcSoftcardOps_ResetSparcToSparcInt call _SparcSoftcardOps_ResetSparcToSparcInt nop rd %psr, %l0 ! and %l0, ~INTERRUPT_MASK, %l0 ! reset PIL bits wr %l0, 0, %psr ! nop ! nop ! Wait for %psr to settle nop ! ! ! Enters the C debugger. %o0 holds the %sp address. ! mov %sp, %o0 call _debug ! Enters the C debugger. nop ba returnFromTrap ! Joins the standard restore phase nop PeriphAInt: ! ! Trap routine when interrupted by periph A ! (now real time clock) ! ! Inc _RealTimeClockHigh set _RealTimeClockHigh, %l0 ld [%l0 + 0], %l3 inc %l3 ! increments RealTimeClockHigh st %l3, [%l0 + 0] ! Resets PeriphA Interrupt set 0, %o0 ! InterruptNumber_interruptA=0 call _SparcSoftcardOps_ResetPeriphInt nop ba returnFromTrap ! Joins the standard restore phase nop .seg "data" .align 4 .global _RealTimeClockHigh _RealTimeClockHigh: .long 0 .seg "text" PeriphBInt: ! ! Trap routine when interrupted by periph B ! (now DMAEnd) ! ! Resets PeriphB Interrupt set 1, %o0 ! InterruptNumber_interruptB = 1 call _SparcSoftcardOps_ResetPeriphInt nop call _PIInterrupt ! executes the core of the routine nop ba returnFromTrap ! Joins the standard restore phase nop ! ! Returns from trap. All the registers have to be reloaded. ! This part of the code is entered with trap enabled ! Be carefull with ET and PIL bits in %psr ! returnFromTrap: RESTORE_WINDOW (%sp) ! updates the current in and local to the content of the stack ! ! The previous window is ALWAYS invalid => It has to be restored before rett ! (Otherwise a reset trap occurs) ! restore %g0, %g0, %g0 ! save %g0, %g0, %g0 ! Restore previous window rd %psr, %l0 ! and %l0, ~0x20, %l0 ! Disable traps wr %l0, 0, %psr ! ! ! If the CWP bits in %psr have been touched you are in trouble... ! ldd [%fp - (8-0) *4], %g0 ! ldd [%fp - (8-2) *4], %g2 ! Reloads globals ldd [%fp - (8-4) *4], %g4 ! ldd [%fp - (8-6) *4], %g6 ! ! ! If the ET bit in %psr has been touched you can be in trouble... ! wr %l4, 0, %y ! wr %l5, 0, %psr ! Restores %y, %psr and %tbr. wr %l7, 0, %tbr ! Do NOT restore %wim nop nop nop ! ! Return to the trapping program ! jmpl %l1, %g0 ! two standard steps rett %l2 ! to return from trap nop !*************************************************************** ! ! JCC version of window_save_all (alias trap 3) ! !*************************************************************** .seg "text" .global window_save_all window_save_all: ! ! If current window is invalid then make it valid ! allowed to use the only the local registers remaining (not %l1 and %l2) ! mov %psr, %l5 ! mov %wim,%l6 ! Moves %psr and %wim into locals set 1, %l0 sll %l0, %l5, %l0 ! creates the current window position pattern and %l0, %l6, %l0 ! compare with %wim tst %l0 be saveall1 ! if window valid nothing to do. nop ! ! Make window valid ! wr %g0, 0, %wim ! IMPORTANT otherwise restore will fail in some cases save %g0, %g0, %g0 ! go to the next window and don't add anything SAVE_WINDOW (%sp) ! writes the registers on the memory stack restore %g0, %g0, %g0 ! go back to the trap window ! moves the invalid bit in the %wim and %l6, ((1 << NB_WINDOWS) - 1), %l0 srl %l0, 1, %l0 ! tst %l0 ! Rotates the low order bits of %l0 left bne saveall2 ! nop ! set (1 << (NB_WINDOWS - 1)), %l0 ! <- Implementation dependant saveall2: ! wr %l0, 0, %wim ! writes back the new %wim saveall1: ! ! ReEnable traps ! rd %psr, %l0 or %l0, 0x20, %l0 ! set ET bit wr %l0, 0, %psr nop ! nop ! Wait for %psr to settle nop ! ! ! Push everything on the stack ! mov %g1, %l0 ! save %g1 set NB_WINDOWS, %g1 saveall3: save %sp, - 64, %sp dec %g1 tst %g1 bne saveall3 nop set NB_WINDOWS, %g1 saveall4: restore %g0, %g0, %g0 dec %g1 tst %g1 bne saveall4 nop mov %l0, %g1 ! restore %g1 ! ! Disable traps ! rd %psr, %l0 ! and %l0, ~0x20, %l0 ! Disable traps wr %l0, 0, %psr ! nop ! nop ! Wait for %psr to settle nop ! ! ! Return to the trapping program AFTER the trapping instruction ! jmpl %l2, %g0 ! two standard steps rett %l2 + 4 ! to return from trap after the trapping instruction nop !*************************************************************** ! ! JCC version of window_overflow and window_underflow traps ! !*************************************************************** .seg "text" .global window_overflow window_overflow: ! ! Current window is marked invalid. Next window must ! be saved and marked invalid ! rd %wim, %l0 ! saves %wim wr %g0, 0, %wim ! clear %wim -> disable futher overflows or underflows save %g0, %g0, %g0 ! go to the next window and don't add anything SAVE_WINDOW (%sp) ! writes the registers on the memory stack ld [%g0 + 0], %l0 ! sub %sp, %l0, %l0 ! tst %l0 ! bpos 1f ! *** DEBUG find lowest value of the stack ( TB Removed) *** nop ! st %sp, [%g0 + 0] ! 1: restore %g0, %g0, %g0 ! go back to the trap window ! moves the invalid bit in the %wim and %l0, ((1 << NB_WINDOWS) - 1), %l0 ! extract the correct bits <- Implementation dependant srl %l0, 1, %l0 ! tst %l0 ! Rotates the low order bits of %l0 left bne label0 ! nop ! set (1 << (NB_WINDOWS - 1)), %l0 ! <- Implementation dependant label0: ! wr %l0, 0, %wim ! writes back the new %wim nop ! wait for the %wim to settle nop jmpl %l1, %g0 ! two standard steps rett %l2 ! to return from trap nop .global window_underflow window_underflow: ! ! Previous window is last active window. The window before that ! is marked invalid and must be restored. The window before that ! becomes the new invalid window. ! rd %wim, %l0 ! saves %wim wr %g0, 0, %wim ! clear %wim -> disable futher overflows or underflows restore %g0, %g0, %g0 ! back two windows to point restore %g0, %g0, %g0 ! to the registers to be restored. RESTORE_WINDOW (%sp) ! loads the registers from the memory stack save %g0, %g0, %g0 ! again to the trap window save %g0, %g0, %g0 ! moves the invalid bit in the %wim and %l0, ((1 << NB_WINDOWS) - 1), %l0 ! extract the correct bits <- Implementation dependant sll %l0, 1, %l0 ! cmp %l0, (1 << NB_WINDOWS) ! <- Implementation dependant bne label1 ! nop ! set 1, %l0 ! label1: ! wr %l0, 0, %wim ! writes back the new %wim nop ! wait for the %wim to settle nop jmpl %l1, %g0 ! two standard steps rett %l2 ! to return from trap nop ʘJ˜J˜*J˜J˜J˜J˜J˜J˜J˜J˜˜J˜—˜J˜GJ˜J˜.J˜.J˜J˜GJ˜—J˜J˜ J˜J˜˜ J˜J˜J˜J˜>J˜J˜J˜J˜2J˜;J˜J˜ J˜BJ˜'J˜ J˜/J˜J˜J˜J˜J˜HJ˜CJ˜>J˜3J˜%J˜&J˜J˜6J˜J˜ J˜A—˜J˜,J˜—˜J˜J˜LJ˜J˜J˜-J˜J˜ J˜"J˜ J˜J˜J˜J˜J˜!J˜J˜ J˜"J˜ J˜:J˜J˜J˜&J˜J˜J˜J˜J˜J˜J˜J˜J˜J˜J˜—˜J˜J˜J˜ J˜ J˜J˜—˜J˜J˜J˜ J˜ J˜J˜J˜J˜5J˜+J˜J˜J˜,J˜J˜4J˜ J˜J˜1J˜ J˜J˜2J˜ J˜J˜,J˜ J˜J˜+J˜ J˜J˜,J˜ J˜J˜(J˜ J˜—J˜J˜J˜J˜J˜ ˜ J˜J˜"J˜>J˜—˜.J˜,J˜J˜J˜0J˜J˜ J˜#J˜ J˜J˜J˜J˜3J˜J˜J˜ J˜&J˜J˜5J˜J˜J˜—˜ J˜J˜,J˜J˜J˜J˜J˜J˜+J˜J˜J˜,J˜%J˜J˜5J˜—J˜ J˜J˜J˜J˜J˜ J˜J˜˜ J˜J˜,J˜J˜J˜J˜.J˜%J˜J˜7J˜J˜5J˜J˜J˜J˜J˜J˜;J˜4J˜*J˜J˜—˜J˜TJ˜J˜MJ˜#J˜J˜J˜.J˜J˜%J˜J˜J˜DJ˜J˜J˜.J˜J˜J˜J˜DJ˜J˜J˜3J˜+J˜J˜J˜J˜J˜ J˜J˜$J˜"J˜J˜J˜J˜J˜J˜J˜J˜J˜AJ˜J˜2J˜J˜A—J˜J˜ J˜J˜˜J˜J˜J˜2J˜IJ˜J˜J˜J˜4J˜ J˜EJ˜*J˜ J˜4J˜J˜J˜J˜J˜J˜J˜HJ˜CJ˜>J˜3J˜%J˜&J˜J˜6J˜J˜ J˜A—˜J˜,—˜ J˜J˜J˜J˜J˜J˜J˜!J˜J˜ J˜"J˜ J˜J˜J˜J˜J˜J˜J˜—˜ J˜J˜J˜ J˜ J˜J˜J˜—˜ J˜J˜J˜ J˜ J˜J˜J˜J˜J˜J˜J˜J˜J˜%J˜J˜ J˜"J˜ J˜J˜J˜?J˜J˜J˜$J˜DJ˜J˜J˜J˜J˜J˜J˜J˜—˜J˜AJ˜J˜=J˜J˜A—J˜J˜ J˜J˜˜J˜J˜J˜4J˜J˜J˜J˜J˜IJ˜J˜CJ˜J˜>J˜J˜J˜J˜J˜JJ˜ J˜—˜J˜J˜J˜J˜3J˜J˜J˜#J˜˜&J˜6—J˜J˜6J˜J˜ J˜A—˜J˜,J˜J˜'J˜J˜J˜$J˜"J˜—˜J˜J˜J˜—J˜˜J˜J˜J˜?J˜@J˜!J˜J˜J˜J˜IJ˜J˜2J˜:J˜J˜@J˜J˜/J˜J˜J˜#J˜˜&J˜6—J˜J˜;J˜J˜ J˜—˜J˜,J˜J˜'J˜J˜J˜$J˜"J˜—J˜—…—&„,