xref: /openbmc/qemu/target/arm/machine.c (revision e1e7cbc9046c776dc63c37b9b682f8179bc8e898)
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