Statistics
| Branch: | Revision:

root / target-i386 / machine.c @ ac72472b

History | View | Annotate | Download (11 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 b0a46a33 Jan Kiszka
    cpu_synchronize_state(env, 0);
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 79c4f6b0 Huang Ying
 }
175 8dd3dca3 aurel32
176 8dd3dca3 aurel32
#ifdef USE_X86LDOUBLE
177 8dd3dca3 aurel32
/* XXX: add that in a FPU generic layer */
178 8dd3dca3 aurel32
union x86_longdouble {
179 8dd3dca3 aurel32
    uint64_t mant;
180 8dd3dca3 aurel32
    uint16_t exp;
181 8dd3dca3 aurel32
};
182 8dd3dca3 aurel32
183 8dd3dca3 aurel32
#define MANTD1(fp)        (fp & ((1LL << 52) - 1))
184 8dd3dca3 aurel32
#define EXPBIAS1 1023
185 8dd3dca3 aurel32
#define EXPD1(fp)        ((fp >> 52) & 0x7FF)
186 8dd3dca3 aurel32
#define SIGND1(fp)        ((fp >> 32) & 0x80000000)
187 8dd3dca3 aurel32
188 8dd3dca3 aurel32
static void fp64_to_fp80(union x86_longdouble *p, uint64_t temp)
189 8dd3dca3 aurel32
{
190 8dd3dca3 aurel32
    int e;
191 8dd3dca3 aurel32
    /* mantissa */
192 8dd3dca3 aurel32
    p->mant = (MANTD1(temp) << 11) | (1LL << 63);
193 8dd3dca3 aurel32
    /* exponent + sign */
194 8dd3dca3 aurel32
    e = EXPD1(temp) - EXPBIAS1 + 16383;
195 8dd3dca3 aurel32
    e |= SIGND1(temp) >> 16;
196 8dd3dca3 aurel32
    p->exp = e;
197 8dd3dca3 aurel32
}
198 8dd3dca3 aurel32
#endif
199 8dd3dca3 aurel32
200 8dd3dca3 aurel32
int cpu_load(QEMUFile *f, void *opaque, int version_id)
201 8dd3dca3 aurel32
{
202 8dd3dca3 aurel32
    CPUState *env = opaque;
203 8dd3dca3 aurel32
    int i, guess_mmx;
204 8dd3dca3 aurel32
    uint32_t hflags;
205 8dd3dca3 aurel32
    uint16_t fpus, fpuc, fptag, fpregs_format;
206 7caa33f7 aurel32
    int32_t a20_mask;
207 059b8b1e Jan Kiszka
    int32_t pending_irq;
208 8dd3dca3 aurel32
209 f8d926e9 Jan Kiszka
    if (version_id < 3 || version_id > CPU_SAVE_VERSION)
210 8dd3dca3 aurel32
        return -EINVAL;
211 8dd3dca3 aurel32
    for(i = 0; i < CPU_NB_REGS; i++)
212 8dd3dca3 aurel32
        qemu_get_betls(f, &env->regs[i]);
213 8dd3dca3 aurel32
    qemu_get_betls(f, &env->eip);
214 8dd3dca3 aurel32
    qemu_get_betls(f, &env->eflags);
215 8dd3dca3 aurel32
    qemu_get_be32s(f, &hflags);
216 8dd3dca3 aurel32
217 8dd3dca3 aurel32
    qemu_get_be16s(f, &fpuc);
218 8dd3dca3 aurel32
    qemu_get_be16s(f, &fpus);
219 8dd3dca3 aurel32
    qemu_get_be16s(f, &fptag);
220 8dd3dca3 aurel32
    qemu_get_be16s(f, &fpregs_format);
221 8dd3dca3 aurel32
222 8dd3dca3 aurel32
    /* NOTE: we cannot always restore the FPU state if the image come
223 8dd3dca3 aurel32
       from a host with a different 'USE_X86LDOUBLE' define. We guess
224 8dd3dca3 aurel32
       if we are in an MMX state to restore correctly in that case. */
225 8dd3dca3 aurel32
    guess_mmx = ((fptag == 0xff) && (fpus & 0x3800) == 0);
226 8dd3dca3 aurel32
    for(i = 0; i < 8; i++) {
227 8dd3dca3 aurel32
        uint64_t mant;
228 8dd3dca3 aurel32
        uint16_t exp;
229 8dd3dca3 aurel32
230 8dd3dca3 aurel32
        switch(fpregs_format) {
231 8dd3dca3 aurel32
        case 0:
232 8dd3dca3 aurel32
            mant = qemu_get_be64(f);
233 8dd3dca3 aurel32
            exp = qemu_get_be16(f);
234 8dd3dca3 aurel32
#ifdef USE_X86LDOUBLE
235 8dd3dca3 aurel32
            env->fpregs[i].d = cpu_set_fp80(mant, exp);
236 8dd3dca3 aurel32
#else
237 8dd3dca3 aurel32
            /* difficult case */
238 8dd3dca3 aurel32
            if (guess_mmx)
239 8dd3dca3 aurel32
                env->fpregs[i].mmx.MMX_Q(0) = mant;
240 8dd3dca3 aurel32
            else
241 8dd3dca3 aurel32
                env->fpregs[i].d = cpu_set_fp80(mant, exp);
242 8dd3dca3 aurel32
#endif
243 8dd3dca3 aurel32
            break;
244 8dd3dca3 aurel32
        case 1:
245 8dd3dca3 aurel32
            mant = qemu_get_be64(f);
246 8dd3dca3 aurel32
#ifdef USE_X86LDOUBLE
247 8dd3dca3 aurel32
            {
248 8dd3dca3 aurel32
                union x86_longdouble *p;
249 8dd3dca3 aurel32
                /* difficult case */
250 8dd3dca3 aurel32
                p = (void *)&env->fpregs[i];
251 8dd3dca3 aurel32
                if (guess_mmx) {
252 8dd3dca3 aurel32
                    p->mant = mant;
253 8dd3dca3 aurel32
                    p->exp = 0xffff;
254 8dd3dca3 aurel32
                } else {
255 8dd3dca3 aurel32
                    fp64_to_fp80(p, mant);
256 8dd3dca3 aurel32
                }
257 8dd3dca3 aurel32
            }
258 8dd3dca3 aurel32
#else
259 8dd3dca3 aurel32
            env->fpregs[i].mmx.MMX_Q(0) = mant;
260 8dd3dca3 aurel32
#endif
261 8dd3dca3 aurel32
            break;
262 8dd3dca3 aurel32
        default:
263 8dd3dca3 aurel32
            return -EINVAL;
264 8dd3dca3 aurel32
        }
265 8dd3dca3 aurel32
    }
266 8dd3dca3 aurel32
267 8dd3dca3 aurel32
    env->fpuc = fpuc;
268 8dd3dca3 aurel32
    /* XXX: restore FPU round state */
269 8dd3dca3 aurel32
    env->fpstt = (fpus >> 11) & 7;
270 8dd3dca3 aurel32
    env->fpus = fpus & ~0x3800;
271 8dd3dca3 aurel32
    fptag ^= 0xff;
272 8dd3dca3 aurel32
    for(i = 0; i < 8; i++) {
273 8dd3dca3 aurel32
        env->fptags[i] = (fptag >> i) & 1;
274 8dd3dca3 aurel32
    }
275 8dd3dca3 aurel32
276 8dd3dca3 aurel32
    for(i = 0; i < 6; i++)
277 8dd3dca3 aurel32
        cpu_get_seg(f, &env->segs[i]);
278 8dd3dca3 aurel32
    cpu_get_seg(f, &env->ldt);
279 8dd3dca3 aurel32
    cpu_get_seg(f, &env->tr);
280 8dd3dca3 aurel32
    cpu_get_seg(f, &env->gdt);
281 8dd3dca3 aurel32
    cpu_get_seg(f, &env->idt);
282 8dd3dca3 aurel32
283 8dd3dca3 aurel32
    qemu_get_be32s(f, &env->sysenter_cs);
284 2436b61a balrog
    if (version_id >= 7) {
285 2436b61a balrog
        qemu_get_betls(f, &env->sysenter_esp);
286 2436b61a balrog
        qemu_get_betls(f, &env->sysenter_eip);
287 2436b61a balrog
    } else {
288 e5ceb244 aliguori
        env->sysenter_esp = qemu_get_be32(f);
289 e5ceb244 aliguori
        env->sysenter_eip = qemu_get_be32(f);
290 2436b61a balrog
    }
291 8dd3dca3 aurel32
292 8dd3dca3 aurel32
    qemu_get_betls(f, &env->cr[0]);
293 8dd3dca3 aurel32
    qemu_get_betls(f, &env->cr[2]);
294 8dd3dca3 aurel32
    qemu_get_betls(f, &env->cr[3]);
295 8dd3dca3 aurel32
    qemu_get_betls(f, &env->cr[4]);
296 8dd3dca3 aurel32
297 8dd3dca3 aurel32
    for(i = 0; i < 8; i++)
298 8dd3dca3 aurel32
        qemu_get_betls(f, &env->dr[i]);
299 01df040b aliguori
    cpu_breakpoint_remove_all(env, BP_CPU);
300 01df040b aliguori
    cpu_watchpoint_remove_all(env, BP_CPU);
301 01df040b aliguori
    for (i = 0; i < 4; i++)
302 01df040b aliguori
        hw_breakpoint_insert(env, i);
303 8dd3dca3 aurel32
304 8dd3dca3 aurel32
    /* MMU */
305 b6c4f71f blueswir1
    qemu_get_sbe32s(f, &a20_mask);
306 7caa33f7 aurel32
    env->a20_mask = a20_mask;
307 8dd3dca3 aurel32
308 8dd3dca3 aurel32
    qemu_get_be32s(f, &env->mxcsr);
309 8dd3dca3 aurel32
    for(i = 0; i < CPU_NB_REGS; i++) {
310 8dd3dca3 aurel32
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(0));
311 8dd3dca3 aurel32
        qemu_get_be64s(f, &env->xmm_regs[i].XMM_Q(1));
312 8dd3dca3 aurel32
    }
