Commit 24ac0fb1 authored by Peter Maydell's avatar Peter Maydell
Browse files

hw/intc/armv7m_nvic: Implement SCR



We were previously making the system control register (SCR)
just RAZ/WI. Although we don't implement the functionality
this register controls, we should at least provide the state,
including the banked state for v8M.

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-id: 20180209165810.6668-7-peter.maydell@linaro.org
parent 43bbce7f
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -863,8 +863,7 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
        }
        return val;
    case 0xd10: /* System Control.  */
        /* TODO: Implement SLEEPONEXIT.  */
        return 0;
        return cpu->env.v7m.scr[attrs.secure];
    case 0xd14: /* Configuration Control.  */
        /* The BFHFNMIGN bit is the only non-banked bit; we
         * keep it in the non-secure copy of the register.
@@ -1285,8 +1284,13 @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
        }
        break;
    case 0xd10: /* System Control.  */
        /* TODO: Implement control registers.  */
        qemu_log_mask(LOG_UNIMP, "NVIC: SCR unimplemented\n");
        /* We don't implement deep-sleep so these bits are RAZ/WI.
         * The other bits in the register are banked.
         * QEMU's implementation ignores SEVONPEND and SLEEPONEXIT, which
         * is architecturally permitted.
         */
        value &= ~(R_V7M_SCR_SLEEPDEEP_MASK | R_V7M_SCR_SLEEPDEEPS_MASK);
        cpu->env.v7m.scr[attrs.secure] = value;
        break;
    case 0xd14: /* Configuration Control.  */
        /* Enforce RAZ/WI on reserved and must-RAZ/WI bits */
+7 −0
Original line number Diff line number Diff line
@@ -497,6 +497,7 @@ typedef struct CPUARMState {
        uint32_t aircr; /* only holds r/w state if security extn implemented */
        uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
        uint32_t csselr[M_REG_NUM_BANKS];
        uint32_t scr[M_REG_NUM_BANKS];
    } v7m;

    /* Information associated with an exception about to be taken:
@@ -1258,6 +1259,12 @@ FIELD(V7M_CCR, STKALIGN, 9, 1)
FIELD(V7M_CCR, DC, 16, 1)
FIELD(V7M_CCR, IC, 17, 1)

/* V7M SCR bits */
FIELD(V7M_SCR, SLEEPONEXIT, 1, 1)
FIELD(V7M_SCR, SLEEPDEEP, 2, 1)
FIELD(V7M_SCR, SLEEPDEEPS, 3, 1)
FIELD(V7M_SCR, SEVONPEND, 4, 1)

/* V7M AIRCR bits */
FIELD(V7M_AIRCR, VECTRESET, 0, 1)
FIELD(V7M_AIRCR, VECTCLRACTIVE, 1, 1)
+12 −0
Original line number Diff line number Diff line
@@ -226,6 +226,16 @@ static const VMStateDescription vmstate_m_csselr = {
    }
};

static const VMStateDescription vmstate_m_scr = {
    .name = "cpu/m/scr",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(env.v7m.scr[M_REG_NS], ARMCPU),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_m = {
    .name = "cpu/m",
    .version_id = 4,
@@ -248,6 +258,7 @@ static const VMStateDescription vmstate_m = {
    .subsections = (const VMStateDescription*[]) {
        &vmstate_m_faultmask_primask,
        &vmstate_m_csselr,
        &vmstate_m_scr,
        NULL
    }
};
@@ -411,6 +422,7 @@ static const VMStateDescription vmstate_m_security = {
        VMSTATE_UINT32(env.sau.rnr, ARMCPU),
        VMSTATE_VALIDATE("SAU_RNR is valid", sau_rnr_vmstate_validate),
        VMSTATE_UINT32(env.sau.ctrl, ARMCPU),
        VMSTATE_UINT32(env.v7m.scr[M_REG_S], ARMCPU),
        VMSTATE_END_OF_LIST()
    }
};