提交 a25dc805 编写于 作者: M Michael Davidsaver 提交者: Peter Maydell

armv7m: Simpler and faster exception start

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: NMichael 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: NPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
上级 a5d82355
...@@ -6110,22 +6110,22 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) ...@@ -6110,22 +6110,22 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
case EXCP_UDEF: case EXCP_UDEF:
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
env->v7m.cfsr |= R_V7M_CFSR_UNDEFINSTR_MASK; env->v7m.cfsr |= R_V7M_CFSR_UNDEFINSTR_MASK;
return; break;
case EXCP_NOCP: case EXCP_NOCP:
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE); armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
env->v7m.cfsr |= R_V7M_CFSR_NOCP_MASK; env->v7m.cfsr |= R_V7M_CFSR_NOCP_MASK;
return; break;
case EXCP_SWI: case EXCP_SWI:
/* The PC already points to the next instruction. */ /* The PC already points to the next instruction. */
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC); armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC);
return; break;
case EXCP_PREFETCH_ABORT: case EXCP_PREFETCH_ABORT:
case EXCP_DATA_ABORT: case EXCP_DATA_ABORT:
/* TODO: if we implemented the MPU registers, this is where we /* TODO: if we implemented the MPU registers, this is where we
* should set the MMFAR, etc from exception.fsr and exception.vaddress. * should set the MMFAR, etc from exception.fsr and exception.vaddress.
*/ */
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM); armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
return; break;
case EXCP_BKPT: case EXCP_BKPT:
if (semihosting_enabled()) { if (semihosting_enabled()) {
int nr; int nr;
...@@ -6140,9 +6140,8 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) ...@@ -6140,9 +6140,8 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
} }
} }
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG); armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG);
return; break;
case EXCP_IRQ: case EXCP_IRQ:
armv7m_nvic_acknowledge_irq(env->nvic);
break; break;
case EXCP_EXCEPTION_EXIT: case EXCP_EXCEPTION_EXIT:
do_v7m_exception_exit(env); do_v7m_exception_exit(env);
...@@ -6152,6 +6151,10 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs) ...@@ -6152,6 +6151,10 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
return; /* Never happens. Keep compiler happy. */ 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 */ /* Align stack pointer if the guest wants that */
if ((env->regs[13] & 4) && (env->v7m.ccr & R_V7M_CCR_STKALIGN_MASK)) { if ((env->regs[13] & 4) && (env->v7m.ccr & R_V7M_CCR_STKALIGN_MASK)) {
env->regs[13] -= 4; env->regs[13] -= 4;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册