Statistics
| Branch: | Revision:

root / target-i386 / machine.c @ 49a945a3

History | View | Annotate | Download (13.6 kB)

1 8dd3dca3 aurel32
#include "hw/hw.h"
2 8dd3dca3 aurel32
#include "hw/boards.h"
3 8dd3dca3 aurel32
#include "hw/pc.h"
4 8dd3dca3 aurel32
#include "hw/isa.h"
5 8dd3dca3 aurel32
6 8dd3dca3 aurel32
#include "exec-all.h"
7 b0a46a33 Jan Kiszka
#include "kvm.h"
8 8dd3dca3 aurel32
9 66e6d55b Juan Quintela
static const VMStateDescription vmstate_segment = {
10 66e6d55b Juan Quintela
    .name = "segment",
11 66e6d55b Juan Quintela
    .version_id = 1,
12 66e6d55b Juan Quintela
    .minimum_version_id = 1,
13 66e6d55b Juan Quintela
    .minimum_version_id_old = 1,
14 66e6d55b Juan Quintela
    .fields      = (VMStateField []) {
15 66e6d55b Juan Quintela
        VMSTATE_UINT32(selector, SegmentCache),
16 66e6d55b Juan Quintela
        VMSTATE_UINTTL(base, SegmentCache),
17 66e6d55b Juan Quintela
        VMSTATE_UINT32(limit, SegmentCache),
18 66e6d55b Juan Quintela
        VMSTATE_UINT32(flags, SegmentCache),
19 66e6d55b Juan Quintela
        VMSTATE_END_OF_LIST()
20 66e6d55b Juan Quintela
    }
21 66e6d55b Juan Quintela
};
22 66e6d55b Juan Quintela
23 0cb892aa Juan Quintela
#define VMSTATE_SEGMENT(_field, _state) {                            \
24 0cb892aa Juan Quintela
    .name       = (stringify(_field)),                               \
25 0cb892aa Juan Quintela
    .size       = sizeof(SegmentCache),                              \
26 0cb892aa Juan Quintela
    .vmsd       = &vmstate_segment,                                  \
27 0cb892aa Juan Quintela
    .flags      = VMS_STRUCT,                                        \
28 0cb892aa Juan Quintela
    .offset     = offsetof(_state, _field)                           \
29 0cb892aa Juan Quintela
            + type_check(SegmentCache,typeof_field(_state, _field))  \
30 8dd3dca3 aurel32
}
31 8dd3dca3 aurel32
32 0cb892aa Juan Quintela
#define VMSTATE_SEGMENT_ARRAY(_field, _state, _n)                    \
33 0cb892aa Juan Quintela
    VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_segment, SegmentCache)
34 8dd3dca3 aurel32
35 fc3b0aa2 Juan Quintela
static const VMStateDescription vmstate_xmm_reg = {
36 fc3b0aa2 Juan Quintela
    .name = "xmm_reg",
37 fc3b0aa2 Juan Quintela
    .version_id = 1,
38 fc3b0aa2 Juan Quintela
    .minimum_version_id = 1,
39 fc3b0aa2 Juan Quintela
    .minimum_version_id_old = 1,
40 fc3b0aa2 Juan Quintela
    .fields      = (VMStateField []) {
41 fc3b0aa2 Juan Quintela
        VMSTATE_UINT64(XMM_Q(0), XMMReg),
42 fc3b0aa2 Juan Quintela
        VMSTATE_UINT64(XMM_Q(1), XMMReg),
43 fc3b0aa2 Juan Quintela
        VMSTATE_END_OF_LIST()
44 fc3b0aa2 Juan Quintela
    }
45 fc3b0aa2 Juan Quintela
};
46 fc3b0aa2 Juan Quintela
47 0cb892aa Juan Quintela
#define VMSTATE_XMM_REGS(_field, _state, _n)                         \
48 0cb892aa Juan Quintela
    VMSTATE_STRUCT_ARRAY(_field, _state, _n, 0, vmstate_xmm_reg, XMMReg)
49 fc3b0aa2 Juan Quintela
50 216c07c3 Juan Quintela
static const VMStateDescription vmstate_mtrr_var = {
51 216c07c3 Juan Quintela
    .name = "mtrr_var",
52 216c07c3 Juan Quintela
    .version_id = 1,
53 216c07c3 Juan Quintela
    .minimum_version_id = 1,
54 216c07c3 Juan Quintela
    .minimum_version_id_old = 1,
55 216c07c3 Juan Quintela
    .fields      = (VMStateField []) {
56 216c07c3 Juan Quintela
        VMSTATE_UINT64(base, MTRRVar),
57 216c07c3 Juan Quintela
        VMSTATE_UINT64(mask, MTRRVar),
58 216c07c3 Juan Quintela
        VMSTATE_END_OF_LIST()
59 216c07c3 Juan Quintela
    }
60 216c07c3 Juan Quintela
};
61 216c07c3 Juan Quintela
62 0cb892aa Juan Quintela
#define VMSTATE_MTRR_VARS(_field, _state, _n, _v)                    \
63 0cb892aa Juan Quintela
    VMSTATE_STRUCT_ARRAY(_field, _state, _n, _v, vmstate_mtrr_var, MTRRVar)
