e2k: Fix syscall restart.
We cannot just change the IP address in E2K to restart the instruction because the same register can be read and written in the same instruction (and many more situations), but we can create a fake syscall instruction and restart it. Signed-off-by: Denis Drakhnya <numas13@gmail.com>
This commit is contained in:
parent
19e386d72a
commit
4ca7a8e3fe
|
@ -44,18 +44,18 @@ void cpu_loop(CPUE2KState *env)
|
|||
// TODO: check what happens if env->wd.size is zero
|
||||
memcpy(args, env->regs, psize * sizeof(args[0]));
|
||||
|
||||
do {
|
||||
ret = do_syscall(env, args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7], args[8]);
|
||||
// FIXME: I don't know how to properly handle syscall restart
|
||||
} while (ret == -TARGET_ERESTARTSYS);
|
||||
ret = do_syscall(env, args[0], args[1], args[2], args[3],
|
||||
args[4], args[5], args[6], args[7], args[8]);
|
||||
|
||||
if (ret != -TARGET_QEMU_ESIGRETURN && env->wd.psize > 0) {
|
||||
if (ret == -TARGET_ERESTARTSYS) {
|
||||
/* do not set sysret address and syscall will be restarted */
|
||||
} else if (ret != -TARGET_QEMU_ESIGRETURN && env->wd.psize > 0) {
|
||||
memset(env->tags, E2K_TAG_NON_NUMBER64,
|
||||
psize * sizeof(env->tags[0]));
|
||||
|
||||
env->regs[0] = ret;
|
||||
env->tags[0] = E2K_TAG_NUMBER64;
|
||||
env->ip = E2K_SYSRET_ADDR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1188,7 +1188,6 @@ static void e2k_tr_translate_insn(DisasContextBase *db, CPUState *cs)
|
|||
case E2K_SYSCALL_ADDR6:
|
||||
/* fake enter into syscall handler */
|
||||
ctx->base.is_jmp = DISAS_NORETURN;
|
||||
e2k_gen_save_pc(E2K_SYSRET_ADDR);
|
||||
gen_helper_syscall(cpu_env);
|
||||
tcg_gen_exit_tb(NULL, TB_EXIT_IDX0);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue