1 #include "hw/hw.h" 2 #include "hw/boards.h" 3 #include "hw/i386/pc.h" 4 #include "hw/isa/isa.h" 5 6 #include "cpu.h" 7 #include "sysemu/kvm.h" 8 9 static void cpu_put_seg(QEMUFile *f, SegmentCache *dt) 10 { 11 qemu_put_be32(f, dt->selector); 12 qemu_put_betl(f, dt->base); 13 qemu_put_be32(f, dt->limit); 14 qemu_put_be32(f, dt->flags); 15 } 16 17 static void cpu_get_seg(QEMUFile *f, SegmentCache *dt) 18 { 19 dt->selector = qemu_get_be32(f); 20 dt->base = qemu_get_betl(f); 21 dt->limit = qemu_get_be32(f); 22 dt->flags = qemu_get_be32(f); 23 } 24 25 void cpu_save(QEMUFile *f, void *opaque) 26 { 27 CPUX86State *env = opaque; 28 uint16_t fptag, fpus, fpuc, fpregs_format; 29 uint32_t hflags; 30 int32_t a20_mask; 31 int i; 32 33 cpu_synchronize_state(ENV_GET_CPU(env), 0); 34 35 for(i = 0; i < CPU_NB_REGS; i++) 36 qemu_put_betls(f, &env->regs[i]); 37 qemu_put_betls(f, &env->eip); 38 qemu_put_betls(f, &env->eflags); 39 hflags = env->hflags; /* XXX: suppress most of the redundant hflags */ 40 qemu_put_be32s(f, &hflags); 41 42 /* FPU */ 43 fpuc = env->fpuc; 44 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; 45 fptag = 0; 46 for(i = 0; i < 8; i++) { 47 fptag |= ((!env->fptags[i]) << i); 48 } 49 50 qemu_put_be16s(f, &fpuc); 51 qemu_put_be16s(f, &fpus); 52 qemu_put_be16s(f, &fptag); 53 54 fpregs_format = 1; 55 qemu_put_be16s(f, &fpregs_format); 56 57 for(i = 0; i < 8; i++) { 58 /* if we use doubles for float emulation, we save the doubles to 59 avoid losing information in case of MMX usage. It can give 60 problems if the image is restored on a CPU where long 61 doubles are used instead. */ 62 qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0)); 63 } 64 65 for(i = 0; i < 6; i++) 66 cpu_put_seg(f, &env->segs[i]); 67 cpu_put_seg(f, &env->ldt); 68 cpu_put_seg(f, &env->tr); 69 cpu_put_seg(f, &env->gdt); 70 cpu_put_seg(f, &env->idt); 71 72 qemu_put_be32s(f, &env->sysenter_cs); 73 qemu_put_betls(f, &env->sysenter_esp); 74 qemu_put_betls(f, &env->sysenter_eip); 75 76 qemu_put_betls(f, &env->cr[0]); 77 qemu_put_betls(f, &env->cr[2]); 78 qemu_put_betls(f, &env->cr[3]); 79 qemu_put_betls(f, &env->cr[4]); 80 81 for(i = 0; i < 8; i++) 82 qemu_put_betls(f, &env->dr[i]); 83 84 /* MMU */ 85 a20_mask = (int32_t) env->a20_mask; 86 qemu_put_sbe32s(f, &a20_mask); 87 88 /* XMM */ 89 qemu_put_be32s(f, &env->mxcsr); 90 for(i = 0; i < CPU_NB_REGS; i++) { 91 qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0)); 92 qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1)); 93 } 94 95 #ifdef TARGET_X86_64 96 qemu_put_be64s(f, &env->efer); 97 qemu_put_be64s(f, &env->star); 98 qemu_put_be64s(f, &env->lstar); 99 qemu_put_be64s(f, &env->cstar); 100 qemu_put_be64s(f, &env->fmask); 101 qemu_put_be64s(f, &env->kernelgsbase); 102 #endif 103 qemu_put_be32s(f, &env->smbase); 104 105 qemu_put_be64s(f, &env->pat); 106 qemu_put_be32s(f, &env->hflags2); 107 108 qemu_put_be64s(f, &env->vm_hsave); 109 qemu_put_be64s(f, &env->vm_vmcb); 110 qemu_put_be64s(f, &env->tsc_offset); 111 qemu_put_be64s(f, &env->intercept); 112 qemu_put_be16s(f, &env->intercept_cr_read); 113 qemu_put_be16s(f, &env->intercept_cr_write); 114 qemu_put_be16s(f, &env->intercept_dr_read); 115 qemu_put_be16s(f, &env->intercept_dr_write); 116 qemu_put_be32s(f, &env->intercept_exceptions); 117 qemu_put_8s(f, &env->v_tpr); 118 119 /* MTRRs */ 120 for(i = 0; i < 11; i++) 121 qemu_put_be64s(f, &env->mtrr_fixed[i]); 122 qemu_put_be64s(f, &env->mtrr_deftype); 123 for(i = 0; i < 8; i++) { 124 qemu_put_be64s(f, &env->mtrr_var[i].base); 125 qemu_put_be64s(f, &env->mtrr_var[i].mask); 126 } 127 128 for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) { 129 qemu_put_be64s(f, &env->interrupt_bitmap[i]); 130 } 131 qemu_put_be64s(f, &env->tsc); 132 qemu_put_be32s(f, &env->mp_state); 133 134 /* MCE */ 135 qemu_put_be64s(f, &env->mcg_cap); 136 if (env->mcg_cap) { 137 qemu_put_be64s(f, &env->mcg_status); 138 qemu_put_be64s(f, &env->mcg_ctl); 139 for (i = 0; i < (env->mcg_cap & 0xff); i++) { 140 qemu_put_be64s(f, &env->mce_banks[4*i]); 141 qemu_put_be64s(f, &env->mce_banks[4*i + 1]); 142 qemu_put_be64s(f, &env->mce_banks[4*i + 2]); 143 qemu_put_be64s(f, &env->mce_banks[4*i + 3]); 144 } 145 } 146 } 147 148 int cpu_load(QEMUFile *f, void *opaque, int version_id) 149 { 150 CPUX86State *env = opaque; 151 int i, guess_mmx; 152 uint32_t hflags; 153 uint16_t fpus, fpuc, fptag, fpregs_format; 154 int32_t a20_mask; 155 156 if (version_id < 3 || version_id > CPU_SAVE_VERSION) 157 return -EINVAL; 158 for(i = 0; i < CPU_NB_REGS; i++) 159 qemu_get_betls(f, &env->regs[i]); 160 qemu_get_betls(f, &env->eip); 161 qemu_get_betls(f, &env->eflags); 162 qemu_get_be32s(f, &hflags); 163 164 qemu_get_be16s(f, &fpuc); 165 qemu_get_be16s(f, &fpus); 166 qemu_get_be16s(f, &fptag); 167 qemu_get_be16s(f, &fpregs_format); 168 169 /* NOTE: we cannot always restore the FPU state if the image come 170 from a host with a different 'USE_X86LDOUBLE' define. We guess 171 if we are in an MMX state to restore correctly in that case. */ 172 guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0); 173 for(i = 0; i < 8; i++) { 174 uint64_t mant; 175 uint16_t exp; 176 177 switch(fpregs_format) { 178 case 0: 179 mant = qemu_get_be64(f); 180 exp = qemu_get_be16(f); 181 /* difficult case */ 182 if (guess_mmx) 183 env->fpregs[i].mmx.MMX_Q(0) = mant; 184 else 185 env->fpregs[i].d = cpu_set_fp80(mant, exp); 186 break; 187 case 1: 188 mant = qemu_get_be64(f); 189 env->fpregs[i].mmx.MMX_Q(0) = mant; 190 break; 191 default: 192 return -EINVAL; 193 } 194 } 195 196 env->fpuc = fpuc; 197 /* XXX: restore FPU round state */ 198 env->fpstt = (fpus >> 11) & 7; 199 env->fpus = fpus & ~0x3800; 200 fptag ^= 0xff; 201 for(i = 0; i < 8; i++) { 202 env->fptags[i] = (fptag >> i) & 1; 203 } 204 205 for(i = 0; i < 6; i++) 206 cpu_get_seg(f, &env->segs[i]); 207 cpu_get_seg(f, &env->ldt); 208 cpu_get_seg(f, &env->tr); 209 cpu_get_seg(f, &env->gdt); 210 cpu_get_seg(f, &env->idt); 211 212 qemu_get_be32s(f, &env->sysenter_cs); 213 if (version_id >= 7) { 214 qemu_get_betls(f, &env->sysenter_esp); 215 qemu_get_betls(f, &env->sysenter_eip); 216 } else { 217 env->sysenter_esp = qemu_get_be32(f); 218 env->sysenter_eip = qemu_get_be32(f); 219 } 220 221 qemu_get_betls(f, &env->cr[0]); 222 qemu_get_betls(f, &env->cr[2]); 223 qemu_get_betls(f, &env->cr[3]); 224 qemu_get_betls(f, &env->cr[4]); 225 226 for(i = 0; i < 8; i++) 227 qemu_get_betls(f, &env->dr[i]); 228 cpu_breakpoint_remove_all(env, BP_CPU); 229 cpu_watchpoint_remove_all(env, BP_CPU); 230 for (i = 0; i < 4; i++) 231 hw_breakpoint_insert(env, i); 232 233 /* MMU */ 234 qemu_get_sbe32s(f, &a20_mask); 235 env->a20_mask = a20_mask; 236 237 qemu_get_be32s(f, &env->mxcsr); 238 for(i = 0; i < CPU_NB_REGS; i++) { 239 qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0)); 240 qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1)); 241 } 242 243 #ifdef TARGET_X86_64 244 qemu_get_be64s(f, &env->efer); 245 qemu_get_be64s(f, &env->star); 246 qemu_get_be64s(f, &env->lstar); 247 qemu_get_be64s(f, &env->cstar); 248 qemu_get_be64s(f, &env->fmask); 249 qemu_get_be64s(f, &env->kernelgsbase); 250 #endif 251 if (version_id >= 4) { 252 qemu_get_be32s(f, &env->smbase); 253 } 254 if (version_id >= 5) { 255 qemu_get_be64s(f, &env->pat); 256 qemu_get_be32s(f, &env->hflags2); 257 if (version_id < 6) 258 qemu_get_be32s(f, &ENV_GET_CPU(env)->halted); 259 260 qemu_get_be64s(f, &env->vm_hsave); 261 qemu_get_be64s(f, &env->vm_vmcb); 262 qemu_get_be64s(f, &env->tsc_offset); 263 qemu_get_be64s(f, &env->intercept); 264 qemu_get_be16s(f, &env->intercept_cr_read); 265 qemu_get_be16s(f, &env->intercept_cr_write); 266 qemu_get_be16s(f, &env->intercept_dr_read); 267 qemu_get_be16s(f, &env->intercept_dr_write); 268 qemu_get_be32s(f, &env->intercept_exceptions); 269 qemu_get_8s(f, &env->v_tpr); 270 } 271 272 if (version_id >= 8) { 273 /* MTRRs */ 274 for(i = 0; i < 11; i++) 275 qemu_get_be64s(f, &env->mtrr_fixed[i]); 276 qemu_get_be64s(f, &env->mtrr_deftype); 277 for(i = 0; i < 8; i++) { 278 qemu_get_be64s(f, &env->mtrr_var[i].base); 279 qemu_get_be64s(f, &env->mtrr_var[i].mask); 280 } 281 } 282 if (version_id >= 9) { 283 for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) { 284 qemu_get_be64s(f, &env->interrupt_bitmap[i]); 285 } 286 qemu_get_be64s(f, &env->tsc); 287 qemu_get_be32s(f, &env->mp_state); 288 } 289 290 if (version_id >= 10) { 291 qemu_get_be64s(f, &env->mcg_cap); 292 if (env->mcg_cap) { 293 qemu_get_be64s(f, &env->mcg_status); 294 qemu_get_be64s(f, &env->mcg_ctl); 295 for (i = 0; i < (env->mcg_cap & 0xff); i++) { 296 qemu_get_be64s(f, &env->mce_banks[4*i]); 297 qemu_get_be64s(f, &env->mce_banks[4*i + 1]); 298 qemu_get_be64s(f, &env->mce_banks[4*i + 2]); 299 qemu_get_be64s(f, &env->mce_banks[4*i + 3]); 300 } 301 } 302 } 303 304 305 /* XXX: ensure compatiblity for halted bit ? */ 306 /* XXX: compute redundant hflags bits */ 307 env->hflags = hflags; 308 tlb_flush(env, 1); 309 cpu_synchronize_state(ENV_GET_CPU(env), 1); 310 return 0; 311 } 312