Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ e737b32a

History | View | Annotate | Download (41.2 kB)

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
#include "qemu-common.h"
32

    
33
//#define DEBUG_MMU
34

    
35
static int cpu_x86_register (CPUX86State *env, const char *cpu_model);
36

    
37
static void add_flagname_to_bitmaps(char *flagname, uint32_t *features, 
38
                                    uint32_t *ext_features, 
39
                                    uint32_t *ext2_features, 
40
                                    uint32_t *ext3_features)
41
{
42
    int i;
43
    /* feature flags taken from "Intel Processor Identification and the CPUID
44
     * Instruction" and AMD's "CPUID Specification". In cases of disagreement 
45
     * about feature names, the Linux name is used. */
46
    static const char *feature_name[] = {
47
        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
48
        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
49
        "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
50
        "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
51
    };
52
    static const char *ext_feature_name[] = {
53
       "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
54
       "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
55
       NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
56
       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
57
    };
58
    static const char *ext2_feature_name[] = {
59
       "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
60
       "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mttr", "pge", "mca", "cmov",
61
       "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
62
       "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
63
    };
64
    static const char *ext3_feature_name[] = {
65
       "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
66
       "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
67
       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
68
       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
69
    };
70

    
71
    for ( i = 0 ; i < 32 ; i++ ) 
72
        if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
73
            *features |= 1 << i;
74
            return;
75
        }
76
    for ( i = 0 ; i < 32 ; i++ ) 
77
        if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
78
            *ext_features |= 1 << i;
79
            return;
80
        }
81
    for ( i = 0 ; i < 32 ; i++ ) 
82
        if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
83
            *ext2_features |= 1 << i;
84
            return;
85
        }
86
    for ( i = 0 ; i < 32 ; i++ ) 
87
        if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
88
            *ext3_features |= 1 << i;
89
            return;
90
        }
91
    fprintf(stderr, "CPU feature %s not found\n", flagname);
92
}
93

    
94
CPUX86State *cpu_x86_init(const char *cpu_model)
95
{
96
    CPUX86State *env;
97
    static int inited;
98

    
99
    env = qemu_mallocz(sizeof(CPUX86State));
100
    if (!env)
101
        return NULL;
102
    cpu_exec_init(env);
103
    env->cpu_model_str = cpu_model;
104

    
105
    /* init various static tables */
106
    if (!inited) {
107
        inited = 1;
108
        optimize_flags_init();
109
    }
110
    if (cpu_x86_register(env, cpu_model) < 0) {
111
        cpu_x86_close(env);
112
        return NULL;
113
    }
114
    cpu_reset(env);
115
#ifdef USE_KQEMU
116
    kqemu_init(env);
117
#endif
118
    return env;
119
}
120

    
121
typedef struct x86_def_t {
122
    const char *name;
123
    uint32_t level;
124
    uint32_t vendor1, vendor2, vendor3;
125
    int family;
126
    int model;
127
    int stepping;
128
    uint32_t features, ext_features, ext2_features, ext3_features;
129
    uint32_t xlevel;
130
    char model_id[48];
131
} x86_def_t;
132

    
133
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
134
#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
135
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX)
136
#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
137
          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
138
          CPUID_PSE36 | CPUID_FXSR)
139
#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
140
#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
141
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
142
          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
143
          CPUID_PAE | CPUID_SEP | CPUID_APIC)
