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