[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-arm] [PATCH v2 10/13] armv7m: Extract "exception taken" code i
From: |
Alex Bennée |
Subject: |
Re: [Qemu-arm] [PATCH v2 10/13] armv7m: Extract "exception taken" code into functions |
Date: |
Fri, 24 Feb 2017 17:13:47 +0000 |
User-agent: |
mu4e 0.9.19; emacs 25.2.5 |
Peter Maydell <address@hidden> writes:
> Extract the code from the tail end of arm_v7m_do_interrupt() which
> enters the exception handler into a pair of utility functions
> v7m_exception_taken() and v7m_push_stack(), which correspond roughly
> to the pseudocode PushStack() and ExceptionTaken().
>
> This also requires us to move the arm_v7m_load_vector() utility
> routine up so we can call it.
>
> Handling illegal exception returns has some cases where we want to
> take a UsageFault either on an existing stack frame or with a new
> stack frame but with a specific LR value, so we want to be able to
> call these without having to go via arm_v7m_cpu_do_interrupt().
>
> Signed-off-by: Peter Maydell <address@hidden>
Reviewed-by: Alex Bennée <address@hidden>
> ---
> target/arm/helper.c | 118
> ++++++++++++++++++++++++++++++----------------------
> 1 file changed, 68 insertions(+), 50 deletions(-)
>
> diff --git a/target/arm/helper.c b/target/arm/helper.c
> index 1844852..f94d1c7 100644
> --- a/target/arm/helper.c
> +++ b/target/arm/helper.c
> @@ -6001,6 +6001,72 @@ static void switch_v7m_sp(CPUARMState *env, bool
> new_spsel)
> }
> }
>
> +static uint32_t arm_v7m_load_vector(ARMCPU *cpu)
> +{
> + CPUState *cs = CPU(cpu);
> + CPUARMState *env = &cpu->env;
> + MemTxResult result;
> + hwaddr vec = env->v7m.vecbase + env->v7m.exception * 4;
> + uint32_t addr;
> +
> + addr = address_space_ldl(cs->as, vec,
> + MEMTXATTRS_UNSPECIFIED, &result);
> + if (result != MEMTX_OK) {
> + /* Architecturally this should cause a HardFault setting
> HSFR.VECTTBL,
> + * which would then be immediately followed by our failing to load
> + * the entry vector for that HardFault, which is a Lockup case.
> + * Since we don't model Lockup, we just report this guest error
> + * via cpu_abort().
> + */
> + cpu_abort(cs, "Failed to read from exception vector table "
> + "entry %08x\n", (unsigned)vec);
> + }
> + return addr;
> +}
> +
> +static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr)
> +{
> + /* Do the "take the exception" parts of exception entry,
> + * but not the pushing of state to the stack. This is
> + * similar to the pseudocode ExceptionTaken() function.
> + */
> + CPUARMState *env = &cpu->env;
> + uint32_t addr;
> +
> + armv7m_nvic_acknowledge_irq(env->nvic);
> + switch_v7m_sp(env, 0);
> + /* Clear IT bits */
> + env->condexec_bits = 0;
> + env->regs[14] = lr;
> + addr = arm_v7m_load_vector(cpu);
> + env->regs[15] = addr & 0xfffffffe;
> + env->thumb = addr & 1;
> +}
> +
> +static void v7m_push_stack(ARMCPU *cpu)
> +{
> + /* Do the "set up stack frame" part of exception entry,
> + * similar to pseudocode PushStack().
> + */
> + CPUARMState *env = &cpu->env;
> + uint32_t xpsr = xpsr_read(env);
> +
> + /* 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;
> + xpsr |= 0x200;
> + }
> + /* Switch to the handler mode. */
> + v7m_push(env, xpsr);
> + v7m_push(env, env->regs[15]);
> + v7m_push(env, env->regs[14]);
> + v7m_push(env, env->regs[12]);
> + v7m_push(env, env->regs[3]);
> + v7m_push(env, env->regs[2]);
> + v7m_push(env, env->regs[1]);
> + v7m_push(env, env->regs[0]);
> +}
> +
> static void do_v7m_exception_exit(CPUARMState *env)
> {
> uint32_t type;
> @@ -6062,37 +6128,11 @@ static void arm_log_exception(int idx)
> }
> }
>
> -static uint32_t arm_v7m_load_vector(ARMCPU *cpu)
> -
> -{
> - CPUState *cs = CPU(cpu);
> - CPUARMState *env = &cpu->env;
> - MemTxResult result;
> - hwaddr vec = env->v7m.vecbase + env->v7m.exception * 4;
> - uint32_t addr;
> -
> - addr = address_space_ldl(cs->as, vec,
> - MEMTXATTRS_UNSPECIFIED, &result);
> - if (result != MEMTX_OK) {
> - /* Architecturally this should cause a HardFault setting
> HSFR.VECTTBL,
> - * which would then be immediately followed by our failing to load
> - * the entry vector for that HardFault, which is a Lockup case.
> - * Since we don't model Lockup, we just report this guest error
> - * via cpu_abort().
> - */
> - cpu_abort(cs, "Failed to read from exception vector table "
> - "entry %08x\n", (unsigned)vec);
> - }
> - return addr;
> -}
> -
> void arm_v7m_cpu_do_interrupt(CPUState *cs)
> {
> ARMCPU *cpu = ARM_CPU(cs);
> CPUARMState *env = &cpu->env;
> - uint32_t xpsr = xpsr_read(env);
> uint32_t lr;
> - uint32_t addr;
>
> arm_log_exception(cs->exception_index);
>
> @@ -6150,31 +6190,9 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
> return; /* Never happens. Keep compiler happy. */
> }
>
> - armv7m_nvic_acknowledge_irq(env->nvic);
> -
> + v7m_push_stack(cpu);
> + v7m_exception_taken(cpu, lr);
> 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;
> - xpsr |= 0x200;
> - }
> - /* Switch to the handler mode. */
> - v7m_push(env, xpsr);
> - v7m_push(env, env->regs[15]);
> - v7m_push(env, env->regs[14]);
> - v7m_push(env, env->regs[12]);
> - v7m_push(env, env->regs[3]);
> - v7m_push(env, env->regs[2]);
> - v7m_push(env, env->regs[1]);
> - v7m_push(env, env->regs[0]);
> - switch_v7m_sp(env, 0);
> - /* Clear IT bits */
> - env->condexec_bits = 0;
> - env->regs[14] = lr;
> - addr = arm_v7m_load_vector(cpu);
> - env->regs[15] = addr & 0xfffffffe;
> - env->thumb = addr & 1;
> }
>
> /* Function used to synchronize QEMU's AArch64 register set with AArch32
--
Alex Bennée
- [Qemu-arm] [PATCH v2 00/13] Rewrite NVIC to not depend on the GIC, Peter Maydell, 2017/02/16
- [Qemu-arm] [PATCH v2 02/13] armv7m: Implement reading and writing of PRIGROUP, Peter Maydell, 2017/02/16
- [Qemu-arm] [PATCH v2 13/13] armv7m: Allow SHCSR writes to change pending and active bits, Peter Maydell, 2017/02/16
- [Qemu-arm] [PATCH v2 12/13] armv7m: Raise correct kind of UsageFault for attempts to execute ARM code, Peter Maydell, 2017/02/16
- [Qemu-arm] [PATCH v2 11/13] armv7m: Check exception return consistency, Peter Maydell, 2017/02/16
- [Qemu-arm] [PATCH v2 10/13] armv7m: Extract "exception taken" code into functions, Peter Maydell, 2017/02/16
- Re: [Qemu-arm] [PATCH v2 10/13] armv7m: Extract "exception taken" code into functions,
Alex Bennée <=
- [Qemu-arm] [PATCH v2 08/13] armv7m: Simpler and faster exception start, Peter Maydell, 2017/02/16
- [Qemu-arm] [PATCH v2 09/13] armv7m: VECTCLRACTIVE and VECTRESET are UNPREDICTABLE, Peter Maydell, 2017/02/16
- [Qemu-arm] [PATCH v2 05/13] arm: gic: Remove references to NVIC, Peter Maydell, 2017/02/16
- [Qemu-arm] [PATCH v2 07/13] armv7m: Remove unused armv7m_nvic_acknowledge_irq() return value, Peter Maydell, 2017/02/16
- [Qemu-arm] [PATCH v2 04/13] armv7m: Fix condition check for taking exceptions, Peter Maydell, 2017/02/16
- [Qemu-arm] [PATCH v2 01/13] armv7m: Rename nvic_state to NVICState, Peter Maydell, 2017/02/16
- [Qemu-arm] [PATCH v2 06/13] armv7m: Escalate exceptions to HardFault if necessary, Peter Maydell, 2017/02/16
- [Qemu-arm] [PATCH v2 03/13] armv7m: Rewrite NVIC to not use any GIC code, Peter Maydell, 2017/02/16