]> git.proxmox.com Git - qemu.git/commitdiff
Merge branch 'x86cpu_qom_tcg_v2' of git://github.com/imammedo/qemu
authorBlue Swirl <blauwirbel@gmail.com>
Thu, 9 Aug 2012 18:44:49 +0000 (18:44 +0000)
committerBlue Swirl <blauwirbel@gmail.com>
Thu, 9 Aug 2012 18:44:49 +0000 (18:44 +0000)
* '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

1  2 
cpu-exec.c
target-i386/cpu.c
target-i386/cpu.h
target-i386/helper.c

diff --combined cpu-exec.c
index 543460c34c49dff09d15ddf662c69dc8400deca9,24607fbed5fc430dacb62b40dad8675926d14918..4fee0618bdc0317e460096eff3ed6a3a0bf36742
@@@ -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)
                      }
  #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);
                      } 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;
                                       (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);
                                     !(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);
                          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) &&
                | 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 857b94ea87eedea935b5fce571c803678ce05282,445274c97deaa2314f20ab21622416254e32f191..880cfea3f8babe84baab03f321c235e34156580c
@@@ -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);
  
                          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 2a61c810bb19bfafe91324bfd15f23554e136bb1,80dcb493919a3c25bed20e1ec465c597f196fbcc..60f9e972bd4fd7afa1afe03b96ae844619148acc
  #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)
                                   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 b748d90063dfbe48054c0f0e2934127f7982adbf,c52ec130e57e990489b97abfbcc80d977e782d9d..8a5da3d7c098d96216b6e50db270f058814ddac3
@@@ -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;
  
          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);
          }
              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)