Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ 853f6931

History | View | Annotate | Download (43 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
        .level = 10,
171
        .family = 6,
172
        .model = 15,
173
        .stepping = 11,
174
        /* The original CPU also implements these features:
175
               CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
176
               CPUID_TM, CPUID_PBE */
177
        .features = PPRO_FEATURES |
178
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
179
            CPUID_PSE36,
180
        /* The original CPU also implements these ext features:
181
               CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
182
               CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
183
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
184
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
185
        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
186
        .xlevel = 0x80000008,
187
        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
188
    },
189
#endif
190
    {
191
        .name = "qemu32",
192
        .level = 2,
193
        .family = 6,
194
        .model = 3,
195
        .stepping = 3,
196
        .features = PPRO_FEATURES,
197
        .ext_features = CPUID_EXT_SSE3,
198
        .xlevel = 0,
199
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
200
    },
201
    {
202
        .name = "coreduo",
203
        .level = 10,
204
        .family = 6,
205
        .model = 14,
206
        .stepping = 8,
207
        /* The original CPU also implements these features:
208
               CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
209
               CPUID_TM, CPUID_PBE */
210
        .features = PPRO_FEATURES | CPUID_VME |
211
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
212
        /* The original CPU also implements these ext features:
213
               CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
214
               CPUID_EXT_PDCM */
215
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
216
        .ext2_features = CPUID_EXT2_NX,
217
        .xlevel = 0x80000008,
218
        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
219
    },
220
    {
221
        .name = "486",
222
        .level = 0,
223
        .family = 4,
224
        .model = 0,
225
        .stepping = 0,
226
        .features = I486_FEATURES,
227
        .xlevel = 0,
228
    },
229
    {
230
        .name = "pentium",
231
        .level = 1,
232
        .family = 5,
233
        .model = 4,
234
        .stepping = 3,
235
        .features = PENTIUM_FEATURES,
236
        .xlevel = 0,
237
    },
238
    {
239
        .name = "pentium2",
240
        .level = 2,
241
        .family = 6,
242
        .model = 5,
243
        .stepping = 2,
244
        .features = PENTIUM2_FEATURES,
245
        .xlevel = 0,
246
    },
247
    {
248
        .name = "pentium3",
249
        .level = 2,
250
        .family = 6,
251
        .model = 7,
252
        .stepping = 3,
253
        .features = PENTIUM3_FEATURES,
254
        .xlevel = 0,
255
    },
256
    {
257
        .name = "athlon",
258
        .level = 2,
259
        .vendor1 = 0x68747541, /* "Auth" */
260
        .vendor2 = 0x69746e65, /* "enti" */
261
        .vendor3 = 0x444d4163, /* "cAMD" */
262
        .family = 6,
263
        .model = 2,
264
        .stepping = 3,
265
        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
266
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
267
        .xlevel = 0x80000008,
268
        /* XXX: put another string ? */
269
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
270
    },
271
    {
272
        .name = "n270",
273
        /* original is on level 10 */
274
        .level = 5,
275
        .family = 6,
276
        .model = 28,
277
        .stepping = 2,
278
        .features = PPRO_FEATURES |
279
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
280
            /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
281
             * CPUID_HT | CPUID_TM | CPUID_PBE */
282
            /* Some CPUs got no CPUID_SEP */
283
        .ext_features = CPUID_EXT_MONITOR |
284
            CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
285
            /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
286
             * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
287
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
288
        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
289
        .xlevel = 0x8000000A,
290
        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
291
    },
