From 2935a9af7ae8172b95e1eb8f1a84991fcccfbe8e Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 2 Mar 2018 15:01:36 -0500 Subject: [PATCH] arm: Remove workarounds for old M-profile exception return implementation Now that we've rewritten M-profile exception return so that the magic PC values are not visible to other parts of QEMU, we can delete the special casing of them elsewhere. Backports commit f4e8e4edda875cab9df91dc4ae9767f7cb1f50aa from qemu --- qemu/target/arm/cpu.c | 47 +++++++------------------------------ qemu/target/arm/translate.c | 8 ------- 2 files changed, 8 insertions(+), 47 deletions(-) diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index a74503bf..73d96a7f 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -302,33 +302,6 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request) } #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) -static void arm_v7m_unassigned_access(CPUState *cpu, hwaddr addr, - bool is_write, bool is_exec, int opaque, - unsigned size) -{ - ARMCPU *arm = ARM_CPU(cpu->uc, cpu); - CPUARMState *env = &arm->env; - - /* ARMv7-M interrupt return works by loading a magic value into the PC. - * On real hardware the load causes the return to occur. The qemu - * implementation performs the jump normally, then does the exception - * return by throwing a special exception when when the CPU tries to - * execute code at the magic address. - */ - if (env->v7m.exception != 0 && addr >= 0xfffffff0 && is_exec) { - cpu->exception_index = EXCP_EXCEPTION_EXIT; - cpu_loop_exit(cpu); - } - - /* In real hardware an attempt to access parts of the address space - * with nothing there will usually cause an external abort. - * However our QEMU board models are often missing device models where - * the guest can boot anyway with the default read-as-zero/writes-ignored - * behaviour that you get without a QEMU unassigned_access hook. - * So just return here to retain that default behaviour. - */ -} - static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) { CPUARMState *env = cs->env_ptr; @@ -342,19 +315,16 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) cc->do_interrupt(cs); ret = true; } - /* ARMv7-M interrupt return works by loading a magic value - * into the PC. On real hardware the load causes the - * return to occur. The qemu implementation performs the - * jump normally, then does the exception return when the - * CPU tries to execute code at the magic address. - * This will cause the magic PC value to be pushed to - * the stack if an interrupt occurred at the wrong time. - * We avoid this by disabling interrupts when - * pc contains a magic address. + + /* ARMv7-M interrupt masking works differently than -A or -R. + * There is no FIQ/IRQ distinction. Instead of I and F bits + * masking FIQ and IRQ interrupts, an exception is taken only + * if it is higher priority than the current execution priority + * (which depends on state like BASEPRI, FAULTMASK and the + * currently active exception). */ if (interrupt_request & CPU_INTERRUPT_HARD - && !(env->daif & PSTATE_I) - && (env->regs[15] < 0xfffffff0)) { + /*&& (armv7m_nvic_can_take_pending_exception(env->nvic)) */) { cs->exception_index = EXCP_IRQ; cc->do_interrupt(cs); ret = true; @@ -908,7 +878,6 @@ static void arm_v7m_class_init(struct uc_struct *uc, ObjectClass *oc, void *data cc->do_interrupt = arm_v7m_cpu_do_interrupt; #endif - cc->do_unassigned_access = arm_v7m_unassigned_access; cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt; } diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index 9f7efc7b..4e04b25d 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -12141,14 +12141,6 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) dc->is_jmp = DISAS_EXC; break; } -#else - if (arm_dc_feature(dc, ARM_FEATURE_M)) { - /* Branches to the magic exception-return addresses should - * already have been caught via the arm_v7m_unassigned_access hook, - * and never get here. - */ - assert(dc->pc < 0xfffffff0); - } #endif if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {