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