]> git.proxmox.com Git - qemu.git/blob - target-i386/helper.c
Handle init/sipi in a main cpu exec loop. (v2)
[qemu.git] / target-i386 / helper.c
1 /*
2 * i386 helpers (without register variable usage)
3 *
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
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA
19 */
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
27 #include "cpu.h"
28 #include "exec-all.h"
29 #include "qemu-common.h"
30 #include "kvm.h"
31
32 //#define DEBUG_MMU
33
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. */
37 static 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 };
43 static 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 };
49 static 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 };
55 static 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
62 static 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;
68 int found = 0;
69
70 for ( i = 0 ; i < 32 ; i++ )
71 if (feature_name[i] && !strcmp (flagname, feature_name[i])) {
72 *features |= 1 << i;
73 found = 1;
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;
78 found = 1;
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;
83 found = 1;
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;
88 found = 1;
89 }
90 if (!found) {
91 fprintf(stderr, "CPU feature %s not found\n", flagname);
92 }
93 }
94
95 static 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)) {
104 *features &= ~mask;
105 }
106 }
107 }
108
109 typedef 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;
118 char model_id[48];
119 int vendor_override;
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)
133 static x86_def_t x86_defs[] = {
134 #ifdef TARGET_X86_64
135 {
136 .name = "qemu64",
137 .level = 2,
138 .vendor1 = CPUID_VENDOR_AMD_1,
139 .vendor2 = CPUID_VENDOR_AMD_2,
140 .vendor3 = CPUID_VENDOR_AMD_3,
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,
155 .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
156 },
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 },
185 {
186 .name = "core2duo",
187 .level = 10,
188 .family = 6,
189 .model = 15,
190 .stepping = 11,
191 /* The original CPU also implements these features:
192 CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
193 CPUID_TM, CPUID_PBE */
194 .features = PPRO_FEATURES |
195 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
196 CPUID_PSE36,
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 */
200 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
201 .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
202 /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
203 .xlevel = 0x80000008,
204 .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
205 },
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,
216 .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
217 },
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 },
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,
282 .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
283 .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
284 .xlevel = 0x80000008,
285 /* XXX: put another string ? */
286 .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
287 },
288 {
289 .name = "n270",
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 |
301 CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
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 },
309 };
310
311 static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
312 {
313 unsigned int i;
314 x86_def_t *def;
315
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;
321
322 def = NULL;
323 for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {
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);
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);
354 if (!*val || *err || model < 0 || model > 0xff) {
355 fprintf(stderr, "bad numerical value %s\n", val);
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);
364 goto error;
365 }
366 x86_cpu_def->stepping = stepping;
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 }
380 x86_cpu_def->vendor_override = 1;
381 } else if (!strcmp(featurestr, "model_id")) {
382 pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
383 val);
384 } else {
385 fprintf(stderr, "unrecognized feature %s\n", featurestr);
386 goto error;
387 }
388 } else {
389 fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
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
405 error:
406 free(s);
407 return -1;
408 }
409
410 void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
411 {
412 unsigned int i;
413
414 for (i = 0; i < ARRAY_SIZE(x86_defs); i++)
415 (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);
416 }
417
418 static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
419 {
420 x86_def_t def1, *def = &def1;
421
422 if (cpu_x86_find_by_name(def, cpu_model) < 0)
423 return -1;
424 if (def->vendor1) {
425 env->cpuid_vendor1 = def->vendor1;
426 env->cpuid_vendor2 = def->vendor2;
427 env->cpuid_vendor3 = def->vendor3;
428 } else {
429 env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
430 env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
431 env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
432 }
433 env->cpuid_vendor_override = def->vendor_override;
434 env->cpuid_level = def->level;
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;
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 {
448 const char *model_id = def->model_id;
449 int c, len, i;
450 if (!model_id)
451 model_id = "";
452 len = strlen(model_id);
453 for(i = 0; i < 48; i++) {
454 if (i >= len)
455 c = '\0';
456 else
457 c = (uint8_t)model_id[i];
458 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
459 }
460 }
461 return 0;
462 }
463
464 /* NOTE: must be called outside the CPU execute loop */
465 void cpu_reset(CPUX86State *env)
466 {
467 int i;
468
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
474 memset(env, 0, offsetof(CPUX86State, breakpoints));
475
476 tlb_flush(env, 1);
477
478 env->old_exception = -1;
479
480 /* init to reset state */
481
482 #ifdef CONFIG_SOFTMMU
483 env->hflags |= HF_SOFTMMU_MASK;
484 #endif
485 env->hflags2 |= HF2_GIF_MASK;
486
487 cpu_x86_update_cr0(env, 0x60000010);
488 env->a20_mask = ~0x0;
489 env->smbase = 0x30000;
490
491 env->idt.limit = 0xffff;
492 env->gdt.limit = 0xffff;
493 env->ldt.limit = 0xffff;
494 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
495 env->tr.limit = 0xffff;
496 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
497
498 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
499 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
500 DESC_R_MASK | DESC_A_MASK);
501 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
502 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
503 DESC_A_MASK);
504 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
505 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
506 DESC_A_MASK);
507 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
508 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
509 DESC_A_MASK);
510 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
511 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
512 DESC_A_MASK);
513 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
514 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
515 DESC_A_MASK);
516
517 env->eip = 0xfff0;
518 env->regs[R_EDX] = env->cpuid_version;
519
520 env->eflags = 0x2;
521
522 /* FPU init */
523 for(i = 0;i < 8; i++)
524 env->fptags[i] = 1;
525 env->fpuc = 0x37f;
526
527 env->mxcsr = 0x1f80;
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);
534 }
535
536 void cpu_x86_close(CPUX86State *env)
537 {
538 qemu_free(env);
539 }
540
541 /***********************************************************/
542 /* x86 debug */
543
544 static const char *cc_op_str[] = {
545 "DYNAMIC",
546 "EFLAGS",
547
548 "MULB",
549 "MULW",
550 "MULL",
551 "MULQ",
552
553 "ADDB",
554 "ADDW",
555 "ADDL",
556 "ADDQ",
557
558 "ADCB",
559 "ADCW",
560 "ADCL",
561 "ADCQ",
562
563 "SUBB",
564 "SUBW",
565 "SUBL",
566 "SUBQ",
567
568 "SBBB",
569 "SBBW",
570 "SBBL",
571 "SBBQ",
572
573 "LOGICB",
574 "LOGICW",
575 "LOGICL",
576 "LOGICQ",
577
578 "INCB",
579 "INCW",
580 "INCL",
581 "INCQ",
582
583 "DECB",
584 "DECW",
585 "DECL",
586 "DECQ",
587
588 "SHLB",
589 "SHLW",
590 "SHLL",
591 "SHLQ",
592
593 "SARB",
594 "SARW",
595 "SARL",
596 "SARQ",
597 };
598
599 static void
600 cpu_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 }
650 done:
651 cpu_fprintf(f, "\n");
652 }
653
654 void 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" };
661
662 if (kvm_enabled())
663 kvm_arch_get_registers(env);
664
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,
702 env->halted);
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,
729 env->halted);
730 }
731
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
739 #ifdef TARGET_X86_64
740 if (env->hflags & HF_LMA_MASK) {
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]);
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",
753 env->dr[6], env->dr[7]);
754 } else
755 #endif
756 {
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]);
766 for(i = 0; i < 4; i++)
767 cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]);
768 cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]);
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 }
787 }
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 }
837 }
838 }
839
840 /***********************************************************/
841 /* x86 mmu */
842 /* XXX: add PGE support */
843
844 void cpu_x86_set_a20(CPUX86State *env, int a20_state)
845 {
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);
854
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);
859 }
860 }
861
862 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
863 {
864 int pe_state;
865
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 }
873
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;
892
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));
901 }
902
903 /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
904 the PDPT */
905 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
906 {
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 }
914 }
915
916 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
917 {
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;
932
933 env->cr[4] = new_cr4;
934 }
935
936 #if defined(CONFIG_USER_ONLY)
937
938 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
939 int is_write, int mmu_idx, int is_softmmu)
940 {
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;
948 }
949
950 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
951 {
952 return addr;
953 }
954
955 #else
956
957 /* XXX: This value should match the one returned by CPUID
958 * and in exec.c */
959 #if defined(CONFIG_KQEMU)
960 #define PHYS_ADDR_MASK 0xfffff000LL
961 #else
962 # if defined(TARGET_X86_64)
963 # define PHYS_ADDR_MASK 0xfffffff000LL
964 # else
965 # define PHYS_ADDR_MASK 0xffffff000LL
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 */
975 int 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;
1003
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 }
1016
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;
1061 }
1062
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);
1143 }
1144 } else {
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 }
1175
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 }
1184
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;
1192 }
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;
1204 }
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;
1214 }
1215 }
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;
1230 }
1231 }
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;
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);
1257 } else {
1258 env->cr[2] = addr;
1259 }
1260 env->error_code = error_code;
1261 env->exception_index = EXCP0E_PAGE;
1262 return 1;
1263 }
1264
1265 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1266 {
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;
1272
1273 if (env->cr[4] & CR4_PAE_MASK) {
1274 target_ulong pdpe_addr;
1275 uint64_t pde, pdpe;
1276
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;
1306 }
1307
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 }
1325 if (!(pte & PG_PRESENT_MASK))
1326 return -1;
1327 } else {
1328 uint32_t pde;
1329
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;
1352 }
1353
1354 page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1355 paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1356 return paddr;
1357 }
1358
1359 void 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
1387 void 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
1406 int 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
1428 static CPUDebugExcpHandler *prev_debug_excp_handler;
1429
1430 void raise_exception(int exception_index);
1431
1432 static 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 {
1445 TAILQ_FOREACH(bp, &env->breakpoints, entry)
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 }
1457 #endif /* !CONFIG_USER_ONLY */
1458
1459 static void host_cpuid(uint32_t function, uint32_t count,
1460 uint32_t *eax, uint32_t *ebx,
1461 uint32_t *ecx, uint32_t *edx)
1462 {
1463 #if defined(CONFIG_KVM)
1464 uint32_t vec[4];
1465
1466 #ifdef __x86_64__
1467 asm volatile("cpuid"
1468 : "=a"(vec[0]), "=b"(vec[1]),
1469 "=c"(vec[2]), "=d"(vec[3])
1470 : "0"(function), "c"(count) : "cc");
1471 #else
1472 asm volatile("pusha \n\t"
1473 "cpuid \n\t"
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"
1478 "popa"
1479 : : "a"(function), "c"(count), "S"(vec)
1480 : "memory", "cc");
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];
1491 #endif
1492 }
1493
1494 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
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;
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. */
1518 if (kvm_enabled() && !env->cpuid_vendor_override)
1519 host_cpuid(0, 0, NULL, ebx, ecx, edx);
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;
1526
1527 /* "Hypervisor present" bit required for Microsoft SVVP */
1528 if (kvm_enabled())
1529 *ecx |= (1 << 31);
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 */
1540 switch (count) {
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 }
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;
1606
1607 if (kvm_enabled()) {
1608 uint32_t h_eax, h_edx;
1609
1610 host_cpuid(index, 0, &h_eax, NULL, NULL, &h_edx);
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 */
1629 *edx &= ~0xc0000000;
1630 }
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 */
1659 #if defined(CONFIG_KQEMU)
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 {
1666 #if defined(CONFIG_KQEMU)
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 }
1694
1695 CPUX86State *cpu_x86_init(const char *cpu_model)
1696 {
1697 CPUX86State *env;
1698 static int inited;
1699
1700 env = qemu_mallocz(sizeof(CPUX86State));
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);
1718 #ifdef CONFIG_KQEMU
1719 kqemu_init(env);
1720 #endif
1721
1722 qemu_init_vcpu(env);
1723
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
1739 return env;
1740 }
1741
1742 #if !defined(CONFIG_USER_ONLY)
1743 void do_cpu_init(CPUState *env)
1744 {
1745 int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
1746 cpu_reset(env);
1747 env->interrupt_request = sipi;
1748 apic_init_reset(env);
1749 }
1750
1751 void do_cpu_sipi(CPUState *env)
1752 {
1753 apic_sipi(env);
1754 }
1755 #else
1756 void do_cpu_init(CPUState *env)
1757 {
1758 }
1759 void do_cpu_sipi(CPUState *env)
1760 {
1761 }
1762 #endif