Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ 640f42e4

History | View | Annotate | Download (55.7 kB)

1 2c0262af bellard
/*
2 eaa728ee bellard
 *  i386 helpers (without register variable usage)
3 5fafdf24 ths
 *
4 2c0262af bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 2c0262af bellard
 *
6 2c0262af bellard
 * This library is free software; you can redistribute it and/or
7 2c0262af bellard
 * modify it under the terms of the GNU Lesser General Public
8 2c0262af bellard
 * License as published by the Free Software Foundation; either
9 2c0262af bellard
 * version 2 of the License, or (at your option) any later version.
10 2c0262af bellard
 *
11 2c0262af bellard
 * This library is distributed in the hope that it will be useful,
12 2c0262af bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 2c0262af bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 2c0262af bellard
 * Lesser General Public License for more details.
15 2c0262af bellard
 *
16 2c0262af bellard
 * You should have received a copy of the GNU Lesser General Public
17 2c0262af bellard
 * License along with this library; if not, write to the Free Software
18 fad6cb1a aurel32
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
19 2c0262af bellard
 */
20 eaa728ee bellard
#include <stdarg.h>
21 eaa728ee bellard
#include <stdlib.h>
22 eaa728ee bellard
#include <stdio.h>
23 eaa728ee bellard
#include <string.h>
24 eaa728ee bellard
#include <inttypes.h>
25 eaa728ee bellard
#include <signal.h>
26 eaa728ee bellard
#include <assert.h>
27 2c0262af bellard
28 eaa728ee bellard
#include "cpu.h"
29 eaa728ee bellard
#include "exec-all.h"
30 eaa728ee bellard
#include "qemu-common.h"
31 7ba1e619 aliguori
#include "kvm.h"
32 f3f2d9be bellard
33 eaa728ee bellard
//#define DEBUG_MMU
34 2c0262af bellard
35 eaa728ee bellard
static void add_flagname_to_bitmaps(char *flagname, uint32_t *features, 
36 eaa728ee bellard
                                    uint32_t *ext_features, 
37 eaa728ee bellard
                                    uint32_t *ext2_features, 
38 eaa728ee bellard
                                    uint32_t *ext3_features)
39 eaa728ee bellard
{
40 eaa728ee bellard
    int i;
41 eaa728ee bellard
    /* feature flags taken from "Intel Processor Identification and the CPUID
42 eaa728ee bellard
     * Instruction" and AMD's "CPUID Specification". In cases of disagreement 
43 eaa728ee bellard
     * about feature names, the Linux name is used. */
44 40f8e2fa bellard
    static const char *feature_name[] = {
45 eaa728ee bellard
        "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
46 eaa728ee bellard
        "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
47 eaa728ee bellard
        "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",
48 eaa728ee bellard
        "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",
49 eaa728ee bellard
    };
50 40f8e2fa bellard
    static const char *ext_feature_name[] = {
51 eaa728ee bellard
       "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",
52 eaa728ee bellard
       "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,
53 eaa728ee bellard
       NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",
54 eaa728ee bellard
       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
55 eaa728ee bellard
    };
56 40f8e2fa bellard
    static const char *ext2_feature_name[] = {
57 eaa728ee bellard
       "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
58 33049de7 aliguori
       "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",
59 eaa728ee bellard
       "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",
60 eaa728ee bellard
       "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
61 eaa728ee bellard
    };
62 40f8e2fa bellard
    static const char *ext3_feature_name[] = {
63 eaa728ee bellard
       "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
64 eaa728ee bellard
       "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,
65 eaa728ee bellard
       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
66 eaa728ee bellard
       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
67 eaa728ee bellard
    };
68 eaa728ee bellard
69 eaa728ee bellard
    for ( i = 0 ; i < 32 ; i++ ) 
70 eaa728ee bellard
        if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
71 eaa728ee bellard
            *features |= 1 << i;
72 eaa728ee bellard
            return;
73 eaa728ee bellard
        }
74 eaa728ee bellard
    for ( i = 0 ; i < 32 ; i++ ) 
75 eaa728ee bellard
        if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {
76 eaa728ee bellard
            *ext_features |= 1 << i;
77 eaa728ee bellard
            return;
78 eaa728ee bellard
        }
79 eaa728ee bellard
    for ( i = 0 ; i < 32 ; i++ ) 
80 eaa728ee bellard
        if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {
81 eaa728ee bellard
            *ext2_features |= 1 << i;
82 eaa728ee bellard
            return;
83 eaa728ee bellard
        }
84 eaa728ee bellard
    for ( i = 0 ; i < 32 ; i++ ) 
85 eaa728ee bellard
        if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {
86 eaa728ee bellard
            *ext3_features |= 1 << i;
87 eaa728ee bellard
            return;
88 eaa728ee bellard
        }
89 eaa728ee bellard
    fprintf(stderr, "CPU feature %s not found\n", flagname);
90 eaa728ee bellard
}
91 2c0262af bellard
92 eaa728ee bellard
typedef struct x86_def_t {
93 eaa728ee bellard
    const char *name;
94 eaa728ee bellard
    uint32_t level;
95 eaa728ee bellard
    uint32_t vendor1, vendor2, vendor3;
96 eaa728ee bellard
    int family;
97 eaa728ee bellard
    int model;
98 eaa728ee bellard
    int stepping;
99 eaa728ee bellard
    uint32_t features, ext_features, ext2_features, ext3_features;
100 eaa728ee bellard
    uint32_t xlevel;
101 40f8e2fa bellard
    char model_id[48];
102 eaa728ee bellard
} x86_def_t;
103 eaa728ee bellard
104 eaa728ee bellard
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
105 eaa728ee bellard
#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
106 eaa728ee bellard
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX)
107 eaa728ee bellard
#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
108 eaa728ee bellard
          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
109 eaa728ee bellard
          CPUID_PSE36 | CPUID_FXSR)
110 eaa728ee bellard
#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
111 eaa728ee bellard
#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
112 eaa728ee bellard
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
113 eaa728ee bellard
          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
114 eaa728ee bellard
          CPUID_PAE | CPUID_SEP | CPUID_APIC)
115 eaa728ee bellard
static x86_def_t x86_defs[] = {
116 eaa728ee bellard
#ifdef TARGET_X86_64
117 eaa728ee bellard
    {
118 eaa728ee bellard
        .name = "qemu64",
119 eaa728ee bellard
        .level = 2,
120 c5096daf balrog
        .vendor1 = CPUID_VENDOR_AMD_1,
121 c5096daf balrog
        .vendor2 = CPUID_VENDOR_AMD_2,
122 c5096daf balrog
        .vendor3 = CPUID_VENDOR_AMD_3,
123 eaa728ee bellard
        .family = 6,
124 eaa728ee bellard
        .model = 2,
125 eaa728ee bellard
        .stepping = 3,
126 eaa728ee bellard
        .features = PPRO_FEATURES | 
127 eaa728ee bellard
        /* these features are needed for Win64 and aren't fully implemented */
128 eaa728ee bellard
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
129 eaa728ee bellard
        /* this feature is needed for Solaris and isn't fully implemented */
130 eaa728ee bellard
            CPUID_PSE36,
131 eaa728ee bellard
        .ext_features = CPUID_EXT_SSE3,
132 eaa728ee bellard
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
133 eaa728ee bellard
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
134 eaa728ee bellard
            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
135 eaa728ee bellard
        .ext3_features = CPUID_EXT3_SVM,
136 eaa728ee bellard
        .xlevel = 0x8000000A,
137 40f8e2fa bellard
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
138 eaa728ee bellard
    },
139 e737b32a balrog
    {
140 9bdba1b6 aliguori
        .name = "phenom",
141 9bdba1b6 aliguori
        .level = 5,
142 9bdba1b6 aliguori
        .vendor1 = CPUID_VENDOR_AMD_1,
143 9bdba1b6 aliguori
        .vendor2 = CPUID_VENDOR_AMD_2,
144 9bdba1b6 aliguori
        .vendor3 = CPUID_VENDOR_AMD_3,
145 9bdba1b6 aliguori
        .family = 16,
146 9bdba1b6 aliguori
        .model = 2,
147 9bdba1b6 aliguori
        .stepping = 3,
148 9bdba1b6 aliguori
        /* Missing: CPUID_VME, CPUID_HT */
149 9bdba1b6 aliguori
        .features = PPRO_FEATURES | 
150 9bdba1b6 aliguori
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
151 9bdba1b6 aliguori
            CPUID_PSE36,
152 9bdba1b6 aliguori
        /* Missing: CPUID_EXT_CX16, CPUID_EXT_POPCNT */
153 9bdba1b6 aliguori
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
154 9bdba1b6 aliguori
        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
155 9bdba1b6 aliguori
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
156 9bdba1b6 aliguori
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
157 9bdba1b6 aliguori
            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
158 9bdba1b6 aliguori
            CPUID_EXT2_FFXSR,
159 9bdba1b6 aliguori
        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
160 9bdba1b6 aliguori
                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
161 9bdba1b6 aliguori
                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
162 9bdba1b6 aliguori
                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
163 9bdba1b6 aliguori
        .ext3_features = CPUID_EXT3_SVM,
164 9bdba1b6 aliguori
        .xlevel = 0x8000001A,
165 9bdba1b6 aliguori
        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
166 9bdba1b6 aliguori
    },
167 9bdba1b6 aliguori
    {
168 e737b32a balrog
        .name = "core2duo",
169 558fa836 pbrook
        .level = 10,
170 e737b32a balrog
        .family = 6,
171 e737b32a balrog
        .model = 15,
172 e737b32a balrog
        .stepping = 11,
173 558fa836 pbrook
        /* The original CPU also implements these features:
174 558fa836 pbrook
               CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
175 558fa836 pbrook
               CPUID_TM, CPUID_PBE */
176 0086de1c balrog
        .features = PPRO_FEATURES |
177 e737b32a balrog
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
178 e737b32a balrog
            CPUID_PSE36,
179 558fa836 pbrook
        /* The original CPU also implements these ext features:
180 558fa836 pbrook
               CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
181 558fa836 pbrook
               CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
182 0086de1c balrog
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
183 558fa836 pbrook
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
184 558fa836 pbrook
        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
185 45fd08ef aurel32
        .xlevel = 0x80000008,
186 e737b32a balrog
        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
187 e737b32a balrog
    },
188 eaa728ee bellard
#endif
189 eaa728ee bellard
    {
190 eaa728ee bellard
        .name = "qemu32",
191 eaa728ee bellard
        .level = 2,
192 eaa728ee bellard
        .family = 6,
193 eaa728ee bellard
        .model = 3,
194 eaa728ee bellard
        .stepping = 3,
195 eaa728ee bellard
        .features = PPRO_FEATURES,
196 eaa728ee bellard
        .ext_features = CPUID_EXT_SSE3,
197 eaa728ee bellard
        .xlevel = 0,
198 40f8e2fa bellard
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
199 eaa728ee bellard
    },
200 eaa728ee bellard
    {
201 45fd08ef aurel32
        .name = "coreduo",
202 45fd08ef aurel32
        .level = 10,
203 45fd08ef aurel32
        .family = 6,
204 45fd08ef aurel32
        .model = 14,
205 45fd08ef aurel32
        .stepping = 8,
206 45fd08ef aurel32
        /* The original CPU also implements these features:
207 45fd08ef aurel32
               CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
208 45fd08ef aurel32
               CPUID_TM, CPUID_PBE */
209 45fd08ef aurel32
        .features = PPRO_FEATURES | CPUID_VME |
210 45fd08ef aurel32
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
211 45fd08ef aurel32
        /* The original CPU also implements these ext features:
212 45fd08ef aurel32
               CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
213 45fd08ef aurel32
               CPUID_EXT_PDCM */
214 45fd08ef aurel32
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
215 45fd08ef aurel32
        .ext2_features = CPUID_EXT2_NX,
216 45fd08ef aurel32
        .xlevel = 0x80000008,
217 45fd08ef aurel32
        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
218 45fd08ef aurel32
    },
219 45fd08ef aurel32
    {
220 eaa728ee bellard
        .name = "486",
221 eaa728ee bellard
        .level = 0,
222 eaa728ee bellard
        .family = 4,
223 eaa728ee bellard
        .model = 0,
224 eaa728ee bellard
        .stepping = 0,
225 eaa728ee bellard
        .features = I486_FEATURES,
226 eaa728ee bellard
        .xlevel = 0,
227 eaa728ee bellard
    },
228 eaa728ee bellard
    {
229 eaa728ee bellard
        .name = "pentium",
230 eaa728ee bellard
        .level = 1,
231 eaa728ee bellard
        .family = 5,
232 eaa728ee bellard
        .model = 4,
233 eaa728ee bellard
        .stepping = 3,
234 eaa728ee bellard
        .features = PENTIUM_FEATURES,
235 eaa728ee bellard
        .xlevel = 0,
236 eaa728ee bellard
    },
237 eaa728ee bellard
    {
238 eaa728ee bellard
        .name = "pentium2",
239 eaa728ee bellard
        .level = 2,
240 eaa728ee bellard
        .family = 6,
241 eaa728ee bellard
        .model = 5,
242 eaa728ee bellard
        .stepping = 2,
243 eaa728ee bellard
        .features = PENTIUM2_FEATURES,
244 eaa728ee bellard
        .xlevel = 0,
245 eaa728ee bellard
    },
246 eaa728ee bellard
    {
247 eaa728ee bellard
        .name = "pentium3",
248 eaa728ee bellard
        .level = 2,
249 eaa728ee bellard
        .family = 6,
250 eaa728ee bellard
        .model = 7,
251 eaa728ee bellard
        .stepping = 3,
252 eaa728ee bellard
        .features = PENTIUM3_FEATURES,
253 eaa728ee bellard
        .xlevel = 0,
254 eaa728ee bellard
    },
255 eaa728ee bellard
    {
256 eaa728ee bellard
        .name = "athlon",
257 eaa728ee bellard
        .level = 2,
258 eaa728ee bellard
        .vendor1 = 0x68747541, /* "Auth" */
259 eaa728ee bellard
        .vendor2 = 0x69746e65, /* "enti" */
260 eaa728ee bellard
        .vendor3 = 0x444d4163, /* "cAMD" */
261 eaa728ee bellard
        .family = 6,
262 eaa728ee bellard
        .model = 2,
263 eaa728ee bellard
        .stepping = 3,
264 558fa836 pbrook
        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
265 eaa728ee bellard
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
266 eaa728ee bellard
        .xlevel = 0x80000008,
267 40f8e2fa bellard
        /* XXX: put another string ? */
268 40f8e2fa bellard
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
269 eaa728ee bellard
    },
270 0086de1c balrog
    {
271 c0d82995 balrog
        .name = "n270",
272 0086de1c balrog
        /* original is on level 10 */
273 0086de1c balrog
        .level = 5,
274 0086de1c balrog
        .family = 6,
275 0086de1c balrog
        .model = 28,
276 0086de1c balrog
        .stepping = 2,
277 0086de1c balrog
        .features = PPRO_FEATURES |
278 0086de1c balrog
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
279 0086de1c balrog
            /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
280 0086de1c balrog
             * CPUID_HT | CPUID_TM | CPUID_PBE */
281 0086de1c balrog
            /* Some CPUs got no CPUID_SEP */
282 0086de1c balrog
        .ext_features = CPUID_EXT_MONITOR |
283 853f6931 balrog
            CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
284 0086de1c balrog
            /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
285 0086de1c balrog
             * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
286 0086de1c balrog
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
287 0086de1c balrog
        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
288 0086de1c balrog
        .xlevel = 0x8000000A,
289 0086de1c balrog
        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
290 0086de1c balrog
    },
291 eaa728ee bellard
};
292 2c0262af bellard
293 eaa728ee bellard
static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
294 2c0262af bellard
{
295 eaa728ee bellard
    unsigned int i;
296 eaa728ee bellard
    x86_def_t *def;
297 2c0262af bellard
298 eaa728ee bellard
    char *s = strdup(cpu_model);
299 eaa728ee bellard
    char *featurestr, *name = strtok(s, ",");
300 eaa728ee bellard
    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;
301 eaa728ee bellard
    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;
302 eaa728ee bellard
    int family = -1, model = -1, stepping = -1;
303 2c0262af bellard
304 eaa728ee bellard
    def = NULL;
305 b1503cda malc
    for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
306 eaa728ee bellard
        if (strcmp(name, x86_defs[i].name) == 0) {
307 eaa728ee bellard
            def = &x86_defs[i];
308 eaa728ee bellard
            break;
309 eaa728ee bellard
        }
310 eaa728ee bellard
    }