144
static x86_def_t x86_defs[] = {
145
#ifdef TARGET_X86_64
146
    {
147
        .name = "qemu64",
148
        .level = 2,
149
        .vendor1 = CPUID_VENDOR_AMD_1,
150
        .vendor2 = CPUID_VENDOR_AMD_2,
151
        .vendor3 = CPUID_VENDOR_AMD_3,
152
        .family = 6,
153
        .model = 2,
154
        .stepping = 3,
155
        .features = PPRO_FEATURES | 
156
        /* these features are needed for Win64 and aren't fully implemented */
157
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
158
        /* this feature is needed for Solaris and isn't fully implemented */
159
            CPUID_PSE36,
160
        .ext_features = CPUID_EXT_SSE3,
161
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
162
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
163
            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
164
        .ext3_features = CPUID_EXT3_SVM,
165
        .xlevel = 0x8000000A,
166
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
167
    },
168
    {
169
        .name = "core2duo",
170
        /* original is on level 10 */
171
        .level = 5,
172
        .family = 6,
173
        .model = 15,
174
        .stepping = 11,
175
        /* the original CPU does have many more features that are
176
         * not implemented yet */
177
        .features = PPRO_FEATURES | 
178
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
179
            CPUID_PSE36,
180
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
181
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
182
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
183
        .xlevel = 0x8000000A,
184
        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
185
    },
186
#endif
187
    {
188
        .name = "qemu32",
189
        .level = 2,
190
        .family = 6,
191
        .model = 3,
192
        .stepping = 3,
193
        .features = PPRO_FEATURES,
194
        .ext_features = CPUID_EXT_SSE3,
195
        .xlevel = 0,
196
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
197
    },
198
    {
199
        .name = "486",
200
        .level = 0,
201
        .family = 4,
202
        .model = 0,
203
        .stepping = 0,
204
        .features = I486_FEATURES,
205
        .xlevel = 0,
206
    },
207
    {
208
        .name = "pentium",
209
        .level = 1,
210
        .family = 5,
211
        .model = 4,
212
        .stepping = 3,
213
        .features = PENTIUM_FEATURES,
214
        .xlevel = 0,
215
    },
216
    {
217
        .name = "pentium2",
218
        .level = 2,
219
        .family = 6,
220
        .model = 5,
221
        .stepping = 2,
222
        .features = PENTIUM2_FEATURES,
223
        .xlevel = 0,
224
    },
225
    {
226
        .name = "pentium3",
227
        .level = 2,
228
        .family = 6,
229
        .model = 7,
230
        .stepping = 3,
231
        .features = PENTIUM3_FEATURES,
232
        .xlevel = 0,
233
    },
234
    {
235
        .name = "athlon",
236
        .level = 2,
237
        .vendor1 = 0x68747541, /* "Auth" */
238
        .vendor2 = 0x69746e65, /* "enti" */
239
        .vendor3 = 0x444d4163, /* "cAMD" */
240
        .family = 6,
241
        .model = 2,
242
        .stepping = 3,
243
        .features = PPRO_FEATURES | PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
244
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
245
        .xlevel = 0x80000008,
246
        /* XXX: put another string ? */
247
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
248
    },
249
};
250

    
251
static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
252
{
253
    unsigned int i;
254
    x86_def_t *def;
255

    
256
    char *s = strdup(cpu_model);
257
    char *featurestr, *name = strtok(s, ",");
258
    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
259
    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
260
    int family = -1, model = -1, stepping = -1;
261

    
262
    def = NULL;
263
    for (i = 0; i < sizeof(x86_defs) / sizeof(x86_def_t); i++) {
264
        if (strcmp(name, x86_defs[i].name) == 0) {
265
            def = &x86_defs[i];
266
            break;
267
        }
268
    }
269
    if (!def)
270
        goto error;
271
    memcpy(x86_cpu_def, def, sizeof(*def));
272

    
273
    featurestr = strtok(NULL, ",");
274

    
275
    while (featurestr) {
276
        char *val;
277
        if (featurestr[0] == '+') {
278
            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
279
        } else if (featurestr[0] == '-') {
280
            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
281
        } else if ((val = strchr(featurestr, '='))) {
282
            *val = 0; val++;
283
            if (!strcmp(featurestr, "family")) {
284
                char *err;
285
                family = strtol(val, &err, 10);
286
                if (!*val || *err || family < 0) {
287
                    fprintf(stderr, "bad numerical value %s\n", val);
288
                    goto error;
289
                }
290
                x86_cpu_def->family = family;
291
            } else if (!strcmp(featurestr, "model")) {
292
                char *err;
293
                model = strtol(val, &err, 10);
294
                if (!*val || *err || model < 0 || model > 0xf) {
295
                    fprintf(stderr, "bad numerical value %s\n", val);
296
                    goto error;
297
                }
298
                x86_cpu_def->model = model;
299
            } else if (!strcmp(featurestr, "stepping")) {
300
                char *err;
301
                stepping = strtol(val, &err, 10);
302
                if (!*val || *err || stepping < 0 || stepping > 0xf) {
303
                    fprintf(stderr, "bad numerical value %s\n", val);
304
                    goto error;
305
                }
306
                x86_cpu_def->stepping = stepping;
307
            } else if (!strcmp(featurestr, "vendor")) {
308
                if (strlen(val) != 12) {
309
                    fprintf(stderr, "vendor string must be 12 chars long\n");
310
                    goto error;
311
                }
312
                x86_cpu_def->vendor1 = 0;
313
                x86_cpu_def->vendor2 = 0;
314
                x86_cpu_def->vendor3 = 0;
315
                for(i = 0; i < 4; i++) {
316
                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
317
                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
318
                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
319
                }
320
            } else if (!strcmp(featurestr, "model_id")) {
321
                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
322
                        val);
323
            } else {
324
                fprintf(stderr, "unrecognized feature %s\n", featurestr);
325
                goto error;
326
            }
327
        } else {
328
            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
329
            goto error;
330
        }
331
        featurestr = strtok(NULL, ",");
332
    }
333
    x86_cpu_def->features |= plus_features;
334
    x86_cpu_def->ext_features |= plus_ext_features;
335
    x86_cpu_def->ext2_features |= plus_ext2_features;
336
    x86_cpu_def->ext3_features |= plus_ext3_features;
337
    x86_cpu_def->features &= ~minus_features;
338
    x86_cpu_def->ext_features &= ~minus_ext_features;
339
    x86_cpu_def->ext2_features &= ~minus_ext2_features;
340
    x86_cpu_def->ext3_features &= ~minus_ext3_features;
341
    free(s);
342
    return 0;
343

    
344
error:
345
    free(s);
346
    return -1;