292
};
293

    
294
static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
295
{
296
    unsigned int i;
297
    x86_def_t *def;
298

    
299
    char *s = strdup(cpu_model);
300
    char *featurestr, *name = strtok(s, ",");
301
    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
302
    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
303
    int family = -1, model = -1, stepping = -1;
304

    
305
    def = NULL;
306
    for (i = 0; i < sizeof(x86_defs) / sizeof(x86_def_t); i++) {
307
        if (strcmp(name, x86_defs[i].name) == 0) {
308
            def = &x86_defs[i];
309
            break;
310
        }
311
    }
312
    if (!def)
313
        goto error;
314
    memcpy(x86_cpu_def, def, sizeof(*def));
315

    
316
    featurestr = strtok(NULL, ",");
317

    
318
    while (featurestr) {
319
        char *val;
320
        if (featurestr[0] == '+') {
321
            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
322
        } else if (featurestr[0] == '-') {
323
            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
324
        } else if ((val = strchr(featurestr, '='))) {
325
            *val = 0; val++;
326
            if (!strcmp(featurestr, "family")) {
327
                char *err;
328
                family = strtol(val, &err, 10);
329
                if (!*val || *err || family < 0) {
330
                    fprintf(stderr, "bad numerical value %s\n", val);
331
                    goto error;
332
                }
333
                x86_cpu_def->family = family;
334
            } else if (!strcmp(featurestr, "model")) {
335
                char *err;
336
                model = strtol(val, &err, 10);
337
                if (!*val || *err || model < 0 || model > 0xf) {
338
                    fprintf(stderr, "bad numerical value %s\n", val);
339
                    goto error;
340
                }
341
                x86_cpu_def->model = model;
342
            } else if (!strcmp(featurestr, "stepping")) {
343
                char *err;
344
                stepping = strtol(val, &err, 10);
345
                if (!*val || *err || stepping < 0 || stepping > 0xf) {
346
                    fprintf(stderr, "bad numerical value %s\n", val);
347
                    goto error;
348
                }
349
                x86_cpu_def->stepping = stepping;
350
            } else if (!strcmp(featurestr, "vendor")) {
351
                if (strlen(val) != 12) {
352
                    fprintf(stderr, "vendor string must be 12 chars long\n");
353
                    goto error;
354
                }
355
                x86_cpu_def->vendor1 = 0;
356
                x86_cpu_def->vendor2 = 0;
357
                x86_cpu_def->vendor3 = 0;
358
                for(i = 0; i < 4; i++) {
359
                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
360
                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
361
                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
362
                }
363
            } else if (!strcmp(featurestr, "model_id")) {
364
                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
365
                        val);
366
            } else {
367
                fprintf(stderr, "unrecognized feature %s\n", featurestr);
368
                goto error;
369
            }
370
        } else {
371
            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
372
            goto error;
373
        }
374
        featurestr = strtok(NULL, ",");
375
    }
376
    x86_cpu_def->features |= plus_features;
377
    x86_cpu_def->ext_features |= plus_ext_features;
378
    x86_cpu_def->ext2_features |= plus_ext2_features;
379
    x86_cpu_def->ext3_features |= plus_ext3_features;
380
    x86_cpu_def->features &= ~minus_features;
381
    x86_cpu_def->ext_features &= ~minus_ext_features;
382
    x86_cpu_def->ext2_features &= ~minus_ext2_features;
383
    x86_cpu_def->ext3_features &= ~minus_ext3_features;
384
    free(s);
385
    return 0;
386

    
387
error:
388
    free(s);
389
    return -1;
390
}
391

    
392
void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
393
{
394
    unsigned int i;
395

    
396
    for (i = 0; i < sizeof(x86_defs) / sizeof(x86_def_t); i++)
397
        (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
398
}
399

    
400
static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
401
{
402
    x86_def_t def1, *def = &def1;
403

    
404
    if (cpu_x86_find_by_name(def, cpu_model) < 0)
405
        return -1;
406
    if (def->vendor1) {
407
        env->cpuid_vendor1 = def->vendor1;
408
        env->cpuid_vendor2 = def->vendor2;
409
        env->cpuid_vendor3 = def->vendor3;
410
    } else {
411
        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
412
        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
413
        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
414
    }
415
    env->cpuid_level = def->level;
416
    env->cpuid_version = (def->family << 8) | (def->model << 4) | def->stepping;
417
    env->cpuid_features = def->features;
418
    env->pat = 0x0007040600070406ULL;
419
    env->cpuid_ext_features = def->ext_features;
420
    env->cpuid_ext2_features = def->ext2_features;
421
    env->cpuid_xlevel = def->xlevel;
422
    env->cpuid_ext3_features = def->ext3_features;
423
    {
424
        const char *model_id = def->model_id;
425
        int c, len, i;
426
        if (!model_id)
427
            model_id = "";
428
        len = strlen(model_id);
429
        for(i = 0; i < 48; i++) {
430
            if (i >= len)
431
                c = '\0';
432
            else
433
                c = (uint8_t)model_id[i];
434
            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
435
        }
436
    }
437
    return 0;
438
}
439

    
440
/* NOTE: must be called outside the CPU execute loop */
441
void cpu_reset(CPUX86State *env)
442
{
443
    int i;
444

    
445
    memset(env, 0, offsetof(CPUX86State, breakpoints));
446

    
447
    tlb_flush(env, 1);
448

    
449
    env->old_exception = -1;
450

    
451
    /* init to reset state */
452

    
453
#ifdef CONFIG_SOFTMMU
454
    env->hflags |= HF_SOFTMMU_MASK;
455
#endif
456
    env->hflags2 |= HF2_GIF_MASK;
457

    
458
    cpu_x86_update_cr0(env, 0x60000010);
459
    env->a20_mask = ~0x0;
460
    env->smbase = 0x30000;
461

    
462
    env->idt.limit = 0xffff;
463
    env->gdt.limit = 0xffff;
464
    env->ldt.limit = 0xffff;
465
    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
466
    env->tr.limit = 0xffff;
467
    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
468

    
469
    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
470
                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK | DESC_R_MASK);
471
    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
472
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
473
    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
474
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
475
    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
476
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
477
    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
478
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
479
    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
480
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
481

    
482
    env->eip = 0xfff0;
483
    env->regs[R_EDX] = env->cpuid_version;
484

    
485
    env->eflags = 0x2;
486

    
487
    /* FPU init */
488
    for(i = 0;i < 8; i++)
489
        env->fptags[i] = 1;
490
    env->fpuc = 0x37f;
491

    
492
    env->mxcsr = 0x1f80;
493
}
494

    
495
void cpu_x86_close(CPUX86State *env)
496
{
497
    qemu_free(env);
498
}
499

    
500
/***********************************************************/
501
/* x86 debug */
502

    
503
static const char *cc_op_str[] = {
504
    "DYNAMIC",
505
    "EFLAGS",
506

    
507
    "MULB",
508
    "MULW",
509
    "MULL",
510
    "MULQ",
511

    
512
    "ADDB",
513
    "ADDW",
514
    "ADDL",
515
    "ADDQ",
516

    
517
    "ADCB",
518
    "ADCW",
519
    "ADCL",
520
    "ADCQ",
521

    
522
    "SUBB",
523
    "SUBW",
524
    "SUBL",
525
    "SUBQ",
526

    
527
    "SBBB",
528
    "SBBW",
529
    "SBBL",
530
    "SBBQ",
531

    
532
    "LOGICB",
533
    "LOGICW",
534
    "LOGICL",
535
    "LOGICQ",
536

    
537
    "INCB",
538
    "INCW",
539
    "INCL",
540
    "INCQ",
541

    
542
    "DECB",
543
    "DECW",
544
    "DECL",
545
    "DECQ",
546

    
547
    "SHLB",
548
    "SHLW",
549
    "SHLL",
550
    "SHLQ",
551

    
552
    "SARB",
553
    "SARW",
554
    "SARL",
555
    "SARQ",
556
};
557

    
558
void cpu_dump_state(CPUState *env, FILE *f,
559
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
560
                    int flags)