311 eaa728ee bellard
    if (!def)
312 eaa728ee bellard
        goto error;
313 eaa728ee bellard
    memcpy(x86_cpu_def, def, sizeof(*def));
314 eaa728ee bellard
315 eaa728ee bellard
    featurestr = strtok(NULL, ",");
316 eaa728ee bellard
317 eaa728ee bellard
    while (featurestr) {
318 eaa728ee bellard
        char *val;
319 eaa728ee bellard
        if (featurestr[0] == '+') {
320 eaa728ee bellard
            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);
321 eaa728ee bellard
        } else if (featurestr[0] == '-') {
322 eaa728ee bellard
            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);
323 eaa728ee bellard
        } else if ((val = strchr(featurestr, '='))) {
324 eaa728ee bellard
            *val = 0; val++;
325 eaa728ee bellard
            if (!strcmp(featurestr, "family")) {
326 eaa728ee bellard
                char *err;
327 eaa728ee bellard
                family = strtol(val, &err, 10);
328 eaa728ee bellard
                if (!*val || *err || family < 0) {
329 eaa728ee bellard
                    fprintf(stderr, "bad numerical value %s\n", val);
330 eaa728ee bellard
                    goto error;
331 eaa728ee bellard
                }
332 eaa728ee bellard
                x86_cpu_def->family = family;
333 eaa728ee bellard
            } else if (!strcmp(featurestr, "model")) {
334 eaa728ee bellard
                char *err;
335 eaa728ee bellard
                model = strtol(val, &err, 10);
336 59795a1f balrog
                if (!*val || *err || model < 0 || model > 0xff) {
337 eaa728ee bellard
                    fprintf(stderr, "bad numerical value %s\n", val);
338 eaa728ee bellard
                    goto error;
339 eaa728ee bellard
                }
340 eaa728ee bellard
                x86_cpu_def->model = model;
341 eaa728ee bellard
            } else if (!strcmp(featurestr, "stepping")) {
342 eaa728ee bellard
                char *err;
343 eaa728ee bellard
                stepping = strtol(val, &err, 10);
344 eaa728ee bellard
                if (!*val || *err || stepping < 0 || stepping > 0xf) {
345 eaa728ee bellard
                    fprintf(stderr, "bad numerical value %s\n", val);
346 eaa728ee bellard
                    goto error;
347 eaa728ee bellard
                }
348 eaa728ee bellard
                x86_cpu_def->stepping = stepping;
349 40f8e2fa bellard
            } else if (!strcmp(featurestr, "vendor")) {
350 40f8e2fa bellard
                if (strlen(val) != 12) {
351 40f8e2fa bellard
                    fprintf(stderr, "vendor string must be 12 chars long\n");
352 40f8e2fa bellard
                    goto error;
353 40f8e2fa bellard
                }
354 40f8e2fa bellard
                x86_cpu_def->vendor1 = 0;
355 40f8e2fa bellard
                x86_cpu_def->vendor2 = 0;
356 40f8e2fa bellard
                x86_cpu_def->vendor3 = 0;
357 40f8e2fa bellard
                for(i = 0; i < 4; i++) {
358 40f8e2fa bellard
                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
359 40f8e2fa bellard
                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
360 40f8e2fa bellard
                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
361 40f8e2fa bellard
                }
362 40f8e2fa bellard
            } else if (!strcmp(featurestr, "model_id")) {
363 40f8e2fa bellard
                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
364 40f8e2fa bellard
                        val);
365 eaa728ee bellard
            } else {
366 eaa728ee bellard
                fprintf(stderr, "unrecognized feature %s\n", featurestr);
367 eaa728ee bellard
                goto error;
368 eaa728ee bellard
            }
369 eaa728ee bellard
        } else {
370 eaa728ee bellard
            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
371 eaa728ee bellard
            goto error;
372 eaa728ee bellard
        }
373 eaa728ee bellard
        featurestr = strtok(NULL, ",");
374 eaa728ee bellard
    }
375 eaa728ee bellard
    x86_cpu_def->features |= plus_features;
376 eaa728ee bellard
    x86_cpu_def->ext_features |= plus_ext_features;
377 eaa728ee bellard
    x86_cpu_def->ext2_features |= plus_ext2_features;
378 eaa728ee bellard
    x86_cpu_def->ext3_features |= plus_ext3_features;
379 eaa728ee bellard
    x86_cpu_def->features &= ~minus_features;
380 eaa728ee bellard
    x86_cpu_def->ext_features &= ~minus_ext_features;
381 eaa728ee bellard
    x86_cpu_def->ext2_features &= ~minus_ext2_features;
382 eaa728ee bellard
    x86_cpu_def->ext3_features &= ~minus_ext3_features;
383 eaa728ee bellard
    free(s);
384 eaa728ee bellard
    return 0;
385 eaa728ee bellard
386 eaa728ee bellard
error:
387 eaa728ee bellard
    free(s);
388 eaa728ee bellard
    return -1;
389 bd7a7b33 bellard
}
390 bd7a7b33 bellard
391 eaa728ee bellard
void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
392 bd7a7b33 bellard
{
393 eaa728ee bellard
    unsigned int i;
394 eaa728ee bellard
395 b1503cda malc
    for (i = 0; i < ARRAY_SIZE(x86_defs); i++)
396 eaa728ee bellard
        (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
397 bd7a7b33 bellard
}
398 bd7a7b33 bellard
399 eaa728ee bellard
static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
400 7e84c249 bellard
{
401 eaa728ee bellard
    x86_def_t def1, *def = &def1;
402 7e84c249 bellard
403 eaa728ee bellard
    if (cpu_x86_find_by_name(def, cpu_model) < 0)
404 7e84c249 bellard
        return -1;
405 eaa728ee bellard
    if (def->vendor1) {
406 eaa728ee bellard
        env->cpuid_vendor1 = def->vendor1;
407 eaa728ee bellard
        env->cpuid_vendor2 = def->vendor2;
408 eaa728ee bellard
        env->cpuid_vendor3 = def->vendor3;
409 eaa728ee bellard
    } else {
410 c5096daf balrog
        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
411 c5096daf balrog
        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
412 c5096daf balrog
        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
413 eaa728ee bellard
    }
414 eaa728ee bellard
    env->cpuid_level = def->level;
415 59795a1f balrog
    if (def->family > 0x0f)
416 59795a1f balrog
        env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
417 59795a1f balrog
    else
418 59795a1f balrog
        env->cpuid_version = def->family << 8;
419 59795a1f balrog
    env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
420 59795a1f balrog
    env->cpuid_version |= def->stepping;
421 eaa728ee bellard
    env->cpuid_features = def->features;
422 eaa728ee bellard
    env->pat = 0x0007040600070406ULL;
423 eaa728ee bellard
    env->cpuid_ext_features = def->ext_features;
424 eaa728ee bellard
    env->cpuid_ext2_features = def->ext2_features;
425 eaa728ee bellard
    env->cpuid_xlevel = def->xlevel;
426 eaa728ee bellard
    env->cpuid_ext3_features = def->ext3_features;
427 eaa728ee bellard
    {
428 40f8e2fa bellard
        const char *model_id = def->model_id;
429 eaa728ee bellard
        int c, len, i;
430 40f8e2fa bellard
        if (!model_id)
431 40f8e2fa bellard
            model_id = "";
432 eaa728ee bellard
        len = strlen(model_id);
433 eaa728ee bellard
        for(i = 0; i < 48; i++) {
434 eaa728ee bellard
            if (i >= len)
435 eaa728ee bellard
                c = '\0';
436 eaa728ee bellard
            else
437 40f8e2fa bellard
                c = (uint8_t)model_id[i];
438 eaa728ee bellard
            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
439 eaa728ee bellard
        }
440 eaa728ee bellard
    }
441 7e84c249 bellard
    return 0;
442 7e84c249 bellard
}
443 3b46e624 ths
444 eaa728ee bellard
/* NOTE: must be called outside the CPU execute loop */
445 eaa728ee bellard
void cpu_reset(CPUX86State *env)
446 7e84c249 bellard
{
447 eaa728ee bellard
    int i;
448 7e84c249 bellard
449 eca1bdf4 aliguori
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
450 eca1bdf4 aliguori
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
451 eca1bdf4 aliguori
        log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
452 eca1bdf4 aliguori
    }
453 eca1bdf4 aliguori
454 eaa728ee bellard
    memset(env, 0, offsetof(CPUX86State, breakpoints));
455 7e84c249 bellard
456 eaa728ee bellard
    tlb_flush(env, 1);
457 7e84c249 bellard
458 eaa728ee bellard
    env->old_exception = -1;
459 7e84c249 bellard
460 eaa728ee bellard
    /* init to reset state */
461 3b46e624 ths
462 eaa728ee bellard
#ifdef CONFIG_SOFTMMU
463 eaa728ee bellard
    env->hflags |= HF_SOFTMMU_MASK;
464 2c0262af bellard
#endif
465 db620f46 bellard
    env->hflags2 |= HF2_GIF_MASK;
466 2c0262af bellard
467 eaa728ee bellard
    cpu_x86_update_cr0(env, 0x60000010);
468 eaa728ee bellard
    env->a20_mask = ~0x0;
469 eaa728ee bellard
    env->smbase = 0x30000;
470 7e84c249 bellard
471 eaa728ee bellard
    env->idt.limit = 0xffff;
472 eaa728ee bellard
    env->gdt.limit = 0xffff;
473 eaa728ee bellard
    env->ldt.limit = 0xffff;
474 262ffdae bellard
    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
475 eaa728ee bellard
    env->tr.limit = 0xffff;
476 23e6c399 aliguori
    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
477 262ffdae bellard
478 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
479 262ffdae bellard
                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK | DESC_R_MASK);
