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 135*cd208a1cSRichard Henderson return cpu_isar_feature(aa64_sve, cpu); 136ef401601SRichard Henderson } 137ef401601SRichard Henderson 138ef401601SRichard Henderson /* The first two words of each Zreg is stored in VFP state. */ 139ef401601SRichard Henderson static const VMStateDescription vmstate_zreg_hi_reg = { 140ef401601SRichard Henderson .name = "cpu/sve/zreg_hi", 141ef401601SRichard Henderson .version_id = 1, 142ef401601SRichard Henderson .minimum_version_id = 1, 143ef401601SRichard Henderson .fields = (VMStateField[]) { 144ef401601SRichard Henderson VMSTATE_UINT64_SUB_ARRAY(d, ARMVectorReg, 2, ARM_MAX_VQ - 2), 145ef401601SRichard Henderson VMSTATE_END_OF_LIST() 146ef401601SRichard Henderson } 147ef401601SRichard Henderson }; 148ef401601SRichard Henderson 149ef401601SRichard Henderson static const VMStateDescription vmstate_preg_reg = { 150ef401601SRichard Henderson .name = "cpu/sve/preg", 151ef401601SRichard Henderson .version_id = 1, 152ef401601SRichard Henderson .minimum_version_id = 1, 153ef401601SRichard Henderson .fields = (VMStateField[]) { 154ef401601SRichard Henderson VMSTATE_UINT64_ARRAY(p, ARMPredicateReg, 2 * ARM_MAX_VQ / 8), 155ef401601SRichard Henderson VMSTATE_END_OF_LIST() 156ef401601SRichard Henderson } 157ef401601SRichard Henderson }; 158ef401601SRichard Henderson 159ef401601SRichard Henderson static const VMStateDescription vmstate_sve = { 160ef401601SRichard Henderson .name = "cpu/sve", 161ef401601SRichard Henderson .version_id = 1, 162ef401601SRichard Henderson .minimum_version_id = 1, 163ef401601SRichard Henderson .needed = sve_needed, 164ef401601SRichard Henderson .fields = (VMStateField[]) { 165ef401601SRichard Henderson VMSTATE_STRUCT_ARRAY(env.vfp.zregs, ARMCPU, 32, 0, 166ef401601SRichard Henderson vmstate_zreg_hi_reg, ARMVectorReg), 167ef401601SRichard Henderson VMSTATE_STRUCT_ARRAY(env.vfp.pregs, ARMCPU, 17, 0, 168ef401601SRichard Henderson vmstate_preg_reg, ARMPredicateReg), 169ef401601SRichard Henderson VMSTATE_END_OF_LIST() 170ef401601SRichard Henderson } 171ef401601SRichard Henderson }; 172ef401601SRichard Henderson #endif /* AARCH64 */ 173ef401601SRichard Henderson 174202ccb6bSDongjiu Geng static bool serror_needed(void *opaque) 175202ccb6bSDongjiu Geng { 176202ccb6bSDongjiu Geng ARMCPU *cpu = opaque; 177202ccb6bSDongjiu Geng CPUARMState *env = &cpu->env; 178202ccb6bSDongjiu Geng 179202ccb6bSDongjiu Geng return env->serror.pending != 0; 180202ccb6bSDongjiu Geng } 181202ccb6bSDongjiu Geng 182202ccb6bSDongjiu Geng static const VMStateDescription vmstate_serror = { 183202ccb6bSDongjiu Geng .name = "cpu/serror", 184202ccb6bSDongjiu Geng .version_id = 1, 185202ccb6bSDongjiu Geng .minimum_version_id = 1, 186202ccb6bSDongjiu Geng .needed = serror_needed, 187202ccb6bSDongjiu Geng .fields = (VMStateField[]) { 188202ccb6bSDongjiu Geng VMSTATE_UINT8(env.serror.pending, ARMCPU), 189202ccb6bSDongjiu Geng VMSTATE_UINT8(env.serror.has_esr, ARMCPU), 190202ccb6bSDongjiu Geng VMSTATE_UINT64(env.serror.esr, ARMCPU), 191202ccb6bSDongjiu Geng VMSTATE_END_OF_LIST() 192202ccb6bSDongjiu Geng } 193202ccb6bSDongjiu Geng }; 194202ccb6bSDongjiu Geng 195fcf5ef2aSThomas Huth static bool m_needed(void *opaque) 196fcf5ef2aSThomas Huth { 197fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 198fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 199fcf5ef2aSThomas Huth 200fcf5ef2aSThomas Huth return arm_feature(env, ARM_FEATURE_M); 201fcf5ef2aSThomas Huth } 202fcf5ef2aSThomas Huth 203e6ae5981SPeter Maydell static const VMStateDescription vmstate_m_faultmask_primask = { 204e6ae5981SPeter Maydell .name = "cpu/m/faultmask-primask", 205e6ae5981SPeter Maydell .version_id = 1, 206e6ae5981SPeter Maydell .minimum_version_id = 1, 2077b69454aSPeter Maydell .needed = m_needed, 208e6ae5981SPeter Maydell .fields = (VMStateField[]) { 20942a6686bSPeter Maydell VMSTATE_UINT32(env.v7m.faultmask[M_REG_NS], ARMCPU), 2106d804834SPeter Maydell VMSTATE_UINT32(env.v7m.primask[M_REG_NS], ARMCPU), 211e6ae5981SPeter Maydell VMSTATE_END_OF_LIST() 212e6ae5981SPeter Maydell } 213e6ae5981SPeter Maydell }; 214e6ae5981SPeter Maydell 21543bbce7fSPeter Maydell /* CSSELR is in a subsection because we didn't implement it previously. 21643bbce7fSPeter Maydell * Migration from an old implementation will leave it at zero, which 21743bbce7fSPeter Maydell * is OK since the only CPUs in the old implementation make the 21843bbce7fSPeter Maydell * register RAZ/WI. 21943bbce7fSPeter Maydell * Since there was no version of QEMU which implemented the CSSELR for 22043bbce7fSPeter Maydell * just non-secure, we transfer both banks here rather than putting 22143bbce7fSPeter Maydell * the secure banked version in the m-security subsection. 22243bbce7fSPeter Maydell */ 22343bbce7fSPeter Maydell static bool csselr_vmstate_validate(void *opaque, int version_id) 22443bbce7fSPeter Maydell { 22543bbce7fSPeter Maydell ARMCPU *cpu = opaque; 22643bbce7fSPeter Maydell 22743bbce7fSPeter Maydell return cpu->env.v7m.csselr[M_REG_NS] <= R_V7M_CSSELR_INDEX_MASK 22843bbce7fSPeter Maydell && cpu->env.v7m.csselr[M_REG_S] <= R_V7M_CSSELR_INDEX_MASK; 22943bbce7fSPeter Maydell } 23043bbce7fSPeter Maydell 23143bbce7fSPeter Maydell static bool m_csselr_needed(void *opaque) 23243bbce7fSPeter Maydell { 23343bbce7fSPeter Maydell ARMCPU *cpu = opaque; 23443bbce7fSPeter Maydell 23543bbce7fSPeter Maydell return !arm_v7m_csselr_razwi(cpu); 23643bbce7fSPeter Maydell } 23743bbce7fSPeter Maydell 23843bbce7fSPeter Maydell static const VMStateDescription vmstate_m_csselr = { 23943bbce7fSPeter Maydell .name = "cpu/m/csselr", 24043bbce7fSPeter Maydell .version_id = 1, 24143bbce7fSPeter Maydell .minimum_version_id = 1, 24243bbce7fSPeter Maydell .needed = m_csselr_needed, 24343bbce7fSPeter Maydell .fields = (VMStateField[]) { 24443bbce7fSPeter Maydell VMSTATE_UINT32_ARRAY(env.v7m.csselr, ARMCPU, M_REG_NUM_BANKS), 24543bbce7fSPeter Maydell VMSTATE_VALIDATE("CSSELR is valid", csselr_vmstate_validate), 24643bbce7fSPeter Maydell VMSTATE_END_OF_LIST() 24743bbce7fSPeter Maydell } 24843bbce7fSPeter Maydell }; 24943bbce7fSPeter Maydell 25024ac0fb1SPeter Maydell static const VMStateDescription vmstate_m_scr = { 25124ac0fb1SPeter Maydell .name = "cpu/m/scr", 25224ac0fb1SPeter Maydell .version_id = 1, 25324ac0fb1SPeter Maydell .minimum_version_id = 1, 2547b69454aSPeter Maydell .needed = m_needed, 25524ac0fb1SPeter Maydell .fields = (VMStateField[]) { 25624ac0fb1SPeter Maydell VMSTATE_UINT32(env.v7m.scr[M_REG_NS], ARMCPU), 25724ac0fb1SPeter Maydell VMSTATE_END_OF_LIST() 25824ac0fb1SPeter Maydell } 25924ac0fb1SPeter Maydell }; 26024ac0fb1SPeter Maydell 261e1e7cbc9SPeter Maydell static const VMStateDescription vmstate_m_other_sp = { 262e1e7cbc9SPeter Maydell .name = "cpu/m/other-sp", 263e1e7cbc9SPeter Maydell .version_id = 1, 264e1e7cbc9SPeter Maydell .minimum_version_id = 1, 2657b69454aSPeter Maydell .needed = m_needed, 266e1e7cbc9SPeter Maydell .fields = (VMStateField[]) { 267e1e7cbc9SPeter Maydell VMSTATE_UINT32(env.v7m.other_sp, ARMCPU), 268e1e7cbc9SPeter Maydell VMSTATE_END_OF_LIST() 269e1e7cbc9SPeter Maydell } 270e1e7cbc9SPeter Maydell }; 271e1e7cbc9SPeter Maydell 27257bb3156SPeter Maydell static bool m_v8m_needed(void *opaque) 27357bb3156SPeter Maydell { 27457bb3156SPeter Maydell ARMCPU *cpu = opaque; 27557bb3156SPeter Maydell CPUARMState *env = &cpu->env; 27657bb3156SPeter Maydell 27757bb3156SPeter Maydell return arm_feature(env, ARM_FEATURE_M) && arm_feature(env, ARM_FEATURE_V8); 27857bb3156SPeter Maydell } 27957bb3156SPeter Maydell 28057bb3156SPeter Maydell static const VMStateDescription vmstate_m_v8m = { 28157bb3156SPeter Maydell .name = "cpu/m/v8m", 28257bb3156SPeter Maydell .version_id = 1, 28357bb3156SPeter Maydell .minimum_version_id = 1, 28457bb3156SPeter Maydell .needed = m_v8m_needed, 28557bb3156SPeter Maydell .fields = (VMStateField[]) { 28657bb3156SPeter Maydell VMSTATE_UINT32_ARRAY(env.v7m.msplim, ARMCPU, M_REG_NUM_BANKS), 28757bb3156SPeter Maydell VMSTATE_UINT32_ARRAY(env.v7m.psplim, ARMCPU, M_REG_NUM_BANKS), 28857bb3156SPeter Maydell VMSTATE_END_OF_LIST() 28957bb3156SPeter Maydell } 29057bb3156SPeter Maydell }; 29157bb3156SPeter Maydell 292fcf5ef2aSThomas Huth static const VMStateDescription vmstate_m = { 293fcf5ef2aSThomas Huth .name = "cpu/m", 29429c483a5SMichael Davidsaver .version_id = 4, 29529c483a5SMichael Davidsaver .minimum_version_id = 4, 296fcf5ef2aSThomas Huth .needed = m_needed, 297fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 29845db7ba6SPeter Maydell VMSTATE_UINT32(env.v7m.vecbase[M_REG_NS], ARMCPU), 299acf94941SPeter Maydell VMSTATE_UINT32(env.v7m.basepri[M_REG_NS], ARMCPU), 3008bfc26eaSPeter Maydell VMSTATE_UINT32(env.v7m.control[M_REG_NS], ARMCPU), 3019d40cd8aSPeter Maydell VMSTATE_UINT32(env.v7m.ccr[M_REG_NS], ARMCPU), 302334e8dadSPeter Maydell VMSTATE_UINT32(env.v7m.cfsr[M_REG_NS], ARMCPU), 3032c4da50dSPeter Maydell VMSTATE_UINT32(env.v7m.hfsr, ARMCPU), 3042c4da50dSPeter Maydell VMSTATE_UINT32(env.v7m.dfsr, ARMCPU), 305c51a5cfcSPeter Maydell VMSTATE_UINT32(env.v7m.mmfar[M_REG_NS], ARMCPU), 3062c4da50dSPeter Maydell VMSTATE_UINT32(env.v7m.bfar, ARMCPU), 307ecf5e8eaSPeter Maydell VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_NS], ARMCPU), 308fcf5ef2aSThomas Huth VMSTATE_INT32(env.v7m.exception, ARMCPU), 309fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 310e6ae5981SPeter Maydell }, 311e6ae5981SPeter Maydell .subsections = (const VMStateDescription*[]) { 312e6ae5981SPeter Maydell &vmstate_m_faultmask_primask, 31343bbce7fSPeter Maydell &vmstate_m_csselr, 31424ac0fb1SPeter Maydell &vmstate_m_scr, 315e1e7cbc9SPeter Maydell &vmstate_m_other_sp, 31657bb3156SPeter Maydell &vmstate_m_v8m, 317e6ae5981SPeter Maydell NULL 318fcf5ef2aSThomas Huth } 319fcf5ef2aSThomas Huth }; 320fcf5ef2aSThomas Huth 321fcf5ef2aSThomas Huth static bool thumb2ee_needed(void *opaque) 322fcf5ef2aSThomas Huth { 323fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 324fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 325fcf5ef2aSThomas Huth 326fcf5ef2aSThomas Huth return arm_feature(env, ARM_FEATURE_THUMB2EE); 327fcf5ef2aSThomas Huth } 328fcf5ef2aSThomas Huth 329fcf5ef2aSThomas Huth static const VMStateDescription vmstate_thumb2ee = { 330fcf5ef2aSThomas Huth .name = "cpu/thumb2ee", 331fcf5ef2aSThomas Huth .version_id = 1, 332fcf5ef2aSThomas Huth .minimum_version_id = 1, 333fcf5ef2aSThomas Huth .needed = thumb2ee_needed, 334fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 335fcf5ef2aSThomas Huth VMSTATE_UINT32(env.teecr, ARMCPU), 336fcf5ef2aSThomas Huth VMSTATE_UINT32(env.teehbr, ARMCPU), 337fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 338fcf5ef2aSThomas Huth } 339fcf5ef2aSThomas Huth }; 340fcf5ef2aSThomas Huth 341fcf5ef2aSThomas Huth static bool pmsav7_needed(void *opaque) 342fcf5ef2aSThomas Huth { 343fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 344fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 345fcf5ef2aSThomas Huth 346452a0955SPeter Maydell return arm_feature(env, ARM_FEATURE_PMSA) && 3470e1a46bbSPeter Maydell arm_feature(env, ARM_FEATURE_V7) && 3480e1a46bbSPeter Maydell !arm_feature(env, ARM_FEATURE_V8); 349fcf5ef2aSThomas Huth } 350fcf5ef2aSThomas Huth 351fcf5ef2aSThomas Huth static bool pmsav7_rgnr_vmstate_validate(void *opaque, int version_id) 352fcf5ef2aSThomas Huth { 353fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 354fcf5ef2aSThomas Huth 3551bc04a88SPeter Maydell return cpu->env.pmsav7.rnr[M_REG_NS] < cpu->pmsav7_dregion; 356fcf5ef2aSThomas Huth } 357fcf5ef2aSThomas Huth 358fcf5ef2aSThomas Huth static const VMStateDescription vmstate_pmsav7 = { 359fcf5ef2aSThomas Huth .name = "cpu/pmsav7", 360fcf5ef2aSThomas Huth .version_id = 1, 361fcf5ef2aSThomas Huth .minimum_version_id = 1, 362fcf5ef2aSThomas Huth .needed = pmsav7_needed, 363fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 364fcf5ef2aSThomas Huth VMSTATE_VARRAY_UINT32(env.pmsav7.drbar, ARMCPU, pmsav7_dregion, 0, 365fcf5ef2aSThomas Huth vmstate_info_uint32, uint32_t), 366fcf5ef2aSThomas Huth VMSTATE_VARRAY_UINT32(env.pmsav7.drsr, ARMCPU, pmsav7_dregion, 0, 367fcf5ef2aSThomas Huth vmstate_info_uint32, uint32_t), 368fcf5ef2aSThomas Huth VMSTATE_VARRAY_UINT32(env.pmsav7.dracr, ARMCPU, pmsav7_dregion, 0, 369fcf5ef2aSThomas Huth vmstate_info_uint32, uint32_t), 370fcf5ef2aSThomas Huth VMSTATE_VALIDATE("rgnr is valid", pmsav7_rgnr_vmstate_validate), 371fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 372fcf5ef2aSThomas Huth } 373fcf5ef2aSThomas Huth }; 374fcf5ef2aSThomas Huth 375f1a46940SPeter Maydell static bool pmsav7_rnr_needed(void *opaque) 376f1a46940SPeter Maydell { 377f1a46940SPeter Maydell ARMCPU *cpu = opaque; 378f1a46940SPeter Maydell CPUARMState *env = &cpu->env; 379f1a46940SPeter Maydell 380f1a46940SPeter Maydell /* For R profile cores pmsav7.rnr is migrated via the cpreg 381f1a46940SPeter Maydell * "RGNR" definition in helper.h. For M profile we have to 382f1a46940SPeter Maydell * migrate it separately. 383f1a46940SPeter Maydell */ 384f1a46940SPeter Maydell return arm_feature(env, ARM_FEATURE_M); 385f1a46940SPeter Maydell } 386f1a46940SPeter Maydell 387f1a46940SPeter Maydell static const VMStateDescription vmstate_pmsav7_rnr = { 388f1a46940SPeter Maydell .name = "cpu/pmsav7-rnr", 389f1a46940SPeter Maydell .version_id = 1, 390f1a46940SPeter Maydell .minimum_version_id = 1, 391f1a46940SPeter Maydell .needed = pmsav7_rnr_needed, 392f1a46940SPeter Maydell .fields = (VMStateField[]) { 3931bc04a88SPeter Maydell VMSTATE_UINT32(env.pmsav7.rnr[M_REG_NS], ARMCPU), 394f1a46940SPeter Maydell VMSTATE_END_OF_LIST() 395f1a46940SPeter Maydell } 396f1a46940SPeter Maydell }; 397f1a46940SPeter Maydell 3980e1a46bbSPeter Maydell static bool pmsav8_needed(void *opaque) 3990e1a46bbSPeter Maydell { 4000e1a46bbSPeter Maydell ARMCPU *cpu = opaque; 4010e1a46bbSPeter Maydell CPUARMState *env = &cpu->env; 4020e1a46bbSPeter Maydell 4030e1a46bbSPeter Maydell return arm_feature(env, ARM_FEATURE_PMSA) && 4040e1a46bbSPeter Maydell arm_feature(env, ARM_FEATURE_V8); 4050e1a46bbSPeter Maydell } 4060e1a46bbSPeter Maydell 4070e1a46bbSPeter Maydell static const VMStateDescription vmstate_pmsav8 = { 4080e1a46bbSPeter Maydell .name = "cpu/pmsav8", 4090e1a46bbSPeter Maydell .version_id = 1, 4100e1a46bbSPeter Maydell .minimum_version_id = 1, 4110e1a46bbSPeter Maydell .needed = pmsav8_needed, 4120e1a46bbSPeter Maydell .fields = (VMStateField[]) { 41362c58ee0SPeter Maydell VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_NS], ARMCPU, pmsav7_dregion, 41462c58ee0SPeter Maydell 0, vmstate_info_uint32, uint32_t), 41562c58ee0SPeter Maydell VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_NS], ARMCPU, pmsav7_dregion, 41662c58ee0SPeter Maydell 0, vmstate_info_uint32, uint32_t), 4174125e6feSPeter Maydell VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU), 4184125e6feSPeter Maydell VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU), 4190e1a46bbSPeter Maydell VMSTATE_END_OF_LIST() 4200e1a46bbSPeter Maydell } 4210e1a46bbSPeter Maydell }; 4220e1a46bbSPeter Maydell 4231bc04a88SPeter Maydell static bool s_rnr_vmstate_validate(void *opaque, int version_id) 4241bc04a88SPeter Maydell { 4251bc04a88SPeter Maydell ARMCPU *cpu = opaque; 4261bc04a88SPeter Maydell 4271bc04a88SPeter Maydell return cpu->env.pmsav7.rnr[M_REG_S] < cpu->pmsav7_dregion; 4281bc04a88SPeter Maydell } 4291bc04a88SPeter Maydell 4309901c576SPeter Maydell static bool sau_rnr_vmstate_validate(void *opaque, int version_id) 4319901c576SPeter Maydell { 4329901c576SPeter Maydell ARMCPU *cpu = opaque; 4339901c576SPeter Maydell 4349901c576SPeter Maydell return cpu->env.sau.rnr < cpu->sau_sregion; 4359901c576SPeter Maydell } 4369901c576SPeter Maydell 4371e577cc7SPeter Maydell static bool m_security_needed(void *opaque) 4381e577cc7SPeter Maydell { 4391e577cc7SPeter Maydell ARMCPU *cpu = opaque; 4401e577cc7SPeter Maydell CPUARMState *env = &cpu->env; 4411e577cc7SPeter Maydell 4421e577cc7SPeter Maydell return arm_feature(env, ARM_FEATURE_M_SECURITY); 4431e577cc7SPeter Maydell } 4441e577cc7SPeter Maydell 4451e577cc7SPeter Maydell static const VMStateDescription vmstate_m_security = { 4461e577cc7SPeter Maydell .name = "cpu/m-security", 4471e577cc7SPeter Maydell .version_id = 1, 4481e577cc7SPeter Maydell .minimum_version_id = 1, 4491e577cc7SPeter Maydell .needed = m_security_needed, 4501e577cc7SPeter Maydell .fields = (VMStateField[]) { 4511e577cc7SPeter Maydell VMSTATE_UINT32(env.v7m.secure, ARMCPU), 452fb602cb7SPeter Maydell VMSTATE_UINT32(env.v7m.other_ss_msp, ARMCPU), 453fb602cb7SPeter Maydell VMSTATE_UINT32(env.v7m.other_ss_psp, ARMCPU), 454acf94941SPeter Maydell VMSTATE_UINT32(env.v7m.basepri[M_REG_S], ARMCPU), 4556d804834SPeter Maydell VMSTATE_UINT32(env.v7m.primask[M_REG_S], ARMCPU), 45642a6686bSPeter Maydell VMSTATE_UINT32(env.v7m.faultmask[M_REG_S], ARMCPU), 4578bfc26eaSPeter Maydell VMSTATE_UINT32(env.v7m.control[M_REG_S], ARMCPU), 45845db7ba6SPeter Maydell VMSTATE_UINT32(env.v7m.vecbase[M_REG_S], ARMCPU), 4594125e6feSPeter Maydell VMSTATE_UINT32(env.pmsav8.mair0[M_REG_S], ARMCPU), 4604125e6feSPeter Maydell VMSTATE_UINT32(env.pmsav8.mair1[M_REG_S], ARMCPU), 46162c58ee0SPeter Maydell VMSTATE_VARRAY_UINT32(env.pmsav8.rbar[M_REG_S], ARMCPU, pmsav7_dregion, 46262c58ee0SPeter Maydell 0, vmstate_info_uint32, uint32_t), 46362c58ee0SPeter Maydell VMSTATE_VARRAY_UINT32(env.pmsav8.rlar[M_REG_S], ARMCPU, pmsav7_dregion, 46462c58ee0SPeter Maydell 0, vmstate_info_uint32, uint32_t), 4651bc04a88SPeter Maydell VMSTATE_UINT32(env.pmsav7.rnr[M_REG_S], ARMCPU), 4661bc04a88SPeter Maydell VMSTATE_VALIDATE("secure MPU_RNR is valid", s_rnr_vmstate_validate), 467ecf5e8eaSPeter Maydell VMSTATE_UINT32(env.v7m.mpu_ctrl[M_REG_S], ARMCPU), 4689d40cd8aSPeter Maydell VMSTATE_UINT32(env.v7m.ccr[M_REG_S], ARMCPU), 469c51a5cfcSPeter Maydell VMSTATE_UINT32(env.v7m.mmfar[M_REG_S], ARMCPU), 470334e8dadSPeter Maydell VMSTATE_UINT32(env.v7m.cfsr[M_REG_S], ARMCPU), 471bed079daSPeter Maydell VMSTATE_UINT32(env.v7m.sfsr, ARMCPU), 472bed079daSPeter Maydell VMSTATE_UINT32(env.v7m.sfar, ARMCPU), 4739901c576SPeter Maydell VMSTATE_VARRAY_UINT32(env.sau.rbar, ARMCPU, sau_sregion, 0, 4749901c576SPeter Maydell vmstate_info_uint32, uint32_t), 4759901c576SPeter Maydell VMSTATE_VARRAY_UINT32(env.sau.rlar, ARMCPU, sau_sregion, 0, 4769901c576SPeter Maydell vmstate_info_uint32, uint32_t), 4779901c576SPeter Maydell VMSTATE_UINT32(env.sau.rnr, ARMCPU), 4789901c576SPeter Maydell VMSTATE_VALIDATE("SAU_RNR is valid", sau_rnr_vmstate_validate), 4799901c576SPeter Maydell VMSTATE_UINT32(env.sau.ctrl, ARMCPU), 48024ac0fb1SPeter Maydell VMSTATE_UINT32(env.v7m.scr[M_REG_S], ARMCPU), 48147825770SPeter Maydell /* AIRCR is not secure-only, but our implementation is R/O if the 48247825770SPeter Maydell * security extension is unimplemented, so we migrate it here. 48347825770SPeter Maydell */ 48447825770SPeter Maydell VMSTATE_UINT32(env.v7m.aircr, ARMCPU), 4851e577cc7SPeter Maydell VMSTATE_END_OF_LIST() 4861e577cc7SPeter Maydell } 4871e577cc7SPeter Maydell }; 4881e577cc7SPeter Maydell 4892c21ee76SJianjun Duan static int get_cpsr(QEMUFile *f, void *opaque, size_t size, 4902c21ee76SJianjun Duan VMStateField *field) 491fcf5ef2aSThomas Huth { 492fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 493fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 494fcf5ef2aSThomas Huth uint32_t val = qemu_get_be32(f); 495fcf5ef2aSThomas Huth 496e6ae5981SPeter Maydell if (arm_feature(env, ARM_FEATURE_M)) { 497eeade001SPeter Maydell if (val & XPSR_EXCP) { 498eeade001SPeter Maydell /* This is a CPSR format value from an older QEMU. (We can tell 499eeade001SPeter Maydell * because values transferred in XPSR format always have zero 500eeade001SPeter Maydell * for the EXCP field, and CPSR format will always have bit 4 501eeade001SPeter Maydell * set in CPSR_M.) Rearrange it into XPSR format. The significant 502eeade001SPeter Maydell * differences are that the T bit is not in the same place, the 503eeade001SPeter Maydell * primask/faultmask info may be in the CPSR I and F bits, and 504eeade001SPeter Maydell * we do not want the mode bits. 5056d804834SPeter Maydell * We know that this cleanup happened before v8M, so there 5066d804834SPeter Maydell * is no complication with banked primask/faultmask. 507eeade001SPeter Maydell */ 508eeade001SPeter Maydell uint32_t newval = val; 509eeade001SPeter Maydell 5106d804834SPeter Maydell assert(!arm_feature(env, ARM_FEATURE_M_SECURITY)); 5116d804834SPeter Maydell 512eeade001SPeter Maydell newval &= (CPSR_NZCV | CPSR_Q | CPSR_IT | CPSR_GE); 513eeade001SPeter Maydell if (val & CPSR_T) { 514eeade001SPeter Maydell newval |= XPSR_T; 515eeade001SPeter Maydell } 516e6ae5981SPeter Maydell /* If the I or F bits are set then this is a migration from 517e6ae5981SPeter Maydell * an old QEMU which still stored the M profile FAULTMASK 518eeade001SPeter Maydell * and PRIMASK in env->daif. For a new QEMU, the data is 519eeade001SPeter Maydell * transferred using the vmstate_m_faultmask_primask subsection. 520e6ae5981SPeter Maydell */ 521e6ae5981SPeter Maydell if (val & CPSR_F) { 52242a6686bSPeter Maydell env->v7m.faultmask[M_REG_NS] = 1; 523e6ae5981SPeter Maydell } 524e6ae5981SPeter Maydell if (val & CPSR_I) { 5256d804834SPeter Maydell env->v7m.primask[M_REG_NS] = 1; 526e6ae5981SPeter Maydell } 527eeade001SPeter Maydell val = newval; 528eeade001SPeter Maydell } 529eeade001SPeter Maydell /* Ignore the low bits, they are handled by vmstate_m. */ 530eeade001SPeter Maydell xpsr_write(env, val, ~XPSR_EXCP); 531eeade001SPeter Maydell return 0; 532e6ae5981SPeter Maydell } 533e6ae5981SPeter Maydell 534fcf5ef2aSThomas Huth env->aarch64 = ((val & PSTATE_nRW) == 0); 535fcf5ef2aSThomas Huth 536fcf5ef2aSThomas Huth if (is_a64(env)) { 537fcf5ef2aSThomas Huth pstate_write(env, val); 538fcf5ef2aSThomas Huth return 0; 539fcf5ef2aSThomas Huth } 540fcf5ef2aSThomas Huth 541fcf5ef2aSThomas Huth cpsr_write(env, val, 0xffffffff, CPSRWriteRaw); 542fcf5ef2aSThomas Huth return 0; 543fcf5ef2aSThomas Huth } 544fcf5ef2aSThomas Huth 5452c21ee76SJianjun Duan static int put_cpsr(QEMUFile *f, void *opaque, size_t size, 5462c21ee76SJianjun Duan VMStateField *field, QJSON *vmdesc) 547fcf5ef2aSThomas Huth { 548fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 549fcf5ef2aSThomas Huth CPUARMState *env = &cpu->env; 550fcf5ef2aSThomas Huth uint32_t val; 551fcf5ef2aSThomas Huth 552eeade001SPeter Maydell if (arm_feature(env, ARM_FEATURE_M)) { 553eeade001SPeter Maydell /* The low 9 bits are v7m.exception, which is handled by vmstate_m. */ 554eeade001SPeter Maydell val = xpsr_read(env) & ~XPSR_EXCP; 555eeade001SPeter Maydell } else if (is_a64(env)) { 556fcf5ef2aSThomas Huth val = pstate_read(env); 557fcf5ef2aSThomas Huth } else { 558fcf5ef2aSThomas Huth val = cpsr_read(env); 559fcf5ef2aSThomas Huth } 560fcf5ef2aSThomas Huth 561fcf5ef2aSThomas Huth qemu_put_be32(f, val); 5622c21ee76SJianjun Duan return 0; 563fcf5ef2aSThomas Huth } 564fcf5ef2aSThomas Huth 565fcf5ef2aSThomas Huth static const VMStateInfo vmstate_cpsr = { 566fcf5ef2aSThomas Huth .name = "cpsr", 567fcf5ef2aSThomas Huth .get = get_cpsr, 568fcf5ef2aSThomas Huth .put = put_cpsr, 569fcf5ef2aSThomas Huth }; 570fcf5ef2aSThomas Huth 571062ba099SAlex Bennée static int get_power(QEMUFile *f, void *opaque, size_t size, 572062ba099SAlex Bennée VMStateField *field) 573062ba099SAlex Bennée { 574062ba099SAlex Bennée ARMCPU *cpu = opaque; 575062ba099SAlex Bennée bool powered_off = qemu_get_byte(f); 576062ba099SAlex Bennée cpu->power_state = powered_off ? PSCI_OFF : PSCI_ON; 577062ba099SAlex Bennée return 0; 578062ba099SAlex Bennée } 579062ba099SAlex Bennée 580062ba099SAlex Bennée static int put_power(QEMUFile *f, void *opaque, size_t size, 581062ba099SAlex Bennée VMStateField *field, QJSON *vmdesc) 582062ba099SAlex Bennée { 583062ba099SAlex Bennée ARMCPU *cpu = opaque; 584062ba099SAlex Bennée 585062ba099SAlex Bennée /* Migration should never happen while we transition power states */ 586062ba099SAlex Bennée 587062ba099SAlex Bennée if (cpu->power_state == PSCI_ON || 588062ba099SAlex Bennée cpu->power_state == PSCI_OFF) { 589062ba099SAlex Bennée bool powered_off = (cpu->power_state == PSCI_OFF) ? true : false; 590062ba099SAlex Bennée qemu_put_byte(f, powered_off); 591062ba099SAlex Bennée return 0; 592062ba099SAlex Bennée } else { 593062ba099SAlex Bennée return 1; 594062ba099SAlex Bennée } 595062ba099SAlex Bennée } 596062ba099SAlex Bennée 597062ba099SAlex Bennée static const VMStateInfo vmstate_powered_off = { 598062ba099SAlex Bennée .name = "powered_off", 599062ba099SAlex Bennée .get = get_power, 600062ba099SAlex Bennée .put = put_power, 601062ba099SAlex Bennée }; 602062ba099SAlex Bennée 60344b1ff31SDr. David Alan Gilbert static int cpu_pre_save(void *opaque) 604fcf5ef2aSThomas Huth { 605fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 606fcf5ef2aSThomas Huth 607fcf5ef2aSThomas Huth if (kvm_enabled()) { 608fcf5ef2aSThomas Huth if (!write_kvmstate_to_list(cpu)) { 609fcf5ef2aSThomas Huth /* This should never fail */ 610fcf5ef2aSThomas Huth abort(); 611fcf5ef2aSThomas Huth } 612fcf5ef2aSThomas Huth } else { 613fcf5ef2aSThomas Huth if (!write_cpustate_to_list(cpu)) { 614fcf5ef2aSThomas Huth /* This should never fail. */ 615fcf5ef2aSThomas Huth abort(); 616fcf5ef2aSThomas Huth } 617fcf5ef2aSThomas Huth } 618fcf5ef2aSThomas Huth 619fcf5ef2aSThomas Huth cpu->cpreg_vmstate_array_len = cpu->cpreg_array_len; 620fcf5ef2aSThomas Huth memcpy(cpu->cpreg_vmstate_indexes, cpu->cpreg_indexes, 621fcf5ef2aSThomas Huth cpu->cpreg_array_len * sizeof(uint64_t)); 622fcf5ef2aSThomas Huth memcpy(cpu->cpreg_vmstate_values, cpu->cpreg_values, 623fcf5ef2aSThomas Huth cpu->cpreg_array_len * sizeof(uint64_t)); 62444b1ff31SDr. David Alan Gilbert 62544b1ff31SDr. David Alan Gilbert return 0; 626fcf5ef2aSThomas Huth } 627fcf5ef2aSThomas Huth 628fcf5ef2aSThomas Huth static int cpu_post_load(void *opaque, int version_id) 629fcf5ef2aSThomas Huth { 630fcf5ef2aSThomas Huth ARMCPU *cpu = opaque; 631fcf5ef2aSThomas Huth int i, v; 632fcf5ef2aSThomas Huth 633fcf5ef2aSThomas Huth /* Update the values list from the incoming migration data. 634fcf5ef2aSThomas Huth * Anything in the incoming data which we don't know about is 635fcf5ef2aSThomas Huth * a migration failure; anything we know about but the incoming 636fcf5ef2aSThomas Huth * data doesn't specify retains its current (reset) value. 637fcf5ef2aSThomas Huth * The indexes list remains untouched -- we only inspect the 638fcf5ef2aSThomas Huth * incoming migration index list so we can match the values array 639fcf5ef2aSThomas Huth * entries with the right slots in our own values array. 640fcf5ef2aSThomas Huth */ 641fcf5ef2aSThomas Huth 642fcf5ef2aSThomas Huth for (i = 0, v = 0; i < cpu->cpreg_array_len 643fcf5ef2aSThomas Huth && v < cpu->cpreg_vmstate_array_len; i++) { 644fcf5ef2aSThomas Huth if (cpu->cpreg_vmstate_indexes[v] > cpu->cpreg_indexes[i]) { 645fcf5ef2aSThomas Huth /* register in our list but not incoming : skip it */ 646fcf5ef2aSThomas Huth continue; 647fcf5ef2aSThomas Huth } 648fcf5ef2aSThomas Huth if (cpu->cpreg_vmstate_indexes[v] < cpu->cpreg_indexes[i]) { 649fcf5ef2aSThomas Huth /* register in their list but not ours: fail migration */ 650fcf5ef2aSThomas Huth return -1; 651fcf5ef2aSThomas Huth } 652fcf5ef2aSThomas Huth /* matching register, copy the value over */ 653fcf5ef2aSThomas Huth cpu->cpreg_values[i] = cpu->cpreg_vmstate_values[v]; 654fcf5ef2aSThomas Huth v++; 655fcf5ef2aSThomas Huth } 656fcf5ef2aSThomas Huth 657fcf5ef2aSThomas Huth if (kvm_enabled()) { 658fcf5ef2aSThomas Huth if (!write_list_to_kvmstate(cpu, KVM_PUT_FULL_STATE)) { 659fcf5ef2aSThomas Huth return -1; 660fcf5ef2aSThomas Huth } 661fcf5ef2aSThomas Huth /* Note that it's OK for the TCG side not to know about 662fcf5ef2aSThomas Huth * every register in the list; KVM is authoritative if 663fcf5ef2aSThomas Huth * we're using it. 664fcf5ef2aSThomas Huth */ 665fcf5ef2aSThomas Huth write_list_to_cpustate(cpu); 666fcf5ef2aSThomas Huth } else { 667fcf5ef2aSThomas Huth if (!write_list_to_cpustate(cpu)) { 668fcf5ef2aSThomas Huth return -1; 669fcf5ef2aSThomas Huth } 670fcf5ef2aSThomas Huth } 671fcf5ef2aSThomas Huth 672fcf5ef2aSThomas Huth hw_breakpoint_update_all(cpu); 673fcf5ef2aSThomas Huth hw_watchpoint_update_all(cpu); 674fcf5ef2aSThomas Huth 675fcf5ef2aSThomas Huth return 0; 676fcf5ef2aSThomas Huth } 677fcf5ef2aSThomas Huth 678fcf5ef2aSThomas Huth const VMStateDescription vmstate_arm_cpu = { 679fcf5ef2aSThomas Huth .name = "cpu", 680fcf5ef2aSThomas Huth .version_id = 22, 681fcf5ef2aSThomas Huth .minimum_version_id = 22, 682fcf5ef2aSThomas Huth .pre_save = cpu_pre_save, 683fcf5ef2aSThomas Huth .post_load = cpu_post_load, 684fcf5ef2aSThomas Huth .fields = (VMStateField[]) { 685fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.regs, ARMCPU, 16), 686fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.xregs, ARMCPU, 32), 687fcf5ef2aSThomas Huth VMSTATE_UINT64(env.pc, ARMCPU), 688fcf5ef2aSThomas Huth { 689fcf5ef2aSThomas Huth .name = "cpsr", 690fcf5ef2aSThomas Huth .version_id = 0, 691fcf5ef2aSThomas Huth .size = sizeof(uint32_t), 692fcf5ef2aSThomas Huth .info = &vmstate_cpsr, 693fcf5ef2aSThomas Huth .flags = VMS_SINGLE, 694fcf5ef2aSThomas Huth .offset = 0, 695fcf5ef2aSThomas Huth }, 696fcf5ef2aSThomas Huth VMSTATE_UINT32(env.spsr, ARMCPU), 697fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.banked_spsr, ARMCPU, 8), 698fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.banked_r13, ARMCPU, 8), 699fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.banked_r14, ARMCPU, 8), 700fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.usr_regs, ARMCPU, 5), 701fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.fiq_regs, ARMCPU, 5), 702fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.elr_el, ARMCPU, 4), 703fcf5ef2aSThomas Huth VMSTATE_UINT64_ARRAY(env.sp_el, ARMCPU, 4), 704fcf5ef2aSThomas Huth /* The length-check must come before the arrays to avoid 705fcf5ef2aSThomas Huth * incoming data possibly overflowing the array. 706fcf5ef2aSThomas Huth */ 707fcf5ef2aSThomas Huth VMSTATE_INT32_POSITIVE_LE(cpreg_vmstate_array_len, ARMCPU), 708fcf5ef2aSThomas Huth VMSTATE_VARRAY_INT32(cpreg_vmstate_indexes, ARMCPU, 709fcf5ef2aSThomas Huth cpreg_vmstate_array_len, 710fcf5ef2aSThomas Huth 0, vmstate_info_uint64, uint64_t), 711fcf5ef2aSThomas Huth VMSTATE_VARRAY_INT32(cpreg_vmstate_values, ARMCPU, 712fcf5ef2aSThomas Huth cpreg_vmstate_array_len, 713fcf5ef2aSThomas Huth 0, vmstate_info_uint64, uint64_t), 714fcf5ef2aSThomas Huth VMSTATE_UINT64(env.exclusive_addr, ARMCPU), 715fcf5ef2aSThomas Huth VMSTATE_UINT64(env.exclusive_val, ARMCPU), 716fcf5ef2aSThomas Huth VMSTATE_UINT64(env.exclusive_high, ARMCPU), 717fcf5ef2aSThomas Huth VMSTATE_UINT64(env.features, ARMCPU), 718fcf5ef2aSThomas Huth VMSTATE_UINT32(env.exception.syndrome, ARMCPU), 719fcf5ef2aSThomas Huth VMSTATE_UINT32(env.exception.fsr, ARMCPU), 720fcf5ef2aSThomas Huth VMSTATE_UINT64(env.exception.vaddress, ARMCPU), 721fcf5ef2aSThomas Huth VMSTATE_TIMER_PTR(gt_timer[GTIMER_PHYS], ARMCPU), 722fcf5ef2aSThomas Huth VMSTATE_TIMER_PTR(gt_timer[GTIMER_VIRT], ARMCPU), 723062ba099SAlex Bennée { 724062ba099SAlex Bennée .name = "power_state", 725062ba099SAlex Bennée .version_id = 0, 726062ba099SAlex Bennée .size = sizeof(bool), 727062ba099SAlex Bennée .info = &vmstate_powered_off, 728062ba099SAlex Bennée .flags = VMS_SINGLE, 729062ba099SAlex Bennée .offset = 0, 730062ba099SAlex Bennée }, 731fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST() 732fcf5ef2aSThomas Huth }, 733fcf5ef2aSThomas Huth .subsections = (const VMStateDescription*[]) { 734fcf5ef2aSThomas Huth &vmstate_vfp, 735fcf5ef2aSThomas Huth &vmstate_iwmmxt, 736fcf5ef2aSThomas Huth &vmstate_m, 737fcf5ef2aSThomas Huth &vmstate_thumb2ee, 738f1a46940SPeter Maydell /* pmsav7_rnr must come before pmsav7 so that we have the 739f1a46940SPeter Maydell * region number before we test it in the VMSTATE_VALIDATE 740f1a46940SPeter Maydell * in vmstate_pmsav7. 741f1a46940SPeter Maydell */ 742f1a46940SPeter Maydell &vmstate_pmsav7_rnr, 743fcf5ef2aSThomas Huth &vmstate_pmsav7, 7440e1a46bbSPeter Maydell &vmstate_pmsav8, 7451e577cc7SPeter Maydell &vmstate_m_security, 746ef401601SRichard Henderson #ifdef TARGET_AARCH64 747ef401601SRichard Henderson &vmstate_sve, 748ef401601SRichard Henderson #endif 749202ccb6bSDongjiu Geng &vmstate_serror, 750fcf5ef2aSThomas Huth NULL 751fcf5ef2aSThomas Huth } 752fcf5ef2aSThomas Huth }; 753