From: Blue Swirl Date: Thu, 9 Aug 2012 18:44:49 +0000 (+0000) Subject: Merge branch 'x86cpu_qom_tcg_v2' of git://github.com/imammedo/qemu X-Git-Tag: v1.2.0-rc0~61 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=d3da41e32bc6d6fac80d402aa1cc0f1d30539d98;hp=-c;p=qemu.git Merge branch 'x86cpu_qom_tcg_v2' of git://github.com/imammedo/qemu * 'x86cpu_qom_tcg_v2' of git://github.com/imammedo/qemu: target-i386: move tcg initialization into x86_cpu_initfn() cleanup cpu_set_debug_excp_handler target-xtensa: drop usage of prev_debug_excp_handler target-i386: drop usage of prev_debug_excp_handler --- d3da41e32bc6d6fac80d402aa1cc0f1d30539d98 diff --combined cpu-exec.c index 543460c34,24607fbed..4fee0618b --- a/cpu-exec.c +++ b/cpu-exec.c @@@ -156,12 -156,9 +156,9 @@@ static inline TranslationBlock *tb_find static CPUDebugExcpHandler *debug_excp_handler; - CPUDebugExcpHandler *cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler) + void cpu_set_debug_excp_handler(CPUDebugExcpHandler *handler) { - CPUDebugExcpHandler *old_handler = debug_excp_handler; - debug_excp_handler = handler; - return old_handler; } static void cpu_handle_debug_exception(CPUArchState *env) @@@ -225,7 -222,6 +222,7 @@@ int cpu_exec(CPUArchState *env #elif defined(TARGET_LM32) #elif defined(TARGET_MICROBLAZE) #elif defined(TARGET_MIPS) +#elif defined(TARGET_OPENRISC) #elif defined(TARGET_SH4) #elif defined(TARGET_CRIS) #elif defined(TARGET_S390X) @@@ -289,15 -285,8 +286,15 @@@ } #endif #if defined(TARGET_I386) +#if !defined(CONFIG_USER_ONLY) + if (interrupt_request & CPU_INTERRUPT_POLL) { + env->interrupt_request &= ~CPU_INTERRUPT_POLL; + apic_poll_irq(env->apic_state); + } +#endif if (interrupt_request & CPU_INTERRUPT_INIT) { - svm_check_intercept(env, SVM_EXIT_INIT); + cpu_svm_check_intercept_param(env, SVM_EXIT_INIT, + 0); do_cpu_init(x86_env_get_cpu(env)); env->exception_index = EXCP_HALTED; cpu_loop_exit(env); @@@ -306,8 -295,7 +303,8 @@@ } else if (env->hflags2 & HF2_GIF_MASK) { if ((interrupt_request & CPU_INTERRUPT_SMI) && !(env->hflags & HF_SMM_MASK)) { - svm_check_intercept(env, SVM_EXIT_SMI); + cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, + 0); env->interrupt_request &= ~CPU_INTERRUPT_SMI; do_smm_enter(env); next_tb = 0; @@@ -328,8 -316,7 +325,8 @@@ (env->eflags & IF_MASK && !(env->hflags & HF_INHIBIT_IRQ_MASK))))) { int intno; - svm_check_intercept(env, SVM_EXIT_INTR); + cpu_svm_check_intercept_param(env, SVM_EXIT_INTR, + 0); env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ); intno = cpu_get_pic_interrupt(env); qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno); @@@ -343,8 -330,7 +340,8 @@@ !(env->hflags & HF_INHIBIT_IRQ_MASK)) { int intno; /* FIXME: this should respect TPR */ - svm_check_intercept(env, SVM_EXIT_VINTR); + cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, + 0); intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector)); qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno); do_interrupt_x86_hardirq(env, intno, 1); @@@ -388,23 -374,6 +385,23 @@@ do_interrupt(env); next_tb = 0; } +#elif defined(TARGET_OPENRISC) + { + int idx = -1; + if ((interrupt_request & CPU_INTERRUPT_HARD) + && (env->sr & SR_IEE)) { + idx = EXCP_INT; + } + if ((interrupt_request & CPU_INTERRUPT_TIMER) + && (env->sr & SR_TEE)) { + idx = EXCP_TICK; + } + if (idx >= 0) { + env->exception_index = idx; + do_interrupt(env); + next_tb = 0; + } + } #elif defined(TARGET_SPARC) if (interrupt_request & CPU_INTERRUPT_HARD) { if (cpu_interrupts_enabled(env) && @@@ -658,7 -627,6 +655,7 @@@ | env->cc_dest | (env->cc_x << 4); #elif defined(TARGET_MICROBLAZE) #elif defined(TARGET_MIPS) +#elif defined(TARGET_OPENRISC) #elif defined(TARGET_SH4) #elif defined(TARGET_ALPHA) #elif defined(TARGET_CRIS) diff --combined target-i386/cpu.c index 857b94ea8,445274c97..880cfea3f --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@@ -31,8 -31,6 +31,8 @@@ #include "hyperv.h" +#include "hw/hw.h" + /* feature flags taken from "Intel Processor Identification and the CPUID * Instruction" and AMD's "CPUID Specification". In cases of disagreement * between feature naming conventions, aliases may be added. @@@ -52,7 -50,7 +52,7 @@@ static const char *ext_feature_name[] "ds_cpl", "vmx", "smx", "est", "tm2", "ssse3", "cid", NULL, "fma", "cx16", "xtpr", "pdcm", - NULL, NULL, "dca", "sse4.1|sse4_1", + NULL, "pcid", "dca", "sse4.1|sse4_1", "sse4.2|sse4_2", "x2apic", "movbe", "popcnt", "tsc-deadline", "aes", "xsave", "osxsave", "avx", NULL, NULL, "hypervisor", @@@ -79,7 -77,7 +79,7 @@@ static const char *ext3_feature_name[] }; static const char *kvm_feature_name[] = { - "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, NULL, NULL, + "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, "kvm_pv_eoi", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@@ -1305,7 -1303,7 +1305,7 @@@ void x86_cpudef_setup(void builtin_x86_defs[i].flags = 1; /* Look for specific "cpudef" models that */ - /* have the QEmu version in .model_id */ + /* have the QEMU version in .model_id */ for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) { if (strcmp(model_with_versions[j], builtin_x86_defs[i].name) == 0) { pstrcpy(builtin_x86_defs[i].model_id, sizeof(builtin_x86_defs[i].model_id), "QEMU Virtual CPU version "); @@@ -1688,31 -1686,8 +1688,31 @@@ static void x86_cpu_reset(CPUState *s env->dr[7] = DR7_FIXED_1; cpu_breakpoint_remove_all(env, BP_CPU); cpu_watchpoint_remove_all(env, BP_CPU); + +#if !defined(CONFIG_USER_ONLY) + /* We hard-wire the BSP to the first CPU. */ + if (env->cpu_index == 0) { + apic_designate_bsp(env->apic_state); + } + + env->halted = !cpu_is_bsp(cpu); +#endif } +#ifndef CONFIG_USER_ONLY +bool cpu_is_bsp(X86CPU *cpu) +{ + return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP; +} + +/* TODO: remove me, when reset over QOM tree is implemented */ +static void x86_cpu_machine_reset_cb(void *opaque) +{ + X86CPU *cpu = opaque; + cpu_reset(CPU(cpu)); +} +#endif + static void mce_init(X86CPU *cpu) { CPUX86State *cenv = &cpu->env; @@@ -1733,19 -1708,15 +1733,20 @@@ void x86_cpu_realize(Object *obj, Erro { X86CPU *cpu = X86_CPU(obj); +#ifndef CONFIG_USER_ONLY + qemu_register_reset(x86_cpu_machine_reset_cb, cpu); +#endif + mce_init(cpu); qemu_init_vcpu(&cpu->env); + cpu_reset(CPU(cpu)); } static void x86_cpu_initfn(Object *obj) { X86CPU *cpu = X86_CPU(obj); CPUX86State *env = &cpu->env; + static int inited; cpu_exec_init(env); @@@ -1775,6 -1746,15 +1776,15 @@@ x86_cpuid_set_tsc_freq, NULL, NULL, NULL); env->cpuid_apic_id = env->cpu_index; + + /* init various static tables used in TCG mode */ + if (tcg_enabled() && !inited) { + inited = 1; + optimize_flags_init(); + #ifndef CONFIG_USER_ONLY + cpu_set_debug_excp_handler(breakpoint_handler); + #endif + } } static void x86_cpu_common_class_init(ObjectClass *oc, void *data) diff --combined target-i386/cpu.h index 2a61c810b,80dcb4939..60f9e972b --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@@ -400,7 -400,6 +400,7 @@@ #define CPUID_EXT_X2APIC (1 << 21) #define CPUID_EXT_MOVBE (1 << 22) #define CPUID_EXT_POPCNT (1 << 23) +#define CPUID_EXT_TSC_DEADLINE_TIMER (1 << 24) #define CPUID_EXT_XSAVE (1 << 26) #define CPUID_EXT_OSXSAVE (1 << 27) #define CPUID_EXT_HYPERVISOR (1 << 31) @@@ -478,7 -477,6 +478,7 @@@ for syscall instruction */ /* i386-specific interrupt pending bits. */ +#define CPU_INTERRUPT_POLL CPU_INTERRUPT_TGT_EXT_1 #define CPU_INTERRUPT_SMI CPU_INTERRUPT_TGT_EXT_2 #define CPU_INTERRUPT_NMI CPU_INTERRUPT_TGT_EXT_3 #define CPU_INTERRUPT_MCE CPU_INTERRUPT_TGT_EXT_4 @@@ -935,6 -933,7 +935,7 @@@ static inline int hw_breakpoint_len(uns void hw_breakpoint_insert(CPUX86State *env, int index); void hw_breakpoint_remove(CPUX86State *env, int index); int check_hw_breakpoints(CPUX86State *env, int force_dr6_update); + void breakpoint_handler(CPUX86State *env); /* will be suppressed */ void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0); @@@ -1012,16 -1011,6 +1013,16 @@@ static inline int cpu_mmu_index (CPUX86 #define CC_DST (env->cc_dst) #define CC_OP (env->cc_op) +/* n must be a constant to be efficient */ +static inline target_long lshift(target_long x, int n) +{ + if (n >= 0) { + return x << n; + } else { + return x >> (-n); + } +} + /* float macros */ #define FT0 (env->ft0) #define ST0 (env->fpregs[env->fpstt].d) @@@ -1049,8 -1038,7 +1050,8 @@@ static inline void cpu_clone_regs(CPUX8 static inline bool cpu_has_work(CPUX86State *env) { - return ((env->interrupt_request & CPU_INTERRUPT_HARD) && + return ((env->interrupt_request & (CPU_INTERRUPT_HARD | + CPU_INTERRUPT_POLL)) && (env->eflags & IF_MASK)) || (env->interrupt_request & (CPU_INTERRUPT_NMI | CPU_INTERRUPT_INIT | @@@ -1084,57 -1072,19 +1085,57 @@@ void cpu_x86_inject_mce(Monitor *mon, C uint64_t status, uint64_t mcg_status, uint64_t addr, uint64_t misc, int flags); +/* excp_helper.c */ +void QEMU_NORETURN raise_exception(CPUX86State *env, int exception_index); +void QEMU_NORETURN raise_exception_err(CPUX86State *env, int exception_index, + int error_code); +void QEMU_NORETURN raise_interrupt(CPUX86State *nenv, int intno, int is_int, + int error_code, int next_eip_addend); + +/* cc_helper.c */ +extern const uint8_t parity_table[256]; +uint32_t cpu_cc_compute_all(CPUX86State *env1, int op); + +static inline uint32_t cpu_compute_eflags(CPUX86State *env) +{ + return env->eflags | cpu_cc_compute_all(env, CC_OP) | (DF & DF_MASK); +} + +/* NOTE: CC_OP must be modified manually to CC_OP_EFLAGS */ +static inline void cpu_load_eflags(CPUX86State *env, int eflags, + int update_mask) +{ + CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); + DF = 1 - (2 * ((eflags >> 10) & 1)); + env->eflags = (env->eflags & ~update_mask) | + (eflags & update_mask) | 0x2; +} + +/* load efer and update the corresponding hflags. XXX: do consistency + checks with cpuid bits? */ +static inline void cpu_load_efer(CPUX86State *env, uint64_t val) +{ + env->efer = val; + env->hflags &= ~(HF_LMA_MASK | HF_SVME_MASK); + if (env->efer & MSR_EFER_LMA) { + env->hflags |= HF_LMA_MASK; + } + if (env->efer & MSR_EFER_SVME) { + env->hflags |= HF_SVME_MASK; + } +} + +/* svm_helper.c */ +void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type, + uint64_t param); +void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1); + /* op_helper.c */ void do_interrupt(CPUX86State *env); void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw); -void QEMU_NORETURN raise_exception_env(int exception_index, CPUX86State *nenv); -void QEMU_NORETURN raise_exception_err_env(CPUX86State *nenv, int exception_index, - int error_code); void do_smm_enter(CPUX86State *env1); -void svm_check_intercept(CPUX86State *env1, uint32_t type); - -uint32_t cpu_cc_compute_all(CPUX86State *env1, int op); - void cpu_report_tpr_access(CPUX86State *env, TPRAccess access); #endif /* CPU_I386_H */ diff --combined target-i386/helper.c index b748d9006,c52ec130e..8a5da3d7c --- a/target-i386/helper.c +++ b/target-i386/helper.c @@@ -941,9 -941,7 +941,7 @@@ int check_hw_breakpoints(CPUX86State *e return hit_enabled; } - static CPUDebugExcpHandler *prev_debug_excp_handler; - - static void breakpoint_handler(CPUX86State *env) + void breakpoint_handler(CPUX86State *env) { CPUBreakpoint *bp; @@@ -951,7 -949,7 +949,7 @@@ if (env->watchpoint_hit->flags & BP_CPU) { env->watchpoint_hit = NULL; if (check_hw_breakpoints(env, 0)) - raise_exception_env(EXCP01_DB, env); + raise_exception(env, EXCP01_DB); else cpu_resume_from_signal(env, NULL); } @@@ -960,13 -958,11 +958,11 @@@ if (bp->pc == env->eip) { if (bp->flags & BP_CPU) { check_hw_breakpoints(env, 1); - raise_exception_env(EXCP01_DB, env); + raise_exception(env, EXCP01_DB); } break; } } - if (prev_debug_excp_handler) - prev_debug_excp_handler(env); } typedef struct MCEInjectionParams { @@@ -1155,21 -1151,11 +1151,11 @@@ X86CPU *cpu_x86_init(const char *cpu_mo { X86CPU *cpu; CPUX86State *env; - static int inited; cpu = X86_CPU(object_new(TYPE_X86_CPU)); env = &cpu->env; env->cpu_model_str = cpu_model; - /* init various static tables used in TCG mode */ - if (tcg_enabled() && !inited) { - inited = 1; - optimize_flags_init(); - #ifndef CONFIG_USER_ONLY - prev_debug_excp_handler = - cpu_set_debug_excp_handler(breakpoint_handler); - #endif - } if (cpu_x86_register(cpu, cpu_model) < 0) { object_delete(OBJECT(cpu)); return NULL; @@@ -1191,6 -1177,7 +1177,6 @@@ void do_cpu_init(X86CPU *cpu env->interrupt_request = sipi; env->pat = pat; apic_init_reset(env->apic_state); - env->halted = !cpu_is_bsp(env); } void do_cpu_sipi(X86CPU *cpu)