Statistics
| Branch: | Revision:

root / target-i386 / machine.c @ 0cb892aa

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