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