561
{
562
    int eflags, i, nb;
563
    char cc_op_name[32];
564
    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
565

    
566
    eflags = env->eflags;
567
#ifdef TARGET_X86_64
568
    if (env->hflags & HF_CS64_MASK) {
569
        cpu_fprintf(f,
570
                    "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
571
                    "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
572
                    "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
573
                    "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
574
                    "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
575
                    env->regs[R_EAX],
576
                    env->regs[R_EBX],
577
                    env->regs[R_ECX],
578
                    env->regs[R_EDX],
579
                    env->regs[R_ESI],
580
                    env->regs[R_EDI],
581
                    env->regs[R_EBP],
582
                    env->regs[R_ESP],
583
                    env->regs[8],
584
                    env->regs[9],
585
                    env->regs[10],
586
                    env->regs[11],
587
                    env->regs[12],
588
                    env->regs[13],
589
                    env->regs[14],
590
                    env->regs[15],
591
                    env->eip, eflags,
592
                    eflags & DF_MASK ? 'D' : '-',
593
                    eflags & CC_O ? 'O' : '-',
594
                    eflags & CC_S ? 'S' : '-',
595
                    eflags & CC_Z ? 'Z' : '-',
596
                    eflags & CC_A ? 'A' : '-',
597
                    eflags & CC_P ? 'P' : '-',
598
                    eflags & CC_C ? 'C' : '-',
599
                    env->hflags & HF_CPL_MASK,
600
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
601
                    (int)(env->a20_mask >> 20) & 1,
602
                    (env->hflags >> HF_SMM_SHIFT) & 1,
603
                    env->halted);
604
    } else
605
#endif
606
    {
607
        cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
608
                    "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
609
                    "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
610
                    (uint32_t)env->regs[R_EAX],
611
                    (uint32_t)env->regs[R_EBX],
612
                    (uint32_t)env->regs[R_ECX],
613
                    (uint32_t)env->regs[R_EDX],
614
                    (uint32_t)env->regs[R_ESI],
615
                    (uint32_t)env->regs[R_EDI],
616
                    (uint32_t)env->regs[R_EBP],
617
                    (uint32_t)env->regs[R_ESP],
618
                    (uint32_t)env->eip, eflags,
619
                    eflags & DF_MASK ? 'D' : '-',
620
                    eflags & CC_O ? 'O' : '-',
621
                    eflags & CC_S ? 'S' : '-',
622
                    eflags & CC_Z ? 'Z' : '-',
623
                    eflags & CC_A ? 'A' : '-',
624
                    eflags & CC_P ? 'P' : '-',
625
                    eflags & CC_C ? 'C' : '-',
626
                    env->hflags & HF_CPL_MASK,
627
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
628
                    (int)(env->a20_mask >> 20) & 1,
629
                    (env->hflags >> HF_SMM_SHIFT) & 1,
630
                    env->halted);
631
    }
