static int cpu_post_load(void *opaque, int version_id) { PowerPCCPU *cpu = opaque; CPUPPCState *env = &cpu->env; int i; env->lr = env->spr[SPR_LR]; env->ctr = env->spr[SPR_CTR]; env->xer = env->spr[SPR_XER]; #if defined(TARGET_PPC64) env->cfar = env->spr[SPR_CFAR]; #endif env->spe_fscr = env->spr[SPR_BOOKE_SPEFSCR]; for (i = 0; (i < 4) && (i < env->nb_BATs); i++) { env->DBAT[0][i] = env->spr[SPR_DBAT0U + 2*i]; env->DBAT[1][i] = env->spr[SPR_DBAT0U + 2*i + 1]; env->IBAT[0][i] = env->spr[SPR_IBAT0U + 2*i]; env->IBAT[1][i] = env->spr[SPR_IBAT0U + 2*i + 1]; } for (i = 0; (i < 4) && ((i+4) < env->nb_BATs); i++) { env->DBAT[0][i+4] = env->spr[SPR_DBAT4U + 2*i]; env->DBAT[1][i+4] = env->spr[SPR_DBAT4U + 2*i + 1]; env->IBAT[0][i+4] = env->spr[SPR_IBAT4U + 2*i]; env->IBAT[1][i+4] = env->spr[SPR_IBAT4U + 2*i + 1]; } /* Restore htab_base and htab_mask variables */ ppc_store_sdr1(env, env->spr[SPR_SDR1]); hreg_compute_hflags(env); hreg_compute_mem_idx(env); return 0; }
static int cpu_post_load(void *opaque, int version_id) { PowerPCCPU *cpu = opaque; CPUPPCState *env = &cpu->env; int i; target_ulong msr; /* * We always ignore the source PVR. The user or management * software has to take care of running QEMU in a compatible mode. */ env->spr[SPR_PVR] = env->spr_cb[SPR_PVR].default_value; env->lr = env->spr[SPR_LR]; env->ctr = env->spr[SPR_CTR]; cpu_write_xer(env, env->spr[SPR_XER]); #if defined(TARGET_PPC64) env->cfar = env->spr[SPR_CFAR]; #endif env->spe_fscr = env->spr[SPR_BOOKE_SPEFSCR]; for (i = 0; (i < 4) && (i < env->nb_BATs); i++) { env->DBAT[0][i] = env->spr[SPR_DBAT0U + 2*i]; env->DBAT[1][i] = env->spr[SPR_DBAT0U + 2*i + 1]; env->IBAT[0][i] = env->spr[SPR_IBAT0U + 2*i]; env->IBAT[1][i] = env->spr[SPR_IBAT0U + 2*i + 1]; } for (i = 0; (i < 4) && ((i+4) < env->nb_BATs); i++) { env->DBAT[0][i+4] = env->spr[SPR_DBAT4U + 2*i]; env->DBAT[1][i+4] = env->spr[SPR_DBAT4U + 2*i + 1]; env->IBAT[0][i+4] = env->spr[SPR_IBAT4U + 2*i]; env->IBAT[1][i+4] = env->spr[SPR_IBAT4U + 2*i + 1]; } if (!env->external_htab) { /* Restore htab_base and htab_mask variables */ ppc_store_sdr1(env, env->spr[SPR_SDR1]); } /* Invalidate all msr bits except MSR_TGPR/MSR_HVB before restoring */ msr = env->msr; env->msr ^= ~((1ULL << MSR_TGPR) | MSR_HVB); ppc_store_msr(env, msr); hreg_compute_mem_idx(env); return 0; }
static int cpu_load_old(QEMUFile *f, void *opaque, int version_id) { PowerPCCPU *cpu = opaque; CPUPPCState *env = &cpu->env; unsigned int i, j; target_ulong sdr1; uint32_t fpscr; target_ulong xer; for (i = 0; i < 32; i++) qemu_get_betls(f, &env->gpr[i]); #if !defined(TARGET_PPC64) for (i = 0; i < 32; i++) qemu_get_betls(f, &env->gprh[i]); #endif qemu_get_betls(f, &env->lr); qemu_get_betls(f, &env->ctr); for (i = 0; i < 8; i++) qemu_get_be32s(f, &env->crf[i]); qemu_get_betls(f, &xer); cpu_write_xer(env, xer); qemu_get_betls(f, &env->reserve_addr); qemu_get_betls(f, &env->msr); for (i = 0; i < 4; i++) qemu_get_betls(f, &env->tgpr[i]); for (i = 0; i < 32; i++) { union { float64 d; uint64_t l; } u; u.l = qemu_get_be64(f); env->fpr[i] = u.d; } qemu_get_be32s(f, &fpscr); env->fpscr = fpscr; qemu_get_sbe32s(f, &env->access_type); #if defined(TARGET_PPC64) qemu_get_betls(f, &env->spr[SPR_ASR]); qemu_get_sbe32s(f, &env->slb_nr); #endif qemu_get_betls(f, &sdr1); for (i = 0; i < 32; i++) qemu_get_betls(f, &env->sr[i]); for (i = 0; i < 2; i++) for (j = 0; j < 8; j++) qemu_get_betls(f, &env->DBAT[i][j]); for (i = 0; i < 2; i++) for (j = 0; j < 8; j++) qemu_get_betls(f, &env->IBAT[i][j]); qemu_get_sbe32s(f, &env->nb_tlb); qemu_get_sbe32s(f, &env->tlb_per_way); qemu_get_sbe32s(f, &env->nb_ways); qemu_get_sbe32s(f, &env->last_way); qemu_get_sbe32s(f, &env->id_tlbs); qemu_get_sbe32s(f, &env->nb_pids); if (env->tlb.tlb6) { // XXX assumes 6xx for (i = 0; i < env->nb_tlb; i++) { qemu_get_betls(f, &env->tlb.tlb6[i].pte0); qemu_get_betls(f, &env->tlb.tlb6[i].pte1); qemu_get_betls(f, &env->tlb.tlb6[i].EPN); } } for (i = 0; i < 4; i++) qemu_get_betls(f, &env->pb[i]); for (i = 0; i < 1024; i++) qemu_get_betls(f, &env->spr[i]); if (!env->external_htab) { ppc_store_sdr1(env, sdr1); } qemu_get_be32s(f, &env->vscr); qemu_get_be64s(f, &env->spe_acc); qemu_get_be32s(f, &env->spe_fscr); qemu_get_betls(f, &env->msr_mask); qemu_get_be32s(f, &env->flags); qemu_get_sbe32s(f, &env->error_code); qemu_get_be32s(f, &env->pending_interrupts); qemu_get_be32s(f, &env->irq_input_state); for (i = 0; i < POWERPC_EXCP_NB; i++) qemu_get_betls(f, &env->excp_vectors[i]); qemu_get_betls(f, &env->excp_prefix); qemu_get_betls(f, &env->ivor_mask); qemu_get_betls(f, &env->ivpr_mask); qemu_get_betls(f, &env->hreset_vector); qemu_get_betls(f, &env->nip); qemu_get_betls(f, &env->hflags); qemu_get_betls(f, &env->hflags_nmsr); qemu_get_sbe32s(f, &env->mmu_idx); qemu_get_sbe32(f); /* Discard unused power_mode */ return 0; }
static int cpu_post_load(void *opaque, int version_id) { PowerPCCPU *cpu = opaque; CPUPPCState *env = &cpu->env; int i; target_ulong msr; /* * If we're operating in compat mode, we should be ok as long as * the destination supports the same compatiblity mode. * * Otherwise, however, we require that the destination has exactly * the same CPU model as the source. */ #if defined(TARGET_PPC64) if (cpu->compat_pvr) { uint32_t compat_pvr = cpu->compat_pvr; Error *local_err = NULL; cpu->compat_pvr = 0; ppc_set_compat(cpu, compat_pvr, &local_err); if (local_err) { error_report_err(local_err); return -1; } } else #endif { if (!pvr_match(cpu, env->spr[SPR_PVR])) { return -1; } } /* * If we're running with KVM HV, there is a chance that the guest * is running with KVM HV and its kernel does not have the * capability of dealing with a different PVR other than this * exact host PVR in KVM_SET_SREGS. If that happens, the * guest freezes after migration. * * The function kvmppc_pvr_workaround_required does this verification * by first checking if the kernel has the cap, returning true immediately * if that is the case. Otherwise, it checks if we're running in KVM PR. * If the guest kernel does not have the cap and we're not running KVM-PR * (so, it is running KVM-HV), we need to ensure that KVM_SET_SREGS will * receive the PVR it expects as a workaround. * */ #if defined(CONFIG_KVM) if (kvmppc_pvr_workaround_required(cpu)) { env->spr[SPR_PVR] = env->spr_cb[SPR_PVR].default_value; } #endif env->lr = env->spr[SPR_LR]; env->ctr = env->spr[SPR_CTR]; cpu_write_xer(env, env->spr[SPR_XER]); #if defined(TARGET_PPC64) env->cfar = env->spr[SPR_CFAR]; #endif env->spe_fscr = env->spr[SPR_BOOKE_SPEFSCR]; for (i = 0; (i < 4) && (i < env->nb_BATs); i++) { env->DBAT[0][i] = env->spr[SPR_DBAT0U + 2*i]; env->DBAT[1][i] = env->spr[SPR_DBAT0U + 2*i + 1]; env->IBAT[0][i] = env->spr[SPR_IBAT0U + 2*i]; env->IBAT[1][i] = env->spr[SPR_IBAT0U + 2*i + 1]; } for (i = 0; (i < 4) && ((i+4) < env->nb_BATs); i++) { env->DBAT[0][i+4] = env->spr[SPR_DBAT4U + 2*i]; env->DBAT[1][i+4] = env->spr[SPR_DBAT4U + 2*i + 1]; env->IBAT[0][i+4] = env->spr[SPR_IBAT4U + 2*i]; env->IBAT[1][i+4] = env->spr[SPR_IBAT4U + 2*i + 1]; } if (!cpu->vhyp) { ppc_store_sdr1(env, env->spr[SPR_SDR1]); } /* Invalidate all supported msr bits except MSR_TGPR/MSR_HVB before restoring */ msr = env->msr; env->msr ^= env->msr_mask & ~((1ULL << MSR_TGPR) | MSR_HVB); ppc_store_msr(env, msr); hreg_compute_mem_idx(env); return 0; }