480 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
481 262ffdae bellard
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
482 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
483 262ffdae bellard
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
484 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
485 262ffdae bellard
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
486 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
487 262ffdae bellard
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
488 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
489 262ffdae bellard
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK);
490 7e84c249 bellard
491 eaa728ee bellard
    env->eip = 0xfff0;
492 eaa728ee bellard
    env->regs[R_EDX] = env->cpuid_version;
493 2c0262af bellard
494 eaa728ee bellard
    env->eflags = 0x2;
495 7e84c249 bellard
496 eaa728ee bellard
    /* FPU init */
497 eaa728ee bellard
    for(i = 0;i < 8; i++)
498 eaa728ee bellard
        env->fptags[i] = 1;
499 eaa728ee bellard
    env->fpuc = 0x37f;
500 7e84c249 bellard
501 eaa728ee bellard
    env->mxcsr = 0x1f80;
502 01df040b aliguori
503 01df040b aliguori
    memset(env->dr, 0, sizeof(env->dr));
504 01df040b aliguori
    env->dr[6] = DR6_FIXED_1;
505 01df040b aliguori
    env->dr[7] = DR7_FIXED_1;
506 01df040b aliguori
    cpu_breakpoint_remove_all(env, BP_CPU);
507 01df040b aliguori
    cpu_watchpoint_remove_all(env, BP_CPU);
508 eaa728ee bellard
}
509 7e84c249 bellard
510 eaa728ee bellard
void cpu_x86_close(CPUX86State *env)
511 eaa728ee bellard
{
512 bb332cb2 balrog
    qemu_free(env);
513 eaa728ee bellard
}
514 7e84c249 bellard
515 eaa728ee bellard
/***********************************************************/
516 eaa728ee bellard
/* x86 debug */
517 3b46e624 ths
518 eaa728ee bellard
static const char *cc_op_str[] = {
519 eaa728ee bellard
    "DYNAMIC",
520 eaa728ee bellard
    "EFLAGS",
521 7e84c249 bellard
522 eaa728ee bellard
    "MULB",
523 eaa728ee bellard
    "MULW",
524 eaa728ee bellard
    "MULL",
525 eaa728ee bellard
    "MULQ",
526 3b46e624 ths
527 eaa728ee bellard
    "ADDB",
528 eaa728ee bellard
    "ADDW",
529 eaa728ee bellard
    "ADDL",
530 eaa728ee bellard
    "ADDQ",
531 3b46e624 ths
532 eaa728ee bellard
    "ADCB",
533 eaa728ee bellard
    "ADCW",
534 eaa728ee bellard
    "ADCL",
535 eaa728ee bellard
    "ADCQ",
536 3b46e624 ths
537 eaa728ee bellard
    "SUBB",
538 eaa728ee bellard
    "SUBW",
539 eaa728ee bellard
    "SUBL",
540 eaa728ee bellard
    "SUBQ",
541 7e84c249 bellard
542 eaa728ee bellard
    "SBBB",
543 eaa728ee bellard
    "SBBW",
544 eaa728ee bellard
    "SBBL",
545 eaa728ee bellard
    "SBBQ",
546 7e84c249 bellard
547 eaa728ee bellard
    "LOGICB",
548 eaa728ee bellard
    "LOGICW",
549 eaa728ee bellard
    "LOGICL",
550 eaa728ee bellard
    "LOGICQ",
551 7e84c249 bellard
552 eaa728ee bellard
    "INCB",
553 eaa728ee bellard
    "INCW",
554 eaa728ee bellard
    "INCL",
555 eaa728ee bellard
    "INCQ",
556 3b46e624 ths
557 eaa728ee bellard
    "DECB",
558 eaa728ee bellard
    "DECW",
559 eaa728ee bellard
    "DECL",
560 eaa728ee bellard
    "DECQ",
561 3b46e624 ths
562 eaa728ee bellard
    "SHLB",
563 eaa728ee bellard
    "SHLW",
564 eaa728ee bellard
    "SHLL",
565 eaa728ee bellard
    "SHLQ",
566 3b46e624 ths
567 eaa728ee bellard
    "SARB",
568 eaa728ee bellard
    "SARW",
569 eaa728ee bellard
    "SARL",
570 eaa728ee bellard
    "SARQ",
571 eaa728ee bellard
};
572 7e84c249 bellard
573 a3867ed2 aliguori
static void
574 a3867ed2 aliguori
cpu_x86_dump_seg_cache(CPUState *env, FILE *f,
575 a3867ed2 aliguori
                       int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
576 a3867ed2 aliguori
                       const char *name, struct SegmentCache *sc)
577 a3867ed2 aliguori
{
578 a3867ed2 aliguori
#ifdef TARGET_X86_64
579 a3867ed2 aliguori
    if (env->hflags & HF_CS64_MASK) {
580 a3867ed2 aliguori
        cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
581 a3867ed2 aliguori
                    sc->selector, sc->base, sc->limit, sc->flags);
582 a3867ed2 aliguori
    } else
583 a3867ed2 aliguori
#endif
584 a3867ed2 aliguori
    {
585 a3867ed2 aliguori
        cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
586 a3867ed2 aliguori
                    (uint32_t)sc->base, sc->limit, sc->flags);
587 a3867ed2 aliguori
    }
588 a3867ed2 aliguori
589 a3867ed2 aliguori
    if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
590 a3867ed2 aliguori
        goto done;
591 a3867ed2 aliguori
592 a3867ed2 aliguori
    cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
593 a3867ed2 aliguori
    if (sc->flags & DESC_S_MASK) {
594 a3867ed2 aliguori
        if (sc->flags & DESC_CS_MASK) {
595 a3867ed2 aliguori
            cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
596 a3867ed2 aliguori
                           ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
597 a3867ed2 aliguori
            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
598 a3867ed2 aliguori
                        (sc->flags & DESC_R_MASK) ? 'R' : '-');
599 a3867ed2 aliguori
        } else {
600 a3867ed2 aliguori
            cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS  " : "DS16");
601 a3867ed2 aliguori
            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
602 a3867ed2 aliguori
                        (sc->flags & DESC_W_MASK) ? 'W' : '-');
603 a3867ed2 aliguori
        }
604 a3867ed2 aliguori
        cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
605 a3867ed2 aliguori
    } else {
606 a3867ed2 aliguori
        static const char *sys_type_name[2][16] = {
607 a3867ed2 aliguori
            { /* 32 bit mode */
608 a3867ed2 aliguori
                "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
609 a3867ed2 aliguori
                "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
610 a3867ed2 aliguori
                "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
611 a3867ed2 aliguori
                "CallGate32", "Reserved", "IntGate32", "TrapGate32"
612 a3867ed2 aliguori
            },
613 a3867ed2 aliguori
            { /* 64 bit mode */
614 a3867ed2 aliguori
                "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
615 a3867ed2 aliguori
                "Reserved", "Reserved", "Reserved", "Reserved",
616 a3867ed2 aliguori
                "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
617 a3867ed2 aliguori
                "Reserved", "IntGate64", "TrapGate64"
618 a3867ed2 aliguori
            }
619 a3867ed2 aliguori
        };
620 a3867ed2 aliguori
        cpu_fprintf(f, sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
621 a3867ed2 aliguori
                                    [(sc->flags & DESC_TYPE_MASK)
622 a3867ed2 aliguori
                                     >> DESC_TYPE_SHIFT]);
623 a3867ed2 aliguori
    }
624 a3867ed2 aliguori
done:
625 a3867ed2 aliguori
    cpu_fprintf(f, "\n");
626 a3867ed2 aliguori
}
627 a3867ed2 aliguori
628 eaa728ee bellard
void cpu_dump_state(CPUState *env, FILE *f,
629 eaa728ee bellard
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
630 eaa728ee bellard
                    int flags)
