acpi unit-test: compare DSDT and SSDT tables against expected values
[qemu/cris-port.git] / target-i386 / cpu.c
blobe6f7eaf5cd4524fc56b1fc366b815e1943c2a219
1 /*
2 * i386 CPUID helper functions
4 * Copyright (c) 2003 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <inttypes.h>
24 #include "cpu.h"
25 #include "sysemu/kvm.h"
26 #include "sysemu/cpus.h"
27 #include "topology.h"
29 #include "qemu/option.h"
30 #include "qemu/config-file.h"
31 #include "qapi/qmp/qerror.h"
33 #include "qapi-types.h"
34 #include "qapi-visit.h"
35 #include "qapi/visitor.h"
36 #include "sysemu/arch_init.h"
38 #include "hw/hw.h"
39 #if defined(CONFIG_KVM)
40 #include <linux/kvm_para.h>
41 #endif
43 #include "sysemu/sysemu.h"
44 #include "hw/qdev-properties.h"
45 #include "hw/cpu/icc_bus.h"
46 #ifndef CONFIG_USER_ONLY
47 #include "hw/xen/xen.h"
48 #include "hw/i386/apic_internal.h"
49 #endif
52 /* Cache topology CPUID constants: */
54 /* CPUID Leaf 2 Descriptors */
56 #define CPUID_2_L1D_32KB_8WAY_64B 0x2c
57 #define CPUID_2_L1I_32KB_8WAY_64B 0x30
58 #define CPUID_2_L2_2MB_8WAY_64B 0x7d
61 /* CPUID Leaf 4 constants: */
63 /* EAX: */
64 #define CPUID_4_TYPE_DCACHE 1
65 #define CPUID_4_TYPE_ICACHE 2
66 #define CPUID_4_TYPE_UNIFIED 3
68 #define CPUID_4_LEVEL(l) ((l) << 5)
70 #define CPUID_4_SELF_INIT_LEVEL (1 << 8)
71 #define CPUID_4_FULLY_ASSOC (1 << 9)
73 /* EDX: */
74 #define CPUID_4_NO_INVD_SHARING (1 << 0)
75 #define CPUID_4_INCLUSIVE (1 << 1)
76 #define CPUID_4_COMPLEX_IDX (1 << 2)
78 #define ASSOC_FULL 0xFF
80 /* AMD associativity encoding used on CPUID Leaf 0x80000006: */
81 #define AMD_ENC_ASSOC(a) (a <= 1 ? a : \
82 a == 2 ? 0x2 : \
83 a == 4 ? 0x4 : \
84 a == 8 ? 0x6 : \
85 a == 16 ? 0x8 : \
86 a == 32 ? 0xA : \
87 a == 48 ? 0xB : \
88 a == 64 ? 0xC : \
89 a == 96 ? 0xD : \
90 a == 128 ? 0xE : \
91 a == ASSOC_FULL ? 0xF : \
92 0 /* invalid value */)
95 /* Definitions of the hardcoded cache entries we expose: */
97 /* L1 data cache: */
98 #define L1D_LINE_SIZE 64
99 #define L1D_ASSOCIATIVITY 8
100 #define L1D_SETS 64
101 #define L1D_PARTITIONS 1
102 /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
103 #define L1D_DESCRIPTOR CPUID_2_L1D_32KB_8WAY_64B
104 /*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
105 #define L1D_LINES_PER_TAG 1
106 #define L1D_SIZE_KB_AMD 64
107 #define L1D_ASSOCIATIVITY_AMD 2
109 /* L1 instruction cache: */
110 #define L1I_LINE_SIZE 64
111 #define L1I_ASSOCIATIVITY 8
112 #define L1I_SETS 64
113 #define L1I_PARTITIONS 1
114 /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
115 #define L1I_DESCRIPTOR CPUID_2_L1I_32KB_8WAY_64B
116 /*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
117 #define L1I_LINES_PER_TAG 1
118 #define L1I_SIZE_KB_AMD 64
119 #define L1I_ASSOCIATIVITY_AMD 2
121 /* Level 2 unified cache: */
122 #define L2_LINE_SIZE 64
123 #define L2_ASSOCIATIVITY 16
124 #define L2_SETS 4096
125 #define L2_PARTITIONS 1
126 /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 4MiB */
127 /*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
128 #define L2_DESCRIPTOR CPUID_2_L2_2MB_8WAY_64B
129 /*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
130 #define L2_LINES_PER_TAG 1
131 #define L2_SIZE_KB_AMD 512
133 /* No L3 cache: */
134 #define L3_SIZE_KB 0 /* disabled */
135 #define L3_ASSOCIATIVITY 0 /* disabled */
136 #define L3_LINES_PER_TAG 0 /* disabled */
137 #define L3_LINE_SIZE 0 /* disabled */
139 /* TLB definitions: */
141 #define L1_DTLB_2M_ASSOC 1
142 #define L1_DTLB_2M_ENTRIES 255
143 #define L1_DTLB_4K_ASSOC 1
144 #define L1_DTLB_4K_ENTRIES 255
146 #define L1_ITLB_2M_ASSOC 1
147 #define L1_ITLB_2M_ENTRIES 255
148 #define L1_ITLB_4K_ASSOC 1
149 #define L1_ITLB_4K_ENTRIES 255
151 #define L2_DTLB_2M_ASSOC 0 /* disabled */
152 #define L2_DTLB_2M_ENTRIES 0 /* disabled */
153 #define L2_DTLB_4K_ASSOC 4
154 #define L2_DTLB_4K_ENTRIES 512
156 #define L2_ITLB_2M_ASSOC 0 /* disabled */
157 #define L2_ITLB_2M_ENTRIES 0 /* disabled */
158 #define L2_ITLB_4K_ASSOC 4
159 #define L2_ITLB_4K_ENTRIES 512
163 static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
164 uint32_t vendor2, uint32_t vendor3)
166 int i;
167 for (i = 0; i < 4; i++) {
168 dst[i] = vendor1 >> (8 * i);
169 dst[i + 4] = vendor2 >> (8 * i);
170 dst[i + 8] = vendor3 >> (8 * i);
172 dst[CPUID_VENDOR_SZ] = '\0';
175 /* feature flags taken from "Intel Processor Identification and the CPUID
176 * Instruction" and AMD's "CPUID Specification". In cases of disagreement
177 * between feature naming conventions, aliases may be added.
179 static const char *feature_name[] = {
180 "fpu", "vme", "de", "pse",
181 "tsc", "msr", "pae", "mce",
182 "cx8", "apic", NULL, "sep",
183 "mtrr", "pge", "mca", "cmov",
184 "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
185 NULL, "ds" /* Intel dts */, "acpi", "mmx",
186 "fxsr", "sse", "sse2", "ss",
187 "ht" /* Intel htt */, "tm", "ia64", "pbe",
189 static const char *ext_feature_name[] = {
190 "pni|sse3" /* Intel,AMD sse3 */, "pclmulqdq|pclmuldq", "dtes64", "monitor",
191 "ds_cpl", "vmx", "smx", "est",
192 "tm2", "ssse3", "cid", NULL,
193 "fma", "cx16", "xtpr", "pdcm",
194 NULL, "pcid", "dca", "sse4.1|sse4_1",
195 "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
196 "tsc-deadline", "aes", "xsave", "osxsave",
197 "avx", "f16c", "rdrand", "hypervisor",
199 /* Feature names that are already defined on feature_name[] but are set on
200 * CPUID[8000_0001].EDX on AMD CPUs don't have their names on
201 * ext2_feature_name[]. They are copied automatically to cpuid_ext2_features
202 * if and only if CPU vendor is AMD.
204 static const char *ext2_feature_name[] = {
205 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
206 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
207 NULL /* cx8 */ /* AMD CMPXCHG8B */, NULL /* apic */, NULL, "syscall",
208 NULL /* mtrr */, NULL /* pge */, NULL /* mca */, NULL /* cmov */,
209 NULL /* pat */, NULL /* pse36 */, NULL, NULL /* Linux mp */,
210 "nx|xd", NULL, "mmxext", NULL /* mmx */,
211 NULL /* fxsr */, "fxsr_opt|ffxsr", "pdpe1gb" /* AMD Page1GB */, "rdtscp",
212 NULL, "lm|i64", "3dnowext", "3dnow",
214 static const char *ext3_feature_name[] = {
215 "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
216 "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
217 "3dnowprefetch", "osvw", "ibs", "xop",
218 "skinit", "wdt", NULL, "lwp",
219 "fma4", "tce", NULL, "nodeid_msr",
220 NULL, "tbm", "topoext", "perfctr_core",
221 "perfctr_nb", NULL, NULL, NULL,
222 NULL, NULL, NULL, NULL,
225 static const char *ext4_feature_name[] = {
226 NULL, NULL, "xstore", "xstore-en",
227 NULL, NULL, "xcrypt", "xcrypt-en",
228 "ace2", "ace2-en", "phe", "phe-en",
229 "pmm", "pmm-en", NULL, NULL,
230 NULL, NULL, NULL, NULL,
231 NULL, NULL, NULL, NULL,
232 NULL, NULL, NULL, NULL,
233 NULL, NULL, NULL, NULL,
236 static const char *kvm_feature_name[] = {
237 "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock",
238 "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", "kvm_pv_unhalt",
239 NULL, NULL, NULL, NULL,
240 NULL, NULL, NULL, NULL,
241 NULL, NULL, NULL, NULL,
242 NULL, NULL, NULL, NULL,
243 NULL, NULL, NULL, NULL,
244 NULL, NULL, NULL, NULL,
247 static const char *svm_feature_name[] = {
248 "npt", "lbrv", "svm_lock", "nrip_save",
249 "tsc_scale", "vmcb_clean", "flushbyasid", "decodeassists",
250 NULL, NULL, "pause_filter", NULL,
251 "pfthreshold", NULL, NULL, NULL,
252 NULL, NULL, NULL, NULL,
253 NULL, NULL, NULL, NULL,
254 NULL, NULL, NULL, NULL,
255 NULL, NULL, NULL, NULL,
258 static const char *cpuid_7_0_ebx_feature_name[] = {
259 "fsgsbase", NULL, NULL, "bmi1", "hle", "avx2", NULL, "smep",
260 "bmi2", "erms", "invpcid", "rtm", NULL, NULL, NULL, NULL,
261 NULL, NULL, "rdseed", "adx", "smap", NULL, NULL, NULL,
262 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
265 typedef struct FeatureWordInfo {
266 const char **feat_names;
267 uint32_t cpuid_eax; /* Input EAX for CPUID */
268 bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
269 uint32_t cpuid_ecx; /* Input ECX value for CPUID */
270 int cpuid_reg; /* output register (R_* constant) */
271 } FeatureWordInfo;
273 static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
274 [FEAT_1_EDX] = {
275 .feat_names = feature_name,
276 .cpuid_eax = 1, .cpuid_reg = R_EDX,
278 [FEAT_1_ECX] = {
279 .feat_names = ext_feature_name,
280 .cpuid_eax = 1, .cpuid_reg = R_ECX,
282 [FEAT_8000_0001_EDX] = {
283 .feat_names = ext2_feature_name,
284 .cpuid_eax = 0x80000001, .cpuid_reg = R_EDX,
286 [FEAT_8000_0001_ECX] = {
287 .feat_names = ext3_feature_name,
288 .cpuid_eax = 0x80000001, .cpuid_reg = R_ECX,
290 [FEAT_C000_0001_EDX] = {
291 .feat_names = ext4_feature_name,
292 .cpuid_eax = 0xC0000001, .cpuid_reg = R_EDX,
294 [FEAT_KVM] = {
295 .feat_names = kvm_feature_name,
296 .cpuid_eax = KVM_CPUID_FEATURES, .cpuid_reg = R_EAX,
298 [FEAT_SVM] = {
299 .feat_names = svm_feature_name,
300 .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX,
302 [FEAT_7_0_EBX] = {
303 .feat_names = cpuid_7_0_ebx_feature_name,
304 .cpuid_eax = 7,
305 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
306 .cpuid_reg = R_EBX,
310 typedef struct X86RegisterInfo32 {
311 /* Name of register */
312 const char *name;
313 /* QAPI enum value register */
314 X86CPURegister32 qapi_enum;
315 } X86RegisterInfo32;
317 #define REGISTER(reg) \
318 [R_##reg] = { .name = #reg, .qapi_enum = X86_C_P_U_REGISTER32_##reg }
319 X86RegisterInfo32 x86_reg_info_32[CPU_NB_REGS32] = {
320 REGISTER(EAX),
321 REGISTER(ECX),
322 REGISTER(EDX),
323 REGISTER(EBX),
324 REGISTER(ESP),
325 REGISTER(EBP),
326 REGISTER(ESI),
327 REGISTER(EDI),
329 #undef REGISTER
331 typedef struct ExtSaveArea {
332 uint32_t feature, bits;
333 uint32_t offset, size;
334 } ExtSaveArea;
336 static const ExtSaveArea ext_save_areas[] = {
337 [2] = { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
338 .offset = 0x240, .size = 0x100 },
339 [3] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
340 .offset = 0x3c0, .size = 0x40 },
341 [4] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX,
342 .offset = 0x400, .size = 0x10 },
345 const char *get_register_name_32(unsigned int reg)
347 if (reg >= CPU_NB_REGS32) {
348 return NULL;
350 return x86_reg_info_32[reg].name;
353 /* collects per-function cpuid data
355 typedef struct model_features_t {
356 uint32_t *guest_feat;
357 uint32_t *host_feat;
358 FeatureWord feat_word;
359 } model_features_t;
361 static uint32_t kvm_default_features = (1 << KVM_FEATURE_CLOCKSOURCE) |
362 (1 << KVM_FEATURE_NOP_IO_DELAY) |
363 (1 << KVM_FEATURE_CLOCKSOURCE2) |
364 (1 << KVM_FEATURE_ASYNC_PF) |
365 (1 << KVM_FEATURE_STEAL_TIME) |
366 (1 << KVM_FEATURE_PV_EOI) |
367 (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
369 void disable_kvm_pv_eoi(void)
371 kvm_default_features &= ~(1UL << KVM_FEATURE_PV_EOI);
374 void host_cpuid(uint32_t function, uint32_t count,
375 uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
377 #if defined(CONFIG_KVM)
378 uint32_t vec[4];
380 #ifdef __x86_64__
381 asm volatile("cpuid"
382 : "=a"(vec[0]), "=b"(vec[1]),
383 "=c"(vec[2]), "=d"(vec[3])
384 : "0"(function), "c"(count) : "cc");
385 #else
386 asm volatile("pusha \n\t"
387 "cpuid \n\t"
388 "mov %%eax, 0(%2) \n\t"
389 "mov %%ebx, 4(%2) \n\t"
390 "mov %%ecx, 8(%2) \n\t"
391 "mov %%edx, 12(%2) \n\t"
392 "popa"
393 : : "a"(function), "c"(count), "S"(vec)
394 : "memory", "cc");
395 #endif
397 if (eax)
398 *eax = vec[0];
399 if (ebx)
400 *ebx = vec[1];
401 if (ecx)
402 *ecx = vec[2];
403 if (edx)
404 *edx = vec[3];
405 #endif
408 #define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
410 /* general substring compare of *[s1..e1) and *[s2..e2). sx is start of
411 * a substring. ex if !NULL points to the first char after a substring,
412 * otherwise the string is assumed to sized by a terminating nul.
413 * Return lexical ordering of *s1:*s2.
415 static int sstrcmp(const char *s1, const char *e1, const char *s2,
416 const char *e2)
418 for (;;) {
419 if (!*s1 || !*s2 || *s1 != *s2)
420 return (*s1 - *s2);
421 ++s1, ++s2;
422 if (s1 == e1 && s2 == e2)
423 return (0);
424 else if (s1 == e1)
425 return (*s2);
426 else if (s2 == e2)
427 return (*s1);
431 /* compare *[s..e) to *altstr. *altstr may be a simple string or multiple
432 * '|' delimited (possibly empty) strings in which case search for a match
433 * within the alternatives proceeds left to right. Return 0 for success,
434 * non-zero otherwise.
436 static int altcmp(const char *s, const char *e, const char *altstr)
438 const char *p, *q;
440 for (q = p = altstr; ; ) {
441 while (*p && *p != '|')
442 ++p;
443 if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
444 return (0);
445 if (!*p)
446 return (1);
447 else
448 q = ++p;
452 /* search featureset for flag *[s..e), if found set corresponding bit in
453 * *pval and return true, otherwise return false
455 static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
456 const char **featureset)
458 uint32_t mask;
459 const char **ppc;
460 bool found = false;
462 for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
463 if (*ppc && !altcmp(s, e, *ppc)) {
464 *pval |= mask;
465 found = true;
468 return found;
471 static void add_flagname_to_bitmaps(const char *flagname,
472 FeatureWordArray words)
474 FeatureWord w;
475 for (w = 0; w < FEATURE_WORDS; w++) {
476 FeatureWordInfo *wi = &feature_word_info[w];
477 if (wi->feat_names &&
478 lookup_feature(&words[w], flagname, NULL, wi->feat_names)) {
479 break;
482 if (w == FEATURE_WORDS) {
483 fprintf(stderr, "CPU feature %s not found\n", flagname);
487 typedef struct x86_def_t {
488 const char *name;
489 uint32_t level;
490 uint32_t xlevel;
491 uint32_t xlevel2;
492 /* vendor is zero-terminated, 12 character ASCII string */
493 char vendor[CPUID_VENDOR_SZ + 1];
494 int family;
495 int model;
496 int stepping;
497 FeatureWordArray features;
498 char model_id[48];
499 bool cache_info_passthrough;
500 } x86_def_t;
502 #define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
503 #define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
504 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
505 #define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
506 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
507 CPUID_PSE36 | CPUID_FXSR)
508 #define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
509 #define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
510 CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
511 CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
512 CPUID_PAE | CPUID_SEP | CPUID_APIC)
514 #define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
515 CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
516 CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
517 CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
518 CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
519 /* partly implemented:
520 CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
521 CPUID_PSE36 (needed for Solaris) */
522 /* missing:
523 CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
524 #define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | \
525 CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | \
526 CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_POPCNT | \
527 CPUID_EXT_MOVBE | CPUID_EXT_AES | CPUID_EXT_HYPERVISOR)
528 /* missing:
529 CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_SMX,
530 CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_CID, CPUID_EXT_FMA,
531 CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_PCID, CPUID_EXT_DCA,
532 CPUID_EXT_X2APIC, CPUID_EXT_TSC_DEADLINE_TIMER, CPUID_EXT_XSAVE,
533 CPUID_EXT_OSXSAVE, CPUID_EXT_AVX, CPUID_EXT_F16C,
534 CPUID_EXT_RDRAND */
535 #define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
536 CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
537 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
538 /* missing:
539 CPUID_EXT2_PDPE1GB */
540 #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
541 CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
542 #define TCG_SVM_FEATURES 0
543 #define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP \
544 CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ADX)
545 /* missing:
546 CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
547 CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
548 CPUID_7_0_EBX_RDSEED */
550 /* built-in CPU model definitions
552 static x86_def_t builtin_x86_defs[] = {
554 .name = "qemu64",
555 .level = 4,
556 .vendor = CPUID_VENDOR_AMD,
557 .family = 6,
558 .model = 6,
559 .stepping = 3,
560 .features[FEAT_1_EDX] =
561 PPRO_FEATURES |
562 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
563 CPUID_PSE36,
564 .features[FEAT_1_ECX] =
565 CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
566 .features[FEAT_8000_0001_EDX] =
567 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
568 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
569 .features[FEAT_8000_0001_ECX] =
570 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
571 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
572 .xlevel = 0x8000000A,
575 .name = "phenom",
576 .level = 5,
577 .vendor = CPUID_VENDOR_AMD,
578 .family = 16,
579 .model = 2,
580 .stepping = 3,
581 .features[FEAT_1_EDX] =
582 PPRO_FEATURES |
583 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
584 CPUID_PSE36 | CPUID_VME | CPUID_HT,
585 .features[FEAT_1_ECX] =
586 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
587 CPUID_EXT_POPCNT,
588 .features[FEAT_8000_0001_EDX] =
589 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
590 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
591 CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
592 CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
593 /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
594 CPUID_EXT3_CR8LEG,
595 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
596 CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
597 .features[FEAT_8000_0001_ECX] =
598 CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
599 CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
600 .features[FEAT_SVM] =
601 CPUID_SVM_NPT | CPUID_SVM_LBRV,
602 .xlevel = 0x8000001A,
603 .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
606 .name = "core2duo",
607 .level = 10,
608 .vendor = CPUID_VENDOR_INTEL,
609 .family = 6,
610 .model = 15,
611 .stepping = 11,
612 .features[FEAT_1_EDX] =
613 PPRO_FEATURES |
614 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
615 CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
616 CPUID_HT | CPUID_TM | CPUID_PBE,
617 .features[FEAT_1_ECX] =
618 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
619 CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
620 CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
621 .features[FEAT_8000_0001_EDX] =
622 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
623 .features[FEAT_8000_0001_ECX] =
624 CPUID_EXT3_LAHF_LM,
625 .xlevel = 0x80000008,
626 .model_id = "Intel(R) Core(TM)2 Duo CPU T7700 @ 2.40GHz",
629 .name = "kvm64",
630 .level = 5,
631 .vendor = CPUID_VENDOR_INTEL,
632 .family = 15,
633 .model = 6,
634 .stepping = 1,
635 /* Missing: CPUID_VME, CPUID_HT */
636 .features[FEAT_1_EDX] =
637 PPRO_FEATURES |
638 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
639 CPUID_PSE36,
640 /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
641 .features[FEAT_1_ECX] =
642 CPUID_EXT_SSE3 | CPUID_EXT_CX16,
643 /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
644 .features[FEAT_8000_0001_EDX] =
645 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
646 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
647 /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
648 CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
649 CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
650 CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
651 .features[FEAT_8000_0001_ECX] =
653 .xlevel = 0x80000008,
654 .model_id = "Common KVM processor"
657 .name = "qemu32",
658 .level = 4,
659 .vendor = CPUID_VENDOR_INTEL,
660 .family = 6,
661 .model = 6,
662 .stepping = 3,
663 .features[FEAT_1_EDX] =
664 PPRO_FEATURES,
665 .features[FEAT_1_ECX] =
666 CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
667 .xlevel = 0x80000004,
670 .name = "kvm32",
671 .level = 5,
672 .vendor = CPUID_VENDOR_INTEL,
673 .family = 15,
674 .model = 6,
675 .stepping = 1,
676 .features[FEAT_1_EDX] =
677 PPRO_FEATURES |
678 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
679 .features[FEAT_1_ECX] =
680 CPUID_EXT_SSE3,
681 .features[FEAT_8000_0001_EDX] =
682 PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES,
683 .features[FEAT_8000_0001_ECX] =
685 .xlevel = 0x80000008,
686 .model_id = "Common 32-bit KVM processor"
689 .name = "coreduo",
690 .level = 10,
691 .vendor = CPUID_VENDOR_INTEL,
692 .family = 6,
693 .model = 14,
694 .stepping = 8,
695 .features[FEAT_1_EDX] =
696 PPRO_FEATURES | CPUID_VME |
697 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
698 CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
699 .features[FEAT_1_ECX] =
700 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
701 CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
702 .features[FEAT_8000_0001_EDX] =
703 CPUID_EXT2_NX,
704 .xlevel = 0x80000008,
705 .model_id = "Genuine Intel(R) CPU T2600 @ 2.16GHz",
708 .name = "486",
709 .level = 1,
710 .vendor = CPUID_VENDOR_INTEL,
711 .family = 4,
712 .model = 8,
713 .stepping = 0,
714 .features[FEAT_1_EDX] =
715 I486_FEATURES,
716 .xlevel = 0,
719 .name = "pentium",
720 .level = 1,
721 .vendor = CPUID_VENDOR_INTEL,
722 .family = 5,
723 .model = 4,
724 .stepping = 3,
725 .features[FEAT_1_EDX] =
726 PENTIUM_FEATURES,
727 .xlevel = 0,
730 .name = "pentium2",
731 .level = 2,
732 .vendor = CPUID_VENDOR_INTEL,
733 .family = 6,
734 .model = 5,
735 .stepping = 2,
736 .features[FEAT_1_EDX] =
737 PENTIUM2_FEATURES,
738 .xlevel = 0,
741 .name = "pentium3",
742 .level = 2,
743 .vendor = CPUID_VENDOR_INTEL,
744 .family = 6,
745 .model = 7,
746 .stepping = 3,
747 .features[FEAT_1_EDX] =
748 PENTIUM3_FEATURES,
749 .xlevel = 0,
752 .name = "athlon",
753 .level = 2,
754 .vendor = CPUID_VENDOR_AMD,
755 .family = 6,
756 .model = 2,
757 .stepping = 3,
758 .features[FEAT_1_EDX] =
759 PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
760 CPUID_MCA,
761 .features[FEAT_8000_0001_EDX] =
762 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
763 CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
764 .xlevel = 0x80000008,
767 .name = "n270",
768 /* original is on level 10 */
769 .level = 5,
770 .vendor = CPUID_VENDOR_INTEL,
771 .family = 6,
772 .model = 28,
773 .stepping = 2,
774 .features[FEAT_1_EDX] =
775 PPRO_FEATURES |
776 CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
777 CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
778 /* Some CPUs got no CPUID_SEP */
779 .features[FEAT_1_ECX] =
780 CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
781 CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR |
782 CPUID_EXT_MOVBE,
783 .features[FEAT_8000_0001_EDX] =
784 (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
785 CPUID_EXT2_NX,
786 .features[FEAT_8000_0001_ECX] =
787 CPUID_EXT3_LAHF_LM,
788 .xlevel = 0x8000000A,
789 .model_id = "Intel(R) Atom(TM) CPU N270 @ 1.60GHz",
792 .name = "Conroe",
793 .level = 4,
794 .vendor = CPUID_VENDOR_INTEL,
795 .family = 6,
796 .model = 15,
797 .stepping = 3,
798 .features[FEAT_1_EDX] =
799 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
800 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
801 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
802 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
803 CPUID_DE | CPUID_FP87,
804 .features[FEAT_1_ECX] =
805 CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
806 .features[FEAT_8000_0001_EDX] =
807 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
808 .features[FEAT_8000_0001_ECX] =
809 CPUID_EXT3_LAHF_LM,
810 .xlevel = 0x8000000A,
811 .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
814 .name = "Penryn",
815 .level = 4,
816 .vendor = CPUID_VENDOR_INTEL,
817 .family = 6,
818 .model = 23,
819 .stepping = 3,
820 .features[FEAT_1_EDX] =
821 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
822 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
823 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
824 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
825 CPUID_DE | CPUID_FP87,
826 .features[FEAT_1_ECX] =
827 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
828 CPUID_EXT_SSE3,
829 .features[FEAT_8000_0001_EDX] =
830 CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
831 .features[FEAT_8000_0001_ECX] =
832 CPUID_EXT3_LAHF_LM,
833 .xlevel = 0x8000000A,
834 .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
837 .name = "Nehalem",
838 .level = 4,
839 .vendor = CPUID_VENDOR_INTEL,
840 .family = 6,
841 .model = 26,
842 .stepping = 3,
843 .features[FEAT_1_EDX] =
844 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
845 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
846 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
847 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
848 CPUID_DE | CPUID_FP87,
849 .features[FEAT_1_ECX] =
850 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
851 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
852 .features[FEAT_8000_0001_EDX] =
853 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
854 .features[FEAT_8000_0001_ECX] =
855 CPUID_EXT3_LAHF_LM,
856 .xlevel = 0x8000000A,
857 .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
860 .name = "Westmere",
861 .level = 11,
862 .vendor = CPUID_VENDOR_INTEL,
863 .family = 6,
864 .model = 44,
865 .stepping = 1,
866 .features[FEAT_1_EDX] =
867 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
868 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
869 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
870 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
871 CPUID_DE | CPUID_FP87,
872 .features[FEAT_1_ECX] =
873 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
874 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
875 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
876 .features[FEAT_8000_0001_EDX] =
877 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
878 .features[FEAT_8000_0001_ECX] =
879 CPUID_EXT3_LAHF_LM,
880 .xlevel = 0x8000000A,
881 .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
884 .name = "SandyBridge",
885 .level = 0xd,
886 .vendor = CPUID_VENDOR_INTEL,
887 .family = 6,
888 .model = 42,
889 .stepping = 1,
890 .features[FEAT_1_EDX] =
891 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
892 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
893 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
894 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
895 CPUID_DE | CPUID_FP87,
896 .features[FEAT_1_ECX] =
897 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
898 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
899 CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
900 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
901 CPUID_EXT_SSE3,
902 .features[FEAT_8000_0001_EDX] =
903 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
904 CPUID_EXT2_SYSCALL,
905 .features[FEAT_8000_0001_ECX] =
906 CPUID_EXT3_LAHF_LM,
907 .xlevel = 0x8000000A,
908 .model_id = "Intel Xeon E312xx (Sandy Bridge)",
911 .name = "Haswell",
912 .level = 0xd,
913 .vendor = CPUID_VENDOR_INTEL,
914 .family = 6,
915 .model = 60,
916 .stepping = 1,
917 .features[FEAT_1_EDX] =
918 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
919 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
920 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
921 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
922 CPUID_DE | CPUID_FP87,
923 .features[FEAT_1_ECX] =
924 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
925 CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
926 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
927 CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
928 CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
929 CPUID_EXT_PCID,
930 .features[FEAT_8000_0001_EDX] =
931 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
932 CPUID_EXT2_SYSCALL,
933 .features[FEAT_8000_0001_ECX] =
934 CPUID_EXT3_LAHF_LM,
935 .features[FEAT_7_0_EBX] =
936 CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
937 CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
938 CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
939 CPUID_7_0_EBX_RTM,
940 .xlevel = 0x8000000A,
941 .model_id = "Intel Core Processor (Haswell)",
944 .name = "Opteron_G1",
945 .level = 5,
946 .vendor = CPUID_VENDOR_AMD,
947 .family = 15,
948 .model = 6,
949 .stepping = 1,
950 .features[FEAT_1_EDX] =
951 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
952 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
953 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
954 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
955 CPUID_DE | CPUID_FP87,
956 .features[FEAT_1_ECX] =
957 CPUID_EXT_SSE3,
958 .features[FEAT_8000_0001_EDX] =
959 CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
960 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
961 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
962 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
963 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
964 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
965 .xlevel = 0x80000008,
966 .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
969 .name = "Opteron_G2",
970 .level = 5,
971 .vendor = CPUID_VENDOR_AMD,
972 .family = 15,
973 .model = 6,
974 .stepping = 1,
975 .features[FEAT_1_EDX] =
976 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
977 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
978 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
979 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
980 CPUID_DE | CPUID_FP87,
981 .features[FEAT_1_ECX] =
982 CPUID_EXT_CX16 | CPUID_EXT_SSE3,
983 .features[FEAT_8000_0001_EDX] =
984 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
985 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
986 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
987 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
988 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
989 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
990 CPUID_EXT2_DE | CPUID_EXT2_FPU,
991 .features[FEAT_8000_0001_ECX] =
992 CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
993 .xlevel = 0x80000008,
994 .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
997 .name = "Opteron_G3",
998 .level = 5,
999 .vendor = CPUID_VENDOR_AMD,
1000 .family = 15,
1001 .model = 6,
1002 .stepping = 1,
1003 .features[FEAT_1_EDX] =
1004 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1005 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1006 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1007 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1008 CPUID_DE | CPUID_FP87,
1009 .features[FEAT_1_ECX] =
1010 CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
1011 CPUID_EXT_SSE3,
1012 .features[FEAT_8000_0001_EDX] =
1013 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
1014 CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
1015 CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
1016 CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
1017 CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
1018 CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
1019 CPUID_EXT2_DE | CPUID_EXT2_FPU,
1020 .features[FEAT_8000_0001_ECX] =
1021 CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
1022 CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
1023 .xlevel = 0x80000008,
1024 .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
1027 .name = "Opteron_G4",
1028 .level = 0xd,
1029 .vendor = CPUID_VENDOR_AMD,
1030 .family = 21,
1031 .model = 1,
1032 .stepping = 2,
1033 .features[FEAT_1_EDX] =
1034 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1035 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1036 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1037 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1038 CPUID_DE | CPUID_FP87,
1039 .features[FEAT_1_ECX] =
1040 CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
1041 CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
1042 CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
1043 CPUID_EXT_SSE3,
1044 .features[FEAT_8000_0001_EDX] =
1045 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
1046 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1047 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1048 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1049 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1050 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1051 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
1052 .features[FEAT_8000_0001_ECX] =
1053 CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
1054 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1055 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1056 CPUID_EXT3_LAHF_LM,
1057 .xlevel = 0x8000001A,
1058 .model_id = "AMD Opteron 62xx class CPU",
1061 .name = "Opteron_G5",
1062 .level = 0xd,
1063 .vendor = CPUID_VENDOR_AMD,
1064 .family = 21,
1065 .model = 2,
1066 .stepping = 0,
1067 .features[FEAT_1_EDX] =
1068 CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
1069 CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
1070 CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
1071 CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
1072 CPUID_DE | CPUID_FP87,
1073 .features[FEAT_1_ECX] =
1074 CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
1075 CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
1076 CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
1077 CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
1078 .features[FEAT_8000_0001_EDX] =
1079 CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
1080 CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
1081 CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
1082 CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
1083 CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
1084 CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
1085 CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
1086 .features[FEAT_8000_0001_ECX] =
1087 CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
1088 CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
1089 CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
1090 CPUID_EXT3_LAHF_LM,
1091 .xlevel = 0x8000001A,
1092 .model_id = "AMD Opteron 63xx class CPU",
1097 * x86_cpu_compat_set_features:
1098 * @cpu_model: CPU model name to be changed. If NULL, all CPU models are changed
1099 * @w: Identifies the feature word to be changed.
1100 * @feat_add: Feature bits to be added to feature word
1101 * @feat_remove: Feature bits to be removed from feature word
1103 * Change CPU model feature bits for compatibility.
1105 * This function may be used by machine-type compatibility functions
1106 * to enable or disable feature bits on specific CPU models.
1108 void x86_cpu_compat_set_features(const char *cpu_model, FeatureWord w,
1109 uint32_t feat_add, uint32_t feat_remove)
1111 x86_def_t *def;
1112 int i;
1113 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1114 def = &builtin_x86_defs[i];
1115 if (!cpu_model || !strcmp(cpu_model, def->name)) {
1116 def->features[w] |= feat_add;
1117 def->features[w] &= ~feat_remove;
1122 #ifdef CONFIG_KVM
1123 static int cpu_x86_fill_model_id(char *str)
1125 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1126 int i;
1128 for (i = 0; i < 3; i++) {
1129 host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
1130 memcpy(str + i * 16 + 0, &eax, 4);
1131 memcpy(str + i * 16 + 4, &ebx, 4);
1132 memcpy(str + i * 16 + 8, &ecx, 4);
1133 memcpy(str + i * 16 + 12, &edx, 4);
1135 return 0;
1137 #endif
1139 /* Fill a x86_def_t struct with information about the host CPU, and
1140 * the CPU features supported by the host hardware + host kernel
1142 * This function may be called only if KVM is enabled.
1144 static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
1146 #ifdef CONFIG_KVM
1147 KVMState *s = kvm_state;
1148 uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
1150 assert(kvm_enabled());
1152 x86_cpu_def->name = "host";
1153 x86_cpu_def->cache_info_passthrough = true;
1154 host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
1155 x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
1157 host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
1158 x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
1159 x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
1160 x86_cpu_def->stepping = eax & 0x0F;
1162 x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
1163 x86_cpu_def->features[FEAT_1_EDX] =
1164 kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX);
1165 x86_cpu_def->features[FEAT_1_ECX] =
1166 kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX);
1168 if (x86_cpu_def->level >= 7) {
1169 x86_cpu_def->features[FEAT_7_0_EBX] =
1170 kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX);
1171 } else {
1172 x86_cpu_def->features[FEAT_7_0_EBX] = 0;
1175 x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
1176 x86_cpu_def->features[FEAT_8000_0001_EDX] =
1177 kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX);
1178 x86_cpu_def->features[FEAT_8000_0001_ECX] =
1179 kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX);
1181 cpu_x86_fill_model_id(x86_cpu_def->model_id);
1183 /* Call Centaur's CPUID instruction. */
1184 if (!strcmp(x86_cpu_def->vendor, CPUID_VENDOR_VIA)) {
1185 host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
1186 eax = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
1187 if (eax >= 0xC0000001) {
1188 /* Support VIA max extended level */
1189 x86_cpu_def->xlevel2 = eax;
1190 host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
1191 x86_cpu_def->features[FEAT_C000_0001_EDX] =
1192 kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
1196 /* Other KVM-specific feature fields: */
1197 x86_cpu_def->features[FEAT_SVM] =
1198 kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX);
1199 x86_cpu_def->features[FEAT_KVM] =
1200 kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
1202 #endif /* CONFIG_KVM */
1205 static int unavailable_host_feature(FeatureWordInfo *f, uint32_t mask)
1207 int i;
1209 for (i = 0; i < 32; ++i)
1210 if (1 << i & mask) {
1211 const char *reg = get_register_name_32(f->cpuid_reg);
1212 assert(reg);
1213 fprintf(stderr, "warning: host doesn't support requested feature: "
1214 "CPUID.%02XH:%s%s%s [bit %d]\n",
1215 f->cpuid_eax, reg,
1216 f->feat_names[i] ? "." : "",
1217 f->feat_names[i] ? f->feat_names[i] : "", i);
1218 break;
1220 return 0;
1223 /* Check if all requested cpu flags are making their way to the guest
1225 * Returns 0 if all flags are supported by the host, non-zero otherwise.
1227 * This function may be called only if KVM is enabled.
1229 static int kvm_check_features_against_host(X86CPU *cpu)
1231 CPUX86State *env = &cpu->env;
1232 x86_def_t host_def;
1233 uint32_t mask;
1234 int rv, i;
1235 struct model_features_t ft[] = {
1236 {&env->features[FEAT_1_EDX],
1237 &host_def.features[FEAT_1_EDX],
1238 FEAT_1_EDX },
1239 {&env->features[FEAT_1_ECX],
1240 &host_def.features[FEAT_1_ECX],
1241 FEAT_1_ECX },
1242 {&env->features[FEAT_8000_0001_EDX],
1243 &host_def.features[FEAT_8000_0001_EDX],
1244 FEAT_8000_0001_EDX },
1245 {&env->features[FEAT_8000_0001_ECX],
1246 &host_def.features[FEAT_8000_0001_ECX],
1247 FEAT_8000_0001_ECX },
1248 {&env->features[FEAT_C000_0001_EDX],
1249 &host_def.features[FEAT_C000_0001_EDX],
1250 FEAT_C000_0001_EDX },
1251 {&env->features[FEAT_7_0_EBX],
1252 &host_def.features[FEAT_7_0_EBX],
1253 FEAT_7_0_EBX },
1254 {&env->features[FEAT_SVM],
1255 &host_def.features[FEAT_SVM],
1256 FEAT_SVM },
1257 {&env->features[FEAT_KVM],
1258 &host_def.features[FEAT_KVM],
1259 FEAT_KVM },
1262 assert(kvm_enabled());
1264 kvm_cpu_fill_host(&host_def);
1265 for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i) {
1266 FeatureWord w = ft[i].feat_word;
1267 FeatureWordInfo *wi = &feature_word_info[w];
1268 for (mask = 1; mask; mask <<= 1) {
1269 if (*ft[i].guest_feat & mask &&
1270 !(*ft[i].host_feat & mask)) {
1271 unavailable_host_feature(wi, mask);
1272 rv = 1;
1276 return rv;
1279 static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
1280 const char *name, Error **errp)
1282 X86CPU *cpu = X86_CPU(obj);
1283 CPUX86State *env = &cpu->env;
1284 int64_t value;
1286 value = (env->cpuid_version >> 8) & 0xf;
1287 if (value == 0xf) {
1288 value += (env->cpuid_version >> 20) & 0xff;
1290 visit_type_int(v, &value, name, errp);
1293 static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
1294 const char *name, Error **errp)
1296 X86CPU *cpu = X86_CPU(obj);
1297 CPUX86State *env = &cpu->env;
1298 const int64_t min = 0;
1299 const int64_t max = 0xff + 0xf;
1300 int64_t value;
1302 visit_type_int(v, &value, name, errp);
1303 if (error_is_set(errp)) {
1304 return;
1306 if (value < min || value > max) {
1307 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1308 name ? name : "null", value, min, max);
1309 return;
1312 env->cpuid_version &= ~0xff00f00;
1313 if (value > 0x0f) {
1314 env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
1315 } else {
1316 env->cpuid_version |= value << 8;
1320 static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
1321 const char *name, Error **errp)
1323 X86CPU *cpu = X86_CPU(obj);
1324 CPUX86State *env = &cpu->env;
1325 int64_t value;
1327 value = (env->cpuid_version >> 4) & 0xf;
1328 value |= ((env->cpuid_version >> 16) & 0xf) << 4;
1329 visit_type_int(v, &value, name, errp);
1332 static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
1333 const char *name, Error **errp)
1335 X86CPU *cpu = X86_CPU(obj);
1336 CPUX86State *env = &cpu->env;
1337 const int64_t min = 0;
1338 const int64_t max = 0xff;
1339 int64_t value;
1341 visit_type_int(v, &value, name, errp);
1342 if (error_is_set(errp)) {
1343 return;
1345 if (value < min || value > max) {
1346 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1347 name ? name : "null", value, min, max);
1348 return;
1351 env->cpuid_version &= ~0xf00f0;
1352 env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
1355 static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
1356 void *opaque, const char *name,
1357 Error **errp)
1359 X86CPU *cpu = X86_CPU(obj);
1360 CPUX86State *env = &cpu->env;
1361 int64_t value;
1363 value = env->cpuid_version & 0xf;
1364 visit_type_int(v, &value, name, errp);
1367 static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
1368 void *opaque, const char *name,
1369 Error **errp)
1371 X86CPU *cpu = X86_CPU(obj);
1372 CPUX86State *env = &cpu->env;
1373 const int64_t min = 0;
1374 const int64_t max = 0xf;
1375 int64_t value;
1377 visit_type_int(v, &value, name, errp);
1378 if (error_is_set(errp)) {
1379 return;
1381 if (value < min || value > max) {
1382 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1383 name ? name : "null", value, min, max);
1384 return;
1387 env->cpuid_version &= ~0xf;
1388 env->cpuid_version |= value & 0xf;
1391 static void x86_cpuid_get_level(Object *obj, Visitor *v, void *opaque,
1392 const char *name, Error **errp)
1394 X86CPU *cpu = X86_CPU(obj);
1396 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
1399 static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
1400 const char *name, Error **errp)
1402 X86CPU *cpu = X86_CPU(obj);
1404 visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
1407 static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
1408 const char *name, Error **errp)
1410 X86CPU *cpu = X86_CPU(obj);
1412 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
1415 static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
1416 const char *name, Error **errp)
1418 X86CPU *cpu = X86_CPU(obj);
1420 visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
1423 static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1425 X86CPU *cpu = X86_CPU(obj);
1426 CPUX86State *env = &cpu->env;
1427 char *value;
1429 value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
1430 x86_cpu_vendor_words2str(value, env->cpuid_vendor1, env->cpuid_vendor2,
1431 env->cpuid_vendor3);
1432 return value;
1435 static void x86_cpuid_set_vendor(Object *obj, const char *value,
1436 Error **errp)
1438 X86CPU *cpu = X86_CPU(obj);
1439 CPUX86State *env = &cpu->env;
1440 int i;
1442 if (strlen(value) != CPUID_VENDOR_SZ) {
1443 error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
1444 "vendor", value);
1445 return;
1448 env->cpuid_vendor1 = 0;
1449 env->cpuid_vendor2 = 0;
1450 env->cpuid_vendor3 = 0;
1451 for (i = 0; i < 4; i++) {
1452 env->cpuid_vendor1 |= ((uint8_t)value[i ]) << (8 * i);
1453 env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1454 env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1458 static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1460 X86CPU *cpu = X86_CPU(obj);
1461 CPUX86State *env = &cpu->env;
1462 char *value;
1463 int i;
1465 value = g_malloc(48 + 1);
1466 for (i = 0; i < 48; i++) {
1467 value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1469 value[48] = '\0';
1470 return value;
1473 static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1474 Error **errp)
1476 X86CPU *cpu = X86_CPU(obj);
1477 CPUX86State *env = &cpu->env;
1478 int c, len, i;
1480 if (model_id == NULL) {
1481 model_id = "";
1483 len = strlen(model_id);
1484 memset(env->cpuid_model, 0, 48);
1485 for (i = 0; i < 48; i++) {
1486 if (i >= len) {
1487 c = '\0';
1488 } else {
1489 c = (uint8_t)model_id[i];
1491 env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1495 static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
1496 const char *name, Error **errp)
1498 X86CPU *cpu = X86_CPU(obj);
1499 int64_t value;
1501 value = cpu->env.tsc_khz * 1000;
1502 visit_type_int(v, &value, name, errp);
1505 static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
1506 const char *name, Error **errp)
1508 X86CPU *cpu = X86_CPU(obj);
1509 const int64_t min = 0;
1510 const int64_t max = INT64_MAX;
1511 int64_t value;
1513 visit_type_int(v, &value, name, errp);
1514 if (error_is_set(errp)) {
1515 return;
1517 if (value < min || value > max) {
1518 error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1519 name ? name : "null", value, min, max);
1520 return;
1523 cpu->env.tsc_khz = value / 1000;
1526 static void x86_cpuid_get_apic_id(Object *obj, Visitor *v, void *opaque,
1527 const char *name, Error **errp)
1529 X86CPU *cpu = X86_CPU(obj);
1530 int64_t value = cpu->env.cpuid_apic_id;
1532 visit_type_int(v, &value, name, errp);
1535 static void x86_cpuid_set_apic_id(Object *obj, Visitor *v, void *opaque,
1536 const char *name, Error **errp)
1538 X86CPU *cpu = X86_CPU(obj);
1539 DeviceState *dev = DEVICE(obj);
1540 const int64_t min = 0;
1541 const int64_t max = UINT32_MAX;
1542 Error *error = NULL;
1543 int64_t value;
1545 if (dev->realized) {
1546 error_setg(errp, "Attempt to set property '%s' on '%s' after "
1547 "it was realized", name, object_get_typename(obj));
1548 return;
1551 visit_type_int(v, &value, name, &error);
1552 if (error) {
1553 error_propagate(errp, error);
1554 return;
1556 if (value < min || value > max) {
1557 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1558 " (minimum: %" PRId64 ", maximum: %" PRId64 ")" ,
1559 object_get_typename(obj), name, value, min, max);
1560 return;
1563 if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
1564 error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
1565 return;
1567 cpu->env.cpuid_apic_id = value;
1570 /* Generic getter for "feature-words" and "filtered-features" properties */
1571 static void x86_cpu_get_feature_words(Object *obj, Visitor *v, void *opaque,
1572 const char *name, Error **errp)
1574 uint32_t *array = (uint32_t *)opaque;
1575 FeatureWord w;
1576 Error *err = NULL;
1577 X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
1578 X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
1579 X86CPUFeatureWordInfoList *list = NULL;
1581 for (w = 0; w < FEATURE_WORDS; w++) {
1582 FeatureWordInfo *wi = &feature_word_info[w];
1583 X86CPUFeatureWordInfo *qwi = &word_infos[w];
1584 qwi->cpuid_input_eax = wi->cpuid_eax;
1585 qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
1586 qwi->cpuid_input_ecx = wi->cpuid_ecx;
1587 qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
1588 qwi->features = array[w];
1590 /* List will be in reverse order, but order shouldn't matter */
1591 list_entries[w].next = list;
1592 list_entries[w].value = &word_infos[w];
1593 list = &list_entries[w];
1596 visit_type_X86CPUFeatureWordInfoList(v, &list, "feature-words", &err);
1597 error_propagate(errp, err);
1600 static void x86_get_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
1601 const char *name, Error **errp)
1603 X86CPU *cpu = X86_CPU(obj);
1604 int64_t value = cpu->hyperv_spinlock_attempts;
1606 visit_type_int(v, &value, name, errp);
1609 static void x86_set_hv_spinlocks(Object *obj, Visitor *v, void *opaque,
1610 const char *name, Error **errp)
1612 const int64_t min = 0xFFF;
1613 const int64_t max = UINT_MAX;
1614 X86CPU *cpu = X86_CPU(obj);
1615 Error *err = NULL;
1616 int64_t value;
1618 visit_type_int(v, &value, name, &err);
1619 if (err) {
1620 error_propagate(errp, err);
1621 return;
1624 if (value < min || value > max) {
1625 error_setg(errp, "Property %s.%s doesn't take value %" PRId64
1626 " (minimum: %" PRId64 ", maximum: %" PRId64 ")",
1627 object_get_typename(obj), name ? name : "null",
1628 value, min, max);
1629 return;
1631 cpu->hyperv_spinlock_attempts = value;
1634 static PropertyInfo qdev_prop_spinlocks = {
1635 .name = "int",
1636 .get = x86_get_hv_spinlocks,
1637 .set = x86_set_hv_spinlocks,
1640 static int cpu_x86_find_by_name(X86CPU *cpu, x86_def_t *x86_cpu_def,
1641 const char *name)
1643 x86_def_t *def;
1644 int i;
1646 if (name == NULL) {
1647 return -1;
1649 if (kvm_enabled() && strcmp(name, "host") == 0) {
1650 kvm_cpu_fill_host(x86_cpu_def);
1651 object_property_set_bool(OBJECT(cpu), true, "pmu", &error_abort);
1652 return 0;
1655 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1656 def = &builtin_x86_defs[i];
1657 if (strcmp(name, def->name) == 0) {
1658 memcpy(x86_cpu_def, def, sizeof(*def));
1659 /* sysenter isn't supported in compatibility mode on AMD,
1660 * syscall isn't supported in compatibility mode on Intel.
1661 * Normally we advertise the actual CPU vendor, but you can
1662 * override this using the 'vendor' property if you want to use
1663 * KVM's sysenter/syscall emulation in compatibility mode and
1664 * when doing cross vendor migration
1666 if (kvm_enabled()) {
1667 uint32_t ebx = 0, ecx = 0, edx = 0;
1668 host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
1669 x86_cpu_vendor_words2str(x86_cpu_def->vendor, ebx, edx, ecx);
1671 return 0;
1675 return -1;
1678 /* Convert all '_' in a feature string option name to '-', to make feature
1679 * name conform to QOM property naming rule, which uses '-' instead of '_'.
1681 static inline void feat2prop(char *s)
1683 while ((s = strchr(s, '_'))) {
1684 *s = '-';
1688 /* Parse "+feature,-feature,feature=foo" CPU feature string
1690 static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
1692 char *featurestr; /* Single 'key=value" string being parsed */
1693 /* Features to be added */
1694 FeatureWordArray plus_features = { 0 };
1695 /* Features to be removed */
1696 FeatureWordArray minus_features = { 0 };
1697 uint32_t numvalue;
1698 CPUX86State *env = &cpu->env;
1700 featurestr = features ? strtok(features, ",") : NULL;
1702 while (featurestr) {
1703 char *val;
1704 if (featurestr[0] == '+') {
1705 add_flagname_to_bitmaps(featurestr + 1, plus_features);
1706 } else if (featurestr[0] == '-') {
1707 add_flagname_to_bitmaps(featurestr + 1, minus_features);
1708 } else if ((val = strchr(featurestr, '='))) {
1709 *val = 0; val++;
1710 feat2prop(featurestr);
1711 if (!strcmp(featurestr, "xlevel")) {
1712 char *err;
1713 char num[32];
1715 numvalue = strtoul(val, &err, 0);
1716 if (!*val || *err) {
1717 error_setg(errp, "bad numerical value %s", val);
1718 goto out;
1720 if (numvalue < 0x80000000) {
1721 fprintf(stderr, "xlevel value shall always be >= 0x80000000"
1722 ", fixup will be removed in future versions\n");
1723 numvalue += 0x80000000;
1725 snprintf(num, sizeof(num), "%" PRIu32, numvalue);
1726 object_property_parse(OBJECT(cpu), num, featurestr, errp);
1727 } else if (!strcmp(featurestr, "tsc-freq")) {
1728 int64_t tsc_freq;
1729 char *err;
1730 char num[32];
1732 tsc_freq = strtosz_suffix_unit(val, &err,
1733 STRTOSZ_DEFSUFFIX_B, 1000);
1734 if (tsc_freq < 0 || *err) {
1735 error_setg(errp, "bad numerical value %s", val);
1736 goto out;
1738 snprintf(num, sizeof(num), "%" PRId64, tsc_freq);
1739 object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
1740 } else if (!strcmp(featurestr, "hv-spinlocks")) {
1741 char *err;
1742 const int min = 0xFFF;
1743 char num[32];
1744 numvalue = strtoul(val, &err, 0);
1745 if (!*val || *err) {
1746 error_setg(errp, "bad numerical value %s", val);
1747 goto out;
1749 if (numvalue < min) {
1750 fprintf(stderr, "hv-spinlocks value shall always be >= 0x%x"
1751 ", fixup will be removed in future versions\n",
1752 min);
1753 numvalue = min;
1755 snprintf(num, sizeof(num), "%" PRId32, numvalue);
1756 object_property_parse(OBJECT(cpu), num, featurestr, errp);
1757 } else {
1758 object_property_parse(OBJECT(cpu), val, featurestr, errp);
1760 } else {
1761 feat2prop(featurestr);
1762 object_property_parse(OBJECT(cpu), "on", featurestr, errp);
1764 if (error_is_set(errp)) {
1765 goto out;
1767 featurestr = strtok(NULL, ",");
1769 env->features[FEAT_1_EDX] |= plus_features[FEAT_1_EDX];
1770 env->features[FEAT_1_ECX] |= plus_features[FEAT_1_ECX];
1771 env->features[FEAT_8000_0001_EDX] |= plus_features[FEAT_8000_0001_EDX];
1772 env->features[FEAT_8000_0001_ECX] |= plus_features[FEAT_8000_0001_ECX];
1773 env->features[FEAT_C000_0001_EDX] |= plus_features[FEAT_C000_0001_EDX];
1774 env->features[FEAT_KVM] |= plus_features[FEAT_KVM];
1775 env->features[FEAT_SVM] |= plus_features[FEAT_SVM];
1776 env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX];
1777 env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX];
1778 env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX];
1779 env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX];
1780 env->features[FEAT_8000_0001_ECX] &= ~minus_features[FEAT_8000_0001_ECX];
1781 env->features[FEAT_C000_0001_EDX] &= ~minus_features[FEAT_C000_0001_EDX];
1782 env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM];
1783 env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM];
1784 env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX];
1786 out:
1787 return;
1790 /* generate a composite string into buf of all cpuid names in featureset
1791 * selected by fbits. indicate truncation at bufsize in the event of overflow.
1792 * if flags, suppress names undefined in featureset.
1794 static void listflags(char *buf, int bufsize, uint32_t fbits,
1795 const char **featureset, uint32_t flags)
1797 const char **p = &featureset[31];
1798 char *q, *b, bit;
1799 int nc;
1801 b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1802 *buf = '\0';
1803 for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1804 if (fbits & 1 << bit && (*p || !flags)) {
1805 if (*p)
1806 nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1807 else
1808 nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1809 if (bufsize <= nc) {
1810 if (b) {
1811 memcpy(b, "...", sizeof("..."));
1813 return;
1815 q += nc;
1816 bufsize -= nc;
1820 /* generate CPU information. */
1821 void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
1823 x86_def_t *def;
1824 char buf[256];
1825 int i;
1827 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1828 def = &builtin_x86_defs[i];
1829 snprintf(buf, sizeof(buf), "%s", def->name);
1830 (*cpu_fprintf)(f, "x86 %16s %-48s\n", buf, def->model_id);
1832 #ifdef CONFIG_KVM
1833 (*cpu_fprintf)(f, "x86 %16s %-48s\n", "host",
1834 "KVM processor with all supported host features "
1835 "(only available in KVM mode)");
1836 #endif
1838 (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
1839 for (i = 0; i < ARRAY_SIZE(feature_word_info); i++) {
1840 FeatureWordInfo *fw = &feature_word_info[i];
1842 listflags(buf, sizeof(buf), (uint32_t)~0, fw->feat_names, 1);
1843 (*cpu_fprintf)(f, " %s\n", buf);
1847 CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
1849 CpuDefinitionInfoList *cpu_list = NULL;
1850 x86_def_t *def;
1851 int i;
1853 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); i++) {
1854 CpuDefinitionInfoList *entry;
1855 CpuDefinitionInfo *info;
1857 def = &builtin_x86_defs[i];
1858 info = g_malloc0(sizeof(*info));
1859 info->name = g_strdup(def->name);
1861 entry = g_malloc0(sizeof(*entry));
1862 entry->value = info;
1863 entry->next = cpu_list;
1864 cpu_list = entry;
1867 return cpu_list;
1870 #ifdef CONFIG_KVM
1871 static void filter_features_for_kvm(X86CPU *cpu)
1873 CPUX86State *env = &cpu->env;
1874 KVMState *s = kvm_state;
1875 FeatureWord w;
1877 for (w = 0; w < FEATURE_WORDS; w++) {
1878 FeatureWordInfo *wi = &feature_word_info[w];
1879 uint32_t host_feat = kvm_arch_get_supported_cpuid(s, wi->cpuid_eax,
1880 wi->cpuid_ecx,
1881 wi->cpuid_reg);
1882 uint32_t requested_features = env->features[w];
1883 env->features[w] &= host_feat;
1884 cpu->filtered_features[w] = requested_features & ~env->features[w];
1887 #endif
1889 static void cpu_x86_register(X86CPU *cpu, const char *name, Error **errp)
1891 CPUX86State *env = &cpu->env;
1892 x86_def_t def1, *def = &def1;
1894 memset(def, 0, sizeof(*def));
1896 if (cpu_x86_find_by_name(cpu, def, name) < 0) {
1897 error_setg(errp, "Unable to find CPU definition: %s", name);
1898 return;
1901 if (kvm_enabled()) {
1902 def->features[FEAT_KVM] |= kvm_default_features;
1904 def->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
1906 object_property_set_str(OBJECT(cpu), def->vendor, "vendor", errp);
1907 object_property_set_int(OBJECT(cpu), def->level, "level", errp);
1908 object_property_set_int(OBJECT(cpu), def->family, "family", errp);
1909 object_property_set_int(OBJECT(cpu), def->model, "model", errp);
1910 object_property_set_int(OBJECT(cpu), def->stepping, "stepping", errp);
1911 env->features[FEAT_1_EDX] = def->features[FEAT_1_EDX];
1912 env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX];
1913 env->features[FEAT_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX];
1914 env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_ECX];
1915 object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp);
1916 env->features[FEAT_KVM] = def->features[FEAT_KVM];
1917 env->features[FEAT_SVM] = def->features[FEAT_SVM];
1918 env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX];
1919 env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX];
1920 env->cpuid_xlevel2 = def->xlevel2;
1921 cpu->cache_info_passthrough = def->cache_info_passthrough;
1923 object_property_set_str(OBJECT(cpu), def->model_id, "model-id", errp);
1926 X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
1927 Error **errp)
1929 X86CPU *cpu = NULL;
1930 gchar **model_pieces;
1931 char *name, *features;
1932 char *typename;
1933 Error *error = NULL;
1935 model_pieces = g_strsplit(cpu_model, ",", 2);
1936 if (!model_pieces[0]) {
1937 error_setg(&error, "Invalid/empty CPU model name");
1938 goto out;
1940 name = model_pieces[0];
1941 features = model_pieces[1];
1943 cpu = X86_CPU(object_new(TYPE_X86_CPU));
1944 #ifndef CONFIG_USER_ONLY
1945 if (icc_bridge == NULL) {
1946 error_setg(&error, "Invalid icc-bridge value");
1947 goto out;
1949 qdev_set_parent_bus(DEVICE(cpu), qdev_get_child_bus(icc_bridge, "icc"));
1950 object_unref(OBJECT(cpu));
1951 #endif
1953 cpu_x86_register(cpu, name, &error);
1954 if (error) {
1955 goto out;
1958 /* Emulate per-model subclasses for global properties */
1959 typename = g_strdup_printf("%s-" TYPE_X86_CPU, name);
1960 qdev_prop_set_globals_for_type(DEVICE(cpu), typename, &error);
1961 g_free(typename);
1962 if (error) {
1963 goto out;
1966 cpu_x86_parse_featurestr(cpu, features, &error);
1967 if (error) {
1968 goto out;
1971 out:
1972 if (error != NULL) {
1973 error_propagate(errp, error);
1974 object_unref(OBJECT(cpu));
1975 cpu = NULL;
1977 g_strfreev(model_pieces);
1978 return cpu;
1981 X86CPU *cpu_x86_init(const char *cpu_model)
1983 Error *error = NULL;
1984 X86CPU *cpu;
1986 cpu = cpu_x86_create(cpu_model, NULL, &error);
1987 if (error) {
1988 goto out;
1991 object_property_set_bool(OBJECT(cpu), true, "realized", &error);
1993 out:
1994 if (error) {
1995 error_report("%s", error_get_pretty(error));
1996 error_free(error);
1997 if (cpu != NULL) {
1998 object_unref(OBJECT(cpu));
1999 cpu = NULL;
2002 return cpu;
2005 #if !defined(CONFIG_USER_ONLY)
2007 void cpu_clear_apic_feature(CPUX86State *env)
2009 env->features[FEAT_1_EDX] &= ~CPUID_APIC;
2012 #endif /* !CONFIG_USER_ONLY */
2014 /* Initialize list of CPU models, filling some non-static fields if necessary
2016 void x86_cpudef_setup(void)
2018 int i, j;
2019 static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
2021 for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
2022 x86_def_t *def = &builtin_x86_defs[i];
2024 /* Look for specific "cpudef" models that */
2025 /* have the QEMU version in .model_id */
2026 for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
2027 if (strcmp(model_with_versions[j], def->name) == 0) {
2028 pstrcpy(def->model_id, sizeof(def->model_id),
2029 "QEMU Virtual CPU version ");
2030 pstrcat(def->model_id, sizeof(def->model_id),
2031 qemu_get_version());
2032 break;
2038 static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
2039 uint32_t *ecx, uint32_t *edx)
2041 *ebx = env->cpuid_vendor1;
2042 *edx = env->cpuid_vendor2;
2043 *ecx = env->cpuid_vendor3;
2046 void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
2047 uint32_t *eax, uint32_t *ebx,
2048 uint32_t *ecx, uint32_t *edx)
2050 X86CPU *cpu = x86_env_get_cpu(env);
2051 CPUState *cs = CPU(cpu);
2053 /* test if maximum index reached */
2054 if (index & 0x80000000) {
2055 if (index > env->cpuid_xlevel) {
2056 if (env->cpuid_xlevel2 > 0) {
2057 /* Handle the Centaur's CPUID instruction. */
2058 if (index > env->cpuid_xlevel2) {
2059 index = env->cpuid_xlevel2;
2060 } else if (index < 0xC0000000) {
2061 index = env->cpuid_xlevel;
2063 } else {
2064 /* Intel documentation states that invalid EAX input will
2065 * return the same information as EAX=cpuid_level
2066 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
2068 index = env->cpuid_level;
2071 } else {
2072 if (index > env->cpuid_level)
2073 index = env->cpuid_level;
2076 switch(index) {
2077 case 0:
2078 *eax = env->cpuid_level;
2079 get_cpuid_vendor(env, ebx, ecx, edx);
2080 break;
2081 case 1:
2082 *eax = env->cpuid_version;
2083 *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
2084 *ecx = env->features[FEAT_1_ECX];
2085 *edx = env->features[FEAT_1_EDX];
2086 if (cs->nr_cores * cs->nr_threads > 1) {
2087 *ebx |= (cs->nr_cores * cs->nr_threads) << 16;
2088 *edx |= 1 << 28; /* HTT bit */
2090 break;
2091 case 2:
2092 /* cache info: needed for Pentium Pro compatibility */
2093 if (cpu->cache_info_passthrough) {
2094 host_cpuid(index, 0, eax, ebx, ecx, edx);
2095 break;
2097 *eax = 1; /* Number of CPUID[EAX=2] calls required */
2098 *ebx = 0;
2099 *ecx = 0;
2100 *edx = (L1D_DESCRIPTOR << 16) | \
2101 (L1I_DESCRIPTOR << 8) | \
2102 (L2_DESCRIPTOR);
2103 break;
2104 case 4:
2105 /* cache info: needed for Core compatibility */
2106 if (cpu->cache_info_passthrough) {
2107 host_cpuid(index, count, eax, ebx, ecx, edx);
2108 *eax &= ~0xFC000000;
2109 } else {
2110 *eax = 0;
2111 switch (count) {
2112 case 0: /* L1 dcache info */
2113 *eax |= CPUID_4_TYPE_DCACHE | \
2114 CPUID_4_LEVEL(1) | \
2115 CPUID_4_SELF_INIT_LEVEL;
2116 *ebx = (L1D_LINE_SIZE - 1) | \
2117 ((L1D_PARTITIONS - 1) << 12) | \
2118 ((L1D_ASSOCIATIVITY - 1) << 22);
2119 *ecx = L1D_SETS - 1;
2120 *edx = CPUID_4_NO_INVD_SHARING;
2121 break;
2122 case 1: /* L1 icache info */
2123 *eax |= CPUID_4_TYPE_ICACHE | \
2124 CPUID_4_LEVEL(1) | \
2125 CPUID_4_SELF_INIT_LEVEL;
2126 *ebx = (L1I_LINE_SIZE - 1) | \
2127 ((L1I_PARTITIONS - 1) << 12) | \
2128 ((L1I_ASSOCIATIVITY - 1) << 22);
2129 *ecx = L1I_SETS - 1;
2130 *edx = CPUID_4_NO_INVD_SHARING;
2131 break;
2132 case 2: /* L2 cache info */
2133 *eax |= CPUID_4_TYPE_UNIFIED | \
2134 CPUID_4_LEVEL(2) | \
2135 CPUID_4_SELF_INIT_LEVEL;
2136 if (cs->nr_threads > 1) {
2137 *eax |= (cs->nr_threads - 1) << 14;
2139 *ebx = (L2_LINE_SIZE - 1) | \
2140 ((L2_PARTITIONS - 1) << 12) | \
2141 ((L2_ASSOCIATIVITY - 1) << 22);
2142 *ecx = L2_SETS - 1;
2143 *edx = CPUID_4_NO_INVD_SHARING;
2144 break;
2145 default: /* end of info */
2146 *eax = 0;
2147 *ebx = 0;
2148 *ecx = 0;
2149 *edx = 0;
2150 break;
2154 /* QEMU gives out its own APIC IDs, never pass down bits 31..26. */
2155 if ((*eax & 31) && cs->nr_cores > 1) {
2156 *eax |= (cs->nr_cores - 1) << 26;
2158 break;
2159 case 5:
2160 /* mwait info: needed for Core compatibility */
2161 *eax = 0; /* Smallest monitor-line size in bytes */
2162 *ebx = 0; /* Largest monitor-line size in bytes */
2163 *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
2164 *edx = 0;
2165 break;
2166 case 6:
2167 /* Thermal and Power Leaf */
2168 *eax = 0;
2169 *ebx = 0;
2170 *ecx = 0;
2171 *edx = 0;
2172 break;
2173 case 7:
2174 /* Structured Extended Feature Flags Enumeration Leaf */
2175 if (count == 0) {
2176 *eax = 0; /* Maximum ECX value for sub-leaves */
2177 *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
2178 *ecx = 0; /* Reserved */
2179 *edx = 0; /* Reserved */
2180 } else {
2181 *eax = 0;
2182 *ebx = 0;
2183 *ecx = 0;
2184 *edx = 0;
2186 break;
2187 case 9:
2188 /* Direct Cache Access Information Leaf */
2189 *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
2190 *ebx = 0;
2191 *ecx = 0;
2192 *edx = 0;
2193 break;
2194 case 0xA:
2195 /* Architectural Performance Monitoring Leaf */
2196 if (kvm_enabled() && cpu->enable_pmu) {
2197 KVMState *s = cs->kvm_state;
2199 *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
2200 *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
2201 *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
2202 *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
2203 } else {
2204 *eax = 0;
2205 *ebx = 0;
2206 *ecx = 0;
2207 *edx = 0;
2209 break;
2210 case 0xD: {
2211 KVMState *s = cs->kvm_state;
2212 uint64_t kvm_mask;
2213 int i;
2215 /* Processor Extended State */
2216 *eax = 0;
2217 *ebx = 0;
2218 *ecx = 0;
2219 *edx = 0;
2220 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE) || !kvm_enabled()) {
2221 break;
2223 kvm_mask =
2224 kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EAX) |
2225 ((uint64_t)kvm_arch_get_supported_cpuid(s, 0xd, 0, R_EDX) << 32);
2227 if (count == 0) {
2228 *ecx = 0x240;
2229 for (i = 2; i < ARRAY_SIZE(ext_save_areas); i++) {
2230 const ExtSaveArea *esa = &ext_save_areas[i];
2231 if ((env->features[esa->feature] & esa->bits) == esa->bits &&
2232 (kvm_mask & (1 << i)) != 0) {
2233 if (i < 32) {
2234 *eax |= 1 << i;
2235 } else {
2236 *edx |= 1 << (i - 32);
2238 *ecx = MAX(*ecx, esa->offset + esa->size);
2241 *eax |= kvm_mask & (XSTATE_FP | XSTATE_SSE);
2242 *ebx = *ecx;
2243 } else if (count == 1) {
2244 *eax = kvm_arch_get_supported_cpuid(s, 0xd, 1, R_EAX);
2245 } else if (count < ARRAY_SIZE(ext_save_areas)) {
2246 const ExtSaveArea *esa = &ext_save_areas[count];
2247 if ((env->features[esa->feature] & esa->bits) == esa->bits &&
2248 (kvm_mask & (1 << count)) != 0) {
2249 *eax = esa->size;
2250 *ebx = esa->offset;
2253 break;
2255 case 0x80000000:
2256 *eax = env->cpuid_xlevel;
2257 *ebx = env->cpuid_vendor1;
2258 *edx = env->cpuid_vendor2;
2259 *ecx = env->cpuid_vendor3;
2260 break;
2261 case 0x80000001:
2262 *eax = env->cpuid_version;
2263 *ebx = 0;
2264 *ecx = env->features[FEAT_8000_0001_ECX];
2265 *edx = env->features[FEAT_8000_0001_EDX];
2267 /* The Linux kernel checks for the CMPLegacy bit and
2268 * discards multiple thread information if it is set.
2269 * So dont set it here for Intel to make Linux guests happy.
2271 if (cs->nr_cores * cs->nr_threads > 1) {
2272 uint32_t tebx, tecx, tedx;
2273 get_cpuid_vendor(env, &tebx, &tecx, &tedx);
2274 if (tebx != CPUID_VENDOR_INTEL_1 ||
2275 tedx != CPUID_VENDOR_INTEL_2 ||
2276 tecx != CPUID_VENDOR_INTEL_3) {
2277 *ecx |= 1 << 1; /* CmpLegacy bit */
2280 break;
2281 case 0x80000002:
2282 case 0x80000003:
2283 case 0x80000004:
2284 *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2285 *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2286 *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2287 *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2288 break;
2289 case 0x80000005:
2290 /* cache info (L1 cache) */
2291 if (cpu->cache_info_passthrough) {
2292 host_cpuid(index, 0, eax, ebx, ecx, edx);
2293 break;
2295 *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) | \
2296 (L1_ITLB_2M_ASSOC << 8) | (L1_ITLB_2M_ENTRIES);
2297 *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
2298 (L1_ITLB_4K_ASSOC << 8) | (L1_ITLB_4K_ENTRIES);
2299 *ecx = (L1D_SIZE_KB_AMD << 24) | (L1D_ASSOCIATIVITY_AMD << 16) | \
2300 (L1D_LINES_PER_TAG << 8) | (L1D_LINE_SIZE);
2301 *edx = (L1I_SIZE_KB_AMD << 24) | (L1I_ASSOCIATIVITY_AMD << 16) | \
2302 (L1I_LINES_PER_TAG << 8) | (L1I_LINE_SIZE);
2303 break;
2304 case 0x80000006:
2305 /* cache info (L2 cache) */
2306 if (cpu->cache_info_passthrough) {
2307 host_cpuid(index, 0, eax, ebx, ecx, edx);
2308 break;
2310 *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) | \
2311 (L2_DTLB_2M_ENTRIES << 16) | \
2312 (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) | \
2313 (L2_ITLB_2M_ENTRIES);
2314 *ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) | \
2315 (L2_DTLB_4K_ENTRIES << 16) | \
2316 (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
2317 (L2_ITLB_4K_ENTRIES);
2318 *ecx = (L2_SIZE_KB_AMD << 16) | \
2319 (AMD_ENC_ASSOC(L2_ASSOCIATIVITY) << 12) | \
2320 (L2_LINES_PER_TAG << 8) | (L2_LINE_SIZE);
2321 *edx = ((L3_SIZE_KB/512) << 18) | \
2322 (AMD_ENC_ASSOC(L3_ASSOCIATIVITY) << 12) | \
2323 (L3_LINES_PER_TAG << 8) | (L3_LINE_SIZE);
2324 break;
2325 case 0x80000008:
2326 /* virtual & phys address size in low 2 bytes. */
2327 /* XXX: This value must match the one used in the MMU code. */
2328 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
2329 /* 64 bit processor */
2330 /* XXX: The physical address space is limited to 42 bits in exec.c. */
2331 *eax = 0x00003028; /* 48 bits virtual, 40 bits physical */
2332 } else {
2333 if (env->features[FEAT_1_EDX] & CPUID_PSE36) {
2334 *eax = 0x00000024; /* 36 bits physical */
2335 } else {
2336 *eax = 0x00000020; /* 32 bits physical */
2339 *ebx = 0;
2340 *ecx = 0;
2341 *edx = 0;
2342 if (cs->nr_cores * cs->nr_threads > 1) {
2343 *ecx |= (cs->nr_cores * cs->nr_threads) - 1;
2345 break;
2346 case 0x8000000A:
2347 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
2348 *eax = 0x00000001; /* SVM Revision */
2349 *ebx = 0x00000010; /* nr of ASIDs */
2350 *ecx = 0;
2351 *edx = env->features[FEAT_SVM]; /* optional features */
2352 } else {
2353 *eax = 0;
2354 *ebx = 0;
2355 *ecx = 0;
2356 *edx = 0;
2358 break;
2359 case 0xC0000000:
2360 *eax = env->cpuid_xlevel2;
2361 *ebx = 0;
2362 *ecx = 0;
2363 *edx = 0;
2364 break;
2365 case 0xC0000001:
2366 /* Support for VIA CPU's CPUID instruction */
2367 *eax = env->cpuid_version;
2368 *ebx = 0;
2369 *ecx = 0;
2370 *edx = env->features[FEAT_C000_0001_EDX];
2371 break;
2372 case 0xC0000002:
2373 case 0xC0000003:
2374 case 0xC0000004:
2375 /* Reserved for the future, and now filled with zero */
2376 *eax = 0;
2377 *ebx = 0;
2378 *ecx = 0;
2379 *edx = 0;
2380 break;
2381 default:
2382 /* reserved values: zero */
2383 *eax = 0;
2384 *ebx = 0;
2385 *ecx = 0;
2386 *edx = 0;
2387 break;
2391 /* CPUClass::reset() */
2392 static void x86_cpu_reset(CPUState *s)
2394 X86CPU *cpu = X86_CPU(s);
2395 X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
2396 CPUX86State *env = &cpu->env;
2397 int i;
2399 xcc->parent_reset(s);
2402 memset(env, 0, offsetof(CPUX86State, breakpoints));
2404 tlb_flush(env, 1);
2406 env->old_exception = -1;
2408 /* init to reset state */
2410 #ifdef CONFIG_SOFTMMU
2411 env->hflags |= HF_SOFTMMU_MASK;
2412 #endif
2413 env->hflags2 |= HF2_GIF_MASK;
2415 cpu_x86_update_cr0(env, 0x60000010);
2416 env->a20_mask = ~0x0;
2417 env->smbase = 0x30000;
2419 env->idt.limit = 0xffff;
2420 env->gdt.limit = 0xffff;
2421 env->ldt.limit = 0xffff;
2422 env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
2423 env->tr.limit = 0xffff;
2424 env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
2426 cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
2427 DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
2428 DESC_R_MASK | DESC_A_MASK);
2429 cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
2430 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2431 DESC_A_MASK);
2432 cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
2433 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2434 DESC_A_MASK);
2435 cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
2436 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2437 DESC_A_MASK);
2438 cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
2439 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2440 DESC_A_MASK);
2441 cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
2442 DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
2443 DESC_A_MASK);
2445 env->eip = 0xfff0;
2446 env->regs[R_EDX] = env->cpuid_version;
2448 env->eflags = 0x2;
2450 /* FPU init */
2451 for (i = 0; i < 8; i++) {
2452 env->fptags[i] = 1;
2454 env->fpuc = 0x37f;
2456 env->mxcsr = 0x1f80;
2457 env->xstate_bv = XSTATE_FP | XSTATE_SSE;
2459 env->pat = 0x0007040600070406ULL;
2460 env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2462 memset(env->dr, 0, sizeof(env->dr));
2463 env->dr[6] = DR6_FIXED_1;
2464 env->dr[7] = DR7_FIXED_1;
2465 cpu_breakpoint_remove_all(env, BP_CPU);
2466 cpu_watchpoint_remove_all(env, BP_CPU);
2468 env->tsc_adjust = 0;
2469 env->tsc = 0;
2471 #if !defined(CONFIG_USER_ONLY)
2472 /* We hard-wire the BSP to the first CPU. */
2473 if (s->cpu_index == 0) {
2474 apic_designate_bsp(cpu->apic_state);
2477 s->halted = !cpu_is_bsp(cpu);
2478 #endif
2481 #ifndef CONFIG_USER_ONLY
2482 bool cpu_is_bsp(X86CPU *cpu)
2484 return cpu_get_apic_base(cpu->apic_state) & MSR_IA32_APICBASE_BSP;
2487 /* TODO: remove me, when reset over QOM tree is implemented */
2488 static void x86_cpu_machine_reset_cb(void *opaque)
2490 X86CPU *cpu = opaque;
2491 cpu_reset(CPU(cpu));
2493 #endif
2495 static void mce_init(X86CPU *cpu)
2497 CPUX86State *cenv = &cpu->env;
2498 unsigned int bank;
2500 if (((cenv->cpuid_version >> 8) & 0xf) >= 6
2501 && (cenv->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) ==
2502 (CPUID_MCE | CPUID_MCA)) {
2503 cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
2504 cenv->mcg_ctl = ~(uint64_t)0;
2505 for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2506 cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2511 #ifndef CONFIG_USER_ONLY
2512 static void x86_cpu_apic_create(X86CPU *cpu, Error **errp)
2514 CPUX86State *env = &cpu->env;
2515 DeviceState *dev = DEVICE(cpu);
2516 APICCommonState *apic;
2517 const char *apic_type = "apic";
2519 if (kvm_irqchip_in_kernel()) {
2520 apic_type = "kvm-apic";
2521 } else if (xen_enabled()) {
2522 apic_type = "xen-apic";
2525 cpu->apic_state = qdev_try_create(qdev_get_parent_bus(dev), apic_type);
2526 if (cpu->apic_state == NULL) {
2527 error_setg(errp, "APIC device '%s' could not be created", apic_type);
2528 return;
2531 object_property_add_child(OBJECT(cpu), "apic",
2532 OBJECT(cpu->apic_state), NULL);
2533 qdev_prop_set_uint8(cpu->apic_state, "id", env->cpuid_apic_id);
2534 /* TODO: convert to link<> */
2535 apic = APIC_COMMON(cpu->apic_state);
2536 apic->cpu = cpu;
2539 static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2541 if (cpu->apic_state == NULL) {
2542 return;
2545 if (qdev_init(cpu->apic_state)) {
2546 error_setg(errp, "APIC device '%s' could not be initialized",
2547 object_get_typename(OBJECT(cpu->apic_state)));
2548 return;
2551 #else
2552 static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
2555 #endif
2557 static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
2559 CPUState *cs = CPU(dev);
2560 X86CPU *cpu = X86_CPU(dev);
2561 X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
2562 CPUX86State *env = &cpu->env;
2563 Error *local_err = NULL;
2565 if (env->features[FEAT_7_0_EBX] && env->cpuid_level < 7) {
2566 env->cpuid_level = 7;
2569 /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
2570 * CPUID[1].EDX.
2572 if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
2573 env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
2574 env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
2575 env->features[FEAT_8000_0001_EDX] &= ~CPUID_EXT2_AMD_ALIASES;
2576 env->features[FEAT_8000_0001_EDX] |= (env->features[FEAT_1_EDX]
2577 & CPUID_EXT2_AMD_ALIASES);
2580 if (!kvm_enabled()) {
2581 env->features[FEAT_1_EDX] &= TCG_FEATURES;
2582 env->features[FEAT_1_ECX] &= TCG_EXT_FEATURES;
2583 env->features[FEAT_8000_0001_EDX] &= (TCG_EXT2_FEATURES
2584 #ifdef TARGET_X86_64
2585 | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
2586 #endif
2588 env->features[FEAT_8000_0001_ECX] &= TCG_EXT3_FEATURES;
2589 env->features[FEAT_SVM] &= TCG_SVM_FEATURES;
2590 } else {
2591 if ((cpu->check_cpuid || cpu->enforce_cpuid)
2592 && kvm_check_features_against_host(cpu) && cpu->enforce_cpuid) {
2593 error_setg(&local_err,
2594 "Host's CPU doesn't support requested features");
2595 goto out;
2597 #ifdef CONFIG_KVM
2598 filter_features_for_kvm(cpu);
2599 #endif
2602 #ifndef CONFIG_USER_ONLY
2603 qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
2605 if (cpu->env.features[FEAT_1_EDX] & CPUID_APIC || smp_cpus > 1) {
2606 x86_cpu_apic_create(cpu, &local_err);
2607 if (local_err != NULL) {
2608 goto out;
2611 #endif
2613 mce_init(cpu);
2614 qemu_init_vcpu(cs);
2616 x86_cpu_apic_realize(cpu, &local_err);
2617 if (local_err != NULL) {
2618 goto out;
2620 cpu_reset(cs);
2622 xcc->parent_realize(dev, &local_err);
2623 out:
2624 if (local_err != NULL) {
2625 error_propagate(errp, local_err);
2626 return;
2630 /* Enables contiguous-apic-ID mode, for compatibility */
2631 static bool compat_apic_id_mode;
2633 void enable_compat_apic_id_mode(void)
2635 compat_apic_id_mode = true;
2638 /* Calculates initial APIC ID for a specific CPU index
2640 * Currently we need to be able to calculate the APIC ID from the CPU index
2641 * alone (without requiring a CPU object), as the QEMU<->Seabios interfaces have
2642 * no concept of "CPU index", and the NUMA tables on fw_cfg need the APIC ID of
2643 * all CPUs up to max_cpus.
2645 uint32_t x86_cpu_apic_id_from_index(unsigned int cpu_index)
2647 uint32_t correct_id;
2648 static bool warned;
2650 correct_id = x86_apicid_from_cpu_idx(smp_cores, smp_threads, cpu_index);
2651 if (compat_apic_id_mode) {
2652 if (cpu_index != correct_id && !warned) {
2653 error_report("APIC IDs set in compatibility mode, "
2654 "CPU topology won't match the configuration");
2655 warned = true;
2657 return cpu_index;
2658 } else {
2659 return correct_id;
2663 static void x86_cpu_initfn(Object *obj)
2665 CPUState *cs = CPU(obj);
2666 X86CPU *cpu = X86_CPU(obj);
2667 CPUX86State *env = &cpu->env;
2668 static int inited;
2670 cs->env_ptr = env;
2671 cpu_exec_init(env);
2673 object_property_add(obj, "family", "int",
2674 x86_cpuid_version_get_family,
2675 x86_cpuid_version_set_family, NULL, NULL, NULL);
2676 object_property_add(obj, "model", "int",
2677 x86_cpuid_version_get_model,
2678 x86_cpuid_version_set_model, NULL, NULL, NULL);
2679 object_property_add(obj, "stepping", "int",
2680 x86_cpuid_version_get_stepping,
2681 x86_cpuid_version_set_stepping, NULL, NULL, NULL);
2682 object_property_add(obj, "level", "int",
2683 x86_cpuid_get_level,
2684 x86_cpuid_set_level, NULL, NULL, NULL);
2685 object_property_add(obj, "xlevel", "int",
2686 x86_cpuid_get_xlevel,
2687 x86_cpuid_set_xlevel, NULL, NULL, NULL);
2688 object_property_add_str(obj, "vendor",
2689 x86_cpuid_get_vendor,
2690 x86_cpuid_set_vendor, NULL);
2691 object_property_add_str(obj, "model-id",
2692 x86_cpuid_get_model_id,
2693 x86_cpuid_set_model_id, NULL);
2694 object_property_add(obj, "tsc-frequency", "int",
2695 x86_cpuid_get_tsc_freq,
2696 x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
2697 object_property_add(obj, "apic-id", "int",
2698 x86_cpuid_get_apic_id,
2699 x86_cpuid_set_apic_id, NULL, NULL, NULL);
2700 object_property_add(obj, "feature-words", "X86CPUFeatureWordInfo",
2701 x86_cpu_get_feature_words,
2702 NULL, NULL, (void *)env->features, NULL);
2703 object_property_add(obj, "filtered-features", "X86CPUFeatureWordInfo",
2704 x86_cpu_get_feature_words,
2705 NULL, NULL, (void *)cpu->filtered_features, NULL);
2707 cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
2708 env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
2710 /* init various static tables used in TCG mode */
2711 if (tcg_enabled() && !inited) {
2712 inited = 1;
2713 optimize_flags_init();
2714 #ifndef CONFIG_USER_ONLY
2715 cpu_set_debug_excp_handler(breakpoint_handler);
2716 #endif
2720 static int64_t x86_cpu_get_arch_id(CPUState *cs)
2722 X86CPU *cpu = X86_CPU(cs);
2723 CPUX86State *env = &cpu->env;
2725 return env->cpuid_apic_id;
2728 static bool x86_cpu_get_paging_enabled(const CPUState *cs)
2730 X86CPU *cpu = X86_CPU(cs);
2732 return cpu->env.cr[0] & CR0_PG_MASK;
2735 static void x86_cpu_set_pc(CPUState *cs, vaddr value)
2737 X86CPU *cpu = X86_CPU(cs);
2739 cpu->env.eip = value;
2742 static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
2744 X86CPU *cpu = X86_CPU(cs);
2746 cpu->env.eip = tb->pc - tb->cs_base;
2749 static Property x86_cpu_properties[] = {
2750 DEFINE_PROP_BOOL("pmu", X86CPU, enable_pmu, false),
2751 { .name = "hv-spinlocks", .info = &qdev_prop_spinlocks },
2752 DEFINE_PROP_BOOL("hv-relaxed", X86CPU, hyperv_relaxed_timing, false),
2753 DEFINE_PROP_BOOL("hv-vapic", X86CPU, hyperv_vapic, false),
2754 DEFINE_PROP_BOOL("check", X86CPU, check_cpuid, false),
2755 DEFINE_PROP_BOOL("enforce", X86CPU, enforce_cpuid, false),
2756 DEFINE_PROP_END_OF_LIST()
2759 static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
2761 X86CPUClass *xcc = X86_CPU_CLASS(oc);
2762 CPUClass *cc = CPU_CLASS(oc);
2763 DeviceClass *dc = DEVICE_CLASS(oc);
2765 xcc->parent_realize = dc->realize;
2766 dc->realize = x86_cpu_realizefn;
2767 dc->bus_type = TYPE_ICC_BUS;
2768 dc->props = x86_cpu_properties;
2770 xcc->parent_reset = cc->reset;
2771 cc->reset = x86_cpu_reset;
2772 cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP;
2774 cc->do_interrupt = x86_cpu_do_interrupt;
2775 cc->dump_state = x86_cpu_dump_state;
2776 cc->set_pc = x86_cpu_set_pc;
2777 cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
2778 cc->gdb_read_register = x86_cpu_gdb_read_register;
2779 cc->gdb_write_register = x86_cpu_gdb_write_register;
2780 cc->get_arch_id = x86_cpu_get_arch_id;
2781 cc->get_paging_enabled = x86_cpu_get_paging_enabled;
2782 #ifndef CONFIG_USER_ONLY
2783 cc->get_memory_mapping = x86_cpu_get_memory_mapping;
2784 cc->get_phys_page_debug = x86_cpu_get_phys_page_debug;
2785 cc->write_elf64_note = x86_cpu_write_elf64_note;
2786 cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote;
2787 cc->write_elf32_note = x86_cpu_write_elf32_note;
2788 cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
2789 cc->vmsd = &vmstate_x86_cpu;
2790 #endif
2791 cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25;
2794 static const TypeInfo x86_cpu_type_info = {
2795 .name = TYPE_X86_CPU,
2796 .parent = TYPE_CPU,
2797 .instance_size = sizeof(X86CPU),
2798 .instance_init = x86_cpu_initfn,
2799 .abstract = false,
2800 .class_size = sizeof(X86CPUClass),
2801 .class_init = x86_cpu_common_class_init,
2804 static void x86_cpu_register_types(void)
2806 type_register_static(&x86_cpu_type_info);
2809 type_init(x86_cpu_register_types)