diff options
Diffstat (limited to 'cpu-exec.c')
-rw-r--r-- | cpu-exec.c | 415 |
1 files changed, 6 insertions, 409 deletions
diff --git a/cpu-exec.c b/cpu-exec.c index 17fe972598..bf20ada1a0 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -746,6 +746,10 @@ void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32) #if !defined(CONFIG_SOFTMMU) #if defined(TARGET_I386) +#define EXCEPTION_ACTION raise_exception_err(env->exception_index, env->error_code) +#else +#define EXCEPTION_ACTION cpu_loop_exit() +#endif /* 'pc' is the host PC at which the exception was raised. 'address' is the effective address of the memory exception. 'is_write' is 1 if a @@ -770,56 +774,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, } /* see if it is an MMU fault */ - ret = cpu_x86_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); - if (ret < 0) - return 0; /* not an MMU fault */ - if (ret == 0) - return 1; /* the MMU fault was handled without causing real CPU fault */ - /* now we have a real cpu fault */ - tb = tb_find_pc(pc); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, pc, puc); - } - if (ret == 1) { -#if 0 - printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n", - env->eip, env->cr[2], env->error_code); -#endif - /* we restore the process signal mask as the sigreturn should - do it (XXX: use sigsetjmp) */ - sigprocmask(SIG_SETMASK, old_set, NULL); - raise_exception_err(env->exception_index, env->error_code); - } else { - /* activate soft MMU for this block */ - env->hflags |= HF_SOFTMMU_MASK; - cpu_resume_from_signal(env, puc); - } - /* never comes here */ - return 1; -} - -#elif defined(TARGET_ARM) -static inline int handle_cpu_signal(unsigned long pc, unsigned long address, - int is_write, sigset_t *old_set, - void *puc) -{ - TranslationBlock *tb; - int ret; - - if (cpu_single_env) - env = cpu_single_env; /* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL) - printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", - pc, address, is_write, *(unsigned long *)old_set); -#endif - /* XXX: locking issue */ - if (is_write && page_unprotect(h2g(address), pc, puc)) { - return 1; - } - /* see if it is an MMU fault */ - ret = cpu_arm_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); + ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); if (ret < 0) return 0; /* not an MMU fault */ if (ret == 0) @@ -831,374 +786,16 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, a virtual CPU fault */ cpu_restore_state(tb, env, pc, puc); } - /* we restore the process signal mask as the sigreturn should - do it (XXX: use sigsetjmp) */ - sigprocmask(SIG_SETMASK, old_set, NULL); - cpu_loop_exit(); - /* never comes here */ - return 1; -} -#elif defined(TARGET_SPARC) -static inline int handle_cpu_signal(unsigned long pc, unsigned long address, - int is_write, sigset_t *old_set, - void *puc) -{ - TranslationBlock *tb; - int ret; - if (cpu_single_env) - env = cpu_single_env; /* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL) - printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", - pc, address, is_write, *(unsigned long *)old_set); -#endif - /* XXX: locking issue */ - if (is_write && page_unprotect(h2g(address), pc, puc)) { - return 1; - } - /* see if it is an MMU fault */ - ret = cpu_sparc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); - if (ret < 0) - return 0; /* not an MMU fault */ - if (ret == 0) - return 1; /* the MMU fault was handled without causing real CPU fault */ - /* now we have a real cpu fault */ - tb = tb_find_pc(pc); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, pc, puc); - } /* we restore the process signal mask as the sigreturn should do it (XXX: use sigsetjmp) */ sigprocmask(SIG_SETMASK, old_set, NULL); - cpu_loop_exit(); - /* never comes here */ - return 1; -} -#elif defined (TARGET_PPC) -static inline int handle_cpu_signal(unsigned long pc, unsigned long address, - int is_write, sigset_t *old_set, - void *puc) -{ - TranslationBlock *tb; - int ret; - - if (cpu_single_env) - env = cpu_single_env; /* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL) - printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", - pc, address, is_write, *(unsigned long *)old_set); -#endif - /* XXX: locking issue */ - if (is_write && page_unprotect(h2g(address), pc, puc)) { - return 1; - } - - /* see if it is an MMU fault */ - ret = cpu_ppc_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); - if (ret < 0) - return 0; /* not an MMU fault */ - if (ret == 0) - return 1; /* the MMU fault was handled without causing real CPU fault */ - - /* now we have a real cpu fault */ - tb = tb_find_pc(pc); - if (tb) { - /* the PC is inside the translated code. It means that we have - 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); - cpu_loop_exit(); - } else { - /* activate soft MMU for this block */ - cpu_resume_from_signal(env, puc); - } - /* never comes here */ - return 1; -} + EXCEPTION_ACTION; -#elif defined(TARGET_M68K) -static inline int handle_cpu_signal(unsigned long pc, unsigned long address, - int is_write, sigset_t *old_set, - void *puc) -{ - TranslationBlock *tb; - int ret; - - if (cpu_single_env) - env = cpu_single_env; /* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL) - printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", - pc, address, is_write, *(unsigned long *)old_set); -#endif - /* XXX: locking issue */ - if (is_write && page_unprotect(address, pc, puc)) { - return 1; - } - /* see if it is an MMU fault */ - ret = cpu_m68k_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); - if (ret < 0) - return 0; /* not an MMU fault */ - if (ret == 0) - return 1; /* the MMU fault was handled without causing real CPU fault */ - /* now we have a real cpu fault */ - tb = tb_find_pc(pc); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, pc, puc); - } - /* we restore the process signal mask as the sigreturn should - do it (XXX: use sigsetjmp) */ - sigprocmask(SIG_SETMASK, old_set, NULL); - cpu_loop_exit(); /* never comes here */ return 1; } -#elif defined (TARGET_MIPS) -static inline int handle_cpu_signal(unsigned long pc, unsigned long address, - int is_write, sigset_t *old_set, - void *puc) -{ - TranslationBlock *tb; - int ret; - - if (cpu_single_env) - env = cpu_single_env; /* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL) - printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", - pc, address, is_write, *(unsigned long *)old_set); -#endif - /* XXX: locking issue */ - if (is_write && page_unprotect(h2g(address), pc, puc)) { - return 1; - } - - /* see if it is an MMU fault */ - ret = cpu_mips_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); - if (ret < 0) - return 0; /* not an MMU fault */ - if (ret == 0) - return 1; /* the MMU fault was handled without causing real CPU fault */ - - /* now we have a real cpu fault */ - tb = tb_find_pc(pc); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, pc, puc); - } - if (ret == 1) { -#if 0 - printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n", - env->PC, 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); - cpu_loop_exit(); - } else { - /* activate soft MMU for this block */ - cpu_resume_from_signal(env, puc); - } - /* never comes here */ - return 1; -} - -#elif defined (TARGET_MICROBLAZE) -static inline int handle_cpu_signal(unsigned long pc, unsigned long address, - int is_write, sigset_t *old_set, - void *puc) -{ - TranslationBlock *tb; - int ret; - - if (cpu_single_env) - env = cpu_single_env; /* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL) - printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", - pc, address, is_write, *(unsigned long *)old_set); -#endif - /* XXX: locking issue */ - if (is_write && page_unprotect(h2g(address), pc, puc)) { - return 1; - } - - /* see if it is an MMU fault */ - ret = cpu_mb_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); - if (ret < 0) - return 0; /* not an MMU fault */ - if (ret == 0) - return 1; /* the MMU fault was handled without causing real CPU fault */ - - /* now we have a real cpu fault */ - tb = tb_find_pc(pc); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, pc, puc); - } - if (ret == 1) { -#if 0 - printf("PF exception: PC=0x" TARGET_FMT_lx " error=0x%x %p\n", - env->PC, 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); - cpu_loop_exit(); - } else { - /* activate soft MMU for this block */ - cpu_resume_from_signal(env, puc); - } - /* never comes here */ - return 1; -} - -#elif defined (TARGET_SH4) -static inline int handle_cpu_signal(unsigned long pc, unsigned long address, - int is_write, sigset_t *old_set, - void *puc) -{ - TranslationBlock *tb; - int ret; - - if (cpu_single_env) - env = cpu_single_env; /* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL) - printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", - pc, address, is_write, *(unsigned long *)old_set); -#endif - /* XXX: locking issue */ - if (is_write && page_unprotect(h2g(address), pc, puc)) { - return 1; - } - - /* see if it is an MMU fault */ - ret = cpu_sh4_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); - if (ret < 0) - return 0; /* not an MMU fault */ - if (ret == 0) - return 1; /* the MMU fault was handled without causing real CPU fault */ - - /* now we have a real cpu fault */ - tb = tb_find_pc(pc); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, pc, puc); - } -#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); - cpu_loop_exit(); - /* never comes here */ - return 1; -} - -#elif defined (TARGET_ALPHA) -static inline int handle_cpu_signal(unsigned long pc, unsigned long address, - int is_write, sigset_t *old_set, - void *puc) -{ - TranslationBlock *tb; - int ret; - - if (cpu_single_env) - env = cpu_single_env; /* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL) - printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", - pc, address, is_write, *(unsigned long *)old_set); -#endif - /* XXX: locking issue */ - if (is_write && page_unprotect(h2g(address), pc, puc)) { - return 1; - } - - /* see if it is an MMU fault */ - ret = cpu_alpha_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); - if (ret < 0) - return 0; /* not an MMU fault */ - if (ret == 0) - return 1; /* the MMU fault was handled without causing real CPU fault */ - - /* now we have a real cpu fault */ - tb = tb_find_pc(pc); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, pc, puc); - } -#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); - cpu_loop_exit(); - /* never comes here */ - return 1; -} -#elif defined (TARGET_CRIS) -static inline int handle_cpu_signal(unsigned long pc, unsigned long address, - int is_write, sigset_t *old_set, - void *puc) -{ - TranslationBlock *tb; - int ret; - - if (cpu_single_env) - env = cpu_single_env; /* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL) - printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", - pc, address, is_write, *(unsigned long *)old_set); -#endif - /* XXX: locking issue */ - if (is_write && page_unprotect(h2g(address), pc, puc)) { - return 1; - } - - /* see if it is an MMU fault */ - ret = cpu_cris_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0); - if (ret < 0) - return 0; /* not an MMU fault */ - if (ret == 0) - return 1; /* the MMU fault was handled without causing real CPU fault */ - - /* now we have a real cpu fault */ - tb = tb_find_pc(pc); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, pc, puc); - } - /* we restore the process signal mask as the sigreturn should - do it (XXX: use sigsetjmp) */ - sigprocmask(SIG_SETMASK, old_set, NULL); - cpu_loop_exit(); - /* never comes here */ - return 1; -} - -#else -#error unsupported target CPU -#endif - #if defined(__i386__) #if defined(__APPLE__) |