632

    
633
#ifdef TARGET_X86_64
634
    if (env->hflags & HF_LMA_MASK) {
635
        for(i = 0; i < 6; i++) {
636
            SegmentCache *sc = &env->segs[i];
637
            cpu_fprintf(f, "%s =%04x %016" PRIx64 " %08x %08x\n",
638
                        seg_name[i],
639
                        sc->selector,
640
                        sc->base,
641
                        sc->limit,
642
                        sc->flags);
643
        }
644
        cpu_fprintf(f, "LDT=%04x %016" PRIx64 " %08x %08x\n",
645
                    env->ldt.selector,
646
                    env->ldt.base,
647
                    env->ldt.limit,
648
                    env->ldt.flags);
649
        cpu_fprintf(f, "TR =%04x %016" PRIx64 " %08x %08x\n",
650
                    env->tr.selector,
651
                    env->tr.base,
652
                    env->tr.limit,
653
                    env->tr.flags);
654
        cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
655
                    env->gdt.base, env->gdt.limit);
656
        cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
657
                    env->idt.base, env->idt.limit);
658
        cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
659
                    (uint32_t)env->cr[0],
660
                    env->cr[2],
661
                    env->cr[3],
662
                    (uint32_t)env->cr[4]);
663
    } else
664
#endif
665
    {
666
        for(i = 0; i < 6; i++) {
667
            SegmentCache *sc = &env->segs[i];
668
            cpu_fprintf(f, "%s =%04x %08x %08x %08x\n",
669
                        seg_name[i],
670
                        sc->selector,
671
                        (uint32_t)sc->base,
672
                        sc->limit,
673
                        sc->flags);
674
        }
675
        cpu_fprintf(f, "LDT=%04x %08x %08x %08x\n",
676
                    env->ldt.selector,
677
                    (uint32_t)env->ldt.base,
678
                    env->ldt.limit,
679
                    env->ldt.flags);
680
        cpu_fprintf(f, "TR =%04x %08x %08x %08x\n",
681
                    env->tr.selector,
682
                    (uint32_t)env->tr.base,
683
                    env->tr.limit,
684
                    env->tr.flags);
685
        cpu_fprintf(f, "GDT=     %08x %08x\n",
686
                    (uint32_t)env->gdt.base, env->gdt.limit);
687
        cpu_fprintf(f, "IDT=     %08x %08x\n",
688
                    (uint32_t)env->idt.base, env->idt.limit);
689
        cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
690
                    (uint32_t)env->cr[0],
691
                    (uint32_t)env->cr[2],
692
                    (uint32_t)env->cr[3],
693
                    (uint32_t)env->cr[4]);
694
    }
695
    if (flags & X86_DUMP_CCOP) {
696
        if ((unsigned)env->cc_op < CC_OP_NB)
697
            snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
698
        else
699
            snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
700
#ifdef TARGET_X86_64
701
        if (env->hflags & HF_CS64_MASK) {
702
            cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
703
                        env->cc_src, env->cc_dst,
704
                        cc_op_name);
705
        } else
706
#endif
707
        {
708
            cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
709
                        (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
710
                        cc_op_name);
711
        }
712
    }
713
    if (flags & X86_DUMP_FPU) {
714
        int fptag;
715
        fptag = 0;
716
        for(i = 0; i < 8; i++) {
717
            fptag |= ((!env->fptags[i]) << i);
718
        }
719
        cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
720
                    env->fpuc,
721
                    (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
722
                    env->fpstt,
723
                    fptag,
724
                    env->mxcsr);
725
        for(i=0;i<8;i++) {
726
#if defined(USE_X86LDOUBLE)
727
            union {
728
                long double d;
729
                struct {
730
                    uint64_t lower;
731
                    uint16_t upper;
732
                } l;
733
            } tmp;
734
            tmp.d = env->fpregs[i].d;
735
            cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
736
                        i, tmp.l.lower, tmp.l.upper);
737
#else
738
            cpu_fprintf(f, "FPR%d=%016" PRIx64,
739
                        i, env->fpregs[i].mmx.q);
740
#endif
741
            if ((i & 1) == 1)
742
                cpu_fprintf(f, "\n");
743
            else
744
                cpu_fprintf(f, " ");
745
        }
746
        if (env->hflags & HF_CS64_MASK)
747
            nb = 16;
748
        else
749
            nb = 8;
