[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC qom-cpu v2 1/2] target-i386: Convert CPU definitions i
From: |
Andreas Färber |
Subject: |
[Qemu-devel] [RFC qom-cpu v2 1/2] target-i386: Convert CPU definitions into X86CPU subclasses |
Date: |
Mon, 10 Dec 2012 23:59:31 +0100 |
TODO: sort classes for -cpu ?, generalize X86CPUListState, more testing
Signed-off-by: Andreas Färber <address@hidden>
Cc: Eduardo Habkost <address@hidden>
Cc: Igor Mammedov <address@hidden>
---
target-i386/cpu-qom.h | 17 +
target-i386/cpu.c | 1481 +++++++++++++++++++++++++++++--------------------
target-i386/helper.c | 24 -
3 Dateien geändert, 911 Zeilen hinzugefügt(+), 611 Zeilen entfernt(-)
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 5901140..19f5aa7 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -49,6 +49,23 @@ typedef struct X86CPUClass {
/*< public >*/
void (*parent_reset)(CPUState *cpu);
+
+ uint32_t level;
+ uint32_t vendor1, vendor2, vendor3;
+ int family;
+ int model;
+ int stepping;
+ int tsc_khz;
+ uint32_t features, ext_features, ext2_features, ext3_features;
+ uint32_t kvm_features, svm_features;
+ uint32_t xlevel;
+ char model_id[48];
+ int vendor_override;
+ /* Store the results of Centaur's CPUID instructions */
+ uint32_t ext4_features;
+ uint32_t xlevel2;
+ /* The feature bits on CPUID[EAX=7,ECX=0].EBX */
+ uint32_t cpuid_7_0_ebx_features;
} X86CPUClass;
/**
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 6465040..c59c6a5 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -271,26 +271,6 @@ static void add_flagname_to_bitmaps(const char *flagname,
uint32_t *features,
fprintf(stderr, "CPU feature %s not found\n", flagname);
}
-typedef struct x86_def_t {
- const char *name;
- uint32_t level;
- uint32_t vendor1, vendor2, vendor3;
- int family;
- int model;
- int stepping;
- int tsc_khz;
- uint32_t features, ext_features, ext2_features, ext3_features;
- uint32_t kvm_features, svm_features;
- uint32_t xlevel;
- char model_id[48];
- int vendor_override;
- /* Store the results of Centaur's CPUID instructions */
- uint32_t ext4_features;
- uint32_t xlevel2;
- /* The feature bits on CPUID[EAX=7,ECX=0].EBX */
- uint32_t cpuid_7_0_ebx_features;
-} x86_def_t;
-
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
@@ -331,488 +311,735 @@ typedef struct x86_def_t {
/* built-in cpu model definitions
*/
-static x86_def_t builtin_x86_defs[] = {
- {
- .name = "qemu64",
- .level = 4,
- .vendor1 = CPUID_VENDOR_AMD_1,
- .vendor2 = CPUID_VENDOR_AMD_2,
- .vendor3 = CPUID_VENDOR_AMD_3,
- .family = 6,
- .model = 2,
- .stepping = 3,
- .features = PPRO_FEATURES |
+
+#define TYPE(x) x "-" TYPE_X86_CPU
+
+static void qemu64_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+ xcc->level = 4;
+ xcc->vendor1 = CPUID_VENDOR_AMD_1;
+ xcc->vendor2 = CPUID_VENDOR_AMD_2;
+ xcc->vendor3 = CPUID_VENDOR_AMD_3;
+ xcc->family = 6;
+ xcc->model = 2;
+ xcc->stepping = 3;
+ xcc->features = PPRO_FEATURES |
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
- CPUID_PSE36,
- .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
- .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
- CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
- .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
- CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
- .xlevel = 0x8000000A,
- },
- {
- .name = "phenom",
- .level = 5,
- .vendor1 = CPUID_VENDOR_AMD_1,
- .vendor2 = CPUID_VENDOR_AMD_2,
- .vendor3 = CPUID_VENDOR_AMD_3,
- .family = 16,
- .model = 2,
- .stepping = 3,
- .features = PPRO_FEATURES |
+ CPUID_PSE36;
+ xcc->ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT;
+ xcc->ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
+ CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
+ xcc->ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
+ CPUID_EXT3_ABM | CPUID_EXT3_SSE4A;
+ xcc->xlevel = 0x8000000A;
+
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "QEMU Virtual CPU version ");
+ pstrcat(xcc->model_id, sizeof(xcc->model_id),
+ qemu_get_version());
+}
+
+static const TypeInfo qemu64_cpu_type_info = {
+ .name = TYPE("qemu64"),
+ .parent = TYPE_X86_CPU,
+ .class_init = qemu64_cpu_class_init,
+};
+
+static void phenom_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 5;
+ xcc->vendor1 = CPUID_VENDOR_AMD_1;
+ xcc->vendor2 = CPUID_VENDOR_AMD_2;
+ xcc->vendor3 = CPUID_VENDOR_AMD_3;
+ xcc->family = 16;
+ xcc->model = 2;
+ xcc->stepping = 3;
+ xcc->features = PPRO_FEATURES |
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
- CPUID_PSE36 | CPUID_VME | CPUID_HT,
- .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
- CPUID_EXT_POPCNT,
- .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
+ CPUID_PSE36 | CPUID_VME | CPUID_HT;
+ xcc->ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
+ CPUID_EXT_POPCNT;
+ xcc->ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
- CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
+ CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP;
/* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
CPUID_EXT3_CR8LEG,
CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
- .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
- CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
- .svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV,
- .xlevel = 0x8000001A,
- .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
- },
- {
- .name = "core2duo",
- .level = 10,
- .family = 6,
- .model = 15,
- .stepping = 11,
- .features = PPRO_FEATURES |
+ xcc->ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
+ CPUID_EXT3_ABM | CPUID_EXT3_SSE4A;
+ xcc->svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV;
+ xcc->xlevel = 0x8000001A;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "AMD Phenom(tm) 9550 Quad-Core Processor");
+}
+
+static const TypeInfo phenom_cpu_type_info = {
+ .name = TYPE("phenom"),
+ .parent = TYPE_X86_CPU,
+ .class_init = phenom_cpu_class_init,
+};
+
+static void core2duo_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 10;
+ xcc->family = 6;
+ xcc->model = 15;
+ xcc->stepping = 11;
+ xcc->features = PPRO_FEATURES |
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
- CPUID_HT | CPUID_TM | CPUID_PBE,
- .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
+ CPUID_HT | CPUID_TM | CPUID_PBE;
+ xcc->ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST
|
- CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
- .ext3_features = CPUID_EXT3_LAHF_LM,
- .xlevel = 0x80000008,
- .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
- },
- {
- .name = "kvm64",
- .level = 5,
- .vendor1 = CPUID_VENDOR_INTEL_1,
- .vendor2 = CPUID_VENDOR_INTEL_2,
- .vendor3 = CPUID_VENDOR_INTEL_3,
- .family = 15,
- .model = 6,
- .stepping = 1,
+ CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM;
+ xcc->ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
+ xcc->ext3_features = CPUID_EXT3_LAHF_LM;
+ xcc->xlevel = 0x80000008;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz");
+}
+
+static const TypeInfo core2duo_cpu_type_info = {
+ .name = TYPE("core2duo"),
+ .parent = TYPE_X86_CPU,
+ .class_init = core2duo_cpu_class_init,
+};
+
+static void kvm64_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 5;
+ xcc->vendor1 = CPUID_VENDOR_INTEL_1;
+ xcc->vendor2 = CPUID_VENDOR_INTEL_2;
+ xcc->vendor3 = CPUID_VENDOR_INTEL_3;
+ xcc->family = 15;
+ xcc->model = 6;
+ xcc->stepping = 1;
/* Missing: CPUID_VME, CPUID_HT */
- .features = PPRO_FEATURES |
+ xcc->features = PPRO_FEATURES |
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
- CPUID_PSE36,
+ CPUID_PSE36;
/* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
- .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
+ xcc->ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16;
/* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
- .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
- CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+ xcc->ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
+ CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
/* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
- .ext3_features = 0,
- .xlevel = 0x80000008,
- .model_id = "Common KVM processor"
- },
- {
- .name = "qemu32",
- .level = 4,
- .family = 6,
- .model = 3,
- .stepping = 3,
- .features = PPRO_FEATURES,
- .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
- .xlevel = 0x80000004,
- },
- {
- .name = "kvm32",
- .level = 5,
- .family = 15,
- .model = 6,
- .stepping = 1,
- .features = PPRO_FEATURES |
- CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
- .ext_features = CPUID_EXT_SSE3,
- .ext2_features = PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES,
- .ext3_features = 0,
- .xlevel = 0x80000008,
- .model_id = "Common 32-bit KVM processor"
- },
- {
- .name = "coreduo",
- .level = 10,
- .family = 6,
- .model = 14,
- .stepping = 8,
- .features = PPRO_FEATURES | CPUID_VME |
+ xcc->ext3_features = 0;
+ xcc->xlevel = 0x80000008;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "Common KVM processor");
+}
+
+static const TypeInfo kvm64_cpu_type_info = {
+ .name = TYPE("kvm64"),
+ .parent = TYPE_X86_CPU,
+ .class_init = kvm64_cpu_class_init,
+};
+
+static void qemu32_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 4;
+ xcc->family = 6;
+ xcc->model = 3;
+ xcc->stepping = 3;
+ xcc->features = PPRO_FEATURES;
+ xcc->ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT;
+ xcc->xlevel = 0x80000004;
+
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "QEMU Virtual CPU version ");
+ pstrcat(xcc->model_id, sizeof(xcc->model_id),
+ qemu_get_version());
+}
+
+static const TypeInfo qemu32_cpu_type_info = {
+ .name = TYPE("qemu32"),
+ .parent = TYPE_X86_CPU,
+ .class_init = qemu32_cpu_class_init,
+};
+
+static void kvm32_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 5;
+ xcc->family = 15;
+ xcc->model = 6;
+ xcc->stepping = 1;
+ xcc->features = PPRO_FEATURES |
+ CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36;
+ xcc->ext_features = CPUID_EXT_SSE3;
+ xcc->ext2_features = PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES;
+ xcc->ext3_features = 0;
+ xcc->xlevel = 0x80000008;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "Common 32-bit KVM processor");
+}
+
+static const TypeInfo kvm32_cpu_type_info = {
+ .name = TYPE("kvm32"),
+ .parent = TYPE_X86_CPU,
+ .class_init = kvm32_cpu_class_init,
+};
+
+static void coreduo_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 10;
+ xcc->family = 6;
+ xcc->model = 14;
+ xcc->stepping = 8;
+ xcc->features = PPRO_FEATURES | CPUID_VME |
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
- CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
- .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
- CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
- .ext2_features = CPUID_EXT2_NX,
- .xlevel = 0x80000008,
- .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
- },
- {
- .name = "486",
- .level = 1,
- .family = 4,
- .model = 0,
- .stepping = 0,
- .features = I486_FEATURES,
- .xlevel = 0,
- },
- {
- .name = "pentium",
- .level = 1,
- .family = 5,
- .model = 4,
- .stepping = 3,
- .features = PENTIUM_FEATURES,
- .xlevel = 0,
- },
- {
- .name = "pentium2",
- .level = 2,
- .family = 6,
- .model = 5,
- .stepping = 2,
- .features = PENTIUM2_FEATURES,
- .xlevel = 0,
- },
- {
- .name = "pentium3",
- .level = 2,
- .family = 6,
- .model = 7,
- .stepping = 3,
- .features = PENTIUM3_FEATURES,
- .xlevel = 0,
- },
- {
- .name = "athlon",
- .level = 2,
- .vendor1 = CPUID_VENDOR_AMD_1,
- .vendor2 = CPUID_VENDOR_AMD_2,
- .vendor3 = CPUID_VENDOR_AMD_3,
- .family = 6,
- .model = 2,
- .stepping = 3,
- .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
- CPUID_MCA,
- .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
- CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
- .xlevel = 0x80000008,
- },
- {
- .name = "n270",
- /* original is on level 10 */
- .level = 5,
- .family = 6,
- .model = 28,
- .stepping = 2,
- .features = PPRO_FEATURES |
+ CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE;
+ xcc->ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
+ CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM;
+ xcc->ext2_features = CPUID_EXT2_NX;
+ xcc->xlevel = 0x80000008;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "Genuine Intel(R) CPU T2600 @ 2.16GHz");
+}
+
+static const TypeInfo coreduo_cpu_type_info = {
+ .name = TYPE("coreduo"),
+ .parent = TYPE_X86_CPU,
+ .class_init = coreduo_cpu_class_init,
+};
+
+static void i486_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 1;
+ xcc->family = 4;
+ xcc->model = 0;
+ xcc->stepping = 0;
+ xcc->features = I486_FEATURES;
+ xcc->xlevel = 0;
+}
+
+static const TypeInfo i486_cpu_type_info = {
+ .name = TYPE("486"),
+ .parent = TYPE_X86_CPU,
+ .class_init = i486_cpu_class_init,
+};
+
+static void pentium_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 1;
+ xcc->family = 5;
+ xcc->model = 4;
+ xcc->stepping = 3;
+ xcc->features = PENTIUM_FEATURES;
+ xcc->xlevel = 0;
+}
+
+static const TypeInfo pentium_cpu_type_info = {
+ .name = TYPE("pentium"),
+ .parent = TYPE_X86_CPU,
+ .class_init = pentium_cpu_class_init,
+};
+
+static void pentium2_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 2;
+ xcc->family = 6;
+ xcc->model = 5;
+ xcc->stepping = 2;
+ xcc->features = PENTIUM2_FEATURES;
+ xcc->xlevel = 0;
+}
+
+static const TypeInfo pentium2_cpu_type_info = {
+ .name = TYPE("pentium2"),
+ .parent = TYPE_X86_CPU,
+ .class_init = pentium2_cpu_class_init,
+};
+
+static void pentium3_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 2;
+ xcc->family = 6;
+ xcc->model = 7;
+ xcc->stepping = 3;
+ xcc->features = PENTIUM3_FEATURES;
+ xcc->xlevel = 0;
+}
+
+static const TypeInfo pentium3_cpu_type_info = {
+ .name = TYPE("pentium3"),
+ .parent = TYPE_X86_CPU,
+ .class_init = pentium3_cpu_class_init,
+};
+
+static void athlon_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 2;
+ xcc->vendor1 = CPUID_VENDOR_AMD_1;
+ xcc->vendor2 = CPUID_VENDOR_AMD_2;
+ xcc->vendor3 = CPUID_VENDOR_AMD_3;
+ xcc->family = 6;
+ xcc->model = 2;
+ xcc->stepping = 3;
+ xcc->features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
+ CPUID_MCA;
+ xcc->ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
+ CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT;
+ xcc->xlevel = 0x80000008;
+
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "QEMU Virtual CPU version ");
+ pstrcat(xcc->model_id, sizeof(xcc->model_id),
+ qemu_get_version());
+}
+
+static const TypeInfo athlon_cpu_type_info = {
+ .name = TYPE("athlon"),
+ .parent = TYPE_X86_CPU,
+ .class_init = athlon_cpu_class_init,
+};
+
+static void n270_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ /* original is on level 10 */
+ xcc->level = 5;
+ xcc->family = 6;
+ xcc->model = 28;
+ xcc->stepping = 2;
+ xcc->features = PPRO_FEATURES |
CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
- CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
+ CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE;
/* Some CPUs got no CPUID_SEP */
- .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
- CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR,
- .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
- CPUID_EXT2_NX,
- .ext3_features = CPUID_EXT3_LAHF_LM,
- .xlevel = 0x8000000A,
- .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
- },
- {
- .name = "Conroe",
- .level = 2,
- .vendor1 = CPUID_VENDOR_INTEL_1,
- .vendor2 = CPUID_VENDOR_INTEL_2,
- .vendor3 = CPUID_VENDOR_INTEL_3,
- .family = 6,
- .model = 2,
- .stepping = 3,
- .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ xcc->ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
+ CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR;
+ xcc->ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
+ CPUID_EXT2_NX;
+ xcc->ext3_features = CPUID_EXT3_LAHF_LM;
+ xcc->xlevel = 0x8000000A;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "Intel(R) Atom(TM) CPU N270 @ 1.60GHz");
+}
+
+static const TypeInfo n270_cpu_type_info = {
+ .name = TYPE("n270"),
+ .parent = TYPE_X86_CPU,
+ .class_init = n270_cpu_class_init,
+};
+
+static void conroe_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 2;
+ xcc->vendor1 = CPUID_VENDOR_INTEL_1;
+ xcc->vendor2 = CPUID_VENDOR_INTEL_2;
+ xcc->vendor3 = CPUID_VENDOR_INTEL_3;
+ xcc->family = 6;
+ xcc->model = 2;
+ xcc->stepping = 3;
+ xcc->features = 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_FP87,
- .ext_features = CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
- .ext3_features = CPUID_EXT3_LAHF_LM,
- .xlevel = 0x8000000A,
- .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
- },
- {
- .name = "Penryn",
- .level = 2,
- .vendor1 = CPUID_VENDOR_INTEL_1,
- .vendor2 = CPUID_VENDOR_INTEL_2,
- .vendor3 = CPUID_VENDOR_INTEL_3,
- .family = 6,
- .model = 2,
- .stepping = 3,
- .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ CPUID_DE | CPUID_FP87;
+ xcc->ext_features = CPUID_EXT_SSSE3 | CPUID_EXT_SSE3;
+ xcc->ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL;
+ xcc->ext3_features = CPUID_EXT3_LAHF_LM;
+ xcc->xlevel = 0x8000000A;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "Intel Celeron_4x0 (Conroe/Merom Class Core 2)");
+}
+
+static const TypeInfo conroe_cpu_type_info = {
+ .name = TYPE("Conroe"),
+ .parent = TYPE_X86_CPU,
+ .class_init = conroe_cpu_class_init,
+};
+
+static void penryn_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 2;
+ xcc->vendor1 = CPUID_VENDOR_INTEL_1;
+ xcc->vendor2 = CPUID_VENDOR_INTEL_2;
+ xcc->vendor3 = CPUID_VENDOR_INTEL_3;
+ xcc->family = 6;
+ xcc->model = 2;
+ xcc->stepping = 3;
+ xcc->features = 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_FP87,
- .ext_features = CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
- CPUID_EXT_SSE3,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
- .ext3_features = CPUID_EXT3_LAHF_LM,
- .xlevel = 0x8000000A,
- .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
- },
- {
- .name = "Nehalem",
- .level = 2,
- .vendor1 = CPUID_VENDOR_INTEL_1,
- .vendor2 = CPUID_VENDOR_INTEL_2,
- .vendor3 = CPUID_VENDOR_INTEL_3,
- .family = 6,
- .model = 2,
- .stepping = 3,
- .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ CPUID_DE | CPUID_FP87;
+ xcc->ext_features = CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
+ CPUID_EXT_SSE3;
+ xcc->ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL;
+ xcc->ext3_features = CPUID_EXT3_LAHF_LM;
+ xcc->xlevel = 0x8000000A;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "Intel Core 2 Duo P9xxx (Penryn Class Core 2)");
+}
+
+static const TypeInfo penryn_cpu_type_info = {
+ .name = TYPE("Penryn"),
+ .parent = TYPE_X86_CPU,
+ .class_init = penryn_cpu_class_init,
+};
+
+static void nehalem_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 2;
+ xcc->vendor1 = CPUID_VENDOR_INTEL_1;
+ xcc->vendor2 = CPUID_VENDOR_INTEL_2;
+ xcc->vendor3 = CPUID_VENDOR_INTEL_3;
+ xcc->family = 6;
+ xcc->model = 2;
+ xcc->stepping = 3;
+ xcc->features = 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_FP87,
- .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
- CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
- .ext3_features = CPUID_EXT3_LAHF_LM,
- .xlevel = 0x8000000A,
- .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
- },
- {
- .name = "Westmere",
- .level = 11,
- .vendor1 = CPUID_VENDOR_INTEL_1,
- .vendor2 = CPUID_VENDOR_INTEL_2,
- .vendor3 = CPUID_VENDOR_INTEL_3,
- .family = 6,
- .model = 44,
- .stepping = 1,
- .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ CPUID_DE | CPUID_FP87;
+ xcc->ext_features = CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
+ CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3;
+ xcc->ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
+ xcc->ext3_features = CPUID_EXT3_LAHF_LM;
+ xcc->xlevel = 0x8000000A;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "Intel Core i7 9xx (Nehalem Class Core i7)");
+}
+
+static const TypeInfo nehalem_cpu_type_info = {
+ .name = TYPE("Nehalem"),
+ .parent = TYPE_X86_CPU,
+ .class_init = nehalem_cpu_class_init,
+};
+
+static void westmere_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 11;
+ xcc->vendor1 = CPUID_VENDOR_INTEL_1;
+ xcc->vendor2 = CPUID_VENDOR_INTEL_2;
+ xcc->vendor3 = CPUID_VENDOR_INTEL_3;
+ xcc->family = 6;
+ xcc->model = 44;
+ xcc->stepping = 1;
+ xcc->features = 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_FP87,
- .ext_features = CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
+ CPUID_DE | CPUID_FP87;
+ xcc->ext_features = CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
- CPUID_EXT_SSE3,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
- .ext3_features = CPUID_EXT3_LAHF_LM,
- .xlevel = 0x8000000A,
- .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
- },
- {
- .name = "SandyBridge",
- .level = 0xd,
- .vendor1 = CPUID_VENDOR_INTEL_1,
- .vendor2 = CPUID_VENDOR_INTEL_2,
- .vendor3 = CPUID_VENDOR_INTEL_3,
- .family = 6,
- .model = 42,
- .stepping = 1,
- .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ CPUID_EXT_SSE3;
+ xcc->ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX;
+ xcc->ext3_features = CPUID_EXT3_LAHF_LM;
+ xcc->xlevel = 0x8000000A;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "Westmere E56xx/L56xx/X56xx (Nehalem-C)");
+}
+
+static const TypeInfo westmere_cpu_type_info = {
+ .name = TYPE("Westmere"),
+ .parent = TYPE_X86_CPU,
+ .class_init = westmere_cpu_class_init,
+};
+
+static void sandybridge_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 0xd;
+ xcc->vendor1 = CPUID_VENDOR_INTEL_1;
+ xcc->vendor2 = CPUID_VENDOR_INTEL_2;
+ xcc->vendor3 = CPUID_VENDOR_INTEL_3;
+ xcc->family = 6;
+ xcc->model = 42;
+ xcc->stepping = 1;
+ xcc->features = 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_FP87,
- .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
+ CPUID_DE | CPUID_FP87;
+ xcc->ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
- CPUID_EXT_SSE3,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
- CPUID_EXT2_SYSCALL,
- .ext3_features = CPUID_EXT3_LAHF_LM,
- .xlevel = 0x8000000A,
- .model_id = "Intel Xeon E312xx (Sandy Bridge)",
- },
- {
- .name = "Haswell",
- .level = 0xd,
- .vendor1 = CPUID_VENDOR_INTEL_1,
- .vendor2 = CPUID_VENDOR_INTEL_2,
- .vendor3 = CPUID_VENDOR_INTEL_3,
- .family = 6,
- .model = 60,
- .stepping = 1,
- .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ CPUID_EXT_SSE3;
+ xcc->ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
+ CPUID_EXT2_SYSCALL;
+ xcc->ext3_features = CPUID_EXT3_LAHF_LM;
+ xcc->xlevel = 0x8000000A;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "Intel Xeon E312xx (Sandy Bridge)");
+}
+
+static const TypeInfo sandybridge_cpu_type_info = {
+ .name = TYPE("SandyBridge"),
+ .parent = TYPE_X86_CPU,
+ .class_init = sandybridge_cpu_class_init,
+};
+
+static void haswell_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 0xd;
+ xcc->vendor1 = CPUID_VENDOR_INTEL_1;
+ xcc->vendor2 = CPUID_VENDOR_INTEL_2;
+ xcc->vendor3 = CPUID_VENDOR_INTEL_3;
+ xcc->family = 6;
+ xcc->model = 60;
+ xcc->stepping = 1;
+ xcc->features = 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_FP87,
- .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
+ CPUID_DE | CPUID_FP87;
+ xcc->ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
- CPUID_EXT_PCID,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
- CPUID_EXT2_SYSCALL,
- .ext3_features = CPUID_EXT3_LAHF_LM,
- .cpuid_7_0_ebx_features = CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
+ CPUID_EXT_PCID;
+ xcc->ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
+ CPUID_EXT2_SYSCALL;
+ xcc->ext3_features = CPUID_EXT3_LAHF_LM;
+ xcc->cpuid_7_0_ebx_features = CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
- CPUID_7_0_EBX_RTM,
- .xlevel = 0x8000000A,
- .model_id = "Intel Core Processor (Haswell)",
- },
- {
- .name = "Opteron_G1",
- .level = 5,
- .vendor1 = CPUID_VENDOR_AMD_1,
- .vendor2 = CPUID_VENDOR_AMD_2,
- .vendor3 = CPUID_VENDOR_AMD_3,
- .family = 15,
- .model = 6,
- .stepping = 1,
- .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ CPUID_7_0_EBX_RTM;
+ xcc->xlevel = 0x8000000A;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "Intel Core Processor (Haswell)");
+}
+
+static const TypeInfo haswell_cpu_type_info = {
+ .name = TYPE("Haswell"),
+ .parent = TYPE_X86_CPU,
+ .class_init = haswell_cpu_class_init,
+};
+
+static void opteron_g1_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 5;
+ xcc->vendor1 = CPUID_VENDOR_AMD_1;
+ xcc->vendor2 = CPUID_VENDOR_AMD_2;
+ xcc->vendor3 = CPUID_VENDOR_AMD_3;
+ xcc->family = 15;
+ xcc->model = 6;
+ xcc->stepping = 1;
+ xcc->features = 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_FP87,
- .ext_features = CPUID_EXT_SSE3,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
+ CPUID_DE | CPUID_FP87;
+ xcc->ext_features = CPUID_EXT_SSE3;
+ xcc->ext2_features = CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR
|
- 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",
- .level = 5,
- .vendor1 = CPUID_VENDOR_AMD_1,
- .vendor2 = CPUID_VENDOR_AMD_2,
- .vendor3 = CPUID_VENDOR_AMD_3,
- .family = 15,
- .model = 6,
- .stepping = 1,
- .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU;
+ xcc->xlevel = 0x80000008;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "AMD Opteron 240 (Gen 1 Class Opteron)");
+}
+
+static const TypeInfo opteron_g1_cpu_type_info = {
+ .name = TYPE("Opteron_G1"),
+ .parent = TYPE_X86_CPU,
+ .class_init = opteron_g1_cpu_class_init,
+};
+
+static void opteron_g2_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 5;
+ xcc->vendor1 = CPUID_VENDOR_AMD_1;
+ xcc->vendor2 = CPUID_VENDOR_AMD_2;
+ xcc->vendor3 = CPUID_VENDOR_AMD_3;
+ xcc->family = 15;
+ xcc->model = 6;
+ xcc->stepping = 1;
+ xcc->features = 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_FP87,
- .ext_features = CPUID_EXT_CX16 | CPUID_EXT_SSE3,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
+ CPUID_DE | CPUID_FP87;
+ xcc->ext_features = CPUID_EXT_CX16 | CPUID_EXT_SSE3;
+ xcc->ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE
|
- CPUID_EXT2_DE | CPUID_EXT2_FPU,
- .ext3_features = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
- .xlevel = 0x80000008,
- .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
- },
- {
- .name = "Opteron_G3",
- .level = 5,
- .vendor1 = CPUID_VENDOR_AMD_1,
- .vendor2 = CPUID_VENDOR_AMD_2,
- .vendor3 = CPUID_VENDOR_AMD_3,
- .family = 15,
- .model = 6,
- .stepping = 1,
- .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ CPUID_EXT2_DE | CPUID_EXT2_FPU;
+ xcc->ext3_features = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM;
+ xcc->xlevel = 0x80000008;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "AMD Opteron 22xx (Gen 2 Class Opteron)");
+}
+
+static const TypeInfo opteron_g2_cpu_type_info = {
+ .name = TYPE("Opteron_G2"),
+ .parent = TYPE_X86_CPU,
+ .class_init = opteron_g2_cpu_class_init,
+};
+
+static void opteron_g3_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 5;
+ xcc->vendor1 = CPUID_VENDOR_AMD_1;
+ xcc->vendor2 = CPUID_VENDOR_AMD_2;
+ xcc->vendor3 = CPUID_VENDOR_AMD_3;
+ xcc->family = 15;
+ xcc->model = 6;
+ xcc->stepping = 1;
+ xcc->features = 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_FP87,
- .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
- CPUID_EXT_SSE3,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
+ CPUID_DE | CPUID_FP87;
+ xcc->ext_features = CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
+ CPUID_EXT_SSE3;
+ xcc->ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE
|
- CPUID_EXT2_DE | CPUID_EXT2_FPU,
- .ext3_features = CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
- CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
- .xlevel = 0x80000008,
- .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
- },
- {
- .name = "Opteron_G4",
- .level = 0xd,
- .vendor1 = CPUID_VENDOR_AMD_1,
- .vendor2 = CPUID_VENDOR_AMD_2,
- .vendor3 = CPUID_VENDOR_AMD_3,
- .family = 21,
- .model = 1,
- .stepping = 2,
- .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ CPUID_EXT2_DE | CPUID_EXT2_FPU;
+ xcc->ext3_features = CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
+ CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM;
+ xcc->xlevel = 0x80000008;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "AMD Opteron 23xx (Gen 3 Class Opteron)");
+}
+
+static const TypeInfo opteron_g3_cpu_type_info = {
+ .name = TYPE("Opteron_G3"),
+ .parent = TYPE_X86_CPU,
+ .class_init = opteron_g3_cpu_class_init,
+};
+
+static void opteron_g4_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 0xd;
+ xcc->vendor1 = CPUID_VENDOR_AMD_1;
+ xcc->vendor2 = CPUID_VENDOR_AMD_2;
+ xcc->vendor3 = CPUID_VENDOR_AMD_3;
+ xcc->family = 21;
+ xcc->model = 1;
+ xcc->stepping = 2;
+ xcc->features = 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_FP87,
- .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
+ CPUID_DE | CPUID_FP87;
+ xcc->ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
- CPUID_EXT_SSE3,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
+ CPUID_EXT_SSE3;
+ xcc->ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR
|
- CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
- .ext3_features = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
+ CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU;
+ xcc->ext3_features = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
- CPUID_EXT3_LAHF_LM,
- .xlevel = 0x8000001A,
- .model_id = "AMD Opteron 62xx class CPU",
- },
- {
- .name = "Opteron_G5",
- .level = 0xd,
- .vendor1 = CPUID_VENDOR_AMD_1,
- .vendor2 = CPUID_VENDOR_AMD_2,
- .vendor3 = CPUID_VENDOR_AMD_3,
- .family = 21,
- .model = 2,
- .stepping = 0,
- .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+ CPUID_EXT3_LAHF_LM;
+ xcc->xlevel = 0x8000001A;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "AMD Opteron 62xx class CPU");
+}
+
+static const TypeInfo opteron_g4_cpu_type_info = {
+ .name = TYPE("Opteron_G4"),
+ .parent = TYPE_X86_CPU,
+ .class_init = opteron_g4_cpu_class_init,
+};
+
+static void opteron_g5_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->level = 0xd;
+ xcc->vendor1 = CPUID_VENDOR_AMD_1;
+ xcc->vendor2 = CPUID_VENDOR_AMD_2;
+ xcc->vendor3 = CPUID_VENDOR_AMD_3;
+ xcc->family = 21;
+ xcc->model = 2;
+ xcc->stepping = 0;
+ xcc->features = 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_FP87,
- .ext_features = CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
+ CPUID_DE | CPUID_FP87;
+ xcc->ext_features = CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
- CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
- .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
+ CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3;
+ xcc->ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR
|
- CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
- .ext3_features = CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
+ CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU;
+ xcc->ext3_features = CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
- CPUID_EXT3_LAHF_LM,
- .xlevel = 0x8000001A,
- .model_id = "AMD Opteron 63xx class CPU",
- },
+ CPUID_EXT3_LAHF_LM;
+ xcc->xlevel = 0x8000001A;
+ pstrcpy(xcc->model_id, sizeof(xcc->model_id),
+ "AMD Opteron 63xx class CPU");
+}
+
+static const TypeInfo opteron_g5_cpu_type_info = {
+ .name = TYPE("Opteron_G5"),
+ .parent = TYPE_X86_CPU,
+ .class_init = opteron_g5_cpu_class_init,
};
#ifdef CONFIG_KVM
@@ -832,61 +1059,60 @@ static int cpu_x86_fill_model_id(char *str)
}
#endif
-/* Fill a x86_def_t struct with information about the host CPU, and
+#ifdef CONFIG_KVM
+
+/* Fill a CPU class with information about the host CPU, and
* the CPU features supported by the host hardware + host kernel
- *
- * This function may be called only if KVM is enabled.
*/
-static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
+static void kvm_host_cpu_class_init(ObjectClass *oc, void *data)
{
-#ifdef CONFIG_KVM
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
KVMState *s = kvm_state;
uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
assert(kvm_enabled());
- x86_cpu_def->name = "host";
host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
- x86_cpu_def->vendor1 = ebx;
- x86_cpu_def->vendor2 = edx;
- x86_cpu_def->vendor3 = ecx;
+ xcc->vendor1 = ebx;
+ xcc->vendor2 = edx;
+ xcc->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;
+ xcc->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
+ xcc->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
+ xcc->stepping = eax & 0x0F;
- x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
- x86_cpu_def->features = kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX);
- x86_cpu_def->ext_features = kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX);
+ xcc->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
+ xcc->features = kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX);
+ xcc->ext_features = kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX);
- if (x86_cpu_def->level >= 7) {
- x86_cpu_def->cpuid_7_0_ebx_features =
+ if (xcc->level >= 7) {
+ xcc->cpuid_7_0_ebx_features =
kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX);
} else {
- x86_cpu_def->cpuid_7_0_ebx_features = 0;
+ xcc->cpuid_7_0_ebx_features = 0;
}
- x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0,
R_EAX);
- x86_cpu_def->ext2_features =
+ xcc->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
+ xcc->ext2_features =
kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX);
- x86_cpu_def->ext3_features =
+ xcc->ext3_features =
kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX);
- cpu_x86_fill_model_id(x86_cpu_def->model_id);
- x86_cpu_def->vendor_override = 0;
+ cpu_x86_fill_model_id(xcc->model_id);
+ xcc->vendor_override = 0;
/* Call Centaur's CPUID instruction. */
- if (x86_cpu_def->vendor1 == CPUID_VENDOR_VIA_1 &&
- x86_cpu_def->vendor2 == CPUID_VENDOR_VIA_2 &&
- x86_cpu_def->vendor3 == CPUID_VENDOR_VIA_3) {
+ if (xcc->vendor1 == CPUID_VENDOR_VIA_1 &&
+ xcc->vendor2 == CPUID_VENDOR_VIA_2 &&
+ xcc->vendor3 == CPUID_VENDOR_VIA_3) {
host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
eax = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
if (eax >= 0xC0000001) {
/* Support VIA max extended level */
- x86_cpu_def->xlevel2 = eax;
+ xcc->xlevel2 = eax;
host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
- x86_cpu_def->ext4_features =
+ xcc->ext4_features =
kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
}
}
@@ -897,10 +1123,17 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
* available on the host hardware. Just set all bits and mask out the
* unsupported ones later.
*/
- x86_cpu_def->svm_features = -1;
-#endif /* CONFIG_KVM */
+ xcc->svm_features = -1;
}
+static const TypeInfo kvm_host_cpu_type_info = {
+ .name = TYPE("host"),
+ .parent = TYPE_X86_CPU,
+ .class_init = kvm_host_cpu_class_init,
+};
+
+#endif /* CONFIG_KVM */
+
static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
{
int i;
@@ -922,24 +1155,24 @@ static int unavailable_host_feature(struct
model_features_t *f, uint32_t mask)
*
* This function may be called only if KVM is enabled.
*/
-static int kvm_check_features_against_host(x86_def_t *guest_def)
+static int kvm_check_features_against_host(X86CPU *guest_cpu)
{
- x86_def_t host_def;
+ CPUX86State *guest_env = &guest_cpu->env;
+ X86CPUClass *host_xcc = X86_CPU_CLASS(object_class_by_name(TYPE("host")));
uint32_t mask;
int rv, i;
struct model_features_t ft[] = {
- {&guest_def->features, &host_def.features,
+ {&guest_env->cpuid_features, &host_xcc->features,
~0, feature_name, 0x00000000},
- {&guest_def->ext_features, &host_def.ext_features,
+ {&guest_env->cpuid_ext_features, &host_xcc->ext_features,
~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},
- {&guest_def->ext2_features, &host_def.ext2_features,
+ {&guest_env->cpuid_ext2_features, &host_xcc->ext2_features,
~PPRO_FEATURES, ext2_feature_name, 0x80000000},
- {&guest_def->ext3_features, &host_def.ext3_features,
+ {&guest_env->cpuid_ext3_features, &host_xcc->ext3_features,
~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};
assert(kvm_enabled());
- kvm_cpu_fill_host(&host_def);
for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i)
for (mask = 1; mask; mask <<= 1)
if (ft[i].check_feat & mask && *ft[i].guest_feat & mask &&
@@ -1203,26 +1436,12 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor
*v, void *opaque,
cpu->env.tsc_khz = value / 1000;
}
-static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *name)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
- x86_def_t *def = &builtin_x86_defs[i];
- if (strcmp(name, def->name) == 0) {
- memcpy(x86_cpu_def, def, sizeof(*def));
- return 0;
- }
- }
-
- return -1;
-}
-
/* Parse "+feature,-feature,feature=foo" CPU feature string
*/
-static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features)
+static int cpu_x86_parse_featurestr(X86CPU *cpu, char *features)
{
- unsigned int i;
+ CPUX86State *env = &cpu->env;
+ Error *error = NULL;
char *featurestr; /* Single 'key=value" string being parsed */
/* Features to be added */
uint32_t plus_features = 0, plus_ext_features = 0;
@@ -1259,27 +1478,39 @@ static int cpu_x86_parse_featurestr(x86_def_t
*x86_cpu_def, char *features)
if (!strcmp(featurestr, "family")) {
char *err;
numvalue = strtoul(val, &err, 0);
- if (!*val || *err || numvalue > 0xff + 0xf) {
+ if (!*val || *err) {
fprintf(stderr, "bad numerical value %s\n", val);
goto error;
}
- x86_cpu_def->family = numvalue;
+ object_property_set_int(OBJECT(cpu), numvalue, "family",
+ &error);
+ if (error != NULL) {
+ goto error;
+ }
} else if (!strcmp(featurestr, "model")) {
char *err;
numvalue = strtoul(val, &err, 0);
- if (!*val || *err || numvalue > 0xff) {
+ if (!*val || *err) {
fprintf(stderr, "bad numerical value %s\n", val);
goto error;
}
- x86_cpu_def->model = numvalue;
+ object_property_set_int(OBJECT(cpu), numvalue, "model",
+ &error);
+ if (error != NULL) {
+ goto error;
+ }
} else if (!strcmp(featurestr, "stepping")) {
char *err;
numvalue = strtoul(val, &err, 0);
- if (!*val || *err || numvalue > 0xf) {
+ if (!*val || *err) {
fprintf(stderr, "bad numerical value %s\n", val);
goto error;
}
- x86_cpu_def->stepping = numvalue ;
+ object_property_set_int(OBJECT(cpu), numvalue, "stepping",
+ &error);
+ if (error != NULL) {
+ goto error;
+ }
} else if (!strcmp(featurestr, "level")) {
char *err;
numvalue = strtoul(val, &err, 0);
@@ -1287,7 +1518,11 @@ static int cpu_x86_parse_featurestr(x86_def_t
*x86_cpu_def, char *features)
fprintf(stderr, "bad numerical value %s\n", val);
goto error;
}
- x86_cpu_def->level = numvalue;
+ object_property_set_int(OBJECT(cpu), numvalue, "level",
+ &error);
+ if (error != NULL) {
+ goto error;
+ }
} else if (!strcmp(featurestr, "xlevel")) {
char *err;
numvalue = strtoul(val, &err, 0);
@@ -1298,35 +1533,36 @@ static int cpu_x86_parse_featurestr(x86_def_t
*x86_cpu_def, char *features)
if (numvalue < 0x80000000) {
numvalue += 0x80000000;
}
- x86_cpu_def->xlevel = numvalue;
- } else if (!strcmp(featurestr, "vendor")) {
- if (strlen(val) != 12) {
- fprintf(stderr, "vendor string must be 12 chars long\n");
+ object_property_set_int(OBJECT(cpu), numvalue, "xlevel",
+ &error);
+ if (error != NULL) {
goto error;
}
- x86_cpu_def->vendor1 = 0;
- x86_cpu_def->vendor2 = 0;
- x86_cpu_def->vendor3 = 0;
- for(i = 0; i < 4; i++) {
- x86_cpu_def->vendor1 |= ((uint8_t)val[i ]) << (8 * i);
- x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
- x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
+ } else if (!strcmp(featurestr, "vendor")) {
+ object_property_set_str(OBJECT(cpu), val, "vendor", &error);
+ if (error != NULL) {
+ goto error;
}
- x86_cpu_def->vendor_override = 1;
} else if (!strcmp(featurestr, "model_id")) {
- pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
- val);
+ object_property_set_str(OBJECT(cpu), val, "model-id", &error);
+ if (error != NULL) {
+ goto error;
+ }
} else if (!strcmp(featurestr, "tsc_freq")) {
int64_t tsc_freq;
char *err;
tsc_freq = strtosz_suffix_unit(val, &err,
STRTOSZ_DEFSUFFIX_B, 1000);
- if (tsc_freq < 0 || *err) {
+ if (*err) {
fprintf(stderr, "bad numerical value %s\n", val);
goto error;
}
- x86_cpu_def->tsc_khz = tsc_freq / 1000;
+ object_property_set_int(OBJECT(cpu), tsc_freq,
+ "tsc-frequency", &error);
+ if (error != NULL) {
+ goto error;
+ }
} else if (!strcmp(featurestr, "hv_spinlocks")) {
char *err;
numvalue = strtoul(val, &err, 0);
@@ -1353,27 +1589,32 @@ static int cpu_x86_parse_featurestr(x86_def_t
*x86_cpu_def, char *features)
}
featurestr = strtok(NULL, ",");
}
- x86_cpu_def->features |= plus_features;
- x86_cpu_def->ext_features |= plus_ext_features;
- x86_cpu_def->ext2_features |= plus_ext2_features;
- x86_cpu_def->ext3_features |= plus_ext3_features;
- x86_cpu_def->kvm_features |= plus_kvm_features;
- x86_cpu_def->svm_features |= plus_svm_features;
- x86_cpu_def->cpuid_7_0_ebx_features |= plus_7_0_ebx_features;
- x86_cpu_def->features &= ~minus_features;
- x86_cpu_def->ext_features &= ~minus_ext_features;
- x86_cpu_def->ext2_features &= ~minus_ext2_features;
- x86_cpu_def->ext3_features &= ~minus_ext3_features;
- x86_cpu_def->kvm_features &= ~minus_kvm_features;
- x86_cpu_def->svm_features &= ~minus_svm_features;
- x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_7_0_ebx_features;
+ env->cpuid_features |= plus_features;
+ env->cpuid_ext_features |= plus_ext_features;
+ env->cpuid_ext2_features |= plus_ext2_features;
+ env->cpuid_ext3_features |= plus_ext3_features;
+ env->cpuid_kvm_features |= plus_kvm_features;
+ env->cpuid_svm_features |= plus_svm_features;
+ env->cpuid_7_0_ebx_features |= plus_7_0_ebx_features;
+ env->cpuid_features &= ~minus_features;
+ env->cpuid_ext_features &= ~minus_ext_features;
+ env->cpuid_ext2_features &= ~minus_ext2_features;
+ env->cpuid_ext3_features &= ~minus_ext3_features;
+ env->cpuid_kvm_features &= ~minus_kvm_features;
+ env->cpuid_svm_features &= ~minus_svm_features;
+ env->cpuid_7_0_ebx_features &= ~minus_7_0_ebx_features;
if (check_cpuid && kvm_enabled()) {
- if (kvm_check_features_against_host(x86_cpu_def) && enforce_cpuid)
+ if (kvm_check_features_against_host(cpu) && enforce_cpuid) {
goto error;
+ }
}
return 0;
error:
+ if (error != NULL) {
+ fprintf(stderr, "%s\n", error_get_pretty(error));
+ error_free(error);
+ }
return -1;
}
@@ -1407,23 +1648,60 @@ static void listflags(char *buf, int bufsize, uint32_t
fbits,
}
}
+static ObjectClass *x86_cpu_class_by_name(const char *cpu_model)
+{
+ ObjectClass *oc;
+ char *typename;
+
+ oc = object_class_by_name(cpu_model);
+ if (oc != NULL && object_class_dynamic_cast(oc, TYPE_X86_CPU) != NULL) {
+ return oc;
+ }
+
+ typename = g_strdup_printf(TYPE("%s"), cpu_model);
+ oc = object_class_by_name(typename);
+ g_free(typename);
+ if (oc != NULL && object_class_dynamic_cast(oc, TYPE_X86_CPU) != NULL) {
+ return oc;
+ }
+
+ return NULL;
+}
+
/* generate CPU information. */
+
+typedef struct X86CPUListState {
+ fprintf_function cpu_fprintf;
+ FILE *file;
+} X86CPUListState;
+
+static void x86_cpu_list_entry(gpointer data, gpointer user_data)
+{
+ ObjectClass *oc = data;
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+ X86CPUListState *s = user_data;
+ char buf[256];
+
+ snprintf(buf, MIN(sizeof(buf), strlen(object_class_get_name(oc))
+ - strlen("-" TYPE_X86_CPU) + 1),
+ "%s", object_class_get_name(oc));
+ (*s->cpu_fprintf)(s->file, "x86 %16s %-48s\n",
+ buf, xcc->model_id);
+}
+
void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
{
- int i;
+ X86CPUListState s = {
+ .file = f,
+ .cpu_fprintf = cpu_fprintf,
+ };
+ GSList *list;
char buf[256];
- /* Force creation of CPU class */
- object_class_by_name(TYPE_X86_CPU);
+ list = object_class_get_list(TYPE_X86_CPU, false);
+ g_slist_foreach(list, x86_cpu_list_entry, &s);
+ g_slist_free(list);
- for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
- x86_def_t *def = &builtin_x86_defs[i];
- snprintf(buf, sizeof(buf), "%s", def->name);
- (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
- }
- if (kvm_enabled()) {
- (*cpu_fprintf)(f, "x86 %16s\n", "[host]");
- }
(*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
listflags(buf, sizeof(buf), (uint32_t)~0, feature_name, 1);
(*cpu_fprintf)(f, " %s\n", buf);
@@ -1435,25 +1713,38 @@ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
(*cpu_fprintf)(f, " %s\n", buf);
}
-CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
-{
- CpuDefinitionInfoList *cpu_list = NULL;
- int i;
+typedef struct X86CPUDefsState {
+ CpuDefinitionInfoList *cpu_list;
+} X86CPUDefsState;
- for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
- CpuDefinitionInfoList *entry;
- CpuDefinitionInfo *info;
+static void x86_cpu_defs_entry(gpointer data, gpointer user_data)
+{
+ ObjectClass *oc = data;
+ X86CPUDefsState *s = user_data;
+ CpuDefinitionInfoList *entry;
+ CpuDefinitionInfo *info;
+
+ info = g_malloc0(sizeof(*info));
+ info->name = g_strdup(object_class_get_name(oc));
+
+ entry = g_malloc0(sizeof(*entry));
+ entry->value = info;
+ entry->next = s->cpu_list;
+ s->cpu_list = entry;
+}
- info = g_malloc0(sizeof(*info));
- info->name = g_strdup(builtin_x86_defs[i].name);
+CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
+{
+ X86CPUDefsState s = {
+ .cpu_list = NULL,
+ };
+ GSList *list;
- entry = g_malloc0(sizeof(*entry));
- entry->value = info;
- entry->next = cpu_list;
- cpu_list = entry;
- }
+ list = object_class_get_list(TYPE_X86_CPU, false);
+ g_slist_foreach(list, x86_cpu_defs_entry, &s);
+ g_slist_free(list);
- return cpu_list;
+ return s.cpu_list;
}
#ifdef CONFIG_KVM
@@ -1482,16 +1773,16 @@ static void filter_features_for_kvm(X86CPU *cpu)
}
#endif
-int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
+X86CPU *cpu_x86_init(const char *cpu_model)
{
- CPUX86State *env = &cpu->env;
- x86_def_t def1, *def = &def1;
+ X86CPU *cpu = NULL;
+ CPUX86State *env;
+ ObjectClass *oc;
+ X86CPUClass *xcc;
Error *error = NULL;
char *name, *features;
gchar **model_pieces;
- memset(def, 0, sizeof(*def));
-
model_pieces = g_strsplit(cpu_model, ",", 2);
if (!model_pieces[0]) {
goto error;
@@ -1499,43 +1790,45 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
name = model_pieces[0];
features = model_pieces[1];
- if (kvm_enabled() && strcmp(name, "host") == 0) {
- kvm_cpu_fill_host(def);
- } else {
- if (cpu_x86_find_by_name(def, name) < 0) {
- goto error;
- }
+ if (!kvm_enabled() && strcmp(name, "host") == 0) {
+ goto error;
}
-
- if (cpu_x86_parse_featurestr(def, features) < 0) {
+ oc = x86_cpu_class_by_name(name);
+ if (oc == NULL) {
goto error;
}
- if (def->vendor1) {
- env->cpuid_vendor1 = def->vendor1;
- env->cpuid_vendor2 = def->vendor2;
- env->cpuid_vendor3 = def->vendor3;
+ cpu = X86_CPU(object_new(object_class_get_name(oc)));
+ env = &cpu->env;
+ env->cpu_model_str = cpu_model;
+ xcc = X86_CPU_GET_CLASS(cpu);
+
+ if (xcc->vendor1) {
+ env->cpuid_vendor1 = xcc->vendor1;
+ env->cpuid_vendor2 = xcc->vendor2;
+ env->cpuid_vendor3 = xcc->vendor3;
} else {
env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
}
- env->cpuid_vendor_override = def->vendor_override;
- object_property_set_int(OBJECT(cpu), def->level, "level", &error);
- object_property_set_int(OBJECT(cpu), def->family, "family", &error);
- object_property_set_int(OBJECT(cpu), def->model, "model", &error);
- object_property_set_int(OBJECT(cpu), def->stepping, "stepping", &error);
- env->cpuid_features = def->features;
- env->cpuid_ext_features = def->ext_features;
- env->cpuid_ext2_features = def->ext2_features;
- env->cpuid_ext3_features = def->ext3_features;
- object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", &error);
- env->cpuid_kvm_features = def->kvm_features;
- env->cpuid_svm_features = def->svm_features;
- env->cpuid_ext4_features = def->ext4_features;
- env->cpuid_7_0_ebx_features = def->cpuid_7_0_ebx_features;
- env->cpuid_xlevel2 = def->xlevel2;
- object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000,
+ env->cpuid_vendor_override = xcc->vendor_override;
+ object_property_set_int(OBJECT(cpu), xcc->level, "level", &error);
+ object_property_set_int(OBJECT(cpu), xcc->family, "family", &error);
+ object_property_set_int(OBJECT(cpu), xcc->model, "model", &error);
+ object_property_set_int(OBJECT(cpu), xcc->stepping, "stepping", &error);
+ env->cpuid_features = xcc->features;
+ env->cpuid_ext_features = xcc->ext_features;
+ env->cpuid_ext2_features = xcc->ext2_features;
+ env->cpuid_ext3_features = xcc->ext3_features;
+ object_property_set_int(OBJECT(cpu), xcc->xlevel, "xlevel", &error);
+ env->cpuid_kvm_features = xcc->kvm_features;
+ env->cpuid_svm_features = xcc->svm_features;
+ env->cpuid_ext4_features = xcc->ext4_features;
+ env->cpuid_7_0_ebx_features = xcc->cpuid_7_0_ebx_features;
+ env->cpuid_xlevel2 = xcc->xlevel2;
+ object_property_set_int(OBJECT(cpu), (int64_t)xcc->tsc_khz * 1000,
"tsc-frequency", &error);
+ object_property_set_str(OBJECT(cpu), xcc->model_id, "model-id", &error);
/* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
* CPUID[1].EDX.
@@ -1544,7 +1837,11 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
env->cpuid_ext2_features &= ~CPUID_EXT2_AMD_ALIASES;
- env->cpuid_ext2_features |= (def->features & CPUID_EXT2_AMD_ALIASES);
+ env->cpuid_ext2_features |= (xcc->features & CPUID_EXT2_AMD_ALIASES);
+ }
+
+ if (cpu_x86_parse_featurestr(cpu, features) < 0) {
+ goto error;
}
if (!kvm_enabled()) {
@@ -1562,7 +1859,13 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
filter_features_for_kvm(cpu);
#endif
}
- object_property_set_str(OBJECT(cpu), def->model_id, "model-id", &error);
+ if (error) {
+ fprintf(stderr, "%s\n", error_get_pretty(error));
+ error_free(error);
+ goto error;
+ }
+
+ x86_cpu_realize(OBJECT(cpu), &error);
if (error) {
fprintf(stderr, "%s\n", error_get_pretty(error));
error_free(error);
@@ -1570,10 +1873,13 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
}
g_strfreev(model_pieces);
- return 0;
+ return cpu;
error:
+ if (cpu != NULL) {
+ object_delete(OBJECT(cpu));
+ }
g_strfreev(model_pieces);
- return -1;
+ return NULL;
}
#if !defined(CONFIG_USER_ONLY)
@@ -1585,30 +1891,6 @@ void cpu_clear_apic_feature(CPUX86State *env)
#endif /* !CONFIG_USER_ONLY */
-/* Initialize list of CPU models, filling some non-static fields if necessary
- */
-static 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];
-
- /* 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;
- }
- }
- }
-}
-
static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx)
{
@@ -2140,8 +2422,6 @@ static void x86_cpu_common_class_init(ObjectClass *oc,
void *data)
xcc->parent_reset = cc->reset;
cc->reset = x86_cpu_reset;
-
- x86_cpudef_setup();
}
static const TypeInfo x86_cpu_type_info = {
@@ -2149,7 +2429,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,
};
@@ -2157,6 +2437,33 @@ static const TypeInfo x86_cpu_type_info = {
static void x86_cpu_register_types(void)
{
type_register_static(&x86_cpu_type_info);
+ type_register_static(&qemu64_cpu_type_info);
+ type_register_static(&phenom_cpu_type_info);
+ type_register_static(&core2duo_cpu_type_info);
+ type_register_static(&kvm64_cpu_type_info);
+ type_register_static(&qemu32_cpu_type_info);
+ type_register_static(&kvm32_cpu_type_info);
+ type_register_static(&coreduo_cpu_type_info);
+ type_register_static(&i486_cpu_type_info);
+ type_register_static(&pentium_cpu_type_info);
+ type_register_static(&pentium2_cpu_type_info);
+ type_register_static(&pentium3_cpu_type_info);
+ type_register_static(&athlon_cpu_type_info);
+ type_register_static(&n270_cpu_type_info);
+ type_register_static(&conroe_cpu_type_info);
+ type_register_static(&penryn_cpu_type_info);
+ type_register_static(&nehalem_cpu_type_info);
+ type_register_static(&westmere_cpu_type_info);
+ type_register_static(&sandybridge_cpu_type_info);
+ type_register_static(&haswell_cpu_type_info);
+ type_register_static(&opteron_g1_cpu_type_info);
+ type_register_static(&opteron_g2_cpu_type_info);
+ type_register_static(&opteron_g3_cpu_type_info);
+ type_register_static(&opteron_g4_cpu_type_info);
+ type_register_static(&opteron_g5_cpu_type_info);
+#ifdef CONFIG_KVM
+ type_register_static(&kvm_host_cpu_type_info);
+#endif
}
type_init(x86_cpu_register_types)
diff --git a/target-i386/helper.c b/target-i386/helper.c
index bf206cf..47b53ed 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1240,30 +1240,6 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned
int selector,
return 1;
}
-X86CPU *cpu_x86_init(const char *cpu_model)
-{
- X86CPU *cpu;
- CPUX86State *env;
- Error *error = NULL;
-
- cpu = X86_CPU(object_new(TYPE_X86_CPU));
- env = &cpu->env;
- env->cpu_model_str = cpu_model;
-
- if (cpu_x86_register(cpu, cpu_model) < 0) {
- object_delete(OBJECT(cpu));
- return NULL;
- }
-
- x86_cpu_realize(OBJECT(cpu), &error);
- if (error) {
- error_free(error);
- object_delete(OBJECT(cpu));
- return NULL;
- }
- return cpu;
-}
-
#if !defined(CONFIG_USER_ONLY)
void do_cpu_init(X86CPU *cpu)
{
--
1.7.10.4
[Qemu-devel] [RFC qom-cpu v2 1/2] target-i386: Convert CPU definitions into X86CPU subclasses,
Andreas Färber <=