예제 #1
0
파일: machine.c 프로젝트: 01org/qemu-lite
static void cpu_pre_save(void *opaque)
{
    PowerPCCPU *cpu = opaque;
    CPUPPCState *env = &cpu->env;
    int i;

    env->spr[SPR_LR] = env->lr;
    env->spr[SPR_CTR] = env->ctr;
    env->spr[SPR_XER] = cpu_read_xer(env);
#if defined(TARGET_PPC64)
    env->spr[SPR_CFAR] = env->cfar;
#endif
    env->spr[SPR_BOOKE_SPEFSCR] = env->spe_fscr;

    for (i = 0; (i < 4) && (i < env->nb_BATs); i++) {
        env->spr[SPR_DBAT0U + 2*i] = env->DBAT[0][i];
        env->spr[SPR_DBAT0U + 2*i + 1] = env->DBAT[1][i];
        env->spr[SPR_IBAT0U + 2*i] = env->IBAT[0][i];
        env->spr[SPR_IBAT0U + 2*i + 1] = env->IBAT[1][i];
    }
    for (i = 0; (i < 4) && ((i+4) < env->nb_BATs); i++) {
        env->spr[SPR_DBAT4U + 2*i] = env->DBAT[0][i+4];
        env->spr[SPR_DBAT4U + 2*i + 1] = env->DBAT[1][i+4];
        env->spr[SPR_IBAT4U + 2*i] = env->IBAT[0][i+4];
        env->spr[SPR_IBAT4U + 2*i + 1] = env->IBAT[1][i+4];
    }
}
예제 #2
0
파일: machine.c 프로젝트: BernardXiong/qemu
void cpu_save(QEMUFile *f, void *opaque)
{
    CPUPPCState *env = (CPUPPCState *)opaque;
    unsigned int i, j;
    uint32_t fpscr;
    target_ulong xer;

    for (i = 0; i < 32; i++)
        qemu_put_betls(f, &env->gpr[i]);
#if !defined(TARGET_PPC64)
    for (i = 0; i < 32; i++)
        qemu_put_betls(f, &env->gprh[i]);
#endif
    qemu_put_betls(f, &env->lr);
    qemu_put_betls(f, &env->ctr);
    for (i = 0; i < 8; i++)
        qemu_put_be32s(f, &env->crf[i]);
    xer = cpu_read_xer(env);
    qemu_put_betls(f, &xer);
    qemu_put_betls(f, &env->reserve_addr);
    qemu_put_betls(f, &env->msr);
    for (i = 0; i < 4; i++)
        qemu_put_betls(f, &env->tgpr[i]);
    for (i = 0; i < 32; i++) {
        union {
            float64 d;
            uint64_t l;
        } u;
        u.d = env->fpr[i];
        qemu_put_be64(f, u.l);
    }
    fpscr = env->fpscr;
    qemu_put_be32s(f, &fpscr);
    qemu_put_sbe32s(f, &env->access_type);
#if defined(TARGET_PPC64)
    qemu_put_betls(f, &env->spr[SPR_ASR]);
    qemu_put_sbe32s(f, &env->slb_nr);
#endif
    qemu_put_betls(f, &env->spr[SPR_SDR1]);
    for (i = 0; i < 32; i++)
        qemu_put_betls(f, &env->sr[i]);
    for (i = 0; i < 2; i++)
        for (j = 0; j < 8; j++)
            qemu_put_betls(f, &env->DBAT[i][j]);
    for (i = 0; i < 2; i++)
        for (j = 0; j < 8; j++)
            qemu_put_betls(f, &env->IBAT[i][j]);
    qemu_put_sbe32s(f, &env->nb_tlb);
    qemu_put_sbe32s(f, &env->tlb_per_way);
    qemu_put_sbe32s(f, &env->nb_ways);
    qemu_put_sbe32s(f, &env->last_way);
    qemu_put_sbe32s(f, &env->id_tlbs);
    qemu_put_sbe32s(f, &env->nb_pids);
    if (env->tlb.tlb6) {
        // XXX assumes 6xx
        for (i = 0; i < env->nb_tlb; i++) {
            qemu_put_betls(f, &env->tlb.tlb6[i].pte0);
            qemu_put_betls(f, &env->tlb.tlb6[i].pte1);
            qemu_put_betls(f, &env->tlb.tlb6[i].EPN);
        }
    }
    for (i = 0; i < 4; i++)
        qemu_put_betls(f, &env->pb[i]);
    for (i = 0; i < 1024; i++)
        qemu_put_betls(f, &env->spr[i]);
    qemu_put_be32s(f, &env->vscr);
    qemu_put_be64s(f, &env->spe_acc);
    qemu_put_be32s(f, &env->spe_fscr);
    qemu_put_betls(f, &env->msr_mask);
    qemu_put_be32s(f, &env->flags);
    qemu_put_sbe32s(f, &env->error_code);
    qemu_put_be32s(f, &env->pending_interrupts);
    qemu_put_be32s(f, &env->irq_input_state);
    for (i = 0; i < POWERPC_EXCP_NB; i++)
        qemu_put_betls(f, &env->excp_vectors[i]);
    qemu_put_betls(f, &env->excp_prefix);
    qemu_put_betls(f, &env->hreset_excp_prefix);
    qemu_put_betls(f, &env->ivor_mask);
    qemu_put_betls(f, &env->ivpr_mask);
    qemu_put_betls(f, &env->hreset_vector);
    qemu_put_betls(f, &env->nip);
    qemu_put_betls(f, &env->hflags);
    qemu_put_betls(f, &env->hflags_nmsr);
    qemu_put_sbe32s(f, &env->mmu_idx);
    qemu_put_sbe32(f, 0);
}
예제 #3
0
파일: kvm.c 프로젝트: jhaberstro/qemu
int kvm_arch_put_registers(CPUState *cs, int level)
{
    PowerPCCPU *cpu = POWERPC_CPU(cs);
    CPUPPCState *env = &cpu->env;
    struct kvm_regs regs;
    int ret;
    int i;

    ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
    if (ret < 0) {
        return ret;
    }

    regs.ctr = env->ctr;
    regs.lr  = env->lr;
    regs.xer = cpu_read_xer(env);
    regs.msr = env->msr;
    regs.pc = env->nip;

    regs.srr0 = env->spr[SPR_SRR0];
    regs.srr1 = env->spr[SPR_SRR1];

    regs.sprg0 = env->spr[SPR_SPRG0];
    regs.sprg1 = env->spr[SPR_SPRG1];
    regs.sprg2 = env->spr[SPR_SPRG2];
    regs.sprg3 = env->spr[SPR_SPRG3];
    regs.sprg4 = env->spr[SPR_SPRG4];
    regs.sprg5 = env->spr[SPR_SPRG5];
    regs.sprg6 = env->spr[SPR_SPRG6];
    regs.sprg7 = env->spr[SPR_SPRG7];

    regs.pid = env->spr[SPR_BOOKE_PID];

    for (i = 0;i < 32; i++)
        regs.gpr[i] = env->gpr[i];

    ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);
    if (ret < 0)
        return ret;

    kvm_put_fp(cs);

    if (env->tlb_dirty) {
        kvm_sw_tlb_put(cpu);
        env->tlb_dirty = false;
    }

    if (cap_segstate && (level >= KVM_PUT_RESET_STATE)) {
        struct kvm_sregs sregs;

        sregs.pvr = env->spr[SPR_PVR];

        sregs.u.s.sdr1 = env->spr[SPR_SDR1];

        /* Sync SLB */
#ifdef TARGET_PPC64
        for (i = 0; i < 64; i++) {
            sregs.u.s.ppc64.slb[i].slbe = env->slb[i].esid;
            sregs.u.s.ppc64.slb[i].slbv = env->slb[i].vsid;
        }
#endif

        /* Sync SRs */
        for (i = 0; i < 16; i++) {
            sregs.u.s.ppc32.sr[i] = env->sr[i];
        }

        /* Sync BATs */
        for (i = 0; i < 8; i++) {
            /* Beware. We have to swap upper and lower bits here */
            sregs.u.s.ppc32.dbat[i] = ((uint64_t)env->DBAT[0][i] << 32)
                | env->DBAT[1][i];
            sregs.u.s.ppc32.ibat[i] = ((uint64_t)env->IBAT[0][i] << 32)
                | env->IBAT[1][i];
        }

        ret = kvm_vcpu_ioctl(cs, KVM_SET_SREGS, &sregs);
        if (ret) {
            return ret;
        }
    }

    if (cap_hior && (level >= KVM_PUT_RESET_STATE)) {
        kvm_put_one_spr(cs, KVM_REG_PPC_HIOR, SPR_HIOR);
    }

    if (cap_one_reg) {
        int i;

        /* We deliberately ignore errors here, for kernels which have
         * the ONE_REG calls, but don't support the specific
         * registers, there's a reasonable chance things will still
         * work, at least until we try to migrate. */
        for (i = 0; i < 1024; i++) {
            uint64_t id = env->spr_cb[i].one_reg_id;

            if (id != 0) {
                kvm_put_one_spr(cs, id, i);
            }
        }
    }

    return ret;
}
예제 #4
0
파일: machine.c 프로젝트: cminyard/qemu
static int cpu_pre_save(void *opaque)
{
    PowerPCCPU *cpu = opaque;
    CPUPPCState *env = &cpu->env;
    int i;
    uint64_t insns_compat_mask =
        PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB
        | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES
        | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES
        | PPC_FLOAT_STFIWX | PPC_FLOAT_EXT
        | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ
        | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC
        | PPC_64B | PPC_64BX | PPC_ALTIVEC
        | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD;
    uint64_t insns_compat_mask2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX
        | PPC2_PERM_ISA206 | PPC2_DIVE_ISA206
        | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206
        | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207
        | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207
        | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM;

    env->spr[SPR_LR] = env->lr;
    env->spr[SPR_CTR] = env->ctr;
    env->spr[SPR_XER] = cpu_read_xer(env);
#if defined(TARGET_PPC64)
    env->spr[SPR_CFAR] = env->cfar;
#endif
    env->spr[SPR_BOOKE_SPEFSCR] = env->spe_fscr;

    for (i = 0; (i < 4) && (i < env->nb_BATs); i++) {
        env->spr[SPR_DBAT0U + 2*i] = env->DBAT[0][i];
        env->spr[SPR_DBAT0U + 2*i + 1] = env->DBAT[1][i];
        env->spr[SPR_IBAT0U + 2*i] = env->IBAT[0][i];
        env->spr[SPR_IBAT0U + 2*i + 1] = env->IBAT[1][i];
    }
    for (i = 0; (i < 4) && ((i+4) < env->nb_BATs); i++) {
        env->spr[SPR_DBAT4U + 2*i] = env->DBAT[0][i+4];
        env->spr[SPR_DBAT4U + 2*i + 1] = env->DBAT[1][i+4];
        env->spr[SPR_IBAT4U + 2*i] = env->IBAT[0][i+4];
        env->spr[SPR_IBAT4U + 2*i + 1] = env->IBAT[1][i+4];
    }

    /* Hacks for migration compatibility between 2.6, 2.7 & 2.8 */
    if (cpu->pre_2_8_migration) {
        /* Mask out bits that got added to msr_mask since the versions
         * which stupidly included it in the migration stream. */
        target_ulong metamask = 0
#if defined(TARGET_PPC64)
            | (1ULL << MSR_TS0)
            | (1ULL << MSR_TS1)
#endif
            ;
        cpu->mig_msr_mask = env->msr_mask & ~metamask;
        cpu->mig_insns_flags = env->insns_flags & insns_compat_mask;
        /* CPU models supported by old machines all have PPC_MEM_TLBIE,
         * so we set it unconditionally to allow backward migration from
         * a POWER9 host to a POWER8 host.
         */
        cpu->mig_insns_flags |= PPC_MEM_TLBIE;
        cpu->mig_insns_flags2 = env->insns_flags2 & insns_compat_mask2;
        cpu->mig_nb_BATs = env->nb_BATs;
    }
    if (cpu->pre_3_0_migration) {
        if (cpu->hash64_opts) {
            cpu->mig_slb_nr = cpu->hash64_opts->slb_size;
        }
    }

    return 0;
}