xref: /qemu/target/ppc/machine.c (revision d5ee641cfc5c3cbd51282d0c6e996f990b9d62a3)
10d75590dSPeter Maydell #include "qemu/osdep.h"
233c11879SPaolo Bonzini #include "cpu.h"
363c91552SPaolo Bonzini #include "exec/exec-all.h"
49c17d615SPaolo Bonzini #include "sysemu/kvm.h"
533edcde7SDaniel Henrique Barboza #include "sysemu/tcg.h"
6a90db158SAlexey Kardashevskiy #include "helper_regs.h"
7cd6a9bb6SDavid Gibson #include "mmu-hash64.h"
81e00b8d5SPaolo Bonzini #include "migration/cpu.h"
9d5fc133eSDavid Gibson #include "qapi/error.h"
10c363a37aSDaniel Henrique Barboza #include "kvm_ppc.h"
116e8b9903SRichard Henderson #include "power8-pmu.h"
128dd3dca3Saurel32 
13edece45dSRichard Henderson static void post_load_update_msr(CPUPPCState *env)
14edece45dSRichard Henderson {
15edece45dSRichard Henderson     target_ulong msr = env->msr;
16edece45dSRichard Henderson 
17edece45dSRichard Henderson     /*
18edece45dSRichard Henderson      * Invalidate all supported msr bits except MSR_TGPR/MSR_HVB
19d764184dSRichard Henderson      * before restoring.  Note that this recomputes hflags.
20edece45dSRichard Henderson      */
21edece45dSRichard Henderson     env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB);
22edece45dSRichard Henderson     ppc_store_msr(env, msr);
2333edcde7SDaniel Henrique Barboza }
24edece45dSRichard Henderson 
2503fee66fSMarc-André Lureau static int get_avr(QEMUFile *f, void *pv, size_t size,
2603fee66fSMarc-André Lureau                    const VMStateField *field)
27a90db158SAlexey Kardashevskiy {
28a90db158SAlexey Kardashevskiy     ppc_avr_t *v = pv;
29a90db158SAlexey Kardashevskiy 
30a90db158SAlexey Kardashevskiy     v->u64[0] = qemu_get_be64(f);
31a90db158SAlexey Kardashevskiy     v->u64[1] = qemu_get_be64(f);
32a90db158SAlexey Kardashevskiy 
33a90db158SAlexey Kardashevskiy     return 0;
34a90db158SAlexey Kardashevskiy }
35a90db158SAlexey Kardashevskiy 
3603fee66fSMarc-André Lureau static int put_avr(QEMUFile *f, void *pv, size_t size,
373ddba9a9SMarkus Armbruster                    const VMStateField *field, JSONWriter *vmdesc)
38a90db158SAlexey Kardashevskiy {
39a90db158SAlexey Kardashevskiy     ppc_avr_t *v = pv;
40a90db158SAlexey Kardashevskiy 
41a90db158SAlexey Kardashevskiy     qemu_put_be64(f, v->u64[0]);
42a90db158SAlexey Kardashevskiy     qemu_put_be64(f, v->u64[1]);
432c21ee76SJianjun Duan     return 0;
44a90db158SAlexey Kardashevskiy }
45a90db158SAlexey Kardashevskiy 
46cfd54a04SStefan Weil static const VMStateInfo vmstate_info_avr = {
47a90db158SAlexey Kardashevskiy     .name = "avr",
48a90db158SAlexey Kardashevskiy     .get  = get_avr,
49a90db158SAlexey Kardashevskiy     .put  = put_avr,
50a90db158SAlexey Kardashevskiy };
51a90db158SAlexey Kardashevskiy 
52a90db158SAlexey Kardashevskiy #define VMSTATE_AVR_ARRAY_V(_f, _s, _n, _v)                       \
53ef96e3aeSMark Cave-Ayland     VMSTATE_SUB_ARRAY(_f, _s, 32, _n, _v, vmstate_info_avr, ppc_avr_t)
54a90db158SAlexey Kardashevskiy 
55a90db158SAlexey Kardashevskiy #define VMSTATE_AVR_ARRAY(_f, _s, _n)                             \
56a90db158SAlexey Kardashevskiy     VMSTATE_AVR_ARRAY_V(_f, _s, _n, 0)
57a90db158SAlexey Kardashevskiy 
58ef96e3aeSMark Cave-Ayland static int get_fpr(QEMUFile *f, void *pv, size_t size,
59ef96e3aeSMark Cave-Ayland                    const VMStateField *field)
60ef96e3aeSMark Cave-Ayland {
61ef96e3aeSMark Cave-Ayland     ppc_vsr_t *v = pv;
62ef96e3aeSMark Cave-Ayland 
638a14d31bSMark Cave-Ayland     v->VsrD(0) = qemu_get_be64(f);
64ef96e3aeSMark Cave-Ayland 
65ef96e3aeSMark Cave-Ayland     return 0;
66ef96e3aeSMark Cave-Ayland }
67ef96e3aeSMark Cave-Ayland 
68ef96e3aeSMark Cave-Ayland static int put_fpr(QEMUFile *f, void *pv, size_t size,
693ddba9a9SMarkus Armbruster                    const VMStateField *field, JSONWriter *vmdesc)
70ef96e3aeSMark Cave-Ayland {
71ef96e3aeSMark Cave-Ayland     ppc_vsr_t *v = pv;
72ef96e3aeSMark Cave-Ayland 
738a14d31bSMark Cave-Ayland     qemu_put_be64(f, v->VsrD(0));
74ef96e3aeSMark Cave-Ayland     return 0;
75ef96e3aeSMark Cave-Ayland }
76ef96e3aeSMark Cave-Ayland 
77ef96e3aeSMark Cave-Ayland static const VMStateInfo vmstate_info_fpr = {
78ef96e3aeSMark Cave-Ayland     .name = "fpr",
79ef96e3aeSMark Cave-Ayland     .get  = get_fpr,
80ef96e3aeSMark Cave-Ayland     .put  = put_fpr,
81ef96e3aeSMark Cave-Ayland };
82ef96e3aeSMark Cave-Ayland 
83ef96e3aeSMark Cave-Ayland #define VMSTATE_FPR_ARRAY_V(_f, _s, _n, _v)                       \
84ef96e3aeSMark Cave-Ayland     VMSTATE_SUB_ARRAY(_f, _s, 0, _n, _v, vmstate_info_fpr, ppc_vsr_t)
85ef96e3aeSMark Cave-Ayland 
86ef96e3aeSMark Cave-Ayland #define VMSTATE_FPR_ARRAY(_f, _s, _n)                             \
87ef96e3aeSMark Cave-Ayland     VMSTATE_FPR_ARRAY_V(_f, _s, _n, 0)
88ef96e3aeSMark Cave-Ayland 
89ef96e3aeSMark Cave-Ayland static int get_vsr(QEMUFile *f, void *pv, size_t size,
90ef96e3aeSMark Cave-Ayland                    const VMStateField *field)
91ef96e3aeSMark Cave-Ayland {
92ef96e3aeSMark Cave-Ayland     ppc_vsr_t *v = pv;
93ef96e3aeSMark Cave-Ayland 
948a14d31bSMark Cave-Ayland     v->VsrD(1) = qemu_get_be64(f);
95ef96e3aeSMark Cave-Ayland 
96ef96e3aeSMark Cave-Ayland     return 0;
97ef96e3aeSMark Cave-Ayland }
98ef96e3aeSMark Cave-Ayland 
99ef96e3aeSMark Cave-Ayland static int put_vsr(QEMUFile *f, void *pv, size_t size,
1003ddba9a9SMarkus Armbruster                    const VMStateField *field, JSONWriter *vmdesc)
101ef96e3aeSMark Cave-Ayland {
102ef96e3aeSMark Cave-Ayland     ppc_vsr_t *v = pv;
103ef96e3aeSMark Cave-Ayland 
1048a14d31bSMark Cave-Ayland     qemu_put_be64(f, v->VsrD(1));
105ef96e3aeSMark Cave-Ayland     return 0;
106ef96e3aeSMark Cave-Ayland }
107ef96e3aeSMark Cave-Ayland 
108ef96e3aeSMark Cave-Ayland static const VMStateInfo vmstate_info_vsr = {
109ef96e3aeSMark Cave-Ayland     .name = "vsr",
110ef96e3aeSMark Cave-Ayland     .get  = get_vsr,
111ef96e3aeSMark Cave-Ayland     .put  = put_vsr,
112ef96e3aeSMark Cave-Ayland };
113ef96e3aeSMark Cave-Ayland 
114ef96e3aeSMark Cave-Ayland #define VMSTATE_VSR_ARRAY_V(_f, _s, _n, _v)                       \
115ef96e3aeSMark Cave-Ayland     VMSTATE_SUB_ARRAY(_f, _s, 0, _n, _v, vmstate_info_vsr, ppc_vsr_t)
116ef96e3aeSMark Cave-Ayland 
117ef96e3aeSMark Cave-Ayland #define VMSTATE_VSR_ARRAY(_f, _s, _n)                             \
118ef96e3aeSMark Cave-Ayland     VMSTATE_VSR_ARRAY_V(_f, _s, _n, 0)
119ef96e3aeSMark Cave-Ayland 
120146c11f1SDavid Gibson static bool cpu_pre_2_8_migration(void *opaque, int version_id)
121146c11f1SDavid Gibson {
122146c11f1SDavid Gibson     PowerPCCPU *cpu = opaque;
123146c11f1SDavid Gibson 
124146c11f1SDavid Gibson     return cpu->pre_2_8_migration;
125146c11f1SDavid Gibson }
126146c11f1SDavid Gibson 
12767d7d66fSDavid Gibson #if defined(TARGET_PPC64)
128d8c0c7afSPeter Maydell static bool cpu_pre_3_0_migration(void *opaque, int version_id)
12967d7d66fSDavid Gibson {
13067d7d66fSDavid Gibson     PowerPCCPU *cpu = opaque;
13167d7d66fSDavid Gibson 
132d8c0c7afSPeter Maydell     return cpu->pre_3_0_migration;
13367d7d66fSDavid Gibson }
13467d7d66fSDavid Gibson #endif
13567d7d66fSDavid Gibson 
13644b1ff31SDr. David Alan Gilbert static int cpu_pre_save(void *opaque)
137a90db158SAlexey Kardashevskiy {
138a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
139a90db158SAlexey Kardashevskiy     CPUPPCState *env = &cpu->env;
140a90db158SAlexey Kardashevskiy     int i;
14116a2497bSDavid Gibson     uint64_t insns_compat_mask =
14216a2497bSDavid Gibson         PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB
14316a2497bSDavid Gibson         | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES
14416a2497bSDavid Gibson         | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES
14516a2497bSDavid Gibson         | PPC_FLOAT_STFIWX | PPC_FLOAT_EXT
14616a2497bSDavid Gibson         | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ
14716a2497bSDavid Gibson         | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC
14816a2497bSDavid Gibson         | PPC_64B | PPC_64BX | PPC_ALTIVEC
14916a2497bSDavid Gibson         | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD;
15016a2497bSDavid Gibson     uint64_t insns_compat_mask2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX
15116a2497bSDavid Gibson         | PPC2_PERM_ISA206 | PPC2_DIVE_ISA206
15216a2497bSDavid Gibson         | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206
15316a2497bSDavid Gibson         | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207
15416a2497bSDavid Gibson         | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207
15503abfd90SNicholas Piggin         | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM
15603abfd90SNicholas Piggin         | PPC2_MEM_LWSYNC;
157a90db158SAlexey Kardashevskiy 
158a90db158SAlexey Kardashevskiy     env->spr[SPR_LR] = env->lr;
159a90db158SAlexey Kardashevskiy     env->spr[SPR_CTR] = env->ctr;
160aa378598SThomas Huth     env->spr[SPR_XER] = cpu_read_xer(env);
161a90db158SAlexey Kardashevskiy #if defined(TARGET_PPC64)
162a90db158SAlexey Kardashevskiy     env->spr[SPR_CFAR] = env->cfar;
163a90db158SAlexey Kardashevskiy #endif
164a90db158SAlexey Kardashevskiy     env->spr[SPR_BOOKE_SPEFSCR] = env->spe_fscr;
165a90db158SAlexey Kardashevskiy 
166a90db158SAlexey Kardashevskiy     for (i = 0; (i < 4) && (i < env->nb_BATs); i++) {
167a90db158SAlexey Kardashevskiy         env->spr[SPR_DBAT0U + 2 * i] = env->DBAT[0][i];
168a90db158SAlexey Kardashevskiy         env->spr[SPR_DBAT0U + 2 * i + 1] = env->DBAT[1][i];
169a90db158SAlexey Kardashevskiy         env->spr[SPR_IBAT0U + 2 * i] = env->IBAT[0][i];
170a90db158SAlexey Kardashevskiy         env->spr[SPR_IBAT0U + 2 * i + 1] = env->IBAT[1][i];
171a90db158SAlexey Kardashevskiy     }
172a90db158SAlexey Kardashevskiy     for (i = 0; (i < 4) && ((i + 4) < env->nb_BATs); i++) {
173a90db158SAlexey Kardashevskiy         env->spr[SPR_DBAT4U + 2 * i] = env->DBAT[0][i + 4];
174a90db158SAlexey Kardashevskiy         env->spr[SPR_DBAT4U + 2 * i + 1] = env->DBAT[1][i + 4];
175a90db158SAlexey Kardashevskiy         env->spr[SPR_IBAT4U + 2 * i] = env->IBAT[0][i + 4];
176a90db158SAlexey Kardashevskiy         env->spr[SPR_IBAT4U + 2 * i + 1] = env->IBAT[1][i + 4];
177a90db158SAlexey Kardashevskiy     }
17816a2497bSDavid Gibson 
17916a2497bSDavid Gibson     /* Hacks for migration compatibility between 2.6, 2.7 & 2.8 */
180146c11f1SDavid Gibson     if (cpu->pre_2_8_migration) {
1816f7a6993SDavid Gibson         /*
1826f7a6993SDavid Gibson          * Mask out bits that got added to msr_mask since the versions
1836f7a6993SDavid Gibson          * which stupidly included it in the migration stream.
1846f7a6993SDavid Gibson          */
185efb7db25SDavid Gibson         target_ulong metamask = 0
186efb7db25SDavid Gibson #if defined(TARGET_PPC64)
187efb7db25SDavid Gibson             | (1ULL << MSR_TS0)
188efb7db25SDavid Gibson             | (1ULL << MSR_TS1)
189efb7db25SDavid Gibson #endif
190efb7db25SDavid Gibson             ;
191efb7db25SDavid Gibson         cpu->mig_msr_mask = env->msr_mask & ~metamask;
19216a2497bSDavid Gibson         cpu->mig_insns_flags = env->insns_flags & insns_compat_mask;
1936f7a6993SDavid Gibson         /*
1946f7a6993SDavid Gibson          * CPU models supported by old machines all have
1956f7a6993SDavid Gibson          * PPC_MEM_TLBIE, so we set it unconditionally to allow
1966f7a6993SDavid Gibson          * backward migration from a POWER9 host to a POWER8 host.
197bce00964SGreg Kurz          */
198bce00964SGreg Kurz         cpu->mig_insns_flags |= PPC_MEM_TLBIE;
19916a2497bSDavid Gibson         cpu->mig_insns_flags2 = env->insns_flags2 & insns_compat_mask2;
20016a2497bSDavid Gibson         cpu->mig_nb_BATs = env->nb_BATs;
201a90db158SAlexey Kardashevskiy     }
202d8c0c7afSPeter Maydell     if (cpu->pre_3_0_migration) {
20367d7d66fSDavid Gibson         if (cpu->hash64_opts) {
20467d7d66fSDavid Gibson             cpu->mig_slb_nr = cpu->hash64_opts->slb_size;
20567d7d66fSDavid Gibson         }
20667d7d66fSDavid Gibson     }
20744b1ff31SDr. David Alan Gilbert 
208005b69fdSCédric Le Goater     /* Used to retain migration compatibility for pre 6.0 for 601 machines. */
209005b69fdSCédric Le Goater     env->hflags_compat_nmsr = 0;
210f7a7b652SRichard Henderson 
21144b1ff31SDr. David Alan Gilbert     return 0;
212146c11f1SDavid Gibson }
213a90db158SAlexey Kardashevskiy 
214d5fc133eSDavid Gibson /*
215d5fc133eSDavid Gibson  * Determine if a given PVR is a "close enough" match to the CPU
216d5fc133eSDavid Gibson  * object.  For TCG and KVM PR it would probably be sufficient to
217d5fc133eSDavid Gibson  * require an exact PVR match.  However for KVM HV the user is
218d5fc133eSDavid Gibson  * restricted to a PVR exactly matching the host CPU.  The correct way
219d5fc133eSDavid Gibson  * to handle this is to put the guest into an architected
220d5fc133eSDavid Gibson  * compatibility mode.  However, to allow a more forgiving transition
221d5fc133eSDavid Gibson  * and migration from before this was widely done, we allow migration
222d5fc133eSDavid Gibson  * between sufficiently similar PVRs, as determined by the CPU class's
223d5fc133eSDavid Gibson  * pvr_match() hook.
224d5fc133eSDavid Gibson  */
225d5fc133eSDavid Gibson static bool pvr_match(PowerPCCPU *cpu, uint32_t pvr)
226d5fc133eSDavid Gibson {
227d5fc133eSDavid Gibson     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
228d5fc133eSDavid Gibson 
229d5fc133eSDavid Gibson     if (pvr == pcc->pvr) {
230d5fc133eSDavid Gibson         return true;
231d5fc133eSDavid Gibson     }
23221d3a78eSNicholas Piggin     return pcc->pvr_match(pcc, pvr, true);
233d5fc133eSDavid Gibson }
234d5fc133eSDavid Gibson 
235a90db158SAlexey Kardashevskiy static int cpu_post_load(void *opaque, int version_id)
236a90db158SAlexey Kardashevskiy {
237a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
238a90db158SAlexey Kardashevskiy     CPUPPCState *env = &cpu->env;
239a90db158SAlexey Kardashevskiy     int i;
240a90db158SAlexey Kardashevskiy 
241569be9f0SAlexey Kardashevskiy     /*
242d5fc133eSDavid Gibson      * If we're operating in compat mode, we should be ok as long as
243136fbf65Szhaolichang      * the destination supports the same compatibility mode.
244d5fc133eSDavid Gibson      *
245d5fc133eSDavid Gibson      * Otherwise, however, we require that the destination has exactly
246d5fc133eSDavid Gibson      * the same CPU model as the source.
247569be9f0SAlexey Kardashevskiy      */
248d5fc133eSDavid Gibson 
249d5fc133eSDavid Gibson #if defined(TARGET_PPC64)
250d5fc133eSDavid Gibson     if (cpu->compat_pvr) {
251e07cc192SSuraj Jitindar Singh         uint32_t compat_pvr = cpu->compat_pvr;
252d5fc133eSDavid Gibson         Error *local_err = NULL;
253899134ebSGreg Kurz         int ret;
254d5fc133eSDavid Gibson 
255e07cc192SSuraj Jitindar Singh         cpu->compat_pvr = 0;
256899134ebSGreg Kurz         ret = ppc_set_compat(cpu, compat_pvr, &local_err);
257899134ebSGreg Kurz         if (ret < 0) {
258d5fc133eSDavid Gibson             error_report_err(local_err);
259899134ebSGreg Kurz             return ret;
260d5fc133eSDavid Gibson         }
261d5fc133eSDavid Gibson     } else
262d5fc133eSDavid Gibson #endif
263d5fc133eSDavid Gibson     {
264d5fc133eSDavid Gibson         if (!pvr_match(cpu, env->spr[SPR_PVR])) {
265899134ebSGreg Kurz             return -EINVAL;
266d5fc133eSDavid Gibson         }
267d5fc133eSDavid Gibson     }
268d5fc133eSDavid Gibson 
269c363a37aSDaniel Henrique Barboza     /*
270c363a37aSDaniel Henrique Barboza      * If we're running with KVM HV, there is a chance that the guest
271c363a37aSDaniel Henrique Barboza      * is running with KVM HV and its kernel does not have the
272c363a37aSDaniel Henrique Barboza      * capability of dealing with a different PVR other than this
273c363a37aSDaniel Henrique Barboza      * exact host PVR in KVM_SET_SREGS. If that happens, the
274c363a37aSDaniel Henrique Barboza      * guest freezes after migration.
275c363a37aSDaniel Henrique Barboza      *
276c363a37aSDaniel Henrique Barboza      * The function kvmppc_pvr_workaround_required does this verification
277c363a37aSDaniel Henrique Barboza      * by first checking if the kernel has the cap, returning true immediately
278c363a37aSDaniel Henrique Barboza      * if that is the case. Otherwise, it checks if we're running in KVM PR.
279c363a37aSDaniel Henrique Barboza      * If the guest kernel does not have the cap and we're not running KVM-PR
280c363a37aSDaniel Henrique Barboza      * (so, it is running KVM-HV), we need to ensure that KVM_SET_SREGS will
281c363a37aSDaniel Henrique Barboza      * receive the PVR it expects as a workaround.
282c363a37aSDaniel Henrique Barboza      *
283c363a37aSDaniel Henrique Barboza      */
284c363a37aSDaniel Henrique Barboza     if (kvmppc_pvr_workaround_required(cpu)) {
285c363a37aSDaniel Henrique Barboza         env->spr[SPR_PVR] = env->spr_cb[SPR_PVR].default_value;
286c363a37aSDaniel Henrique Barboza     }
287c363a37aSDaniel Henrique Barboza 
288a90db158SAlexey Kardashevskiy     env->lr = env->spr[SPR_LR];
289a90db158SAlexey Kardashevskiy     env->ctr = env->spr[SPR_CTR];
2906a9620e6SMark Cave-Ayland     cpu_write_xer(env, env->spr[SPR_XER]);
291a90db158SAlexey Kardashevskiy #if defined(TARGET_PPC64)
292a90db158SAlexey Kardashevskiy     env->cfar = env->spr[SPR_CFAR];
293a90db158SAlexey Kardashevskiy #endif
294a90db158SAlexey Kardashevskiy     env->spe_fscr = env->spr[SPR_BOOKE_SPEFSCR];
295a90db158SAlexey Kardashevskiy 
296a90db158SAlexey Kardashevskiy     for (i = 0; (i < 4) && (i < env->nb_BATs); i++) {
297a90db158SAlexey Kardashevskiy         env->DBAT[0][i] = env->spr[SPR_DBAT0U + 2 * i];
298a90db158SAlexey Kardashevskiy         env->DBAT[1][i] = env->spr[SPR_DBAT0U + 2 * i + 1];
299a90db158SAlexey Kardashevskiy         env->IBAT[0][i] = env->spr[SPR_IBAT0U + 2 * i];
300a90db158SAlexey Kardashevskiy         env->IBAT[1][i] = env->spr[SPR_IBAT0U + 2 * i + 1];
301a90db158SAlexey Kardashevskiy     }
302a90db158SAlexey Kardashevskiy     for (i = 0; (i < 4) && ((i + 4) < env->nb_BATs); i++) {
303a90db158SAlexey Kardashevskiy         env->DBAT[0][i + 4] = env->spr[SPR_DBAT4U + 2 * i];
304a90db158SAlexey Kardashevskiy         env->DBAT[1][i + 4] = env->spr[SPR_DBAT4U + 2 * i + 1];
305a90db158SAlexey Kardashevskiy         env->IBAT[0][i + 4] = env->spr[SPR_IBAT4U + 2 * i];
306a90db158SAlexey Kardashevskiy         env->IBAT[1][i + 4] = env->spr[SPR_IBAT4U + 2 * i + 1];
307a90db158SAlexey Kardashevskiy     }
308a90db158SAlexey Kardashevskiy 
309e57ca75cSDavid Gibson     if (!cpu->vhyp) {
310a90db158SAlexey Kardashevskiy         ppc_store_sdr1(env, env->spr[SPR_SDR1]);
311f3c75d42SAneesh Kumar K.V     }
3122360b6e8SMark Cave-Ayland 
313edece45dSRichard Henderson     post_load_update_msr(env);
3142360b6e8SMark Cave-Ayland 
3156494d2c1SNicholas Piggin     if (tcg_enabled()) {
31614192307SNicholas Piggin         /* Re-set breaks based on regs */
31714192307SNicholas Piggin #if defined(TARGET_PPC64)
31814192307SNicholas Piggin         ppc_update_ciabr(env);
319*d5ee641cSNicholas Piggin         ppc_update_daw0(env);
32014192307SNicholas Piggin #endif
3216494d2c1SNicholas Piggin         pmu_mmcr01_updated(env);
3226494d2c1SNicholas Piggin     }
3236494d2c1SNicholas Piggin 
324a90db158SAlexey Kardashevskiy     return 0;
325a90db158SAlexey Kardashevskiy }
326a90db158SAlexey Kardashevskiy 
327a90db158SAlexey Kardashevskiy static bool fpu_needed(void *opaque)
328a90db158SAlexey Kardashevskiy {
329a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
330a90db158SAlexey Kardashevskiy 
3316f7a6993SDavid Gibson     return cpu->env.insns_flags & PPC_FLOAT;
332a90db158SAlexey Kardashevskiy }
333a90db158SAlexey Kardashevskiy 
334a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_fpu = {
335a90db158SAlexey Kardashevskiy     .name = "cpu/fpu",
336a90db158SAlexey Kardashevskiy     .version_id = 1,
337a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
3385cd8cadaSJuan Quintela     .needed = fpu_needed,
339a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
340ef96e3aeSMark Cave-Ayland         VMSTATE_FPR_ARRAY(env.vsr, PowerPCCPU, 32),
341a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(env.fpscr, PowerPCCPU),
342a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
343a90db158SAlexey Kardashevskiy     },
344a90db158SAlexey Kardashevskiy };
345a90db158SAlexey Kardashevskiy 
346a90db158SAlexey Kardashevskiy static bool altivec_needed(void *opaque)
347a90db158SAlexey Kardashevskiy {
348a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
349a90db158SAlexey Kardashevskiy 
3506f7a6993SDavid Gibson     return cpu->env.insns_flags & PPC_ALTIVEC;
351a90db158SAlexey Kardashevskiy }
352a90db158SAlexey Kardashevskiy 
353596fff20SRichard Henderson static int get_vscr(QEMUFile *f, void *opaque, size_t size,
354596fff20SRichard Henderson                     const VMStateField *field)
355596fff20SRichard Henderson {
356596fff20SRichard Henderson     PowerPCCPU *cpu = opaque;
35787aff238SBruno Larsen (billionai)     ppc_store_vscr(&cpu->env, qemu_get_be32(f));
358596fff20SRichard Henderson     return 0;
359596fff20SRichard Henderson }
360596fff20SRichard Henderson 
361596fff20SRichard Henderson static int put_vscr(QEMUFile *f, void *opaque, size_t size,
3623ddba9a9SMarkus Armbruster                     const VMStateField *field, JSONWriter *vmdesc)
363596fff20SRichard Henderson {
364596fff20SRichard Henderson     PowerPCCPU *cpu = opaque;
36587aff238SBruno Larsen (billionai)     qemu_put_be32(f, ppc_get_vscr(&cpu->env));
366596fff20SRichard Henderson     return 0;
367596fff20SRichard Henderson }
368596fff20SRichard Henderson 
369596fff20SRichard Henderson static const VMStateInfo vmstate_vscr = {
370596fff20SRichard Henderson     .name = "cpu/altivec/vscr",
371596fff20SRichard Henderson     .get = get_vscr,
372596fff20SRichard Henderson     .put = put_vscr,
373596fff20SRichard Henderson };
374596fff20SRichard Henderson 
375a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_altivec = {
376a90db158SAlexey Kardashevskiy     .name = "cpu/altivec",
377a90db158SAlexey Kardashevskiy     .version_id = 1,
378a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
3795cd8cadaSJuan Quintela     .needed = altivec_needed,
380a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
381ef96e3aeSMark Cave-Ayland         VMSTATE_AVR_ARRAY(env.vsr, PowerPCCPU, 32),
382596fff20SRichard Henderson         /*
383596fff20SRichard Henderson          * Save the architecture value of the vscr, not the internally
384596fff20SRichard Henderson          * expanded version.  Since this architecture value does not
385596fff20SRichard Henderson          * exist in memory to be stored, this requires a but of hoop
386596fff20SRichard Henderson          * jumping.  We want OFFSET=0 so that we effectively pass CPU
387596fff20SRichard Henderson          * to the helper functions.
388596fff20SRichard Henderson          */
389596fff20SRichard Henderson         {
390596fff20SRichard Henderson             .name = "vscr",
391596fff20SRichard Henderson             .version_id = 0,
392596fff20SRichard Henderson             .size = sizeof(uint32_t),
393596fff20SRichard Henderson             .info = &vmstate_vscr,
394596fff20SRichard Henderson             .flags = VMS_SINGLE,
395596fff20SRichard Henderson             .offset = 0
396596fff20SRichard Henderson         },
397a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
398a90db158SAlexey Kardashevskiy     },
399a90db158SAlexey Kardashevskiy };
400a90db158SAlexey Kardashevskiy 
401a90db158SAlexey Kardashevskiy static bool vsx_needed(void *opaque)
402a90db158SAlexey Kardashevskiy {
403a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
404a90db158SAlexey Kardashevskiy 
4056f7a6993SDavid Gibson     return cpu->env.insns_flags2 & PPC2_VSX;
406a90db158SAlexey Kardashevskiy }
407a90db158SAlexey Kardashevskiy 
408a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_vsx = {
409a90db158SAlexey Kardashevskiy     .name = "cpu/vsx",
410a90db158SAlexey Kardashevskiy     .version_id = 1,
411a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
4125cd8cadaSJuan Quintela     .needed = vsx_needed,
413a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
414ef96e3aeSMark Cave-Ayland         VMSTATE_VSR_ARRAY(env.vsr, PowerPCCPU, 32),
415a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
416a90db158SAlexey Kardashevskiy     },
417a90db158SAlexey Kardashevskiy };
418a90db158SAlexey Kardashevskiy 
41980b3f79bSAlexey Kardashevskiy #ifdef TARGET_PPC64
42080b3f79bSAlexey Kardashevskiy /* Transactional memory state */
42180b3f79bSAlexey Kardashevskiy static bool tm_needed(void *opaque)
42280b3f79bSAlexey Kardashevskiy {
42380b3f79bSAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
42480b3f79bSAlexey Kardashevskiy     CPUPPCState *env = &cpu->env;
425ca241959SVíctor Colombo     return FIELD_EX64(env->msr, MSR, TS);
42680b3f79bSAlexey Kardashevskiy }
42780b3f79bSAlexey Kardashevskiy 
42880b3f79bSAlexey Kardashevskiy static const VMStateDescription vmstate_tm = {
42980b3f79bSAlexey Kardashevskiy     .name = "cpu/tm",
43080b3f79bSAlexey Kardashevskiy     .version_id = 1,
43180b3f79bSAlexey Kardashevskiy     .minimum_version_id = 1,
4325cd8cadaSJuan Quintela     .needed = tm_needed,
43380b3f79bSAlexey Kardashevskiy     .fields      = (VMStateField []) {
43480b3f79bSAlexey Kardashevskiy         VMSTATE_UINTTL_ARRAY(env.tm_gpr, PowerPCCPU, 32),
43580b3f79bSAlexey Kardashevskiy         VMSTATE_AVR_ARRAY(env.tm_vsr, PowerPCCPU, 64),
43680b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_cr, PowerPCCPU),
43780b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_lr, PowerPCCPU),
43880b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_ctr, PowerPCCPU),
43980b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_fpscr, PowerPCCPU),
44080b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_amr, PowerPCCPU),
44180b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_ppr, PowerPCCPU),
44280b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_vrsave, PowerPCCPU),
44380b3f79bSAlexey Kardashevskiy         VMSTATE_UINT32(env.tm_vscr, PowerPCCPU),
44480b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_dscr, PowerPCCPU),
44580b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_tar, PowerPCCPU),
44680b3f79bSAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
44780b3f79bSAlexey Kardashevskiy     },
44880b3f79bSAlexey Kardashevskiy };
44980b3f79bSAlexey Kardashevskiy #endif
45080b3f79bSAlexey Kardashevskiy 
451a90db158SAlexey Kardashevskiy static bool sr_needed(void *opaque)
452a90db158SAlexey Kardashevskiy {
453a90db158SAlexey Kardashevskiy #ifdef TARGET_PPC64
454a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
455a90db158SAlexey Kardashevskiy 
456d57d72a8SGreg Kurz     return !mmu_is_64bit(cpu->env.mmu_model);
457a90db158SAlexey Kardashevskiy #else
458a90db158SAlexey Kardashevskiy     return true;
459a90db158SAlexey Kardashevskiy #endif
460a90db158SAlexey Kardashevskiy }
461a90db158SAlexey Kardashevskiy 
462a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_sr = {
463a90db158SAlexey Kardashevskiy     .name = "cpu/sr",
464a90db158SAlexey Kardashevskiy     .version_id = 1,
465a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
4665cd8cadaSJuan Quintela     .needed = sr_needed,
467a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
468a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL_ARRAY(env.sr, PowerPCCPU, 32),
469a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
470a90db158SAlexey Kardashevskiy     },
471a90db158SAlexey Kardashevskiy };
472a90db158SAlexey Kardashevskiy 
473a90db158SAlexey Kardashevskiy #ifdef TARGET_PPC64
47403fee66fSMarc-André Lureau static int get_slbe(QEMUFile *f, void *pv, size_t size,
47503fee66fSMarc-André Lureau                     const VMStateField *field)
476a90db158SAlexey Kardashevskiy {
477a90db158SAlexey Kardashevskiy     ppc_slb_t *v = pv;
478a90db158SAlexey Kardashevskiy 
479a90db158SAlexey Kardashevskiy     v->esid = qemu_get_be64(f);
480a90db158SAlexey Kardashevskiy     v->vsid = qemu_get_be64(f);
481a90db158SAlexey Kardashevskiy 
482a90db158SAlexey Kardashevskiy     return 0;
483a90db158SAlexey Kardashevskiy }
484a90db158SAlexey Kardashevskiy 
48503fee66fSMarc-André Lureau static int put_slbe(QEMUFile *f, void *pv, size_t size,
4863ddba9a9SMarkus Armbruster                     const VMStateField *field, JSONWriter *vmdesc)
487a90db158SAlexey Kardashevskiy {
488a90db158SAlexey Kardashevskiy     ppc_slb_t *v = pv;
489a90db158SAlexey Kardashevskiy 
490a90db158SAlexey Kardashevskiy     qemu_put_be64(f, v->esid);
491a90db158SAlexey Kardashevskiy     qemu_put_be64(f, v->vsid);
4922c21ee76SJianjun Duan     return 0;
493a90db158SAlexey Kardashevskiy }
494a90db158SAlexey Kardashevskiy 
495cfd54a04SStefan Weil static const VMStateInfo vmstate_info_slbe = {
496a90db158SAlexey Kardashevskiy     .name = "slbe",
497a90db158SAlexey Kardashevskiy     .get  = get_slbe,
498a90db158SAlexey Kardashevskiy     .put  = put_slbe,
499a90db158SAlexey Kardashevskiy };
500a90db158SAlexey Kardashevskiy 
501a90db158SAlexey Kardashevskiy #define VMSTATE_SLB_ARRAY_V(_f, _s, _n, _v)                       \
502a90db158SAlexey Kardashevskiy     VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_slbe, ppc_slb_t)
503a90db158SAlexey Kardashevskiy 
504a90db158SAlexey Kardashevskiy #define VMSTATE_SLB_ARRAY(_f, _s, _n)                             \
505a90db158SAlexey Kardashevskiy     VMSTATE_SLB_ARRAY_V(_f, _s, _n, 0)
506a90db158SAlexey Kardashevskiy 
507a90db158SAlexey Kardashevskiy static bool slb_needed(void *opaque)
508a90db158SAlexey Kardashevskiy {
509a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
510a90db158SAlexey Kardashevskiy 
511a90db158SAlexey Kardashevskiy     /* We don't support any of the old segment table based 64-bit CPUs */
512d57d72a8SGreg Kurz     return mmu_is_64bit(cpu->env.mmu_model);
513a90db158SAlexey Kardashevskiy }
514a90db158SAlexey Kardashevskiy 
515cd6a9bb6SDavid Gibson static int slb_post_load(void *opaque, int version_id)
516cd6a9bb6SDavid Gibson {
517cd6a9bb6SDavid Gibson     PowerPCCPU *cpu = opaque;
518cd6a9bb6SDavid Gibson     CPUPPCState *env = &cpu->env;
519cd6a9bb6SDavid Gibson     int i;
520cd6a9bb6SDavid Gibson 
5216f7a6993SDavid Gibson     /*
5226f7a6993SDavid Gibson      * We've pulled in the raw esid and vsid values from the migration
5236f7a6993SDavid Gibson      * stream, but we need to recompute the page size pointers
5246f7a6993SDavid Gibson      */
52567d7d66fSDavid Gibson     for (i = 0; i < cpu->hash64_opts->slb_size; i++) {
526cd6a9bb6SDavid Gibson         if (ppc_store_slb(cpu, i, env->slb[i].esid, env->slb[i].vsid) < 0) {
527cd6a9bb6SDavid Gibson             /* Migration source had bad values in its SLB */
528cd6a9bb6SDavid Gibson             return -1;
529cd6a9bb6SDavid Gibson         }
530cd6a9bb6SDavid Gibson     }
531cd6a9bb6SDavid Gibson 
532cd6a9bb6SDavid Gibson     return 0;
533cd6a9bb6SDavid Gibson }
534cd6a9bb6SDavid Gibson 
535a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_slb = {
536a90db158SAlexey Kardashevskiy     .name = "cpu/slb",
537a90db158SAlexey Kardashevskiy     .version_id = 1,
538a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
5395cd8cadaSJuan Quintela     .needed = slb_needed,
540cd6a9bb6SDavid Gibson     .post_load = slb_post_load,
541a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
542d8c0c7afSPeter Maydell         VMSTATE_INT32_TEST(mig_slb_nr, PowerPCCPU, cpu_pre_3_0_migration),
543d83af167SAneesh Kumar K.V         VMSTATE_SLB_ARRAY(env.slb, PowerPCCPU, MAX_SLB_ENTRIES),
544a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
545a90db158SAlexey Kardashevskiy     }
546a90db158SAlexey Kardashevskiy };
547a90db158SAlexey Kardashevskiy #endif /* TARGET_PPC64 */
548a90db158SAlexey Kardashevskiy 
549a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_tlb6xx_entry = {
550a90db158SAlexey Kardashevskiy     .name = "cpu/tlb6xx_entry",
551a90db158SAlexey Kardashevskiy     .version_id = 1,
552a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
553a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
554a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(pte0, ppc6xx_tlb_t),
555a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(pte1, ppc6xx_tlb_t),
556a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(EPN, ppc6xx_tlb_t),
557a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
558a90db158SAlexey Kardashevskiy     },
559a90db158SAlexey Kardashevskiy };
560a90db158SAlexey Kardashevskiy 
561a90db158SAlexey Kardashevskiy static bool tlb6xx_needed(void *opaque)
562a90db158SAlexey Kardashevskiy {
563a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
564a90db158SAlexey Kardashevskiy     CPUPPCState *env = &cpu->env;
565a90db158SAlexey Kardashevskiy 
566a90db158SAlexey Kardashevskiy     return env->nb_tlb && (env->tlb_type == TLB_6XX);
567a90db158SAlexey Kardashevskiy }
568a90db158SAlexey Kardashevskiy 
569a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_tlb6xx = {
570a90db158SAlexey Kardashevskiy     .name = "cpu/tlb6xx",
571a90db158SAlexey Kardashevskiy     .version_id = 1,
572a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
5735cd8cadaSJuan Quintela     .needed = tlb6xx_needed,
574a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
575d2164ad3SHalil Pasic         VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU, NULL),
576a90db158SAlexey Kardashevskiy         VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlb6, PowerPCCPU,
577a90db158SAlexey Kardashevskiy                                             env.nb_tlb,
578a90db158SAlexey Kardashevskiy                                             vmstate_tlb6xx_entry,
579a90db158SAlexey Kardashevskiy                                             ppc6xx_tlb_t),
580a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL_ARRAY(env.tgpr, PowerPCCPU, 4),
581a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
582a90db158SAlexey Kardashevskiy     }
583a90db158SAlexey Kardashevskiy };
584a90db158SAlexey Kardashevskiy 
585a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_tlbemb_entry = {
586a90db158SAlexey Kardashevskiy     .name = "cpu/tlbemb_entry",
587a90db158SAlexey Kardashevskiy     .version_id = 1,
588a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
589a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
590a90db158SAlexey Kardashevskiy         VMSTATE_UINT64(RPN, ppcemb_tlb_t),
591a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(EPN, ppcemb_tlb_t),
592a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(PID, ppcemb_tlb_t),
593a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(size, ppcemb_tlb_t),
594a90db158SAlexey Kardashevskiy         VMSTATE_UINT32(prot, ppcemb_tlb_t),
595a90db158SAlexey Kardashevskiy         VMSTATE_UINT32(attr, ppcemb_tlb_t),
596a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
597a90db158SAlexey Kardashevskiy     },
598a90db158SAlexey Kardashevskiy };
599a90db158SAlexey Kardashevskiy 
600a90db158SAlexey Kardashevskiy static bool tlbemb_needed(void *opaque)
601a90db158SAlexey Kardashevskiy {
602a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
603a90db158SAlexey Kardashevskiy     CPUPPCState *env = &cpu->env;
604a90db158SAlexey Kardashevskiy 
605a90db158SAlexey Kardashevskiy     return env->nb_tlb && (env->tlb_type == TLB_EMB);
606a90db158SAlexey Kardashevskiy }
607a90db158SAlexey Kardashevskiy 
608a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_tlbemb = {
609a90db158SAlexey Kardashevskiy     .name = "cpu/tlb6xx",
610a90db158SAlexey Kardashevskiy     .version_id = 1,
611a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
6125cd8cadaSJuan Quintela     .needed = tlbemb_needed,
613a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
614d2164ad3SHalil Pasic         VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU, NULL),
615a90db158SAlexey Kardashevskiy         VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlbe, PowerPCCPU,
616a90db158SAlexey Kardashevskiy                                             env.nb_tlb,
617a90db158SAlexey Kardashevskiy                                             vmstate_tlbemb_entry,
618a90db158SAlexey Kardashevskiy                                             ppcemb_tlb_t),
619a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
620a90db158SAlexey Kardashevskiy     },
621a90db158SAlexey Kardashevskiy };
622a90db158SAlexey Kardashevskiy 
623a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_tlbmas_entry = {
624a90db158SAlexey Kardashevskiy     .name = "cpu/tlbmas_entry",
625a90db158SAlexey Kardashevskiy     .version_id = 1,
626a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
627a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
628a90db158SAlexey Kardashevskiy         VMSTATE_UINT32(mas8, ppcmas_tlb_t),
629a90db158SAlexey Kardashevskiy         VMSTATE_UINT32(mas1, ppcmas_tlb_t),
630a90db158SAlexey Kardashevskiy         VMSTATE_UINT64(mas2, ppcmas_tlb_t),
631a90db158SAlexey Kardashevskiy         VMSTATE_UINT64(mas7_3, ppcmas_tlb_t),
632a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
633a90db158SAlexey Kardashevskiy     },
634a90db158SAlexey Kardashevskiy };
635a90db158SAlexey Kardashevskiy 
636a90db158SAlexey Kardashevskiy static bool tlbmas_needed(void *opaque)
637a90db158SAlexey Kardashevskiy {
638a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
639a90db158SAlexey Kardashevskiy     CPUPPCState *env = &cpu->env;
640a90db158SAlexey Kardashevskiy 
641a90db158SAlexey Kardashevskiy     return env->nb_tlb && (env->tlb_type == TLB_MAS);
642a90db158SAlexey Kardashevskiy }
643a90db158SAlexey Kardashevskiy 
644a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_tlbmas = {
645a90db158SAlexey Kardashevskiy     .name = "cpu/tlbmas",
646a90db158SAlexey Kardashevskiy     .version_id = 1,
647a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
6485cd8cadaSJuan Quintela     .needed = tlbmas_needed,
649a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
650d2164ad3SHalil Pasic         VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU, NULL),
651a90db158SAlexey Kardashevskiy         VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlbm, PowerPCCPU,
652a90db158SAlexey Kardashevskiy                                             env.nb_tlb,
653a90db158SAlexey Kardashevskiy                                             vmstate_tlbmas_entry,
654a90db158SAlexey Kardashevskiy                                             ppcmas_tlb_t),
655a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
656a90db158SAlexey Kardashevskiy     }
657a90db158SAlexey Kardashevskiy };
658a90db158SAlexey Kardashevskiy 
659d5fc133eSDavid Gibson static bool compat_needed(void *opaque)
660d5fc133eSDavid Gibson {
661d5fc133eSDavid Gibson     PowerPCCPU *cpu = opaque;
662d5fc133eSDavid Gibson 
663d5fc133eSDavid Gibson     assert(!(cpu->compat_pvr && !cpu->vhyp));
664d5fc133eSDavid Gibson     return !cpu->pre_2_10_migration && cpu->compat_pvr != 0;
665d5fc133eSDavid Gibson }
666d5fc133eSDavid Gibson 
667d5fc133eSDavid Gibson static const VMStateDescription vmstate_compat = {
668d5fc133eSDavid Gibson     .name = "cpu/compat",
669d5fc133eSDavid Gibson     .version_id = 1,
670d5fc133eSDavid Gibson     .minimum_version_id = 1,
671d5fc133eSDavid Gibson     .needed = compat_needed,
672d5fc133eSDavid Gibson     .fields = (VMStateField[]) {
673d5fc133eSDavid Gibson         VMSTATE_UINT32(compat_pvr, PowerPCCPU),
674d5fc133eSDavid Gibson         VMSTATE_END_OF_LIST()
675d5fc133eSDavid Gibson     }
676d5fc133eSDavid Gibson };
677d5fc133eSDavid Gibson 
678a90db158SAlexey Kardashevskiy const VMStateDescription vmstate_ppc_cpu = {
679a90db158SAlexey Kardashevskiy     .name = "cpu",
680a90db158SAlexey Kardashevskiy     .version_id = 5,
681a90db158SAlexey Kardashevskiy     .minimum_version_id = 5,
682a90db158SAlexey Kardashevskiy     .pre_save = cpu_pre_save,
683a90db158SAlexey Kardashevskiy     .post_load = cpu_post_load,
684a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
685569be9f0SAlexey Kardashevskiy         VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.spr[SPR_PVR]) */
686a90db158SAlexey Kardashevskiy 
687a90db158SAlexey Kardashevskiy         /* User mode architected state */
688a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL_ARRAY(env.gpr, PowerPCCPU, 32),
689a90db158SAlexey Kardashevskiy #if !defined(TARGET_PPC64)
690a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL_ARRAY(env.gprh, PowerPCCPU, 32),
691a90db158SAlexey Kardashevskiy #endif
692a90db158SAlexey Kardashevskiy         VMSTATE_UINT32_ARRAY(env.crf, PowerPCCPU, 8),
693a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(env.nip, PowerPCCPU),
694a90db158SAlexey Kardashevskiy 
695a90db158SAlexey Kardashevskiy         /* SPRs */
696a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL_ARRAY(env.spr, PowerPCCPU, 1024),
697a90db158SAlexey Kardashevskiy         VMSTATE_UINT64(env.spe_acc, PowerPCCPU),
698a90db158SAlexey Kardashevskiy 
699a90db158SAlexey Kardashevskiy         /* Reservation */
700a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(env.reserve_addr, PowerPCCPU),
701a90db158SAlexey Kardashevskiy 
702a90db158SAlexey Kardashevskiy         /* Supervisor mode architected state */
703a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(env.msr, PowerPCCPU),
704a90db158SAlexey Kardashevskiy 
705f7a7b652SRichard Henderson         /* Backward compatible internal state */
706f7a7b652SRichard Henderson         VMSTATE_UINTTL(env.hflags_compat_nmsr, PowerPCCPU),
707a90db158SAlexey Kardashevskiy 
708a90db158SAlexey Kardashevskiy         /* Sanity checking */
709146c11f1SDavid Gibson         VMSTATE_UINTTL_TEST(mig_msr_mask, PowerPCCPU, cpu_pre_2_8_migration),
710146c11f1SDavid Gibson         VMSTATE_UINT64_TEST(mig_insns_flags, PowerPCCPU, cpu_pre_2_8_migration),
711146c11f1SDavid Gibson         VMSTATE_UINT64_TEST(mig_insns_flags2, PowerPCCPU,
712146c11f1SDavid Gibson                             cpu_pre_2_8_migration),
713146c11f1SDavid Gibson         VMSTATE_UINT32_TEST(mig_nb_BATs, PowerPCCPU, cpu_pre_2_8_migration),
714a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
715a90db158SAlexey Kardashevskiy     },
7165cd8cadaSJuan Quintela     .subsections = (const VMStateDescription*[]) {
7175cd8cadaSJuan Quintela         &vmstate_fpu,
7185cd8cadaSJuan Quintela         &vmstate_altivec,
7195cd8cadaSJuan Quintela         &vmstate_vsx,
7205cd8cadaSJuan Quintela         &vmstate_sr,
721a90db158SAlexey Kardashevskiy #ifdef TARGET_PPC64
7225cd8cadaSJuan Quintela         &vmstate_tm,
7235cd8cadaSJuan Quintela         &vmstate_slb,
724a90db158SAlexey Kardashevskiy #endif /* TARGET_PPC64 */
7255cd8cadaSJuan Quintela         &vmstate_tlb6xx,
7265cd8cadaSJuan Quintela         &vmstate_tlbemb,
7275cd8cadaSJuan Quintela         &vmstate_tlbmas,
728d5fc133eSDavid Gibson         &vmstate_compat,
7295cd8cadaSJuan Quintela         NULL
730a90db158SAlexey Kardashevskiy     }
731a90db158SAlexey Kardashevskiy };
732