64 216c07c3 Juan Quintela
65 0cb892aa Juan Quintela
static void put_fpreg_error(QEMUFile *f, void *opaque, size_t size)
66 216c07c3 Juan Quintela
{
67 0cb892aa Juan Quintela
    fprintf(stderr, "call put_fpreg() with invalid arguments\n");
68 0cb892aa Juan Quintela
    exit(0);
69 216c07c3 Juan Quintela
}
70 216c07c3 Juan Quintela
71 3c8ce630 Juan Quintela
#ifdef USE_X86LDOUBLE
72 3c8ce630 Juan Quintela
/* XXX: add that in a FPU generic layer */
73 3c8ce630 Juan Quintela
union x86_longdouble {
74 3c8ce630 Juan Quintela
    uint64_t mant;
75 3c8ce630 Juan Quintela
    uint16_t exp;
76 3c8ce630 Juan Quintela
};
77 3c8ce630 Juan Quintela
78 3c8ce630 Juan Quintela
#define MANTD1(fp)        (fp & ((1LL << 52) - 1))
79 3c8ce630 Juan Quintela
#define EXPBIAS1 1023
80 3c8ce630 Juan Quintela
#define EXPD1(fp)        ((fp >> 52) & 0x7FF)
81 3c8ce630 Juan Quintela
#define SIGND1(fp)        ((fp >> 32) & 0x80000000)
82 3c8ce630 Juan Quintela
83 3c8ce630 Juan Quintela
static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
84 3c8ce630 Juan Quintela
{
85 3c8ce630 Juan Quintela
    int e;
86 3c8ce630 Juan Quintela
    /* mantissa */
87 3c8ce630 Juan Quintela
    p->mant = (MANTD1(temp) << 11) | (1LL << 63);
88 3c8ce630 Juan Quintela
    /* exponent + sign */
89 3c8ce630 Juan Quintela
    e = EXPD1(temp) - EXPBIAS1 + 16383;
90 3c8ce630 Juan Quintela
    e |= SIGND1(temp) >> 16;
91 3c8ce630 Juan Quintela
    p->exp = e;
92 3c8ce630 Juan Quintela
}
93 3c8ce630 Juan Quintela
94 3c8ce630 Juan Quintela
static int get_fpreg(QEMUFile *f, void *opaque, size_t size)
95 3c8ce630 Juan Quintela
{
96 3c8ce630 Juan Quintela
    FPReg *fp_reg = opaque;
97 3c8ce630 Juan Quintela
    uint64_t mant;
98 3c8ce630 Juan Quintela
    uint16_t exp;
99 3c8ce630 Juan Quintela
100 3c8ce630 Juan Quintela
    qemu_get_be64s(f, &mant);
101 3c8ce630 Juan Quintela
    qemu_get_be16s(f, &exp);
102 3c8ce630 Juan Quintela
    fp_reg->d = cpu_set_fp80(mant, exp);
103 3c8ce630 Juan Quintela
    return 0;
104 3c8ce630 Juan Quintela
}
105 3c8ce630 Juan Quintela
106 3c8ce630 Juan Quintela
static void put_fpreg(QEMUFile *f, void *opaque, size_t size)
107 3c8ce630 Juan Quintela
{
108 3c8ce630 Juan Quintela
    FPReg *fp_reg = opaque;
109 3c8ce630 Juan Quintela
    uint64_t mant;
110 3c8ce630 Juan Quintela
    uint16_t exp;
111 3c8ce630 Juan Quintela
    /* we save the real CPU data (in case of MMX usage only 'mant'
112 3c8ce630 Juan Quintela
       contains the MMX register */
113 3c8ce630 Juan Quintela
    cpu_get_fp80(&mant, &exp, fp_reg->d);
114 3c8ce630 Juan Quintela
    qemu_put_be64s(f, &mant);
115 3c8ce630 Juan Quintela
    qemu_put_be16s(f, &exp);
116 3c8ce630 Juan Quintela
}
117 3c8ce630 Juan Quintela
118 976b2037 Blue Swirl
static const VMStateInfo vmstate_fpreg = {
119 0cb892aa Juan Quintela
    .name = "fpreg",
120 0cb892aa Juan Quintela
    .get  = get_fpreg,
121 0cb892aa Juan Quintela
    .put  = put_fpreg,
122 0cb892aa Juan Quintela
};
123 0cb892aa Juan Quintela
124 3c8ce630 Juan Quintela
static int get_fpreg_1_mmx(QEMUFile *f, void *opaque, size_t size)
125 3c8ce630 Juan Quintela
{
126 3c8ce630 Juan Quintela
    union x86_longdouble *p = opaque;
127 3c8ce630 Juan Quintela
    uint64_t mant;
128 3c8ce630 Juan Quintela
129 3c8ce630 Juan Quintela
    qemu_get_be64s(f, &mant);
130 3c8ce630 Juan Quintela
    p->mant = mant;
131 3c8ce630 Juan Quintela
    p->exp = 0xffff;
132 3c8ce630 Juan Quintela
    return 0;
133 3c8ce630 Juan Quintela
}
134 3c8ce630 Juan Quintela
135 976b2037 Blue Swirl
static const VMStateInfo vmstate_fpreg_1_mmx = {
136 0cb892aa Juan Quintela
    .name = "fpreg_1_mmx",
137 0cb892aa Juan Quintela
    .get  = get_fpreg_1_mmx,
138 0cb892aa Juan Quintela
    .put  = put_fpreg_error,
139 0cb892aa Juan Quintela
};
140 0cb892aa Juan Quintela
141 3c8ce630 Juan Quintela
static int get_fpreg_1_no_mmx(QEMUFile *f, void *opaque, size_t size)
142 3c8ce630 Juan Quintela
{
143 3c8ce630 Juan Quintela
    union x86_longdouble *p = opaque;
144 3c8ce630 Juan Quintela
    uint64_t mant;
145 3c8ce630 Juan Quintela
146 3c8ce630 Juan Quintela
    qemu_get_be64s(f, &mant);
147 3c8ce630 Juan Quintela
    fp64_to_fp80(p, mant);
148 3c8ce630 Juan Quintela
    return 0;
149 3c8ce630 Juan Quintela
}
150 3c8ce630 Juan Quintela
151 976b2037 Blue Swirl
static const VMStateInfo vmstate_fpreg_1_no_mmx = {
152 0cb892aa Juan Quintela
    .name = "fpreg_1_no_mmx",
153 0cb892aa Juan Quintela
    .get  = get_fpreg_1_no_mmx,
154 0cb892aa Juan Quintela
    .put  = put_fpreg_error,
155 0cb892aa Juan Quintela
};
156 0cb892aa Juan Quintela
157 0cb892aa Juan Quintela
static bool fpregs_is_0(void *opaque, int version_id)
158 0cb892aa Juan Quintela
{
159 0cb892aa Juan Quintela
    CPUState *env = opaque;
160 0cb892aa Juan Quintela
161 0cb892aa Juan Quintela
    return (env->fpregs_format_vmstate == 0);
162 0cb892aa Juan Quintela
}
163 0cb892aa Juan Quintela
164 0cb892aa Juan Quintela
static bool fpregs_is_1_mmx(void *opaque, int version_id)
165 0cb892aa Juan Quintela
{
166 0cb892aa Juan Quintela
    CPUState *env = opaque;
167 0cb892aa Juan Quintela
    int guess_mmx;
168 0cb892aa Juan Quintela
169 0cb892aa Juan Quintela
    guess_mmx = ((env->fptag_vmstate == 0xff) &&
170 0cb892aa Juan Quintela
                 (env->fpus_vmstate & 0x3800) == 0);
171 0cb892aa Juan Quintela
    return (guess_mmx && (env->fpregs_format_vmstate == 1));
172 0cb892aa Juan Quintela
}
173 0cb892aa Juan Quintela
174 0cb892aa Juan Quintela
static bool fpregs_is_1_no_mmx(void *opaque, int version_id)
175 0cb892aa Juan Quintela
{
176 0cb892aa Juan Quintela
    CPUState *env = opaque;
177 0cb892aa Juan Quintela
    int guess_mmx;
178 0cb892aa Juan Quintela
179 0cb892aa Juan Quintela
    guess_mmx = ((env->fptag_vmstate == 0xff) &&
180 0cb892aa Juan Quintela
                 (env->fpus_vmstate & 0x3800) == 0);
181 0cb892aa Juan Quintela
    return (!guess_mmx && (env->fpregs_format_vmstate == 1));
182 0cb892aa Juan Quintela
}
183 0cb892aa Juan Quintela
184 0cb892aa Juan Quintela
#define VMSTATE_FP_REGS(_field, _state, _n)                               \
185 0cb892aa Juan Quintela
    VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_0, vmstate_fpreg, FPReg), \
