linux-user: Add cpu loop for AArch64
Add the main linux-user cpu loop for AArch64. Since AArch64 has a different system call interface, doesn't need to worry about FPA emulation and may in the future keep the prefetch/data abort information in different system registers, it's simplest just to use a completely separate loop from the 32 bit ARM target, rather than peppering it with ifdefs. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 1378235544-22290-14-git-send-email-peter.maydell@linaro.org
This commit is contained in:
parent
067d983127
commit
1861c4543f
@ -449,6 +449,9 @@ void cpu_loop(CPUX86State *env)
|
||||
__r; \
|
||||
})
|
||||
|
||||
#ifdef TARGET_ABI32
|
||||
/* Commpage handling -- there is no commpage for AArch64 */
|
||||
|
||||
/*
|
||||
* See the Linux kernel's Documentation/arm/kernel_user_helpers.txt
|
||||
* Input:
|
||||
@ -582,6 +585,7 @@ do_kernel_trap(CPUARMState *env)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int do_strex(CPUARMState *env)
|
||||
{
|
||||
@ -661,6 +665,7 @@ done:
|
||||
return segv;
|
||||
}
|
||||
|
||||
#ifdef TARGET_ABI32
|
||||
void cpu_loop(CPUARMState *env)
|
||||
{
|
||||
CPUState *cs = CPU(arm_env_get_cpu(env));
|
||||
@ -873,6 +878,83 @@ void cpu_loop(CPUARMState *env)
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* AArch64 main loop */
|
||||
void cpu_loop(CPUARMState *env)
|
||||
{
|
||||
CPUState *cs = CPU(arm_env_get_cpu(env));
|
||||
int trapnr, sig;
|
||||
target_siginfo_t info;
|
||||
uint32_t addr;
|
||||
|
||||
for (;;) {
|
||||
cpu_exec_start(cs);
|
||||
trapnr = cpu_arm_exec(env);
|
||||
cpu_exec_end(cs);
|
||||
|
||||
switch (trapnr) {
|
||||
case EXCP_SWI:
|
||||
env->xregs[0] = do_syscall(env,
|
||||
env->xregs[8],
|
||||
env->xregs[0],
|
||||
env->xregs[1],
|
||||
env->xregs[2],
|
||||
env->xregs[3],
|
||||
env->xregs[4],
|
||||
env->xregs[5],
|
||||
0, 0);
|
||||
break;
|
||||
case EXCP_INTERRUPT:
|
||||
/* just indicate that signals should be handled asap */
|
||||
break;
|
||||
case EXCP_UDEF:
|
||||
info.si_signo = SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->pc;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
break;
|
||||
case EXCP_PREFETCH_ABORT:
|
||||
addr = env->cp15.c6_insn;
|
||||
goto do_segv;
|
||||
case EXCP_DATA_ABORT:
|
||||
addr = env->cp15.c6_data;
|
||||
do_segv:
|
||||
info.si_signo = SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
/* XXX: check env->error_code */
|
||||
info.si_code = TARGET_SEGV_MAPERR;
|
||||
info._sifields._sigfault._addr = addr;
|
||||
queue_signal(env, info.si_signo, &info);
|
||||
break;
|
||||
case EXCP_DEBUG:
|
||||
case EXCP_BKPT:
|
||||
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, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_STREX:
|
||||
if (do_strex(env)) {
|
||||
addr = env->cp15.c6_data;
|
||||
goto do_segv;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
|
||||
trapnr);
|
||||
cpu_dump_state(cs, stderr, fprintf, 0);
|
||||
abort();
|
||||
}
|
||||
process_pending_signals(env);
|
||||
}
|
||||
}
|
||||
#endif /* ndef TARGET_ABI32 */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_UNICORE32
|
||||
|
Loading…
Reference in New Issue
Block a user