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