631 eaa728ee bellard
{
632 eaa728ee bellard
    int eflags, i, nb;
633 eaa728ee bellard
    char cc_op_name[32];
634 eaa728ee bellard
    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
635 7e84c249 bellard
636 ff3c01ca balrog
    if (kvm_enabled())
637 ff3c01ca balrog
        kvm_arch_get_registers(env);
638 ff3c01ca balrog
639 eaa728ee bellard
    eflags = env->eflags;
640 eaa728ee bellard
#ifdef TARGET_X86_64
641 eaa728ee bellard
    if (env->hflags & HF_CS64_MASK) {
642 eaa728ee bellard
        cpu_fprintf(f,
643 eaa728ee bellard
                    "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
644 eaa728ee bellard
                    "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
645 eaa728ee bellard
                    "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
646 eaa728ee bellard
                    "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
647 eaa728ee bellard
                    "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
648 eaa728ee bellard
                    env->regs[R_EAX],
649 eaa728ee bellard
                    env->regs[R_EBX],
650 eaa728ee bellard
                    env->regs[R_ECX],
651 eaa728ee bellard
                    env->regs[R_EDX],
652 eaa728ee bellard
                    env->regs[R_ESI],
653 eaa728ee bellard
                    env->regs[R_EDI],
654 eaa728ee bellard
                    env->regs[R_EBP],
655 eaa728ee bellard
                    env->regs[R_ESP],
656 eaa728ee bellard
                    env->regs[8],
657 eaa728ee bellard
                    env->regs[9],
658 eaa728ee bellard
                    env->regs[10],
659 eaa728ee bellard
                    env->regs[11],
660 eaa728ee bellard
                    env->regs[12],
661 eaa728ee bellard
                    env->regs[13],
662 eaa728ee bellard
                    env->regs[14],
663 eaa728ee bellard
                    env->regs[15],
664 eaa728ee bellard
                    env->eip, eflags,
665 eaa728ee bellard
                    eflags & DF_MASK ? 'D' : '-',
666 eaa728ee bellard
                    eflags & CC_O ? 'O' : '-',
667 eaa728ee bellard
                    eflags & CC_S ? 'S' : '-',
668 eaa728ee bellard
                    eflags & CC_Z ? 'Z' : '-',
669 eaa728ee bellard
                    eflags & CC_A ? 'A' : '-',
670 eaa728ee bellard
                    eflags & CC_P ? 'P' : '-',
671 eaa728ee bellard
                    eflags & CC_C ? 'C' : '-',
672 eaa728ee bellard
                    env->hflags & HF_CPL_MASK,
673 eaa728ee bellard
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
674 eaa728ee bellard
                    (int)(env->a20_mask >> 20) & 1,
675 eaa728ee bellard
                    (env->hflags >> HF_SMM_SHIFT) & 1,
676 ce5232c5 bellard
                    env->halted);
677 eaa728ee bellard
    } else
678 eaa728ee bellard
#endif
679 eaa728ee bellard
    {
680 eaa728ee bellard
        cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
681 eaa728ee bellard
                    "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
682 eaa728ee bellard
                    "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
683 eaa728ee bellard
                    (uint32_t)env->regs[R_EAX],
684 eaa728ee bellard
                    (uint32_t)env->regs[R_EBX],
685 eaa728ee bellard
                    (uint32_t)env->regs[R_ECX],
686 eaa728ee bellard
                    (uint32_t)env->regs[R_EDX],
687 eaa728ee bellard
                    (uint32_t)env->regs[R_ESI],
688 eaa728ee bellard
                    (uint32_t)env->regs[R_EDI],
689 eaa728ee bellard
                    (uint32_t)env->regs[R_EBP],
690 eaa728ee bellard
                    (uint32_t)env->regs[R_ESP],
691 eaa728ee bellard
                    (uint32_t)env->eip, eflags,
692 eaa728ee bellard
                    eflags & DF_MASK ? 'D' : '-',
693 eaa728ee bellard
                    eflags & CC_O ? 'O' : '-',
694 eaa728ee bellard
                    eflags & CC_S ? 'S' : '-',
695 eaa728ee bellard
                    eflags & CC_Z ? 'Z' : '-',
696 eaa728ee bellard
                    eflags & CC_A ? 'A' : '-',
697 eaa728ee bellard
                    eflags & CC_P ? 'P' : '-',
698 eaa728ee bellard
                    eflags & CC_C ? 'C' : '-',
699 eaa728ee bellard
                    env->hflags & HF_CPL_MASK,
700 eaa728ee bellard
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
701 eaa728ee bellard
                    (int)(env->a20_mask >> 20) & 1,
702 eaa728ee bellard
                    (env->hflags >> HF_SMM_SHIFT) & 1,
703 ce5232c5 bellard
                    env->halted);
704 8145122b bellard
    }
705 3b46e624 ths
706 a3867ed2 aliguori
    for(i = 0; i < 6; i++) {
707 a3867ed2 aliguori
        cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
708 a3867ed2 aliguori
                               &env->segs[i]);
709 a3867ed2 aliguori
    }
710 a3867ed2 aliguori
    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
711 a3867ed2 aliguori
    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
712 a3867ed2 aliguori
713 eaa728ee bellard
#ifdef TARGET_X86_64
714 eaa728ee bellard
    if (env->hflags & HF_LMA_MASK) {
715 eaa728ee bellard
        cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
716 eaa728ee bellard
                    env->gdt.base, env->gdt.limit);
717 eaa728ee bellard
        cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
718 eaa728ee bellard
                    env->idt.base, env->idt.limit);
719 eaa728ee bellard
        cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
720 eaa728ee bellard
                    (uint32_t)env->cr[0],
721 eaa728ee bellard
                    env->cr[2],
722 eaa728ee bellard
                    env->cr[3],
723 eaa728ee bellard
                    (uint32_t)env->cr[4]);
724 a59cb4e0 aliguori
        for(i = 0; i < 4; i++)
725 a59cb4e0 aliguori
            cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
726 a59cb4e0 aliguori
        cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
727 d4b55be5 aliguori
                    env->dr[6], env->dr[7]);
728 eaa728ee bellard
    } else
729 eaa728ee bellard
#endif
730 eaa728ee bellard
    {
731 eaa728ee bellard
        cpu_fprintf(f, "GDT=     %08x %08x\n",
732 eaa728ee bellard
                    (uint32_t)env->gdt.base, env->gdt.limit);
733 eaa728ee bellard
        cpu_fprintf(f, "IDT=     %08x %08x\n",
734 eaa728ee bellard
                    (uint32_t)env->idt.base, env->idt.limit);
735 eaa728ee bellard
        cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
736 eaa728ee bellard
                    (uint32_t)env->cr[0],
737 eaa728ee bellard
                    (uint32_t)env->cr[2],
738 eaa728ee bellard
                    (uint32_t)env->cr[3],
739 eaa728ee bellard
                    (uint32_t)env->cr[4]);
740 a59cb4e0 aliguori
        for(i = 0; i < 4; i++)
741 a59cb4e0 aliguori
            cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]);
742 d4b55be5 aliguori
        cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]);
743 eaa728ee bellard
    }
744 eaa728ee bellard
    if (flags & X86_DUMP_CCOP) {
745 eaa728ee bellard
        if ((unsigned)env->cc_op < CC_OP_NB)
746 eaa728ee bellard
            snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
747 eaa728ee bellard
        else
748 eaa728ee bellard
            snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
749 eaa728ee bellard
#ifdef TARGET_X86_64
750 eaa728ee bellard
        if (env->hflags & HF_CS64_MASK) {
751 eaa728ee bellard
            cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
752 eaa728ee bellard
                        env->cc_src, env->cc_dst,
753 eaa728ee bellard
                        cc_op_name);
754 eaa728ee bellard
        } else
755 eaa728ee bellard
#endif
756 eaa728ee bellard
        {
757 eaa728ee bellard
            cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
758 eaa728ee bellard
                        (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
759 eaa728ee bellard
                        cc_op_name);
760 eaa728ee bellard
        }
761 7e84c249 bellard
    }
762 eaa728ee bellard
    if (flags & X86_DUMP_FPU) {
763 eaa728ee bellard
        int fptag;
764 eaa728ee bellard
        fptag = 0;
765 eaa728ee bellard
        for(i = 0; i < 8; i++) {
766 eaa728ee bellard
            fptag |= ((!env->fptags[i]) << i);
767 eaa728ee bellard
        }
768 eaa728ee bellard
        cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
769 eaa728ee bellard
                    env->fpuc,
770 eaa728ee bellard
                    (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
771 eaa728ee bellard
                    env->fpstt,
772 eaa728ee bellard
                    fptag,
773 eaa728ee bellard
                    env->mxcsr);
774 eaa728ee bellard
        for(i=0;i<8;i++) {
775 eaa728ee bellard
#if defined(USE_X86LDOUBLE)
776 eaa728ee bellard
            union {
777 eaa728ee bellard
                long double d;
778 eaa728ee bellard
                struct {
779 eaa728ee bellard
                    uint64_t lower;
780 eaa728ee bellard
                    uint16_t upper;
781 eaa728ee bellard
                } l;
782 eaa728ee bellard
            } tmp;
783 eaa728ee bellard
            tmp.d = env->fpregs[i].d;
784 eaa728ee bellard
            cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
785 eaa728ee bellard
                        i, tmp.l.lower, tmp.l.upper);
786 eaa728ee bellard
#else
787 eaa728ee bellard
            cpu_fprintf(f, "FPR%d=%016" PRIx64,
788 eaa728ee bellard
                        i, env->fpregs[i].mmx.q);
789 eaa728ee bellard
#endif
790 eaa728ee bellard
            if ((i & 1) == 1)
791 eaa728ee bellard
                cpu_fprintf(f, "\n");
792 eaa728ee bellard
            else
793 eaa728ee bellard
                cpu_fprintf(f, " ");
794 eaa728ee bellard
        }
795 eaa728ee bellard
        if (env->hflags & HF_CS64_MASK)
796 eaa728ee bellard
            nb = 16;
797 eaa728ee bellard
        else
798 eaa728ee bellard
            nb = 8;
799 eaa728ee bellard
        for(i=0;i<nb;i++) {
800 eaa728ee bellard
            cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
801 eaa728ee bellard
                        i,
802 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(3),
803 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(2),
804 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(1),
805 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(0));
806 eaa728ee bellard
            if ((i & 1) == 1)
807 eaa728ee bellard
                cpu_fprintf(f, "\n");
808 eaa728ee bellard
            else
809 eaa728ee bellard
                cpu_fprintf(f, " ");
810 eaa728ee bellard
        }
811 7e84c249 bellard
    }
812 2c0262af bellard
}
813 7e84c249 bellard
814 eaa728ee bellard
/***********************************************************/
815 eaa728ee bellard
/* x86 mmu */
816 eaa728ee bellard
/* XXX: add PGE support */
817 eaa728ee bellard
818 eaa728ee bellard
void cpu_x86_set_a20(CPUX86State *env, int a20_state)
819 2c0262af bellard
{
820 eaa728ee bellard
    a20_state = (a20_state != 0);
821 eaa728ee bellard
    if (a20_state != ((env->a20_mask >> 20) & 1)) {
822 eaa728ee bellard
#if defined(DEBUG_MMU)
823 eaa728ee bellard
        printf("A20 update: a20=%d\n", a20_state);
824 eaa728ee bellard
#endif
825 eaa728ee bellard
        /* if the cpu is currently executing code, we must unlink it and
826 eaa728ee bellard
           all the potentially executing TB */
827 eaa728ee bellard
        cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
828 3b46e624 ths
829 eaa728ee bellard
        /* when a20 is changed, all the MMU mappings are invalid, so
830 eaa728ee bellard
           we must flush everything */
831 eaa728ee bellard
        tlb_flush(env, 1);
832 eaa728ee bellard
        env->a20_mask = (~0x100000) | (a20_state << 20);
833 7e84c249 bellard
    }
834 2c0262af bellard
}
835 2c0262af bellard
836 eaa728ee bellard
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
837 2c0262af bellard
{
838 eaa728ee bellard
    int pe_state;
839 2c0262af bellard
840 eaa728ee bellard
#if defined(DEBUG_MMU)
841 eaa728ee bellard
    printf("CR0 update: CR0=0x%08x\n", new_cr0);
842 eaa728ee bellard
#endif
843 eaa728ee bellard
    if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
844 eaa728ee bellard
        (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
845 eaa728ee bellard
        tlb_flush(env, 1);
846 eaa728ee bellard
    }
847 2c0262af bellard
848 eaa728ee bellard
#ifdef TARGET_X86_64
849 eaa728ee bellard
    if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
850 eaa728ee bellard
        (env->efer & MSR_EFER_LME)) {
851 eaa728ee bellard
        /* enter in long mode */
852 eaa728ee bellard
        /* XXX: generate an exception */
853 eaa728ee bellard
        if (!(env->cr[4] & CR4_PAE_MASK))
854 eaa728ee bellard
            return;
855 eaa728ee bellard
        env->efer |= MSR_EFER_LMA;
856 eaa728ee bellard
        env->hflags |= HF_LMA_MASK;
857 eaa728ee bellard
    } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
858 eaa728ee bellard
               (env->efer & MSR_EFER_LMA)) {
859 eaa728ee bellard
        /* exit long mode */
860 eaa728ee bellard
        env->efer &= ~MSR_EFER_LMA;
861 eaa728ee bellard
        env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
862 eaa728ee bellard
        env->eip &= 0xffffffff;
863 eaa728ee bellard
    }
864 eaa728ee bellard
#endif
865 eaa728ee bellard
    env->cr[0] = new_cr0 | CR0_ET_MASK;
866 7e84c249 bellard
867 eaa728ee bellard
    /* update PE flag in hidden flags */
868 eaa728ee bellard
    pe_state = (env->cr[0] & CR0_PE_MASK);
869 eaa728ee bellard
    env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
870 eaa728ee bellard
    /* ensure that ADDSEG is always set in real mode */
871 eaa728ee bellard
    env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
872 eaa728ee bellard
    /* update FPU flags */
873 eaa728ee bellard
    env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
874 eaa728ee bellard
        ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
875 7e84c249 bellard
}
876 7e84c249 bellard
877 eaa728ee bellard
/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
878 eaa728ee bellard
   the PDPT */