313 8dd3dca3 aurel32
314 8dd3dca3 aurel32
#ifdef TARGET_X86_64
315 8dd3dca3 aurel32
    qemu_get_be64s(f, &env->efer);
316 8dd3dca3 aurel32
    qemu_get_be64s(f, &env->star);
317 8dd3dca3 aurel32
    qemu_get_be64s(f, &env->lstar);
318 8dd3dca3 aurel32
    qemu_get_be64s(f, &env->cstar);
319 8dd3dca3 aurel32
    qemu_get_be64s(f, &env->fmask);
320 8dd3dca3 aurel32
    qemu_get_be64s(f, &env->kernelgsbase);
321 8dd3dca3 aurel32
#endif
322 5cc1d1e6 bellard
    if (version_id >= 4) {
323 8dd3dca3 aurel32
        qemu_get_be32s(f, &env->smbase);
324 5cc1d1e6 bellard
    }
325 5cc1d1e6 bellard
    if (version_id >= 5) {
326 5cc1d1e6 bellard
        qemu_get_be64s(f, &env->pat);
327 5cc1d1e6 bellard
        qemu_get_be32s(f, &env->hflags2);
328 9656f324 pbrook
        if (version_id < 6)
329 9656f324 pbrook
            qemu_get_be32s(f, &env->halted);
330 5cc1d1e6 bellard
331 5cc1d1e6 bellard
        qemu_get_be64s(f, &env->vm_hsave);
332 5cc1d1e6 bellard
        qemu_get_be64s(f, &env->vm_vmcb);
333 5cc1d1e6 bellard
        qemu_get_be64s(f, &env->tsc_offset);
334 5cc1d1e6 bellard
        qemu_get_be64s(f, &env->intercept);
335 5cc1d1e6 bellard
        qemu_get_be16s(f, &env->intercept_cr_read);
336 5cc1d1e6 bellard
        qemu_get_be16s(f, &env->intercept_cr_write);
337 5cc1d1e6 bellard
        qemu_get_be16s(f, &env->intercept_dr_read);
338 5cc1d1e6 bellard
        qemu_get_be16s(f, &env->intercept_dr_write);
339 5cc1d1e6 bellard
        qemu_get_be32s(f, &env->intercept_exceptions);
340 5cc1d1e6 bellard
        qemu_get_8s(f, &env->v_tpr);
341 5cc1d1e6 bellard
    }
