Index: c/src/exec/score/cpu/mips/ChangeLog
===================================================================
--- c/src/exec/score/cpu/mips/ChangeLog	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ c/src/exec/score/cpu/mips/ChangeLog	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -1,2 +1,18 @@
+2002-02-27	Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+	* cpu_asm.S: Fixed exception return address, modified FP context
+	switch so FPU is properly enabled and also doesn't screw up the
+	exception FP handling.
+	* idtcpu.h: Added C0_TAR, the MIPS target address register used for 
+	returning from exceptions.
+	* iregdef.h: Added R_TAR to the stack frame so the target address
+	can be saved on a per-exception basis.  The new entry is past the
+	end of the frame gdb cares about, so doesn't affect gdb or cpu.h
+	stuff.
+	* rtems/score/cpu.h: added an #ifdef so cpu_asm.S can include it
+	to obtain FPU defines without systax errors generated by the C
+	defintions.
+	* cpu.c: Improved interrupt level saves & restores.
+	
 2002-02-08	Joel Sherrill <joel@OARcorp.com>
 
Index: c/src/exec/score/cpu/mips/cpu.c
===================================================================
--- c/src/exec/score/cpu/mips/cpu.c	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ c/src/exec/score/cpu/mips/cpu.c	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -1,4 +1,10 @@
 /*
  *  Mips CPU Dependent Source
+ *
+ *  2002:       Greg Menke (gregory.menke@gsfc.nasa.gov)
+ *      Overhauled interrupt level and interrupt enable/disable code
+ *      to more exactly support MIPS.  Our mods were for MIPS1 processors
+ *      MIPS3 ports are affected, though apps written to the old behavior
+ *      should still work OK.
  *
  *  Conversion to MIPS port by Alan Cudmore <alanc@linuxstart.com> and
@@ -75,5 +81,5 @@
  *  This routine returns the current interrupt level.
  */
-   
+
 unsigned32 _CPU_ISR_Get_level( void )
 {
@@ -81,16 +87,20 @@
 
   mips_get_sr(sr);
+
+  //printf("current sr=%08X, ",sr);
 
 #if __mips == 3
 /* EXL bit and shift down hardware ints into bits 1 thru 6 */
-  return ((sr & SR_EXL) >> 1) + ((sr & 0xfc00) >> 9);
+  sr = ((sr & SR_EXL) >> 1) | ((sr & 0xfc00) >> 9);
 
 #elif __mips == 1
 /* IEC bit and shift down hardware ints into bits 1 thru 6 */
-  return (sr & SR_IEC) + ((sr & 0xfc00) >> 9);
+  sr = (sr & SR_IEC) | ((sr & 0xfc00) >> 9);
 
 #else
 #error "CPU ISR level: unknown MIPS level for SR handling"
 #endif
+  //printf("intlevel=%02X\n",sr);
+  return sr;
 }
 
@@ -109,14 +119,15 @@
   */
 
+  new_level &= 0xff;
 
   mips_get_sr(sr);
 
 #if __mips == 3
