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
This commit is contained in:
Peter Maydell 2018-03-02 15:01:36 -05:00 committed by Lioncash
parent 44bf8985e5
commit 2935a9af7a
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
2 changed files with 8 additions and 47 deletions

View file

@ -302,33 +302,6 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
} }
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) #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) static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
CPUARMState *env = cs->env_ptr; 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); cc->do_interrupt(cs);
ret = true; ret = true;
} }
/* ARMv7-M interrupt return works by loading a magic value
* into the PC. On real hardware the load causes the /* ARMv7-M interrupt masking works differently than -A or -R.
* return to occur. The qemu implementation performs the * There is no FIQ/IRQ distinction. Instead of I and F bits
* jump normally, then does the exception return when the * masking FIQ and IRQ interrupts, an exception is taken only
* CPU tries to execute code at the magic address. * if it is higher priority than the current execution priority
* This will cause the magic PC value to be pushed to * (which depends on state like BASEPRI, FAULTMASK and the
* the stack if an interrupt occurred at the wrong time. * currently active exception).
* We avoid this by disabling interrupts when
* pc contains a magic address.
*/ */
if (interrupt_request & CPU_INTERRUPT_HARD if (interrupt_request & CPU_INTERRUPT_HARD
&& !(env->daif & PSTATE_I) /*&& (armv7m_nvic_can_take_pending_exception(env->nvic)) */) {
&& (env->regs[15] < 0xfffffff0)) {
cs->exception_index = EXCP_IRQ; cs->exception_index = EXCP_IRQ;
cc->do_interrupt(cs); cc->do_interrupt(cs);
ret = true; 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; cc->do_interrupt = arm_v7m_cpu_do_interrupt;
#endif #endif
cc->do_unassigned_access = arm_v7m_unassigned_access;
cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt; cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
} }

View file

@ -12141,14 +12141,6 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
dc->is_jmp = DISAS_EXC; dc->is_jmp = DISAS_EXC;
break; 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 #endif
if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {