]> Git Repo - qemu.git/blobdiff - cpu-exec.c
Handle all MMU models in switches, even if it's just to abort because of lack
[qemu.git] / cpu-exec.c
index 5326edf09c22513adf672407585da9ea058392e7..55758faef299e8439d8bfa267f0f6f75a764eb36 100644 (file)
@@ -77,20 +77,20 @@ void cpu_resume_from_signal(CPUState *env1, void *puc)
 
 static TranslationBlock *tb_find_slow(target_ulong pc,
                                       target_ulong cs_base,
-                                      unsigned int flags)
+                                      uint64_t flags)
 {
     TranslationBlock *tb, **ptb1;
     int code_gen_size;
     unsigned int h;
     target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
     uint8_t *tc_ptr;
-   
+
     spin_lock(&tb_lock);
 
     tb_invalidated_flag = 0;
-   
+
     regs_to_env(); /* XXX: do it just before cpu_gen_code() */
-   
+
     /* find translated block using physical mappings */
     phys_pc = get_phys_addr_code(env, pc);
     phys_page1 = phys_pc & TARGET_PAGE_MASK;
@@ -135,7 +135,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc,
     tb->flags = flags;
     cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size);
     code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
-   
+
     /* check next page if needed */
     virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
     phys_page2 = -1;
@@ -143,7 +143,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc,
         phys_page2 = get_phys_addr_code(env, virt_page2);
     }
     tb_link_phys(tb, phys_pc, phys_page2);
-   
+
  found:
     /* we add the TB in the virtual pc hash table */
     env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
@@ -155,7 +155,7 @@ static inline TranslationBlock *tb_find_fast(void)
 {
     TranslationBlock *tb;
     target_ulong cs_base, pc;
-    unsigned int flags;
+    uint64_t flags;
 
     /* we record a subset of the CPU state. It will
        always be the same before a given translated block
@@ -163,6 +163,7 @@ static inline TranslationBlock *tb_find_fast(void)
 #if defined(TARGET_I386)
     flags = env->hflags;
     flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
+    flags |= env->intercept;
     cs_base = env->segs[R_CS].base;
     pc = cs_base + env->eip;
 #elif defined(TARGET_ARM)
@@ -180,15 +181,15 @@ static inline TranslationBlock *tb_find_fast(void)
     flags = (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
         | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
 #else
-    // FPU enable . MMU enabled . MMU no-fault . Supervisor
-    flags = (env->psref << 3) | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)
+    // FPU enable . MMU Boot . MMU enabled . MMU no-fault . Supervisor
+    flags = (env->psref << 4) | (((env->mmuregs[0] & MMU_BM) >> 14) << 3)
+        | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1)
         | env->psrs;
 #endif
     cs_base = env->npc;
     pc = env->pc;
 #elif defined(TARGET_PPC)
-    flags = (msr_pr << MSR_PR) | (msr_fp << MSR_FP) |
-        (msr_se << MSR_SE) | (msr_le << MSR_LE);
+    flags = env->hflags;
     cs_base = 0;
     pc = env->nip;
 #elif defined(TARGET_MIPS)
@@ -371,9 +372,13 @@ int cpu_exec(CPUState *env1)
 #if defined(__sparc__) && !defined(HOST_SOLARIS)
                 /* g1 can be modified by some libc? functions */
                 tmp_T0 = T0;
-#endif    
+#endif
                 interrupt_request = env->interrupt_request;
-                if (__builtin_expect(interrupt_request, 0)) {
+                if (__builtin_expect(interrupt_request, 0)
+#if defined(TARGET_I386)
+                       && env->hflags & HF_GIF_MASK
+#endif
+                               ) {
                     if (interrupt_request & CPU_INTERRUPT_DEBUG) {
                         env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
                         env->exception_index = EXCP_DEBUG;
@@ -391,6 +396,7 @@ int cpu_exec(CPUState *env1)
 #if defined(TARGET_I386)
                     if ((interrupt_request & CPU_INTERRUPT_SMI) &&
                         !(env->hflags & HF_SMM_MASK)) {
+                        svm_check_intercept(SVM_EXIT_SMI);
                         env->interrupt_request &= ~CPU_INTERRUPT_SMI;
                         do_smm_enter();
 #if defined(__sparc__) && !defined(HOST_SOLARIS)
@@ -399,10 +405,11 @@ int cpu_exec(CPUState *env1)
                         T0 = 0;
 #endif
                     } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
-                        (env->eflags & IF_MASK) &&
+                        (env->eflags & IF_MASK || env->hflags & HF_HIF_MASK) &&
                         !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
                         int intno;
-                        env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+                        svm_check_intercept(SVM_EXIT_INTR);
+                        env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
                         intno = cpu_get_pic_interrupt(env);
                         if (loglevel & CPU_LOG_TB_IN_ASM) {
                             fprintf(logfile, "Servicing hardware INT=0x%02x\n", intno);
@@ -414,6 +421,25 @@ int cpu_exec(CPUState *env1)
                         tmp_T0 = 0;
 #else
                         T0 = 0;
+#endif
+#if !defined(CONFIG_USER_ONLY)
+                    } else if ((interrupt_request & CPU_INTERRUPT_VIRQ) &&
+                        (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
+                         int intno;
+                         /* FIXME: this should respect TPR */
+                         env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
+                         svm_check_intercept(SVM_EXIT_VINTR);
+                         intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
+                         if (loglevel & CPU_LOG_TB_IN_ASM)
+                             fprintf(logfile, "Servicing virtual hardware INT=0x%02x\n", intno);
+                        do_interrupt(intno, 0, 0, -1, 1);
+                         stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl),
+                                  ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl)) & ~V_IRQ_MASK);
+#if defined(__sparc__) && !defined(HOST_SOLARIS)
+                         tmp_T0 = 0;
+#else
+                         T0 = 0;
+#endif
 #endif
                     }
 #elif defined(TARGET_PPC)
@@ -565,7 +591,7 @@ int cpu_exec(CPUState *env1)
 #endif
 #if defined(__sparc__) && !defined(HOST_SOLARIS)
                 T0 = tmp_T0;
-#endif    
+#endif
                 /* see if we can patch the calling TB. When the TB
                    spans two pages, we cannot safely do a direct
                    jump. */
@@ -796,7 +822,7 @@ void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32)
 
     saved_env = env;
     env = s;
