diff mbox series

[v2,08/13] armv7m: Simpler and faster exception start

Message ID 1487262963-11519-9-git-send-email-peter.maydell@linaro.org
State Superseded
Headers show
Series Rewrite NVIC to not depend on the GIC | expand

Commit Message

Peter Maydell Feb. 16, 2017, 4:35 p.m. UTC
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>

---
 target/arm/helper.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

-- 
2.7.4

Comments

Philippe Mathieu-Daudé April 17, 2017, 3:44 a.m. UTC | #1
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;

>
diff mbox series

Patch

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;