Revision 2d5f20b5 target-i386/cpuid.c
b/target-i386/cpuid.c | ||
---|---|---|
230 | 230 |
char model_id[48]; |
231 | 231 |
int vendor_override; |
232 | 232 |
uint32_t flags; |
233 |
/* Store the results of Centaur's CPUID instructions */ |
|
234 |
uint32_t ext4_features; |
|
235 |
uint32_t xlevel2; |
|
233 | 236 |
} x86_def_t; |
234 | 237 |
|
235 | 238 |
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE) |
... | ... | |
522 | 525 |
cpu_x86_fill_model_id(x86_cpu_def->model_id); |
523 | 526 |
x86_cpu_def->vendor_override = 0; |
524 | 527 |
|
528 |
/* Call Centaur's CPUID instruction. */ |
|
529 |
if (x86_cpu_def->vendor1 == CPUID_VENDOR_VIA_1 && |
|
530 |
x86_cpu_def->vendor2 == CPUID_VENDOR_VIA_2 && |
|
531 |
x86_cpu_def->vendor3 == CPUID_VENDOR_VIA_3) { |
|
532 |
host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx); |
|
533 |
if (eax >= 0xC0000001) { |
|
534 |
/* Support VIA max extended level */ |
|
535 |
x86_cpu_def->xlevel2 = eax; |
|
536 |
host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx); |
|
537 |
x86_cpu_def->ext4_features = edx; |
|
538 |
} |
|
539 |
} |
|
525 | 540 |
|
526 | 541 |
/* |
527 | 542 |
* Every SVM feature requires emulation support in KVM - so we can't just |
... | ... | |
855 | 870 |
env->cpuid_xlevel = def->xlevel; |
856 | 871 |
env->cpuid_kvm_features = def->kvm_features; |
857 | 872 |
env->cpuid_svm_features = def->svm_features; |
873 |
env->cpuid_ext4_features = def->ext4_features; |
|
874 |
env->cpuid_xlevel2 = def->xlevel2; |
|
858 | 875 |
if (!kvm_enabled()) { |
859 | 876 |
env->cpuid_features &= TCG_FEATURES; |
860 | 877 |
env->cpuid_ext_features &= TCG_EXT_FEATURES; |
... | ... | |
1035 | 1052 |
{ |
1036 | 1053 |
/* test if maximum index reached */ |
1037 | 1054 |
if (index & 0x80000000) { |
1038 |
if (index > env->cpuid_xlevel) |
|
1039 |
index = env->cpuid_level; |
|
1055 |
if (index > env->cpuid_xlevel) { |
|
1056 |
if (env->cpuid_xlevel2 > 0) { |
|
1057 |
/* Handle the Centaur's CPUID instruction. */ |
|
1058 |
if (index > env->cpuid_xlevel2) { |
|
1059 |
index = env->cpuid_xlevel2; |
|
1060 |
} else if (index < 0xC0000000) { |
|
1061 |
index = env->cpuid_xlevel; |
|
1062 |
} |
|
1063 |
} else { |
|
1064 |
index = env->cpuid_xlevel; |
|
1065 |
} |
|
1066 |
} |
|
1040 | 1067 |
} else { |
1041 | 1068 |
if (index > env->cpuid_level) |
1042 | 1069 |
index = env->cpuid_level; |
... | ... | |
1231 | 1258 |
*edx = 0; |
1232 | 1259 |
} |
1233 | 1260 |
break; |
1261 |
case 0xC0000000: |
|
1262 |
*eax = env->cpuid_xlevel2; |
|
1263 |
*ebx = 0; |
|
1264 |
*ecx = 0; |
|
1265 |
*edx = 0; |
|
1266 |
break; |
|
1267 |
case 0xC0000001: |
|
1268 |
/* Support for VIA CPU's CPUID instruction */ |
|
1269 |
*eax = env->cpuid_version; |
|
1270 |
*ebx = 0; |
|
1271 |
*ecx = 0; |
|
1272 |
*edx = env->cpuid_ext4_features; |
|
1273 |
break; |
|
1274 |
case 0xC0000002: |
|
1275 |
case 0xC0000003: |
|
1276 |
case 0xC0000004: |
|
1277 |
/* Reserved for the future, and now filled with zero */ |
|
1278 |
*eax = 0; |
|
1279 |
*ebx = 0; |
|
1280 |
*ecx = 0; |
|
1281 |
*edx = 0; |
|
1282 |
break; |
|
1234 | 1283 |
default: |
1235 | 1284 |
/* reserved values: zero */ |
1236 | 1285 |
*eax = 0; |
Also available in: Unified diff