summaryrefslogtreecommitdiff
path: root/linux-user/sh4
diff options
context:
space:
mode:
authorLaurent Vivier <laurent@vivier.eu>2018-04-11 20:56:42 +0200
committerLaurent Vivier <laurent@vivier.eu>2018-04-30 09:48:13 +0200
commitc37dcb4fa881998363b21a31212dc7a4bb80880d (patch)
tree104afd33a1e7e2f64abd091847442140c473acf3 /linux-user/sh4
parent1ef7bca2e784d3fc3206416723aaeb06bb9d8302 (diff)
linux-user: move sh4 cpu loop to sh4 directory
No code change, only move code from main.c to sh4/cpu_loop.c. Signed-off-by: Laurent Vivier <laurent@vivier.eu> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-Id: <20180411185651.21351-11-laurent@vivier.eu>
Diffstat (limited to 'linux-user/sh4')
-rw-r--r--linux-user/sh4/cpu_loop.c85
1 files changed, 85 insertions, 0 deletions
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;
}