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