tcg/i386: Fix dupi for avx2 32-bit hosts
[qemu/ar7.git] / target / i386 / helper.c
blob32fa21a7bbf87f00693c9dc872405c2ebf67981a
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 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 (recursive) {
912 need_reset = true;
913 msg = g_strdup_printf("CPU %d: Previous MCE still in progress, "
914 "raising triple fault", cs->cpu_index);
917 if (!(cenv->cr[4] & CR4_MCE_MASK)) {
918 need_reset = true;
919 msg = g_strdup_printf("CPU %d: MCE capability is not enabled, "
920 "raising triple fault", cs->cpu_index);
923 if (need_reset) {
924 emit_guest_memory_failure(MEMORY_FAILURE_ACTION_RESET, ar,
925 recursive);
926 monitor_printf(params->mon, "%s", msg);
927 qemu_log_mask(CPU_LOG_RESET, "%s\n", msg);
928 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
929 return;
932 if (banks[1] & MCI_STATUS_VAL) {
933 params->status |= MCI_STATUS_OVER;
935 banks[2] = params->addr;
936 banks[3] = params->misc;
937 cenv->mcg_status = params->mcg_status;
938 banks[1] = params->status;
939 cpu_interrupt(cs, CPU_INTERRUPT_MCE);
940 } else if (!(banks[1] & MCI_STATUS_VAL)
941 || !(banks[1] & MCI_STATUS_UC)) {
942 if (banks[1] & MCI_STATUS_VAL) {
943 params->status |= MCI_STATUS_OVER;
945 banks[2] = params->addr;
946 banks[3] = params->misc;
947 banks[1] = params->status;
948 } else {
949 banks[1] |= MCI_STATUS_OVER;
952 emit_guest_memory_failure(MEMORY_FAILURE_ACTION_INJECT, ar, recursive);
955 void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
956 uint64_t status, uint64_t mcg_status, uint64_t addr,
957 uint64_t misc, int flags)
959 CPUState *cs = CPU(cpu);
960 CPUX86State *cenv = &cpu->env;
961 MCEInjectionParams params = {
962 .mon = mon,
963 .bank = bank,
964 .status = status,
965 .mcg_status = mcg_status,
966 .addr = addr,
967 .misc = misc,
968 .flags = flags,
970 unsigned bank_num = cenv->mcg_cap & 0xff;
972 if (!cenv->mcg_cap) {
973 monitor_printf(mon, "MCE injection not supported\n");
974 return;
976 if (bank >= bank_num) {
977 monitor_printf(mon, "Invalid MCE bank number\n");
978 return;
980 if (!(status & MCI_STATUS_VAL)) {
981 monitor_printf(mon, "Invalid MCE status code\n");
982 return;
984 if ((flags & MCE_INJECT_BROADCAST)
985 && !cpu_x86_support_mca_broadcast(cenv)) {
986 monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
987 return;
990 run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
991 if (flags & MCE_INJECT_BROADCAST) {
992 CPUState *other_cs;
994 params.bank = 1;
995 params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
996 params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
997 params.addr = 0;
998 params.misc = 0;
999 CPU_FOREACH(other_cs) {
1000 if (other_cs == cs) {
1001 continue;
1003 run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
1008 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
1010 X86CPU *cpu = env_archcpu(env);
1011 CPUState *cs = env_cpu(env);
1013 if (kvm_enabled() || whpx_enabled()) {
1014 env->tpr_access_type = access;
1016 cpu_interrupt(cs, CPU_INTERRUPT_TPR);
1017 } else if (tcg_enabled()) {
1018 cpu_restore_state(cs, cs->mem_io_pc, false);
1020 apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
1023 #endif /* !CONFIG_USER_ONLY */
1025 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1026 target_ulong *base, unsigned int *limit,
1027 unsigned int *flags)
1029 CPUState *cs = env_cpu(env);
1030 SegmentCache *dt;
1031 target_ulong ptr;
1032 uint32_t e1, e2;
1033 int index;
1035 if (selector & 0x4)
1036 dt = &env->ldt;
1037 else
1038 dt = &env->gdt;
1039 index = selector & ~7;
1040 ptr = dt->base + index;
1041 if ((index + 7) > dt->limit
1042 || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1043 || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1044 return 0;
1046 *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1047 *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1048 if (e2 & DESC_G_MASK)
1049 *limit = (*limit << 12) | 0xfff;
1050 *flags = e2;
1052 return 1;
1055 #if !defined(CONFIG_USER_ONLY)
1056 void do_cpu_init(X86CPU *cpu)
1058 CPUState *cs = CPU(cpu);
1059 CPUX86State *env = &cpu->env;
1060 CPUX86State *save = g_new(CPUX86State, 1);
1061 int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
1063 *save = *env;
1065 cpu_reset(cs);
1066 cs->interrupt_request = sipi;
1067 memcpy(&env->start_init_save, &save->start_init_save,
1068 offsetof(CPUX86State, end_init_save) -
1069 offsetof(CPUX86State, start_init_save));
1070 g_free(save);
1072 if (kvm_enabled()) {
1073 kvm_arch_do_init_vcpu(cpu);
1075 apic_init_reset(cpu->apic_state);
1078 void do_cpu_sipi(X86CPU *cpu)
1080 apic_sipi(cpu->apic_state);
1082 #else
1083 void do_cpu_init(X86CPU *cpu)
1086 void do_cpu_sipi(X86CPU *cpu)
1089 #endif
1091 /* Frob eflags into and out of the CPU temporary format. */
1093 void x86_cpu_exec_enter(CPUState *cs)
1095 X86CPU *cpu = X86_CPU(cs);
1096 CPUX86State *env = &cpu->env;
1098 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1099 env->df = 1 - (2 * ((env->eflags >> 10) & 1));
1100 CC_OP = CC_OP_EFLAGS;
1101 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1104 void x86_cpu_exec_exit(CPUState *cs)
1106 X86CPU *cpu = X86_CPU(cs);
1107 CPUX86State *env = &cpu->env;
1109 env->eflags = cpu_compute_eflags(env);
1112 #ifndef CONFIG_USER_ONLY
1113 uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr)
1115 X86CPU *cpu = X86_CPU(cs);
1116 CPUX86State *env = &cpu->env;
1117 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1118 AddressSpace *as = cpu_addressspace(cs, attrs);
1120 return address_space_ldub(as, addr, attrs, NULL);
1123 uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr)
1125 X86CPU *cpu = X86_CPU(cs);
1126 CPUX86State *env = &cpu->env;
1127 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1128 AddressSpace *as = cpu_addressspace(cs, attrs);
1130 return address_space_lduw(as, addr, attrs, NULL);
1133 uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr)
1135 X86CPU *cpu = X86_CPU(cs);
1136 CPUX86State *env = &cpu->env;
1137 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1138 AddressSpace *as = cpu_addressspace(cs, attrs);
1140 return address_space_ldl(as, addr, attrs, NULL);
1143 uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr)
1145 X86CPU *cpu = X86_CPU(cs);
1146 CPUX86State *env = &cpu->env;
1147 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1148 AddressSpace *as = cpu_addressspace(cs, attrs);
1150 return address_space_ldq(as, addr, attrs, NULL);
1153 void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val)
1155 X86CPU *cpu = X86_CPU(cs);
1156 CPUX86State *env = &cpu->env;
1157 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1158 AddressSpace *as = cpu_addressspace(cs, attrs);
1160 address_space_stb(as, addr, val, attrs, NULL);
1163 void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val)
1165 X86CPU *cpu = X86_CPU(cs);
1166 CPUX86State *env = &cpu->env;
1167 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1168 AddressSpace *as = cpu_addressspace(cs, attrs);
1170 address_space_stl_notdirty(as, addr, val, attrs, NULL);
1173 void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val)
1175 X86CPU *cpu = X86_CPU(cs);
1176 CPUX86State *env = &cpu->env;
1177 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1178 AddressSpace *as = cpu_addressspace(cs, attrs);
1180 address_space_stw(as, addr, val, attrs, NULL);
1183 void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val)
1185 X86CPU *cpu = X86_CPU(cs);
1186 CPUX86State *env = &cpu->env;
1187 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1188 AddressSpace *as = cpu_addressspace(cs, attrs);
1190 address_space_stl(as, addr, val, attrs, NULL);
1193 void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val)
1195 X86CPU *cpu = X86_CPU(cs);
1196 CPUX86State *env = &cpu->env;
1197 MemTxAttrs attrs = cpu_get_mem_attrs(env);
1198 AddressSpace *as = cpu_addressspace(cs, attrs);
1200 address_space_stq(as, addr, val, attrs, NULL);
1202 #endif