-  mips_set_sr(sr & ~SR_IE);                 /* first disable ie bit (recommended) */
+  mips_set_sr( (sr & ~SR_IE) );                 /* first disable ie bit (recommended) */
 
   srbits = sr & ~(0xfc00 | SR_EXL | SR_IE);
 
   sr = srbits | ((new_level==0)? (0xfc00 | SR_EXL | SR_IE): \
-		 (((new_level<<9) & 0xfc000) | \
+		 (((new_level<<9) & 0xfc00) | \
 		  (new_level & 1)?(SR_EXL | SR_IE):0));
 /*
@@ -135,8 +146,10 @@
  
 #elif __mips == 1
-  mips_set_sr( (sr & ~SR_IEC) );	
-
+  mips_set_sr( (sr & ~SR_IEC) );
   srbits = sr & ~(0xfc00 | SR_IEC);
-  sr = srbits | ((new_level==0)?0xfc01:( ((new_level<<9) & 0xfc000) | (new_level & 1)));
+  //printf("current sr=%08X, newlevel=%02X, srbits=%08X, ",sr,new_level,srbits);
+  sr = srbits | ((new_level==0)?0xfc01:( ((new_level<<9) & 0xfc00) | \
+                                         (new_level & SR_IEC)));
+  //printf("new sr=%08X\n",sr);
 #else
 #error "CPU ISR level: unknown MIPS level for SR handling"
@@ -144,4 +157,6 @@
   mips_set_sr( sr );
 }
+
+
 
 /*PAGE
Index: c/src/exec/score/cpu/mips/cpu_asm.S
===================================================================
--- c/src/exec/score/cpu/mips/cpu_asm.S	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ c/src/exec/score/cpu/mips/cpu_asm.S	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -48,4 +48,8 @@
 #include "idtcpu.h"
 
+#define ASSEMBLY_ONLY
+#include <rtems/score/cpu.h>
+
+		
 /* enable debugging shadow writes to misc ram, this is a vestigal
 * Mongoose-ism debug tool- but may be handy in the future so we
@@ -54,5 +58,5 @@
 
 #define INSTRUMENT_ISR_VECTORING
-//#define INSTRUMENT_EXECUTING_THREAD
+/* #define INSTRUMENT_EXECUTING_THREAD */
 
 
@@ -176,27 +180,39 @@
  */
 
-#if ( CPU_HARDWARE_FP == FALSE )
+#if ( CPU_HARDWARE_FP == TRUE )
 FRAME(_CPU_Context_save_fp,sp,0,ra)
+        .set noreorder
         .set noat
 
-#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
 	/* 
-	** Make sure the FPU is on before we save state.  This code is here
-	** because the FPU context switch might occur when an integer
-	** task is switching out w/ an FP task switching in, but the current 
-	** FPU state was left by a sometime previously scheduled FP task.
-	**
-	** In non-deferred FP context switch, if the exiting task is FP, then
-	** the FPU is already on so we don't need to do this.
+	** Make sure the FPU is on before we save state.  This code 
+	** is here because the FPU context switch might occur when an 
+	** integer task is switching out with a FP task switching in.
 	*/
-	
-	MFC0	t0,C0_SR	
-	li	k0,SR_CU1	
-	or	t0,k0
+	MFC0	t0,C0_SR
+	li	t2,SR_CU1	
+	move	t1,t0
+	or	t0,t2		/* turn on the fpu */
+#if __mips == 3
+	li	t2,SR_EXL | SR_IE
+#elif __mips == 1
+	li	t2,SR_IEC
+#endif
+	not	t2
+	and	t0,t2		/* turn off interrupts */	
 	MTC0	t0,C0_SR	
-#endif
 		
-	ld   a1,(a0)
-	NOP
+	ld	a1,(a0)
+	move	t0,ra
+	jal	_CPU_Context_save_fp_from_exception
+	NOP
+	
+	/* 
+	** Reassert the task's state because we've not saved it yet.
+	*/
+	MTC0	t1,C0_SR	
+	j	t0	
+	NOP
+	
 	.globl _CPU_Context_save_fp_from_exception
 _CPU_Context_save_fp_from_exception:
@@ -234,5 +250,5 @@
         swc1 $f31,FP31_OFFSET*F_SZ(a1)
         j ra
-        nop
+        NOP
         .set at
 ENDFRAME(_CPU_Context_save_fp)
@@ -257,7 +273,8 @@
  */
 
-#if ( CPU_HARDWARE_FP == FALSE )
+#if ( CPU_HARDWARE_FP == TRUE )
 FRAME(_CPU_Context_restore_fp,sp,0,ra)
         .set noat
+        .set noreorder
 	
 	/* 
@@ -266,12 +283,30 @@
 	** integer task is switching out with a FP task switching in.
 	*/
-	
-	MFC0	t0,C0_SR	
-	li	k0,SR_CU1	
-	or	t0,k0
+	MFC0	t0,C0_SR
+	li	t2,SR_CU1	
+	move	t1,t0
+	or	t0,t2		/* turn on the fpu */
+#if __mips == 3
+	li	t2,SR_EXL | SR_IE
+#elif __mips == 1
+	li	t2,SR_IEC
+#endif
+	not	t2
+	and	t0,t2		/* turn off interrupts */	
 	MTC0	t0,C0_SR	
 
-	ld a1,(a0)
-	NOP
+	ld	a1,(a0)
+	move	t0,ra
+	jal	_CPU_Context_restore_fp_from_exception
+	NOP
+
+	/* 
+	** Reassert the old task's state because we've not restored the
+	** new one yet.
+	*/
+	MTC0	t1,C0_SR	
+	j	t0
+	NOP
+	
 	.globl _CPU_Context_restore_fp_from_exception
 _CPU_Context_restore_fp_from_exception:
@@ -309,5 +344,5 @@
         lwc1 $f31,FP31_OFFSET*4(a1)
         j ra
-        nop
+        NOP
         .set at
 ENDFRAME(_CPU_Context_restore_fp)
@@ -326,15 +361,19 @@
 
 FRAME(_CPU_Context_switch,sp,0,ra)
-
-        MFC0  t0,C0_SR
-        li    t1,~(SR_INTERRUPT_ENABLE_BITS)
-	STREG t0,C0_SR_OFFSET*R_SZ(a0)
-        and   t0,t1
+        .set noreorder
+
+        MFC0	t0,C0_SR
 #if __mips == 3
-        ori   t0,(SR_EXL|SR_IE)		/* enable exception level to disable interrupts */
-#endif
-        MTC0  t0,C0_SR
-
-        STREG ra,RA_OFFSET*R_SZ(a0)	/* save current context */
+	li	t1,SR_EXL | SR_IE
+#elif __mips == 1
+	li	t1,SR_IEC
+#endif
+	STREG	t0,C0_SR_OFFSET*R_SZ(a0)	/* save the task's SR */
+	not	t1
+        and	t0,t1				/* mask off interrupts while we context switch */
+        MTC0	t0,C0_SR
+	NOP
+
+        STREG ra,RA_OFFSET*R_SZ(a0)		/* save current context */
         STREG sp,SP_OFFSET*R_SZ(a0)
         STREG fp,FP_OFFSET*R_SZ(a0)
@@ -348,12 +387,7 @@
         STREG s7,S7_OFFSET*R_SZ(a0)
 
-	/*  EPC is readonly...
-        MFC0  t0,C0_EPC
-	NOP
-        STREG t0,C0_EPC_OFFSET*R_SZ(a0)
-	*/
 
 _CPU_Context_switch_restore:
-        LDREG ra,RA_OFFSET*R_SZ(a1)	    /* restore context */
+	LDREG ra,RA_OFFSET*R_SZ(a1)		/* restore context */
         LDREG sp,SP_OFFSET*R_SZ(a1)
         LDREG fp,FP_OFFSET*R_SZ(a1)
@@ -366,10 +400,4 @@
         LDREG s6,S6_OFFSET*R_SZ(a1)
         LDREG s7,S7_OFFSET*R_SZ(a1)
-
-	/*  EPC is readonly...
-        LDREG t0,C0_EPC_OFFSET*R_SZ(a1)
-	NOP
-        MTC0  t0,C0_EPC
-	*/
 
         LDREG t0, C0_SR_OFFSET*R_SZ(a1)
@@ -395,7 +423,7 @@
 //	  NOP
 
-	
+
 /*
-** Incorporate the new thread's FP coprocessor state and interrupt mask/enable
+** Incorporate the new task's FP coprocessor state and interrupt mask/enable
 ** into the status register.  We jump thru the requisite hoops to ensure we 
 ** maintain all other SR bits as global values.
@@ -405,28 +433,43 @@
 ** Interrupt Level & int level manipulation functions cannot enable/disable them, 
 ** so they are automatically enabled for all tasks.  To turn them off, a thread  
-** must itself manipulate the SR register.
+** must itself manipulate the SR register.  
+**
+** Although something of a hack on this processor, we treat the SR register
+** int enables as the RTEMS interrupt level.  We use the int level
+** value as a bitmask, not as any sort of greater than/less than metric.
+** Manipulation of a task's interrupt level directly corresponds to manipulation
+** of that task's SR bits, as seen in cpu.c
+**
+** Note, interrupts are disabled before context is saved, though the thread's
+** interrupt enable state is recorded.  The task swapping in will apply its
+** specific SR bits, including interrupt enable.  If further task-specific
+** SR bits are arranged, it is this code, the cpu.c interrupt level stuff and
+** cpu.h task initialization code that will be affected.  
 */
 
+	li	t2,SR_CU1
+	or	t2,SR_IMASK
+
+	/* int enable bits */
 #if __mips == 3
-	li	k0,(SR_CU1 | SR_IMASK | SR_EXL | SR_IE)
+	or	t2,SR_EXL + SR_IE
 #elif __mips == 1
-	li	k0,(SR_CU1 | SR_IMASK | SR_IEC)
-#endif
-	and	t0,k0		
+	or	t2,SR_IEC + SR_IEP	/* save current & previous int enable */
+#endif
+	and	t0,t2		/* keep only the per-task bits */
 		
 	MFC0	t1,C0_SR	/* grab the current SR */
-	not	k0		/* invert k0 so we can clear out the SR bits */
-	and	t1,k0
-
-	or	t0,t1		/* setup the new task's SR value */
-
-        MTC0	t0,C0_SR	/* and load the new SR */
+	not	t2		
+	and	t1,t2		/* mask off the old task's bits */
+	or	t1,t0		/* or in the new task's bits */
+        MTC0	t1,C0_SR	/* and load the new SR */
 	NOP
 	
 /* _CPU_Context_1: */
-        j ra
+        j	ra
         NOP
 ENDFRAME(_CPU_Context_switch)
 
+	
 /*
  *  _CPU_Context_restore
@@ -443,9 +486,12 @@
 
 FRAME(_CPU_Context_restore,sp,0,ra)
-        ADD a1,a0,zero
-        j   _CPU_Context_switch_restore
-        NOP
+        .set noreorder
+        move	a1,a0
+        j	_CPU_Context_switch_restore
+        NOP
+
 ENDFRAME(_CPU_Context_restore)
 
+	
 ASM_EXTERN(_ISR_Nest_level, SZ_INT)
 ASM_EXTERN(_Thread_Dispatch_disable_level,SZ_INT)
@@ -453,4 +499,5 @@
 ASM_EXTERN(_ISR_Signals_to_thread_executing,SZ_INT)
 ASM_EXTERN(_Thread_Executing,SZ_INT)
+	
 .extern _Thread_Dispatch
 .extern _ISR_Vector_table
@@ -527,5 +574,5 @@
 #ifdef INSTRUMENT_EXECUTING_THREAD
 	lw t2, _Thread_Executing
-	nop
+	NOP
 	sw t2, 0x8001FFF0
 #endif
@@ -541,4 +588,9 @@
 _ISR_Handler_Exception:
 
+	/*
+	sw	k0,0x8001FF00
+	sw	t1,0x8001FF04
+	*/
+	
 	/*  If we return from the exception, it is assumed nothing
          *  bad is going on and we can continue to run normally.
@@ -548,4 +600,7 @@
          *  NOTE: This is the path the debugger stub will take.
          */
+
+	/* already got k0 = cause in the interrupt test above */
+        STREG    k0,R_CAUSE*R_SZ(sp)
 
         STREG    sp,SP_OFFSET*R_SZ(sp)     /* save sp */
@@ -560,24 +615,22 @@
         STREG    s7,S7_OFFSET*R_SZ(sp)
 
-        MFC0     k0,C0_CAUSE               /* save cause */
-	NOP
-        STREG    k0,R_CAUSE*R_SZ(sp)
-
         /* CP0 special registers */
 
-        MFC0     t0,C0_BADVADDR
-        nop
-        STREG    t0,R_BADVADDR*R_SZ(sp)
-
+	MFC0	 t0,C0_TAR
+        MFC0     t1,C0_BADVADDR
+        STREG	 t0,R_TAR*R_SZ(sp)
+        STREG    t1,R_BADVADDR*R_SZ(sp)
+	
 #if ( CPU_HARDWARE_FP == TRUE )
         MFC0     t0,C0_SR                 /* FPU is enabled, save state */
+	NOP
         srl      t0,t0,16
         andi     t0,t0,(SR_CU1 >> 16)
         beqz     t0, 1f
-        nop
+        NOP
         
         la       a1,R_F0*R_SZ(sp)
         jal      _CPU_Context_save_fp_from_exception 
-        nop
+        NOP
         MFC1     t0,C1_REVISION
         MFC1     t1,C1_STATUS
@@ -587,18 +640,53 @@
 1:      
 #endif
+	
 	move	 a0,sp
         jal	 mips_vector_exceptions
-	nop
-
+	NOP
+
+	/* since we're returning, compute the address of the instruction we'll return to */
+
+	LDREG	t1, R_CAUSE*R_SZ(sp)
+	LDREG	t0, R_EPC*R_SZ(sp)
+
+	/* first see if the exception happened in the delay slot */
+	li	t3,CAUSE_BD
+	AND	t4,t1,t3
+	beqz	t4,excnodelay
+	NOP
+	
+	/* it did, now see if the branch occured or not */
+	li	t3,CAUSE_BT
+	AND	t4,t1,t3
+	beqz	t4,excnobranch
+	NOP
+	
+	/* branch was taken, we resume at the branch target */
+	LDREG	t0, R_TAR*R_SZ(sp)
+	j	excreturn
+	NOP
+
+excnobranch:
+	ADDU	t0,R_SZ
+
+excnodelay:	
+	ADDU	t0,R_SZ
+		
+excreturn:	
+	STREG	t0, R_EPC*R_SZ(sp)
+	NOP
+	
+	
 #if ( CPU_HARDWARE_FP == TRUE )
         MFC0     t0,C0_SR               /* FPU is enabled, restore state */
+	NOP
         srl      t0,t0,16
         andi     t0,t0,(SR_CU1 >> 16)
         beqz     t0, 2f
-        nop
+        NOP
         
         la       a1,R_F0*R_SZ(sp)
         jal      _CPU_Context_restore_fp_from_exception
-        nop
+        NOP
         LDREG    t0,R_FEIR*R_SZ(sp)
         LDREG    t1,R_FCSR*R_SZ(sp)
@@ -620,5 +708,5 @@
 
 	j	 _ISR_Handler_exit
-	nop
+	NOP
 
 _ISR_Handler_1:
@@ -634,5 +722,4 @@
 	beq      k0,zero,_ISR_Handler_exit
 
-	
 	
 	
@@ -669,5 +756,5 @@
 	
 #ifdef INSTRUMENT_ISR_VECTORING
-	nop
+	NOP
 	li	t1, 1
 	sw	t1, 0x8001e000
@@ -676,10 +763,10 @@
 	move	 a0,sp
         jal      mips_vector_isr_handlers
-        nop
+        NOP
 	
 #ifdef INSTRUMENT_ISR_VECTORING
 	li	t1, 0
 	sw	t1, 0x8001e000
-	nop
+	NOP
 #endif
 		
@@ -704,5 +791,5 @@
         or  t0,t2,t1
         bne t0,zero,_ISR_Handler_exit
-        nop
+        NOP
 
 
@@ -726,5 +813,5 @@
         or    t0,t0,t1
         beq   t0,zero,_ISR_Handler_exit
-        nop
+        NOP
 
 	
@@ -732,5 +819,5 @@
 #ifdef INSTRUMENT_EXECUTING_THREAD
 	lw	t0,_Thread_Executing
-	nop
+	NOP
 	sw	t0,0x8001FFF4
 #endif
@@ -744,15 +831,34 @@
 
         MFC0    t0, C0_SR
-	NOP
-	or	t0, SR_INTERRUPT_ENABLE_BITS
+#if __mips == 3
+	li	t1,SR_EXL | SR_IE
+#elif __mips == 1
+	li	t1,SR_IEC
+#endif
+	or	t0, t1
         MTC0    t0, C0_SR
 	NOP
-		
+			
         jal     _Thread_Dispatch
         NOP
 
+/* 
+** turn interrupts back off while we restore context so
+** a badly timed interrupt won't accidentally mess up k0
+*/
+        MFC0    t0, C0_SR
+#if __mips == 3
+	li	t1,SR_EXL | SR_IE
+#elif __mips == 1
+	li	t1,SR_IEC | SR_KUC	/* ints off, kernel mode on (kernel mode enabled is bit clear..argh!) */
+#endif
+	not	t1
+	and	t0, t1
+        MTC0    t0, C0_SR
+	NOP
+	
 #ifdef INSTRUMENT_EXECUTING_THREAD
 	lw	t0,_Thread_Executing
-	nop
+	NOP
 	sw	t0,0x8001FFF8
 #endif
@@ -772,13 +878,12 @@
 ** Skip the SR restore because its a global register. _CPU_Context_switch_restore
 ** adjusts it according to each task's configuration.  If we didn't dispatch, the
-** SR value isn't changing, so all we need to do is return.
+** SR value isn't changed, so all we need to do is return.
 **
 */
-
 	/* restore context from stack */
 	
 #ifdef INSTRUMENT_EXECUTING_THREAD
 	lw	t0,_Thread_Executing
-	nop
+	NOP
 	sw	t0, 0x8001FFFC
 #endif
@@ -817,18 +922,18 @@
 	j         k0
 	rfe
-        nop
+        NOP
 
        .set    reorder
 ENDFRAME(_ISR_Handler)
 
-	
+
+	
+		
 FRAME(mips_break,sp,0,ra)
-#if 1
-        break 0x0 
-        j mips_break
-#else
-        j ra
-#endif
-        nop
+        .set noreorder
+	break	0x0
+        j	ra
+        NOP
+       .set    reorder
 ENDFRAME(mips_break)
 
Index: c/src/exec/score/cpu/mips/idtcpu.h
===================================================================
--- c/src/exec/score/cpu/mips/idtcpu.h	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ c/src/exec/score/cpu/mips/idtcpu.h	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -363,4 +363,5 @@
  */
 #define	CAUSE_BD	0x80000000	/* Branch delay slot */
+#define	CAUSE_BT	0x40000000	/* Branch Taken */
 #define	CAUSE_CEMASK	0x30000000	/* coprocessor error */
 #define	CAUSE_CESHIFT	28
@@ -392,4 +393,8 @@
 #define C0_PAGEMASK	$5		/* tlb page mask */
 #define C0_WIRED	$6		/* number of wired tlb entries */
+#endif
+
+#if  __mips == 1
+#define C0_TAR          $6
 #endif
 
Index: c/src/exec/score/cpu/mips/iregdef.h
===================================================================
--- c/src/exec/score/cpu/mips/iregdef.h	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ c/src/exec/score/cpu/mips/iregdef.h	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -226,10 +226,12 @@
 #define R_FEIR		71
 #define	R_TLBHI		72
+
 #if __mips == 1
 #define	R_TLBLO		73
 #endif
 #if  __mips == 3
-#define	R_TLBLO0	74
-#endif
+#define	R_TLBLO0	73
+#endif
+
 #define	R_INX		74
 #define	R_RAND		75
@@ -238,25 +240,26 @@
 #define R_MODE		78
 #define	R_PRID		79
+#define R_TAR           80
 #if __mips == 1
-#define NREGS		80
+#define NREGS		81
 #endif
 #if  __mips == 3
-#define	R_TLBLO1	80
-#define R_PAGEMASK	81
-#define R_WIRED		82
-#define R_COUNT		83
-#define R_COMPARE	84
-#define R_CONFIG	85
-#define R_LLADDR	86
-#define R_WATCHLO	87
-#define R_WATCHHI	88
-#define R_ECC		89
-#define R_CACHEERR	90
-#define R_TAGLO		91
-#define R_TAGHI		92
-#define R_ERRPC		93
-#define R_XCTXT         94  /* Ketan added from SIM64bit */
-
-#define	NREGS		95
+#define	R_TLBLO1	81
+#define R_PAGEMASK	82
+#define R_WIRED		83
+#define R_COUNT		84
+#define R_COMPARE	85
+#define R_CONFIG	86
+#define R_LLADDR	87
+#define R_WATCHLO	88
+#define R_WATCHHI	89
+#define R_ECC		90
+#define R_CACHEERR	91
+#define R_TAGLO		92
+#define R_TAGHI		93
+#define R_ERRPC		94
+#define R_XCTXT         95  /* Ketan added from SIM64bit */
+
+#define	NREGS		96
 #endif
 
Index: c/src/exec/score/cpu/mips/rtems/score/cpu.h
===================================================================
--- c/src/exec/score/cpu/mips/rtems/score/cpu.h	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ c/src/exec/score/cpu/mips/rtems/score/cpu.h	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -315,5 +315,5 @@
  */
 
-#define CPU_MODES_INTERRUPT_MASK   0x00000001
+#define CPU_MODES_INTERRUPT_MASK   0x000000ff
 
 /*
@@ -360,4 +360,6 @@
  *  a debugger such as gdb.  But that is another problem.
  */
+
+#ifndef ASSEMBLY_ONLY
 
 /* WARNING: If this structure is modified, the constants in cpu.h must be updated. */
@@ -596,4 +598,5 @@
 }   rtems_cpu_table;
 
