On 02/16/2017 01:35 PM, Peter Maydell wrote:
> From: Michael Davidsaver <mdavidsaver@gmail.com>
>
> All the places in armv7m_cpu_do_interrupt() which pend an
> exception in the NVIC are doing so for synchronous
> exceptions. We know that we will always take some
> exception in this case, so we can just acknowledge it
> immediately, rather than returning and then immediately
> being called again because the NVIC has raised its outbound
> IRQ line.
>
> Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com>
> [PMM: tweaked commit message; added DEBUG to the set of
> exceptions we handle immediately, since it is synchronous
> when it results from the BKPT instruction]
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
> target/arm/helper.c | 15 +++++++++------
> 1 file changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 050d8df..1844852 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -6109,22 +6109,22 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
> case EXCP_UDEF:
> armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
> env->v7m.cfsr |= R_V7M_CFSR_UNDEFINSTR_MASK;
> - return;
> + break;
> case EXCP_NOCP:
> armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
> env->v7m.cfsr |= R_V7M_CFSR_NOCP_MASK;
> - return;
> + break;
> case EXCP_SWI:
> /* The PC already points to the next instruction. */
> armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC);
> - return;
> + break;
> case EXCP_PREFETCH_ABORT:
> case EXCP_DATA_ABORT:
> /* TODO: if we implemented the MPU registers, this is where we
> * should set the MMFAR, etc from exception.fsr and exception.vaddress.
> */
> armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
> - return;
> + break;
> case EXCP_BKPT:
> if (semihosting_enabled()) {
> int nr;
> @@ -6139,9 +6139,8 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
> }
> }
> armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG);
> - return;
> + break;
> case EXCP_IRQ:
> - armv7m_nvic_acknowledge_irq(env->nvic);
> break;
> case EXCP_EXCEPTION_EXIT:
> do_v7m_exception_exit(env);
> @@ -6151,6 +6150,10 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
> return; /* Never happens. Keep compiler happy. */
> }
>
> + armv7m_nvic_acknowledge_irq(env->nvic);
> +
> + qemu_log_mask(CPU_LOG_INT, "... as %d\n", env->v7m.exception);
> +
> /* Align stack pointer if the guest wants that */
> if ((env->regs[13] & 4) && (env->v7m.ccr & R_V7M_CCR_STKALIGN_MASK)) {
> env->regs[13] -= 4;
>