186 0cb892aa Juan Quintela
    VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_1_mmx, vmstate_fpreg_1_mmx, FPReg), \
187 0cb892aa Juan Quintela
    VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_1_no_mmx, vmstate_fpreg_1_no_mmx, FPReg)
188 0cb892aa Juan Quintela
189 3c8ce630 Juan Quintela
#else
190 3c8ce630 Juan Quintela
static int get_fpreg(QEMUFile *f, void *opaque, size_t size)
191 3c8ce630 Juan Quintela
{
192 3c8ce630 Juan Quintela
    FPReg *fp_reg = opaque;
193 3c8ce630 Juan Quintela
194 3c8ce630 Juan Quintela
    qemu_get_be64s(f, &fp_reg->mmx.MMX_Q(0));
195 3c8ce630 Juan Quintela
    return 0;
196 3c8ce630 Juan Quintela
}
197 3c8ce630 Juan Quintela
198 3c8ce630 Juan Quintela
static void put_fpreg(QEMUFile *f, void *opaque, size_t size)
199 3c8ce630 Juan Quintela
{
200 3c8ce630 Juan Quintela
    FPReg *fp_reg = opaque;
201 3c8ce630 Juan Quintela
    /* if we use doubles for float emulation, we save the doubles to
202 3c8ce630 Juan Quintela
       avoid losing information in case of MMX usage. It can give
203 3c8ce630 Juan Quintela
       problems if the image is restored on a CPU where long
204 3c8ce630 Juan Quintela
       doubles are used instead. */
205 3c8ce630 Juan Quintela
    qemu_put_be64s(f, &fp_reg->mmx.MMX_Q(0));
206 3c8ce630 Juan Quintela
}
207 3c8ce630 Juan Quintela
208 0cb892aa Juan Quintela
const VMStateInfo vmstate_fpreg = {
209 0cb892aa Juan Quintela
    .name = "fpreg",
210 0cb892aa Juan Quintela
    .get  = get_fpreg,
211 0cb892aa Juan Quintela
    .put  = put_fpreg,
212 0cb892aa Juan Quintela
};
213 0cb892aa Juan Quintela
214 3c8ce630 Juan Quintela
static int get_fpreg_0_mmx(QEMUFile *f, void *opaque, size_t size)
215 3c8ce630 Juan Quintela
{
216 3c8ce630 Juan Quintela
    FPReg *fp_reg = opaque;
217 3c8ce630 Juan Quintela
    uint64_t mant;
218 3c8ce630 Juan Quintela
    uint16_t exp;
219 3c8ce630 Juan Quintela
220 3c8ce630 Juan Quintela
    qemu_get_be64s(f, &mant);
221 3c8ce630 Juan Quintela
    qemu_get_be16s(f, &exp);
222 3c8ce630 Juan Quintela
    fp_reg->mmx.MMX_Q(0) = mant;
223 3c8ce630 Juan Quintela
    return 0;
224 3c8ce630 Juan Quintela
}
225 3c8ce630 Juan Quintela
226 0cb892aa Juan Quintela
const VMStateInfo vmstate_fpreg_0_mmx = {
227 0cb892aa Juan Quintela
    .name = "fpreg_0_mmx",
228 0cb892aa Juan Quintela
    .get  = get_fpreg_0_mmx,
229 0cb892aa Juan Quintela
    .put  = put_fpreg_error,
230 0cb892aa Juan Quintela
};
231 0cb892aa Juan Quintela
232 3c8ce630 Juan Quintela
static int get_fpreg_0_no_mmx(QEMUFile *f, void *opaque, size_t size)
233 3c8ce630 Juan Quintela
{
234 3c8ce630 Juan Quintela
    FPReg *fp_reg = opaque;
235 3c8ce630 Juan Quintela
    uint64_t mant;
236 3c8ce630 Juan Quintela
    uint16_t exp;
237 3c8ce630 Juan Quintela
238 3c8ce630 Juan Quintela
    qemu_get_be64s(f, &mant);
239 3c8ce630 Juan Quintela
    qemu_get_be16s(f, &exp);
240 3c8ce630 Juan Quintela
241 3c8ce630 Juan Quintela
    fp_reg->d = cpu_set_fp80(mant, exp);
242 3c8ce630 Juan Quintela
    return 0;
243 3c8ce630 Juan Quintela
}
244 3c8ce630 Juan Quintela
245 0cb892aa Juan Quintela
const VMStateInfo vmstate_fpreg_0_no_mmx = {
246 0cb892aa Juan Quintela
    .name = "fpreg_0_no_mmx",
247 0cb892aa Juan Quintela
    .get  = get_fpreg_0_no_mmx,
248 0cb892aa Juan Quintela
    .put  = put_fpreg_error,
249 0cb892aa Juan Quintela
};
250 0cb892aa Juan Quintela
251 0cb892aa Juan Quintela
static bool fpregs_is_1(void *opaque, int version_id)
252 0cb892aa Juan Quintela
{
253 0cb892aa Juan Quintela
    CPUState *env = opaque;
254 0cb892aa Juan Quintela
255 0cb892aa Juan Quintela
    return env->fpregs_format_vmstate == 1;
256 0cb892aa Juan Quintela
}
257 0cb892aa Juan Quintela
258 0cb892aa Juan Quintela
static bool fpregs_is_0_mmx(void *opaque, int version_id)
259 0cb892aa Juan Quintela
{
260 0cb892aa Juan Quintela
    CPUState *env = opaque;
261 0cb892aa Juan Quintela
    int guess_mmx;
262 0cb892aa Juan Quintela
263 0cb892aa Juan Quintela
    guess_mmx = ((env->fptag_vmstate == 0xff) &&
264 0cb892aa Juan Quintela
                 (env->fpus_vmstate & 0x3800) == 0);
265 0cb892aa Juan Quintela
    return guess_mmx && env->fpregs_format_vmstate == 0;
266 0cb892aa Juan Quintela
}
267 0cb892aa Juan Quintela
268 0cb892aa Juan Quintela
static bool fpregs_is_0_no_mmx(void *opaque, int version_id)
269 0cb892aa Juan Quintela
{
270 0cb892aa Juan Quintela
    CPUState *env = opaque;
271 0cb892aa Juan Quintela
    int guess_mmx;
272 0cb892aa Juan Quintela
273 0cb892aa Juan Quintela
    guess_mmx = ((env->fptag_vmstate == 0xff) &&
274 0cb892aa Juan Quintela
                 (env->fpus_vmstate & 0x3800) == 0);
275 0cb892aa Juan Quintela
    return !guess_mmx && env->fpregs_format_vmstate == 0;
276 0cb892aa Juan Quintela
}
277 0cb892aa Juan Quintela
278 0cb892aa Juan Quintela
#define VMSTATE_FP_REGS(_field, _state, _n)                               \
279 0cb892aa Juan Quintela
    VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_1, vmstate_fpreg, FPReg), \
