Diff for /qemu/cpu-exec.c between versions 1.1.1.8 and 1.1.1.9

version 1.1.1.8, 2018/04/24 16:56:15 version 1.1.1.9, 2018/04/24 17:20:28
Line 14 Line 14
  * Lesser General Public License for more details.   * Lesser General Public License for more details.
  *   *
  * You should have received a copy of the GNU Lesser General Public   * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software   * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA  
  */   */
 #include "config.h"  #include "config.h"
 #define CPU_NO_GLOBAL_REGS  
 #include "exec.h"  #include "exec.h"
 #include "disas.h"  #include "disas.h"
 #include "tcg.h"  #include "tcg.h"
Line 51  int tb_invalidated_flag; Line 49  int tb_invalidated_flag;
 //#define DEBUG_EXEC  //#define DEBUG_EXEC
 //#define DEBUG_SIGNAL  //#define DEBUG_SIGNAL
   
   int qemu_cpu_has_work(CPUState *env)
   {
       return cpu_has_work(env);
   }
   
 void cpu_loop_exit(void)  void cpu_loop_exit(void)
 {  {
     /* NOTE: the register at this point must be saved by hand because      /* NOTE: the register at this point must be saved by hand because
Line 242  int cpu_exec(CPUState *env1) Line 245  int cpu_exec(CPUState *env1)
 #elif defined(TARGET_ALPHA)  #elif defined(TARGET_ALPHA)
 #elif defined(TARGET_ARM)  #elif defined(TARGET_ARM)
 #elif defined(TARGET_PPC)  #elif defined(TARGET_PPC)
   #elif defined(TARGET_MICROBLAZE)
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
 #elif defined(TARGET_SH4)  #elif defined(TARGET_SH4)
 #elif defined(TARGET_CRIS)  #elif defined(TARGET_CRIS)
Line 254  int cpu_exec(CPUState *env1) Line 258  int cpu_exec(CPUState *env1)
     /* prepare setjmp context for exception handling */      /* prepare setjmp context for exception handling */
     for(;;) {      for(;;) {
         if (setjmp(env->jmp_env) == 0) {          if (setjmp(env->jmp_env) == 0) {
   #if defined(__sparc__) && !defined(HOST_SOLARIS)
   #undef env
                       env = cpu_single_env;
   #define env cpu_single_env
   #endif
             env->current_tb = NULL;              env->current_tb = NULL;
             /* if an exception is pending, we execute it here */              /* if an exception is pending, we execute it here */
             if (env->exception_index >= 0) {              if (env->exception_index >= 0) {
Line 291  int cpu_exec(CPUState *env1) Line 300  int cpu_exec(CPUState *env1)
                     env->old_exception = -1;                      env->old_exception = -1;
 #elif defined(TARGET_PPC)  #elif defined(TARGET_PPC)
                     do_interrupt(env);                      do_interrupt(env);
   #elif defined(TARGET_MICROBLAZE)
                       do_interrupt(env);
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
                     do_interrupt(env);                      do_interrupt(env);
 #elif defined(TARGET_SPARC)  #elif defined(TARGET_SPARC)
Line 310  int cpu_exec(CPUState *env1) Line 321  int cpu_exec(CPUState *env1)
                 }                  }
                 env->exception_index = -1;                  env->exception_index = -1;
             }              }
 #ifdef USE_KQEMU  #ifdef CONFIG_KQEMU
             if (kqemu_is_ok(env) && env->interrupt_request == 0 && env->exit_request == 0) {              if (kqemu_is_ok(env) && env->interrupt_request == 0 && env->exit_request == 0) {
                 int ret;                  int ret;
                 env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);                  env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
Line 358  int cpu_exec(CPUState *env1) Line 369  int cpu_exec(CPUState *env1)
                         cpu_loop_exit();                          cpu_loop_exit();
                     }                      }
 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \  #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
     defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS)      defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
       defined(TARGET_MICROBLAZE)
                     if (interrupt_request & CPU_INTERRUPT_HALT) {                      if (interrupt_request & CPU_INTERRUPT_HALT) {
                         env->interrupt_request &= ~CPU_INTERRUPT_HALT;                          env->interrupt_request &= ~CPU_INTERRUPT_HALT;
                         env->halted = 1;                          env->halted = 1;
Line 367  int cpu_exec(CPUState *env1) Line 379  int cpu_exec(CPUState *env1)
                     }                      }
 #endif  #endif
 #if defined(TARGET_I386)  #if defined(TARGET_I386)
                     if (env->hflags2 & HF2_GIF_MASK) {                      if (interrupt_request & CPU_INTERRUPT_INIT) {
                               svm_check_intercept(SVM_EXIT_INIT);
                               do_cpu_init(env);
                               env->exception_index = EXCP_HALTED;
                               cpu_loop_exit();
                       } else if (interrupt_request & CPU_INTERRUPT_SIPI) {
                               do_cpu_sipi(env);
                       } else if (env->hflags2 & HF2_GIF_MASK) {
                         if ((interrupt_request & CPU_INTERRUPT_SMI) &&                          if ((interrupt_request & CPU_INTERRUPT_SMI) &&
                             !(env->hflags & HF_SMM_MASK)) {                              !(env->hflags & HF_SMM_MASK)) {
                             svm_check_intercept(SVM_EXIT_SMI);                              svm_check_intercept(SVM_EXIT_SMI);
Line 380  int cpu_exec(CPUState *env1) Line 399  int cpu_exec(CPUState *env1)
                             env->hflags2 |= HF2_NMI_MASK;                              env->hflags2 |= HF2_NMI_MASK;
                             do_interrupt(EXCP02_NMI, 0, 0, 0, 1);                              do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
                             next_tb = 0;                              next_tb = 0;
                           } else if (interrupt_request & CPU_INTERRUPT_MCE) {
                               env->interrupt_request &= ~CPU_INTERRUPT_MCE;
                               do_interrupt(EXCP12_MCHK, 0, 0, 0, 0);
                               next_tb = 0;
                         } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&                          } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
                                    (((env->hflags2 & HF2_VINTR_MASK) &&                                      (((env->hflags2 & HF2_VINTR_MASK) && 
                                      (env->hflags2 & HF2_HIF_MASK)) ||                                       (env->hflags2 & HF2_HIF_MASK)) ||
Line 391  int cpu_exec(CPUState *env1) Line 414  int cpu_exec(CPUState *env1)
                             env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);                              env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
                             intno = cpu_get_pic_interrupt(env);                              intno = cpu_get_pic_interrupt(env);
                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);                              qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
   #if defined(__sparc__) && !defined(HOST_SOLARIS)
   #undef env
                       env = cpu_single_env;
   #define env cpu_single_env
   #endif
                             do_interrupt(intno, 0, 0, 0, 1);                              do_interrupt(intno, 0, 0, 0, 1);
                             /* ensure that no TB jump will be modified as                              /* ensure that no TB jump will be modified as
                                the program flow was changed */                                 the program flow was changed */
Line 422  int cpu_exec(CPUState *env1) Line 450  int cpu_exec(CPUState *env1)
                             env->interrupt_request &= ~CPU_INTERRUPT_HARD;                              env->interrupt_request &= ~CPU_INTERRUPT_HARD;
                         next_tb = 0;                          next_tb = 0;
                     }                      }
   #elif defined(TARGET_MICROBLAZE)
                       if ((interrupt_request & CPU_INTERRUPT_HARD)
                           && (env->sregs[SR_MSR] & MSR_IE)
                           && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
                           && !(env->iflags & (D_FLAG | IMM_FLAG))) {
                           env->exception_index = EXCP_IRQ;
                           do_interrupt(env);
                           next_tb = 0;
                       }
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&                      if ((interrupt_request & CPU_INTERRUPT_HARD) &&
                         (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&                          (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
Line 437  int cpu_exec(CPUState *env1) Line 474  int cpu_exec(CPUState *env1)
                     }                      }
 #elif defined(TARGET_SPARC)  #elif defined(TARGET_SPARC)
                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&                      if ((interrupt_request & CPU_INTERRUPT_HARD) &&
                         (env->psret != 0)) {                          cpu_interrupts_enabled(env)) {
                         int pil = env->interrupt_index & 15;                          int pil = env->interrupt_index & 15;
                         int type = env->interrupt_index & 0xf0;                          int type = env->interrupt_index & 0xf0;
   
Line 448  int cpu_exec(CPUState *env1) Line 485  int cpu_exec(CPUState *env1)
                             env->exception_index = env->interrupt_index;                              env->exception_index = env->interrupt_index;
                             do_interrupt(env);                              do_interrupt(env);
                             env->interrupt_index = 0;                              env->interrupt_index = 0;
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)  #if !defined(CONFIG_USER_ONLY)
                             cpu_check_irqs(env);                              cpu_check_irqs(env);
 #endif  #endif
                         next_tb = 0;                          next_tb = 0;
Line 551  int cpu_exec(CPUState *env1) Line 588  int cpu_exec(CPUState *env1)
                     env->sr = (env->sr & 0xffe0)                      env->sr = (env->sr & 0xffe0)
                               | env->cc_dest | (env->cc_x << 4);                                | env->cc_dest | (env->cc_x << 4);
                     log_cpu_state(env, 0);                      log_cpu_state(env, 0);
   #elif defined(TARGET_MICROBLAZE)
                       log_cpu_state(env, 0);
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
                     log_cpu_state(env, 0);                      log_cpu_state(env, 0);
 #elif defined(TARGET_SH4)  #elif defined(TARGET_SH4)
Line 585  int cpu_exec(CPUState *env1) Line 624  int cpu_exec(CPUState *env1)
                    jump. */                     jump. */
                 {                  {
                     if (next_tb != 0 &&                      if (next_tb != 0 &&
 #ifdef USE_KQEMU  #ifdef CONFIG_KQEMU
                         (env->kqemu_enabled != 2) &&                          (env->kqemu_enabled != 2) &&
 #endif  #endif
                         tb->page_addr[1] == -1) {                          tb->page_addr[1] == -1) {
Line 642  int cpu_exec(CPUState *env1) Line 681  int cpu_exec(CPUState *env1)
                 }                  }
                 /* reset soft MMU for next block (it can currently                  /* reset soft MMU for next block (it can currently
                    only be set by a memory fault) */                     only be set by a memory fault) */
 #if defined(USE_KQEMU)  #if defined(CONFIG_KQEMU)
 #define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)  #define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
                 if (kqemu_is_ok(env) &&                  if (kqemu_is_ok(env) &&
                     (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {                      (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
Line 668  int cpu_exec(CPUState *env1) Line 707  int cpu_exec(CPUState *env1)
     env->cc_op = CC_OP_FLAGS;      env->cc_op = CC_OP_FLAGS;
     env->sr = (env->sr & 0xffe0)      env->sr = (env->sr & 0xffe0)
               | env->cc_dest | (env->cc_x << 4);                | env->cc_dest | (env->cc_x << 4);
   #elif defined(TARGET_MICROBLAZE)
 #elif defined(TARGET_MIPS)  #elif defined(TARGET_MIPS)
 #elif defined(TARGET_SH4)  #elif defined(TARGET_SH4)
 #elif defined(TARGET_ALPHA)  #elif defined(TARGET_ALPHA)
Line 1014  static inline int handle_cpu_signal(unsi Line 1054  static inline int handle_cpu_signal(unsi
     return 1;      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)  #elif defined (TARGET_SH4)
 static inline int handle_cpu_signal(unsigned long pc, unsigned long address,  static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
                                     int is_write, sigset_t *old_set,                                      int is_write, sigset_t *old_set,
Line 1156  static inline int handle_cpu_signal(unsi Line 1246  static inline int handle_cpu_signal(unsi
 # define EIP_sig(context)  (*((unsigned long*)&(context)->uc_mcontext->ss.eip))  # define EIP_sig(context)  (*((unsigned long*)&(context)->uc_mcontext->ss.eip))
 # define TRAP_sig(context)    ((context)->uc_mcontext->es.trapno)  # define TRAP_sig(context)    ((context)->uc_mcontext->es.trapno)
 # define ERROR_sig(context)   ((context)->uc_mcontext->es.err)  # define ERROR_sig(context)   ((context)->uc_mcontext->es.err)
   # define MASK_sig(context)    ((context)->uc_sigmask)
   #elif defined(__OpenBSD__)
   # define EIP_sig(context)     ((context)->sc_eip)
   # define TRAP_sig(context)    ((context)->sc_trapno)
   # define ERROR_sig(context)   ((context)->sc_err)
   # define MASK_sig(context)    ((context)->sc_mask)
 #else  #else
 # define EIP_sig(context)     ((context)->uc_mcontext.gregs[REG_EIP])  # define EIP_sig(context)     ((context)->uc_mcontext.gregs[REG_EIP])
 # define TRAP_sig(context)    ((context)->uc_mcontext.gregs[REG_TRAPNO])  # define TRAP_sig(context)    ((context)->uc_mcontext.gregs[REG_TRAPNO])
 # define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])  # define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
   # define MASK_sig(context)    ((context)->uc_sigmask)
 #endif  #endif
   
 int cpu_signal_handler(int host_signum, void *pinfo,  int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)                         void *puc)
 {  {
     siginfo_t *info = pinfo;      siginfo_t *info = pinfo;
   #if defined(__OpenBSD__)
       struct sigcontext *uc = puc;
   #else
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
   #endif
     unsigned long pc;      unsigned long pc;
     int trapno;      int trapno;
   
Line 1181  int cpu_signal_handler(int host_signum,  Line 1282  int cpu_signal_handler(int host_signum, 
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,      return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              trapno == 0xe ?                               trapno == 0xe ?
                              (ERROR_sig(uc) >> 1) & 1 : 0,                               (ERROR_sig(uc) >> 1) & 1 : 0,
                              &uc->uc_sigmask, puc);                               &MASK_sig(uc), puc);
 }  }
   
 #elif defined(__x86_64__)  #elif defined(__x86_64__)
   
 #ifdef __NetBSD__  #ifdef __NetBSD__
 #define REG_ERR _REG_ERR  #define PC_sig(context)       _UC_MACHINE_PC(context)
 #define REG_TRAPNO _REG_TRAPNO  #define TRAP_sig(context)     ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
   #define ERROR_sig(context)    ((context)->uc_mcontext.__gregs[_REG_ERR])
 #define QEMU_UC_MCONTEXT_GREGS(uc, reg) (uc)->uc_mcontext.__gregs[(reg)]  #define MASK_sig(context)     ((context)->uc_sigmask)
 #define QEMU_UC_MACHINE_PC(uc)          _UC_MACHINE_PC(uc)  #elif defined(__OpenBSD__)
   #define PC_sig(context)       ((context)->sc_rip)
   #define TRAP_sig(context)     ((context)->sc_trapno)
   #define ERROR_sig(context)    ((context)->sc_err)
   #define MASK_sig(context)     ((context)->sc_mask)
 #else  #else
 #define QEMU_UC_MCONTEXT_GREGS(uc, reg) (uc)->uc_mcontext.gregs[(reg)]  #define PC_sig(context)       ((context)->uc_mcontext.gregs[REG_RIP])
 #define QEMU_UC_MACHINE_PC(uc)          QEMU_UC_MCONTEXT_GREGS(uc, REG_RIP)  #define TRAP_sig(context)     ((context)->uc_mcontext.gregs[REG_TRAPNO])
   #define ERROR_sig(context)    ((context)->uc_mcontext.gregs[REG_ERR])
   #define MASK_sig(context)     ((context)->uc_sigmask)
 #endif  #endif
   
 int cpu_signal_handler(int host_signum, void *pinfo,  int cpu_signal_handler(int host_signum, void *pinfo,
Line 1204  int cpu_signal_handler(int host_signum,  Line 1311  int cpu_signal_handler(int host_signum, 
     unsigned long pc;      unsigned long pc;
 #ifdef __NetBSD__  #ifdef __NetBSD__
     ucontext_t *uc = puc;      ucontext_t *uc = puc;
   #elif defined(__OpenBSD__)
       struct sigcontext *uc = puc;
 #else  #else
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
 #endif  #endif
   
     pc = QEMU_UC_MACHINE_PC(uc);      pc = PC_sig(uc);
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,      return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              QEMU_UC_MCONTEXT_GREGS(uc, REG_TRAPNO) == 0xe ?                               TRAP_sig(uc) == 0xe ?
                              (QEMU_UC_MCONTEXT_GREGS(uc, REG_ERR) >> 1) & 1 : 0,                               (ERROR_sig(uc) >> 1) & 1 : 0,
                              &uc->uc_sigmask, puc);                               &MASK_sig(uc), puc);
 }  }
   
 #elif defined(_ARCH_PPC)  #elif defined(_ARCH_PPC)
Line 1349  int cpu_signal_handler(int host_signum,  Line 1458  int cpu_signal_handler(int host_signum, 
     if ((insn >> 30) == 3) {      if ((insn >> 30) == 3) {
       switch((insn >> 19) & 0x3f) {        switch((insn >> 19) & 0x3f) {
       case 0x05: // stb        case 0x05: // stb
         case 0x15: // stba
       case 0x06: // sth        case 0x06: // sth
         case 0x16: // stha
       case 0x04: // st        case 0x04: // st
         case 0x14: // sta
       case 0x07: // std        case 0x07: // std
         case 0x17: // stda
         case 0x0e: // stx
         case 0x1e: // stxa
       case 0x24: // stf        case 0x24: // stf
         case 0x34: // stfa
       case 0x27: // stdf        case 0x27: // stdf
         case 0x37: // stdfa
         case 0x26: // stqf
         case 0x36: // stqfa
       case 0x25: // stfsr        case 0x25: // stfsr
         case 0x3c: // casa
         case 0x3e: // casxa
         is_write = 1;          is_write = 1;
         break;          break;
       }        }

Removed from v.1.1.1.8  
changed lines
  Added in v.1.1.1.9


unix.superglobalmegacorp.com