]> git.proxmox.com Git - qemu.git/blame - target-i386/helper.c
Merge remote branch 'rth/axp-next' into alpha-merge
[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 */
eaa728ee
FB
19#include <stdarg.h>
20#include <stdlib.h>
21#include <stdio.h>
22#include <string.h>
23#include <inttypes.h>
2c0262af 24
eaa728ee
FB
25#include "cpu.h"
26#include "exec-all.h"
eaa728ee 27#include "qemu-common.h"
7ba1e619 28#include "kvm.h"
2fa11da0
JK
29#ifndef CONFIG_USER_ONLY
30#include "sysemu.h"
316378e4 31#include "monitor.h"
2fa11da0 32#endif
f3f2d9be 33
eaa728ee 34//#define DEBUG_MMU
b5ec5ce0 35
eaa728ee
FB
36/* NOTE: must be called outside the CPU execute loop */
37void cpu_reset(CPUX86State *env)
7e84c249 38{
eaa728ee 39 int i;
7e84c249 40
eca1bdf4
AL
41 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
42 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
43 log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
44 }
45
eaa728ee 46 memset(env, 0, offsetof(CPUX86State, breakpoints));
7e84c249 47
eaa728ee 48 tlb_flush(env, 1);
7e84c249 49
eaa728ee 50 env->old_exception = -1;
7e84c249 51
eaa728ee 52 /* init to reset state */
3b46e624 53
eaa728ee
FB
54#ifdef CONFIG_SOFTMMU
55 env->hflags |= HF_SOFTMMU_MASK;
2c0262af 56#endif
db620f46 57 env->hflags2 |= HF2_GIF_MASK;
2c0262af 58
eaa728ee
FB
59 cpu_x86_update_cr0(env, 0x60000010);
60 env->a20_mask = ~0x0;
61 env->smbase = 0x30000;
7e84c249 62
eaa728ee
FB
63 env->idt.limit = 0xffff;
64 env->gdt.limit = 0xffff;
65 env->ldt.limit = 0xffff;
262ffdae 66 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
eaa728ee 67 env->tr.limit = 0xffff;
23e6c399 68 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
262ffdae
FB
69
70 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
538f3686
NK
71 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
72 DESC_R_MASK | DESC_A_MASK);
262ffdae 73 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
538f3686
NK
74 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
75 DESC_A_MASK);
262ffdae 76 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
538f3686
NK
77 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
78 DESC_A_MASK);
262ffdae 79 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
538f3686
NK
80 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
81 DESC_A_MASK);
262ffdae 82 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
538f3686
NK
83 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
84 DESC_A_MASK);
262ffdae 85 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
538f3686
NK
86 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
87 DESC_A_MASK);
7e84c249 88
eaa728ee
FB
89 env->eip = 0xfff0;
90 env->regs[R_EDX] = env->cpuid_version;
2c0262af 91
eaa728ee 92 env->eflags = 0x2;
7e84c249 93
eaa728ee
FB
94 /* FPU init */
95 for(i = 0;i < 8; i++)
96 env->fptags[i] = 1;
97 env->fpuc = 0x37f;
7e84c249 98
eaa728ee 99 env->mxcsr = 0x1f80;
01df040b 100
ebda377f
JK
101 env->pat = 0x0007040600070406ULL;
102
01df040b
AL
103 memset(env->dr, 0, sizeof(env->dr));
104 env->dr[6] = DR6_FIXED_1;
105 env->dr[7] = DR7_FIXED_1;
106 cpu_breakpoint_remove_all(env, BP_CPU);
107 cpu_watchpoint_remove_all(env, BP_CPU);
eaa728ee 108}
7e84c249 109
eaa728ee
FB
110void cpu_x86_close(CPUX86State *env)
111{
bb332cb2 112 qemu_free(env);
eaa728ee 113}
7e84c249 114
2bd3e04c
JD
115static void cpu_x86_version(CPUState *env, int *family, int *model)
116{
117 int cpuver = env->cpuid_version;
118
119 if (family == NULL || model == NULL) {
120 return;
121 }
122
123 *family = (cpuver >> 8) & 0x0f;
124 *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
125}
126
127/* Broadcast MCA signal for processor version 06H_EH and above */
128int cpu_x86_support_mca_broadcast(CPUState *env)
129{
130 int family = 0;
131 int model = 0;
132
133 cpu_x86_version(env, &family, &model);
134 if ((family == 6 && model >= 14) || family > 6) {
135 return 1;
136 }
137
138 return 0;
139}
140
eaa728ee
FB
141/***********************************************************/
142/* x86 debug */
3b46e624 143
eaa728ee
FB
144static const char *cc_op_str[] = {
145 "DYNAMIC",
146 "EFLAGS",
7e84c249 147
eaa728ee
FB
148 "MULB",
149 "MULW",
150 "MULL",
151 "MULQ",
3b46e624 152
eaa728ee
FB
153 "ADDB",
154 "ADDW",
155 "ADDL",
156 "ADDQ",
3b46e624 157
eaa728ee
FB
158 "ADCB",
159 "ADCW",
160 "ADCL",
161 "ADCQ",
3b46e624 162
eaa728ee
FB
163 "SUBB",
164 "SUBW",
165 "SUBL",
166 "SUBQ",
7e84c249 167
eaa728ee
FB
168 "SBBB",
169 "SBBW",
170 "SBBL",
171 "SBBQ",
7e84c249 172
eaa728ee
FB
173 "LOGICB",
174 "LOGICW",
175 "LOGICL",
176 "LOGICQ",
7e84c249 177
eaa728ee
FB
178 "INCB",
179 "INCW",
180 "INCL",
181 "INCQ",
3b46e624 182
eaa728ee
FB
183 "DECB",
184 "DECW",
185 "DECL",
186 "DECQ",
3b46e624 187
eaa728ee
FB
188 "SHLB",
189 "SHLW",
190 "SHLL",
191 "SHLQ",
3b46e624 192
eaa728ee
FB
193 "SARB",
194 "SARW",
195 "SARL",
196 "SARQ",
197};
7e84c249 198
a3867ed2 199static void
9a78eead 200cpu_x86_dump_seg_cache(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
a3867ed2
AL
201 const char *name, struct SegmentCache *sc)
202{
203#ifdef TARGET_X86_64
204 if (env->hflags & HF_CS64_MASK) {
205 cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
4058fd98 206 sc->selector, sc->base, sc->limit, sc->flags & 0x00ffff00);
a3867ed2
AL
207 } else
208#endif
209 {
210 cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
4058fd98 211 (uint32_t)sc->base, sc->limit, sc->flags & 0x00ffff00);
a3867ed2
AL
212 }
213
214 if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
215 goto done;
216
217 cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
218 if (sc->flags & DESC_S_MASK) {
219 if (sc->flags & DESC_CS_MASK) {
220 cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
221 ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
222 cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
223 (sc->flags & DESC_R_MASK) ? 'R' : '-');
224 } else {
225 cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS " : "DS16");
226 cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
227 (sc->flags & DESC_W_MASK) ? 'W' : '-');
228 }
229 cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
230 } else {
231 static const char *sys_type_name[2][16] = {
232 { /* 32 bit mode */
233 "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
234 "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
235 "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
236 "CallGate32", "Reserved", "IntGate32", "TrapGate32"
237 },
238 { /* 64 bit mode */
239 "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
240 "Reserved", "Reserved", "Reserved", "Reserved",
241 "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
242 "Reserved", "IntGate64", "TrapGate64"
243 }
244 };
e5c15eff
SW
245 cpu_fprintf(f, "%s",
246 sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
247 [(sc->flags & DESC_TYPE_MASK)
248 >> DESC_TYPE_SHIFT]);
a3867ed2
AL
249 }
250done:
251 cpu_fprintf(f, "\n");
252}
253
f5c848ee
JK
254#define DUMP_CODE_BYTES_TOTAL 50
255#define DUMP_CODE_BYTES_BACKWARD 20
256
9a78eead 257void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
eaa728ee
FB
258 int flags)
259{
260 int eflags, i, nb;
261 char cc_op_name[32];
262 static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
7e84c249 263
23054111 264 cpu_synchronize_state(env);
ff3c01ca 265
eaa728ee
FB
266 eflags = env->eflags;
267#ifdef TARGET_X86_64
268 if (env->hflags & HF_CS64_MASK) {
269 cpu_fprintf(f,
270 "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
271 "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
272 "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
273 "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
274 "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
275 env->regs[R_EAX],
276 env->regs[R_EBX],
277 env->regs[R_ECX],
278 env->regs[R_EDX],
279 env->regs[R_ESI],
280 env->regs[R_EDI],
281 env->regs[R_EBP],
282 env->regs[R_ESP],
283 env->regs[8],
284 env->regs[9],
285 env->regs[10],
286 env->regs[11],
287 env->regs[12],
288 env->regs[13],
289 env->regs[14],
290 env->regs[15],
291 env->eip, eflags,
292 eflags & DF_MASK ? 'D' : '-',
293 eflags & CC_O ? 'O' : '-',
294 eflags & CC_S ? 'S' : '-',
295 eflags & CC_Z ? 'Z' : '-',
296 eflags & CC_A ? 'A' : '-',
297 eflags & CC_P ? 'P' : '-',
298 eflags & CC_C ? 'C' : '-',
299 env->hflags & HF_CPL_MASK,
300 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
5ee0ffaa 301 (env->a20_mask >> 20) & 1,
eaa728ee 302 (env->hflags >> HF_SMM_SHIFT) & 1,
ce5232c5 303 env->halted);
eaa728ee
FB
304 } else
305#endif
306 {
307 cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
308 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
309 "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
310 (uint32_t)env->regs[R_EAX],
311 (uint32_t)env->regs[R_EBX],
312 (uint32_t)env->regs[R_ECX],
313 (uint32_t)env->regs[R_EDX],
314 (uint32_t)env->regs[R_ESI],
315 (uint32_t)env->regs[R_EDI],
316 (uint32_t)env->regs[R_EBP],
317 (uint32_t)env->regs[R_ESP],
318 (uint32_t)env->eip, eflags,
319 eflags & DF_MASK ? 'D' : '-',
320 eflags & CC_O ? 'O' : '-',
321 eflags & CC_S ? 'S' : '-',
322 eflags & CC_Z ? 'Z' : '-',
323 eflags & CC_A ? 'A' : '-',
324 eflags & CC_P ? 'P' : '-',
325 eflags & CC_C ? 'C' : '-',
326 env->hflags & HF_CPL_MASK,
327 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
5ee0ffaa 328 (env->a20_mask >> 20) & 1,
eaa728ee 329 (env->hflags >> HF_SMM_SHIFT) & 1,
ce5232c5 330 env->halted);
8145122b 331 }
3b46e624 332
a3867ed2
AL
333 for(i = 0; i < 6; i++) {
334 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
335 &env->segs[i]);
336 }
337 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
338 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
339
eaa728ee
FB
340#ifdef TARGET_X86_64
341 if (env->hflags & HF_LMA_MASK) {
eaa728ee
FB
342 cpu_fprintf(f, "GDT= %016" PRIx64 " %08x\n",
343 env->gdt.base, env->gdt.limit);
344 cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
345 env->idt.base, env->idt.limit);
346 cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
347 (uint32_t)env->cr[0],
348 env->cr[2],
349 env->cr[3],
350 (uint32_t)env->cr[4]);
a59cb4e0
AL
351 for(i = 0; i < 4; i++)
352 cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
353 cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
d4b55be5 354 env->dr[6], env->dr[7]);
eaa728ee
FB
355 } else
356#endif
357 {
eaa728ee
FB
358 cpu_fprintf(f, "GDT= %08x %08x\n",
359 (uint32_t)env->gdt.base, env->gdt.limit);
360 cpu_fprintf(f, "IDT= %08x %08x\n",
361 (uint32_t)env->idt.base, env->idt.limit);
362 cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
363 (uint32_t)env->cr[0],
364 (uint32_t)env->cr[2],
365 (uint32_t)env->cr[3],
366 (uint32_t)env->cr[4]);
9a78eead
SW
367 for(i = 0; i < 4; i++) {
368 cpu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
369 }
370 cpu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
371 env->dr[6], env->dr[7]);
eaa728ee
FB
372 }
373 if (flags & X86_DUMP_CCOP) {
374 if ((unsigned)env->cc_op < CC_OP_NB)
375 snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
376 else
377 snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
378#ifdef TARGET_X86_64
379 if (env->hflags & HF_CS64_MASK) {
380 cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
381 env->cc_src, env->cc_dst,
382 cc_op_name);
383 } else
384#endif
385 {
386 cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
387 (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
388 cc_op_name);
389 }
7e84c249 390 }
b5e5a934 391 cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
eaa728ee
FB
392 if (flags & X86_DUMP_FPU) {
393 int fptag;
394 fptag = 0;
395 for(i = 0; i < 8; i++) {
396 fptag |= ((!env->fptags[i]) << i);
397 }
398 cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
399 env->fpuc,
400 (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
401 env->fpstt,
402 fptag,
403 env->mxcsr);
404 for(i=0;i<8;i++) {
1ffd41ee
AJ
405 CPU_LDoubleU u;
406 u.d = env->fpregs[i].d;
eaa728ee 407 cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
1ffd41ee 408 i, u.l.lower, u.l.upper);
eaa728ee
FB
409 if ((i & 1) == 1)
410 cpu_fprintf(f, "\n");
411 else
412 cpu_fprintf(f, " ");
413 }
414 if (env->hflags & HF_CS64_MASK)
415 nb = 16;
416 else
417 nb = 8;
418 for(i=0;i<nb;i++) {
419 cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
420 i,
421 env->xmm_regs[i].XMM_L(3),
422 env->xmm_regs[i].XMM_L(2),
423 env->xmm_regs[i].XMM_L(1),
424 env->xmm_regs[i].XMM_L(0));
425 if ((i & 1) == 1)
426 cpu_fprintf(f, "\n");
427 else
428 cpu_fprintf(f, " ");
429 }
7e84c249 430 }
f5c848ee
JK
431 if (flags & CPU_DUMP_CODE) {
432 target_ulong base = env->segs[R_CS].base + env->eip;
433 target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
434 uint8_t code;
435 char codestr[3];
436
437 cpu_fprintf(f, "Code=");
438 for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
439 if (cpu_memory_rw_debug(env, base - offs + i, &code, 1, 0) == 0) {
440 snprintf(codestr, sizeof(codestr), "%02x", code);
441 } else {
442 snprintf(codestr, sizeof(codestr), "??");
443 }
444 cpu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
445 i == offs ? "<" : "", codestr, i == offs ? ">" : "");
446 }
447 cpu_fprintf(f, "\n");
448 }
2c0262af 449}
7e84c249 450
eaa728ee
FB
451/***********************************************************/
452/* x86 mmu */
453/* XXX: add PGE support */
454
455void cpu_x86_set_a20(CPUX86State *env, int a20_state)
2c0262af 456{
eaa728ee
FB
457 a20_state = (a20_state != 0);
458 if (a20_state != ((env->a20_mask >> 20) & 1)) {
459#if defined(DEBUG_MMU)
460 printf("A20 update: a20=%d\n", a20_state);
461#endif
462 /* if the cpu is currently executing code, we must unlink it and
463 all the potentially executing TB */
464 cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
3b46e624 465
eaa728ee
FB
466 /* when a20 is changed, all the MMU mappings are invalid, so
467 we must flush everything */
468 tlb_flush(env, 1);
5ee0ffaa 469 env->a20_mask = ~(1 << 20) | (a20_state << 20);
7e84c249 470 }
2c0262af
FB
471}
472
eaa728ee 473void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
2c0262af 474{
eaa728ee 475 int pe_state;
2c0262af 476
eaa728ee
FB
477#if defined(DEBUG_MMU)
478 printf("CR0 update: CR0=0x%08x\n", new_cr0);
479#endif
480 if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
481 (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
482 tlb_flush(env, 1);
483 }
2c0262af 484
eaa728ee
FB
485#ifdef TARGET_X86_64
486 if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
487 (env->efer & MSR_EFER_LME)) {
488 /* enter in long mode */
489 /* XXX: generate an exception */
490 if (!(env->cr[4] & CR4_PAE_MASK))
491 return;
492 env->efer |= MSR_EFER_LMA;
493 env->hflags |= HF_LMA_MASK;
494 } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
495 (env->efer & MSR_EFER_LMA)) {
496 /* exit long mode */
497 env->efer &= ~MSR_EFER_LMA;
498 env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
499 env->eip &= 0xffffffff;
500 }
501#endif
502 env->cr[0] = new_cr0 | CR0_ET_MASK;
7e84c249 503
eaa728ee
FB
504 /* update PE flag in hidden flags */
505 pe_state = (env->cr[0] & CR0_PE_MASK);
506 env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
507 /* ensure that ADDSEG is always set in real mode */
508 env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
509 /* update FPU flags */
510 env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
511 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
7e84c249
FB
512}
513
eaa728ee
FB
514/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
515 the PDPT */
516void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
7e84c249 517{
eaa728ee
FB
518 env->cr[3] = new_cr3;
519 if (env->cr[0] & CR0_PG_MASK) {
520#if defined(DEBUG_MMU)
521 printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
522#endif
523 tlb_flush(env, 0);
524 }
7e84c249
FB
525}
526
eaa728ee 527void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
7e84c249 528{
eaa728ee
FB
529#if defined(DEBUG_MMU)
530 printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
531#endif
532 if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
533 (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
534 tlb_flush(env, 1);
535 }
536 /* SSE handling */
537 if (!(env->cpuid_features & CPUID_SSE))
538 new_cr4 &= ~CR4_OSFXSR_MASK;
539 if (new_cr4 & CR4_OSFXSR_MASK)
540 env->hflags |= HF_OSFXSR_MASK;
541 else
542 env->hflags &= ~HF_OSFXSR_MASK;
b8b6a50b 543
eaa728ee 544 env->cr[4] = new_cr4;
b8b6a50b
FB
545}
546
eaa728ee
FB
547#if defined(CONFIG_USER_ONLY)
548
549int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
550 int is_write, int mmu_idx, int is_softmmu)
b8b6a50b 551{
eaa728ee
FB
552 /* user mode only emulation */
553 is_write &= 1;
554 env->cr[2] = addr;
555 env->error_code = (is_write << PG_ERROR_W_BIT);
556 env->error_code |= PG_ERROR_U_MASK;
557 env->exception_index = EXCP0E_PAGE;
558 return 1;
2c0262af
FB
559}
560
8d7b0fbb 561#else
891b38e4 562
eaa728ee
FB
563/* XXX: This value should match the one returned by CPUID
564 * and in exec.c */
eaa728ee 565# if defined(TARGET_X86_64)
2c90d794 566# define PHYS_ADDR_MASK 0xfffffff000LL
eaa728ee 567# else
2c90d794 568# define PHYS_ADDR_MASK 0xffffff000LL
eaa728ee 569# endif
eaa728ee
FB
570
571/* return value:
572 -1 = cannot handle fault
573 0 = nothing more to do
574 1 = generate PF fault
eaa728ee
FB
575*/
576int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
577 int is_write1, int mmu_idx, int is_softmmu)
578{
579 uint64_t ptep, pte;
580 target_ulong pde_addr, pte_addr;
d4c430a8 581 int error_code, is_dirty, prot, page_size, is_write, is_user;
c227f099 582 target_phys_addr_t paddr;
eaa728ee
FB
583 uint32_t page_offset;
584 target_ulong vaddr, virt_addr;
585
586 is_user = mmu_idx == MMU_USER_IDX;
587#if defined(DEBUG_MMU)
588 printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
589 addr, is_write1, is_user, env->eip);
590#endif
591 is_write = is_write1 & 1;
592
593 if (!(env->cr[0] & CR0_PG_MASK)) {
594 pte = addr;
595 virt_addr = addr & TARGET_PAGE_MASK;
596 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
597 page_size = 4096;
598 goto do_mapping;
599 }
600
601 if (env->cr[4] & CR4_PAE_MASK) {
602 uint64_t pde, pdpe;
603 target_ulong pdpe_addr;
2c0262af 604
eaa728ee
FB
605#ifdef TARGET_X86_64
606 if (env->hflags & HF_LMA_MASK) {
607 uint64_t pml4e_addr, pml4e;
608 int32_t sext;
609
610 /* test virtual address sign extension */
611 sext = (int64_t)addr >> 47;
612 if (sext != 0 && sext != -1) {
613 env->error_code = 0;
614 env->exception_index = EXCP0D_GPF;
615 return 1;
616 }
0573fbfc 617
eaa728ee
FB
618 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
619 env->a20_mask;
620 pml4e = ldq_phys(pml4e_addr);
621 if (!(pml4e & PG_PRESENT_MASK)) {
622 error_code = 0;
623 goto do_fault;
624 }
625 if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
626 error_code = PG_ERROR_RSVD_MASK;
627 goto do_fault;
628 }
629 if (!(pml4e & PG_ACCESSED_MASK)) {
630 pml4e |= PG_ACCESSED_MASK;
631 stl_phys_notdirty(pml4e_addr, pml4e);
632 }
633 ptep = pml4e ^ PG_NX_MASK;
634 pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
635 env->a20_mask;
636 pdpe = ldq_phys(pdpe_addr);
637 if (!(pdpe & PG_PRESENT_MASK)) {
638 error_code = 0;
639 goto do_fault;
640 }
641 if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
642 error_code = PG_ERROR_RSVD_MASK;
643 goto do_fault;
644 }
645 ptep &= pdpe ^ PG_NX_MASK;
646 if (!(pdpe & PG_ACCESSED_MASK)) {
647 pdpe |= PG_ACCESSED_MASK;
648 stl_phys_notdirty(pdpe_addr, pdpe);
649 }
650 } else
651#endif
652 {
653 /* XXX: load them when cr3 is loaded ? */
654 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
655 env->a20_mask;
656 pdpe = ldq_phys(pdpe_addr);
657 if (!(pdpe & PG_PRESENT_MASK)) {
658 error_code = 0;
659 goto do_fault;
660 }
661 ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
7e84c249 662 }
7e84c249 663
eaa728ee
FB
664 pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
665 env->a20_mask;
666 pde = ldq_phys(pde_addr);
667 if (!(pde & PG_PRESENT_MASK)) {
668 error_code = 0;
669 goto do_fault;
670 }
671 if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
672 error_code = PG_ERROR_RSVD_MASK;
673 goto do_fault;
674 }
675 ptep &= pde ^ PG_NX_MASK;
676 if (pde & PG_PSE_MASK) {
677 /* 2 MB page */
678 page_size = 2048 * 1024;
679 ptep ^= PG_NX_MASK;
680 if ((ptep & PG_NX_MASK) && is_write1 == 2)
681 goto do_fault_protect;
682 if (is_user) {
683 if (!(ptep & PG_USER_MASK))
684 goto do_fault_protect;
685 if (is_write && !(ptep & PG_RW_MASK))
686 goto do_fault_protect;
687 } else {
688 if ((env->cr[0] & CR0_WP_MASK) &&
689 is_write && !(ptep & PG_RW_MASK))
690 goto do_fault_protect;
691 }
692 is_dirty = is_write && !(pde & PG_DIRTY_MASK);
693 if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
694 pde |= PG_ACCESSED_MASK;
695 if (is_dirty)
696 pde |= PG_DIRTY_MASK;
697 stl_phys_notdirty(pde_addr, pde);
698 }
699 /* align to page_size */
700 pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
701 virt_addr = addr & ~(page_size - 1);
702 } else {
703 /* 4 KB page */
704 if (!(pde & PG_ACCESSED_MASK)) {
705 pde |= PG_ACCESSED_MASK;
706 stl_phys_notdirty(pde_addr, pde);
707 }
708 pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
709 env->a20_mask;
710 pte = ldq_phys(pte_addr);
711 if (!(pte & PG_PRESENT_MASK)) {
712 error_code = 0;
713 goto do_fault;
714 }
715 if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
716 error_code = PG_ERROR_RSVD_MASK;
717 goto do_fault;
718 }
719 /* combine pde and pte nx, user and rw protections */
720 ptep &= pte ^ PG_NX_MASK;
721 ptep ^= PG_NX_MASK;
722 if ((ptep & PG_NX_MASK) && is_write1 == 2)
723 goto do_fault_protect;
724 if (is_user) {
725 if (!(ptep & PG_USER_MASK))
726 goto do_fault_protect;
727 if (is_write && !(ptep & PG_RW_MASK))
728 goto do_fault_protect;
729 } else {
730 if ((env->cr[0] & CR0_WP_MASK) &&
731 is_write && !(ptep & PG_RW_MASK))
732 goto do_fault_protect;
733 }
734 is_dirty = is_write && !(pte & PG_DIRTY_MASK);
735 if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
736 pte |= PG_ACCESSED_MASK;
737 if (is_dirty)
738 pte |= PG_DIRTY_MASK;
739 stl_phys_notdirty(pte_addr, pte);
740 }
741 page_size = 4096;
742 virt_addr = addr & ~0xfff;
743 pte = pte & (PHYS_ADDR_MASK | 0xfff);
7e84c249 744 }
2c0262af 745 } else {
eaa728ee
FB
746 uint32_t pde;
747
748 /* page directory entry */
749 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
750 env->a20_mask;
751 pde = ldl_phys(pde_addr);
752 if (!(pde & PG_PRESENT_MASK)) {
753 error_code = 0;
754 goto do_fault;
755 }
756 /* if PSE bit is set, then we use a 4MB page */
757 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
758 page_size = 4096 * 1024;
759 if (is_user) {
760 if (!(pde & PG_USER_MASK))
761 goto do_fault_protect;
762 if (is_write && !(pde & PG_RW_MASK))
763 goto do_fault_protect;
764 } else {
765 if ((env->cr[0] & CR0_WP_MASK) &&
766 is_write && !(pde & PG_RW_MASK))
767 goto do_fault_protect;
768 }
769 is_dirty = is_write && !(pde & PG_DIRTY_MASK);
770 if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
771 pde |= PG_ACCESSED_MASK;
772 if (is_dirty)
773 pde |= PG_DIRTY_MASK;
774 stl_phys_notdirty(pde_addr, pde);
775 }
2c0262af 776
eaa728ee
FB
777 pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
778 ptep = pte;
779 virt_addr = addr & ~(page_size - 1);
780 } else {
781 if (!(pde & PG_ACCESSED_MASK)) {
782 pde |= PG_ACCESSED_MASK;
783 stl_phys_notdirty(pde_addr, pde);
784 }
891b38e4 785
eaa728ee
FB
786 /* page directory entry */
787 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
788 env->a20_mask;
789 pte = ldl_phys(pte_addr);
790 if (!(pte & PG_PRESENT_MASK)) {
791 error_code = 0;
792 goto do_fault;
8e682019 793 }
eaa728ee
FB
794 /* combine pde and pte user and rw protections */
795 ptep = pte & pde;
796 if (is_user) {
797 if (!(ptep & PG_USER_MASK))
798 goto do_fault_protect;
799 if (is_write && !(ptep & PG_RW_MASK))
800 goto do_fault_protect;
801 } else {
802 if ((env->cr[0] & CR0_WP_MASK) &&
803 is_write && !(ptep & PG_RW_MASK))
804 goto do_fault_protect;
8e682019 805 }
eaa728ee
FB
806 is_dirty = is_write && !(pte & PG_DIRTY_MASK);
807 if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
808 pte |= PG_ACCESSED_MASK;
809 if (is_dirty)
810 pte |= PG_DIRTY_MASK;
811 stl_phys_notdirty(pte_addr, pte);
812 }
813 page_size = 4096;
814 virt_addr = addr & ~0xfff;
2c0262af
FB
815 }
816 }
eaa728ee
FB
817 /* the page can be put in the TLB */
818 prot = PAGE_READ;
819 if (!(ptep & PG_NX_MASK))
820 prot |= PAGE_EXEC;
821 if (pte & PG_DIRTY_MASK) {
822 /* only set write access if already dirty... otherwise wait
823 for dirty access */
824 if (is_user) {
825 if (ptep & PG_RW_MASK)
826 prot |= PAGE_WRITE;
827 } else {
828 if (!(env->cr[0] & CR0_WP_MASK) ||
829 (ptep & PG_RW_MASK))
830 prot |= PAGE_WRITE;
8e682019 831 }
891b38e4 832 }
eaa728ee
FB
833 do_mapping:
834 pte = pte & env->a20_mask;
835
836 /* Even if 4MB pages, we map only one 4KB page in the cache to
837 avoid filling it too fast */
838 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
839 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
840 vaddr = virt_addr + page_offset;
841
d4c430a8
PB
842 tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
843 return 0;
eaa728ee
FB
844 do_fault_protect:
845 error_code = PG_ERROR_P_MASK;
846 do_fault:
847 error_code |= (is_write << PG_ERROR_W_BIT);
848 if (is_user)
849 error_code |= PG_ERROR_U_MASK;
850 if (is_write1 == 2 &&
851 (env->efer & MSR_EFER_NXE) &&
852 (env->cr[4] & CR4_PAE_MASK))
853 error_code |= PG_ERROR_I_D_MASK;
872929aa
FB
854 if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
855 /* cr2 is not modified in case of exceptions */
856 stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
857 addr);
eaa728ee
FB
858 } else {
859 env->cr[2] = addr;
2c0262af 860 }
eaa728ee
FB
861 env->error_code = error_code;
862 env->exception_index = EXCP0E_PAGE;
eaa728ee 863 return 1;
14ce26e7
FB
864}
865
c227f099 866target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
14ce26e7 867{
eaa728ee
FB
868 target_ulong pde_addr, pte_addr;
869 uint64_t pte;
c227f099 870 target_phys_addr_t paddr;
eaa728ee
FB
871 uint32_t page_offset;
872 int page_size;
14ce26e7 873
eaa728ee
FB
874 if (env->cr[4] & CR4_PAE_MASK) {
875 target_ulong pdpe_addr;
876 uint64_t pde, pdpe;
14ce26e7 877
eaa728ee
FB
878#ifdef TARGET_X86_64
879 if (env->hflags & HF_LMA_MASK) {
880 uint64_t pml4e_addr, pml4e;
881 int32_t sext;
882
883 /* test virtual address sign extension */
884 sext = (int64_t)addr >> 47;
885 if (sext != 0 && sext != -1)
886 return -1;
887
888 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
889 env->a20_mask;
890 pml4e = ldq_phys(pml4e_addr);
891 if (!(pml4e & PG_PRESENT_MASK))
892 return -1;
893
894 pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
895 env->a20_mask;
896 pdpe = ldq_phys(pdpe_addr);
897 if (!(pdpe & PG_PRESENT_MASK))
898 return -1;
899 } else
900#endif
901 {
902 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
903 env->a20_mask;
904 pdpe = ldq_phys(pdpe_addr);
905 if (!(pdpe & PG_PRESENT_MASK))
906 return -1;
14ce26e7 907 }
14ce26e7 908
eaa728ee
FB
909 pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
910 env->a20_mask;
911 pde = ldq_phys(pde_addr);
912 if (!(pde & PG_PRESENT_MASK)) {
913 return -1;
914 }
915 if (pde & PG_PSE_MASK) {
916 /* 2 MB page */
917 page_size = 2048 * 1024;
918 pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
919 } else {
920 /* 4 KB page */
921 pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
922 env->a20_mask;
923 page_size = 4096;
924 pte = ldq_phys(pte_addr);
925 }
ca1c9e15
AL
926 if (!(pte & PG_PRESENT_MASK))
927 return -1;
14ce26e7 928 } else {
eaa728ee 929 uint32_t pde;
3b46e624 930
eaa728ee
FB
931 if (!(env->cr[0] & CR0_PG_MASK)) {
932 pte = addr;
933 page_size = 4096;
934 } else {
935 /* page directory entry */
936 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
937 pde = ldl_phys(pde_addr);
938 if (!(pde & PG_PRESENT_MASK))
939 return -1;
940 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
941 pte = pde & ~0x003ff000; /* align to 4MB */
942 page_size = 4096 * 1024;
943 } else {
944 /* page directory entry */
945 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
946 pte = ldl_phys(pte_addr);
947 if (!(pte & PG_PRESENT_MASK))
948 return -1;
949 page_size = 4096;
950 }
951 }
952 pte = pte & env->a20_mask;
14ce26e7 953 }
14ce26e7 954
eaa728ee
FB
955 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
956 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
957 return paddr;
3b21e03e 958}
01df040b
AL
959
960void hw_breakpoint_insert(CPUState *env, int index)
961{
962 int type, err = 0;
963
964 switch (hw_breakpoint_type(env->dr[7], index)) {
965 case 0:
966 if (hw_breakpoint_enabled(env->dr[7], index))
967 err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
968 &env->cpu_breakpoint[index]);
969 break;
970 case 1:
971 type = BP_CPU | BP_MEM_WRITE;
972 goto insert_wp;
973 case 2:
974 /* No support for I/O watchpoints yet */
975 break;
976 case 3:
977 type = BP_CPU | BP_MEM_ACCESS;
978 insert_wp:
979 err = cpu_watchpoint_insert(env, env->dr[index],
980 hw_breakpoint_len(env->dr[7], index),
981 type, &env->cpu_watchpoint[index]);
982 break;
983 }
984 if (err)
985 env->cpu_breakpoint[index] = NULL;
986}
987
988void hw_breakpoint_remove(CPUState *env, int index)
989{
990 if (!env->cpu_breakpoint[index])
991 return;
992 switch (hw_breakpoint_type(env->dr[7], index)) {
993 case 0:
994 if (hw_breakpoint_enabled(env->dr[7], index))
995 cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
996 break;
997 case 1:
998 case 3:
999 cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
1000 break;
1001 case 2:
1002 /* No support for I/O watchpoints yet */
1003 break;
1004 }
1005}
1006
1007int check_hw_breakpoints(CPUState *env, int force_dr6_update)
1008{
1009 target_ulong dr6;
1010 int reg, type;
1011 int hit_enabled = 0;
1012
1013 dr6 = env->dr[6] & ~0xf;
1014 for (reg = 0; reg < 4; reg++) {
1015 type = hw_breakpoint_type(env->dr[7], reg);
1016 if ((type == 0 && env->dr[reg] == env->eip) ||
1017 ((type & 1) && env->cpu_watchpoint[reg] &&
1018 (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
1019 dr6 |= 1 << reg;
1020 if (hw_breakpoint_enabled(env->dr[7], reg))
1021 hit_enabled = 1;
1022 }
1023 }
1024 if (hit_enabled || force_dr6_update)
1025 env->dr[6] = dr6;
1026 return hit_enabled;
1027}
1028
1029static CPUDebugExcpHandler *prev_debug_excp_handler;
1030
63a54736 1031void raise_exception_env(int exception_index, CPUState *env);
01df040b
AL
1032
1033static void breakpoint_handler(CPUState *env)
1034{
1035 CPUBreakpoint *bp;
1036
1037 if (env->watchpoint_hit) {
1038 if (env->watchpoint_hit->flags & BP_CPU) {
1039 env->watchpoint_hit = NULL;
1040 if (check_hw_breakpoints(env, 0))
63a54736 1041 raise_exception_env(EXCP01_DB, env);
01df040b
AL
1042 else
1043 cpu_resume_from_signal(env, NULL);
1044 }
1045 } else {
72cf2d4f 1046 QTAILQ_FOREACH(bp, &env->breakpoints, entry)
01df040b
AL
1047 if (bp->pc == env->eip) {
1048 if (bp->flags & BP_CPU) {
1049 check_hw_breakpoints(env, 1);
63a54736 1050 raise_exception_env(EXCP01_DB, env);
01df040b
AL
1051 }
1052 break;
1053 }
1054 }
1055 if (prev_debug_excp_handler)
1056 prev_debug_excp_handler(env);
1057}
79c4f6b0 1058
d5bfda33
JK
1059typedef struct MCEInjectionParams {
1060 Monitor *mon;
1061 CPUState *env;
1062 int bank;
1063 uint64_t status;
1064 uint64_t mcg_status;
1065 uint64_t addr;
1066 uint64_t misc;
1067 int flags;
1068} MCEInjectionParams;
1069
1070static void do_inject_x86_mce(void *data)
79c4f6b0 1071{
d5bfda33
JK
1072 MCEInjectionParams *params = data;
1073 CPUState *cenv = params->env;
1074 uint64_t *banks = cenv->mce_banks + 4 * params->bank;
1075
1076 cpu_synchronize_state(cenv);
316378e4 1077
747461c7
JK
1078 /*
1079 * If there is an MCE exception being processed, ignore this SRAO MCE
1080 * unless unconditional injection was requested.
1081 */
d5bfda33
JK
1082 if (!(params->flags & MCE_INJECT_UNCOND_AO)
1083 && !(params->status & MCI_STATUS_AR)
747461c7
JK
1084 && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1085 return;
1086 }
d5bfda33
JK
1087
1088 if (params->status & MCI_STATUS_UC) {
316378e4
JK
1089 /*
1090 * if MSR_MCG_CTL is not all 1s, the uncorrected error
1091 * reporting is disabled
1092 */
d5bfda33
JK
1093 if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1094 monitor_printf(params->mon,
316378e4
JK
1095 "CPU %d: Uncorrected error reporting disabled\n",
1096 cenv->cpu_index);
1097 return;
1098 }
1099
1100 /*
1101 * if MSR_MCi_CTL is not all 1s, the uncorrected error
1102 * reporting is disabled for the bank
1103 */
1104 if (banks[0] != ~(uint64_t)0) {
d5bfda33
JK
1105 monitor_printf(params->mon,
1106 "CPU %d: Uncorrected error reporting disabled for"
1107 " bank %d\n",
1108 cenv->cpu_index, params->bank);
316378e4
JK
1109 return;
1110 }
1111
79c4f6b0
HY
1112 if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1113 !(cenv->cr[4] & CR4_MCE_MASK)) {
d5bfda33
JK
1114 monitor_printf(params->mon,
1115 "CPU %d: Previous MCE still in progress, raising"
1116 " triple fault\n",
1117 cenv->cpu_index);
79c4f6b0
HY
1118 qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1119 qemu_system_reset_request();
1120 return;
1121 }
2fa11da0 1122 if (banks[1] & MCI_STATUS_VAL) {
d5bfda33 1123 params->status |= MCI_STATUS_OVER;
2fa11da0 1124 }
d5bfda33
JK
1125 banks[2] = params->addr;
1126 banks[3] = params->misc;
1127 cenv->mcg_status = params->mcg_status;
1128 banks[1] = params->status;
79c4f6b0
HY
1129 cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
1130 } else if (!(banks[1] & MCI_STATUS_VAL)
1131 || !(banks[1] & MCI_STATUS_UC)) {
2fa11da0 1132 if (banks[1] & MCI_STATUS_VAL) {
d5bfda33 1133 params->status |= MCI_STATUS_OVER;
2fa11da0 1134 }
d5bfda33
JK
1135 banks[2] = params->addr;
1136 banks[3] = params->misc;
1137 banks[1] = params->status;
2fa11da0 1138 } else {
79c4f6b0 1139 banks[1] |= MCI_STATUS_OVER;
2fa11da0 1140 }
79c4f6b0 1141}
b3cd24e0 1142
316378e4
JK
1143void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank,
1144 uint64_t status, uint64_t mcg_status, uint64_t addr,
747461c7 1145 uint64_t misc, int flags)
b3cd24e0 1146{
d5bfda33
JK
1147 MCEInjectionParams params = {
1148 .mon = mon,
1149 .env = cenv,
1150 .bank = bank,
1151 .status = status,
1152 .mcg_status = mcg_status,
1153 .addr = addr,
1154 .misc = misc,
1155 .flags = flags,
1156 };
b3cd24e0 1157 unsigned bank_num = cenv->mcg_cap & 0xff;
31ce5e0c 1158 CPUState *env;
b3cd24e0 1159
316378e4
JK
1160 if (!cenv->mcg_cap) {
1161 monitor_printf(mon, "MCE injection not supported\n");
b3cd24e0
JD
1162 return;
1163 }
316378e4
JK
1164 if (bank >= bank_num) {
1165 monitor_printf(mon, "Invalid MCE bank number\n");
1166 return;
1167 }
1168 if (!(status & MCI_STATUS_VAL)) {
1169 monitor_printf(mon, "Invalid MCE status code\n");
1170 return;
1171 }
747461c7
JK
1172 if ((flags & MCE_INJECT_BROADCAST)
1173 && !cpu_x86_support_mca_broadcast(cenv)) {
316378e4
JK
1174 monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
1175 return;
2bd3e04c
JD
1176 }
1177
c34d440a
JK
1178 run_on_cpu(cenv, do_inject_x86_mce, &params);
1179 if (flags & MCE_INJECT_BROADCAST) {
1180 params.bank = 1;
1181 params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
1182 params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
1183 params.addr = 0;
1184 params.misc = 0;
1185 for (env = first_cpu; env != NULL; env = env->next_cpu) {
1186 if (cenv == env) {
1187 continue;
31ce5e0c 1188 }
c34d440a
JK
1189 params.env = env;
1190 run_on_cpu(cenv, do_inject_x86_mce, &params);
31ce5e0c 1191 }
b3cd24e0
JD
1192 }
1193}
74ce674f 1194#endif /* !CONFIG_USER_ONLY */
6fd805e1 1195
79c4f6b0
HY
1196static void mce_init(CPUX86State *cenv)
1197{
2fa11da0 1198 unsigned int bank;
79c4f6b0 1199
2fa11da0
JK
1200 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
1201 && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
1202 (CPUID_MCE | CPUID_MCA)) {
79c4f6b0
HY
1203 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1204 cenv->mcg_ctl = ~(uint64_t)0;
2fa11da0
JK
1205 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
1206 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
1207 }
79c4f6b0
HY
1208 }
1209}
1210
84273177
JK
1211int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1212 target_ulong *base, unsigned int *limit,
1213 unsigned int *flags)
1214{
1215 SegmentCache *dt;
1216 target_ulong ptr;
1217 uint32_t e1, e2;
1218 int index;
1219
1220 if (selector & 0x4)
1221 dt = &env->ldt;
1222 else
1223 dt = &env->gdt;
1224 index = selector & ~7;
1225 ptr = dt->base + index;
1226 if ((index + 7) > dt->limit
1227 || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1228 || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1229 return 0;
1230
1231 *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1232 *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1233 if (e2 & DESC_G_MASK)
1234 *limit = (*limit << 12) | 0xfff;
1235 *flags = e2;
1236
1237 return 1;
1238}
1239
01df040b
AL
1240CPUX86State *cpu_x86_init(const char *cpu_model)
1241{
1242 CPUX86State *env;
1243 static int inited;
1244
1245 env = qemu_mallocz(sizeof(CPUX86State));
01df040b
AL
1246 cpu_exec_init(env);
1247 env->cpu_model_str = cpu_model;
1248
1249 /* init various static tables */
1250 if (!inited) {
1251 inited = 1;
1252 optimize_flags_init();
1253#ifndef CONFIG_USER_ONLY
1254 prev_debug_excp_handler =
1255 cpu_set_debug_excp_handler(breakpoint_handler);
1256#endif
1257 }
1258 if (cpu_x86_register(env, cpu_model) < 0) {
1259 cpu_x86_close(env);
1260 return NULL;
1261 }
79c4f6b0 1262 mce_init(env);
0bf46a40
AL
1263
1264 qemu_init_vcpu(env);
1265
01df040b
AL
1266 return env;
1267}
b09ea7d5
GN
1268
1269#if !defined(CONFIG_USER_ONLY)
1270void do_cpu_init(CPUState *env)
1271{
1272 int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
ebda377f
JK
1273 uint64_t pat = env->pat;
1274
b09ea7d5
GN
1275 cpu_reset(env);
1276 env->interrupt_request = sipi;
ebda377f 1277 env->pat = pat;
4a942cea 1278 apic_init_reset(env->apic_state);
052be86b 1279 env->halted = !cpu_is_bsp(env);
b09ea7d5
GN
1280}
1281
1282void do_cpu_sipi(CPUState *env)
1283{
4a942cea 1284 apic_sipi(env->apic_state);
b09ea7d5
GN
1285}
1286#else
1287void do_cpu_init(CPUState *env)
1288{
1289}
1290void do_cpu_sipi(CPUState *env)
1291{
1292}
1293#endif