RISC-V Linux User Emulation

Implementation of linux user emulation for RISC-V.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Sagar Karandikar <sagark@eecs.berkeley.edu>
Signed-off-by: Michael Clark <mjc@sifive.com>
This commit is contained in:
Michael Clark 2018-03-03 01:31:11 +13:00
parent 65c5b75c38
commit 47ae93cdfe
No known key found for this signature in database
GPG key ID: 6BF1D7B357EF3E4F
13 changed files with 1012 additions and 6 deletions

View file

@ -3653,6 +3653,100 @@ void cpu_loop(CPUTLGState *env)
#endif
#ifdef TARGET_RISCV
void cpu_loop(CPURISCVState *env)
{
CPUState *cs = CPU(riscv_env_get_cpu(env));
int trapnr, signum, sigcode;
target_ulong sigaddr;
target_ulong ret;
for (;;) {
cpu_exec_start(cs);
trapnr = cpu_exec(cs);
cpu_exec_end(cs);
process_queued_cpu_work(cs);
signum = 0;
sigcode = 0;
sigaddr = 0;
switch (trapnr) {
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
break;
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
break;
case RISCV_EXCP_U_ECALL:
env->pc += 4;
if (env->gpr[xA7] == TARGET_NR_arch_specific_syscall + 15) {
/* riscv_flush_icache_syscall is a no-op in QEMU as
self-modifying code is automatically detected */
ret = 0;
} else {
ret = do_syscall(env,
env->gpr[xA7],
env->gpr[xA0],
env->gpr[xA1],
env->gpr[xA2],
env->gpr[xA3],
env->gpr[xA4],
env->gpr[xA5],
0, 0);
}
if (ret == -TARGET_ERESTARTSYS) {
env->pc -= 4;
} else if (ret != -TARGET_QEMU_ESIGRETURN) {
env->gpr[xA0] = ret;
}
if (cs->singlestep_enabled) {
goto gdbstep;
}
break;
case RISCV_EXCP_ILLEGAL_INST:
signum = TARGET_SIGILL;
sigcode = TARGET_ILL_ILLOPC;
break;
case RISCV_EXCP_BREAKPOINT:
signum = TARGET_SIGTRAP;
sigcode = TARGET_TRAP_BRKPT;
sigaddr = env->pc;
break;
case RISCV_EXCP_INST_PAGE_FAULT:
case RISCV_EXCP_LOAD_PAGE_FAULT:
case RISCV_EXCP_STORE_PAGE_FAULT:
signum = TARGET_SIGSEGV;
sigcode = TARGET_SEGV_MAPERR;
break;
case EXCP_DEBUG:
gdbstep:
signum = gdb_handlesig(cs, TARGET_SIGTRAP);
sigcode = TARGET_TRAP_BRKPT;
break;
default:
EXCP_DUMP(env, "\nqemu: unhandled CPU exception %#x - aborting\n",
trapnr);
exit(EXIT_FAILURE);
}
if (signum) {
target_siginfo_t info = {
.si_signo = signum,
.si_errno = 0,
.si_code = sigcode,
._sifields._sigfault._addr = sigaddr
};
queue_signal(env, info.si_signo, QEMU_SI_KILL, &info);
}
process_pending_signals(env);
}
}
#endif /* TARGET_RISCV */
#ifdef TARGET_HPPA
static abi_ulong hppa_lws(CPUHPPAState *env)
@ -4803,6 +4897,11 @@ int main(int argc, char **argv, char **envp)
env->pc = regs->pc;
cpu_set_sr(env, regs->sr);
}
#elif defined(TARGET_RISCV)
{
env->pc = regs->sepc;
env->gpr[xSP] = regs->sp;
}
#elif defined(TARGET_SH4)
{
int i;