]> git.proxmox.com Git - mirror_qemu.git/blame - target-i386/helper.c
Merge remote-tracking branch 'remotes/rth/tags/pull-sparc-20161031-2' into staging
[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"
83c9089e 27#include "monitor/monitor.h"
1f871d49 28#include "hw/i386/apic_internal.h"
2fa11da0 29#endif
f3f2d9be 30
317ac620 31static void cpu_x86_version(CPUX86State *env, int *family, int *model)
2bd3e04c
JD
32{
33 int cpuver = env->cpuid_version;
34
35 if (family == NULL || model == NULL) {
36 return;
37 }
38
39 *family = (cpuver >> 8) & 0x0f;
40 *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
41}
42
43/* Broadcast MCA signal for processor version 06H_EH and above */
317ac620 44int cpu_x86_support_mca_broadcast(CPUX86State *env)
2bd3e04c
JD
45{
46 int family = 0;
47 int model = 0;
48
49 cpu_x86_version(env, &family, &model);
50 if ((family == 6 && model >= 14) || family > 6) {
51 return 1;
52 }
53
54 return 0;
55}
56
eaa728ee
FB
57/***********************************************************/
58/* x86 debug */
3b46e624 59
bc4b43dc 60static const char *cc_op_str[CC_OP_NB] = {
eaa728ee
FB
61 "DYNAMIC",
62 "EFLAGS",
7e84c249 63
eaa728ee
FB
64 "MULB",
65 "MULW",
66 "MULL",
67 "MULQ",
3b46e624 68
eaa728ee
FB
69 "ADDB",
70 "ADDW",
71 "ADDL",
72 "ADDQ",
3b46e624 73
eaa728ee
FB
74 "ADCB",
75 "ADCW",
76 "ADCL",
77 "ADCQ",
3b46e624 78
eaa728ee
FB
79 "SUBB",
80 "SUBW",
81 "SUBL",
82 "SUBQ",
7e84c249 83
eaa728ee
FB
84 "SBBB",
85 "SBBW",
86 "SBBL",
87 "SBBQ",
7e84c249 88
eaa728ee
FB
89 "LOGICB",
90 "LOGICW",
91 "LOGICL",
92 "LOGICQ",
7e84c249 93
eaa728ee
FB
94 "INCB",
95 "INCW",
96 "INCL",
97 "INCQ",
3b46e624 98
eaa728ee
FB
99 "DECB",
100 "DECW",
101 "DECL",
102 "DECQ",
3b46e624 103
eaa728ee
FB
104 "SHLB",
105 "SHLW",
106 "SHLL",
107 "SHLQ",
3b46e624 108
eaa728ee
FB
109 "SARB",
110 "SARW",
111 "SARL",
112 "SARQ",
bc4b43dc
RH
113
114 "BMILGB",
115 "BMILGW",
116 "BMILGL",
117 "BMILGQ",
cd7f97ca
RH
118
119 "ADCX",
120 "ADOX",
121 "ADCOX",
436ff2d2
RH
122
123 "CLR",
eaa728ee 124};
7e84c249 125
a3867ed2 126static void
317ac620 127cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
a3867ed2
AL
128 const char *name, struct SegmentCache *sc)
129{
130#ifdef TARGET_X86_64
131 if (env->hflags & HF_CS64_MASK) {
132 cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
4058fd98 133 sc->selector, sc->base, sc->limit, sc->flags & 0x00ffff00);
a3867ed2
AL
134 } else
135#endif
136 {
137 cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
4058fd98 138 (uint32_t)sc->base, sc->limit, sc->flags & 0x00ffff00);
a3867ed2
AL
139 }
140
141 if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
142 goto done;
143
144 cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
145 if (sc->flags & DESC_S_MASK) {
146 if (sc->flags & DESC_CS_MASK) {
147 cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
148 ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
149 cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
150 (sc->flags & DESC_R_MASK) ? 'R' : '-');
151 } else {
469936ae
TM
152 cpu_fprintf(f,
153 (sc->flags & DESC_B_MASK || env->hflags & HF_LMA_MASK)
154 ? "DS " : "DS16");
a3867ed2
AL
155 cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
156 (sc->flags & DESC_W_MASK) ? 'W' : '-');
157 }
158 cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
159 } else {
160 static const char *sys_type_name[2][16] = {
161 { /* 32 bit mode */
162 "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
163 "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
164 "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
165 "CallGate32", "Reserved", "IntGate32", "TrapGate32"
166 },
167 { /* 64 bit mode */
168 "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
169 "Reserved", "Reserved", "Reserved", "Reserved",
170 "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
171 "Reserved", "IntGate64", "TrapGate64"
172 }
173 };
e5c15eff
SW
174 cpu_fprintf(f, "%s",
175 sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
176 [(sc->flags & DESC_TYPE_MASK)
177 >> DESC_TYPE_SHIFT]);
a3867ed2
AL
178 }
179done:
180 cpu_fprintf(f, "\n");
181}
182
1f871d49
PB
183#ifndef CONFIG_USER_ONLY
184
185/* ARRAY_SIZE check is not required because
186 * DeliveryMode(dm) has a size of 3 bit.
187 */
188static inline const char *dm2str(uint32_t dm)
189{
190 static const char *str[] = {
191 "Fixed",
192 "...",
193 "SMI",
194 "...",
195 "NMI",
196 "INIT",
197 "...",
198 "ExtINT"
199 };
200 return str[dm];
201}
202
203static void dump_apic_lvt(FILE *f, fprintf_function cpu_fprintf,
204 const char *name, uint32_t lvt, bool is_timer)
205{
206 uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT;
207 cpu_fprintf(f,
208 "%s\t 0x%08x %s %-5s %-6s %-7s %-12s %-6s",
209 name, lvt,
210 lvt & APIC_LVT_INT_POLARITY ? "active-lo" : "active-hi",
211 lvt & APIC_LVT_LEVEL_TRIGGER ? "level" : "edge",
212 lvt & APIC_LVT_MASKED ? "masked" : "",
213 lvt & APIC_LVT_DELIV_STS ? "pending" : "",
214 !is_timer ?
215 "" : lvt & APIC_LVT_TIMER_PERIODIC ?
216 "periodic" : lvt & APIC_LVT_TIMER_TSCDEADLINE ?
217 "tsc-deadline" : "one-shot",
218 dm2str(dm));
219 if (dm != APIC_DM_NMI) {
220 cpu_fprintf(f, " (vec %u)\n", lvt & APIC_VECTOR_MASK);
221 } else {
222 cpu_fprintf(f, "\n");
223 }
224}
225
226/* ARRAY_SIZE check is not required because
227 * destination shorthand has a size of 2 bit.
228 */
229static inline const char *shorthand2str(uint32_t shorthand)
230{
231 const char *str[] = {
232 "no-shorthand", "self", "all-self", "all"
233 };
234 return str[shorthand];
235}
236
237static inline uint8_t divider_conf(uint32_t divide_conf)
238{
239 uint8_t divide_val = ((divide_conf & 0x8) >> 1) | (divide_conf & 0x3);
240
241 return divide_val == 7 ? 1 : 2 << divide_val;
242}
243
244static inline void mask2str(char *str, uint32_t val, uint8_t size)
245{
246 while (size--) {
247 *str++ = (val >> size) & 1 ? '1' : '0';
248 }
249 *str = 0;
250}
251
252#define MAX_LOGICAL_APIC_ID_MASK_SIZE 16
253
254static void dump_apic_icr(FILE *f, fprintf_function cpu_fprintf,
255 APICCommonState *s, CPUX86State *env)
256{
257 uint32_t icr = s->icr[0], icr2 = s->icr[1];
258 uint8_t dest_shorthand = \
259 (icr & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT;
260 bool logical_mod = icr & APIC_ICR_DEST_MOD;
261 char apic_id_str[MAX_LOGICAL_APIC_ID_MASK_SIZE + 1];
262 uint32_t dest_field;
263 bool x2apic;
264
265 cpu_fprintf(f, "ICR\t 0x%08x %s %s %s %s\n",
266 icr,
267 logical_mod ? "logical" : "physical",
268 icr & APIC_ICR_TRIGGER_MOD ? "level" : "edge",
269 icr & APIC_ICR_LEVEL ? "assert" : "de-assert",
270 shorthand2str(dest_shorthand));
271
272 cpu_fprintf(f, "ICR2\t 0x%08x", icr2);
273 if (dest_shorthand != 0) {
274 cpu_fprintf(f, "\n");
275 return;
276 }
277 x2apic = env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC;
278 dest_field = x2apic ? icr2 : icr2 >> APIC_ICR_DEST_SHIFT;
279
280 if (!logical_mod) {
281 if (x2apic) {
282 cpu_fprintf(f, " cpu %u (X2APIC ID)\n", dest_field);
283 } else {
284 cpu_fprintf(f, " cpu %u (APIC ID)\n",
285 dest_field & APIC_LOGDEST_XAPIC_ID);
286 }
287 return;
288 }
289
290 if (s->dest_mode == 0xf) { /* flat mode */
291 mask2str(apic_id_str, icr2 >> APIC_ICR_DEST_SHIFT, 8);
292 cpu_fprintf(f, " mask %s (APIC ID)\n", apic_id_str);
293 } else if (s->dest_mode == 0) { /* cluster mode */
294 if (x2apic) {
295 mask2str(apic_id_str, dest_field & APIC_LOGDEST_X2APIC_ID, 16);
296 cpu_fprintf(f, " cluster %u mask %s (X2APIC ID)\n",
297 dest_field >> APIC_LOGDEST_X2APIC_SHIFT, apic_id_str);
298 } else {
299 mask2str(apic_id_str, dest_field & APIC_LOGDEST_XAPIC_ID, 4);
300 cpu_fprintf(f, " cluster %u mask %s (APIC ID)\n",
301 dest_field >> APIC_LOGDEST_XAPIC_SHIFT, apic_id_str);
302 }
303 }
304}
305
306static void dump_apic_interrupt(FILE *f, fprintf_function cpu_fprintf,
307 const char *name, uint32_t *ireg_tab,
308 uint32_t *tmr_tab)
309{
310 int i, empty = true;
311
312 cpu_fprintf(f, "%s\t ", name);
313 for (i = 0; i < 256; i++) {
314 if (apic_get_bit(ireg_tab, i)) {
315 cpu_fprintf(f, "%u%s ", i,
316 apic_get_bit(tmr_tab, i) ? "(level)" : "");
317 empty = false;
318 }
319 }
320 cpu_fprintf(f, "%s\n", empty ? "(none)" : "");
321}
322
323void x86_cpu_dump_local_apic_state(CPUState *cs, FILE *f,
324 fprintf_function cpu_fprintf, int flags)
325{
326 X86CPU *cpu = X86_CPU(cs);
327 APICCommonState *s = APIC_COMMON(cpu->apic_state);
328 uint32_t *lvt = s->lvt;
329
330 cpu_fprintf(f, "dumping local APIC state for CPU %-2u\n\n",
331 CPU(cpu)->cpu_index);
332 dump_apic_lvt(f, cpu_fprintf, "LVT0", lvt[APIC_LVT_LINT0], false);
333 dump_apic_lvt(f, cpu_fprintf, "LVT1", lvt[APIC_LVT_LINT1], false);
334 dump_apic_lvt(f, cpu_fprintf, "LVTPC", lvt[APIC_LVT_PERFORM], false);
335 dump_apic_lvt(f, cpu_fprintf, "LVTERR", lvt[APIC_LVT_ERROR], false);
336 dump_apic_lvt(f, cpu_fprintf, "LVTTHMR", lvt[APIC_LVT_THERMAL], false);
337 dump_apic_lvt(f, cpu_fprintf, "LVTT", lvt[APIC_LVT_TIMER], true);
338
339 cpu_fprintf(f, "Timer\t DCR=0x%x (divide by %u) initial_count = %u\n",
340 s->divide_conf & APIC_DCR_MASK,
341 divider_conf(s->divide_conf),
342 s->initial_count);
343
344 cpu_fprintf(f, "SPIV\t 0x%08x APIC %s, focus=%s, spurious vec %u\n",
345 s->spurious_vec,
346 s->spurious_vec & APIC_SPURIO_ENABLED ? "enabled" : "disabled",
347 s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off",
348 s->spurious_vec & APIC_VECTOR_MASK);
349
350 dump_apic_icr(f, cpu_fprintf, s, &cpu->env);
351
352 cpu_fprintf(f, "ESR\t 0x%08x\n", s->esr);
353
354 dump_apic_interrupt(f, cpu_fprintf, "ISR", s->isr, s->tmr);
355 dump_apic_interrupt(f, cpu_fprintf, "IRR", s->irr, s->tmr);
356
357 cpu_fprintf(f, "\nAPR 0x%02x TPR 0x%02x DFR 0x%02x LDR 0x%02x",
358 s->arb_id, s->tpr, s->dest_mode, s->log_dest);
359 if (s->dest_mode == 0) {
360 cpu_fprintf(f, "(cluster %u: id %u)",
361 s->log_dest >> APIC_LOGDEST_XAPIC_SHIFT,
362 s->log_dest & APIC_LOGDEST_XAPIC_ID);
363 }
364 cpu_fprintf(f, " PPR 0x%02x\n", apic_get_ppr(s));
365}
366#else
367void x86_cpu_dump_local_apic_state(CPUState *cs, FILE *f,
368 fprintf_function cpu_fprintf, int flags)
369{
370}
371#endif /* !CONFIG_USER_ONLY */
372
f5c848ee
JK
373#define DUMP_CODE_BYTES_TOTAL 50
374#define DUMP_CODE_BYTES_BACKWARD 20
375
878096ee
AF
376void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
377 int flags)
eaa728ee 378{
878096ee
AF
379 X86CPU *cpu = X86_CPU(cs);
380 CPUX86State *env = &cpu->env;
eaa728ee
FB
381 int eflags, i, nb;
382 char cc_op_name[32];
383 static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
7e84c249 384
4980ef9e 385 eflags = cpu_compute_eflags(env);
eaa728ee
FB
386#ifdef TARGET_X86_64
387 if (env->hflags & HF_CS64_MASK) {
388 cpu_fprintf(f,
389 "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
390 "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
391 "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
392 "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
393 "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
394 env->regs[R_EAX],
395 env->regs[R_EBX],
396 env->regs[R_ECX],
397 env->regs[R_EDX],
398 env->regs[R_ESI],
399 env->regs[R_EDI],
400 env->regs[R_EBP],
401 env->regs[R_ESP],
402 env->regs[8],
403 env->regs[9],
404 env->regs[10],
405 env->regs[11],
406 env->regs[12],
407 env->regs[13],
408 env->regs[14],
409 env->regs[15],
410 env->eip, eflags,
411 eflags & DF_MASK ? 'D' : '-',
412 eflags & CC_O ? 'O' : '-',
413 eflags & CC_S ? 'S' : '-',
414 eflags & CC_Z ? 'Z' : '-',
415 eflags & CC_A ? 'A' : '-',
416 eflags & CC_P ? 'P' : '-',
417 eflags & CC_C ? 'C' : '-',
418 env->hflags & HF_CPL_MASK,
419 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
5ee0ffaa 420 (env->a20_mask >> 20) & 1,
eaa728ee 421 (env->hflags >> HF_SMM_SHIFT) & 1,
259186a7 422 cs->halted);
eaa728ee
FB
423 } else
424#endif
425 {
426 cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
427 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
428 "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
429 (uint32_t)env->regs[R_EAX],
430 (uint32_t)env->regs[R_EBX],
431 (uint32_t)env->regs[R_ECX],
432 (uint32_t)env->regs[R_EDX],
433 (uint32_t)env->regs[R_ESI],
434 (uint32_t)env->regs[R_EDI],
435 (uint32_t)env->regs[R_EBP],
436 (uint32_t)env->regs[R_ESP],
437 (uint32_t)env->eip, eflags,
438 eflags & DF_MASK ? 'D' : '-',
439 eflags & CC_O ? 'O' : '-',
440 eflags & CC_S ? 'S' : '-',
441 eflags & CC_Z ? 'Z' : '-',
442 eflags & CC_A ? 'A' : '-',
443 eflags & CC_P ? 'P' : '-',
444 eflags & CC_C ? 'C' : '-',
445 env->hflags & HF_CPL_MASK,
446 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
5ee0ffaa 447 (env->a20_mask >> 20) & 1,
eaa728ee 448 (env->hflags >> HF_SMM_SHIFT) & 1,
259186a7 449 cs->halted);
8145122b 450 }
3b46e624 451
a3867ed2
AL
452 for(i = 0; i < 6; i++) {
453 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
454 &env->segs[i]);
455 }
456 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
457 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
458
eaa728ee
FB
459#ifdef TARGET_X86_64
460 if (env->hflags & HF_LMA_MASK) {
eaa728ee
FB
461 cpu_fprintf(f, "GDT= %016" PRIx64 " %08x\n",
462 env->gdt.base, env->gdt.limit);
463 cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
464 env->idt.base, env->idt.limit);
465 cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
466 (uint32_t)env->cr[0],
467 env->cr[2],
468 env->cr[3],
469 (uint32_t)env->cr[4]);
a59cb4e0
AL
470 for(i = 0; i < 4; i++)
471 cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
472 cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
d4b55be5 473 env->dr[6], env->dr[7]);
eaa728ee
FB
474 } else
475#endif
476 {
eaa728ee
FB
477 cpu_fprintf(f, "GDT= %08x %08x\n",
478 (uint32_t)env->gdt.base, env->gdt.limit);
479 cpu_fprintf(f, "IDT= %08x %08x\n",
480 (uint32_t)env->idt.base, env->idt.limit);
481 cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
482 (uint32_t)env->cr[0],
483 (uint32_t)env->cr[2],
484 (uint32_t)env->cr[3],
485 (uint32_t)env->cr[4]);
9a78eead
SW
486 for(i = 0; i < 4; i++) {
487 cpu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
488 }
489 cpu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
490 env->dr[6], env->dr[7]);
eaa728ee 491 }
6fd2a026 492 if (flags & CPU_DUMP_CCOP) {
eaa728ee
FB
493 if ((unsigned)env->cc_op < CC_OP_NB)
494 snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
495 else
496 snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
497#ifdef TARGET_X86_64
498 if (env->hflags & HF_CS64_MASK) {
499 cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
500 env->cc_src, env->cc_dst,
501 cc_op_name);
502 } else
503#endif
504 {
505 cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
506 (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
507 cc_op_name);
508 }
7e84c249 509 }
b5e5a934 510 cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
6fd2a026 511 if (flags & CPU_DUMP_FPU) {
eaa728ee
FB
512 int fptag;
513 fptag = 0;
514 for(i = 0; i < 8; i++) {
515 fptag |= ((!env->fptags[i]) << i);
516 }
517 cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
518 env->fpuc,
519 (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
520 env->fpstt,
521 fptag,
522 env->mxcsr);
523 for(i=0;i<8;i++) {
1ffd41ee
AJ
524 CPU_LDoubleU u;
525 u.d = env->fpregs[i].d;
eaa728ee 526 cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
1ffd41ee 527 i, u.l.lower, u.l.upper);
eaa728ee
FB
528 if ((i & 1) == 1)
529 cpu_fprintf(f, "\n");
530 else
531 cpu_fprintf(f, " ");
532 }
533 if (env->hflags & HF_CS64_MASK)
534 nb = 16;
535 else
536 nb = 8;
537 for(i=0;i<nb;i++) {
538 cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
539 i,
19cbd87c
EH
540 env->xmm_regs[i].ZMM_L(3),
541 env->xmm_regs[i].ZMM_L(2),
542 env->xmm_regs[i].ZMM_L(1),
543 env->xmm_regs[i].ZMM_L(0));
eaa728ee
FB
544 if ((i & 1) == 1)
545 cpu_fprintf(f, "\n");
546 else
547 cpu_fprintf(f, " ");
548 }
7e84c249 549 }
f5c848ee
JK
550 if (flags & CPU_DUMP_CODE) {
551 target_ulong base = env->segs[R_CS].base + env->eip;
552 target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
553 uint8_t code;
554 char codestr[3];
555
556 cpu_fprintf(f, "Code=");
557 for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
f17ec444 558 if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
f5c848ee
JK
559 snprintf(codestr, sizeof(codestr), "%02x", code);
560 } else {
561 snprintf(codestr, sizeof(codestr), "??");
562 }
563 cpu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
564 i == offs ? "<" : "", codestr, i == offs ? ">" : "");
565 }
566 cpu_fprintf(f, "\n");
567 }
2c0262af 568}
7e84c249 569
eaa728ee
FB
570/***********************************************************/
571/* x86 mmu */
572/* XXX: add PGE support */
573
cc36a7a2 574void x86_cpu_set_a20(X86CPU *cpu, int a20_state)
2c0262af 575{
cc36a7a2
AF
576 CPUX86State *env = &cpu->env;
577
eaa728ee
FB
578 a20_state = (a20_state != 0);
579 if (a20_state != ((env->a20_mask >> 20) & 1)) {
00c8cb0a
AF
580 CPUState *cs = CPU(cpu);
581
339aaf5b 582 qemu_log_mask(CPU_LOG_MMU, "A20 update: a20=%d\n", a20_state);
eaa728ee
FB
583 /* if the cpu is currently executing code, we must unlink it and
584 all the potentially executing TB */
00c8cb0a 585 cpu_interrupt(cs, CPU_INTERRUPT_EXITTB);
3b46e624 586
eaa728ee
FB
587 /* when a20 is changed, all the MMU mappings are invalid, so
588 we must flush everything */
00c8cb0a 589 tlb_flush(cs, 1);
5ee0ffaa 590 env->a20_mask = ~(1 << 20) | (a20_state << 20);
7e84c249 591 }
2c0262af
FB
592}
593
eaa728ee 594void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
2c0262af 595{
00c8cb0a 596 X86CPU *cpu = x86_env_get_cpu(env);
eaa728ee 597 int pe_state;
2c0262af 598
339aaf5b 599 qemu_log_mask(CPU_LOG_MMU, "CR0 update: CR0=0x%08x\n", new_cr0);
eaa728ee
FB
600 if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
601 (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
00c8cb0a 602 tlb_flush(CPU(cpu), 1);
eaa728ee 603 }
2c0262af 604
eaa728ee
FB
605#ifdef TARGET_X86_64
606 if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
607 (env->efer & MSR_EFER_LME)) {
608 /* enter in long mode */
609 /* XXX: generate an exception */
610 if (!(env->cr[4] & CR4_PAE_MASK))
611 return;
612 env->efer |= MSR_EFER_LMA;
613 env->hflags |= HF_LMA_MASK;
614 } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
615 (env->efer & MSR_EFER_LMA)) {
616 /* exit long mode */
617 env->efer &= ~MSR_EFER_LMA;
618 env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
619 env->eip &= 0xffffffff;
620 }
621#endif
622 env->cr[0] = new_cr0 | CR0_ET_MASK;
7e84c249 623
eaa728ee
FB
624 /* update PE flag in hidden flags */
625 pe_state = (env->cr[0] & CR0_PE_MASK);
626 env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
627 /* ensure that ADDSEG is always set in real mode */
628 env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
629 /* update FPU flags */
630 env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
631 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
7e84c249
FB
632}
633
eaa728ee
FB
634/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
635 the PDPT */
636void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
7e84c249 637{
00c8cb0a
AF
638 X86CPU *cpu = x86_env_get_cpu(env);
639
eaa728ee
FB
640 env->cr[3] = new_cr3;
641 if (env->cr[0] & CR0_PG_MASK) {
339aaf5b
AP
642 qemu_log_mask(CPU_LOG_MMU,
643 "CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
00c8cb0a 644 tlb_flush(CPU(cpu), 0);
eaa728ee 645 }
7e84c249
FB
646}
647
eaa728ee 648void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
7e84c249 649{
00c8cb0a 650 X86CPU *cpu = x86_env_get_cpu(env);
19dc85db 651 uint32_t hflags;
00c8cb0a 652
eaa728ee
FB
653#if defined(DEBUG_MMU)
654 printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
655#endif
a9321a4d
PA
656 if ((new_cr4 ^ env->cr[4]) &
657 (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK |
658 CR4_SMEP_MASK | CR4_SMAP_MASK)) {
00c8cb0a 659 tlb_flush(CPU(cpu), 1);
eaa728ee 660 }
19dc85db
RH
661
662 /* Clear bits we're going to recompute. */
663 hflags = env->hflags & ~(HF_OSFXSR_MASK | HF_SMAP_MASK);
664
eaa728ee 665 /* SSE handling */
0514ef2f 666 if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) {
eaa728ee 667 new_cr4 &= ~CR4_OSFXSR_MASK;
a9321a4d 668 }
a9321a4d 669 if (new_cr4 & CR4_OSFXSR_MASK) {
19dc85db 670 hflags |= HF_OSFXSR_MASK;
a9321a4d
PA
671 }
672
0514ef2f 673 if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) {
a9321a4d
PA
674 new_cr4 &= ~CR4_SMAP_MASK;
675 }
a9321a4d 676 if (new_cr4 & CR4_SMAP_MASK) {
19dc85db 677 hflags |= HF_SMAP_MASK;
a9321a4d 678 }
b8b6a50b 679
0f70ed47
PB
680 if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) {
681 new_cr4 &= ~CR4_PKE_MASK;
682 }
683
eaa728ee 684 env->cr[4] = new_cr4;
19dc85db 685 env->hflags = hflags;
f4f1110e
RH
686
687 cpu_sync_bndcs_hflags(env);
b8b6a50b
FB
688}
689
eaa728ee
FB
690#if defined(CONFIG_USER_ONLY)
691
7510454e 692int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
97b348e7 693 int is_write, int mmu_idx)
b8b6a50b 694{
7510454e
AF
695 X86CPU *cpu = X86_CPU(cs);
696 CPUX86State *env = &cpu->env;
697
eaa728ee
FB
698 /* user mode only emulation */
699 is_write &= 1;
700 env->cr[2] = addr;
701 env->error_code = (is_write << PG_ERROR_W_BIT);
702 env->error_code |= PG_ERROR_U_MASK;
27103424 703 cs->exception_index = EXCP0E_PAGE;
0c33682d
PM
704 env->exception_is_int = 0;
705 env->exception_next_eip = -1;
eaa728ee 706 return 1;
2c0262af
FB
707}
708
8d7b0fbb 709#else
891b38e4 710
eaa728ee 711/* return value:
7510454e
AF
712 * -1 = cannot handle fault
713 * 0 = nothing more to do
714 * 1 = generate PF fault
715 */
716int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
97b348e7 717 int is_write1, int mmu_idx)
eaa728ee 718{
7510454e
AF
719 X86CPU *cpu = X86_CPU(cs);
720 CPUX86State *env = &cpu->env;
eaa728ee
FB
721 uint64_t ptep, pte;
722 target_ulong pde_addr, pte_addr;
c1eb2fa3
PB
723 int error_code = 0;
724 int is_dirty, prot, page_size, is_write, is_user;
a8170e5e 725 hwaddr paddr;
e8f6d00c 726 uint64_t rsvd_mask = PG_HI_RSVD_MASK;
eaa728ee 727 uint32_t page_offset;
e7e898a7 728 target_ulong vaddr;
eaa728ee
FB
729
730 is_user = mmu_idx == MMU_USER_IDX;
731#if defined(DEBUG_MMU)
7510454e 732 printf("MMU fault: addr=%" VADDR_PRIx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
eaa728ee
FB
733 addr, is_write1, is_user, env->eip);
734#endif
735 is_write = is_write1 & 1;
736
737 if (!(env->cr[0] & CR0_PG_MASK)) {
738 pte = addr;
33dfdb56
AG
739#ifdef TARGET_X86_64
740 if (!(env->hflags & HF_LMA_MASK)) {
741 /* Without long mode we can only address 32bits in real mode */
742 pte = (uint32_t)pte;
743 }
744#endif
eaa728ee
FB
745 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
746 page_size = 4096;
747 goto do_mapping;
748 }
749
e2a32ebb
PB
750 if (!(env->efer & MSR_EFER_NXE)) {
751 rsvd_mask |= PG_NX_MASK;
752 }
753
eaa728ee
FB
754 if (env->cr[4] & CR4_PAE_MASK) {
755 uint64_t pde, pdpe;
756 target_ulong pdpe_addr;
2c0262af 757
eaa728ee
FB
758#ifdef TARGET_X86_64
759 if (env->hflags & HF_LMA_MASK) {
760 uint64_t pml4e_addr, pml4e;
761 int32_t sext;
762
763 /* test virtual address sign extension */
764 sext = (int64_t)addr >> 47;
765 if (sext != 0 && sext != -1) {
766 env->error_code = 0;
27103424 767 cs->exception_index = EXCP0D_GPF;
eaa728ee
FB
768 return 1;
769 }
0573fbfc 770
eaa728ee
FB
771 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
772 env->a20_mask;
b216aa6c 773 pml4e = x86_ldq_phys(cs, pml4e_addr);
eaa728ee 774 if (!(pml4e & PG_PRESENT_MASK)) {
eaa728ee
FB
775 goto do_fault;
776 }
e8f6d00c 777 if (pml4e & (rsvd_mask | PG_PSE_MASK)) {
b728464a
PB
778 goto do_fault_rsvd;
779 }
eaa728ee
FB
780 if (!(pml4e & PG_ACCESSED_MASK)) {
781 pml4e |= PG_ACCESSED_MASK;
b216aa6c 782 x86_stl_phys_notdirty(cs, pml4e_addr, pml4e);
eaa728ee
FB
783 }
784 ptep = pml4e ^ PG_NX_MASK;
e8f6d00c 785 pdpe_addr = ((pml4e & PG_ADDRESS_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
eaa728ee 786 env->a20_mask;
b216aa6c 787 pdpe = x86_ldq_phys(cs, pdpe_addr);
eaa728ee 788 if (!(pdpe & PG_PRESENT_MASK)) {
eaa728ee
FB
789 goto do_fault;
790 }
e8f6d00c
PB
791 if (pdpe & rsvd_mask) {
792 goto do_fault_rsvd;
793 }
eaa728ee
FB
794 ptep &= pdpe ^ PG_NX_MASK;
795 if (!(pdpe & PG_ACCESSED_MASK)) {
796 pdpe |= PG_ACCESSED_MASK;
b216aa6c 797 x86_stl_phys_notdirty(cs, pdpe_addr, pdpe);
eaa728ee 798 }
77549a78
PB
799 if (pdpe & PG_PSE_MASK) {
800 /* 1 GB page */
801 page_size = 1024 * 1024 * 1024;
802 pte_addr = pdpe_addr;
803 pte = pdpe;
804 goto do_check_protect;
805 }
eaa728ee
FB
806 } else
807#endif
808 {
809 /* XXX: load them when cr3 is loaded ? */
810 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
811 env->a20_mask;
b216aa6c 812 pdpe = x86_ldq_phys(cs, pdpe_addr);
eaa728ee 813 if (!(pdpe & PG_PRESENT_MASK)) {
eaa728ee
FB
814 goto do_fault;
815 }
1844e68e
WG
816 rsvd_mask |= PG_HI_USER_MASK;
817 if (pdpe & (rsvd_mask | PG_NX_MASK)) {
e8f6d00c
PB
818 goto do_fault_rsvd;
819 }
eaa728ee 820 ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
7e84c249 821 }
7e84c249 822
e8f6d00c 823 pde_addr = ((pdpe & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
eaa728ee 824 env->a20_mask;
b216aa6c 825 pde = x86_ldq_phys(cs, pde_addr);
eaa728ee 826 if (!(pde & PG_PRESENT_MASK)) {
eaa728ee
FB
827 goto do_fault;
828 }
e8f6d00c
PB
829 if (pde & rsvd_mask) {
830 goto do_fault_rsvd;
831 }
eaa728ee
FB
832 ptep &= pde ^ PG_NX_MASK;
833 if (pde & PG_PSE_MASK) {
834 /* 2 MB page */
835 page_size = 2048 * 1024;
00cc3e1d
PB
836 pte_addr = pde_addr;
837 pte = pde;
b052e450
PB
838 goto do_check_protect;
839 }
840 /* 4 KB page */
841 if (!(pde & PG_ACCESSED_MASK)) {
842 pde |= PG_ACCESSED_MASK;
b216aa6c 843 x86_stl_phys_notdirty(cs, pde_addr, pde);
b052e450 844 }
e8f6d00c 845 pte_addr = ((pde & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
b052e450 846 env->a20_mask;
b216aa6c 847 pte = x86_ldq_phys(cs, pte_addr);
b052e450 848 if (!(pte & PG_PRESENT_MASK)) {
b052e450
PB
849 goto do_fault;
850 }
e8f6d00c
PB
851 if (pte & rsvd_mask) {
852 goto do_fault_rsvd;
853 }
b052e450
PB
854 /* combine pde and pte nx, user and rw protections */
855 ptep &= pte ^ PG_NX_MASK;
856 page_size = 4096;
2c0262af 857 } else {
eaa728ee
FB
858 uint32_t pde;
859
860 /* page directory entry */
861 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
862 env->a20_mask;
b216aa6c 863 pde = x86_ldl_phys(cs, pde_addr);
eaa728ee 864 if (!(pde & PG_PRESENT_MASK)) {
eaa728ee
FB
865 goto do_fault;
866 }
870a7067
PB
867 ptep = pde | PG_NX_MASK;
868
eaa728ee
FB
869 /* if PSE bit is set, then we use a 4MB page */
870 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
871 page_size = 4096 * 1024;
487cad88 872 pte_addr = pde_addr;
de431a65
PB
873
874 /* Bits 20-13 provide bits 39-32 of the address, bit 21 is reserved.
875 * Leave bits 20-13 in place for setting accessed/dirty bits below.
876 */
388ee48a 877 pte = pde | ((pde & 0x1fe000LL) << (32 - 13));
de431a65
PB
878 rsvd_mask = 0x200000;
879 goto do_check_protect_pse36;
b052e450 880 }
891b38e4 881
b052e450
PB
882 if (!(pde & PG_ACCESSED_MASK)) {
883 pde |= PG_ACCESSED_MASK;
b216aa6c 884 x86_stl_phys_notdirty(cs, pde_addr, pde);
b052e450
PB
885 }
886
887 /* page directory entry */
888 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
889 env->a20_mask;
b216aa6c 890 pte = x86_ldl_phys(cs, pte_addr);
b052e450 891 if (!(pte & PG_PRESENT_MASK)) {
b052e450 892 goto do_fault;
487cad88 893 }
b052e450
PB
894 /* combine pde and pte user and rw protections */
895 ptep &= pte | PG_NX_MASK;
896 page_size = 4096;
e8f6d00c 897 rsvd_mask = 0;
7c822560 898 }
487cad88 899
b052e450 900do_check_protect:
eaad03e4 901 rsvd_mask |= (page_size - 1) & PG_ADDRESS_MASK & ~PG_PSE_PAT_MASK;
de431a65 902do_check_protect_pse36:
e8f6d00c
PB
903 if (pte & rsvd_mask) {
904 goto do_fault_rsvd;
905 }
870a7067 906 ptep ^= PG_NX_MASK;
76c64d33
PB
907
908 /* can the page can be put in the TLB? prot will tell us */
909 if (is_user && !(ptep & PG_USER_MASK)) {
7c822560
PB
910 goto do_fault_protect;
911 }
487cad88 912
76c64d33
PB
913 prot = 0;
914 if (mmu_idx != MMU_KSMAP_IDX || !(ptep & PG_USER_MASK)) {
915 prot |= PAGE_READ;
916 if ((ptep & PG_RW_MASK) || (!is_user && !(env->cr[0] & CR0_WP_MASK))) {
917 prot |= PAGE_WRITE;
2c0262af 918 }
76c64d33
PB
919 }
920 if (!(ptep & PG_NX_MASK) &&
921 (mmu_idx == MMU_USER_IDX ||
922 !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) {
923 prot |= PAGE_EXEC;
924 }
0f70ed47
PB
925 if ((env->cr[4] & CR4_PKE_MASK) && (env->hflags & HF_LMA_MASK) &&
926 (ptep & PG_USER_MASK) && env->pkru) {
927 uint32_t pk = (pte & PG_PKRU_MASK) >> PG_PKRU_BIT;
928 uint32_t pkru_ad = (env->pkru >> pk * 2) & 1;
929 uint32_t pkru_wd = (env->pkru >> pk * 2) & 2;
44d066a2 930 uint32_t pkru_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
0f70ed47
PB
931
932 if (pkru_ad) {
44d066a2 933 pkru_prot &= ~(PAGE_READ | PAGE_WRITE);
0f70ed47 934 } else if (pkru_wd && (is_user || env->cr[0] & CR0_WP_MASK)) {
44d066a2 935 pkru_prot &= ~PAGE_WRITE;
0f70ed47 936 }
44d066a2
PB
937
938 prot &= pkru_prot;
939 if ((pkru_prot & (1 << is_write1)) == 0) {
0f70ed47
PB
940 assert(is_write1 != 2);
941 error_code |= PG_ERROR_PK_MASK;
942 goto do_fault_protect;
943 }
944 }
945
44d066a2
PB
946 if ((prot & (1 << is_write1)) == 0) {
947 goto do_fault_protect;
948 }
949
76c64d33 950 /* yes, it can! */
7c822560
PB
951 is_dirty = is_write && !(pte & PG_DIRTY_MASK);
952 if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
953 pte |= PG_ACCESSED_MASK;
954 if (is_dirty) {
955 pte |= PG_DIRTY_MASK;
956 }
b216aa6c 957 x86_stl_phys_notdirty(cs, pte_addr, pte);
2c0262af 958 }
7c822560 959
76c64d33 960 if (!(pte & PG_DIRTY_MASK)) {
eaa728ee
FB
961 /* only set write access if already dirty... otherwise wait
962 for dirty access */
76c64d33
PB
963 assert(!is_write);
964 prot &= ~PAGE_WRITE;
891b38e4 965 }
76c64d33 966
eaa728ee
FB
967 do_mapping:
968 pte = pte & env->a20_mask;
969
e7e898a7
PB
970 /* align to page_size */
971 pte &= PG_ADDRESS_MASK & ~(page_size - 1);
972
eaa728ee
FB
973 /* Even if 4MB pages, we map only one 4KB page in the cache to
974 avoid filling it too fast */
e7e898a7
PB
975 vaddr = addr & TARGET_PAGE_MASK;
976 page_offset = vaddr & (page_size - 1);
977 paddr = pte + page_offset;
eaa728ee 978
76c64d33 979 assert(prot & (1 << is_write1));
f794aa4a
PB
980 tlb_set_page_with_attrs(cs, vaddr, paddr, cpu_get_mem_attrs(env),
981 prot, mmu_idx, page_size);
d4c430a8 982 return 0;
c1eb2fa3
PB
983 do_fault_rsvd:
984 error_code |= PG_ERROR_RSVD_MASK;
eaa728ee 985 do_fault_protect:
c1eb2fa3 986 error_code |= PG_ERROR_P_MASK;
eaa728ee
FB
987 do_fault:
988 error_code |= (is_write << PG_ERROR_W_BIT);
989 if (is_user)
990 error_code |= PG_ERROR_U_MASK;
991 if (is_write1 == 2 &&
a9321a4d
PA
992 (((env->efer & MSR_EFER_NXE) &&
993 (env->cr[4] & CR4_PAE_MASK)) ||
994 (env->cr[4] & CR4_SMEP_MASK)))
eaa728ee 995 error_code |= PG_ERROR_I_D_MASK;
872929aa
FB
996 if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
997 /* cr2 is not modified in case of exceptions */
b216aa6c 998 x86_stq_phys(cs,
f606604f 999 env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
872929aa 1000 addr);
eaa728ee
FB
1001 } else {
1002 env->cr[2] = addr;
2c0262af 1003 }
eaa728ee 1004 env->error_code = error_code;
27103424 1005 cs->exception_index = EXCP0E_PAGE;
eaa728ee 1006 return 1;
14ce26e7
FB
1007}
1008
00b941e5 1009hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
14ce26e7 1010{
00b941e5
AF
1011 X86CPU *cpu = X86_CPU(cs);
1012 CPUX86State *env = &cpu->env;
eaa728ee
FB
1013 target_ulong pde_addr, pte_addr;
1014 uint64_t pte;
eaa728ee
FB
1015 uint32_t page_offset;
1016 int page_size;
14ce26e7 1017
f2f8560c
PB
1018 if (!(env->cr[0] & CR0_PG_MASK)) {
1019 pte = addr & env->a20_mask;
1020 page_size = 4096;
1021 } else if (env->cr[4] & CR4_PAE_MASK) {
eaa728ee
FB
1022 target_ulong pdpe_addr;
1023 uint64_t pde, pdpe;
14ce26e7 1024
eaa728ee
FB
1025#ifdef TARGET_X86_64
1026 if (env->hflags & HF_LMA_MASK) {
1027 uint64_t pml4e_addr, pml4e;
1028 int32_t sext;
1029
1030 /* test virtual address sign extension */
1031 sext = (int64_t)addr >> 47;
16b96f82 1032 if (sext != 0 && sext != -1) {
eaa728ee 1033 return -1;
16b96f82 1034 }
eaa728ee
FB
1035 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
1036 env->a20_mask;
b216aa6c 1037 pml4e = x86_ldq_phys(cs, pml4e_addr);
16b96f82 1038 if (!(pml4e & PG_PRESENT_MASK)) {
eaa728ee 1039 return -1;
16b96f82
PB
1040 }
1041 pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
3f2cbf0d 1042 (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
b216aa6c 1043 pdpe = x86_ldq_phys(cs, pdpe_addr);
16b96f82 1044 if (!(pdpe & PG_PRESENT_MASK)) {
eaa728ee 1045 return -1;
16b96f82 1046 }
c8c14bcb
LC
1047 if (pdpe & PG_PSE_MASK) {
1048 page_size = 1024 * 1024 * 1024;
16b96f82 1049 pte = pdpe;
c8c14bcb
LC
1050 goto out;
1051 }
1052
eaa728ee
FB
1053 } else
1054#endif
1055 {
1056 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1057 env->a20_mask;
b216aa6c 1058 pdpe = x86_ldq_phys(cs, pdpe_addr);
eaa728ee
FB
1059 if (!(pdpe & PG_PRESENT_MASK))
1060 return -1;
14ce26e7 1061 }
14ce26e7 1062
16b96f82 1063 pde_addr = ((pdpe & PG_ADDRESS_MASK) +
3f2cbf0d 1064 (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
b216aa6c 1065 pde = x86_ldq_phys(cs, pde_addr);
eaa728ee
FB
1066 if (!(pde & PG_PRESENT_MASK)) {
1067 return -1;
1068 }
1069 if (pde & PG_PSE_MASK) {
1070 /* 2 MB page */
1071 page_size = 2048 * 1024;
16b96f82 1072 pte = pde;
eaa728ee
FB
1073 } else {
1074 /* 4 KB page */
16b96f82 1075 pte_addr = ((pde & PG_ADDRESS_MASK) +
3f2cbf0d 1076 (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
eaa728ee 1077 page_size = 4096;
b216aa6c 1078 pte = x86_ldq_phys(cs, pte_addr);
eaa728ee 1079 }
16b96f82 1080 if (!(pte & PG_PRESENT_MASK)) {
ca1c9e15 1081 return -1;
16b96f82 1082 }
14ce26e7 1083 } else {
eaa728ee 1084 uint32_t pde;
3b46e624 1085
f2f8560c
PB
1086 /* page directory entry */
1087 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
b216aa6c 1088 pde = x86_ldl_phys(cs, pde_addr);
f2f8560c
PB
1089 if (!(pde & PG_PRESENT_MASK))
1090 return -1;
1091 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
388ee48a 1092 pte = pde | ((pde & 0x1fe000LL) << (32 - 13));
f2f8560c 1093 page_size = 4096 * 1024;
eaa728ee
FB
1094 } else {
1095 /* page directory entry */
f2f8560c 1096 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
b216aa6c 1097 pte = x86_ldl_phys(cs, pte_addr);
16b96f82 1098 if (!(pte & PG_PRESENT_MASK)) {
eaa728ee 1099 return -1;
16b96f82 1100 }
f2f8560c 1101 page_size = 4096;
eaa728ee
FB
1102 }
1103 pte = pte & env->a20_mask;
14ce26e7 1104 }
14ce26e7 1105
c8c14bcb
LC
1106#ifdef TARGET_X86_64
1107out:
1108#endif
16b96f82 1109 pte &= PG_ADDRESS_MASK & ~(page_size - 1);
eaa728ee 1110 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
16b96f82 1111 return pte | page_offset;
3b21e03e 1112}
01df040b 1113
d5bfda33
JK
1114typedef struct MCEInjectionParams {
1115 Monitor *mon;
d5bfda33
JK
1116 int bank;
1117 uint64_t status;
1118 uint64_t mcg_status;
1119 uint64_t addr;
1120 uint64_t misc;
1121 int flags;
1122} MCEInjectionParams;
1123
14e6fe12 1124static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
79c4f6b0 1125{
14e6fe12 1126 MCEInjectionParams *params = data.host_ptr;
e0eeb4a2
AB
1127 X86CPU *cpu = X86_CPU(cs);
1128 CPUX86State *cenv = &cpu->env;
d5bfda33
JK
1129 uint64_t *banks = cenv->mce_banks + 4 * params->bank;
1130
e0eeb4a2 1131 cpu_synchronize_state(cs);
316378e4 1132
747461c7
JK
1133 /*
1134 * If there is an MCE exception being processed, ignore this SRAO MCE
1135 * unless unconditional injection was requested.
1136 */
d5bfda33
JK
1137 if (!(params->flags & MCE_INJECT_UNCOND_AO)
1138 && !(params->status & MCI_STATUS_AR)
747461c7
JK
1139 && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1140 return;
1141 }
d5bfda33
JK
1142
1143 if (params->status & MCI_STATUS_UC) {
316378e4
JK
1144 /*
1145 * if MSR_MCG_CTL is not all 1s, the uncorrected error
1146 * reporting is disabled
1147 */
d5bfda33
JK
1148 if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1149 monitor_printf(params->mon,
316378e4 1150 "CPU %d: Uncorrected error reporting disabled\n",
e0eeb4a2 1151 cs->cpu_index);
316378e4
JK
1152 return;
1153 }
1154
1155 /*
1156 * if MSR_MCi_CTL is not all 1s, the uncorrected error
1157 * reporting is disabled for the bank
1158 */
1159 if (banks[0] != ~(uint64_t)0) {
d5bfda33
JK
1160 monitor_printf(params->mon,
1161 "CPU %d: Uncorrected error reporting disabled for"
1162 " bank %d\n",
e0eeb4a2 1163 cs->cpu_index, params->bank);
316378e4
JK
1164 return;
1165 }
1166
79c4f6b0
HY
1167 if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1168 !(cenv->cr[4] & CR4_MCE_MASK)) {
d5bfda33
JK
1169 monitor_printf(params->mon,
1170 "CPU %d: Previous MCE still in progress, raising"
1171 " triple fault\n",
e0eeb4a2 1172 cs->cpu_index);
79c4f6b0
HY
1173 qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1174 qemu_system_reset_request();
1175 return;
1176 }
2fa11da0 1177 if (banks[1] & MCI_STATUS_VAL) {
d5bfda33 1178 params->status |= MCI_STATUS_OVER;
2fa11da0 1179 }
d5bfda33
JK
1180 banks[2] = params->addr;
1181 banks[3] = params->misc;
1182 cenv->mcg_status = params->mcg_status;
1183 banks[1] = params->status;
e0eeb4a2 1184 cpu_interrupt(cs, CPU_INTERRUPT_MCE);
79c4f6b0
HY
1185 } else if (!(banks[1] & MCI_STATUS_VAL)
1186 || !(banks[1] & MCI_STATUS_UC)) {
2fa11da0 1187 if (banks[1] & MCI_STATUS_VAL) {
d5bfda33 1188 params->status |= MCI_STATUS_OVER;
2fa11da0 1189 }
d5bfda33
JK
1190 banks[2] = params->addr;
1191 banks[3] = params->misc;
1192 banks[1] = params->status;
2fa11da0 1193 } else {
79c4f6b0 1194 banks[1] |= MCI_STATUS_OVER;
2fa11da0 1195 }
79c4f6b0 1196}
b3cd24e0 1197
8c5cf3b6 1198void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
316378e4 1199 uint64_t status, uint64_t mcg_status, uint64_t addr,
747461c7 1200 uint64_t misc, int flags)
b3cd24e0 1201{
182735ef 1202 CPUState *cs = CPU(cpu);
8c5cf3b6 1203 CPUX86State *cenv = &cpu->env;
d5bfda33
JK
1204 MCEInjectionParams params = {
1205 .mon = mon,
d5bfda33
JK
1206 .bank = bank,
1207 .status = status,
1208 .mcg_status = mcg_status,
1209 .addr = addr,
1210 .misc = misc,
1211 .flags = flags,
1212 };
b3cd24e0
JD
1213 unsigned bank_num = cenv->mcg_cap & 0xff;
1214
316378e4
JK
1215 if (!cenv->mcg_cap) {
1216 monitor_printf(mon, "MCE injection not supported\n");
b3cd24e0
JD
1217 return;
1218 }
316378e4
JK
1219 if (bank >= bank_num) {
1220 monitor_printf(mon, "Invalid MCE bank number\n");
1221 return;
1222 }
1223 if (!(status & MCI_STATUS_VAL)) {
1224 monitor_printf(mon, "Invalid MCE status code\n");
1225 return;
1226 }
747461c7
JK
1227 if ((flags & MCE_INJECT_BROADCAST)
1228 && !cpu_x86_support_mca_broadcast(cenv)) {
316378e4
JK
1229 monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
1230 return;
2bd3e04c
JD
1231 }
1232
14e6fe12 1233 run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
c34d440a 1234 if (flags & MCE_INJECT_BROADCAST) {
182735ef
AF
1235 CPUState *other_cs;
1236
c34d440a
JK
1237 params.bank = 1;
1238 params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
1239 params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
1240 params.addr = 0;
1241 params.misc = 0;
bdc44640 1242 CPU_FOREACH(other_cs) {
182735ef 1243 if (other_cs == cs) {
c34d440a 1244 continue;
31ce5e0c 1245 }
14e6fe12 1246 run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
31ce5e0c 1247 }
b3cd24e0
JD
1248 }
1249}
d362e757 1250
317ac620 1251void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
d362e757 1252{
02e51483 1253 X86CPU *cpu = x86_env_get_cpu(env);
93afeade 1254 CPUState *cs = CPU(cpu);
02e51483 1255
d362e757
JK
1256 if (kvm_enabled()) {
1257 env->tpr_access_type = access;
1258
93afeade 1259 cpu_interrupt(cs, CPU_INTERRUPT_TPR);
d362e757 1260 } else {
3f38f309 1261 cpu_restore_state(cs, cs->mem_io_pc);
d362e757 1262
02e51483 1263 apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
d362e757
JK
1264 }
1265}
74ce674f 1266#endif /* !CONFIG_USER_ONLY */
6fd805e1 1267
84273177
JK
1268int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1269 target_ulong *base, unsigned int *limit,
1270 unsigned int *flags)
1271{
f17ec444
AF
1272 X86CPU *cpu = x86_env_get_cpu(env);
1273 CPUState *cs = CPU(cpu);
84273177
JK
1274 SegmentCache *dt;
1275 target_ulong ptr;
1276 uint32_t e1, e2;
1277 int index;
1278
1279 if (selector & 0x4)
1280 dt = &env->ldt;
1281 else
1282 dt = &env->gdt;
1283 index = selector & ~7;
1284 ptr = dt->base + index;
1285 if ((index + 7) > dt->limit
f17ec444
AF
1286 || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1287 || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
84273177
JK
1288 return 0;
1289
1290 *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1291 *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1292 if (e2 & DESC_G_MASK)
1293 *limit = (*limit << 12) | 0xfff;
1294 *flags = e2;
1295
1296 return 1;
1297}
1298
b09ea7d5 1299#if !defined(CONFIG_USER_ONLY)
232fc23b 1300void do_cpu_init(X86CPU *cpu)
b09ea7d5 1301{
259186a7 1302 CPUState *cs = CPU(cpu);
232fc23b 1303 CPUX86State *env = &cpu->env;
43175fa9 1304 CPUX86State *save = g_new(CPUX86State, 1);
259186a7 1305 int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
43175fa9
PB
1306
1307 *save = *env;
ebda377f 1308
259186a7
AF
1309 cpu_reset(cs);
1310 cs->interrupt_request = sipi;
43175fa9
PB
1311 memcpy(&env->start_init_save, &save->start_init_save,
1312 offsetof(CPUX86State, end_init_save) -
1313 offsetof(CPUX86State, start_init_save));
1314 g_free(save);
1315
e0723c45
PB
1316 if (kvm_enabled()) {
1317 kvm_arch_do_init_vcpu(cpu);
1318 }
02e51483 1319 apic_init_reset(cpu->apic_state);
b09ea7d5
GN
1320}
1321
232fc23b 1322void do_cpu_sipi(X86CPU *cpu)
b09ea7d5 1323{
02e51483 1324 apic_sipi(cpu->apic_state);
b09ea7d5
GN
1325}
1326#else
232fc23b 1327void do_cpu_init(X86CPU *cpu)
b09ea7d5
GN
1328{
1329}
232fc23b 1330void do_cpu_sipi(X86CPU *cpu)
b09ea7d5
GN
1331{
1332}
1333#endif
374e0cd4
RH
1334
1335/* Frob eflags into and out of the CPU temporary format. */
1336
1337void x86_cpu_exec_enter(CPUState *cs)
1338{
1339 X86CPU *cpu = X86_CPU(cs);
1340 CPUX86State *env = &cpu->env;
1341
1342 CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1343 env->df = 1 - (2 * ((env->eflags >> 10) & 1));
1344 CC_OP = CC_OP_EFLAGS;
1345 env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1346}
1347
1348void x86_cpu_exec_exit(CPUState *cs)
1349{
1350 X86CPU *cpu = X86_CPU(cs);
1351 CPUX86State *env = &cpu->env;
1352
1353 env->eflags = cpu_compute_eflags(env);
1354}
b216aa6c
PB
1355
1356#ifndef CONFIG_USER_ONLY
1357uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr)
1358{
1359 X86CPU *cpu = X86_CPU(cs);
1360 CPUX86State *env = &cpu->env;
1361
1362 return address_space_ldub(cs->as, addr,
1363 cpu_get_mem_attrs(env),
1364 NULL);
1365}
1366
1367uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr)
1368{
1369 X86CPU *cpu = X86_CPU(cs);
1370 CPUX86State *env = &cpu->env;
1371
1372 return address_space_lduw(cs->as, addr,
1373 cpu_get_mem_attrs(env),
1374 NULL);
1375}
1376
1377uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr)
1378{
1379 X86CPU *cpu = X86_CPU(cs);
1380 CPUX86State *env = &cpu->env;
1381
1382 return address_space_ldl(cs->as, addr,
1383 cpu_get_mem_attrs(env),
1384 NULL);
1385}
1386
1387uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr)
1388{
1389 X86CPU *cpu = X86_CPU(cs);
1390 CPUX86State *env = &cpu->env;
1391
1392 return address_space_ldq(cs->as, addr,
1393 cpu_get_mem_attrs(env),
1394 NULL);
1395}
1396
1397void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val)
1398{
1399 X86CPU *cpu = X86_CPU(cs);
1400 CPUX86State *env = &cpu->env;
1401
1402 address_space_stb(cs->as, addr, val,
1403 cpu_get_mem_attrs(env),
1404 NULL);
1405}
1406
1407void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val)
1408{
1409 X86CPU *cpu = X86_CPU(cs);
1410 CPUX86State *env = &cpu->env;
1411
1412 address_space_stl_notdirty(cs->as, addr, val,
1413 cpu_get_mem_attrs(env),
1414 NULL);
1415}
1416
1417void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val)
1418{
1419 X86CPU *cpu = X86_CPU(cs);
1420 CPUX86State *env = &cpu->env;
1421
1422 address_space_stw(cs->as, addr, val,
1423 cpu_get_mem_attrs(env),
1424 NULL);
1425}
1426
1427void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val)
1428{
1429 X86CPU *cpu = X86_CPU(cs);
1430 CPUX86State *env = &cpu->env;
1431
1432 address_space_stl(cs->as, addr, val,
1433 cpu_get_mem_attrs(env),
1434 NULL);
1435}
1436
1437void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val)
1438{
1439 X86CPU *cpu = X86_CPU(cs);
1440 CPUX86State *env = &cpu->env;
1441
1442 address_space_stq(cs->as, addr, val,
1443 cpu_get_mem_attrs(env),
1444 NULL);
1445}
1446#endif