Commit 40f8e2fa4173c3338f53531c144e891ce03aabe5
1 parent
92af06d2
added model_id and vendor cpu model options (initial patch by Dan Kenigsberg) - various cleanup
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4757 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
29 additions
and
11 deletions
target-i386/helper.c
| @@ -43,25 +43,25 @@ static void add_flagname_to_bitmaps(char *flagname, uint32_t *features, | @@ -43,25 +43,25 @@ static void add_flagname_to_bitmaps(char *flagname, uint32_t *features, | ||
| 43 | /* feature flags taken from "Intel Processor Identification and the CPUID | 43 | /* feature flags taken from "Intel Processor Identification and the CPUID |
| 44 | * Instruction" and AMD's "CPUID Specification". In cases of disagreement | 44 | * Instruction" and AMD's "CPUID Specification". In cases of disagreement |
| 45 | * about feature names, the Linux name is used. */ | 45 | * about feature names, the Linux name is used. */ |
| 46 | - const char *feature_name[] = { | 46 | + static const char *feature_name[] = { |
| 47 | "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", | 47 | "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", |
| 48 | "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", | 48 | "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", |
| 49 | "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx", | 49 | "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx", |
| 50 | "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe", | 50 | "fxsr", "sse", "sse2", "ss", "ht" /* Intel htt */, "tm", "ia64", "pbe", |
| 51 | }; | 51 | }; |
| 52 | - const char *ext_feature_name[] = { | 52 | + static const char *ext_feature_name[] = { |
| 53 | "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est", | 53 | "pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est", |
| 54 | "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL, | 54 | "tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL, |
| 55 | NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt", | 55 | NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt", |
| 56 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 56 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
| 57 | }; | 57 | }; |
| 58 | - const char *ext2_feature_name[] = { | 58 | + static const char *ext2_feature_name[] = { |
| 59 | "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", | 59 | "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", |
| 60 | "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mttr", "pge", "mca", "cmov", | 60 | "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mttr", "pge", "mca", "cmov", |
| 61 | "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx", | 61 | "pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx", |
| 62 | "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow", | 62 | "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp", NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow", |
| 63 | }; | 63 | }; |
| 64 | - const char *ext3_feature_name[] = { | 64 | + static const char *ext3_feature_name[] = { |
| 65 | "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse", | 65 | "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse", |
| 66 | "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL, | 66 | "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL, |
| 67 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 67 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
| @@ -127,6 +127,7 @@ typedef struct x86_def_t { | @@ -127,6 +127,7 @@ typedef struct x86_def_t { | ||
| 127 | int stepping; | 127 | int stepping; |
| 128 | uint32_t features, ext_features, ext2_features, ext3_features; | 128 | uint32_t features, ext_features, ext2_features, ext3_features; |
| 129 | uint32_t xlevel; | 129 | uint32_t xlevel; |
| 130 | + char model_id[48]; | ||
| 130 | } x86_def_t; | 131 | } x86_def_t; |
| 131 | 132 | ||
| 132 | #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE) | 133 | #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE) |
| @@ -162,6 +163,7 @@ static x86_def_t x86_defs[] = { | @@ -162,6 +163,7 @@ static x86_def_t x86_defs[] = { | ||
| 162 | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, | 163 | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, |
| 163 | .ext3_features = CPUID_EXT3_SVM, | 164 | .ext3_features = CPUID_EXT3_SVM, |
| 164 | .xlevel = 0x8000000A, | 165 | .xlevel = 0x8000000A, |
| 166 | + .model_id = "QEMU Virtual CPU version " QEMU_VERSION, | ||
| 165 | }, | 167 | }, |
| 166 | #endif | 168 | #endif |
| 167 | { | 169 | { |
| @@ -173,6 +175,7 @@ static x86_def_t x86_defs[] = { | @@ -173,6 +175,7 @@ static x86_def_t x86_defs[] = { | ||
| 173 | .features = PPRO_FEATURES, | 175 | .features = PPRO_FEATURES, |
| 174 | .ext_features = CPUID_EXT_SSE3, | 176 | .ext_features = CPUID_EXT_SSE3, |
| 175 | .xlevel = 0, | 177 | .xlevel = 0, |
| 178 | + .model_id = "QEMU Virtual CPU version " QEMU_VERSION, | ||
| 176 | }, | 179 | }, |
| 177 | { | 180 | { |
| 178 | .name = "486", | 181 | .name = "486", |
| @@ -222,6 +225,8 @@ static x86_def_t x86_defs[] = { | @@ -222,6 +225,8 @@ static x86_def_t x86_defs[] = { | ||
| 222 | .features = PPRO_FEATURES | PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA, | 225 | .features = PPRO_FEATURES | PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA, |
| 223 | .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, | 226 | .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, |
| 224 | .xlevel = 0x80000008, | 227 | .xlevel = 0x80000008, |
| 228 | + /* XXX: put another string ? */ | ||
| 229 | + .model_id = "QEMU Virtual CPU version " QEMU_VERSION, | ||
| 225 | }, | 230 | }, |
| 226 | }; | 231 | }; |
| 227 | 232 | ||
| @@ -262,7 +267,6 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) | @@ -262,7 +267,6 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) | ||
| 262 | family = strtol(val, &err, 10); | 267 | family = strtol(val, &err, 10); |
| 263 | if (!*val || *err || family < 0) { | 268 | if (!*val || *err || family < 0) { |
| 264 | fprintf(stderr, "bad numerical value %s\n", val); | 269 | fprintf(stderr, "bad numerical value %s\n", val); |
| 265 | - x86_cpu_def = 0; | ||
| 266 | goto error; | 270 | goto error; |
| 267 | } | 271 | } |
| 268 | x86_cpu_def->family = family; | 272 | x86_cpu_def->family = family; |
| @@ -271,7 +275,6 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) | @@ -271,7 +275,6 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) | ||
| 271 | model = strtol(val, &err, 10); | 275 | model = strtol(val, &err, 10); |
| 272 | if (!*val || *err || model < 0 || model > 0xf) { | 276 | if (!*val || *err || model < 0 || model > 0xf) { |
| 273 | fprintf(stderr, "bad numerical value %s\n", val); | 277 | fprintf(stderr, "bad numerical value %s\n", val); |
| 274 | - x86_cpu_def = 0; | ||
| 275 | goto error; | 278 | goto error; |
| 276 | } | 279 | } |
| 277 | x86_cpu_def->model = model; | 280 | x86_cpu_def->model = model; |
| @@ -280,18 +283,31 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) | @@ -280,18 +283,31 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) | ||
| 280 | stepping = strtol(val, &err, 10); | 283 | stepping = strtol(val, &err, 10); |
| 281 | if (!*val || *err || stepping < 0 || stepping > 0xf) { | 284 | if (!*val || *err || stepping < 0 || stepping > 0xf) { |
| 282 | fprintf(stderr, "bad numerical value %s\n", val); | 285 | fprintf(stderr, "bad numerical value %s\n", val); |
| 283 | - x86_cpu_def = 0; | ||
| 284 | goto error; | 286 | goto error; |
| 285 | } | 287 | } |
| 286 | x86_cpu_def->stepping = stepping; | 288 | x86_cpu_def->stepping = stepping; |
| 289 | + } else if (!strcmp(featurestr, "vendor")) { | ||
| 290 | + if (strlen(val) != 12) { | ||
| 291 | + fprintf(stderr, "vendor string must be 12 chars long\n"); | ||
| 292 | + goto error; | ||
| 293 | + } | ||
| 294 | + x86_cpu_def->vendor1 = 0; | ||
| 295 | + x86_cpu_def->vendor2 = 0; | ||
| 296 | + x86_cpu_def->vendor3 = 0; | ||
| 297 | + for(i = 0; i < 4; i++) { | ||
| 298 | + x86_cpu_def->vendor1 |= ((uint8_t)val[i ]) << (8 * i); | ||
| 299 | + x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i); | ||
| 300 | + x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i); | ||
| 301 | + } | ||
| 302 | + } else if (!strcmp(featurestr, "model_id")) { | ||
| 303 | + pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id), | ||
| 304 | + val); | ||
| 287 | } else { | 305 | } else { |
| 288 | fprintf(stderr, "unrecognized feature %s\n", featurestr); | 306 | fprintf(stderr, "unrecognized feature %s\n", featurestr); |
| 289 | - x86_cpu_def = 0; | ||
| 290 | goto error; | 307 | goto error; |
| 291 | } | 308 | } |
| 292 | } else { | 309 | } else { |
| 293 | fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr); | 310 | fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr); |
| 294 | - x86_cpu_def = 0; | ||
| 295 | goto error; | 311 | goto error; |
| 296 | } | 312 | } |
| 297 | featurestr = strtok(NULL, ","); | 313 | featurestr = strtok(NULL, ","); |
| @@ -344,14 +360,16 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model) | @@ -344,14 +360,16 @@ static int cpu_x86_register (CPUX86State *env, const char *cpu_model) | ||
| 344 | env->cpuid_xlevel = def->xlevel; | 360 | env->cpuid_xlevel = def->xlevel; |
| 345 | env->cpuid_ext3_features = def->ext3_features; | 361 | env->cpuid_ext3_features = def->ext3_features; |
| 346 | { | 362 | { |
| 347 | - const char *model_id = "QEMU Virtual CPU version " QEMU_VERSION; | 363 | + const char *model_id = def->model_id; |
| 348 | int c, len, i; | 364 | int c, len, i; |
| 365 | + if (!model_id) | ||
| 366 | + model_id = ""; | ||
| 349 | len = strlen(model_id); | 367 | len = strlen(model_id); |
| 350 | for(i = 0; i < 48; i++) { | 368 | for(i = 0; i < 48; i++) { |
| 351 | if (i >= len) | 369 | if (i >= len) |
| 352 | c = '\0'; | 370 | c = '\0'; |
| 353 | else | 371 | else |
| 354 | - c = model_id[i]; | 372 | + c = (uint8_t)model_id[i]; |
| 355 | env->cpuid_model[i >> 2] |= c << (8 * (i & 3)); | 373 | env->cpuid_model[i >> 2] |= c << (8 * (i & 3)); |
| 356 | } | 374 | } |
| 357 | } | 375 | } |