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 19443bbce7fSPeter Maydell /* CSSELR is in a subsection because we didn't implement it previously. 19543bbce7fSPeter Maydell * Migration from an old implementation will leave it at zero, which 19643bbce7fSPeter Maydell * is OK since the only CPUs in the old implementation make the 19743bbce7fSPeter Maydell * register RAZ/WI. 19843bbce7fSPeter Maydell * Since there was no version of QEMU which implemented the CSSELR for 19943bbce7fSPeter Maydell * just non-secure, we transfer both banks here rather than putting 20043bbce7fSPeter Maydell * the secure banked version in the m-security subsection. 20143bbce7fSPeter Maydell */ 20243bbce7fSPeter Maydell static bool csselr_vmstate_validate(void *opaque, int version_id) 20343bbce7fSPeter Maydell { 20443bbce7fSPeter Maydell ARMCPU *cpu = opaque; 20543bbce7fSPeter Maydell 20643bbce7fSPeter Maydell return cpu->env.v7m.csselr[M_REG_NS] <= R_V7M_CSSELR_INDEX_MASK 20743bbce7fSPeter Maydell && cpu->env.v7m.csselr[M_REG_S] <= R_V7M_CSSELR_INDEX_MASK; 20843bbce7fSPeter Maydell } 20943bbce7fSPeter Maydell 21043bbce7fSPeter Maydell static bool m_csselr_needed(void *opaque) 21143bbce7fSPeter Maydell { 21243bbce7fSPeter Maydell ARMCPU *cpu = opaque; 21343bbce7fSPeter Maydell 21443bbce7fSPeter Maydell return !arm_v7m_csselr_razwi(cpu); 21543bbce7fSPeter Maydell } 21643bbce7fSPeter Maydell 21743bbce7fSPeter Maydell static const VMStateDescription vmstate_m_csselr = { 21843bbce7fSPeter Maydell .name = "cpu/m/csselr", 21943bbce7fSPeter Maydell .version_id = 1, 22043bbce7fSPeter Maydell .minimum_version_id = 1, 22143bbce7fSPeter Maydell .needed = m_csselr_needed, 22243bbce7fSPeter Maydell .fields = (VMStateField[]) { 22343bbce7fSPeter Maydell VMSTATE_UINT32_ARRAY(env.v7m.csselr, ARMCPU, M_REG_NUM_BANKS), 22443bbce7fSPeter Maydell VMSTATE_VALIDATE("CSSELR is valid", csselr_vmstate_validate), 22543bbce7fSPeter Maydell VMSTATE_END_OF_LIST() 22643bbce7fSPeter Maydell } 22743bbce7fSPeter Maydell }; 22843bbce7fSPeter Maydell 22924ac0fb1SPeter Maydell static const VMStateDescription vmstate_m_scr = { 23024ac0fb1SPeter Maydell .name = "cpu/m/scr", 23124ac0fb1SPeter Maydell .version_id = 1, 23224ac0fb1SPeter Maydell .minimum_version_id = 1, 23324ac0fb1SPeter Maydell .fields = (VMStateField[]) { 23424ac0fb1SPeter Maydell VMSTATE_UINT32(env.v7m.scr[M_REG_NS], ARMCPU), 23524ac0fb1SPeter Maydell VMSTATE_END_OF_LIST() 23624ac0fb1SPeter Maydell } 23724ac0fb1SPeter Maydell }; 23824ac0fb1SPeter Maydell 239*e1e7cbc9SPeter Maydell static const VMStateDescription vmstate_m_other_sp = { 240*e1e7cbc9SPeter Maydell .name = "cpu/m/other-sp", 241*e1e7cbc9SPeter Maydell .version_id = 1, 242*e1e7cbc9SPeter Maydell .minimum_version_id = 1, 243*e1e7cbc9SPeter Maydell .fields = (VMStateField[]) { 244*e1e7cbc9SPeter Maydell VMSTATE_UINT32(env.v7m.other_sp, ARMCPU), 245*e1e7cbc9SPeter Maydell VMSTATE_END_OF_LIST() 246*e1e7cbc9SPeter Maydell } 247*e1e7cbc9SPeter Maydell }; 248*e1e7cbc9SPeter Maydell 249fcf5ef2aSThomas Huth static const VMStateDescription vmstate_m = { 250fcf5ef2aSThomas Huth .name = "cpu/m", 25129c483a5SMichael Davidsaver .version_id = 4, 25229c483a5SMichael Davidsaver .minimum_version_id = 4, 253fcf5ef2aSThomas Huth .needed = m_needed, 254fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 25545db7ba6SPeter Maydell VMSTATE_UINT32(env.v7m.vecbase[M_REG_NS], ARMCPU), 256acf94941SPeter Maydell VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU), 2578bfc26eaSPeter Maydell VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU), 2589d40cd8aSPeter Maydell VMSTATE_UINT32(env.v7m.ccr[M_REG_NS], ARMCPU), 259334e8dadSPeter Maydell VMSTATE_UINT32(env.v7m.cfsr[M_REG_NS], ARMCPU), 2602c4da50dSPeter Maydell VMSTATE_UINT32(env.v7m.hfsr, ARMCPU), 2612c4da50dSPeter Maydell VMSTATE_UINT32(env.v7m.dfsr, ARMCPU), 262c51a5cfcSPeter Maydell VMSTATE_UINT32(env.v7m.mmfar[M_REG_NS], ARMCPU), 2632c4da50dSPeter Maydell VMSTATE_UINT32(env.v7m.bfar, ARMCPU), 264ecf5e8eaSPeter Maydell VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_NS], ARMCPU), 265fcf5ef2aSThomas Huth VMSTATE_INT32(env.v7m.exception, ARMCPU), 266fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 267e6ae5981SPeter Maydell }, 268e6ae5981SPeter Maydell .subsections = (const VMStateDescription*[]) { 269e6ae5981SPeter Maydell &vmstate_m_faultmask_primask, 27043bbce7fSPeter Maydell &vmstate_m_csselr, 27124ac0fb1SPeter Maydell &vmstate_m_scr, 272*e1e7cbc9SPeter Maydell &vmstate_m_other_sp, 273e6ae5981SPeter Maydell NULL 274fcf5ef2aSThomas Huth } 275fcf5ef2aSThomas Huth }; 276fcf5ef2aSThomas Huth 277fcf5ef2aSThomas Huth static bool thumb2ee_needed(void *opaque) 278fcf5ef2aSThomas Huth { 279fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 280fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 281fcf5ef2aSThomas Huth 282fcf5ef2aSThomas Huth return arm_feature(env, ARM_FEATURE_THUMB2EE); 283fcf5ef2aSThomas Huth } 284fcf5ef2aSThomas Huth 285fcf5ef2aSThomas Huth static const VMStateDescription vmstate_thumb2ee = { 286fcf5ef2aSThomas Huth .name = "cpu/thumb2ee", 287fcf5ef2aSThomas Huth .version_id = 1, 288fcf5ef2aSThomas Huth .minimum_version_id = 1, 289fcf5ef2aSThomas Huth .needed = thumb2ee_needed, 290fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 291fcf5ef2aSThomas Huth VMSTATE_UINT32(env.teecr, ARMCPU), 292fcf5ef2aSThomas Huth VMSTATE_UINT32(env.teehbr, ARMCPU), 293fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 294fcf5ef2aSThomas Huth } 295fcf5ef2aSThomas Huth }; 296fcf5ef2aSThomas Huth 297fcf5ef2aSThomas Huth static bool pmsav7_needed(void *opaque) 298fcf5ef2aSThomas Huth { 299fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 300fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 301fcf5ef2aSThomas Huth 302452a0955SPeter Maydell return arm_feature(env, ARM_FEATURE_PMSA) && 3030e1a46bbSPeter Maydell arm_feature(env, ARM_FEATURE_V7) && 3040e1a46bbSPeter Maydell !arm_feature(env, ARM_FEATURE_V8); 305fcf5ef2aSThomas Huth } 306fcf5ef2aSThomas Huth 307fcf5ef2aSThomas Huth static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id) 308fcf5ef2aSThomas Huth { 309fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 310fcf5ef2aSThomas Huth 3111bc04a88SPeter Maydell return cpu->env.pmsav7.rnr[M_REG_NS] < cpu->pmsav7_dregion; 312fcf5ef2aSThomas Huth } 313fcf5ef2aSThomas Huth 314fcf5ef2aSThomas Huth static const VMStateDescription vmstate_pmsav7 = { 315fcf5ef2aSThomas Huth .name = "cpu/pmsav7", 316fcf5ef2aSThomas Huth .version_id = 1, 317fcf5ef2aSThomas Huth .minimum_version_id = 1, 318fcf5ef2aSThomas Huth .needed = pmsav7_needed, 319fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 320fcf5ef2aSThomas Huth VMSTATE_VARRAY_UINT32(env.pmsav7.drbar, ARMCPU, pmsav7_dregion, 0, 321fcf5ef2aSThomas Huth vmstate_info_uint32, uint32_t), 322fcf5ef2aSThomas Huth VMSTATE_VARRAY_UINT32(env.pmsav7.drsr, ARMCPU, pmsav7_dregion, 0, 323fcf5ef2aSThomas Huth vmstate_info_uint32, uint32_t), 324fcf5ef2aSThomas Huth VMSTATE_VARRAY_UINT32(env.pmsav7.dracr, ARMCPU, pmsav7_dregion, 0, 325fcf5ef2aSThomas Huth vmstate_info_uint32, uint32_t), 326fcf5ef2aSThomas Huth VMSTATE_VALIDATE("rgnr is valid", pmsav7_rgnr_vmstate_validate), 327fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 328fcf5ef2aSThomas Huth } 329fcf5ef2aSThomas Huth }; 330fcf5ef2aSThomas Huth 331f1a46940SPeter Maydell static bool pmsav7_rnr_needed(void *opaque) 332f1a46940SPeter Maydell { 333f1a46940SPeter Maydell ARMCPU *cpu = opaque; 334f1a46940SPeter Maydell CPUARMState *env = &cpu->env; 335f1a46940SPeter Maydell 336f1a46940SPeter Maydell /* For R profile cores pmsav7.rnr is migrated via the cpreg 337f1a46940SPeter Maydell * "RGNR" definition in helper.h. For M profile we have to 338f1a46940SPeter Maydell * migrate it separately. 339f1a46940SPeter Maydell */ 340f1a46940SPeter Maydell return arm_feature(env, ARM_FEATURE_M); 341f1a46940SPeter Maydell } 342f1a46940SPeter Maydell 343f1a46940SPeter Maydell static const VMStateDescription vmstate_pmsav7_rnr = { 344f1a46940SPeter Maydell .name = "cpu/pmsav7-rnr", 345f1a46940SPeter Maydell .version_id = 1, 346f1a46940SPeter Maydell .minimum_version_id = 1, 347f1a46940SPeter Maydell .needed = pmsav7_rnr_needed, 348f1a46940SPeter Maydell .fields = (VMStateField[]) { 3491bc04a88SPeter Maydell VMSTATE_UINT32(env.pmsav7.rnr[M_REG_NS], ARMCPU), 350f1a46940SPeter Maydell VMSTATE_END_OF_LIST() 351f1a46940SPeter Maydell } 352f1a46940SPeter Maydell }; 353f1a46940SPeter Maydell 3540e1a46bbSPeter Maydell static bool pmsav8_needed(void *opaque) 3550e1a46bbSPeter Maydell { 3560e1a46bbSPeter Maydell ARMCPU *cpu = opaque; 3570e1a46bbSPeter Maydell CPUARMState *env = &cpu->env; 3580e1a46bbSPeter Maydell 3590e1a46bbSPeter Maydell return arm_feature(env, ARM_FEATURE_PMSA) && 3600e1a46bbSPeter Maydell arm_feature(env, ARM_FEATURE_V8); 3610e1a46bbSPeter Maydell } 3620e1a46bbSPeter Maydell 3630e1a46bbSPeter Maydell static const VMStateDescription vmstate_pmsav8 = { 3640e1a46bbSPeter Maydell .name = "cpu/pmsav8", 3650e1a46bbSPeter Maydell .version_id = 1, 3660e1a46bbSPeter Maydell .minimum_version_id = 1, 3670e1a46bbSPeter Maydell .needed = pmsav8_needed, 3680e1a46bbSPeter Maydell .fields = (VMStateField[]) { 36962c58ee0SPeter Maydell VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_NS], ARMCPU, pmsav7_dregion, 37062c58ee0SPeter Maydell 0, vmstate_info_uint32, uint32_t), 37162c58ee0SPeter Maydell VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_NS], ARMCPU, pmsav7_dregion, 37262c58ee0SPeter Maydell 0, vmstate_info_uint32, uint32_t), 3734125e6feSPeter Maydell VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU), 3744125e6feSPeter Maydell VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU), 3750e1a46bbSPeter Maydell VMSTATE_END_OF_LIST() 3760e1a46bbSPeter Maydell } 3770e1a46bbSPeter Maydell }; 3780e1a46bbSPeter Maydell 3791bc04a88SPeter Maydell static bool s_rnr_vmstate_validate(void *opaque, int version_id) 3801bc04a88SPeter Maydell { 3811bc04a88SPeter Maydell ARMCPU *cpu = opaque; 3821bc04a88SPeter Maydell 3831bc04a88SPeter Maydell return cpu->env.pmsav7.rnr[M_REG_S] < cpu->pmsav7_dregion; 3841bc04a88SPeter Maydell } 3851bc04a88SPeter Maydell 3869901c576SPeter Maydell static bool sau_rnr_vmstate_validate(void *opaque, int version_id) 3879901c576SPeter Maydell { 3889901c576SPeter Maydell ARMCPU *cpu = opaque; 3899901c576SPeter Maydell 3909901c576SPeter Maydell return cpu->env.sau.rnr < cpu->sau_sregion; 3919901c576SPeter Maydell } 3929901c576SPeter Maydell 3931e577cc7SPeter Maydell static bool m_security_needed(void *opaque) 3941e577cc7SPeter Maydell { 3951e577cc7SPeter Maydell ARMCPU *cpu = opaque; 3961e577cc7SPeter Maydell CPUARMState *env = &cpu->env; 3971e577cc7SPeter Maydell 3981e577cc7SPeter Maydell return arm_feature(env, ARM_FEATURE_M_SECURITY); 3991e577cc7SPeter Maydell } 4001e577cc7SPeter Maydell 4011e577cc7SPeter Maydell static const VMStateDescription vmstate_m_security = { 4021e577cc7SPeter Maydell .name = "cpu/m-security", 4031e577cc7SPeter Maydell .version_id = 1, 4041e577cc7SPeter Maydell .minimum_version_id = 1, 4051e577cc7SPeter Maydell .needed = m_security_needed, 4061e577cc7SPeter Maydell .fields = (VMStateField[]) { 4071e577cc7SPeter Maydell VMSTATE_UINT32(env.v7m.secure, ARMCPU), 408fb602cb7SPeter Maydell VMSTATE_UINT32(env.v7m.other_ss_msp, ARMCPU), 409fb602cb7SPeter Maydell VMSTATE_UINT32(env.v7m.other_ss_psp, ARMCPU), 410acf94941SPeter Maydell VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU), 4116d804834SPeter Maydell VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU), 41242a6686bSPeter Maydell VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU), 4138bfc26eaSPeter Maydell VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU), 41445db7ba6SPeter Maydell VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU), 4154125e6feSPeter Maydell VMSTATE_UINT32(env.pmsav8.mair0[M_REG_S], ARMCPU), 4164125e6feSPeter Maydell VMSTATE_UINT32(env.pmsav8.mair1[M_REG_S], ARMCPU), 41762c58ee0SPeter Maydell VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_S], ARMCPU, pmsav7_dregion, 41862c58ee0SPeter Maydell 0, vmstate_info_uint32, uint32_t), 41962c58ee0SPeter Maydell VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_S], ARMCPU, pmsav7_dregion, 42062c58ee0SPeter Maydell 0, vmstate_info_uint32, uint32_t), 4211bc04a88SPeter Maydell VMSTATE_UINT32(env.pmsav7.rnr[M_REG_S], ARMCPU), 4221bc04a88SPeter Maydell VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate), 423ecf5e8eaSPeter Maydell VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU), 4249d40cd8aSPeter Maydell VMSTATE_UINT32(env.v7m.ccr[M_REG_S], ARMCPU), 425c51a5cfcSPeter Maydell VMSTATE_UINT32(env.v7m.mmfar[M_REG_S], ARMCPU), 426334e8dadSPeter Maydell VMSTATE_UINT32(env.v7m.cfsr[M_REG_S], ARMCPU), 427bed079daSPeter Maydell VMSTATE_UINT32(env.v7m.sfsr, ARMCPU), 428bed079daSPeter Maydell VMSTATE_UINT32(env.v7m.sfar, ARMCPU), 4299901c576SPeter Maydell VMSTATE_VARRAY_UINT32(env.sau.rbar, ARMCPU, sau_sregion, 0, 4309901c576SPeter Maydell vmstate_info_uint32, uint32_t), 4319901c576SPeter Maydell VMSTATE_VARRAY_UINT32(env.sau.rlar, ARMCPU, sau_sregion, 0, 4329901c576SPeter Maydell vmstate_info_uint32, uint32_t), 4339901c576SPeter Maydell VMSTATE_UINT32(env.sau.rnr, ARMCPU), 4349901c576SPeter Maydell VMSTATE_VALIDATE("SAU_RNR is valid", sau_rnr_vmstate_validate), 4359901c576SPeter Maydell VMSTATE_UINT32(env.sau.ctrl, ARMCPU), 43624ac0fb1SPeter Maydell VMSTATE_UINT32(env.v7m.scr[M_REG_S], ARMCPU), 43747825770SPeter Maydell /* AIRCR is not secure-only, but our implementation is R/O if the 43847825770SPeter Maydell * security extension is unimplemented, so we migrate it here. 43947825770SPeter Maydell */ 44047825770SPeter Maydell VMSTATE_UINT32(env.v7m.aircr, ARMCPU), 4411e577cc7SPeter Maydell VMSTATE_END_OF_LIST() 4421e577cc7SPeter Maydell } 4431e577cc7SPeter Maydell }; 4441e577cc7SPeter Maydell 4452c21ee76SJianjun Duan static int get_cpsr(QEMUFile *f, void *opaque, size_t size, 4462c21ee76SJianjun Duan VMStateField *field) 447fcf5ef2aSThomas Huth { 448fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 449fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 450fcf5ef2aSThomas Huth uint32_t val = qemu_get_be32(f); 451fcf5ef2aSThomas Huth 452e6ae5981SPeter Maydell if (arm_feature(env, ARM_FEATURE_M)) { 453eeade001SPeter Maydell if (val & XPSR_EXCP) { 454eeade001SPeter Maydell /* This is a CPSR format value from an older QEMU. (We can tell 455eeade001SPeter Maydell * because values transferred in XPSR format always have zero 456eeade001SPeter Maydell * for the EXCP field, and CPSR format will always have bit 4 457eeade001SPeter Maydell * set in CPSR_M.) Rearrange it into XPSR format. The significant 458eeade001SPeter Maydell * differences are that the T bit is not in the same place, the 459eeade001SPeter Maydell * primask/faultmask info may be in the CPSR I and F bits, and 460eeade001SPeter Maydell * we do not want the mode bits. 4616d804834SPeter Maydell * We know that this cleanup happened before v8M, so there 4626d804834SPeter Maydell * is no complication with banked primask/faultmask. 463eeade001SPeter Maydell */ 464eeade001SPeter Maydell uint32_t newval = val; 465eeade001SPeter Maydell 4666d804834SPeter Maydell assert(!arm_feature(env, ARM_FEATURE_M_SECURITY)); 4676d804834SPeter Maydell 468eeade001SPeter Maydell newval &= (CPSR_NZCV | CPSR_Q | CPSR_IT | CPSR_GE); 469eeade001SPeter Maydell if (val & CPSR_T) { 470eeade001SPeter Maydell newval |= XPSR_T; 471eeade001SPeter Maydell } 472e6ae5981SPeter Maydell /* If the I or F bits are set then this is a migration from 473e6ae5981SPeter Maydell * an old QEMU which still stored the M profile FAULTMASK 474eeade001SPeter Maydell * and PRIMASK in env->daif. For a new QEMU, the data is 475eeade001SPeter Maydell * transferred using the vmstate_m_faultmask_primask subsection. 476e6ae5981SPeter Maydell */ 477e6ae5981SPeter Maydell if (val & CPSR_F) { 47842a6686bSPeter Maydell env->v7m.faultmask[M_REG_NS] = 1; 479e6ae5981SPeter Maydell } 480e6ae5981SPeter Maydell if (val & CPSR_I) { 4816d804834SPeter Maydell env->v7m.primask[M_REG_NS] = 1; 482e6ae5981SPeter Maydell } 483eeade001SPeter Maydell val = newval; 484eeade001SPeter Maydell } 485eeade001SPeter Maydell /* Ignore the low bits, they are handled by vmstate_m. */ 486eeade001SPeter Maydell xpsr_write(env, val, ~XPSR_EXCP); 487eeade001SPeter Maydell return 0; 488e6ae5981SPeter Maydell } 489e6ae5981SPeter Maydell 490fcf5ef2aSThomas Huth env->aarch64 = ((val & PSTATE_nRW) == 0); 491fcf5ef2aSThomas Huth 492fcf5ef2aSThomas Huth if (is_a64(env)) { 493fcf5ef2aSThomas Huth pstate_write(env, val); 494fcf5ef2aSThomas Huth return 0; 495fcf5ef2aSThomas Huth } 496fcf5ef2aSThomas Huth 497fcf5ef2aSThomas Huth cpsr_write(env, val, 0xffffffff, CPSRWriteRaw); 498fcf5ef2aSThomas Huth return 0; 499fcf5ef2aSThomas Huth } 500fcf5ef2aSThomas Huth 5012c21ee76SJianjun Duan static int put_cpsr(QEMUFile *f, void *opaque, size_t size, 5022c21ee76SJianjun Duan VMStateField *field, QJSON *vmdesc) 503fcf5ef2aSThomas Huth { 504fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 505fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 506fcf5ef2aSThomas Huth uint32_t val; 507fcf5ef2aSThomas Huth 508eeade001SPeter Maydell if (arm_feature(env, ARM_FEATURE_M)) { 509eeade001SPeter Maydell /* The low 9 bits are v7m.exception, which is handled by vmstate_m. */ 510eeade001SPeter Maydell val = xpsr_read(env) & ~XPSR_EXCP; 511eeade001SPeter Maydell } else if (is_a64(env)) { 512fcf5ef2aSThomas Huth val = pstate_read(env); 513fcf5ef2aSThomas Huth } else { 514fcf5ef2aSThomas Huth val = cpsr_read(env); 515fcf5ef2aSThomas Huth } 516fcf5ef2aSThomas Huth 517fcf5ef2aSThomas Huth qemu_put_be32(f, val); 5182c21ee76SJianjun Duan return 0; 519fcf5ef2aSThomas Huth } 520fcf5ef2aSThomas Huth 521fcf5ef2aSThomas Huth static const VMStateInfo vmstate_cpsr = { 522fcf5ef2aSThomas Huth .name = "cpsr", 523fcf5ef2aSThomas Huth .get = get_cpsr, 524fcf5ef2aSThomas Huth .put = put_cpsr, 525fcf5ef2aSThomas Huth }; 526fcf5ef2aSThomas Huth 527062ba099SAlex Bennée static int get_power(QEMUFile *f, void *opaque, size_t size, 528062ba099SAlex Bennée VMStateField *field) 529062ba099SAlex Bennée { 530062ba099SAlex Bennée ARMCPU *cpu = opaque; 531062ba099SAlex Bennée bool powered_off = qemu_get_byte(f); 532062ba099SAlex Bennée cpu->power_state = powered_off ? PSCI_OFF : PSCI_ON; 533062ba099SAlex Bennée return 0; 534062ba099SAlex Bennée } 535062ba099SAlex Bennée 536062ba099SAlex Bennée static int put_power(QEMUFile *f, void *opaque, size_t size, 537062ba099SAlex Bennée VMStateField *field, QJSON *vmdesc) 538062ba099SAlex Bennée { 539062ba099SAlex Bennée ARMCPU *cpu = opaque; 540062ba099SAlex Bennée 541062ba099SAlex Bennée /* Migration should never happen while we transition power states */ 542062ba099SAlex Bennée 543062ba099SAlex Bennée if (cpu->power_state == PSCI_ON || 544062ba099SAlex Bennée cpu->power_state == PSCI_OFF) { 545062ba099SAlex Bennée bool powered_off = (cpu->power_state == PSCI_OFF) ? true : false; 546062ba099SAlex Bennée qemu_put_byte(f, powered_off); 547062ba099SAlex Bennée return 0; 548062ba099SAlex Bennée } else { 549062ba099SAlex Bennée return 1; 550062ba099SAlex Bennée } 551062ba099SAlex Bennée } 552062ba099SAlex Bennée 553062ba099SAlex Bennée static const VMStateInfo vmstate_powered_off = { 554062ba099SAlex Bennée .name = "powered_off", 555062ba099SAlex Bennée .get = get_power, 556062ba099SAlex Bennée .put = put_power, 557062ba099SAlex Bennée }; 558062ba099SAlex Bennée 55944b1ff31SDr. David Alan Gilbert static int cpu_pre_save(void *opaque) 560fcf5ef2aSThomas Huth { 561fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 562fcf5ef2aSThomas Huth 563fcf5ef2aSThomas Huth if (kvm_enabled()) { 564fcf5ef2aSThomas Huth if (!write_kvmstate_to_list(cpu)) { 565fcf5ef2aSThomas Huth /* This should never fail */ 566fcf5ef2aSThomas Huth abort(); 567fcf5ef2aSThomas Huth } 568fcf5ef2aSThomas Huth } else { 569fcf5ef2aSThomas Huth if (!write_cpustate_to_list(cpu)) { 570fcf5ef2aSThomas Huth /* This should never fail. */ 571fcf5ef2aSThomas Huth abort(); 572fcf5ef2aSThomas Huth } 573fcf5ef2aSThomas Huth } 574fcf5ef2aSThomas Huth 575fcf5ef2aSThomas Huth cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len; 576fcf5ef2aSThomas Huth memcpy(cpu->cpreg_vmstate_indexes, cpu->cpreg_indexes, 577fcf5ef2aSThomas Huth cpu->cpreg_array_len * sizeof(uint64_t)); 578fcf5ef2aSThomas Huth memcpy(cpu->cpreg_vmstate_values, cpu->cpreg_values, 579fcf5ef2aSThomas Huth cpu->cpreg_array_len * sizeof(uint64_t)); 58044b1ff31SDr. David Alan Gilbert 58144b1ff31SDr. David Alan Gilbert return 0; 582fcf5ef2aSThomas Huth } 583fcf5ef2aSThomas Huth 584fcf5ef2aSThomas Huth static int cpu_post_load(void *opaque, int version_id) 585fcf5ef2aSThomas Huth { 586fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 587fcf5ef2aSThomas Huth int i, v; 588fcf5ef2aSThomas Huth 589fcf5ef2aSThomas Huth /* Update the values list from the incoming migration data. 590fcf5ef2aSThomas Huth * Anything in the incoming data which we don't know about is 591fcf5ef2aSThomas Huth * a migration failure; anything we know about but the incoming 592fcf5ef2aSThomas Huth * data doesn't specify retains its current (reset) value. 593fcf5ef2aSThomas Huth * The indexes list remains untouched -- we only inspect the 594fcf5ef2aSThomas Huth * incoming migration index list so we can match the values array 595fcf5ef2aSThomas Huth * entries with the right slots in our own values array. 596fcf5ef2aSThomas Huth */ 597fcf5ef2aSThomas Huth 598fcf5ef2aSThomas Huth for (i = 0, v = 0; i < cpu->cpreg_array_len 599fcf5ef2aSThomas Huth && v < cpu->cpreg_vmstate_array_len; i++) { 600fcf5ef2aSThomas Huth if (cpu->cpreg_vmstate_indexes[v] > cpu->cpreg_indexes[i]) { 601fcf5ef2aSThomas Huth /* register in our list but not incoming : skip it */ 602fcf5ef2aSThomas Huth continue; 603fcf5ef2aSThomas Huth } 604fcf5ef2aSThomas Huth if (cpu->cpreg_vmstate_indexes[v] < cpu->cpreg_indexes[i]) { 605fcf5ef2aSThomas Huth /* register in their list but not ours: fail migration */ 606fcf5ef2aSThomas Huth return -1; 607fcf5ef2aSThomas Huth } 608fcf5ef2aSThomas Huth /* matching register, copy the value over */ 609fcf5ef2aSThomas Huth cpu->cpreg_values[i] = cpu->cpreg_vmstate_values[v]; 610fcf5ef2aSThomas Huth v++; 611fcf5ef2aSThomas Huth } 612fcf5ef2aSThomas Huth 613fcf5ef2aSThomas Huth if (kvm_enabled()) { 614fcf5ef2aSThomas Huth if (!write_list_to_kvmstate(cpu, KVM_PUT_FULL_STATE)) { 615fcf5ef2aSThomas Huth return -1; 616fcf5ef2aSThomas Huth } 617fcf5ef2aSThomas Huth /* Note that it's OK for the TCG side not to know about 618fcf5ef2aSThomas Huth * every register in the list; KVM is authoritative if 619fcf5ef2aSThomas Huth * we're using it. 620fcf5ef2aSThomas Huth */ 621fcf5ef2aSThomas Huth write_list_to_cpustate(cpu); 622fcf5ef2aSThomas Huth } else { 623fcf5ef2aSThomas Huth if (!write_list_to_cpustate(cpu)) { 624fcf5ef2aSThomas Huth return -1; 625fcf5ef2aSThomas Huth } 626fcf5ef2aSThomas Huth } 627fcf5ef2aSThomas Huth 628fcf5ef2aSThomas Huth hw_breakpoint_update_all(cpu); 629fcf5ef2aSThomas Huth hw_watchpoint_update_all(cpu); 630fcf5ef2aSThomas Huth 631fcf5ef2aSThomas Huth return 0; 632fcf5ef2aSThomas Huth } 633fcf5ef2aSThomas Huth 634fcf5ef2aSThomas Huth const VMStateDescription vmstate_arm_cpu = { 635fcf5ef2aSThomas Huth .name = "cpu", 636fcf5ef2aSThomas Huth .version_id = 22, 637fcf5ef2aSThomas Huth .minimum_version_id = 22, 638fcf5ef2aSThomas Huth .pre_save = cpu_pre_save, 639fcf5ef2aSThomas Huth .post_load = cpu_post_load, 640fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 641fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16), 642fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.xregs, ARMCPU, 32), 643fcf5ef2aSThomas Huth VMSTATE_UINT64(env.pc, ARMCPU), 644fcf5ef2aSThomas Huth { 645fcf5ef2aSThomas Huth .name = "cpsr", 646fcf5ef2aSThomas Huth .version_id = 0, 647fcf5ef2aSThomas Huth .size = sizeof(uint32_t), 648fcf5ef2aSThomas Huth .info = &vmstate_cpsr, 649fcf5ef2aSThomas Huth .flags = VMS_SINGLE, 650fcf5ef2aSThomas Huth .offset = 0, 651fcf5ef2aSThomas Huth }, 652fcf5ef2aSThomas Huth VMSTATE_UINT32(env.spsr, ARMCPU), 653fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.banked_spsr, ARMCPU, 8), 654fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 8), 655fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 8), 656fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5), 657fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5), 658fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.elr_el, ARMCPU, 4), 659fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.sp_el, ARMCPU, 4), 660fcf5ef2aSThomas Huth /* The length-check must come before the arrays to avoid 661fcf5ef2aSThomas Huth * incoming data possibly overflowing the array. 662fcf5ef2aSThomas Huth */ 663fcf5ef2aSThomas Huth VMSTATE_INT32_POSITIVE_LE(cpreg_vmstate_array_len, ARMCPU), 664fcf5ef2aSThomas Huth VMSTATE_VARRAY_INT32(cpreg_vmstate_indexes, ARMCPU, 665fcf5ef2aSThomas Huth cpreg_vmstate_array_len, 666fcf5ef2aSThomas Huth 0, vmstate_info_uint64, uint64_t), 667fcf5ef2aSThomas Huth VMSTATE_VARRAY_INT32(cpreg_vmstate_values, ARMCPU, 668fcf5ef2aSThomas Huth cpreg_vmstate_array_len, 669fcf5ef2aSThomas Huth 0, vmstate_info_uint64, uint64_t), 670fcf5ef2aSThomas Huth VMSTATE_UINT64(env.exclusive_addr, ARMCPU), 671fcf5ef2aSThomas Huth VMSTATE_UINT64(env.exclusive_val, ARMCPU), 672fcf5ef2aSThomas Huth VMSTATE_UINT64(env.exclusive_high, ARMCPU), 673fcf5ef2aSThomas Huth VMSTATE_UINT64(env.features, ARMCPU), 674fcf5ef2aSThomas Huth VMSTATE_UINT32(env.exception.syndrome, ARMCPU), 675fcf5ef2aSThomas Huth VMSTATE_UINT32(env.exception.fsr, ARMCPU), 676fcf5ef2aSThomas Huth VMSTATE_UINT64(env.exception.vaddress, ARMCPU), 677fcf5ef2aSThomas Huth VMSTATE_TIMER_PTR(gt_timer[GTIMER_PHYS], ARMCPU), 678fcf5ef2aSThomas Huth VMSTATE_TIMER_PTR(gt_timer[GTIMER_VIRT], ARMCPU), 679062ba099SAlex Bennée { 680062ba099SAlex Bennée .name = "power_state", 681062ba099SAlex Bennée .version_id = 0, 682062ba099SAlex Bennée .size = sizeof(bool), 683062ba099SAlex Bennée .info = &vmstate_powered_off, 684062ba099SAlex Bennée .flags = VMS_SINGLE, 685062ba099SAlex Bennée .offset = 0, 686062ba099SAlex Bennée }, 687fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 688fcf5ef2aSThomas Huth }, 689fcf5ef2aSThomas Huth .subsections = (const VMStateDescription*[]) { 690fcf5ef2aSThomas Huth &vmstate_vfp, 691fcf5ef2aSThomas Huth &vmstate_iwmmxt, 692fcf5ef2aSThomas Huth &vmstate_m, 693fcf5ef2aSThomas Huth &vmstate_thumb2ee, 694f1a46940SPeter Maydell /* pmsav7_rnr must come before pmsav7 so that we have the 695f1a46940SPeter Maydell * region number before we test it in the VMSTATE_VALIDATE 696f1a46940SPeter Maydell * in vmstate_pmsav7. 697f1a46940SPeter Maydell */ 698f1a46940SPeter Maydell &vmstate_pmsav7_rnr, 699fcf5ef2aSThomas Huth &vmstate_pmsav7, 7000e1a46bbSPeter Maydell &vmstate_pmsav8, 7011e577cc7SPeter Maydell &vmstate_m_security, 702ef401601SRichard Henderson #ifdef TARGET_AARCH64 703ef401601SRichard Henderson &vmstate_sve, 704ef401601SRichard Henderson #endif 705fcf5ef2aSThomas Huth NULL 706fcf5ef2aSThomas Huth } 707fcf5ef2aSThomas Huth }; 708