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