Add support for building the kvm external module
[qemu-kvm/fedora.git] / target-i386 / machine.c
blob399204deb300236ec8477cfc0c43755af9ac812b
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 for(i = 0; i < CPU_NB_REGS; i++)
200 qemu_get_betls(f, &env->regs[i]);
201 qemu_get_betls(f, &env->eip);
202 qemu_get_betls(f, &env->eflags);
203 qemu_get_be32s(f, &hflags);
205 qemu_get_be16s(f, &fpuc);
206 qemu_get_be16s(f, &fpus);
207 qemu_get_be16s(f, &fptag);
208 qemu_get_be16s(f, &fpregs_format);
210 /* NOTE: we cannot always restore the FPU state if the image come
211 from a host with a different 'USE_X86LDOUBLE' define. We guess
212 if we are in an MMX state to restore correctly in that case. */
213 guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
214 for(i = 0; i < 8; i++) {
215 uint64_t mant;
216 uint16_t exp;
218 switch(fpregs_format) {
219 case 0:
220 mant = qemu_get_be64(f);
221 exp = qemu_get_be16(f);
222 #ifdef USE_X86LDOUBLE
223 env->fpregs[i].d = cpu_set_fp80(mant, exp);
224 #else
225 /* difficult case */
226 if (guess_mmx)
227 env->fpregs[i].mmx.MMX_Q(0) = mant;
228 else
229 env->fpregs[i].d = cpu_set_fp80(mant, exp);
230 #endif
231 break;
232 case 1:
233 mant = qemu_get_be64(f);
234 #ifdef USE_X86LDOUBLE
236 union x86_longdouble *p;
237 /* difficult case */
238 p = (void *)&env->fpregs[i];
239 if (guess_mmx) {
240 p->mant = mant;
241 p->exp = 0xffff;
242 } else {
243 fp64_to_fp80(p, mant);
246 #else
247 env->fpregs[i].mmx.MMX_Q(0) = mant;
248 #endif
249 break;
250 default:
251 return -EINVAL;
255 env->fpuc = fpuc;
256 /* XXX: restore FPU round state */
257 env->fpstt = (fpus >> 11) & 7;
258 env->fpus = fpus & ~0x3800;
259 fptag ^= 0xff;
260 for(i = 0; i < 8; i++) {
261 env->fptags[i] = (fptag >> i) & 1;
264 for(i = 0; i < 6; i++)
265 cpu_get_seg(f, &env->segs[i]);
266 cpu_get_seg(f, &env->ldt);
267 cpu_get_seg(f, &env->tr);
268 cpu_get_seg(f, &env->gdt);
269 cpu_get_seg(f, &env->idt);
271 qemu_get_be32s(f, &env->sysenter_cs);
272 if (version_id >= 7) {
273 qemu_get_betls(f, &env->sysenter_esp);
274 qemu_get_betls(f, &env->sysenter_eip);
275 } else {
276 env->sysenter_esp = qemu_get_be32(f);
277 env->sysenter_eip = qemu_get_be32(f);
280 qemu_get_betls(f, &env->cr[0]);
281 qemu_get_betls(f, &env->cr[2]);
282 qemu_get_betls(f, &env->cr[3]);
283 qemu_get_betls(f, &env->cr[4]);
285 for(i = 0; i < 8; i++)
286 qemu_get_betls(f, &env->dr[i]);
287 cpu_breakpoint_remove_all(env, BP_CPU);
288 cpu_watchpoint_remove_all(env, BP_CPU);
289 for (i = 0; i < 4; i++)
290 hw_breakpoint_insert(env, i);
292 /* MMU */
293 qemu_get_sbe32s(f, &a20_mask);
294 env->a20_mask = a20_mask;
296 qemu_get_be32s(f, &env->mxcsr);
297 for(i = 0; i < CPU_NB_REGS; i++) {
298 qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
299 qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
302 #ifdef TARGET_X86_64
303 qemu_get_be64s(f, &env->efer);
304 qemu_get_be64s(f, &env->star);
305 qemu_get_be64s(f, &env->lstar);
306 qemu_get_be64s(f, &env->cstar);
307 qemu_get_be64s(f, &env->fmask);
308 qemu_get_be64s(f, &env->kernelgsbase);
309 #endif
310 if (version_id >= 4) {
311 qemu_get_be32s(f, &env->smbase);
313 if (version_id >= 5) {
314 qemu_get_be64s(f, &env->pat);
315 qemu_get_be32s(f, &env->hflags2);
316 if (version_id < 6)
317 qemu_get_be32s(f, &env->halted);
319 qemu_get_be64s(f, &env->vm_hsave);
320 qemu_get_be64s(f, &env->vm_vmcb);
321 qemu_get_be64s(f, &env->tsc_offset);
322 qemu_get_be64s(f, &env->intercept);
323 qemu_get_be16s(f, &env->intercept_cr_read);
324 qemu_get_be16s(f, &env->intercept_cr_write);
325 qemu_get_be16s(f, &env->intercept_dr_read);
326 qemu_get_be16s(f, &env->intercept_dr_write);
327 qemu_get_be32s(f, &env->intercept_exceptions);
328 qemu_get_8s(f, &env->v_tpr);
331 if (version_id >= 8) {
332 /* MTRRs */
333 for(i = 0; i < 11; i++)
334 qemu_get_be64s(f, &env->mtrr_fixed[i]);
335 qemu_get_be64s(f, &env->mtrr_deftype);
336 for(i = 0; i < 8; i++) {
337 qemu_get_be64s(f, &env->mtrr_var[i].base);
338 qemu_get_be64s(f, &env->mtrr_var[i].mask);
342 /* XXX: ensure compatiblity for halted bit ? */
343 /* XXX: compute redundant hflags bits */
344 env->hflags = hflags;
345 tlb_flush(env, 1);
346 if (kvm_enabled()) {
347 /* when in-kernel irqchip is used, env->halted causes deadlock
348 because no userspace IRQs will ever clear this flag */
349 env->halted = 0;
350 for (i = 0; i < sizeof(env->interrupt_bitmap)/8; i++) {
351 qemu_get_be64s(f, &env->interrupt_bitmap[i]);
353 qemu_get_be64s(f, &env->tsc);
354 kvm_load_registers(env);
355 kvm_load_tsc(env);
356 if (version_id >= 5) {
357 qemu_get_be32s(f, &env->mp_state);
358 kvm_load_mpstate(env);
361 return 0;