]> git.proxmox.com Git - mirror_qemu.git/blame - target/i386/helper.c
Merge remote-tracking branch 'remotes/awilliam/tags/vfio-updates-20190311.0' into...
[mirror_qemu.git] / target / i386 / helper.c
CommitLineData
2c0262af 1/*
eaa728ee 2 * i386 helpers (without register variable usage)
5fafdf24 3 *
2c0262af
FB
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
8167ee88 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
2c0262af 18 */
2c0262af 19
b6a0aa05 20#include "qemu/osdep.h"
eaa728ee 21#include "cpu.h"
63c91552 22#include "exec/exec-all.h"
9c17d615 23#include "sysemu/kvm.h"
e0723c45 24#include "kvm_i386.h"
2fa11da0 25#ifndef CONFIG_USER_ONLY
9c17d615 26#include "sysemu/sysemu.h"
b3946626 27#include "sysemu/hw_accel.h"
83c9089e 28#include "monitor/monitor.h"
1f871d49 29#include "hw/i386/apic_internal.h"
2fa11da0 30#endif
f3f2d9be 31
ab0a19d4
YZ
32void cpu_sync_bndcs_hflags(CPUX86State *env)
33{
34 uint32_t hflags = env->hflags;
35 uint32_t hflags2 = env->hflags2;
36 uint32_t bndcsr;
37
38 if ((hflags & HF_CPL_MASK) == 3) {
39 bndcsr = env->bndcs_regs.cfgu;
40 } else {
41 bndcsr = env->msr_bndcfgs;
42 }
43
44 if ((env->cr[4] & CR4_OSXSAVE_MASK)
45 && (env->xcr0 & XSTATE_BNDCSR_MASK)
46 && (bndcsr & BNDCFG_ENABLE)) {
47 hflags |= HF_MPX_EN_MASK;
48 } else {
49 hflags &= ~HF_MPX_EN_MASK;
50 }
51
52 if (bndcsr & BNDCFG_BNDPRESERVE) {
53 hflags2 |= HF2_MPX_PR_MASK;
54 } else {
55 hflags2 &= ~HF2_MPX_PR_MASK;
56 }
57
58 env->hflags = hflags;
59 env->hflags2 = hflags2;
60}
61
317ac620 62static void cpu_x86_version(CPUX86State *env, int *family, int *model)
2bd3e04c
JD
63{
64 int cpuver = env->cpuid_version;
65
66 if (family == NULL || model == NULL) {
67 return;
68 }
69
70 *family = (cpuver >> 8) & 0x0f;
71 *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
72}
73
74/* Broadcast MCA signal for processor version 06H_EH and above */
317ac620 75int cpu_x86_support_mca_broadcast(CPUX86State *env)
2bd3e04c
JD
76{
77 int family = 0;
78 int model = 0;
79
80 cpu_x86_version(env, &family, &model);
81 if ((family == 6 && model >= 14) || family > 6) {
82 return 1;
83 }
84
85 return 0;
86}
87
eaa728ee
FB
88/***********************************************************/
89/* x86 debug */
3b46e624 90
bc4b43dc 91static const char *cc_op_str[CC_OP_NB] = {
eaa728ee
FB
92 "DYNAMIC",
93 "EFLAGS",
7e84c249 94
eaa728ee
FB
95 "MULB",
96 "MULW",
97 "MULL",
98 "MULQ",
3b46e624 99
eaa728ee
FB
100 "ADDB",
101 "ADDW",
102 "ADDL",
103 "ADDQ",
3b46e624 104
eaa728ee
FB
105 "ADCB",
106 "ADCW",
107 "ADCL",
108 "ADCQ",
3b46e624 109
eaa728ee
FB
110 "SUBB",
111 "SUBW",
112 "SUBL",
113 "SUBQ",
7e84c249 114
eaa728ee
FB
115 "SBBB",
116 "SBBW",
117 "SBBL",
118 "SBBQ",
7e84c249 119
eaa728ee
FB
120 "LOGICB",
121 "LOGICW",
122 "LOGICL",
123 "LOGICQ",
7e84c249 124
eaa728ee
FB
125 "INCB",
126 "INCW",
127 "INCL",
128 "INCQ",
3b46e624 129
eaa728ee
FB
130 "DECB",
131 "DECW",
132 "DECL",
133 "DECQ",
3b46e624 134
eaa728ee
FB
135 "SHLB",
136 "SHLW",
137 "SHLL",
138 "SHLQ",
3b46e624 139
eaa728ee
FB
140 "SARB",
141 "SARW",
142 "SARL",
143 "SARQ",
bc4b43dc
RH
144
145 "BMILGB",
146 "BMILGW",
147 "BMILGL",
148 "BMILGQ",
cd7f97ca
RH
149
150 "ADCX",
151 "ADOX",
152 "ADCOX",
436ff2d2
RH
153
154 "CLR",
eaa728ee 155};
7e84c249 156
a3867ed2 157static void
317ac620 158cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
a3867ed2
AL
159 const char *name, struct SegmentCache *sc)
160{
161#ifdef TARGET_X86_64
162 if (env->hflags & HF_CS64_MASK) {
163 cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
4058fd98 164 sc->selector, sc->base, sc->limit, sc->flags & 0x00ffff00);
a3867ed2
AL
165 } else
166#endif
167 {
168 cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
4058fd98 169 (uint32_t)sc->base, sc->limit, sc->flags & 0x00ffff00);
a3867ed2
AL
170 }
171
172 if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
173 goto done;
174
175 cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
176 if (sc->flags & DESC_S_MASK) {
177 if (sc->flags & DESC_CS_MASK) {
178 cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
179 ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
180 cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
181 (sc->flags & DESC_R_MASK) ? 'R' : '-');
182 } else {
469936ae
TM
183 cpu_fprintf(f,
184 (sc->flags & DESC_B_MASK || env->hflags & HF_LMA_MASK)
185 ? "DS " : "DS16");
a3867ed2
AL
186 cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
187 (sc->flags & DESC_W_MASK) ? 'W' : '-');
188 }
189 cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
190 } else {
191 static const char *sys_type_name[2][16] = {
192 { /* 32 bit mode */
193 "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
194 "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
195 "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
196 "CallGate32", "Reserved", "IntGate32", "TrapGate32"
197 },
198 { /* 64 bit mode */
199 "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
200 "Reserved", "Reserved", "Reserved", "Reserved",
201 "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
202 "Reserved", "IntGate64", "TrapGate64"
203 }
204 };
e5c15eff
SW
205 cpu_fprintf(f, "%s",
206 sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
207 [(sc->flags & DESC_TYPE_MASK)
208 >> DESC_TYPE_SHIFT]);
a3867ed2
AL
209 }
210done:
211 cpu_fprintf(f, "\n");
212}
213
1f871d49
PB
214#ifndef CONFIG_USER_ONLY
215
216/* ARRAY_SIZE check is not required because
217 * DeliveryMode(dm) has a size of 3 bit.
218 */
219static inline const char *dm2str(uint32_t dm)
220{
221 static const char *str[] = {
222 "Fixed",
223 "...",
224 "SMI",
225 "...",
226 "NMI",
227 "INIT",
228 "...",
229 "ExtINT"
230 };
231 return str[dm];
232}
233
234static void dump_apic_lvt(FILE *f, fprintf_function cpu_fprintf,
235 const char *name, uint32_t lvt, bool is_timer)
236{
237 uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT;
238 cpu_fprintf(f,
239 "%s\t 0x%08x %s %-5s %-6s %-7s %-12s %-6s",
240 name, lvt,
241 lvt & APIC_LVT_INT_POLARITY ? "active-lo" : "active-hi",
242 lvt & APIC_LVT_LEVEL_TRIGGER ? "level" : "edge",
243 lvt & APIC_LVT_MASKED ? "masked" : "",
244 lvt & APIC_LVT_DELIV_STS ? "pending" : "",
245 !is_timer ?
246 "" : lvt & APIC_LVT_TIMER_PERIODIC ?
247 "periodic" : lvt & APIC_LVT_TIMER_TSCDEADLINE ?
248 "tsc-deadline" : "one-shot",
249 dm2str(dm));
250 if (dm != APIC_DM_NMI) {
251 cpu_fprintf(f, " (vec %u)\n", lvt & APIC_VECTOR_MASK);
252 } else {
253 cpu_fprintf(f, "\n");
254 }
255}
256
257/* ARRAY_SIZE check is not required because
258 * destination shorthand has a size of 2 bit.
259 */
260static inline const char *shorthand2str(uint32_t shorthand)
261{
262 const char *str[] = {
263 "no-shorthand", "self", "all-self", "all"
264 };
265 return str[shorthand];
266}
267
268static inline uint8_t divider_conf(uint32_t divide_conf)
269{
270 uint8_t divide_val = ((divide_conf & 0x8) >> 1) | (divide_conf & 0x3);
271
272 return divide_val == 7 ? 1 : 2 << divide_val;
273}
274
275static inline void mask2str(char *str, uint32_t val, uint8_t size)
276{
277 while (size--) {
278 *str++ = (val >> size) & 1 ? '1' : '0';
279 }
280 *str = 0;
281}
282
283#define MAX_LOGICAL_APIC_ID_MASK_SIZE 16
284
285static void dump_apic_icr(FILE *f, fprintf_function cpu_fprintf,
286 APICCommonState *s, CPUX86State *env)
287{
288 uint32_t icr = s->icr[0], icr2 = s->icr[1];
289 uint8_t dest_shorthand = \
290 (icr & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT;
291 bool logical_mod = icr & APIC_ICR_DEST_MOD;
292 char apic_id_str[MAX_LOGICAL_APIC_ID_MASK_SIZE + 1];
293 uint32_t dest_field;
294 bool x2apic;
295
296 cpu_fprintf(f, "ICR\t 0x%08x %s %s %s %s\n",
297 icr,
298 logical_mod ? "logical" : "physical",
299 icr & APIC_ICR_TRIGGER_MOD ? "level" : "edge",
300 icr & APIC_ICR_LEVEL ? "assert" : "de-assert",
301 shorthand2str(dest_shorthand));
302
303 cpu_fprintf(f, "ICR2\t 0x%08x", icr2);
304 if (dest_shorthand != 0) {
305 cpu_fprintf(f, "\n");
306 return;
307 }
308 x2apic = env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC;
309 dest_field = x2apic ? icr2 : icr2 >> APIC_ICR_DEST_SHIFT;
310
311 if (!logical_mod) {
312 if (x2apic) {
313 cpu_fprintf(f, " cpu %u (X2APIC ID)\n", dest_field);
314 } else {
315 cpu_fprintf(f, " cpu %u (APIC ID)\n",
316 dest_field & APIC_LOGDEST_XAPIC_ID);
317 }
318 return;
319 }
320
321 if (s->dest_mode == 0xf) { /* flat mode */
322 mask2str(apic_id_str, icr2 >> APIC_ICR_DEST_SHIFT, 8);
323 cpu_fprintf(f, " mask %s (APIC ID)\n", apic_id_str);
324 } else if (s->dest_mode == 0) { /* cluster mode */
325 if (x2apic) {
326 mask2str(apic_id_str, dest_field & APIC_LOGDEST_X2APIC_ID, 16);
327 cpu_fprintf(f, " cluster %u mask %s (X2APIC ID)\n",
328 dest_field >> APIC_LOGDEST_X2APIC_SHIFT, apic_id_str);
329 } else {
330 mask2str(apic_id_str, dest_field & APIC_LOGDEST_XAPIC_ID, 4);
331 cpu_fprintf(f, " cluster %u mask %s (APIC ID)\n",
332 dest_field >> APIC_LOGDEST_XAPIC_SHIFT, apic_id_str);
333 }
334 }
335}
336
337static void dump_apic_interrupt(FILE *f, fprintf_function cpu_fprintf,
338 const char *name, uint32_t *ireg_tab,
339 uint32_t *tmr_tab)
340{
341 int i, empty = true;
342
343 cpu_fprintf(f, "%s\t ", name);
344 for (i = 0; i < 256; i++) {
345 if (apic_get_bit(ireg_tab, i)) {
346 cpu_fprintf(f, "%u%s ", i,
347 apic_get_bit(tmr_tab, i) ? "(level)" : "");
348 empty = false;
349 }
350 }
351 cpu_fprintf(f, "%s\n", empty ? "(none)" : "");
352}
353
354void x86_cpu_dump_local_apic_state(CPUState *cs, FILE *f,
355 fprintf_function cpu_fprintf, int flags)
356{
357 X86CPU *cpu = X86_CPU(cs);
358 APICCommonState *s = APIC_COMMON(cpu->apic_state);
c7f15bc9
TP
359 if (!s) {
360 cpu_fprintf(f, "local apic state not available\n");
361 return;
362 }
1f871d49
PB
363 uint32_t *lvt = s->lvt;
364
365 cpu_fprintf(f, "dumping local APIC state for CPU %-2u\n\n",
366 CPU(cpu)->cpu_index);
367 dump_apic_lvt(f, cpu_fprintf, "LVT0", lvt[APIC_LVT_LINT0], false);
368 dump_apic_lvt(f, cpu_fprintf, "LVT1", lvt[APIC_LVT_LINT1], false);
369 dump_apic_lvt(f, cpu_fprintf, "LVTPC", lvt[APIC_LVT_PERFORM], false);
370 dump_apic_lvt(f, cpu_fprintf, "LVTERR", lvt[APIC_LVT_ERROR], false);
371 dump_apic_lvt(f, cpu_fprintf, "LVTTHMR", lvt[APIC_LVT_THERMAL], false);
372 dump_apic_lvt(f, cpu_fprintf, "LVTT", lvt[APIC_LVT_TIMER], true);
373
374 cpu_fprintf(f, "Timer\t DCR=0x%x (divide by %u) initial_count = %u\n",
375 s->divide_conf & APIC_DCR_MASK,
376 divider_conf(s->divide_conf),
377 s->initial_count);
378
379 cpu_fprintf(f, "SPIV\t 0x%08x APIC %s, focus=%s, spurious vec %u\n",
380 s->spurious_vec,
381 s->spurious_vec & APIC_SPURIO_ENABLED ? "enabled" : "disabled",
382 s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off",
383 s->spurious_vec & APIC_VECTOR_MASK);
384
385 dump_apic_icr(f, cpu_fprintf, s, &cpu->env);
386
387 cpu_fprintf(f, "ESR\t 0x%08x\n", s->esr);
388
389 dump_apic_interrupt(f, cpu_fprintf, "ISR", s->isr, s->tmr);
390 dump_apic_interrupt(f, cpu_fprintf, "IRR", s->irr, s->tmr);
391
392 cpu_fprintf(f, "\nAPR 0x%02x TPR 0x%02x DFR 0x%02x LDR 0x%02x",
393 s->arb_id, s->tpr, s->dest_mode, s->log_dest);
394 if (s->dest_mode == 0) {
395 cpu_fprintf(f, "(cluster %u: id %u)",
396 s->log_dest >> APIC_LOGDEST_XAPIC_SHIFT,
397 s->log_dest & APIC_LOGDEST_XAPIC_ID);
398 }
399 cpu_fprintf(f, " PPR 0x%02x\n", apic_get_ppr(s));
400}
401#else
402void x86_cpu_dump_local_apic_state(CPUState *cs, FILE *f,
403 fprintf_function cpu_fprintf, int flags)
404{
405}
406#endif /* !CONFIG_USER_ONLY */
407
f5c848ee
JK
408#define DUMP_CODE_BYTES_TOTAL 50
409#define DUMP_CODE_BYTES_BACKWARD 20
410
878096ee
AF
411void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
412 int flags)
eaa728ee 413{
878096ee
AF
414 X86CPU *cpu = X86_CPU(cs);
415 CPUX86State *env = &cpu->env;
eaa728ee
FB
416 int eflags, i, nb;
417 char cc_op_name[32];
418 static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
7e84c249 419
4980ef9e 420 eflags = cpu_compute_eflags(env);
eaa728ee
FB
421#ifdef TARGET_X86_64
422 if (env->hflags & HF_CS64_MASK) {
423 cpu_fprintf(f,
424 "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
425 "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
426 "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
427 "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
428 "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
429 env->regs[R_EAX],
430 env->regs[R_EBX],
431 env->regs[R_ECX],
432 env->regs[R_EDX],
433 env->regs[R_ESI],
434 env->regs[R_EDI],
435 env->regs[R_EBP],
436 env->regs[R_ESP],
437 env->regs[8],
438 env->regs[9],
439 env->regs[10],
440 env->regs[11],
441 env->regs[12],
442 env->regs[13],
443 env->regs[14],
444 env->regs[15],
445 env->eip, eflags,
446 eflags & DF_MASK ? 'D' : '-',
447 eflags & CC_O ? 'O' : '-',
448 eflags & CC_S ? 'S' : '-',
449 eflags & CC_Z ? 'Z' : '-',
450 eflags & CC_A ? 'A' : '-',
451 eflags & CC_P ? 'P' : '-',
452 eflags & CC_C ? 'C' : '-',
453 env->hflags & HF_CPL_MASK,
454 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
5ee0ffaa 455 (env->a20_mask >> 20) & 1,
eaa728ee 456 (env->hflags >> HF_SMM_SHIFT) & 1,
259186a7 457 cs->halted);
eaa728ee
FB
458 } else
459#endif
460 {
461 cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
462 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
463 "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
464 (uint32_t)env->regs[R_EAX],
465 (uint32_t)env->regs[R_EBX],
466 (uint32_t)env->regs[R_ECX],
467 (uint32_t)env->regs[R_EDX],
468 (uint32_t)env->regs[R_ESI],
469 (uint32_t)env->regs[R_EDI],
470 (uint32_t)env->regs[R_EBP],
471 (uint32_t)env->regs[R_ESP],
472 (uint32_t)env->eip, eflags,
473 eflags & DF_MASK ? 'D' : '-',
474 eflags & CC_O ? 'O' : '-',
475 eflags & CC_S ? 'S' : '-',
476 eflags & CC_Z ? 'Z' : '-',
477 eflags & CC_A ? 'A' : '-',
478 eflags & CC_P ? 'P' : '-',
479 eflags & CC_C ? 'C' : '-',
480 env->hflags & HF_CPL_MASK,
481 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
5ee0ffaa 482 (env->a20_mask >> 20) & 1,
eaa728ee 483 (env->hflags >> HF_SMM_SHIFT) & 1,
259186a7 484 cs->halted);
8145122b 485 }
3b46e624 486
a3867ed2
AL
487 for(i = 0; i < 6; i++) {
488 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
489 &env->segs[i]);
490 }
491 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
492 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
493
eaa728ee
FB
494#ifdef TARGET_X86_64
495 if (env->hflags & HF_LMA_MASK) {
eaa728ee
FB
496 cpu_fprintf(f, "GDT= %016" PRIx64 " %08x\n",
497 env->gdt.base, env->gdt.limit);
498 cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
499 env->idt.base, env->idt.limit);
500 cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
501 (uint32_t)env->cr[0],
502 env->cr[2],
503 env->cr[3],
504 (uint32_t)env->cr[4]);
a59cb4e0
AL
505 for(i = 0; i < 4; i++)
506 cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
507 cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
d4b55be5 508 env->dr[6], env->dr[7]);
eaa728ee
FB
509 } else
510#endif
511 {
eaa728ee
FB
512 cpu_fprintf(f, "GDT= %08x %08x\n",
513 (uint32_t)env->gdt.base, env->gdt.limit);
514 cpu_fprintf(f, "IDT= %08x %08x\n",
515 (uint32_t)env->idt.base, env->idt.limit);
516 cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
517 (uint32_t)env->cr[0],
518 (uint32_t)env->cr[2],
519 (uint32_t)env->cr[3],
520 (uint32_t)env->cr[4]);
9a78eead
SW
521 for(i = 0; i < 4; i++) {
522 cpu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
523 }
524 cpu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
525 env->dr[6], env->dr[7]);
eaa728ee 526 }
6fd2a026 527 if (flags & CPU_DUMP_CCOP) {
eaa728ee
FB
528 if ((unsigned)env->cc_op < CC_OP_NB)
529 snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
530 else
531 snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
532#ifdef TARGET_X86_64
533 if (env->hflags & HF_CS64_MASK) {
534 cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
535 env->cc_src, env->cc_dst,
536 cc_op_name);
537 } else
538#endif
539 {
540 cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
541 (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
542 cc_op_name);
543 }
7e84c249 544 }
b5e5a934 545 cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
6fd2a026 546 if (flags & CPU_DUMP_FPU) {
eaa728ee
FB
547 int fptag;
548 fptag = 0;
549 for(i = 0; i < 8; i++) {
550 fptag |= ((!env->fptags[i]) << i);
551 }
552 cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
553 env->fpuc,
554 (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
555 env->fpstt,
556 fptag,
557 env->mxcsr);
558 for(i=0;i<8;i++) {
1ffd41ee
AJ
559 CPU_LDoubleU u;
560 u.d = env->fpregs[i].d;
eaa728ee 561 cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
1ffd41ee 562 i, u.l.lower, u.l.upper);
eaa728ee
FB
563 if ((i & 1) == 1)
564 cpu_fprintf(f, "\n");
565 else
566 cpu_fprintf(f, " ");
567 }
568 if (env->hflags & HF_CS64_MASK)
569 nb = 16;
570 else
571 nb = 8;
572 for(i=0;i<nb;i++) {
573 cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
574 i,
19cbd87c
EH
575 env->xmm_regs[i].ZMM_L(3),
576 env->xmm_regs[i].ZMM_L(2),
577 env->xmm_regs[i].ZMM_L(1),
578 env->xmm_regs[i].ZMM_L(0));
eaa728ee
FB
579 if ((i & 1) == 1)
580 cpu_fprintf(f, "\n");
581 else
582 cpu_fprintf(f, " ");
583 }
7e84c249 584 }
f5c848ee
JK
585 if (flags & CPU_DUMP_CODE) {
586 target_ulong base = env->segs[R_CS].base + env->eip;
587 target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
588 uint8_t code;
589 char codestr[3];
590
591 cpu_fprintf(f, "Code=");
592 for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
f17ec444 593 if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
f5c848ee
JK
594 snprintf(codestr, sizeof(codestr), "%02x", code);
595 } else {
596 snprintf(codestr, sizeof(codestr), "??");
597 }
598 cpu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
599 i == offs ? "<" : "", codestr, i == offs ? ">" : "");
600 }
601 cpu_fprintf(f, "\n");
602 }
2c0262af 603}
7e84c249 604
eaa728ee
FB
605/***********************************************************/
606/* x86 mmu */
607/* XXX: add PGE support */
608
cc36a7a2 609void x86_cpu_set_a20(X86CPU *cpu, int a20_state)
2c0262af 610{
cc36a7a2
AF
611 CPUX86State *env = &cpu->env;
612
eaa728ee
FB
613 a20_state = (a20_state != 0);
614 if (a20_state != ((env->a20_mask >> 20) & 1)) {
00c8cb0a
AF
615 CPUState *cs = CPU(cpu);
616
339aaf5b 617 qemu_log_mask(CPU_LOG_MMU, "A20 update: a20=%d\n", a20_state);
eaa728ee
FB
618 /* if the cpu is currently executing code, we must unlink it and
619 all the potentially executing TB */
00c8cb0a 620 cpu_interrupt(cs, CPU_INTERRUPT_EXITTB);
3b46e624 621
eaa728ee
FB
622 /* when a20 is changed, all the MMU mappings are invalid, so
623 we must flush everything */
d10eb08f 624 tlb_flush(cs);
5ee0ffaa 625 env->a20_mask = ~(1 << 20) | (a20_state << 20);
7e84c249 626 }
2c0262af
FB
627}
628
eaa728ee 629void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
2c0262af 630{
00c8cb0a 631 X86CPU *cpu = x86_env_get_cpu(env);
eaa728ee 632 int pe_state;
2c0262af 633
339aaf5b 634 qemu_log_mask(CPU_LOG_MMU, "CR0 update: CR0=0x%08x\n", new_cr0);
eaa728ee
FB
635 if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
636 (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
d10eb08f 637 tlb_flush(CPU(cpu));
eaa728ee 638 }
2c0262af 639
eaa728ee
FB
640#ifdef TARGET_X86_64
641 if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
642 (env->efer & MSR_EFER_LME)) {
643 /* enter in long mode */
644 /* XXX: generate an exception */
645 if (!(env->cr[4] & CR4_PAE_MASK))
646 return;
647 env->efer |= MSR_EFER_LMA;
648 env->hflags |= HF_LMA_MASK;
649 } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
650 (env->efer & MSR_EFER_LMA)) {
651 /* exit long mode */
652 env->efer &= ~MSR_EFER_LMA;
653 env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
654 env->eip &= 0xffffffff;
655 }
656#endif
657 env->cr[0] = new_cr0 | CR0_ET_MASK;
7e84c249 658
eaa728ee
FB
659 /* update PE flag in hidden flags */
660 pe_state = (env->cr[0] & CR0_PE_MASK);
661 env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
662 /* ensure that ADDSEG is always set in real mode */
663 env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
664 /* update FPU flags */
665 env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
666 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
7e84c249
FB
667}
668
eaa728ee
FB
669/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
670 the PDPT */
671void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
7e84c249 672{
00c8cb0a
AF
673 X86CPU *cpu = x86_env_get_cpu(env);
674
eaa728ee
FB
675 env->cr[3] = new_cr3;
676 if (env->cr[0] & CR0_PG_MASK) {
339aaf5b
AP
677 qemu_log_mask(CPU_LOG_MMU,
678 "CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
d10eb08f 679 tlb_flush(CPU(cpu));
eaa728ee 680 }
7e84c249
FB
681}
682
eaa728ee 683void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
7e84c249 684{
00c8cb0a 685 X86CPU *cpu = x86_env_get_cpu(env);
19dc85db 686 uint32_t hflags;
00c8cb0a 687
eaa728ee 688#if defined(DEBUG_MMU)
6c7c3c21 689 printf("CR4 update: %08x -> %08x\n", (uint32_t)env->cr[4], new_cr4);
eaa728ee 690#endif
a9321a4d
PA
691 if ((new_cr4 ^ env->cr[4]) &
692 (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK |
6c7c3c21 693 CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_LA57_MASK)) {
d10eb08f 694 tlb_flush(CPU(cpu));
eaa728ee 695 }
19dc85db
RH
696
697 /* Clear bits we're going to recompute. */
698 hflags = env->hflags & ~(HF_OSFXSR_MASK | HF_SMAP_MASK);
699
eaa728ee 700 /* SSE handling */
0514ef2f 701 if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) {
eaa728ee 702 new_cr4 &= ~CR4_OSFXSR_MASK;
a9321a4d 703 }
a9321a4d 704 if (new_cr4 & CR4_OSFXSR_MASK) {
19dc85db 705 hflags |= HF_OSFXSR_MASK;
a9321a4d
PA
706 }
707
0514ef2f 708 if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) {
a9321a4d
PA
709 new_cr4 &= ~CR4_SMAP_MASK;
710 }
a9321a4d 711 if (new_cr4 & CR4_SMAP_MASK) {
19dc85db 712 hflags |= HF_SMAP_MASK;
a9321a4d 713 }
b8b6a50b 714
0f70ed47
PB
715 if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) {
716 new_cr4 &= ~CR4_PKE_MASK;
717 }
718
eaa728ee 719 env->cr[4] = new_cr4;
19dc85db 720 env->hflags = hflags;
f4f1110e
RH
721
722 cpu_sync_bndcs_hflags(env);
b8b6a50b
FB
723}
724
6578eb25 725#if !defined(CONFIG_USER_ONLY)
00b941e5 726hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
14ce26e7 727{
00b941e5
AF
728 X86CPU *cpu = X86_CPU(cs);
729 CPUX86State *env = &cpu->env;
eaa728ee
FB
730 target_ulong pde_addr, pte_addr;
731 uint64_t pte;
c8bc83a4 732 int32_t a20_mask;
eaa728ee
FB
733 uint32_t page_offset;
734 int page_size;
14ce26e7 735
c8bc83a4 736 a20_mask = x86_get_a20_mask(env);
f2f8560c 737 if (!(env->cr[0] & CR0_PG_MASK)) {
c8bc83a4 738 pte = addr & a20_mask;
f2f8560c
PB
739 page_size = 4096;
740 } else if (env->cr[4] & CR4_PAE_MASK) {
eaa728ee
FB
741 target_ulong pdpe_addr;
742 uint64_t pde, pdpe;
14ce26e7 743
eaa728ee
FB
744#ifdef TARGET_X86_64
745 if (env->hflags & HF_LMA_MASK) {
6c7c3c21
KS
746 bool la57 = env->cr[4] & CR4_LA57_MASK;
747 uint64_t pml5e_addr, pml5e;
eaa728ee
FB
748 uint64_t pml4e_addr, pml4e;
749 int32_t sext;
750
751 /* test virtual address sign extension */
6c7c3c21 752 sext = la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47;
16b96f82 753 if (sext != 0 && sext != -1) {
eaa728ee 754 return -1;
16b96f82 755 }
6c7c3c21
KS
756
757 if (la57) {
758 pml5e_addr = ((env->cr[3] & ~0xfff) +
c8bc83a4 759 (((addr >> 48) & 0x1ff) << 3)) & a20_mask;
6c7c3c21
KS
760 pml5e = x86_ldq_phys(cs, pml5e_addr);
761 if (!(pml5e & PG_PRESENT_MASK)) {
762 return -1;
763 }
764 } else {
765 pml5e = env->cr[3];
766 }
767
768 pml4e_addr = ((pml5e & PG_ADDRESS_MASK) +
c8bc83a4 769 (((addr >> 39) & 0x1ff) << 3)) & a20_mask;
b216aa6c 770 pml4e = x86_ldq_phys(cs, pml4e_addr);
16b96f82 771 if (!(pml4e & PG_PRESENT_MASK)) {
eaa728ee 772 return -1;
16b96f82
PB
773 }
774 pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
c8bc83a4 775 (((addr >> 30) & 0x1ff) << 3)) & a20_mask;
b216aa6c 776 pdpe = x86_ldq_phys(cs, pdpe_addr);
16b96f82 777 if (!(pdpe & PG_PRESENT_MASK)) {
eaa728ee 778 return -1;
16b96f82 779 }
c8c14bcb
LC
780 if (pdpe & PG_PSE_MASK) {
781 page_size = 1024 * 1024 * 1024;
16b96f82 782 pte = pdpe;
c8c14bcb
LC
783 goto out;
784 }
785
eaa728ee
FB
786 } else
787#endif
788 {
789 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
c8bc83a4 790 a20_mask;
b216aa6c 791 pdpe = x86_ldq_phys(cs, pdpe_addr);
eaa728ee
FB
792 if (!(pdpe & PG_PRESENT_MASK))
793 return -1;
14ce26e7 794 }
14ce26e7 795
16b96f82 796 pde_addr = ((pdpe & PG_ADDRESS_MASK) +
c8bc83a4 797 (((addr >> 21) & 0x1ff) << 3)) & a20_mask;
b216aa6c 798 pde = x86_ldq_phys(cs, pde_addr);
eaa728ee
FB
799 if (!(pde & PG_PRESENT_MASK)) {
800 return -1;
801 }
802 if (pde & PG_PSE_MASK) {
803 /* 2 MB page */
804 page_size = 2048 * 1024;
16b96f82 805 pte = pde;
eaa728ee
FB
806 } else {
807 /* 4 KB page */
16b96f82 808 pte_addr = ((pde & PG_ADDRESS_MASK) +
c8bc83a4 809 (((addr >> 12) & 0x1ff) << 3)) & a20_mask;
eaa728ee 810 page_size = 4096;
b216aa6c 811 pte = x86_ldq_phys(cs, pte_addr);
eaa728ee 812 }
16b96f82 813 if (!(pte & PG_PRESENT_MASK)) {
ca1c9e15 814 return -1;
16b96f82 815 }
14ce26e7 816 } else {
eaa728ee 817 uint32_t pde;
3b46e624 818
f2f8560c 819 /* page directory entry */
c8bc83a4 820 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & a20_mask;
b216aa6c 821 pde = x86_ldl_phys(cs, pde_addr);
f2f8560c
PB
822 if (!(pde & PG_PRESENT_MASK))
823 return -1;
824 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
388ee48a 825 pte = pde | ((pde & 0x1fe000LL) << (32 - 13));
f2f8560c 826 page_size = 4096 * 1024;
eaa728ee
FB
827 } else {
828 /* page directory entry */
c8bc83a4 829 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_mask;
b216aa6c 830 pte = x86_ldl_phys(cs, pte_addr);
16b96f82 831 if (!(pte & PG_PRESENT_MASK)) {
eaa728ee 832 return -1;
16b96f82 833 }
f2f8560c 834 page_size = 4096;
eaa728ee 835 }
c8bc83a4 836 pte = pte & a20_mask;
14ce26e7 837 }
14ce26e7 838
c8c14bcb
LC
839#ifdef TARGET_X86_64
840out:
841#endif
16b96f82 842 pte &= PG_ADDRESS_MASK & ~(page_size - 1);
eaa728ee 843 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
16b96f82 844 return pte | page_offset;
3b21e03e 845}
01df040b 846
d5bfda33
JK
847typedef struct MCEInjectionParams {
848 Monitor *mon;
d5bfda33
JK
849 int bank;
850 uint64_t status;
851 uint64_t mcg_status;
852 uint64_t addr;
853 uint64_t misc;
854 int flags;
855} MCEInjectionParams;
856
14e6fe12 857static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
79c4f6b0 858{
14e6fe12 859 MCEInjectionParams *params = data.host_ptr;
e0eeb4a2
AB
860 X86CPU *cpu = X86_CPU(cs);
861 CPUX86State *cenv = &cpu->env;
d5bfda33
JK
862 uint64_t *banks = cenv->mce_banks + 4 * params->bank;
863
e0eeb4a2 864 cpu_synchronize_state(cs);
316378e4 865
747461c7
JK
866 /*
867 * If there is an MCE exception being processed, ignore this SRAO MCE
868 * unless unconditional injection was requested.
869 */
d5bfda33
JK
870 if (!(params->flags & MCE_INJECT_UNCOND_AO)
871 && !(params->status & MCI_STATUS_AR)
747461c7
JK
872 && (cenv->mcg_status & MCG_STATUS_MCIP)) {
873 return;
874 }
d5bfda33
JK
875
876 if (params->status & MCI_STATUS_UC) {
316378e4
JK
877 /*
878 * if MSR_MCG_CTL is not all 1s, the uncorrected error
879 * reporting is disabled
880 */
d5bfda33
JK
881 if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
882 monitor_printf(params->mon,
316378e4 883 "CPU %d: Uncorrected error reporting disabled\n",
e0eeb4a2 884 cs->cpu_index);
316378e4
JK
885 return;
886 }
887
888 /*
889 * if MSR_MCi_CTL is not all 1s, the uncorrected error
890 * reporting is disabled for the bank
891 */
892 if (banks[0] != ~(uint64_t)0) {
d5bfda33
JK
893 monitor_printf(params->mon,
894 "CPU %d: Uncorrected error reporting disabled for"
895 " bank %d\n",
e0eeb4a2 896 cs->cpu_index, params->bank);
316378e4
JK
897 return;
898 }
899
79c4f6b0
HY
900 if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
901 !(cenv->cr[4] & CR4_MCE_MASK)) {
d5bfda33
JK
902 monitor_printf(params->mon,
903 "CPU %d: Previous MCE still in progress, raising"
904 " triple fault\n",
e0eeb4a2 905 cs->cpu_index);
79c4f6b0 906 qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
cf83f140 907 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
79c4f6b0
HY
908 return;
909 }
2fa11da0 910 if (banks[1] & MCI_STATUS_VAL) {
d5bfda33 911 params->status |= MCI_STATUS_OVER;
2fa11da0 912 }
d5bfda33
JK
913 banks[2] = params->addr;
914 banks[3] = params->misc;
915 cenv->mcg_status = params->mcg_status;
916 banks[1] = params->status;
e0eeb4a2 917 cpu_interrupt(cs, CPU_INTERRUPT_MCE);
79c4f6b0
HY
918 } else if (!(banks[1] & MCI_STATUS_VAL)
919 || !(banks[1] & MCI_STATUS_UC)) {
2fa11da0 920 if (banks[1] & MCI_STATUS_VAL) {
d5bfda33 921 params->status |= MCI_STATUS_OVER;
2fa11da0 922 }
d5bfda33
JK
923 banks[2] = params->addr;
924 banks[3] = params->misc;
925 banks[1] = params->status;
2fa11da0 926 } else {
79c4f6b0 927 banks[1] |= MCI_STATUS_OVER;
2fa11da0 928 }
79c4f6b0 929}
b3cd24e0 930
8c5cf3b6 931void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
316378e4 932 uint64_t status, uint64_t mcg_status, uint64_t addr,
747461c7 933 uint64_t misc, int flags)
b3cd24e0 934{
182735ef 935 CPUState *cs = CPU(cpu);
8c5cf3b6 936 CPUX86State *cenv = &cpu->env;
d5bfda33
JK
937 MCEInjectionParams params = {
938 .mon = mon,
d5bfda33
JK
939 .bank = bank,
940 .status = status,
941 .mcg_status = mcg_status,
942 .addr = addr,
943 .misc = misc,
944 .flags = flags,
945 };
b3cd24e0
JD
946 unsigned bank_num = cenv->mcg_cap & 0xff;
947
316378e4
JK
948 if (!cenv->mcg_cap) {
949 monitor_printf(mon, "MCE injection not supported\n");
b3cd24e0
JD
950 return;
951 }
316378e4
JK
952 if (bank >= bank_num) {
953 monitor_printf(mon, "Invalid MCE bank number\n");
954 return;
955 }
956 if (!(status & MCI_STATUS_VAL)) {
957 monitor_printf(mon, "Invalid MCE status code\n");
958 return;
959 }
747461c7
JK
960 if ((flags & MCE_INJECT_BROADCAST)
961 && !cpu_x86_support_mca_broadcast(cenv)) {
316378e4
JK
962 monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
963 return;
2bd3e04c
JD
964 }
965
14e6fe12 966 run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
c34d440a 967 if (flags & MCE_INJECT_BROADCAST) {
182735ef
AF
968 CPUState *other_cs;
969
c34d440a
JK
970 params.bank = 1;
971 params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
972 params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
973 params.addr = 0;
974 params.misc = 0;
bdc44640 975 CPU_FOREACH(other_cs) {
182735ef 976 if (other_cs == cs) {
c34d440a 977 continue;
31ce5e0c 978 }
14e6fe12 979 run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
31ce5e0c 980 }
b3cd24e0
JD
981 }
982}
d362e757 983
317ac620 984void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
d362e757 985{
02e51483 986 X86CPU *cpu = x86_env_get_cpu(env);
93afeade 987 CPUState *cs = CPU(cpu);
02e51483 988
19306806 989 if (kvm_enabled() || whpx_enabled()) {
d362e757
JK
990 env->tpr_access_type = access;
991
93afeade 992 cpu_interrupt(cs, CPU_INTERRUPT_TPR);
79c664f6 993 } else if (tcg_enabled()) {
afd46fca 994 cpu_restore_state(cs, cs->mem_io_pc, false);
d362e757 995
02e51483 996 apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
d362e757
JK
997 }
998}
74ce674f 999#endif /* !CONFIG_USER_ONLY */
6fd805e1 1000
84273177
JK
1001int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1002 target_ulong *base, unsigned int *limit,
1003 unsigned int *flags)
1004{
f17ec444
AF
1005 X86CPU *cpu = x86_env_get_cpu(env);
1006 CPUState *cs = CPU(cpu);
84273177
JK
1007 SegmentCache *dt;
1008 target_ulong ptr;
1009 uint32_t e1, e2;
1010 int index;
1011
1012 if (selector & 0x4)
1013 dt = &env->ldt;
1014 else
1015 dt = &env->gdt;
1016 index = selector & ~7;
1017 ptr = dt->base + index;
1018 if ((index + 7) > dt->limit
f17ec444
AF
1019 || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1020 || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
84273177
JK
1021 return 0;
1022
1023 *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1024 *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1025 if (e2 & DESC_G_MASK)
1026 *limit = (*limit << 12) | 0xfff;
1027 *flags = e2;
1028
1029 return 1;
1030}
1031
b09ea7d5 1032#if !defined(CONFIG_USER_ONLY)
232fc23b 1033void do_cpu_init(X86CPU *cpu)
b09ea7d5 1034{
259186a7 1035 CPUState *cs = CPU(cpu);
232fc23b 1036 CPUX86State *env = &cpu->env;
43175fa9 1037 CPUX86State *save = g_new(CPUX86State, 1);
259186a7 1038 int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
43175fa9
PB
1039
1040 *save = *env;
ebda377f 1041
259186a7
AF
1042 cpu_reset(cs);
1043 cs->interrupt_request = sipi;
43175fa9
PB
1044 memcpy(&env->start_init_save, &save->start_init_save,
1045 offsetof(CPUX86State, end_init_save) -
1046 offsetof(CPUX86State, start_init_save));
1047 g_free(save);
1048
e0723c45
PB
1049 if (kvm_enabled()) {
1050 kvm_arch_do_init_vcpu(cpu);
1051 }
02e51483 1052 apic_init_reset(cpu->apic_state);
b09ea7d5
GN
1053}
1054
232fc23b 1055void do_cpu_sipi(X86CPU *cpu)
b09ea7d5 1056{
02e51483 1057 apic_sipi(cpu->apic_state);
b09ea7d5
GN
1058}
1059#else
232fc23b 1060void do_cpu_init(X86CPU *cpu)
b09ea7d5
GN
1061{
1062}
232fc23b 1063void do_cpu_sipi(X86CPU *cpu)
b09ea7d5
GN
1064{
1065}
1066#endif
374e0cd4
RH
1067
1068/* Frob eflags into and out of the CPU temporary format. */
1069
1070void x86_cpu_exec_enter(CPUState *cs)
1071{
1072 X86CPU *cpu = X86_CPU(cs);
1073 CPUX86State *env = &cpu->env;
1074
1075 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1076 env->df = 1 - (2 * ((env->eflags >> 10) & 1));
1077 CC_OP = CC_OP_EFLAGS;
1078 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1079}
1080
1081void x86_cpu_exec_exit(CPUState *cs)
1082{
1083 X86CPU *cpu = X86_CPU(cs);
1084 CPUX86State *env = &cpu->env;
1085
1086 env->eflags = cpu_compute_eflags(env);
1087}
b216aa6c
PB
1088
1089#ifndef CONFIG_USER_ONLY
1090uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr)
1091{
1092 X86CPU *cpu = X86_CPU(cs);
1093 CPUX86State *env = &cpu->env;
f8c45c65
PB
1094 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1095 AddressSpace *as = cpu_addressspace(cs, attrs);
b216aa6c 1096
f8c45c65 1097 return address_space_ldub(as, addr, attrs, NULL);
b216aa6c
PB
1098}
1099
1100uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr)
1101{
1102 X86CPU *cpu = X86_CPU(cs);
1103 CPUX86State *env = &cpu->env;
f8c45c65
PB
1104 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1105 AddressSpace *as = cpu_addressspace(cs, attrs);
b216aa6c 1106
f8c45c65 1107 return address_space_lduw(as, addr, attrs, NULL);
b216aa6c
PB
1108}
1109
1110uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr)
1111{
1112 X86CPU *cpu = X86_CPU(cs);
1113 CPUX86State *env = &cpu->env;
f8c45c65
PB
1114 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1115 AddressSpace *as = cpu_addressspace(cs, attrs);
b216aa6c 1116
f8c45c65 1117 return address_space_ldl(as, addr, attrs, NULL);
b216aa6c
PB
1118}
1119
1120uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr)
1121{
1122 X86CPU *cpu = X86_CPU(cs);
1123 CPUX86State *env = &cpu->env;
f8c45c65
PB
1124 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1125 AddressSpace *as = cpu_addressspace(cs, attrs);
b216aa6c 1126
f8c45c65 1127 return address_space_ldq(as, addr, attrs, NULL);
b216aa6c
PB
1128}
1129
1130void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val)
1131{
1132 X86CPU *cpu = X86_CPU(cs);
1133 CPUX86State *env = &cpu->env;
f8c45c65
PB
1134 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1135 AddressSpace *as = cpu_addressspace(cs, attrs);
b216aa6c 1136
f8c45c65 1137 address_space_stb(as, addr, val, attrs, NULL);
b216aa6c
PB
1138}
1139
1140void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val)
1141{
1142 X86CPU *cpu = X86_CPU(cs);
1143 CPUX86State *env = &cpu->env;
f8c45c65
PB
1144 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1145 AddressSpace *as = cpu_addressspace(cs, attrs);
b216aa6c 1146
f8c45c65 1147 address_space_stl_notdirty(as, addr, val, attrs, NULL);
b216aa6c
PB
1148}
1149
1150void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val)
1151{
1152 X86CPU *cpu = X86_CPU(cs);
1153 CPUX86State *env = &cpu->env;
f8c45c65
PB
1154 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1155 AddressSpace *as = cpu_addressspace(cs, attrs);
b216aa6c 1156
f8c45c65 1157 address_space_stw(as, addr, val, attrs, NULL);
b216aa6c
PB
1158}
1159
1160void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val)
1161{
1162 X86CPU *cpu = X86_CPU(cs);
1163 CPUX86State *env = &cpu->env;
f8c45c65
PB
1164 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1165 AddressSpace *as = cpu_addressspace(cs, attrs);
b216aa6c 1166
f8c45c65 1167 address_space_stl(as, addr, val, attrs, NULL);
b216aa6c
PB
1168}
1169
1170void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val)
1171{
1172 X86CPU *cpu = X86_CPU(cs);
1173 CPUX86State *env = &cpu->env;
f8c45c65
PB
1174 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1175 AddressSpace *as = cpu_addressspace(cs, attrs);
b216aa6c 1176
f8c45c65 1177 address_space_stq(as, addr, val, attrs, NULL);
b216aa6c
PB
1178}
1179#endif