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