!
! traps.s Takes care of traps routines.
!
#define KERNEL
#include <sun4/asm←linkage.h>
#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𡤎ntry
debug𡤎ntry:
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 ug ! 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𡤊ll (alias trap 3)
!
!***************************************************************
.seg "text"
.global window←save𡤊ll
window←save𡤊ll:
!
! 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
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