347
}
348

    
349
void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
350
{
351
    unsigned int i;
352

    
353
    for (i = 0; i < sizeof(x86_defs) / sizeof(x86_def_t); i++)
354
        (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
355
}
356

    
357
static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
358
{
359
    x86_def_t def1, *def = &def1;
360

    
361
    if (cpu_x86_find_by_name(def, cpu_model) < 0)
362
        return -1;
363
    if (def->vendor1) {
364
        env->cpuid_vendor1 = def->vendor1;
365
        env->cpuid_vendor2 = def->vendor2;
366
        env->cpuid_vendor3 = def->vendor3;
367
    } else {
368
        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
369
        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
370
        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
371
    }
372
    env->cpuid_level = def->level;
373
    env->cpuid_version = (def->family << 8) | (def->model << 4) | def->stepping;
374
    env->cpuid_features = def->features;
375
    env->pat = 0x0007040600070406ULL;
376
    env->cpuid_ext_features = def->ext_features;
377
    env->cpuid_ext2_features = def->ext2_features;
378
    env->cpuid_xlevel = def->xlevel;
379
    env->cpuid_ext3_features = def->ext3_features;
380
    {
381
        const char *model_id = def->model_id;
382
        int c, len, i;
383
        if (!model_id)
384
            model_id = "";
385
        len = strlen(model_id);
386
        for(i = 0; i < 48; i++) {
387
            if (i >= len)
388
                c = '\0';
389
            else
390
                c = (uint8_t)model_id[i];
391
            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
392
        }
393
    }
394
    return 0;
395
}
396

    
397
/* NOTE: must be called outside the CPU execute loop */
398
void cpu_reset(CPUX86State *env)
399
{
400
    int i;
401

    
402
    memset(env, 0, offsetof(CPUX86State, breakpoints));
403

    
404
    tlb_flush(env, 1);
405

    
406
    env->old_exception = -1;
407

    
408
    /* init to reset state */
409

    
410
#ifdef CONFIG_SOFTMMU
411
    env->hflags |= HF_SOFTMMU_MASK;
412
#endif
413
    env->hflags2 |= HF2_GIF_MASK;
414

    
415
    cpu_x86_update_cr0(env, 0x60000010);
416
    env->a20_mask = ~0x0;
417
    env->smbase = 0x30000;
418

    
419
    env->idt.limit = 0xffff;
420
    env->gdt.limit = 0xffff;
421
    env->ldt.limit = 0xffff;
422
    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
423
    env->tr.limit = 0xffff;
424
    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
425

    
426
    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
427
                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK | DESC_R_MASK);
428
    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
429
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
430
    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
431
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
432
    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
433
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
434
    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
435
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
436
    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
437
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
438

    
439
    env->eip = 0xfff0;
440
    env->regs[R_EDX] = env->cpuid_version;
441

    
442
    env->eflags = 0x2;
443

    
444
    /* FPU init */
445
    for(i = 0;i < 8; i++)
446
        env->fptags[i] = 1;
447
    env->fpuc = 0x37f;
448

    
449
    env->mxcsr = 0x1f80;
450
}
451

    
452
void cpu_x86_close(CPUX86State *env)
453
{
454
    qemu_free(env);
455
}
456

    
457
/***********************************************************/
458
/* x86 debug */
459

    
460
static const char *cc_op_str[] = {
461
    "DYNAMIC",
462
    "EFLAGS",
463

    
464
    "MULB",
465
    "MULW",
466
    "MULL",
467
    "MULQ",
468

    
469
    "ADDB",
470
    "ADDW",
471
    "ADDL",
472
    "ADDQ",
473

    
474
    "ADCB",
475
    "ADCW",
476
    "ADCL",
477
    "ADCQ",
478

    
479
    "SUBB",
480
    "SUBW",
481
    "SUBL",
482
    "SUBQ",
483

    
484
    "SBBB",
485
    "SBBW",
486
    "SBBL",
487
    "SBBQ",
488

    
489
    "LOGICB",
490
    "LOGICW",
491
    "LOGICL",
492
    "LOGICQ",
493

    
494
    "INCB",
495
    "INCW",
496
    "INCL",
497
    "INCQ",
498

    
499
    "DECB",
500
    "DECW",
501
    "DECL",
502
    "DECQ",
503

    
504
    "SHLB",
505
    "SHLW",
506
    "SHLL",
507
    "SHLQ",
508

    
509
    "SARB",
510
    "SARW",
511
    "SARL",
512
    "SARQ",
513
};
514

    
515
void cpu_dump_state(CPUState *env, FILE *f,
516
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
517
                    int flags)