750
        for(i=0;i<nb;i++) {
751
            cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
752
                        i,
753
                        env->xmm_regs[i].XMM_L(3),
754
                        env->xmm_regs[i].XMM_L(2),
755
                        env->xmm_regs[i].XMM_L(1),
756
                        env->xmm_regs[i].XMM_L(0));
757
            if ((i & 1) == 1)
758
                cpu_fprintf(f, "\n");
759
            else
760
                cpu_fprintf(f, " ");
761
        }
762
    }
763
}
764

    
765
/***********************************************************/
766
/* x86 mmu */
767
/* XXX: add PGE support */
768

    
769
void cpu_x86_set_a20(CPUX86State *env, int a20_state)
770
{
771
    a20_state = (a20_state != 0);
772
    if (a20_state != ((env->a20_mask >> 20) & 1)) {
773
#if defined(DEBUG_MMU)
774
        printf("A20 update: a20=%d\n", a20_state);
775
#endif
776
        /* if the cpu is currently executing code, we must unlink it and
777
           all the potentially executing TB */
778
        cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
779

    
780
        /* when a20 is changed, all the MMU mappings are invalid, so
781
           we must flush everything */
782
        tlb_flush(env, 1);
783
        env->a20_mask = (~0x100000) | (a20_state << 20);
784
    }
785
}
786

    
787
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
788
{
789
    int pe_state;
790

    
791
#if defined(DEBUG_MMU)
792
    printf("CR0 update: CR0=0x%08x\n", new_cr0);
793
#endif
794
    if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
795
        (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
796
        tlb_flush(env, 1);
797
    }
798

    
799
#ifdef TARGET_X86_64
800
    if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
801
        (env->efer & MSR_EFER_LME)) {
802
        /* enter in long mode */
803
        /* XXX: generate an exception */
804
        if (!(env->cr[4] & CR4_PAE_MASK))
805
            return;
806
        env->efer |= MSR_EFER_LMA;
807
        env->hflags |= HF_LMA_MASK;
808
    } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
809
               (env->efer & MSR_EFER_LMA)) {
810
        /* exit long mode */
811
        env->efer &= ~MSR_EFER_LMA;
812
        env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
813
        env->eip &= 0xffffffff;
814
    }
815
#endif
816
    env->cr[0] = new_cr0 | CR0_ET_MASK;
817

    
818
    /* update PE flag in hidden flags */
819
    pe_state = (env->cr[0] & CR0_PE_MASK);
820
    env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
821
    /* ensure that ADDSEG is always set in real mode */
822
    env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
823
    /* update FPU flags */
824
    env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
825
        ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
826
}
827

    
828
/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
829
   the PDPT */
830
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
831
{
832
    env->cr[3] = new_cr3;
833
    if (env->cr[0] & CR0_PG_MASK) {
834
#if defined(DEBUG_MMU)
835
        printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
836
#endif
837
        tlb_flush(env, 0);
838
    }
839
}
840

    
841
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
842
{
843
#if defined(DEBUG_MMU)
844
    printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
845
#endif
846
    if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
847
        (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
848
        tlb_flush(env, 1);
849
    }
850
    /* SSE handling */
851
    if (!(env->cpuid_features & CPUID_SSE))
852
        new_cr4 &= ~CR4_OSFXSR_MASK;
853
    if (new_cr4 & CR4_OSFXSR_MASK)
854
        env->hflags |= HF_OSFXSR_MASK;
855
    else
856
        env->hflags &= ~HF_OSFXSR_MASK;
857

    
858
    env->cr[4] = new_cr4;
859
}
860

    
861
/* XXX: also flush 4MB pages */
862
void cpu_x86_flush_tlb(CPUX86State *env, target_ulong addr)
863
{
864
    tlb_flush_page(env, addr);
865
}
866

    
867
#if defined(CONFIG_USER_ONLY)
868

    
869
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
870
                             int is_write, int mmu_idx, int is_softmmu)
871
{
872
    /* user mode only emulation */
873
    is_write &= 1;
874
    env->cr[2] = addr;
875
    env->error_code = (is_write << PG_ERROR_W_BIT);
876
    env->error_code |= PG_ERROR_U_MASK;
877
    env->exception_index = EXCP0E_PAGE;
878
    return 1;
879
}
880

    
881
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
882
{
883
    return addr;
884
}
885

    
886
#else
887

    
888
/* XXX: This value should match the one returned by CPUID
889
 * and in exec.c */
890
#if defined(USE_KQEMU)
891
#define PHYS_ADDR_MASK 0xfffff000LL
892
#else
893
# if defined(TARGET_X86_64)
894
# define PHYS_ADDR_MASK 0xfffffff000LL
895
# else
896
# define PHYS_ADDR_MASK 0xffffff000LL
897
# endif
898
#endif
899

    
900
/* return value:
901
   -1 = cannot handle fault
902
   0  = nothing more to do
903
   1  = generate PF fault
904
   2  = soft MMU activation required for this block
905
*/
906
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
907
                             int is_write1, int mmu_idx, int is_softmmu)
