Home | History | Annotate | Download | only in target-mips
      1 #include "hw/hw.h"
      2 #include "hw/boards.h"
      3 
      4 #include "exec-all.h"
      5 
      6 static void save_tc(QEMUFile *f, TCState *tc)
      7 {
      8     int i;
      9 
     10     /* Save active TC */
     11     for(i = 0; i < 32; i++)
     12         qemu_put_betls(f, &tc->gpr[i]);
     13     qemu_put_betls(f, &tc->PC);
     14     for(i = 0; i < MIPS_DSP_ACC; i++)
     15         qemu_put_betls(f, &tc->HI[i]);
     16     for(i = 0; i < MIPS_DSP_ACC; i++)
     17         qemu_put_betls(f, &tc->LO[i]);
     18     for(i = 0; i < MIPS_DSP_ACC; i++)
     19         qemu_put_betls(f, &tc->ACX[i]);
     20     qemu_put_betls(f, &tc->DSPControl);
     21     qemu_put_sbe32s(f, &tc->CP0_TCStatus);
     22     qemu_put_sbe32s(f, &tc->CP0_TCBind);
     23     qemu_put_betls(f, &tc->CP0_TCHalt);
     24     qemu_put_betls(f, &tc->CP0_TCContext);
     25     qemu_put_betls(f, &tc->CP0_TCSchedule);
     26     qemu_put_betls(f, &tc->CP0_TCScheFBack);
     27     qemu_put_sbe32s(f, &tc->CP0_Debug_tcstatus);
     28 }
     29 
     30 static void save_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
     31 {
     32     int i;
     33 
     34     for(i = 0; i < 32; i++)
     35         qemu_put_be64s(f, &fpu->fpr[i].d);
     36     qemu_put_s8s(f, &fpu->fp_status.float_detect_tininess);
     37     qemu_put_s8s(f, &fpu->fp_status.float_rounding_mode);
     38     qemu_put_s8s(f, &fpu->fp_status.float_exception_flags);
     39     qemu_put_be32s(f, &fpu->fcr0);
     40     qemu_put_be32s(f, &fpu->fcr31);
     41 }
     42 
     43 void cpu_save(QEMUFile *f, void *opaque)
     44 {
     45     CPUState *env = opaque;
     46     int i;
     47 
     48     /* Save active TC */
     49     save_tc(f, &env->active_tc);
     50 
     51     /* Save active FPU */
     52     save_fpu(f, &env->active_fpu);
     53 
     54     /* Save MVP */
     55     qemu_put_sbe32s(f, &env->mvp->CP0_MVPControl);
     56     qemu_put_sbe32s(f, &env->mvp->CP0_MVPConf0);
     57     qemu_put_sbe32s(f, &env->mvp->CP0_MVPConf1);
     58 
     59     /* Save TLB */
     60     qemu_put_be32s(f, &env->tlb->nb_tlb);
     61     for(i = 0; i < MIPS_TLB_MAX; i++) {
     62         uint16_t flags = ((env->tlb->mmu.r4k.tlb[i].G << 10) |
     63                           (env->tlb->mmu.r4k.tlb[i].C0 << 7) |
     64                           (env->tlb->mmu.r4k.tlb[i].C1 << 4) |
     65                           (env->tlb->mmu.r4k.tlb[i].V0 << 3) |
     66                           (env->tlb->mmu.r4k.tlb[i].V1 << 2) |
     67                           (env->tlb->mmu.r4k.tlb[i].D0 << 1) |
     68                           (env->tlb->mmu.r4k.tlb[i].D1 << 0));
     69         uint8_t asid;
     70 
     71         qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
     72         qemu_put_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
     73         asid = env->tlb->mmu.r4k.tlb[i].ASID;
     74         qemu_put_8s(f, &asid);
     75         qemu_put_be16s(f, &flags);
     76         qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
     77         qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
     78     }
     79 
     80     /* Save CPU metastate */
     81     qemu_put_be32s(f, &env->current_tc);
     82     qemu_put_be32s(f, &env->current_fpu);
     83     qemu_put_sbe32s(f, &env->error_code);
     84     qemu_put_be32s(f, &env->hflags);
     85     qemu_put_betls(f, &env->btarget);
     86     i = env->bcond;
     87     qemu_put_sbe32s(f, &i);
     88 
     89     /* Save remaining CP1 registers */
     90     qemu_put_sbe32s(f, &env->CP0_Index);
     91     qemu_put_sbe32s(f, &env->CP0_Random);
     92     qemu_put_sbe32s(f, &env->CP0_VPEControl);
     93     qemu_put_sbe32s(f, &env->CP0_VPEConf0);
     94     qemu_put_sbe32s(f, &env->CP0_VPEConf1);
     95     qemu_put_betls(f, &env->CP0_YQMask);
     96     qemu_put_betls(f, &env->CP0_VPESchedule);
     97     qemu_put_betls(f, &env->CP0_VPEScheFBack);
     98     qemu_put_sbe32s(f, &env->CP0_VPEOpt);
     99     qemu_put_betls(f, &env->CP0_EntryLo0);
    100     qemu_put_betls(f, &env->CP0_EntryLo1);
    101     qemu_put_betls(f, &env->CP0_Context);
    102     qemu_put_sbe32s(f, &env->CP0_PageMask);
    103     qemu_put_sbe32s(f, &env->CP0_PageGrain);
    104     qemu_put_sbe32s(f, &env->CP0_Wired);
    105     qemu_put_sbe32s(f, &env->CP0_SRSConf0);
    106     qemu_put_sbe32s(f, &env->CP0_SRSConf1);
    107     qemu_put_sbe32s(f, &env->CP0_SRSConf2);
    108     qemu_put_sbe32s(f, &env->CP0_SRSConf3);
    109     qemu_put_sbe32s(f, &env->CP0_SRSConf4);
    110     qemu_put_sbe32s(f, &env->CP0_HWREna);
    111     qemu_put_betls(f, &env->CP0_BadVAddr);
    112     qemu_put_sbe32s(f, &env->CP0_Count);
    113     qemu_put_betls(f, &env->CP0_EntryHi);
    114     qemu_put_sbe32s(f, &env->CP0_Compare);
    115     qemu_put_sbe32s(f, &env->CP0_Status);
    116     qemu_put_sbe32s(f, &env->CP0_IntCtl);
    117     qemu_put_sbe32s(f, &env->CP0_SRSCtl);
    118     qemu_put_sbe32s(f, &env->CP0_SRSMap);
    119     qemu_put_sbe32s(f, &env->CP0_Cause);
    120     qemu_put_betls(f, &env->CP0_EPC);
    121     qemu_put_sbe32s(f, &env->CP0_PRid);
    122     qemu_put_sbe32s(f, &env->CP0_EBase);
    123     qemu_put_sbe32s(f, &env->CP0_Config0);
    124     qemu_put_sbe32s(f, &env->CP0_Config1);
    125     qemu_put_sbe32s(f, &env->CP0_Config2);
    126     qemu_put_sbe32s(f, &env->CP0_Config3);
    127     qemu_put_sbe32s(f, &env->CP0_Config6);
    128     qemu_put_sbe32s(f, &env->CP0_Config7);
    129     qemu_put_betls(f, &env->lladdr);
    130     for(i = 0; i < 8; i++)
    131         qemu_put_betls(f, &env->CP0_WatchLo[i]);
    132     for(i = 0; i < 8; i++)
    133         qemu_put_sbe32s(f, &env->CP0_WatchHi[i]);
    134     qemu_put_betls(f, &env->CP0_XContext);
    135     qemu_put_sbe32s(f, &env->CP0_Framemask);
    136     qemu_put_sbe32s(f, &env->CP0_Debug);
    137     qemu_put_betls(f, &env->CP0_DEPC);
    138     qemu_put_sbe32s(f, &env->CP0_Performance0);
    139     qemu_put_sbe32s(f, &env->CP0_TagLo);
    140     qemu_put_sbe32s(f, &env->CP0_DataLo);
    141     qemu_put_sbe32s(f, &env->CP0_TagHi);
    142     qemu_put_sbe32s(f, &env->CP0_DataHi);
    143     qemu_put_betls(f, &env->CP0_ErrorEPC);
    144     qemu_put_sbe32s(f, &env->CP0_DESAVE);
    145 
    146     /* Save inactive TC state */
    147     for (i = 0; i < MIPS_SHADOW_SET_MAX; i++)
    148         save_tc(f, &env->tcs[i]);
    149     for (i = 0; i < MIPS_FPU_MAX; i++)
    150         save_fpu(f, &env->fpus[i]);
    151 }
    152 
    153 static void load_tc(QEMUFile *f, TCState *tc)
    154 {
    155     int i;
    156 
    157     /* Save active TC */
    158     for(i = 0; i < 32; i++)
    159         qemu_get_betls(f, &tc->gpr[i]);
    160     qemu_get_betls(f, &tc->PC);
    161     for(i = 0; i < MIPS_DSP_ACC; i++)
    162         qemu_get_betls(f, &tc->HI[i]);
    163     for(i = 0; i < MIPS_DSP_ACC; i++)
    164         qemu_get_betls(f, &tc->LO[i]);
    165     for(i = 0; i < MIPS_DSP_ACC; i++)
    166         qemu_get_betls(f, &tc->ACX[i]);
    167     qemu_get_betls(f, &tc->DSPControl);
    168     qemu_get_sbe32s(f, &tc->CP0_TCStatus);
    169     qemu_get_sbe32s(f, &tc->CP0_TCBind);
    170     qemu_get_betls(f, &tc->CP0_TCHalt);
    171     qemu_get_betls(f, &tc->CP0_TCContext);
    172     qemu_get_betls(f, &tc->CP0_TCSchedule);
    173     qemu_get_betls(f, &tc->CP0_TCScheFBack);
    174     qemu_get_sbe32s(f, &tc->CP0_Debug_tcstatus);
    175 }
    176 
    177 static void load_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
    178 {
    179     int i;
    180 
    181     for(i = 0; i < 32; i++)
    182         qemu_get_be64s(f, &fpu->fpr[i].d);
    183     qemu_get_s8s(f, &fpu->fp_status.float_detect_tininess);
    184     qemu_get_s8s(f, &fpu->fp_status.float_rounding_mode);
    185     qemu_get_s8s(f, &fpu->fp_status.float_exception_flags);
    186     qemu_get_be32s(f, &fpu->fcr0);
    187     qemu_get_be32s(f, &fpu->fcr31);
    188 }
    189 
    190 int cpu_load(QEMUFile *f, void *opaque, int version_id)
    191 {
    192     CPUState *env = opaque;
    193     int i;
    194 
    195     if (version_id != 3)
    196         return -EINVAL;
    197 
    198     /* Load active TC */
    199     load_tc(f, &env->active_tc);
    200 
    201     /* Load active FPU */
    202     load_fpu(f, &env->active_fpu);
    203 
    204     /* Load MVP */
    205     qemu_get_sbe32s(f, &env->mvp->CP0_MVPControl);
    206     qemu_get_sbe32s(f, &env->mvp->CP0_MVPConf0);
    207     qemu_get_sbe32s(f, &env->mvp->CP0_MVPConf1);
    208 
    209     /* Load TLB */
    210     qemu_get_be32s(f, &env->tlb->nb_tlb);
    211     for(i = 0; i < MIPS_TLB_MAX; i++) {
    212         uint16_t flags;
    213         uint8_t asid;
    214 
    215         qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
    216         qemu_get_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
    217         qemu_get_8s(f, &asid);
    218         env->tlb->mmu.r4k.tlb[i].ASID = asid;
    219         qemu_get_be16s(f, &flags);
    220         env->tlb->mmu.r4k.tlb[i].G = (flags >> 10) & 1;
    221         env->tlb->mmu.r4k.tlb[i].C0 = (flags >> 7) & 3;
    222         env->tlb->mmu.r4k.tlb[i].C1 = (flags >> 4) & 3;
    223         env->tlb->mmu.r4k.tlb[i].V0 = (flags >> 3) & 1;
    224         env->tlb->mmu.r4k.tlb[i].V1 = (flags >> 2) & 1;
    225         env->tlb->mmu.r4k.tlb[i].D0 = (flags >> 1) & 1;
    226         env->tlb->mmu.r4k.tlb[i].D1 = (flags >> 0) & 1;
    227         qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
    228         qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
    229     }
    230 
    231     /* Load CPU metastate */
    232     qemu_get_be32s(f, &env->current_tc);
    233     qemu_get_be32s(f, &env->current_fpu);
    234     qemu_get_sbe32s(f, &env->error_code);
    235     qemu_get_be32s(f, &env->hflags);
    236     qemu_get_betls(f, &env->btarget);
    237     qemu_get_sbe32s(f, &i);
    238     env->bcond = i;
    239 
    240     /* Load remaining CP1 registers */
    241     qemu_get_sbe32s(f, &env->CP0_Index);
    242     qemu_get_sbe32s(f, &env->CP0_Random);
    243     qemu_get_sbe32s(f, &env->CP0_VPEControl);
    244     qemu_get_sbe32s(f, &env->CP0_VPEConf0);
    245     qemu_get_sbe32s(f, &env->CP0_VPEConf1);
    246     qemu_get_betls(f, &env->CP0_YQMask);
    247     qemu_get_betls(f, &env->CP0_VPESchedule);
    248     qemu_get_betls(f, &env->CP0_VPEScheFBack);
    249     qemu_get_sbe32s(f, &env->CP0_VPEOpt);
    250     qemu_get_betls(f, &env->CP0_EntryLo0);
    251     qemu_get_betls(f, &env->CP0_EntryLo1);
    252     qemu_get_betls(f, &env->CP0_Context);
    253     qemu_get_sbe32s(f, &env->CP0_PageMask);
    254     qemu_get_sbe32s(f, &env->CP0_PageGrain);
    255     qemu_get_sbe32s(f, &env->CP0_Wired);
    256     qemu_get_sbe32s(f, &env->CP0_SRSConf0);
    257     qemu_get_sbe32s(f, &env->CP0_SRSConf1);
    258     qemu_get_sbe32s(f, &env->CP0_SRSConf2);
    259     qemu_get_sbe32s(f, &env->CP0_SRSConf3);
    260     qemu_get_sbe32s(f, &env->CP0_SRSConf4);
    261     qemu_get_sbe32s(f, &env->CP0_HWREna);
    262     qemu_get_betls(f, &env->CP0_BadVAddr);
    263     qemu_get_sbe32s(f, &env->CP0_Count);
    264     qemu_get_betls(f, &env->CP0_EntryHi);
    265     qemu_get_sbe32s(f, &env->CP0_Compare);
    266     qemu_get_sbe32s(f, &env->CP0_Status);
    267     qemu_get_sbe32s(f, &env->CP0_IntCtl);
    268     qemu_get_sbe32s(f, &env->CP0_SRSCtl);
    269     qemu_get_sbe32s(f, &env->CP0_SRSMap);
    270     qemu_get_sbe32s(f, &env->CP0_Cause);
    271     qemu_get_betls(f, &env->CP0_EPC);
    272     qemu_get_sbe32s(f, &env->CP0_PRid);
    273     qemu_get_sbe32s(f, &env->CP0_EBase);
    274     qemu_get_sbe32s(f, &env->CP0_Config0);
    275     qemu_get_sbe32s(f, &env->CP0_Config1);
    276     qemu_get_sbe32s(f, &env->CP0_Config2);
    277     qemu_get_sbe32s(f, &env->CP0_Config3);
    278     qemu_get_sbe32s(f, &env->CP0_Config6);
    279     qemu_get_sbe32s(f, &env->CP0_Config7);
    280     qemu_get_betls(f, &env->lladdr);
    281     for(i = 0; i < 8; i++)
    282         qemu_get_betls(f, &env->CP0_WatchLo[i]);
    283     for(i = 0; i < 8; i++)
    284         qemu_get_sbe32s(f, &env->CP0_WatchHi[i]);
    285     qemu_get_betls(f, &env->CP0_XContext);
    286     qemu_get_sbe32s(f, &env->CP0_Framemask);
    287     qemu_get_sbe32s(f, &env->CP0_Debug);
    288     qemu_get_betls(f, &env->CP0_DEPC);
    289     qemu_get_sbe32s(f, &env->CP0_Performance0);
    290     qemu_get_sbe32s(f, &env->CP0_TagLo);
    291     qemu_get_sbe32s(f, &env->CP0_DataLo);
    292     qemu_get_sbe32s(f, &env->CP0_TagHi);
    293     qemu_get_sbe32s(f, &env->CP0_DataHi);
    294     qemu_get_betls(f, &env->CP0_ErrorEPC);
    295     qemu_get_sbe32s(f, &env->CP0_DESAVE);
    296 
    297     /* Load inactive TC state */
    298     for (i = 0; i < MIPS_SHADOW_SET_MAX; i++)
    299         load_tc(f, &env->tcs[i]);
    300     for (i = 0; i < MIPS_FPU_MAX; i++)
    301         load_fpu(f, &env->fpus[i]);
    302 
    303     /* XXX: ensure compatiblity for halted bit ? */
    304     tlb_flush(env, 1);
    305     return 0;
    306 }
    307