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