docs: Add QED image format specification
[qemu-kvm/stefanha.git] / target-i386 / helper.c
blobd765cc6f24ef75960fdf3883255a97a42fe78150
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"
30 #include "kvm_x86.h"
32 #include "qemu-kvm.h"
34 //#define DEBUG_MMU
36 /* NOTE: must be called outside the CPU execute loop */
37 void cpu_reset(CPUX86State *env)
39 int i;
41 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
42 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
43 log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
46 memset(env, 0, offsetof(CPUX86State, breakpoints));
48 tlb_flush(env, 1);
50 env->old_exception = -1;
52 /* init to reset state */
54 #ifdef CONFIG_SOFTMMU
55 env->hflags |= HF_SOFTMMU_MASK;
56 #endif
57 env->hflags2 |= HF2_GIF_MASK;
59 cpu_x86_update_cr0(env, 0x60000010);
60 env->a20_mask = ~0x0;
61 env->smbase = 0x30000;
63 env->idt.limit = 0xffff;
64 env->gdt.limit = 0xffff;
65 env->ldt.limit = 0xffff;
66 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
67 env->tr.limit = 0xffff;
68 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
70 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
71 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
72 DESC_R_MASK | DESC_A_MASK);
73 cpu_x86_load_seg_cache(env, R_DS, 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_ES, 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_SS, 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_FS, 0, 0, 0xffff,
83 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
84 DESC_A_MASK);
85 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
86 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
87 DESC_A_MASK);
89 env->eip = 0xfff0;
90 env->regs[R_EDX] = env->cpuid_version;
92 env->eflags = 0x2;
94 /* FPU init */
95 for(i = 0;i < 8; i++)
96 env->fptags[i] = 1;
97 env->fpuc = 0x37f;
99 env->mxcsr = 0x1f80;
101 memset(env->dr, 0, sizeof(env->dr));
102 env->dr[6] = DR6_FIXED_1;
103 env->dr[7] = DR7_FIXED_1;
104 cpu_breakpoint_remove_all(env, BP_CPU);
105 cpu_watchpoint_remove_all(env, BP_CPU);
107 env->mcg_status = 0;
110 void cpu_x86_close(CPUX86State *env)
112 qemu_free(env);
115 /***********************************************************/
116 /* x86 debug */
118 static const char *cc_op_str[] = {
119 "DYNAMIC",
120 "EFLAGS",
122 "MULB",
123 "MULW",
124 "MULL",
125 "MULQ",
127 "ADDB",
128 "ADDW",
129 "ADDL",
130 "ADDQ",
132 "ADCB",
133 "ADCW",
134 "ADCL",
135 "ADCQ",
137 "SUBB",
138 "SUBW",
139 "SUBL",
140 "SUBQ",
142 "SBBB",
143 "SBBW",
144 "SBBL",
145 "SBBQ",
147 "LOGICB",
148 "LOGICW",
149 "LOGICL",
150 "LOGICQ",
152 "INCB",
153 "INCW",
154 "INCL",
155 "INCQ",
157 "DECB",
158 "DECW",
159 "DECL",
160 "DECQ",
162 "SHLB",
163 "SHLW",
164 "SHLL",
165 "SHLQ",
167 "SARB",
168 "SARW",
169 "SARL",
170 "SARQ",
173 static void
174 cpu_x86_dump_seg_cache(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
175 const char *name, struct SegmentCache *sc)
177 #ifdef TARGET_X86_64
178 if (env->hflags & HF_CS64_MASK) {
179 cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
180 sc->selector, sc->base, sc->limit, sc->flags);
181 } else
182 #endif
184 cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
185 (uint32_t)sc->base, sc->limit, sc->flags);
188 if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
189 goto done;
191 cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
192 if (sc->flags & DESC_S_MASK) {
193 if (sc->flags & DESC_CS_MASK) {
194 cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
195 ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
196 cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
197 (sc->flags & DESC_R_MASK) ? 'R' : '-');
198 } else {
199 cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS " : "DS16");
200 cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
201 (sc->flags & DESC_W_MASK) ? 'W' : '-');
203 cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
204 } else {
205 static const char *sys_type_name[2][16] = {
206 { /* 32 bit mode */
207 "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
208 "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
209 "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
210 "CallGate32", "Reserved", "IntGate32", "TrapGate32"
212 { /* 64 bit mode */
213 "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
214 "Reserved", "Reserved", "Reserved", "Reserved",
215 "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
216 "Reserved", "IntGate64", "TrapGate64"
219 cpu_fprintf(f, "%s",
220 sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
221 [(sc->flags & DESC_TYPE_MASK)
222 >> DESC_TYPE_SHIFT]);
224 done:
225 cpu_fprintf(f, "\n");
228 void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
229 int flags)
231 int eflags, i, nb;
232 char cc_op_name[32];
233 static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
235 cpu_synchronize_state(env);
237 eflags = env->eflags;
238 #ifdef TARGET_X86_64
239 if (env->hflags & HF_CS64_MASK) {
240 cpu_fprintf(f,
241 "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
242 "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
243 "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
244 "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
245 "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
246 env->regs[R_EAX],
247 env->regs[R_EBX],
248 env->regs[R_ECX],
249 env->regs[R_EDX],
250 env->regs[R_ESI],
251 env->regs[R_EDI],
252 env->regs[R_EBP],
253 env->regs[R_ESP],
254 env->regs[8],
255 env->regs[9],
256 env->regs[10],
257 env->regs[11],
258 env->regs[12],
259 env->regs[13],
260 env->regs[14],
261 env->regs[15],
262 env->eip, eflags,
263 eflags & DF_MASK ? 'D' : '-',
264 eflags & CC_O ? 'O' : '-',
265 eflags & CC_S ? 'S' : '-',
266 eflags & CC_Z ? 'Z' : '-',
267 eflags & CC_A ? 'A' : '-',
268 eflags & CC_P ? 'P' : '-',
269 eflags & CC_C ? 'C' : '-',
270 env->hflags & HF_CPL_MASK,
271 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
272 (env->a20_mask >> 20) & 1,
273 (env->hflags >> HF_SMM_SHIFT) & 1,
274 env->halted);
275 } else
276 #endif
278 cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
279 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
280 "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
281 (uint32_t)env->regs[R_EAX],
282 (uint32_t)env->regs[R_EBX],
283 (uint32_t)env->regs[R_ECX],
284 (uint32_t)env->regs[R_EDX],
285 (uint32_t)env->regs[R_ESI],
286 (uint32_t)env->regs[R_EDI],
287 (uint32_t)env->regs[R_EBP],
288 (uint32_t)env->regs[R_ESP],
289 (uint32_t)env->eip, eflags,
290 eflags & DF_MASK ? 'D' : '-',
291 eflags & CC_O ? 'O' : '-',
292 eflags & CC_S ? 'S' : '-',
293 eflags & CC_Z ? 'Z' : '-',
294 eflags & CC_A ? 'A' : '-',
295 eflags & CC_P ? 'P' : '-',
296 eflags & CC_C ? 'C' : '-',
297 env->hflags & HF_CPL_MASK,
298 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
299 (env->a20_mask >> 20) & 1,
300 (env->hflags >> HF_SMM_SHIFT) & 1,
301 env->halted);
304 for(i = 0; i < 6; i++) {
305 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
306 &env->segs[i]);
308 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
309 cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
311 #ifdef TARGET_X86_64
312 if (env->hflags & HF_LMA_MASK) {
313 cpu_fprintf(f, "GDT= %016" PRIx64 " %08x\n",
314 env->gdt.base, env->gdt.limit);
315 cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
316 env->idt.base, env->idt.limit);
317 cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
318 (uint32_t)env->cr[0],
319 env->cr[2],
320 env->cr[3],
321 (uint32_t)env->cr[4]);
322 for(i = 0; i < 4; i++)
323 cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
324 cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
325 env->dr[6], env->dr[7]);
326 } else
327 #endif
329 cpu_fprintf(f, "GDT= %08x %08x\n",
330 (uint32_t)env->gdt.base, env->gdt.limit);
331 cpu_fprintf(f, "IDT= %08x %08x\n",
332 (uint32_t)env->idt.base, env->idt.limit);
333 cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
334 (uint32_t)env->cr[0],
335 (uint32_t)env->cr[2],
336 (uint32_t)env->cr[3],
337 (uint32_t)env->cr[4]);
338 for(i = 0; i < 4; i++) {
339 cpu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
341 cpu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
342 env->dr[6], env->dr[7]);
344 if (flags & X86_DUMP_CCOP) {
345 if ((unsigned)env->cc_op < CC_OP_NB)
346 snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
347 else
348 snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
349 #ifdef TARGET_X86_64
350 if (env->hflags & HF_CS64_MASK) {
351 cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
352 env->cc_src, env->cc_dst,
353 cc_op_name);
354 } else
355 #endif
357 cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
358 (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
359 cc_op_name);
362 cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
363 if (flags & X86_DUMP_FPU) {
364 int fptag;
365 fptag = 0;
366 for(i = 0; i < 8; i++) {
367 fptag |= ((!env->fptags[i]) << i);
369 cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
370 env->fpuc,
371 (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
372 env->fpstt,
373 fptag,
374 env->mxcsr);
375 for(i=0;i<8;i++) {
376 #if defined(USE_X86LDOUBLE)
377 union {
378 long double d;
379 struct {
380 uint64_t lower;
381 uint16_t upper;
382 } l;
383 } tmp;
384 tmp.d = env->fpregs[i].d;
385 cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
386 i, tmp.l.lower, tmp.l.upper);
387 #else
388 cpu_fprintf(f, "FPR%d=%016" PRIx64,
389 i, env->fpregs[i].mmx.q);
390 #endif
391 if ((i & 1) == 1)
392 cpu_fprintf(f, "\n");
393 else
394 cpu_fprintf(f, " ");
396 if (env->hflags & HF_CS64_MASK)
397 nb = 16;
398 else
399 nb = 8;
400 for(i=0;i<nb;i++) {
401 cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
403 env->xmm_regs[i].XMM_L(3),
404 env->xmm_regs[i].XMM_L(2),
405 env->xmm_regs[i].XMM_L(1),
406 env->xmm_regs[i].XMM_L(0));
407 if ((i & 1) == 1)
408 cpu_fprintf(f, "\n");
409 else
410 cpu_fprintf(f, " ");
415 /***********************************************************/
416 /* x86 mmu */
417 /* XXX: add PGE support */
419 void cpu_x86_set_a20(CPUX86State *env, int a20_state)
421 a20_state = (a20_state != 0);
422 if (a20_state != ((env->a20_mask >> 20) & 1)) {
423 #if defined(DEBUG_MMU)
424 printf("A20 update: a20=%d\n", a20_state);
425 #endif
426 /* if the cpu is currently executing code, we must unlink it and
427 all the potentially executing TB */
428 cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
430 /* when a20 is changed, all the MMU mappings are invalid, so
431 we must flush everything */
432 tlb_flush(env, 1);
433 env->a20_mask = ~(1 << 20) | (a20_state << 20);
437 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
439 int pe_state;
441 #if defined(DEBUG_MMU)
442 printf("CR0 update: CR0=0x%08x\n", new_cr0);
443 #endif
444 if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
445 (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
446 tlb_flush(env, 1);
449 #ifdef TARGET_X86_64
450 if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
451 (env->efer & MSR_EFER_LME)) {
452 /* enter in long mode */
453 /* XXX: generate an exception */
454 if (!(env->cr[4] & CR4_PAE_MASK))
455 return;
456 env->efer |= MSR_EFER_LMA;
457 env->hflags |= HF_LMA_MASK;
458 } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
459 (env->efer & MSR_EFER_LMA)) {
460 /* exit long mode */
461 env->efer &= ~MSR_EFER_LMA;
462 env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
463 env->eip &= 0xffffffff;
465 #endif
466 env->cr[0] = new_cr0 | CR0_ET_MASK;
468 /* update PE flag in hidden flags */
469 pe_state = (env->cr[0] & CR0_PE_MASK);
470 env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
471 /* ensure that ADDSEG is always set in real mode */
472 env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
473 /* update FPU flags */
474 env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
475 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
478 /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
479 the PDPT */
480 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
482 env->cr[3] = new_cr3;
483 if (env->cr[0] & CR0_PG_MASK) {
484 #if defined(DEBUG_MMU)
485 printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
486 #endif
487 tlb_flush(env, 0);
491 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
493 #if defined(DEBUG_MMU)
494 printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
495 #endif
496 if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
497 (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
498 tlb_flush(env, 1);
500 /* SSE handling */
501 if (!(env->cpuid_features & CPUID_SSE))
502 new_cr4 &= ~CR4_OSFXSR_MASK;
503 if (new_cr4 & CR4_OSFXSR_MASK)
504 env->hflags |= HF_OSFXSR_MASK;
505 else
506 env->hflags &= ~HF_OSFXSR_MASK;
508 env->cr[4] = new_cr4;
511 #if defined(CONFIG_USER_ONLY)
513 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
514 int is_write, int mmu_idx, int is_softmmu)
516 /* user mode only emulation */
517 is_write &= 1;
518 env->cr[2] = addr;
519 env->error_code = (is_write << PG_ERROR_W_BIT);
520 env->error_code |= PG_ERROR_U_MASK;
521 env->exception_index = EXCP0E_PAGE;
522 return 1;
525 #else
527 /* XXX: This value should match the one returned by CPUID
528 * and in exec.c */
529 # if defined(TARGET_X86_64)
530 # define PHYS_ADDR_MASK 0xfffffff000LL
531 # else
532 # define PHYS_ADDR_MASK 0xffffff000LL
533 # endif
535 /* return value:
536 -1 = cannot handle fault
537 0 = nothing more to do
538 1 = generate PF fault
540 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
541 int is_write1, int mmu_idx, int is_softmmu)
543 uint64_t ptep, pte;
544 target_ulong pde_addr, pte_addr;
545 int error_code, is_dirty, prot, page_size, is_write, is_user;
546 target_phys_addr_t paddr;
547 uint32_t page_offset;
548 target_ulong vaddr, virt_addr;
550 is_user = mmu_idx == MMU_USER_IDX;
551 #if defined(DEBUG_MMU)
552 printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
553 addr, is_write1, is_user, env->eip);
554 #endif
555 is_write = is_write1 & 1;
557 if (!(env->cr[0] & CR0_PG_MASK)) {
558 pte = addr;
559 virt_addr = addr & TARGET_PAGE_MASK;
560 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
561 page_size = 4096;
562 goto do_mapping;
565 if (env->cr[4] & CR4_PAE_MASK) {
566 uint64_t pde, pdpe;
567 target_ulong pdpe_addr;
569 #ifdef TARGET_X86_64
570 if (env->hflags & HF_LMA_MASK) {
571 uint64_t pml4e_addr, pml4e;
572 int32_t sext;
574 /* test virtual address sign extension */
575 sext = (int64_t)addr >> 47;
576 if (sext != 0 && sext != -1) {
577 env->error_code = 0;
578 env->exception_index = EXCP0D_GPF;
579 return 1;
582 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
583 env->a20_mask;
584 pml4e = ldq_phys(pml4e_addr);
585 if (!(pml4e & PG_PRESENT_MASK)) {
586 error_code = 0;
587 goto do_fault;
589 if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
590 error_code = PG_ERROR_RSVD_MASK;
591 goto do_fault;
593 if (!(pml4e & PG_ACCESSED_MASK)) {
594 pml4e |= PG_ACCESSED_MASK;
595 stl_phys_notdirty(pml4e_addr, pml4e);
597 ptep = pml4e ^ PG_NX_MASK;
598 pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
599 env->a20_mask;
600 pdpe = ldq_phys(pdpe_addr);
601 if (!(pdpe & PG_PRESENT_MASK)) {
602 error_code = 0;
603 goto do_fault;
605 if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
606 error_code = PG_ERROR_RSVD_MASK;
607 goto do_fault;
609 ptep &= pdpe ^ PG_NX_MASK;
610 if (!(pdpe & PG_ACCESSED_MASK)) {
611 pdpe |= PG_ACCESSED_MASK;
612 stl_phys_notdirty(pdpe_addr, pdpe);
614 } else
615 #endif
617 /* XXX: load them when cr3 is loaded ? */
618 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
619 env->a20_mask;
620 pdpe = ldq_phys(pdpe_addr);
621 if (!(pdpe & PG_PRESENT_MASK)) {
622 error_code = 0;
623 goto do_fault;
625 ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
628 pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
629 env->a20_mask;
630 pde = ldq_phys(pde_addr);
631 if (!(pde & PG_PRESENT_MASK)) {
632 error_code = 0;
633 goto do_fault;
635 if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
636 error_code = PG_ERROR_RSVD_MASK;
637 goto do_fault;
639 ptep &= pde ^ PG_NX_MASK;
640 if (pde & PG_PSE_MASK) {
641 /* 2 MB page */
642 page_size = 2048 * 1024;
643 ptep ^= PG_NX_MASK;
644 if ((ptep & PG_NX_MASK) && is_write1 == 2)
645 goto do_fault_protect;
646 if (is_user) {
647 if (!(ptep & PG_USER_MASK))
648 goto do_fault_protect;
649 if (is_write && !(ptep & PG_RW_MASK))
650 goto do_fault_protect;
651 } else {
652 if ((env->cr[0] & CR0_WP_MASK) &&
653 is_write && !(ptep & PG_RW_MASK))
654 goto do_fault_protect;
656 is_dirty = is_write && !(pde & PG_DIRTY_MASK);
657 if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
658 pde |= PG_ACCESSED_MASK;
659 if (is_dirty)
660 pde |= PG_DIRTY_MASK;
661 stl_phys_notdirty(pde_addr, pde);
663 /* align to page_size */
664 pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
665 virt_addr = addr & ~(page_size - 1);
666 } else {
667 /* 4 KB page */
668 if (!(pde & PG_ACCESSED_MASK)) {
669 pde |= PG_ACCESSED_MASK;
670 stl_phys_notdirty(pde_addr, pde);
672 pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
673 env->a20_mask;
674 pte = ldq_phys(pte_addr);
675 if (!(pte & PG_PRESENT_MASK)) {
676 error_code = 0;
677 goto do_fault;
679 if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
680 error_code = PG_ERROR_RSVD_MASK;
681 goto do_fault;
683 /* combine pde and pte nx, user and rw protections */
684 ptep &= pte ^ PG_NX_MASK;
685 ptep ^= PG_NX_MASK;
686 if ((ptep & PG_NX_MASK) && is_write1 == 2)
687 goto do_fault_protect;
688 if (is_user) {
689 if (!(ptep & PG_USER_MASK))
690 goto do_fault_protect;
691 if (is_write && !(ptep & PG_RW_MASK))
692 goto do_fault_protect;
693 } else {
694 if ((env->cr[0] & CR0_WP_MASK) &&
695 is_write && !(ptep & PG_RW_MASK))
696 goto do_fault_protect;
698 is_dirty = is_write && !(pte & PG_DIRTY_MASK);
699 if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
700 pte |= PG_ACCESSED_MASK;
701 if (is_dirty)
702 pte |= PG_DIRTY_MASK;
703 stl_phys_notdirty(pte_addr, pte);
705 page_size = 4096;
706 virt_addr = addr & ~0xfff;
707 pte = pte & (PHYS_ADDR_MASK | 0xfff);
709 } else {
710 uint32_t pde;
712 /* page directory entry */
713 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
714 env->a20_mask;
715 pde = ldl_phys(pde_addr);
716 if (!(pde & PG_PRESENT_MASK)) {
717 error_code = 0;
718 goto do_fault;
720 /* if PSE bit is set, then we use a 4MB page */
721 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
722 page_size = 4096 * 1024;
723 if (is_user) {
724 if (!(pde & PG_USER_MASK))
725 goto do_fault_protect;
726 if (is_write && !(pde & PG_RW_MASK))
727 goto do_fault_protect;
728 } else {
729 if ((env->cr[0] & CR0_WP_MASK) &&
730 is_write && !(pde & PG_RW_MASK))
731 goto do_fault_protect;
733 is_dirty = is_write && !(pde & PG_DIRTY_MASK);
734 if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
735 pde |= PG_ACCESSED_MASK;
736 if (is_dirty)
737 pde |= PG_DIRTY_MASK;
738 stl_phys_notdirty(pde_addr, pde);
741 pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
742 ptep = pte;
743 virt_addr = addr & ~(page_size - 1);
744 } else {
745 if (!(pde & PG_ACCESSED_MASK)) {
746 pde |= PG_ACCESSED_MASK;
747 stl_phys_notdirty(pde_addr, pde);
750 /* page directory entry */
751 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
752 env->a20_mask;
753 pte = ldl_phys(pte_addr);
754 if (!(pte & PG_PRESENT_MASK)) {
755 error_code = 0;
756 goto do_fault;
758 /* combine pde and pte user and rw protections */
759 ptep = pte & pde;
760 if (is_user) {
761 if (!(ptep & PG_USER_MASK))
762 goto do_fault_protect;
763 if (is_write && !(ptep & PG_RW_MASK))
764 goto do_fault_protect;
765 } else {
766 if ((env->cr[0] & CR0_WP_MASK) &&
767 is_write && !(ptep & PG_RW_MASK))
768 goto do_fault_protect;
770 is_dirty = is_write && !(pte & PG_DIRTY_MASK);
771 if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
772 pte |= PG_ACCESSED_MASK;
773 if (is_dirty)
774 pte |= PG_DIRTY_MASK;
775 stl_phys_notdirty(pte_addr, pte);
777 page_size = 4096;
778 virt_addr = addr & ~0xfff;
781 /* the page can be put in the TLB */
782 prot = PAGE_READ;
783 if (!(ptep & PG_NX_MASK))
784 prot |= PAGE_EXEC;
785 if (pte & PG_DIRTY_MASK) {
786 /* only set write access if already dirty... otherwise wait
787 for dirty access */
788 if (is_user) {
789 if (ptep & PG_RW_MASK)
790 prot |= PAGE_WRITE;
791 } else {
792 if (!(env->cr[0] & CR0_WP_MASK) ||
793 (ptep & PG_RW_MASK))
794 prot |= PAGE_WRITE;
797 do_mapping:
798 pte = pte & env->a20_mask;
800 /* Even if 4MB pages, we map only one 4KB page in the cache to
801 avoid filling it too fast */
802 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
803 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
804 vaddr = virt_addr + page_offset;
806 tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
807 return 0;
808 do_fault_protect:
809 error_code = PG_ERROR_P_MASK;
810 do_fault:
811 error_code |= (is_write << PG_ERROR_W_BIT);
812 if (is_user)
813 error_code |= PG_ERROR_U_MASK;
814 if (is_write1 == 2 &&
815 (env->efer & MSR_EFER_NXE) &&
816 (env->cr[4] & CR4_PAE_MASK))
817 error_code |= PG_ERROR_I_D_MASK;
818 if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
819 /* cr2 is not modified in case of exceptions */
820 stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
821 addr);
822 } else {
823 env->cr[2] = addr;
825 env->error_code = error_code;
826 env->exception_index = EXCP0E_PAGE;
827 return 1;
830 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
832 target_ulong pde_addr, pte_addr;
833 uint64_t pte;
834 target_phys_addr_t paddr;
835 uint32_t page_offset;
836 int page_size;
838 if (env->cr[4] & CR4_PAE_MASK) {
839 target_ulong pdpe_addr;
840 uint64_t pde, pdpe;
842 #ifdef TARGET_X86_64
843 if (env->hflags & HF_LMA_MASK) {
844 uint64_t pml4e_addr, pml4e;
845 int32_t sext;
847 /* test virtual address sign extension */
848 sext = (int64_t)addr >> 47;
849 if (sext != 0 && sext != -1)
850 return -1;
852 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
853 env->a20_mask;
854 pml4e = ldq_phys(pml4e_addr);
855 if (!(pml4e & PG_PRESENT_MASK))
856 return -1;
858 pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
859 env->a20_mask;
860 pdpe = ldq_phys(pdpe_addr);
861 if (!(pdpe & PG_PRESENT_MASK))
862 return -1;
863 } else
864 #endif
866 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
867 env->a20_mask;
868 pdpe = ldq_phys(pdpe_addr);
869 if (!(pdpe & PG_PRESENT_MASK))
870 return -1;
873 pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
874 env->a20_mask;
875 pde = ldq_phys(pde_addr);
876 if (!(pde & PG_PRESENT_MASK)) {
877 return -1;
879 if (pde & PG_PSE_MASK) {
880 /* 2 MB page */
881 page_size = 2048 * 1024;
882 pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
883 } else {
884 /* 4 KB page */
885 pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
886 env->a20_mask;
887 page_size = 4096;
888 pte = ldq_phys(pte_addr);
890 if (!(pte & PG_PRESENT_MASK))
891 return -1;
892 } else {
893 uint32_t pde;
895 if (!(env->cr[0] & CR0_PG_MASK)) {
896 pte = addr;
897 page_size = 4096;
898 } else {
899 /* page directory entry */
900 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
901 pde = ldl_phys(pde_addr);
902 if (!(pde & PG_PRESENT_MASK))
903 return -1;
904 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
905 pte = pde & ~0x003ff000; /* align to 4MB */
906 page_size = 4096 * 1024;
907 } else {
908 /* page directory entry */
909 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
910 pte = ldl_phys(pte_addr);
911 if (!(pte & PG_PRESENT_MASK))
912 return -1;
913 page_size = 4096;
916 pte = pte & env->a20_mask;
919 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
920 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
921 return paddr;
924 void hw_breakpoint_insert(CPUState *env, int index)
926 int type, err = 0;
928 switch (hw_breakpoint_type(env->dr[7], index)) {
929 case 0:
930 if (hw_breakpoint_enabled(env->dr[7], index))
931 err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
932 &env->cpu_breakpoint[index]);
933 break;
934 case 1:
935 type = BP_CPU | BP_MEM_WRITE;
936 goto insert_wp;
937 case 2:
938 /* No support for I/O watchpoints yet */
939 break;
940 case 3:
941 type = BP_CPU | BP_MEM_ACCESS;
942 insert_wp:
943 err = cpu_watchpoint_insert(env, env->dr[index],
944 hw_breakpoint_len(env->dr[7], index),
945 type, &env->cpu_watchpoint[index]);
946 break;
948 if (err)
949 env->cpu_breakpoint[index] = NULL;
952 void hw_breakpoint_remove(CPUState *env, int index)
954 if (!env->cpu_breakpoint[index])
955 return;
956 switch (hw_breakpoint_type(env->dr[7], index)) {
957 case 0:
958 if (hw_breakpoint_enabled(env->dr[7], index))
959 cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
960 break;
961 case 1:
962 case 3:
963 cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
964 break;
965 case 2:
966 /* No support for I/O watchpoints yet */
967 break;
971 int check_hw_breakpoints(CPUState *env, int force_dr6_update)
973 target_ulong dr6;
974 int reg, type;
975 int hit_enabled = 0;
977 dr6 = env->dr[6] & ~0xf;
978 for (reg = 0; reg < 4; reg++) {
979 type = hw_breakpoint_type(env->dr[7], reg);
980 if ((type == 0 && env->dr[reg] == env->eip) ||
981 ((type & 1) && env->cpu_watchpoint[reg] &&
982 (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
983 dr6 |= 1 << reg;
984 if (hw_breakpoint_enabled(env->dr[7], reg))
985 hit_enabled = 1;
988 if (hit_enabled || force_dr6_update)
989 env->dr[6] = dr6;
990 return hit_enabled;
993 static CPUDebugExcpHandler *prev_debug_excp_handler;
995 void raise_exception_env(int exception_index, CPUState *env);
997 static void breakpoint_handler(CPUState *env)
999 CPUBreakpoint *bp;
1001 if (env->watchpoint_hit) {
1002 if (env->watchpoint_hit->flags & BP_CPU) {
1003 env->watchpoint_hit = NULL;
1004 if (check_hw_breakpoints(env, 0))
1005 raise_exception_env(EXCP01_DB, env);
1006 else
1007 cpu_resume_from_signal(env, NULL);
1009 } else {
1010 QTAILQ_FOREACH(bp, &env->breakpoints, entry)
1011 if (bp->pc == env->eip) {
1012 if (bp->flags & BP_CPU) {
1013 check_hw_breakpoints(env, 1);
1014 raise_exception_env(EXCP01_DB, env);
1016 break;
1019 if (prev_debug_excp_handler)
1020 prev_debug_excp_handler(env);
1023 /* This should come from sysemu.h - if we could include it here... */
1024 void qemu_system_reset_request(void);
1026 void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
1027 uint64_t mcg_status, uint64_t addr, uint64_t misc)
1029 uint64_t mcg_cap = cenv->mcg_cap;
1030 unsigned bank_num = mcg_cap & 0xff;
1031 uint64_t *banks = cenv->mce_banks;
1033 if (bank >= bank_num || !(status & MCI_STATUS_VAL))
1034 return;
1036 if (kvm_enabled()) {
1037 kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, 0);
1038 return;
1042 * if MSR_MCG_CTL is not all 1s, the uncorrected error
1043 * reporting is disabled
1045 if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
1046 cenv->mcg_ctl != ~(uint64_t)0)
1047 return;
1048 banks += 4 * bank;
1050 * if MSR_MCi_CTL is not all 1s, the uncorrected error
1051 * reporting is disabled for the bank
1053 if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0)
1054 return;
1055 if (status & MCI_STATUS_UC) {
1056 if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1057 !(cenv->cr[4] & CR4_MCE_MASK)) {
1058 fprintf(stderr, "injects mce exception while previous "
1059 "one is in progress!\n");
1060 qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1061 qemu_system_reset_request();
1062 return;
1064 if (banks[1] & MCI_STATUS_VAL)
1065 status |= MCI_STATUS_OVER;
1066 banks[2] = addr;
1067 banks[3] = misc;
1068 cenv->mcg_status = mcg_status;
1069 banks[1] = status;
1070 cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
1071 } else if (!(banks[1] & MCI_STATUS_VAL)
1072 || !(banks[1] & MCI_STATUS_UC)) {
1073 if (banks[1] & MCI_STATUS_VAL)
1074 status |= MCI_STATUS_OVER;
1075 banks[2] = addr;
1076 banks[3] = misc;
1077 banks[1] = status;
1078 } else
1079 banks[1] |= MCI_STATUS_OVER;
1081 #endif /* !CONFIG_USER_ONLY */
1083 static void mce_init(CPUX86State *cenv)
1085 unsigned int bank, bank_num;
1087 if (((cenv->cpuid_version >> 8)&0xf) >= 6
1088 && (cenv->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)) {
1089 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1090 cenv->mcg_ctl = ~(uint64_t)0;
1091 bank_num = MCE_BANKS_DEF;
1092 for (bank = 0; bank < bank_num; bank++)
1093 cenv->mce_banks[bank*4] = ~(uint64_t)0;
1097 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1098 target_ulong *base, unsigned int *limit,
1099 unsigned int *flags)
1101 SegmentCache *dt;
1102 target_ulong ptr;
1103 uint32_t e1, e2;
1104 int index;
1106 if (selector & 0x4)
1107 dt = &env->ldt;
1108 else
1109 dt = &env->gdt;
1110 index = selector & ~7;
1111 ptr = dt->base + index;
1112 if ((index + 7) > dt->limit
1113 || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1114 || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1115 return 0;
1117 *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1118 *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1119 if (e2 & DESC_G_MASK)
1120 *limit = (*limit << 12) | 0xfff;
1121 *flags = e2;
1123 return 1;
1126 CPUX86State *cpu_x86_init(const char *cpu_model)
1128 CPUX86State *env;
1129 static int inited;
1131 env = qemu_mallocz(sizeof(CPUX86State));
1132 cpu_exec_init(env);
1133 env->cpu_model_str = cpu_model;
1135 /* init various static tables */
1136 if (!inited) {
1137 inited = 1;
1138 optimize_flags_init();
1139 #ifndef CONFIG_USER_ONLY
1140 prev_debug_excp_handler =
1141 cpu_set_debug_excp_handler(breakpoint_handler);
1142 #endif
1144 if (cpu_x86_register(env, cpu_model) < 0) {
1145 cpu_x86_close(env);
1146 return NULL;
1148 mce_init(env);
1150 qemu_init_vcpu(env);
1152 return env;
1155 #if !defined(CONFIG_USER_ONLY)
1156 void do_cpu_init(CPUState *env)
1158 int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
1159 cpu_reset(env);
1160 env->interrupt_request = sipi;
1161 apic_init_reset(env->apic_state);
1162 env->halted = !cpu_is_bsp(env);
1165 void do_cpu_sipi(CPUState *env)
1167 apic_sipi(env->apic_state);
1169 #else
1170 void do_cpu_init(CPUState *env)
1173 void do_cpu_sipi(CPUState *env)
1176 #endif