518
{
519
    int eflags, i, nb;
520
    char cc_op_name[32];
521
    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
522

    
523
    eflags = env->eflags;
524
#ifdef TARGET_X86_64
525
    if (env->hflags & HF_CS64_MASK) {
526
        cpu_fprintf(f,
527
                    "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
528
                    "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
529
                    "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
530
                    "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
531
                    "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
532
                    env->regs[R_EAX],
533
                    env->regs[R_EBX],
534
                    env->regs[R_ECX],
535
                    env->regs[R_EDX],
536
                    env->regs[R_ESI],
537
                    env->regs[R_EDI],
538
                    env->regs[R_EBP],
539
                    env->regs[R_ESP],
540
                    env->regs[8],
541
                    env->regs[9],
542
                    env->regs[10],
543
                    env->regs[11],
544
                    env->regs[12],
545
                    env->regs[13],
546
                    env->regs[14],
547
                    env->regs[15],
548
                    env->eip, eflags,
549
                    eflags & DF_MASK ? 'D' : '-',
550
                    eflags & CC_O ? 'O' : '-',
551
                    eflags & CC_S ? 'S' : '-',
552
                    eflags & CC_Z ? 'Z' : '-',
553
                    eflags & CC_A ? 'A' : '-',
554
                    eflags & CC_P ? 'P' : '-',
555
                    eflags & CC_C ? 'C' : '-',
556
                    env->hflags & HF_CPL_MASK,
557
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
558
                    (int)(env->a20_mask >> 20) & 1,
559
                    (env->hflags >> HF_SMM_SHIFT) & 1,
560
                    env->halted);
561
    } else
562
#endif
563
    {
564
        cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
565
                    "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
566
                    "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
567
                    (uint32_t)env->regs[R_EAX],
568
                    (uint32_t)env->regs[R_EBX],
569
                    (uint32_t)env->regs[R_ECX],
570
                    (uint32_t)env->regs[R_EDX],
571
                    (uint32_t)env->regs[R_ESI],
572
                    (uint32_t)env->regs[R_EDI],
573
                    (uint32_t)env->regs[R_EBP],
574
                    (uint32_t)env->regs[R_ESP],
575
                    (uint32_t)env->eip, eflags,
576
                    eflags & DF_MASK ? 'D' : '-',
577
                    eflags & CC_O ? 'O' : '-',
578
                    eflags & CC_S ? 'S' : '-',
579
                    eflags & CC_Z ? 'Z' : '-',
580
                    eflags & CC_A ? 'A' : '-',
581
                    eflags & CC_P ? 'P' : '-',
582
                    eflags & CC_C ? 'C' : '-',
583
                    env->hflags & HF_CPL_MASK,
584
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
585
                    (int)(env->a20_mask >> 20) & 1,
586
                    (env->hflags >> HF_SMM_SHIFT) & 1,
587
                    env->halted);
588
    }
589

    
590
#ifdef TARGET_X86_64
591
    if (env->hflags & HF_LMA_MASK) {
592
        for(i = 0; i < 6; i++) {
593
            SegmentCache *sc = &env->segs[i];
594
            cpu_fprintf(f, "%s =%04x %016" PRIx64 " %08x %08x\n",
595
                        seg_name[i],
596
                        sc->selector,
597
                        sc->base,
598
                        sc->limit,
599
                        sc->flags);
600
        }
601
        cpu_fprintf(f, "LDT=%04x %016" PRIx64 " %08x %08x\n",
602
                    env->ldt.selector,
603
                    env->ldt.base,
604
                    env->ldt.limit,
605
                    env->ldt.flags);
606
        cpu_fprintf(f, "TR =%04x %016" PRIx64 " %08x %08x\n",
607
                    env->tr.selector,
608
                    env->tr.base,
609
                    env->tr.limit,
610
                    env->tr.flags);
611
        cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
612
                    env->gdt.base, env->gdt.limit);
613
        cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
614
                    env->idt.base, env->idt.limit);
615
        cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
616
                    (uint32_t)env->cr[0],
617
                    env->cr[2],
618
                    env->cr[3],
619
                    (uint32_t)env->cr[4]);
620
    } else
621
#endif
622
    {
623
        for(i = 0; i < 6; i++) {
624
            SegmentCache *sc = &env->segs[i];
625
            cpu_fprintf(f, "%s =%04x %08x %08x %08x\n",
626
                        seg_name[i],
627
                        sc->selector,
628
                        (uint32_t)sc->base,
629
                        sc->limit,
630
                        sc->flags);
631
        }
632
        cpu_fprintf(f, "LDT=%04x %08x %08x %08x\n",
633
                    env->ldt.selector,
634
                    (uint32_t)env->ldt.base,
635
                    env->ldt.limit,
636
                    env->ldt.flags);
637
        cpu_fprintf(f, "TR =%04x %08x %08x %08x\n",
638
                    env->tr.selector,
639
                    (uint32_t)env->tr.base,
640
                    env->tr.limit,
641
                    env->tr.flags);
642
        cpu_fprintf(f, "GDT=     %08x %08x\n",
643
                    (uint32_t)env->gdt.base, env->gdt.limit);
644
        cpu_fprintf(f, "IDT=     %08x %08x\n",
645
                    (uint32_t)env->idt.base, env->idt.limit);
646
        cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
647
                    (uint32_t)env->cr[0],
648
                    (uint32_t)env->cr[2],
649
                    (uint32_t)env->cr[3],
650
                    (uint32_t)env->cr[4]);
651
    }