908
{
909
    uint64_t ptep, pte;
910
    target_ulong pde_addr, pte_addr;
911
    int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
912
    target_phys_addr_t paddr;
913
    uint32_t page_offset;
914
    target_ulong vaddr, virt_addr;
915

    
916
    is_user = mmu_idx == MMU_USER_IDX;
917
#if defined(DEBUG_MMU)
918
    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
919
           addr, is_write1, is_user, env->eip);
920
#endif
921
    is_write = is_write1 & 1;
922

    
923
    if (!(env->cr[0] & CR0_PG_MASK)) {
924
        pte = addr;
925
        virt_addr = addr & TARGET_PAGE_MASK;
926
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
927
        page_size = 4096;
928
        goto do_mapping;
929
    }
930

    
931
    if (env->cr[4] & CR4_PAE_MASK) {
932
        uint64_t pde, pdpe;
933
        target_ulong pdpe_addr;
934

    
935
#ifdef TARGET_X86_64
936
        if (env->hflags & HF_LMA_MASK) {
937
            uint64_t pml4e_addr, pml4e;
938
            int32_t sext;
939

    
940
            /* test virtual address sign extension */
941
            sext = (int64_t)addr >> 47;
942
            if (sext != 0 && sext != -1) {
943
                env->error_code = 0;
944
                env->exception_index = EXCP0D_GPF;
945
                return 1;
946
            }
947

    
948
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
949
                env->a20_mask;
950
            pml4e = ldq_phys(pml4e_addr);
951
            if (!(pml4e & PG_PRESENT_MASK)) {
952
                error_code = 0;
953
                goto do_fault;
954
            }
955
            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
956
                error_code = PG_ERROR_RSVD_MASK;
957
                goto do_fault;
958
            }
959
            if (!(pml4e & PG_ACCESSED_MASK)) {
960
                pml4e |= PG_ACCESSED_MASK;
961
                stl_phys_notdirty(pml4e_addr, pml4e);
962
            }
963
            ptep = pml4e ^ PG_NX_MASK;
964
            pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
965
                env->a20_mask;
966
            pdpe = ldq_phys(pdpe_addr);
967
            if (!(pdpe & PG_PRESENT_MASK)) {
968
                error_code = 0;
969
                goto do_fault;
970
            }
971
            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
972
                error_code = PG_ERROR_RSVD_MASK;
973
                goto do_fault;
974
            }
975
            ptep &= pdpe ^ PG_NX_MASK;
976
            if (!(pdpe & PG_ACCESSED_MASK)) {
977
                pdpe |= PG_ACCESSED_MASK;
978
                stl_phys_notdirty(pdpe_addr, pdpe);
979
            }
980
        } else
981
#endif
982
        {
983
            /* XXX: load them when cr3 is loaded ? */
984
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
985
                env->a20_mask;
986
            pdpe = ldq_phys(pdpe_addr);
987
            if (!(pdpe & PG_PRESENT_MASK)) {
988
                error_code = 0;
989
                goto do_fault;
990
            }
991
            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
992
        }
993

    
994
        pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
995
            env->a20_mask;
996
        pde = ldq_phys(pde_addr);
997
        if (!(pde & PG_PRESENT_MASK)) {
998
            error_code = 0;
999
            goto do_fault;
1000
        }
1001
        if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
1002
            error_code = PG_ERROR_RSVD_MASK;
1003
            goto do_fault;
1004
        }
1005
        ptep &= pde ^ PG_NX_MASK;
1006
        if (pde & PG_PSE_MASK) {
1007
            /* 2 MB page */
1008
            page_size = 2048 * 1024;
1009
            ptep ^= PG_NX_MASK;
1010
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
1011
                goto do_fault_protect;
1012
            if (is_user) {
1013
                if (!(ptep & PG_USER_MASK))
1014
                    goto do_fault_protect;
1015
                if (is_write && !(ptep & PG_RW_MASK))
1016
                    goto do_fault_protect;
1017
            } else {
1018
                if ((env->cr[0] & CR0_WP_MASK) &&
1019
                    is_write && !(ptep & PG_RW_MASK))
1020
                    goto do_fault_protect;
1021
            }
1022
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
1023
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
1024
                pde |= PG_ACCESSED_MASK;
1025
                if (is_dirty)
1026
                    pde |= PG_DIRTY_MASK;
1027
                stl_phys_notdirty(pde_addr, pde);
1028
            }
1029
            /* align to page_size */
1030
            pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
