Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ ac72472b

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