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