Commit 4ff5ef9e authored by Alex Bennée's avatar Alex Bennée
Browse files

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.

Signed-off-by: default avatarAlex Bennée <alex.bennee@linaro.org>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Reviewed-by: default avatarKeith Packard <keithp@keithp.com>
Tested-by: default avatarKeith Packard <keithp@keithp.com>
parent b906acbb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -130,6 +130,7 @@ void cpu_loop(CPUARMState *env)
            break;
        case EXCP_SEMIHOST:
            env->xregs[0] = do_arm_semihosting(env);
            env->pc += 4;
            break;
        case EXCP_YIELD:
            /* nothing to do here for user-mode, just resume guest code */
+1 −0
Original line number Diff line number Diff line
@@ -377,6 +377,7 @@ void cpu_loop(CPUARMState *env)
            break;
        case EXCP_SEMIHOST:
            env->regs[0] = do_arm_semihosting(env);
            env->regs[15] += env->thumb ? 2 : 4;
            break;
        case EXCP_INTERRUPT:
            /* just indicate that signals should be handled asap */
+2 −0
Original line number Diff line number Diff line
@@ -8614,11 +8614,13 @@ static void handle_semihosting(CPUState *cs)
                      "...handling as semihosting call 0x%" PRIx64 "\n",
                      env->xregs[0]);
        env->xregs[0] = do_arm_semihosting(env);
        env->pc += 4;
    } else {
        qemu_log_mask(CPU_LOG_INT,
                      "...handling as semihosting call 0x%x\n",
                      env->regs[0]);
        env->regs[0] = do_arm_semihosting(env);
        env->regs[15] += env->thumb ? 2 : 4;
    }
}
#endif
+1 −0
Original line number Diff line number Diff line
@@ -2185,6 +2185,7 @@ void arm_v7m_cpu_do_interrupt(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;
    case EXCP_BKPT:
        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG, false);
+1 −1
Original line number Diff line number Diff line
@@ -1937,7 +1937,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);
        }
Loading