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