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