diff options
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/main.c | 90 | ||||
-rw-r--r-- | linux-user/sh4/cpu_loop.c | 85 |
2 files changed, 85 insertions, 90 deletions
diff --git a/linux-user/main.c b/linux-user/main.c index af26a17c46..d7fee3e3db 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -149,87 +149,6 @@ void fork_end(int child) } } -#ifdef TARGET_SH4 -void cpu_loop(CPUSH4State *env) -{ - CPUState *cs = CPU(sh_env_get_cpu(env)); - int trapnr, ret; - target_siginfo_t info; - - while (1) { - bool arch_interrupt = true; - - cpu_exec_start(cs); - trapnr = cpu_exec(cs); - cpu_exec_end(cs); - process_queued_cpu_work(cs); - - switch (trapnr) { - case 0x160: - env->pc += 2; - ret = do_syscall(env, - env->gregs[3], - env->gregs[4], - env->gregs[5], - env->gregs[6], - env->gregs[7], - env->gregs[0], - env->gregs[1], - 0, 0); - if (ret == -TARGET_ERESTARTSYS) { - env->pc -= 2; - } else if (ret != -TARGET_QEMU_ESIGRETURN) { - env->gregs[0] = ret; - } - break; - case EXCP_INTERRUPT: - /* just indicate that signals should be handled asap */ - break; - case EXCP_DEBUG: - { - int sig; - - sig = gdb_handlesig(cs, TARGET_SIGTRAP); - 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: - case 0xc0: - info.si_signo = TARGET_SIGSEGV; - info.si_errno = 0; - info.si_code = TARGET_SEGV_MAPERR; - 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); - cpu_dump_state(cs, stderr, fprintf, 0); - 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 - #ifdef TARGET_CRIS void cpu_loop(CPUCRISState *env) { @@ -2361,15 +2280,6 @@ int main(int argc, char **argv, char **envp) env->pc = regs->sepc; env->gpr[xSP] = regs->sp; } -#elif defined(TARGET_SH4) - { - int i; - - for(i = 0; i < 16; i++) { - env->gregs[i] = regs->regs[i]; - } - env->pc = regs->pc; - } #elif defined(TARGET_ALPHA) { int i; diff --git a/linux-user/sh4/cpu_loop.c b/linux-user/sh4/cpu_loop.c index b7700a5561..418833ea25 100644 --- a/linux-user/sh4/cpu_loop.c +++ b/linux-user/sh4/cpu_loop.c @@ -21,6 +21,91 @@ #include "qemu.h" #include "cpu_loop-common.h" +void cpu_loop(CPUSH4State *env) +{ + CPUState *cs = CPU(sh_env_get_cpu(env)); + int trapnr, ret; + target_siginfo_t info; + + while (1) { + bool arch_interrupt = true; + + cpu_exec_start(cs); + trapnr = cpu_exec(cs); + cpu_exec_end(cs); + process_queued_cpu_work(cs); + + switch (trapnr) { + case 0x160: + env->pc += 2; + ret = do_syscall(env, + env->gregs[3], + env->gregs[4], + env->gregs[5], + env->gregs[6], + env->gregs[7], + env->gregs[0], + env->gregs[1], + 0, 0); + if (ret == -TARGET_ERESTARTSYS) { + env->pc -= 2; + } else if (ret != -TARGET_QEMU_ESIGRETURN) { + env->gregs[0] = ret; + } + break; + case EXCP_INTERRUPT: + /* just indicate that signals should be handled asap */ + break; + case EXCP_DEBUG: + { + int sig; + + sig = gdb_handlesig(cs, TARGET_SIGTRAP); + 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: + case 0xc0: + info.si_signo = TARGET_SIGSEGV; + info.si_errno = 0; + info.si_code = TARGET_SEGV_MAPERR; + 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); + cpu_dump_state(cs, stderr, fprintf, 0); + 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; + } + } +} + void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) { + int i; + + for(i = 0; i < 16; i++) { + env->gregs[i] = regs->regs[i]; + } + env->pc = regs->pc; } |