Remove the dependency for phys_ram_base for ipf.c
[qemu-kvm/fedora.git] / target-i386 / machine.c
blob7f75d31094124bc3c1bf1aa9196fd8b6884a6296
1 #include "hw/hw.h"
2 #include "hw/boards.h"
3 #include "hw/pc.h"
4 #include "hw/isa.h"
6 #include "exec-all.h"
7 #include "qemu-kvm.h"
9 void register_machines(void)
11 qemu_register_machine(&pc_machine);
12 qemu_register_machine(&isapc_machine);
13 #ifdef CONFIG_XEN
14 qemu_register_machine(&xenpv_machine);
15 #endif
18 static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
20 qemu_put_be32(f, dt->selector);
21 qemu_put_betl(f, dt->base);
22 qemu_put_be32(f, dt->limit);
23 qemu_put_be32(f, dt->flags);
26 static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
28 dt->selector = qemu_get_be32(f);
29 dt->base = qemu_get_betl(f);
30 dt->limit = qemu_get_be32(f);
31 dt->flags = qemu_get_be32(f);
34 void cpu_save(QEMUFile *f, void *opaque)
36 CPUState *env = opaque;
37 uint16_t fptag, fpus, fpuc, fpregs_format;
38 uint32_t hflags;
39 int32_t a20_mask;
40 int i;
42 if (kvm_enabled()) {
43 kvm_save_registers(env);
44 kvm_save_mpstate(env);
47 for(i = 0; i < CPU_NB_REGS; i++)
48 qemu_put_betls(f, &env->regs[i]);
49 qemu_put_betls(f, &env->eip);
50 qemu_put_betls(f, &env->eflags);
51 hflags = env->hflags; /* XXX: suppress most of the redundant hflags */
52 qemu_put_be32s(f, &hflags);
54 /* FPU */
55 fpuc = env->fpuc;
56 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
57 fptag = 0;
58 for(i = 0; i < 8; i++) {
59 fptag |= ((!env->fptags[i]) << i);
62 qemu_put_be16s(f, &fpuc);
63 qemu_put_be16s(f, &fpus);
64 qemu_put_be16s(f, &fptag);
66 #ifdef USE_X86LDOUBLE
67 fpregs_format = 0;
68 #else
69 fpregs_format = 1;
70 #endif
71 qemu_put_be16s(f, &fpregs_format);
73 for(i = 0; i < 8; i++) {
74 #ifdef USE_X86LDOUBLE
76 uint64_t mant;
77 uint16_t exp;
78 /* we save the real CPU data (in case of MMX usage only 'mant'
79 contains the MMX register */
80 cpu_get_fp80(&mant, &exp, env->fpregs[i].d);
81 qemu_put_be64(f, mant);
82 qemu_put_be16(f, exp);
84 #else
85 /* if we use doubles for float emulation, we save the doubles to
86 avoid losing information in case of MMX usage. It can give
87 problems if the image is restored on a CPU where long
88 doubles are used instead. */
89 qemu_put_be64(f, env->fpregs[i].mmx.MMX_Q(0));
90 #endif
93 for(i = 0; i < 6; i++)
94 cpu_put_seg(f, &env->segs[i]);
95 cpu_put_seg(f, &env->ldt);
96 cpu_put_seg(f, &env->tr);
97 cpu_put_seg(f, &env->gdt);
98 cpu_put_seg(f, &env->idt);
100 qemu_put_be32s(f, &env->sysenter_cs);
101 qemu_put_betls(f, &env->sysenter_esp);
102 qemu_put_betls(f, &env->sysenter_eip);
104 qemu_put_betls(f, &env->cr[0]);
105 qemu_put_betls(f, &env->cr[2]);
106 qemu_put_betls(f, &env->cr[3]);
107 qemu_put_betls(f, &env->cr[4]);
109 for(i = 0; i < 8; i++)
110 qemu_put_betls(f, &env->dr[i]);
112 /* MMU */
113 a20_mask = (int32_t) env->a20_mask;
114 qemu_put_sbe32s(f, &a20_mask);
116 /* XMM */
117 qemu_put_be32s(f, &env->mxcsr);
118 for(i = 0; i < CPU_NB_REGS; i++) {
119 qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(0));
120 qemu_put_be64s(f, &env->xmm_regs[i].XMM_Q(1));
123 #ifdef TARGET_X86_64
124 qemu_put_be64s(f, &env->efer);
125 qemu_put_be64s(f, &env->star);
126 qemu_put_be64s(f, &env->lstar);
127 qemu_put_be64s(f, &env->cstar);
128 qemu_put_be64s(f, &env->fmask);
129 qemu_put_be64s(f, &env->kernelgsbase);
130 #endif
131 qemu_put_be32s(f, &env->smbase);
132 qemu_put_be64s(f, &env->pat);
133 qemu_put_be32s(f, &env->hflags2);
135 qemu_put_be64s(f, &env->vm_hsave);
136 qemu_put_be64s(f, &env->vm_vmcb);
137 qemu_put_be64s(f, &env->tsc_offset);
138 qemu_put_be64s(f, &env->intercept);
139 qemu_put_be16s(f, &env->intercept_cr_read);
140 qemu_put_be16s(f, &env->intercept_cr_write);
141 qemu_put_be16s(f, &env->intercept_dr_read);
142 qemu_put_be16s(f, &env->intercept_dr_write);
143 qemu_put_be32s(f, &env->intercept_exceptions);
144 qemu_put_8s(f, &env->v_tpr);
146 /* MTRRs */
147 for(i = 0; i < 11; i++)
148 qemu_put_be64s(f, &env->mtrr_fixed[i]);
149 qemu_put_be64s(f, &env->mtrr_deftype);
150 for(i = 0; i < 8; i++) {
151 qemu_put_be64s(f, &env->mtrr_var[i].base);
152 qemu_put_be64s(f, &env->mtrr_var[i].mask);
155 if (kvm_enabled()) {
156 for (i = 0; i < sizeof(env->interrupt_bitmap)/8 ; i++) {
157 qemu_put_be64s(f, &env->interrupt_bitmap[i]);
159 qemu_put_be64s(f, &env->tsc);
160 qemu_put_be32s(f, &env->mp_state);
164 #ifdef USE_X86LDOUBLE
165 /* XXX: add that in a FPU generic layer */
166 union x86_longdouble {
167 uint64_t mant;
168 uint16_t exp;
171 #define MANTD1(fp) (fp & ((1LL << 52) - 1))
172 #define EXPBIAS1 1023
173 #define EXPD1(fp) ((fp >> 52) & 0x7FF)
174 #define SIGND1(fp) ((fp >> 32) & 0x80000000)
176 static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
178 int e;
179 /* mantissa */
180 p->mant = (MANTD1(temp) << 11) | (1LL << 63);
181 /* exponent + sign */
182 e = EXPD1(temp) - EXPBIAS1 + 16383;
183 e |= SIGND1(temp) >> 16;
184 p->exp = e;
186 #endif
188 int cpu_load(QEMUFile *f, void *opaque, int version_id)
190 CPUState *env = opaque;
191 int i, guess_mmx;
192 uint32_t hflags;
193 uint16_t fpus, fpuc, fptag, fpregs_format;
194 int32_t a20_mask;
196 if (version_id != 3 && version_id != 4 && version_id != 5
197 && version_id != 6 && version_id != 7 && version_id != 8)
198 return -EINVAL;
199 /* KVM cannot accept migrations from QEMU today */
200 if (version_id != 9)
201 return -EINVAL;
202 for(i = 0; i < CPU_NB_REGS; i++)
203 qemu_get_betls(f, &env->regs[i]);
204 qemu_get_betls(f, &env->eip);
205 qemu_get_betls(f, &env->eflags);
206 qemu_get_be32s(f, &hflags);
208 qemu_get_be16s(f, &fpuc);
209 qemu_get_be16s(f, &fpus);
210 qemu_get_be16s(f, &fptag);
211 qemu_get_be16s(f, &fpregs_format);
213 /* NOTE: we cannot always restore the FPU state if the image come
214 from a host with a different 'USE_X86LDOUBLE' define. We guess
215 if we are in an MMX state to restore correctly in that case. */
216 guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
217 for(i = 0; i < 8; i++) {
218 uint64_t mant;
219 uint16_t exp;
221 switch(fpregs_format) {
222 case 0:
223 mant = qemu_get_be64(f);
224 exp = qemu_get_be16(f);
225 #ifdef USE_X86LDOUBLE
226 env->fpregs[i].d = cpu_set_fp80(mant, exp);
227 #else
228 /* difficult case */
229 if (guess_mmx)
230 env->fpregs[i].mmx.MMX_Q(0) = mant;
231 else
232 env->fpregs[i].d = cpu_set_fp80(mant, exp);
233 #endif
234 break;
235 case 1:
236 mant = qemu_get_be64(f);
237 #ifdef USE_X86LDOUBLE
239 union x86_longdouble *p;
240 /* difficult case */
241 p = (void *)&env->fpregs[i];
242 if (guess_mmx) {
243 p->mant = mant;
244 p->exp = 0xffff;
245 } else {
246 fp64_to_fp80(p, mant);
249 #else
250 env->fpregs[i].mmx.MMX_Q(0) = mant;
251 #endif
252 break;
253 default:
254 return -EINVAL;
258 env->fpuc = fpuc;
259 /* XXX: restore FPU round state */
260 env->fpstt = (fpus >> 11) & 7;
261 env->fpus = fpus & ~0x3800;
262 fptag ^= 0xff;
263 for(i = 0; i < 8; i++) {
264 env->fptags[i] = (fptag >> i) & 1;
267 for(i = 0; i < 6; i++)
268 cpu_get_seg(f, &env->segs[i]);
269 cpu_get_seg(f, &env->ldt);
270 cpu_get_seg(f, &env->tr);
271 cpu_get_seg(f, &env->gdt);
272 cpu_get_seg(f, &env->idt);
274 qemu_get_be32s(f, &env->sysenter_cs);
275 if (version_id >= 7) {
276 qemu_get_betls(f, &env->sysenter_esp);
277 qemu_get_betls(f, &env->sysenter_eip);
278 } else {
279 env->sysenter_esp = qemu_get_be32(f);
280 env->sysenter_eip = qemu_get_be32(f);
283 qemu_get_betls(f, &env->cr[0]);
284 qemu_get_betls(f, &env->cr[2]);
285 qemu_get_betls(f, &env->cr[3]);
286 qemu_get_betls(f, &env->cr[4]);
288 for(i = 0; i < 8; i++)
289 qemu_get_betls(f, &env->dr[i]);
290 cpu_breakpoint_remove_all(env, BP_CPU);
291 cpu_watchpoint_remove_all(env, BP_CPU);
292 for (i = 0; i < 4; i++)
293 hw_breakpoint_insert(env, i);
295 /* MMU */
296 qemu_get_sbe32s(f, &a20_mask);
297 env->a20_mask = a20_mask;
299 qemu_get_be32s(f, &env->mxcsr);
300 for(i = 0; i < CPU_NB_REGS; i++) {
301 qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
302 qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
305 #ifdef TARGET_X86_64
306 qemu_get_be64s(f, &env->efer);
307 qemu_get_be64s(f, &env->star);
308 qemu_get_be64s(f, &env->lstar);
309 qemu_get_be64s(f, &env->cstar);
310 qemu_get_be64s(f, &env->fmask);
311 qemu_get_be64s(f, &env->kernelgsbase);
312 #endif
313 if (version_id >= 4) {
314 qemu_get_be32s(f, &env->smbase);
316 if (version_id >= 5) {
317 qemu_get_be64s(f, &env->pat);
318 qemu_get_be32s(f, &env->hflags2);
319 if (version_id < 6)
320 qemu_get_be32s(f, &env->halted);
322 qemu_get_be64s(f, &env->vm_hsave);
323 qemu_get_be64s(f, &env->vm_vmcb);
324 qemu_get_be64s(f, &env->tsc_offset);
325 qemu_get_be64s(f, &env->intercept);
326 qemu_get_be16s(f, &env->intercept_cr_read);
327 qemu_get_be16s(f, &env->intercept_cr_write);
328 qemu_get_be16s(f, &env->intercept_dr_read);
329 qemu_get_be16s(f, &env->intercept_dr_write);
330 qemu_get_be32s(f, &env->intercept_exceptions);
331 qemu_get_8s(f, &env->v_tpr);
334 if (version_id >= 8) {
335 /* MTRRs */
336 for(i = 0; i < 11; i++)
337 qemu_get_be64s(f, &env->mtrr_fixed[i]);
338 qemu_get_be64s(f, &env->mtrr_deftype);
339 for(i = 0; i < 8; i++) {
340 qemu_get_be64s(f, &env->mtrr_var[i].base);
341 qemu_get_be64s(f, &env->mtrr_var[i].mask);
345 /* XXX: ensure compatiblity for halted bit ? */
346 /* XXX: compute redundant hflags bits */
347 env->hflags = hflags;
348 tlb_flush(env, 1);
349 if (kvm_enabled()) {
350 /* when in-kernel irqchip is used, env->halted causes deadlock
351 because no userspace IRQs will ever clear this flag */
352 env->halted = 0;
353 for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) {
354 qemu_get_be64s(f, &env->interrupt_bitmap[i]);
356 qemu_get_be64s(f, &env->tsc);
357 kvm_load_registers(env);
358 kvm_load_tsc(env);
359 if (version_id >= 5) {
360 qemu_get_be32s(f, &env->mp_state);
361 kvm_load_mpstate(env);
364 return 0;