--- qemu/cpu-exec.c 2018/04/24 16:42:36 1.1.1.4 +++ qemu/cpu-exec.c 2018/04/24 16:44:47 1.1.1.5 @@ -40,14 +40,14 @@ int tb_invalidated_flag; //#define DEBUG_EXEC //#define DEBUG_SIGNAL -#if defined(TARGET_ARM) || defined(TARGET_SPARC) +#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_M68K) /* XXX: unify with i386 target */ void cpu_loop_exit(void) { longjmp(env->jmp_env, 1); } #endif -#if !(defined(TARGET_SPARC) || defined(TARGET_SH4)) +#if !(defined(TARGET_SPARC) || defined(TARGET_SH4) || defined(TARGET_M68K)) #define reg_T2 #endif @@ -194,6 +194,10 @@ static inline TranslationBlock *tb_find_ flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK); cs_base = 0; pc = env->PC; +#elif defined(TARGET_M68K) + flags = env->fpcr & M68K_FPCR_PREC; + cs_base = 0; + pc = env->pc; #elif defined(TARGET_SH4) flags = env->sr & (SR_MD | SR_RB); cs_base = 0; /* XXXXX */ @@ -222,43 +226,16 @@ static inline TranslationBlock *tb_find_ int cpu_exec(CPUState *env1) { - int saved_T0, saved_T1; -#if defined(reg_T2) - int saved_T2; -#endif - CPUState *saved_env; -#if defined(TARGET_I386) -#ifdef reg_EAX - int saved_EAX; -#endif -#ifdef reg_ECX - int saved_ECX; -#endif -#ifdef reg_EDX - int saved_EDX; -#endif -#ifdef reg_EBX - int saved_EBX; -#endif -#ifdef reg_ESP - int saved_ESP; -#endif -#ifdef reg_EBP - int saved_EBP; -#endif -#ifdef reg_ESI - int saved_ESI; -#endif -#ifdef reg_EDI - int saved_EDI; -#endif -#elif defined(TARGET_SPARC) +#define DECLARE_HOST_REGS 1 +#include "hostregs_helper.h" +#if defined(TARGET_SPARC) #if defined(reg_REGWPTR) uint32_t *saved_regwptr; #endif #endif #if defined(__sparc__) && !defined(HOST_SOLARIS) - int saved_i7, tmp_T0; + int saved_i7; + target_ulong tmp_T0; #endif int ret, interrupt_request; void (*gen_func)(void); @@ -320,44 +297,15 @@ int cpu_exec(CPUState *env1) cpu_single_env = env1; /* first we save global registers */ - saved_env = env; +#define SAVE_HOST_REGS 1 +#include "hostregs_helper.h" env = env1; - saved_T0 = T0; - saved_T1 = T1; -#if defined(reg_T2) - saved_T2 = T2; -#endif #if defined(__sparc__) && !defined(HOST_SOLARIS) /* we also save i7 because longjmp may not restore it */ asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); #endif #if defined(TARGET_I386) -#ifdef reg_EAX - saved_EAX = EAX; -#endif -#ifdef reg_ECX - saved_ECX = ECX; -#endif -#ifdef reg_EDX - saved_EDX = EDX; -#endif -#ifdef reg_EBX - saved_EBX = EBX; -#endif -#ifdef reg_ESP - saved_ESP = ESP; -#endif -#ifdef reg_EBP - saved_EBP = EBP; -#endif -#ifdef reg_ESI - saved_ESI = ESI; -#endif -#ifdef reg_EDI - saved_EDI = EDI; -#endif - env_to_regs(); /* put eflags in CPU temporary format */ CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); @@ -370,6 +318,10 @@ int cpu_exec(CPUState *env1) saved_regwptr = REGWPTR; #endif #elif defined(TARGET_PPC) +#elif defined(TARGET_M68K) + env->cc_op = CC_OP_FLAGS; + env->cc_dest = env->sr & 0xf; + env->cc_x = (env->sr >> 4) & 1; #elif defined(TARGET_MIPS) #elif defined(TARGET_SH4) /* XXXXX */ @@ -390,7 +342,7 @@ int cpu_exec(CPUState *env1) break; } else if (env->user_mode_only) { /* if user mode only, we simulate a fake exception - which will be hanlded outside the cpu execution + which will be handled outside the cpu execution loop */ #if defined(TARGET_I386) do_interrupt_user(env->exception_index, @@ -458,8 +410,16 @@ int cpu_exec(CPUState *env1) interrupt_request = env->interrupt_request; if (__builtin_expect(interrupt_request, 0)) { #if defined(TARGET_I386) - /* if hardware interrupt pending, we execute it */ - if ((interrupt_request & CPU_INTERRUPT_HARD) && + if ((interrupt_request & CPU_INTERRUPT_SMI) && + !(env->hflags & HF_SMM_MASK)) { + env->interrupt_request &= ~CPU_INTERRUPT_SMI; + do_smm_enter(); +#if defined(__sparc__) && !defined(HOST_SOLARIS) + tmp_T0 = 0; +#else + T0 = 0; +#endif + } else if ((interrupt_request & CPU_INTERRUPT_HARD) && (env->eflags & IF_MASK) && !(env->hflags & HF_INHIBIT_IRQ_MASK)) { int intno; @@ -519,7 +479,6 @@ int cpu_exec(CPUState *env1) env->exception_index = EXCP_EXT_INTERRUPT; env->error_code = 0; do_interrupt(env); - env->interrupt_request &= ~CPU_INTERRUPT_HARD; #if defined(__sparc__) && !defined(HOST_SOLARIS) tmp_T0 = 0; #else @@ -548,8 +507,10 @@ int cpu_exec(CPUState *env1) //do_interrupt(0, 0, 0, 0, 0); env->interrupt_request &= ~CPU_INTERRUPT_TIMER; } else if (interrupt_request & CPU_INTERRUPT_HALT) { - env1->halted = 1; - return EXCP_HALTED; + env->interrupt_request &= ~CPU_INTERRUPT_HALT; + env->halted = 1; + env->exception_index = EXCP_HLT; + cpu_loop_exit(); } #elif defined(TARGET_ARM) if (interrupt_request & CPU_INTERRUPT_FIQ @@ -622,6 +583,12 @@ int cpu_exec(CPUState *env1) cpu_dump_state(env, logfile, fprintf, 0); #elif defined(TARGET_PPC) cpu_dump_state(env, logfile, fprintf, 0); +#elif defined(TARGET_M68K) + cpu_m68k_flush_flags(env, env->cc_op); + env->cc_op = CC_OP_FLAGS; + env->sr = (env->sr & 0xffe0) + | env->cc_dest | (env->cc_x << 4); + cpu_dump_state(env, logfile, fprintf, 0); #elif defined(TARGET_MIPS) cpu_dump_state(env, logfile, fprintf, 0); #elif defined(TARGET_SH4) @@ -803,32 +770,6 @@ int cpu_exec(CPUState *env1) #endif /* restore flags in standard format */ env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); - - /* restore global registers */ -#ifdef reg_EAX - EAX = saved_EAX; -#endif -#ifdef reg_ECX - ECX = saved_ECX; -#endif -#ifdef reg_EDX - EDX = saved_EDX; -#endif -#ifdef reg_EBX - EBX = saved_EBX; -#endif -#ifdef reg_ESP - ESP = saved_ESP; -#endif -#ifdef reg_EBP - EBP = saved_EBP; -#endif -#ifdef reg_ESI - ESI = saved_ESI; -#endif -#ifdef reg_EDI - EDI = saved_EDI; -#endif #elif defined(TARGET_ARM) /* XXX: Save/restore host fpu exception state?. */ #elif defined(TARGET_SPARC) @@ -836,21 +777,24 @@ int cpu_exec(CPUState *env1) REGWPTR = saved_regwptr; #endif #elif defined(TARGET_PPC) +#elif defined(TARGET_M68K) + cpu_m68k_flush_flags(env, env->cc_op); + env->cc_op = CC_OP_FLAGS; + env->sr = (env->sr & 0xffe0) + | env->cc_dest | (env->cc_x << 4); #elif defined(TARGET_MIPS) #elif defined(TARGET_SH4) /* XXXXX */ #else #error unsupported target CPU #endif + + /* restore global registers */ #if defined(__sparc__) && !defined(HOST_SOLARIS) asm volatile ("mov %0, %%i7" : : "r" (saved_i7)); #endif - T0 = saved_T0; - T1 = saved_T1; -#if defined(reg_T2) - T2 = saved_T2; -#endif - env = saved_env; +#include "hostregs_helper.h" + /* fail safe : never use cpu_single_env outside cpu_exec() */ cpu_single_env = NULL; return ret; @@ -1093,6 +1037,45 @@ static inline int handle_cpu_signal(unsi return 1; } +#elif defined(TARGET_M68K) +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(address, pc, puc)) { + return 1; + } + /* see if it is an MMU fault */ + ret = cpu_m68k_handle_mmu_fault(env, address, is_write, 1, 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); + } + /* we restore the process signal mask as the sigreturn should + do it (XXX: use sigsetjmp) */ + sigprocmask(SIG_SETMASK, old_set, NULL); + cpu_loop_exit(); + /* never comes here */ + return 1; +} + #elif defined (TARGET_MIPS) static inline int handle_cpu_signal(unsigned long pc, unsigned long address, int is_write, sigset_t *old_set, @@ -1193,6 +1176,18 @@ static inline int handle_cpu_signal(unsi #if defined(__i386__) +#if defined(__APPLE__) +# include + +# define EIP_sig(context) (*((unsigned long*)&(context)->uc_mcontext->ss.eip)) +# define TRAP_sig(context) ((context)->uc_mcontext->es.trapno) +# define ERROR_sig(context) ((context)->uc_mcontext->es.err) +#else +# define EIP_sig(context) ((context)->uc_mcontext.gregs[REG_EIP]) +# define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO]) +# define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR]) +#endif + #if defined(USE_CODE_COPY) static void cpu_send_trap(unsigned long pc, int trap, struct ucontext *uc) @@ -1213,9 +1208,10 @@ static void cpu_send_trap(unsigned long } #endif -int cpu_signal_handler(int host_signum, struct siginfo *info, +int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { + siginfo_t *info = pinfo; struct ucontext *uc = puc; unsigned long pc; int trapno; @@ -1226,8 +1222,8 @@ int cpu_signal_handler(int host_signum, #define REG_ERR ERR #define REG_TRAPNO TRAPNO #endif - pc = uc->uc_mcontext.gregs[REG_EIP]; - trapno = uc->uc_mcontext.gregs[REG_TRAPNO]; + pc = EIP_sig(uc); + trapno = TRAP_sig(uc); #if defined(TARGET_I386) && defined(USE_CODE_COPY) if (trapno == 0x00 || trapno == 0x05) { /* send division by zero or bound exception */ @@ -1237,15 +1233,16 @@ int cpu_signal_handler(int host_signum, #endif return handle_cpu_signal(pc, (unsigned long)info->si_addr, trapno == 0xe ? - (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0, + (ERROR_sig(uc) >> 1) & 1 : 0, &uc->uc_sigmask, puc); } #elif defined(__x86_64__) -int cpu_signal_handler(int host_signum, struct siginfo *info, +int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { + siginfo_t *info = pinfo; struct ucontext *uc = puc; unsigned long pc; @@ -1307,9 +1304,10 @@ typedef struct ucontext SIGCONTEXT; # define TRAP_sig(context) EXCEPREG_sig(exception, context) /* number of powerpc exception taken */ #endif /* __APPLE__ */ -int cpu_signal_handler(int host_signum, struct siginfo *info, +int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { + siginfo_t *info = pinfo; struct ucontext *uc = puc; unsigned long pc; int is_write; @@ -1330,9 +1328,10 @@ int cpu_signal_handler(int host_signum, #elif defined(__alpha__) -int cpu_signal_handler(int host_signum, struct siginfo *info, +int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { + siginfo_t *info = pinfo; struct ucontext *uc = puc; uint32_t *pc = uc->uc_mcontext.sc_pc; uint32_t insn = *pc; @@ -1359,9 +1358,10 @@ int cpu_signal_handler(int host_signum, } #elif defined(__sparc__) -int cpu_signal_handler(int host_signum, struct siginfo *info, +int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { + siginfo_t *info = pinfo; uint32_t *regs = (uint32_t *)(info + 1); void *sigmask = (regs + 20); unsigned long pc; @@ -1392,9 +1392,10 @@ int cpu_signal_handler(int host_signum, #elif defined(__arm__) -int cpu_signal_handler(int host_signum, struct siginfo *info, +int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { + siginfo_t *info = pinfo; struct ucontext *uc = puc; unsigned long pc; int is_write; @@ -1404,14 +1405,15 @@ int cpu_signal_handler(int host_signum, is_write = 0; return handle_cpu_signal(pc, (unsigned long)info->si_addr, is_write, - &uc->uc_sigmask); + &uc->uc_sigmask, puc); } #elif defined(__mc68000) -int cpu_signal_handler(int host_signum, struct siginfo *info, +int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { + siginfo_t *info = pinfo; struct ucontext *uc = puc; unsigned long pc; int is_write; @@ -1431,8 +1433,9 @@ int cpu_signal_handler(int host_signum, # define __ISR_VALID 1 #endif -int cpu_signal_handler(int host_signum, struct siginfo *info, void *puc) +int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { + siginfo_t *info = pinfo; struct ucontext *uc = puc; unsigned long ip; int is_write = 0; @@ -1459,9 +1462,10 @@ int cpu_signal_handler(int host_signum, #elif defined(__s390__) -int cpu_signal_handler(int host_signum, struct siginfo *info, +int cpu_signal_handler(int host_signum, void *pinfo, void *puc) { + siginfo_t *info = pinfo; struct ucontext *uc = puc; unsigned long pc; int is_write;