target/arm: remove run time semihosting checks

Now we do all our checking and use a common EXCP_SEMIHOST for
semihosting operations we can make helper code a lot simpler.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190913151845.12582-5-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Alex Bennée 2019-09-19 14:18:41 +01:00 committed by Peter Maydell
parent 5651697f1f
commit ed6e6ba9c4
1 changed files with 22 additions and 74 deletions

View File

@ -8352,88 +8352,32 @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
new_el, env->pc, pstate_read(env));
}
static inline bool check_for_semihosting(CPUState *cs)
{
/*
* Do semihosting call and set the appropriate return value. All the
* permission and validity checks have been done at translate time.
*
* We only see semihosting exceptions in TCG only as they are not
* trapped to the hypervisor in KVM.
*/
#ifdef CONFIG_TCG
/* Check whether this exception is a semihosting call; if so
* then handle it and return true; otherwise return false.
*/
static void handle_semihosting(CPUState *cs)
{
ARMCPU *cpu = ARM_CPU(cs);
CPUARMState *env = &cpu->env;
if (is_a64(env)) {
if (cs->exception_index == EXCP_SEMIHOST) {
/* This is always the 64-bit semihosting exception.
* The "is this usermode" and "is semihosting enabled"
* checks have been done at translate time.
*/
qemu_log_mask(CPU_LOG_INT,
"...handling as semihosting call 0x%" PRIx64 "\n",
env->xregs[0]);
env->xregs[0] = do_arm_semihosting(env);
return true;
}
return false;
qemu_log_mask(CPU_LOG_INT,
"...handling as semihosting call 0x%" PRIx64 "\n",
env->xregs[0]);
env->xregs[0] = do_arm_semihosting(env);
} else {
uint32_t imm;
/* Only intercept calls from privileged modes, to provide some
* semblance of security.
*/
if (cs->exception_index != EXCP_SEMIHOST &&
(!semihosting_enabled() ||
((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR))) {
return false;
}
switch (cs->exception_index) {
case EXCP_SEMIHOST:
/* This is always a semihosting call; the "is this usermode"
* and "is semihosting enabled" checks have been done at
* translate time.
*/
break;
case EXCP_SWI:
/* Check for semihosting interrupt. */
if (env->thumb) {
imm = arm_lduw_code(env, env->regs[15] - 2, arm_sctlr_b(env))
& 0xff;
if (imm == 0xab) {
break;
}
} else {
imm = arm_ldl_code(env, env->regs[15] - 4, arm_sctlr_b(env))
& 0xffffff;
if (imm == 0x123456) {
break;
}
}
return false;
case EXCP_BKPT:
/* See if this is a semihosting syscall. */
if (env->thumb) {
imm = arm_lduw_code(env, env->regs[15], arm_sctlr_b(env))
& 0xff;
if (imm == 0xab) {
env->regs[15] += 2;
break;
}
}
return false;
default:
return false;
}
qemu_log_mask(CPU_LOG_INT,
"...handling as semihosting call 0x%x\n",
env->regs[0]);
env->regs[0] = do_arm_semihosting(env);
return true;
}
#else
return false;
#endif
}
#endif
/* Handle a CPU exception for A and R profile CPUs.
* Do any appropriate logging, handle PSCI calls, and then hand off
@ -8464,13 +8408,17 @@ void arm_cpu_do_interrupt(CPUState *cs)
return;
}
/* Semihosting semantics depend on the register width of the
* code that caused the exception, not the target exception level,
* so must be handled here.
/*
* Semihosting semantics depend on the register width of the code
* that caused the exception, not the target exception level, so
* must be handled here.
*/
if (check_for_semihosting(cs)) {
#ifdef CONFIG_TCG
if (cs->exception_index == EXCP_SEMIHOST) {
handle_semihosting(cs);
return;
}
#endif
/* Hooks may change global state so BQL should be held, also the
* BQL needs to be held for any modification of