652
    if (flags & X86_DUMP_CCOP) {
653
        if ((unsigned)env->cc_op < CC_OP_NB)
654
            snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
655
        else
656
            snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
657
#ifdef TARGET_X86_64
658
        if (env->hflags & HF_CS64_MASK) {
659
            cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
660
                        env->cc_src, env->cc_dst,
661
                        cc_op_name);
662
        } else
663
#endif
664
        {
665
            cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
666
                        (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
667
                        cc_op_name);
668
        }
669
    }
670
    if (flags & X86_DUMP_FPU) {
671
        int fptag;
672
        fptag = 0;
673
        for(i = 0; i < 8; i++) {
674
            fptag |= ((!env->fptags[i]) << i);
675
        }
676
        cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
677
                    env->fpuc,
678
                    (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
679
                    env->fpstt,
680
                    fptag,
681
                    env->mxcsr);
682
        for(i=0;i<8;i++) {
683
#if defined(USE_X86LDOUBLE)
684
            union {
685
                long double d;
686
                struct {
687
                    uint64_t lower;
688
                    uint16_t upper;
689
                } l;
690
            } tmp;
691
            tmp.d = env->fpregs[i].d;
692
            cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
693
                        i, tmp.l.lower, tmp.l.upper);
694
#else
695
            cpu_fprintf(f, "FPR%d=%016" PRIx64,
696
                        i, env->fpregs[i].mmx.q);
697
#endif
698
            if ((i & 1) == 1)
699
                cpu_fprintf(f, "\n");
700
            else
701
                cpu_fprintf(f, " ");
702
        }
703
        if (env->hflags & HF_CS64_MASK)
704
            nb = 16;
705
        else
706
            nb = 8;
707
        for(i=0;i<nb;i++) {
708
            cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
709
                        i,
710
                        env->xmm_regs[i].XMM_L(3),
711
                        env->xmm_regs[i].XMM_L(2),
712
                        env->xmm_regs[i].XMM_L(1),
713
                        env->xmm_regs[i].XMM_L(0));
714
            if ((i & 1) == 1)
715
                cpu_fprintf(f, "\n");
716
            else
717
                cpu_fprintf(f, " ");
718
        }
719
    }
720
}
721

    
722
/***********************************************************/
723
/* x86 mmu */
724
/* XXX: add PGE support */
725

    
726
void cpu_x86_set_a20(CPUX86State *env, int a20_state)
727
{
728
    a20_state = (a20_state != 0);
729
    if (a20_state != ((env->a20_mask >> 20) & 1)) {
730
#if defined(DEBUG_MMU)
731
        printf("A20 update: a20=%d\n", a20_state);
732
#endif
733
        /* if the cpu is currently executing code, we must unlink it and
734
           all the potentially executing TB */
735
        cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
736

    
737
        /* when a20 is changed, all the MMU mappings are invalid, so
738
           we must flush everything */
739
        tlb_flush(env, 1);
740
        env->a20_mask = (~0x100000) | (a20_state << 20);
741
    }
742
}
743

    
744
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
745
{
746
    int pe_state;
747

    
748
#if defined(DEBUG_MMU)
749
    printf("CR0 update: CR0=0x%08x\n", new_cr0);
750
#endif
751
    if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
752
        (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
753
        tlb_flush(env, 1);
754
    }
755

    
756
#ifdef TARGET_X86_64
757
    if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
758
        (env->efer & MSR_EFER_LME)) {
759
        /* enter in long mode */
760
        /* XXX: generate an exception */
761
        if (!(env->cr[4] & CR4_PAE_MASK))
762
            return;
763
        env->efer |= MSR_EFER_LMA;
764
        env->hflags |= HF_LMA_MASK;
765
    } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
766
               (env->efer & MSR_EFER_LMA)) {
767
        /* exit long mode */
768
        env->efer &= ~MSR_EFER_LMA;
769
        env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
770
        env->eip &= 0xffffffff;
771
    }
772
#endif
773
    env->cr[0] = new_cr0 | CR0_ET_MASK;
774

    
775
    /* update PE flag in hidden flags */
776
    pe_state = (env->cr[0] & CR0_PE_MASK);
777
    env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
778
    /* ensure that ADDSEG is always set in real mode */
779
    env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
780
    /* update FPU flags */
781
    env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
782
        ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
783
}
784

    
785
/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
786
   the PDPT */
787
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
788
{
789
    env->cr[3] = new_cr3;
790
    if (env->cr[0] & CR0_PG_MASK) {
791
#if defined(DEBUG_MMU)
792
        printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
793
#endif
794
        tlb_flush(env, 0);
795
    }
796
}
797

    
798
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
799
{
800
#if defined(DEBUG_MMU)
801
    printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
802
#endif
803
    if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
804
        (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
805
        tlb_flush(env, 1);
806
    }
807
    /* SSE handling */
808
    if (!(env->cpuid_features & CPUID_SSE))
809
        new_cr4 &= ~CR4_OSFXSR_MASK;
810
    if (new_cr4 & CR4_OSFXSR_MASK)
811
        env->hflags |= HF_OSFXSR_MASK;
812
    else
813
        env->hflags &= ~HF_OSFXSR_MASK;
814

    
815
    env->cr[4] = new_cr4;
816
}
817

    
818
/* XXX: also flush 4MB pages */
819
void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr)
820
{
821
    tlb_flush_page(env, addr);
822
}
823

    
824
#if defined(CONFIG_USER_ONLY)
825

    
826
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
827
                             int is_write, int mmu_idx, int is_softmmu)
