summaryrefslogtreecommitdiffstats
path: root/private/ntos/fw/mips/j3trap.s
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/fw/mips/j3trap.s')
-rw-r--r--private/ntos/fw/mips/j3trap.s288
1 files changed, 288 insertions, 0 deletions
diff --git a/private/ntos/fw/mips/j3trap.s b/private/ntos/fw/mips/j3trap.s
new file mode 100644
index 000000000..2e4f7fabe
--- /dev/null
+++ b/private/ntos/fw/mips/j3trap.s
@@ -0,0 +1,288 @@
+#if defined(JAZZ) && defined(R3000)
+
+/*++
+
+Copyright (c) 1990 Microsoft Corporation
+
+Module Name:
+
+ j3trap.s
+
+Abstract:
+
+ This module will handle exceptions
+ It will save the state of the processor, check jump table
+ to see if it should dispatch somewhere, and then return to
+ monitor.
+
+Author:
+
+ John Cooper (johncoop) 4-Oct-90
+
+Environment:
+
+ Kernel mode
+
+Revision History:
+
+
+--*/
+//
+// include header file
+//
+
+#include "ksmips.h"
+#include "selfmap.h"
+#include "led.h"
+#define PROM_BASE (KSEG1_BASE | 0x1fc00000)
+#define PROM_ENTRY(x) (PROM_BASE + ((x) * 8))
+
+.set noat
+.set noreorder
+.text
+
+
+
+ .globl ExceptionDispatch
+ExceptionDispatch:
+/*++
+
+Routine Description:
+
+ This routine will use a lookup table based on the exception
+ cause, to call an exception handler. If the value in
+ lookup table is zero, the state of the machine is saved,
+ and control is passed to monitor.
+ The return value of the exception handler indicates where
+ control should go when the exception condition is cleared.
+
+Arguments:
+
+ K1 - Contains the cause register.
+
+Return Value:
+
+ None.
+
+--*/
+ //
+ // Need to save return address before calling an exec. handler.
+ //
+
+ li k0,GLOBAL_DATA_BASE // base of saved state
+ sw ra, 0x7C(k0) // save ra
+
+ //
+ // Get jump vector from lookup table based on cause.
+ // Call handler if value is non-zero
+ //
+ li k0,EXCEPTION_JUMP_TABLE // base of jump table
+ addu k0,k0,k1 // add offset to base
+ lw k1,0(k0) // get jump vector from tbl
+ li k0,GOTO_MONITOR // go back to monitor by default
+ beq k1,zero,ExceptionReturn // go save state and call mon.
+ li ra,COMMONEXCEPTION // load this value into ra.
+ // this will get passed as
+ // argument to MonitorInit()
+ // which will then print a message
+ // saying a COMMONEXCEPTION occured.
+ // COMMON EXCEPTION is an unaligned #.
+ // if k1 != zero the jal reloads ra
+ jal k1 // with the right value.
+ nop // control will pass to the
+ // Exception Return routine next.
+ // return value from handler
+ // should be returned in k0.
+ // this is passed as argument
+ // to ExceptionReturn.
+
+ .globl ExceptionReturn
+ExceptionReturn:
+
+/*++
+
+Routine Description:
+
+ This routine will restore any registers that have been modified
+ by the trap handler. Control is then passed back to one
+ of three places. Either the monitor, the location stored in the
+ EPC, or the value supplied in the argumnet k0.
+
+Arguments:
+
+ k0 - supplies indication of where to go after clearing exception.
+ if bits [1:0] are 00B then go to location indicated
+ in k0. if bits [1:0] are GOTO_MONITOR, then control
+ is passed to MonitorReInit(). if bits are GOTO_EPC then
+ control is returned to location where exception occured.
+
+Return Value:
+
+ None.
+
+--*/
+
+
+ //
+ // Return value from exec. handler is in k0.
+ // if low bits are 00, then return to value in k0
+ // if low bits are 01, then return to Err PC
+ // if low bits are 10, then return to monitor
+ //
+ andi k1,k0,3 // k1 = k0 & 3
+ beq k1,zero,returntok0 // go if return code is 0
+ andi k1,k0,GOTO_EPC // k1 = k0 & 1
+ bne k1,zero,returntoEPC // if bit1=1 then GOTO_EPC
+ andi k1,k0,GOTO_MONITOR // k1 = k0 & 2
+ bne k1,zero,returntomonitor // if bit2=1 then GOTO_MONITOR
+ nop
+ b returntomonitor // default return action
+ nop
+returntok0:
+
+ //
+ // restore value to ra
+ //
+
+ li k1,GLOBAL_DATA_BASE // base of saved state
+ lw ra, 0x7C(k1) // restore ra
+
+ //
+ // return to value in k0 when clearing exception condition
+ // do this by putting k0 in EPC
+ //
+ j k0 // return to k0
+ rfe // restore pre-exc state
+returntoEPC:
+
+ //
+ // restore value to ra
+ //
+
+ li k1,GLOBAL_DATA_BASE // base of saved state
+
+ //
+ // return to location where exeception was caused
+ //
+ mfc0 k0,epc // get return PC from cop0
+ lw ra, 0x7C(k1) // restore ra
+ j k0 // jump to (EPC)
+ rfe // clear exception condition
+
+returntomonitor:
+
+ //
+ // return to monitor by calling MonitorReInit()
+ //
+ //li k0,MONITOR_LINK_ADDRESS
+ //j k0
+ //rfe // restore pre-exc state
+ li k0,PROM_ENTRY(14)
+ lui a0,LED_BLINK
+ jal k0
+ ori a0,a0,0xFC
+
+ .globl TLBMiss
+TLBMiss:
+
+/*++
+
+Routine Description:
+
+ This routine will modifiy the TLB when a miss occurs.
+ It will take the failed virtual address and place it
+ in the TLB as a physical address. This will make
+ a one to one mapping between virtual and physical.
+ If the address is E2000000 - E3FFFFFF, then routine
+ will subtract off 52000000 for eisa spaces.
+ This routine is only expected to be used for the R3000
+
+ Note that the control from the exception vector is passed
+ to the dispatch routine. The dispatch routine calls this
+ routine - control is passed back to the dispatch routine.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+ //
+ // load bad virtual address - the address that missed in TLB
+ //
+
+ mfc0 k0,badvaddr
+
+ //
+ // mask out page offset to get virtual page number.
+ // offset differs in size between R4000 and R3000
+ //
+
+ li k1,0xFFFFF000
+
+ and k0,k0,k1
+
+ //
+ // store bad virtual address in the EntryHi register to
+ //
+
+ mtc0 k0,entryhi
+
+ //
+ // check if value is between E2000000 - E3FFFFFF
+ // set bits in range (01FFFFFF) and compare to E3FFFFFF
+ //
+
+ li k1,0x01FFFFFF
+ or k0,k0,k1
+ li k1,0xE3FFFFFF
+
+ bne k1,k0,noteisa
+
+ //
+ // subtract off 52000000
+ //
+
+ mfc0 k0,entryhi
+ li k1,0x52000000
+ sub k0,k0,k1
+ nop
+
+noteisa:
+ //
+ // set non-cached, dirty, valid, and global bits
+ //
+ //
+
+ li k1,(1<<ENTRYLO_D) + (1<<ENTRYLO_V) + (1<<ENTRYLO_G) + (1<<ENTRYLO_N)
+ or k0,k0,k1
+ mtc0 k0,entrylo
+
+ //
+ // set index to 63 to write the 63 entry. always replace this
+ // entry to preserve all the other entries.
+ //
+
+ li k0,(63<<INDEX_INDEX)
+ mtc0 k0,index
+ nop
+
+ //
+ // write the tlb entry.
+ //
+
+ tlbwi
+ nop
+
+ //
+ // return from exception - tell dispatch to go to EPC
+ //
+
+ j ra
+ li k0,GOTO_EPC
+
+#endif // R3000 && JAZZ