diff --git a/target-i386/helper.c b/target-i386/helper.c index cb9113e8c80d5240e6a8be7e5480cfb0d69d39f7..d7563f7bbd6dd789ac205a65f030ba5de78016e3 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -273,9 +273,9 @@ static x86_def_t x86_defs[] = { { .name = "athlon", .level = 2, - .vendor1 = 0x68747541, /* "Auth" */ - .vendor2 = 0x69746e65, /* "enti" */ - .vendor3 = 0x444d4163, /* "cAMD" */ + .vendor1 = CPUID_VENDOR_AMD_1, + .vendor2 = CPUID_VENDOR_AMD_2, + .vendor3 = CPUID_VENDOR_AMD_3, .family = 6, .model = 2, .stepping = 3, @@ -308,6 +308,54 @@ static x86_def_t x86_defs[] = { }, }; +static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax, + uint32_t *ebx, uint32_t *ecx, uint32_t *edx); + +static int cpu_x86_fill_model_id(char *str) +{ + uint32_t eax, ebx, ecx, edx; + int i; + + for (i = 0; i < 3; i++) { + host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx); + memcpy(str + i * 16 + 0, &eax, 4); + memcpy(str + i * 16 + 4, &ebx, 4); + memcpy(str + i * 16 + 8, &ecx, 4); + memcpy(str + i * 16 + 12, &edx, 4); + } + return 0; +} + +static int cpu_x86_fill_host(x86_def_t *x86_cpu_def) +{ + uint32_t eax, ebx, ecx, edx; + + x86_cpu_def->name = "host"; + host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx); + x86_cpu_def->level = eax; + x86_cpu_def->vendor1 = ebx; + x86_cpu_def->vendor2 = edx; + x86_cpu_def->vendor3 = ecx; + + host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx); + x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF); + x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12); + x86_cpu_def->stepping = eax & 0x0F; + x86_cpu_def->ext_features = ecx; + x86_cpu_def->features = edx; + + host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx); + x86_cpu_def->xlevel = eax; + + host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx); + x86_cpu_def->ext2_features = edx; + x86_cpu_def->ext3_features = ecx; + cpu_x86_fill_model_id(x86_cpu_def->model_id); + x86_cpu_def->vendor_override = 0; + + return 0; +} + static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) { unsigned int i; @@ -326,9 +374,14 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model) break; } } - if (!def) - goto error; - memcpy(x86_cpu_def, def, sizeof(*def)); + if (!def) { + if (strcmp(name, "host") != 0) { + goto error; + } + cpu_x86_fill_host(x86_cpu_def); + } else { + memcpy(x86_cpu_def, def, sizeof(*def)); + } add_flagname_to_bitmaps("hypervisor", &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features);