#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<