280 0cb892aa Juan Quintela
    VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_0_mmx, vmstate_fpreg_0_mmx, FPReg), \
281 0cb892aa Juan Quintela
    VMSTATE_ARRAY_TEST(_field, _state, _n, fpregs_is_0_no_mmx, vmstate_fpreg_0_no_mmx, FPReg)
282 0cb892aa Juan Quintela
283 3c8ce630 Juan Quintela
#endif /* USE_X86LDOUBLE */
284 3c8ce630 Juan Quintela
285 0cb892aa Juan Quintela
static bool version_is_5(void *opaque, int version_id)
286 0cb892aa Juan Quintela
{
287 0cb892aa Juan Quintela
    return version_id == 5;
288 0cb892aa Juan Quintela
}
289 0cb892aa Juan Quintela
290 0cb892aa Juan Quintela
#ifdef TARGET_X86_64
291 0cb892aa Juan Quintela
static bool less_than_7(void *opaque, int version_id)
292 0cb892aa Juan Quintela
{
293 0cb892aa Juan Quintela
    return version_id < 7;
294 0cb892aa Juan Quintela
}
295 0cb892aa Juan Quintela
296 0cb892aa Juan Quintela
static int get_uint64_as_uint32(QEMUFile *f, void *pv, size_t size)
297 0cb892aa Juan Quintela
{
298 0cb892aa Juan Quintela
    uint64_t *v = pv;
299 0cb892aa Juan Quintela
    *v = qemu_get_be32(f);
300 0cb892aa Juan Quintela
    return 0;
301 0cb892aa Juan Quintela
}
302 0cb892aa Juan Quintela
303 0cb892aa Juan Quintela
static void put_uint64_as_uint32(QEMUFile *f, void *pv, size_t size)
304 0cb892aa Juan Quintela
{
305 0cb892aa Juan Quintela
    uint64_t *v = pv;
306 0cb892aa Juan Quintela
    qemu_put_be32(f, *v);
307 0cb892aa Juan Quintela
}
308 0cb892aa Juan Quintela
309 976b2037 Blue Swirl
static const VMStateInfo vmstate_hack_uint64_as_uint32 = {
310 0cb892aa Juan Quintela
    .name = "uint64_as_uint32",
311 0cb892aa Juan Quintela
    .get  = get_uint64_as_uint32,
312 0cb892aa Juan Quintela
    .put  = put_uint64_as_uint32,
313 0cb892aa Juan Quintela
};
314 0cb892aa Juan Quintela
315 0cb892aa Juan Quintela
#define VMSTATE_HACK_UINT32(_f, _s, _t)                                  \
316 d4829d49 Juan Quintela
    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_hack_uint64_as_uint32, uint64_t)
