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