Statistics
| Branch: | Revision:

root / target-i386 / machine.c @ 09d85fb8

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