root / target-i386 / machine.c @ 16415335
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 | } |