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