From: Eduardo Habkost <ehabkost@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Igor Mammedov" <imammedo@redhat.com>,
"Andreas Färber" <afaerber@suse.de>
Subject: [Qemu-devel] [RFC 8/9] target-i386: CPU subclasses for predefined CPU models
Date: Fri, 28 Dec 2012 18:34:05 -0200 [thread overview]
Message-ID: <1356726846-10637-9-git-send-email-ehabkost@redhat.com> (raw)
In-Reply-To: <1356726846-10637-1-git-send-email-ehabkost@redhat.com>
This uses a separate base class (TYPE_X86_PREDEF_CPU) for all the
predefined CPU models, because those classes will have a x86_def_t
struct embedded into the class struct (while TYPE_X86_HOST_CPU, for
example, doesn't have it). The code that was inside
x86_cpu_create_from_name() is now inside the instance_init function for
TYPE_X86_PREDEF_CPU.
The qemu_get_version() hacks inside x86_cpudef_setup() were moved to the
class_init functions of qemu64, qemu32, and athlon CPU models.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
target-i386/cpu.c | 656 ++++++++++++++++++++++++++++++++++++++++--------------
target-i386/cpu.h | 2 -
2 files changed, 494 insertions(+), 164 deletions(-)
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 2b6cc3b..fa7fab0 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -273,8 +273,6 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
}
typedef struct x86_def_t {
- struct x86_def_t *next;
- const char *name;
uint32_t level;
char vendor[CPUID_VENDOR_SZ + 1];
int family;
@@ -335,18 +333,51 @@ typedef struct x86_def_t {
#define CPU_CLASS_NAME(name) (name "-" TYPE_X86_CPU)
+/* -cpu "host" */
#define TYPE_X86_HOST_CPU CPU_CLASS_NAME("host")
-/* maintains list of cpu model definitions
- */
-static x86_def_t *x86_defs = {NULL};
+/* Base class for predefined CPU models: */
+#define TYPE_X86_PREDEF_CPU TYPE_X86_CPU "-predefined"
+
+#define PREDEF_X86_CPU_CLASS(klass) \
+ OBJECT_CLASS_CHECK(PredefX86CPUClass, (klass), TYPE_X86_PREDEF_CPU)
+#define PREDEF_X86_CPU(obj) \
+ OBJECT_CHECK(X86CPU, (obj), TYPE_X86_PREDEF_CPU)
+#define PREDEF_X86_CPU_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(PredefX86CPUClass, (obj), TYPE_X86_PREDEF_CPU)
-/* built-in cpu model definitions (deprecated)
+
+/**
+ * PredefX86CPUClass:
+ *
+ * A predefined x86 CPU model.
*/
-static x86_def_t builtin_x86_defs[] = {
- {
- .name = "qemu64",
+typedef struct PredefX86CPUClass {
+ /*< private >*/
+ X86CPUClass parent_class;
+ /*< public >*/
+
+ x86_def_t cpudef;
+} PredefX86CPUClass;
+
+
+static void x86_cpu_predef_initfn(Object *obj);
+
+static const TypeInfo predef_x86_cpu_type_info = {
+ .name = TYPE_X86_PREDEF_CPU,
+ .parent = TYPE_X86_CPU,
+ .instance_size = sizeof(X86CPU),
+ .instance_init = x86_cpu_predef_initfn,
+ .abstract = true,
+ .class_size = sizeof(PredefX86CPUClass),
+};
+
+
+static void x86_cpu_class_init_qemu64(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 4,
.vendor = CPUID_VENDOR_AMD,
.family = 6,
@@ -361,9 +392,24 @@ static x86_def_t builtin_x86_defs[] = {
.ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
.xlevel = 0x8000000A,
- },
- {
- .name = "phenom",
+ };
+ pstrcpy(cc->cpudef.model_id, sizeof(cc->cpudef.model_id), "QEMU Virtual CPU version ");
+ pstrcat(cc->cpudef.model_id, sizeof(cc->cpudef.model_id), qemu_get_version());
+}
+
+static const TypeInfo x86_cpu_qemu64_type_info = {
+ .name = CPU_CLASS_NAME("qemu64"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_qemu64,
+};
+
+static void x86_cpu_class_init_phenom(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 16,
@@ -387,9 +433,22 @@ static x86_def_t builtin_x86_defs[] = {
.svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV,
.xlevel = 0x8000001A,
.model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
- },
- {
- .name = "core2duo",
+ };
+}
+
+static const TypeInfo x86_cpu_phenom_type_info = {
+ .name = CPU_CLASS_NAME("phenom"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_phenom,
+};
+
+static void x86_cpu_class_init_core2duo(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 10,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -406,9 +465,22 @@ static x86_def_t builtin_x86_defs[] = {
.ext3_features = CPUID_EXT3_LAHF_LM,
.xlevel = 0x80000008,
.model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
- },
- {
- .name = "kvm64",
+ };
+}
+
+static const TypeInfo x86_cpu_core2duo_type_info = {
+ .name = CPU_CLASS_NAME("core2duo"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_core2duo,
+};
+
+static void x86_cpu_class_init_kvm64(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 5,
.vendor = CPUID_VENDOR_INTEL,
.family = 15,
@@ -430,9 +502,22 @@ static x86_def_t builtin_x86_defs[] = {
.ext3_features = 0,
.xlevel = 0x80000008,
.model_id = "Common KVM processor"
- },
- {
- .name = "qemu32",
+ };
+}
+
+static const TypeInfo x86_cpu_kvm64_type_info = {
+ .name = CPU_CLASS_NAME("kvm64"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_kvm64,
+};
+
+static void x86_cpu_class_init_qemu32(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 4,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -441,9 +526,24 @@ static x86_def_t builtin_x86_defs[] = {
.features = PPRO_FEATURES,
.ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
.xlevel = 0x80000004,
- },
- {
- .name = "kvm32",
+ };
+ pstrcpy(cc->cpudef.model_id, sizeof(cc->cpudef.model_id), "QEMU Virtual CPU version ");
+ pstrcat(cc->cpudef.model_id, sizeof(cc->cpudef.model_id), qemu_get_version());
+}
+
+static const TypeInfo x86_cpu_qemu32_type_info = {
+ .name = CPU_CLASS_NAME("qemu32"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_qemu32,
+};
+
+static void x86_cpu_class_init_kvm32(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 5,
.vendor = CPUID_VENDOR_INTEL,
.family = 15,
@@ -456,9 +556,22 @@ static x86_def_t builtin_x86_defs[] = {
.ext3_features = 0,
.xlevel = 0x80000008,
.model_id = "Common 32-bit KVM processor"
- },
- {
- .name = "coreduo",
+ };
+}
+
+static const TypeInfo x86_cpu_kvm32_type_info = {
+ .name = CPU_CLASS_NAME("kvm32"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_kvm32,
+};
+
+static void x86_cpu_class_init_coreduo(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 10,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -472,9 +585,22 @@ static x86_def_t builtin_x86_defs[] = {
.ext2_features = CPUID_EXT2_NX,
.xlevel = 0x80000008,
.model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
- },
- {
- .name = "486",
+ };
+}
+
+static const TypeInfo x86_cpu_coreduo_type_info = {
+ .name = CPU_CLASS_NAME("coreduo"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_coreduo,
+};
+
+static void x86_cpu_class_init_486(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 1,
.vendor = CPUID_VENDOR_INTEL,
.family = 4,
@@ -482,9 +608,22 @@ static x86_def_t builtin_x86_defs[] = {
.stepping = 0,
.features = I486_FEATURES,
.xlevel = 0,
- },
- {
- .name = "pentium",
+ };
+}
+
+static const TypeInfo x86_cpu_486_type_info = {
+ .name = CPU_CLASS_NAME("486"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_486,
+};
+
+static void x86_cpu_class_init_pentium(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 1,
.vendor = CPUID_VENDOR_INTEL,
.family = 5,
@@ -492,9 +631,22 @@ static x86_def_t builtin_x86_defs[] = {
.stepping = 3,
.features = PENTIUM_FEATURES,
.xlevel = 0,
- },
- {
- .name = "pentium2",
+ };
+}
+
+static const TypeInfo x86_cpu_pentium_type_info = {
+ .name = CPU_CLASS_NAME("pentium"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_pentium,
+};
+
+static void x86_cpu_class_init_pentium2(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 2,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -502,9 +654,22 @@ static x86_def_t builtin_x86_defs[] = {
.stepping = 2,
.features = PENTIUM2_FEATURES,
.xlevel = 0,
- },
- {
- .name = "pentium3",
+ };
+}
+
+static const TypeInfo x86_cpu_pentium2_type_info = {
+ .name = CPU_CLASS_NAME("pentium2"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_pentium2,
+};
+
+static void x86_cpu_class_init_pentium3(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 2,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -512,9 +677,22 @@ static x86_def_t builtin_x86_defs[] = {
.stepping = 3,
.features = PENTIUM3_FEATURES,
.xlevel = 0,
- },
- {
- .name = "athlon",
+ };
+}
+
+static const TypeInfo x86_cpu_pentium3_type_info = {
+ .name = CPU_CLASS_NAME("pentium3"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_pentium3,
+};
+
+static void x86_cpu_class_init_athlon(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 2,
.vendor = CPUID_VENDOR_AMD,
.family = 6,
@@ -525,9 +703,24 @@ static x86_def_t builtin_x86_defs[] = {
.ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
.xlevel = 0x80000008,
- },
- {
- .name = "n270",
+ };
+ pstrcpy(cc->cpudef.model_id, sizeof(cc->cpudef.model_id), "QEMU Virtual CPU version ");
+ pstrcat(cc->cpudef.model_id, sizeof(cc->cpudef.model_id), qemu_get_version());
+}
+
+static const TypeInfo x86_cpu_athlon_type_info = {
+ .name = CPU_CLASS_NAME("athlon"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_athlon,
+};
+
+static void x86_cpu_class_init_n270(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
/* original is on level 10 */
.level = 5,
.vendor = CPUID_VENDOR_INTEL,
@@ -545,9 +738,22 @@ static x86_def_t builtin_x86_defs[] = {
.ext3_features = CPUID_EXT3_LAHF_LM,
.xlevel = 0x8000000A,
.model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
- },
- {
- .name = "Conroe",
+ };
+}
+
+static const TypeInfo x86_cpu_n270_type_info = {
+ .name = CPU_CLASS_NAME("n270"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_n270,
+};
+
+static void x86_cpu_class_init_Conroe(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 2,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -563,9 +769,22 @@ static x86_def_t builtin_x86_defs[] = {
.ext3_features = CPUID_EXT3_LAHF_LM,
.xlevel = 0x8000000A,
.model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
- },
- {
- .name = "Penryn",
+ };
+}
+
+static const TypeInfo x86_cpu_Conroe_type_info = {
+ .name = CPU_CLASS_NAME("Conroe"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_Conroe,
+};
+
+static void x86_cpu_class_init_Penryn(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 2,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -582,9 +801,22 @@ static x86_def_t builtin_x86_defs[] = {
.ext3_features = CPUID_EXT3_LAHF_LM,
.xlevel = 0x8000000A,
.model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
- },
- {
- .name = "Nehalem",
+ };
+}
+
+static const TypeInfo x86_cpu_Penryn_type_info = {
+ .name = CPU_CLASS_NAME("Penryn"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_Penryn,
+};
+
+static void x86_cpu_class_init_Nehalem(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 2,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -601,9 +833,22 @@ static x86_def_t builtin_x86_defs[] = {
.ext3_features = CPUID_EXT3_LAHF_LM,
.xlevel = 0x8000000A,
.model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
- },
- {
- .name = "Westmere",
+ };
+}
+
+static const TypeInfo x86_cpu_Nehalem_type_info = {
+ .name = CPU_CLASS_NAME("Nehalem"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_Nehalem,
+};
+
+static void x86_cpu_class_init_Westmere(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 11,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -621,9 +866,22 @@ static x86_def_t builtin_x86_defs[] = {
.ext3_features = CPUID_EXT3_LAHF_LM,
.xlevel = 0x8000000A,
.model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
- },
- {
- .name = "SandyBridge",
+ };
+}
+
+static const TypeInfo x86_cpu_Westmere_type_info = {
+ .name = CPU_CLASS_NAME("Westmere"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_Westmere,
+};
+
+static void x86_cpu_class_init_SandyBridge(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -644,9 +902,22 @@ static x86_def_t builtin_x86_defs[] = {
.ext3_features = CPUID_EXT3_LAHF_LM,
.xlevel = 0x8000000A,
.model_id = "Intel Xeon E312xx (Sandy Bridge)",
- },
- {
- .name = "Haswell",
+ };
+}
+
+static const TypeInfo x86_cpu_SandyBridge_type_info = {
+ .name = CPU_CLASS_NAME("SandyBridge"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_SandyBridge,
+};
+
+static void x86_cpu_class_init_Haswell(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 0xd,
.vendor = CPUID_VENDOR_INTEL,
.family = 6,
@@ -672,9 +943,22 @@ static x86_def_t builtin_x86_defs[] = {
CPUID_7_0_EBX_RTM,
.xlevel = 0x8000000A,
.model_id = "Intel Core Processor (Haswell)",
- },
- {
- .name = "Opteron_G1",
+ };
+}
+
+static const TypeInfo x86_cpu_Haswell_type_info = {
+ .name = CPU_CLASS_NAME("Haswell"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_Haswell,
+};
+
+static void x86_cpu_class_init_Opteron_G1(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -694,9 +978,22 @@ static x86_def_t builtin_x86_defs[] = {
CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
.xlevel = 0x80000008,
.model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
- },
- {
- .name = "Opteron_G2",
+ };
+}
+
+static const TypeInfo x86_cpu_Opteron_G1_type_info = {
+ .name = CPU_CLASS_NAME("Opteron_G1"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_Opteron_G1,
+};
+
+static void x86_cpu_class_init_Opteron_G2(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -718,9 +1015,22 @@ static x86_def_t builtin_x86_defs[] = {
.ext3_features = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
.xlevel = 0x80000008,
.model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
- },
- {
- .name = "Opteron_G3",
+ };
+}
+
+static const TypeInfo x86_cpu_Opteron_G2_type_info = {
+ .name = CPU_CLASS_NAME("Opteron_G2"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_Opteron_G2,
+};
+
+static void x86_cpu_class_init_Opteron_G3(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 5,
.vendor = CPUID_VENDOR_AMD,
.family = 15,
@@ -744,9 +1054,22 @@ static x86_def_t builtin_x86_defs[] = {
CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
.xlevel = 0x80000008,
.model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
- },
- {
- .name = "Opteron_G4",
+ };
+}
+
+static const TypeInfo x86_cpu_Opteron_G3_type_info = {
+ .name = CPU_CLASS_NAME("Opteron_G3"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_Opteron_G3,
+};
+
+static void x86_cpu_class_init_Opteron_G4(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
.family = 21,
@@ -774,9 +1097,22 @@ static x86_def_t builtin_x86_defs[] = {
CPUID_EXT3_LAHF_LM,
.xlevel = 0x8000001A,
.model_id = "AMD Opteron 62xx class CPU",
- },
- {
- .name = "Opteron_G5",
+ };
+}
+
+static const TypeInfo x86_cpu_Opteron_G4_type_info = {
+ .name = CPU_CLASS_NAME("Opteron_G4"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_Opteron_G4,
+};
+
+static void x86_cpu_class_init_Opteron_G5(ObjectClass *oc, void *data)
+{
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_CLASS(oc);
+ cc->cpudef = (x86_def_t) {
.level = 0xd,
.vendor = CPUID_VENDOR_AMD,
.family = 21,
@@ -804,7 +1140,16 @@ static x86_def_t builtin_x86_defs[] = {
CPUID_EXT3_LAHF_LM,
.xlevel = 0x8000001A,
.model_id = "AMD Opteron 63xx class CPU",
- },
+ };
+}
+
+static const TypeInfo x86_cpu_Opteron_G5_type_info = {
+ .name = CPU_CLASS_NAME("Opteron_G5"),
+ .parent = TYPE_X86_PREDEF_CPU,
+ .instance_size = sizeof(X86CPU),
+ .abstract = false,
+ .class_size = sizeof(PredefX86CPUClass),
+ .class_init = x86_cpu_class_init_Opteron_G5,
};
static void x86cpu_vendor_words2str(char *dst, uint32_t ebx, uint32_t ecx,
@@ -847,7 +1192,6 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
assert(kvm_enabled());
- x86_cpu_def->name = "host";
host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
x86cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
@@ -1219,60 +1563,67 @@ static void cpudef_2_x86_cpu(X86CPU *cpu, x86_def_t *def, Error **errp)
object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
}
+static void x86_cpu_predef_initfn(Object *obj)
+{
+ X86CPU *cpu = X86_CPU(obj);
+ PredefX86CPUClass *cc = PREDEF_X86_CPU_GET_CLASS(cpu);
+ Error *error = NULL;
+ x86_def_t cpudef;
+
+ memcpy(&cpudef, &cc->cpudef, sizeof(cpudef));
+ /* sysenter isn't supported on compatibility mode on AMD, syscall
+ * isn't supported in compatibility mode on Intel.
+ * Normally we advertise the actual cpu vendor, but you can override
+ * this using the 'vendor' property if you want to use KVM's
+ * sysenter/syscall emulation in compatibility mode and when doing
+ * cross vendor migration
+ */
+ if (kvm_enabled()) {
+ uint32_t ebx = 0, ecx = 0, edx = 0;
+ host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
+ x86cpu_vendor_words2str(cpudef.vendor, ebx, edx, ecx);
+ }
+
+ cpudef.kvm_features |= kvm_default_features;
+ add_flagname_to_bitmaps("hypervisor", &cpudef.features,
+ &cpudef.ext_features,
+ &cpudef.ext2_features,
+ &cpudef.ext3_features,
+ &cpudef.kvm_features,
+ &cpudef.svm_features,
+ &cpudef.cpuid_7_0_ebx_features);
+
+ cpudef_2_x86_cpu(cpu, &cpudef, &error);
+
+ if (error) {
+ error_report("cpu_init: %s", error_get_pretty(error));
+ exit(1);
+ }
+}
+
static X86CPU *x86_cpu_create_from_name(const char *name, Error **errp)
{
Error *error = NULL;
X86CPU *cpu = NULL;
- x86_def_t def1, *x86_cpu_def = &def1;
+ char *class_name = g_strdup_printf(CPU_CLASS_NAME("%s"), name);
- memset(&def1, 0, sizeof(def1));
if (kvm_enabled() && name && strcmp(name, "host") == 0) {
#ifdef CONFIG_KVM
cpu = X86_CPU(object_new(TYPE_X86_HOST_CPU));
#endif
} else {
- x86_def_t *def;
-
- for (def = x86_defs; def; def = def->next) {
- if (name && !strcmp(name, def->name)) {
- break;
- }
- }
- if (!def) {
+ if (!object_class_by_name(class_name)) {
error_setg(&error, "Unable to find CPU definition: %s", name);
goto out;
}
- cpu = X86_CPU(object_new(TYPE_X86_CPU));
- memcpy(x86_cpu_def, def, sizeof(*def));
- /* sysenter isn't supported on compatibility mode on AMD, syscall
- * isn't supported in compatibility mode on Intel.
- * Normally we advertise the actual cpu vendor, but you can override
- * this using the 'vendor' property if you want to use KVM's
- * sysenter/syscall emulation in compatibility mode and when doing
- * cross vendor migration
- */
- if (kvm_enabled()) {
- uint32_t ebx = 0, ecx = 0, edx = 0;
- host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
- x86cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
- }
-
- x86_cpu_def->kvm_features |= kvm_default_features;
- add_flagname_to_bitmaps("hypervisor", &x86_cpu_def->features,
- &x86_cpu_def->ext_features,
- &x86_cpu_def->ext2_features,
- &x86_cpu_def->ext3_features,
- &x86_cpu_def->kvm_features,
- &x86_cpu_def->svm_features,
- &x86_cpu_def->cpuid_7_0_ebx_features);
-
- cpudef_2_x86_cpu(cpu, x86_cpu_def, &error);
+ cpu = X86_CPU(object_new(class_name));
}
out:
+ g_free(class_name);
if (error) {
error_propagate(errp, error);
if (cpu) {
@@ -1452,13 +1803,9 @@ static void listflags(char *buf, int bufsize, uint32_t fbits,
/* generate CPU information. */
void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
{
- x86_def_t *def;
char buf[256];
- for (def = x86_defs; def; def = def->next) {
- snprintf(buf, sizeof(buf), "%s", def->name);
- (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
- }
+ /***** TODO: class listing */
if (kvm_enabled()) {
(*cpu_fprintf)(f, "x86 %16s\n", "[host]");
}
@@ -1476,20 +1823,7 @@ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
{
CpuDefinitionInfoList *cpu_list = NULL;
- x86_def_t *def;
-
- for (def = x86_defs; def; def = def->next) {
- CpuDefinitionInfoList *entry;
- CpuDefinitionInfo *info;
-
- info = g_malloc0(sizeof(*info));
- info->name = g_strdup(def->name);
-
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = cpu_list;
- cpu_list = entry;
- }
+ /***** TODO: class listing */
return cpu_list;
}
@@ -1577,33 +1911,6 @@ void cpu_clear_apic_feature(CPUX86State *env)
#endif /* !CONFIG_USER_ONLY */
-/* Initialize list of CPU models, filling some non-static fields if necessary
- */
-void x86_cpudef_setup(void)
-{
- int i, j;
- static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
-
- for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
- x86_def_t *def = &builtin_x86_defs[i];
- def->next = x86_defs;
-
- /* Look for specific "cpudef" models that */
- /* have the QEMU version in .model_id */
- for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
- if (strcmp(model_with_versions[j], def->name) == 0) {
- pstrcpy(def->model_id, sizeof(def->model_id),
- "QEMU Virtual CPU version ");
- pstrcat(def->model_id, sizeof(def->model_id),
- qemu_get_version());
- break;
- }
- }
-
- x86_defs = def;
- }
-}
-
static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
{
@@ -2169,7 +2476,7 @@ static const TypeInfo x86_cpu_type_info = {
.parent = TYPE_CPU,
.instance_size = sizeof(X86CPU),
.instance_init = x86_cpu_initfn,
- .abstract = false,
+ .abstract = true,
.class_size = sizeof(X86CPUClass),
.class_init = x86_cpu_common_class_init,
};
@@ -2210,6 +2517,31 @@ static void x86_cpu_register_types(void)
#ifdef CONFIG_KVM
type_register_static(&x86_host_cpu_type_info);
#endif
+ type_register_static(&predef_x86_cpu_type_info);
+ type_register_static(&x86_cpu_qemu64_type_info);
+ type_register_static(&x86_cpu_phenom_type_info);
+ type_register_static(&x86_cpu_core2duo_type_info);
+ type_register_static(&x86_cpu_kvm64_type_info);
+ type_register_static(&x86_cpu_qemu32_type_info);
+ type_register_static(&x86_cpu_kvm32_type_info);
+ type_register_static(&x86_cpu_coreduo_type_info);
+ type_register_static(&x86_cpu_486_type_info);
+ type_register_static(&x86_cpu_pentium_type_info);
+ type_register_static(&x86_cpu_pentium2_type_info);
+ type_register_static(&x86_cpu_pentium3_type_info);
+ type_register_static(&x86_cpu_athlon_type_info);
+ type_register_static(&x86_cpu_n270_type_info);
+ type_register_static(&x86_cpu_Conroe_type_info);
+ type_register_static(&x86_cpu_Penryn_type_info);
+ type_register_static(&x86_cpu_Nehalem_type_info);
+ type_register_static(&x86_cpu_Westmere_type_info);
+ type_register_static(&x86_cpu_SandyBridge_type_info);
+ type_register_static(&x86_cpu_Haswell_type_info);
+ type_register_static(&x86_cpu_Opteron_G1_type_info);
+ type_register_static(&x86_cpu_Opteron_G2_type_info);
+ type_register_static(&x86_cpu_Opteron_G3_type_info);
+ type_register_static(&x86_cpu_Opteron_G4_type_info);
+ type_register_static(&x86_cpu_Opteron_G5_type_info);
}
type_init(x86_cpu_register_types)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 2b45c09..6c41500 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -864,7 +864,6 @@ typedef struct CPUX86State {
X86CPU *cpu_x86_init(const char *cpu_model);
int cpu_x86_exec(CPUX86State *s);
void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf);
-void x86_cpudef_setup(void);
int cpu_x86_support_mca_broadcast(CPUX86State *env);
int cpu_get_pic_interrupt(CPUX86State *s);
@@ -1046,7 +1045,6 @@ static inline CPUX86State *cpu_init(const char *cpu_model)
#define cpu_gen_code cpu_x86_gen_code
#define cpu_signal_handler cpu_x86_signal_handler
#define cpu_list x86_cpu_list
-#define cpudef_setup x86_cpudef_setup
#define CPU_SAVE_VERSION 12
--
1.7.11.7
next prev parent reply other threads:[~2012-12-28 20:32 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-28 20:33 [Qemu-devel] [PATCH 0/9] x86 CPU subclasses Eduardo Habkost
2012-12-28 20:33 ` [Qemu-devel] [PATCH 1/9] target-i386: Move CPU object creation to cpu.c Eduardo Habkost
2012-12-28 20:33 ` [Qemu-devel] [PATCH 2/9] target-i386: Make cpu_x86_create() get Error argument Eduardo Habkost
2012-12-28 20:34 ` [Qemu-devel] [PATCH 3/9] target-i386: Simplify cpu_x86_find_by_name() logic Eduardo Habkost
2012-12-28 20:34 ` [Qemu-devel] [RFC 4/9] target-i386: Set feature string parsing results directly on CPU object Eduardo Habkost
2012-12-28 20:34 ` [Qemu-devel] [RFC 5/9] target-i386: Move kvm_features/hypervisor initialization to cpu_x86_find_by_name() Eduardo Habkost
2012-12-28 20:34 ` [Qemu-devel] [RFC 6/9] target-i386: Move CPU creation code to model name lookup function Eduardo Habkost
2012-12-28 20:34 ` [Qemu-devel] [RFC 7/9] target-i386: CPU subclass for -cpu "host" Eduardo Habkost
2013-01-02 19:00 ` Igor Mammedov
2013-01-02 20:07 ` Igor Mammedov
2013-01-02 20:20 ` Eduardo Habkost
2013-01-02 20:16 ` Eduardo Habkost
2012-12-28 20:34 ` Eduardo Habkost [this message]
2012-12-28 20:34 ` [Qemu-devel] [RFC 9/9] target-i386: Unify CPU object creation on x86_cpu_create_from_name() Eduardo Habkost
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1356726846-10637-9-git-send-email-ehabkost@redhat.com \
--to=ehabkost@redhat.com \
--cc=afaerber@suse.de \
--cc=imammedo@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.