Update Changelog with new Xscale platforms and vmsvga.
[qemu] / target-i386 / helper2.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, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <inttypes.h>
25 #include <signal.h>
26 #include <assert.h>
27
28 #include "cpu.h"
29 #include "exec-all.h"
30 #include "svm.h"
31
32 //#define DEBUG_MMU
33
34 static int cpu_x86_register (CPUX86State *env, const char *cpu_model);
35
36 static void add_flagname_to_bitmaps(char *flagname, uint32_t *features, 
37                                     uint32_t *ext_features, 
38                                     uint32_t *ext2_features, 
39                                     uint32_t *ext3_features)
40 {
41     int i;
42     /* feature flags taken from "Intel Processor Identification and the CPUID
43      * Instruction" and AMD's "CPUID Specification". In cases of disagreement 
44      * about feature names, the Linux name is used. */
45     const char *feature_name[] = {
46         "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
47         "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
48         "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
49         "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
50     };
51     const char *ext_feature_name[] = {
52        "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
53        "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
54        NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
55        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
56     };
57     const char *ext2_feature_name[] = {
58        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
59        "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mttr", "pge", "mca", "cmov",
60        "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
61        "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
62     };
63     const char *ext3_feature_name[] = {
64        "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
65        "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
66        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
67        NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
68     };
69
70     for ( i = 0 ; i < 32 ; i++ ) 
71         if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
72             *features |= 1 << i;
73             return;
74         }
75     for ( i = 0 ; i < 32 ; i++ ) 
76         if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
77             *ext_features |= 1 << i;
78             return;
79         }
80     for ( i = 0 ; i < 32 ; i++ ) 
81         if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
82             *ext2_features |= 1 << i;
83             return;
84         }
85     for ( i = 0 ; i < 32 ; i++ ) 
86         if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
87             *ext3_features |= 1 << i;
88             return;
89         }
90     fprintf(stderr, "CPU feature %s not found\n", flagname);
91 }
92
93 CPUX86State *cpu_x86_init(const char *cpu_model)
94 {
95     CPUX86State *env;
96     static int inited;
97
98     env = qemu_mallocz(sizeof(CPUX86State));
99     if (!env)
100         return NULL;
101     cpu_exec_init(env);
102     env->cpu_model_str = cpu_model;
103
104     /* init various static tables */
105     if (!inited) {
106         inited = 1;
107         optimize_flags_init();
108     }
109     if (cpu_x86_register(env, cpu_model) < 0) {
110         cpu_x86_close(env);
111         return NULL;
112     }
113     cpu_reset(env);
114 #ifdef USE_KQEMU
115     kqemu_init(env);
116 #endif
117     return env;
118 }
119
120 typedef struct x86_def_t {
121     const char *name;
122     uint32_t level;
123     uint32_t vendor1, vendor2, vendor3;
124     int family;
125     int model;
126     int stepping;
127     uint32_t features, ext_features, ext2_features, ext3_features;
128     uint32_t xlevel;
129 } x86_def_t;
130
131 #define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
132           CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
133           CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
134           CPUID_PAE | CPUID_SEP | CPUID_APIC)
135 static x86_def_t x86_defs[] = {
136 #ifdef TARGET_X86_64
137     {
138         .name = "qemu64",
139         .level = 2,
140         .vendor1 = 0x68747541, /* "Auth" */
141         .vendor2 = 0x69746e65, /* "enti" */
142         .vendor3 = 0x444d4163, /* "cAMD" */
143         .family = 6,
144         .model = 2,
145         .stepping = 3,
146         .features = PPRO_FEATURES | 
147         /* these features are needed for Win64 and aren't fully implemented */
148             CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
149         /* this feature is needed for Solaris and isn't fully implemented */
150             CPUID_PSE36,
151         .ext_features = CPUID_EXT_SSE3,
152         .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
153             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
154         .ext3_features = CPUID_EXT3_SVM,
155         .xlevel = 0x8000000A,
156     },
157 #endif
158     {
159         .name = "qemu32",
160         .level = 2,
161         .family = 6,
162         .model = 3,
163         .stepping = 3,
164         .features = PPRO_FEATURES,
165         .ext_features = CPUID_EXT_SSE3,
166         .xlevel = 0,
167     },
168     {
169         .name = "486",
170         .level = 0,
171         .family = 4,
172         .model = 0,
173         .stepping = 0,
174         .features = 0x0000000B,
175         .xlevel = 0,
176     },
177     {
178         .name = "pentium",
179         .level = 1,
180         .family = 5,
181         .model = 4,
182         .stepping = 3,
183         .features = 0x008001BF,
184         .xlevel = 0,
185     },
186     {
187         .name = "pentium2",
188         .level = 2,
189         .family = 6,
190         .model = 5,
191         .stepping = 2,
192         .features = 0x0183F9FF,
193         .xlevel = 0,
194     },
195     {
196         .name = "pentium3",
197         .level = 2,
198         .family = 6,
199         .model = 7,
200         .stepping = 3,
201         .features = 0x0383F9FF,
202         .xlevel = 0,
203     },
204 };
205
206 static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
207 {
208     unsigned int i;
209     x86_def_t *def;
210
211     char *s = strdup(cpu_model);
212     char *featurestr, *name = strtok(s, ",");
213     uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
214     uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
215     int family = -1, model = -1, stepping = -1;
216
217     def = NULL;
218     for (i = 0; i < sizeof(x86_defs) / sizeof(x86_def_t); i++) {
219         if (strcmp(name, x86_defs[i].name) == 0) {
220             def = &x86_defs[i];
221             break;
222         }
223     }
224     if (!def)
225         goto error;
226     memcpy(x86_cpu_def, def, sizeof(*def));
227
228     featurestr = strtok(NULL, ",");
229
230     while (featurestr) {
231         char *val;
232         if (featurestr[0] == '+') {
233             add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
234         } else if (featurestr[0] == '-') {
235             add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
236         } else if ((val = strchr(featurestr, '='))) {
237             *val = 0; val++;
238             if (!strcmp(featurestr, "family")) {
239                 char *err;
240                 family = strtol(val, &err, 10);
241                 if (!*val || *err || family < 0) {
242                     fprintf(stderr, "bad numerical value %s\n", val);
243                     x86_cpu_def = 0;
244                     goto error;
245                 }
246                 x86_cpu_def->family = family;
247             } else if (!strcmp(featurestr, "model")) {
248                 char *err;
249                 model = strtol(val, &err, 10);
250                 if (!*val || *err || model < 0 || model > 0xf) {
251                     fprintf(stderr, "bad numerical value %s\n", val);
252                     x86_cpu_def = 0;
253                     goto error;
254                 }
255                 x86_cpu_def->model = model;
256             } else if (!strcmp(featurestr, "stepping")) {
257                 char *err;
258                 stepping = strtol(val, &err, 10);
259                 if (!*val || *err || stepping < 0 || stepping > 0xf) {
260                     fprintf(stderr, "bad numerical value %s\n", val);
261                     x86_cpu_def = 0;
262                     goto error;
263                 }
264                 x86_cpu_def->stepping = stepping;
265             } else {
266                 fprintf(stderr, "unrecognized feature %s\n", featurestr);
267                 x86_cpu_def = 0;
268                 goto error;
269             }
270         } else {
271             fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
272             x86_cpu_def = 0;
273             goto error;
274         }
275         featurestr = strtok(NULL, ",");
276     }
277     x86_cpu_def->features |= plus_features;
278     x86_cpu_def->ext_features |= plus_ext_features;
279     x86_cpu_def->ext2_features |= plus_ext2_features;
280     x86_cpu_def->ext3_features |= plus_ext3_features;
281     x86_cpu_def->features &= ~minus_features;
282     x86_cpu_def->ext_features &= ~minus_ext_features;
283     x86_cpu_def->ext2_features &= ~minus_ext2_features;
284     x86_cpu_def->ext3_features &= ~minus_ext3_features;
285     free(s);
286     return 0;
287
288 error:
289     free(s);
290     return -1;
291 }
292
293 void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
294 {
295     unsigned int i;
296
297     for (i = 0; i < sizeof(x86_defs) / sizeof(x86_def_t); i++)
298         (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
299 }
300
301 static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
302 {
303     x86_def_t def1, *def = &def1;
304
305     if (cpu_x86_find_by_name(def, cpu_model) < 0)
306         return -1;
307     if (def->vendor1) {
308         env->cpuid_vendor1 = def->vendor1;
309         env->cpuid_vendor2 = def->vendor2;
310         env->cpuid_vendor3 = def->vendor3;
311     } else {
312         env->cpuid_vendor1 = 0x756e6547; /* "Genu" */
313         env->cpuid_vendor2 = 0x49656e69; /* "ineI" */
314         env->cpuid_vendor3 = 0x6c65746e; /* "ntel" */
315     }
316     env->cpuid_level = def->level;
317     env->cpuid_version = (def->family << 8) | (def->model << 4) | def->stepping;
318     env->cpuid_features = def->features;
319     env->pat = 0x0007040600070406ULL;
320     env->cpuid_ext_features = def->ext_features;
321     env->cpuid_ext2_features = def->ext2_features;
322     env->cpuid_xlevel = def->xlevel;
323     env->cpuid_ext3_features = def->ext3_features;
324     {
325         const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION;
326         int c, len, i;
327         len = strlen(model_id);
328         for(i = 0; i < 48; i++) {
329             if (i >= len)
330                 c = '\0';
331             else
332                 c = model_id[i];
333             env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
334         }
335     }
336     return 0;
337 }
338
339 /* NOTE: must be called outside the CPU execute loop */
340 void cpu_reset(CPUX86State *env)
341 {
342     int i;
343
344     memset(env, 0, offsetof(CPUX86State, breakpoints));
345
346     tlb_flush(env, 1);
347
348     env->old_exception = -1;
349
350     /* init to reset state */
351
352 #ifdef CONFIG_SOFTMMU
353     env->hflags |= HF_SOFTMMU_MASK;
354 #endif
355     env->hflags |= HF_GIF_MASK;
356
357     cpu_x86_update_cr0(env, 0x60000010);
358     env->a20_mask = 0xffffffff;
359     env->smbase = 0x30000;
360
361     env->idt.limit = 0xffff;
362     env->gdt.limit = 0xffff;
363     env->ldt.limit = 0xffff;
364     env->ldt.flags = DESC_P_MASK;
365     env->tr.limit = 0xffff;
366     env->tr.flags = DESC_P_MASK;
367
368     cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff, 0);
369     cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff, 0);
370     cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff, 0);
371     cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff, 0);
372     cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff, 0);
373     cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff, 0);
374
375     env->eip = 0xfff0;
376     env->regs[R_EDX] = env->cpuid_version;
377
378     env->eflags = 0x2;
379
380     /* FPU init */
381     for(i = 0;i < 8; i++)
382         env->fptags[i] = 1;
383     env->fpuc = 0x37f;
384
385     env->mxcsr = 0x1f80;
386 }
387
388 void cpu_x86_close(CPUX86State *env)
389 {
390     free(env);
391 }
392
393 /***********************************************************/
394 /* x86 debug */
395
396 static const char *cc_op_str[] = {
397     "DYNAMIC",
398     "EFLAGS",
399
400     "MULB",
401     "MULW",
402     "MULL",
403     "MULQ",
404
405     "ADDB",
406     "ADDW",
407     "ADDL",
408     "ADDQ",
409
410     "ADCB",
411     "ADCW",
412     "ADCL",
413     "ADCQ",
414
415     "SUBB",
416     "SUBW",
417     "SUBL",
418     "SUBQ",
419
420     "SBBB",
421     "SBBW",
422     "SBBL",
423     "SBBQ",
424
425     "LOGICB",
426     "LOGICW",
427     "LOGICL",
428     "LOGICQ",
429
430     "INCB",
431     "INCW",
432     "INCL",
433     "INCQ",
434
435     "DECB",
436     "DECW",
437     "DECL",
438     "DECQ",
439
440     "SHLB",
441     "SHLW",
442     "SHLL",
443     "SHLQ",
444
445     "SARB",
446     "SARW",
447     "SARL",
448     "SARQ",
449 };
450
451 void cpu_dump_state(CPUState *env, FILE *f,
452                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
453                     int flags)
454 {
455     int eflags, i, nb;
456     char cc_op_name[32];
457     static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
458
459     eflags = env->eflags;
460 #ifdef TARGET_X86_64
461     if (env->hflags & HF_CS64_MASK) {
462         cpu_fprintf(f,
463                     "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
464                     "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
465                     "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
466                     "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
467                     "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
468                     env->regs[R_EAX],
469                     env->regs[R_EBX],
470                     env->regs[R_ECX],
471                     env->regs[R_EDX],
472                     env->regs[R_ESI],
473                     env->regs[R_EDI],
474                     env->regs[R_EBP],
475                     env->regs[R_ESP],
476                     env->regs[8],
477                     env->regs[9],
478                     env->regs[10],
479                     env->regs[11],
480                     env->regs[12],
481                     env->regs[13],
482                     env->regs[14],
483                     env->regs[15],
484                     env->eip, eflags,
485                     eflags & DF_MASK ? 'D' : '-',
486                     eflags & CC_O ? 'O' : '-',
487                     eflags & CC_S ? 'S' : '-',
488                     eflags & CC_Z ? 'Z' : '-',
489                     eflags & CC_A ? 'A' : '-',
490                     eflags & CC_P ? 'P' : '-',
491                     eflags & CC_C ? 'C' : '-',
492                     env->hflags & HF_CPL_MASK,
493                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
494                     (env->a20_mask >> 20) & 1,
495                     (env->hflags >> HF_SMM_SHIFT) & 1,
496                     (env->hflags >> HF_HALTED_SHIFT) & 1);
497     } else
498 #endif
499     {
500         cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
501                     "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
502                     "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
503                     (uint32_t)env->regs[R_EAX],
504                     (uint32_t)env->regs[R_EBX],
505                     (uint32_t)env->regs[R_ECX],
506                     (uint32_t)env->regs[R_EDX],
507                     (uint32_t)env->regs[R_ESI],
508                     (uint32_t)env->regs[R_EDI],
509                     (uint32_t)env->regs[R_EBP],
510                     (uint32_t)env->regs[R_ESP],
511                     (uint32_t)env->eip, eflags,
512                     eflags & DF_MASK ? 'D' : '-',
513                     eflags & CC_O ? 'O' : '-',
514                     eflags & CC_S ? 'S' : '-',
515                     eflags & CC_Z ? 'Z' : '-',
516                     eflags & CC_A ? 'A' : '-',
517                     eflags & CC_P ? 'P' : '-',
518                     eflags & CC_C ? 'C' : '-',
519                     env->hflags & HF_CPL_MASK,
520                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
521                     (env->a20_mask >> 20) & 1,
522                     (env->hflags >> HF_SMM_SHIFT) & 1,
523                     (env->hflags >> HF_HALTED_SHIFT) & 1);
524     }
525
526 #ifdef TARGET_X86_64
527     if (env->hflags & HF_LMA_MASK) {
528         for(i = 0; i < 6; i++) {
529             SegmentCache *sc = &env->segs[i];
530             cpu_fprintf(f, "%s =%04x %016" PRIx64 " %08x %08x\n",
531                         seg_name[i],
532                         sc->selector,
533                         sc->base,
534                         sc->limit,
535                         sc->flags);
536         }
537         cpu_fprintf(f, "LDT=%04x %016" PRIx64 " %08x %08x\n",
538                     env->ldt.selector,
539                     env->ldt.base,
540                     env->ldt.limit,
541                     env->ldt.flags);
542         cpu_fprintf(f, "TR =%04x %016" PRIx64 " %08x %08x\n",
543                     env->tr.selector,
544                     env->tr.base,
545                     env->tr.limit,
546                     env->tr.flags);
547         cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
548                     env->gdt.base, env->gdt.limit);
549         cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
550                     env->idt.base, env->idt.limit);
551         cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
552                     (uint32_t)env->cr[0],
553                     env->cr[2],
554                     env->cr[3],
555                     (uint32_t)env->cr[4]);
556     } else
557 #endif
558     {
559         for(i = 0; i < 6; i++) {
560             SegmentCache *sc = &env->segs[i];
561             cpu_fprintf(f, "%s =%04x %08x %08x %08x\n",
562                         seg_name[i],
563                         sc->selector,
564                         (uint32_t)sc->base,
565                         sc->limit,
566                         sc->flags);
567         }
568         cpu_fprintf(f, "LDT=%04x %08x %08x %08x\n",
569                     env->ldt.selector,
570                     (uint32_t)env->ldt.base,
571                     env->ldt.limit,
572                     env->ldt.flags);
573         cpu_fprintf(f, "TR =%04x %08x %08x %08x\n",
574                     env->tr.selector,
575                     (uint32_t)env->tr.base,
576                     env->tr.limit,
577                     env->tr.flags);
578         cpu_fprintf(f, "GDT=     %08x %08x\n",
579                     (uint32_t)env->gdt.base, env->gdt.limit);
580         cpu_fprintf(f, "IDT=     %08x %08x\n",
581                     (uint32_t)env->idt.base, env->idt.limit);
582         cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
583                     (uint32_t)env->cr[0],
584                     (uint32_t)env->cr[2],
585                     (uint32_t)env->cr[3],
586                     (uint32_t)env->cr[4]);
587     }
588     if (flags & X86_DUMP_CCOP) {
589         if ((unsigned)env->cc_op < CC_OP_NB)
590             snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
591         else
592             snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
593 #ifdef TARGET_X86_64
594         if (env->hflags & HF_CS64_MASK) {
595             cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
596                         env->cc_src, env->cc_dst,
597                         cc_op_name);
598         } else
599 #endif
600         {
601             cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
602                         (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
603                         cc_op_name);
604         }
605     }
606     if (flags & X86_DUMP_FPU) {
607         int fptag;
608         fptag = 0;
609         for(i = 0; i < 8; i++) {
610             fptag |= ((!env->fptags[i]) << i);
611         }
612         cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
613                     env->fpuc,
614                     (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
615                     env->fpstt,
616                     fptag,
617                     env->mxcsr);
618         for(i=0;i<8;i++) {
619 #if defined(USE_X86LDOUBLE)
620             union {
621                 long double d;
622                 struct {
623                     uint64_t lower;
624                     uint16_t upper;
625                 } l;
626             } tmp;
627             tmp.d = env->fpregs[i].d;
628             cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
629                         i, tmp.l.lower, tmp.l.upper);
630 #else
631             cpu_fprintf(f, "FPR%d=%016" PRIx64,
632                         i, env->fpregs[i].mmx.q);
633 #endif
634             if ((i & 1) == 1)
635                 cpu_fprintf(f, "\n");
636             else
637                 cpu_fprintf(f, " ");
638         }
639         if (env->hflags & HF_CS64_MASK)
640             nb = 16;
641         else
642             nb = 8;
643         for(i=0;i<nb;i++) {
644             cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
645                         i,
646                         env->xmm_regs[i].XMM_L(3),
647                         env->xmm_regs[i].XMM_L(2),
648                         env->xmm_regs[i].XMM_L(1),
649                         env->xmm_regs[i].XMM_L(0));
650             if ((i & 1) == 1)
651                 cpu_fprintf(f, "\n");
652             else
653                 cpu_fprintf(f, " ");
654         }
655     }
656 }
657
658 /***********************************************************/
659 /* x86 mmu */
660 /* XXX: add PGE support */
661
662 void cpu_x86_set_a20(CPUX86State *env, int a20_state)
663 {
664     a20_state = (a20_state != 0);
665     if (a20_state != ((env->a20_mask >> 20) & 1)) {
666 #if defined(DEBUG_MMU)
667         printf("A20 update: a20=%d\n", a20_state);
668 #endif
669         /* if the cpu is currently executing code, we must unlink it and
670            all the potentially executing TB */
671         cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
672
673         /* when a20 is changed, all the MMU mappings are invalid, so
674            we must flush everything */
675         tlb_flush(env, 1);
676         env->a20_mask = 0xffefffff | (a20_state << 20);
677     }
678 }
679
680 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
681 {
682     int pe_state;
683
684 #if defined(DEBUG_MMU)
685     printf("CR0 update: CR0=0x%08x\n", new_cr0);
686 #endif
687     if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
688         (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
689         tlb_flush(env, 1);
690     }
691
692 #ifdef TARGET_X86_64
693     if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
694         (env->efer & MSR_EFER_LME)) {
695         /* enter in long mode */
696         /* XXX: generate an exception */
697         if (!(env->cr[4] & CR4_PAE_MASK))
698             return;
699         env->efer |= MSR_EFER_LMA;
700         env->hflags |= HF_LMA_MASK;
701     } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
702                (env->efer & MSR_EFER_LMA)) {
703         /* exit long mode */
704         env->efer &= ~MSR_EFER_LMA;
705         env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
706         env->eip &= 0xffffffff;
707     }
708 #endif
709     env->cr[0] = new_cr0 | CR0_ET_MASK;
710
711     /* update PE flag in hidden flags */
712     pe_state = (env->cr[0] & CR0_PE_MASK);
713     env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
714     /* ensure that ADDSEG is always set in real mode */
715     env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
716     /* update FPU flags */
717     env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
718         ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
719 }
720
721 /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
722    the PDPT */
723 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
724 {
725     env->cr[3] = new_cr3;
726     if (env->cr[0] & CR0_PG_MASK) {
727 #if defined(DEBUG_MMU)
728         printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
729 #endif
730         tlb_flush(env, 0);
731     }
732 }
733
734 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
735 {
736 #if defined(DEBUG_MMU)
737     printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
738 #endif
739     if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
740         (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
741         tlb_flush(env, 1);
742     }
743     /* SSE handling */
744     if (!(env->cpuid_features & CPUID_SSE))
745         new_cr4 &= ~CR4_OSFXSR_MASK;
746     if (new_cr4 & CR4_OSFXSR_MASK)
747         env->hflags |= HF_OSFXSR_MASK;
748     else
749         env->hflags &= ~HF_OSFXSR_MASK;
750
751     env->cr[4] = new_cr4;
752 }
753
754 /* XXX: also flush 4MB pages */
755 void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr)
756 {
757     tlb_flush_page(env, addr);
758 }
759
760 #if defined(CONFIG_USER_ONLY)
761
762 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
763                              int is_write, int mmu_idx, int is_softmmu)
764 {
765     /* user mode only emulation */
766     is_write &= 1;
767     env->cr[2] = addr;
768     env->error_code = (is_write << PG_ERROR_W_BIT);
769     env->error_code |= PG_ERROR_U_MASK;
770     env->exception_index = EXCP0E_PAGE;
771     return 1;
772 }
773
774 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
775 {
776     return addr;
777 }
778
779 #else
780
781 #define PHYS_ADDR_MASK 0xfffff000
782
783 /* return value:
784    -1 = cannot handle fault
785    0  = nothing more to do
786    1  = generate PF fault
787    2  = soft MMU activation required for this block
788 */
789 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
790                              int is_write1, int mmu_idx, int is_softmmu)
791 {
792     uint64_t ptep, pte;
793     uint32_t pdpe_addr, pde_addr, pte_addr;
794     int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
795     unsigned long paddr, page_offset;
796     target_ulong vaddr, virt_addr;
797
798     is_user = mmu_idx == MMU_USER_IDX;
799 #if defined(DEBUG_MMU)
800     printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
801            addr, is_write1, is_user, env->eip);
802 #endif
803     is_write = is_write1 & 1;
804
805     if (!(env->cr[0] & CR0_PG_MASK)) {
806         pte = addr;
807         virt_addr = addr & TARGET_PAGE_MASK;
808         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
809         page_size = 4096;
810         goto do_mapping;
811     }
812
813     if (env->cr[4] & CR4_PAE_MASK) {
814         uint64_t pde, pdpe;
815
816         /* XXX: we only use 32 bit physical addresses */
817 #ifdef TARGET_X86_64
818         if (env->hflags & HF_LMA_MASK) {
819             uint32_t pml4e_addr;
820             uint64_t pml4e;
821             int32_t sext;
822
823             /* test virtual address sign extension */
824             sext = (int64_t)addr >> 47;
825             if (sext != 0 && sext != -1) {
826                 env->error_code = 0;
827                 env->exception_index = EXCP0D_GPF;
828                 return 1;
829             }
830
831             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
832                 env->a20_mask;
833             pml4e = ldq_phys(pml4e_addr);
834             if (!(pml4e & PG_PRESENT_MASK)) {
835                 error_code = 0;
836                 goto do_fault;
837             }
838             if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
839                 error_code = PG_ERROR_RSVD_MASK;
840                 goto do_fault;
841             }
842             if (!(pml4e & PG_ACCESSED_MASK)) {
843                 pml4e |= PG_ACCESSED_MASK;
844                 stl_phys_notdirty(pml4e_addr, pml4e);
845             }
846             ptep = pml4e ^ PG_NX_MASK;
847             pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
848                 env->a20_mask;
849             pdpe = ldq_phys(pdpe_addr);
850             if (!(pdpe & PG_PRESENT_MASK)) {
851                 error_code = 0;
852                 goto do_fault;
853             }
854             if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
855                 error_code = PG_ERROR_RSVD_MASK;
856                 goto do_fault;
857             }
858             ptep &= pdpe ^ PG_NX_MASK;
859             if (!(pdpe & PG_ACCESSED_MASK)) {
860                 pdpe |= PG_ACCESSED_MASK;
861                 stl_phys_notdirty(pdpe_addr, pdpe);
862             }
863         } else
864 #endif
865         {
866             /* XXX: load them when cr3 is loaded ? */
867             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
868                 env->a20_mask;
869             pdpe = ldq_phys(pdpe_addr);
870             if (!(pdpe & PG_PRESENT_MASK)) {
871                 error_code = 0;
872                 goto do_fault;
873             }
874             ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
875         }
876
877         pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
878             env->a20_mask;
879         pde = ldq_phys(pde_addr);
880         if (!(pde & PG_PRESENT_MASK)) {
881             error_code = 0;
882             goto do_fault;
883         }
884         if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
885             error_code = PG_ERROR_RSVD_MASK;
886             goto do_fault;
887         }
888         ptep &= pde ^ PG_NX_MASK;
889         if (pde & PG_PSE_MASK) {
890             /* 2 MB page */
891             page_size = 2048 * 1024;
892             ptep ^= PG_NX_MASK;
893             if ((ptep & PG_NX_MASK) && is_write1 == 2)
894                 goto do_fault_protect;
895             if (is_user) {
896                 if (!(ptep & PG_USER_MASK))
897                     goto do_fault_protect;
898                 if (is_write && !(ptep & PG_RW_MASK))
899                     goto do_fault_protect;
900             } else {
901                 if ((env->cr[0] & CR0_WP_MASK) &&
902                     is_write && !(ptep & PG_RW_MASK))
903                     goto do_fault_protect;
904             }
905             is_dirty = is_write && !(pde & PG_DIRTY_MASK);
906             if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
907                 pde |= PG_ACCESSED_MASK;
908                 if (is_dirty)
909                     pde |= PG_DIRTY_MASK;
910                 stl_phys_notdirty(pde_addr, pde);
911             }
912             /* align to page_size */
913             pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
914             virt_addr = addr & ~(page_size - 1);
915         } else {
916             /* 4 KB page */
917             if (!(pde & PG_ACCESSED_MASK)) {
918                 pde |= PG_ACCESSED_MASK;
919                 stl_phys_notdirty(pde_addr, pde);
920             }
921             pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
922                 env->a20_mask;
923             pte = ldq_phys(pte_addr);
924             if (!(pte & PG_PRESENT_MASK)) {
925                 error_code = 0;
926                 goto do_fault;
927             }
928             if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
929                 error_code = PG_ERROR_RSVD_MASK;
930                 goto do_fault;
931             }
932             /* combine pde and pte nx, user and rw protections */
933             ptep &= pte ^ PG_NX_MASK;
934             ptep ^= PG_NX_MASK;
935             if ((ptep & PG_NX_MASK) && is_write1 == 2)
936                 goto do_fault_protect;
937             if (is_user) {
938                 if (!(ptep & PG_USER_MASK))
939                     goto do_fault_protect;
940                 if (is_write && !(ptep & PG_RW_MASK))
941                     goto do_fault_protect;
942             } else {
943                 if ((env->cr[0] & CR0_WP_MASK) &&
944                     is_write && !(ptep & PG_RW_MASK))
945                     goto do_fault_protect;
946             }
947             is_dirty = is_write && !(pte & PG_DIRTY_MASK);
948             if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
949                 pte |= PG_ACCESSED_MASK;
950                 if (is_dirty)
951                     pte |= PG_DIRTY_MASK;
952                 stl_phys_notdirty(pte_addr, pte);
953             }
954             page_size = 4096;
955             virt_addr = addr & ~0xfff;
956             pte = pte & (PHYS_ADDR_MASK | 0xfff);
957         }
958     } else {
959         uint32_t pde;
960
961         /* page directory entry */
962         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
963             env->a20_mask;
964         pde = ldl_phys(pde_addr);
965         if (!(pde & PG_PRESENT_MASK)) {
966             error_code = 0;
967             goto do_fault;
968         }
969         /* if PSE bit is set, then we use a 4MB page */
970         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
971             page_size = 4096 * 1024;
972             if (is_user) {
973                 if (!(pde & PG_USER_MASK))
974                     goto do_fault_protect;
975                 if (is_write && !(pde & PG_RW_MASK))
976                     goto do_fault_protect;
977             } else {
978                 if ((env->cr[0] & CR0_WP_MASK) &&
979                     is_write && !(pde & PG_RW_MASK))
980                     goto do_fault_protect;
981             }
982             is_dirty = is_write && !(pde & PG_DIRTY_MASK);
983             if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
984                 pde |= PG_ACCESSED_MASK;
985                 if (is_dirty)
986                     pde |= PG_DIRTY_MASK;
987                 stl_phys_notdirty(pde_addr, pde);
988             }
989
990             pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
991             ptep = pte;
992             virt_addr = addr & ~(page_size - 1);
993         } else {
994             if (!(pde & PG_ACCESSED_MASK)) {
995                 pde |= PG_ACCESSED_MASK;
996                 stl_phys_notdirty(pde_addr, pde);
997             }
998
999             /* page directory entry */
1000             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
1001                 env->a20_mask;
1002             pte = ldl_phys(pte_addr);
1003             if (!(pte & PG_PRESENT_MASK)) {
1004                 error_code = 0;
1005                 goto do_fault;
1006             }
1007             /* combine pde and pte user and rw protections */
1008             ptep = pte & pde;
1009             if (is_user) {
1010                 if (!(ptep & PG_USER_MASK))
1011                     goto do_fault_protect;
1012                 if (is_write && !(ptep & PG_RW_MASK))
1013                     goto do_fault_protect;
1014             } else {
1015                 if ((env->cr[0] & CR0_WP_MASK) &&
1016                     is_write && !(ptep & PG_RW_MASK))
1017                     goto do_fault_protect;
1018             }
1019             is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1020             if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1021                 pte |= PG_ACCESSED_MASK;
1022                 if (is_dirty)
1023                     pte |= PG_DIRTY_MASK;
1024                 stl_phys_notdirty(pte_addr, pte);
1025             }
1026             page_size = 4096;
1027             virt_addr = addr & ~0xfff;
1028         }
1029     }
1030     /* the page can be put in the TLB */
1031     prot = PAGE_READ;
1032     if (!(ptep & PG_NX_MASK))
1033         prot |= PAGE_EXEC;
1034     if (pte & PG_DIRTY_MASK) {
1035         /* only set write access if already dirty... otherwise wait
1036            for dirty access */
1037         if (is_user) {
1038             if (ptep & PG_RW_MASK)
1039                 prot |= PAGE_WRITE;
1040         } else {
1041             if (!(env->cr[0] & CR0_WP_MASK) ||
1042                 (ptep & PG_RW_MASK))
1043                 prot |= PAGE_WRITE;
1044         }
1045     }
1046  do_mapping:
1047     pte = pte & env->a20_mask;
1048
1049     /* Even if 4MB pages, we map only one 4KB page in the cache to
1050        avoid filling it too fast */
1051     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1052     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1053     vaddr = virt_addr + page_offset;
1054
1055     ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
1056     return ret;
1057  do_fault_protect:
1058     error_code = PG_ERROR_P_MASK;
1059  do_fault:
1060     error_code |= (is_write << PG_ERROR_W_BIT);
1061     if (is_user)
1062         error_code |= PG_ERROR_U_MASK;
1063     if (is_write1 == 2 &&
1064         (env->efer & MSR_EFER_NXE) &&
1065         (env->cr[4] & CR4_PAE_MASK))
1066         error_code |= PG_ERROR_I_D_MASK;
1067     if (INTERCEPTEDl(_exceptions, 1 << EXCP0E_PAGE)) {
1068         stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), addr);
1069     } else {
1070         env->cr[2] = addr;
1071     }
1072     env->error_code = error_code;
1073     env->exception_index = EXCP0E_PAGE;
1074     /* the VMM will handle this */
1075     if (INTERCEPTEDl(_exceptions, 1 << EXCP0E_PAGE))
1076         return 2;
1077     return 1;
1078 }
1079
1080 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1081 {
1082     uint32_t pde_addr, pte_addr;
1083     uint32_t pde, pte, paddr, page_offset, page_size;
1084
1085     if (env->cr[4] & CR4_PAE_MASK) {
1086         uint32_t pdpe_addr, pde_addr, pte_addr;
1087         uint32_t pdpe;
1088
1089         /* XXX: we only use 32 bit physical addresses */
1090 #ifdef TARGET_X86_64
1091         if (env->hflags & HF_LMA_MASK) {
1092             uint32_t pml4e_addr, pml4e;
1093             int32_t sext;
1094
1095             /* test virtual address sign extension */
1096             sext = (int64_t)addr >> 47;
1097             if (sext != 0 && sext != -1)
1098                 return -1;
1099
1100             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
1101                 env->a20_mask;
1102             pml4e = ldl_phys(pml4e_addr);
1103             if (!(pml4e & PG_PRESENT_MASK))
1104                 return -1;
1105
1106             pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
1107                 env->a20_mask;
1108             pdpe = ldl_phys(pdpe_addr);
1109             if (!(pdpe & PG_PRESENT_MASK))
1110                 return -1;
1111         } else
1112 #endif
1113         {
1114             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1115                 env->a20_mask;
1116             pdpe = ldl_phys(pdpe_addr);
1117             if (!(pdpe & PG_PRESENT_MASK))
1118                 return -1;
1119         }
1120
1121         pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
1122             env->a20_mask;
1123         pde = ldl_phys(pde_addr);
1124         if (!(pde & PG_PRESENT_MASK)) {
1125             return -1;
1126         }
1127         if (pde & PG_PSE_MASK) {
1128             /* 2 MB page */
1129             page_size = 2048 * 1024;
1130             pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1131         } else {
1132             /* 4 KB page */
1133             pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
1134                 env->a20_mask;
1135             page_size = 4096;
1136             pte = ldl_phys(pte_addr);
1137         }
1138     } else {
1139         if (!(env->cr[0] & CR0_PG_MASK)) {
1140             pte = addr;
1141             page_size = 4096;
1142         } else {
1143             /* page directory entry */
1144             pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
1145             pde = ldl_phys(pde_addr);
1146             if (!(pde & PG_PRESENT_MASK))
1147                 return -1;
1148             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1149                 pte = pde & ~0x003ff000; /* align to 4MB */
1150                 page_size = 4096 * 1024;
1151             } else {
1152                 /* page directory entry */
1153                 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
1154                 pte = ldl_phys(pte_addr);
1155                 if (!(pte & PG_PRESENT_MASK))
1156                     return -1;
1157                 page_size = 4096;
1158             }
1159         }
1160         pte = pte & env->a20_mask;
1161     }
1162
1163     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1164     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1165     return paddr;
1166 }
1167 #endif /* !CONFIG_USER_ONLY */