828
{
829
    /* user mode only emulation */
830
    is_write &= 1;
831
    env->cr[2] = addr;
832
    env->error_code = (is_write << PG_ERROR_W_BIT);
833
    env->error_code |= PG_ERROR_U_MASK;
834
    env->exception_index = EXCP0E_PAGE;
835
    return 1;
836
}
837

    
838
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
839
{
840
    return addr;
841
}
842

    
843
#else
844

    
845
/* XXX: This value should match the one returned by CPUID
846
 * and in exec.c */
847
#if defined(USE_KQEMU)
848
#define PHYS_ADDR_MASK 0xfffff000LL
849
#else
850
# if defined(TARGET_X86_64)
851
# define PHYS_ADDR_MASK 0xfffffff000LL
852
# else
853
# define PHYS_ADDR_MASK 0xffffff000LL
854
# endif
855
#endif
856

    
857
/* return value:
858
   -1 = cannot handle fault
859
   0  = nothing more to do
860
   1  = generate PF fault
861
   2  = soft MMU activation required for this block
862
*/
863
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
864
                             int is_write1, int mmu_idx, int is_softmmu)
865
{
866
    uint64_t ptep, pte;
867
    target_ulong pde_addr, pte_addr;
868
    int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
869
    target_phys_addr_t paddr;
870
    uint32_t page_offset;
871
    target_ulong vaddr, virt_addr;
872

    
873
    is_user = mmu_idx == MMU_USER_IDX;
874
#if defined(DEBUG_MMU)
875
    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
876
           addr, is_write1, is_user, env->eip);
877
#endif
878
    is_write = is_write1 & 1;
879

    
880
    if (!(env->cr[0] & CR0_PG_MASK)) {
881
        pte = addr;
882
        virt_addr = addr & TARGET_PAGE_MASK;
883
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
884
        page_size = 4096;
885
        goto do_mapping;
886
    }
887

    
888
    if (env->cr[4] & CR4_PAE_MASK) {
889
        uint64_t pde, pdpe;
890
        target_ulong pdpe_addr;
891

    
892
#ifdef TARGET_X86_64
893
        if (env->hflags & HF_LMA_MASK) {
894
            uint64_t pml4e_addr, pml4e;
895
            int32_t sext;
896

    
897
            /* test virtual address sign extension */
898
            sext = (int64_t)addr >> 47;
899
            if (sext != 0 && sext != -1) {
900
                env->error_code = 0;
901
                env->exception_index = EXCP0D_GPF;
902
                return 1;
903
            }
904

    
905
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
906
                env->a20_mask;
907
            pml4e = ldq_phys(pml4e_addr);
908
            if (!(pml4e & PG_PRESENT_MASK)) {
909
                error_code = 0;
910
                goto do_fault;
911
            }
912
            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
913
                error_code = PG_ERROR_RSVD_MASK;
914
                goto do_fault;
915
            }
916
            if (!(pml4e & PG_ACCESSED_MASK)) {
917
                pml4e |= PG_ACCESSED_MASK;
918
                stl_phys_notdirty(pml4e_addr, pml4e);
919
            }
920
            ptep = pml4e ^ PG_NX_MASK;
921
            pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
922
                env->a20_mask;
923
            pdpe = ldq_phys(pdpe_addr);
924
            if (!(pdpe & PG_PRESENT_MASK)) {
925
                error_code = 0;
926
                goto do_fault;
927
            }
928
            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
929
                error_code = PG_ERROR_RSVD_MASK;
930
                goto do_fault;
931
            }
932
            ptep &= pdpe ^ PG_NX_MASK;
933
            if (!(pdpe & PG_ACCESSED_MASK)) {
934
                pdpe |= PG_ACCESSED_MASK;
935
                stl_phys_notdirty(pdpe_addr, pdpe);
936
            }
937
        } else
938
#endif
939
        {
940
            /* XXX: load them when cr3 is loaded ? */
941
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
942
                env->a20_mask;
943
            pdpe = ldq_phys(pdpe_addr);
944
            if (!(pdpe & PG_PRESENT_MASK)) {
945
                error_code = 0;
946
                goto do_fault;
947
            }
948
            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
949
        }
950

    
951
        pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
952
            env->a20_mask;
953
        pde = ldq_phys(pde_addr);
954
        if (!(pde & PG_PRESENT_MASK)) {
955
            error_code = 0;
956
            goto do_fault;
957
        }
958
        if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
959
            error_code = PG_ERROR_RSVD_MASK;
960
            goto do_fault;
961
        }
962
        ptep &= pde ^ PG_NX_MASK;