+
 /*
  *  Macros to access required entires in the CPU Table are in
@@ -648,4 +651,6 @@
  */
 
+
+
 /*
  *  Nothing prevents the porter from declaring more CPU specific variables.
@@ -686,4 +691,5 @@
 
 #define CPU_STACK_MINIMUM_SIZE          (2048*sizeof(unsigned32))
+
 
 /*
@@ -846,7 +852,9 @@
 #if __mips == 3
 #define _INTON	(SR_EXL | SR_IE)
+#define _EXTRABITS      0
 #endif
 #if __mips == 1
-#define _INTON  SR_IEC
+#define _INTON          SR_IEC
+#define _EXTRABITS      0  /* make sure we're in user mode on MIPS1 processors */
 #endif
 
@@ -863,5 +871,5 @@
 						       0x300 | \
 						       ((_intlvl & 1)?_INTON:0)) ) | \
-				SR_CU0 | ((_is_fp)?SR_CU1:0); \
+				SR_CU0 | ((_is_fp)?SR_CU1:0) | _EXTRABITS; \
   }
 
@@ -1179,4 +1187,9 @@
   (((value&0xff) << 8) | ((value >> 8)&0xff))
 
+
+#endif
+
+
+
 #ifdef __cplusplus
 }
Index: cpukit/score/cpu/mips/ChangeLog
===================================================================
--- cpukit/score/cpu/mips/ChangeLog	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ cpukit/score/cpu/mips/ChangeLog	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -1,2 +1,18 @@
+2002-02-27	Greg Menke <gregory.menke@gsfc.nasa.gov>
+
+	* cpu_asm.S: Fixed exception return address, modified FP context
+	switch so FPU is properly enabled and also doesn't screw up the
+	exception FP handling.
+	* idtcpu.h: Added C0_TAR, the MIPS target address register used for 
+	returning from exceptions.
+	* iregdef.h: Added R_TAR to the stack frame so the target address
+	can be saved on a per-exception basis.  The new entry is past the
+	end of the frame gdb cares about, so doesn't affect gdb or cpu.h
+	stuff.
+	* rtems/score/cpu.h: added an #ifdef so cpu_asm.S can include it
+	to obtain FPU defines without systax errors generated by the C
+	defintions.
+	* cpu.c: Improved interrupt level saves & restores.
+	
 2002-02-08	Joel Sherrill <joel@OARcorp.com>
 
