Revision 40f8e2fa
b/target-i386/helper.c | ||
---|---|---|
43 | 43 |
/* feature flags taken from "Intel Processor Identification and the CPUID |
44 | 44 |
* Instruction" and AMD's "CPUID Specification". In cases of disagreement |
45 | 45 |
* about feature names, the Linux name is used. */ |
46 |
const char *feature_name[] = { |
|
46 |
static const char *feature_name[] = {
|
|
47 | 47 |
"fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", |
48 | 48 |
"cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", |
49 | 49 |
"pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */, NULL, "ds" /* Intel dts */, "acpi", "mmx", |
50 | 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 | 53 |
"pni" /* Intel,AMD sse3 */, NULL, NULL, "monitor", "ds_cpl", "vmx", NULL /* Linux smx */, "est", |
54 | 54 |
"tm2", "ssse3", "cid", NULL, NULL, "cx16", "xtpr", NULL, |
55 | 55 |
NULL, NULL, "dca", NULL, NULL, NULL, NULL, "popcnt", |
56 | 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 | 59 |
"fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", |
60 | 60 |
"cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall", "mttr", "pge", "mca", "cmov", |
61 | 61 |
"pat", "pse36", NULL, NULL /* Linux mp */, "nx" /* Intel xd */, NULL, "mmxext", "mmx", |
62 | 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 | 65 |
"lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */, "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse", |
66 | 66 |
"3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL, "skinit", "wdt", NULL, NULL, |
67 | 67 |
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
... | ... | |
127 | 127 |
int stepping; |
128 | 128 |
uint32_t features, ext_features, ext2_features, ext3_features; |
129 | 129 |
uint32_t xlevel; |
130 |
char model_id[48]; |
|
130 | 131 |
} x86_def_t; |
131 | 132 |
|
132 | 133 |
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE) |
... | ... | |
162 | 163 |
CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, |
163 | 164 |
.ext3_features = CPUID_EXT3_SVM, |
164 | 165 |
.xlevel = 0x8000000A, |
166 |
.model_id = "QEMU Virtual CPU version " QEMU_VERSION, |
|
165 | 167 |
}, |
166 | 168 |
#endif |
167 | 169 |
{ |
... | ... | |
173 | 175 |
.features = PPRO_FEATURES, |
174 | 176 |
.ext_features = CPUID_EXT_SSE3, |
175 | 177 |
.xlevel = 0, |
178 |
.model_id = "QEMU Virtual CPU version " QEMU_VERSION, |
|
176 | 179 |
}, |
177 | 180 |
{ |
178 | 181 |
.name = "486", |
... | ... | |
222 | 225 |
.features = PPRO_FEATURES | PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA, |
223 | 226 |
.ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT, |
224 | 227 |
.xlevel = 0x80000008, |
228 |
/* XXX: put another string ? */ |
|
229 |
.model_id = "QEMU Virtual CPU version " QEMU_VERSION, |
|
225 | 230 |
}, |
226 | 231 |
}; |
227 | 232 |
|
... | ... | |
262 | 267 |
family = strtol(val, &err, 10); |
263 | 268 |
if (!*val || *err || family < 0) { |
264 | 269 |
fprintf(stderr, "bad numerical value %s\n", val); |
265 |
x86_cpu_def = 0; |
|
266 | 270 |
goto error; |
267 | 271 |
} |
268 | 272 |
x86_cpu_def->family = family; |
... | ... | |
271 | 275 |
model = strtol(val, &err, 10); |
272 | 276 |
if (!*val || *err || model < 0 || model > 0xf) { |
273 | 277 |
fprintf(stderr, "bad numerical value %s\n", val); |
274 |
x86_cpu_def = 0; |
|
275 | 278 |
goto error; |
276 | 279 |
} |
277 | 280 |
x86_cpu_def->model = model; |
... | ... | |
280 | 283 |
stepping = strtol(val, &err, 10); |
281 | 284 |
if (!*val || *err || stepping < 0 || stepping > 0xf) { |
282 | 285 |
fprintf(stderr, "bad numerical value %s\n", val); |
283 |
x86_cpu_def = 0; |
|
284 | 286 |
goto error; |
285 | 287 |
} |
286 | 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 | 305 |
} else { |
288 | 306 |
fprintf(stderr, "unrecognized feature %s\n", featurestr); |
289 |
x86_cpu_def = 0; |
|
290 | 307 |
goto error; |
291 | 308 |
} |
292 | 309 |
} else { |
293 | 310 |
fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr); |
294 |
x86_cpu_def = 0; |
|
295 | 311 |
goto error; |
296 | 312 |
} |
297 | 313 |
featurestr = strtok(NULL, ","); |
... | ... | |
344 | 360 |
env->cpuid_xlevel = def->xlevel; |
345 | 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 | 364 |
int c, len, i; |
365 |
if (!model_id) |
|
366 |
model_id = ""; |
|
349 | 367 |
len = strlen(model_id); |
350 | 368 |
for(i = 0; i < 48; i++) { |
351 | 369 |
if (i >= len) |
352 | 370 |
c = '\0'; |
353 | 371 |
else |
354 |
c = model_id[i]; |
|
372 |
c = (uint8_t)model_id[i];
|
|
355 | 373 |
env->cpuid_model[i >> 2] |= c << (8 * (i & 3)); |
356 | 374 |
} |
357 | 375 |
} |
Also available in: Unified diff