]> Git Repo - qemu.git/blame - target-i386/helper.c
Merge remote-tracking branch 'remotes/spice/tags/pull-spice-7' into staging
[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)) {
00c8cb0a
AF
388 CPUState *cs = CPU(cpu);
389
eaa728ee
FB
390#if defined(DEBUG_MMU)
391 printf("A20 update: a20=%d\n", a20_state);
392#endif
393 /* if the cpu is currently executing code, we must unlink it and
394 all the potentially executing TB */
00c8cb0a 395 cpu_interrupt(cs, CPU_INTERRUPT_EXITTB);
3b46e624 396
eaa728ee
FB
397 /* when a20 is changed, all the MMU mappings are invalid, so
398 we must flush everything */
00c8cb0a 399 tlb_flush(cs, 1);
5ee0ffaa 400 env->a20_mask = ~(1 << 20) | (a20_state << 20);
7e84c249 401 }
2c0262af
FB
402}
403
eaa728ee 404void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
2c0262af 405{
00c8cb0a 406 X86CPU *cpu = x86_env_get_cpu(env);
eaa728ee 407 int pe_state;
2c0262af 408
eaa728ee
FB
409#if defined(DEBUG_MMU)
410 printf("CR0 update: CR0=0x%08x\n", new_cr0);
411#endif
412 if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
413 (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
00c8cb0a 414 tlb_flush(CPU(cpu), 1);
eaa728ee 415 }
2c0262af 416
eaa728ee
FB
417#ifdef TARGET_X86_64
418 if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
419 (env->efer & MSR_EFER_LME)) {
420 /* enter in long mode */
421 /* XXX: generate an exception */
422 if (!(env->cr[4] & CR4_PAE_MASK))
423 return;
424 env->efer |= MSR_EFER_LMA;
425 env->hflags |= HF_LMA_MASK;
426 } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
427 (env->efer & MSR_EFER_LMA)) {
428 /* exit long mode */
429 env->efer &= ~MSR_EFER_LMA;
430 env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
431 env->eip &= 0xffffffff;
432 }
433#endif
434 env->cr[0] = new_cr0 | CR0_ET_MASK;
7e84c249 435
eaa728ee
FB
436 /* update PE flag in hidden flags */
437 pe_state = (env->cr[0] & CR0_PE_MASK);
438 env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
439 /* ensure that ADDSEG is always set in real mode */
440 env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
441 /* update FPU flags */
442 env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
443 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
7e84c249
FB
444}
445
eaa728ee
FB
446/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
447 the PDPT */
448void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
7e84c249 449{
00c8cb0a
AF
450 X86CPU *cpu = x86_env_get_cpu(env);
451
eaa728ee
FB
452 env->cr[3] = new_cr3;
453 if (env->cr[0] & CR0_PG_MASK) {
454#if defined(DEBUG_MMU)
455 printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
456#endif
00c8cb0a 457 tlb_flush(CPU(cpu), 0);
eaa728ee 458 }
7e84c249
FB
459}
460
eaa728ee 461void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
7e84c249 462{
00c8cb0a
AF
463 X86CPU *cpu = x86_env_get_cpu(env);
464
eaa728ee
FB
465#if defined(DEBUG_MMU)
466 printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
467#endif
a9321a4d
PA
468 if ((new_cr4 ^ env->cr[4]) &
469 (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK |
470 CR4_SMEP_MASK | CR4_SMAP_MASK)) {
00c8cb0a 471 tlb_flush(CPU(cpu), 1);
eaa728ee
FB
472 }
473 /* SSE handling */
0514ef2f 474 if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) {
eaa728ee 475 new_cr4 &= ~CR4_OSFXSR_MASK;
a9321a4d
PA
476 }
477 env->hflags &= ~HF_OSFXSR_MASK;
478 if (new_cr4 & CR4_OSFXSR_MASK) {
eaa728ee 479 env->hflags |= HF_OSFXSR_MASK;
a9321a4d
PA
480 }
481
0514ef2f 482 if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) {
a9321a4d
PA
483 new_cr4 &= ~CR4_SMAP_MASK;
484 }
485 env->hflags &= ~HF_SMAP_MASK;
486 if (new_cr4 & CR4_SMAP_MASK) {
487 env->hflags |= HF_SMAP_MASK;
488 }
b8b6a50b 489
eaa728ee 490 env->cr[4] = new_cr4;
b8b6a50b
FB
491}
492
eaa728ee
FB
493#if defined(CONFIG_USER_ONLY)
494
7510454e 495int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
97b348e7 496 int is_write, int mmu_idx)
b8b6a50b 497{
7510454e
AF
498 X86CPU *cpu = X86_CPU(cs);
499 CPUX86State *env = &cpu->env;
500
eaa728ee
FB
501 /* user mode only emulation */
502 is_write &= 1;
503 env->cr[2] = addr;
504 env->error_code = (is_write << PG_ERROR_W_BIT);
505 env->error_code |= PG_ERROR_U_MASK;
27103424 506 cs->exception_index = EXCP0E_PAGE;
eaa728ee 507 return 1;
2c0262af
FB
508}
509
8d7b0fbb 510#else
891b38e4 511
eaa728ee
FB
512/* XXX: This value should match the one returned by CPUID
513 * and in exec.c */
eaa728ee 514# if defined(TARGET_X86_64)
2c90d794 515# define PHYS_ADDR_MASK 0xfffffff000LL
eaa728ee 516# else
2c90d794 517# define PHYS_ADDR_MASK 0xffffff000LL
eaa728ee 518# endif
eaa728ee
FB
519
520/* return value:
7510454e
AF
521 * -1 = cannot handle fault
522 * 0 = nothing more to do
523 * 1 = generate PF fault
524 */
525int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
97b348e7 526 int is_write1, int mmu_idx)
eaa728ee 527{
7510454e
AF
528 X86CPU *cpu = X86_CPU(cs);
529 CPUX86State *env = &cpu->env;
eaa728ee
FB
530 uint64_t ptep, pte;
531 target_ulong pde_addr, pte_addr;
d4c430a8 532 int error_code, is_dirty, prot, page_size, is_write, is_user;
a8170e5e 533 hwaddr paddr;
eaa728ee
FB
534 uint32_t page_offset;
535 target_ulong vaddr, virt_addr;
536
537 is_user = mmu_idx == MMU_USER_IDX;
538#if defined(DEBUG_MMU)
7510454e 539 printf("MMU fault: addr=%" VADDR_PRIx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
eaa728ee
FB
540 addr, is_write1, is_user, env->eip);
541#endif
542 is_write = is_write1 & 1;
543
544 if (!(env->cr[0] & CR0_PG_MASK)) {
545 pte = addr;
33dfdb56
AG
546#ifdef TARGET_X86_64
547 if (!(env->hflags & HF_LMA_MASK)) {
548 /* Without long mode we can only address 32bits in real mode */
549 pte = (uint32_t)pte;
550 }
551#endif
eaa728ee
FB
552 virt_addr = addr & TARGET_PAGE_MASK;
553 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
554 page_size = 4096;
555 goto do_mapping;
556 }
557
558 if (env->cr[4] & CR4_PAE_MASK) {
559 uint64_t pde, pdpe;
560 target_ulong pdpe_addr;
2c0262af 561
eaa728ee
FB
562#ifdef TARGET_X86_64
563 if (env->hflags & HF_LMA_MASK) {
564 uint64_t pml4e_addr, pml4e;
565 int32_t sext;
566
567 /* test virtual address sign extension */
568 sext = (int64_t)addr >> 47;
569 if (sext != 0 && sext != -1) {
570 env->error_code = 0;
27103424 571 cs->exception_index = EXCP0D_GPF;
eaa728ee
FB
572 return 1;
573 }
0573fbfc 574
eaa728ee
FB
575 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
576 env->a20_mask;
2c17449b 577 pml4e = ldq_phys(cs->as, pml4e_addr);
eaa728ee
FB
578 if (!(pml4e & PG_PRESENT_MASK)) {
579 error_code = 0;
580 goto do_fault;
581 }
582 if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
583 error_code = PG_ERROR_RSVD_MASK;
584 goto do_fault;
585 }
586 if (!(pml4e & PG_ACCESSED_MASK)) {
587 pml4e |= PG_ACCESSED_MASK;
2198a121 588 stl_phys_notdirty(cs->as, pml4e_addr, pml4e);
eaa728ee
FB
589 }
590 ptep = pml4e ^ PG_NX_MASK;
591 pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
592 env->a20_mask;
2c17449b 593 pdpe = ldq_phys(cs->as, pdpe_addr);
eaa728ee
FB
594 if (!(pdpe & PG_PRESENT_MASK)) {
595 error_code = 0;
596 goto do_fault;
597 }
598 if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
599 error_code = PG_ERROR_RSVD_MASK;
600 goto do_fault;
601 }
602 ptep &= pdpe ^ PG_NX_MASK;
603 if (!(pdpe & PG_ACCESSED_MASK)) {
604 pdpe |= PG_ACCESSED_MASK;
2198a121 605 stl_phys_notdirty(cs->as, pdpe_addr, pdpe);
eaa728ee
FB
606 }
607 } else
608#endif
609 {
610 /* XXX: load them when cr3 is loaded ? */
611 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
612 env->a20_mask;
2c17449b 613 pdpe = ldq_phys(cs->as, pdpe_addr);
eaa728ee
FB
614 if (!(pdpe & PG_PRESENT_MASK)) {
615 error_code = 0;
616 goto do_fault;
617 }
618 ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
7e84c249 619 }
7e84c249 620
eaa728ee
FB
621 pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
622 env->a20_mask;
2c17449b 623 pde = ldq_phys(cs->as, pde_addr);
eaa728ee
FB
624 if (!(pde & PG_PRESENT_MASK)) {
625 error_code = 0;
626 goto do_fault;
627 }
628 if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
629 error_code = PG_ERROR_RSVD_MASK;
630 goto do_fault;
631 }
632 ptep &= pde ^ PG_NX_MASK;
633 if (pde & PG_PSE_MASK) {
634 /* 2 MB page */
635 page_size = 2048 * 1024;
636 ptep ^= PG_NX_MASK;
a9321a4d 637 if ((ptep & PG_NX_MASK) && is_write1 == 2) {
eaa728ee 638 goto do_fault_protect;
a9321a4d
PA
639 }
640 switch (mmu_idx) {
641 case MMU_USER_IDX:
642 if (!(ptep & PG_USER_MASK)) {
eaa728ee 643 goto do_fault_protect;
a9321a4d
PA
644 }
645 if (is_write && !(ptep & PG_RW_MASK)) {
eaa728ee 646 goto do_fault_protect;
a9321a4d
PA
647 }
648 break;
649
650 case MMU_KERNEL_IDX:
651 if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
652 (ptep & PG_USER_MASK)) {
653 goto do_fault_protect;
654 }
655 /* fall through */
656 case MMU_KSMAP_IDX:
657 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
658 (ptep & PG_USER_MASK)) {
659 goto do_fault_protect;
660 }
eaa728ee 661 if ((env->cr[0] & CR0_WP_MASK) &&
a9321a4d 662 is_write && !(ptep & PG_RW_MASK)) {
eaa728ee 663 goto do_fault_protect;
a9321a4d
PA
664 }
665 break;
666
667 default: /* cannot happen */
668 break;
eaa728ee
FB
669 }
670 is_dirty = is_write && !(pde & PG_DIRTY_MASK);
671 if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
672 pde |= PG_ACCESSED_MASK;
673 if (is_dirty)
674 pde |= PG_DIRTY_MASK;
2198a121 675 stl_phys_notdirty(cs->as, pde_addr, pde);
eaa728ee
FB
676 }
677 /* align to page_size */
678 pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
679 virt_addr = addr & ~(page_size - 1);
680 } else {
681 /* 4 KB page */
682 if (!(pde & PG_ACCESSED_MASK)) {
683 pde |= PG_ACCESSED_MASK;
2198a121 684 stl_phys_notdirty(cs->as, pde_addr, pde);
eaa728ee
FB
685 }
686 pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
687 env->a20_mask;
2c17449b 688 pte = ldq_phys(cs->as, pte_addr);
eaa728ee
FB
689 if (!(pte & PG_PRESENT_MASK)) {
690 error_code = 0;
691 goto do_fault;
692 }
693 if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
694 error_code = PG_ERROR_RSVD_MASK;
695 goto do_fault;
696 }
697 /* combine pde and pte nx, user and rw protections */
698 ptep &= pte ^ PG_NX_MASK;
699 ptep ^= PG_NX_MASK;
700 if ((ptep & PG_NX_MASK) && is_write1 == 2)
701 goto do_fault_protect;
a9321a4d
PA
702 switch (mmu_idx) {
703 case MMU_USER_IDX:
704 if (!(ptep & PG_USER_MASK)) {
eaa728ee 705 goto do_fault_protect;
a9321a4d
PA
706 }
707 if (is_write && !(ptep & PG_RW_MASK)) {
eaa728ee 708 goto do_fault_protect;
a9321a4d
PA
709 }
710 break;
711
712 case MMU_KERNEL_IDX:
713 if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
714 (ptep & PG_USER_MASK)) {
715 goto do_fault_protect;
716 }
717 /* fall through */
718 case MMU_KSMAP_IDX:
719 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
720 (ptep & PG_USER_MASK)) {
721 goto do_fault_protect;
722 }
eaa728ee 723 if ((env->cr[0] & CR0_WP_MASK) &&
a9321a4d 724 is_write && !(ptep & PG_RW_MASK)) {
eaa728ee 725 goto do_fault_protect;
a9321a4d
PA
726 }
727 break;
728
729 default: /* cannot happen */
730 break;
eaa728ee
FB
731 }
732 is_dirty = is_write && !(pte & PG_DIRTY_MASK);
733 if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
734 pte |= PG_ACCESSED_MASK;
735 if (is_dirty)
736 pte |= PG_DIRTY_MASK;
2198a121 737 stl_phys_notdirty(cs->as, pte_addr, pte);
eaa728ee
FB
738 }
739 page_size = 4096;
740 virt_addr = addr & ~0xfff;
741 pte = pte & (PHYS_ADDR_MASK | 0xfff);
7e84c249 742 }
2c0262af 743 } else {
eaa728ee
FB
744 uint32_t pde;
745
746 /* page directory entry */
747 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
748 env->a20_mask;
fdfba1a2 749 pde = ldl_phys(cs->as, pde_addr);
eaa728ee
FB
750 if (!(pde & PG_PRESENT_MASK)) {
751 error_code = 0;
752 goto do_fault;
753 }
754 /* if PSE bit is set, then we use a 4MB page */
755 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
756 page_size = 4096 * 1024;
a9321a4d
PA
757 switch (mmu_idx) {
758 case MMU_USER_IDX:
759 if (!(pde & PG_USER_MASK)) {
eaa728ee 760 goto do_fault_protect;
a9321a4d
PA
761 }
762 if (is_write && !(pde & PG_RW_MASK)) {
eaa728ee 763 goto do_fault_protect;
a9321a4d
PA
764 }
765 break;
766
767 case MMU_KERNEL_IDX:
768 if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
769 (pde & PG_USER_MASK)) {
770 goto do_fault_protect;
771 }
772 /* fall through */
773 case MMU_KSMAP_IDX:
774 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
775 (pde & PG_USER_MASK)) {
776 goto do_fault_protect;
777 }
eaa728ee 778 if ((env->cr[0] & CR0_WP_MASK) &&
a9321a4d 779 is_write && !(pde & PG_RW_MASK)) {
eaa728ee 780 goto do_fault_protect;
a9321a4d
PA
781 }
782 break;
783
784 default: /* cannot happen */
785 break;
eaa728ee
FB
786 }
787 is_dirty = is_write && !(pde & PG_DIRTY_MASK);
788 if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
789 pde |= PG_ACCESSED_MASK;
790 if (is_dirty)
791 pde |= PG_DIRTY_MASK;
2198a121 792 stl_phys_notdirty(cs->as, pde_addr, pde);
eaa728ee 793 }
2c0262af 794
eaa728ee
FB
795 pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
796 ptep = pte;
797 virt_addr = addr & ~(page_size - 1);
798 } else {
799 if (!(pde & PG_ACCESSED_MASK)) {
800 pde |= PG_ACCESSED_MASK;
2198a121 801 stl_phys_notdirty(cs->as, pde_addr, pde);
eaa728ee 802 }
891b38e4 803
eaa728ee
FB
804 /* page directory entry */
805 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
806 env->a20_mask;
fdfba1a2 807 pte = ldl_phys(cs->as, pte_addr);
eaa728ee
FB
808 if (!(pte & PG_PRESENT_MASK)) {
809 error_code = 0;
810 goto do_fault;
8e682019 811 }
eaa728ee
FB
812 /* combine pde and pte user and rw protections */
813 ptep = pte & pde;
a9321a4d
PA
814 switch (mmu_idx) {
815 case MMU_USER_IDX:
816 if (!(ptep & PG_USER_MASK)) {
eaa728ee 817 goto do_fault_protect;
a9321a4d
PA
818 }
819 if (is_write && !(ptep & PG_RW_MASK)) {
eaa728ee 820 goto do_fault_protect;
a9321a4d
PA
821 }
822 break;
823
824 case MMU_KERNEL_IDX:
825 if (is_write1 != 2 && (env->cr[4] & CR4_SMAP_MASK) &&
826 (ptep & PG_USER_MASK)) {
827 goto do_fault_protect;
828 }
829 /* fall through */
830 case MMU_KSMAP_IDX:
831 if (is_write1 == 2 && (env->cr[4] & CR4_SMEP_MASK) &&
832 (ptep & PG_USER_MASK)) {
833 goto do_fault_protect;
834 }
eaa728ee 835 if ((env->cr[0] & CR0_WP_MASK) &&
a9321a4d 836 is_write && !(ptep & PG_RW_MASK)) {
eaa728ee 837 goto do_fault_protect;
a9321a4d
PA
838 }
839 break;
840
841 default: /* cannot happen */
842 break;
8e682019 843 }
eaa728ee
FB
844 is_dirty = is_write && !(pte & PG_DIRTY_MASK);
845 if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
846 pte |= PG_ACCESSED_MASK;
847 if (is_dirty)
848 pte |= PG_DIRTY_MASK;
2198a121 849 stl_phys_notdirty(cs->as, pte_addr, pte);
eaa728ee
FB
850 }
851 page_size = 4096;
852 virt_addr = addr & ~0xfff;
2c0262af
FB
853 }
854 }
eaa728ee
FB
855 /* the page can be put in the TLB */
856 prot = PAGE_READ;
857 if (!(ptep & PG_NX_MASK))
858 prot |= PAGE_EXEC;
859 if (pte & PG_DIRTY_MASK) {
860 /* only set write access if already dirty... otherwise wait
861 for dirty access */
862 if (is_user) {
863 if (ptep & PG_RW_MASK)
864 prot |= PAGE_WRITE;
865 } else {
866 if (!(env->cr[0] & CR0_WP_MASK) ||
867 (ptep & PG_RW_MASK))
868 prot |= PAGE_WRITE;
8e682019 869 }
891b38e4 870 }
eaa728ee
FB
871 do_mapping:
872 pte = pte & env->a20_mask;
873
874 /* Even if 4MB pages, we map only one 4KB page in the cache to
875 avoid filling it too fast */
876 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
877 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
878 vaddr = virt_addr + page_offset;
879
0c591eb0 880 tlb_set_page(cs, vaddr, paddr, prot, mmu_idx, page_size);
d4c430a8 881 return 0;
eaa728ee
FB
882 do_fault_protect:
883 error_code = PG_ERROR_P_MASK;
884 do_fault:
885 error_code |= (is_write << PG_ERROR_W_BIT);
886 if (is_user)
887 error_code |= PG_ERROR_U_MASK;
888 if (is_write1 == 2 &&
a9321a4d
PA
889 (((env->efer & MSR_EFER_NXE) &&
890 (env->cr[4] & CR4_PAE_MASK)) ||
891 (env->cr[4] & CR4_SMEP_MASK)))
eaa728ee 892 error_code |= PG_ERROR_I_D_MASK;
872929aa
FB
893 if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
894 /* cr2 is not modified in case of exceptions */
f606604f
EI
895 stq_phys(cs->as,
896 env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
872929aa 897 addr);
eaa728ee
FB
898 } else {
899 env->cr[2] = addr;
2c0262af 900 }
eaa728ee 901 env->error_code = error_code;
27103424 902 cs->exception_index = EXCP0E_PAGE;
eaa728ee 903 return 1;
14ce26e7
FB
904}
905
00b941e5 906hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
14ce26e7 907{
00b941e5
AF
908 X86CPU *cpu = X86_CPU(cs);
909 CPUX86State *env = &cpu->env;
eaa728ee
FB
910 target_ulong pde_addr, pte_addr;
911 uint64_t pte;
a8170e5e 912 hwaddr paddr;
eaa728ee
FB
913 uint32_t page_offset;
914 int page_size;
14ce26e7 915
f2f8560c
PB
916 if (!(env->cr[0] & CR0_PG_MASK)) {
917 pte = addr & env->a20_mask;
918 page_size = 4096;
919 } else if (env->cr[4] & CR4_PAE_MASK) {
eaa728ee
FB
920 target_ulong pdpe_addr;
921 uint64_t pde, pdpe;
14ce26e7 922
eaa728ee
FB
923#ifdef TARGET_X86_64
924 if (env->hflags & HF_LMA_MASK) {
925 uint64_t pml4e_addr, pml4e;
926 int32_t sext;
927
928 /* test virtual address sign extension */
929 sext = (int64_t)addr >> 47;
930 if (sext != 0 && sext != -1)
931 return -1;
932
933 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
934 env->a20_mask;
2c17449b 935 pml4e = ldq_phys(cs->as, pml4e_addr);
eaa728ee
FB
936 if (!(pml4e & PG_PRESENT_MASK))
937 return -1;
938
3f2cbf0d
JK
939 pdpe_addr = ((pml4e & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
940 (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
2c17449b 941 pdpe = ldq_phys(cs->as, pdpe_addr);
eaa728ee
FB
942 if (!(pdpe & PG_PRESENT_MASK))
943 return -1;
c8c14bcb
LC
944
945 if (pdpe & PG_PSE_MASK) {
946 page_size = 1024 * 1024 * 1024;
947 pte = pdpe & ~( (page_size - 1) & ~0xfff);
948 pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
949 goto out;
950 }
951
eaa728ee
FB
952 } else
953#endif
954 {
955 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
956 env->a20_mask;
2c17449b 957 pdpe = ldq_phys(cs->as, pdpe_addr);
eaa728ee
FB
958 if (!(pdpe & PG_PRESENT_MASK))
959 return -1;
14ce26e7 960 }
14ce26e7 961
3f2cbf0d
JK
962 pde_addr = ((pdpe & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
963 (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
2c17449b 964 pde = ldq_phys(cs->as, pde_addr);
eaa728ee
FB
965 if (!(pde & PG_PRESENT_MASK)) {
966 return -1;
967 }
968 if (pde & PG_PSE_MASK) {
969 /* 2 MB page */
970 page_size = 2048 * 1024;
971 pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
972 } else {
973 /* 4 KB page */
3f2cbf0d
JK
974 pte_addr = ((pde & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
975 (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
eaa728ee 976 page_size = 4096;
2c17449b 977 pte = ldq_phys(cs->as, pte_addr);
eaa728ee 978 }
3f2cbf0d 979 pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
ca1c9e15
AL
980 if (!(pte & PG_PRESENT_MASK))
981 return -1;
14ce26e7 982 } else {
eaa728ee 983 uint32_t pde;
3b46e624 984
f2f8560c
PB
985 /* page directory entry */
986 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
fdfba1a2 987 pde = ldl_phys(cs->as, pde_addr);
f2f8560c
PB
988 if (!(pde & PG_PRESENT_MASK))
989 return -1;
990 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
991 pte = pde & ~0x003ff000; /* align to 4MB */
992 page_size = 4096 * 1024;
eaa728ee
FB
993 } else {
994 /* page directory entry */
f2f8560c 995 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
fdfba1a2 996 pte = ldl_phys(cs->as, pte_addr);
f2f8560c 997 if (!(pte & PG_PRESENT_MASK))
eaa728ee 998 return -1;
f2f8560c 999 page_size = 4096;
eaa728ee
FB
1000 }
1001 pte = pte & env->a20_mask;
14ce26e7 1002 }
14ce26e7 1003
c8c14bcb
LC
1004#ifdef TARGET_X86_64
1005out:
1006#endif
eaa728ee
FB
1007 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1008 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1009 return paddr;
3b21e03e 1010}
01df040b 1011
317ac620 1012void hw_breakpoint_insert(CPUX86State *env, int index)
01df040b 1013{
75a34036 1014 CPUState *cs = CPU(x86_env_get_cpu(env));
1cc21a18 1015 int type = 0, err = 0;
01df040b
AL
1016
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)) {
b3310ab3 1020 err = cpu_breakpoint_insert(cs, env->dr[index], BP_CPU,
01df040b 1021 &env->cpu_breakpoint[index]);
5902564a 1022 }
01df040b 1023 break;
428065ce 1024 case DR7_TYPE_DATA_WR:
01df040b 1025 type = BP_CPU | BP_MEM_WRITE;
1cc21a18 1026 break;
428065ce 1027 case DR7_TYPE_IO_RW:
1cc21a18 1028 /* No support for I/O watchpoints yet */
01df040b 1029 break;
428065ce 1030 case DR7_TYPE_DATA_RW:
01df040b 1031 type = BP_CPU | BP_MEM_ACCESS;
1cc21a18
LG
1032 break;
1033 }
1034
1035 if (type != 0) {
75a34036 1036 err = cpu_watchpoint_insert(cs, env->dr[index],
01df040b
AL
1037 hw_breakpoint_len(env->dr[7], index),
1038 type, &env->cpu_watchpoint[index]);
01df040b 1039 }
1cc21a18
LG
1040
1041 if (err) {
01df040b 1042 env->cpu_breakpoint[index] = NULL;
1cc21a18 1043 }
01df040b
AL
1044}
1045
317ac620 1046void hw_breakpoint_remove(CPUX86State *env, int index)
01df040b 1047{
75a34036
AF
1048 CPUState *cs;
1049
1050 if (!env->cpu_breakpoint[index]) {
01df040b 1051 return;
75a34036
AF
1052 }
1053 cs = CPU(x86_env_get_cpu(env));
01df040b 1054 switch (hw_breakpoint_type(env->dr[7], index)) {
428065ce 1055 case DR7_TYPE_BP_INST:
5902564a 1056 if (hw_breakpoint_enabled(env->dr[7], index)) {
b3310ab3 1057 cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]);
5902564a 1058 }
01df040b 1059 break;
428065ce
LG
1060 case DR7_TYPE_DATA_WR:
1061 case DR7_TYPE_DATA_RW:
75a34036 1062 cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]);
01df040b 1063 break;
428065ce 1064 case DR7_TYPE_IO_RW:
01df040b
AL
1065 /* No support for I/O watchpoints yet */
1066 break;
1067 }
1068}
1069
e175bce5 1070bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
01df040b
AL
1071{
1072 target_ulong dr6;
e175bce5
LG
1073 int reg;
1074 bool hit_enabled = false;
01df040b
AL
1075
1076 dr6 = env->dr[6] & ~0xf;
428065ce 1077 for (reg = 0; reg < DR7_MAX_BP; reg++) {
e175bce5
LG
1078 bool bp_match = false;
1079 bool wp_match = false;
1080
1081 switch (hw_breakpoint_type(env->dr[7], reg)) {
1082 case DR7_TYPE_BP_INST:
1083 if (env->dr[reg] == env->eip) {
1084 bp_match = true;
1085 }
1086 break;
1087 case DR7_TYPE_DATA_WR:
1088 case DR7_TYPE_DATA_RW:
1089 if (env->cpu_watchpoint[reg] &&
1090 env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT) {
1091 wp_match = true;
1092 }
1093 break;
1094 case DR7_TYPE_IO_RW:
1095 break;
1096 }
1097 if (bp_match || wp_match) {
01df040b 1098 dr6 |= 1 << reg;
5902564a 1099 if (hw_breakpoint_enabled(env->dr[7], reg)) {
e175bce5 1100 hit_enabled = true;
5902564a 1101 }
01df040b
AL
1102 }
1103 }
e175bce5
LG
1104
1105 if (hit_enabled || force_dr6_update) {
01df040b 1106 env->dr[6] = dr6;
e175bce5
LG
1107 }
1108
01df040b
AL
1109 return hit_enabled;
1110}
1111
d65e9815 1112void breakpoint_handler(CPUX86State *env)
01df040b 1113{
ff4700b0 1114 CPUState *cs = CPU(x86_env_get_cpu(env));
01df040b
AL
1115 CPUBreakpoint *bp;
1116
ff4700b0
AF
1117 if (cs->watchpoint_hit) {
1118 if (cs->watchpoint_hit->flags & BP_CPU) {
1119 cs->watchpoint_hit = NULL;
e175bce5 1120 if (check_hw_breakpoints(env, false)) {
77b2bc2c 1121 raise_exception(env, EXCP01_DB);
e175bce5 1122 } else {
0ea8cb88 1123 cpu_resume_from_signal(cs, NULL);
e175bce5 1124 }
01df040b
AL
1125 }
1126 } else {
f0c3c505 1127 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
01df040b
AL
1128 if (bp->pc == env->eip) {
1129 if (bp->flags & BP_CPU) {
e175bce5 1130 check_hw_breakpoints(env, true);
77b2bc2c 1131 raise_exception(env, EXCP01_DB);
01df040b
AL
1132 }
1133 break;
1134 }
f0c3c505 1135 }
01df040b 1136 }
01df040b 1137}
79c4f6b0 1138
d5bfda33
JK
1139typedef struct MCEInjectionParams {
1140 Monitor *mon;
55e5c285 1141 X86CPU *cpu;
d5bfda33
JK
1142 int bank;
1143 uint64_t status;
1144 uint64_t mcg_status;
1145 uint64_t addr;
1146 uint64_t misc;
1147 int flags;
1148} MCEInjectionParams;
1149
1150static void do_inject_x86_mce(void *data)
79c4f6b0 1151{
d5bfda33 1152 MCEInjectionParams *params = data;
55e5c285
AF
1153 CPUX86State *cenv = &params->cpu->env;
1154 CPUState *cpu = CPU(params->cpu);
d5bfda33
JK
1155 uint64_t *banks = cenv->mce_banks + 4 * params->bank;
1156
cb446eca 1157 cpu_synchronize_state(cpu);
316378e4 1158
747461c7
JK
1159 /*
1160 * If there is an MCE exception being processed, ignore this SRAO MCE
1161 * unless unconditional injection was requested.
1162 */
d5bfda33
JK
1163 if (!(params->flags & MCE_INJECT_UNCOND_AO)
1164 && !(params->status & MCI_STATUS_AR)
747461c7
JK
1165 && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1166 return;
1167 }
d5bfda33
JK
1168
1169 if (params->status & MCI_STATUS_UC) {
316378e4
JK
1170 /*
1171 * if MSR_MCG_CTL is not all 1s, the uncorrected error
1172 * reporting is disabled
1173 */
d5bfda33
JK
1174 if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1175 monitor_printf(params->mon,
316378e4 1176 "CPU %d: Uncorrected error reporting disabled\n",
55e5c285 1177 cpu->cpu_index);
316378e4
JK
1178 return;
1179 }
1180
1181 /*
1182 * if MSR_MCi_CTL is not all 1s, the uncorrected error
1183 * reporting is disabled for the bank
1184 */
1185 if (banks[0] != ~(uint64_t)0) {
d5bfda33
JK
1186 monitor_printf(params->mon,
1187 "CPU %d: Uncorrected error reporting disabled for"
1188 " bank %d\n",
55e5c285 1189 cpu->cpu_index, params->bank);
316378e4
JK
1190 return;
1191 }
1192
79c4f6b0
HY
1193 if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1194 !(cenv->cr[4] & CR4_MCE_MASK)) {
d5bfda33
JK
1195 monitor_printf(params->mon,
1196 "CPU %d: Previous MCE still in progress, raising"
1197 " triple fault\n",
55e5c285 1198 cpu->cpu_index);
79c4f6b0
HY
1199 qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1200 qemu_system_reset_request();
1201 return;
1202 }
2fa11da0 1203 if (banks[1] & MCI_STATUS_VAL) {
d5bfda33 1204 params->status |= MCI_STATUS_OVER;
2fa11da0 1205 }
d5bfda33
JK
1206 banks[2] = params->addr;
1207 banks[3] = params->misc;
1208 cenv->mcg_status = params->mcg_status;
1209 banks[1] = params->status;
c3affe56 1210 cpu_interrupt(cpu, CPU_INTERRUPT_MCE);
79c4f6b0
HY
1211 } else if (!(banks[1] & MCI_STATUS_VAL)
1212 || !(banks[1] & MCI_STATUS_UC)) {
2fa11da0 1213 if (banks[1] & MCI_STATUS_VAL) {
d5bfda33 1214 params->status |= MCI_STATUS_OVER;
2fa11da0 1215 }
d5bfda33
JK
1216 banks[2] = params->addr;
1217 banks[3] = params->misc;
1218 banks[1] = params->status;
2fa11da0 1219 } else {
79c4f6b0 1220 banks[1] |= MCI_STATUS_OVER;
2fa11da0 1221 }
79c4f6b0 1222}
b3cd24e0 1223
8c5cf3b6 1224void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
316378e4 1225 uint64_t status, uint64_t mcg_status, uint64_t addr,
747461c7 1226 uint64_t misc, int flags)
b3cd24e0 1227{
182735ef 1228 CPUState *cs = CPU(cpu);
8c5cf3b6 1229 CPUX86State *cenv = &cpu->env;
d5bfda33
JK
1230 MCEInjectionParams params = {
1231 .mon = mon,
55e5c285 1232 .cpu = cpu,
d5bfda33
JK
1233 .bank = bank,
1234 .status = status,
1235 .mcg_status = mcg_status,
1236 .addr = addr,
1237 .misc = misc,
1238 .flags = flags,
1239 };
b3cd24e0
JD
1240 unsigned bank_num = cenv->mcg_cap & 0xff;
1241
316378e4
JK
1242 if (!cenv->mcg_cap) {
1243 monitor_printf(mon, "MCE injection not supported\n");
b3cd24e0
JD
1244 return;
1245 }
316378e4
JK
1246 if (bank >= bank_num) {
1247 monitor_printf(mon, "Invalid MCE bank number\n");
1248 return;
1249 }
1250 if (!(status & MCI_STATUS_VAL)) {
1251 monitor_printf(mon, "Invalid MCE status code\n");
1252 return;
1253 }
747461c7
JK
1254 if ((flags & MCE_INJECT_BROADCAST)
1255 && !cpu_x86_support_mca_broadcast(cenv)) {
316378e4
JK
1256 monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
1257 return;
2bd3e04c
JD
1258 }
1259
182735ef 1260 run_on_cpu(cs, do_inject_x86_mce, &params);
c34d440a 1261 if (flags & MCE_INJECT_BROADCAST) {
182735ef
AF
1262 CPUState *other_cs;
1263
c34d440a
JK
1264 params.bank = 1;
1265 params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
1266 params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
1267 params.addr = 0;
1268 params.misc = 0;
bdc44640 1269 CPU_FOREACH(other_cs) {
182735ef 1270 if (other_cs == cs) {
c34d440a 1271 continue;
31ce5e0c 1272 }
182735ef
AF
1273 params.cpu = X86_CPU(other_cs);
1274 run_on_cpu(other_cs, do_inject_x86_mce, &params);
31ce5e0c 1275 }
b3cd24e0
JD
1276 }
1277}
d362e757 1278
317ac620 1279void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
d362e757 1280{
02e51483 1281 X86CPU *cpu = x86_env_get_cpu(env);
93afeade 1282 CPUState *cs = CPU(cpu);
02e51483 1283
d362e757
JK
1284 if (kvm_enabled()) {
1285 env->tpr_access_type = access;
1286
93afeade 1287 cpu_interrupt(cs, CPU_INTERRUPT_TPR);
d362e757 1288 } else {
3f38f309 1289 cpu_restore_state(cs, cs->mem_io_pc);
d362e757 1290
02e51483 1291 apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
d362e757
JK
1292 }
1293}
74ce674f 1294#endif /* !CONFIG_USER_ONLY */
6fd805e1 1295
84273177
JK
1296int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1297 target_ulong *base, unsigned int *limit,
1298 unsigned int *flags)
1299{
f17ec444
AF
1300 X86CPU *cpu = x86_env_get_cpu(env);
1301 CPUState *cs = CPU(cpu);
84273177
JK
1302 SegmentCache *dt;
1303 target_ulong ptr;
1304 uint32_t e1, e2;
1305 int index;
1306
1307 if (selector & 0x4)
1308 dt = &env->ldt;
1309 else
1310 dt = &env->gdt;
1311 index = selector & ~7;
1312 ptr = dt->base + index;
1313 if ((index + 7) > dt->limit
f17ec444
AF
1314 || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1315 || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
84273177
JK
1316 return 0;
1317
1318 *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1319 *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1320 if (e2 & DESC_G_MASK)
1321 *limit = (*limit << 12) | 0xfff;
1322 *flags = e2;
1323
1324 return 1;
1325}
1326
b09ea7d5 1327#if !defined(CONFIG_USER_ONLY)
232fc23b 1328void do_cpu_init(X86CPU *cpu)
b09ea7d5 1329{
259186a7 1330 CPUState *cs = CPU(cpu);
232fc23b 1331 CPUX86State *env = &cpu->env;
259186a7 1332 int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
ebda377f
JK
1333 uint64_t pat = env->pat;
1334
259186a7
AF
1335 cpu_reset(cs);
1336 cs->interrupt_request = sipi;
ebda377f 1337 env->pat = pat;
02e51483 1338 apic_init_reset(cpu->apic_state);
b09ea7d5
GN
1339}
1340
232fc23b 1341void do_cpu_sipi(X86CPU *cpu)
b09ea7d5 1342{
02e51483 1343 apic_sipi(cpu->apic_state);
b09ea7d5
GN
1344}
1345#else
232fc23b 1346void do_cpu_init(X86CPU *cpu)
b09ea7d5
GN
1347{
1348}
232fc23b 1349void do_cpu_sipi(X86CPU *cpu)
b09ea7d5
GN
1350{
1351}
1352#endif
This page took 1.104531 seconds and 4 git commands to generate.