Commit 45da08fa authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20141104' into staging



target-arm queue:
 * avoid passing CPU env pointer around in A32/T32 decoders
 * split M profile exception masking out from A/R profile

# gpg: Signature made Tue 04 Nov 2014 12:28:15 GMT using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-target-arm-20141104:
  target-arm: Correct condition for taking VIRQ and VFIQ
  target-arm: Separate out M profile cpu_exec_interrupt handling
  target-arm/translate.c: Don't pass CPUARMState * to disas_arm_insn()
  target-arm/translate.c: Don't pass CPUARMState around in the decoder
  target-arm/translate.c: Don't use IS_M()
  target-arm/translate.c: Use arm_dc_feature() rather than arm_feature()
  target-arm/translate.c: Use arm_dc_feature() in ENABLE_ARCH_ macros

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 69431090 9fae24f5
Loading
Loading
Loading
Loading
+39 −10
Original line number Diff line number Diff line
@@ -203,15 +203,6 @@ bool arm_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.  */
    if (interrupt_request & CPU_INTERRUPT_HARD
        && arm_excp_unmasked(cs, EXCP_IRQ)) {
        cs->exception_index = EXCP_IRQ;
@@ -234,6 +225,42 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
    return ret;
}

#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
    CPUClass *cc = CPU_GET_CLASS(cs);
    ARMCPU *cpu = ARM_CPU(cs);
    CPUARMState *env = &cpu->env;
    bool ret = false;


    if (interrupt_request & CPU_INTERRUPT_FIQ
        && !(env->daif & PSTATE_F)) {
        cs->exception_index = EXCP_FIQ;
        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.
     */
    if (interrupt_request & CPU_INTERRUPT_HARD
        && !(env->daif & PSTATE_I)
        && (env->regs[15] < 0xfffffff0)) {
        cs->exception_index = EXCP_IRQ;
        cc->do_interrupt(cs);
        ret = true;
    }
    return ret;
}
#endif

#ifndef CONFIG_USER_ONLY
static void arm_cpu_set_irq(void *opaque, int irq, int level)
{
@@ -670,11 +697,13 @@ static void cortex_m3_initfn(Object *obj)

static void arm_v7m_class_init(ObjectClass *oc, void *data)
{
#ifndef CONFIG_USER_ONLY
    CPUClass *cc = CPU_CLASS(oc);

#ifndef CONFIG_USER_ONLY
    cc->do_interrupt = arm_v7m_cpu_do_interrupt;
#endif

    cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
}

static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
+4 −16
Original line number Diff line number Diff line
@@ -1251,18 +1251,6 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
    bool secure = false;
    /* If in EL1/0, Physical IRQ routing to EL2 only happens from NS state.  */
    bool irq_can_hyp = !secure && cur_el < 2 && target_el == 2;
    /* 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.
     */
    bool irq_unmasked = !(env->daif & PSTATE_I)
                        && (!IS_M(env) || env->regs[15] < 0xfffffff0);

    /* Don't take exceptions if they target a lower EL.  */
    if (cur_el > target_el) {
@@ -1279,19 +1267,19 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
        if (irq_can_hyp && (env->cp15.hcr_el2 & HCR_IMO)) {
            return true;
        }
        return irq_unmasked;
        return !(env->daif & PSTATE_I);
    case EXCP_VFIQ:
        if (!secure && !(env->cp15.hcr_el2 & HCR_FMO)) {
        if (secure || !(env->cp15.hcr_el2 & HCR_FMO)) {
            /* VFIQs are only taken when hypervized and non-secure.  */
            return false;
        }
        return !(env->daif & PSTATE_F);
    case EXCP_VIRQ:
        if (!secure && !(env->cp15.hcr_el2 & HCR_IMO)) {
        if (secure || !(env->cp15.hcr_el2 & HCR_IMO)) {
            /* VIRQs are only taken when hypervized and non-secure.  */
            return false;
        }
        return irq_unmasked;
        return !(env->daif & PSTATE_I);
    default:
        g_assert_not_reached();
    }
+154 −126

File changed.

Preview size limit exceeded, changes collapsed.