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