317 0cb892aa Juan Quintela
#endif
318 0cb892aa Juan Quintela
319 c4c38c8c Juan Quintela
static void cpu_pre_save(void *opaque)
320 8dd3dca3 aurel32
{
321 8dd3dca3 aurel32
    CPUState *env = opaque;
322 0e607a80 Jan Kiszka
    int i;
323 8dd3dca3 aurel32
324 4c0960c0 Avi Kivity
    cpu_synchronize_state(env);
325 b0a46a33 Jan Kiszka
326 8dd3dca3 aurel32
    /* FPU */
327 67b8f419 Juan Quintela
    env->fpus_vmstate = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
328 cdc0c58f Juan Quintela
    env->fptag_vmstate = 0;
329 8dd3dca3 aurel32
    for(i = 0; i < 8; i++) {
330 cdc0c58f Juan Quintela
        env->fptag_vmstate |= ((!env->fptags[i]) << i);
331 8dd3dca3 aurel32
    }
332 8dd3dca3 aurel32
333 8dd3dca3 aurel32
#ifdef USE_X86LDOUBLE
334 60a902f1 Juan Quintela
    env->fpregs_format_vmstate = 0;
335 8dd3dca3 aurel32
#else
336 60a902f1 Juan Quintela
    env->fpregs_format_vmstate = 1;
337 8dd3dca3 aurel32
#endif
338 c4c38c8c Juan Quintela
}
339 c4c38c8c Juan Quintela
340 468f6581 Juan Quintela
static int cpu_pre_load(void *opaque)
341 468f6581 Juan Quintela
{
342 468f6581 Juan Quintela
    CPUState *env = opaque;
343 468f6581 Juan Quintela
344 468f6581 Juan Quintela
    cpu_synchronize_state(env);
345 468f6581 Juan Quintela
    return 0;
346 468f6581 Juan Quintela
}
347 468f6581 Juan Quintela
348 468f6581 Juan Quintela
static int cpu_post_load(void *opaque, int version_id)
349 468f6581 Juan Quintela
{
350 468f6581 Juan Quintela
    CPUState *env = opaque;
351 468f6581 Juan Quintela
    int i;
352 468f6581 Juan Quintela
353 468f6581 Juan Quintela
    /* XXX: restore FPU round state */
354 468f6581 Juan Quintela
    env->fpstt = (env->fpus_vmstate >> 11) & 7;
355 468f6581 Juan Quintela
    env->fpus = env->fpus_vmstate & ~0x3800;
356 468f6581 Juan Quintela
    env->fptag_vmstate ^= 0xff;
357 468f6581 Juan Quintela
    for(i = 0; i < 8; i++) {
358 468f6581 Juan Quintela
        env->fptags[i] = (env->fptag_vmstate >> i) & 1;
359 468f6581 Juan Quintela
    }
360 468f6581 Juan Quintela
361 468f6581 Juan Quintela
    cpu_breakpoint_remove_all(env, BP_CPU);
362 468f6581 Juan Quintela
    cpu_watchpoint_remove_all(env, BP_CPU);
363 468f6581 Juan Quintela
    for (i = 0; i < 4; i++)
364 468f6581 Juan Quintela
        hw_breakpoint_insert(env, i);
365 468f6581 Juan Quintela
366 1e7fbc6d Juan Quintela
    tlb_flush(env, 1);
367 1e7fbc6d Juan Quintela
    return 0;
368 468f6581 Juan Quintela
}
369 468f6581 Juan Quintela
370 976b2037 Blue Swirl
static const VMStateDescription vmstate_cpu = {
371 0cb892aa Juan Quintela
    .name = "cpu",
372 0cb892aa Juan Quintela
    .version_id = CPU_SAVE_VERSION,
373 0cb892aa Juan Quintela
    .minimum_version_id = 3,
374 0cb892aa Juan Quintela
    .minimum_version_id_old = 3,
375 0cb892aa Juan Quintela
    .pre_save = cpu_pre_save,
376 0cb892aa Juan Quintela
    .pre_load = cpu_pre_load,
377 0cb892aa Juan Quintela
    .post_load = cpu_post_load,
378 0cb892aa Juan Quintela
    .fields      = (VMStateField []) {
379 0cb892aa Juan Quintela
        VMSTATE_UINTTL_ARRAY(regs, CPUState, CPU_NB_REGS),
380 0cb892aa Juan Quintela
        VMSTATE_UINTTL(eip, CPUState),
381 0cb892aa Juan Quintela
        VMSTATE_UINTTL(eflags, CPUState),
382 0cb892aa Juan Quintela
        VMSTATE_UINT32(hflags, CPUState),
383 0cb892aa Juan Quintela
        /* FPU */
384 0cb892aa Juan Quintela
        VMSTATE_UINT16(fpuc, CPUState),
385 0cb892aa Juan Quintela
        VMSTATE_UINT16(fpus_vmstate, CPUState),
386 0cb892aa Juan Quintela
        VMSTATE_UINT16(fptag_vmstate, CPUState),
387 0cb892aa Juan Quintela
        VMSTATE_UINT16(fpregs_format_vmstate, CPUState),
388 0cb892aa Juan Quintela
        VMSTATE_FP_REGS(fpregs, CPUState, 8),
389 0cb892aa Juan Quintela
390 0cb892aa Juan Quintela
        VMSTATE_SEGMENT_ARRAY(segs, CPUState, 6),
391 0cb892aa Juan Quintela
        VMSTATE_SEGMENT(ldt, CPUState),
392 0cb892aa Juan Quintela
        VMSTATE_SEGMENT(tr, CPUState),
393 0cb892aa Juan Quintela
        VMSTATE_SEGMENT(gdt, CPUState),
394 0cb892aa Juan Quintela
        VMSTATE_SEGMENT(idt, CPUState),
395 0cb892aa Juan Quintela
396 0cb892aa Juan Quintela
        VMSTATE_UINT32(sysenter_cs, CPUState),
397 0cb892aa Juan Quintela
#ifdef TARGET_X86_64
398 0cb892aa Juan Quintela
        /* Hack: In v7 size changed from 32 to 64 bits on x86_64 */
399 0cb892aa Juan Quintela
        VMSTATE_HACK_UINT32(sysenter_esp, CPUState, less_than_7),
400 0cb892aa Juan Quintela
        VMSTATE_HACK_UINT32(sysenter_eip, CPUState, less_than_7),
401 0cb892aa Juan Quintela
        VMSTATE_UINTTL_V(sysenter_esp, CPUState, 7),
402 0cb892aa Juan Quintela
        VMSTATE_UINTTL_V(sysenter_eip, CPUState, 7),
403 8dd3dca3 aurel32
#else
404 0cb892aa Juan Quintela
        VMSTATE_UINTTL(sysenter_esp, CPUState),
405 0cb892aa Juan Quintela
        VMSTATE_UINTTL(sysenter_eip, CPUState),
406 3c8ce630 Juan Quintela
#endif
407 8dd3dca3 aurel32
408 0cb892aa Juan Quintela
        VMSTATE_UINTTL(cr[0], CPUState),
409 0cb892aa Juan Quintela
        VMSTATE_UINTTL(cr[2], CPUState),
410 0cb892aa Juan Quintela
        VMSTATE_UINTTL(cr[3], CPUState),
411 0cb892aa Juan Quintela
        VMSTATE_UINTTL(cr[4], CPUState),
412 0cb892aa Juan Quintela
        VMSTATE_UINTTL_ARRAY(dr, CPUState, 8),
413 0cb892aa Juan Quintela
        /* MMU */
414 0cb892aa Juan Quintela
        VMSTATE_INT32(a20_mask, CPUState),
415 0cb892aa Juan Quintela
        /* XMM */
416 0cb892aa Juan Quintela
        VMSTATE_UINT32(mxcsr, CPUState),
417 0cb892aa Juan Quintela
        VMSTATE_XMM_REGS(xmm_regs, CPUState, CPU_NB_REGS),
418 8dd3dca3 aurel32
419 8dd3dca3 aurel32
#ifdef TARGET_X86_64
420 0cb892aa Juan Quintela
        VMSTATE_UINT64(efer, CPUState),
421 0cb892aa Juan Quintela
        VMSTATE_UINT64(star, CPUState),
422 0cb892aa Juan Quintela
        VMSTATE_UINT64(lstar, CPUState),
423 0cb892aa Juan Quintela
        VMSTATE_UINT64(cstar, CPUState),
424 0cb892aa Juan Quintela
        VMSTATE_UINT64(fmask, CPUState),
425 0cb892aa Juan Quintela
        VMSTATE_UINT64(kernelgsbase, CPUState),
426 8dd3dca3 aurel32
#endif
427 0cb892aa Juan Quintela
        VMSTATE_UINT32_V(smbase, CPUState, 4),
428 0cb892aa Juan Quintela
429 0cb892aa Juan Quintela
        VMSTATE_UINT64_V(pat, CPUState, 5),
430 0cb892aa Juan Quintela
        VMSTATE_UINT32_V(hflags2, CPUState, 5),
431 0cb892aa Juan Quintela
432 0cb892aa Juan Quintela
        VMSTATE_UINT32_TEST(halted, CPUState, version_is_5),
433 0cb892aa Juan Quintela
        VMSTATE_UINT64_V(vm_hsave, CPUState, 5),
434 0cb892aa Juan Quintela
        VMSTATE_UINT64_V(vm_vmcb, CPUState, 5),
435 0cb892aa Juan Quintela
        VMSTATE_UINT64_V(tsc_offset, CPUState, 5),
436 0cb892aa Juan Quintela
        VMSTATE_UINT64_V(intercept, CPUState, 5),
437 0cb892aa Juan Quintela
        VMSTATE_UINT16_V(intercept_cr_read, CPUState, 5),
438 0cb892aa Juan Quintela
        VMSTATE_UINT16_V(intercept_cr_write, CPUState, 5),
439 0cb892aa Juan Quintela
        VMSTATE_UINT16_V(intercept_dr_read, CPUState, 5),
440 0cb892aa Juan Quintela
        VMSTATE_UINT16_V(intercept_dr_write, CPUState, 5),
441 0cb892aa Juan Quintela
        VMSTATE_UINT32_V(intercept_exceptions, CPUState, 5),
442 0cb892aa Juan Quintela
        VMSTATE_UINT8_V(v_tpr, CPUState, 5),
443 dd5e3b17 aliguori
        /* MTRRs */
444 0cb892aa Juan Quintela
        VMSTATE_UINT64_ARRAY_V(mtrr_fixed, CPUState, 11, 8),
445 0cb892aa Juan Quintela
        VMSTATE_UINT64_V(mtrr_deftype, CPUState, 8),
446 0cb892aa Juan Quintela
        VMSTATE_MTRR_VARS(mtrr_var, CPUState, 8, 8),
447 0cb892aa Juan Quintela
        /* KVM-related states */
448 0e607a80 Jan Kiszka
        VMSTATE_INT32_V(interrupt_injected, CPUState, 9),
449 0cb892aa Juan Quintela
        VMSTATE_UINT32_V(mp_state, CPUState, 9),
450 0cb892aa Juan Quintela
        VMSTATE_UINT64_V(tsc, CPUState, 9),
451 31827373 Jan Kiszka
        VMSTATE_INT32_V(exception_injected, CPUState, 11),
452 a0fb002c Jan Kiszka
        VMSTATE_UINT8_V(soft_interrupt, CPUState, 11),
453 a0fb002c Jan Kiszka
        VMSTATE_UINT8_V(nmi_injected, CPUState, 11),
454 a0fb002c Jan Kiszka
        VMSTATE_UINT8_V(nmi_pending, CPUState, 11),
455 a0fb002c Jan Kiszka
        VMSTATE_UINT8_V(has_error_code, CPUState, 11),
456 a0fb002c Jan Kiszka
        VMSTATE_UINT32_V(sipi_vector, CPUState, 11),
457 0cb892aa Juan Quintela
        /* MCE */
458 0cb892aa Juan Quintela
        VMSTATE_UINT64_V(mcg_cap, CPUState, 10),
459 0cb892aa Juan Quintela
        VMSTATE_UINT64_V(mcg_status, CPUState, 10),
460 0cb892aa Juan Quintela
        VMSTATE_UINT64_V(mcg_ctl, CPUState, 10),
461 0cb892aa Juan Quintela
        VMSTATE_UINT64_ARRAY_V(mce_banks, CPUState, MCE_BANKS_DEF *4, 10),
462 0cb892aa Juan Quintela
        /* rdtscp */
463 0cb892aa Juan Quintela
        VMSTATE_UINT64_V(tsc_aux, CPUState, 11),
464 1a03675d Glauber Costa
        /* KVM pvclock msr */
465 1a03675d Glauber Costa
        VMSTATE_UINT64_V(system_time_msr, CPUState, 11),
466 1a03675d Glauber Costa
        VMSTATE_UINT64_V(wall_clock_msr, CPUState, 11),
467 0cb892aa Juan Quintela
        VMSTATE_END_OF_LIST()
468 a0fb002c Jan Kiszka
        /* The above list is not sorted /wrt version numbers, watch out! */
469 79c4f6b0 Huang Ying
    }
470 0cb892aa Juan Quintela
};
471 79c4f6b0 Huang Ying
472 0cb892aa Juan Quintela
void cpu_save(QEMUFile *f, void *opaque)
473 0cb892aa Juan Quintela
{
474 0cb892aa Juan Quintela
    vmstate_save_state(f, &vmstate_cpu, opaque);
475 0cb892aa Juan Quintela
}
476 1f76b9b9 Juan Quintela
477 0cb892aa Juan Quintela
int cpu_load(QEMUFile *f, void *opaque, int version_id)
478 0cb892aa Juan Quintela
{
479 0cb892aa Juan Quintela
    return vmstate_load_state(f, &vmstate_cpu, opaque, version_id);
480 8dd3dca3 aurel32
}