SH usermode fault handling.
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 17 Jun 2006 19:58:25 +0000 (19:58 +0000)
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 17 Jun 2006 19:58:25 +0000 (19:58 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1988 c046a42c-6fe2-441c-8c8c-71466251a162

cpu-exec.c
linux-user/main.c
target-sh4/helper.c
target-sh4/translate.c

index b08f7af..9d5c35e 100644 (file)
@@ -1172,19 +1172,14 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
            a virtual CPU fault */
         cpu_restore_state(tb, env, pc, puc);
     }
-    if (ret == 1) {
 #if 0
         printf("PF exception: NIP=0x%08x error=0x%x %p\n", 
                env->nip, env->error_code, tb);
 #endif
     /* we restore the process signal mask as the sigreturn should
        do it (XXX: use sigsetjmp) */
-        sigprocmask(SIG_SETMASK, old_set, NULL);
-        //        do_raise_exception_err(env->exception_index, env->error_code);
-    } else {
-        /* activate soft MMU for this block */
-        cpu_resume_from_signal(env, puc);
-    }
+    sigprocmask(SIG_SETMASK, old_set, NULL);
+    cpu_loop_exit();
     /* never comes here */
     return 1;
 }
index 5b4182b..74642cc 100644 (file)
@@ -1362,7 +1362,7 @@ void cpu_loop(CPUMIPSState *env)
 void cpu_loop (CPUState *env)
 {
     int trapnr, ret;
-    //    target_siginfo_t info;
+    target_siginfo_t info;
     
     while (1) {
         trapnr = cpu_sh4_exec (env);
@@ -1380,6 +1380,20 @@ void cpu_loop (CPUState *env)
             env->gregs[0x10] = ret;
             env->pc += 2;
             break;
+        case EXCP_DEBUG:
+            {
+                int sig;
+
+                sig = gdb_handlesig (env, TARGET_SIGTRAP);
+                if (sig)
+                  {
+                    info.si_signo = sig;
+                    info.si_errno = 0;
+                    info.si_code = TARGET_TRAP_BRKPT;
+                    queue_signal(info.si_signo, &info);
+                  }
+            }
+            break;
         default:
             printf ("Unhandled trap: 0x%x\n", trapnr);
             cpu_dump_state(env, stderr, fprintf, 0);
index 5ab505a..1839c96 100644 (file)
 #include "cpu.h"
 #include "exec-all.h"
 
+#if defined(CONFIG_USER_ONLY)
+
+void do_interrupt (CPUState *env)
+{
+  env->exception_index = -1;
+}
+
+int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
+                            int is_user, int is_softmmu)
+{
+    env->tea = address;
+    switch (rw) {
+    case 0:
+        env->exception_index = 0x0a0;
+        break;
+    case 1:
+        env->exception_index = 0x0c0;
+        break;
+    case 2:
+        env->exception_index = 0x0a0;
+        break;
+    }
+    return 1;
+}
+
+target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
+{
+    return addr;
+}
+
+#else /* !CONFIG_USER_ONLY */
+
 #define MMU_OK                   0
 #define MMU_ITLB_MISS            (-1)
 #define MMU_ITLB_MULTIPLE        (-2)
@@ -396,3 +428,14 @@ int cpu_sh4_handle_mmu_fault(CPUState * env, target_ulong address, int rw,
 
     return tlb_set_page(env, address, physical, prot, is_user, is_softmmu);
 }
+
+target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
+{
+    target_ulong physical;
+    int prot;
+
+    get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0);
+    return physical;
+}
+
+#endif
index b08d25a..84deced 100644 (file)
@@ -144,22 +144,6 @@ CPUSH4State *cpu_sh4_init(void)
     return env;
 }
 
-#ifdef CONFIG_USER_ONLY
-target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
-{
-    return addr;
-}
-#else
-target_ulong cpu_get_phys_page_debug(CPUState * env, target_ulong addr)
-{
-    target_ulong physical;
-    int prot;
-
-    get_physical_address(env, &physical, &prot, addr, PAGE_READ, 0);
-    return physical;
-}
-#endif
-
 static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
 {
     TranslationBlock *tb;
@@ -1108,7 +1092,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
     target_ulong pc_start;
     static uint16_t *gen_opc_end;
     uint32_t old_flags;
-    int i;
+    int i, ii;
 
     pc_start = tb->pc;
     gen_opc_ptr = gen_opc_buf;
@@ -1135,6 +1119,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
     }
 #endif
 
+    ii = -1;
     while ((old_flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) == 0 &&
           (ctx.flags & (BRANCH | BRANCH_CONDITIONAL | MODE_CHANGE |
                         BRANCH_EXCEPTION)) == 0 &&
@@ -1151,6 +1136,16 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
                }
            }
        }
+        if (search_pc) {
+            i = gen_opc_ptr - gen_opc_buf;
+            if (ii < i) {
+                ii++;
+                while (ii < i)
+                    gen_opc_instr_start[ii++] = 0;
+            }
+            gen_opc_pc[ii] = ctx.pc;
+            gen_opc_instr_start[ii] = 1;
+        }
 #if 0
        fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
        fflush(stderr);
@@ -1192,7 +1187,15 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
        gen_op_debug();
     }
     *gen_opc_ptr = INDEX_op_end;
-    tb->size = ctx.pc - pc_start;
+    if (search_pc) {
+        i = gen_opc_ptr - gen_opc_buf;
+        ii++;
+        while (ii <= i)
+            gen_opc_instr_start[ii++] = 0;
+        tb->size = 0;
+    } else {
+        tb->size = ctx.pc - pc_start;
+    }
 
 #ifdef DEBUG_DISAS
 #ifdef SH4_DEBUG_DISAS
@@ -1220,6 +1223,5 @@ int gen_intermediate_code(CPUState * env, struct TranslationBlock *tb)
 
 int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
 {
-    assert(0);
     return gen_intermediate_code_internal(env, tb, 1);
 }