Commit 6d804834 authored by Peter Maydell's avatar Peter Maydell
Browse files

target/arm: Make PRIMASK register banked for v8M



Make the PRIMASK register banked if v8M security extensions are enabled.

Note that we do not yet implement the functionality of the new
AIRCR.PRIS bit (which allows the effect of the NS copy of PRIMASK to
be restricted).

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 1503414539-28762-8-git-send-email-peter.maydell@linaro.org
parent acf94941
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -169,7 +169,7 @@ static inline int nvic_exec_prio(NVICState *s)

    if (env->v7m.faultmask) {
        running = -1;
    } else if (env->v7m.primask) {
    } else if (env->v7m.primask[env->v7m.secure]) {
        running = 0;
    } else if (env->v7m.basepri[env->v7m.secure] > 0) {
        running = env->v7m.basepri[env->v7m.secure] & nvic_gprio_mask(s);
+1 −1
Original line number Diff line number Diff line
@@ -431,7 +431,7 @@ typedef struct CPUARMState {
        uint32_t bfar; /* BusFault Address */
        unsigned mpu_ctrl; /* MPU_CTRL */
        int exception;
        uint32_t primask;
        uint32_t primask[2];
        uint32_t faultmask;
        uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
    } v7m;
+2 −2
Original line number Diff line number Diff line
@@ -8830,7 +8830,7 @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
        return (env->v7m.control & R_V7M_CONTROL_SPSEL_MASK) ?
            env->regs[13] : env->v7m.other_sp;
    case 16: /* PRIMASK */
        return env->v7m.primask;
        return env->v7m.primask[env->v7m.secure];
    case 17: /* BASEPRI */
    case 18: /* BASEPRI_MAX */
        return env->v7m.basepri[env->v7m.secure];
@@ -8890,7 +8890,7 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
        }
        break;
    case 16: /* PRIMASK */
        env->v7m.primask = val & 1;
        env->v7m.primask[env->v7m.secure] = val & 1;
        break;
    case 17: /* BASEPRI */
        env->v7m.basepri[env->v7m.secure] = val & 0xff;
+7 −2
Original line number Diff line number Diff line
@@ -103,7 +103,7 @@ static const VMStateDescription vmstate_m_faultmask_primask = {
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(env.v7m.faultmask, ARMCPU),
        VMSTATE_UINT32(env.v7m.primask, ARMCPU),
        VMSTATE_UINT32(env.v7m.primask[M_REG_NS], ARMCPU),
        VMSTATE_END_OF_LIST()
    }
};
@@ -251,6 +251,7 @@ static const VMStateDescription vmstate_m_security = {
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(env.v7m.secure, ARMCPU),
        VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU),
        VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU),
        VMSTATE_END_OF_LIST()
    }
};
@@ -271,9 +272,13 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
             * differences are that the T bit is not in the same place, the
             * primask/faultmask info may be in the CPSR I and F bits, and
             * we do not want the mode bits.
             * We know that this cleanup happened before v8M, so there
             * is no complication with banked primask/faultmask.
             */
            uint32_t newval = val;

            assert(!arm_feature(env, ARM_FEATURE_M_SECURITY));

            newval &= (CPSR_NZCV | CPSR_Q | CPSR_IT | CPSR_GE);
            if (val & CPSR_T) {
                newval |= XPSR_T;
@@ -287,7 +292,7 @@ static int get_cpsr(QEMUFile *f, void *opaque, size_t size,
                env->v7m.faultmask = 1;
            }
            if (val & CPSR_I) {
                env->v7m.primask = 1;
                env->v7m.primask[M_REG_NS] = 1;
            }
            val = newval;
        }