]> Git Repo - qemu.git/blob - target-i386/helper.c
Rename cpu_reset() to cpu_state_reset()
[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_state_reset(CPUState *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 & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
889                          (((addr >> 30) & 0x1ff) << 3)) & 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 & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
904                     (((addr >> 21) & 0x1ff) << 3)) & 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 & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
916                         (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
917             page_size = 4096;
918             pte = ldq_phys(pte_addr);
919         }
920         pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
921         if (!(pte & PG_PRESENT_MASK))
922             return -1;
923     } else {
924         uint32_t pde;
925
926         if (!(env->cr[0] & CR0_PG_MASK)) {
927             pte = addr;
928             page_size = 4096;
929         } else {
930             /* page directory entry */
931             pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
932             pde = ldl_phys(pde_addr);
933             if (!(pde & PG_PRESENT_MASK))
934                 return -1;
935             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
936                 pte = pde & ~0x003ff000; /* align to 4MB */
937                 page_size = 4096 * 1024;
938             } else {
939                 /* page directory entry */
940                 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
941                 pte = ldl_phys(pte_addr);
942                 if (!(pte & PG_PRESENT_MASK))
943                     return -1;
944                 page_size = 4096;
945             }
946         }
947         pte = pte & env->a20_mask;
948     }
949
950     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
951     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
952     return paddr;
953 }
954
955 void hw_breakpoint_insert(CPUState *env, int index)
956 {
957     int type, err = 0;
958
959     switch (hw_breakpoint_type(env->dr[7], index)) {
960     case 0:
961         if (hw_breakpoint_enabled(env->dr[7], index))
962             err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
963                                         &env->cpu_breakpoint[index]);
964         break;
965     case 1:
966         type = BP_CPU | BP_MEM_WRITE;
967         goto insert_wp;
968     case 2:
969          /* No support for I/O watchpoints yet */
970         break;
971     case 3:
972         type = BP_CPU | BP_MEM_ACCESS;
973     insert_wp:
974         err = cpu_watchpoint_insert(env, env->dr[index],
975                                     hw_breakpoint_len(env->dr[7], index),
976                                     type, &env->cpu_watchpoint[index]);
977         break;
978     }
979     if (err)
980         env->cpu_breakpoint[index] = NULL;
981 }
982
983 void hw_breakpoint_remove(CPUState *env, int index)
984 {
985     if (!env->cpu_breakpoint[index])
986         return;
987     switch (hw_breakpoint_type(env->dr[7], index)) {
988     case 0:
989         if (hw_breakpoint_enabled(env->dr[7], index))
990             cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
991         break;
992     case 1:
993     case 3:
994         cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
995         break;
996     case 2:
997         /* No support for I/O watchpoints yet */
998         break;
999     }
1000 }
1001
1002 int check_hw_breakpoints(CPUState *env, int force_dr6_update)
1003 {
1004     target_ulong dr6;
1005     int reg, type;
1006     int hit_enabled = 0;
1007
1008     dr6 = env->dr[6] & ~0xf;
1009     for (reg = 0; reg < 4; reg++) {
1010         type = hw_breakpoint_type(env->dr[7], reg);
1011         if ((type == 0 && env->dr[reg] == env->eip) ||
1012             ((type & 1) && env->cpu_watchpoint[reg] &&
1013              (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
1014             dr6 |= 1 << reg;
1015             if (hw_breakpoint_enabled(env->dr[7], reg))
1016                 hit_enabled = 1;
1017         }
1018     }
1019     if (hit_enabled || force_dr6_update)
1020         env->dr[6] = dr6;
1021     return hit_enabled;
1022 }
1023
1024 static CPUDebugExcpHandler *prev_debug_excp_handler;
1025
1026 static void breakpoint_handler(CPUState *env)
1027 {
1028     CPUBreakpoint *bp;
1029
1030     if (env->watchpoint_hit) {
1031         if (env->watchpoint_hit->flags & BP_CPU) {
1032             env->watchpoint_hit = NULL;
1033             if (check_hw_breakpoints(env, 0))
1034                 raise_exception_env(EXCP01_DB, env);
1035             else
1036                 cpu_resume_from_signal(env, NULL);
1037         }
1038     } else {
1039         QTAILQ_FOREACH(bp, &env->breakpoints, entry)
1040             if (bp->pc == env->eip) {
1041                 if (bp->flags & BP_CPU) {
1042                     check_hw_breakpoints(env, 1);
1043                     raise_exception_env(EXCP01_DB, env);
1044                 }
1045                 break;
1046             }
1047     }
1048     if (prev_debug_excp_handler)
1049         prev_debug_excp_handler(env);
1050 }
1051
1052 typedef struct MCEInjectionParams {
1053     Monitor *mon;
1054     CPUState *env;
1055     int bank;
1056     uint64_t status;
1057     uint64_t mcg_status;
1058     uint64_t addr;
1059     uint64_t misc;
1060     int flags;
1061 } MCEInjectionParams;
1062
1063 static void do_inject_x86_mce(void *data)
1064 {
1065     MCEInjectionParams *params = data;
1066     CPUState *cenv = params->env;
1067     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
1068
1069     cpu_synchronize_state(cenv);
1070
1071     /*
1072      * If there is an MCE exception being processed, ignore this SRAO MCE
1073      * unless unconditional injection was requested.
1074      */
1075     if (!(params->flags & MCE_INJECT_UNCOND_AO)
1076         && !(params->status & MCI_STATUS_AR)
1077         && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1078         return;
1079     }
1080
1081     if (params->status & MCI_STATUS_UC) {
1082         /*
1083          * if MSR_MCG_CTL is not all 1s, the uncorrected error
1084          * reporting is disabled
1085          */
1086         if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1087             monitor_printf(params->mon,
1088                            "CPU %d: Uncorrected error reporting disabled\n",
1089                            cenv->cpu_index);
1090             return;
1091         }
1092
1093         /*
1094          * if MSR_MCi_CTL is not all 1s, the uncorrected error
1095          * reporting is disabled for the bank
1096          */
1097         if (banks[0] != ~(uint64_t)0) {
1098             monitor_printf(params->mon,
1099                            "CPU %d: Uncorrected error reporting disabled for"
1100                            " bank %d\n",
1101                            cenv->cpu_index, params->bank);
1102             return;
1103         }
1104
1105         if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1106             !(cenv->cr[4] & CR4_MCE_MASK)) {
1107             monitor_printf(params->mon,
1108                            "CPU %d: Previous MCE still in progress, raising"
1109                            " triple fault\n",
1110                            cenv->cpu_index);
1111             qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1112             qemu_system_reset_request();
1113             return;
1114         }
1115         if (banks[1] & MCI_STATUS_VAL) {
1116             params->status |= MCI_STATUS_OVER;
1117         }
1118         banks[2] = params->addr;
1119         banks[3] = params->misc;
1120         cenv->mcg_status = params->mcg_status;
1121         banks[1] = params->status;
1122         cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
1123     } else if (!(banks[1] & MCI_STATUS_VAL)
1124                || !(banks[1] & MCI_STATUS_UC)) {
1125         if (banks[1] & MCI_STATUS_VAL) {
1126             params->status |= MCI_STATUS_OVER;
1127         }
1128         banks[2] = params->addr;
1129         banks[3] = params->misc;
1130         banks[1] = params->status;
1131     } else {
1132         banks[1] |= MCI_STATUS_OVER;
1133     }
1134 }
1135
1136 void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank,
1137                         uint64_t status, uint64_t mcg_status, uint64_t addr,
1138                         uint64_t misc, int flags)
1139 {
1140     MCEInjectionParams params = {
1141         .mon = mon,
1142         .env = cenv,
1143         .bank = bank,
1144         .status = status,
1145         .mcg_status = mcg_status,
1146         .addr = addr,
1147         .misc = misc,
1148         .flags = flags,
1149     };
1150     unsigned bank_num = cenv->mcg_cap & 0xff;
1151     CPUState *env;
1152
1153     if (!cenv->mcg_cap) {
1154         monitor_printf(mon, "MCE injection not supported\n");
1155         return;
1156     }
1157     if (bank >= bank_num) {
1158         monitor_printf(mon, "Invalid MCE bank number\n");
1159         return;
1160     }
1161     if (!(status & MCI_STATUS_VAL)) {
1162         monitor_printf(mon, "Invalid MCE status code\n");
1163         return;
1164     }
1165     if ((flags & MCE_INJECT_BROADCAST)
1166         && !cpu_x86_support_mca_broadcast(cenv)) {
1167         monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
1168         return;
1169     }
1170
1171     run_on_cpu(cenv, do_inject_x86_mce, &params);
1172     if (flags & MCE_INJECT_BROADCAST) {
1173         params.bank = 1;
1174         params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
1175         params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
1176         params.addr = 0;
1177         params.misc = 0;
1178         for (env = first_cpu; env != NULL; env = env->next_cpu) {
1179             if (cenv == env) {
1180                 continue;
1181             }
1182             params.env = env;
1183             run_on_cpu(cenv, do_inject_x86_mce, &params);
1184         }
1185     }
1186 }
1187
1188 void cpu_report_tpr_access(CPUState *env, TPRAccess access)
1189 {
1190     TranslationBlock *tb;
1191
1192     if (kvm_enabled()) {
1193         env->tpr_access_type = access;
1194
1195         cpu_interrupt(env, CPU_INTERRUPT_TPR);
1196     } else {
1197         tb = tb_find_pc(env->mem_io_pc);
1198         cpu_restore_state(tb, env, env->mem_io_pc);
1199
1200         apic_handle_tpr_access_report(env->apic_state, env->eip, access);
1201     }
1202 }
1203 #endif /* !CONFIG_USER_ONLY */
1204
1205 static void mce_init(CPUX86State *cenv)
1206 {
1207     unsigned int bank;
1208
1209     if (((cenv->cpuid_version >> 8) & 0xf) >= 6
1210         && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
1211             (CPUID_MCE | CPUID_MCA)) {
1212         cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1213         cenv->mcg_ctl = ~(uint64_t)0;
1214         for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
1215             cenv->mce_banks[bank * 4] = ~(uint64_t)0;
1216         }
1217     }
1218 }
1219
1220 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1221                             target_ulong *base, unsigned int *limit,
1222                             unsigned int *flags)
1223 {
1224     SegmentCache *dt;
1225     target_ulong ptr;
1226     uint32_t e1, e2;
1227     int index;
1228
1229     if (selector & 0x4)
1230         dt = &env->ldt;
1231     else
1232         dt = &env->gdt;
1233     index = selector & ~7;
1234     ptr = dt->base + index;
1235     if ((index + 7) > dt->limit
1236         || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1237         || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1238         return 0;
1239
1240     *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1241     *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1242     if (e2 & DESC_G_MASK)
1243         *limit = (*limit << 12) | 0xfff;
1244     *flags = e2;
1245
1246     return 1;
1247 }
1248
1249 CPUX86State *cpu_x86_init(const char *cpu_model)
1250 {
1251     CPUX86State *env;
1252     static int inited;
1253
1254     env = g_malloc0(sizeof(CPUX86State));
1255     cpu_exec_init(env);
1256     env->cpu_model_str = cpu_model;
1257
1258     /* init various static tables used in TCG mode */
1259     if (tcg_enabled() && !inited) {
1260         inited = 1;
1261         optimize_flags_init();
1262 #ifndef CONFIG_USER_ONLY
1263         prev_debug_excp_handler =
1264             cpu_set_debug_excp_handler(breakpoint_handler);
1265 #endif
1266     }
1267     if (cpu_x86_register(env, cpu_model) < 0) {
1268         cpu_x86_close(env);
1269         return NULL;
1270     }
1271     env->cpuid_apic_id = env->cpu_index;
1272     mce_init(env);
1273
1274     qemu_init_vcpu(env);
1275
1276     return env;
1277 }
1278
1279 #if !defined(CONFIG_USER_ONLY)
1280 void do_cpu_init(CPUState *env)
1281 {
1282     int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
1283     uint64_t pat = env->pat;
1284
1285     cpu_state_reset(env);
1286     env->interrupt_request = sipi;
1287     env->pat = pat;
1288     apic_init_reset(env->apic_state);
1289     env->halted = !cpu_is_bsp(env);
1290 }
1291
1292 void do_cpu_sipi(CPUState *env)
1293 {
1294     apic_sipi(env->apic_state);
1295 }
1296 #else
1297 void do_cpu_init(CPUState *env)
1298 {
1299 }
1300 void do_cpu_sipi(CPUState *env)
1301 {
1302 }
1303 #endif
This page took 0.098675 seconds and 4 git commands to generate.