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