diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2018-01-11 22:01:17 +0200 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2018-01-11 22:03:50 +0200 |
commit | acc95bc85036c443da8bf7159a77edf9f00dcd80 (patch) | |
tree | 21965c6e60a2e29664b7685e52feacdb6a86e0bd /linux-user | |
parent | 880b1ffe6ec2f0ae25cc4175716227ad275e8b8a (diff) | |
parent | 997eba28a3ed5400a80f754bf3a1c8044b75b9ff (diff) | |
download | qemu-acc95bc85036c443da8bf7159a77edf9f00dcd80.zip qemu-acc95bc85036c443da8bf7159a77edf9f00dcd80.tar.gz qemu-acc95bc85036c443da8bf7159a77edf9f00dcd80.tar.bz2 |
Merge remote-tracking branch 'origin/master' into HEAD
Resolve conflicts around apb.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/aarch64/target_syscall.h | 4 | ||||
-rw-r--r-- | linux-user/arm/nwfpe/fpa11.c | 9 | ||||
-rw-r--r-- | linux-user/main.c | 33 | ||||
-rw-r--r-- | linux-user/signal.c | 19 |
4 files changed, 53 insertions, 12 deletions
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h index 1b62953..604ab99 100644 --- a/linux-user/aarch64/target_syscall.h +++ b/linux-user/aarch64/target_syscall.h @@ -8,7 +8,11 @@ struct target_pt_regs { uint64_t pstate; }; +#if defined(TARGET_WORDS_BIGENDIAN) +#define UNAME_MACHINE "aarch64_be" +#else #define UNAME_MACHINE "aarch64" +#endif #define UNAME_MINIMUM_RELEASE "3.8.0" #define TARGET_CLONE_BACKWARDS #define TARGET_MINSIGSTKSZ 2048 diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c index 441e3b1..f6f8163 100644 --- a/linux-user/arm/nwfpe/fpa11.c +++ b/linux-user/arm/nwfpe/fpa11.c @@ -137,8 +137,17 @@ unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs) unsigned int nRc = 0; // unsigned long flags; FPA11 *fpa11; + unsigned int cp; // save_flags(flags); sti(); + /* Check that this is really an FPA11 instruction: the coprocessor + * field in bits [11:8] must be 1 or 2. + */ + cp = (opcode >> 8) & 0xf; + if (cp != 1 && cp != 2) { + return 0; + } + qemufpa=qfpa; user_registers=qregs; diff --git a/linux-user/main.c b/linux-user/main.c index 6286661..450eb3c 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -35,7 +35,6 @@ #include "elf.h" #include "exec/log.h" #include "trace/control.h" -#include "glib-compat.h" char *exec_path; @@ -2680,6 +2679,8 @@ void cpu_loop(CPUSH4State *env) target_siginfo_t info; while (1) { + bool arch_interrupt = true; + cpu_exec_start(cs); trapnr = cpu_exec(cs); cpu_exec_end(cs); @@ -2711,13 +2712,14 @@ void cpu_loop(CPUSH4State *env) int sig; sig = gdb_handlesig(cs, TARGET_SIGTRAP); - if (sig) - { + if (sig) { info.si_signo = sig; info.si_errno = 0; info.si_code = TARGET_TRAP_BRKPT; queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - } + } else { + arch_interrupt = false; + } } break; case 0xa0: @@ -2728,9 +2730,9 @@ void cpu_loop(CPUSH4State *env) info._sifields._sigfault._addr = env->tea; queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; - case EXCP_ATOMIC: cpu_exec_step_atomic(cs); + arch_interrupt = false; break; default: printf ("Unhandled trap: 0x%x\n", trapnr); @@ -2738,6 +2740,14 @@ void cpu_loop(CPUSH4State *env) exit(EXIT_FAILURE); } process_pending_signals (env); + + /* Most of the traps imply an exception or interrupt, which + implies an REI instruction has been executed. Which means + that LDST (aka LOK_ADDR) should be cleared. But there are + a few exceptions for traps internal to QEMU. */ + if (arch_interrupt) { + env->lock_addr = -1; + } } } #endif @@ -2975,6 +2985,13 @@ void cpu_loop(CPUM68KState *env) info._sifields._sigfault._addr = env->pc; queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; + case EXCP_CHK: + info.si_signo = TARGET_SIGFPE; + info.si_errno = 0; + info.si_code = TARGET_FPE_INTOVF; + info._sifields._sigfault._addr = env->pc; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; case EXCP_DIV0: info.si_signo = TARGET_SIGFPE; info.si_errno = 0; @@ -4612,6 +4629,12 @@ int main(int argc, char **argv, char **envp) } env->pc = regs->pc; env->xregs[31] = regs->sp; +#ifdef TARGET_WORDS_BIGENDIAN + env->cp15.sctlr_el[1] |= SCTLR_E0E; + for (i = 1; i < 4; ++i) { + env->cp15.sctlr_el[i] |= SCTLR_EE; + } +#endif } #elif defined(TARGET_ARM) { diff --git a/linux-user/signal.c b/linux-user/signal.c index cf35473..f85f0dd 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -1599,9 +1599,13 @@ static void target_setup_frame(int usig, struct target_sigaction *ka, if (ka->sa_flags & TARGET_SA_RESTORER) { return_addr = ka->sa_restorer; } else { - /* mov x8,#__NR_rt_sigreturn; svc #0 */ - __put_user(0xd2801168, &frame->tramp[0]); - __put_user(0xd4000001, &frame->tramp[1]); + /* + * mov x8,#__NR_rt_sigreturn; svc #0 + * Since these are instructions they need to be put as little-endian + * regardless of target default or current CPU endianness. + */ + __put_user_e(0xd2801168, &frame->tramp[0], le); + __put_user_e(0xd4000001, &frame->tramp[1], le); return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp); } env->xregs[0] = usig; @@ -5612,13 +5616,14 @@ struct target_rt_sigframe static void setup_sigcontext(struct target_sigcontext *sc, CPUM68KState *env, abi_ulong mask) { + uint32_t sr = (env->sr & 0xff00) | cpu_m68k_get_ccr(env); __put_user(mask, &sc->sc_mask); __put_user(env->aregs[7], &sc->sc_usp); __put_user(env->dregs[0], &sc->sc_d0); __put_user(env->dregs[1], &sc->sc_d1); __put_user(env->aregs[0], &sc->sc_a0); __put_user(env->aregs[1], &sc->sc_a1); - __put_user(env->sr, &sc->sc_sr); + __put_user(sr, &sc->sc_sr); __put_user(env->pc, &sc->sc_pc); } @@ -5634,7 +5639,7 @@ restore_sigcontext(CPUM68KState *env, struct target_sigcontext *sc) __get_user(env->aregs[1], &sc->sc_a1); __get_user(env->pc, &sc->sc_pc); __get_user(temp, &sc->sc_sr); - env->sr = (env->sr & 0xff00) | (temp & 0xff); + cpu_m68k_set_ccr(env, temp); } /* @@ -5726,7 +5731,7 @@ static inline int target_rt_setup_ucontext(struct target_ucontext *uc, CPUM68KState *env) { target_greg_t *gregs = uc->tuc_mcontext.gregs; - uint32_t sr = cpu_m68k_get_ccr(env); + uint32_t sr = (env->sr & 0xff00) | cpu_m68k_get_ccr(env); __put_user(TARGET_MCONTEXT_VERSION, &uc->tuc_mcontext.version); __put_user(env->dregs[0], &gregs[0]); @@ -6530,7 +6535,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka, haddr = dest; } env->iaoq_f = haddr; - env->iaoq_b = haddr + 4;; + env->iaoq_b = haddr + 4; return; give_sigsegv: |