diff options
Diffstat (limited to 'target/arm/machine.c')
| -rw-r--r-- | target/arm/machine.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/target/arm/machine.c b/target/arm/machine.c index 2c8b43062f..2e28d086bd 100644 --- a/target/arm/machine.c +++ b/target/arm/machine.c @@ -191,6 +191,81 @@ static const VMStateDescription vmstate_m_faultmask_primask = { } }; +/* CSSELR is in a subsection because we didn't implement it previously. + * Migration from an old implementation will leave it at zero, which + * is OK since the only CPUs in the old implementation make the + * register RAZ/WI. + * Since there was no version of QEMU which implemented the CSSELR for + * just non-secure, we transfer both banks here rather than putting + * the secure banked version in the m-security subsection. + */ +static bool csselr_vmstate_validate(void *opaque, int version_id) +{ + ARMCPU *cpu = opaque; + + return cpu->env.v7m.csselr[M_REG_NS] <= R_V7M_CSSELR_INDEX_MASK + && cpu->env.v7m.csselr[M_REG_S] <= R_V7M_CSSELR_INDEX_MASK; +} + +static bool m_csselr_needed(void *opaque) +{ + ARMCPU *cpu = opaque; + + return !arm_v7m_csselr_razwi(cpu); +} + +static const VMStateDescription vmstate_m_csselr = { + .name = "cpu/m/csselr", + .version_id = 1, + .minimum_version_id = 1, + .needed = m_csselr_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(env.v7m.csselr, ARMCPU, M_REG_NUM_BANKS), + VMSTATE_VALIDATE("CSSELR is valid", csselr_vmstate_validate), + VMSTATE_END_OF_LIST() + } +}; + +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_other_sp = { + .name = "cpu/m/other-sp", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(env.v7m.other_sp, ARMCPU), + VMSTATE_END_OF_LIST() + } +}; + +static bool m_v8m_needed(void *opaque) +{ + ARMCPU *cpu = opaque; + CPUARMState *env = &cpu->env; + + return arm_feature(env, ARM_FEATURE_M) && arm_feature(env, ARM_FEATURE_V8); +} + +static const VMStateDescription vmstate_m_v8m = { + .name = "cpu/m/v8m", + .version_id = 1, + .minimum_version_id = 1, + .needed = m_v8m_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(env.v7m.msplim, ARMCPU, M_REG_NUM_BANKS), + VMSTATE_UINT32_ARRAY(env.v7m.psplim, ARMCPU, M_REG_NUM_BANKS), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_m = { .name = "cpu/m", .version_id = 4, @@ -212,6 +287,10 @@ static const VMStateDescription vmstate_m = { }, .subsections = (const VMStateDescription*[]) { &vmstate_m_faultmask_primask, + &vmstate_m_csselr, + &vmstate_m_scr, + &vmstate_m_other_sp, + &vmstate_m_v8m, NULL } }; @@ -375,6 +454,11 @@ 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), + /* AIRCR is not secure-only, but our implementation is R/O if the + * security extension is unimplemented, so we migrate it here. + */ + VMSTATE_UINT32(env.v7m.aircr, ARMCPU), VMSTATE_END_OF_LIST() } }; |