X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=cpu-exec.c;h=30cfa2a63a68bc0eeddca36257946c89fe6f5ec5;hb=8b7acc79b9adb4dda6cc867b90e3a1e873f4f7e8;hp=aa8fa893d9cafffbc13fcc1e5dce713d15e23648;hpb=ec9bd89fa48147e1d16e078217513c1235f9132a;p=qemu.git diff --git a/cpu-exec.c b/cpu-exec.c index aa8fa893d..30cfa2a63 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -23,8 +23,6 @@ #include "qemu/atomic.h" #include "sysemu/qtest.h" -//#define CONFIG_DEBUG_EXEC - bool qemu_cpu_has_work(CPUState *cpu) { return cpu_has_work(cpu); @@ -55,14 +53,20 @@ void cpu_resume_from_signal(CPUArchState *env, void *puc) static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) { CPUArchState *env = cpu->env_ptr; - tcg_target_ulong next_tb = tcg_qemu_tb_exec(env, tb_ptr); + uintptr_t next_tb = tcg_qemu_tb_exec(env, tb_ptr); if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) { /* We didn't start executing this TB (eg because the instruction * counter hit zero); we must restore the guest PC to the address * of the start of the TB. */ + CPUClass *cc = CPU_GET_CLASS(cpu); TranslationBlock *tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); - cpu_pc_from_tb(env, tb); + if (cc->synchronize_from_tb) { + cc->synchronize_from_tb(cpu, tb); + } else { + assert(cc->set_pc); + cc->set_pc(cpu, tb->pc); + } } if ((next_tb & TB_EXIT_MASK) == TB_EXIT_REQUESTED) { /* We were asked to stop executing TBs (probably a pending @@ -205,7 +209,7 @@ int cpu_exec(CPUArchState *env) int ret, interrupt_request; TranslationBlock *tb; uint8_t *tc_ptr; - tcg_target_ulong next_tb; + uintptr_t next_tb; if (cpu->halted) { if (!cpu_has_work(cpu)) { @@ -215,12 +219,12 @@ int cpu_exec(CPUArchState *env) cpu->halted = 0; } - cpu_single_env = env; + current_cpu = cpu; - /* As long as cpu_single_env is null, up to the assignment just above, + /* As long as current_cpu is null, up to the assignment just above, * requests by other threads to exit the execution loop are expected to * be issued using the exit_request global. We must make sure that our - * evaluation of the global value is performed past the cpu_single_env + * evaluation of the global value is performed past the current_cpu * value transition point, which requires a memory barrier as well as * an instruction scheduling constraint on modern architectures. */ smp_mb(); @@ -232,7 +236,7 @@ int cpu_exec(CPUArchState *env) #if defined(TARGET_I386) /* put eflags in CPU temporary format */ CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - DF = 1 - (2 * ((env->eflags >> 10) & 1)); + env->df = 1 - (2 * ((env->eflags >> 10) & 1)); CC_OP = CC_OP_EFLAGS; env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); #elif defined(TARGET_SPARC) @@ -293,7 +297,7 @@ int cpu_exec(CPUArchState *env) for(;;) { interrupt_request = cpu->interrupt_request; if (unlikely(interrupt_request)) { - if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) { + if (unlikely(cpu->singlestep_enabled & SSTEP_NOIRQ)) { /* Mask out external interrupts for this step. */ interrupt_request &= ~CPU_INTERRUPT_SSTEP_MASK; } @@ -333,7 +337,7 @@ int cpu_exec(CPUArchState *env) cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0); cpu->interrupt_request &= ~CPU_INTERRUPT_SMI; - do_smm_enter(env); + do_smm_enter(x86_env_get_cpu(env)); next_tb = 0; } else if ((interrupt_request & CPU_INTERRUPT_NMI) && !(env->hflags2 & HF2_NMI_MASK)) { @@ -575,22 +579,22 @@ int cpu_exec(CPUArchState *env) env->exception_index = EXCP_INTERRUPT; cpu_loop_exit(env); } -#if defined(DEBUG_DISAS) || defined(CONFIG_DEBUG_EXEC) +#if defined(DEBUG_DISAS) if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) { /* restore flags in standard format */ #if defined(TARGET_I386) - log_cpu_state(env, CPU_DUMP_CCOP); + log_cpu_state(cpu, CPU_DUMP_CCOP); #elif defined(TARGET_M68K) cpu_m68k_flush_flags(env, env->cc_op); env->cc_op = CC_OP_FLAGS; env->sr = (env->sr & 0xffe0) | env->cc_dest | (env->cc_x << 4); - log_cpu_state(env, 0); + log_cpu_state(cpu, 0); #else - log_cpu_state(env, 0); + log_cpu_state(cpu, 0); #endif } -#endif /* DEBUG_DISAS || CONFIG_DEBUG_EXEC */ +#endif /* DEBUG_DISAS */ spin_lock(&tcg_ctx.tb_ctx.tb_lock); tb = tb_find_fast(env); /* Note: we do it here to avoid a gcc bug on Mac OS X when @@ -602,11 +606,10 @@ int cpu_exec(CPUArchState *env) next_tb = 0; tcg_ctx.tb_ctx.tb_invalidated_flag = 0; } -#ifdef CONFIG_DEBUG_EXEC - qemu_log_mask(CPU_LOG_EXEC, "Trace %p [" TARGET_FMT_lx "] %s\n", - tb->tc_ptr, tb->pc, - lookup_symbol(tb->pc)); -#endif + if (qemu_loglevel_mask(CPU_LOG_EXEC)) { + qemu_log("Trace %p [" TARGET_FMT_lx "] %s\n", + tb->tc_ptr, tb->pc, lookup_symbol(tb->pc)); + } /* see if we can patch the calling TB. When the TB spans two pages, we cannot safely do a direct jump. */ @@ -676,7 +679,12 @@ int cpu_exec(CPUArchState *env) } else { /* Reload env after longjmp - the compiler may have smashed all * local variables as longjmp is marked 'noreturn'. */ - env = cpu_single_env; + cpu = current_cpu; + env = cpu->env_ptr; +#if !(defined(CONFIG_USER_ONLY) && \ + (defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X))) + cc = CPU_GET_CLASS(cpu); +#endif } } /* for(;;) */ @@ -684,7 +692,7 @@ int cpu_exec(CPUArchState *env) #if defined(TARGET_I386) /* restore flags in standard format */ env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP) - | (DF & DF_MASK); + | (env->df & DF_MASK); #elif defined(TARGET_ARM) /* XXX: Save/restore host fpu exception state?. */ #elif defined(TARGET_UNICORE32) @@ -710,7 +718,7 @@ int cpu_exec(CPUArchState *env) #error unsupported target CPU #endif - /* fail safe : never use cpu_single_env outside cpu_exec() */ - cpu_single_env = NULL; + /* fail safe : never use current_cpu outside cpu_exec() */ + current_cpu = NULL; return ret; }