]> git.proxmox.com Git - qemu.git/blame - target-i386/helper.c
Remove GenOpFunc typedefs
[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
eaa728ee
FB
573void cpu_dump_state(CPUState *env, FILE *f,
574 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
575 int flags)
576{
577 int eflags, i, nb;
578 char cc_op_name[32];
579 static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
7e84c249 580
eaa728ee
FB
581 eflags = env->eflags;
582#ifdef TARGET_X86_64
583 if (env->hflags & HF_CS64_MASK) {
584 cpu_fprintf(f,
585 "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
586 "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
587 "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
588 "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
589 "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
590 env->regs[R_EAX],
591 env->regs[R_EBX],
592 env->regs[R_ECX],
593 env->regs[R_EDX],
594 env->regs[R_ESI],
595 env->regs[R_EDI],
596 env->regs[R_EBP],
597 env->regs[R_ESP],
598 env->regs[8],
599 env->regs[9],
600 env->regs[10],
601 env->regs[11],
602 env->regs[12],
603 env->regs[13],
604 env->regs[14],
605 env->regs[15],
606 env->eip, eflags,
607 eflags & DF_MASK ? 'D' : '-',
608 eflags & CC_O ? 'O' : '-',
609 eflags & CC_S ? 'S' : '-',
610 eflags & CC_Z ? 'Z' : '-',
611 eflags & CC_A ? 'A' : '-',
612 eflags & CC_P ? 'P' : '-',
613 eflags & CC_C ? 'C' : '-',
614 env->hflags & HF_CPL_MASK,
615 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
616 (int)(env->a20_mask >> 20) & 1,
617 (env->hflags >> HF_SMM_SHIFT) & 1,
ce5232c5 618 env->halted);
eaa728ee
FB
619 } else
620#endif
621 {
622 cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
623 "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
624 "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
625 (uint32_t)env->regs[R_EAX],
626 (uint32_t)env->regs[R_EBX],
627 (uint32_t)env->regs[R_ECX],
628 (uint32_t)env->regs[R_EDX],
629 (uint32_t)env->regs[R_ESI],
630 (uint32_t)env->regs[R_EDI],
631 (uint32_t)env->regs[R_EBP],
632 (uint32_t)env->regs[R_ESP],
633 (uint32_t)env->eip, eflags,
634 eflags & DF_MASK ? 'D' : '-',
635 eflags & CC_O ? 'O' : '-',
636 eflags & CC_S ? 'S' : '-',
637 eflags & CC_Z ? 'Z' : '-',
638 eflags & CC_A ? 'A' : '-',
639 eflags & CC_P ? 'P' : '-',
640 eflags & CC_C ? 'C' : '-',
641 env->hflags & HF_CPL_MASK,
642 (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
643 (int)(env->a20_mask >> 20) & 1,
644 (env->hflags >> HF_SMM_SHIFT) & 1,
ce5232c5 645 env->halted);
8145122b 646 }
3b46e624 647
eaa728ee
FB
648#ifdef TARGET_X86_64
649 if (env->hflags & HF_LMA_MASK) {
650 for(i = 0; i < 6; i++) {
651 SegmentCache *sc = &env->segs[i];
652 cpu_fprintf(f, "%s =%04x %016" PRIx64 " %08x %08x\n",
653 seg_name[i],
654 sc->selector,
655 sc->base,
656 sc->limit,
657 sc->flags);
658 }
659 cpu_fprintf(f, "LDT=%04x %016" PRIx64 " %08x %08x\n",
660 env->ldt.selector,
661 env->ldt.base,
662 env->ldt.limit,
663 env->ldt.flags);
664 cpu_fprintf(f, "TR =%04x %016" PRIx64 " %08x %08x\n",
665 env->tr.selector,
666 env->tr.base,
667 env->tr.limit,
668 env->tr.flags);
669 cpu_fprintf(f, "GDT= %016" PRIx64 " %08x\n",
670 env->gdt.base, env->gdt.limit);
671 cpu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
672 env->idt.base, env->idt.limit);
673 cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
674 (uint32_t)env->cr[0],
675 env->cr[2],
676 env->cr[3],
677 (uint32_t)env->cr[4]);
a59cb4e0
AL
678 for(i = 0; i < 4; i++)
679 cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
680 cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
d4b55be5 681 env->dr[6], env->dr[7]);
eaa728ee
FB
682 } else
683#endif
684 {
685 for(i = 0; i < 6; i++) {
686 SegmentCache *sc = &env->segs[i];
687 cpu_fprintf(f, "%s =%04x %08x %08x %08x\n",
688 seg_name[i],
689 sc->selector,
690 (uint32_t)sc->base,
691 sc->limit,
692 sc->flags);
693 }
694 cpu_fprintf(f, "LDT=%04x %08x %08x %08x\n",
695 env->ldt.selector,
696 (uint32_t)env->ldt.base,
697 env->ldt.limit,
698 env->ldt.flags);
699 cpu_fprintf(f, "TR =%04x %08x %08x %08x\n",
700 env->tr.selector,
701 (uint32_t)env->tr.base,
702 env->tr.limit,
703 env->tr.flags);
704 cpu_fprintf(f, "GDT= %08x %08x\n",
705 (uint32_t)env->gdt.base, env->gdt.limit);
706 cpu_fprintf(f, "IDT= %08x %08x\n",
707 (uint32_t)env->idt.base, env->idt.limit);
708 cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
709 (uint32_t)env->cr[0],
710 (uint32_t)env->cr[2],
711 (uint32_t)env->cr[3],
712 (uint32_t)env->cr[4]);
a59cb4e0
AL
713 for(i = 0; i < 4; i++)
714 cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]);
d4b55be5 715 cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]);
eaa728ee
FB
716 }
717 if (flags & X86_DUMP_CCOP) {
718 if ((unsigned)env->cc_op < CC_OP_NB)
719 snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
720 else
721 snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
722#ifdef TARGET_X86_64
723 if (env->hflags & HF_CS64_MASK) {
724 cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
725 env->cc_src, env->cc_dst,
726 cc_op_name);
727 } else
728#endif
729 {
730 cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
731 (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
732 cc_op_name);
733 }
7e84c249 734 }
eaa728ee
FB
735 if (flags & X86_DUMP_FPU) {
736 int fptag;
737 fptag = 0;
738 for(i = 0; i < 8; i++) {
739 fptag |= ((!env->fptags[i]) << i);
740 }
741 cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
742 env->fpuc,
743 (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
744 env->fpstt,
745 fptag,
746 env->mxcsr);
747 for(i=0;i<8;i++) {
748#if defined(USE_X86LDOUBLE)
749 union {
750 long double d;
751 struct {
752 uint64_t lower;
753 uint16_t upper;
754 } l;
755 } tmp;
756 tmp.d = env->fpregs[i].d;
757 cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
758 i, tmp.l.lower, tmp.l.upper);
759#else
760 cpu_fprintf(f, "FPR%d=%016" PRIx64,
761 i, env->fpregs[i].mmx.q);
762#endif
763 if ((i & 1) == 1)
764 cpu_fprintf(f, "\n");
765 else
766 cpu_fprintf(f, " ");
767 }
768 if (env->hflags & HF_CS64_MASK)
769 nb = 16;
770 else
771 nb = 8;
772 for(i=0;i<nb;i++) {
773 cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
774 i,
775 env->xmm_regs[i].XMM_L(3),
776 env->xmm_regs[i].XMM_L(2),
777 env->xmm_regs[i].XMM_L(1),
778 env->xmm_regs[i].XMM_L(0));
779 if ((i & 1) == 1)
780 cpu_fprintf(f, "\n");
781 else
782 cpu_fprintf(f, " ");
783 }
7e84c249 784 }
2c0262af 785}
7e84c249 786
eaa728ee
FB
787/***********************************************************/
788/* x86 mmu */
789/* XXX: add PGE support */
790
791void cpu_x86_set_a20(CPUX86State *env, int a20_state)
2c0262af 792{
eaa728ee
FB
793 a20_state = (a20_state != 0);
794 if (a20_state != ((env->a20_mask >> 20) & 1)) {
795#if defined(DEBUG_MMU)
796 printf("A20 update: a20=%d\n", a20_state);
797#endif
798 /* if the cpu is currently executing code, we must unlink it and
799 all the potentially executing TB */
800 cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
3b46e624 801
eaa728ee
FB
802 /* when a20 is changed, all the MMU mappings are invalid, so
803 we must flush everything */
804 tlb_flush(env, 1);
805 env->a20_mask = (~0x100000) | (a20_state << 20);
7e84c249 806 }
2c0262af
FB
807}
808
eaa728ee 809void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
2c0262af 810{
eaa728ee 811 int pe_state;
2c0262af 812
eaa728ee
FB
813#if defined(DEBUG_MMU)
814 printf("CR0 update: CR0=0x%08x\n", new_cr0);
815#endif
816 if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
817 (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
818 tlb_flush(env, 1);
819 }
2c0262af 820
eaa728ee
FB
821#ifdef TARGET_X86_64
822 if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
823 (env->efer & MSR_EFER_LME)) {
824 /* enter in long mode */
825 /* XXX: generate an exception */
826 if (!(env->cr[4] & CR4_PAE_MASK))
827 return;
828 env->efer |= MSR_EFER_LMA;
829 env->hflags |= HF_LMA_MASK;
830 } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
831 (env->efer & MSR_EFER_LMA)) {
832 /* exit long mode */
833 env->efer &= ~MSR_EFER_LMA;
834 env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
835 env->eip &= 0xffffffff;
836 }
837#endif
838 env->cr[0] = new_cr0 | CR0_ET_MASK;
7e84c249 839
eaa728ee
FB
840 /* update PE flag in hidden flags */
841 pe_state = (env->cr[0] & CR0_PE_MASK);
842 env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
843 /* ensure that ADDSEG is always set in real mode */
844 env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
845 /* update FPU flags */
846 env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
847 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
7e84c249
FB
848}
849
eaa728ee
FB
850/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
851 the PDPT */
852void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
7e84c249 853{
eaa728ee
FB
854 env->cr[3] = new_cr3;
855 if (env->cr[0] & CR0_PG_MASK) {
856#if defined(DEBUG_MMU)
857 printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
858#endif
859 tlb_flush(env, 0);
860 }
7e84c249
FB
861}
862
eaa728ee 863void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
7e84c249 864{
eaa728ee
FB
865#if defined(DEBUG_MMU)
866 printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
867#endif
868 if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
869 (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
870 tlb_flush(env, 1);
871 }
872 /* SSE handling */
873 if (!(env->cpuid_features & CPUID_SSE))
874 new_cr4 &= ~CR4_OSFXSR_MASK;
875 if (new_cr4 & CR4_OSFXSR_MASK)
876 env->hflags |= HF_OSFXSR_MASK;
877 else
878 env->hflags &= ~HF_OSFXSR_MASK;
b8b6a50b 879
eaa728ee 880 env->cr[4] = new_cr4;
b8b6a50b
FB
881}
882
eaa728ee
FB
883#if defined(CONFIG_USER_ONLY)
884
885int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
886 int is_write, int mmu_idx, int is_softmmu)
b8b6a50b 887{
eaa728ee
FB
888 /* user mode only emulation */
889 is_write &= 1;
890 env->cr[2] = addr;
891 env->error_code = (is_write << PG_ERROR_W_BIT);
892 env->error_code |= PG_ERROR_U_MASK;
893 env->exception_index = EXCP0E_PAGE;
894 return 1;
2c0262af
FB
895}
896
eaa728ee 897target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
891b38e4 898{
eaa728ee 899 return addr;
891b38e4
FB
900}
901
8d7b0fbb 902#else
891b38e4 903
eaa728ee
FB
904/* XXX: This value should match the one returned by CPUID
905 * and in exec.c */
906#if defined(USE_KQEMU)
2c90d794 907#define PHYS_ADDR_MASK 0xfffff000LL
eaa728ee
FB
908#else
909# if defined(TARGET_X86_64)
2c90d794 910# define PHYS_ADDR_MASK 0xfffffff000LL
eaa728ee 911# else
2c90d794 912# define PHYS_ADDR_MASK 0xffffff000LL
eaa728ee
FB
913# endif
914#endif
915
916/* return value:
917 -1 = cannot handle fault
918 0 = nothing more to do
919 1 = generate PF fault
920 2 = soft MMU activation required for this block
921*/
922int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
923 int is_write1, int mmu_idx, int is_softmmu)
924{
925 uint64_t ptep, pte;
926 target_ulong pde_addr, pte_addr;
927 int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
928 target_phys_addr_t paddr;
929 uint32_t page_offset;
930 target_ulong vaddr, virt_addr;
931
932 is_user = mmu_idx == MMU_USER_IDX;
933#if defined(DEBUG_MMU)
934 printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
935 addr, is_write1, is_user, env->eip);
936#endif
937 is_write = is_write1 & 1;
938
939 if (!(env->cr[0] & CR0_PG_MASK)) {
940 pte = addr;
941 virt_addr = addr & TARGET_PAGE_MASK;
942 prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
943 page_size = 4096;
944 goto do_mapping;
945 }
946
947 if (env->cr[4] & CR4_PAE_MASK) {
948 uint64_t pde, pdpe;
949 target_ulong pdpe_addr;
2c0262af 950
eaa728ee
FB
951#ifdef TARGET_X86_64
952 if (env->hflags & HF_LMA_MASK) {
953 uint64_t pml4e_addr, pml4e;
954 int32_t sext;
955
956 /* test virtual address sign extension */
957 sext = (int64_t)addr >> 47;
958 if (sext != 0 && sext != -1) {
959 env->error_code = 0;
960 env->exception_index = EXCP0D_GPF;
961 return 1;
962 }
0573fbfc 963
eaa728ee
FB
964 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
965 env->a20_mask;
966 pml4e = ldq_phys(pml4e_addr);
967 if (!(pml4e & PG_PRESENT_MASK)) {
968 error_code = 0;
969 goto do_fault;
970 }
971 if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
972 error_code = PG_ERROR_RSVD_MASK;
973 goto do_fault;
974 }
975 if (!(pml4e & PG_ACCESSED_MASK)) {
976 pml4e |= PG_ACCESSED_MASK;
977 stl_phys_notdirty(pml4e_addr, pml4e);
978 }
979 ptep = pml4e ^ PG_NX_MASK;
980 pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
981 env->a20_mask;
982 pdpe = ldq_phys(pdpe_addr);
983 if (!(pdpe & PG_PRESENT_MASK)) {
984 error_code = 0;
985 goto do_fault;
986 }
987 if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
988 error_code = PG_ERROR_RSVD_MASK;
989 goto do_fault;
990 }
991 ptep &= pdpe ^ PG_NX_MASK;
992 if (!(pdpe & PG_ACCESSED_MASK)) {
993 pdpe |= PG_ACCESSED_MASK;
994 stl_phys_notdirty(pdpe_addr, pdpe);
995 }
996 } else
997#endif
998 {
999 /* XXX: load them when cr3 is loaded ? */
1000 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1001 env->a20_mask;
1002 pdpe = ldq_phys(pdpe_addr);
1003 if (!(pdpe & PG_PRESENT_MASK)) {
1004 error_code = 0;
1005 goto do_fault;
1006 }
1007 ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
7e84c249 1008 }
7e84c249 1009
eaa728ee
FB
1010 pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
1011 env->a20_mask;
1012 pde = ldq_phys(pde_addr);
1013 if (!(pde & PG_PRESENT_MASK)) {
1014 error_code = 0;
1015 goto do_fault;
1016 }
1017 if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
1018 error_code = PG_ERROR_RSVD_MASK;
1019 goto do_fault;
1020 }
1021 ptep &= pde ^ PG_NX_MASK;
1022 if (pde & PG_PSE_MASK) {
1023 /* 2 MB page */
1024 page_size = 2048 * 1024;
1025 ptep ^= PG_NX_MASK;
1026 if ((ptep & PG_NX_MASK) && is_write1 == 2)
1027 goto do_fault_protect;
1028 if (is_user) {
1029 if (!(ptep & PG_USER_MASK))
1030 goto do_fault_protect;
1031 if (is_write && !(ptep & PG_RW_MASK))
1032 goto do_fault_protect;
1033 } else {
1034 if ((env->cr[0] & CR0_WP_MASK) &&
1035 is_write && !(ptep & PG_RW_MASK))
1036 goto do_fault_protect;
1037 }
1038 is_dirty = is_write && !(pde & PG_DIRTY_MASK);
1039 if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
1040 pde |= PG_ACCESSED_MASK;
1041 if (is_dirty)
1042 pde |= PG_DIRTY_MASK;
1043 stl_phys_notdirty(pde_addr, pde);
1044 }
1045 /* align to page_size */
1046 pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
1047 virt_addr = addr & ~(page_size - 1);
1048 } else {
1049 /* 4 KB page */
1050 if (!(pde & PG_ACCESSED_MASK)) {
1051 pde |= PG_ACCESSED_MASK;
1052 stl_phys_notdirty(pde_addr, pde);
1053 }
1054 pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
1055 env->a20_mask;
1056 pte = ldq_phys(pte_addr);
1057 if (!(pte & PG_PRESENT_MASK)) {
1058 error_code = 0;
1059 goto do_fault;
1060 }
1061 if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
1062 error_code = PG_ERROR_RSVD_MASK;
1063 goto do_fault;
1064 }
1065 /* combine pde and pte nx, user and rw protections */
1066 ptep &= pte ^ PG_NX_MASK;
1067 ptep ^= PG_NX_MASK;
1068 if ((ptep & PG_NX_MASK) && is_write1 == 2)
1069 goto do_fault_protect;
1070 if (is_user) {
1071 if (!(ptep & PG_USER_MASK))
1072 goto do_fault_protect;
1073 if (is_write && !(ptep & PG_RW_MASK))
1074 goto do_fault_protect;
1075 } else {
1076 if ((env->cr[0] & CR0_WP_MASK) &&
1077 is_write && !(ptep & PG_RW_MASK))
1078 goto do_fault_protect;
1079 }
1080 is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1081 if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1082 pte |= PG_ACCESSED_MASK;
1083 if (is_dirty)
1084 pte |= PG_DIRTY_MASK;
1085 stl_phys_notdirty(pte_addr, pte);
1086 }
1087 page_size = 4096;
1088 virt_addr = addr & ~0xfff;
1089 pte = pte & (PHYS_ADDR_MASK | 0xfff);
7e84c249 1090 }
2c0262af 1091 } else {
eaa728ee
FB
1092 uint32_t pde;
1093
1094 /* page directory entry */
1095 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
1096 env->a20_mask;
1097 pde = ldl_phys(pde_addr);
1098 if (!(pde & PG_PRESENT_MASK)) {
1099 error_code = 0;
1100 goto do_fault;
1101 }
1102 /* if PSE bit is set, then we use a 4MB page */
1103 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1104 page_size = 4096 * 1024;
1105 if (is_user) {
1106 if (!(pde & PG_USER_MASK))
1107 goto do_fault_protect;
1108 if (is_write && !(pde & PG_RW_MASK))
1109 goto do_fault_protect;
1110 } else {
1111 if ((env->cr[0] & CR0_WP_MASK) &&
1112 is_write && !(pde & PG_RW_MASK))
1113 goto do_fault_protect;
1114 }
1115 is_dirty = is_write && !(pde & PG_DIRTY_MASK);
1116 if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
1117 pde |= PG_ACCESSED_MASK;
1118 if (is_dirty)
1119 pde |= PG_DIRTY_MASK;
1120 stl_phys_notdirty(pde_addr, pde);
1121 }
2c0262af 1122
eaa728ee
FB
1123 pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1124 ptep = pte;
1125 virt_addr = addr & ~(page_size - 1);
1126 } else {
1127 if (!(pde & PG_ACCESSED_MASK)) {
1128 pde |= PG_ACCESSED_MASK;
1129 stl_phys_notdirty(pde_addr, pde);
1130 }
891b38e4 1131
eaa728ee
FB
1132 /* page directory entry */
1133 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
1134 env->a20_mask;
1135 pte = ldl_phys(pte_addr);
1136 if (!(pte & PG_PRESENT_MASK)) {
1137 error_code = 0;
1138 goto do_fault;
8e682019 1139 }
eaa728ee
FB
1140 /* combine pde and pte user and rw protections */
1141 ptep = pte & pde;
1142 if (is_user) {
1143 if (!(ptep & PG_USER_MASK))
1144 goto do_fault_protect;
1145 if (is_write && !(ptep & PG_RW_MASK))
1146 goto do_fault_protect;
1147 } else {
1148 if ((env->cr[0] & CR0_WP_MASK) &&
1149 is_write && !(ptep & PG_RW_MASK))
1150 goto do_fault_protect;
8e682019 1151 }
eaa728ee
FB
1152 is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1153 if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1154 pte |= PG_ACCESSED_MASK;
1155 if (is_dirty)
1156 pte |= PG_DIRTY_MASK;
1157 stl_phys_notdirty(pte_addr, pte);
1158 }
1159 page_size = 4096;
1160 virt_addr = addr & ~0xfff;
2c0262af
FB
1161 }
1162 }
eaa728ee
FB
1163 /* the page can be put in the TLB */
1164 prot = PAGE_READ;
1165 if (!(ptep & PG_NX_MASK))
1166 prot |= PAGE_EXEC;
1167 if (pte & PG_DIRTY_MASK) {
1168 /* only set write access if already dirty... otherwise wait
1169 for dirty access */
1170 if (is_user) {
1171 if (ptep & PG_RW_MASK)
1172 prot |= PAGE_WRITE;
1173 } else {
1174 if (!(env->cr[0] & CR0_WP_MASK) ||
1175 (ptep & PG_RW_MASK))
1176 prot |= PAGE_WRITE;
8e682019 1177 }
891b38e4 1178 }
eaa728ee
FB
1179 do_mapping:
1180 pte = pte & env->a20_mask;
1181
1182 /* Even if 4MB pages, we map only one 4KB page in the cache to
1183 avoid filling it too fast */
1184 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1185 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1186 vaddr = virt_addr + page_offset;
1187
1188 ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
1189 return ret;
1190 do_fault_protect:
1191 error_code = PG_ERROR_P_MASK;
1192 do_fault:
1193 error_code |= (is_write << PG_ERROR_W_BIT);
1194 if (is_user)
1195 error_code |= PG_ERROR_U_MASK;
1196 if (is_write1 == 2 &&
1197 (env->efer & MSR_EFER_NXE) &&
1198 (env->cr[4] & CR4_PAE_MASK))
1199 error_code |= PG_ERROR_I_D_MASK;
872929aa
FB
1200 if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
1201 /* cr2 is not modified in case of exceptions */
1202 stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
1203 addr);
eaa728ee
FB
1204 } else {
1205 env->cr[2] = addr;
2c0262af 1206 }
eaa728ee
FB
1207 env->error_code = error_code;
1208 env->exception_index = EXCP0E_PAGE;
eaa728ee 1209 return 1;
14ce26e7
FB
1210}
1211
eaa728ee 1212target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
14ce26e7 1213{
eaa728ee
FB
1214 target_ulong pde_addr, pte_addr;
1215 uint64_t pte;
1216 target_phys_addr_t paddr;
1217 uint32_t page_offset;
1218 int page_size;
14ce26e7 1219
eaa728ee
FB
1220 if (env->cr[4] & CR4_PAE_MASK) {
1221 target_ulong pdpe_addr;
1222 uint64_t pde, pdpe;
14ce26e7 1223
eaa728ee
FB
1224#ifdef TARGET_X86_64
1225 if (env->hflags & HF_LMA_MASK) {
1226 uint64_t pml4e_addr, pml4e;
1227 int32_t sext;
1228
1229 /* test virtual address sign extension */
1230 sext = (int64_t)addr >> 47;
1231 if (sext != 0 && sext != -1)
1232 return -1;
1233
1234 pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
1235 env->a20_mask;
1236 pml4e = ldq_phys(pml4e_addr);
1237 if (!(pml4e & PG_PRESENT_MASK))
1238 return -1;
1239
1240 pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
1241 env->a20_mask;
1242 pdpe = ldq_phys(pdpe_addr);
1243 if (!(pdpe & PG_PRESENT_MASK))
1244 return -1;
1245 } else
1246#endif
1247 {
1248 pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1249 env->a20_mask;
1250 pdpe = ldq_phys(pdpe_addr);
1251 if (!(pdpe & PG_PRESENT_MASK))
1252 return -1;
14ce26e7 1253 }
14ce26e7 1254
eaa728ee
FB
1255 pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
1256 env->a20_mask;
1257 pde = ldq_phys(pde_addr);
1258 if (!(pde & PG_PRESENT_MASK)) {
1259 return -1;
1260 }
1261 if (pde & PG_PSE_MASK) {
1262 /* 2 MB page */
1263 page_size = 2048 * 1024;
1264 pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1265 } else {
1266 /* 4 KB page */
1267 pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
1268 env->a20_mask;
1269 page_size = 4096;
1270 pte = ldq_phys(pte_addr);
1271 }
ca1c9e15
AL
1272 if (!(pte & PG_PRESENT_MASK))
1273 return -1;
14ce26e7 1274 } else {
eaa728ee 1275 uint32_t pde;
3b46e624 1276
eaa728ee
FB
1277 if (!(env->cr[0] & CR0_PG_MASK)) {
1278 pte = addr;
1279 page_size = 4096;
1280 } else {
1281 /* page directory entry */
1282 pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
1283 pde = ldl_phys(pde_addr);
1284 if (!(pde & PG_PRESENT_MASK))
1285 return -1;
1286 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1287 pte = pde & ~0x003ff000; /* align to 4MB */
1288 page_size = 4096 * 1024;
1289 } else {
1290 /* page directory entry */
1291 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
1292 pte = ldl_phys(pte_addr);
1293 if (!(pte & PG_PRESENT_MASK))
1294 return -1;
1295 page_size = 4096;
1296 }
1297 }
1298 pte = pte & env->a20_mask;
14ce26e7 1299 }
14ce26e7 1300
eaa728ee
FB
1301 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1302 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1303 return paddr;
3b21e03e 1304}
01df040b
AL
1305
1306void hw_breakpoint_insert(CPUState *env, int index)
1307{
1308 int type, err = 0;
1309
1310 switch (hw_breakpoint_type(env->dr[7], index)) {
1311 case 0:
1312 if (hw_breakpoint_enabled(env->dr[7], index))
1313 err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
1314 &env->cpu_breakpoint[index]);
1315 break;
1316 case 1:
1317 type = BP_CPU | BP_MEM_WRITE;
1318 goto insert_wp;
1319 case 2:
1320 /* No support for I/O watchpoints yet */
1321 break;
1322 case 3:
1323 type = BP_CPU | BP_MEM_ACCESS;
1324 insert_wp:
1325 err = cpu_watchpoint_insert(env, env->dr[index],
1326 hw_breakpoint_len(env->dr[7], index),
1327 type, &env->cpu_watchpoint[index]);
1328 break;
1329 }
1330 if (err)
1331 env->cpu_breakpoint[index] = NULL;
1332}
1333
1334void hw_breakpoint_remove(CPUState *env, int index)
1335{
1336 if (!env->cpu_breakpoint[index])
1337 return;
1338 switch (hw_breakpoint_type(env->dr[7], index)) {
1339 case 0:
1340 if (hw_breakpoint_enabled(env->dr[7], index))
1341 cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
1342 break;
1343 case 1:
1344 case 3:
1345 cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
1346 break;
1347 case 2:
1348 /* No support for I/O watchpoints yet */
1349 break;
1350 }
1351}
1352
1353int check_hw_breakpoints(CPUState *env, int force_dr6_update)
1354{
1355 target_ulong dr6;
1356 int reg, type;
1357 int hit_enabled = 0;
1358
1359 dr6 = env->dr[6] & ~0xf;
1360 for (reg = 0; reg < 4; reg++) {
1361 type = hw_breakpoint_type(env->dr[7], reg);
1362 if ((type == 0 && env->dr[reg] == env->eip) ||
1363 ((type & 1) && env->cpu_watchpoint[reg] &&
1364 (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
1365 dr6 |= 1 << reg;
1366 if (hw_breakpoint_enabled(env->dr[7], reg))
1367 hit_enabled = 1;
1368 }
1369 }
1370 if (hit_enabled || force_dr6_update)
1371 env->dr[6] = dr6;
1372 return hit_enabled;
1373}
1374
1375static CPUDebugExcpHandler *prev_debug_excp_handler;
1376
1377void raise_exception(int exception_index);
1378
1379static void breakpoint_handler(CPUState *env)
1380{
1381 CPUBreakpoint *bp;
1382
1383 if (env->watchpoint_hit) {
1384 if (env->watchpoint_hit->flags & BP_CPU) {
1385 env->watchpoint_hit = NULL;
1386 if (check_hw_breakpoints(env, 0))
1387 raise_exception(EXCP01_DB);
1388 else
1389 cpu_resume_from_signal(env, NULL);
1390 }
1391 } else {
c0ce998e 1392 TAILQ_FOREACH(bp, &env->breakpoints, entry)
01df040b
AL
1393 if (bp->pc == env->eip) {
1394 if (bp->flags & BP_CPU) {
1395 check_hw_breakpoints(env, 1);
1396 raise_exception(EXCP01_DB);
1397 }
1398 break;
1399 }
1400 }
1401 if (prev_debug_excp_handler)
1402 prev_debug_excp_handler(env);
1403}
74ce674f 1404#endif /* !CONFIG_USER_ONLY */
6fd805e1 1405
7ba1e619
AL
1406static void host_cpuid(uint32_t function, uint32_t *eax, uint32_t *ebx,
1407 uint32_t *ecx, uint32_t *edx)
1408{
10781c09 1409#if defined(CONFIG_KVM)
7ba1e619
AL
1410 uint32_t vec[4];
1411
1412#ifdef __x86_64__
1413 asm volatile("cpuid"
1414 : "=a"(vec[0]), "=b"(vec[1]),
1415 "=c"(vec[2]), "=d"(vec[3])
1416 : "0"(function) : "cc");
1417#else
1418 asm volatile("pusha \n\t"
1419 "cpuid \n\t"
1420 "mov %%eax, 0(%1) \n\t"
1421 "mov %%ebx, 4(%1) \n\t"
1422 "mov %%ecx, 8(%1) \n\t"
1423 "mov %%edx, 12(%1) \n\t"
1424 "popa"
1425 : : "a"(function), "S"(vec)
1426 : "memory", "cc");
1427#endif
1428
1429 if (eax)
1430 *eax = vec[0];
1431 if (ebx)
1432 *ebx = vec[1];
1433 if (ecx)
1434 *ecx = vec[2];
1435 if (edx)
1436 *edx = vec[3];
7ba1e619 1437#endif
10781c09 1438}
7ba1e619 1439
6fd805e1
AL
1440void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
1441 uint32_t *eax, uint32_t *ebx,
1442 uint32_t *ecx, uint32_t *edx)
1443{
1444 /* test if maximum index reached */
1445 if (index & 0x80000000) {
1446 if (index > env->cpuid_xlevel)
1447 index = env->cpuid_level;
1448 } else {
1449 if (index > env->cpuid_level)
1450 index = env->cpuid_level;
1451 }
1452
1453 switch(index) {
1454 case 0:
1455 *eax = env->cpuid_level;
1456 *ebx = env->cpuid_vendor1;
1457 *edx = env->cpuid_vendor2;
1458 *ecx = env->cpuid_vendor3;
7ba1e619
AL
1459
1460 /* sysenter isn't supported on compatibility mode on AMD. and syscall
1461 * isn't supported in compatibility mode on Intel. so advertise the
1462 * actuall cpu, and say goodbye to migration between different vendors
1463 * is you use compatibility mode. */
1464 if (kvm_enabled())
1465 host_cpuid(0, NULL, ebx, ecx, edx);
6fd805e1
AL
1466 break;
1467 case 1:
1468 *eax = env->cpuid_version;
1469 *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
1470 *ecx = env->cpuid_ext_features;
1471 *edx = env->cpuid_features;
7ba1e619
AL
1472
1473 /* "Hypervisor present" bit required for Microsoft SVVP */
1474 if (kvm_enabled())
1475 *ecx |= (1 << 31);
6fd805e1
AL
1476 break;
1477 case 2:
1478 /* cache info: needed for Pentium Pro compatibility */
1479 *eax = 1;
1480 *ebx = 0;
1481 *ecx = 0;
1482 *edx = 0x2c307d;
1483 break;
1484 case 4:
1485 /* cache info: needed for Core compatibility */
1486 switch (*ecx) {
1487 case 0: /* L1 dcache info */
1488 *eax = 0x0000121;
1489 *ebx = 0x1c0003f;
1490 *ecx = 0x000003f;
1491 *edx = 0x0000001;
1492 break;
1493 case 1: /* L1 icache info */
1494 *eax = 0x0000122;
1495 *ebx = 0x1c0003f;
1496 *ecx = 0x000003f;
1497 *edx = 0x0000001;
1498 break;
1499 case 2: /* L2 cache info */
1500 *eax = 0x0000143;
1501 *ebx = 0x3c0003f;
1502 *ecx = 0x0000fff;
1503 *edx = 0x0000001;
1504 break;
1505 default: /* end of info */
1506 *eax = 0;
1507 *ebx = 0;
1508 *ecx = 0;
1509 *edx = 0;
1510 break;
1511 }
1512
1513 break;
1514 case 5:
1515 /* mwait info: needed for Core compatibility */
1516 *eax = 0; /* Smallest monitor-line size in bytes */
1517 *ebx = 0; /* Largest monitor-line size in bytes */
1518 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
1519 *edx = 0;
1520 break;
1521 case 6:
1522 /* Thermal and Power Leaf */
1523 *eax = 0;
1524 *ebx = 0;
1525 *ecx = 0;
1526 *edx = 0;
1527 break;
1528 case 9:
1529 /* Direct Cache Access Information Leaf */
1530 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
1531 *ebx = 0;
1532 *ecx = 0;
1533 *edx = 0;
1534 break;
1535 case 0xA:
1536 /* Architectural Performance Monitoring Leaf */
1537 *eax = 0;
1538 *ebx = 0;
1539 *ecx = 0;
1540 *edx = 0;
1541 break;
1542 case 0x80000000:
1543 *eax = env->cpuid_xlevel;
1544 *ebx = env->cpuid_vendor1;
1545 *edx = env->cpuid_vendor2;
1546 *ecx = env->cpuid_vendor3;
1547 break;
1548 case 0x80000001:
1549 *eax = env->cpuid_features;
1550 *ebx = 0;
1551 *ecx = env->cpuid_ext3_features;
1552 *edx = env->cpuid_ext2_features;
7ba1e619
AL
1553
1554 if (kvm_enabled()) {
1555 uint32_t h_eax, h_edx;
1556
1557 host_cpuid(0x80000001, &h_eax, NULL, NULL, &h_edx);
1558
1559 /* disable CPU features that the host does not support */
1560
1561 /* long mode */
1562 if ((h_edx & 0x20000000) == 0 /* || !lm_capable_kernel */)
1563 *edx &= ~0x20000000;
1564 /* syscall */
1565 if ((h_edx & 0x00000800) == 0)
1566 *edx &= ~0x00000800;
1567 /* nx */
1568 if ((h_edx & 0x00100000) == 0)
1569 *edx &= ~0x00100000;
1570
1571 /* disable CPU features that KVM cannot support */
1572
1573 /* svm */
1574 *ecx &= ~4UL;
1575 /* 3dnow */
57003085 1576 *edx &= ~0xc0000000;
7ba1e619 1577 }
6fd805e1
AL
1578 break;
1579 case 0x80000002:
1580 case 0x80000003:
1581 case 0x80000004:
1582 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
1583 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
1584 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
1585 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
1586 break;
1587 case 0x80000005:
1588 /* cache info (L1 cache) */
1589 *eax = 0x01ff01ff;
1590 *ebx = 0x01ff01ff;
1591 *ecx = 0x40020140;
1592 *edx = 0x40020140;
1593 break;
1594 case 0x80000006:
1595 /* cache info (L2 cache) */
1596 *eax = 0;
1597 *ebx = 0x42004200;
1598 *ecx = 0x02008140;
1599 *edx = 0;
1600 break;
1601 case 0x80000008:
1602 /* virtual & phys address size in low 2 bytes. */
1603/* XXX: This value must match the one used in the MMU code. */
1604 if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
1605 /* 64 bit processor */
1606#if defined(USE_KQEMU)
1607 *eax = 0x00003020; /* 48 bits virtual, 32 bits physical */
1608#else
1609/* XXX: The physical address space is limited to 42 bits in exec.c. */
1610 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
1611#endif
1612 } else {
1613#if defined(USE_KQEMU)
1614 *eax = 0x00000020; /* 32 bits physical */
1615#else
1616 if (env->cpuid_features & CPUID_PSE36)
1617 *eax = 0x00000024; /* 36 bits physical */
1618 else
1619 *eax = 0x00000020; /* 32 bits physical */
1620#endif
1621 }
1622 *ebx = 0;
1623 *ecx = 0;
1624 *edx = 0;
1625 break;
1626 case 0x8000000A:
1627 *eax = 0x00000001; /* SVM Revision */
1628 *ebx = 0x00000010; /* nr of ASIDs */
1629 *ecx = 0;
1630 *edx = 0; /* optional features */
1631 break;
1632 default:
1633 /* reserved values: zero */
1634 *eax = 0;
1635 *ebx = 0;
1636 *ecx = 0;
1637 *edx = 0;
1638 break;
1639 }
1640}
01df040b
AL
1641
1642CPUX86State *cpu_x86_init(const char *cpu_model)
1643{
1644 CPUX86State *env;
1645 static int inited;
1646
1647 env = qemu_mallocz(sizeof(CPUX86State));
01df040b
AL
1648 cpu_exec_init(env);
1649 env->cpu_model_str = cpu_model;
1650
1651 /* init various static tables */
1652 if (!inited) {
1653 inited = 1;
1654 optimize_flags_init();
1655#ifndef CONFIG_USER_ONLY
1656 prev_debug_excp_handler =
1657 cpu_set_debug_excp_handler(breakpoint_handler);
1658#endif
1659 }
1660 if (cpu_x86_register(env, cpu_model) < 0) {
1661 cpu_x86_close(env);
1662 return NULL;
1663 }
1664 cpu_reset(env);
1665#ifdef USE_KQEMU
1666 kqemu_init(env);
1667#endif
1668 if (kvm_enabled())
1669 kvm_init_vcpu(env);
1670 return env;
1671}