879 eaa728ee bellard
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
880 7e84c249 bellard
{
881 eaa728ee bellard
    env->cr[3] = new_cr3;
882 eaa728ee bellard
    if (env->cr[0] & CR0_PG_MASK) {
883 eaa728ee bellard
#if defined(DEBUG_MMU)
884 eaa728ee bellard
        printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
885 eaa728ee bellard
#endif
886 eaa728ee bellard
        tlb_flush(env, 0);
887 eaa728ee bellard
    }
888 7e84c249 bellard
}
889 7e84c249 bellard
890 eaa728ee bellard
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
891 7e84c249 bellard
{
892 eaa728ee bellard
#if defined(DEBUG_MMU)
893 eaa728ee bellard
    printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
894 eaa728ee bellard
#endif
895 eaa728ee bellard
    if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
896 eaa728ee bellard
        (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
897 eaa728ee bellard
        tlb_flush(env, 1);
898 eaa728ee bellard
    }
899 eaa728ee bellard
    /* SSE handling */
900 eaa728ee bellard
    if (!(env->cpuid_features & CPUID_SSE))
901 eaa728ee bellard
        new_cr4 &= ~CR4_OSFXSR_MASK;
902 eaa728ee bellard
    if (new_cr4 & CR4_OSFXSR_MASK)
903 eaa728ee bellard
        env->hflags |= HF_OSFXSR_MASK;
904 eaa728ee bellard
    else
905 eaa728ee bellard
        env->hflags &= ~HF_OSFXSR_MASK;
906 b8b6a50b bellard
907 eaa728ee bellard
    env->cr[4] = new_cr4;
908 b8b6a50b bellard
}
909 b8b6a50b bellard
910 eaa728ee bellard
#if defined(CONFIG_USER_ONLY)
911 eaa728ee bellard
912 eaa728ee bellard
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
913 eaa728ee bellard
                             int is_write, int mmu_idx, int is_softmmu)
914 b8b6a50b bellard
{
915 eaa728ee bellard
    /* user mode only emulation */
916 eaa728ee bellard
    is_write &= 1;
917 eaa728ee bellard
    env->cr[2] = addr;
918 eaa728ee bellard
    env->error_code = (is_write << PG_ERROR_W_BIT);
919 eaa728ee bellard
    env->error_code |= PG_ERROR_U_MASK;
920 eaa728ee bellard
    env->exception_index = EXCP0E_PAGE;
921 eaa728ee bellard
    return 1;
922 2c0262af bellard
}
923 2c0262af bellard
924 eaa728ee bellard
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
925 891b38e4 bellard
{
926 eaa728ee bellard
    return addr;
927 891b38e4 bellard
}
928 891b38e4 bellard
929 8d7b0fbb bellard
#else
930 891b38e4 bellard
931 eaa728ee bellard
/* XXX: This value should match the one returned by CPUID
932 eaa728ee bellard
 * and in exec.c */
933 640f42e4 blueswir1
#if defined(CONFIG_KQEMU)
934 2c90d794 ths
#define PHYS_ADDR_MASK 0xfffff000LL
935 eaa728ee bellard
#else
936 eaa728ee bellard
# if defined(TARGET_X86_64)
937 2c90d794 ths
# define PHYS_ADDR_MASK 0xfffffff000LL
938 eaa728ee bellard
# else
939 2c90d794 ths
# define PHYS_ADDR_MASK 0xffffff000LL
940 eaa728ee bellard
# endif
941 eaa728ee bellard
#endif
942 eaa728ee bellard
943 eaa728ee bellard
/* return value:
944 eaa728ee bellard
   -1 = cannot handle fault
945 eaa728ee bellard
   0  = nothing more to do
946 eaa728ee bellard
   1  = generate PF fault
947 eaa728ee bellard
   2  = soft MMU activation required for this block
948 eaa728ee bellard
*/
949 eaa728ee bellard
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
950 eaa728ee bellard
                             int is_write1, int mmu_idx, int is_softmmu)
951 eaa728ee bellard
{
952 eaa728ee bellard
    uint64_t ptep, pte;
953 eaa728ee bellard
    target_ulong pde_addr, pte_addr;
954 eaa728ee bellard
    int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
955 eaa728ee bellard
    target_phys_addr_t paddr;
956 eaa728ee bellard
    uint32_t page_offset;
957 eaa728ee bellard
    target_ulong vaddr, virt_addr;
958 eaa728ee bellard
959 eaa728ee bellard
    is_user = mmu_idx == MMU_USER_IDX;
960 eaa728ee bellard
#if defined(DEBUG_MMU)
961 eaa728ee bellard
    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
962 eaa728ee bellard
           addr, is_write1, is_user, env->eip);
963 eaa728ee bellard
#endif
964 eaa728ee bellard
    is_write = is_write1 & 1;
965 eaa728ee bellard
966 eaa728ee bellard
    if (!(env->cr[0] & CR0_PG_MASK)) {
967 eaa728ee bellard
        pte = addr;
968 eaa728ee bellard
        virt_addr = addr & TARGET_PAGE_MASK;
969 eaa728ee bellard
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
970 eaa728ee bellard
        page_size = 4096;
971 eaa728ee bellard
        goto do_mapping;
972 eaa728ee bellard
    }
973 eaa728ee bellard
974 eaa728ee bellard
    if (env->cr[4] & CR4_PAE_MASK) {
975 eaa728ee bellard
        uint64_t pde, pdpe;
976 eaa728ee bellard
        target_ulong pdpe_addr;
977 2c0262af bellard
978 eaa728ee bellard
#ifdef TARGET_X86_64
979 eaa728ee bellard
        if (env->hflags & HF_LMA_MASK) {
980 eaa728ee bellard
            uint64_t pml4e_addr, pml4e;
981 eaa728ee bellard
            int32_t sext;
982 eaa728ee bellard
983 eaa728ee bellard
            /* test virtual address sign extension */
984 eaa728ee bellard
            sext = (int64_t)addr >> 47;
985 eaa728ee bellard
            if (sext != 0 && sext != -1) {
986 eaa728ee bellard
                env->error_code = 0;
987 eaa728ee bellard
                env->exception_index = EXCP0D_GPF;
988 eaa728ee bellard
                return 1;
989 eaa728ee bellard
            }
990 0573fbfc ths
991 eaa728ee bellard
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
992 eaa728ee bellard
                env->a20_mask;
993 eaa728ee bellard
            pml4e = ldq_phys(pml4e_addr);
994 eaa728ee bellard
            if (!(pml4e & PG_PRESENT_MASK)) {
995 eaa728ee bellard
                error_code = 0;
996 eaa728ee bellard
                goto do_fault;
997 eaa728ee bellard
            }
998 eaa728ee bellard
            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
999 eaa728ee bellard
                error_code = PG_ERROR_RSVD_MASK;
1000 eaa728ee bellard
                goto do_fault;
1001 eaa728ee bellard
            }
1002 eaa728ee bellard
            if (!(pml4e & PG_ACCESSED_MASK)) {
1003 eaa728ee bellard
                pml4e |= PG_ACCESSED_MASK;
1004 eaa728ee bellard
                stl_phys_notdirty(pml4e_addr, pml4e);
1005 eaa728ee bellard
            }
1006 eaa728ee bellard
            ptep = pml4e ^ PG_NX_MASK;
1007 eaa728ee bellard
            pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
1008 eaa728ee bellard
                env->a20_mask;
1009 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
1010 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK)) {
1011 eaa728ee bellard
                error_code = 0;
1012 eaa728ee bellard
                goto do_fault;
1013 eaa728ee bellard
            }
1014 eaa728ee bellard
            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
1015 eaa728ee bellard
                error_code = PG_ERROR_RSVD_MASK;
1016 eaa728ee bellard
                goto do_fault;
1017 eaa728ee bellard
            }
1018 eaa728ee bellard
            ptep &= pdpe ^ PG_NX_MASK;
1019 eaa728ee bellard
            if (!(pdpe & PG_ACCESSED_MASK)) {
1020 eaa728ee bellard
                pdpe |= PG_ACCESSED_MASK;
1021 eaa728ee bellard
                stl_phys_notdirty(pdpe_addr, pdpe);
1022 eaa728ee bellard
            }
1023 eaa728ee bellard
        } else
1024 eaa728ee bellard
#endif
1025 eaa728ee bellard
        {
1026 eaa728ee bellard
            /* XXX: load them when cr3 is loaded ? */
1027 eaa728ee bellard
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1028 eaa728ee bellard
                env->a20_mask;
1029 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
1030 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK)) {
1031 eaa728ee bellard
                error_code = 0;
1032 eaa728ee bellard
                goto do_fault;
1033 eaa728ee bellard
            }
1034 eaa728ee bellard
            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
1035 7e84c249 bellard
        }
1036 7e84c249 bellard
1037 eaa728ee bellard
        pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
1038 eaa728ee bellard
            env->a20_mask;
1039 eaa728ee bellard
        pde = ldq_phys(pde_addr);
1040 eaa728ee bellard
        if (!(pde & PG_PRESENT_MASK)) {
1041 eaa728ee bellard
            error_code = 0;
1042 eaa728ee bellard
            goto do_fault;
1043 eaa728ee bellard
        }
1044 eaa728ee bellard
        if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
1045 eaa728ee bellard
            error_code = PG_ERROR_RSVD_MASK;
1046 eaa728ee bellard
            goto do_fault;
1047 eaa728ee bellard
        }
1048 eaa728ee bellard
        ptep &= pde ^ PG_NX_MASK;
1049 eaa728ee bellard
        if (pde & PG_PSE_MASK) {
1050 eaa728ee bellard
            /* 2 MB page */
1051 eaa728ee bellard
            page_size = 2048 * 1024;
1052 eaa728ee bellard
            ptep ^= PG_NX_MASK;
1053 eaa728ee bellard
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
1054 eaa728ee bellard
                goto do_fault_protect;
1055 eaa728ee bellard
            if (is_user) {
1056 eaa728ee bellard
                if (!(ptep & PG_USER_MASK))
1057 eaa728ee bellard
                    goto do_fault_protect;
1058 eaa728ee bellard
                if (is_write && !(ptep & PG_RW_MASK))
1059 eaa728ee bellard
                    goto do_fault_protect;
1060 eaa728ee bellard
            } else {
1061 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
1062 eaa728ee bellard
                    is_write && !(ptep & PG_RW_MASK))
1063 eaa728ee bellard
                    goto do_fault_protect;
1064 eaa728ee bellard
            }
1065 eaa728ee bellard
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
1066 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
1067 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
1068 eaa728ee bellard
                if (is_dirty)
1069 eaa728ee bellard
                    pde |= PG_DIRTY_MASK;
1070 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
1071 eaa728ee bellard
            }
1072 eaa728ee bellard
            /* align to page_size */
1073 eaa728ee bellard
            pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
1074 eaa728ee bellard
            virt_addr = addr & ~(page_size - 1);
1075 eaa728ee bellard
        } else {
1076 eaa728ee bellard
            /* 4 KB page */
1077 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK)) {
1078 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
1079 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
1080 eaa728ee bellard
            }
1081 eaa728ee bellard
            pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
1082 eaa728ee bellard
                env->a20_mask;
1083 eaa728ee bellard
            pte = ldq_phys(pte_addr);
1084 eaa728ee bellard
            if (!(pte & PG_PRESENT_MASK)) {
1085 eaa728ee bellard
                error_code = 0;
1086 eaa728ee bellard
                goto do_fault;
1087 eaa728ee bellard
            }
1088 eaa728ee bellard
            if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
1089 eaa728ee bellard
                error_code = PG_ERROR_RSVD_MASK;
1090 eaa728ee bellard
                goto do_fault;
1091 eaa728ee bellard
            }
1092 eaa728ee bellard
            /* combine pde and pte nx, user and rw protections */
1093 eaa728ee bellard
            ptep &= pte ^ PG_NX_MASK;
1094 eaa728ee bellard
            ptep ^= PG_NX_MASK;
1095 eaa728ee bellard
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
1096 eaa728ee bellard
                goto do_fault_protect;