1031
            virt_addr = addr & ~(page_size - 1);
1032
        } else {
1033
            /* 4 KB page */
1034
            if (!(pde & PG_ACCESSED_MASK)) {
1035
                pde |= PG_ACCESSED_MASK;
1036
                stl_phys_notdirty(pde_addr, pde);
1037
            }
1038
            pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
1039
                env->a20_mask;
1040
            pte = ldq_phys(pte_addr);
1041
            if (!(pte & PG_PRESENT_MASK)) {
1042
                error_code = 0;
1043
                goto do_fault;
1044
            }
1045
            if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
1046
                error_code = PG_ERROR_RSVD_MASK;
1047
                goto do_fault;
1048
            }
1049
            /* combine pde and pte nx, user and rw protections */
1050
            ptep &= pte ^ PG_NX_MASK;
1051
            ptep ^= PG_NX_MASK;
1052
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
1053
                goto do_fault_protect;
1054
            if (is_user) {
1055
                if (!(ptep & PG_USER_MASK))
1056
                    goto do_fault_protect;
1057
                if (is_write && !(ptep & PG_RW_MASK))
1058
                    goto do_fault_protect;
1059
            } else {
1060
                if ((env->cr[0] & CR0_WP_MASK) &&
1061
                    is_write && !(ptep & PG_RW_MASK))
1062
                    goto do_fault_protect;
1063
            }
1064
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1065
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1066
                pte |= PG_ACCESSED_MASK;
1067
                if (is_dirty)
1068
                    pte |= PG_DIRTY_MASK;
1069
                stl_phys_notdirty(pte_addr, pte);
1070
            }
1071
            page_size = 4096;
1072
            virt_addr = addr & ~0xfff;
1073
            pte = pte & (PHYS_ADDR_MASK | 0xfff);
1074
        }
1075
    } else {
1076
        uint32_t pde;
1077

    
1078
        /* page directory entry */
1079
        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
1080
            env->a20_mask;
1081
        pde = ldl_phys(pde_addr);
1082
        if (!(pde & PG_PRESENT_MASK)) {
1083
            error_code = 0;
1084
            goto do_fault;
1085
        }
1086
        /* if PSE bit is set, then we use a 4MB page */
1087
        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1088
            page_size = 4096 * 1024;
1089
            if (is_user) {
1090
                if (!(pde & PG_USER_MASK))
1091
                    goto do_fault_protect;
1092
                if (is_write && !(pde & PG_RW_MASK))
1093
                    goto do_fault_protect;
1094
            } else {
1095
                if ((env->cr[0] & CR0_WP_MASK) &&
1096
                    is_write && !(pde & PG_RW_MASK))
1097
                    goto do_fault_protect;
1098
            }
1099
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
1100
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
1101
                pde |= PG_ACCESSED_MASK;
1102
                if (is_dirty)
1103
                    pde |= PG_DIRTY_MASK;
1104
                stl_phys_notdirty(pde_addr, pde);
1105
            }
1106

    
1107
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1108
            ptep = pte;
1109
            virt_addr = addr & ~(page_size - 1);
1110
        } else {
1111
            if (!(pde & PG_ACCESSED_MASK)) {
1112
                pde |= PG_ACCESSED_MASK;
1113
                stl_phys_notdirty(pde_addr, pde);
1114
            }
1115

    
1116
            /* page directory entry */
1117
            pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
1118
                env->a20_mask;
1119
            pte = ldl_phys(pte_addr);
1120
            if (!(pte & PG_PRESENT_MASK)) {
1121
                error_code = 0;
1122
                goto do_fault;
1123
            }
1124
            /* combine pde and pte user and rw protections */
1125
            ptep = pte & pde;
1126
            if (is_user) {
1127
                if (!(ptep & PG_USER_MASK))
1128
                    goto do_fault_protect;
1129
                if (is_write && !(ptep & PG_RW_MASK))
1130
                    goto do_fault_protect;
1131
            } else {
1132
                if ((env->cr[0] & CR0_WP_MASK) &&
1133
                    is_write && !(ptep & PG_RW_MASK))
1134
                    goto do_fault_protect;
1135
            }
1136
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1137
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1138
                pte |= PG_ACCESSED_MASK;
1139
                if (is_dirty)
1140
                    pte |= PG_DIRTY_MASK;
1141
                stl_phys_notdirty(pte_addr, pte);
1142
            }
1143
            page_size = 4096;
1144
            virt_addr = addr & ~0xfff;
1145
        }
1146
    }
1147
    /* the page can be put in the TLB */
1148
    prot = PAGE_READ;
1149
    if (!(ptep & PG_NX_MASK))
1150
        prot |= PAGE_EXEC;
