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