summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAurelien Jarno <aurelien@aurel32.net>2010-02-06 17:02:45 +0100
committerAurelien Jarno <aurelien@aurel32.net>2010-02-06 17:23:33 +0100
commitc36bbb28ad62b4b1f494df0b199432d8c79876db (patch)
tree5c58e047685761144079d31456142ddf9adc057f
parent3f26c1227e3b08010f2a65379cecf4cb4b5933fa (diff)
downloadfocaccia-qemu-c36bbb28ad62b4b1f494df0b199432d8c79876db.tar.gz
focaccia-qemu-c36bbb28ad62b4b1f494df0b199432d8c79876db.zip
target-mips: don't call cpu_loop_exit() from helper.c
In helper.c AREG0 may not correspond do env, so it's not possible to
call cpu_loop_exit() here. Call it from op_helper.c instead.

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
-rw-r--r--target-mips/cpu.h4
-rw-r--r--target-mips/helper.c8
-rw-r--r--target-mips/op_helper.c18
3 files changed, 22 insertions, 8 deletions
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index b78aec52e0..8291bf9b0a 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -599,8 +599,8 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
 #define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault
 void do_interrupt (CPUState *env);
 void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra);
-target_phys_addr_t do_translate_address (CPUState *env, target_ulong address,
-		                         int rw);
+target_phys_addr_t cpu_mips_translate_address (CPUState *env, target_ulong address,
+		                               int rw);
 
 static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
 {
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 903987bb83..a3f099f04b 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -311,7 +311,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
 }
 
 #if !defined(CONFIG_USER_ONLY)
-target_phys_addr_t do_translate_address(CPUState *env, target_ulong address, int rw)
+target_phys_addr_t cpu_mips_translate_address(CPUState *env, target_ulong address, int rw)
 {
     target_phys_addr_t physical;
     int prot;
@@ -326,10 +326,10 @@ target_phys_addr_t do_translate_address(CPUState *env, target_ulong address, int
                                address, rw, access_type);
     if (ret != TLBRET_MATCH) {
         raise_mmu_exception(env, address, rw, ret);
-        cpu_loop_exit();
+        return -1LL;
+    } else {
+        return physical;
     }
-
-    return physical;
 }
 #endif
 
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index cccfd8e07e..2bfdd5002f 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -276,10 +276,24 @@ void helper_dmultu (target_ulong arg1, target_ulong arg2)
 #endif
 
 #ifndef CONFIG_USER_ONLY
+
+static inline target_phys_addr_t do_translate_address(target_ulong address, int rw)
+{
+    target_phys_addr_t lladdr;
+
+    lladdr = cpu_mips_translate_address(env, address, rw);
+
+    if (lladdr == -1LL) {
+        cpu_loop_exit();
+    } else {
+        return lladdr;
+    }
+}
+
 #define HELPER_LD_ATOMIC(name, insn)                                          \
 target_ulong helper_##name(target_ulong arg, int mem_idx)                     \
 {                                                                             \
-    env->lladdr = do_translate_address(env, arg, 0);                          \
+    env->lladdr = do_translate_address(arg, 0);                               \
     env->llval = do_##insn(arg, mem_idx);                                     \
     return env->llval;                                                        \
 }
@@ -298,7 +312,7 @@ target_ulong helper_##name(target_ulong arg1, target_ulong arg2, int mem_idx) \
         env->CP0_BadVAddr = arg2;                                             \
         helper_raise_exception(EXCP_AdES);                                    \
     }                                                                         \
-    if (do_translate_address(env, arg2, 1) == env->lladdr) {                  \
+    if (do_translate_address(arg2, 1) == env->lladdr) {                       \
         tmp = do_##ld_insn(arg2, mem_idx);                                    \
         if (tmp == env->llval) {                                              \
             do_##st_insn(arg2, arg1, mem_idx);                                \