1fcf5ef2aSThomas Huth #include "qemu/osdep.h" 2fcf5ef2aSThomas Huth #include "qemu-common.h" 3fcf5ef2aSThomas Huth #include "cpu.h" 4fcf5ef2aSThomas Huth #include "hw/hw.h" 5fcf5ef2aSThomas Huth #include "hw/boards.h" 6fcf5ef2aSThomas Huth #include "qemu/error-report.h" 7fcf5ef2aSThomas Huth #include "sysemu/kvm.h" 8fcf5ef2aSThomas Huth #include "kvm_arm.h" 9fcf5ef2aSThomas Huth #include "internals.h" 10fcf5ef2aSThomas Huth #include "migration/cpu.h" 11fcf5ef2aSThomas Huth 12fcf5ef2aSThomas Huth static bool vfp_needed(void *opaque) 13fcf5ef2aSThomas Huth { 14fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 15fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 16fcf5ef2aSThomas Huth 17fcf5ef2aSThomas Huth return arm_feature(env, ARM_FEATURE_VFP); 18fcf5ef2aSThomas Huth } 19fcf5ef2aSThomas Huth 202c21ee76SJianjun Duan static int get_fpscr(QEMUFile *f, void *opaque, size_t size, 212c21ee76SJianjun Duan VMStateField *field) 22fcf5ef2aSThomas Huth { 23fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 24fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 25fcf5ef2aSThomas Huth uint32_t val = qemu_get_be32(f); 26fcf5ef2aSThomas Huth 27fcf5ef2aSThomas Huth vfp_set_fpscr(env, val); 28fcf5ef2aSThomas Huth return 0; 29fcf5ef2aSThomas Huth } 30fcf5ef2aSThomas Huth 312c21ee76SJianjun Duan static int put_fpscr(QEMUFile *f, void *opaque, size_t size, 322c21ee76SJianjun Duan VMStateField *field, QJSON *vmdesc) 33fcf5ef2aSThomas Huth { 34fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 35fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 36fcf5ef2aSThomas Huth 37fcf5ef2aSThomas Huth qemu_put_be32(f, vfp_get_fpscr(env)); 382c21ee76SJianjun Duan return 0; 39fcf5ef2aSThomas Huth } 40fcf5ef2aSThomas Huth 41fcf5ef2aSThomas Huth static const VMStateInfo vmstate_fpscr = { 42fcf5ef2aSThomas Huth .name = "fpscr", 43fcf5ef2aSThomas Huth .get = get_fpscr, 44fcf5ef2aSThomas Huth .put = put_fpscr, 45fcf5ef2aSThomas Huth }; 46fcf5ef2aSThomas Huth 47fcf5ef2aSThomas Huth static const VMStateDescription vmstate_vfp = { 48fcf5ef2aSThomas Huth .name = "cpu/vfp", 49fcf5ef2aSThomas Huth .version_id = 3, 50fcf5ef2aSThomas Huth .minimum_version_id = 3, 51fcf5ef2aSThomas Huth .needed = vfp_needed, 52fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 53c39c2b90SRichard Henderson /* For compatibility, store Qn out of Zn here. */ 54c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[0].d, ARMCPU, 0, 2), 55c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[1].d, ARMCPU, 0, 2), 56c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[2].d, ARMCPU, 0, 2), 57c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[3].d, ARMCPU, 0, 2), 58c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[4].d, ARMCPU, 0, 2), 59c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[5].d, ARMCPU, 0, 2), 60c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[6].d, ARMCPU, 0, 2), 61c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[7].d, ARMCPU, 0, 2), 62c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[8].d, ARMCPU, 0, 2), 63c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[9].d, ARMCPU, 0, 2), 64c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[10].d, ARMCPU, 0, 2), 65c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[11].d, ARMCPU, 0, 2), 66c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[12].d, ARMCPU, 0, 2), 67c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[13].d, ARMCPU, 0, 2), 68c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[14].d, ARMCPU, 0, 2), 69c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[15].d, ARMCPU, 0, 2), 70c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[16].d, ARMCPU, 0, 2), 71c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[17].d, ARMCPU, 0, 2), 72c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[18].d, ARMCPU, 0, 2), 73c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[19].d, ARMCPU, 0, 2), 74c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[20].d, ARMCPU, 0, 2), 75c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[21].d, ARMCPU, 0, 2), 76c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[22].d, ARMCPU, 0, 2), 77c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[23].d, ARMCPU, 0, 2), 78c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[24].d, ARMCPU, 0, 2), 79c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[25].d, ARMCPU, 0, 2), 80c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[26].d, ARMCPU, 0, 2), 81c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[27].d, ARMCPU, 0, 2), 82c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[28].d, ARMCPU, 0, 2), 83c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[29].d, ARMCPU, 0, 2), 84c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[30].d, ARMCPU, 0, 2), 85c39c2b90SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(env.vfp.zregs[31].d, ARMCPU, 0, 2), 86c39c2b90SRichard Henderson 87fcf5ef2aSThomas Huth /* The xregs array is a little awkward because element 1 (FPSCR) 88fcf5ef2aSThomas Huth * requires a specific accessor, so we have to split it up in 89fcf5ef2aSThomas Huth * the vmstate: 90fcf5ef2aSThomas Huth */ 91fcf5ef2aSThomas Huth VMSTATE_UINT32(env.vfp.xregs[0], ARMCPU), 92fcf5ef2aSThomas Huth VMSTATE_UINT32_SUB_ARRAY(env.vfp.xregs, ARMCPU, 2, 14), 93fcf5ef2aSThomas Huth { 94fcf5ef2aSThomas Huth .name = "fpscr", 95fcf5ef2aSThomas Huth .version_id = 0, 96fcf5ef2aSThomas Huth .size = sizeof(uint32_t), 97fcf5ef2aSThomas Huth .info = &vmstate_fpscr, 98fcf5ef2aSThomas Huth .flags = VMS_SINGLE, 99fcf5ef2aSThomas Huth .offset = 0, 100fcf5ef2aSThomas Huth }, 101fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 102fcf5ef2aSThomas Huth } 103fcf5ef2aSThomas Huth }; 104fcf5ef2aSThomas Huth 105fcf5ef2aSThomas Huth static bool iwmmxt_needed(void *opaque) 106fcf5ef2aSThomas Huth { 107fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 108fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 109fcf5ef2aSThomas Huth 110fcf5ef2aSThomas Huth return arm_feature(env, ARM_FEATURE_IWMMXT); 111fcf5ef2aSThomas Huth } 112fcf5ef2aSThomas Huth 113fcf5ef2aSThomas Huth static const VMStateDescription vmstate_iwmmxt = { 114fcf5ef2aSThomas Huth .name = "cpu/iwmmxt", 115fcf5ef2aSThomas Huth .version_id = 1, 116fcf5ef2aSThomas Huth .minimum_version_id = 1, 117fcf5ef2aSThomas Huth .needed = iwmmxt_needed, 118fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 119fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.iwmmxt.regs, ARMCPU, 16), 120fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.iwmmxt.cregs, ARMCPU, 16), 121fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 122fcf5ef2aSThomas Huth } 123fcf5ef2aSThomas Huth }; 124fcf5ef2aSThomas Huth 125ef401601SRichard Henderson #ifdef TARGET_AARCH64 126ef401601SRichard Henderson /* The expression ARM_MAX_VQ - 2 is 0 for pure AArch32 build, 127ef401601SRichard Henderson * and ARMPredicateReg is actively empty. This triggers errors 128ef401601SRichard Henderson * in the expansion of the VMSTATE macros. 129ef401601SRichard Henderson */ 130ef401601SRichard Henderson 131ef401601SRichard Henderson static bool sve_needed(void *opaque) 132ef401601SRichard Henderson { 133ef401601SRichard Henderson ARMCPU *cpu = opaque; 134ef401601SRichard Henderson CPUARMState *env = &cpu->env; 135ef401601SRichard Henderson 136ef401601SRichard Henderson return arm_feature(env, ARM_FEATURE_SVE); 137ef401601SRichard Henderson } 138ef401601SRichard Henderson 139ef401601SRichard Henderson /* The first two words of each Zreg is stored in VFP state. */ 140ef401601SRichard Henderson static const VMStateDescription vmstate_zreg_hi_reg = { 141ef401601SRichard Henderson .name = "cpu/sve/zreg_hi", 142ef401601SRichard Henderson .version_id = 1, 143ef401601SRichard Henderson .minimum_version_id = 1, 144ef401601SRichard Henderson .fields = (VMStateField[]) { 145ef401601SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(d, ARMVectorReg, 2, ARM_MAX_VQ - 2), 146ef401601SRichard Henderson VMSTATE_END_OF_LIST() 147ef401601SRichard Henderson } 148ef401601SRichard Henderson }; 149ef401601SRichard Henderson 150ef401601SRichard Henderson static const VMStateDescription vmstate_preg_reg = { 151ef401601SRichard Henderson .name = "cpu/sve/preg", 152ef401601SRichard Henderson .version_id = 1, 153ef401601SRichard Henderson .minimum_version_id = 1, 154ef401601SRichard Henderson .fields = (VMStateField[]) { 155ef401601SRichard Henderson VMSTATE_UINT64_ARRAY(p, ARMPredicateReg, 2 * ARM_MAX_VQ / 8), 156ef401601SRichard Henderson VMSTATE_END_OF_LIST() 157ef401601SRichard Henderson } 158ef401601SRichard Henderson }; 159ef401601SRichard Henderson 160ef401601SRichard Henderson static const VMStateDescription vmstate_sve = { 161ef401601SRichard Henderson .name = "cpu/sve", 162ef401601SRichard Henderson .version_id = 1, 163ef401601SRichard Henderson .minimum_version_id = 1, 164ef401601SRichard Henderson .needed = sve_needed, 165ef401601SRichard Henderson .fields = (VMStateField[]) { 166ef401601SRichard Henderson VMSTATE_STRUCT_ARRAY(env.vfp.zregs, ARMCPU, 32, 0, 167ef401601SRichard Henderson vmstate_zreg_hi_reg, ARMVectorReg), 168ef401601SRichard Henderson VMSTATE_STRUCT_ARRAY(env.vfp.pregs, ARMCPU, 17, 0, 169ef401601SRichard Henderson vmstate_preg_reg, ARMPredicateReg), 170ef401601SRichard Henderson VMSTATE_END_OF_LIST() 171ef401601SRichard Henderson } 172ef401601SRichard Henderson }; 173ef401601SRichard Henderson #endif /* AARCH64 */ 174ef401601SRichard Henderson 175fcf5ef2aSThomas Huth static bool m_needed(void *opaque) 176fcf5ef2aSThomas Huth { 177fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 178fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 179fcf5ef2aSThomas Huth 180fcf5ef2aSThomas Huth return arm_feature(env, ARM_FEATURE_M); 181fcf5ef2aSThomas Huth } 182fcf5ef2aSThomas Huth 183e6ae5981SPeter Maydell static const VMStateDescription vmstate_m_faultmask_primask = { 184e6ae5981SPeter Maydell .name = "cpu/m/faultmask-primask", 185e6ae5981SPeter Maydell .version_id = 1, 186e6ae5981SPeter Maydell .minimum_version_id = 1, 187e6ae5981SPeter Maydell .fields = (VMStateField[]) { 18842a6686bSPeter Maydell VMSTATE_UINT32(env.v7m.faultmask[M_REG_NS], ARMCPU), 1896d804834SPeter Maydell VMSTATE_UINT32(env.v7m.primask[M_REG_NS], ARMCPU), 190e6ae5981SPeter Maydell VMSTATE_END_OF_LIST() 191e6ae5981SPeter Maydell } 192e6ae5981SPeter Maydell }; 193e6ae5981SPeter Maydell 194*43bbce7fSPeter Maydell /* CSSELR is in a subsection because we didn't implement it previously. 195*43bbce7fSPeter Maydell * Migration from an old implementation will leave it at zero, which 196*43bbce7fSPeter Maydell * is OK since the only CPUs in the old implementation make the 197*43bbce7fSPeter Maydell * register RAZ/WI. 198*43bbce7fSPeter Maydell * Since there was no version of QEMU which implemented the CSSELR for 199*43bbce7fSPeter Maydell * just non-secure, we transfer both banks here rather than putting 200*43bbce7fSPeter Maydell * the secure banked version in the m-security subsection. 201*43bbce7fSPeter Maydell */ 202*43bbce7fSPeter Maydell static bool csselr_vmstate_validate(void *opaque, int version_id) 203*43bbce7fSPeter Maydell { 204*43bbce7fSPeter Maydell ARMCPU *cpu = opaque; 205*43bbce7fSPeter Maydell 206*43bbce7fSPeter Maydell return cpu->env.v7m.csselr[M_REG_NS] <= R_V7M_CSSELR_INDEX_MASK 207*43bbce7fSPeter Maydell && cpu->env.v7m.csselr[M_REG_S] <= R_V7M_CSSELR_INDEX_MASK; 208*43bbce7fSPeter Maydell } 209*43bbce7fSPeter Maydell 210*43bbce7fSPeter Maydell static bool m_csselr_needed(void *opaque) 211*43bbce7fSPeter Maydell { 212*43bbce7fSPeter Maydell ARMCPU *cpu = opaque; 213*43bbce7fSPeter Maydell 214*43bbce7fSPeter Maydell return !arm_v7m_csselr_razwi(cpu); 215*43bbce7fSPeter Maydell } 216*43bbce7fSPeter Maydell 217*43bbce7fSPeter Maydell static const VMStateDescription vmstate_m_csselr = { 218*43bbce7fSPeter Maydell .name = "cpu/m/csselr", 219*43bbce7fSPeter Maydell .version_id = 1, 220*43bbce7fSPeter Maydell .minimum_version_id = 1, 221*43bbce7fSPeter Maydell .needed = m_csselr_needed, 222*43bbce7fSPeter Maydell .fields = (VMStateField[]) { 223*43bbce7fSPeter Maydell VMSTATE_UINT32_ARRAY(env.v7m.csselr, ARMCPU, M_REG_NUM_BANKS), 224*43bbce7fSPeter Maydell VMSTATE_VALIDATE("CSSELR is valid", csselr_vmstate_validate), 225*43bbce7fSPeter Maydell VMSTATE_END_OF_LIST() 226*43bbce7fSPeter Maydell } 227*43bbce7fSPeter Maydell }; 228*43bbce7fSPeter Maydell 229fcf5ef2aSThomas Huth static const VMStateDescription vmstate_m = { 230fcf5ef2aSThomas Huth .name = "cpu/m", 23129c483a5SMichael Davidsaver .version_id = 4, 23229c483a5SMichael Davidsaver .minimum_version_id = 4, 233fcf5ef2aSThomas Huth .needed = m_needed, 234fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 23545db7ba6SPeter Maydell VMSTATE_UINT32(env.v7m.vecbase[M_REG_NS], ARMCPU), 236acf94941SPeter Maydell VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU), 2378bfc26eaSPeter Maydell VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU), 2389d40cd8aSPeter Maydell VMSTATE_UINT32(env.v7m.ccr[M_REG_NS], ARMCPU), 239334e8dadSPeter Maydell VMSTATE_UINT32(env.v7m.cfsr[M_REG_NS], ARMCPU), 2402c4da50dSPeter Maydell VMSTATE_UINT32(env.v7m.hfsr, ARMCPU), 2412c4da50dSPeter Maydell VMSTATE_UINT32(env.v7m.dfsr, ARMCPU), 242c51a5cfcSPeter Maydell VMSTATE_UINT32(env.v7m.mmfar[M_REG_NS], ARMCPU), 2432c4da50dSPeter Maydell VMSTATE_UINT32(env.v7m.bfar, ARMCPU), 244ecf5e8eaSPeter Maydell VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_NS], ARMCPU), 245fcf5ef2aSThomas Huth VMSTATE_INT32(env.v7m.exception, ARMCPU), 246fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 247e6ae5981SPeter Maydell }, 248e6ae5981SPeter Maydell .subsections = (const VMStateDescription*[]) { 249e6ae5981SPeter Maydell &vmstate_m_faultmask_primask, 250*43bbce7fSPeter Maydell &vmstate_m_csselr, 251e6ae5981SPeter Maydell NULL 252fcf5ef2aSThomas Huth } 253fcf5ef2aSThomas Huth }; 254fcf5ef2aSThomas Huth 255fcf5ef2aSThomas Huth static bool thumb2ee_needed(void *opaque) 256fcf5ef2aSThomas Huth { 257fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 258fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 259fcf5ef2aSThomas Huth 260fcf5ef2aSThomas Huth return arm_feature(env, ARM_FEATURE_THUMB2EE); 261fcf5ef2aSThomas Huth } 262fcf5ef2aSThomas Huth 263fcf5ef2aSThomas Huth static const VMStateDescription vmstate_thumb2ee = { 264fcf5ef2aSThomas Huth .name = "cpu/thumb2ee", 265fcf5ef2aSThomas Huth .version_id = 1, 266fcf5ef2aSThomas Huth .minimum_version_id = 1, 267fcf5ef2aSThomas Huth .needed = thumb2ee_needed, 268fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 269fcf5ef2aSThomas Huth VMSTATE_UINT32(env.teecr, ARMCPU), 270fcf5ef2aSThomas Huth VMSTATE_UINT32(env.teehbr, ARMCPU), 271fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 272fcf5ef2aSThomas Huth } 273fcf5ef2aSThomas Huth }; 274fcf5ef2aSThomas Huth 275fcf5ef2aSThomas Huth static bool pmsav7_needed(void *opaque) 276fcf5ef2aSThomas Huth { 277fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 278fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 279fcf5ef2aSThomas Huth 280452a0955SPeter Maydell return arm_feature(env, ARM_FEATURE_PMSA) && 2810e1a46bbSPeter Maydell arm_feature(env, ARM_FEATURE_V7) && 2820e1a46bbSPeter Maydell !arm_feature(env, ARM_FEATURE_V8); 283fcf5ef2aSThomas Huth } 284fcf5ef2aSThomas Huth 285fcf5ef2aSThomas Huth static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id) 286fcf5ef2aSThomas Huth { 287fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 288fcf5ef2aSThomas Huth 2891bc04a88SPeter Maydell return cpu->env.pmsav7.rnr[M_REG_NS] < cpu->pmsav7_dregion; 290fcf5ef2aSThomas Huth } 291fcf5ef2aSThomas Huth 292fcf5ef2aSThomas Huth static const VMStateDescription vmstate_pmsav7 = { 293fcf5ef2aSThomas Huth .name = "cpu/pmsav7", 294fcf5ef2aSThomas Huth .version_id = 1, 295fcf5ef2aSThomas Huth .minimum_version_id = 1, 296fcf5ef2aSThomas Huth .needed = pmsav7_needed, 297fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 298fcf5ef2aSThomas Huth VMSTATE_VARRAY_UINT32(env.pmsav7.drbar, ARMCPU, pmsav7_dregion, 0, 299fcf5ef2aSThomas Huth vmstate_info_uint32, uint32_t), 300fcf5ef2aSThomas Huth VMSTATE_VARRAY_UINT32(env.pmsav7.drsr, ARMCPU, pmsav7_dregion, 0, 301fcf5ef2aSThomas Huth vmstate_info_uint32, uint32_t), 302fcf5ef2aSThomas Huth VMSTATE_VARRAY_UINT32(env.pmsav7.dracr, ARMCPU, pmsav7_dregion, 0, 303fcf5ef2aSThomas Huth vmstate_info_uint32, uint32_t), 304fcf5ef2aSThomas Huth VMSTATE_VALIDATE("rgnr is valid", pmsav7_rgnr_vmstate_validate), 305fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 306fcf5ef2aSThomas Huth } 307fcf5ef2aSThomas Huth }; 308fcf5ef2aSThomas Huth 309f1a46940SPeter Maydell static bool pmsav7_rnr_needed(void *opaque) 310f1a46940SPeter Maydell { 311f1a46940SPeter Maydell ARMCPU *cpu = opaque; 312f1a46940SPeter Maydell CPUARMState *env = &cpu->env; 313f1a46940SPeter Maydell 314f1a46940SPeter Maydell /* For R profile cores pmsav7.rnr is migrated via the cpreg 315f1a46940SPeter Maydell * "RGNR" definition in helper.h. For M profile we have to 316f1a46940SPeter Maydell * migrate it separately. 317f1a46940SPeter Maydell */ 318f1a46940SPeter Maydell return arm_feature(env, ARM_FEATURE_M); 319f1a46940SPeter Maydell } 320f1a46940SPeter Maydell 321f1a46940SPeter Maydell static const VMStateDescription vmstate_pmsav7_rnr = { 322f1a46940SPeter Maydell .name = "cpu/pmsav7-rnr", 323f1a46940SPeter Maydell .version_id = 1, 324f1a46940SPeter Maydell .minimum_version_id = 1, 325f1a46940SPeter Maydell .needed = pmsav7_rnr_needed, 326f1a46940SPeter Maydell .fields = (VMStateField[]) { 3271bc04a88SPeter Maydell VMSTATE_UINT32(env.pmsav7.rnr[M_REG_NS], ARMCPU), 328f1a46940SPeter Maydell VMSTATE_END_OF_LIST() 329f1a46940SPeter Maydell } 330f1a46940SPeter Maydell }; 331f1a46940SPeter Maydell 3320e1a46bbSPeter Maydell static bool pmsav8_needed(void *opaque) 3330e1a46bbSPeter Maydell { 3340e1a46bbSPeter Maydell ARMCPU *cpu = opaque; 3350e1a46bbSPeter Maydell CPUARMState *env = &cpu->env; 3360e1a46bbSPeter Maydell 3370e1a46bbSPeter Maydell return arm_feature(env, ARM_FEATURE_PMSA) && 3380e1a46bbSPeter Maydell arm_feature(env, ARM_FEATURE_V8); 3390e1a46bbSPeter Maydell } 3400e1a46bbSPeter Maydell 3410e1a46bbSPeter Maydell static const VMStateDescription vmstate_pmsav8 = { 3420e1a46bbSPeter Maydell .name = "cpu/pmsav8", 3430e1a46bbSPeter Maydell .version_id = 1, 3440e1a46bbSPeter Maydell .minimum_version_id = 1, 3450e1a46bbSPeter Maydell .needed = pmsav8_needed, 3460e1a46bbSPeter Maydell .fields = (VMStateField[]) { 34762c58ee0SPeter Maydell VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_NS], ARMCPU, pmsav7_dregion, 34862c58ee0SPeter Maydell 0, vmstate_info_uint32, uint32_t), 34962c58ee0SPeter Maydell VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_NS], ARMCPU, pmsav7_dregion, 35062c58ee0SPeter Maydell 0, vmstate_info_uint32, uint32_t), 3514125e6feSPeter Maydell VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU), 3524125e6feSPeter Maydell VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU), 3530e1a46bbSPeter Maydell VMSTATE_END_OF_LIST() 3540e1a46bbSPeter Maydell } 3550e1a46bbSPeter Maydell }; 3560e1a46bbSPeter Maydell 3571bc04a88SPeter Maydell static bool s_rnr_vmstate_validate(void *opaque, int version_id) 3581bc04a88SPeter Maydell { 3591bc04a88SPeter Maydell ARMCPU *cpu = opaque; 3601bc04a88SPeter Maydell 3611bc04a88SPeter Maydell return cpu->env.pmsav7.rnr[M_REG_S] < cpu->pmsav7_dregion; 3621bc04a88SPeter Maydell } 3631bc04a88SPeter Maydell 3649901c576SPeter Maydell static bool sau_rnr_vmstate_validate(void *opaque, int version_id) 3659901c576SPeter Maydell { 3669901c576SPeter Maydell ARMCPU *cpu = opaque; 3679901c576SPeter Maydell 3689901c576SPeter Maydell return cpu->env.sau.rnr < cpu->sau_sregion; 3699901c576SPeter Maydell } 3709901c576SPeter Maydell 3711e577cc7SPeter Maydell static bool m_security_needed(void *opaque) 3721e577cc7SPeter Maydell { 3731e577cc7SPeter Maydell ARMCPU *cpu = opaque; 3741e577cc7SPeter Maydell CPUARMState *env = &cpu->env; 3751e577cc7SPeter Maydell 3761e577cc7SPeter Maydell return arm_feature(env, ARM_FEATURE_M_SECURITY); 3771e577cc7SPeter Maydell } 3781e577cc7SPeter Maydell 3791e577cc7SPeter Maydell static const VMStateDescription vmstate_m_security = { 3801e577cc7SPeter Maydell .name = "cpu/m-security", 3811e577cc7SPeter Maydell .version_id = 1, 3821e577cc7SPeter Maydell .minimum_version_id = 1, 3831e577cc7SPeter Maydell .needed = m_security_needed, 3841e577cc7SPeter Maydell .fields = (VMStateField[]) { 3851e577cc7SPeter Maydell VMSTATE_UINT32(env.v7m.secure, ARMCPU), 386fb602cb7SPeter Maydell VMSTATE_UINT32(env.v7m.other_ss_msp, ARMCPU), 387fb602cb7SPeter Maydell VMSTATE_UINT32(env.v7m.other_ss_psp, ARMCPU), 388acf94941SPeter Maydell VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU), 3896d804834SPeter Maydell VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU), 39042a6686bSPeter Maydell VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU), 3918bfc26eaSPeter Maydell VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU), 39245db7ba6SPeter Maydell VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU), 3934125e6feSPeter Maydell VMSTATE_UINT32(env.pmsav8.mair0[M_REG_S], ARMCPU), 3944125e6feSPeter Maydell VMSTATE_UINT32(env.pmsav8.mair1[M_REG_S], ARMCPU), 39562c58ee0SPeter Maydell VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_S], ARMCPU, pmsav7_dregion, 39662c58ee0SPeter Maydell 0, vmstate_info_uint32, uint32_t), 39762c58ee0SPeter Maydell VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_S], ARMCPU, pmsav7_dregion, 39862c58ee0SPeter Maydell 0, vmstate_info_uint32, uint32_t), 3991bc04a88SPeter Maydell VMSTATE_UINT32(env.pmsav7.rnr[M_REG_S], ARMCPU), 4001bc04a88SPeter Maydell VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate), 401ecf5e8eaSPeter Maydell VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU), 4029d40cd8aSPeter Maydell VMSTATE_UINT32(env.v7m.ccr[M_REG_S], ARMCPU), 403c51a5cfcSPeter Maydell VMSTATE_UINT32(env.v7m.mmfar[M_REG_S], ARMCPU), 404334e8dadSPeter Maydell VMSTATE_UINT32(env.v7m.cfsr[M_REG_S], ARMCPU), 405bed079daSPeter Maydell VMSTATE_UINT32(env.v7m.sfsr, ARMCPU), 406bed079daSPeter Maydell VMSTATE_UINT32(env.v7m.sfar, ARMCPU), 4079901c576SPeter Maydell VMSTATE_VARRAY_UINT32(env.sau.rbar, ARMCPU, sau_sregion, 0, 4089901c576SPeter Maydell vmstate_info_uint32, uint32_t), 4099901c576SPeter Maydell VMSTATE_VARRAY_UINT32(env.sau.rlar, ARMCPU, sau_sregion, 0, 4109901c576SPeter Maydell vmstate_info_uint32, uint32_t), 4119901c576SPeter Maydell VMSTATE_UINT32(env.sau.rnr, ARMCPU), 4129901c576SPeter Maydell VMSTATE_VALIDATE("SAU_RNR is valid", sau_rnr_vmstate_validate), 4139901c576SPeter Maydell VMSTATE_UINT32(env.sau.ctrl, ARMCPU), 4141e577cc7SPeter Maydell VMSTATE_END_OF_LIST() 4151e577cc7SPeter Maydell } 4161e577cc7SPeter Maydell }; 4171e577cc7SPeter Maydell 4182c21ee76SJianjun Duan static int get_cpsr(QEMUFile *f, void *opaque, size_t size, 4192c21ee76SJianjun Duan VMStateField *field) 420fcf5ef2aSThomas Huth { 421fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 422fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 423fcf5ef2aSThomas Huth uint32_t val = qemu_get_be32(f); 424fcf5ef2aSThomas Huth 425e6ae5981SPeter Maydell if (arm_feature(env, ARM_FEATURE_M)) { 426eeade001SPeter Maydell if (val & XPSR_EXCP) { 427eeade001SPeter Maydell /* This is a CPSR format value from an older QEMU. (We can tell 428eeade001SPeter Maydell * because values transferred in XPSR format always have zero 429eeade001SPeter Maydell * for the EXCP field, and CPSR format will always have bit 4 430eeade001SPeter Maydell * set in CPSR_M.) Rearrange it into XPSR format. The significant 431eeade001SPeter Maydell * differences are that the T bit is not in the same place, the 432eeade001SPeter Maydell * primask/faultmask info may be in the CPSR I and F bits, and 433eeade001SPeter Maydell * we do not want the mode bits. 4346d804834SPeter Maydell * We know that this cleanup happened before v8M, so there 4356d804834SPeter Maydell * is no complication with banked primask/faultmask. 436eeade001SPeter Maydell */ 437eeade001SPeter Maydell uint32_t newval = val; 438eeade001SPeter Maydell 4396d804834SPeter Maydell assert(!arm_feature(env, ARM_FEATURE_M_SECURITY)); 4406d804834SPeter Maydell 441eeade001SPeter Maydell newval &= (CPSR_NZCV | CPSR_Q | CPSR_IT | CPSR_GE); 442eeade001SPeter Maydell if (val & CPSR_T) { 443eeade001SPeter Maydell newval |= XPSR_T; 444eeade001SPeter Maydell } 445e6ae5981SPeter Maydell /* If the I or F bits are set then this is a migration from 446e6ae5981SPeter Maydell * an old QEMU which still stored the M profile FAULTMASK 447eeade001SPeter Maydell * and PRIMASK in env->daif. For a new QEMU, the data is 448eeade001SPeter Maydell * transferred using the vmstate_m_faultmask_primask subsection. 449e6ae5981SPeter Maydell */ 450e6ae5981SPeter Maydell if (val & CPSR_F) { 45142a6686bSPeter Maydell env->v7m.faultmask[M_REG_NS] = 1; 452e6ae5981SPeter Maydell } 453e6ae5981SPeter Maydell if (val & CPSR_I) { 4546d804834SPeter Maydell env->v7m.primask[M_REG_NS] = 1; 455e6ae5981SPeter Maydell } 456eeade001SPeter Maydell val = newval; 457eeade001SPeter Maydell } 458eeade001SPeter Maydell /* Ignore the low bits, they are handled by vmstate_m. */ 459eeade001SPeter Maydell xpsr_write(env, val, ~XPSR_EXCP); 460eeade001SPeter Maydell return 0; 461e6ae5981SPeter Maydell } 462e6ae5981SPeter Maydell 463fcf5ef2aSThomas Huth env->aarch64 = ((val & PSTATE_nRW) == 0); 464fcf5ef2aSThomas Huth 465fcf5ef2aSThomas Huth if (is_a64(env)) { 466fcf5ef2aSThomas Huth pstate_write(env, val); 467fcf5ef2aSThomas Huth return 0; 468fcf5ef2aSThomas Huth } 469fcf5ef2aSThomas Huth 470fcf5ef2aSThomas Huth cpsr_write(env, val, 0xffffffff, CPSRWriteRaw); 471fcf5ef2aSThomas Huth return 0; 472fcf5ef2aSThomas Huth } 473fcf5ef2aSThomas Huth 4742c21ee76SJianjun Duan static int put_cpsr(QEMUFile *f, void *opaque, size_t size, 4752c21ee76SJianjun Duan VMStateField *field, QJSON *vmdesc) 476fcf5ef2aSThomas Huth { 477fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 478fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 479fcf5ef2aSThomas Huth uint32_t val; 480fcf5ef2aSThomas Huth 481eeade001SPeter Maydell if (arm_feature(env, ARM_FEATURE_M)) { 482eeade001SPeter Maydell /* The low 9 bits are v7m.exception, which is handled by vmstate_m. */ 483eeade001SPeter Maydell val = xpsr_read(env) & ~XPSR_EXCP; 484eeade001SPeter Maydell } else if (is_a64(env)) { 485fcf5ef2aSThomas Huth val = pstate_read(env); 486fcf5ef2aSThomas Huth } else { 487fcf5ef2aSThomas Huth val = cpsr_read(env); 488fcf5ef2aSThomas Huth } 489fcf5ef2aSThomas Huth 490fcf5ef2aSThomas Huth qemu_put_be32(f, val); 4912c21ee76SJianjun Duan return 0; 492fcf5ef2aSThomas Huth } 493fcf5ef2aSThomas Huth 494fcf5ef2aSThomas Huth static const VMStateInfo vmstate_cpsr = { 495fcf5ef2aSThomas Huth .name = "cpsr", 496fcf5ef2aSThomas Huth .get = get_cpsr, 497fcf5ef2aSThomas Huth .put = put_cpsr, 498fcf5ef2aSThomas Huth }; 499fcf5ef2aSThomas Huth 500062ba099SAlex Bennée static int get_power(QEMUFile *f, void *opaque, size_t size, 501062ba099SAlex Bennée VMStateField *field) 502062ba099SAlex Bennée { 503062ba099SAlex Bennée ARMCPU *cpu = opaque; 504062ba099SAlex Bennée bool powered_off = qemu_get_byte(f); 505062ba099SAlex Bennée cpu->power_state = powered_off ? PSCI_OFF : PSCI_ON; 506062ba099SAlex Bennée return 0; 507062ba099SAlex Bennée } 508062ba099SAlex Bennée 509062ba099SAlex Bennée static int put_power(QEMUFile *f, void *opaque, size_t size, 510062ba099SAlex Bennée VMStateField *field, QJSON *vmdesc) 511062ba099SAlex Bennée { 512062ba099SAlex Bennée ARMCPU *cpu = opaque; 513062ba099SAlex Bennée 514062ba099SAlex Bennée /* Migration should never happen while we transition power states */ 515062ba099SAlex Bennée 516062ba099SAlex Bennée if (cpu->power_state == PSCI_ON || 517062ba099SAlex Bennée cpu->power_state == PSCI_OFF) { 518062ba099SAlex Bennée bool powered_off = (cpu->power_state == PSCI_OFF) ? true : false; 519062ba099SAlex Bennée qemu_put_byte(f, powered_off); 520062ba099SAlex Bennée return 0; 521062ba099SAlex Bennée } else { 522062ba099SAlex Bennée return 1; 523062ba099SAlex Bennée } 524062ba099SAlex Bennée } 525062ba099SAlex Bennée 526062ba099SAlex Bennée static const VMStateInfo vmstate_powered_off = { 527062ba099SAlex Bennée .name = "powered_off", 528062ba099SAlex Bennée .get = get_power, 529062ba099SAlex Bennée .put = put_power, 530062ba099SAlex Bennée }; 531062ba099SAlex Bennée 53244b1ff31SDr. David Alan Gilbert static int cpu_pre_save(void *opaque) 533fcf5ef2aSThomas Huth { 534fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 535fcf5ef2aSThomas Huth 536fcf5ef2aSThomas Huth if (kvm_enabled()) { 537fcf5ef2aSThomas Huth if (!write_kvmstate_to_list(cpu)) { 538fcf5ef2aSThomas Huth /* This should never fail */ 539fcf5ef2aSThomas Huth abort(); 540fcf5ef2aSThomas Huth } 541fcf5ef2aSThomas Huth } else { 542fcf5ef2aSThomas Huth if (!write_cpustate_to_list(cpu)) { 543fcf5ef2aSThomas Huth /* This should never fail. */ 544fcf5ef2aSThomas Huth abort(); 545fcf5ef2aSThomas Huth } 546fcf5ef2aSThomas Huth } 547fcf5ef2aSThomas Huth 548fcf5ef2aSThomas Huth cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len; 549fcf5ef2aSThomas Huth memcpy(cpu->cpreg_vmstate_indexes, cpu->cpreg_indexes, 550fcf5ef2aSThomas Huth cpu->cpreg_array_len * sizeof(uint64_t)); 551fcf5ef2aSThomas Huth memcpy(cpu->cpreg_vmstate_values, cpu->cpreg_values, 552fcf5ef2aSThomas Huth cpu->cpreg_array_len * sizeof(uint64_t)); 55344b1ff31SDr. David Alan Gilbert 55444b1ff31SDr. David Alan Gilbert return 0; 555fcf5ef2aSThomas Huth } 556fcf5ef2aSThomas Huth 557fcf5ef2aSThomas Huth static int cpu_post_load(void *opaque, int version_id) 558fcf5ef2aSThomas Huth { 559fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 560fcf5ef2aSThomas Huth int i, v; 561fcf5ef2aSThomas Huth 562fcf5ef2aSThomas Huth /* Update the values list from the incoming migration data. 563fcf5ef2aSThomas Huth * Anything in the incoming data which we don't know about is 564fcf5ef2aSThomas Huth * a migration failure; anything we know about but the incoming 565fcf5ef2aSThomas Huth * data doesn't specify retains its current (reset) value. 566fcf5ef2aSThomas Huth * The indexes list remains untouched -- we only inspect the 567fcf5ef2aSThomas Huth * incoming migration index list so we can match the values array 568fcf5ef2aSThomas Huth * entries with the right slots in our own values array. 569fcf5ef2aSThomas Huth */ 570fcf5ef2aSThomas Huth 571fcf5ef2aSThomas Huth for (i = 0, v = 0; i < cpu->cpreg_array_len 572fcf5ef2aSThomas Huth && v < cpu->cpreg_vmstate_array_len; i++) { 573fcf5ef2aSThomas Huth if (cpu->cpreg_vmstate_indexes[v] > cpu->cpreg_indexes[i]) { 574fcf5ef2aSThomas Huth /* register in our list but not incoming : skip it */ 575fcf5ef2aSThomas Huth continue; 576fcf5ef2aSThomas Huth } 577fcf5ef2aSThomas Huth if (cpu->cpreg_vmstate_indexes[v] < cpu->cpreg_indexes[i]) { 578fcf5ef2aSThomas Huth /* register in their list but not ours: fail migration */ 579fcf5ef2aSThomas Huth return -1; 580fcf5ef2aSThomas Huth } 581fcf5ef2aSThomas Huth /* matching register, copy the value over */ 582fcf5ef2aSThomas Huth cpu->cpreg_values[i] = cpu->cpreg_vmstate_values[v]; 583fcf5ef2aSThomas Huth v++; 584fcf5ef2aSThomas Huth } 585fcf5ef2aSThomas Huth 586fcf5ef2aSThomas Huth if (kvm_enabled()) { 587fcf5ef2aSThomas Huth if (!write_list_to_kvmstate(cpu, KVM_PUT_FULL_STATE)) { 588fcf5ef2aSThomas Huth return -1; 589fcf5ef2aSThomas Huth } 590fcf5ef2aSThomas Huth /* Note that it's OK for the TCG side not to know about 591fcf5ef2aSThomas Huth * every register in the list; KVM is authoritative if 592fcf5ef2aSThomas Huth * we're using it. 593fcf5ef2aSThomas Huth */ 594fcf5ef2aSThomas Huth write_list_to_cpustate(cpu); 595fcf5ef2aSThomas Huth } else { 596fcf5ef2aSThomas Huth if (!write_list_to_cpustate(cpu)) { 597fcf5ef2aSThomas Huth return -1; 598fcf5ef2aSThomas Huth } 599fcf5ef2aSThomas Huth } 600fcf5ef2aSThomas Huth 601fcf5ef2aSThomas Huth hw_breakpoint_update_all(cpu); 602fcf5ef2aSThomas Huth hw_watchpoint_update_all(cpu); 603fcf5ef2aSThomas Huth 604fcf5ef2aSThomas Huth return 0; 605fcf5ef2aSThomas Huth } 606fcf5ef2aSThomas Huth 607fcf5ef2aSThomas Huth const VMStateDescription vmstate_arm_cpu = { 608fcf5ef2aSThomas Huth .name = "cpu", 609fcf5ef2aSThomas Huth .version_id = 22, 610fcf5ef2aSThomas Huth .minimum_version_id = 22, 611fcf5ef2aSThomas Huth .pre_save = cpu_pre_save, 612fcf5ef2aSThomas Huth .post_load = cpu_post_load, 613fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 614fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16), 615fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.xregs, ARMCPU, 32), 616fcf5ef2aSThomas Huth VMSTATE_UINT64(env.pc, ARMCPU), 617fcf5ef2aSThomas Huth { 618fcf5ef2aSThomas Huth .name = "cpsr", 619fcf5ef2aSThomas Huth .version_id = 0, 620fcf5ef2aSThomas Huth .size = sizeof(uint32_t), 621fcf5ef2aSThomas Huth .info = &vmstate_cpsr, 622fcf5ef2aSThomas Huth .flags = VMS_SINGLE, 623fcf5ef2aSThomas Huth .offset = 0, 624fcf5ef2aSThomas Huth }, 625fcf5ef2aSThomas Huth VMSTATE_UINT32(env.spsr, ARMCPU), 626fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.banked_spsr, ARMCPU, 8), 627fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 8), 628fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 8), 629fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5), 630fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5), 631fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.elr_el, ARMCPU, 4), 632fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.sp_el, ARMCPU, 4), 633fcf5ef2aSThomas Huth /* The length-check must come before the arrays to avoid 634fcf5ef2aSThomas Huth * incoming data possibly overflowing the array. 635fcf5ef2aSThomas Huth */ 636fcf5ef2aSThomas Huth VMSTATE_INT32_POSITIVE_LE(cpreg_vmstate_array_len, ARMCPU), 637fcf5ef2aSThomas Huth VMSTATE_VARRAY_INT32(cpreg_vmstate_indexes, ARMCPU, 638fcf5ef2aSThomas Huth cpreg_vmstate_array_len, 639fcf5ef2aSThomas Huth 0, vmstate_info_uint64, uint64_t), 640fcf5ef2aSThomas Huth VMSTATE_VARRAY_INT32(cpreg_vmstate_values, ARMCPU, 641fcf5ef2aSThomas Huth cpreg_vmstate_array_len, 642fcf5ef2aSThomas Huth 0, vmstate_info_uint64, uint64_t), 643fcf5ef2aSThomas Huth VMSTATE_UINT64(env.exclusive_addr, ARMCPU), 644fcf5ef2aSThomas Huth VMSTATE_UINT64(env.exclusive_val, ARMCPU), 645fcf5ef2aSThomas Huth VMSTATE_UINT64(env.exclusive_high, ARMCPU), 646fcf5ef2aSThomas Huth VMSTATE_UINT64(env.features, ARMCPU), 647fcf5ef2aSThomas Huth VMSTATE_UINT32(env.exception.syndrome, ARMCPU), 648fcf5ef2aSThomas Huth VMSTATE_UINT32(env.exception.fsr, ARMCPU), 649fcf5ef2aSThomas Huth VMSTATE_UINT64(env.exception.vaddress, ARMCPU), 650fcf5ef2aSThomas Huth VMSTATE_TIMER_PTR(gt_timer[GTIMER_PHYS], ARMCPU), 651fcf5ef2aSThomas Huth VMSTATE_TIMER_PTR(gt_timer[GTIMER_VIRT], ARMCPU), 652062ba099SAlex Bennée { 653062ba099SAlex Bennée .name = "power_state", 654062ba099SAlex Bennée .version_id = 0, 655062ba099SAlex Bennée .size = sizeof(bool), 656062ba099SAlex Bennée .info = &vmstate_powered_off, 657062ba099SAlex Bennée .flags = VMS_SINGLE, 658062ba099SAlex Bennée .offset = 0, 659062ba099SAlex Bennée }, 660fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 661fcf5ef2aSThomas Huth }, 662fcf5ef2aSThomas Huth .subsections = (const VMStateDescription*[]) { 663fcf5ef2aSThomas Huth &vmstate_vfp, 664fcf5ef2aSThomas Huth &vmstate_iwmmxt, 665fcf5ef2aSThomas Huth &vmstate_m, 666fcf5ef2aSThomas Huth &vmstate_thumb2ee, 667f1a46940SPeter Maydell /* pmsav7_rnr must come before pmsav7 so that we have the 668f1a46940SPeter Maydell * region number before we test it in the VMSTATE_VALIDATE 669f1a46940SPeter Maydell * in vmstate_pmsav7. 670f1a46940SPeter Maydell */ 671f1a46940SPeter Maydell &vmstate_pmsav7_rnr, 672fcf5ef2aSThomas Huth &vmstate_pmsav7, 6730e1a46bbSPeter Maydell &vmstate_pmsav8, 6741e577cc7SPeter Maydell &vmstate_m_security, 675ef401601SRichard Henderson #ifdef TARGET_AARCH64 676ef401601SRichard Henderson &vmstate_sve, 677ef401601SRichard Henderson #endif 678fcf5ef2aSThomas Huth NULL 679fcf5ef2aSThomas Huth } 680fcf5ef2aSThomas Huth }; 681