Index: cpukit/score/cpu/mips/cpu.c
===================================================================
--- cpukit/score/cpu/mips/cpu.c	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ cpukit/score/cpu/mips/cpu.c	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -1,4 +1,10 @@
 /*
  *  Mips CPU Dependent Source
+ *
+ *  2002:       Greg Menke (gregory.menke@gsfc.nasa.gov)
+ *      Overhauled interrupt level and interrupt enable/disable code
+ *      to more exactly support MIPS.  Our mods were for MIPS1 processors
+ *      MIPS3 ports are affected, though apps written to the old behavior
+ *      should still work OK.
  *
  *  Conversion to MIPS port by Alan Cudmore <alanc@linuxstart.com> and
@@ -75,5 +81,5 @@
  *  This routine returns the current interrupt level.
  */
-   
+
 unsigned32 _CPU_ISR_Get_level( void )
 {
@@ -81,16 +87,20 @@
 
   mips_get_sr(sr);
+
+  //printf("current sr=%08X, ",sr);
 
 #if __mips == 3
 /* EXL bit and shift down hardware ints into bits 1 thru 6 */
-  return ((sr & SR_EXL) >> 1) + ((sr & 0xfc00) >> 9);
+  sr = ((sr & SR_EXL) >> 1) | ((sr & 0xfc00) >> 9);
 
 #elif __mips == 1
 /* IEC bit and shift down hardware ints into bits 1 thru 6 */
-  return (sr & SR_IEC) + ((sr & 0xfc00) >> 9);
+  sr = (sr & SR_IEC) | ((sr & 0xfc00) >> 9);
 
 #else
 #error "CPU ISR level: unknown MIPS level for SR handling"
 #endif
+  //printf("intlevel=%02X\n",sr);
+  return sr;
 }
 
