[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC 8/9] target-i386: CPU subclasses for predefined CPU mo
From: |
Eduardo Habkost |
Subject: |
[Qemu-devel] [RFC 8/9] target-i386: CPU subclasses for predefined CPU models |
Date: |
Fri, 28 Dec 2012 18:34:05 -0200 |
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 <address@hidden>
---
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
- [Qemu-devel] [PATCH 0/9] x86 CPU subclasses, Eduardo Habkost, 2012/12/28
- [Qemu-devel] [PATCH 3/9] target-i386: Simplify cpu_x86_find_by_name() logic, Eduardo Habkost, 2012/12/28
- [Qemu-devel] [PATCH 1/9] target-i386: Move CPU object creation to cpu.c, Eduardo Habkost, 2012/12/28
- [Qemu-devel] [RFC 9/9] target-i386: Unify CPU object creation on x86_cpu_create_from_name(), Eduardo Habkost, 2012/12/28
- [Qemu-devel] [PATCH 2/9] target-i386: Make cpu_x86_create() get Error argument, Eduardo Habkost, 2012/12/28
- [Qemu-devel] [RFC 7/9] target-i386: CPU subclass for -cpu "host", Eduardo Habkost, 2012/12/28
- [Qemu-devel] [RFC 4/9] target-i386: Set feature string parsing results directly on CPU object, Eduardo Habkost, 2012/12/28
- [Qemu-devel] [RFC 6/9] target-i386: Move CPU creation code to model name lookup function, Eduardo Habkost, 2012/12/28
- [Qemu-devel] [RFC 5/9] target-i386: Move kvm_features/hypervisor initialization to cpu_x86_find_by_name(), Eduardo Habkost, 2012/12/28
- [Qemu-devel] [RFC 8/9] target-i386: CPU subclasses for predefined CPU models,
Eduardo Habkost <=