target/arm: only update pc after semihosting completes

Before we introduce blocking semihosting calls we need to ensure we
can restart the system on semi hosting exception. To be able to do
this the EXCP_SEMIHOST operation should be idempotent until it finally
completes. Practically this means ensureing we only update the pc
after the semihosting call has completed.

Backports commit 4ff5ef9e911c670ca10cdd36dd27c5395ec2c753 from qemu
This commit is contained in:
Alex Bennée 2020-01-14 08:24:37 -05:00 committed by Lioncash
parent ea2714796f
commit 8f275077b0
4 changed files with 17 additions and 16 deletions

View file

@ -7755,6 +7755,12 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
return target_el;
}
target_ulong do_arm_semihosting(CPUARMState *env)
{
/* Unicorn: We don't handle semihosting */
g_assert_not_reached();
}
/*
* Function used to synchronize QEMU's AArch64 register set with AArch32
* register set. This is necessary when switching between AArch32 and AArch64
@ -8385,6 +8391,7 @@ static inline bool check_for_semihosting(CPUState *cs)
"...handling as semihosting call 0x%" PRIx64 "\n",
env->xregs[0]);
env->xregs[0] = do_arm_semihosting(env);
env->pc += 4;
return true;
}
return false;
@ -8444,6 +8451,7 @@ static inline bool check_for_semihosting(CPUState *cs)
"...handling as semihosting call 0x%x\n",
env->regs[0]);
env->regs[0] = do_arm_semihosting(env);
env->regs[15] += env->thumb ? 2 : 4;
return true;
}
#else

View file

@ -2115,21 +2115,14 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
break;
}
break;
case EXCP_BKPT:
#if 0
if (semihosting_enabled) {
int nr;
nr = arm_lduw_code(env, env->regs[15], arm_sctlr_b(env)) & 0xff;
if (nr == 0xab) {
env->regs[15] += 2;
case EXCP_SEMIHOST:
qemu_log_mask(CPU_LOG_INT,
"...handling as semihosting call 0x%x\n",
env->regs[0]);
env->regs[0] = do_arm_semihosting(env);
return;
}
}
#endif
env->regs[15] += env->thumb ? 2 : 4;
break;
case EXCP_BKPT:
//armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG, false);
break;
case EXCP_IRQ:

View file

@ -2131,7 +2131,7 @@ static void disas_exc(DisasContext *s, uint32_t insn)
break;
}
#endif
gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
} else {
unsupported_encoding(s, insn);
}

View file

@ -1174,7 +1174,7 @@ static inline void gen_hlt(DisasContext *s, int imm)
s->current_el != 0 &&
#endif
(imm == (s->thumb ? 0x3c : 0xf000))) {
gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
return;
}