xref: /qemu/target/ppc/machine.c (revision 578912ad7312ececb9a88b4c38d406dda640346d)
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 
211*578912adSNicholas Piggin     if (tcg_enabled()) {
212*578912adSNicholas Piggin         /*
213*578912adSNicholas Piggin          * TCG does not maintain the DECR spr (unlike KVM) so have to save
214*578912adSNicholas Piggin          * it here.
215*578912adSNicholas Piggin          */
216*578912adSNicholas Piggin         env->spr[SPR_DECR] = cpu_ppc_load_decr(env);
217*578912adSNicholas Piggin     }
218*578912adSNicholas Piggin 
21944b1ff31SDr. David Alan Gilbert     return 0;
220146c11f1SDavid Gibson }
221a90db158SAlexey Kardashevskiy 
222d5fc133eSDavid Gibson /*
223d5fc133eSDavid Gibson  * Determine if a given PVR is a "close enough" match to the CPU
224d5fc133eSDavid Gibson  * object.  For TCG and KVM PR it would probably be sufficient to
225d5fc133eSDavid Gibson  * require an exact PVR match.  However for KVM HV the user is
226d5fc133eSDavid Gibson  * restricted to a PVR exactly matching the host CPU.  The correct way
227d5fc133eSDavid Gibson  * to handle this is to put the guest into an architected
228d5fc133eSDavid Gibson  * compatibility mode.  However, to allow a more forgiving transition
229d5fc133eSDavid Gibson  * and migration from before this was widely done, we allow migration
230d5fc133eSDavid Gibson  * between sufficiently similar PVRs, as determined by the CPU class's
231d5fc133eSDavid Gibson  * pvr_match() hook.
232d5fc133eSDavid Gibson  */
233d5fc133eSDavid Gibson static bool pvr_match(PowerPCCPU *cpu, uint32_t pvr)
234d5fc133eSDavid Gibson {
235d5fc133eSDavid Gibson     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
236d5fc133eSDavid Gibson 
237d5fc133eSDavid Gibson     if (pvr == pcc->pvr) {
238d5fc133eSDavid Gibson         return true;
239d5fc133eSDavid Gibson     }
24021d3a78eSNicholas Piggin     return pcc->pvr_match(pcc, pvr, true);
241d5fc133eSDavid Gibson }
242d5fc133eSDavid Gibson 
243a90db158SAlexey Kardashevskiy static int cpu_post_load(void *opaque, int version_id)
244a90db158SAlexey Kardashevskiy {
245a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
246a90db158SAlexey Kardashevskiy     CPUPPCState *env = &cpu->env;
247a90db158SAlexey Kardashevskiy     int i;
248a90db158SAlexey Kardashevskiy 
249569be9f0SAlexey Kardashevskiy     /*
250d5fc133eSDavid Gibson      * If we're operating in compat mode, we should be ok as long as
251136fbf65Szhaolichang      * the destination supports the same compatibility mode.
252d5fc133eSDavid Gibson      *
253d5fc133eSDavid Gibson      * Otherwise, however, we require that the destination has exactly
254d5fc133eSDavid Gibson      * the same CPU model as the source.
255569be9f0SAlexey Kardashevskiy      */
256d5fc133eSDavid Gibson 
257d5fc133eSDavid Gibson #if defined(TARGET_PPC64)
258d5fc133eSDavid Gibson     if (cpu->compat_pvr) {
259e07cc192SSuraj Jitindar Singh         uint32_t compat_pvr = cpu->compat_pvr;
260d5fc133eSDavid Gibson         Error *local_err = NULL;
261899134ebSGreg Kurz         int ret;
262d5fc133eSDavid Gibson 
263e07cc192SSuraj Jitindar Singh         cpu->compat_pvr = 0;
264899134ebSGreg Kurz         ret = ppc_set_compat(cpu, compat_pvr, &local_err);
265899134ebSGreg Kurz         if (ret < 0) {
266d5fc133eSDavid Gibson             error_report_err(local_err);
267899134ebSGreg Kurz             return ret;
268d5fc133eSDavid Gibson         }
269d5fc133eSDavid Gibson     } else
270d5fc133eSDavid Gibson #endif
271d5fc133eSDavid Gibson     {
272d5fc133eSDavid Gibson         if (!pvr_match(cpu, env->spr[SPR_PVR])) {
273899134ebSGreg Kurz             return -EINVAL;
274d5fc133eSDavid Gibson         }
275d5fc133eSDavid Gibson     }
276d5fc133eSDavid Gibson 
277c363a37aSDaniel Henrique Barboza     /*
278c363a37aSDaniel Henrique Barboza      * If we're running with KVM HV, there is a chance that the guest
279c363a37aSDaniel Henrique Barboza      * is running with KVM HV and its kernel does not have the
280c363a37aSDaniel Henrique Barboza      * capability of dealing with a different PVR other than this
281c363a37aSDaniel Henrique Barboza      * exact host PVR in KVM_SET_SREGS. If that happens, the
282c363a37aSDaniel Henrique Barboza      * guest freezes after migration.
283c363a37aSDaniel Henrique Barboza      *
284c363a37aSDaniel Henrique Barboza      * The function kvmppc_pvr_workaround_required does this verification
285c363a37aSDaniel Henrique Barboza      * by first checking if the kernel has the cap, returning true immediately
286c363a37aSDaniel Henrique Barboza      * if that is the case. Otherwise, it checks if we're running in KVM PR.
287c363a37aSDaniel Henrique Barboza      * If the guest kernel does not have the cap and we're not running KVM-PR
288c363a37aSDaniel Henrique Barboza      * (so, it is running KVM-HV), we need to ensure that KVM_SET_SREGS will
289c363a37aSDaniel Henrique Barboza      * receive the PVR it expects as a workaround.
290c363a37aSDaniel Henrique Barboza      *
291c363a37aSDaniel Henrique Barboza      */
292c363a37aSDaniel Henrique Barboza     if (kvmppc_pvr_workaround_required(cpu)) {
293c363a37aSDaniel Henrique Barboza         env->spr[SPR_PVR] = env->spr_cb[SPR_PVR].default_value;
294c363a37aSDaniel Henrique Barboza     }
295c363a37aSDaniel Henrique Barboza 
296a90db158SAlexey Kardashevskiy     env->lr = env->spr[SPR_LR];
297a90db158SAlexey Kardashevskiy     env->ctr = env->spr[SPR_CTR];
2986a9620e6SMark Cave-Ayland     cpu_write_xer(env, env->spr[SPR_XER]);
299a90db158SAlexey Kardashevskiy #if defined(TARGET_PPC64)
300a90db158SAlexey Kardashevskiy     env->cfar = env->spr[SPR_CFAR];
301a90db158SAlexey Kardashevskiy #endif
302a90db158SAlexey Kardashevskiy     env->spe_fscr = env->spr[SPR_BOOKE_SPEFSCR];
303a90db158SAlexey Kardashevskiy 
304a90db158SAlexey Kardashevskiy     for (i = 0; (i < 4) && (i < env->nb_BATs); i++) {
305a90db158SAlexey Kardashevskiy         env->DBAT[0][i] = env->spr[SPR_DBAT0U + 2 * i];
306a90db158SAlexey Kardashevskiy         env->DBAT[1][i] = env->spr[SPR_DBAT0U + 2 * i + 1];
307a90db158SAlexey Kardashevskiy         env->IBAT[0][i] = env->spr[SPR_IBAT0U + 2 * i];
308a90db158SAlexey Kardashevskiy         env->IBAT[1][i] = env->spr[SPR_IBAT0U + 2 * i + 1];
309a90db158SAlexey Kardashevskiy     }
310a90db158SAlexey Kardashevskiy     for (i = 0; (i < 4) && ((i + 4) < env->nb_BATs); i++) {
311a90db158SAlexey Kardashevskiy         env->DBAT[0][i + 4] = env->spr[SPR_DBAT4U + 2 * i];
312a90db158SAlexey Kardashevskiy         env->DBAT[1][i + 4] = env->spr[SPR_DBAT4U + 2 * i + 1];
313a90db158SAlexey Kardashevskiy         env->IBAT[0][i + 4] = env->spr[SPR_IBAT4U + 2 * i];
314a90db158SAlexey Kardashevskiy         env->IBAT[1][i + 4] = env->spr[SPR_IBAT4U + 2 * i + 1];
315a90db158SAlexey Kardashevskiy     }
316a90db158SAlexey Kardashevskiy 
317e57ca75cSDavid Gibson     if (!cpu->vhyp) {
318a90db158SAlexey Kardashevskiy         ppc_store_sdr1(env, env->spr[SPR_SDR1]);
319f3c75d42SAneesh Kumar K.V     }
3202360b6e8SMark Cave-Ayland 
321edece45dSRichard Henderson     post_load_update_msr(env);
3222360b6e8SMark Cave-Ayland 
3236494d2c1SNicholas Piggin     if (tcg_enabled()) {
32414192307SNicholas Piggin         /* Re-set breaks based on regs */
32514192307SNicholas Piggin #if defined(TARGET_PPC64)
32614192307SNicholas Piggin         ppc_update_ciabr(env);
327d5ee641cSNicholas Piggin         ppc_update_daw0(env);
32814192307SNicholas Piggin #endif
329*578912adSNicholas Piggin         /*
330*578912adSNicholas Piggin          * TCG needs to re-start the decrementer timer and/or raise the
331*578912adSNicholas Piggin          * interrupt. This works for level-triggered decrementer. Edge
332*578912adSNicholas Piggin          * triggered types (including HDEC) would need to carry more state.
333*578912adSNicholas Piggin          */
334*578912adSNicholas Piggin         cpu_ppc_store_decr(env, env->spr[SPR_DECR]);
3356494d2c1SNicholas Piggin         pmu_mmcr01_updated(env);
3366494d2c1SNicholas Piggin     }
3376494d2c1SNicholas Piggin 
338a90db158SAlexey Kardashevskiy     return 0;
339a90db158SAlexey Kardashevskiy }
340a90db158SAlexey Kardashevskiy 
341a90db158SAlexey Kardashevskiy static bool fpu_needed(void *opaque)
342a90db158SAlexey Kardashevskiy {
343a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
344a90db158SAlexey Kardashevskiy 
3456f7a6993SDavid Gibson     return cpu->env.insns_flags & PPC_FLOAT;
346a90db158SAlexey Kardashevskiy }
347a90db158SAlexey Kardashevskiy 
348a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_fpu = {
349a90db158SAlexey Kardashevskiy     .name = "cpu/fpu",
350a90db158SAlexey Kardashevskiy     .version_id = 1,
351a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
3525cd8cadaSJuan Quintela     .needed = fpu_needed,
353a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
354ef96e3aeSMark Cave-Ayland         VMSTATE_FPR_ARRAY(env.vsr, PowerPCCPU, 32),
355a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(env.fpscr, PowerPCCPU),
356a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
357a90db158SAlexey Kardashevskiy     },
358a90db158SAlexey Kardashevskiy };
359a90db158SAlexey Kardashevskiy 
360a90db158SAlexey Kardashevskiy static bool altivec_needed(void *opaque)
361a90db158SAlexey Kardashevskiy {
362a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
363a90db158SAlexey Kardashevskiy 
3646f7a6993SDavid Gibson     return cpu->env.insns_flags & PPC_ALTIVEC;
365a90db158SAlexey Kardashevskiy }
366a90db158SAlexey Kardashevskiy 
367596fff20SRichard Henderson static int get_vscr(QEMUFile *f, void *opaque, size_t size,
368596fff20SRichard Henderson                     const VMStateField *field)
369596fff20SRichard Henderson {
370596fff20SRichard Henderson     PowerPCCPU *cpu = opaque;
37187aff238SBruno Larsen (billionai)     ppc_store_vscr(&cpu->env, qemu_get_be32(f));
372596fff20SRichard Henderson     return 0;
373596fff20SRichard Henderson }
374596fff20SRichard Henderson 
375596fff20SRichard Henderson static int put_vscr(QEMUFile *f, void *opaque, size_t size,
3763ddba9a9SMarkus Armbruster                     const VMStateField *field, JSONWriter *vmdesc)
377596fff20SRichard Henderson {
378596fff20SRichard Henderson     PowerPCCPU *cpu = opaque;
37987aff238SBruno Larsen (billionai)     qemu_put_be32(f, ppc_get_vscr(&cpu->env));
380596fff20SRichard Henderson     return 0;
381596fff20SRichard Henderson }
382596fff20SRichard Henderson 
383596fff20SRichard Henderson static const VMStateInfo vmstate_vscr = {
384596fff20SRichard Henderson     .name = "cpu/altivec/vscr",
385596fff20SRichard Henderson     .get = get_vscr,
386596fff20SRichard Henderson     .put = put_vscr,
387596fff20SRichard Henderson };
388596fff20SRichard Henderson 
389a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_altivec = {
390a90db158SAlexey Kardashevskiy     .name = "cpu/altivec",
391a90db158SAlexey Kardashevskiy     .version_id = 1,
392a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
3935cd8cadaSJuan Quintela     .needed = altivec_needed,
394a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
395ef96e3aeSMark Cave-Ayland         VMSTATE_AVR_ARRAY(env.vsr, PowerPCCPU, 32),
396596fff20SRichard Henderson         /*
397596fff20SRichard Henderson          * Save the architecture value of the vscr, not the internally
398596fff20SRichard Henderson          * expanded version.  Since this architecture value does not
399596fff20SRichard Henderson          * exist in memory to be stored, this requires a but of hoop
400596fff20SRichard Henderson          * jumping.  We want OFFSET=0 so that we effectively pass CPU
401596fff20SRichard Henderson          * to the helper functions.
402596fff20SRichard Henderson          */
403596fff20SRichard Henderson         {
404596fff20SRichard Henderson             .name = "vscr",
405596fff20SRichard Henderson             .version_id = 0,
406596fff20SRichard Henderson             .size = sizeof(uint32_t),
407596fff20SRichard Henderson             .info = &vmstate_vscr,
408596fff20SRichard Henderson             .flags = VMS_SINGLE,
409596fff20SRichard Henderson             .offset = 0
410596fff20SRichard Henderson         },
411a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
412a90db158SAlexey Kardashevskiy     },
413a90db158SAlexey Kardashevskiy };
414a90db158SAlexey Kardashevskiy 
415a90db158SAlexey Kardashevskiy static bool vsx_needed(void *opaque)
416a90db158SAlexey Kardashevskiy {
417a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
418a90db158SAlexey Kardashevskiy 
4196f7a6993SDavid Gibson     return cpu->env.insns_flags2 & PPC2_VSX;
420a90db158SAlexey Kardashevskiy }
421a90db158SAlexey Kardashevskiy 
422a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_vsx = {
423a90db158SAlexey Kardashevskiy     .name = "cpu/vsx",
424a90db158SAlexey Kardashevskiy     .version_id = 1,
425a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
4265cd8cadaSJuan Quintela     .needed = vsx_needed,
427a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
428ef96e3aeSMark Cave-Ayland         VMSTATE_VSR_ARRAY(env.vsr, PowerPCCPU, 32),
429a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
430a90db158SAlexey Kardashevskiy     },
431a90db158SAlexey Kardashevskiy };
432a90db158SAlexey Kardashevskiy 
43380b3f79bSAlexey Kardashevskiy #ifdef TARGET_PPC64
43480b3f79bSAlexey Kardashevskiy /* Transactional memory state */
43580b3f79bSAlexey Kardashevskiy static bool tm_needed(void *opaque)
43680b3f79bSAlexey Kardashevskiy {
43780b3f79bSAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
43880b3f79bSAlexey Kardashevskiy     CPUPPCState *env = &cpu->env;
439ca241959SVíctor Colombo     return FIELD_EX64(env->msr, MSR, TS);
44080b3f79bSAlexey Kardashevskiy }
44180b3f79bSAlexey Kardashevskiy 
44280b3f79bSAlexey Kardashevskiy static const VMStateDescription vmstate_tm = {
44380b3f79bSAlexey Kardashevskiy     .name = "cpu/tm",
44480b3f79bSAlexey Kardashevskiy     .version_id = 1,
44580b3f79bSAlexey Kardashevskiy     .minimum_version_id = 1,
4465cd8cadaSJuan Quintela     .needed = tm_needed,
44780b3f79bSAlexey Kardashevskiy     .fields      = (VMStateField []) {
44880b3f79bSAlexey Kardashevskiy         VMSTATE_UINTTL_ARRAY(env.tm_gpr, PowerPCCPU, 32),
44980b3f79bSAlexey Kardashevskiy         VMSTATE_AVR_ARRAY(env.tm_vsr, PowerPCCPU, 64),
45080b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_cr, PowerPCCPU),
45180b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_lr, PowerPCCPU),
45280b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_ctr, PowerPCCPU),
45380b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_fpscr, PowerPCCPU),
45480b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_amr, PowerPCCPU),
45580b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_ppr, PowerPCCPU),
45680b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_vrsave, PowerPCCPU),
45780b3f79bSAlexey Kardashevskiy         VMSTATE_UINT32(env.tm_vscr, PowerPCCPU),
45880b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_dscr, PowerPCCPU),
45980b3f79bSAlexey Kardashevskiy         VMSTATE_UINT64(env.tm_tar, PowerPCCPU),
46080b3f79bSAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
46180b3f79bSAlexey Kardashevskiy     },
46280b3f79bSAlexey Kardashevskiy };
46380b3f79bSAlexey Kardashevskiy #endif
46480b3f79bSAlexey Kardashevskiy 
465a90db158SAlexey Kardashevskiy static bool sr_needed(void *opaque)
466a90db158SAlexey Kardashevskiy {
467a90db158SAlexey Kardashevskiy #ifdef TARGET_PPC64
468a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
469a90db158SAlexey Kardashevskiy 
470d57d72a8SGreg Kurz     return !mmu_is_64bit(cpu->env.mmu_model);
471a90db158SAlexey Kardashevskiy #else
472a90db158SAlexey Kardashevskiy     return true;
473a90db158SAlexey Kardashevskiy #endif
474a90db158SAlexey Kardashevskiy }
475a90db158SAlexey Kardashevskiy 
476a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_sr = {
477a90db158SAlexey Kardashevskiy     .name = "cpu/sr",
478a90db158SAlexey Kardashevskiy     .version_id = 1,
479a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
4805cd8cadaSJuan Quintela     .needed = sr_needed,
481a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
482a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL_ARRAY(env.sr, PowerPCCPU, 32),
483a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
484a90db158SAlexey Kardashevskiy     },
485a90db158SAlexey Kardashevskiy };
486a90db158SAlexey Kardashevskiy 
487a90db158SAlexey Kardashevskiy #ifdef TARGET_PPC64
48803fee66fSMarc-André Lureau static int get_slbe(QEMUFile *f, void *pv, size_t size,
48903fee66fSMarc-André Lureau                     const VMStateField *field)
490a90db158SAlexey Kardashevskiy {
491a90db158SAlexey Kardashevskiy     ppc_slb_t *v = pv;
492a90db158SAlexey Kardashevskiy 
493a90db158SAlexey Kardashevskiy     v->esid = qemu_get_be64(f);
494a90db158SAlexey Kardashevskiy     v->vsid = qemu_get_be64(f);
495a90db158SAlexey Kardashevskiy 
496a90db158SAlexey Kardashevskiy     return 0;
497a90db158SAlexey Kardashevskiy }
498a90db158SAlexey Kardashevskiy 
49903fee66fSMarc-André Lureau static int put_slbe(QEMUFile *f, void *pv, size_t size,
5003ddba9a9SMarkus Armbruster                     const VMStateField *field, JSONWriter *vmdesc)
501a90db158SAlexey Kardashevskiy {
502a90db158SAlexey Kardashevskiy     ppc_slb_t *v = pv;
503a90db158SAlexey Kardashevskiy 
504a90db158SAlexey Kardashevskiy     qemu_put_be64(f, v->esid);
505a90db158SAlexey Kardashevskiy     qemu_put_be64(f, v->vsid);
5062c21ee76SJianjun Duan     return 0;
507a90db158SAlexey Kardashevskiy }
508a90db158SAlexey Kardashevskiy 
509cfd54a04SStefan Weil static const VMStateInfo vmstate_info_slbe = {
510a90db158SAlexey Kardashevskiy     .name = "slbe",
511a90db158SAlexey Kardashevskiy     .get  = get_slbe,
512a90db158SAlexey Kardashevskiy     .put  = put_slbe,
513a90db158SAlexey Kardashevskiy };
514a90db158SAlexey Kardashevskiy 
515a90db158SAlexey Kardashevskiy #define VMSTATE_SLB_ARRAY_V(_f, _s, _n, _v)                       \
516a90db158SAlexey Kardashevskiy     VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_slbe, ppc_slb_t)
517a90db158SAlexey Kardashevskiy 
518a90db158SAlexey Kardashevskiy #define VMSTATE_SLB_ARRAY(_f, _s, _n)                             \
519a90db158SAlexey Kardashevskiy     VMSTATE_SLB_ARRAY_V(_f, _s, _n, 0)
520a90db158SAlexey Kardashevskiy 
521a90db158SAlexey Kardashevskiy static bool slb_needed(void *opaque)
522a90db158SAlexey Kardashevskiy {
523a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
524a90db158SAlexey Kardashevskiy 
525a90db158SAlexey Kardashevskiy     /* We don't support any of the old segment table based 64-bit CPUs */
526d57d72a8SGreg Kurz     return mmu_is_64bit(cpu->env.mmu_model);
527a90db158SAlexey Kardashevskiy }
528a90db158SAlexey Kardashevskiy 
529cd6a9bb6SDavid Gibson static int slb_post_load(void *opaque, int version_id)
530cd6a9bb6SDavid Gibson {
531cd6a9bb6SDavid Gibson     PowerPCCPU *cpu = opaque;
532cd6a9bb6SDavid Gibson     CPUPPCState *env = &cpu->env;
533cd6a9bb6SDavid Gibson     int i;
534cd6a9bb6SDavid Gibson 
5356f7a6993SDavid Gibson     /*
5366f7a6993SDavid Gibson      * We've pulled in the raw esid and vsid values from the migration
5376f7a6993SDavid Gibson      * stream, but we need to recompute the page size pointers
5386f7a6993SDavid Gibson      */
53967d7d66fSDavid Gibson     for (i = 0; i < cpu->hash64_opts->slb_size; i++) {
540cd6a9bb6SDavid Gibson         if (ppc_store_slb(cpu, i, env->slb[i].esid, env->slb[i].vsid) < 0) {
541cd6a9bb6SDavid Gibson             /* Migration source had bad values in its SLB */
542cd6a9bb6SDavid Gibson             return -1;
543cd6a9bb6SDavid Gibson         }
544cd6a9bb6SDavid Gibson     }
545cd6a9bb6SDavid Gibson 
546cd6a9bb6SDavid Gibson     return 0;
547cd6a9bb6SDavid Gibson }
548cd6a9bb6SDavid Gibson 
549a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_slb = {
550a90db158SAlexey Kardashevskiy     .name = "cpu/slb",
551a90db158SAlexey Kardashevskiy     .version_id = 1,
552a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
5535cd8cadaSJuan Quintela     .needed = slb_needed,
554cd6a9bb6SDavid Gibson     .post_load = slb_post_load,
555a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
556d8c0c7afSPeter Maydell         VMSTATE_INT32_TEST(mig_slb_nr, PowerPCCPU, cpu_pre_3_0_migration),
557d83af167SAneesh Kumar K.V         VMSTATE_SLB_ARRAY(env.slb, PowerPCCPU, MAX_SLB_ENTRIES),
558a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
559a90db158SAlexey Kardashevskiy     }
560a90db158SAlexey Kardashevskiy };
561a90db158SAlexey Kardashevskiy #endif /* TARGET_PPC64 */
562a90db158SAlexey Kardashevskiy 
563a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_tlb6xx_entry = {
564a90db158SAlexey Kardashevskiy     .name = "cpu/tlb6xx_entry",
565a90db158SAlexey Kardashevskiy     .version_id = 1,
566a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
567a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
568a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(pte0, ppc6xx_tlb_t),
569a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(pte1, ppc6xx_tlb_t),
570a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(EPN, ppc6xx_tlb_t),
571a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
572a90db158SAlexey Kardashevskiy     },
573a90db158SAlexey Kardashevskiy };
574a90db158SAlexey Kardashevskiy 
575a90db158SAlexey Kardashevskiy static bool tlb6xx_needed(void *opaque)
576a90db158SAlexey Kardashevskiy {
577a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
578a90db158SAlexey Kardashevskiy     CPUPPCState *env = &cpu->env;
579a90db158SAlexey Kardashevskiy 
580a90db158SAlexey Kardashevskiy     return env->nb_tlb && (env->tlb_type == TLB_6XX);
581a90db158SAlexey Kardashevskiy }
582a90db158SAlexey Kardashevskiy 
583a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_tlb6xx = {
584a90db158SAlexey Kardashevskiy     .name = "cpu/tlb6xx",
585a90db158SAlexey Kardashevskiy     .version_id = 1,
586a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
5875cd8cadaSJuan Quintela     .needed = tlb6xx_needed,
588a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
589d2164ad3SHalil Pasic         VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU, NULL),
590a90db158SAlexey Kardashevskiy         VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlb6, PowerPCCPU,
591a90db158SAlexey Kardashevskiy                                             env.nb_tlb,
592a90db158SAlexey Kardashevskiy                                             vmstate_tlb6xx_entry,
593a90db158SAlexey Kardashevskiy                                             ppc6xx_tlb_t),
594a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL_ARRAY(env.tgpr, PowerPCCPU, 4),
595a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
596a90db158SAlexey Kardashevskiy     }
597a90db158SAlexey Kardashevskiy };
598a90db158SAlexey Kardashevskiy 
599a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_tlbemb_entry = {
600a90db158SAlexey Kardashevskiy     .name = "cpu/tlbemb_entry",
601a90db158SAlexey Kardashevskiy     .version_id = 1,
602a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
603a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
604a90db158SAlexey Kardashevskiy         VMSTATE_UINT64(RPN, ppcemb_tlb_t),
605a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(EPN, ppcemb_tlb_t),
606a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(PID, ppcemb_tlb_t),
607a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(size, ppcemb_tlb_t),
608a90db158SAlexey Kardashevskiy         VMSTATE_UINT32(prot, ppcemb_tlb_t),
609a90db158SAlexey Kardashevskiy         VMSTATE_UINT32(attr, ppcemb_tlb_t),
610a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
611a90db158SAlexey Kardashevskiy     },
612a90db158SAlexey Kardashevskiy };
613a90db158SAlexey Kardashevskiy 
614a90db158SAlexey Kardashevskiy static bool tlbemb_needed(void *opaque)
615a90db158SAlexey Kardashevskiy {
616a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
617a90db158SAlexey Kardashevskiy     CPUPPCState *env = &cpu->env;
618a90db158SAlexey Kardashevskiy 
619a90db158SAlexey Kardashevskiy     return env->nb_tlb && (env->tlb_type == TLB_EMB);
620a90db158SAlexey Kardashevskiy }
621a90db158SAlexey Kardashevskiy 
622a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_tlbemb = {
623a90db158SAlexey Kardashevskiy     .name = "cpu/tlb6xx",
624a90db158SAlexey Kardashevskiy     .version_id = 1,
625a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
6265cd8cadaSJuan Quintela     .needed = tlbemb_needed,
627a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
628d2164ad3SHalil Pasic         VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU, NULL),
629a90db158SAlexey Kardashevskiy         VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlbe, PowerPCCPU,
630a90db158SAlexey Kardashevskiy                                             env.nb_tlb,
631a90db158SAlexey Kardashevskiy                                             vmstate_tlbemb_entry,
632a90db158SAlexey Kardashevskiy                                             ppcemb_tlb_t),
633a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
634a90db158SAlexey Kardashevskiy     },
635a90db158SAlexey Kardashevskiy };
636a90db158SAlexey Kardashevskiy 
637a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_tlbmas_entry = {
638a90db158SAlexey Kardashevskiy     .name = "cpu/tlbmas_entry",
639a90db158SAlexey Kardashevskiy     .version_id = 1,
640a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
641a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
642a90db158SAlexey Kardashevskiy         VMSTATE_UINT32(mas8, ppcmas_tlb_t),
643a90db158SAlexey Kardashevskiy         VMSTATE_UINT32(mas1, ppcmas_tlb_t),
644a90db158SAlexey Kardashevskiy         VMSTATE_UINT64(mas2, ppcmas_tlb_t),
645a90db158SAlexey Kardashevskiy         VMSTATE_UINT64(mas7_3, ppcmas_tlb_t),
646a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
647a90db158SAlexey Kardashevskiy     },
648a90db158SAlexey Kardashevskiy };
649a90db158SAlexey Kardashevskiy 
650a90db158SAlexey Kardashevskiy static bool tlbmas_needed(void *opaque)
651a90db158SAlexey Kardashevskiy {
652a90db158SAlexey Kardashevskiy     PowerPCCPU *cpu = opaque;
653a90db158SAlexey Kardashevskiy     CPUPPCState *env = &cpu->env;
654a90db158SAlexey Kardashevskiy 
655a90db158SAlexey Kardashevskiy     return env->nb_tlb && (env->tlb_type == TLB_MAS);
656a90db158SAlexey Kardashevskiy }
657a90db158SAlexey Kardashevskiy 
658a90db158SAlexey Kardashevskiy static const VMStateDescription vmstate_tlbmas = {
659a90db158SAlexey Kardashevskiy     .name = "cpu/tlbmas",
660a90db158SAlexey Kardashevskiy     .version_id = 1,
661a90db158SAlexey Kardashevskiy     .minimum_version_id = 1,
6625cd8cadaSJuan Quintela     .needed = tlbmas_needed,
663a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
664d2164ad3SHalil Pasic         VMSTATE_INT32_EQUAL(env.nb_tlb, PowerPCCPU, NULL),
665a90db158SAlexey Kardashevskiy         VMSTATE_STRUCT_VARRAY_POINTER_INT32(env.tlb.tlbm, PowerPCCPU,
666a90db158SAlexey Kardashevskiy                                             env.nb_tlb,
667a90db158SAlexey Kardashevskiy                                             vmstate_tlbmas_entry,
668a90db158SAlexey Kardashevskiy                                             ppcmas_tlb_t),
669a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
670a90db158SAlexey Kardashevskiy     }
671a90db158SAlexey Kardashevskiy };
672a90db158SAlexey Kardashevskiy 
673d5fc133eSDavid Gibson static bool compat_needed(void *opaque)
674d5fc133eSDavid Gibson {
675d5fc133eSDavid Gibson     PowerPCCPU *cpu = opaque;
676d5fc133eSDavid Gibson 
677d5fc133eSDavid Gibson     assert(!(cpu->compat_pvr && !cpu->vhyp));
678d5fc133eSDavid Gibson     return !cpu->pre_2_10_migration && cpu->compat_pvr != 0;
679d5fc133eSDavid Gibson }
680d5fc133eSDavid Gibson 
681d5fc133eSDavid Gibson static const VMStateDescription vmstate_compat = {
682d5fc133eSDavid Gibson     .name = "cpu/compat",
683d5fc133eSDavid Gibson     .version_id = 1,
684d5fc133eSDavid Gibson     .minimum_version_id = 1,
685d5fc133eSDavid Gibson     .needed = compat_needed,
686d5fc133eSDavid Gibson     .fields = (VMStateField[]) {
687d5fc133eSDavid Gibson         VMSTATE_UINT32(compat_pvr, PowerPCCPU),
688d5fc133eSDavid Gibson         VMSTATE_END_OF_LIST()
689d5fc133eSDavid Gibson     }
690d5fc133eSDavid Gibson };
691d5fc133eSDavid Gibson 
692a90db158SAlexey Kardashevskiy const VMStateDescription vmstate_ppc_cpu = {
693a90db158SAlexey Kardashevskiy     .name = "cpu",
694a90db158SAlexey Kardashevskiy     .version_id = 5,
695a90db158SAlexey Kardashevskiy     .minimum_version_id = 5,
696a90db158SAlexey Kardashevskiy     .pre_save = cpu_pre_save,
697a90db158SAlexey Kardashevskiy     .post_load = cpu_post_load,
698a90db158SAlexey Kardashevskiy     .fields = (VMStateField[]) {
699569be9f0SAlexey Kardashevskiy         VMSTATE_UNUSED(sizeof(target_ulong)), /* was _EQUAL(env.spr[SPR_PVR]) */
700a90db158SAlexey Kardashevskiy 
701a90db158SAlexey Kardashevskiy         /* User mode architected state */
702a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL_ARRAY(env.gpr, PowerPCCPU, 32),
703a90db158SAlexey Kardashevskiy #if !defined(TARGET_PPC64)
704a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL_ARRAY(env.gprh, PowerPCCPU, 32),
705a90db158SAlexey Kardashevskiy #endif
706a90db158SAlexey Kardashevskiy         VMSTATE_UINT32_ARRAY(env.crf, PowerPCCPU, 8),
707a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(env.nip, PowerPCCPU),
708a90db158SAlexey Kardashevskiy 
709a90db158SAlexey Kardashevskiy         /* SPRs */
710a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL_ARRAY(env.spr, PowerPCCPU, 1024),
711a90db158SAlexey Kardashevskiy         VMSTATE_UINT64(env.spe_acc, PowerPCCPU),
712a90db158SAlexey Kardashevskiy 
713a90db158SAlexey Kardashevskiy         /* Reservation */
714a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(env.reserve_addr, PowerPCCPU),
715a90db158SAlexey Kardashevskiy 
716a90db158SAlexey Kardashevskiy         /* Supervisor mode architected state */
717a90db158SAlexey Kardashevskiy         VMSTATE_UINTTL(env.msr, PowerPCCPU),
718a90db158SAlexey Kardashevskiy 
719f7a7b652SRichard Henderson         /* Backward compatible internal state */
720f7a7b652SRichard Henderson         VMSTATE_UINTTL(env.hflags_compat_nmsr, PowerPCCPU),
721a90db158SAlexey Kardashevskiy 
722a90db158SAlexey Kardashevskiy         /* Sanity checking */
723146c11f1SDavid Gibson         VMSTATE_UINTTL_TEST(mig_msr_mask, PowerPCCPU, cpu_pre_2_8_migration),
724146c11f1SDavid Gibson         VMSTATE_UINT64_TEST(mig_insns_flags, PowerPCCPU, cpu_pre_2_8_migration),
725146c11f1SDavid Gibson         VMSTATE_UINT64_TEST(mig_insns_flags2, PowerPCCPU,
726146c11f1SDavid Gibson                             cpu_pre_2_8_migration),
727146c11f1SDavid Gibson         VMSTATE_UINT32_TEST(mig_nb_BATs, PowerPCCPU, cpu_pre_2_8_migration),
728a90db158SAlexey Kardashevskiy         VMSTATE_END_OF_LIST()
729a90db158SAlexey Kardashevskiy     },
7305cd8cadaSJuan Quintela     .subsections = (const VMStateDescription*[]) {
7315cd8cadaSJuan Quintela         &vmstate_fpu,
7325cd8cadaSJuan Quintela         &vmstate_altivec,
7335cd8cadaSJuan Quintela         &vmstate_vsx,
7345cd8cadaSJuan Quintela         &vmstate_sr,
735a90db158SAlexey Kardashevskiy #ifdef TARGET_PPC64
7365cd8cadaSJuan Quintela         &vmstate_tm,
7375cd8cadaSJuan Quintela         &vmstate_slb,
738a90db158SAlexey Kardashevskiy #endif /* TARGET_PPC64 */
7395cd8cadaSJuan Quintela         &vmstate_tlb6xx,
7405cd8cadaSJuan Quintela         &vmstate_tlbemb,
7415cd8cadaSJuan Quintela         &vmstate_tlbmas,
742d5fc133eSDavid Gibson         &vmstate_compat,
7435cd8cadaSJuan Quintela         NULL
744a90db158SAlexey Kardashevskiy     }
745a90db158SAlexey Kardashevskiy };
746