1151
    if (pte & PG_DIRTY_MASK) {
1152
        /* only set write access if already dirty... otherwise wait
1153
           for dirty access */
1154
        if (is_user) {
1155
            if (ptep & PG_RW_MASK)
1156
                prot |= PAGE_WRITE;
1157
        } else {
1158
            if (!(env->cr[0] & CR0_WP_MASK) ||
1159
                (ptep & PG_RW_MASK))
1160
                prot |= PAGE_WRITE;
1161
        }
1162
    }
1163
 do_mapping:
1164
    pte = pte & env->a20_mask;
1165

    
1166
    /* Even if 4MB pages, we map only one 4KB page in the cache to
1167
       avoid filling it too fast */
1168
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1169
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1170
    vaddr = virt_addr + page_offset;
1171

    
1172
    ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
1173
    return ret;
1174
 do_fault_protect:
1175
    error_code = PG_ERROR_P_MASK;
1176
 do_fault:
1177
    error_code |= (is_write << PG_ERROR_W_BIT);
1178
    if (is_user)
1179
        error_code |= PG_ERROR_U_MASK;
1180
    if (is_write1 == 2 &&
1181
        (env->efer & MSR_EFER_NXE) &&
1182
        (env->cr[4] & CR4_PAE_MASK))
1183
        error_code |= PG_ERROR_I_D_MASK;
1184
    if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
1185
        /* cr2 is not modified in case of exceptions */
1186
        stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 
1187
                 addr);
1188
    } else {
1189
        env->cr[2] = addr;
1190
    }
1191
    env->error_code = error_code;
1192
    env->exception_index = EXCP0E_PAGE;
1193
    return 1;
1194
}
1195

    
1196
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1197
{
1198
    target_ulong pde_addr, pte_addr;
1199
    uint64_t pte;
1200
    target_phys_addr_t paddr;
1201
    uint32_t page_offset;
1202
    int page_size;
1203

    
1204
    if (env->cr[4] & CR4_PAE_MASK) {
1205
        target_ulong pdpe_addr;
1206
        uint64_t pde, pdpe;
1207

    
1208
#ifdef TARGET_X86_64
1209
        if (env->hflags & HF_LMA_MASK) {
1210
            uint64_t pml4e_addr, pml4e;
1211
            int32_t sext;
1212

    
1213
            /* test virtual address sign extension */
1214
            sext = (int64_t)addr >> 47;
1215
            if (sext != 0 && sext != -1)
1216
                return -1;
1217

    
1218
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
1219
                env->a20_mask;
1220
            pml4e = ldq_phys(pml4e_addr);
1221
            if (!(pml4e & PG_PRESENT_MASK))
1222
                return -1;
1223

    
1224
            pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
1225
                env->a20_mask;
1226
            pdpe = ldq_phys(pdpe_addr);
1227
            if (!(pdpe & PG_PRESENT_MASK))
1228
                return -1;
1229
        } else
1230
#endif
1231
        {
1232
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1233
                env->a20_mask;
1234
            pdpe = ldq_phys(pdpe_addr);
1235
            if (!(pdpe & PG_PRESENT_MASK))
1236
                return -1;
1237
        }
1238

    
1239
        pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
1240
            env->a20_mask;
1241
        pde = ldq_phys(pde_addr);
1242
        if (!(pde & PG_PRESENT_MASK)) {
1243
            return -1;
1244
        }
1245
        if (pde & PG_PSE_MASK) {
1246
            /* 2 MB page */
1247
            page_size = 2048 * 1024;
1248
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1249
        } else {
1250
            /* 4 KB page */
1251
            pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
1252
                env->a20_mask;
1253
            page_size = 4096;
1254
            pte = ldq_phys(pte_addr);
1255
        }
1256
        if (!(pte & PG_PRESENT_MASK))
1257
            return -1;
1258
    } else {
1259
        uint32_t pde;
1260

    
1261
        if (!(env->cr[0] & CR0_PG_MASK)) {
1262
            pte = addr;
1263
            page_size = 4096;
1264
        } else {
1265
            /* page directory entry */
1266
            pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
1267
            pde = ldl_phys(pde_addr);
1268
            if (!(pde & PG_PRESENT_MASK))
1269
                return -1;
1270
            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1271
                pte = pde & ~0x003ff000; /* align to 4MB */
1272
                page_size = 4096 * 1024;
1273
            } else {
1274
                /* page directory entry */
1275
                pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
1276
                pte = ldl_phys(pte_addr);
1277
                if (!(pte & PG_PRESENT_MASK))
1278
                    return -1;
1279
                page_size = 4096;
1280
            }
1281
        }
1282
        pte = pte & env->a20_mask;
1283
    }
1284

    
1285
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1286
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1287
    return paddr;
1288
}
1289
#endif /* !CONFIG_USER_ONLY */