1097 eaa728ee bellard
            if (is_user) {
1098 eaa728ee bellard
                if (!(ptep & PG_USER_MASK))
1099 eaa728ee bellard
                    goto do_fault_protect;
1100 eaa728ee bellard
                if (is_write && !(ptep & PG_RW_MASK))
1101 eaa728ee bellard
                    goto do_fault_protect;
1102 eaa728ee bellard
            } else {
1103 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
1104 eaa728ee bellard
                    is_write && !(ptep & PG_RW_MASK))
1105 eaa728ee bellard
                    goto do_fault_protect;
1106 eaa728ee bellard
            }
1107 eaa728ee bellard
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1108 eaa728ee bellard
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1109 eaa728ee bellard
                pte |= PG_ACCESSED_MASK;
1110 eaa728ee bellard
                if (is_dirty)
1111 eaa728ee bellard
                    pte |= PG_DIRTY_MASK;
1112 eaa728ee bellard
                stl_phys_notdirty(pte_addr, pte);
1113 eaa728ee bellard
            }
1114 eaa728ee bellard
            page_size = 4096;
1115 eaa728ee bellard
            virt_addr = addr & ~0xfff;
1116 eaa728ee bellard
            pte = pte & (PHYS_ADDR_MASK | 0xfff);
1117 7e84c249 bellard
        }
1118 2c0262af bellard
    } else {
1119 eaa728ee bellard
        uint32_t pde;
1120 eaa728ee bellard
1121 eaa728ee bellard
        /* page directory entry */
1122 eaa728ee bellard
        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
1123 eaa728ee bellard
            env->a20_mask;
1124 eaa728ee bellard
        pde = ldl_phys(pde_addr);
1125 eaa728ee bellard
        if (!(pde & PG_PRESENT_MASK)) {
1126 eaa728ee bellard
            error_code = 0;
1127 eaa728ee bellard
            goto do_fault;
1128 eaa728ee bellard
        }
1129 eaa728ee bellard
        /* if PSE bit is set, then we use a 4MB page */
1130 eaa728ee bellard
        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1131 eaa728ee bellard
            page_size = 4096 * 1024;
1132 eaa728ee bellard
            if (is_user) {
1133 eaa728ee bellard
                if (!(pde & PG_USER_MASK))
1134 eaa728ee bellard
                    goto do_fault_protect;
1135 eaa728ee bellard
                if (is_write && !(pde & PG_RW_MASK))
1136 eaa728ee bellard
                    goto do_fault_protect;
1137 eaa728ee bellard
            } else {
1138 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
1139 eaa728ee bellard
                    is_write && !(pde & PG_RW_MASK))
1140 eaa728ee bellard
                    goto do_fault_protect;
1141 eaa728ee bellard
            }
1142 eaa728ee bellard
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
1143 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
1144 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
1145 eaa728ee bellard
                if (is_dirty)
1146 eaa728ee bellard
                    pde |= PG_DIRTY_MASK;
1147 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
1148 eaa728ee bellard
            }
1149 2c0262af bellard
1150 eaa728ee bellard
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1151 eaa728ee bellard
            ptep = pte;
1152 eaa728ee bellard
            virt_addr = addr & ~(page_size - 1);
1153 eaa728ee bellard
        } else {
1154 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK)) {
1155 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
1156 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
1157 eaa728ee bellard
            }
1158 891b38e4 bellard
1159 eaa728ee bellard
            /* page directory entry */
1160 eaa728ee bellard
            pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
1161 eaa728ee bellard
                env->a20_mask;
1162 eaa728ee bellard
            pte = ldl_phys(pte_addr);
1163 eaa728ee bellard
            if (!(pte & PG_PRESENT_MASK)) {
1164 eaa728ee bellard
                error_code = 0;
1165 eaa728ee bellard
                goto do_fault;
1166 8e682019 bellard
            }
1167 eaa728ee bellard
            /* combine pde and pte user and rw protections */
1168 eaa728ee bellard
            ptep = pte & pde;
1169 eaa728ee bellard
            if (is_user) {
1170 eaa728ee bellard
                if (!(ptep & PG_USER_MASK))
1171 eaa728ee bellard
                    goto do_fault_protect;
1172 eaa728ee bellard
                if (is_write && !(ptep & PG_RW_MASK))
1173 eaa728ee bellard
                    goto do_fault_protect;
1174 eaa728ee bellard
            } else {
1175 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
1176 eaa728ee bellard
                    is_write && !(ptep & PG_RW_MASK))
1177 eaa728ee bellard
                    goto do_fault_protect;
1178 8e682019 bellard
            }
1179 eaa728ee bellard
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1180 eaa728ee bellard
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1181 eaa728ee bellard
                pte |= PG_ACCESSED_MASK;
1182 eaa728ee bellard
                if (is_dirty)
1183 eaa728ee bellard
                    pte |= PG_DIRTY_MASK;
1184 eaa728ee bellard
                stl_phys_notdirty(pte_addr, pte);
1185 eaa728ee bellard
            }
1186 eaa728ee bellard
            page_size = 4096;
1187 eaa728ee bellard
            virt_addr = addr & ~0xfff;
1188 2c0262af bellard
        }
1189 2c0262af bellard
    }
1190 eaa728ee bellard
    /* the page can be put in the TLB */
1191 eaa728ee bellard
    prot = PAGE_READ;
1192 eaa728ee bellard
    if (!(ptep & PG_NX_MASK))
1193 eaa728ee bellard
        prot |= PAGE_EXEC;
1194 eaa728ee bellard
    if (pte & PG_DIRTY_MASK) {
1195 eaa728ee bellard
        /* only set write access if already dirty... otherwise wait
1196 eaa728ee bellard
           for dirty access */
1197 eaa728ee bellard
        if (is_user) {
1198 eaa728ee bellard
            if (ptep & PG_RW_MASK)
1199 eaa728ee bellard
                prot |= PAGE_WRITE;
1200 eaa728ee bellard
        } else {
1201 eaa728ee bellard
            if (!(env->cr[0] & CR0_WP_MASK) ||
1202 eaa728ee bellard
                (ptep & PG_RW_MASK))
1203 eaa728ee bellard
                prot |= PAGE_WRITE;
1204 8e682019 bellard
        }
1205 891b38e4 bellard
    }
1206 eaa728ee bellard
 do_mapping:
1207 eaa728ee bellard
    pte = pte & env->a20_mask;
1208 eaa728ee bellard
1209 eaa728ee bellard
    /* Even if 4MB pages, we map only one 4KB page in the cache to
1210 eaa728ee bellard
       avoid filling it too fast */
1211 eaa728ee bellard
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1212 eaa728ee bellard
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1213 eaa728ee bellard
    vaddr = virt_addr + page_offset;
1214 eaa728ee bellard
1215 eaa728ee bellard
    ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
1216 eaa728ee bellard
    return ret;
1217 eaa728ee bellard
 do_fault_protect:
1218 eaa728ee bellard
    error_code = PG_ERROR_P_MASK;
1219 eaa728ee bellard
 do_fault:
1220 eaa728ee bellard
    error_code |= (is_write << PG_ERROR_W_BIT);
1221 eaa728ee bellard
    if (is_user)
1222 eaa728ee bellard
        error_code |= PG_ERROR_U_MASK;
1223 eaa728ee bellard
    if (is_write1 == 2 &&
1224 eaa728ee bellard
        (env->efer & MSR_EFER_NXE) &&
1225 eaa728ee bellard
        (env->cr[4] & CR4_PAE_MASK))
1226 eaa728ee bellard
        error_code |= PG_ERROR_I_D_MASK;
1227 872929aa bellard
    if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
1228 872929aa bellard
        /* cr2 is not modified in case of exceptions */
1229 872929aa bellard
        stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 
1230 872929aa bellard
                 addr);
1231 eaa728ee bellard
    } else {
1232 eaa728ee bellard
        env->cr[2] = addr;
1233 2c0262af bellard
    }
1234 eaa728ee bellard
    env->error_code = error_code;
1235 eaa728ee bellard
    env->exception_index = EXCP0E_PAGE;
1236 eaa728ee bellard
    return 1;
1237 14ce26e7 bellard
}
1238 14ce26e7 bellard
1239 eaa728ee bellard
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1240 14ce26e7 bellard
{
1241 eaa728ee bellard
    target_ulong pde_addr, pte_addr;
1242 eaa728ee bellard
    uint64_t pte;
1243 eaa728ee bellard
    target_phys_addr_t paddr;
1244 eaa728ee bellard
    uint32_t page_offset;
1245 eaa728ee bellard
    int page_size;
1246 14ce26e7 bellard
1247 eaa728ee bellard
    if (env->cr[4] & CR4_PAE_MASK) {
1248 eaa728ee bellard
        target_ulong pdpe_addr;
1249 eaa728ee bellard
        uint64_t pde, pdpe;
1250 14ce26e7 bellard
1251 eaa728ee bellard
#ifdef TARGET_X86_64
1252 eaa728ee bellard
        if (env->hflags & HF_LMA_MASK) {
1253 eaa728ee bellard
            uint64_t pml4e_addr, pml4e;
1254 eaa728ee bellard
            int32_t sext;
1255 eaa728ee bellard
1256 eaa728ee bellard
            /* test virtual address sign extension */
1257 eaa728ee bellard
            sext = (int64_t)addr >> 47;
1258 eaa728ee bellard
            if (sext != 0 && sext != -1)
1259 eaa728ee bellard
                return -1;
1260 eaa728ee bellard
1261 eaa728ee bellard
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
1262 eaa728ee bellard
                env->a20_mask;
1263 eaa728ee bellard
            pml4e = ldq_phys(pml4e_addr);
1264 eaa728ee bellard
            if (!(pml4e & PG_PRESENT_MASK))
1265 eaa728ee bellard
                return -1;
1266 eaa728ee bellard
1267 eaa728ee bellard
            pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
1268 eaa728ee bellard
                env->a20_mask;
1269 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
1270 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK))
1271 eaa728ee bellard
                return -1;
1272 eaa728ee bellard
        } else
1273 eaa728ee bellard
#endif
1274 eaa728ee bellard
        {
1275 eaa728ee bellard
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1276 eaa728ee bellard
                env->a20_mask;
1277 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
1278 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK))
1279 eaa728ee bellard
                return -1;
1280 14ce26e7 bellard
        }
1281 14ce26e7 bellard
1282 eaa728ee bellard
        pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
1283 eaa728ee bellard
            env->a20_mask;
1284 eaa728ee bellard
        pde = ldq_phys(pde_addr);
1285 eaa728ee bellard
        if (!(pde & PG_PRESENT_MASK)) {
1286 eaa728ee bellard
            return -1;
1287 eaa728ee bellard
        }
1288 eaa728ee bellard
        if (pde & PG_PSE_MASK) {
1289 eaa728ee bellard
            /* 2 MB page */
1290 eaa728ee bellard
            page_size = 2048 * 1024;
1291 eaa728ee bellard
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1292 eaa728ee bellard
        } else {
1293 eaa728ee bellard
            /* 4 KB page */
1294 eaa728ee bellard
            pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
1295 eaa728ee bellard
                env->a20_mask;
1296 eaa728ee bellard
            page_size = 4096;
1297 eaa728ee bellard
            pte = ldq_phys(pte_addr);
1298 eaa728ee bellard
        }
1299 ca1c9e15 aliguori
        if (!(pte & PG_PRESENT_MASK))
1300 ca1c9e15 aliguori
            return -1;
