configure / meson: Move check for drm.h to meson.build
[qemu/ar7.git] / target / i386 / helper.c
blob034f46bcc2100f8e0472e4e43f8fd22b66101394
1 /*
2 * i386 helpers (without register variable usage)
4 * Copyright (c) 2003 Fabrice Bellard
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.1 of the License, or (at your option) any later version.
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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "qemu/osdep.h"
21 #include "qapi/qapi-events-run-state.h"
22 #include "cpu.h"
23 #include "exec/exec-all.h"
24 #include "qemu/qemu-print.h"
25 #include "sysemu/kvm.h"
26 #include "sysemu/runstate.h"
27 #include "kvm_i386.h"
28 #ifndef CONFIG_USER_ONLY
29 #include "sysemu/tcg.h"
30 #include "sysemu/hw_accel.h"
31 #include "monitor/monitor.h"
32 #include "hw/i386/apic_internal.h"
33 #endif
35 void cpu_sync_bndcs_hflags(CPUX86State *env)
37 uint32_t hflags = env->hflags;
38 uint32_t hflags2 = env->hflags2;
39 uint32_t bndcsr;
41 if ((hflags & HF_CPL_MASK) == 3) {
42 bndcsr = env->bndcs_regs.cfgu;
43 } else {
44 bndcsr = env->msr_bndcfgs;
47 if ((env->cr[4] & CR4_OSXSAVE_MASK)
48 && (env->xcr0 & XSTATE_BNDCSR_MASK)
49 && (bndcsr & BNDCFG_ENABLE)) {
50 hflags |= HF_MPX_EN_MASK;
51 } else {
52 hflags &= ~HF_MPX_EN_MASK;
55 if (bndcsr & BNDCFG_BNDPRESERVE) {
56 hflags2 |= HF2_MPX_PR_MASK;
57 } else {
58 hflags2 &= ~HF2_MPX_PR_MASK;
61 env->hflags = hflags;
62 env->hflags2 = hflags2;
65 static void cpu_x86_version(CPUX86State *env, int *family, int *model)
67 int cpuver = env->cpuid_version;
69 if (family == NULL || model == NULL) {
70 return;
73 *family = (cpuver >> 8) & 0x0f;
74 *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
77 /* Broadcast MCA signal for processor version 06H_EH and above */
78 int cpu_x86_support_mca_broadcast(CPUX86State *env)
80 int family = 0;
81 int model = 0;
83 cpu_x86_version(env, &family, &model);
84 if ((family == 6 && model >= 14) || family > 6) {
85 return 1;
88 return 0;
91 /***********************************************************/
92 /* x86 debug */
94 static const char *cc_op_str[CC_OP_NB] = {
95 "DYNAMIC",
96 "EFLAGS",
98 "MULB",
99 "MULW",
100 "MULL",
101 "MULQ",
103 "ADDB",
104 "ADDW",
105 "ADDL",
106 "ADDQ",
108 "ADCB",
109 "ADCW",
110 "ADCL",
111 "ADCQ",
113 "SUBB",
114 "SUBW",
115 "SUBL",
116 "SUBQ",
118 "SBBB",
119 "SBBW",
120 "SBBL",
121 "SBBQ",
123 "LOGICB",
124 "LOGICW",
125 "LOGICL",
126 "LOGICQ",
128 "INCB",
129 "INCW",
130 "INCL",
131 "INCQ",
133 "DECB",
134 "DECW",
135 "DECL",
136 "DECQ",
138 "SHLB",
139 "SHLW",
140 "SHLL",
141 "SHLQ",
143 "SARB",
144 "SARW",
145 "SARL",
146 "SARQ",
148 "BMILGB",
149 "BMILGW",
150 "BMILGL",
151 "BMILGQ",
153 "ADCX",
154 "ADOX",
155 "ADCOX",
157 "CLR",
160 static void
161 cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f,
162 const char *name, struct SegmentCache *sc)
164 #ifdef TARGET_X86_64
165 if (env->hflags & HF_CS64_MASK) {
166 qemu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
167 sc->selector, sc->base, sc->limit,
168 sc->flags & 0x00ffff00);
169 } else
170 #endif
172 qemu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
173 (uint32_t)sc->base, sc->limit,
174 sc->flags & 0x00ffff00);
177 if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
178 goto done;
180 qemu_fprintf(f, " DPL=%d ",
181 (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
182 if (sc->flags & DESC_S_MASK) {
183 if (sc->flags & DESC_CS_MASK) {
184 qemu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
185 ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
186 qemu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
187 (sc->flags & DESC_R_MASK) ? 'R' : '-');
188 } else {
189 qemu_fprintf(f, (sc->flags & DESC_B_MASK
190 || env->hflags & HF_LMA_MASK)
191 ? "DS " : "DS16");
192 qemu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
193 (sc->flags & DESC_W_MASK) ? 'W' : '-');
195 qemu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
196 } else {
197 static const char *sys_type_name[2][16] = {
198 { /* 32 bit mode */
199 "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
200 "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
201 "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
202 "CallGate32", "Reserved", "IntGate32", "TrapGate32"
204 { /* 64 bit mode */
205 "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
206 "Reserved", "Reserved", "Reserved", "Reserved",
207 "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
208 "Reserved", "IntGate64", "TrapGate64"
211 qemu_fprintf(f, "%s",
212 sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
213 [(sc->flags & DESC_TYPE_MASK) >> DESC_TYPE_SHIFT]);
215 done:
216 qemu_fprintf(f, "\n");
219 #ifndef CONFIG_USER_ONLY
221 /* ARRAY_SIZE check is not required because
222 * DeliveryMode(dm) has a size of 3 bit.
224 static inline const char *dm2str(uint32_t dm)
226 static const char *str[] = {
227 "Fixed",
228 "...",
229 "SMI",
230 "...",
231 "NMI",
232 "INIT",
233 "...",
234 "ExtINT"
236 return str[dm];
239 static void dump_apic_lvt(const char *name, uint32_t lvt, bool is_timer)
241 uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT;
242 qemu_printf("%s\t 0x%08x %s %-5s %-6s %-7s %-12s %-6s",
243 name, lvt,
244 lvt & APIC_LVT_INT_POLARITY ? "active-lo" : "active-hi",
245 lvt & APIC_LVT_LEVEL_TRIGGER ? "level" : "edge",
246 lvt & APIC_LVT_MASKED ? "masked" : "",
247 lvt & APIC_LVT_DELIV_STS ? "pending" : "",
248 !is_timer ?
249 "" : lvt & APIC_LVT_TIMER_PERIODIC ?
250 "periodic" : lvt & APIC_LVT_TIMER_TSCDEADLINE ?
251 "tsc-deadline" : "one-shot",
252 dm2str(dm));
253 if (dm != APIC_DM_NMI) {
254 qemu_printf(" (vec %u)\n", lvt & APIC_VECTOR_MASK);
255 } else {
256 qemu_printf("\n");
260 /* ARRAY_SIZE check is not required because
261 * destination shorthand has a size of 2 bit.
263 static inline const char *shorthand2str(uint32_t shorthand)
265 const char *str[] = {
266 "no-shorthand", "self", "all-self", "all"
268 return str[shorthand];
271 static inline uint8_t divider_conf(uint32_t divide_conf)
273 uint8_t divide_val = ((divide_conf & 0x8) >> 1) | (divide_conf & 0x3);
275 return divide_val == 7 ? 1 : 2 << divide_val;
278 static inline void mask2str(char *str, uint32_t val, uint8_t size)
280 while (size--) {
281 *str++ = (val >> size) & 1 ? '1' : '0';
283 *str = 0;
286 #define MAX_LOGICAL_APIC_ID_MASK_SIZE 16
288 static void dump_apic_icr(APICCommonState *s, CPUX86State *env)
290 uint32_t icr = s->icr[0], icr2 = s->icr[1];
291 uint8_t dest_shorthand = \
292 (icr & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT;
293 bool logical_mod = icr & APIC_ICR_DEST_MOD;
294 char apic_id_str[MAX_LOGICAL_APIC_ID_MASK_SIZE + 1];
295 uint32_t dest_field;
296 bool x2apic;
298 qemu_printf("ICR\t 0x%08x %s %s %s %s\n",
299 icr,
300 logical_mod ? "logical" : "physical",
301 icr & APIC_ICR_TRIGGER_MOD ? "level" : "edge",
302 icr & APIC_ICR_LEVEL ? "assert" : "de-assert",
303 shorthand2str(dest_shorthand));
305 qemu_printf("ICR2\t 0x%08x", icr2);
306 if (dest_shorthand != 0) {
307 qemu_printf("\n");
308 return;
310 x2apic = env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC;
311 dest_field = x2apic ? icr2 : icr2 >> APIC_ICR_DEST_SHIFT;
313 if (!logical_mod) {
314 if (x2apic) {
315 qemu_printf(" cpu %u (X2APIC ID)\n", dest_field);
316 } else {
317 qemu_printf(" cpu %u (APIC ID)\n",
318 dest_field & APIC_LOGDEST_XAPIC_ID);
320 return;
323 if (s->dest_mode == 0xf) { /* flat mode */
324 mask2str(apic_id_str, icr2 >> APIC_ICR_DEST_SHIFT, 8);
325 qemu_printf(" mask %s (APIC ID)\n", apic_id_str);
326 } else if (s->dest_mode == 0) { /* cluster mode */
327 if (x2apic) {
328 mask2str(apic_id_str, dest_field & APIC_LOGDEST_X2APIC_ID, 16);
329 qemu_printf(" cluster %u mask %s (X2APIC ID)\n",
330 dest_field >> APIC_LOGDEST_X2APIC_SHIFT, apic_id_str);
331 } else {
332 mask2str(apic_id_str, dest_field & APIC_LOGDEST_XAPIC_ID, 4);
333 qemu_printf(" cluster %u mask %s (APIC ID)\n",
334 dest_field >> APIC_LOGDEST_XAPIC_SHIFT, apic_id_str);
339 static void dump_apic_interrupt(const char *name, uint32_t *ireg_tab,
340 uint32_t *tmr_tab)
342 int i, empty = true;
344 qemu_printf("%s\t ", name);
345 for (i = 0; i < 256; i++) {
346 if (apic_get_bit(ireg_tab, i)) {
347 qemu_printf("%u%s ", i,
348 apic_get_bit(tmr_tab, i) ? "(level)" : "");
349 empty = false;
352 qemu_printf("%s\n", empty ? "(none)" : "");
355 void x86_cpu_dump_local_apic_state(CPUState *cs, int flags)
357 X86CPU *cpu = X86_CPU(cs);
358 APICCommonState *s = APIC_COMMON(cpu->apic_state);
359 if (!s) {
360 qemu_printf("local apic state not available\n");
361 return;
363 uint32_t *lvt = s->lvt;
365 qemu_printf("dumping local APIC state for CPU %-2u\n\n",
366 CPU(cpu)->cpu_index);
367 dump_apic_lvt("LVT0", lvt[APIC_LVT_LINT0], false);
368 dump_apic_lvt("LVT1", lvt[APIC_LVT_LINT1], false);
369 dump_apic_lvt("LVTPC", lvt[APIC_LVT_PERFORM], false);
370 dump_apic_lvt("LVTERR", lvt[APIC_LVT_ERROR], false);
371 dump_apic_lvt("LVTTHMR", lvt[APIC_LVT_THERMAL], false);
372 dump_apic_lvt("LVTT", lvt[APIC_LVT_TIMER], true);
374 qemu_printf("Timer\t DCR=0x%x (divide by %u) initial_count = %u"
375 " current_count = %u\n",
376 s->divide_conf & APIC_DCR_MASK,
377 divider_conf(s->divide_conf),
378 s->initial_count, apic_get_current_count(s));
380 qemu_printf("SPIV\t 0x%08x APIC %s, focus=%s, spurious vec %u\n",
381 s->spurious_vec,
382 s->spurious_vec & APIC_SPURIO_ENABLED ? "enabled" : "disabled",
383 s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off",
384 s->spurious_vec & APIC_VECTOR_MASK);
386 dump_apic_icr(s, &cpu->env);
388 qemu_printf("ESR\t 0x%08x\n", s->esr);
390 dump_apic_interrupt("ISR", s->isr, s->tmr);
391 dump_apic_interrupt("IRR", s->irr, s->tmr);
393 qemu_printf("\nAPR 0x%02x TPR 0x%02x DFR 0x%02x LDR 0x%02x",
394 s->arb_id, s->tpr, s->dest_mode, s->log_dest);
395 if (s->dest_mode == 0) {
396 qemu_printf("(cluster %u: id %u)",
397 s->log_dest >> APIC_LOGDEST_XAPIC_SHIFT,
398 s->log_dest & APIC_LOGDEST_XAPIC_ID);
400 qemu_printf(" PPR 0x%02x\n", apic_get_ppr(s));
402 #else
403 void x86_cpu_dump_local_apic_state(CPUState *cs, int flags)
406 #endif /* !CONFIG_USER_ONLY */
408 #define DUMP_CODE_BYTES_TOTAL 50
409 #define DUMP_CODE_BYTES_BACKWARD 20
411 void x86_cpu_dump_state(CPUState *cs, FILE *f, int flags)
413 X86CPU *cpu = X86_CPU(cs);
414 CPUX86State *env = &cpu->env;
415 int eflags, i, nb;
416 char cc_op_name[32];
417 static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
419 eflags = cpu_compute_eflags(env);
420 #ifdef TARGET_X86_64
421 if (env->hflags & HF_CS64_MASK) {
422 qemu_fprintf(f, "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
423 "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
424 "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
425 "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
426 "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
427 env->regs[R_EAX],
428 env->regs[R_EBX],
429 env->regs[R_ECX],
430 env->regs[R_EDX],
431 env->regs[R_ESI],
432 env->regs[R_EDI],
433 env->regs[R_EBP],
434 env->regs[R_ESP],
435 env->regs[8],
436 env->regs[9],
437 env->regs[10],
438 env->regs[11],
439 env->regs[12],
440 env->regs[13],
441 env->regs[14],
442 env->regs[15],
443 env->eip, eflags,
444 eflags & DF_MASK ? 'D' : '-',
445 eflags & CC_O ? 'O' : '-',
446 eflags & CC_S ? 'S' : '-',
447 eflags & CC_Z ? 'Z' : '-',
448 eflags & CC_A ? 'A' : '-',
449 eflags & CC_P ? 'P' : '-',
450 eflags & CC_C ? 'C' : '-',
451 env->hflags & HF_CPL_MASK,
452 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
453 (env->a20_mask >> 20) & 1,
454 (env->hflags >> HF_SMM_SHIFT) & 1,
455 cs->halted);
456 } else
457 #endif
459 qemu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
460 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
461 "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
462 (uint32_t)env->regs[R_EAX],
463 (uint32_t)env->regs[R_EBX],
464 (uint32_t)env->regs[R_ECX],
465 (uint32_t)env->regs[R_EDX],
466 (uint32_t)env->regs[R_ESI],
467 (uint32_t)env->regs[R_EDI],
468 (uint32_t)env->regs[R_EBP],
469 (uint32_t)env->regs[R_ESP],
470 (uint32_t)env->eip, eflags,
471 eflags & DF_MASK ? 'D' : '-',
472 eflags & CC_O ? 'O' : '-',
473 eflags & CC_S ? 'S' : '-',
474 eflags & CC_Z ? 'Z' : '-',
475 eflags & CC_A ? 'A' : '-',
476 eflags & CC_P ? 'P' : '-',
477 eflags & CC_C ? 'C' : '-',
478 env->hflags & HF_CPL_MASK,
479 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
480 (env->a20_mask >> 20) & 1,
481 (env->hflags >> HF_SMM_SHIFT) & 1,
482 cs->halted);
485 for(i = 0; i < 6; i++) {
486 cpu_x86_dump_seg_cache(env, f, seg_name[i], &env->segs[i]);
488 cpu_x86_dump_seg_cache(env, f, "LDT", &env->ldt);
489 cpu_x86_dump_seg_cache(env, f, "TR", &env->tr);
491 #ifdef TARGET_X86_64
492 if (env->hflags & HF_LMA_MASK) {
493 qemu_fprintf(f, "GDT= %016" PRIx64 " %08x\n",
494 env->gdt.base, env->gdt.limit);
495 qemu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
496 env->idt.base, env->idt.limit);
497 qemu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
498 (uint32_t)env->cr[0],
499 env->cr[2],
500 env->cr[3],
501 (uint32_t)env->cr[4]);
502 for(i = 0; i < 4; i++)
503 qemu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
504 qemu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
505 env->dr[6], env->dr[7]);
506 } else
507 #endif
509 qemu_fprintf(f, "GDT= %08x %08x\n",
510 (uint32_t)env->gdt.base, env->gdt.limit);
511 qemu_fprintf(f, "IDT= %08x %08x\n",
512 (uint32_t)env->idt.base, env->idt.limit);
513 qemu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
514 (uint32_t)env->cr[0],
515 (uint32_t)env->cr[2],
516 (uint32_t)env->cr[3],
517 (uint32_t)env->cr[4]);
518 for(i = 0; i < 4; i++) {
519 qemu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
521 qemu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
522 env->dr[6], env->dr[7]);
524 if (flags & CPU_DUMP_CCOP) {
525 if ((unsigned)env->cc_op < CC_OP_NB)
526 snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
527 else
528 snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
529 #ifdef TARGET_X86_64
530 if (env->hflags & HF_CS64_MASK) {
531 qemu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
532 env->cc_src, env->cc_dst,
533 cc_op_name);
534 } else
535 #endif
537 qemu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
538 (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
539 cc_op_name);
542 qemu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
543 if (flags & CPU_DUMP_FPU) {
544 int fptag;
545 fptag = 0;
546 for(i = 0; i < 8; i++) {
547 fptag |= ((!env->fptags[i]) << i);
549 update_mxcsr_from_sse_status(env);
550 qemu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
551 env->fpuc,
552 (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
553 env->fpstt,
554 fptag,
555 env->mxcsr);
556 for(i=0;i<8;i++) {
557 CPU_LDoubleU u;
558 u.d = env->fpregs[i].d;
559 qemu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
560 i, u.l.lower, u.l.upper);
561 if ((i & 1) == 1)
562 qemu_fprintf(f, "\n");
563 else
564 qemu_fprintf(f, " ");
566 if (env->hflags & HF_CS64_MASK)
567 nb = 16;
568 else
569 nb = 8;
570 for(i=0;i<nb;i++) {
571 qemu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
573 env->xmm_regs[i].ZMM_L(3),
574 env->xmm_regs[i].ZMM_L(2),
575 env->xmm_regs[i].ZMM_L(1),
576 env->xmm_regs[i].ZMM_L(0));
577 if ((i & 1) == 1)
578 qemu_fprintf(f, "\n");
579 else
580 qemu_fprintf(f, " ");
583 if (flags & CPU_DUMP_CODE) {
584 target_ulong base = env->segs[R_CS].base + env->eip;
585 target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
586 uint8_t code;
587 char codestr[3];
589 qemu_fprintf(f, "Code=");
590 for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
591 if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
592 snprintf(codestr, sizeof(codestr), "%02x", code);
593 } else {
594 snprintf(codestr, sizeof(codestr), "??");
596 qemu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
597 i == offs ? "<" : "", codestr, i == offs ? ">" : "");
599 qemu_fprintf(f, "\n");
603 /***********************************************************/
604 /* x86 mmu */
605 /* XXX: add PGE support */
607 void x86_cpu_set_a20(X86CPU *cpu, int a20_state)
609 CPUX86State *env = &cpu->env;
611 a20_state = (a20_state != 0);
612 if (a20_state != ((env->a20_mask >> 20) & 1)) {
613 CPUState *cs = CPU(cpu);
615 qemu_log_mask(CPU_LOG_MMU, "A20 update: a20=%d\n", a20_state);
616 /* if the cpu is currently executing code, we must unlink it and
617 all the potentially executing TB */
618 cpu_interrupt(cs, CPU_INTERRUPT_EXITTB);
620 /* when a20 is changed, all the MMU mappings are invalid, so
621 we must flush everything */
622 tlb_flush(cs);
623 env->a20_mask = ~(1 << 20) | (a20_state << 20);
627 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
629 X86CPU *cpu = env_archcpu(env);
630 int pe_state;
632 qemu_log_mask(CPU_LOG_MMU, "CR0 update: CR0=0x%08x\n", new_cr0);
633 if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
634 (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
635 tlb_flush(CPU(cpu));
638 #ifdef TARGET_X86_64
639 if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
640 (env->efer & MSR_EFER_LME)) {
641 /* enter in long mode */
642 /* XXX: generate an exception */
643 if (!(env->cr[4] & CR4_PAE_MASK))
644 return;
645 env->efer |= MSR_EFER_LMA;
646 env->hflags |= HF_LMA_MASK;
647 } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
648 (env->efer & MSR_EFER_LMA)) {
649 /* exit long mode */
650 env->efer &= ~MSR_EFER_LMA;
651 env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
652 env->eip &= 0xffffffff;
654 #endif
655 env->cr[0] = new_cr0 | CR0_ET_MASK;
657 /* update PE flag in hidden flags */
658 pe_state = (env->cr[0] & CR0_PE_MASK);
659 env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
660 /* ensure that ADDSEG is always set in real mode */
661 env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
662 /* update FPU flags */
663 env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
664 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
667 /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
668 the PDPT */
669 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
671 env->cr[3] = new_cr3;
672 if (env->cr[0] & CR0_PG_MASK) {
673 qemu_log_mask(CPU_LOG_MMU,
674 "CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
675 tlb_flush(env_cpu(env));
679 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
681 uint32_t hflags;
683 #if defined(DEBUG_MMU)
684 printf("CR4 update: %08x -> %08x\n", (uint32_t)env->cr[4], new_cr4);
685 #endif
686 if ((new_cr4 ^ env->cr[4]) &
687 (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK |
688 CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_LA57_MASK)) {
689 tlb_flush(env_cpu(env));
692 /* Clear bits we're going to recompute. */
693 hflags = env->hflags & ~(HF_OSFXSR_MASK | HF_SMAP_MASK);
695 /* SSE handling */
696 if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) {
697 new_cr4 &= ~CR4_OSFXSR_MASK;
699 if (new_cr4 & CR4_OSFXSR_MASK) {
700 hflags |= HF_OSFXSR_MASK;
703 if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) {
704 new_cr4 &= ~CR4_SMAP_MASK;
706 if (new_cr4 & CR4_SMAP_MASK) {
707 hflags |= HF_SMAP_MASK;
710 if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) {
711 new_cr4 &= ~CR4_PKE_MASK;
714 env->cr[4] = new_cr4;
715 env->hflags = hflags;
717 cpu_sync_bndcs_hflags(env);
720 #if !defined(CONFIG_USER_ONLY)
721 hwaddr x86_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
722 MemTxAttrs *attrs)
724 X86CPU *cpu = X86_CPU(cs);
725 CPUX86State *env = &cpu->env;
726 target_ulong pde_addr, pte_addr;
727 uint64_t pte;
728 int32_t a20_mask;
729 uint32_t page_offset;
730 int page_size;
732 *attrs = cpu_get_mem_attrs(env);
734 a20_mask = x86_get_a20_mask(env);
735 if (!(env->cr[0] & CR0_PG_MASK)) {
736 pte = addr & a20_mask;
737 page_size = 4096;
738 } else if (env->cr[4] & CR4_PAE_MASK) {
739 target_ulong pdpe_addr;
740 uint64_t pde, pdpe;
742 #ifdef TARGET_X86_64
743 if (env->hflags & HF_LMA_MASK) {
744 bool la57 = env->cr[4] & CR4_LA57_MASK;
745 uint64_t pml5e_addr, pml5e;
746 uint64_t pml4e_addr, pml4e;
747 int32_t sext;
749 /* test virtual address sign extension */
750 sext = la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47;
751 if (sext != 0 && sext != -1) {
752 return -1;
755 if (la57) {
756 pml5e_addr = ((env->cr[3] & ~0xfff) +
757 (((addr >> 48) & 0x1ff) << 3)) & a20_mask;
758 pml5e = x86_ldq_phys(cs, pml5e_addr);
759 if (!(pml5e & PG_PRESENT_MASK)) {
760 return -1;
762 } else {
763 pml5e = env->cr[3];
766 pml4e_addr = ((pml5e & PG_ADDRESS_MASK) +
767 (((addr >> 39) & 0x1ff) << 3)) & a20_mask;
768 pml4e = x86_ldq_phys(cs, pml4e_addr);
769 if (!(pml4e & PG_PRESENT_MASK)) {
770 return -1;
772 pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
773 (((addr >> 30) & 0x1ff) << 3)) & a20_mask;
774 pdpe = x86_ldq_phys(cs, pdpe_addr);
775 if (!(pdpe & PG_PRESENT_MASK)) {
776 return -1;
778 if (pdpe & PG_PSE_MASK) {
779 page_size = 1024 * 1024 * 1024;
780 pte = pdpe;
781 goto out;
784 } else
785 #endif
787 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
788 a20_mask;
789 pdpe = x86_ldq_phys(cs, pdpe_addr);
790 if (!(pdpe & PG_PRESENT_MASK))
791 return -1;
794 pde_addr = ((pdpe & PG_ADDRESS_MASK) +
795 (((addr >> 21) & 0x1ff) << 3)) & a20_mask;
796 pde = x86_ldq_phys(cs, pde_addr);
797 if (!(pde & PG_PRESENT_MASK)) {
798 return -1;
800 if (pde & PG_PSE_MASK) {
801 /* 2 MB page */
802 page_size = 2048 * 1024;
803 pte = pde;
804 } else {
805 /* 4 KB page */
806 pte_addr = ((pde & PG_ADDRESS_MASK) +
807 (((addr >> 12) & 0x1ff) << 3)) & a20_mask;
808 page_size = 4096;
809 pte = x86_ldq_phys(cs, pte_addr);
811 if (!(pte & PG_PRESENT_MASK)) {
812 return -1;
814 } else {
815 uint32_t pde;
817 /* page directory entry */
818 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & a20_mask;
819 pde = x86_ldl_phys(cs, pde_addr);
820 if (!(pde & PG_PRESENT_MASK))
821 return -1;
822 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
823 pte = pde | ((pde & 0x1fe000LL) << (32 - 13));
824 page_size = 4096 * 1024;
825 } else {
826 /* page directory entry */
827 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_mask;
828 pte = x86_ldl_phys(cs, pte_addr);
829 if (!(pte & PG_PRESENT_MASK)) {
830 return -1;
832 page_size = 4096;
834 pte = pte & a20_mask;
837 #ifdef TARGET_X86_64
838 out:
839 #endif
840 pte &= PG_ADDRESS_MASK & ~(page_size - 1);
841 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
842 return pte | page_offset;
845 typedef struct MCEInjectionParams {
846 Monitor *mon;
847 int bank;
848 uint64_t status;
849 uint64_t mcg_status;
850 uint64_t addr;
851 uint64_t misc;
852 int flags;
853 } MCEInjectionParams;
855 static void emit_guest_memory_failure(MemoryFailureAction action, bool ar,
856 bool recursive)
858 MemoryFailureFlags mff = {.action_required = ar, .recursive = recursive};
860 qapi_event_send_memory_failure(MEMORY_FAILURE_RECIPIENT_GUEST, action,
861 &mff);
864 static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
866 MCEInjectionParams *params = data.host_ptr;
867 X86CPU *cpu = X86_CPU(cs);
868 CPUX86State *cenv = &cpu->env;
869 uint64_t *banks = cenv->mce_banks + 4 * params->bank;
870 g_autofree char *msg = NULL;
871 bool need_reset = false;
872 bool recursive;
873 bool ar = !!(params->status & MCI_STATUS_AR);
875 cpu_synchronize_state(cs);
876 recursive = !!(cenv->mcg_status & MCG_STATUS_MCIP);
879 * If there is an MCE exception being processed, ignore this SRAO MCE
880 * unless unconditional injection was requested.
882 if (!(params->flags & MCE_INJECT_UNCOND_AO) && !ar && recursive) {
883 emit_guest_memory_failure(MEMORY_FAILURE_ACTION_IGNORE, ar, recursive);
884 return;
887 if (params->status & MCI_STATUS_UC) {
889 * if MSR_MCG_CTL is not all 1s, the uncorrected error
890 * reporting is disabled
892 if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
893 monitor_printf(params->mon,
894 "CPU %d: Uncorrected error reporting disabled\n",
895 cs->cpu_index);
896 return;
900 * if MSR_MCi_CTL is not all 1s, the uncorrected error
901 * reporting is disabled for the bank
903 if (banks[0] != ~(uint64_t)0) {
904 monitor_printf(params->mon,
905 "CPU %d: Uncorrected error reporting disabled for"
906 " bank %d\n",
907 cs->cpu_index, params->bank);
908 return;
911 if (!(cenv->cr[4] & CR4_MCE_MASK)) {
912 need_reset = true;
913 msg = g_strdup_printf("CPU %d: MCE capability is not enabled, "
914 "raising triple fault", cs->cpu_index);
915 } else if (recursive) {
916 need_reset = true;
917 msg = g_strdup_printf("CPU %d: Previous MCE still in progress, "
918 "raising triple fault", cs->cpu_index);
921 if (need_reset) {
922 emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar,
923 recursive);
924 monitor_printf(params->mon, "%s", msg);
925 qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
926 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
927 return;
930 if (banks[1] & MCI_STATUS_VAL) {
931 params->status |= MCI_STATUS_OVER;
933 banks[2] = params->addr;
934 banks[3] = params->misc;
935 cenv->mcg_status = params->mcg_status;
936 banks[1] = params->status;
937 cpu_interrupt(cs, CPU_INTERRUPT_MCE);
938 } else if (!(banks[1] & MCI_STATUS_VAL)
939 || !(banks[1] & MCI_STATUS_UC)) {
940 if (banks[1] & MCI_STATUS_VAL) {
941 params->status |= MCI_STATUS_OVER;
943 banks[2] = params->addr;
944 banks[3] = params->misc;
945 banks[1] = params->status;
946 } else {
947 banks[1] |= MCI_STATUS_OVER;
950 emit_guest_memory_failure(MEMORY_FAILURE_ACTION_INJECT, ar, recursive);
953 void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
954 uint64_t status, uint64_t mcg_status, uint64_t addr,
955 uint64_t misc, int flags)
957 CPUState *cs = CPU(cpu);
958 CPUX86State *cenv = &cpu->env;
959 MCEInjectionParams params = {
960 .mon = mon,
961 .bank = bank,
962 .status = status,
963 .mcg_status = mcg_status,
964 .addr = addr,
965 .misc = misc,
966 .flags = flags,
968 unsigned bank_num = cenv->mcg_cap & 0xff;
970 if (!cenv->mcg_cap) {
971 monitor_printf(mon, "MCE injection not supported\n");
972 return;
974 if (bank >= bank_num) {
975 monitor_printf(mon, "Invalid MCE bank number\n");
976 return;
978 if (!(status & MCI_STATUS_VAL)) {
979 monitor_printf(mon, "Invalid MCE status code\n");
980 return;
982 if ((flags & MCE_INJECT_BROADCAST)
983 && !cpu_x86_support_mca_broadcast(cenv)) {
984 monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
985 return;
988 run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
989 if (flags & MCE_INJECT_BROADCAST) {
990 CPUState *other_cs;
992 params.bank = 1;
993 params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
994 params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
995 params.addr = 0;
996 params.misc = 0;
997 CPU_FOREACH(other_cs) {
998 if (other_cs == cs) {
999 continue;
1001 run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
1006 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
1008 X86CPU *cpu = env_archcpu(env);
1009 CPUState *cs = env_cpu(env);
1011 if (kvm_enabled() || whpx_enabled()) {
1012 env->tpr_access_type = access;
1014 cpu_interrupt(cs, CPU_INTERRUPT_TPR);
1015 } else if (tcg_enabled()) {
1016 cpu_restore_state(cs, cs->mem_io_pc, false);
1018 apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
1021 #endif /* !CONFIG_USER_ONLY */
1023 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1024 target_ulong *base, unsigned int *limit,
1025 unsigned int *flags)
1027 CPUState *cs = env_cpu(env);
1028 SegmentCache *dt;
1029 target_ulong ptr;
1030 uint32_t e1, e2;
1031 int index;
1033 if (selector & 0x4)
1034 dt = &env->ldt;
1035 else
1036 dt = &env->gdt;
1037 index = selector & ~7;
1038 ptr = dt->base + index;
1039 if ((index + 7) > dt->limit
1040 || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1041 || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1042 return 0;
1044 *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1045 *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1046 if (e2 & DESC_G_MASK)
1047 *limit = (*limit << 12) | 0xfff;
1048 *flags = e2;
1050 return 1;
1053 #if !defined(CONFIG_USER_ONLY)
1054 void do_cpu_init(X86CPU *cpu)
1056 CPUState *cs = CPU(cpu);
1057 CPUX86State *env = &cpu->env;
1058 CPUX86State *save = g_new(CPUX86State, 1);
1059 int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
1061 *save = *env;
1063 cpu_reset(cs);
1064 cs->interrupt_request = sipi;
1065 memcpy(&env->start_init_save, &save->start_init_save,
1066 offsetof(CPUX86State, end_init_save) -
1067 offsetof(CPUX86State, start_init_save));
1068 g_free(save);
1070 if (kvm_enabled()) {
1071 kvm_arch_do_init_vcpu(cpu);
1073 apic_init_reset(cpu->apic_state);
1076 void do_cpu_sipi(X86CPU *cpu)
1078 apic_sipi(cpu->apic_state);
1080 #else
1081 void do_cpu_init(X86CPU *cpu)
1084 void do_cpu_sipi(X86CPU *cpu)
1087 #endif
1089 /* Frob eflags into and out of the CPU temporary format. */
1091 void x86_cpu_exec_enter(CPUState *cs)
1093 X86CPU *cpu = X86_CPU(cs);
1094 CPUX86State *env = &cpu->env;
1096 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1097 env->df = 1 - (2 * ((env->eflags >> 10) & 1));
1098 CC_OP = CC_OP_EFLAGS;
1099 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1102 void x86_cpu_exec_exit(CPUState *cs)
1104 X86CPU *cpu = X86_CPU(cs);
1105 CPUX86State *env = &cpu->env;
1107 env->eflags = cpu_compute_eflags(env);
1110 #ifndef CONFIG_USER_ONLY
1111 uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr)
1113 X86CPU *cpu = X86_CPU(cs);
1114 CPUX86State *env = &cpu->env;
1115 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1116 AddressSpace *as = cpu_addressspace(cs, attrs);
1118 return address_space_ldub(as, addr, attrs, NULL);
1121 uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr)
1123 X86CPU *cpu = X86_CPU(cs);
1124 CPUX86State *env = &cpu->env;
1125 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1126 AddressSpace *as = cpu_addressspace(cs, attrs);
1128 return address_space_lduw(as, addr, attrs, NULL);
1131 uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr)
1133 X86CPU *cpu = X86_CPU(cs);
1134 CPUX86State *env = &cpu->env;
1135 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1136 AddressSpace *as = cpu_addressspace(cs, attrs);
1138 return address_space_ldl(as, addr, attrs, NULL);
1141 uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr)
1143 X86CPU *cpu = X86_CPU(cs);
1144 CPUX86State *env = &cpu->env;
1145 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1146 AddressSpace *as = cpu_addressspace(cs, attrs);
1148 return address_space_ldq(as, addr, attrs, NULL);
1151 void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val)
1153 X86CPU *cpu = X86_CPU(cs);
1154 CPUX86State *env = &cpu->env;
1155 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1156 AddressSpace *as = cpu_addressspace(cs, attrs);
1158 address_space_stb(as, addr, val, attrs, NULL);
1161 void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val)
1163 X86CPU *cpu = X86_CPU(cs);
1164 CPUX86State *env = &cpu->env;
1165 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1166 AddressSpace *as = cpu_addressspace(cs, attrs);
1168 address_space_stl_notdirty(as, addr, val, attrs, NULL);
1171 void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val)
1173 X86CPU *cpu = X86_CPU(cs);
1174 CPUX86State *env = &cpu->env;
1175 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1176 AddressSpace *as = cpu_addressspace(cs, attrs);
1178 address_space_stw(as, addr, val, attrs, NULL);
1181 void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val)
1183 X86CPU *cpu = X86_CPU(cs);
1184 CPUX86State *env = &cpu->env;
1185 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1186 AddressSpace *as = cpu_addressspace(cs, attrs);
1188 address_space_stl(as, addr, val, attrs, NULL);
1191 void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val)
1193 X86CPU *cpu = X86_CPU(cs);
1194 CPUX86State *env = &cpu->env;
1195 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1196 AddressSpace *as = cpu_addressspace(cs, attrs);
1198 address_space_stq(as, addr, val, attrs, NULL);
1200 #endif