Skip to contentSkip to conversation

Fix CP0 LLAddr register

PATCH New Hervé Poussineau 1 participant 1 message Oct 6, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fix CP0 LLAddr register

Hi,

On MIPS R4000 CPU, LLAddr register is read-write, whereas on MIPS64 specification, it is read-only. Attached patch adds a new instruction flag (INSN_R4000), which is checked to know if register is writable.

Also, it changes the return format of the LLAddr register, which is defined as implementation-dependant in MIPS64, so it shouldn't hurt.

Hervé

helper.h +1 -0
Index: target-mips/helper.h
===================================================================
@@ -124,6 +124,7 @@
 DEF_HELPER(void, do_mtc0_ebase, (target_ulong t0))
 DEF_HELPER(void, do_mtc0_config0, (target_ulong t0))
 DEF_HELPER(void, do_mtc0_config2, (target_ulong t0))
+DEF_HELPER(void, do_mtc0_lladdr, (target_ulong t0))
 DEF_HELPER(void, do_mtc0_watchlo, (target_ulong t0, uint32_t sel))
 DEF_HELPER(void, do_mtc0_watchhi, (target_ulong t0, uint32_t sel))
 DEF_HELPER(void, do_mtc0_xcontext, (target_ulong t0))
mips-defs.h +3 -0
Index: target-mips/mips-defs.h
===================================================================
@@ -40,11 +40,14 @@
 
 /* Chip specific instructions. */
 #define		INSN_VR54XX	0x80000000
+#define		INSN_R4000	0x40000000
 
 /* MIPS CPU defines. */
 #define		CPU_MIPS1	(ISA_MIPS1)
 #define		CPU_MIPS2	(CPU_MIPS1 | ISA_MIPS2)
 #define		CPU_MIPS3	(CPU_MIPS2 | ISA_MIPS3)
+#define		CPU_R4000	(CPU_MIPS3 | INSN_R4000)
+
 #define		CPU_MIPS4	(CPU_MIPS3 | ISA_MIPS4)
 #define		CPU_VR54XX	(CPU_MIPS4 | INSN_VR54XX)
 
op_helper.c +6 -1
Index: target-mips/op_helper.c
===================================================================
@@ -762,7 +762,7 @@
 
 target_ulong do_mfc0_lladdr (void)
 {
-    return (int32_t)env->CP0_LLAddr >> 4;
+    return env->CP0_LLAddr;
 }
 
 target_ulong do_mfc0_watchlo (uint32_t sel)
@@ -1265,6 +1265,11 @@
     env->CP0_Config2 = (env->CP0_Config2 & 0x8FFF0FFF);
 }
 
+void do_mtc0_lladdr (target_ulong t0)
+{
+    env->CP0_LLAddr = t0;
+}
+
 void do_mtc0_watchlo (target_ulong t0, uint32_t sel)
 {
     /* Watch exceptions for instructions, data loads, data stores
translate.c +6 -2
Index: target-mips/translate.c
===================================================================
@@ -3780,7 +3780,9 @@
     case 17:
         switch (sel) {
         case 0:
-            /* ignored */
+            if (env->insn_flags & INSN_R4000)
+                tcg_gen_helper_0_1(do_mtc0_lladdr, t0);
+            /* else ignored */
             rn = "LLAddr";
             break;
         default:
@@ -4955,7 +4957,9 @@
     case 17:
         switch (sel) {
         case 0:
-            /* ignored */
+            if (env->insn_flags & INSN_R4000)
+                tcg_gen_helper_0_1(do_mtc0_lladdr, t0);
+            /* else ignored */
             rn = "LLAddr";
             break;
         default:
translate_init.c +1 -1
Index: target-mips/translate_init.c
===================================================================
@@ -302,7 +302,7 @@
         .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
         .SEGBITS = 40,
         .PABITS = 36,
-        .insn_flags = CPU_MIPS3,
+        .insn_flags = CPU_R4000,
         .mmu_type = MMU_TYPE_R4000,
     },
     {