Diff for /qemu/cpu-exec.c between versions 1.1.1.11 and 1.1.1.12

version 1.1.1.11, 2018/04/24 17:57:07 version 1.1.1.12, 2018/04/24 18:23:30
Line 21 Line 21
 #include "disas.h"  #include "disas.h"
 #include "tcg.h"  #include "tcg.h"
 #include "kvm.h"  #include "kvm.h"
   #include "qemu-barrier.h"
   
 #if !defined(CONFIG_SOFTMMU)  #if !defined(CONFIG_SOFTMMU)
 #undef EAX  #undef EAX
Line 56  int qemu_cpu_has_work(CPUState *env) Line 57  int qemu_cpu_has_work(CPUState *env)
   
 void cpu_loop_exit(void)  void cpu_loop_exit(void)
 {  {
     /* NOTE: the register at this point must be saved by hand because      env->current_tb = NULL;
        longjmp restore them */  
     regs_to_env();  
     longjmp(env->jmp_env, 1);      longjmp(env->jmp_env, 1);
 }  }
   
Line 83  void cpu_resume_from_signal(CPUState *en Line 82  void cpu_resume_from_signal(CPUState *en
     if (puc) {      if (puc) {
         /* XXX: use siglongjmp ? */          /* XXX: use siglongjmp ? */
 #ifdef __linux__  #ifdef __linux__
   #ifdef __ia64
           sigprocmask(SIG_SETMASK, (sigset_t *)&uc->uc_sigmask, NULL);
   #else
         sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);          sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
   #endif
 #elif defined(__OpenBSD__)  #elif defined(__OpenBSD__)
         sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);          sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
 #endif  #endif
Line 110  static void cpu_exec_nocache(int max_cyc Line 113  static void cpu_exec_nocache(int max_cyc
     env->current_tb = tb;      env->current_tb = tb;
     /* execute the generated code */      /* execute the generated code */
     next_tb = tcg_qemu_tb_exec(tb->tc_ptr);      next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
       env->current_tb = NULL;
   
     if ((next_tb & 3) == 2) {      if ((next_tb & 3) == 2) {
         /* Restore PC.  This may happen if async event occurs before          /* Restore PC.  This may happen if async event occurs before
Line 126  static TranslationBlock *tb_find_slow(ta Line 130  static TranslationBlock *tb_find_slow(ta
 {  {
     TranslationBlock *tb, **ptb1;      TranslationBlock *tb, **ptb1;
     unsigned int h;      unsigned int h;
     target_ulong phys_pc, phys_page1, phys_page2, virt_page2;      tb_page_addr_t phys_pc, phys_page1, phys_page2;
       target_ulong virt_page2;
   
     tb_invalidated_flag = 0;      tb_invalidated_flag = 0;
   
     regs_to_env(); /* XXX: do it just before cpu_gen_code() */  
   
     /* find translated block using physical mappings */      /* find translated block using physical mappings */
     phys_pc = get_phys_addr_code(env, pc);      phys_pc = get_page_addr_code(env, pc);
     phys_page1 = phys_pc & TARGET_PAGE_MASK;      phys_page1 = phys_pc & TARGET_PAGE_MASK;
     phys_page2 = -1;      phys_page2 = -1;
     h = tb_phys_hash_func(phys_pc);      h = tb_phys_hash_func(phys_pc);
Line 150  static TranslationBlock *tb_find_slow(ta Line 153  static TranslationBlock *tb_find_slow(ta
             if (tb->page_addr[1] != -1) {              if (tb->page_addr[1] != -1) {
                 virt_page2 = (pc & TARGET_PAGE_MASK) +                  virt_page2 = (pc & TARGET_PAGE_MASK) +
                     TARGET_PAGE_SIZE;                      TARGET_PAGE_SIZE;
                 phys_page2 = get_phys_addr_code(env, virt_page2);                  phys_page2 = get_page_addr_code(env, virt_page2);
                 if (tb->page_addr[1] == phys_page2)                  if (tb->page_addr[1] == phys_page2)
                     goto found;                      goto found;
             } else {              } else {
Line 211  static void cpu_handle_debug_exception(C Line 214  static void cpu_handle_debug_exception(C
   
 /* main execution loop */  /* main execution loop */
   
   volatile sig_atomic_t exit_request;
   
 int cpu_exec(CPUState *env1)  int cpu_exec(CPUState *env1)
 {  {
 #define DECLARE_HOST_REGS 1      volatile host_reg_t saved_env_reg;
 #include "hostregs_helper.h"  
     int ret, interrupt_request;      int ret, interrupt_request;
     TranslationBlock *tb;      TranslationBlock *tb;
     uint8_t *tc_ptr;      uint8_t *tc_ptr;
Line 225  int cpu_exec(CPUState *env1) Line 229  int cpu_exec(CPUState *env1)
   
     cpu_single_env = env1;      cpu_single_env = env1;
   
     /* first we save global registers */      /* the access to env below is actually saving the global register's
 #define SAVE_HOST_REGS 1         value, so that files not including target-xyz/exec.h are free to
 #include "hostregs_helper.h"         use it.  */
       QEMU_BUILD_BUG_ON (sizeof (saved_env_reg) != sizeof (env));
       saved_env_reg = (host_reg_t) env;
       barrier();
     env = env1;      env = env1;
   
     env_to_regs();      if (unlikely(exit_request)) {
           env->exit_request = 1;
       }
   
 #if defined(TARGET_I386)  #if defined(TARGET_I386)
     if (!kvm_enabled()) {      if (!kvm_enabled()) {
         /* put eflags in CPU temporary format */          /* put eflags in CPU temporary format */
Line 266  int cpu_exec(CPUState *env1) Line 276  int cpu_exec(CPUState *env1)
                     env = cpu_single_env;                      env = cpu_single_env;
 #define env cpu_single_env  #define env cpu_single_env
 #endif  #endif
             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) {
                 if (env->exception_index >= EXCP_INTERRUPT) {                  if (env->exception_index >= EXCP_INTERRUPT) {
Line 320  int cpu_exec(CPUState *env1) Line 329  int cpu_exec(CPUState *env1)
 #elif defined(TARGET_M68K)  #elif defined(TARGET_M68K)
                     do_interrupt(0);                      do_interrupt(0);
 #endif  #endif
                       env->exception_index = -1;
 #endif  #endif
                 }                  }
                 env->exception_index = -1;  
             }              }
   
             if (kvm_enabled()) {              if (kvm_enabled()) {
Line 451  int cpu_exec(CPUState *env1) Line 460  int cpu_exec(CPUState *env1)
                         next_tb = 0;                          next_tb = 0;
                     }                      }
 #elif defined(TARGET_SPARC)  #elif defined(TARGET_SPARC)
                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&                      if (interrupt_request & CPU_INTERRUPT_HARD) {
                         cpu_interrupts_enabled(env)) {                          if (cpu_interrupts_enabled(env) &&
                         int pil = env->interrupt_index & 15;                              env->interrupt_index > 0) {
                         int type = env->interrupt_index & 0xf0;                              int pil = env->interrupt_index & 0xf;
                               int type = env->interrupt_index & 0xf0;
                         if (((type == TT_EXTINT) &&  
                              (pil == 15 || pil > env->psrpil)) ||                              if (((type == TT_EXTINT) &&
                             type != TT_EXTINT) {                                    cpu_pil_allowed(env, pil)) ||
                             env->interrupt_request &= ~CPU_INTERRUPT_HARD;                                    type != TT_EXTINT) {
                             env->exception_index = env->interrupt_index;                                  env->exception_index = env->interrupt_index;
                             do_interrupt(env);                                  do_interrupt(env);
                             env->interrupt_index = 0;                                  next_tb = 0;
                         next_tb = 0;                              }
                         }                          }
                     } else if (interrupt_request & CPU_INTERRUPT_TIMER) {                      } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
                         //do_interrupt(0, 0, 0, 0, 0);                          //do_interrupt(0, 0, 0, 0, 0);
                         env->interrupt_request &= ~CPU_INTERRUPT_TIMER;                          env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
Line 504  int cpu_exec(CPUState *env1) Line 513  int cpu_exec(CPUState *env1)
                     }                      }
 #elif defined(TARGET_CRIS)  #elif defined(TARGET_CRIS)
                     if (interrupt_request & CPU_INTERRUPT_HARD                      if (interrupt_request & CPU_INTERRUPT_HARD
                         && (env->pregs[PR_CCS] & I_FLAG)) {                          && (env->pregs[PR_CCS] & I_FLAG)
                           && !env->locked_irq) {
                         env->exception_index = EXCP_IRQ;                          env->exception_index = EXCP_IRQ;
                         do_interrupt(env);                          do_interrupt(env);
                         next_tb = 0;                          next_tb = 0;
Line 543  int cpu_exec(CPUState *env1) Line 553  int cpu_exec(CPUState *env1)
                     env->exception_index = EXCP_INTERRUPT;                      env->exception_index = EXCP_INTERRUPT;
                     cpu_loop_exit();                      cpu_loop_exit();
                 }                  }
 #ifdef CONFIG_DEBUG_EXEC  #if defined(DEBUG_DISAS) || defined(CONFIG_DEBUG_EXEC)
                 if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {                  if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
                     /* restore flags in standard format */                      /* restore flags in standard format */
                     regs_to_env();  
 #if defined(TARGET_I386)  #if defined(TARGET_I386)
                     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);
                     log_cpu_state(env, X86_DUMP_CCOP);                      log_cpu_state(env, X86_DUMP_CCOP);
                     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);                      env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
 #elif defined(TARGET_ARM)  
                     log_cpu_state(env, 0);  
 #elif defined(TARGET_SPARC)  
                     log_cpu_state(env, 0);  
 #elif defined(TARGET_PPC)  
                     log_cpu_state(env, 0);  
 #elif defined(TARGET_M68K)  #elif defined(TARGET_M68K)
                     cpu_m68k_flush_flags(env, env->cc_op);                      cpu_m68k_flush_flags(env, env->cc_op);
                     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);
                     log_cpu_state(env, 0);                      log_cpu_state(env, 0);
 #elif defined(TARGET_MICROBLAZE)  
                     log_cpu_state(env, 0);  
 #elif defined(TARGET_MIPS)  
                     log_cpu_state(env, 0);  
 #elif defined(TARGET_SH4)  
                     log_cpu_state(env, 0);  
 #elif defined(TARGET_ALPHA)  
                     log_cpu_state(env, 0);  
 #elif defined(TARGET_CRIS)  
                     log_cpu_state(env, 0);  
 #else  #else
 #error unsupported target CPU                      log_cpu_state(env, 0);
 #endif  #endif
                 }                  }
 #endif  #endif /* DEBUG_DISAS || CONFIG_DEBUG_EXEC */
                 spin_lock(&tb_lock);                  spin_lock(&tb_lock);
                 tb = tb_find_fast();                  tb = tb_find_fast();
                 /* Note: we do it here to avoid a gcc bug on Mac OS X when                  /* Note: we do it here to avoid a gcc bug on Mac OS X when
Line 597  int cpu_exec(CPUState *env1) Line 590  int cpu_exec(CPUState *env1)
                 /* see if we can patch the calling TB. When the TB                  /* see if we can patch the calling TB. When the TB
                    spans two pages, we cannot safely do a direct                     spans two pages, we cannot safely do a direct
                    jump. */                     jump. */
                 {                  if (next_tb != 0 && tb->page_addr[1] == -1) {
                     if (next_tb != 0 && tb->page_addr[1] == -1) {  
                     tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);                      tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
                 }                  }
                 }  
                 spin_unlock(&tb_lock);                  spin_unlock(&tb_lock);
                 env->current_tb = tb;  
   
                 /* cpu_interrupt might be called while translating the                  /* cpu_interrupt might be called while translating the
                    TB, but before it is linked into a potentially                     TB, but before it is linked into a potentially
                    infinite loop and becomes env->current_tb. Avoid                     infinite loop and becomes env->current_tb. Avoid
                    starting execution if there is a pending interrupt. */                     starting execution if there is a pending interrupt. */
                 if (unlikely (env->exit_request))                  env->current_tb = tb;
                     env->current_tb = NULL;                  barrier();
                   if (likely(!env->exit_request)) {
                 while (env->current_tb) {  
                     tc_ptr = tb->tc_ptr;                      tc_ptr = tb->tc_ptr;
                 /* execute the generated code */                  /* execute the generated code */
 #if defined(__sparc__) && !defined(CONFIG_SOLARIS)  #if defined(__sparc__) && !defined(CONFIG_SOLARIS)
Line 621  int cpu_exec(CPUState *env1) Line 610  int cpu_exec(CPUState *env1)
 #define env cpu_single_env  #define env cpu_single_env
 #endif  #endif
                     next_tb = tcg_qemu_tb_exec(tc_ptr);                      next_tb = tcg_qemu_tb_exec(tc_ptr);
                     env->current_tb = NULL;  
                     if ((next_tb & 3) == 2) {                      if ((next_tb & 3) == 2) {
                         /* Instruction counter expired.  */                          /* Instruction counter expired.  */
                         int insns_left;                          int insns_left;
Line 650  int cpu_exec(CPUState *env1) Line 638  int cpu_exec(CPUState *env1)
                         }                          }
                     }                      }
                 }                  }
                   env->current_tb = NULL;
                 /* 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) */
             } /* for(;;) */              } /* for(;;) */
         } else {  
             env_to_regs();  
         }          }
     } /* for(;;) */      } /* for(;;) */
   