342 dd5e3b17 aliguori
343 dd5e3b17 aliguori
    if (version_id >= 8) {
344 dd5e3b17 aliguori
        /* MTRRs */
345 dd5e3b17 aliguori
        for(i = 0; i < 11; i++)
346 dd5e3b17 aliguori
            qemu_get_be64s(f, &env->mtrr_fixed[i]);
347 dd5e3b17 aliguori
        qemu_get_be64s(f, &env->mtrr_deftype);
348 dd5e3b17 aliguori
        for(i = 0; i < 8; i++) {
349 dd5e3b17 aliguori
            qemu_get_be64s(f, &env->mtrr_var[i].base);
350 dd5e3b17 aliguori
            qemu_get_be64s(f, &env->mtrr_var[i].mask);
351 dd5e3b17 aliguori
        }
352 dd5e3b17 aliguori
    }
353 059b8b1e Jan Kiszka
354 f8d926e9 Jan Kiszka
    if (version_id >= 9) {
355 059b8b1e Jan Kiszka
        qemu_get_sbe32s(f, &pending_irq);
356 059b8b1e Jan Kiszka
        memset(&env->interrupt_bitmap, 0, sizeof(env->interrupt_bitmap));
357 059b8b1e Jan Kiszka
        if (pending_irq >= 0) {
358 059b8b1e Jan Kiszka
            env->interrupt_bitmap[pending_irq / 64] |=
359 059b8b1e Jan Kiszka
                (uint64_t)1 << (pending_irq % 64);
360 f8d926e9 Jan Kiszka
        }
361 f8d926e9 Jan Kiszka
        qemu_get_be32s(f, &env->mp_state);
362 059b8b1e Jan Kiszka
        qemu_get_be64s(f, &env->tsc);
363 f8d926e9 Jan Kiszka
    }
