Expose whether a mouse is an absolute device via QMP and the human monitor.
[qemu/aliguori-queue.git] / target-i386 / helper.c
blob35ab72090a49c7bb0b5d1b538350593adc5c37ec
1 /*
2 * i386 helpers (without register variable usage)
4 * Copyright (c) 2003 Fabrice Bellard
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.
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.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include <stdarg.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <inttypes.h>
24 #include <signal.h>
26 #include "cpu.h"
27 #include "exec-all.h"
28 #include "qemu-common.h"
29 #include "kvm.h"
31 //#define DEBUG_MMU
33 /* NOTE: must be called outside the CPU execute loop */
34 void cpu_reset(CPUX86State *env)
36 int i;
38 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
39 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
40 log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
43 memset(env, 0, offsetof(CPUX86State, breakpoints));
45 tlb_flush(env, 1);
47 env->old_exception = -1;
49 /* init to reset state */
51 #ifdef CONFIG_SOFTMMU
52 env->hflags |= HF_SOFTMMU_MASK;
53 #endif
54 env->hflags2 |= HF2_GIF_MASK;
56 cpu_x86_update_cr0(env, 0x60000010);
57 env->a20_mask = ~0x0;
58 env->smbase = 0x30000;
60 env->idt.limit = 0xffff;
61 env->gdt.limit = 0xffff;
62 env->ldt.limit = 0xffff;
63 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
64 env->tr.limit = 0xffff;
65 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
67 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
68 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
69 DESC_R_MASK | DESC_A_MASK);
70 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
71 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
72 DESC_A_MASK);
73 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
74 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
75 DESC_A_MASK);
76 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
77 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
78 DESC_A_MASK);
79 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
80 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
81 DESC_A_MASK);
82 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
83 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
84 DESC_A_MASK);
86 env->eip = 0xfff0;
87 env->regs[R_EDX] = env->cpuid_version;
89 env->eflags = 0x2;
91 /* FPU init */
92 for(i = 0;i < 8; i++)
93 env->fptags[i] = 1;
94 env->fpuc = 0x37f;
96 env->mxcsr = 0x1f80;
98 memset(env->dr, 0, sizeof(env->dr));
99 env->dr[6] = DR6_FIXED_1;
100 env->dr[7] = DR7_FIXED_1;
101 cpu_breakpoint_remove_all(env, BP_CPU);
102 cpu_watchpoint_remove_all(env, BP_CPU);
104 env->mcg_status = 0;
107 void cpu_x86_close(CPUX86State *env)
109 qemu_free(env);
112 /***********************************************************/
113 /* x86 debug */
115 static const char *cc_op_str[] = {
116 "DYNAMIC",
117 "EFLAGS",
119 "MULB",
120 "MULW",
121 "MULL",
122 "MULQ",
124 "ADDB",
125 "ADDW",
126 "ADDL",
127 "ADDQ",
129 "ADCB",
130 "ADCW",
131 "ADCL",
132 "ADCQ",
134 "SUBB",
135 "SUBW",
136 "SUBL",
137 "SUBQ",
139 "SBBB",
140 "SBBW",
141 "SBBL",
142 "SBBQ",
144 "LOGICB",
145 "LOGICW",
146 "LOGICL",
147 "LOGICQ",
149 "INCB",
150 "INCW",
151 "INCL",
152 "INCQ",
154 "DECB",
155 "DECW",
156 "DECL",
157 "DECQ",
159 "SHLB",
160 "SHLW",
161 "SHLL",
162 "SHLQ",
164 "SARB",
165 "SARW",
166 "SARL",
167 "SARQ",
170 static void
171 cpu_x86_dump_seg_cache(CPUState *env, FILE *f,
172 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
173 const char *name, struct SegmentCache *sc)
175 #ifdef TARGET_X86_64
176 if (env->hflags & HF_CS64_MASK) {
177 cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
178 sc->selector, sc->base, sc->limit, sc->flags);
179 } else
180 #endif
182 cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
183 (uint32_t)sc->base, sc->limit, sc->flags);
186 if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
187 goto done;
189 cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
190 if (sc->flags & DESC_S_MASK) {
191 if (sc->flags & DESC_CS_MASK) {
192 cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
193 ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
194 cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
195 (sc->flags & DESC_R_MASK) ? 'R' : '-');
196 } else {
197 cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS " : "DS16");
198 cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
199 (sc->flags & DESC_W_MASK) ? 'W' : '-');
201 cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
202 } else {
203 static const char *sys_type_name[2][16] = {
204 { /* 32 bit mode */
205 "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
206 "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
207 "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
208 "CallGate32", "Reserved", "IntGate32", "TrapGate32"
210 { /* 64 bit mode */
211 "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
212 "Reserved", "Reserved", "Reserved", "Reserved",
213 "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
214 "Reserved", "IntGate64", "TrapGate64"
217 cpu_fprintf(f, sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
218 [(sc->flags & DESC_TYPE_MASK)
219 >> DESC_TYPE_SHIFT]);
221 done:
222 cpu_fprintf(f, "\n");
225 void cpu_dump_state(CPUState *env, FILE *f,
226 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
227 int flags)
229 int eflags, i, nb;
230 char cc_op_name[32];
231 static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
233 cpu_synchronize_state(env);
235 eflags = env->eflags;
236 #ifdef TARGET_X86_64
237 if (env->hflags & HF_CS64_MASK) {
238 cpu_fprintf(f,
239 "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
240 "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
241 "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
242 "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
243 "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
244 env->regs[R_EAX],
245 env->regs[R_EBX],
246 env->regs[R_ECX],
247 env->regs[R_EDX],
248 env->regs[R_ESI],
249 env->regs[R_EDI],
250 env->regs[R_EBP],
251 env->regs[R_ESP],
252 env->regs[8],
253 env->regs[9],
254 env->regs[10],
255 env->regs[11],
256 env->regs[12],
257 env->regs[13],
258 env->regs[14],
259 env->regs[15],
260 env->eip, eflags,
261 eflags & DF_MASK ? 'D' : '-',
262 eflags & CC_O ? 'O' : '-',
263 eflags & CC_S ? 'S' : '-',
264 eflags & CC_Z ? 'Z' : '-',
265 eflags & CC_A ? 'A' : '-',
266 eflags & CC_P ? 'P' : '-',
267 eflags & CC_C ? 'C' : '-',
268 env->hflags & HF_CPL_MASK,
269 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
270 (env->a20_mask >> 20) & 1,
271 (env->hflags >> HF_SMM_SHIFT) & 1,
272 env->halted);
273 } else
274 #endif
276 cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
277 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
278 "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
279 (uint32_t)env->regs[R_EAX],
280 (uint32_t)env->regs[R_EBX],
281 (uint32_t)env->regs[R_ECX],
282 (uint32_t)env->regs[R_EDX],
283 (uint32_t)env->regs[R_ESI],
284 (uint32_t)env->regs[R_EDI],
285 (uint32_t)env->regs[R_EBP],
286 (uint32_t)env->regs[R_ESP],
287 (uint32_t)env->eip, eflags,
288 eflags & DF_MASK ? 'D' : '-',
289 eflags & CC_O ? 'O' : '-',
290 eflags & CC_S ? 'S' : '-',
291 eflags & CC_Z ? 'Z' : '-',
292 eflags & CC_A ? 'A' : '-',
293 eflags & CC_P ? 'P' : '-',
294 eflags & CC_C ? 'C' : '-',
295 env->hflags & HF_CPL_MASK,
296 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
297 (env->a20_mask >> 20) & 1,
298 (env->hflags >> HF_SMM_SHIFT) & 1,
299 env->halted);
302 for(i = 0; i < 6; i++) {
303 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
304 &env->segs[i]);
306 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
307 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
309 #ifdef TARGET_X86_64
310 if (env->hflags & HF_LMA_MASK) {
311 cpu_fprintf(f, "GDT= %016" PRIx64 " %08x\n",
312 env->gdt.base, env->gdt.limit);
313 cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
314 env->idt.base, env->idt.limit);
315 cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
316 (uint32_t)env->cr[0],
317 env->cr[2],
318 env->cr[3],
319 (uint32_t)env->cr[4]);
320 for(i = 0; i < 4; i++)
321 cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
322 cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
323 env->dr[6], env->dr[7]);
324 } else
325 #endif
327 cpu_fprintf(f, "GDT= %08x %08x\n",
328 (uint32_t)env->gdt.base, env->gdt.limit);
329 cpu_fprintf(f, "IDT= %08x %08x\n",
330 (uint32_t)env->idt.base, env->idt.limit);
331 cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
332 (uint32_t)env->cr[0],
333 (uint32_t)env->cr[2],
334 (uint32_t)env->cr[3],
335 (uint32_t)env->cr[4]);
336 for(i = 0; i < 4; i++)
337 cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]);
338 cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]);
340 if (flags & X86_DUMP_CCOP) {
341 if ((unsigned)env->cc_op < CC_OP_NB)
342 snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
343 else
344 snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
345 #ifdef TARGET_X86_64
346 if (env->hflags & HF_CS64_MASK) {
347 cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
348 env->cc_src, env->cc_dst,
349 cc_op_name);
350 } else
351 #endif
353 cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
354 (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
355 cc_op_name);
358 if (flags & X86_DUMP_FPU) {
359 int fptag;
360 fptag = 0;
361 for(i = 0; i < 8; i++) {
362 fptag |= ((!env->fptags[i]) << i);
364 cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
365 env->fpuc,
366 (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
367 env->fpstt,
368 fptag,
369 env->mxcsr);
370 for(i=0;i<8;i++) {
371 #if defined(USE_X86LDOUBLE)
372 union {
373 long double d;
374 struct {
375 uint64_t lower;
376 uint16_t upper;
377 } l;
378 } tmp;
379 tmp.d = env->fpregs[i].d;
380 cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
381 i, tmp.l.lower, tmp.l.upper);
382 #else
383 cpu_fprintf(f, "FPR%d=%016" PRIx64,
384 i, env->fpregs[i].mmx.q);
385 #endif
386 if ((i & 1) == 1)
387 cpu_fprintf(f, "\n");
388 else
389 cpu_fprintf(f, " ");
391 if (env->hflags & HF_CS64_MASK)
392 nb = 16;
393 else
394 nb = 8;
395 for(i=0;i<nb;i++) {
396 cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
398 env->xmm_regs[i].XMM_L(3),
399 env->xmm_regs[i].XMM_L(2),
400 env->xmm_regs[i].XMM_L(1),
401 env->xmm_regs[i].XMM_L(0));
402 if ((i & 1) == 1)
403 cpu_fprintf(f, "\n");
404 else
405 cpu_fprintf(f, " ");
410 /***********************************************************/
411 /* x86 mmu */
412 /* XXX: add PGE support */
414 void cpu_x86_set_a20(CPUX86State *env, int a20_state)
416 a20_state = (a20_state != 0);
417 if (a20_state != ((env->a20_mask >> 20) & 1)) {
418 #if defined(DEBUG_MMU)
419 printf("A20 update: a20=%d\n", a20_state);
420 #endif
421 /* if the cpu is currently executing code, we must unlink it and
422 all the potentially executing TB */
423 cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
425 /* when a20 is changed, all the MMU mappings are invalid, so
426 we must flush everything */
427 tlb_flush(env, 1);
428 env->a20_mask = ~(1 << 20) | (a20_state << 20);
432 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
434 int pe_state;
436 #if defined(DEBUG_MMU)
437 printf("CR0 update: CR0=0x%08x\n", new_cr0);
438 #endif
439 if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
440 (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
441 tlb_flush(env, 1);
444 #ifdef TARGET_X86_64
445 if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
446 (env->efer & MSR_EFER_LME)) {
447 /* enter in long mode */
448 /* XXX: generate an exception */
449 if (!(env->cr[4] & CR4_PAE_MASK))
450 return;
451 env->efer |= MSR_EFER_LMA;
452 env->hflags |= HF_LMA_MASK;
453 } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
454 (env->efer & MSR_EFER_LMA)) {
455 /* exit long mode */
456 env->efer &= ~MSR_EFER_LMA;
457 env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
458 env->eip &= 0xffffffff;
460 #endif
461 env->cr[0] = new_cr0 | CR0_ET_MASK;
463 /* update PE flag in hidden flags */
464 pe_state = (env->cr[0] & CR0_PE_MASK);
465 env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
466 /* ensure that ADDSEG is always set in real mode */
467 env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
468 /* update FPU flags */
469 env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
470 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
473 /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
474 the PDPT */
475 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
477 env->cr[3] = new_cr3;
478 if (env->cr[0] & CR0_PG_MASK) {
479 #if defined(DEBUG_MMU)
480 printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
481 #endif
482 tlb_flush(env, 0);
486 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
488 #if defined(DEBUG_MMU)
489 printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
490 #endif
491 if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
492 (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
493 tlb_flush(env, 1);
495 /* SSE handling */
496 if (!(env->cpuid_features & CPUID_SSE))
497 new_cr4 &= ~CR4_OSFXSR_MASK;
498 if (new_cr4 & CR4_OSFXSR_MASK)
499 env->hflags |= HF_OSFXSR_MASK;
500 else
501 env->hflags &= ~HF_OSFXSR_MASK;
503 env->cr[4] = new_cr4;
506 #if defined(CONFIG_USER_ONLY)
508 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
509 int is_write, int mmu_idx, int is_softmmu)
511 /* user mode only emulation */
512 is_write &= 1;
513 env->cr[2] = addr;
514 env->error_code = (is_write << PG_ERROR_W_BIT);
515 env->error_code |= PG_ERROR_U_MASK;
516 env->exception_index = EXCP0E_PAGE;
517 return 1;
520 #else
522 /* XXX: This value should match the one returned by CPUID
523 * and in exec.c */
524 # if defined(TARGET_X86_64)
525 # define PHYS_ADDR_MASK 0xfffffff000LL
526 # else
527 # define PHYS_ADDR_MASK 0xffffff000LL
528 # endif
530 /* return value:
531 -1 = cannot handle fault
532 0 = nothing more to do
533 1 = generate PF fault
535 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
536 int is_write1, int mmu_idx, int is_softmmu)
538 uint64_t ptep, pte;
539 target_ulong pde_addr, pte_addr;
540 int error_code, is_dirty, prot, page_size, is_write, is_user;
541 target_phys_addr_t paddr;
542 uint32_t page_offset;
543 target_ulong vaddr, virt_addr;
545 is_user = mmu_idx == MMU_USER_IDX;
546 #if defined(DEBUG_MMU)
547 printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
548 addr, is_write1, is_user, env->eip);
549 #endif
550 is_write = is_write1 & 1;
552 if (!(env->cr[0] & CR0_PG_MASK)) {
553 pte = addr;
554 virt_addr = addr & TARGET_PAGE_MASK;
555 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
556 page_size = 4096;
557 goto do_mapping;
560 if (env->cr[4] & CR4_PAE_MASK) {
561 uint64_t pde, pdpe;
562 target_ulong pdpe_addr;
564 #ifdef TARGET_X86_64
565 if (env->hflags & HF_LMA_MASK) {
566 uint64_t pml4e_addr, pml4e;
567 int32_t sext;
569 /* test virtual address sign extension */
570 sext = (int64_t)addr >> 47;
571 if (sext != 0 && sext != -1) {
572 env->error_code = 0;
573 env->exception_index = EXCP0D_GPF;
574 return 1;
577 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
578 env->a20_mask;
579 pml4e = ldq_phys(pml4e_addr);
580 if (!(pml4e & PG_PRESENT_MASK)) {
581 error_code = 0;
582 goto do_fault;
584 if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
585 error_code = PG_ERROR_RSVD_MASK;
586 goto do_fault;
588 if (!(pml4e & PG_ACCESSED_MASK)) {
589 pml4e |= PG_ACCESSED_MASK;
590 stl_phys_notdirty(pml4e_addr, pml4e);
592 ptep = pml4e ^ PG_NX_MASK;
593 pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
594 env->a20_mask;
595 pdpe = ldq_phys(pdpe_addr);
596 if (!(pdpe & PG_PRESENT_MASK)) {
597 error_code = 0;
598 goto do_fault;
600 if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
601 error_code = PG_ERROR_RSVD_MASK;
602 goto do_fault;
604 ptep &= pdpe ^ PG_NX_MASK;
605 if (!(pdpe & PG_ACCESSED_MASK)) {
606 pdpe |= PG_ACCESSED_MASK;
607 stl_phys_notdirty(pdpe_addr, pdpe);
609 } else
610 #endif
612 /* XXX: load them when cr3 is loaded ? */
613 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
614 env->a20_mask;
615 pdpe = ldq_phys(pdpe_addr);
616 if (!(pdpe & PG_PRESENT_MASK)) {
617 error_code = 0;
618 goto do_fault;
620 ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
623 pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
624 env->a20_mask;
625 pde = ldq_phys(pde_addr);
626 if (!(pde & PG_PRESENT_MASK)) {
627 error_code = 0;
628 goto do_fault;
630 if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
631 error_code = PG_ERROR_RSVD_MASK;
632 goto do_fault;
634 ptep &= pde ^ PG_NX_MASK;
635 if (pde & PG_PSE_MASK) {
636 /* 2 MB page */
637 page_size = 2048 * 1024;
638 ptep ^= PG_NX_MASK;
639 if ((ptep & PG_NX_MASK) && is_write1 == 2)
640 goto do_fault_protect;
641 if (is_user) {
642 if (!(ptep & PG_USER_MASK))
643 goto do_fault_protect;
644 if (is_write && !(ptep & PG_RW_MASK))
645 goto do_fault_protect;
646 } else {
647 if ((env->cr[0] & CR0_WP_MASK) &&
648 is_write && !(ptep & PG_RW_MASK))
649 goto do_fault_protect;
651 is_dirty = is_write && !(pde & PG_DIRTY_MASK);
652 if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
653 pde |= PG_ACCESSED_MASK;
654 if (is_dirty)
655 pde |= PG_DIRTY_MASK;
656 stl_phys_notdirty(pde_addr, pde);
658 /* align to page_size */
659 pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
660 virt_addr = addr & ~(page_size - 1);
661 } else {
662 /* 4 KB page */
663 if (!(pde & PG_ACCESSED_MASK)) {
664 pde |= PG_ACCESSED_MASK;
665 stl_phys_notdirty(pde_addr, pde);
667 pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
668 env->a20_mask;
669 pte = ldq_phys(pte_addr);
670 if (!(pte & PG_PRESENT_MASK)) {
671 error_code = 0;
672 goto do_fault;
674 if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
675 error_code = PG_ERROR_RSVD_MASK;
676 goto do_fault;
678 /* combine pde and pte nx, user and rw protections */
679 ptep &= pte ^ PG_NX_MASK;
680 ptep ^= PG_NX_MASK;
681 if ((ptep & PG_NX_MASK) && is_write1 == 2)
682 goto do_fault_protect;
683 if (is_user) {
684 if (!(ptep & PG_USER_MASK))
685 goto do_fault_protect;
686 if (is_write && !(ptep & PG_RW_MASK))
687 goto do_fault_protect;
688 } else {
689 if ((env->cr[0] & CR0_WP_MASK) &&
690 is_write && !(ptep & PG_RW_MASK))
691 goto do_fault_protect;
693 is_dirty = is_write && !(pte & PG_DIRTY_MASK);
694 if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
695 pte |= PG_ACCESSED_MASK;
696 if (is_dirty)
697 pte |= PG_DIRTY_MASK;
698 stl_phys_notdirty(pte_addr, pte);
700 page_size = 4096;
701 virt_addr = addr & ~0xfff;
702 pte = pte & (PHYS_ADDR_MASK | 0xfff);
704 } else {
705 uint32_t pde;
707 /* page directory entry */
708 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
709 env->a20_mask;
710 pde = ldl_phys(pde_addr);
711 if (!(pde & PG_PRESENT_MASK)) {
712 error_code = 0;
713 goto do_fault;
715 /* if PSE bit is set, then we use a 4MB page */
716 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
717 page_size = 4096 * 1024;
718 if (is_user) {
719 if (!(pde & PG_USER_MASK))
720 goto do_fault_protect;
721 if (is_write && !(pde & PG_RW_MASK))
722 goto do_fault_protect;
723 } else {
724 if ((env->cr[0] & CR0_WP_MASK) &&
725 is_write && !(pde & PG_RW_MASK))
726 goto do_fault_protect;
728 is_dirty = is_write && !(pde & PG_DIRTY_MASK);
729 if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
730 pde |= PG_ACCESSED_MASK;
731 if (is_dirty)
732 pde |= PG_DIRTY_MASK;
733 stl_phys_notdirty(pde_addr, pde);
736 pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
737 ptep = pte;
738 virt_addr = addr & ~(page_size - 1);
739 } else {
740 if (!(pde & PG_ACCESSED_MASK)) {
741 pde |= PG_ACCESSED_MASK;
742 stl_phys_notdirty(pde_addr, pde);
745 /* page directory entry */
746 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
747 env->a20_mask;
748 pte = ldl_phys(pte_addr);
749 if (!(pte & PG_PRESENT_MASK)) {
750 error_code = 0;
751 goto do_fault;
753 /* combine pde and pte user and rw protections */
754 ptep = pte & pde;
755 if (is_user) {
756 if (!(ptep & PG_USER_MASK))
757 goto do_fault_protect;
758 if (is_write && !(ptep & PG_RW_MASK))
759 goto do_fault_protect;
760 } else {
761 if ((env->cr[0] & CR0_WP_MASK) &&
762 is_write && !(ptep & PG_RW_MASK))
763 goto do_fault_protect;
765 is_dirty = is_write && !(pte & PG_DIRTY_MASK);
766 if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
767 pte |= PG_ACCESSED_MASK;
768 if (is_dirty)
769 pte |= PG_DIRTY_MASK;
770 stl_phys_notdirty(pte_addr, pte);
772 page_size = 4096;
773 virt_addr = addr & ~0xfff;
776 /* the page can be put in the TLB */
777 prot = PAGE_READ;
778 if (!(ptep & PG_NX_MASK))
779 prot |= PAGE_EXEC;
780 if (pte & PG_DIRTY_MASK) {
781 /* only set write access if already dirty... otherwise wait
782 for dirty access */
783 if (is_user) {
784 if (ptep & PG_RW_MASK)
785 prot |= PAGE_WRITE;
786 } else {
787 if (!(env->cr[0] & CR0_WP_MASK) ||
788 (ptep & PG_RW_MASK))
789 prot |= PAGE_WRITE;
792 do_mapping:
793 pte = pte & env->a20_mask;
795 /* Even if 4MB pages, we map only one 4KB page in the cache to
796 avoid filling it too fast */
797 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
798 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
799 vaddr = virt_addr + page_offset;
801 tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
802 return 0;
803 do_fault_protect:
804 error_code = PG_ERROR_P_MASK;
805 do_fault:
806 error_code |= (is_write << PG_ERROR_W_BIT);
807 if (is_user)
808 error_code |= PG_ERROR_U_MASK;
809 if (is_write1 == 2 &&
810 (env->efer & MSR_EFER_NXE) &&
811 (env->cr[4] & CR4_PAE_MASK))
812 error_code |= PG_ERROR_I_D_MASK;
813 if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
814 /* cr2 is not modified in case of exceptions */
815 stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
816 addr);
817 } else {
818 env->cr[2] = addr;
820 env->error_code = error_code;
821 env->exception_index = EXCP0E_PAGE;
822 return 1;
825 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
827 target_ulong pde_addr, pte_addr;
828 uint64_t pte;
829 target_phys_addr_t paddr;
830 uint32_t page_offset;
831 int page_size;
833 if (env->cr[4] & CR4_PAE_MASK) {
834 target_ulong pdpe_addr;
835 uint64_t pde, pdpe;
837 #ifdef TARGET_X86_64
838 if (env->hflags & HF_LMA_MASK) {
839 uint64_t pml4e_addr, pml4e;
840 int32_t sext;
842 /* test virtual address sign extension */
843 sext = (int64_t)addr >> 47;
844 if (sext != 0 && sext != -1)
845 return -1;
847 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
848 env->a20_mask;
849 pml4e = ldq_phys(pml4e_addr);
850 if (!(pml4e & PG_PRESENT_MASK))
851 return -1;
853 pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
854 env->a20_mask;
855 pdpe = ldq_phys(pdpe_addr);
856 if (!(pdpe & PG_PRESENT_MASK))
857 return -1;
858 } else
859 #endif
861 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
862 env->a20_mask;
863 pdpe = ldq_phys(pdpe_addr);
864 if (!(pdpe & PG_PRESENT_MASK))
865 return -1;
868 pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
869 env->a20_mask;
870 pde = ldq_phys(pde_addr);
871 if (!(pde & PG_PRESENT_MASK)) {
872 return -1;
874 if (pde & PG_PSE_MASK) {
875 /* 2 MB page */
876 page_size = 2048 * 1024;
877 pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
878 } else {
879 /* 4 KB page */
880 pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
881 env->a20_mask;
882 page_size = 4096;
883 pte = ldq_phys(pte_addr);
885 if (!(pte & PG_PRESENT_MASK))
886 return -1;
887 } else {
888 uint32_t pde;
890 if (!(env->cr[0] & CR0_PG_MASK)) {
891 pte = addr;
892 page_size = 4096;
893 } else {
894 /* page directory entry */
895 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
896 pde = ldl_phys(pde_addr);
897 if (!(pde & PG_PRESENT_MASK))
898 return -1;
899 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
900 pte = pde & ~0x003ff000; /* align to 4MB */
901 page_size = 4096 * 1024;
902 } else {
903 /* page directory entry */
904 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
905 pte = ldl_phys(pte_addr);
906 if (!(pte & PG_PRESENT_MASK))
907 return -1;
908 page_size = 4096;
911 pte = pte & env->a20_mask;
914 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
915 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
916 return paddr;
919 void hw_breakpoint_insert(CPUState *env, int index)
921 int type, err = 0;
923 switch (hw_breakpoint_type(env->dr[7], index)) {
924 case 0:
925 if (hw_breakpoint_enabled(env->dr[7], index))
926 err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
927 &env->cpu_breakpoint[index]);
928 break;
929 case 1:
930 type = BP_CPU | BP_MEM_WRITE;
931 goto insert_wp;
932 case 2:
933 /* No support for I/O watchpoints yet */
934 break;
935 case 3:
936 type = BP_CPU | BP_MEM_ACCESS;
937 insert_wp:
938 err = cpu_watchpoint_insert(env, env->dr[index],
939 hw_breakpoint_len(env->dr[7], index),
940 type, &env->cpu_watchpoint[index]);
941 break;
943 if (err)
944 env->cpu_breakpoint[index] = NULL;
947 void hw_breakpoint_remove(CPUState *env, int index)
949 if (!env->cpu_breakpoint[index])
950 return;
951 switch (hw_breakpoint_type(env->dr[7], index)) {
952 case 0:
953 if (hw_breakpoint_enabled(env->dr[7], index))
954 cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
955 break;
956 case 1:
957 case 3:
958 cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
959 break;
960 case 2:
961 /* No support for I/O watchpoints yet */
962 break;
966 int check_hw_breakpoints(CPUState *env, int force_dr6_update)
968 target_ulong dr6;
969 int reg, type;
970 int hit_enabled = 0;
972 dr6 = env->dr[6] & ~0xf;
973 for (reg = 0; reg < 4; reg++) {
974 type = hw_breakpoint_type(env->dr[7], reg);
975 if ((type == 0 && env->dr[reg] == env->eip) ||
976 ((type & 1) && env->cpu_watchpoint[reg] &&
977 (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
978 dr6 |= 1 << reg;
979 if (hw_breakpoint_enabled(env->dr[7], reg))
980 hit_enabled = 1;
983 if (hit_enabled || force_dr6_update)
984 env->dr[6] = dr6;
985 return hit_enabled;
988 static CPUDebugExcpHandler *prev_debug_excp_handler;
990 void raise_exception_env(int exception_index, CPUState *env);
992 static void breakpoint_handler(CPUState *env)
994 CPUBreakpoint *bp;
996 if (env->watchpoint_hit) {
997 if (env->watchpoint_hit->flags & BP_CPU) {
998 env->watchpoint_hit = NULL;
999 if (check_hw_breakpoints(env, 0))
1000 raise_exception_env(EXCP01_DB, env);
1001 else
1002 cpu_resume_from_signal(env, NULL);
1004 } else {
1005 QTAILQ_FOREACH(bp, &env->breakpoints, entry)
1006 if (bp->pc == env->eip) {
1007 if (bp->flags & BP_CPU) {
1008 check_hw_breakpoints(env, 1);
1009 raise_exception_env(EXCP01_DB, env);
1011 break;
1014 if (prev_debug_excp_handler)
1015 prev_debug_excp_handler(env);
1018 /* This should come from sysemu.h - if we could include it here... */
1019 void qemu_system_reset_request(void);
1021 void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
1022 uint64_t mcg_status, uint64_t addr, uint64_t misc)
1024 uint64_t mcg_cap = cenv->mcg_cap;
1025 unsigned bank_num = mcg_cap & 0xff;
1026 uint64_t *banks = cenv->mce_banks;
1028 if (bank >= bank_num || !(status & MCI_STATUS_VAL))
1029 return;
1032 * if MSR_MCG_CTL is not all 1s, the uncorrected error
1033 * reporting is disabled
1035 if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
1036 cenv->mcg_ctl != ~(uint64_t)0)
1037 return;
1038 banks += 4 * bank;
1040 * if MSR_MCi_CTL is not all 1s, the uncorrected error
1041 * reporting is disabled for the bank
1043 if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0)
1044 return;
1045 if (status & MCI_STATUS_UC) {
1046 if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1047 !(cenv->cr[4] & CR4_MCE_MASK)) {
1048 fprintf(stderr, "injects mce exception while previous "
1049 "one is in progress!\n");
1050 qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1051 qemu_system_reset_request();
1052 return;
1054 if (banks[1] & MCI_STATUS_VAL)
1055 status |= MCI_STATUS_OVER;
1056 banks[2] = addr;
1057 banks[3] = misc;
1058 cenv->mcg_status = mcg_status;
1059 banks[1] = status;
1060 cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
1061 } else if (!(banks[1] & MCI_STATUS_VAL)
1062 || !(banks[1] & MCI_STATUS_UC)) {
1063 if (banks[1] & MCI_STATUS_VAL)
1064 status |= MCI_STATUS_OVER;
1065 banks[2] = addr;
1066 banks[3] = misc;
1067 banks[1] = status;
1068 } else
1069 banks[1] |= MCI_STATUS_OVER;
1071 #endif /* !CONFIG_USER_ONLY */
1073 static void mce_init(CPUX86State *cenv)
1075 unsigned int bank, bank_num;
1077 if (((cenv->cpuid_version >> 8)&0xf) >= 6
1078 && (cenv->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)) {
1079 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1080 cenv->mcg_ctl = ~(uint64_t)0;
1081 bank_num = MCE_BANKS_DEF;
1082 for (bank = 0; bank < bank_num; bank++)
1083 cenv->mce_banks[bank*4] = ~(uint64_t)0;
1087 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1088 target_ulong *base, unsigned int *limit,
1089 unsigned int *flags)
1091 SegmentCache *dt;
1092 target_ulong ptr;
1093 uint32_t e1, e2;
1094 int index;
1096 if (selector & 0x4)
1097 dt = &env->ldt;
1098 else
1099 dt = &env->gdt;
1100 index = selector & ~7;
1101 ptr = dt->base + index;
1102 if ((index + 7) > dt->limit
1103 || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1104 || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1105 return 0;
1107 *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1108 *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1109 if (e2 & DESC_G_MASK)
1110 *limit = (*limit << 12) | 0xfff;
1111 *flags = e2;
1113 return 1;
1116 CPUX86State *cpu_x86_init(const char *cpu_model)
1118 CPUX86State *env;
1119 static int inited;
1121 env = qemu_mallocz(sizeof(CPUX86State));
1122 cpu_exec_init(env);
1123 env->cpu_model_str = cpu_model;
1125 /* init various static tables */
1126 if (!inited) {
1127 inited = 1;
1128 optimize_flags_init();
1129 #ifndef CONFIG_USER_ONLY
1130 prev_debug_excp_handler =
1131 cpu_set_debug_excp_handler(breakpoint_handler);
1132 #endif
1134 if (cpu_x86_register(env, cpu_model) < 0) {
1135 cpu_x86_close(env);
1136 return NULL;
1138 mce_init(env);
1140 qemu_init_vcpu(env);
1142 return env;
1145 #if !defined(CONFIG_USER_ONLY)
1146 void do_cpu_init(CPUState *env)
1148 int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
1149 cpu_reset(env);
1150 env->interrupt_request = sipi;
1151 apic_init_reset(env);
1154 void do_cpu_sipi(CPUState *env)
1156 apic_sipi(env);
1158 #else
1159 void do_cpu_init(CPUState *env)
1162 void do_cpu_sipi(CPUState *env)
1165 #endif