diff options
Diffstat (limited to 'target/i386/cpu.c')
-rw-r--r-- | target/i386/cpu.c | 174 |
1 files changed, 151 insertions, 23 deletions
diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 92fafa2659..34b511f078 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1133,7 +1133,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { "clzero", NULL, "xsaveerptr", NULL, NULL, NULL, NULL, NULL, NULL, "wbnoinvd", NULL, NULL, - "ibpb", NULL, NULL, NULL, + "ibpb", NULL, NULL, "amd-stibp", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "amd-ssbd", "virt-ssbd", "amd-no-ssb", NULL, @@ -1690,6 +1690,7 @@ typedef struct PropValue { typedef struct X86CPUVersionDefinition { X86CPUVersion version; const char *alias; + const char *note; PropValue *props; } X86CPUVersionDefinition; @@ -1720,6 +1721,7 @@ struct X86CPUModel { X86CPUDefinition *cpudef; /* CPU model version */ X86CPUVersion version; + const char *note; /* * If true, this is an alias CPU model. * This matters only for "-cpu help" and query-cpu-definitions @@ -1796,6 +1798,56 @@ static CPUCaches epyc_cache_info = { }, }; +static CPUCaches epyc_rome_cache_info = { + .l1d_cache = &(CPUCacheInfo) { + .type = DATA_CACHE, + .level = 1, + .size = 32 * KiB, + .line_size = 64, + .associativity = 8, + .partitions = 1, + .sets = 64, + .lines_per_tag = 1, + .self_init = 1, + .no_invd_sharing = true, + }, + .l1i_cache = &(CPUCacheInfo) { + .type = INSTRUCTION_CACHE, + .level = 1, + .size = 32 * KiB, + .line_size = 64, + .associativity = 8, + .partitions = 1, + .sets = 64, + .lines_per_tag = 1, + .self_init = 1, + .no_invd_sharing = true, + }, + .l2_cache = &(CPUCacheInfo) { + .type = UNIFIED_CACHE, + .level = 2, + .size = 512 * KiB, + .line_size = 64, + .associativity = 8, + .partitions = 1, + .sets = 1024, + .lines_per_tag = 1, + }, + .l3_cache = &(CPUCacheInfo) { + .type = UNIFIED_CACHE, + .level = 3, + .size = 16 * MiB, + .line_size = 64, + .associativity = 16, + .partitions = 1, + .sets = 16384, + .lines_per_tag = 1, + .self_init = true, + .inclusive = true, + .complex_indexing = true, + }, +}; + /* The following VMX features are not supported by KVM and are left out in the * CPU definitions: * @@ -3592,6 +3644,18 @@ static X86CPUDefinition builtin_x86_defs[] = { .features[FEAT_VMX_VMFUNC] = MSR_VMX_VMFUNC_EPT_SWITCHING, .xlevel = 0x80000008, .model_id = "Intel Atom Processor (Denverton)", + .versions = (X86CPUVersionDefinition[]) { + { .version = 1 }, + { + .version = 2, + .props = (PropValue[]) { + { "monitor", "off" }, + { "mpx", "off" }, + { /* end of list */ }, + }, + }, + { /* end of list */ }, + }, }, { .name = "Snowridge", @@ -3928,10 +3992,6 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT | CPUID_7_0_EBX_SHA_NI, - /* Missing: XSAVES (not supported by some Linux versions, - * including v4.1 to v4.12). - * KVM doesn't yet expose any XSAVES state save component. - */ .features[FEAT_XSAVE] = CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | CPUID_XSAVE_XGETBV1, @@ -3954,6 +4014,19 @@ static X86CPUDefinition builtin_x86_defs[] = { { /* end of list */ } } }, + { + .version = 3, + .props = (PropValue[]) { + { "ibpb", "on" }, + { "perfctr-core", "on" }, + { "clzero", "on" }, + { "xsaveerptr", "on" }, + { "xsaves", "on" }, + { "model-id", + "AMD EPYC Processor" }, + { /* end of list */ } + } + }, { /* end of list */ } } }, @@ -4007,6 +4080,56 @@ static X86CPUDefinition builtin_x86_defs[] = { .model_id = "Hygon Dhyana Processor", .cache_info = &epyc_cache_info, }, + { + .name = "EPYC-Rome", + .level = 0xd, + .vendor = CPUID_VENDOR_AMD, + .family = 23, + .model = 49, + .stepping = 0, + .features[FEAT_1_EDX] = + CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX | CPUID_CLFLUSH | + CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA | CPUID_PGE | + CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 | CPUID_MCE | + CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE | CPUID_DE | + CPUID_VME | CPUID_FP87, + .features[FEAT_1_ECX] = + CPUID_EXT_RDRAND | CPUID_EXT_F16C | CPUID_EXT_AVX | + CPUID_EXT_XSAVE | CPUID_EXT_AES | CPUID_EXT_POPCNT | + CPUID_EXT_MOVBE | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 | + CPUID_EXT_CX16 | CPUID_EXT_FMA | CPUID_EXT_SSSE3 | + CPUID_EXT_MONITOR | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3, + .features[FEAT_8000_0001_EDX] = + CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_PDPE1GB | + CPUID_EXT2_FFXSR | CPUID_EXT2_MMXEXT | CPUID_EXT2_NX | + CPUID_EXT2_SYSCALL, + .features[FEAT_8000_0001_ECX] = + CPUID_EXT3_OSVW | CPUID_EXT3_3DNOWPREFETCH | + CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | + CPUID_EXT3_CR8LEG | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM | + CPUID_EXT3_TOPOEXT | CPUID_EXT3_PERFCORE, + .features[FEAT_8000_0008_EBX] = + CPUID_8000_0008_EBX_CLZERO | CPUID_8000_0008_EBX_XSAVEERPTR | + CPUID_8000_0008_EBX_WBNOINVD | CPUID_8000_0008_EBX_IBPB | + CPUID_8000_0008_EBX_STIBP, + .features[FEAT_7_0_EBX] = + CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_AVX2 | + CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_RDSEED | + CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLFLUSHOPT | + CPUID_7_0_EBX_SHA_NI | CPUID_7_0_EBX_CLWB, + .features[FEAT_7_0_ECX] = + CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_RDPID, + .features[FEAT_XSAVE] = + CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC | + CPUID_XSAVE_XGETBV1 | CPUID_XSAVE_XSAVES, + .features[FEAT_6_EAX] = + CPUID_6_EAX_ARAT, + .features[FEAT_SVM] = + CPUID_SVM_NPT | CPUID_SVM_NRIPSAVE, + .xlevel = 0x8000001E, + .model_id = "AMD EPYC-Rome Processor", + .cache_info = &epyc_rome_cache_info, + }, }; /* KVM-specific features that are automatically added/removed @@ -4849,6 +4972,7 @@ static void x86_cpu_list_entry(gpointer data, gpointer user_data) g_autofree char *name = x86_cpu_class_get_model_name(cc); g_autofree char *desc = g_strdup(cc->model_description); g_autofree char *alias_of = x86_cpu_class_get_alias_of(cc); + g_autofree char *model_id = x86_cpu_class_get_model_id(cc); if (!desc && alias_of) { if (cc->model && cc->model->version == CPU_VERSION_AUTO) { @@ -4857,11 +4981,14 @@ static void x86_cpu_list_entry(gpointer data, gpointer user_data) desc = g_strdup_printf("(alias of %s)", alias_of); } } + if (!desc && cc->model && cc->model->note) { + desc = g_strdup_printf("%s [%s]", model_id, cc->model->note); + } if (!desc) { - desc = x86_cpu_class_get_model_id(cc); + desc = g_strdup_printf("%s", model_id); } - qemu_printf("x86 %-20s %-48s\n", name, desc); + qemu_printf("x86 %-20s %-58s\n", name, desc); } /* list available CPU models and flags */ @@ -5338,6 +5465,7 @@ static void x86_register_cpudef_types(X86CPUDefinition *def) x86_cpu_versioned_model_name(def, vdef->version); m->cpudef = def; m->version = vdef->version; + m->note = vdef->note; x86_register_cpu_model_type(name, m); if (vdef->alias) { @@ -5369,6 +5497,11 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, uint32_t die_offset; uint32_t limit; uint32_t signature[3]; + X86CPUTopoInfo topo_info; + + topo_info.dies_per_pkg = env->nr_dies; + topo_info.cores_per_die = cs->nr_cores; + topo_info.threads_per_core = cs->nr_threads; /* Calculate & apply limits for different index ranges */ if (index >= 0xC0000000) { @@ -5455,8 +5588,7 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, eax, ebx, ecx, edx); break; case 3: /* L3 cache info */ - die_offset = apicid_die_offset(env->nr_dies, - cs->nr_cores, cs->nr_threads); + die_offset = apicid_die_offset(&topo_info); if (cpu->enable_l3_cache) { encode_cache_cpuid4(env->cache_info_cpuid4.l3_cache, (1 << die_offset), cs->nr_cores, @@ -5547,14 +5679,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, switch (count) { case 0: - *eax = apicid_core_offset(env->nr_dies, - cs->nr_cores, cs->nr_threads); + *eax = apicid_core_offset(&topo_info); *ebx = cs->nr_threads; *ecx |= CPUID_TOPOLOGY_LEVEL_SMT; break; case 1: - *eax = apicid_pkg_offset(env->nr_dies, - cs->nr_cores, cs->nr_threads); + *eax = apicid_pkg_offset(&topo_info); *ebx = cs->nr_cores * cs->nr_threads; *ecx |= CPUID_TOPOLOGY_LEVEL_CORE; break; @@ -5578,20 +5708,17 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *edx = cpu->apic_id; switch (count) { case 0: - *eax = apicid_core_offset(env->nr_dies, cs->nr_cores, - cs->nr_threads); + *eax = apicid_core_offset(&topo_info); *ebx = cs->nr_threads; *ecx |= CPUID_TOPOLOGY_LEVEL_SMT; break; case 1: - *eax = apicid_die_offset(env->nr_dies, cs->nr_cores, - cs->nr_threads); + *eax = apicid_die_offset(&topo_info); *ebx = cs->nr_cores * cs->nr_threads; *ecx |= CPUID_TOPOLOGY_LEVEL_CORE; break; case 2: - *eax = apicid_pkg_offset(env->nr_dies, cs->nr_cores, - cs->nr_threads); + *eax = apicid_pkg_offset(&topo_info); *ebx = env->nr_dies * cs->nr_cores * cs->nr_threads; *ecx |= CPUID_TOPOLOGY_LEVEL_DIE; break; @@ -5855,9 +5982,9 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, } } -/* CPUClass::reset() */ -static void x86_cpu_reset(CPUState *s) +static void x86_cpu_reset(DeviceState *dev) { + CPUState *s = CPU(dev); X86CPU *cpu = X86_CPU(s); X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu); CPUX86State *env = &cpu->env; @@ -5865,7 +5992,7 @@ static void x86_cpu_reset(CPUState *s) uint64_t xcr0; int i; - xcc->parent_reset(s); + xcc->parent_reset(dev); memset(env, 0, offsetof(CPUX86State, end_reset_fields)); @@ -6830,6 +6957,7 @@ static void x86_cpu_initfn(Object *obj) FeatureWord w; env->nr_dies = 1; + env->nr_nodes = 1; cpu_set_cpustate_pointers(cpu); object_property_add(obj, "family", "int", @@ -7169,7 +7297,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) &xcc->parent_unrealize); device_class_set_props(dc, x86_cpu_properties); - cpu_class_set_parent_reset(cc, x86_cpu_reset, &xcc->parent_reset); + device_class_set_parent_reset(dc, x86_cpu_reset, &xcc->parent_reset); cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP; cc->class_by_name = x86_cpu_class_by_name; |