]> git.proxmox.com Git - qemu.git/blob - target-i386/machine.c
x86: mcg_cap is never 0
[qemu.git] / target-i386 / machine.c
1 #include "hw/hw.h"
2 #include "hw/boards.h"
3 #include "hw/pc.h"
4 #include "hw/isa.h"
5 #include "host-utils.h"
6
7 #include "exec-all.h"
8 #include "kvm.h"
9
10 static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
11 {
12 qemu_put_be32(f, dt->selector);
13 qemu_put_betl(f, dt->base);
14 qemu_put_be32(f, dt->limit);
15 qemu_put_be32(f, dt->flags);
16 }
17
18 static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
19 {
20 dt->selector = qemu_get_be32(f);
21 dt->base = qemu_get_betl(f);
22 dt->limit = qemu_get_be32(f);
23 dt->flags = qemu_get_be32(f);
24 }
25
26 void cpu_save(QEMUFile *f, void *opaque)
27 {
28 CPUState *env = opaque;
29 int i, bit;
30
31 cpu_synchronize_state(env);
32
33 for(i = 0; i < CPU_NB_REGS; i++)
34 qemu_put_betls(f, &env->regs[i]);
35 qemu_put_betls(f, &env->eip);
36 qemu_put_betls(f, &env->eflags);
37 qemu_put_be32s(f, &env->hflags);
38
39 /* FPU */
40 env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
41 env->fptag_vmstate = 0;
42 for(i = 0; i < 8; i++) {
43 env->fptag_vmstate |= ((!env->fptags[i]) << i);
44 }
45
46 qemu_put_be16s(f, &env->fpuc);
47 qemu_put_be16s(f, &env->fpus_vmstate);
48 qemu_put_be16s(f, &env->fptag_vmstate);
49
50 #ifdef USE_X86LDOUBLE
51 env->fpregs_format_vmstate = 0;
52 #else
53 env->fpregs_format_vmstate = 1;
54 #endif
55 qemu_put_be16s(f, &env->fpregs_format_vmstate);
56
57 for(i = 0; i < 8; i++) {
58 #ifdef USE_X86LDOUBLE
59 {
60 uint64_t mant;
61 uint16_t exp;
62 /* we save the real CPU data (in case of MMX usage only 'mant'
63 contains the MMX register */
64 cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
65 qemu_put_be64(f, mant);
66 qemu_put_be16(f, exp);
67 }
68 #else
69 /* if we use doubles for float emulation, we save the doubles to
70 avoid losing information in case of MMX usage. It can give
71 problems if the image is restored on a CPU where long
72 doubles are used instead. */
73 qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0));
74 #endif
75 }
76
77 for(i = 0; i < 6; i++)
78 cpu_put_seg(f, &env->segs[i]);
79 cpu_put_seg(f, &env->ldt);
80 cpu_put_seg(f, &env->tr);
81 cpu_put_seg(f, &env->gdt);
82 cpu_put_seg(f, &env->idt);
83
84 qemu_put_be32s(f, &env->sysenter_cs);
85 qemu_put_betls(f, &env->sysenter_esp);
86 qemu_put_betls(f, &env->sysenter_eip);
87
88 qemu_put_betls(f, &env->cr[0]);
89 qemu_put_betls(f, &env->cr[2]);
90 qemu_put_betls(f, &env->cr[3]);
91 qemu_put_betls(f, &env->cr[4]);
92
93 for(i = 0; i < 8; i++)
94 qemu_put_betls(f, &env->dr[i]);
95
96 /* MMU */
97 qemu_put_sbe32s(f, &env->a20_mask);
98
99 /* XMM */
100 qemu_put_be32s(f, &env->mxcsr);
101 for(i = 0; i < CPU_NB_REGS; i++) {
102 qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
103 qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
104 }
105
106 #ifdef TARGET_X86_64
107 qemu_put_be64s(f, &env->efer);
108 qemu_put_be64s(f, &env->star);
109 qemu_put_be64s(f, &env->lstar);
110 qemu_put_be64s(f, &env->cstar);
111 qemu_put_be64s(f, &env->fmask);
112 qemu_put_be64s(f, &env->kernelgsbase);
113 #endif
114 qemu_put_be32s(f, &env->smbase);
115
116 qemu_put_be64s(f, &env->pat);
117 qemu_put_be32s(f, &env->hflags2);
118
119 qemu_put_be64s(f, &env->vm_hsave);
120 qemu_put_be64s(f, &env->vm_vmcb);
121 qemu_put_be64s(f, &env->tsc_offset);
122 qemu_put_be64s(f, &env->intercept);
123 qemu_put_be16s(f, &env->intercept_cr_read);
124 qemu_put_be16s(f, &env->intercept_cr_write);
125 qemu_put_be16s(f, &env->intercept_dr_read);
126 qemu_put_be16s(f, &env->intercept_dr_write);
127 qemu_put_be32s(f, &env->intercept_exceptions);
128 qemu_put_8s(f, &env->v_tpr);
129
130 /* MTRRs */
131 for(i = 0; i < 11; i++)
132 qemu_put_be64s(f, &env->mtrr_fixed[i]);
133 qemu_put_be64s(f, &env->mtrr_deftype);
134 for(i = 0; i < 8; i++) {
135 qemu_put_be64s(f, &env->mtrr_var[i].base);
136 qemu_put_be64s(f, &env->mtrr_var[i].mask);
137 }
138
139 /* KVM-related states */
140
141 /* There can only be one pending IRQ set in the bitmap at a time, so try
142 to find it and save its number instead (-1 for none). */
143 env->pending_irq_vmstate = -1;
144 for (i = 0; i < ARRAY_SIZE(env->interrupt_bitmap); i++) {
145 if (env->interrupt_bitmap[i]) {
146 bit = ctz64(env->interrupt_bitmap[i]);
147 env->pending_irq_vmstate = i * 64 + bit;
148 break;
149 }
150 }
151 qemu_put_sbe32s(f, &env->pending_irq_vmstate);
152 qemu_put_be32s(f, &env->mp_state);
153 qemu_put_be64s(f, &env->tsc);
154
155 /* MCE */
156 qemu_put_be64s(f, &env->mcg_cap);
157 qemu_put_be64s(f, &env->mcg_status);
158 qemu_put_be64s(f, &env->mcg_ctl);
159 for (i = 0; i < MCE_BANKS_DEF * 4; i++) {
160 qemu_put_be64s(f, &env->mce_banks[i]);
161 }
162 qemu_put_be64s(f, &env->tsc_aux);
163 }
164
165 #ifdef USE_X86LDOUBLE
166 /* XXX: add that in a FPU generic layer */
167 union x86_longdouble {
168 uint64_t mant;
169 uint16_t exp;
170 };
171
172 #define MANTD1(fp) (fp & ((1LL << 52) - 1))
173 #define EXPBIAS1 1023
174 #define EXPD1(fp) ((fp >> 52) & 0x7FF)
175 #define SIGND1(fp) ((fp >> 32) & 0x80000000)
176
177 static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
178 {
179 int e;
180 /* mantissa */
181 p->mant = (MANTD1(temp) << 11) | (1LL << 63);
182 /* exponent + sign */
183 e = EXPD1(temp) - EXPBIAS1 + 16383;
184 e |= SIGND1(temp) >> 16;
185 p->exp = e;
186 }
187 #endif
188
189 int cpu_load(QEMUFile *f, void *opaque, int version_id)
190 {
191 CPUState *env = opaque;
192 int i, guess_mmx;
193
194 cpu_synchronize_state(env);
195 if (version_id < 3 || version_id > CPU_SAVE_VERSION)
196 return -EINVAL;
197 for(i = 0; i < CPU_NB_REGS; i++)
198 qemu_get_betls(f, &env->regs[i]);
199 qemu_get_betls(f, &env->eip);
200 qemu_get_betls(f, &env->eflags);
201 qemu_get_be32s(f, &env->hflags);
202
203 qemu_get_be16s(f, &env->fpuc);
204 qemu_get_be16s(f, &env->fpus_vmstate);
205 qemu_get_be16s(f, &env->fptag_vmstate);
206 qemu_get_be16s(f, &env->fpregs_format_vmstate);
207
208 /* NOTE: we cannot always restore the FPU state if the image come
209 from a host with a different 'USE_X86LDOUBLE' define. We guess
210 if we are in an MMX state to restore correctly in that case. */
211 guess_mmx = ((env->fptag_vmstate == 0xff) && (env->fpus_vmstate & 0x3800) == 0);
212 for(i = 0; i < 8; i++) {
213 uint64_t mant;
214 uint16_t exp;
215
216 switch(env->fpregs_format_vmstate) {
217 case 0:
218 mant = qemu_get_be64(f);
219 exp = qemu_get_be16(f);
220 #ifdef USE_X86LDOUBLE
221 env->fpregs[i].d = cpu_set_fp80(mant, exp);
222 #else
223 /* difficult case */
224 if (guess_mmx)
225 env->fpregs[i].mmx.MMX_Q(0) = mant;
226 else
227 env->fpregs[i].d = cpu_set_fp80(mant, exp);
228 #endif
229 break;
230 case 1:
231 mant = qemu_get_be64(f);
232 #ifdef USE_X86LDOUBLE
233 {
234 union x86_longdouble *p;
235 /* difficult case */
236 p = (void *)&env->fpregs[i];
237 if (guess_mmx) {
238 p->mant = mant;
239 p->exp = 0xffff;
240 } else {
241 fp64_to_fp80(p, mant);
242 }
243 }
244 #else
245 env->fpregs[i].mmx.MMX_Q(0) = mant;
246 #endif
247 break;
248 default:
249 return -EINVAL;
250 }
251 }
252
253 /* XXX: restore FPU round state */
254 env->fpstt = (env->fpus_vmstate >> 11) & 7;
255 env->fpus = env->fpus_vmstate & ~0x3800;
256 env->fptag_vmstate ^= 0xff;
257 for(i = 0; i < 8; i++) {
258 env->fptags[i] = (env->fptag_vmstate >> i) & 1;
259 }
260
261 for(i = 0; i < 6; i++)
262 cpu_get_seg(f, &env->segs[i]);
263 cpu_get_seg(f, &env->ldt);
264 cpu_get_seg(f, &env->tr);
265 cpu_get_seg(f, &env->gdt);
266 cpu_get_seg(f, &env->idt);
267
268 qemu_get_be32s(f, &env->sysenter_cs);
269 if (version_id >= 7) {
270 qemu_get_betls(f, &env->sysenter_esp);
271 qemu_get_betls(f, &env->sysenter_eip);
272 } else {
273 env->sysenter_esp = qemu_get_be32(f);
274 env->sysenter_eip = qemu_get_be32(f);
275 }
276
277 qemu_get_betls(f, &env->cr[0]);
278 qemu_get_betls(f, &env->cr[2]);
279 qemu_get_betls(f, &env->cr[3]);
280 qemu_get_betls(f, &env->cr[4]);
281
282 for(i = 0; i < 8; i++)
283 qemu_get_betls(f, &env->dr[i]);
284 cpu_breakpoint_remove_all(env, BP_CPU);
285 cpu_watchpoint_remove_all(env, BP_CPU);
286 for (i = 0; i < 4; i++)
287 hw_breakpoint_insert(env, i);
288
289 qemu_get_sbe32s(f, &env->a20_mask);
290
291 qemu_get_be32s(f, &env->mxcsr);
292 for(i = 0; i < CPU_NB_REGS; i++) {
293 qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
294 qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
295 }
296
297 #ifdef TARGET_X86_64
298 qemu_get_be64s(f, &env->efer);
299 qemu_get_be64s(f, &env->star);
300 qemu_get_be64s(f, &env->lstar);
301 qemu_get_be64s(f, &env->cstar);
302 qemu_get_be64s(f, &env->fmask);
303 qemu_get_be64s(f, &env->kernelgsbase);
304 #endif
305 if (version_id >= 4) {
306 qemu_get_be32s(f, &env->smbase);
307 }
308 if (version_id >= 5) {
309 qemu_get_be64s(f, &env->pat);
310 qemu_get_be32s(f, &env->hflags2);
311 if (version_id < 6)
312 qemu_get_be32s(f, &env->halted);
313
314 qemu_get_be64s(f, &env->vm_hsave);
315 qemu_get_be64s(f, &env->vm_vmcb);
316 qemu_get_be64s(f, &env->tsc_offset);
317 qemu_get_be64s(f, &env->intercept);
318 qemu_get_be16s(f, &env->intercept_cr_read);
319 qemu_get_be16s(f, &env->intercept_cr_write);
320 qemu_get_be16s(f, &env->intercept_dr_read);
321 qemu_get_be16s(f, &env->intercept_dr_write);
322 qemu_get_be32s(f, &env->intercept_exceptions);
323 qemu_get_8s(f, &env->v_tpr);
324 }
325
326 if (version_id >= 8) {
327 /* MTRRs */
328 for(i = 0; i < 11; i++)
329 qemu_get_be64s(f, &env->mtrr_fixed[i]);
330 qemu_get_be64s(f, &env->mtrr_deftype);
331 for(i = 0; i < 8; i++) {
332 qemu_get_be64s(f, &env->mtrr_var[i].base);
333 qemu_get_be64s(f, &env->mtrr_var[i].mask);
334 }
335 }
336
337 if (version_id >= 9) {
338 qemu_get_sbe32s(f, &env->pending_irq_vmstate);
339 memset(&env->interrupt_bitmap, 0, sizeof(env->interrupt_bitmap));
340 if (env->pending_irq_vmstate >= 0) {
341 env->interrupt_bitmap[env->pending_irq_vmstate / 64] |=
342 (uint64_t)1 << (env->pending_irq_vmstate % 64);
343 }
344 qemu_get_be32s(f, &env->mp_state);
345 qemu_get_be64s(f, &env->tsc);
346 }
347
348 if (version_id >= 10) {
349 qemu_get_be64s(f, &env->mcg_cap);
350 qemu_get_be64s(f, &env->mcg_status);
351 qemu_get_be64s(f, &env->mcg_ctl);
352 for (i = 0; i < MCE_BANKS_DEF * 4; i++) {
353 qemu_get_be64s(f, &env->mce_banks[i]);
354 }
355 }
356
357 if (version_id >= 11) {
358 qemu_get_be64s(f, &env->tsc_aux);
359 }
360
361 tlb_flush(env, 1);
362 return 0;
363 }