-   
+
     helper_fsave((target_ulong)ptr, data32);
 
     env = saved_env;
@@ -808,7 +834,7 @@ void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32)
 
     saved_env = env;
     env = s;
-   
+
     helper_frstor((target_ulong)ptr, data32);
 
     env = saved_env;
@@ -953,7 +979,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
 {
     TranslationBlock *tb;
     int ret;
-   
+
     if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */
 #if defined(DEBUG_SIGNAL)
@@ -1042,7 +1068,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
 {
     TranslationBlock *tb;
     int ret;
-   
+
     if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */
 #if defined(DEBUG_SIGNAL)
@@ -1092,7 +1118,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
 {
     TranslationBlock *tb;
     int ret;
-   
+
     if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */
 #if defined(DEBUG_SIGNAL)
@@ -1137,7 +1163,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
 {
     TranslationBlock *tb;
     int ret;
-   
+
     if (cpu_single_env)
         env = cpu_single_env; /* XXX: find a correct solution for multithread */
 #if defined(DEBUG_SIGNAL)
@@ -1371,7 +1397,7 @@ int cpu_signal_handler(int host_signum, void *pinfo,
     unsigned long pc;
     int is_write;
     uint32_t insn;
-   
+
     /* XXX: is there a standard glibc define ? */
     pc = regs[1];
     /* XXX: need kernel patch to get write flag faster */
@@ -1403,7 +1429,7 @@ int cpu_signal_handler(int host_signum, void *pinfo,
     struct ucontext *uc = puc;
     unsigned long pc;
     int is_write;
-   
+
     pc = uc->uc_mcontext.gregs[R15];
     /* XXX: compute is_write */
     is_write = 0;
@@ -1421,7 +1447,7 @@ int cpu_signal_handler(int host_signum, void *pinfo,
     struct ucontext *uc = puc;
     unsigned long pc;
     int is_write;
-   
+
     pc = uc->uc_mcontext.gregs[16];
     /* XXX: compute is_write */
     is_write = 0;
@@ -1473,7 +1499,7 @@ int cpu_signal_handler(int host_signum, void *pinfo,
     struct ucontext *uc = puc;
     unsigned long pc;
     int is_write;
-   
+
     pc = uc->uc_mcontext.psw.addr;
     /* XXX: compute is_write */
     is_write = 0;
@@ -1490,7 +1516,7 @@ int cpu_signal_handler(int host_signum, void *pinfo,
     struct ucontext *uc = puc;
     greg_t pc = uc->uc_mcontext.pc;
     int is_write;
-   
+
     /* XXX: compute is_write */
     is_write = 0;
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,
This page took 0.027943 seconds and 4 git commands to generate.