364 dd5e3b17 aliguori
365 79c4f6b0 Huang Ying
    if (version_id >= 10) {
366 79c4f6b0 Huang Ying
        qemu_get_be64s(f, &env->mcg_cap);
367 79c4f6b0 Huang Ying
        if (env->mcg_cap) {
368 79c4f6b0 Huang Ying
            qemu_get_be64s(f, &env->mcg_status);
369 79c4f6b0 Huang Ying
            qemu_get_be64s(f, &env->mcg_ctl);
370 79c4f6b0 Huang Ying
            for (i = 0; i < (env->mcg_cap & 0xff); i++) {
371 79c4f6b0 Huang Ying
                qemu_get_be64s(f, &env->mce_banks[4*i]);
372 79c4f6b0 Huang Ying
                qemu_get_be64s(f, &env->mce_banks[4*i + 1]);
373 79c4f6b0 Huang Ying
                qemu_get_be64s(f, &env->mce_banks[4*i + 2]);
374 79c4f6b0 Huang Ying
                qemu_get_be64s(f, &env->mce_banks[4*i + 3]);
375 79c4f6b0 Huang Ying
            }
376 79c4f6b0 Huang Ying
        }
377 79c4f6b0 Huang Ying
    }
378 79c4f6b0 Huang Ying
379 5cc1d1e6 bellard
    /* XXX: ensure compatiblity for halted bit ? */
380 5cc1d1e6 bellard
    /* XXX: compute redundant hflags bits */
381 8dd3dca3 aurel32
    env->hflags = hflags;
382 8dd3dca3 aurel32
    tlb_flush(env, 1);
383 b0a46a33 Jan Kiszka
    cpu_synchronize_state(env, 1);
384 8dd3dca3 aurel32
    return 0;
385 8dd3dca3 aurel32
}