]> git.proxmox.com Git - qemu.git/blobdiff - target-mips/helper.c
target-mips: split code raising MMU exception in a separate function
[qemu.git] / target-mips / helper.c
index 4a372777c75bb9a1b7a0ac5bd72c61f577e1ed1c..0b5ec3e566a1e78de4cc680311c5e6d95182d8ff 100644 (file)
@@ -201,6 +201,58 @@ static int get_physical_address (CPUState *env, target_phys_addr_t *physical,
 }
 #endif
 
+static void raise_mmu_exception(CPUState *env, target_ulong address,
+                                int rw, int tlb_error)
+{
+    int exception = 0, error_code = 0;
+
+    switch (tlb_error) {
+    default:
+    case TLBRET_BADADDR:
+        /* Reference to kernel address from user mode or supervisor mode */
+        /* Reference to supervisor address from user mode */
+        if (rw)
+            exception = EXCP_AdES;
+        else
+            exception = EXCP_AdEL;
+        break;
+    case TLBRET_NOMATCH:
+        /* No TLB match for a mapped address */
+        if (rw)
+            exception = EXCP_TLBS;
+        else
+            exception = EXCP_TLBL;
+        error_code = 1;
+        break;
+    case TLBRET_INVALID:
+        /* TLB match with no valid bit */
+        if (rw)
+            exception = EXCP_TLBS;
+        else
+            exception = EXCP_TLBL;
+        break;
+    case TLBRET_DIRTY:
+        /* TLB match but 'D' bit is cleared */
+        exception = EXCP_LTLBL;
+        break;
+
+    }
+    /* Raise exception */
+    env->CP0_BadVAddr = address;
+    env->CP0_Context = (env->CP0_Context & ~0x007fffff) |
+                       ((address >> 9) & 0x007ffff0);
+    env->CP0_EntryHi =
+        (env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
+#if defined(TARGET_MIPS64)
+    env->CP0_EntryHi &= env->SEGMask;
+    env->CP0_XContext = (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) |
+                        ((address & 0xC00000000000ULL) >> (55 - env->SEGBITS)) |
+                        ((address & ((1ULL << env->SEGBITS) - 1) & 0xFFFFFFFFFFFFE000ULL) >> 9);
+#endif
+    env->exception_index = exception;
+    env->error_code = error_code;
+}
+
 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 {
 #if defined(CONFIG_USER_ONLY)
@@ -222,7 +274,6 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
     target_phys_addr_t physical;
     int prot;
 #endif
-    int exception = 0, error_code = 0;
     int access_type;
     int ret = 0;
 
@@ -252,51 +303,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
     } else if (ret < 0)
 #endif
     {
-        switch (ret) {
-        default:
-        case TLBRET_BADADDR:
-            /* Reference to kernel address from user mode or supervisor mode */
-            /* Reference to supervisor address from user mode */
-            if (rw)
-                exception = EXCP_AdES;
-            else
-                exception = EXCP_AdEL;
-            break;
-        case TLBRET_NOMATCH:
-            /* No TLB match for a mapped address */
-            if (rw)
-                exception = EXCP_TLBS;
-            else
-                exception = EXCP_TLBL;
-            error_code = 1;
-            break;
-        case TLBRET_INVALID:
-            /* TLB match with no valid bit */
-            if (rw)
-                exception = EXCP_TLBS;
-            else
-                exception = EXCP_TLBL;
-            break;
-        case TLBRET_DIRTY:
-            /* TLB match but 'D' bit is cleared */
-            exception = EXCP_LTLBL;
-            break;
-
-        }
-        /* Raise exception */
-        env->CP0_BadVAddr = address;
-        env->CP0_Context = (env->CP0_Context & ~0x007fffff) |
-                           ((address >> 9) &   0x007ffff0);
-        env->CP0_EntryHi =
-            (env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
-#if defined(TARGET_MIPS64)
-        env->CP0_EntryHi &= env->SEGMask;
-        env->CP0_XContext = (env->CP0_XContext & ((~0ULL) << (env->SEGBITS - 7))) |
-                            ((address & 0xC00000000000ULL) >> (55 - env->SEGBITS)) |
-                            ((address & ((1ULL << env->SEGBITS) - 1) & 0xFFFFFFFFFFFFE000ULL) >> 9);
-#endif
-        env->exception_index = exception;
-        env->error_code = error_code;
+        raise_mmu_exception(env, address, rw, ret);
         ret = 1;
     }