Changeset 37689 in vbox for trunk/src/recompiler/target-i386/helper.c
- Timestamp:
- Jun 29, 2011 4:01:23 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 72549
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/recompiler/target-i386/helper.c
r37675 r37689 43 43 //#define DEBUG_MMU 44 44 45 #ifndef VBOX46 /* feature flags taken from "Intel Processor Identification and the CPUID47 * Instruction" and AMD's "CPUID Specification". In cases of disagreement48 * about feature names, the Linux name is used. */49 static const char *feature_name[] = {50 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",51 "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",52 "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx",53 "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe",54 };55 static const char *ext_feature_name[] = {56 "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est",57 "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL,58 NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt",59 NULL, NULL, NULL, NULL, NULL, NULL, NULL, "hypervisor",60 };61 static const char *ext2_feature_name[] = {62 "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",63 "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mtrr", "pge", "mca", "cmov",64 "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx",65 "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",66 };67 static const char *ext3_feature_name[] = {68 "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",69 "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL,70 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,71 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,72 };73 74 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,75 uint32_t *ext_features,76 uint32_t *ext2_features,77 uint32_t *ext3_features)78 {79 int i;80 int found = 0;81 82 for ( i = 0 ; i < 32 ; i++ )83 if (feature_name[i] && !strcmp (flagname, feature_name[i])) {84 *features |= 1 << i;85 found = 1;86 }87 for ( i = 0 ; i < 32 ; i++ )88 if (ext_feature_name[i] && !strcmp (flagname, ext_feature_name[i])) {89 *ext_features |= 1 << i;90 found = 1;91 }92 for ( i = 0 ; i < 32 ; i++ )93 if (ext2_feature_name[i] && !strcmp (flagname, ext2_feature_name[i])) {94 *ext2_features |= 1 << i;95 found = 1;96 }97 for ( i = 0 ; i < 32 ; i++ )98 if (ext3_feature_name[i] && !strcmp (flagname, ext3_feature_name[i])) {99 *ext3_features |= 1 << i;100 found = 1;101 }102 if (!found) {103 fprintf(stderr, "CPU feature %s not found\n", flagname);104 }105 }106 #endif /* !VBOX */107 108 typedef struct x86_def_t {109 const char *name;110 uint32_t level;111 uint32_t vendor1, vendor2, vendor3;112 int family;113 int model;114 int stepping;115 uint32_t features, ext_features, ext2_features, ext3_features;116 uint32_t xlevel;117 char model_id[48];118 int vendor_override;119 } x86_def_t;120 121 #ifndef VBOX122 #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_64135 {136 .name = "qemu64",137 .level = 4,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 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,150 .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |151 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,152 .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |153 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,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 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |171 CPUID_EXT_POPCNT,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_CMP_LEG, CPUID_EXT3_EXTAPIC,178 CPUID_EXT3_CR8LEG,179 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,180 CPUID_EXT3_OSVW, CPUID_EXT3_IBS */181 .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |182 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,183 .xlevel = 0x8000001A,184 .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"185 },186 {187 .name = "core2duo",188 .level = 10,189 .family = 6,190 .model = 15,191 .stepping = 11,192 /* The original CPU also implements these features:193 CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,194 CPUID_TM, CPUID_PBE */195 .features = PPRO_FEATURES |196 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |197 CPUID_PSE36,198 /* The original CPU also implements these ext features:199 CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,200 CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */201 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,202 .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,203 .ext3_features = CPUID_EXT3_LAHF_LM,204 .xlevel = 0x80000008,205 .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",206 },207 {208 .name = "kvm64",209 .level = 5,210 .vendor1 = CPUID_VENDOR_INTEL_1,211 .vendor2 = CPUID_VENDOR_INTEL_2,212 .vendor3 = CPUID_VENDOR_INTEL_3,213 .family = 15,214 .model = 6,215 .stepping = 1,216 /* Missing: CPUID_VME, CPUID_HT */217 .features = PPRO_FEATURES |218 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |219 CPUID_PSE36,220 /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */221 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,222 /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */223 .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |224 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,225 /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,226 CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,227 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,228 CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */229 .ext3_features = 0,230 .xlevel = 0x80000008,231 .model_id = "Common KVM processor"232 },233 #endif234 {235 .name = "qemu32",236 .level = 4,237 .family = 6,238 .model = 3,239 .stepping = 3,240 .features = PPRO_FEATURES,241 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,242 .xlevel = 0,243 .model_id = "QEMU Virtual CPU version " QEMU_VERSION,244 },245 {246 .name = "coreduo",247 .level = 10,248 .family = 6,249 .model = 14,250 .stepping = 8,251 /* The original CPU also implements these features:252 CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,253 CPUID_TM, CPUID_PBE */254 .features = PPRO_FEATURES | CPUID_VME |255 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,256 /* The original CPU also implements these ext features:257 CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,258 CPUID_EXT_PDCM */259 .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,260 .ext2_features = CPUID_EXT2_NX,261 .xlevel = 0x80000008,262 .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",263 },264 {265 .name = "486",266 .level = 0,267 .family = 4,268 .model = 0,269 .stepping = 0,270 .features = I486_FEATURES,271 .xlevel = 0,272 },273 {274 .name = "pentium",275 .level = 1,276 .family = 5,277 .model = 4,278 .stepping = 3,279 .features = PENTIUM_FEATURES,280 .xlevel = 0,281 },282 {283 .name = "pentium2",284 .level = 2,285 .family = 6,286 .model = 5,287 .stepping = 2,288 .features = PENTIUM2_FEATURES,289 .xlevel = 0,290 },291 {292 .name = "pentium3",293 .level = 2,294 .family = 6,295 .model = 7,296 .stepping = 3,297 .features = PENTIUM3_FEATURES,298 .xlevel = 0,299 },300 {301 .name = "athlon",302 .level = 2,303 .vendor1 = CPUID_VENDOR_AMD_1,304 .vendor2 = CPUID_VENDOR_AMD_2,305 .vendor3 = CPUID_VENDOR_AMD_3,306 .family = 6,307 .model = 2,308 .stepping = 3,309 .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,310 .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,311 .xlevel = 0x80000008,312 /* XXX: put another string ? */313 .model_id = "QEMU Virtual CPU version " QEMU_VERSION,314 },315 {316 .name = "n270",317 /* original is on level 10 */318 .level = 5,319 .family = 6,320 .model = 28,321 .stepping = 2,322 .features = PPRO_FEATURES |323 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,324 /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |325 * CPUID_HT | CPUID_TM | CPUID_PBE */326 /* Some CPUs got no CPUID_SEP */327 .ext_features = CPUID_EXT_MONITOR |328 CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,329 /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |330 * CPUID_EXT_TM2 | CPUID_EXT_XTPR */331 .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,332 /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */333 .xlevel = 0x8000000A,334 .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",335 },336 };337 338 static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,339 uint32_t *ebx, uint32_t *ecx, uint32_t *edx);340 341 static int cpu_x86_fill_model_id(char *str)342 {343 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;344 int i;345 346 for (i = 0; i < 3; i++) {347 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);348 memcpy(str + i * 16 + 0, &eax, 4);349 memcpy(str + i * 16 + 4, &ebx, 4);350 memcpy(str + i * 16 + 8, &ecx, 4);351 memcpy(str + i * 16 + 12, &edx, 4);352 }353 return 0;354 }355 356 static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)357 {358 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;359 360 x86_cpu_def->name = "host";361 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);362 x86_cpu_def->level = eax;363 x86_cpu_def->vendor1 = ebx;364 x86_cpu_def->vendor2 = edx;365 x86_cpu_def->vendor3 = ecx;366 367 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);368 x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);369 x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);370 x86_cpu_def->stepping = eax & 0x0F;371 x86_cpu_def->ext_features = ecx;372 x86_cpu_def->features = edx;373 374 host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);375 x86_cpu_def->xlevel = eax;376 377 host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);378 x86_cpu_def->ext2_features = edx;379 x86_cpu_def->ext3_features = ecx;380 cpu_x86_fill_model_id(x86_cpu_def->model_id);381 x86_cpu_def->vendor_override = 0;382 383 return 0;384 }385 386 static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)387 {388 unsigned int i;389 x86_def_t *def;390 391 char *s = strdup(cpu_model);392 char *featurestr, *name = strtok(s, ",");393 uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0;394 uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0;395 uint32_t numvalue;396 397 def = NULL;398 for (i = 0; i < ARRAY_SIZE(x86_defs); i++) {399 if (strcmp(name, x86_defs[i].name) == 0) {400 def = &x86_defs[i];401 break;402 }403 }404 if (kvm_enabled() && strcmp(name, "host") == 0) {405 cpu_x86_fill_host(x86_cpu_def);406 } else if (!def) {407 goto error;408 } else {409 memcpy(x86_cpu_def, def, sizeof(*def));410 }411 412 add_flagname_to_bitmaps("hypervisor", &plus_features,413 &plus_ext_features, &plus_ext2_features, &plus_ext3_features);414 415 featurestr = strtok(NULL, ",");416 417 while (featurestr) {418 char *val;419 if (featurestr[0] == '+') {420 add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);421 } else if (featurestr[0] == '-') {422 add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features);423 } else if ((val = strchr(featurestr, '='))) {424 *val = 0; val++;425 if (!strcmp(featurestr, "family")) {426 char *err;427 numvalue = strtoul(val, &err, 0);428 if (!*val || *err) {429 fprintf(stderr, "bad numerical value %s\n", val);430 goto error;431 }432 x86_cpu_def->family = numvalue;433 } else if (!strcmp(featurestr, "model")) {434 char *err;435 numvalue = strtoul(val, &err, 0);436 if (!*val || *err || numvalue > 0xff) {437 fprintf(stderr, "bad numerical value %s\n", val);438 goto error;439 }440 x86_cpu_def->model = numvalue;441 } else if (!strcmp(featurestr, "stepping")) {442 char *err;443 numvalue = strtoul(val, &err, 0);444 if (!*val || *err || numvalue > 0xf) {445 fprintf(stderr, "bad numerical value %s\n", val);446 goto error;447 }448 x86_cpu_def->stepping = numvalue ;449 } else if (!strcmp(featurestr, "level")) {450 char *err;451 numvalue = strtoul(val, &err, 0);452 if (!*val || *err) {453 fprintf(stderr, "bad numerical value %s\n", val);454 goto error;455 }456 x86_cpu_def->level = numvalue;457 } else if (!strcmp(featurestr, "xlevel")) {458 char *err;459 numvalue = strtoul(val, &err, 0);460 if (!*val || *err) {461 fprintf(stderr, "bad numerical value %s\n", val);462 goto error;463 }464 if (numvalue < 0x80000000) {465 numvalue += 0x80000000;466 }467 x86_cpu_def->xlevel = numvalue;468 } else if (!strcmp(featurestr, "vendor")) {469 if (strlen(val) != 12) {470 fprintf(stderr, "vendor string must be 12 chars long\n");471 goto error;472 }473 x86_cpu_def->vendor1 = 0;474 x86_cpu_def->vendor2 = 0;475 x86_cpu_def->vendor3 = 0;476 for(i = 0; i < 4; i++) {477 x86_cpu_def->vendor1 |= ((uint8_t)val[i ]) << (8 * i);478 x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);479 x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);480 }481 x86_cpu_def->vendor_override = 1;482 } else if (!strcmp(featurestr, "model_id")) {483 pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),484 val);485 } else {486 fprintf(stderr, "unrecognized feature %s\n", featurestr);487 goto error;488 }489 } else {490 fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);491 goto error;492 }493 featurestr = strtok(NULL, ",");494 }495 x86_cpu_def->features |= plus_features;496 x86_cpu_def->ext_features |= plus_ext_features;497 x86_cpu_def->ext2_features |= plus_ext2_features;498 x86_cpu_def->ext3_features |= plus_ext3_features;499 x86_cpu_def->features &= ~minus_features;500 x86_cpu_def->ext_features &= ~minus_ext_features;501 x86_cpu_def->ext2_features &= ~minus_ext2_features;502 x86_cpu_def->ext3_features &= ~minus_ext3_features;503 free(s);504 return 0;505 506 error:507 free(s);508 return -1;509 }510 511 void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))512 {513 unsigned int i;514 515 for (i = 0; i < ARRAY_SIZE(x86_defs); i++)516 (*cpu_fprintf)(f, "x86 %16s\n", x86_defs[i].name);517 }518 #endif /* !VBOX */519 520 static int cpu_x86_register (CPUX86State *env, const char *cpu_model)521 {522 #ifndef VBOX523 x86_def_t def1, *def = &def1;524 525 if (cpu_x86_find_by_name(def, cpu_model) < 0)526 return -1;527 if (def->vendor1) {528 env->cpuid_vendor1 = def->vendor1;529 env->cpuid_vendor2 = def->vendor2;530 env->cpuid_vendor3 = def->vendor3;531 } else {532 env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;533 env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;534 env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;535 }536 env->cpuid_vendor_override = def->vendor_override;537 env->cpuid_level = def->level;538 if (def->family > 0x0f)539 env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);540 else541 env->cpuid_version = def->family << 8;542 env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);543 env->cpuid_version |= def->stepping;544 env->cpuid_features = def->features;545 env->pat = 0x0007040600070406ULL;546 env->cpuid_ext_features = def->ext_features;547 env->cpuid_ext2_features = def->ext2_features;548 env->cpuid_xlevel = def->xlevel;549 env->cpuid_ext3_features = def->ext3_features;550 {551 const char *model_id = def->model_id;552 int c, len, i;553 if (!model_id)554 model_id = "";555 len = strlen(model_id);556 for(i = 0; i < 48; i++) {557 if (i >= len)558 c = '\0';559 else560 c = (uint8_t)model_id[i];561 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));562 }563 }564 #endif /* !VBOX */565 return 0;566 }567 568 45 /* NOTE: must be called outside the CPU execute loop */ 569 46 void cpu_reset(CPUX86State *env) … … 620 97 621 98 env->eip = 0xfff0; 622 #ifndef VBOX 99 #ifndef VBOX /* We'll get the right value from CPUM. */ 623 100 env->regs[R_EDX] = env->cpuid_version; 624 #else625 /** @todo: is it right? */626 env->regs[R_EDX] = 0x600; /* indicate P6 processor */627 101 #endif 628 102 … … 762 236 } 763 237 }; 764 cpu_fprintf(f, sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0] 765 [(sc->flags & DESC_TYPE_MASK) 766 >> DESC_TYPE_SHIFT]); 238 cpu_fprintf(f, "%s", 239 sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0] 240 [(sc->flags & DESC_TYPE_MASK) 241 >> DESC_TYPE_SHIFT]); 767 242 } 768 243 done: … … 909 384 } 910 385 } 386 cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer); 911 387 if (flags & X86_DUMP_FPU) { 912 388 int fptag; … … 1026 502 ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)); 1027 503 #ifdef VBOX 1028 1029 504 remR3ChangeCpuMode(env); 1030 505 #endif … … 1081 556 } 1082 557 1083 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)1084 {1085 return addr;1086 }1087 1088 558 #else 1089 559 … … 1100 570 0 = nothing more to do 1101 571 1 = generate PF fault 1102 2 = soft MMU activation required for this block1103 572 */ 1104 573 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, … … 1107 576 uint64_t ptep, pte; 1108 577 target_ulong pde_addr, pte_addr; 1109 int error_code, is_dirty, prot, page_size, ret,is_write, is_user;578 int error_code, is_dirty, prot, page_size, is_write, is_user; 1110 579 target_phys_addr_t paddr; 1111 580 uint32_t page_offset; … … 1368 837 vaddr = virt_addr + page_offset; 1369 838 1370 ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);1371 return ret;839 tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size); 840 return 0; 1372 841 do_fault_protect: 1373 842 error_code = PG_ERROR_P_MASK; … … 1557 1026 static CPUDebugExcpHandler *prev_debug_excp_handler; 1558 1027 1559 void raise_exception (int exception_index);1028 void raise_exception_env(int exception_index, CPUState *env); 1560 1029 1561 1030 static void breakpoint_handler(CPUState *env) … … 1567 1036 env->watchpoint_hit = NULL; 1568 1037 if (check_hw_breakpoints(env, 0)) 1569 raise_exception (EXCP01_DB);1038 raise_exception_env(EXCP01_DB, env); 1570 1039 else 1571 1040 cpu_resume_from_signal(env, NULL); … … 1576 1045 if (bp->flags & BP_CPU) { 1577 1046 check_hw_breakpoints(env, 1); 1578 raise_exception (EXCP01_DB);1047 raise_exception_env(EXCP01_DB, env); 1579 1048 } 1580 1049 break; … … 1584 1053 prev_debug_excp_handler(env); 1585 1054 } 1586 1587 1055 1588 1056 #ifndef VBOX … … 1659 1127 } 1660 1128 1661 static void host_cpuid(uint32_t function, uint32_t count,1662 uint32_t *eax, uint32_t *ebx,1663 uint32_t *ecx, uint32_t *edx)1664 {1665 #if defined(CONFIG_KVM)1666 uint32_t vec[4];1667 1668 #ifdef __x86_64__1669 asm volatile("cpuid"1670 : "=a"(vec[0]), "=b"(vec[1]),1671 "=c"(vec[2]), "=d"(vec[3])1672 : "0"(function), "c"(count) : "cc");1673 #else1674 asm volatile("pusha \n\t"1675 "cpuid \n\t"1676 "mov %%eax, 0(%2) \n\t"1677 "mov %%ebx, 4(%2) \n\t"1678 "mov %%ecx, 8(%2) \n\t"1679 "mov %%edx, 12(%2) \n\t"1680 "popa"1681 : : "a"(function), "c"(count), "S"(vec)1682 : "memory", "cc");1683 #endif1684 1685 if (eax)1686 *eax = vec[0];1687 if (ebx)1688 *ebx = vec[1];1689 if (ecx)1690 *ecx = vec[2];1691 if (edx)1692 *edx = vec[3];1693 #endif1694 }1695 1696 static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,1697 uint32_t *ecx, uint32_t *edx)1698 {1699 *ebx = env->cpuid_vendor1;1700 *edx = env->cpuid_vendor2;1701 *ecx = env->cpuid_vendor3;1702 1703 /* sysenter isn't supported on compatibility mode on AMD, syscall1704 * isn't supported in compatibility mode on Intel.1705 * Normally we advertise the actual cpu vendor, but you can override1706 * this if you want to use KVM's sysenter/syscall emulation1707 * in compatibility mode and when doing cross vendor migration1708 */1709 if (kvm_enabled() && env->cpuid_vendor_override) {1710 host_cpuid(0, 0, NULL, ebx, ecx, edx);1711 }1712 }1713 1714 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,1715 uint32_t *eax, uint32_t *ebx,1716 uint32_t *ecx, uint32_t *edx)1717 {1718 /* test if maximum index reached */1719 if (index & 0x80000000) {1720 if (index > env->cpuid_xlevel)1721 index = env->cpuid_level;1722 } else {1723 if (index > env->cpuid_level)1724 index = env->cpuid_level;1725 }1726 1727 switch(index) {1728 case 0:1729 *eax = env->cpuid_level;1730 get_cpuid_vendor(env, ebx, ecx, edx);1731 break;1732 case 1:1733 *eax = env->cpuid_version;1734 *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */1735 *ecx = env->cpuid_ext_features;1736 *edx = env->cpuid_features;1737 if (env->nr_cores * env->nr_threads > 1) {1738 *ebx |= (env->nr_cores * env->nr_threads) << 16;1739 *edx |= 1 << 28; /* HTT bit */1740 }1741 break;1742 case 2:1743 /* cache info: needed for Pentium Pro compatibility */1744 *eax = 1;1745 *ebx = 0;1746 *ecx = 0;1747 *edx = 0x2c307d;1748 break;1749 case 4:1750 /* cache info: needed for Core compatibility */1751 if (env->nr_cores > 1) {1752 *eax = (env->nr_cores - 1) << 26;1753 } else {1754 *eax = 0;1755 }1756 switch (count) {1757 case 0: /* L1 dcache info */1758 *eax |= 0x0000121;1759 *ebx = 0x1c0003f;1760 *ecx = 0x000003f;1761 *edx = 0x0000001;1762 break;1763 case 1: /* L1 icache info */1764 *eax |= 0x0000122;1765 *ebx = 0x1c0003f;1766 *ecx = 0x000003f;1767 *edx = 0x0000001;1768 break;1769 case 2: /* L2 cache info */1770 *eax |= 0x0000143;1771 if (env->nr_threads > 1) {1772 *eax |= (env->nr_threads - 1) << 14;1773 }1774 *ebx = 0x3c0003f;1775 *ecx = 0x0000fff;1776 *edx = 0x0000001;1777 break;1778 default: /* end of info */1779 *eax = 0;1780 *ebx = 0;1781 *ecx = 0;1782 *edx = 0;1783 break;1784 }1785 break;1786 case 5:1787 /* mwait info: needed for Core compatibility */1788 *eax = 0; /* Smallest monitor-line size in bytes */1789 *ebx = 0; /* Largest monitor-line size in bytes */1790 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;1791 *edx = 0;1792 break;1793 case 6:1794 /* Thermal and Power Leaf */1795 *eax = 0;1796 *ebx = 0;1797 *ecx = 0;1798 *edx = 0;1799 break;1800 case 9:1801 /* Direct Cache Access Information Leaf */1802 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */1803 *ebx = 0;1804 *ecx = 0;1805 *edx = 0;1806 break;1807 case 0xA:1808 /* Architectural Performance Monitoring Leaf */1809 *eax = 0;1810 *ebx = 0;1811 *ecx = 0;1812 *edx = 0;1813 break;1814 case 0x80000000:1815 *eax = env->cpuid_xlevel;1816 *ebx = env->cpuid_vendor1;1817 *edx = env->cpuid_vendor2;1818 *ecx = env->cpuid_vendor3;1819 break;1820 case 0x80000001:1821 *eax = env->cpuid_version;1822 *ebx = 0;1823 *ecx = env->cpuid_ext3_features;1824 *edx = env->cpuid_ext2_features;1825 1826 /* The Linux kernel checks for the CMPLegacy bit and1827 * discards multiple thread information if it is set.1828 * So dont set it here for Intel to make Linux guests happy.1829 */1830 if (env->nr_cores * env->nr_threads > 1) {1831 uint32_t tebx, tecx, tedx;1832 get_cpuid_vendor(env, &tebx, &tecx, &tedx);1833 if (tebx != CPUID_VENDOR_INTEL_1 ||1834 tedx != CPUID_VENDOR_INTEL_2 ||1835 tecx != CPUID_VENDOR_INTEL_3) {1836 *ecx |= 1 << 1; /* CmpLegacy bit */1837 }1838 }1839 1840 if (kvm_enabled()) {1841 /* Nested SVM not yet supported in upstream QEMU */1842 *ecx &= ~CPUID_EXT3_SVM;1843 }1844 break;1845 case 0x80000002:1846 case 0x80000003:1847 case 0x80000004:1848 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];1849 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];1850 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];1851 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];1852 break;1853 case 0x80000005:1854 /* cache info (L1 cache) */1855 *eax = 0x01ff01ff;1856 *ebx = 0x01ff01ff;1857 *ecx = 0x40020140;1858 *edx = 0x40020140;1859 break;1860 case 0x80000006:1861 /* cache info (L2 cache) */1862 *eax = 0;1863 *ebx = 0x42004200;1864 *ecx = 0x02008140;1865 *edx = 0;1866 break;1867 case 0x80000008:1868 /* virtual & phys address size in low 2 bytes. */1869 /* XXX: This value must match the one used in the MMU code. */1870 if (env->cpuid_ext2_features & CPUID_EXT2_LM) {1871 /* 64 bit processor */1872 /* XXX: The physical address space is limited to 42 bits in exec.c. */1873 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */1874 } else {1875 if (env->cpuid_features & CPUID_PSE36)1876 *eax = 0x00000024; /* 36 bits physical */1877 else1878 *eax = 0x00000020; /* 32 bits physical */1879 }1880 *ebx = 0;1881 *ecx = 0;1882 *edx = 0;1883 if (env->nr_cores * env->nr_threads > 1) {1884 *ecx |= (env->nr_cores * env->nr_threads) - 1;1885 }1886 break;1887 case 0x8000000A:1888 *eax = 0x00000001; /* SVM Revision */1889 *ebx = 0x00000010; /* nr of ASIDs */1890 *ecx = 0;1891 *edx = 0; /* optional features */1892 break;1893 default:1894 /* reserved values: zero */1895 *eax = 0;1896 *ebx = 0;1897 *ecx = 0;1898 *edx = 0;1899 break;1900 }1901 }1902 1903 1904 1129 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector, 1905 1130 target_ulong *base, unsigned int *limit, … … 1959 1184 #endif 1960 1185 } 1186 #ifndef VBOX 1961 1187 if (cpu_x86_register(env, cpu_model) < 0) { 1962 1188 cpu_x86_close(env); 1963 1189 return NULL; 1964 1190 } 1965 #ifndef VBOX1966 1191 mce_init(env); 1967 1192 #endif … … 1979 1204 cpu_reset(env); 1980 1205 env->interrupt_request = sipi; 1981 apic_init_reset(env); 1206 apic_init_reset(env->apic_state); 1207 env->halted = !cpu_is_bsp(env); 1982 1208 } 1983 1209 1984 1210 void do_cpu_sipi(CPUState *env) 1985 1211 { 1986 apic_sipi(env );1212 apic_sipi(env->apic_state); 1987 1213 } 1988 1214 #else
Note:
See TracChangeset
for help on using the changeset viewer.