Commit 33a84765e34421dc4e009dea8176ac17474aff97

Authored by ths
1 parent f9480ffc

A first attempt on supporting snapshots for the MIPS target.

Signed-off-by: Thiemo Seufer <ths@networkno.de>


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