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