Line 683  int cpu_exec(CPUState *env1) Line 670  int cpu_exec(CPUState *env1)
 #endif  #endif
   
     /* restore global registers */      /* restore global registers */
 #include "hostregs_helper.h"      barrier();
       env = (void *) saved_env_reg;
   
     /* fail safe : never use cpu_single_env outside cpu_exec() */      /* fail safe : never use cpu_single_env outside cpu_exec() */
     cpu_single_env = NULL;      cpu_single_env = NULL;
Line 935  int cpu_signal_handler(int host_signum,  Line 923  int cpu_signal_handler(int host_signum, 
 # define TRAP_sig(context)                      REG_sig(trap, context)  # define TRAP_sig(context)                      REG_sig(trap, context)
 #endif /* linux */  #endif /* linux */
   
   #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
   #include <ucontext.h>
   # define IAR_sig(context)               ((context)->uc_mcontext.mc_srr0)
   # define MSR_sig(context)               ((context)->uc_mcontext.mc_srr1)
   # define CTR_sig(context)               ((context)->uc_mcontext.mc_ctr)
   # define XER_sig(context)               ((context)->uc_mcontext.mc_xer)
   # define LR_sig(context)                ((context)->uc_mcontext.mc_lr)
   # define CR_sig(context)                ((context)->uc_mcontext.mc_cr)
   /* Exception Registers access */
   # define DAR_sig(context)               ((context)->uc_mcontext.mc_dar)
   # define DSISR_sig(context)             ((context)->uc_mcontext.mc_dsisr)
   # define TRAP_sig(context)              ((context)->uc_mcontext.mc_exc)
   #endif /* __FreeBSD__|| __FreeBSD_kernel__ */
   
 #ifdef __APPLE__  #ifdef __APPLE__
 # include <sys/ucontext.h>  # include <sys/ucontext.h>
 typedef struct ucontext SIGCONTEXT;  typedef struct ucontext SIGCONTEXT;
Line 964  int cpu_signal_handler(int host_signum,  Line 966  int cpu_signal_handler(int host_signum, 
                        void *puc)                         void *puc)
 {  {
     siginfo_t *info = pinfo;      siginfo_t *info = pinfo;
   #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
       ucontext_t *uc = puc;
   #else
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
   #endif
     unsigned long pc;      unsigned long pc;
     int is_write;      int is_write;
   
Line 1140  int cpu_signal_handler(int host_signum,  Line 1146  int cpu_signal_handler(int host_signum, 
     }      }
     return handle_cpu_signal(ip, (unsigned long)info->si_addr,      return handle_cpu_signal(ip, (unsigned long)info->si_addr,
                              is_write,                               is_write,
                              &uc->uc_sigmask, puc);                               (sigset_t *)&uc->uc_sigmask, puc);
 }  }
   
 #elif defined(__s390__)  #elif defined(__s390__)
Line 1151  int cpu_signal_handler(int host_signum,  Line 1157  int cpu_signal_handler(int host_signum, 
     siginfo_t *info = pinfo;      siginfo_t *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     unsigned long pc;      unsigned long pc;
     int is_write;      uint16_t *pinsn;
       int is_write = 0;
   
     pc = uc->uc_mcontext.psw.addr;      pc = uc->uc_mcontext.psw.addr;
     /* XXX: compute is_write */  
     is_write = 0;      /* ??? On linux, the non-rt signal handler has 4 (!) arguments instead
          of the normal 2 arguments.  The 3rd argument contains the "int_code"
          from the hardware which does in fact contain the is_write value.
          The rt signal handler, as far as I can tell, does not give this value
          at all.  Not that we could get to it from here even if it were.  */
       /* ??? This is not even close to complete, since it ignores all
          of the read-modify-write instructions.  */
       pinsn = (uint16_t *)pc;
       switch (pinsn[0] >> 8) {
       case 0x50: /* ST */
       case 0x42: /* STC */
       case 0x40: /* STH */
           is_write = 1;
           break;
       case 0xc4: /* RIL format insns */
           switch (pinsn[0] & 0xf) {
           case 0xf: /* STRL */
           case 0xb: /* STGRL */
           case 0x7: /* STHRL */
               is_write = 1;
           }
           break;
       case 0xe3: /* RXY format insns */
           switch (pinsn[2] & 0xff) {
           case 0x50: /* STY */
           case 0x24: /* STG */
           case 0x72: /* STCY */
           case 0x70: /* STHY */
           case 0x8e: /* STPQ */
           case 0x3f: /* STRVH */
           case 0x3e: /* STRV */
           case 0x2f: /* STRVG */
               is_write = 1;
           }
           break;
       }
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,      return handle_cpu_signal(pc, (unsigned long)info->si_addr,
                              is_write, &uc->uc_sigmask, puc);                               is_write, &uc->uc_sigmask, puc);
 }  }
Line 1183  int cpu_signal_handler(int host_signum,  Line 1225  int cpu_signal_handler(int host_signum, 
 {  {
     struct siginfo *info = pinfo;      struct siginfo *info = pinfo;
     struct ucontext *uc = puc;      struct ucontext *uc = puc;
     unsigned long pc;      unsigned long pc = uc->uc_mcontext.sc_iaoq[0];
     int is_write;      uint32_t insn = *(uint32_t *)pc;
       int is_write = 0;
   
       /* XXX: need kernel patch to get write flag faster.  */
       switch (insn >> 26) {
       case 0x1a: /* STW */
       case 0x19: /* STH */
       case 0x18: /* STB */
       case 0x1b: /* STWM */
           is_write = 1;
           break;
   
       case 0x09: /* CSTWX, FSTWX, FSTWS */
       case 0x0b: /* CSTDX, FSTDX, FSTDS */
           /* Distinguish from coprocessor load ... */
           is_write = (insn >> 9) & 1;
           break;
   
       case 0x03:
           switch ((insn >> 6) & 15) {
           case 0xa: /* STWS */
           case 0x9: /* STHS */
           case 0x8: /* STBS */
           case 0xe: /* STWAS */
           case 0xc: /* STBYS */
               is_write = 1;
           }
           break;
       }
   
     pc = uc->uc_mcontext.sc_iaoq[0];  
     /* FIXME: compute is_write */  
     is_write = 0;  
     return handle_cpu_signal(pc, (unsigned long)info->si_addr,       return handle_cpu_signal(pc, (unsigned long)info->si_addr, 
                              is_write,                               is_write, &uc->uc_sigmask, puc);
                              &uc->uc_sigmask, puc);  
 }  }
   
 #else  #else

Removed from v.1.1.1.11  
changed lines
  Added in v.1.1.1.12


unix.superglobalmegacorp.com