@@ -109,14 +119,15 @@
   */
 
+  new_level &= 0xff;
 
   mips_get_sr(sr);
 
 #if __mips == 3
-  mips_set_sr(sr & ~SR_IE);                 /* first disable ie bit (recommended) */
+  mips_set_sr( (sr & ~SR_IE) );                 /* first disable ie bit (recommended) */
 
   srbits = sr & ~(0xfc00 | SR_EXL | SR_IE);
 
   sr = srbits | ((new_level==0)? (0xfc00 | SR_EXL | SR_IE): \
-		 (((new_level<<9) & 0xfc000) | \
+		 (((new_level<<9) & 0xfc00) | \
 		  (new_level & 1)?(SR_EXL | SR_IE):0));
 /*
@@ -135,8 +146,10 @@
  
 #elif __mips == 1
-  mips_set_sr( (sr & ~SR_IEC) );	
-
+  mips_set_sr( (sr & ~SR_IEC) );
   srbits = sr & ~(0xfc00 | SR_IEC);
-  sr = srbits | ((new_level==0)?0xfc01:( ((new_level<<9) & 0xfc000) | (new_level & 1)));
+  //printf("current sr=%08X, newlevel=%02X, srbits=%08X, ",sr,new_level,srbits);
+  sr = srbits | ((new_level==0)?0xfc01:( ((new_level<<9) & 0xfc00) | \
+                                         (new_level & SR_IEC)));
+  //printf("new sr=%08X\n",sr);
 #else
 #error "CPU ISR level: unknown MIPS level for SR handling"
@@ -144,4 +157,6 @@
   mips_set_sr( sr );
 }
+
+
 
 /*PAGE
Index: cpukit/score/cpu/mips/cpu_asm.S
===================================================================
--- cpukit/score/cpu/mips/cpu_asm.S	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ cpukit/score/cpu/mips/cpu_asm.S	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -48,4 +48,8 @@
 #include "idtcpu.h"
 
+#define ASSEMBLY_ONLY
+#include <rtems/score/cpu.h>
+
+		
 /* enable debugging shadow writes to misc ram, this is a vestigal
 * Mongoose-ism debug tool- but may be handy in the future so we
@@ -54,5 +58,5 @@
 
 #define INSTRUMENT_ISR_VECTORING
-//#define INSTRUMENT_EXECUTING_THREAD
+/* #define INSTRUMENT_EXECUTING_THREAD */
 
 
@@ -176,27 +180,39 @@
  */
 
-#if ( CPU_HARDWARE_FP == FALSE )
+#if ( CPU_HARDWARE_FP == TRUE )
 FRAME(_CPU_Context_save_fp,sp,0,ra)
+        .set noreorder
         .set noat
 
-#if ( CPU_USE_DEFERRED_FP_SWITCH == TRUE )
 	/* 
-	** Make sure the FPU is on before we save state.  This code is here
-	** because the FPU context switch might occur when an integer
-	** task is switching out w/ an FP task switching in, but the current 
-	** FPU state was left by a sometime previously scheduled FP task.
-	**
-	** In non-deferred FP context switch, if the exiting task is FP, then
-	** the FPU is already on so we don't need to do this.
+	** Make sure the FPU is on before we save state.  This code 
+	** is here because the FPU context switch might occur when an 
+	** integer task is switching out with a FP task switching in.
 	*/
-	
-	MFC0	t0,C0_SR	
-	li	k0,SR_CU1	
-	or	t0,k0
+	MFC0	t0,C0_SR
+	li	t2,SR_CU1	
+	move	t1,t0
+	or	t0,t2		/* turn on the fpu */
+#if __mips == 3
+	li	t2,SR_EXL | SR_IE
+#elif __mips == 1
+	li	t2,SR_IEC
+#endif
+	not	t2
+	and	t0,t2		/* turn off interrupts */	
 	MTC0	t0,C0_SR	
-#endif
 		
-	ld   a1,(a0)
-	NOP
+	ld	a1,(a0)
+	move	t0,ra
+	jal	_CPU_Context_save_fp_from_exception
+	NOP
+	
+	/* 
+	** Reassert the task's state because we've not saved it yet.
+	*/
+	MTC0	t1,C0_SR	
+	j	t0	
+	NOP
+	
 	.globl _CPU_Context_save_fp_from_exception
 _CPU_Context_save_fp_from_exception:
@@ -234,5 +250,5 @@
         swc1 $f31,FP31_OFFSET*F_SZ(a1)
         j ra
-        nop
+        NOP
         .set at
 ENDFRAME(_CPU_Context_save_fp)
@@ -257,7 +273,8 @@
  */
 
-#if ( CPU_HARDWARE_FP == FALSE )
+#if ( CPU_HARDWARE_FP == TRUE )
 FRAME(_CPU_Context_restore_fp,sp,0,ra)
         .set noat
+        .set noreorder
 	
 	/* 
@@ -266,12 +283,30 @@
 	** integer task is switching out with a FP task switching in.
 	*/
-	
-	MFC0	t0,C0_SR	
-	li	k0,SR_CU1	
-	or	t0,k0
+	MFC0	t0,C0_SR
+	li	t2,SR_CU1	
+	move	t1,t0
+	or	t0,t2		/* turn on the fpu */
+#if __mips == 3
+	li	t2,SR_EXL | SR_IE
+#elif __mips == 1
+	li	t2,SR_IEC
+#endif
+	not	t2
+	and	t0,t2		/* turn off interrupts */	
 	MTC0	t0,C0_SR	
 
-	ld a1,(a0)
-	NOP
+	ld	a1,(a0)
+	move	t0,ra
+	jal	_CPU_Context_restore_fp_from_exception
+	NOP
+
+	/* 
+	** Reassert the old task's state because we've not restored the
+	** new one yet.
+	*/
+	MTC0	t1,C0_SR	
+	j	t0
+	NOP
+	
 	.globl _CPU_Context_restore_fp_from_exception
 _CPU_Context_restore_fp_from_exception:
@@ -309,5 +344,5 @@
         lwc1 $f31,FP31_OFFSET*4(a1)
         j ra
-        nop
+        NOP
         .set at
 ENDFRAME(_CPU_Context_restore_fp)
@@ -326,15 +361,19 @@
 
 FRAME(_CPU_Context_switch,sp,0,ra)
-
-        MFC0  t0,C0_SR
-        li    t1,~(SR_INTERRUPT_ENABLE_BITS)
-	STREG t0,C0_SR_OFFSET*R_SZ(a0)
-        and   t0,t1
+        .set noreorder
+
+        MFC0	t0,C0_SR
 #if __mips == 3
-        ori   t0,(SR_EXL|SR_IE)		/* enable exception level to disable interrupts */
-#endif
-        MTC0  t0,C0_SR
-
-        STREG ra,RA_OFFSET*R_SZ(a0)	/* save current context */
+	li	t1,SR_EXL | SR_IE
+#elif __mips == 1
+	li	t1,SR_IEC
+#endif
+	STREG	t0,C0_SR_OFFSET*R_SZ(a0)	/* save the task's SR */
+	not	t1
+        and	t0,t1				/* mask off interrupts while we context switch */
+        MTC0	t0,C0_SR
+	NOP
+
+        STREG ra,RA_OFFSET*R_SZ(a0)		/* save current context */
         STREG sp,SP_OFFSET*R_SZ(a0)
         STREG fp,FP_OFFSET*R_SZ(a0)
@@ -348,12 +387,7 @@
         STREG s7,S7_OFFSET*R_SZ(a0)
 
-	/*  EPC is readonly...
-        MFC0  t0,C0_EPC
-	NOP
-        STREG t0,C0_EPC_OFFSET*R_SZ(a0)
-	*/
 
 _CPU_Context_switch_restore:
-        LDREG ra,RA_OFFSET*R_SZ(a1)	    /* restore context */
+	LDREG ra,RA_OFFSET*R_SZ(a1)		/* restore context */
         LDREG sp,SP_OFFSET*R_SZ(a1)
         LDREG fp,FP_OFFSET*R_SZ(a1)
@@ -366,10 +400,4 @@
         LDREG s6,S6_OFFSET*R_SZ(a1)
         LDREG s7,S7_OFFSET*R_SZ(a1)
-
-	/*  EPC is readonly...
-        LDREG t0,C0_EPC_OFFSET*R_SZ(a1)
-	NOP
-        MTC0  t0,C0_EPC
-	*/
 
         LDREG t0, C0_SR_OFFSET*R_SZ(a1)
@@ -395,7 +423,7 @@
 //	  NOP
 
-	
+
 /*
-** Incorporate the new thread's FP coprocessor state and interrupt mask/enable
+** Incorporate the new task's FP coprocessor state and interrupt mask/enable
 ** into the status register.  We jump thru the requisite hoops to ensure we 
 ** maintain all other SR bits as global values.
@@ -405,28 +433,43 @@
 ** Interrupt Level & int level manipulation functions cannot enable/disable them, 
 ** so they are automatically enabled for all tasks.  To turn them off, a thread  
-** must itself manipulate the SR register.
+** must itself manipulate the SR register.  
+**
+** Although something of a hack on this processor, we treat the SR register
+** int enables as the RTEMS interrupt level.  We use the int level
+** value as a bitmask, not as any sort of greater than/less than metric.
+** Manipulation of a task's interrupt level directly corresponds to manipulation
+** of that task's SR bits, as seen in cpu.c
+**
+** Note, interrupts are disabled before context is saved, though the thread's
+** interrupt enable state is recorded.  The task swapping in will apply its
+** specific SR bits, including interrupt enable.  If further task-specific
+** SR bits are arranged, it is this code, the cpu.c interrupt level stuff and
+** cpu.h task initialization code that will be affected.  
 */
 
+	li	t2,SR_CU1
+	or	t2,SR_IMASK
+
+	/* int enable bits */
 #if __mips == 3
-	li	k0,(SR_CU1 | SR_IMASK | SR_EXL | SR_IE)
+	or	t2,SR_EXL + SR_IE
 #elif __mips == 1
-	li	k0,(SR_CU1 | SR_IMASK | SR_IEC)
-#endif
-	and	t0,k0		
+	or	t2,SR_IEC + SR_IEP	/* save current & previous int enable */
+#endif
+	and	t0,t2		/* keep only the per-task bits */
 		
 	MFC0	t1,C0_SR	/* grab the current SR */
-	not	k0		/* invert k0 so we can clear out the SR bits */
-	and	t1,k0
-
-	or	t0,t1		/* setup the new task's SR value */
-
-        MTC0	t0,C0_SR	/* and load the new SR */
+	not	t2		
+	and	t1,t2		/* mask off the old task's bits */
+	or	t1,t0		/* or in the new task's bits */
+        MTC0	t1,C0_SR	/* and load the new SR */
 	NOP
 	
 /* _CPU_Context_1: */
-        j ra
+        j	ra
         NOP
 ENDFRAME(_CPU_Context_switch)
 
+	
 /*
  *  _CPU_Context_restore
@@ -443,9 +486,12 @@
 
 FRAME(_CPU_Context_restore,sp,0,ra)
-        ADD a1,a0,zero
-        j   _CPU_Context_switch_restore
-        NOP
+        .set noreorder
+        move	a1,a0
+        j	_CPU_Context_switch_restore
+        NOP
+
 ENDFRAME(_CPU_Context_restore)
 
+	
 ASM_EXTERN(_ISR_Nest_level, SZ_INT)
 ASM_EXTERN(_Thread_Dispatch_disable_level,SZ_INT)
@@ -453,4 +499,5 @@
 ASM_EXTERN(_ISR_Signals_to_thread_executing,SZ_INT)
 ASM_EXTERN(_Thread_Executing,SZ_INT)
+	
 .extern _Thread_Dispatch
 .extern _ISR_Vector_table
@@ -527,5 +574,5 @@
 #ifdef INSTRUMENT_EXECUTING_THREAD
 	lw t2, _Thread_Executing
-	nop
+	NOP
 	sw t2, 0x8001FFF0
 #endif
@@ -541,4 +588,9 @@
 _ISR_Handler_Exception:
 
+	/*
+	sw	k0,0x8001FF00
+	sw	t1,0x8001FF04
+	*/
+	
 	/*  If we return from the exception, it is assumed nothing
          *  bad is going on and we can continue to run normally.
@@ -548,4 +600,7 @@
          *  NOTE: This is the path the debugger stub will take.
          */
+
+	/* already got k0 = cause in the interrupt test above */
+        STREG    k0,R_CAUSE*R_SZ(sp)
 
         STREG    sp,SP_OFFSET*R_SZ(sp)     /* save sp */
@@ -560,24 +615,22 @@
         STREG    s7,S7_OFFSET*R_SZ(sp)
 
-        MFC0     k0,C0_CAUSE               /* save cause */
-	NOP
-        STREG    k0,R_CAUSE*R_SZ(sp)
-
         /* CP0 special registers */
 
-        MFC0     t0,C0_BADVADDR
-        nop
-        STREG    t0,R_BADVADDR*R_SZ(sp)
-
+	MFC0	 t0,C0_TAR
+        MFC0     t1,C0_BADVADDR
+        STREG	 t0,R_TAR*R_SZ(sp)
+        STREG    t1,R_BADVADDR*R_SZ(sp)
+	
 #if ( CPU_HARDWARE_FP == TRUE )
         MFC0     t0,C0_SR                 /* FPU is enabled, save state */
+	NOP
         srl      t0,t0,16
         andi     t0,t0,(SR_CU1 >> 16)
         beqz     t0, 1f
-        nop
+        NOP
         
         la       a1,R_F0*R_SZ(sp)
         jal      _CPU_Context_save_fp_from_exception 
-        nop
+        NOP
         MFC1     t0,C1_REVISION
         MFC1     t1,C1_STATUS
@@ -587,18 +640,53 @@
 1:      
 #endif
+	
 	move	 a0,sp
         jal	 mips_vector_exceptions
-	nop
-
+	NOP
+
+	/* since we're returning, compute the address of the instruction we'll return to */
+
+	LDREG	t1, R_CAUSE*R_SZ(sp)
+	LDREG	t0, R_EPC*R_SZ(sp)
+
+	/* first see if the exception happened in the delay slot */
+	li	t3,CAUSE_BD
+	AND	t4,t1,t3
+	beqz	t4,excnodelay
+	NOP
+	
+	/* it did, now see if the branch occured or not */
+	li	t3,CAUSE_BT
+	AND	t4,t1,t3
+	beqz	t4,excnobranch
+	NOP
+	
+	/* branch was taken, we resume at the branch target */
+	LDREG	t0, R_TAR*R_SZ(sp)
+	j	excreturn
+	NOP
+
+excnobranch:
+	ADDU	t0,R_SZ
+
+excnodelay:	
+	ADDU	t0,R_SZ
+		
+excreturn:	
+	STREG	t0, R_EPC*R_SZ(sp)
+	NOP
+	
+	
 #if ( CPU_HARDWARE_FP == TRUE )
         MFC0     t0,C0_SR               /* FPU is enabled, restore state */
+	NOP
         srl      t0,t0,16
         andi     t0,t0,(SR_CU1 >> 16)
         beqz     t0, 2f
-        nop
+        NOP
         
         la       a1,R_F0*R_SZ(sp)
         jal      _CPU_Context_restore_fp_from_exception
-        nop
+        NOP
         LDREG    t0,R_FEIR*R_SZ(sp)
         LDREG    t1,R_FCSR*R_SZ(sp)
@@ -620,5 +708,5 @@
 
 	j	 _ISR_Handler_exit
-	nop
+	NOP
 
 _ISR_Handler_1:
@@ -634,5 +722,4 @@
 	beq      k0,zero,_ISR_Handler_exit
 
-	
 	
 	
@@ -669,5 +756,5 @@
 	
 #ifdef INSTRUMENT_ISR_VECTORING
-	nop
+	NOP
 	li	t1, 1
 	sw	t1, 0x8001e000
@@ -676,10 +763,10 @@
 	move	 a0,sp
         jal      mips_vector_isr_handlers
-        nop
+        NOP
 	
 #ifdef INSTRUMENT_ISR_VECTORING
 	li	t1, 0
 	sw	t1, 0x8001e000
-	nop
+	NOP
 #endif
 		
@@ -704,5 +791,5 @@
         or  t0,t2,t1
         bne t0,zero,_ISR_Handler_exit
-        nop
+        NOP
 
 
@@ -726,5 +813,5 @@
         or    t0,t0,t1
         beq   t0,zero,_ISR_Handler_exit
-        nop
+        NOP
 
 	
@@ -732,5 +819,5 @@
 #ifdef INSTRUMENT_EXECUTING_THREAD
 	lw	t0,_Thread_Executing
-	nop
+	NOP
 	sw	t0,0x8001FFF4
 #endif
@@ -744,15 +831,34 @@
 
         MFC0    t0, C0_SR
-	NOP
-	or	t0, SR_INTERRUPT_ENABLE_BITS
+#if __mips == 3
+	li	t1,SR_EXL | SR_IE
+#elif __mips == 1
+	li	t1,SR_IEC
+#endif
+	or	t0, t1
         MTC0    t0, C0_SR
 	NOP
-		
+			
         jal     _Thread_Dispatch
         NOP
 
+/* 
+** turn interrupts back off while we restore context so
+** a badly timed interrupt won't accidentally mess up k0
+*/
+        MFC0    t0, C0_SR
+#if __mips == 3
+	li	t1,SR_EXL | SR_IE
+#elif __mips == 1
+	li	t1,SR_IEC | SR_KUC	/* ints off, kernel mode on (kernel mode enabled is bit clear..argh!) */
+#endif
+	not	t1
+	and	t0, t1
+        MTC0    t0, C0_SR
+	NOP
+	
 #ifdef INSTRUMENT_EXECUTING_THREAD
 	lw	t0,_Thread_Executing
-	nop
+	NOP
 	sw	t0,0x8001FFF8
 #endif
@@ -772,13 +878,12 @@
 ** Skip the SR restore because its a global register. _CPU_Context_switch_restore
 ** adjusts it according to each task's configuration.  If we didn't dispatch, the
-** SR value isn't changing, so all we need to do is return.
+** SR value isn't changed, so all we need to do is return.
 **
 */
-
 	/* restore context from stack */
 	
 #ifdef INSTRUMENT_EXECUTING_THREAD
 	lw	t0,_Thread_Executing
-	nop
+	NOP
 	sw	t0, 0x8001FFFC
 #endif
@@ -817,18 +922,18 @@
 	j         k0
 	rfe
-        nop
+        NOP
 
        .set    reorder
 ENDFRAME(_ISR_Handler)
 
-	
+
+	
+		
 FRAME(mips_break,sp,0,ra)
-#if 1
-        break 0x0 
-        j mips_break
-#else
-        j ra
-#endif
-        nop
+        .set noreorder
+	break	0x0
+        j	ra
+        NOP
+       .set    reorder
 ENDFRAME(mips_break)
 
Index: cpukit/score/cpu/mips/idtcpu.h
===================================================================
--- cpukit/score/cpu/mips/idtcpu.h	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ cpukit/score/cpu/mips/idtcpu.h	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -363,4 +363,5 @@
  */
 #define	CAUSE_BD	0x80000000	/* Branch delay slot */
+#define	CAUSE_BT	0x40000000	/* Branch Taken */
 #define	CAUSE_CEMASK	0x30000000	/* coprocessor error */
 #define	CAUSE_CESHIFT	28
@@ -392,4 +393,8 @@
 #define C0_PAGEMASK	$5		/* tlb page mask */
 #define C0_WIRED	$6		/* number of wired tlb entries */
+#endif
+
+#if  __mips == 1
+#define C0_TAR          $6
 #endif
 
Index: cpukit/score/cpu/mips/iregdef.h
===================================================================
--- cpukit/score/cpu/mips/iregdef.h	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ cpukit/score/cpu/mips/iregdef.h	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -226,10 +226,12 @@
 #define R_FEIR		71
 #define	R_TLBHI		72
+
 #if __mips == 1
 #define	R_TLBLO		73
 #endif
 #if  __mips == 3
-#define	R_TLBLO0	74
-#endif
+#define	R_TLBLO0	73
+#endif
+
 #define	R_INX		74
 #define	R_RAND		75
@@ -238,25 +240,26 @@
 #define R_MODE		78
 #define	R_PRID		79
+#define R_TAR           80
 #if __mips == 1
-#define NREGS		80
+#define NREGS		81
 #endif
 #if  __mips == 3
-#define	R_TLBLO1	80
-#define R_PAGEMASK	81
-#define R_WIRED		82
-#define R_COUNT		83
-#define R_COMPARE	84
-#define R_CONFIG	85
-#define R_LLADDR	86
-#define R_WATCHLO	87
-#define R_WATCHHI	88
-#define R_ECC		89
-#define R_CACHEERR	90
-#define R_TAGLO		91
-#define R_TAGHI		92
-#define R_ERRPC		93
-#define R_XCTXT         94  /* Ketan added from SIM64bit */
-
-#define	NREGS		95
+#define	R_TLBLO1	81
+#define R_PAGEMASK	82
+#define R_WIRED		83
+#define R_COUNT		84
+#define R_COMPARE	85
+#define R_CONFIG	86
+#define R_LLADDR	87
+#define R_WATCHLO	88
+#define R_WATCHHI	89
+#define R_ECC		90
+#define R_CACHEERR	91
+#define R_TAGLO		92
+#define R_TAGHI		93
+#define R_ERRPC		94
+#define R_XCTXT         95  /* Ketan added from SIM64bit */
+
+#define	NREGS		96
 #endif
 
Index: cpukit/score/cpu/mips/rtems/mips/idtcpu.h
===================================================================
--- cpukit/score/cpu/mips/rtems/mips/idtcpu.h	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ cpukit/score/cpu/mips/rtems/mips/idtcpu.h	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -363,4 +363,5 @@
  */
 #define	CAUSE_BD	0x80000000	/* Branch delay slot */
+#define	CAUSE_BT	0x40000000	/* Branch Taken */
 #define	CAUSE_CEMASK	0x30000000	/* coprocessor error */
 #define	CAUSE_CESHIFT	28
@@ -392,4 +393,8 @@
 #define C0_PAGEMASK	$5		/* tlb page mask */
 #define C0_WIRED	$6		/* number of wired tlb entries */
+#endif
+
+#if  __mips == 1
+#define C0_TAR          $6
 #endif
 
Index: cpukit/score/cpu/mips/rtems/mips/iregdef.h
===================================================================
--- cpukit/score/cpu/mips/rtems/mips/iregdef.h	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ cpukit/score/cpu/mips/rtems/mips/iregdef.h	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -226,10 +226,12 @@
 #define R_FEIR		71
 #define	R_TLBHI		72
+
 #if __mips == 1
 #define	R_TLBLO		73
 #endif
 #if  __mips == 3
-#define	R_TLBLO0	74
-#endif
+#define	R_TLBLO0	73
+#endif
+
 #define	R_INX		74
 #define	R_RAND		75
@@ -238,25 +240,26 @@
 #define R_MODE		78
 #define	R_PRID		79
+#define R_TAR           80
 #if __mips == 1
-#define NREGS		80
+#define NREGS		81
 #endif
 #if  __mips == 3
-#define	R_TLBLO1	80
-#define R_PAGEMASK	81
-#define R_WIRED		82
-#define R_COUNT		83
-#define R_COMPARE	84
-#define R_CONFIG	85
-#define R_LLADDR	86
-#define R_WATCHLO	87
-#define R_WATCHHI	88
-#define R_ECC		89
-#define R_CACHEERR	90
-#define R_TAGLO		91
-#define R_TAGHI		92
-#define R_ERRPC		93
-#define R_XCTXT         94  /* Ketan added from SIM64bit */
-
-#define	NREGS		95
+#define	R_TLBLO1	81
+#define R_PAGEMASK	82
+#define R_WIRED		83
+#define R_COUNT		84
+#define R_COMPARE	85
+#define R_CONFIG	86
+#define R_LLADDR	87
+#define R_WATCHLO	88
+#define R_WATCHHI	89
+#define R_ECC		90
+#define R_CACHEERR	91
+#define R_TAGLO		92
+#define R_TAGHI		93
+#define R_ERRPC		94
+#define R_XCTXT         95  /* Ketan added from SIM64bit */
+
+#define	NREGS		96
 #endif
 
Index: cpukit/score/cpu/mips/rtems/score/cpu.h
===================================================================
--- cpukit/score/cpu/mips/rtems/score/cpu.h	(revision f9d1afc0569e0607fc0f444c55e8206a14b860a2)
+++ cpukit/score/cpu/mips/rtems/score/cpu.h	(revision bd1ecb00d955204b7c01daffe7e6e7cb8c8a765a)
@@ -315,5 +315,5 @@
  */
 
-#define CPU_MODES_INTERRUPT_MASK   0x00000001
+#define CPU_MODES_INTERRUPT_MASK   0x000000ff
 
 /*
@@ -360,4 +360,6 @@
  *  a debugger such as gdb.  But that is another problem.
  */
+
+#ifndef ASSEMBLY_ONLY
 
 /* WARNING: If this structure is modified, the constants in cpu.h must be updated. */
@@ -596,4 +598,5 @@
 }   rtems_cpu_table;
 
+
 /*
  *  Macros to access required entires in the CPU Table are in
@@ -648,4 +651,6 @@
  */
 
+
+
 /*
  *  Nothing prevents the porter from declaring more CPU specific variables.
@@ -686,4 +691,5 @@
 
 #define CPU_STACK_MINIMUM_SIZE          (2048*sizeof(unsigned32))
+
 
 /*
@@ -846,7 +852,9 @@
 #if __mips == 3
 #define _INTON	(SR_EXL | SR_IE)
+#define _EXTRABITS      0
 #endif
 #if __mips == 1
-#define _INTON  SR_IEC
+#define _INTON          SR_IEC
+#define _EXTRABITS      0  /* make sure we're in user mode on MIPS1 processors */
 #endif
 
@@ -863,5 +871,5 @@
 						       0x300 | \
 						       ((_intlvl & 1)?_INTON:0)) ) | \
-				SR_CU0 | ((_is_fp)?SR_CU1:0); \
+				SR_CU0 | ((_is_fp)?SR_CU1:0) | _EXTRABITS; \
   }
 
@@ -1179,4 +1187,9 @@
   (((value&0xff) << 8) | ((value >> 8)&0xff))
 
+
+#endif
+
+
+
 #ifdef __cplusplus
 }