1301 14ce26e7 bellard
    } else {
1302 eaa728ee bellard
        uint32_t pde;
1303 3b46e624 ths
1304 eaa728ee bellard
        if (!(env->cr[0] & CR0_PG_MASK)) {
1305 eaa728ee bellard
            pte = addr;
1306 eaa728ee bellard
            page_size = 4096;
1307 eaa728ee bellard
        } else {
1308 eaa728ee bellard
            /* page directory entry */
1309 eaa728ee bellard
            pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
1310 eaa728ee bellard
            pde = ldl_phys(pde_addr);
1311 eaa728ee bellard
            if (!(pde & PG_PRESENT_MASK))
1312 eaa728ee bellard
                return -1;
1313 eaa728ee bellard
            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1314 eaa728ee bellard
                pte = pde & ~0x003ff000; /* align to 4MB */
1315 eaa728ee bellard
                page_size = 4096 * 1024;
1316 eaa728ee bellard
            } else {
1317 eaa728ee bellard
                /* page directory entry */
1318 eaa728ee bellard
                pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
1319 eaa728ee bellard
                pte = ldl_phys(pte_addr);
1320 eaa728ee bellard
                if (!(pte & PG_PRESENT_MASK))
1321 eaa728ee bellard
                    return -1;
1322 eaa728ee bellard
                page_size = 4096;
1323 eaa728ee bellard
            }
1324 eaa728ee bellard
        }
1325 eaa728ee bellard
        pte = pte & env->a20_mask;
1326 14ce26e7 bellard
    }
1327 14ce26e7 bellard
1328 eaa728ee bellard
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1329 eaa728ee bellard
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1330 eaa728ee bellard
    return paddr;
1331 3b21e03e bellard
}
1332 01df040b aliguori
1333 01df040b aliguori
void hw_breakpoint_insert(CPUState *env, int index)
1334 01df040b aliguori
{
1335 01df040b aliguori
    int type, err = 0;
1336 01df040b aliguori
1337 01df040b aliguori
    switch (hw_breakpoint_type(env->dr[7], index)) {
1338 01df040b aliguori
    case 0:
1339 01df040b aliguori
        if (hw_breakpoint_enabled(env->dr[7], index))
1340 01df040b aliguori
            err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
1341 01df040b aliguori
                                        &env->cpu_breakpoint[index]);
1342 01df040b aliguori
        break;
1343 01df040b aliguori
    case 1:
1344 01df040b aliguori
        type = BP_CPU | BP_MEM_WRITE;
1345 01df040b aliguori
        goto insert_wp;
1346 01df040b aliguori
    case 2:
1347 01df040b aliguori
         /* No support for I/O watchpoints yet */
1348 01df040b aliguori
        break;
1349 01df040b aliguori
    case 3:
1350 01df040b aliguori
        type = BP_CPU | BP_MEM_ACCESS;
1351 01df040b aliguori
    insert_wp:
1352 01df040b aliguori
        err = cpu_watchpoint_insert(env, env->dr[index],
1353 01df040b aliguori
                                    hw_breakpoint_len(env->dr[7], index),
1354 01df040b aliguori
                                    type, &env->cpu_watchpoint[index]);
1355 01df040b aliguori
        break;
1356 01df040b aliguori
    }
1357 01df040b aliguori
    if (err)
1358 01df040b aliguori
        env->cpu_breakpoint[index] = NULL;
