1fcf5ef2aSThomas Huth #include "qemu/osdep.h"
2fcf5ef2aSThomas Huth #include "cpu.h"
3fcf5ef2aSThomas Huth #include "exec/exec-all.h"
4fcf5ef2aSThomas Huth #include "sysemu/kvm.h"
533edcde7SDaniel Henrique Barboza #include "sysemu/tcg.h"
6fcf5ef2aSThomas Huth #include "helper_regs.h"
7fcf5ef2aSThomas Huth #include "mmu-hash64.h"
8fcf5ef2aSThomas Huth #include "migration/cpu.h"
9d5fc133eSDavid Gibson #include "qapi/error.h"
10c363a37aSDaniel Henrique Barboza #include "kvm_ppc.h"
116e8b9903SRichard Henderson #include "power8-pmu.h"
12cdab53ddSNicholas Piggin #include "sysemu/replay.h"
13fcf5ef2aSThomas Huth
post_load_update_msr(CPUPPCState * env)14edece45dSRichard Henderson static void post_load_update_msr(CPUPPCState *env)
15edece45dSRichard Henderson {
16edece45dSRichard Henderson target_ulong msr = env->msr;
17edece45dSRichard Henderson
18edece45dSRichard Henderson /*
19edece45dSRichard Henderson * Invalidate all supported msr bits except MSR_TGPR/MSR_HVB
20d764184dSRichard Henderson * before restoring. Note that this recomputes hflags.
21edece45dSRichard Henderson */
22edece45dSRichard Henderson env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB);
23edece45dSRichard Henderson ppc_store_msr(env, msr);
2433edcde7SDaniel Henrique Barboza }
25edece45dSRichard Henderson
get_avr(QEMUFile * f,void * pv,size_t size,const VMStateField * field)2603fee66fSMarc-André Lureau static int get_avr(QEMUFile *f, void *pv, size_t size,
2703fee66fSMarc-André Lureau const VMStateField *field)
28fcf5ef2aSThomas Huth {
29fcf5ef2aSThomas Huth ppc_avr_t *v = pv;
30fcf5ef2aSThomas Huth
31fcf5ef2aSThomas Huth v->u64[0] = qemu_get_be64(f);
32fcf5ef2aSThomas Huth v->u64[1] = qemu_get_be64(f);
33fcf5ef2aSThomas Huth
34fcf5ef2aSThomas Huth return 0;
35fcf5ef2aSThomas Huth }
36fcf5ef2aSThomas Huth
put_avr(QEMUFile * f,void * pv,size_t size,const VMStateField * field,JSONWriter * vmdesc)3703fee66fSMarc-André Lureau static int put_avr(QEMUFile *f, void *pv, size_t size,
383ddba9a9SMarkus Armbruster const VMStateField *field, JSONWriter *vmdesc)
39fcf5ef2aSThomas Huth {
40fcf5ef2aSThomas Huth ppc_avr_t *v = pv;
41fcf5ef2aSThomas Huth
42fcf5ef2aSThomas Huth qemu_put_be64(f, v->u64[0]);
43fcf5ef2aSThomas Huth qemu_put_be64(f, v->u64[1]);
442c21ee76SJianjun Duan return 0;
45fcf5ef2aSThomas Huth }
46fcf5ef2aSThomas Huth
47fcf5ef2aSThomas Huth static const VMStateInfo vmstate_info_avr = {
48fcf5ef2aSThomas Huth .name = "avr",
49fcf5ef2aSThomas Huth .get = get_avr,
50fcf5ef2aSThomas Huth .put = put_avr,
51fcf5ef2aSThomas Huth };
52fcf5ef2aSThomas Huth
53fcf5ef2aSThomas Huth #define VMSTATE_AVR_ARRAY_V(_f, _s, _n, _v) \
54ef96e3aeSMark Cave-Ayland VMSTATE_SUB_ARRAY(_f, _s, 32, _n, _v, vmstate_info_avr, ppc_avr_t)
55fcf5ef2aSThomas Huth
56fcf5ef2aSThomas Huth #define VMSTATE_AVR_ARRAY(_f, _s, _n) \
57fcf5ef2aSThomas Huth VMSTATE_AVR_ARRAY_V(_f, _s, _n, 0)
58fcf5ef2aSThomas Huth
get_fpr(QEMUFile * f,void * pv,size_t size,const VMStateField * field)59ef96e3aeSMark Cave-Ayland static int get_fpr(QEMUFile *f, void *pv, size_t size,
60ef96e3aeSMark Cave-Ayland const VMStateField *field)
61ef96e3aeSMark Cave-Ayland {
62ef96e3aeSMark Cave-Ayland ppc_vsr_t *v = pv;
63ef96e3aeSMark Cave-Ayland
648a14d31bSMark Cave-Ayland v->VsrD(0) = qemu_get_be64(f);
65ef96e3aeSMark Cave-Ayland
66ef96e3aeSMark Cave-Ayland return 0;
67ef96e3aeSMark Cave-Ayland }
68ef96e3aeSMark Cave-Ayland
put_fpr(QEMUFile * f,void * pv,size_t size,const VMStateField * field,JSONWriter * vmdesc)69ef96e3aeSMark Cave-Ayland static int put_fpr(QEMUFile *f, void *pv, size_t size,
703ddba9a9SMarkus Armbruster const VMStateField *field, JSONWriter *vmdesc)
71ef96e3aeSMark Cave-Ayland {
72ef96e3aeSMark Cave-Ayland ppc_vsr_t *v = pv;
73ef96e3aeSMark Cave-Ayland
748a14d31bSMark Cave-Ayland qemu_put_be64(f, v->VsrD(0));
75ef96e3aeSMark Cave-Ayland return 0;
76ef96e3aeSMark Cave-Ayland }
77ef96e3aeSMark Cave-Ayland
78ef96e3aeSMark Cave-Ayland static const VMStateInfo vmstate_info_fpr = {
79ef96e3aeSMark Cave-Ayland .name = "fpr",
80ef96e3aeSMark Cave-Ayland .get = get_fpr,
81ef96e3aeSMark Cave-Ayland .put = put_fpr,
82ef96e3aeSMark Cave-Ayland };
83ef96e3aeSMark Cave-Ayland
84ef96e3aeSMark Cave-Ayland #define VMSTATE_FPR_ARRAY_V(_f, _s, _n, _v) \
85ef96e3aeSMark Cave-Ayland VMSTATE_SUB_ARRAY(_f, _s, 0, _n, _v, vmstate_info_fpr, ppc_vsr_t)
86ef96e3aeSMark Cave-Ayland
87ef96e3aeSMark Cave-Ayland #define VMSTATE_FPR_ARRAY(_f, _s, _n) \
88ef96e3aeSMark Cave-Ayland VMSTATE_FPR_ARRAY_V(_f, _s, _n, 0)
89ef96e3aeSMark Cave-Ayland
get_vsr(QEMUFile * f,void * pv,size_t size,const VMStateField * field)90ef96e3aeSMark Cave-Ayland static int get_vsr(QEMUFile *f, void *pv, size_t size,
91ef96e3aeSMark Cave-Ayland const VMStateField *field)
92ef96e3aeSMark Cave-Ayland {
93ef96e3aeSMark Cave-Ayland ppc_vsr_t *v = pv;
94ef96e3aeSMark Cave-Ayland
958a14d31bSMark Cave-Ayland v->VsrD(1) = qemu_get_be64(f);
96ef96e3aeSMark Cave-Ayland
97ef96e3aeSMark Cave-Ayland return 0;
98ef96e3aeSMark Cave-Ayland }
99ef96e3aeSMark Cave-Ayland
put_vsr(QEMUFile * f,void * pv,size_t size,const VMStateField * field,JSONWriter * vmdesc)100ef96e3aeSMark Cave-Ayland static int put_vsr(QEMUFile *f, void *pv, size_t size,
1013ddba9a9SMarkus Armbruster const VMStateField *field, JSONWriter *vmdesc)
102ef96e3aeSMark Cave-Ayland {
103ef96e3aeSMark Cave-Ayland ppc_vsr_t *v = pv;
104ef96e3aeSMark Cave-Ayland
1058a14d31bSMark Cave-Ayland qemu_put_be64(f, v->VsrD(1));
106ef96e3aeSMark Cave-Ayland return 0;
107ef96e3aeSMark Cave-Ayland }
108ef96e3aeSMark Cave-Ayland
109ef96e3aeSMark Cave-Ayland static const VMStateInfo vmstate_info_vsr = {
110ef96e3aeSMark Cave-Ayland .name = "vsr",
111ef96e3aeSMark Cave-Ayland .get = get_vsr,
112ef96e3aeSMark Cave-Ayland .put = put_vsr,
113ef96e3aeSMark Cave-Ayland };
114ef96e3aeSMark Cave-Ayland
115ef96e3aeSMark Cave-Ayland #define VMSTATE_VSR_ARRAY_V(_f, _s, _n, _v) \
116ef96e3aeSMark Cave-Ayland VMSTATE_SUB_ARRAY(_f, _s, 0, _n, _v, vmstate_info_vsr, ppc_vsr_t)
117ef96e3aeSMark Cave-Ayland
118ef96e3aeSMark Cave-Ayland #define VMSTATE_VSR_ARRAY(_f, _s, _n) \
119ef96e3aeSMark Cave-Ayland VMSTATE_VSR_ARRAY_V(_f, _s, _n, 0)
120ef96e3aeSMark Cave-Ayland
cpu_pre_save(void * opaque)12144b1ff31SDr. David Alan Gilbert static int cpu_pre_save(void *opaque)
122fcf5ef2aSThomas Huth {
123fcf5ef2aSThomas Huth PowerPCCPU *cpu = opaque;
124fcf5ef2aSThomas Huth CPUPPCState *env = &cpu->env;
125fcf5ef2aSThomas Huth int i;
126fcf5ef2aSThomas Huth
127fcf5ef2aSThomas Huth env->spr[SPR_LR] = env->lr;
128fcf5ef2aSThomas Huth env->spr[SPR_CTR] = env->ctr;
129fcf5ef2aSThomas Huth env->spr[SPR_XER] = cpu_read_xer(env);
130fcf5ef2aSThomas Huth #if defined(TARGET_PPC64)
131fcf5ef2aSThomas Huth env->spr[SPR_CFAR] = env->cfar;
132fcf5ef2aSThomas Huth #endif
133fcf5ef2aSThomas Huth env->spr[SPR_BOOKE_SPEFSCR] = env->spe_fscr;
134fcf5ef2aSThomas Huth
135fcf5ef2aSThomas Huth for (i = 0; (i < 4) && (i < env->nb_BATs); i++) {
136fcf5ef2aSThomas Huth env->spr[SPR_DBAT0U + 2 * i] = env->DBAT[0][i];
137fcf5ef2aSThomas Huth env->spr[SPR_DBAT0U + 2 * i + 1] = env->DBAT[1][i];
138fcf5ef2aSThomas Huth env->spr[SPR_IBAT0U + 2 * i] = env->IBAT[0][i];
139fcf5ef2aSThomas Huth env->spr[SPR_IBAT0U + 2 * i + 1] = env->IBAT[1][i];
140fcf5ef2aSThomas Huth }
141fcf5ef2aSThomas Huth for (i = 0; (i < 4) && ((i + 4) < env->nb_BATs); i++) {
142fcf5ef2aSThomas Huth env->spr[SPR_DBAT4U + 2 * i] = env->DBAT[0][i + 4];
143fcf5ef2aSThomas Huth env->spr[SPR_DBAT4U + 2 * i + 1] = env->DBAT[1][i + 4];
144fcf5ef2aSThomas Huth env->spr[SPR_IBAT4U + 2 * i] = env->IBAT[0][i + 4];
145fcf5ef2aSThomas Huth env->spr[SPR_IBAT4U + 2 * i + 1] = env->IBAT[1][i + 4];
146fcf5ef2aSThomas Huth }
147fcf5ef2aSThomas Huth
148005b69fdSCédric Le Goater /* Used to retain migration compatibility for pre 6.0 for 601 machines. */
149005b69fdSCédric Le Goater env->hflags_compat_nmsr = 0;
150f7a7b652SRichard Henderson
151578912adSNicholas Piggin if (tcg_enabled()) {
152578912adSNicholas Piggin /*
153578912adSNicholas Piggin * TCG does not maintain the DECR spr (unlike KVM) so have to save
154578912adSNicholas Piggin * it here.
155578912adSNicholas Piggin */
156578912adSNicholas Piggin env->spr[SPR_DECR] = cpu_ppc_load_decr(env);
157578912adSNicholas Piggin }
158578912adSNicholas Piggin
15944b1ff31SDr. David Alan Gilbert return 0;
160fcf5ef2aSThomas Huth }
161fcf5ef2aSThomas Huth
162d5fc133eSDavid Gibson /*
163d5fc133eSDavid Gibson * Determine if a given PVR is a "close enough" match to the CPU
164d5fc133eSDavid Gibson * object. For TCG and KVM PR it would probably be sufficient to
165d5fc133eSDavid Gibson * require an exact PVR match. However for KVM HV the user is
166d5fc133eSDavid Gibson * restricted to a PVR exactly matching the host CPU. The correct way
167d5fc133eSDavid Gibson * to handle this is to put the guest into an architected
168d5fc133eSDavid Gibson * compatibility mode. However, to allow a more forgiving transition
169d5fc133eSDavid Gibson * and migration from before this was widely done, we allow migration
170d5fc133eSDavid Gibson * between sufficiently similar PVRs, as determined by the CPU class's
171d5fc133eSDavid Gibson * pvr_match() hook.
172d5fc133eSDavid Gibson */
pvr_match(PowerPCCPU * cpu,uint32_t pvr)173d5fc133eSDavid Gibson static bool pvr_match(PowerPCCPU *cpu, uint32_t pvr)
174d5fc133eSDavid Gibson {
175d5fc133eSDavid Gibson PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
176d5fc133eSDavid Gibson
177d5fc133eSDavid Gibson if (pvr == pcc->pvr) {
178d5fc133eSDavid Gibson return true;
179d5fc133eSDavid Gibson }
18021d3a78eSNicholas Piggin return pcc->pvr_match(pcc, pvr, true);
181d5fc133eSDavid Gibson }
182d5fc133eSDavid Gibson
cpu_post_load(void * opaque,int version_id)183fcf5ef2aSThomas Huth static int cpu_post_load(void *opaque, int version_id)
184fcf5ef2aSThomas Huth {
185fcf5ef2aSThomas Huth PowerPCCPU *cpu = opaque;
186fcf5ef2aSThomas Huth CPUPPCState *env = &cpu->env;
187fcf5ef2aSThomas Huth int i;
188fcf5ef2aSThomas Huth
189fcf5ef2aSThomas Huth /*
190d5fc133eSDavid Gibson * If we're operating in compat mode, we should be ok as long as
191136fbf65Szhaolichang * the destination supports the same compatibility mode.
192d5fc133eSDavid Gibson *
193d5fc133eSDavid Gibson * Otherwise, however, we require that the destination has exactly
194d5fc133eSDavid Gibson * the same CPU model as the source.
195fcf5ef2aSThomas Huth */
196d5fc133eSDavid Gibson
197d5fc133eSDavid Gibson #if defined(TARGET_PPC64)
198d5fc133eSDavid Gibson if (cpu->compat_pvr) {
199e07cc192SSuraj Jitindar Singh uint32_t compat_pvr = cpu->compat_pvr;
200d5fc133eSDavid Gibson Error *local_err = NULL;
201899134ebSGreg Kurz int ret;
202d5fc133eSDavid Gibson
203e07cc192SSuraj Jitindar Singh cpu->compat_pvr = 0;
204899134ebSGreg Kurz ret = ppc_set_compat(cpu, compat_pvr, &local_err);
205899134ebSGreg Kurz if (ret < 0) {
206d5fc133eSDavid Gibson error_report_err(local_err);
207899134ebSGreg Kurz return ret;
208d5fc133eSDavid Gibson }
209d5fc133eSDavid Gibson } else
210d5fc133eSDavid Gibson #endif
211d5fc133eSDavid Gibson {
212d5fc133eSDavid Gibson if (!pvr_match(cpu, env->spr[SPR_PVR])) {
213899134ebSGreg Kurz return -EINVAL;
214d5fc133eSDavid Gibson }
215d5fc133eSDavid Gibson }
216d5fc133eSDavid Gibson
217c363a37aSDaniel Henrique Barboza /*
218c363a37aSDaniel Henrique Barboza * If we're running with KVM HV, there is a chance that the guest
219c363a37aSDaniel Henrique Barboza * is running with KVM HV and its kernel does not have the
220c363a37aSDaniel Henrique Barboza * capability of dealing with a different PVR other than this
221c363a37aSDaniel Henrique Barboza * exact host PVR in KVM_SET_SREGS. If that happens, the
222c363a37aSDaniel Henrique Barboza * guest freezes after migration.
223c363a37aSDaniel Henrique Barboza *
224c363a37aSDaniel Henrique Barboza * The function kvmppc_pvr_workaround_required does this verification
225c363a37aSDaniel Henrique Barboza * by first checking if the kernel has the cap, returning true immediately
226c363a37aSDaniel Henrique Barboza * if that is the case. Otherwise, it checks if we're running in KVM PR.
227c363a37aSDaniel Henrique Barboza * If the guest kernel does not have the cap and we're not running KVM-PR
228c363a37aSDaniel Henrique Barboza * (so, it is running KVM-HV), we need to ensure that KVM_SET_SREGS will
229c363a37aSDaniel Henrique Barboza * receive the PVR it expects as a workaround.
230c363a37aSDaniel Henrique Barboza *
231c363a37aSDaniel Henrique Barboza */
232c363a37aSDaniel Henrique Barboza if (kvmppc_pvr_workaround_required(cpu)) {
233c363a37aSDaniel Henrique Barboza env->spr[SPR_PVR] = env->spr_cb[SPR_PVR].default_value;
234c363a37aSDaniel Henrique Barboza }
235c363a37aSDaniel Henrique Barboza
236fcf5ef2aSThomas Huth env->lr = env->spr[SPR_LR];
237fcf5ef2aSThomas Huth env->ctr = env->spr[SPR_CTR];
238fcf5ef2aSThomas Huth cpu_write_xer(env, env->spr[SPR_XER]);
239fcf5ef2aSThomas Huth #if defined(TARGET_PPC64)
240fcf5ef2aSThomas Huth env->cfar = env->spr[SPR_CFAR];
241fcf5ef2aSThomas Huth #endif
242fcf5ef2aSThomas Huth env->spe_fscr = env->spr[SPR_BOOKE_SPEFSCR];
243fcf5ef2aSThomas Huth
244fcf5ef2aSThomas Huth for (i = 0; (i < 4) && (i < env->nb_BATs); i++) {
245fcf5ef2aSThomas Huth env->DBAT[0][i] = env->spr[SPR_DBAT0U + 2 * i];
246fcf5ef2aSThomas Huth env->DBAT[1][i] = env->spr[SPR_DBAT0U + 2 * i + 1];
247fcf5ef2aSThomas Huth env->IBAT[0][i] = env->spr[SPR_IBAT0U + 2 * i];
248fcf5ef2aSThomas Huth env->IBAT[1][i] = env->spr[SPR_IBAT0U + 2 * i + 1];
249fcf5ef2aSThomas Huth }
250fcf5ef2aSThomas Huth for (i = 0; (i < 4) && ((i + 4) < env->nb_BATs); i++) {
251fcf5ef2aSThomas Huth env->DBAT[0][i + 4] = env->spr[SPR_DBAT4U + 2 * i];
252fcf5ef2aSThomas Huth env->DBAT[1][i + 4] = env->spr[SPR_DBAT4U + 2 * i + 1];
253fcf5ef2aSThomas Huth env->IBAT[0][i + 4] = env->spr[SPR_IBAT4U + 2 * i];
254fcf5ef2aSThomas Huth env->IBAT[1][i + 4] = env->spr[SPR_IBAT4U + 2 * i + 1];
255fcf5ef2aSThomas Huth }
256fcf5ef2aSThomas Huth
257e57ca75cSDavid Gibson if (!cpu->vhyp) {
258fcf5ef2aSThomas Huth ppc_store_sdr1(env, env->spr[SPR_SDR1]);
259fcf5ef2aSThomas Huth }
260fcf5ef2aSThomas Huth
261edece45dSRichard Henderson post_load_update_msr(env);
262fcf5ef2aSThomas Huth
2636494d2c1SNicholas Piggin if (tcg_enabled()) {
26414192307SNicholas Piggin /* Re-set breaks based on regs */
26514192307SNicholas Piggin #if defined(TARGET_PPC64)
26614192307SNicholas Piggin ppc_update_ciabr(env);
267d5ee641cSNicholas Piggin ppc_update_daw0(env);
26814192307SNicholas Piggin #endif
269578912adSNicholas Piggin /*
270578912adSNicholas Piggin * TCG needs to re-start the decrementer timer and/or raise the
271578912adSNicholas Piggin * interrupt. This works for level-triggered decrementer. Edge
272578912adSNicholas Piggin * triggered types (including HDEC) would need to carry more state.
273578912adSNicholas Piggin */
274578912adSNicholas Piggin cpu_ppc_store_decr(env, env->spr[SPR_DECR]);
275a7138e28SGlenn Miles pmu_mmcr01a_updated(env);
2766494d2c1SNicholas Piggin }
2776494d2c1SNicholas Piggin
278fcf5ef2aSThomas Huth return 0;
279fcf5ef2aSThomas Huth }
280fcf5ef2aSThomas Huth
fpu_needed(void * opaque)281fcf5ef2aSThomas Huth static bool fpu_needed(void *opaque)
282fcf5ef2aSThomas Huth {
283fcf5ef2aSThomas Huth PowerPCCPU *cpu = opaque;
284fcf5ef2aSThomas Huth
2856f7a6993SDavid Gibson return cpu->env.insns_flags & PPC_FLOAT;
286fcf5ef2aSThomas Huth }
287fcf5ef2aSThomas Huth
288fcf5ef2aSThomas Huth static const VMStateDescription vmstate_fpu = {
289fcf5ef2aSThomas Huth .name = "cpu/fpu",
290fcf5ef2aSThomas Huth .version_id = 1,
291fcf5ef2aSThomas Huth .minimum_version_id = 1,
292fcf5ef2aSThomas Huth .needed = fpu_needed,
293caae2396SRichard Henderson .fields = (const VMStateField[]) {
294ef96e3aeSMark Cave-Ayland VMSTATE_FPR_ARRAY(env.vsr, PowerPCCPU, 32),
295fcf5ef2aSThomas Huth VMSTATE_UINTTL(env.fpscr, PowerPCCPU),
296fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
297fcf5ef2aSThomas Huth },
298fcf5ef2aSThomas Huth };
299fcf5ef2aSThomas Huth
altivec_needed(void * opaque)300fcf5ef2aSThomas Huth static bool altivec_needed(void *opaque)
301fcf5ef2aSThomas Huth {
302fcf5ef2aSThomas Huth PowerPCCPU *cpu = opaque;
303fcf5ef2aSThomas Huth
3046f7a6993SDavid Gibson return cpu->env.insns_flags & PPC_ALTIVEC;
305fcf5ef2aSThomas Huth }
306fcf5ef2aSThomas Huth
get_vscr(QEMUFile * f,void * opaque,size_t size,const VMStateField * field)307596fff20SRichard Henderson static int get_vscr(QEMUFile *f, void *opaque, size_t size,
308596fff20SRichard Henderson const VMStateField *field)
309596fff20SRichard Henderson {
310596fff20SRichard Henderson PowerPCCPU *cpu = opaque;
31187aff238SBruno Larsen (billionai) ppc_store_vscr(&cpu->env, qemu_get_be32(f));
312596fff20SRichard Henderson return 0;
313596fff20SRichard Henderson }
314596fff20SRichard Henderson
put_vscr(QEMUFile * f,void * opaque,size_t size,const VMStateField * field,JSONWriter * vmdesc)315596fff20SRichard Henderson static int put_vscr(QEMUFile *f, void *opaque, size_t size,
3163ddba9a9SMarkus Armbruster const VMStateField *field, JSONWriter *vmdesc)
317596fff20SRichard Henderson {
318596fff20SRichard Henderson PowerPCCPU *cpu = opaque;
31987aff238SBruno Larsen (billionai) qemu_put_be32(f, ppc_get_vscr(&cpu->env));
320596fff20SRichard Henderson return 0;
321596fff20SRichard Henderson }
322596fff20SRichard Henderson
323596fff20SRichard Henderson static const VMStateInfo vmstate_vscr = {
324596fff20SRichard Henderson .name = "cpu/altivec/vscr",
325596fff20SRichard Henderson .get = get_vscr,
326596fff20SRichard Henderson .put = put_vscr,
327596fff20SRichard Henderson };
328596fff20SRichard Henderson
329fcf5ef2aSThomas Huth static const VMStateDescription vmstate_altivec = {
330fcf5ef2aSThomas Huth .name = "cpu/altivec",
331fcf5ef2aSThomas Huth .version_id = 1,
332fcf5ef2aSThomas Huth .minimum_version_id = 1,
333fcf5ef2aSThomas Huth .needed = altivec_needed,
334caae2396SRichard Henderson .fields = (const VMStateField[]) {
335ef96e3aeSMark Cave-Ayland VMSTATE_AVR_ARRAY(env.vsr, PowerPCCPU, 32),
336596fff20SRichard Henderson /*
337596fff20SRichard Henderson * Save the architecture value of the vscr, not the internally
338596fff20SRichard Henderson * expanded version. Since this architecture value does not
339596fff20SRichard Henderson * exist in memory to be stored, this requires a but of hoop
340596fff20SRichard Henderson * jumping. We want OFFSET=0 so that we effectively pass CPU
341596fff20SRichard Henderson * to the helper functions.
342596fff20SRichard Henderson */
343596fff20SRichard Henderson {
344596fff20SRichard Henderson .name = "vscr",
345596fff20SRichard Henderson .version_id = 0,
346596fff20SRichard Henderson .size = sizeof(uint32_t),
347596fff20SRichard Henderson .info = &vmstate_vscr,
348596fff20SRichard Henderson .flags = VMS_SINGLE,
349596fff20SRichard Henderson .offset = 0
350596fff20SRichard Henderson },
351fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
352fcf5ef2aSThomas Huth },
353fcf5ef2aSThomas Huth };
354fcf5ef2aSThomas Huth
vsx_needed(void * opaque)355fcf5ef2aSThomas Huth static bool vsx_needed(void *opaque)
356fcf5ef2aSThomas Huth {
357fcf5ef2aSThomas Huth PowerPCCPU *cpu = opaque;
358fcf5ef2aSThomas Huth
3596f7a6993SDavid Gibson return cpu->env.insns_flags2 & PPC2_VSX;
360fcf5ef2aSThomas Huth }
361fcf5ef2aSThomas Huth
362fcf5ef2aSThomas Huth static const VMStateDescription vmstate_vsx = {
363fcf5ef2aSThomas Huth .name = "cpu/vsx",
364fcf5ef2aSThomas Huth .version_id = 1,
365fcf5ef2aSThomas Huth .minimum_version_id = 1,
366fcf5ef2aSThomas Huth .needed = vsx_needed,
367caae2396SRichard Henderson .fields = (const VMStateField[]) {
368ef96e3aeSMark Cave-Ayland VMSTATE_VSR_ARRAY(env.vsr, PowerPCCPU, 32),
369fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
370fcf5ef2aSThomas Huth },
371fcf5ef2aSThomas Huth };
372fcf5ef2aSThomas Huth
373fcf5ef2aSThomas Huth #ifdef TARGET_PPC64
374fcf5ef2aSThomas Huth /* Transactional memory state */
tm_needed(void * opaque)375fcf5ef2aSThomas Huth static bool tm_needed(void *opaque)
376fcf5ef2aSThomas Huth {
377fcf5ef2aSThomas Huth PowerPCCPU *cpu = opaque;
378fcf5ef2aSThomas Huth CPUPPCState *env = &cpu->env;
379ca241959SVíctor Colombo return FIELD_EX64(env->msr, MSR, TS);
380fcf5ef2aSThomas Huth }
381fcf5ef2aSThomas Huth
382fcf5ef2aSThomas Huth static const VMStateDescription vmstate_tm = {
383fcf5ef2aSThomas Huth .name = "cpu/tm",
384fcf5ef2aSThomas Huth .version_id = 1,
385fcf5ef2aSThomas Huth .minimum_version_id = 1,
386fcf5ef2aSThomas Huth .needed = tm_needed,
387caae2396SRichard Henderson .fields = (const VMStateField []) {
388fcf5ef2aSThomas Huth VMSTATE_UINTTL_ARRAY(env.tm_gpr, PowerPCCPU, 32),
389fcf5ef2aSThomas Huth VMSTATE_AVR_ARRAY(env.tm_vsr, PowerPCCPU, 64),
390fcf5ef2aSThomas Huth VMSTATE_UINT64(env.tm_cr, PowerPCCPU),
391fcf5ef2aSThomas Huth VMSTATE_UINT64(env.tm_lr, PowerPCCPU),
392fcf5ef2aSThomas Huth VMSTATE_UINT64(env.tm_ctr, PowerPCCPU),
393fcf5ef2aSThomas Huth VMSTATE_UINT64(env.tm_fpscr, PowerPCCPU),
394fcf5ef2aSThomas Huth VMSTATE_UINT64(env.tm_amr, PowerPCCPU),
395fcf5ef2aSThomas Huth VMSTATE_UINT64(env.tm_ppr, PowerPCCPU),
396fcf5ef2aSThomas Huth VMSTATE_UINT64(env.tm_vrsave, PowerPCCPU),
397fcf5ef2aSThomas Huth VMSTATE_UINT32(env.tm_vscr, PowerPCCPU),
398fcf5ef2aSThomas Huth VMSTATE_UINT64(env.tm_dscr, PowerPCCPU),
399fcf5ef2aSThomas Huth VMSTATE_UINT64(env.tm_tar, PowerPCCPU),
400fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
401fcf5ef2aSThomas Huth },
402fcf5ef2aSThomas Huth };
403fcf5ef2aSThomas Huth #endif
404fcf5ef2aSThomas Huth
sr_needed(void * opaque)405fcf5ef2aSThomas Huth static bool sr_needed(void *opaque)
406fcf5ef2aSThomas Huth {
407fcf5ef2aSThomas Huth #ifdef TARGET_PPC64
408fcf5ef2aSThomas Huth PowerPCCPU *cpu = opaque;
409fcf5ef2aSThomas Huth
410d57d72a8SGreg Kurz return !mmu_is_64bit(cpu->env.mmu_model);
411fcf5ef2aSThomas Huth #else
412fcf5ef2aSThomas Huth return true;
413fcf5ef2aSThomas Huth #endif
414fcf5ef2aSThomas Huth }
415fcf5ef2aSThomas Huth
416fcf5ef2aSThomas Huth static const VMStateDescription vmstate_sr = {
417fcf5ef2aSThomas Huth .name = "cpu/sr",
418fcf5ef2aSThomas Huth .version_id = 1,
419fcf5ef2aSThomas Huth .minimum_version_id = 1,
420fcf5ef2aSThomas Huth .needed = sr_needed,
421caae2396SRichard Henderson .fields = (const VMStateField[]) {
422fcf5ef2aSThomas Huth VMSTATE_UINTTL_ARRAY(env.sr, PowerPCCPU, 32),
423fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
424fcf5ef2aSThomas Huth },
425fcf5ef2aSThomas Huth };
426fcf5ef2aSThomas Huth
427fcf5ef2aSThomas Huth #ifdef TARGET_PPC64
get_slbe(QEMUFile * f,void * pv,size_t size,const VMStateField * field)42803fee66fSMarc-André Lureau static int get_slbe(QEMUFile *f, void *pv, size_t size,
42903fee66fSMarc-André Lureau const VMStateField *field)
430fcf5ef2aSThomas Huth {
431fcf5ef2aSThomas Huth ppc_slb_t *v = pv;
432fcf5ef2aSThomas Huth
433fcf5ef2aSThomas Huth v->esid = qemu_get_be64(f);
434fcf5ef2aSThomas Huth v->vsid = qemu_get_be64(f);
435fcf5ef2aSThomas Huth
436fcf5ef2aSThomas Huth return 0;
437fcf5ef2aSThomas Huth }
438fcf5ef2aSThomas Huth
put_slbe(QEMUFile * f,void * pv,size_t size,const VMStateField * field,JSONWriter * vmdesc)43903fee66fSMarc-André Lureau static int put_slbe(QEMUFile *f, void *pv, size_t size,
4403ddba9a9SMarkus Armbruster const VMStateField *field, JSONWriter *vmdesc)
441fcf5ef2aSThomas Huth {
442fcf5ef2aSThomas Huth ppc_slb_t *v = pv;
443fcf5ef2aSThomas Huth
444fcf5ef2aSThomas Huth qemu_put_be64(f, v->esid);
445fcf5ef2aSThomas Huth qemu_put_be64(f, v->vsid);
4462c21ee76SJianjun Duan return 0;
447fcf5ef2aSThomas Huth }
448fcf5ef2aSThomas Huth
449fcf5ef2aSThomas Huth static const VMStateInfo vmstate_info_slbe = {
450fcf5ef2aSThomas Huth .name = "slbe",
451fcf5ef2aSThomas Huth .get = get_slbe,
452fcf5ef2aSThomas Huth .put = put_slbe,
453fcf5ef2aSThomas Huth };
454fcf5ef2aSThomas Huth
455fcf5ef2aSThomas Huth #define VMSTATE_SLB_ARRAY_V(_f, _s, _n, _v) \
456fcf5ef2aSThomas Huth VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_slbe, ppc_slb_t)
457fcf5ef2aSThomas Huth
458fcf5ef2aSThomas Huth #define VMSTATE_SLB_ARRAY(_f, _s, _n) \
459fcf5ef2aSThomas Huth VMSTATE_SLB_ARRAY_V(_f, _s, _n, 0)
460fcf5ef2aSThomas Huth
slb_needed(void * opaque)461fcf5ef2aSThomas Huth static bool slb_needed(void *opaque)
462fcf5ef2aSThomas Huth {
463fcf5ef2aSThomas Huth PowerPCCPU *cpu = opaque;
464fcf5ef2aSThomas Huth
465fcf5ef2aSThomas Huth /* We don't support any of the old segment table based 64-bit CPUs */
466d57d72a8SGreg Kurz return mmu_is_64bit(cpu->env.mmu_model);
467fcf5ef2aSThomas Huth }
468fcf5ef2aSThomas Huth
slb_post_load(void * opaque,int version_id)469fcf5ef2aSThomas Huth static int slb_post_load(void *opaque, int version_id)
470fcf5ef2aSThomas Huth {
471fcf5ef2aSThomas Huth PowerPCCPU *cpu = opaque;
472fcf5ef2aSThomas Huth CPUPPCState *env = &cpu->env;
473fcf5ef2aSThomas Huth int i;
474fcf5ef2aSThomas Huth
4756f7a6993SDavid Gibson /*
4766f7a6993SDavid Gibson * We've pulled in the raw esid and vsid values from the migration
4776f7a6993SDavid Gibson * stream, but we need to recompute the page size pointers
4786f7a6993SDavid Gibson */
47967d7d66fSDavid Gibson for (i = 0; i < cpu->hash64_opts->slb_size; i++) {
480fcf5ef2aSThomas Huth if (ppc_store_slb(cpu, i, env->slb[i].esid, env->slb[i].vsid) < 0) {
481fcf5ef2aSThomas Huth /* Migration source had bad values in its SLB */
482fcf5ef2aSThomas Huth return -1;
483fcf5ef2aSThomas Huth }
484fcf5ef2aSThomas Huth }
485fcf5ef2aSThomas Huth
486fcf5ef2aSThomas Huth return 0;
487fcf5ef2aSThomas Huth }
488fcf5ef2aSThomas Huth
489fcf5ef2aSThomas Huth static const VMStateDescription vmstate_slb = {
490fcf5ef2aSThomas Huth .name = "cpu/slb",
491*c1a13064SHarsh Prateek Bora .version_id = 2,
492fcf5ef2aSThomas Huth .minimum_version_id = 1,
493fcf5ef2aSThomas Huth .needed = slb_needed,
494fcf5ef2aSThomas Huth .post_load = slb_post_load,
495caae2396SRichard Henderson .fields = (const VMStateField[]) {
496fcf5ef2aSThomas Huth VMSTATE_SLB_ARRAY(env.slb, PowerPCCPU, MAX_SLB_ENTRIES),
497fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
498fcf5ef2aSThomas Huth }
499fcf5ef2aSThomas Huth };
500fcf5ef2aSThomas Huth #endif /* TARGET_PPC64 */
501fcf5ef2aSThomas Huth
502fcf5ef2aSThomas Huth static const VMStateDescription vmstate_tlb6xx_entry = {
503fcf5ef2aSThomas Huth .name = "cpu/tlb6xx_entry",
504fcf5ef2aSThomas Huth .version_id = 1,
505fcf5ef2aSThomas Huth .minimum_version_id = 1,
506caae2396SRichard Henderson .fields = (const VMStateField[]) {
507fcf5ef2aSThomas Huth VMSTATE_UINTTL(pte0, ppc6xx_tlb_t),
508fcf5ef2aSThomas Huth VMSTATE_UINTTL(pte1, ppc6xx_tlb_t),
509fcf5ef2aSThomas Huth VMSTATE_UINTTL(EPN, ppc6xx_tlb_t),
510fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
511fcf5ef2aSThomas Huth },
512fcf5ef2aSThomas Huth };
513fcf5ef2aSThomas Huth
tlb6xx_needed(void * opaque)514fcf5ef2aSThomas Huth static bool tlb6xx_needed(void *opaque)
515fcf5ef2aSThomas Huth {
516fcf5ef2aSThomas Huth PowerPCCPU *cpu = opaque;
517fcf5ef2aSThomas Huth CPUPPCState *env = &cpu->env;
518fcf5ef2aSThomas Huth
519fcf5ef2aSThomas Huth return env->nb_tlb && (env->tlb_type == TLB_6XX);
520fcf5ef2aSThomas Huth }
521fcf5ef2aSThomas Huth
522fcf5ef2aSThomas Huth static const VMStateDescription vmstate_tlb6xx = {
523fcf5ef2aSThomas Huth .name = "cpu/tlb6xx",
524fcf5ef2aSThomas Huth .version_id = 1,
525fcf5ef2aSThomas Huth .minimum_version_id = 1,
526fcf5ef2aSThomas Huth .needed = tlb6xx_needed,
527caae2396SRichard Henderson .fields = (const VMStateField[]) {
528d2164ad3SHalil Pasic VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU, NULL),
529fcf5ef2aSThomas Huth VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlb6, PowerPCCPU,
530fcf5ef2aSThomas Huth env.nb_tlb,
531fcf5ef2aSThomas Huth vmstate_tlb6xx_entry,
532fcf5ef2aSThomas Huth ppc6xx_tlb_t),
533fcf5ef2aSThomas Huth VMSTATE_UINTTL_ARRAY(env.tgpr, PowerPCCPU, 4),
534fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
535fcf5ef2aSThomas Huth }
536fcf5ef2aSThomas Huth };
537fcf5ef2aSThomas Huth
538fcf5ef2aSThomas Huth static const VMStateDescription vmstate_tlbemb_entry = {
539fcf5ef2aSThomas Huth .name = "cpu/tlbemb_entry",
540fcf5ef2aSThomas Huth .version_id = 1,
541fcf5ef2aSThomas Huth .minimum_version_id = 1,
542caae2396SRichard Henderson .fields = (const VMStateField[]) {
543fcf5ef2aSThomas Huth VMSTATE_UINT64(RPN, ppcemb_tlb_t),
544fcf5ef2aSThomas Huth VMSTATE_UINTTL(EPN, ppcemb_tlb_t),
545fcf5ef2aSThomas Huth VMSTATE_UINTTL(PID, ppcemb_tlb_t),
546fcf5ef2aSThomas Huth VMSTATE_UINTTL(size, ppcemb_tlb_t),
547fcf5ef2aSThomas Huth VMSTATE_UINT32(prot, ppcemb_tlb_t),
548fcf5ef2aSThomas Huth VMSTATE_UINT32(attr, ppcemb_tlb_t),
549fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
550fcf5ef2aSThomas Huth },
551fcf5ef2aSThomas Huth };
552fcf5ef2aSThomas Huth
tlbemb_needed(void * opaque)553fcf5ef2aSThomas Huth static bool tlbemb_needed(void *opaque)
554fcf5ef2aSThomas Huth {
555fcf5ef2aSThomas Huth PowerPCCPU *cpu = opaque;
556fcf5ef2aSThomas Huth CPUPPCState *env = &cpu->env;
557fcf5ef2aSThomas Huth
558fcf5ef2aSThomas Huth return env->nb_tlb && (env->tlb_type == TLB_EMB);
559fcf5ef2aSThomas Huth }
560fcf5ef2aSThomas Huth
561fcf5ef2aSThomas Huth static const VMStateDescription vmstate_tlbemb = {
562203beb6fSArman Nabiev .name = "cpu/tlbemb",
563fcf5ef2aSThomas Huth .version_id = 1,
564fcf5ef2aSThomas Huth .minimum_version_id = 1,
565fcf5ef2aSThomas Huth .needed = tlbemb_needed,
566caae2396SRichard Henderson .fields = (const VMStateField[]) {
567d2164ad3SHalil Pasic VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU, NULL),
568fcf5ef2aSThomas Huth VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlbe, PowerPCCPU,
569fcf5ef2aSThomas Huth env.nb_tlb,
570fcf5ef2aSThomas Huth vmstate_tlbemb_entry,
571fcf5ef2aSThomas Huth ppcemb_tlb_t),
572fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
573fcf5ef2aSThomas Huth },
574fcf5ef2aSThomas Huth };
575fcf5ef2aSThomas Huth
576fcf5ef2aSThomas Huth static const VMStateDescription vmstate_tlbmas_entry = {
577fcf5ef2aSThomas Huth .name = "cpu/tlbmas_entry",
578fcf5ef2aSThomas Huth .version_id = 1,
579fcf5ef2aSThomas Huth .minimum_version_id = 1,
580caae2396SRichard Henderson .fields = (const VMStateField[]) {
581fcf5ef2aSThomas Huth VMSTATE_UINT32(mas8, ppcmas_tlb_t),
582fcf5ef2aSThomas Huth VMSTATE_UINT32(mas1, ppcmas_tlb_t),
583fcf5ef2aSThomas Huth VMSTATE_UINT64(mas2, ppcmas_tlb_t),
584fcf5ef2aSThomas Huth VMSTATE_UINT64(mas7_3, ppcmas_tlb_t),
585fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
586fcf5ef2aSThomas Huth },
587fcf5ef2aSThomas Huth };
588fcf5ef2aSThomas Huth
tlbmas_needed(void * opaque)589fcf5ef2aSThomas Huth static bool tlbmas_needed(void *opaque)
590fcf5ef2aSThomas Huth {
591fcf5ef2aSThomas Huth PowerPCCPU *cpu = opaque;
592fcf5ef2aSThomas Huth CPUPPCState *env = &cpu->env;
593fcf5ef2aSThomas Huth
594fcf5ef2aSThomas Huth return env->nb_tlb && (env->tlb_type == TLB_MAS);
595fcf5ef2aSThomas Huth }
596fcf5ef2aSThomas Huth
597fcf5ef2aSThomas Huth static const VMStateDescription vmstate_tlbmas = {
598fcf5ef2aSThomas Huth .name = "cpu/tlbmas",
599fcf5ef2aSThomas Huth .version_id = 1,
600fcf5ef2aSThomas Huth .minimum_version_id = 1,
601fcf5ef2aSThomas Huth .needed = tlbmas_needed,
602caae2396SRichard Henderson .fields = (const VMStateField[]) {
603d2164ad3SHalil Pasic VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU, NULL),
604fcf5ef2aSThomas Huth VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlbm, PowerPCCPU,
605fcf5ef2aSThomas Huth env.nb_tlb,
606fcf5ef2aSThomas Huth vmstate_tlbmas_entry,
607fcf5ef2aSThomas Huth ppcmas_tlb_t),
608fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
609fcf5ef2aSThomas Huth }
610fcf5ef2aSThomas Huth };
611fcf5ef2aSThomas Huth
compat_needed(void * opaque)612d5fc133eSDavid Gibson static bool compat_needed(void *opaque)
613d5fc133eSDavid Gibson {
614d5fc133eSDavid Gibson PowerPCCPU *cpu = opaque;
615d5fc133eSDavid Gibson
616d5fc133eSDavid Gibson assert(!(cpu->compat_pvr && !cpu->vhyp));
61724ee9229SHarsh Prateek Bora return cpu->compat_pvr != 0;
618d5fc133eSDavid Gibson }
619d5fc133eSDavid Gibson
620d5fc133eSDavid Gibson static const VMStateDescription vmstate_compat = {
621d5fc133eSDavid Gibson .name = "cpu/compat",
622d5fc133eSDavid Gibson .version_id = 1,
623d5fc133eSDavid Gibson .minimum_version_id = 1,
624d5fc133eSDavid Gibson .needed = compat_needed,
625caae2396SRichard Henderson .fields = (const VMStateField[]) {
626d5fc133eSDavid Gibson VMSTATE_UINT32(compat_pvr, PowerPCCPU),
627d5fc133eSDavid Gibson VMSTATE_END_OF_LIST()
628d5fc133eSDavid Gibson }
629d5fc133eSDavid Gibson };
630d5fc133eSDavid Gibson
reservation_needed(void * opaque)631cdab53ddSNicholas Piggin static bool reservation_needed(void *opaque)
632cdab53ddSNicholas Piggin {
633cdab53ddSNicholas Piggin return (replay_mode != REPLAY_MODE_NONE);
634cdab53ddSNicholas Piggin }
635cdab53ddSNicholas Piggin
636cdab53ddSNicholas Piggin static const VMStateDescription vmstate_reservation = {
637cdab53ddSNicholas Piggin .name = "cpu/reservation",
638cdab53ddSNicholas Piggin .version_id = 1,
639cdab53ddSNicholas Piggin .minimum_version_id = 1,
640cdab53ddSNicholas Piggin .needed = reservation_needed,
641caae2396SRichard Henderson .fields = (const VMStateField[]) {
642cdab53ddSNicholas Piggin VMSTATE_UINTTL(env.reserve_addr, PowerPCCPU),
643cdab53ddSNicholas Piggin VMSTATE_UINTTL(env.reserve_length, PowerPCCPU),
644cdab53ddSNicholas Piggin VMSTATE_UINTTL(env.reserve_val, PowerPCCPU),
645cdab53ddSNicholas Piggin #if defined(TARGET_PPC64)
646cdab53ddSNicholas Piggin VMSTATE_UINTTL(env.reserve_val2, PowerPCCPU),
647cdab53ddSNicholas Piggin #endif
648cdab53ddSNicholas Piggin VMSTATE_END_OF_LIST()
649cdab53ddSNicholas Piggin }
650cdab53ddSNicholas Piggin };
651cdab53ddSNicholas Piggin
652dabd6d3cSGlenn Miles #ifdef TARGET_PPC64
bhrb_needed(void * opaque)653dabd6d3cSGlenn Miles static bool bhrb_needed(void *opaque)
654dabd6d3cSGlenn Miles {
655dabd6d3cSGlenn Miles PowerPCCPU *cpu = opaque;
656dabd6d3cSGlenn Miles return (cpu->env.flags & POWERPC_FLAG_BHRB) != 0;
657dabd6d3cSGlenn Miles }
658dabd6d3cSGlenn Miles
659dabd6d3cSGlenn Miles static const VMStateDescription vmstate_bhrb = {
660dabd6d3cSGlenn Miles .name = "cpu/bhrb",
661dabd6d3cSGlenn Miles .version_id = 1,
662dabd6d3cSGlenn Miles .minimum_version_id = 1,
663dabd6d3cSGlenn Miles .needed = bhrb_needed,
664dabd6d3cSGlenn Miles .fields = (VMStateField[]) {
665dabd6d3cSGlenn Miles VMSTATE_UINTTL(env.bhrb_offset, PowerPCCPU),
666dabd6d3cSGlenn Miles VMSTATE_UINT64_ARRAY(env.bhrb, PowerPCCPU, BHRB_MAX_NUM_ENTRIES),
667dabd6d3cSGlenn Miles VMSTATE_END_OF_LIST()
668dabd6d3cSGlenn Miles }
669dabd6d3cSGlenn Miles };
670dabd6d3cSGlenn Miles #endif
671dabd6d3cSGlenn Miles
672fcf5ef2aSThomas Huth const VMStateDescription vmstate_ppc_cpu = {
673fcf5ef2aSThomas Huth .name = "cpu",
674fcf5ef2aSThomas Huth .version_id = 5,
675fcf5ef2aSThomas Huth .minimum_version_id = 5,
676fcf5ef2aSThomas Huth .pre_save = cpu_pre_save,
677fcf5ef2aSThomas Huth .post_load = cpu_post_load,
678caae2396SRichard Henderson .fields = (const VMStateField[]) {
679fcf5ef2aSThomas Huth VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.spr[SPR_PVR]) */
680fcf5ef2aSThomas Huth
681fcf5ef2aSThomas Huth /* User mode architected state */
682fcf5ef2aSThomas Huth VMSTATE_UINTTL_ARRAY(env.gpr, PowerPCCPU, 32),
683fcf5ef2aSThomas Huth #if !defined(TARGET_PPC64)
684fcf5ef2aSThomas Huth VMSTATE_UINTTL_ARRAY(env.gprh, PowerPCCPU, 32),
685fcf5ef2aSThomas Huth #endif
686fcf5ef2aSThomas Huth VMSTATE_UINT32_ARRAY(env.crf, PowerPCCPU, 8),
687fcf5ef2aSThomas Huth VMSTATE_UINTTL(env.nip, PowerPCCPU),
688fcf5ef2aSThomas Huth
689fcf5ef2aSThomas Huth /* SPRs */
690fcf5ef2aSThomas Huth VMSTATE_UINTTL_ARRAY(env.spr, PowerPCCPU, 1024),
691fcf5ef2aSThomas Huth VMSTATE_UINT64(env.spe_acc, PowerPCCPU),
692fcf5ef2aSThomas Huth
693cdab53ddSNicholas Piggin VMSTATE_UNUSED(sizeof(target_ulong)), /* was env.reserve_addr */
694fcf5ef2aSThomas Huth
695fcf5ef2aSThomas Huth /* Supervisor mode architected state */
696fcf5ef2aSThomas Huth VMSTATE_UINTTL(env.msr, PowerPCCPU),
697fcf5ef2aSThomas Huth
698f7a7b652SRichard Henderson /* Backward compatible internal state */
699f7a7b652SRichard Henderson VMSTATE_UINTTL(env.hflags_compat_nmsr, PowerPCCPU),
700fcf5ef2aSThomas Huth
701fcf5ef2aSThomas Huth VMSTATE_END_OF_LIST()
702fcf5ef2aSThomas Huth },
703caae2396SRichard Henderson .subsections = (const VMStateDescription * const []) {
704fcf5ef2aSThomas Huth &vmstate_fpu,
705fcf5ef2aSThomas Huth &vmstate_altivec,
706fcf5ef2aSThomas Huth &vmstate_vsx,
707fcf5ef2aSThomas Huth &vmstate_sr,
708fcf5ef2aSThomas Huth #ifdef TARGET_PPC64
709fcf5ef2aSThomas Huth &vmstate_tm,
710fcf5ef2aSThomas Huth &vmstate_slb,
711dabd6d3cSGlenn Miles &vmstate_bhrb,
712fcf5ef2aSThomas Huth #endif /* TARGET_PPC64 */
713fcf5ef2aSThomas Huth &vmstate_tlb6xx,
714fcf5ef2aSThomas Huth &vmstate_tlbemb,
715fcf5ef2aSThomas Huth &vmstate_tlbmas,
716d5fc133eSDavid Gibson &vmstate_compat,
717cdab53ddSNicholas Piggin &vmstate_reservation,
718fcf5ef2aSThomas Huth NULL
719fcf5ef2aSThomas Huth }
720fcf5ef2aSThomas Huth };
721