963
        if (pde & PG_PSE_MASK) {
964
            /* 2 MB page */
965
            page_size = 2048 * 1024;
966
            ptep ^= PG_NX_MASK;
967
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
968
                goto do_fault_protect;
969
            if (is_user) {
970
                if (!(ptep & PG_USER_MASK))
971
                    goto do_fault_protect;
972
                if (is_write && !(ptep & PG_RW_MASK))
973
                    goto do_fault_protect;
974
            } else {
975
                if ((env->cr[0] & CR0_WP_MASK) &&
976
                    is_write && !(ptep & PG_RW_MASK))
977
                    goto do_fault_protect;
978
            }
979
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
980
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
981
                pde |= PG_ACCESSED_MASK;
982
                if (is_dirty)
983
                    pde |= PG_DIRTY_MASK;
984
                stl_phys_notdirty(pde_addr, pde);
985
            }
986
            /* align to page_size */
987
            pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
988
            virt_addr = addr & ~(page_size - 1);
989
        } else {
990
            /* 4 KB page */
991
            if (!(pde & PG_ACCESSED_MASK)) {
992
                pde |= PG_ACCESSED_MASK;
993
                stl_phys_notdirty(pde_addr, pde);
994
            }
995
            pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
996
                env->a20_mask;
997
            pte = ldq_phys(pte_addr);
998
            if (!(pte & PG_PRESENT_MASK)) {
999
                error_code = 0;
1000
                goto do_fault;
1001
            }
1002
            if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
1003
                error_code = PG_ERROR_RSVD_MASK;
1004
                goto do_fault;
1005
            }
1006
            /* combine pde and pte nx, user and rw protections */
1007
            ptep &= pte ^ PG_NX_MASK;
1008
            ptep ^= PG_NX_MASK;
1009
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
1010
                goto do_fault_protect;
1011
            if (is_user) {
1012
                if (!(ptep & PG_USER_MASK))
1013
                    goto do_fault_protect;
1014
                if (is_write && !(ptep & PG_RW_MASK))
1015
                    goto do_fault_protect;
1016
            } else {
1017
                if ((env->cr[0] & CR0_WP_MASK) &&
1018
                    is_write && !(ptep & PG_RW_MASK))
1019
                    goto do_fault_protect;
1020
            }
1021
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1022
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1023
                pte |= PG_ACCESSED_MASK;
1024
                if (is_dirty)
1025
                    pte |= PG_DIRTY_MASK;
1026
                stl_phys_notdirty(pte_addr, pte);
1027
            }
1028
            page_size = 4096;
1029
            virt_addr = addr & ~0xfff;
1030
            pte = pte & (PHYS_ADDR_MASK | 0xfff);
1031
        }
1032
    } else {
1033
        uint32_t pde;
1034

    
1035
        /* page directory entry */
1036
        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
1037
            env->a20_mask;
1038
        pde = ldl_phys(pde_addr);
1039
        if (!(pde & PG_PRESENT_MASK)) {
1040
            error_code = 0;
1041
            goto do_fault;
1042
        }
1043
        /* if PSE bit is set, then we use a 4MB page */
1044
        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1045
            page_size = 4096 * 1024;
1046
            if (is_user) {
1047
                if (!(pde & PG_USER_MASK))
1048
                    goto do_fault_protect;
1049
                if (is_write && !(pde & PG_RW_MASK))
1050
                    goto do_fault_protect;
1051
            } else {
1052
                if ((env->cr[0] & CR0_WP_MASK) &&
1053
                    is_write && !(pde & PG_RW_MASK))
1054
                    goto do_fault_protect;
1055
            }
1056
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
1057
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
1058
                pde |= PG_ACCESSED_MASK;
1059
                if (is_dirty)
1060
                    pde |= PG_DIRTY_MASK;
1061
                stl_phys_notdirty(pde_addr, pde);
1062
            }
1063

    
1064
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1065
            ptep = pte;
1066
            virt_addr = addr & ~(page_size - 1);
1067
        } else {
1068
            if (!(pde & PG_ACCESSED_MASK)) {
1069
                pde |= PG_ACCESSED_MASK;
1070
                stl_phys_notdirty(pde_addr, pde);
1071
            }
1072

    
1073
            /* page directory entry */
1074
            pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
1075
                env->a20_mask;
1076
            pte = ldl_phys(pte_addr);
1077
            if (!(pte & PG_PRESENT_MASK)) {
1078
                error_code = 0;
1079
                goto do_fault;
1080
            }
1081
            /* combine pde and pte user and rw protections */
1082
            ptep = pte & pde;
1083
            if (is_user) {
1084
                if (!(ptep & PG_USER_MASK))
1085
                    goto do_fault_protect;
1086
                if (is_write && !(ptep & PG_RW_MASK))
1087
                    goto do_fault_protect;
1088
            } else {
1089
                if ((env->cr[0] & CR0_WP_MASK) &&
1090
                    is_write && !(ptep & PG_RW_MASK))
1091
                    goto do_fault_protect;
1092
            }
1093
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1094
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1095
                pte |= PG_ACCESSED_MASK;
1096
                if (is_dirty)
1097
                    pte |= PG_DIRTY_MASK;
1098
                stl_phys_notdirty(pte_addr, pte);
1099
            }
1100
            page_size = 4096;