1359 01df040b aliguori
}
1360 01df040b aliguori
1361 01df040b aliguori
void hw_breakpoint_remove(CPUState *env, int index)
1362 01df040b aliguori
{
1363 01df040b aliguori
    if (!env->cpu_breakpoint[index])
1364 01df040b aliguori
        return;
1365 01df040b aliguori
    switch (hw_breakpoint_type(env->dr[7], index)) {
1366 01df040b aliguori
    case 0:
1367 01df040b aliguori
        if (hw_breakpoint_enabled(env->dr[7], index))
1368 01df040b aliguori
            cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
1369 01df040b aliguori
        break;
1370 01df040b aliguori
    case 1:
1371 01df040b aliguori
    case 3:
1372 01df040b aliguori
        cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
1373 01df040b aliguori
        break;
1374 01df040b aliguori
    case 2:
1375 01df040b aliguori
        /* No support for I/O watchpoints yet */
1376 01df040b aliguori
        break;
1377 01df040b aliguori
    }
1378 01df040b aliguori
}
1379 01df040b aliguori
1380 01df040b aliguori
int check_hw_breakpoints(CPUState *env, int force_dr6_update)
1381 01df040b aliguori
{
1382 01df040b aliguori
    target_ulong dr6;
1383 01df040b aliguori
    int reg, type;
1384 01df040b aliguori
    int hit_enabled = 0;
1385 01df040b aliguori
1386 01df040b aliguori
    dr6 = env->dr[6] & ~0xf;
1387 01df040b aliguori
    for (reg = 0; reg < 4; reg++) {
1388 01df040b aliguori
        type = hw_breakpoint_type(env->dr[7], reg);
1389 01df040b aliguori
        if ((type == 0 && env->dr[reg] == env->eip) ||
1390 01df040b aliguori
            ((type & 1) && env->cpu_watchpoint[reg] &&
1391 01df040b aliguori
             (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
1392 01df040b aliguori
            dr6 |= 1 << reg;
1393 01df040b aliguori
            if (hw_breakpoint_enabled(env->dr[7], reg))
1394 01df040b aliguori
                hit_enabled = 1;
1395 01df040b aliguori
        }
1396 01df040b aliguori
    }
1397 01df040b aliguori
    if (hit_enabled || force_dr6_update)
1398 01df040b aliguori
        env->dr[6] = dr6;
1399 01df040b aliguori
    return hit_enabled;
1400 01df040b aliguori
}
1401 01df040b aliguori
1402 01df040b aliguori
static CPUDebugExcpHandler *prev_debug_excp_handler;
1403 01df040b aliguori
1404 01df040b aliguori
void raise_exception(int exception_index);
1405 01df040b aliguori
1406 01df040b aliguori
static void breakpoint_handler(CPUState *env)
1407 01df040b aliguori
{
1408 01df040b aliguori
    CPUBreakpoint *bp;
1409 01df040b aliguori
1410 01df040b aliguori
    if (env->watchpoint_hit) {
1411 01df040b aliguori
        if (env->watchpoint_hit->flags & BP_CPU) {
1412 01df040b aliguori
            env->watchpoint_hit = NULL;
1413 01df040b aliguori
            if (check_hw_breakpoints(env, 0))
1414 01df040b aliguori
                raise_exception(EXCP01_DB);
1415 01df040b aliguori
            else
1416 01df040b aliguori
                cpu_resume_from_signal(env, NULL);
1417 01df040b aliguori
        }
1418 01df040b aliguori
    } else {
1419 c0ce998e aliguori
        TAILQ_FOREACH(bp, &env->breakpoints, entry)
1420 01df040b aliguori
            if (bp->pc == env->eip) {
1421 01df040b aliguori
                if (bp->flags & BP_CPU) {
1422 01df040b aliguori
                    check_hw_breakpoints(env, 1);
1423 01df040b aliguori
                    raise_exception(EXCP01_DB);
1424 01df040b aliguori
                }
1425 01df040b aliguori
                break;
1426 01df040b aliguori
            }
1427 01df040b aliguori
    }
1428 01df040b aliguori
    if (prev_debug_excp_handler)
1429 01df040b aliguori
        prev_debug_excp_handler(env);
1430 01df040b aliguori
}
1431 74ce674f bellard
#endif /* !CONFIG_USER_ONLY */
1432 6fd805e1 aliguori
1433 e00b6f80 aliguori
static void host_cpuid(uint32_t function, uint32_t count,
1434 e00b6f80 aliguori
                       uint32_t *eax, uint32_t *ebx,
1435 7ba1e619 aliguori
                       uint32_t *ecx, uint32_t *edx)
1436 7ba1e619 aliguori
{
1437 10781c09 aliguori
#if defined(CONFIG_KVM)
1438 7ba1e619 aliguori
    uint32_t vec[4];
1439 7ba1e619 aliguori
1440 7ba1e619 aliguori
#ifdef __x86_64__
1441 7ba1e619 aliguori
    asm volatile("cpuid"
1442 e00b6f80 aliguori
                 : "=a"(vec[0]), "=b"(vec[1]),
1443 e00b6f80 aliguori
                   "=c"(vec[2]), "=d"(vec[3])
1444 e00b6f80 aliguori
                 : "0"(function), "c"(count) : "cc");
1445 7ba1e619 aliguori
#else
1446 7ba1e619 aliguori
    asm volatile("pusha \n\t"
1447 e00b6f80 aliguori
                 "cpuid \n\t"
1448 b36d24b6 aliguori
                 "mov %%eax, 0(%2) \n\t"
1449 b36d24b6 aliguori
                 "mov %%ebx, 4(%2) \n\t"
1450 b36d24b6 aliguori
                 "mov %%ecx, 8(%2) \n\t"
1451 b36d24b6 aliguori
                 "mov %%edx, 12(%2) \n\t"
1452 e00b6f80 aliguori
                 "popa"
1453 e00b6f80 aliguori
                 : : "a"(function), "c"(count), "S"(vec)
1454 e00b6f80 aliguori
                 : "memory", "cc");
1455 7ba1e619 aliguori
#endif
1456 7ba1e619 aliguori
1457 7ba1e619 aliguori
    if (eax)
1458 7ba1e619 aliguori
        *eax = vec[0];
1459 7ba1e619 aliguori
    if (ebx)
1460 7ba1e619 aliguori
        *ebx = vec[1];
1461 7ba1e619 aliguori
    if (ecx)
1462 7ba1e619 aliguori
        *ecx = vec[2];
1463 7ba1e619 aliguori
    if (edx)
1464 7ba1e619 aliguori
        *edx = vec[3];
1465 7ba1e619 aliguori
#endif
1466 10781c09 aliguori
}
1467 7ba1e619 aliguori
1468 e00b6f80 aliguori
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1469 6fd805e1 aliguori
                   uint32_t *eax, uint32_t *ebx,
1470 6fd805e1 aliguori
                   uint32_t *ecx, uint32_t *edx)
1471 6fd805e1 aliguori
{
1472 6fd805e1 aliguori
    /* test if maximum index reached */
1473 6fd805e1 aliguori
    if (index & 0x80000000) {
1474 6fd805e1 aliguori
        if (index > env->cpuid_xlevel)
1475 6fd805e1 aliguori
            index = env->cpuid_level;
1476 6fd805e1 aliguori
    } else {
1477 6fd805e1 aliguori
        if (index > env->cpuid_level)
1478 6fd805e1 aliguori
            index = env->cpuid_level;
1479 6fd805e1 aliguori
    }
1480 6fd805e1 aliguori
1481 6fd805e1 aliguori
    switch(index) {
1482 6fd805e1 aliguori
    case 0:
1483 6fd805e1 aliguori
        *eax = env->cpuid_level;
1484 6fd805e1 aliguori
        *ebx = env->cpuid_vendor1;
1485 6fd805e1 aliguori
        *edx = env->cpuid_vendor2;
1486 6fd805e1 aliguori
        *ecx = env->cpuid_vendor3;
1487 7ba1e619 aliguori
1488 7ba1e619 aliguori
        /* sysenter isn't supported on compatibility mode on AMD.  and syscall
1489 7ba1e619 aliguori
         * isn't supported in compatibility mode on Intel.  so advertise the
1490 7ba1e619 aliguori
         * actuall cpu, and say goodbye to migration between different vendors
1491 7ba1e619 aliguori
         * is you use compatibility mode. */
1492 7ba1e619 aliguori
        if (kvm_enabled())
1493 e00b6f80 aliguori
            host_cpuid(0, 0, NULL, ebx, ecx, edx);
1494 6fd805e1 aliguori
        break;
1495 6fd805e1 aliguori
    case 1:
1496 6fd805e1 aliguori
        *eax = env->cpuid_version;
1497 6fd805e1 aliguori
        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
1498 6fd805e1 aliguori
        *ecx = env->cpuid_ext_features;
1499 6fd805e1 aliguori
        *edx = env->cpuid_features;
1500 7ba1e619 aliguori
1501 7ba1e619 aliguori
        /* "Hypervisor present" bit required for Microsoft SVVP */
1502 7ba1e619 aliguori
        if (kvm_enabled())
1503 7ba1e619 aliguori
            *ecx |= (1 << 31);
1504 6fd805e1 aliguori
        break;
1505 6fd805e1 aliguori
    case 2:
1506 6fd805e1 aliguori
        /* cache info: needed for Pentium Pro compatibility */
1507 6fd805e1 aliguori
        *eax = 1;
1508 6fd805e1 aliguori
        *ebx = 0;
1509 6fd805e1 aliguori
        *ecx = 0;
1510 6fd805e1 aliguori
        *edx = 0x2c307d;
1511 6fd805e1 aliguori
        break;
1512 6fd805e1 aliguori
    case 4:
1513 6fd805e1 aliguori
        /* cache info: needed for Core compatibility */
1514 e00b6f80 aliguori
        switch (count) {
1515 6fd805e1 aliguori
            case 0: /* L1 dcache info */
1516 6fd805e1 aliguori
                *eax = 0x0000121;
1517 6fd805e1 aliguori
                *ebx = 0x1c0003f;
1518 6fd805e1 aliguori
                *ecx = 0x000003f;
1519 6fd805e1 aliguori
                *edx = 0x0000001;
1520 6fd805e1 aliguori
                break;
1521 6fd805e1 aliguori
            case 1: /* L1 icache info */
1522 6fd805e1 aliguori
                *eax = 0x0000122;
1523 6fd805e1 aliguori
                *ebx = 0x1c0003f;
1524 6fd805e1 aliguori
                *ecx = 0x000003f;
1525 6fd805e1 aliguori
                *edx = 0x0000001;
1526 6fd805e1 aliguori
                break;
1527 6fd805e1 aliguori
            case 2: /* L2 cache info */
1528 6fd805e1 aliguori
                *eax = 0x0000143;
1529 6fd805e1 aliguori
                *ebx = 0x3c0003f;
1530 6fd805e1 aliguori
                *ecx = 0x0000fff;
1531 6fd805e1 aliguori
                *edx = 0x0000001;
1532 6fd805e1 aliguori
                break;
1533 6fd805e1 aliguori
            default: /* end of info */
1534 6fd805e1 aliguori
                *eax = 0;
1535 6fd805e1 aliguori
                *ebx = 0;
1536 6fd805e1 aliguori
                *ecx = 0;
1537 6fd805e1 aliguori
                *edx = 0;
1538 6fd805e1 aliguori
                break;
1539 6fd805e1 aliguori
        }
1540 6fd805e1 aliguori
        break;
1541 6fd805e1 aliguori
    case 5:
1542 6fd805e1 aliguori
        /* mwait info: needed for Core compatibility */
1543 6fd805e1 aliguori
        *eax = 0; /* Smallest monitor-line size in bytes */
1544 6fd805e1 aliguori
        *ebx = 0; /* Largest monitor-line size in bytes */
1545 6fd805e1 aliguori
        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
1546 6fd805e1 aliguori
        *edx = 0;
1547 6fd805e1 aliguori
        break;
1548 6fd805e1 aliguori
    case 6:
1549 6fd805e1 aliguori
        /* Thermal and Power Leaf */
1550 6fd805e1 aliguori
        *eax = 0;
1551 6fd805e1 aliguori
        *ebx = 0;
1552 6fd805e1 aliguori
        *ecx = 0;
1553 6fd805e1 aliguori
        *edx = 0;
1554 6fd805e1 aliguori
        break;
1555 6fd805e1 aliguori
    case 9:
1556 6fd805e1 aliguori
        /* Direct Cache Access Information Leaf */
1557 6fd805e1 aliguori
        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
1558 6fd805e1 aliguori
        *ebx = 0;
1559 6fd805e1 aliguori
        *ecx = 0;
1560 6fd805e1 aliguori
        *edx = 0;
1561 6fd805e1 aliguori
        break;
1562 6fd805e1 aliguori
    case 0xA:
1563 6fd805e1 aliguori
        /* Architectural Performance Monitoring Leaf */
1564 6fd805e1 aliguori
        *eax = 0;
1565 6fd805e1 aliguori
        *ebx = 0;
1566 6fd805e1 aliguori
        *ecx = 0;
1567 6fd805e1 aliguori
        *edx = 0;
1568 6fd805e1 aliguori
        break;
1569 6fd805e1 aliguori
    case 0x80000000:
1570 6fd805e1 aliguori
        *eax = env->cpuid_xlevel;
1571 6fd805e1 aliguori
        *ebx = env->cpuid_vendor1;
1572 6fd805e1 aliguori
        *edx = env->cpuid_vendor2;
1573 6fd805e1 aliguori
        *ecx = env->cpuid_vendor3;
1574 6fd805e1 aliguori
        break;
1575 6fd805e1 aliguori
    case 0x80000001:
1576 6fd805e1 aliguori
        *eax = env->cpuid_features;
1577 6fd805e1 aliguori
        *ebx = 0;
1578 6fd805e1 aliguori
        *ecx = env->cpuid_ext3_features;
1579 6fd805e1 aliguori
        *edx = env->cpuid_ext2_features;
1580 7ba1e619 aliguori
1581 7ba1e619 aliguori
        if (kvm_enabled()) {
1582 7ba1e619 aliguori
            uint32_t h_eax, h_edx;
1583 7ba1e619 aliguori
1584 e00b6f80 aliguori
            host_cpuid(index, 0, &h_eax, NULL, NULL, &h_edx);
1585 7ba1e619 aliguori
1586 7ba1e619 aliguori
            /* disable CPU features that the host does not support */
1587 7ba1e619 aliguori
1588 7ba1e619 aliguori
            /* long mode */
1589 7ba1e619 aliguori
            if ((h_edx & 0x20000000) == 0 /* || !lm_capable_kernel */)
1590 7ba1e619 aliguori
                *edx &= ~0x20000000;
1591 7ba1e619 aliguori
            /* syscall */
1592 7ba1e619 aliguori
            if ((h_edx & 0x00000800) == 0)
1593 7ba1e619 aliguori
                *edx &= ~0x00000800;
1594 7ba1e619 aliguori
            /* nx */
1595 7ba1e619 aliguori
            if ((h_edx & 0x00100000) == 0)
1596 7ba1e619 aliguori
                *edx &= ~0x00100000;
1597 7ba1e619 aliguori
1598 7ba1e619 aliguori
            /* disable CPU features that KVM cannot support */
1599 7ba1e619 aliguori
1600 7ba1e619 aliguori
            /* svm */
1601 7ba1e619 aliguori
            *ecx &= ~4UL;
1602 7ba1e619 aliguori
            /* 3dnow */
1603 57003085 aliguori
            *edx &= ~0xc0000000;
1604 7ba1e619 aliguori
        }
1605 6fd805e1 aliguori
        break;
1606 6fd805e1 aliguori
    case 0x80000002:
1607 6fd805e1 aliguori
    case 0x80000003:
1608 6fd805e1 aliguori
    case 0x80000004:
1609 6fd805e1 aliguori
        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
1610 6fd805e1 aliguori
        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
1611 6fd805e1 aliguori
        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
1612 6fd805e1 aliguori
        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
1613 6fd805e1 aliguori
        break;
1614 6fd805e1 aliguori
    case 0x80000005:
1615 6fd805e1 aliguori
        /* cache info (L1 cache) */
1616 6fd805e1 aliguori
        *eax = 0x01ff01ff;
1617 6fd805e1 aliguori
        *ebx = 0x01ff01ff;
1618 6fd805e1 aliguori
        *ecx = 0x40020140;
1619 6fd805e1 aliguori
        *edx = 0x40020140;
1620 6fd805e1 aliguori
        break;
1621 6fd805e1 aliguori
    case 0x80000006:
1622 6fd805e1 aliguori
        /* cache info (L2 cache) */
1623 6fd805e1 aliguori
        *eax = 0;
1624 6fd805e1 aliguori
        *ebx = 0x42004200;
1625 6fd805e1 aliguori
        *ecx = 0x02008140;
1626 6fd805e1 aliguori
        *edx = 0;
1627 6fd805e1 aliguori
        break;
1628 6fd805e1 aliguori
    case 0x80000008:
1629 6fd805e1 aliguori
        /* virtual & phys address size in low 2 bytes. */
1630 6fd805e1 aliguori
/* XXX: This value must match the one used in the MMU code. */ 
1631 6fd805e1 aliguori
        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
1632 6fd805e1 aliguori
            /* 64 bit processor */
1633 640f42e4 blueswir1
#if defined(CONFIG_KQEMU)
1634 6fd805e1 aliguori
            *eax = 0x00003020;        /* 48 bits virtual, 32 bits physical */
1635 6fd805e1 aliguori
#else
1636 6fd805e1 aliguori
/* XXX: The physical address space is limited to 42 bits in exec.c. */
1637 6fd805e1 aliguori
            *eax = 0x00003028;        /* 48 bits virtual, 40 bits physical */
1638 6fd805e1 aliguori
#endif
1639 6fd805e1 aliguori
        } else {
1640 640f42e4 blueswir1
#if defined(CONFIG_KQEMU)
1641 6fd805e1 aliguori
            *eax = 0x00000020;        /* 32 bits physical */
1642 6fd805e1 aliguori
#else
1643 6fd805e1 aliguori
            if (env->cpuid_features & CPUID_PSE36)
1644 6fd805e1 aliguori
                *eax = 0x00000024; /* 36 bits physical */
1645 6fd805e1 aliguori
            else
1646 6fd805e1 aliguori
                *eax = 0x00000020; /* 32 bits physical */
1647 6fd805e1 aliguori
#endif
1648 6fd805e1 aliguori
        }
1649 6fd805e1 aliguori
        *ebx = 0;
1650 6fd805e1 aliguori
        *ecx = 0;
1651 6fd805e1 aliguori
        *edx = 0;
1652 6fd805e1 aliguori
        break;
1653 6fd805e1 aliguori
    case 0x8000000A:
1654 6fd805e1 aliguori
        *eax = 0x00000001; /* SVM Revision */
1655 6fd805e1 aliguori
        *ebx = 0x00000010; /* nr of ASIDs */
1656 6fd805e1 aliguori
        *ecx = 0;
1657 6fd805e1 aliguori
        *edx = 0; /* optional features */
1658 6fd805e1 aliguori
        break;
1659 6fd805e1 aliguori
    default:
1660 6fd805e1 aliguori
        /* reserved values: zero */
1661 6fd805e1 aliguori
        *eax = 0;
1662 6fd805e1 aliguori
        *ebx = 0;
1663 6fd805e1 aliguori
        *ecx = 0;
1664 6fd805e1 aliguori
        *edx = 0;
1665 6fd805e1 aliguori
        break;
1666 6fd805e1 aliguori
    }
1667 6fd805e1 aliguori
}
1668 01df040b aliguori
1669 01df040b aliguori
CPUX86State *cpu_x86_init(const char *cpu_model)
1670 01df040b aliguori
{
1671 01df040b aliguori
    CPUX86State *env;
1672 01df040b aliguori
    static int inited;
1673 01df040b aliguori
1674 01df040b aliguori
    env = qemu_mallocz(sizeof(CPUX86State));
1675 01df040b aliguori
    cpu_exec_init(env);
1676 01df040b aliguori
    env->cpu_model_str = cpu_model;
1677 01df040b aliguori
1678 01df040b aliguori
    /* init various static tables */
1679 01df040b aliguori
    if (!inited) {
1680 01df040b aliguori
        inited = 1;
1681 01df040b aliguori
        optimize_flags_init();
1682 01df040b aliguori
#ifndef CONFIG_USER_ONLY
1683 01df040b aliguori
        prev_debug_excp_handler =
1684 01df040b aliguori
            cpu_set_debug_excp_handler(breakpoint_handler);
1685 01df040b aliguori
#endif
1686 01df040b aliguori
    }
1687 01df040b aliguori
    if (cpu_x86_register(env, cpu_model) < 0) {
1688 01df040b aliguori
        cpu_x86_close(env);
1689 01df040b aliguori
        return NULL;
1690 01df040b aliguori
    }
1691 01df040b aliguori
    cpu_reset(env);
1692 640f42e4 blueswir1
#ifdef CONFIG_KQEMU
1693 01df040b aliguori
    kqemu_init(env);
1694 01df040b aliguori
#endif
1695 01df040b aliguori
    if (kvm_enabled())
1696 01df040b aliguori
        kvm_init_vcpu(env);
1697 01df040b aliguori
    return env;
1698 01df040b aliguori
}