1101
            virt_addr = addr & ~0xfff;
1102
        }
1103
    }
1104
    /* the page can be put in the TLB */
1105
    prot = PAGE_READ;
1106
    if (!(ptep & PG_NX_MASK))
1107
        prot |= PAGE_EXEC;
1108
    if (pte & PG_DIRTY_MASK) {
1109
        /* only set write access if already dirty... otherwise wait
1110
           for dirty access */
1111
        if (is_user) {
1112
            if (ptep & PG_RW_MASK)
1113
                prot |= PAGE_WRITE;
1114
        } else {
1115
            if (!(env->cr[0] & CR0_WP_MASK) ||
1116
                (ptep & PG_RW_MASK))
1117
                prot |= PAGE_WRITE;
1118
        }
1119
    }
1120
 do_mapping:
1121
    pte = pte & env->a20_mask;
1122

    
1123
    /* Even if 4MB pages, we map only one 4KB page in the cache to
1124
       avoid filling it too fast */
1125
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1126
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1127
    vaddr = virt_addr + page_offset;
1128

    
1129
    ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
1130
    return ret;
1131
 do_fault_protect:
1132
    error_code = PG_ERROR_P_MASK;
1133
 do_fault:
1134
    error_code |= (is_write << PG_ERROR_W_BIT);
1135
    if (is_user)
1136
        error_code |= PG_ERROR_U_MASK;
1137
    if (is_write1 == 2 &&
1138
        (env->efer & MSR_EFER_NXE) &&
1139
        (env->cr[4] & CR4_PAE_MASK))
1140
        error_code |= PG_ERROR_I_D_MASK;
1141
    if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
1142
        /* cr2 is not modified in case of exceptions */
1143
        stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 
1144
                 addr);
1145
    } else {
1146
        env->cr[2] = addr;
1147
    }
1148
    env->error_code = error_code;
1149
    env->exception_index = EXCP0E_PAGE;
1150
    return 1;
1151
}
1152

    
1153
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1154
{
1155
    target_ulong pde_addr, pte_addr;
1156
    uint64_t pte;
1157
    target_phys_addr_t paddr;
1158
    uint32_t page_offset;
1159
    int page_size;
1160

    
1161
    if (env->cr[4] & CR4_PAE_MASK) {
1162
        target_ulong pdpe_addr;
1163
        uint64_t pde, pdpe;
1164

    
1165
#ifdef TARGET_X86_64
1166
        if (env->hflags & HF_LMA_MASK) {
1167
            uint64_t pml4e_addr, pml4e;
1168
            int32_t sext;
1169

    
1170
            /* test virtual address sign extension */
1171
            sext = (int64_t)addr >> 47;
1172
            if (sext != 0 && sext != -1)
1173
                return -1;
1174

    
1175
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
1176
                env->a20_mask;
1177
            pml4e = ldq_phys(pml4e_addr);
1178
            if (!(pml4e & PG_PRESENT_MASK))
1179
                return -1;
1180

    
1181
            pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
1182
                env->a20_mask;
1183
            pdpe = ldq_phys(pdpe_addr);
1184
            if (!(pdpe & PG_PRESENT_MASK))
1185
                return -1;
1186
        } else
1187
#endif
1188
        {
1189
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1190
                env->a20_mask;
1191
            pdpe = ldq_phys(pdpe_addr);
1192
            if (!(pdpe & PG_PRESENT_MASK))
1193
                return -1;
1194
        }
1195

    
1196
        pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
1197
            env->a20_mask;
1198
        pde = ldq_phys(pde_addr);
1199
        if (!(pde & PG_PRESENT_MASK)) {
1200
            return -1;
1201
        }
1202
        if (pde & PG_PSE_MASK) {
1203
            /* 2 MB page */
1204
            page_size = 2048 * 1024;
1205
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1206
        } else {
1207
            /* 4 KB page */
1208
            pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
1209
                env->a20_mask;
1210
            page_size = 4096;
1211
            pte = ldq_phys(pte_addr);
1212
        }
1213
        if (!(pte & PG_PRESENT_MASK))
1214
            return -1;
1215
    } else {
1216
        uint32_t pde;
1217

    
1218
        if (!(env->cr[0] & CR0_PG_MASK)) {
1219
            pte = addr;
1220
            page_size = 4096;
1221
        } else {
1222
            /* page directory entry */
1223
            pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
1224
            pde = ldl_phys(pde_addr);
1225
            if (!(pde & PG_PRESENT_MASK))
1226
                return -1;
1227
            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1228
                pte = pde & ~0x003ff000; /* align to 4MB */
1229
                page_size = 4096 * 1024;
1230
            } else {
1231
                /* page directory entry */
1232
                pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
1233
                pte = ldl_phys(pte_addr);
1234
                if (!(pte & PG_PRESENT_MASK))
1235
                    return -1;
1236
                page_size = 4096;
1237
            }
1238
        }
1239
        pte = pte & env->a20_mask;
1240
    }
1241

    
1242
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1243
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1244
    return paddr;
1245
}
1246
#endif /* !CONFIG_USER_ONLY */