Statistics
| Branch: | Revision:

root / target-i386 / cpu.c @ dc1c13d9

History | View | Annotate | Download (60.3 kB)

1 c6dc6f63 Andre Przywara
/*
2 c6dc6f63 Andre Przywara
 *  i386 CPUID helper functions
3 c6dc6f63 Andre Przywara
 *
4 c6dc6f63 Andre Przywara
 *  Copyright (c) 2003 Fabrice Bellard
5 c6dc6f63 Andre Przywara
 *
6 c6dc6f63 Andre Przywara
 * This library is free software; you can redistribute it and/or
7 c6dc6f63 Andre Przywara
 * modify it under the terms of the GNU Lesser General Public
8 c6dc6f63 Andre Przywara
 * License as published by the Free Software Foundation; either
9 c6dc6f63 Andre Przywara
 * version 2 of the License, or (at your option) any later version.
10 c6dc6f63 Andre Przywara
 *
11 c6dc6f63 Andre Przywara
 * This library is distributed in the hope that it will be useful,
12 c6dc6f63 Andre Przywara
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 c6dc6f63 Andre Przywara
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 c6dc6f63 Andre Przywara
 * Lesser General Public License for more details.
15 c6dc6f63 Andre Przywara
 *
16 c6dc6f63 Andre Przywara
 * You should have received a copy of the GNU Lesser General Public
17 c6dc6f63 Andre Przywara
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 c6dc6f63 Andre Przywara
 */
19 c6dc6f63 Andre Przywara
#include <stdlib.h>
20 c6dc6f63 Andre Przywara
#include <stdio.h>
21 c6dc6f63 Andre Przywara
#include <string.h>
22 c6dc6f63 Andre Przywara
#include <inttypes.h>
23 c6dc6f63 Andre Przywara
24 c6dc6f63 Andre Przywara
#include "cpu.h"
25 c6dc6f63 Andre Przywara
#include "kvm.h"
26 c6dc6f63 Andre Przywara
27 c6dc6f63 Andre Przywara
#include "qemu-option.h"
28 c6dc6f63 Andre Przywara
#include "qemu-config.h"
29 c6dc6f63 Andre Przywara
30 71ad61d3 Andreas Färber
#include "qapi/qapi-visit-core.h"
31 76b64a7a Anthony Liguori
#include "arch_init.h"
32 71ad61d3 Andreas Färber
33 28f52cc0 Vadim Rozenfeld
#include "hyperv.h"
34 28f52cc0 Vadim Rozenfeld
35 65dee380 Igor Mammedov
#include "hw/hw.h"
36 b834b508 Stefan Weil
#if defined(CONFIG_KVM)
37 ef8621b1 Anthony Liguori
#include <linux/kvm_para.h>
38 b834b508 Stefan Weil
#endif
39 65dee380 Igor Mammedov
40 c6dc6f63 Andre Przywara
/* feature flags taken from "Intel Processor Identification and the CPUID
41 c6dc6f63 Andre Przywara
 * Instruction" and AMD's "CPUID Specification".  In cases of disagreement
42 c6dc6f63 Andre Przywara
 * between feature naming conventions, aliases may be added.
43 c6dc6f63 Andre Przywara
 */
44 c6dc6f63 Andre Przywara
static const char *feature_name[] = {
45 c6dc6f63 Andre Przywara
    "fpu", "vme", "de", "pse",
46 c6dc6f63 Andre Przywara
    "tsc", "msr", "pae", "mce",
47 c6dc6f63 Andre Przywara
    "cx8", "apic", NULL, "sep",
48 c6dc6f63 Andre Przywara
    "mtrr", "pge", "mca", "cmov",
49 c6dc6f63 Andre Przywara
    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
50 c6dc6f63 Andre Przywara
    NULL, "ds" /* Intel dts */, "acpi", "mmx",
51 c6dc6f63 Andre Przywara
    "fxsr", "sse", "sse2", "ss",
52 c6dc6f63 Andre Przywara
    "ht" /* Intel htt */, "tm", "ia64", "pbe",
53 c6dc6f63 Andre Przywara
};
54 c6dc6f63 Andre Przywara
static const char *ext_feature_name[] = {
55 f370be3c Eduardo Habkost
    "pni|sse3" /* Intel,AMD sse3 */, "pclmulqdq|pclmuldq", "dtes64", "monitor",
56 e117f772 Andre Przywara
    "ds_cpl", "vmx", "smx", "est",
57 c6dc6f63 Andre Przywara
    "tm2", "ssse3", "cid", NULL,
58 e117f772 Andre Przywara
    "fma", "cx16", "xtpr", "pdcm",
59 434acb81 Mao, Junjie
    NULL, "pcid", "dca", "sse4.1|sse4_1",
60 e117f772 Andre Przywara
    "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
61 eaf3f097 Eduardo Habkost
    "tsc-deadline", "aes", "xsave", "osxsave",
62 e117f772 Andre Przywara
    "avx", NULL, NULL, "hypervisor",
63 c6dc6f63 Andre Przywara
};
64 c6dc6f63 Andre Przywara
static const char *ext2_feature_name[] = {
65 c6dc6f63 Andre Przywara
    "fpu", "vme", "de", "pse",
66 c6dc6f63 Andre Przywara
    "tsc", "msr", "pae", "mce",
67 c6dc6f63 Andre Przywara
    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall",
68 c6dc6f63 Andre Przywara
    "mtrr", "pge", "mca", "cmov",
69 c6dc6f63 Andre Przywara
    "pat", "pse36", NULL, NULL /* Linux mp */,
70 3ac8ebfe Eduardo Habkost
    "nx|xd", NULL, "mmxext", "mmx",
71 f370be3c Eduardo Habkost
    "fxsr", "fxsr_opt|ffxsr", "pdpe1gb" /* AMD Page1GB */, "rdtscp",
72 3ac8ebfe Eduardo Habkost
    NULL, "lm|i64", "3dnowext", "3dnow",
73 c6dc6f63 Andre Przywara
};
74 c6dc6f63 Andre Przywara
static const char *ext3_feature_name[] = {
75 c6dc6f63 Andre Przywara
    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
76 c6dc6f63 Andre Przywara
    "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
77 e117f772 Andre Przywara
    "3dnowprefetch", "osvw", "ibs", "xop",
78 c6dc6f63 Andre Przywara
    "skinit", "wdt", NULL, NULL,
79 e117f772 Andre Przywara
    "fma4", NULL, "cvt16", "nodeid_msr",
80 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL,
81 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL,
82 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL,
83 c6dc6f63 Andre Przywara
};
84 c6dc6f63 Andre Przywara
85 c6dc6f63 Andre Przywara
static const char *kvm_feature_name[] = {
86 bfee7546 Michael S. Tsirkin
    "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, "kvm_pv_eoi", NULL,
87 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
88 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
89 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
90 c6dc6f63 Andre Przywara
};
91 c6dc6f63 Andre Przywara
92 296acb64 Joerg Roedel
static const char *svm_feature_name[] = {
93 296acb64 Joerg Roedel
    "npt", "lbrv", "svm_lock", "nrip_save",
94 296acb64 Joerg Roedel
    "tsc_scale", "vmcb_clean",  "flushbyasid", "decodeassists",
95 296acb64 Joerg Roedel
    NULL, NULL, "pause_filter", NULL,
96 296acb64 Joerg Roedel
    "pfthreshold", NULL, NULL, NULL,
97 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
98 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
99 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
100 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
101 296acb64 Joerg Roedel
};
102 296acb64 Joerg Roedel
103 c6dc6f63 Andre Przywara
/* collects per-function cpuid data
104 c6dc6f63 Andre Przywara
 */
105 c6dc6f63 Andre Przywara
typedef struct model_features_t {
106 c6dc6f63 Andre Przywara
    uint32_t *guest_feat;
107 c6dc6f63 Andre Przywara
    uint32_t *host_feat;
108 c6dc6f63 Andre Przywara
    uint32_t check_feat;
109 c6dc6f63 Andre Przywara
    const char **flag_names;
110 c6dc6f63 Andre Przywara
    uint32_t cpuid;
111 c6dc6f63 Andre Przywara
    } model_features_t;
112 c6dc6f63 Andre Przywara
113 c6dc6f63 Andre Przywara
int check_cpuid = 0;
114 c6dc6f63 Andre Przywara
int enforce_cpuid = 0;
115 c6dc6f63 Andre Przywara
116 bb44e0d1 Jan Kiszka
void host_cpuid(uint32_t function, uint32_t count,
117 bb44e0d1 Jan Kiszka
                uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
118 bdde476a Andre Przywara
{
119 bdde476a Andre Przywara
#if defined(CONFIG_KVM)
120 a1fd24af Anthony Liguori
    uint32_t vec[4];
121 a1fd24af Anthony Liguori
122 a1fd24af Anthony Liguori
#ifdef __x86_64__
123 a1fd24af Anthony Liguori
    asm volatile("cpuid"
124 a1fd24af Anthony Liguori
                 : "=a"(vec[0]), "=b"(vec[1]),
125 a1fd24af Anthony Liguori
                   "=c"(vec[2]), "=d"(vec[3])
126 a1fd24af Anthony Liguori
                 : "0"(function), "c"(count) : "cc");
127 a1fd24af Anthony Liguori
#else
128 a1fd24af Anthony Liguori
    asm volatile("pusha \n\t"
129 a1fd24af Anthony Liguori
                 "cpuid \n\t"
130 a1fd24af Anthony Liguori
                 "mov %%eax, 0(%2) \n\t"
131 a1fd24af Anthony Liguori
                 "mov %%ebx, 4(%2) \n\t"
132 a1fd24af Anthony Liguori
                 "mov %%ecx, 8(%2) \n\t"
133 a1fd24af Anthony Liguori
                 "mov %%edx, 12(%2) \n\t"
134 a1fd24af Anthony Liguori
                 "popa"
135 a1fd24af Anthony Liguori
                 : : "a"(function), "c"(count), "S"(vec)
136 a1fd24af Anthony Liguori
                 : "memory", "cc");
137 a1fd24af Anthony Liguori
#endif
138 a1fd24af Anthony Liguori
139 bdde476a Andre Przywara
    if (eax)
140 a1fd24af Anthony Liguori
        *eax = vec[0];
141 bdde476a Andre Przywara
    if (ebx)
142 a1fd24af Anthony Liguori
        *ebx = vec[1];
143 bdde476a Andre Przywara
    if (ecx)
144 a1fd24af Anthony Liguori
        *ecx = vec[2];
145 bdde476a Andre Przywara
    if (edx)
146 a1fd24af Anthony Liguori
        *edx = vec[3];
147 bdde476a Andre Przywara
#endif
148 bdde476a Andre Przywara
}
149 c6dc6f63 Andre Przywara
150 c6dc6f63 Andre Przywara
#define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
151 c6dc6f63 Andre Przywara
152 c6dc6f63 Andre Przywara
/* general substring compare of *[s1..e1) and *[s2..e2).  sx is start of
153 c6dc6f63 Andre Przywara
 * a substring.  ex if !NULL points to the first char after a substring,
154 c6dc6f63 Andre Przywara
 * otherwise the string is assumed to sized by a terminating nul.
155 c6dc6f63 Andre Przywara
 * Return lexical ordering of *s1:*s2.
156 c6dc6f63 Andre Przywara
 */
157 c6dc6f63 Andre Przywara
static int sstrcmp(const char *s1, const char *e1, const char *s2,
158 c6dc6f63 Andre Przywara
    const char *e2)
159 c6dc6f63 Andre Przywara
{
160 c6dc6f63 Andre Przywara
    for (;;) {
161 c6dc6f63 Andre Przywara
        if (!*s1 || !*s2 || *s1 != *s2)
162 c6dc6f63 Andre Przywara
            return (*s1 - *s2);
163 c6dc6f63 Andre Przywara
        ++s1, ++s2;
164 c6dc6f63 Andre Przywara
        if (s1 == e1 && s2 == e2)
165 c6dc6f63 Andre Przywara
            return (0);
166 c6dc6f63 Andre Przywara
        else if (s1 == e1)
167 c6dc6f63 Andre Przywara
            return (*s2);
168 c6dc6f63 Andre Przywara
        else if (s2 == e2)
169 c6dc6f63 Andre Przywara
            return (*s1);
170 c6dc6f63 Andre Przywara
    }
171 c6dc6f63 Andre Przywara
}
172 c6dc6f63 Andre Przywara
173 c6dc6f63 Andre Przywara
/* compare *[s..e) to *altstr.  *altstr may be a simple string or multiple
174 c6dc6f63 Andre Przywara
 * '|' delimited (possibly empty) strings in which case search for a match
175 c6dc6f63 Andre Przywara
 * within the alternatives proceeds left to right.  Return 0 for success,
176 c6dc6f63 Andre Przywara
 * non-zero otherwise.
177 c6dc6f63 Andre Przywara
 */
178 c6dc6f63 Andre Przywara
static int altcmp(const char *s, const char *e, const char *altstr)
179 c6dc6f63 Andre Przywara
{
180 c6dc6f63 Andre Przywara
    const char *p, *q;
181 c6dc6f63 Andre Przywara
182 c6dc6f63 Andre Przywara
    for (q = p = altstr; ; ) {
183 c6dc6f63 Andre Przywara
        while (*p && *p != '|')
184 c6dc6f63 Andre Przywara
            ++p;
185 c6dc6f63 Andre Przywara
        if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
186 c6dc6f63 Andre Przywara
            return (0);
187 c6dc6f63 Andre Przywara
        if (!*p)
188 c6dc6f63 Andre Przywara
            return (1);
189 c6dc6f63 Andre Przywara
        else
190 c6dc6f63 Andre Przywara
            q = ++p;
191 c6dc6f63 Andre Przywara
    }
192 c6dc6f63 Andre Przywara
}
193 c6dc6f63 Andre Przywara
194 c6dc6f63 Andre Przywara
/* search featureset for flag *[s..e), if found set corresponding bit in
195 e41e0fc6 Jan Kiszka
 * *pval and return true, otherwise return false
196 c6dc6f63 Andre Przywara
 */
197 e41e0fc6 Jan Kiszka
static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
198 e41e0fc6 Jan Kiszka
                           const char **featureset)
199 c6dc6f63 Andre Przywara
{
200 c6dc6f63 Andre Przywara
    uint32_t mask;
201 c6dc6f63 Andre Przywara
    const char **ppc;
202 e41e0fc6 Jan Kiszka
    bool found = false;
203 c6dc6f63 Andre Przywara
204 e41e0fc6 Jan Kiszka
    for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
205 c6dc6f63 Andre Przywara
        if (*ppc && !altcmp(s, e, *ppc)) {
206 c6dc6f63 Andre Przywara
            *pval |= mask;
207 e41e0fc6 Jan Kiszka
            found = true;
208 c6dc6f63 Andre Przywara
        }
209 e41e0fc6 Jan Kiszka
    }
210 e41e0fc6 Jan Kiszka
    return found;
211 c6dc6f63 Andre Przywara
}
212 c6dc6f63 Andre Przywara
213 c6dc6f63 Andre Przywara
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
214 c6dc6f63 Andre Przywara
                                    uint32_t *ext_features,
215 c6dc6f63 Andre Przywara
                                    uint32_t *ext2_features,
216 c6dc6f63 Andre Przywara
                                    uint32_t *ext3_features,
217 296acb64 Joerg Roedel
                                    uint32_t *kvm_features,
218 296acb64 Joerg Roedel
                                    uint32_t *svm_features)
219 c6dc6f63 Andre Przywara
{
220 c6dc6f63 Andre Przywara
    if (!lookup_feature(features, flagname, NULL, feature_name) &&
221 c6dc6f63 Andre Przywara
        !lookup_feature(ext_features, flagname, NULL, ext_feature_name) &&
222 c6dc6f63 Andre Przywara
        !lookup_feature(ext2_features, flagname, NULL, ext2_feature_name) &&
223 c6dc6f63 Andre Przywara
        !lookup_feature(ext3_features, flagname, NULL, ext3_feature_name) &&
224 296acb64 Joerg Roedel
        !lookup_feature(kvm_features, flagname, NULL, kvm_feature_name) &&
225 296acb64 Joerg Roedel
        !lookup_feature(svm_features, flagname, NULL, svm_feature_name))
226 c6dc6f63 Andre Przywara
            fprintf(stderr, "CPU feature %s not found\n", flagname);
227 c6dc6f63 Andre Przywara
}
228 c6dc6f63 Andre Przywara
229 c6dc6f63 Andre Przywara
typedef struct x86_def_t {
230 c6dc6f63 Andre Przywara
    struct x86_def_t *next;
231 c6dc6f63 Andre Przywara
    const char *name;
232 c6dc6f63 Andre Przywara
    uint32_t level;
233 c6dc6f63 Andre Przywara
    uint32_t vendor1, vendor2, vendor3;
234 c6dc6f63 Andre Przywara
    int family;
235 c6dc6f63 Andre Przywara
    int model;
236 c6dc6f63 Andre Przywara
    int stepping;
237 b862d1fe Joerg Roedel
    int tsc_khz;
238 296acb64 Joerg Roedel
    uint32_t features, ext_features, ext2_features, ext3_features;
239 296acb64 Joerg Roedel
    uint32_t kvm_features, svm_features;
240 c6dc6f63 Andre Przywara
    uint32_t xlevel;
241 c6dc6f63 Andre Przywara
    char model_id[48];
242 c6dc6f63 Andre Przywara
    int vendor_override;
243 c6dc6f63 Andre Przywara
    uint32_t flags;
244 b3baa152 brillywu@viatech.com.cn
    /* Store the results of Centaur's CPUID instructions */
245 b3baa152 brillywu@viatech.com.cn
    uint32_t ext4_features;
246 b3baa152 brillywu@viatech.com.cn
    uint32_t xlevel2;
247 13526728 Eduardo Habkost
    /* The feature bits on CPUID[EAX=7,ECX=0].EBX */
248 13526728 Eduardo Habkost
    uint32_t cpuid_7_0_ebx_features;
249 c6dc6f63 Andre Przywara
} x86_def_t;
250 c6dc6f63 Andre Przywara
251 c6dc6f63 Andre Przywara
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
252 c6dc6f63 Andre Przywara
#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
253 c6dc6f63 Andre Przywara
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
254 c6dc6f63 Andre Przywara
#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
255 c6dc6f63 Andre Przywara
          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
256 c6dc6f63 Andre Przywara
          CPUID_PSE36 | CPUID_FXSR)
257 c6dc6f63 Andre Przywara
#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
258 c6dc6f63 Andre Przywara
#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
259 c6dc6f63 Andre Przywara
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
260 c6dc6f63 Andre Przywara
          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
261 c6dc6f63 Andre Przywara
          CPUID_PAE | CPUID_SEP | CPUID_APIC)
262 42673936 Andre Przywara
#define EXT2_FEATURE_MASK 0x0183F3FF
263 c6dc6f63 Andre Przywara
264 551a2dec Andre Przywara
#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
265 551a2dec Andre Przywara
          CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
266 551a2dec Andre Przywara
          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
267 551a2dec Andre Przywara
          CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
268 551a2dec Andre Przywara
          CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
269 8560efed Aurelien Jarno
          /* partly implemented:
270 8560efed Aurelien Jarno
          CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
271 8560efed Aurelien Jarno
          CPUID_PSE36 (needed for Solaris) */
272 8560efed Aurelien Jarno
          /* missing:
273 8560efed Aurelien Jarno
          CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
274 551a2dec Andre Przywara
#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | \
275 8713f8ff Andi Kleen
          CPUID_EXT_CX16 | CPUID_EXT_POPCNT | \
276 551a2dec Andre Przywara
          CPUID_EXT_HYPERVISOR)
277 8560efed Aurelien Jarno
          /* missing:
278 8560efed Aurelien Jarno
          CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
279 8713f8ff Andi Kleen
          CPUID_EXT_TM2, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_XSAVE */
280 551a2dec Andre Przywara
#define TCG_EXT2_FEATURES ((TCG_FEATURES & EXT2_FEATURE_MASK) | \
281 551a2dec Andre Przywara
          CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
282 551a2dec Andre Przywara
          CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
283 8560efed Aurelien Jarno
          /* missing:
284 8560efed Aurelien Jarno
          CPUID_EXT2_PDPE1GB */
285 551a2dec Andre Przywara
#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
286 551a2dec Andre Przywara
          CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
287 296acb64 Joerg Roedel
#define TCG_SVM_FEATURES 0
288 551a2dec Andre Przywara
289 c6dc6f63 Andre Przywara
/* maintains list of cpu model definitions
290 c6dc6f63 Andre Przywara
 */
291 c6dc6f63 Andre Przywara
static x86_def_t *x86_defs = {NULL};
292 c6dc6f63 Andre Przywara
293 c6dc6f63 Andre Przywara
/* built-in cpu model definitions (deprecated)
294 c6dc6f63 Andre Przywara
 */
295 c6dc6f63 Andre Przywara
static x86_def_t builtin_x86_defs[] = {
296 c6dc6f63 Andre Przywara
    {
297 c6dc6f63 Andre Przywara
        .name = "qemu64",
298 c6dc6f63 Andre Przywara
        .level = 4,
299 c6dc6f63 Andre Przywara
        .vendor1 = CPUID_VENDOR_AMD_1,
300 c6dc6f63 Andre Przywara
        .vendor2 = CPUID_VENDOR_AMD_2,
301 c6dc6f63 Andre Przywara
        .vendor3 = CPUID_VENDOR_AMD_3,
302 c6dc6f63 Andre Przywara
        .family = 6,
303 c6dc6f63 Andre Przywara
        .model = 2,
304 c6dc6f63 Andre Przywara
        .stepping = 3,
305 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
306 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
307 c6dc6f63 Andre Przywara
            CPUID_PSE36,
308 c6dc6f63 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
309 42673936 Andre Przywara
        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
310 c6dc6f63 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
311 c6dc6f63 Andre Przywara
        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
312 c6dc6f63 Andre Przywara
            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
313 c6dc6f63 Andre Przywara
        .xlevel = 0x8000000A,
314 c6dc6f63 Andre Przywara
    },
315 c6dc6f63 Andre Przywara
    {
316 c6dc6f63 Andre Przywara
        .name = "phenom",
317 c6dc6f63 Andre Przywara
        .level = 5,
318 c6dc6f63 Andre Przywara
        .vendor1 = CPUID_VENDOR_AMD_1,
319 c6dc6f63 Andre Przywara
        .vendor2 = CPUID_VENDOR_AMD_2,
320 c6dc6f63 Andre Przywara
        .vendor3 = CPUID_VENDOR_AMD_3,
321 c6dc6f63 Andre Przywara
        .family = 16,
322 c6dc6f63 Andre Przywara
        .model = 2,
323 c6dc6f63 Andre Przywara
        .stepping = 3,
324 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
325 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
326 8560efed Aurelien Jarno
            CPUID_PSE36 | CPUID_VME | CPUID_HT,
327 c6dc6f63 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
328 c6dc6f63 Andre Przywara
            CPUID_EXT_POPCNT,
329 42673936 Andre Przywara
        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
330 c6dc6f63 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
331 c6dc6f63 Andre Przywara
            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
332 8560efed Aurelien Jarno
            CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
333 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
334 c6dc6f63 Andre Przywara
                    CPUID_EXT3_CR8LEG,
335 c6dc6f63 Andre Przywara
                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
336 c6dc6f63 Andre Przywara
                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
337 c6dc6f63 Andre Przywara
        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
338 c6dc6f63 Andre Przywara
            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
339 296acb64 Joerg Roedel
        .svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV,
340 c6dc6f63 Andre Przywara
        .xlevel = 0x8000001A,
341 c6dc6f63 Andre Przywara
        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
342 c6dc6f63 Andre Przywara
    },
343 c6dc6f63 Andre Przywara
    {
344 c6dc6f63 Andre Przywara
        .name = "core2duo",
345 c6dc6f63 Andre Przywara
        .level = 10,
346 c6dc6f63 Andre Przywara
        .family = 6,
347 c6dc6f63 Andre Przywara
        .model = 15,
348 c6dc6f63 Andre Przywara
        .stepping = 11,
349 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
350 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
351 8560efed Aurelien Jarno
            CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
352 8560efed Aurelien Jarno
            CPUID_HT | CPUID_TM | CPUID_PBE,
353 8560efed Aurelien Jarno
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
354 8560efed Aurelien Jarno
            CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
355 8560efed Aurelien Jarno
            CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
356 c6dc6f63 Andre Przywara
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
357 c6dc6f63 Andre Przywara
        .ext3_features = CPUID_EXT3_LAHF_LM,
358 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
359 c6dc6f63 Andre Przywara
        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
360 c6dc6f63 Andre Przywara
    },
361 c6dc6f63 Andre Przywara
    {
362 c6dc6f63 Andre Przywara
        .name = "kvm64",
363 c6dc6f63 Andre Przywara
        .level = 5,
364 c6dc6f63 Andre Przywara
        .vendor1 = CPUID_VENDOR_INTEL_1,
365 c6dc6f63 Andre Przywara
        .vendor2 = CPUID_VENDOR_INTEL_2,
366 c6dc6f63 Andre Przywara
        .vendor3 = CPUID_VENDOR_INTEL_3,
367 c6dc6f63 Andre Przywara
        .family = 15,
368 c6dc6f63 Andre Przywara
        .model = 6,
369 c6dc6f63 Andre Przywara
        .stepping = 1,
370 c6dc6f63 Andre Przywara
        /* Missing: CPUID_VME, CPUID_HT */
371 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
372 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
373 c6dc6f63 Andre Przywara
            CPUID_PSE36,
374 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
375 c6dc6f63 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
376 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
377 42673936 Andre Przywara
        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
378 c6dc6f63 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
379 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
380 c6dc6f63 Andre Przywara
                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
381 c6dc6f63 Andre Przywara
                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
382 c6dc6f63 Andre Przywara
                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
383 c6dc6f63 Andre Przywara
        .ext3_features = 0,
384 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
385 c6dc6f63 Andre Przywara
        .model_id = "Common KVM processor"
386 c6dc6f63 Andre Przywara
    },
387 c6dc6f63 Andre Przywara
    {
388 c6dc6f63 Andre Przywara
        .name = "qemu32",
389 c6dc6f63 Andre Przywara
        .level = 4,
390 c6dc6f63 Andre Przywara
        .family = 6,
391 c6dc6f63 Andre Przywara
        .model = 3,
392 c6dc6f63 Andre Przywara
        .stepping = 3,
393 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES,
394 c6dc6f63 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
395 58012d66 Andre Przywara
        .xlevel = 0x80000004,
396 c6dc6f63 Andre Przywara
    },
397 c6dc6f63 Andre Przywara
    {
398 eafaf1e5 Andre Przywara
        .name = "kvm32",
399 eafaf1e5 Andre Przywara
        .level = 5,
400 eafaf1e5 Andre Przywara
        .family = 15,
401 eafaf1e5 Andre Przywara
        .model = 6,
402 eafaf1e5 Andre Przywara
        .stepping = 1,
403 eafaf1e5 Andre Przywara
        .features = PPRO_FEATURES |
404 eafaf1e5 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
405 eafaf1e5 Andre Przywara
        .ext_features = CPUID_EXT_SSE3,
406 eafaf1e5 Andre Przywara
        .ext2_features = PPRO_FEATURES & EXT2_FEATURE_MASK,
407 eafaf1e5 Andre Przywara
        .ext3_features = 0,
408 eafaf1e5 Andre Przywara
        .xlevel = 0x80000008,
409 eafaf1e5 Andre Przywara
        .model_id = "Common 32-bit KVM processor"
410 eafaf1e5 Andre Przywara
    },
411 eafaf1e5 Andre Przywara
    {
412 c6dc6f63 Andre Przywara
        .name = "coreduo",
413 c6dc6f63 Andre Przywara
        .level = 10,
414 c6dc6f63 Andre Przywara
        .family = 6,
415 c6dc6f63 Andre Przywara
        .model = 14,
416 c6dc6f63 Andre Przywara
        .stepping = 8,
417 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES | CPUID_VME |
418 8560efed Aurelien Jarno
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
419 8560efed Aurelien Jarno
            CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
420 8560efed Aurelien Jarno
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
421 8560efed Aurelien Jarno
            CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
422 c6dc6f63 Andre Przywara
        .ext2_features = CPUID_EXT2_NX,
423 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
424 c6dc6f63 Andre Przywara
        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
425 c6dc6f63 Andre Przywara
    },
426 c6dc6f63 Andre Przywara
    {
427 c6dc6f63 Andre Przywara
        .name = "486",
428 58012d66 Andre Przywara
        .level = 1,
429 c6dc6f63 Andre Przywara
        .family = 4,
430 c6dc6f63 Andre Przywara
        .model = 0,
431 c6dc6f63 Andre Przywara
        .stepping = 0,
432 c6dc6f63 Andre Przywara
        .features = I486_FEATURES,
433 c6dc6f63 Andre Przywara
        .xlevel = 0,
434 c6dc6f63 Andre Przywara
    },
435 c6dc6f63 Andre Przywara
    {
436 c6dc6f63 Andre Przywara
        .name = "pentium",
437 c6dc6f63 Andre Przywara
        .level = 1,
438 c6dc6f63 Andre Przywara
        .family = 5,
439 c6dc6f63 Andre Przywara
        .model = 4,
440 c6dc6f63 Andre Przywara
        .stepping = 3,
441 c6dc6f63 Andre Przywara
        .features = PENTIUM_FEATURES,
442 c6dc6f63 Andre Przywara
        .xlevel = 0,
443 c6dc6f63 Andre Przywara
    },
444 c6dc6f63 Andre Przywara
    {
445 c6dc6f63 Andre Przywara
        .name = "pentium2",
446 c6dc6f63 Andre Przywara
        .level = 2,
447 c6dc6f63 Andre Przywara
        .family = 6,
448 c6dc6f63 Andre Przywara
        .model = 5,
449 c6dc6f63 Andre Przywara
        .stepping = 2,
450 c6dc6f63 Andre Przywara
        .features = PENTIUM2_FEATURES,
451 c6dc6f63 Andre Przywara
        .xlevel = 0,
452 c6dc6f63 Andre Przywara
    },
453 c6dc6f63 Andre Przywara
    {
454 c6dc6f63 Andre Przywara
        .name = "pentium3",
455 c6dc6f63 Andre Przywara
        .level = 2,
456 c6dc6f63 Andre Przywara
        .family = 6,
457 c6dc6f63 Andre Przywara
        .model = 7,
458 c6dc6f63 Andre Przywara
        .stepping = 3,
459 c6dc6f63 Andre Przywara
        .features = PENTIUM3_FEATURES,
460 c6dc6f63 Andre Przywara
        .xlevel = 0,
461 c6dc6f63 Andre Przywara
    },
462 c6dc6f63 Andre Przywara
    {
463 c6dc6f63 Andre Przywara
        .name = "athlon",
464 c6dc6f63 Andre Przywara
        .level = 2,
465 c6dc6f63 Andre Przywara
        .vendor1 = CPUID_VENDOR_AMD_1,
466 c6dc6f63 Andre Przywara
        .vendor2 = CPUID_VENDOR_AMD_2,
467 c6dc6f63 Andre Przywara
        .vendor3 = CPUID_VENDOR_AMD_3,
468 c6dc6f63 Andre Przywara
        .family = 6,
469 c6dc6f63 Andre Przywara
        .model = 2,
470 c6dc6f63 Andre Przywara
        .stepping = 3,
471 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
472 42673936 Andre Przywara
        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
473 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
474 c6dc6f63 Andre Przywara
    },
475 c6dc6f63 Andre Przywara
    {
476 c6dc6f63 Andre Przywara
        .name = "n270",
477 c6dc6f63 Andre Przywara
        /* original is on level 10 */
478 c6dc6f63 Andre Przywara
        .level = 5,
479 c6dc6f63 Andre Przywara
        .family = 6,
480 c6dc6f63 Andre Przywara
        .model = 28,
481 c6dc6f63 Andre Przywara
        .stepping = 2,
482 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
483 8560efed Aurelien Jarno
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
484 8560efed Aurelien Jarno
            CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
485 c6dc6f63 Andre Przywara
            /* Some CPUs got no CPUID_SEP */
486 8560efed Aurelien Jarno
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
487 8560efed Aurelien Jarno
            CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR,
488 42673936 Andre Przywara
        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_NX,
489 8560efed Aurelien Jarno
        .ext3_features = CPUID_EXT3_LAHF_LM,
490 c6dc6f63 Andre Przywara
        .xlevel = 0x8000000A,
491 c6dc6f63 Andre Przywara
        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
492 c6dc6f63 Andre Przywara
    },
493 c6dc6f63 Andre Przywara
};
494 c6dc6f63 Andre Przywara
495 c6dc6f63 Andre Przywara
static int cpu_x86_fill_model_id(char *str)
496 c6dc6f63 Andre Przywara
{
497 c6dc6f63 Andre Przywara
    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
498 c6dc6f63 Andre Przywara
    int i;
499 c6dc6f63 Andre Przywara
500 c6dc6f63 Andre Przywara
    for (i = 0; i < 3; i++) {
501 c6dc6f63 Andre Przywara
        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
502 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 +  0, &eax, 4);
503 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 +  4, &ebx, 4);
504 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 +  8, &ecx, 4);
505 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 + 12, &edx, 4);
506 c6dc6f63 Andre Przywara
    }
507 c6dc6f63 Andre Przywara
    return 0;
508 c6dc6f63 Andre Przywara
}
509 c6dc6f63 Andre Przywara
510 c6dc6f63 Andre Przywara
static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
511 c6dc6f63 Andre Przywara
{
512 c6dc6f63 Andre Przywara
    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
513 c6dc6f63 Andre Przywara
514 c6dc6f63 Andre Przywara
    x86_cpu_def->name = "host";
515 c6dc6f63 Andre Przywara
    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
516 c6dc6f63 Andre Przywara
    x86_cpu_def->level = eax;
517 c6dc6f63 Andre Przywara
    x86_cpu_def->vendor1 = ebx;
518 c6dc6f63 Andre Przywara
    x86_cpu_def->vendor2 = edx;
519 c6dc6f63 Andre Przywara
    x86_cpu_def->vendor3 = ecx;
520 c6dc6f63 Andre Przywara
521 c6dc6f63 Andre Przywara
    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
522 c6dc6f63 Andre Przywara
    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
523 c6dc6f63 Andre Przywara
    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
524 c6dc6f63 Andre Przywara
    x86_cpu_def->stepping = eax & 0x0F;
525 c6dc6f63 Andre Przywara
    x86_cpu_def->ext_features = ecx;
526 c6dc6f63 Andre Przywara
    x86_cpu_def->features = edx;
527 c6dc6f63 Andre Przywara
528 13526728 Eduardo Habkost
    if (kvm_enabled() && x86_cpu_def->level >= 7) {
529 13526728 Eduardo Habkost
        x86_cpu_def->cpuid_7_0_ebx_features = kvm_arch_get_supported_cpuid(kvm_state, 0x7, 0, R_EBX);
530 13526728 Eduardo Habkost
    } else {
531 13526728 Eduardo Habkost
        x86_cpu_def->cpuid_7_0_ebx_features = 0;
532 13526728 Eduardo Habkost
    }
533 13526728 Eduardo Habkost
534 c6dc6f63 Andre Przywara
    host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
535 c6dc6f63 Andre Przywara
    x86_cpu_def->xlevel = eax;
536 c6dc6f63 Andre Przywara
537 c6dc6f63 Andre Przywara
    host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
538 c6dc6f63 Andre Przywara
    x86_cpu_def->ext2_features = edx;
539 c6dc6f63 Andre Przywara
    x86_cpu_def->ext3_features = ecx;
540 c6dc6f63 Andre Przywara
    cpu_x86_fill_model_id(x86_cpu_def->model_id);
541 c6dc6f63 Andre Przywara
    x86_cpu_def->vendor_override = 0;
542 c6dc6f63 Andre Przywara
543 b3baa152 brillywu@viatech.com.cn
    /* Call Centaur's CPUID instruction. */
544 b3baa152 brillywu@viatech.com.cn
    if (x86_cpu_def->vendor1 == CPUID_VENDOR_VIA_1 &&
545 b3baa152 brillywu@viatech.com.cn
        x86_cpu_def->vendor2 == CPUID_VENDOR_VIA_2 &&
546 b3baa152 brillywu@viatech.com.cn
        x86_cpu_def->vendor3 == CPUID_VENDOR_VIA_3) {
547 b3baa152 brillywu@viatech.com.cn
        host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
548 b3baa152 brillywu@viatech.com.cn
        if (eax >= 0xC0000001) {
549 b3baa152 brillywu@viatech.com.cn
            /* Support VIA max extended level */
550 b3baa152 brillywu@viatech.com.cn
            x86_cpu_def->xlevel2 = eax;
551 b3baa152 brillywu@viatech.com.cn
            host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
552 b3baa152 brillywu@viatech.com.cn
            x86_cpu_def->ext4_features = edx;
553 b3baa152 brillywu@viatech.com.cn
        }
554 b3baa152 brillywu@viatech.com.cn
    }
555 296acb64 Joerg Roedel
556 296acb64 Joerg Roedel
    /*
557 296acb64 Joerg Roedel
     * Every SVM feature requires emulation support in KVM - so we can't just
558 296acb64 Joerg Roedel
     * read the host features here. KVM might even support SVM features not
559 296acb64 Joerg Roedel
     * available on the host hardware. Just set all bits and mask out the
560 296acb64 Joerg Roedel
     * unsupported ones later.
561 296acb64 Joerg Roedel
     */
562 296acb64 Joerg Roedel
    x86_cpu_def->svm_features = -1;
563 296acb64 Joerg Roedel
564 c6dc6f63 Andre Przywara
    return 0;
565 c6dc6f63 Andre Przywara
}
566 c6dc6f63 Andre Przywara
567 c6dc6f63 Andre Przywara
static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
568 c6dc6f63 Andre Przywara
{
569 c6dc6f63 Andre Przywara
    int i;
570 c6dc6f63 Andre Przywara
571 c6dc6f63 Andre Przywara
    for (i = 0; i < 32; ++i)
572 c6dc6f63 Andre Przywara
        if (1 << i & mask) {
573 c6dc6f63 Andre Przywara
            fprintf(stderr, "warning: host cpuid %04x_%04x lacks requested"
574 c6dc6f63 Andre Przywara
                " flag '%s' [0x%08x]\n",
575 c6dc6f63 Andre Przywara
                f->cpuid >> 16, f->cpuid & 0xffff,
576 c6dc6f63 Andre Przywara
                f->flag_names[i] ? f->flag_names[i] : "[reserved]", mask);
577 c6dc6f63 Andre Przywara
            break;
578 c6dc6f63 Andre Przywara
        }
579 c6dc6f63 Andre Przywara
    return 0;
580 c6dc6f63 Andre Przywara
}
581 c6dc6f63 Andre Przywara
582 c6dc6f63 Andre Przywara
/* best effort attempt to inform user requested cpu flags aren't making
583 c6dc6f63 Andre Przywara
 * their way to the guest.  Note: ft[].check_feat ideally should be
584 c6dc6f63 Andre Przywara
 * specified via a guest_def field to suppress report of extraneous flags.
585 c6dc6f63 Andre Przywara
 */
586 c6dc6f63 Andre Przywara
static int check_features_against_host(x86_def_t *guest_def)
587 c6dc6f63 Andre Przywara
{
588 c6dc6f63 Andre Przywara
    x86_def_t host_def;
589 c6dc6f63 Andre Przywara
    uint32_t mask;
590 c6dc6f63 Andre Przywara
    int rv, i;
591 c6dc6f63 Andre Przywara
    struct model_features_t ft[] = {
592 c6dc6f63 Andre Przywara
        {&guest_def->features, &host_def.features,
593 c6dc6f63 Andre Przywara
            ~0, feature_name, 0x00000000},
594 c6dc6f63 Andre Przywara
        {&guest_def->ext_features, &host_def.ext_features,
595 c6dc6f63 Andre Przywara
            ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},
596 c6dc6f63 Andre Przywara
        {&guest_def->ext2_features, &host_def.ext2_features,
597 c6dc6f63 Andre Przywara
            ~PPRO_FEATURES, ext2_feature_name, 0x80000000},
598 c6dc6f63 Andre Przywara
        {&guest_def->ext3_features, &host_def.ext3_features,
599 c6dc6f63 Andre Przywara
            ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};
600 c6dc6f63 Andre Przywara
601 c6dc6f63 Andre Przywara
    cpu_x86_fill_host(&host_def);
602 66fe09ee Blue Swirl
    for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i)
603 c6dc6f63 Andre Przywara
        for (mask = 1; mask; mask <<= 1)
604 c6dc6f63 Andre Przywara
            if (ft[i].check_feat & mask && *ft[i].guest_feat & mask &&
605 c6dc6f63 Andre Przywara
                !(*ft[i].host_feat & mask)) {
606 c6dc6f63 Andre Przywara
                    unavailable_host_feature(&ft[i], mask);
607 c6dc6f63 Andre Przywara
                    rv = 1;
608 c6dc6f63 Andre Przywara
                }
609 c6dc6f63 Andre Przywara
    return rv;
610 c6dc6f63 Andre Przywara
}
611 c6dc6f63 Andre Przywara
612 95b8519d Andreas Färber
static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
613 95b8519d Andreas Färber
                                         const char *name, Error **errp)
614 95b8519d Andreas Färber
{
615 95b8519d Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
616 95b8519d Andreas Färber
    CPUX86State *env = &cpu->env;
617 95b8519d Andreas Färber
    int64_t value;
618 95b8519d Andreas Färber
619 95b8519d Andreas Färber
    value = (env->cpuid_version >> 8) & 0xf;
620 95b8519d Andreas Färber
    if (value == 0xf) {
621 95b8519d Andreas Färber
        value += (env->cpuid_version >> 20) & 0xff;
622 95b8519d Andreas Färber
    }
623 95b8519d Andreas Färber
    visit_type_int(v, &value, name, errp);
624 95b8519d Andreas Färber
}
625 95b8519d Andreas Färber
626 71ad61d3 Andreas Färber
static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
627 71ad61d3 Andreas Färber
                                         const char *name, Error **errp)
628 ed5e1ec3 Andreas Färber
{
629 71ad61d3 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
630 71ad61d3 Andreas Färber
    CPUX86State *env = &cpu->env;
631 71ad61d3 Andreas Färber
    const int64_t min = 0;
632 71ad61d3 Andreas Färber
    const int64_t max = 0xff + 0xf;
633 71ad61d3 Andreas Färber
    int64_t value;
634 71ad61d3 Andreas Färber
635 71ad61d3 Andreas Färber
    visit_type_int(v, &value, name, errp);
636 71ad61d3 Andreas Färber
    if (error_is_set(errp)) {
637 71ad61d3 Andreas Färber
        return;
638 71ad61d3 Andreas Färber
    }
639 71ad61d3 Andreas Färber
    if (value < min || value > max) {
640 71ad61d3 Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
641 71ad61d3 Andreas Färber
                  name ? name : "null", value, min, max);
642 71ad61d3 Andreas Färber
        return;
643 71ad61d3 Andreas Färber
    }
644 71ad61d3 Andreas Färber
645 ed5e1ec3 Andreas Färber
    env->cpuid_version &= ~0xff00f00;
646 71ad61d3 Andreas Färber
    if (value > 0x0f) {
647 71ad61d3 Andreas Färber
        env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
648 ed5e1ec3 Andreas Färber
    } else {
649 71ad61d3 Andreas Färber
        env->cpuid_version |= value << 8;
650 ed5e1ec3 Andreas Färber
    }
651 ed5e1ec3 Andreas Färber
}
652 ed5e1ec3 Andreas Färber
653 67e30c83 Andreas Färber
static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
654 67e30c83 Andreas Färber
                                        const char *name, Error **errp)
655 67e30c83 Andreas Färber
{
656 67e30c83 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
657 67e30c83 Andreas Färber
    CPUX86State *env = &cpu->env;
658 67e30c83 Andreas Färber
    int64_t value;
659 67e30c83 Andreas Färber
660 67e30c83 Andreas Färber
    value = (env->cpuid_version >> 4) & 0xf;
661 67e30c83 Andreas Färber
    value |= ((env->cpuid_version >> 16) & 0xf) << 4;
662 67e30c83 Andreas Färber
    visit_type_int(v, &value, name, errp);
663 67e30c83 Andreas Färber
}
664 67e30c83 Andreas Färber
665 c5291a4f Andreas Färber
static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
666 c5291a4f Andreas Färber
                                        const char *name, Error **errp)
667 b0704cbd Andreas Färber
{
668 c5291a4f Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
669 c5291a4f Andreas Färber
    CPUX86State *env = &cpu->env;
670 c5291a4f Andreas Färber
    const int64_t min = 0;
671 c5291a4f Andreas Färber
    const int64_t max = 0xff;
672 c5291a4f Andreas Färber
    int64_t value;
673 c5291a4f Andreas Färber
674 c5291a4f Andreas Färber
    visit_type_int(v, &value, name, errp);
675 c5291a4f Andreas Färber
    if (error_is_set(errp)) {
676 c5291a4f Andreas Färber
        return;
677 c5291a4f Andreas Färber
    }
678 c5291a4f Andreas Färber
    if (value < min || value > max) {
679 c5291a4f Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
680 c5291a4f Andreas Färber
                  name ? name : "null", value, min, max);
681 c5291a4f Andreas Färber
        return;
682 c5291a4f Andreas Färber
    }
683 c5291a4f Andreas Färber
684 b0704cbd Andreas Färber
    env->cpuid_version &= ~0xf00f0;
685 c5291a4f Andreas Färber
    env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
686 b0704cbd Andreas Färber
}
687 b0704cbd Andreas Färber
688 35112e41 Andreas Färber
static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
689 35112e41 Andreas Färber
                                           void *opaque, const char *name,
690 35112e41 Andreas Färber
                                           Error **errp)
691 35112e41 Andreas Färber
{
692 35112e41 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
693 35112e41 Andreas Färber
    CPUX86State *env = &cpu->env;
694 35112e41 Andreas Färber
    int64_t value;
695 35112e41 Andreas Färber
696 35112e41 Andreas Färber
    value = env->cpuid_version & 0xf;
697 35112e41 Andreas Färber
    visit_type_int(v, &value, name, errp);
698 35112e41 Andreas Färber
}
699 35112e41 Andreas Färber
700 036e2222 Andreas Färber
static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
701 036e2222 Andreas Färber
                                           void *opaque, const char *name,
702 036e2222 Andreas Färber
                                           Error **errp)
703 38c3dc46 Andreas Färber
{
704 036e2222 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
705 036e2222 Andreas Färber
    CPUX86State *env = &cpu->env;
706 036e2222 Andreas Färber
    const int64_t min = 0;
707 036e2222 Andreas Färber
    const int64_t max = 0xf;
708 036e2222 Andreas Färber
    int64_t value;
709 036e2222 Andreas Färber
710 036e2222 Andreas Färber
    visit_type_int(v, &value, name, errp);
711 036e2222 Andreas Färber
    if (error_is_set(errp)) {
712 036e2222 Andreas Färber
        return;
713 036e2222 Andreas Färber
    }
714 036e2222 Andreas Färber
    if (value < min || value > max) {
715 036e2222 Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
716 036e2222 Andreas Färber
                  name ? name : "null", value, min, max);
717 036e2222 Andreas Färber
        return;
718 036e2222 Andreas Färber
    }
719 036e2222 Andreas Färber
720 38c3dc46 Andreas Färber
    env->cpuid_version &= ~0xf;
721 036e2222 Andreas Färber
    env->cpuid_version |= value & 0xf;
722 38c3dc46 Andreas Färber
}
723 38c3dc46 Andreas Färber
724 8e1898bf Andreas Färber
static void x86_cpuid_get_level(Object *obj, Visitor *v, void *opaque,
725 8e1898bf Andreas Färber
                                const char *name, Error **errp)
726 8e1898bf Andreas Färber
{
727 8e1898bf Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
728 8e1898bf Andreas Färber
729 fa029887 Andreas Färber
    visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
730 8e1898bf Andreas Färber
}
731 8e1898bf Andreas Färber
732 8e1898bf Andreas Färber
static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
733 8e1898bf Andreas Färber
                                const char *name, Error **errp)
734 8e1898bf Andreas Färber
{
735 8e1898bf Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
736 8e1898bf Andreas Färber
737 fa029887 Andreas Färber
    visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
738 8e1898bf Andreas Färber
}
739 8e1898bf Andreas Färber
740 16b93aa8 Andreas Färber
static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
741 16b93aa8 Andreas Färber
                                 const char *name, Error **errp)
742 16b93aa8 Andreas Färber
{
743 16b93aa8 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
744 16b93aa8 Andreas Färber
745 fa029887 Andreas Färber
    visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
746 16b93aa8 Andreas Färber
}
747 16b93aa8 Andreas Färber
748 16b93aa8 Andreas Färber
static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
749 16b93aa8 Andreas Färber
                                 const char *name, Error **errp)
750 16b93aa8 Andreas Färber
{
751 16b93aa8 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
752 16b93aa8 Andreas Färber
753 fa029887 Andreas Färber
    visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
754 16b93aa8 Andreas Färber
}
755 16b93aa8 Andreas Färber
756 d480e1af Andreas Färber
static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
757 d480e1af Andreas Färber
{
758 d480e1af Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
759 d480e1af Andreas Färber
    CPUX86State *env = &cpu->env;
760 d480e1af Andreas Färber
    char *value;
761 d480e1af Andreas Färber
    int i;
762 d480e1af Andreas Färber
763 d480e1af Andreas Färber
    value = (char *)g_malloc(12 + 1);
764 d480e1af Andreas Färber
    for (i = 0; i < 4; i++) {
765 d480e1af Andreas Färber
        value[i    ] = env->cpuid_vendor1 >> (8 * i);
766 d480e1af Andreas Färber
        value[i + 4] = env->cpuid_vendor2 >> (8 * i);
767 d480e1af Andreas Färber
        value[i + 8] = env->cpuid_vendor3 >> (8 * i);
768 d480e1af Andreas Färber
    }
769 d480e1af Andreas Färber
    value[12] = '\0';
770 d480e1af Andreas Färber
    return value;
771 d480e1af Andreas Färber
}
772 d480e1af Andreas Färber
773 d480e1af Andreas Färber
static void x86_cpuid_set_vendor(Object *obj, const char *value,
774 d480e1af Andreas Färber
                                 Error **errp)
775 d480e1af Andreas Färber
{
776 d480e1af Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
777 d480e1af Andreas Färber
    CPUX86State *env = &cpu->env;
778 d480e1af Andreas Färber
    int i;
779 d480e1af Andreas Färber
780 d480e1af Andreas Färber
    if (strlen(value) != 12) {
781 d480e1af Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
782 d480e1af Andreas Färber
                  "vendor", value);
783 d480e1af Andreas Färber
        return;
784 d480e1af Andreas Färber
    }
785 d480e1af Andreas Färber
786 d480e1af Andreas Färber
    env->cpuid_vendor1 = 0;
787 d480e1af Andreas Färber
    env->cpuid_vendor2 = 0;
788 d480e1af Andreas Färber
    env->cpuid_vendor3 = 0;
789 d480e1af Andreas Färber
    for (i = 0; i < 4; i++) {
790 d480e1af Andreas Färber
        env->cpuid_vendor1 |= ((uint8_t)value[i    ]) << (8 * i);
791 d480e1af Andreas Färber
        env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
792 d480e1af Andreas Färber
        env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
793 d480e1af Andreas Färber
    }
794 d480e1af Andreas Färber
    env->cpuid_vendor_override = 1;
795 d480e1af Andreas Färber
}
796 d480e1af Andreas Färber
797 63e886eb Andreas Färber
static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
798 63e886eb Andreas Färber
{
799 63e886eb Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
800 63e886eb Andreas Färber
    CPUX86State *env = &cpu->env;
801 63e886eb Andreas Färber
    char *value;
802 63e886eb Andreas Färber
    int i;
803 63e886eb Andreas Färber
804 63e886eb Andreas Färber
    value = g_malloc(48 + 1);
805 63e886eb Andreas Färber
    for (i = 0; i < 48; i++) {
806 63e886eb Andreas Färber
        value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
807 63e886eb Andreas Färber
    }
808 63e886eb Andreas Färber
    value[48] = '\0';
809 63e886eb Andreas Färber
    return value;
810 63e886eb Andreas Färber
}
811 63e886eb Andreas Färber
812 938d4c25 Andreas Färber
static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
813 938d4c25 Andreas Färber
                                   Error **errp)
814 dcce6675 Andreas Färber
{
815 938d4c25 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
816 938d4c25 Andreas Färber
    CPUX86State *env = &cpu->env;
817 dcce6675 Andreas Färber
    int c, len, i;
818 dcce6675 Andreas Färber
819 dcce6675 Andreas Färber
    if (model_id == NULL) {
820 dcce6675 Andreas Färber
        model_id = "";
821 dcce6675 Andreas Färber
    }
822 dcce6675 Andreas Färber
    len = strlen(model_id);
823 d0a6acf4 Andreas Färber
    memset(env->cpuid_model, 0, 48);
824 dcce6675 Andreas Färber
    for (i = 0; i < 48; i++) {
825 dcce6675 Andreas Färber
        if (i >= len) {
826 dcce6675 Andreas Färber
            c = '\0';
827 dcce6675 Andreas Färber
        } else {
828 dcce6675 Andreas Färber
            c = (uint8_t)model_id[i];
829 dcce6675 Andreas Färber
        }
830 dcce6675 Andreas Färber
        env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
831 dcce6675 Andreas Färber
    }
832 dcce6675 Andreas Färber
}
833 dcce6675 Andreas Färber
834 89e48965 Andreas Färber
static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
835 89e48965 Andreas Färber
                                   const char *name, Error **errp)
836 89e48965 Andreas Färber
{
837 89e48965 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
838 89e48965 Andreas Färber
    int64_t value;
839 89e48965 Andreas Färber
840 89e48965 Andreas Färber
    value = cpu->env.tsc_khz * 1000;
841 89e48965 Andreas Färber
    visit_type_int(v, &value, name, errp);
842 89e48965 Andreas Färber
}
843 89e48965 Andreas Färber
844 89e48965 Andreas Färber
static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
845 89e48965 Andreas Färber
                                   const char *name, Error **errp)
846 89e48965 Andreas Färber
{
847 89e48965 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
848 89e48965 Andreas Färber
    const int64_t min = 0;
849 89e48965 Andreas Färber
    const int64_t max = INT_MAX;
850 89e48965 Andreas Färber
    int64_t value;
851 89e48965 Andreas Färber
852 89e48965 Andreas Färber
    visit_type_int(v, &value, name, errp);
853 89e48965 Andreas Färber
    if (error_is_set(errp)) {
854 89e48965 Andreas Färber
        return;
855 89e48965 Andreas Färber
    }
856 89e48965 Andreas Färber
    if (value < min || value > max) {
857 89e48965 Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
858 89e48965 Andreas Färber
                  name ? name : "null", value, min, max);
859 89e48965 Andreas Färber
        return;
860 89e48965 Andreas Färber
    }
861 89e48965 Andreas Färber
862 89e48965 Andreas Färber
    cpu->env.tsc_khz = value / 1000;
863 89e48965 Andreas Färber
}
864 89e48965 Andreas Färber
865 c6dc6f63 Andre Przywara
static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
866 c6dc6f63 Andre Przywara
{
867 c6dc6f63 Andre Przywara
    unsigned int i;
868 c6dc6f63 Andre Przywara
    x86_def_t *def;
869 c6dc6f63 Andre Przywara
870 d3c481b3 Markus Armbruster
    char *s = g_strdup(cpu_model);
871 c6dc6f63 Andre Przywara
    char *featurestr, *name = strtok(s, ",");
872 296acb64 Joerg Roedel
    /* Features to be added*/
873 296acb64 Joerg Roedel
    uint32_t plus_features = 0, plus_ext_features = 0;
874 296acb64 Joerg Roedel
    uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
875 296acb64 Joerg Roedel
    uint32_t plus_kvm_features = 0, plus_svm_features = 0;
876 296acb64 Joerg Roedel
    /* Features to be removed */
877 296acb64 Joerg Roedel
    uint32_t minus_features = 0, minus_ext_features = 0;
878 296acb64 Joerg Roedel
    uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
879 296acb64 Joerg Roedel
    uint32_t minus_kvm_features = 0, minus_svm_features = 0;
880 c6dc6f63 Andre Przywara
    uint32_t numvalue;
881 c6dc6f63 Andre Przywara
882 c6dc6f63 Andre Przywara
    for (def = x86_defs; def; def = def->next)
883 04c5b17a Markus Armbruster
        if (name && !strcmp(name, def->name))
884 c6dc6f63 Andre Przywara
            break;
885 04c5b17a Markus Armbruster
    if (kvm_enabled() && name && strcmp(name, "host") == 0) {
886 c6dc6f63 Andre Przywara
        cpu_x86_fill_host(x86_cpu_def);
887 c6dc6f63 Andre Przywara
    } else if (!def) {
888 c6dc6f63 Andre Przywara
        goto error;
889 c6dc6f63 Andre Przywara
    } else {
890 c6dc6f63 Andre Przywara
        memcpy(x86_cpu_def, def, sizeof(*def));
891 c6dc6f63 Andre Przywara
    }
892 c6dc6f63 Andre Przywara
893 ef8621b1 Anthony Liguori
#if defined(CONFIG_KVM)
894 ef8621b1 Anthony Liguori
    plus_kvm_features = (1 << KVM_FEATURE_CLOCKSOURCE) |
895 ef8621b1 Anthony Liguori
        (1 << KVM_FEATURE_NOP_IO_DELAY) | 
896 ef8621b1 Anthony Liguori
        (1 << KVM_FEATURE_MMU_OP) |
897 ef8621b1 Anthony Liguori
        (1 << KVM_FEATURE_CLOCKSOURCE2) |
898 ef8621b1 Anthony Liguori
        (1 << KVM_FEATURE_ASYNC_PF) | 
899 ef8621b1 Anthony Liguori
        (1 << KVM_FEATURE_STEAL_TIME) |
900 ef8621b1 Anthony Liguori
        (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
901 ef8621b1 Anthony Liguori
#else
902 ef8621b1 Anthony Liguori
    plus_kvm_features = 0;
903 ef8621b1 Anthony Liguori
#endif
904 c6dc6f63 Andre Przywara
905 c6dc6f63 Andre Przywara
    add_flagname_to_bitmaps("hypervisor", &plus_features,
906 c6dc6f63 Andre Przywara
        &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
907 296acb64 Joerg Roedel
        &plus_kvm_features, &plus_svm_features);
908 c6dc6f63 Andre Przywara
909 c6dc6f63 Andre Przywara
    featurestr = strtok(NULL, ",");
910 c6dc6f63 Andre Przywara
911 c6dc6f63 Andre Przywara
    while (featurestr) {
912 c6dc6f63 Andre Przywara
        char *val;
913 c6dc6f63 Andre Przywara
        if (featurestr[0] == '+') {
914 296acb64 Joerg Roedel
            add_flagname_to_bitmaps(featurestr + 1, &plus_features,
915 296acb64 Joerg Roedel
                            &plus_ext_features, &plus_ext2_features,
916 296acb64 Joerg Roedel
                            &plus_ext3_features, &plus_kvm_features,
917 296acb64 Joerg Roedel
                            &plus_svm_features);
918 c6dc6f63 Andre Przywara
        } else if (featurestr[0] == '-') {
919 296acb64 Joerg Roedel
            add_flagname_to_bitmaps(featurestr + 1, &minus_features,
920 296acb64 Joerg Roedel
                            &minus_ext_features, &minus_ext2_features,
921 296acb64 Joerg Roedel
                            &minus_ext3_features, &minus_kvm_features,
922 296acb64 Joerg Roedel
                            &minus_svm_features);
923 c6dc6f63 Andre Przywara
        } else if ((val = strchr(featurestr, '='))) {
924 c6dc6f63 Andre Przywara
            *val = 0; val++;
925 c6dc6f63 Andre Przywara
            if (!strcmp(featurestr, "family")) {
926 c6dc6f63 Andre Przywara
                char *err;
927 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
928 a88a677f Andreas Färber
                if (!*val || *err || numvalue > 0xff + 0xf) {
929 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
930 c6dc6f63 Andre Przywara
                    goto error;
931 c6dc6f63 Andre Przywara
                }
932 c6dc6f63 Andre Przywara
                x86_cpu_def->family = numvalue;
933 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "model")) {
934 c6dc6f63 Andre Przywara
                char *err;
935 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
936 c6dc6f63 Andre Przywara
                if (!*val || *err || numvalue > 0xff) {
937 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
938 c6dc6f63 Andre Przywara
                    goto error;
939 c6dc6f63 Andre Przywara
                }
940 c6dc6f63 Andre Przywara
                x86_cpu_def->model = numvalue;
941 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "stepping")) {
942 c6dc6f63 Andre Przywara
                char *err;
943 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
944 c6dc6f63 Andre Przywara
                if (!*val || *err || numvalue > 0xf) {
945 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
946 c6dc6f63 Andre Przywara
                    goto error;
947 c6dc6f63 Andre Przywara
                }
948 c6dc6f63 Andre Przywara
                x86_cpu_def->stepping = numvalue ;
949 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "level")) {
950 c6dc6f63 Andre Przywara
                char *err;
951 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
952 c6dc6f63 Andre Przywara
                if (!*val || *err) {
953 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
954 c6dc6f63 Andre Przywara
                    goto error;
955 c6dc6f63 Andre Przywara
                }
956 c6dc6f63 Andre Przywara
                x86_cpu_def->level = numvalue;
957 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "xlevel")) {
958 c6dc6f63 Andre Przywara
                char *err;
959 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
960 c6dc6f63 Andre Przywara
                if (!*val || *err) {
961 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
962 c6dc6f63 Andre Przywara
                    goto error;
963 c6dc6f63 Andre Przywara
                }
964 c6dc6f63 Andre Przywara
                if (numvalue < 0x80000000) {
965 2f7a21c4 Aurelien Jarno
                    numvalue += 0x80000000;
966 c6dc6f63 Andre Przywara
                }
967 c6dc6f63 Andre Przywara
                x86_cpu_def->xlevel = numvalue;
968 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "vendor")) {
969 c6dc6f63 Andre Przywara
                if (strlen(val) != 12) {
970 c6dc6f63 Andre Przywara
                    fprintf(stderr, "vendor string must be 12 chars long\n");
971 c6dc6f63 Andre Przywara
                    goto error;
972 c6dc6f63 Andre Przywara
                }
973 c6dc6f63 Andre Przywara
                x86_cpu_def->vendor1 = 0;
974 c6dc6f63 Andre Przywara
                x86_cpu_def->vendor2 = 0;
975 c6dc6f63 Andre Przywara
                x86_cpu_def->vendor3 = 0;
976 c6dc6f63 Andre Przywara
                for(i = 0; i < 4; i++) {
977 c6dc6f63 Andre Przywara
                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
978 c6dc6f63 Andre Przywara
                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
979 c6dc6f63 Andre Przywara
                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
980 c6dc6f63 Andre Przywara
                }
981 c6dc6f63 Andre Przywara
                x86_cpu_def->vendor_override = 1;
982 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "model_id")) {
983 c6dc6f63 Andre Przywara
                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
984 c6dc6f63 Andre Przywara
                        val);
985 b862d1fe Joerg Roedel
            } else if (!strcmp(featurestr, "tsc_freq")) {
986 b862d1fe Joerg Roedel
                int64_t tsc_freq;
987 b862d1fe Joerg Roedel
                char *err;
988 b862d1fe Joerg Roedel
989 b862d1fe Joerg Roedel
                tsc_freq = strtosz_suffix_unit(val, &err,
990 b862d1fe Joerg Roedel
                                               STRTOSZ_DEFSUFFIX_B, 1000);
991 45009a30 Markus Armbruster
                if (tsc_freq < 0 || *err) {
992 b862d1fe Joerg Roedel
                    fprintf(stderr, "bad numerical value %s\n", val);
993 b862d1fe Joerg Roedel
                    goto error;
994 b862d1fe Joerg Roedel
                }
995 b862d1fe Joerg Roedel
                x86_cpu_def->tsc_khz = tsc_freq / 1000;
996 28f52cc0 Vadim Rozenfeld
            } else if (!strcmp(featurestr, "hv_spinlocks")) {
997 28f52cc0 Vadim Rozenfeld
                char *err;
998 28f52cc0 Vadim Rozenfeld
                numvalue = strtoul(val, &err, 0);
999 28f52cc0 Vadim Rozenfeld
                if (!*val || *err) {
1000 28f52cc0 Vadim Rozenfeld
                    fprintf(stderr, "bad numerical value %s\n", val);
1001 28f52cc0 Vadim Rozenfeld
                    goto error;
1002 28f52cc0 Vadim Rozenfeld
                }
1003 28f52cc0 Vadim Rozenfeld
                hyperv_set_spinlock_retries(numvalue);
1004 c6dc6f63 Andre Przywara
            } else {
1005 c6dc6f63 Andre Przywara
                fprintf(stderr, "unrecognized feature %s\n", featurestr);
1006 c6dc6f63 Andre Przywara
                goto error;
1007 c6dc6f63 Andre Przywara
            }
1008 c6dc6f63 Andre Przywara
        } else if (!strcmp(featurestr, "check")) {
1009 c6dc6f63 Andre Przywara
            check_cpuid = 1;
1010 c6dc6f63 Andre Przywara
        } else if (!strcmp(featurestr, "enforce")) {
1011 c6dc6f63 Andre Przywara
            check_cpuid = enforce_cpuid = 1;
1012 28f52cc0 Vadim Rozenfeld
        } else if (!strcmp(featurestr, "hv_relaxed")) {
1013 28f52cc0 Vadim Rozenfeld
            hyperv_enable_relaxed_timing(true);
1014 28f52cc0 Vadim Rozenfeld
        } else if (!strcmp(featurestr, "hv_vapic")) {
1015 28f52cc0 Vadim Rozenfeld
            hyperv_enable_vapic_recommended(true);
1016 c6dc6f63 Andre Przywara
        } else {
1017 c6dc6f63 Andre Przywara
            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
1018 c6dc6f63 Andre Przywara
            goto error;
1019 c6dc6f63 Andre Przywara
        }
1020 c6dc6f63 Andre Przywara
        featurestr = strtok(NULL, ",");
1021 c6dc6f63 Andre Przywara
    }
1022 c6dc6f63 Andre Przywara
    x86_cpu_def->features |= plus_features;
1023 c6dc6f63 Andre Przywara
    x86_cpu_def->ext_features |= plus_ext_features;
1024 c6dc6f63 Andre Przywara
    x86_cpu_def->ext2_features |= plus_ext2_features;
1025 c6dc6f63 Andre Przywara
    x86_cpu_def->ext3_features |= plus_ext3_features;
1026 c6dc6f63 Andre Przywara
    x86_cpu_def->kvm_features |= plus_kvm_features;
1027 296acb64 Joerg Roedel
    x86_cpu_def->svm_features |= plus_svm_features;
1028 c6dc6f63 Andre Przywara
    x86_cpu_def->features &= ~minus_features;
1029 c6dc6f63 Andre Przywara
    x86_cpu_def->ext_features &= ~minus_ext_features;
1030 c6dc6f63 Andre Przywara
    x86_cpu_def->ext2_features &= ~minus_ext2_features;
1031 c6dc6f63 Andre Przywara
    x86_cpu_def->ext3_features &= ~minus_ext3_features;
1032 c6dc6f63 Andre Przywara
    x86_cpu_def->kvm_features &= ~minus_kvm_features;
1033 296acb64 Joerg Roedel
    x86_cpu_def->svm_features &= ~minus_svm_features;
1034 c6dc6f63 Andre Przywara
    if (check_cpuid) {
1035 c6dc6f63 Andre Przywara
        if (check_features_against_host(x86_cpu_def) && enforce_cpuid)
1036 c6dc6f63 Andre Przywara
            goto error;
1037 c6dc6f63 Andre Przywara
    }
1038 d3c481b3 Markus Armbruster
    g_free(s);
1039 c6dc6f63 Andre Przywara
    return 0;
1040 c6dc6f63 Andre Przywara
1041 c6dc6f63 Andre Przywara
error:
1042 d3c481b3 Markus Armbruster
    g_free(s);
1043 c6dc6f63 Andre Przywara
    return -1;
1044 c6dc6f63 Andre Przywara
}
1045 c6dc6f63 Andre Przywara
1046 c6dc6f63 Andre Przywara
/* generate a composite string into buf of all cpuid names in featureset
1047 c6dc6f63 Andre Przywara
 * selected by fbits.  indicate truncation at bufsize in the event of overflow.
1048 c6dc6f63 Andre Przywara
 * if flags, suppress names undefined in featureset.
1049 c6dc6f63 Andre Przywara
 */
1050 c6dc6f63 Andre Przywara
static void listflags(char *buf, int bufsize, uint32_t fbits,
1051 c6dc6f63 Andre Przywara
    const char **featureset, uint32_t flags)
1052 c6dc6f63 Andre Przywara
{
1053 c6dc6f63 Andre Przywara
    const char **p = &featureset[31];
1054 c6dc6f63 Andre Przywara
    char *q, *b, bit;
1055 c6dc6f63 Andre Przywara
    int nc;
1056 c6dc6f63 Andre Przywara
1057 c6dc6f63 Andre Przywara
    b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1058 c6dc6f63 Andre Przywara
    *buf = '\0';
1059 c6dc6f63 Andre Przywara
    for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1060 c6dc6f63 Andre Przywara
        if (fbits & 1 << bit && (*p || !flags)) {
1061 c6dc6f63 Andre Przywara
            if (*p)
1062 c6dc6f63 Andre Przywara
                nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1063 c6dc6f63 Andre Przywara
            else
1064 c6dc6f63 Andre Przywara
                nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1065 c6dc6f63 Andre Przywara
            if (bufsize <= nc) {
1066 c6dc6f63 Andre Przywara
                if (b) {
1067 c6dc6f63 Andre Przywara
                    memcpy(b, "...", sizeof("..."));
1068 c6dc6f63 Andre Przywara
                }
1069 c6dc6f63 Andre Przywara
                return;
1070 c6dc6f63 Andre Przywara
            }
1071 c6dc6f63 Andre Przywara
            q += nc;
1072 c6dc6f63 Andre Przywara
            bufsize -= nc;
1073 c6dc6f63 Andre Przywara
        }
1074 c6dc6f63 Andre Przywara
}
1075 c6dc6f63 Andre Przywara
1076 c6dc6f63 Andre Przywara
/* generate CPU information:
1077 c6dc6f63 Andre Przywara
 * -?        list model names
1078 c6dc6f63 Andre Przywara
 * -?model   list model names/IDs
1079 c6dc6f63 Andre Przywara
 * -?dump    output all model (x86_def_t) data
1080 c6dc6f63 Andre Przywara
 * -?cpuid   list all recognized cpuid flag names
1081 c6dc6f63 Andre Przywara
 */
1082 9a78eead Stefan Weil
void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
1083 c6dc6f63 Andre Przywara
{
1084 c6dc6f63 Andre Przywara
    unsigned char model = !strcmp("?model", optarg);
1085 c6dc6f63 Andre Przywara
    unsigned char dump = !strcmp("?dump", optarg);
1086 c6dc6f63 Andre Przywara
    unsigned char cpuid = !strcmp("?cpuid", optarg);
1087 c6dc6f63 Andre Przywara
    x86_def_t *def;
1088 c6dc6f63 Andre Przywara
    char buf[256];
1089 c6dc6f63 Andre Przywara
1090 c6dc6f63 Andre Przywara
    if (cpuid) {
1091 c6dc6f63 Andre Przywara
        (*cpu_fprintf)(f, "Recognized CPUID flags:\n");
1092 c6dc6f63 Andre Przywara
        listflags(buf, sizeof (buf), (uint32_t)~0, feature_name, 1);
1093 c6dc6f63 Andre Przywara
        (*cpu_fprintf)(f, "  f_edx: %s\n", buf);
1094 c6dc6f63 Andre Przywara
        listflags(buf, sizeof (buf), (uint32_t)~0, ext_feature_name, 1);
1095 c6dc6f63 Andre Przywara
        (*cpu_fprintf)(f, "  f_ecx: %s\n", buf);
1096 c6dc6f63 Andre Przywara
        listflags(buf, sizeof (buf), (uint32_t)~0, ext2_feature_name, 1);
1097 c6dc6f63 Andre Przywara
        (*cpu_fprintf)(f, "  extf_edx: %s\n", buf);
1098 c6dc6f63 Andre Przywara
        listflags(buf, sizeof (buf), (uint32_t)~0, ext3_feature_name, 1);
1099 c6dc6f63 Andre Przywara
        (*cpu_fprintf)(f, "  extf_ecx: %s\n", buf);
1100 c6dc6f63 Andre Przywara
        return;
1101 c6dc6f63 Andre Przywara
    }
1102 c6dc6f63 Andre Przywara
    for (def = x86_defs; def; def = def->next) {
1103 c6dc6f63 Andre Przywara
        snprintf(buf, sizeof (buf), def->flags ? "[%s]": "%s", def->name);
1104 c6dc6f63 Andre Przywara
        if (model || dump) {
1105 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "x86 %16s  %-48s\n", buf, def->model_id);
1106 c6dc6f63 Andre Przywara
        } else {
1107 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "x86 %16s\n", buf);
1108 c6dc6f63 Andre Przywara
        }
1109 c6dc6f63 Andre Przywara
        if (dump) {
1110 c6dc6f63 Andre Przywara
            memcpy(buf, &def->vendor1, sizeof (def->vendor1));
1111 c6dc6f63 Andre Przywara
            memcpy(buf + 4, &def->vendor2, sizeof (def->vendor2));
1112 c6dc6f63 Andre Przywara
            memcpy(buf + 8, &def->vendor3, sizeof (def->vendor3));
1113 c6dc6f63 Andre Przywara
            buf[12] = '\0';
1114 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f,
1115 c6dc6f63 Andre Przywara
                "  family %d model %d stepping %d level %d xlevel 0x%x"
1116 c6dc6f63 Andre Przywara
                " vendor \"%s\"\n",
1117 c6dc6f63 Andre Przywara
                def->family, def->model, def->stepping, def->level,
1118 c6dc6f63 Andre Przywara
                def->xlevel, buf);
1119 c6dc6f63 Andre Przywara
            listflags(buf, sizeof (buf), def->features, feature_name, 0);
1120 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "  feature_edx %08x (%s)\n", def->features,
1121 c6dc6f63 Andre Przywara
                buf);
1122 c6dc6f63 Andre Przywara
            listflags(buf, sizeof (buf), def->ext_features, ext_feature_name,
1123 c6dc6f63 Andre Przywara
                0);
1124 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "  feature_ecx %08x (%s)\n", def->ext_features,
1125 c6dc6f63 Andre Przywara
                buf);
1126 c6dc6f63 Andre Przywara
            listflags(buf, sizeof (buf), def->ext2_features, ext2_feature_name,
1127 c6dc6f63 Andre Przywara
                0);
1128 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "  extfeature_edx %08x (%s)\n",
1129 c6dc6f63 Andre Przywara
                def->ext2_features, buf);
1130 c6dc6f63 Andre Przywara
            listflags(buf, sizeof (buf), def->ext3_features, ext3_feature_name,
1131 c6dc6f63 Andre Przywara
                0);
1132 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "  extfeature_ecx %08x (%s)\n",
1133 c6dc6f63 Andre Przywara
                def->ext3_features, buf);
1134 c6dc6f63 Andre Przywara
            (*cpu_fprintf)(f, "\n");
1135 c6dc6f63 Andre Przywara
        }
1136 c6dc6f63 Andre Przywara
    }
1137 ed2c54d4 Andre Przywara
    if (kvm_enabled()) {
1138 ed2c54d4 Andre Przywara
        (*cpu_fprintf)(f, "x86 %16s\n", "[host]");
1139 ed2c54d4 Andre Przywara
    }
1140 c6dc6f63 Andre Przywara
}
1141 c6dc6f63 Andre Przywara
1142 76b64a7a Anthony Liguori
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
1143 e3966126 Anthony Liguori
{
1144 e3966126 Anthony Liguori
    CpuDefinitionInfoList *cpu_list = NULL;
1145 e3966126 Anthony Liguori
    x86_def_t *def;
1146 e3966126 Anthony Liguori
1147 e3966126 Anthony Liguori
    for (def = x86_defs; def; def = def->next) {
1148 e3966126 Anthony Liguori
        CpuDefinitionInfoList *entry;
1149 e3966126 Anthony Liguori
        CpuDefinitionInfo *info;
1150 e3966126 Anthony Liguori
1151 e3966126 Anthony Liguori
        info = g_malloc0(sizeof(*info));
1152 e3966126 Anthony Liguori
        info->name = g_strdup(def->name);
1153 e3966126 Anthony Liguori
1154 e3966126 Anthony Liguori
        entry = g_malloc0(sizeof(*entry));
1155 e3966126 Anthony Liguori
        entry->value = info;
1156 e3966126 Anthony Liguori
        entry->next = cpu_list;
1157 e3966126 Anthony Liguori
        cpu_list = entry;
1158 e3966126 Anthony Liguori
    }
1159 e3966126 Anthony Liguori
1160 e3966126 Anthony Liguori
    return cpu_list;
1161 e3966126 Anthony Liguori
}
1162 e3966126 Anthony Liguori
1163 61dcd775 Andreas Färber
int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
1164 c6dc6f63 Andre Przywara
{
1165 61dcd775 Andreas Färber
    CPUX86State *env = &cpu->env;
1166 c6dc6f63 Andre Przywara
    x86_def_t def1, *def = &def1;
1167 71ad61d3 Andreas Färber
    Error *error = NULL;
1168 c6dc6f63 Andre Przywara
1169 db0ad1ba Joerg Roedel
    memset(def, 0, sizeof(*def));
1170 db0ad1ba Joerg Roedel
1171 c6dc6f63 Andre Przywara
    if (cpu_x86_find_by_name(def, cpu_model) < 0)
1172 c6dc6f63 Andre Przywara
        return -1;
1173 c6dc6f63 Andre Przywara
    if (def->vendor1) {
1174 c6dc6f63 Andre Przywara
        env->cpuid_vendor1 = def->vendor1;
1175 c6dc6f63 Andre Przywara
        env->cpuid_vendor2 = def->vendor2;
1176 c6dc6f63 Andre Przywara
        env->cpuid_vendor3 = def->vendor3;
1177 c6dc6f63 Andre Przywara
    } else {
1178 c6dc6f63 Andre Przywara
        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
1179 c6dc6f63 Andre Przywara
        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
1180 c6dc6f63 Andre Przywara
        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
1181 c6dc6f63 Andre Przywara
    }
1182 c6dc6f63 Andre Przywara
    env->cpuid_vendor_override = def->vendor_override;
1183 8e1898bf Andreas Färber
    object_property_set_int(OBJECT(cpu), def->level, "level", &error);
1184 71ad61d3 Andreas Färber
    object_property_set_int(OBJECT(cpu), def->family, "family", &error);
1185 c5291a4f Andreas Färber
    object_property_set_int(OBJECT(cpu), def->model, "model", &error);
1186 036e2222 Andreas Färber
    object_property_set_int(OBJECT(cpu), def->stepping, "stepping", &error);
1187 c6dc6f63 Andre Przywara
    env->cpuid_features = def->features;
1188 c6dc6f63 Andre Przywara
    env->cpuid_ext_features = def->ext_features;
1189 c6dc6f63 Andre Przywara
    env->cpuid_ext2_features = def->ext2_features;
1190 4d067ed7 Andre Przywara
    env->cpuid_ext3_features = def->ext3_features;
1191 16b93aa8 Andreas Färber
    object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", &error);
1192 c6dc6f63 Andre Przywara
    env->cpuid_kvm_features = def->kvm_features;
1193 296acb64 Joerg Roedel
    env->cpuid_svm_features = def->svm_features;
1194 b3baa152 brillywu@viatech.com.cn
    env->cpuid_ext4_features = def->ext4_features;
1195 13526728 Eduardo Habkost
    env->cpuid_7_0_ebx = def->cpuid_7_0_ebx_features;
1196 b3baa152 brillywu@viatech.com.cn
    env->cpuid_xlevel2 = def->xlevel2;
1197 89e48965 Andreas Färber
    object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000,
1198 89e48965 Andreas Färber
                            "tsc-frequency", &error);
1199 551a2dec Andre Przywara
    if (!kvm_enabled()) {
1200 551a2dec Andre Przywara
        env->cpuid_features &= TCG_FEATURES;
1201 551a2dec Andre Przywara
        env->cpuid_ext_features &= TCG_EXT_FEATURES;
1202 551a2dec Andre Przywara
        env->cpuid_ext2_features &= (TCG_EXT2_FEATURES
1203 551a2dec Andre Przywara
#ifdef TARGET_X86_64
1204 551a2dec Andre Przywara
            | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
1205 551a2dec Andre Przywara
#endif
1206 551a2dec Andre Przywara
            );
1207 551a2dec Andre Przywara
        env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
1208 296acb64 Joerg Roedel
        env->cpuid_svm_features &= TCG_SVM_FEATURES;
1209 551a2dec Andre Przywara
    }
1210 938d4c25 Andreas Färber
    object_property_set_str(OBJECT(cpu), def->model_id, "model-id", &error);
1211 71ad61d3 Andreas Färber
    if (error_is_set(&error)) {
1212 71ad61d3 Andreas Färber
        error_free(error);
1213 71ad61d3 Andreas Färber
        return -1;
1214 71ad61d3 Andreas Färber
    }
1215 c6dc6f63 Andre Przywara
    return 0;
1216 c6dc6f63 Andre Przywara
}
1217 c6dc6f63 Andre Przywara
1218 c6dc6f63 Andre Przywara
#if !defined(CONFIG_USER_ONLY)
1219 c6dc6f63 Andre Przywara
/* copy vendor id string to 32 bit register, nul pad as needed
1220 c6dc6f63 Andre Przywara
 */
1221 c6dc6f63 Andre Przywara
static void cpyid(const char *s, uint32_t *id)
1222 c6dc6f63 Andre Przywara
{
1223 c6dc6f63 Andre Przywara
    char *d = (char *)id;
1224 c6dc6f63 Andre Przywara
    char i;
1225 c6dc6f63 Andre Przywara
1226 c6dc6f63 Andre Przywara
    for (i = sizeof (*id); i--; )
1227 c6dc6f63 Andre Przywara
        *d++ = *s ? *s++ : '\0';
1228 c6dc6f63 Andre Przywara
}
1229 c6dc6f63 Andre Przywara
1230 c6dc6f63 Andre Przywara
/* interpret radix and convert from string to arbitrary scalar,
1231 c6dc6f63 Andre Przywara
 * otherwise flag failure
1232 c6dc6f63 Andre Przywara
 */
1233 c6dc6f63 Andre Przywara
#define setscalar(pval, str, perr)                      \
1234 c6dc6f63 Andre Przywara
{                                                       \
1235 c6dc6f63 Andre Przywara
    char *pend;                                         \
1236 c6dc6f63 Andre Przywara
    unsigned long ul;                                   \
1237 c6dc6f63 Andre Przywara
                                                        \
1238 c6dc6f63 Andre Przywara
    ul = strtoul(str, &pend, 0);                        \
1239 c6dc6f63 Andre Przywara
    *str && !*pend ? (*pval = ul) : (*perr = 1);        \
1240 c6dc6f63 Andre Przywara
}
1241 c6dc6f63 Andre Przywara
1242 c6dc6f63 Andre Przywara
/* map cpuid options to feature bits, otherwise return failure
1243 c6dc6f63 Andre Przywara
 * (option tags in *str are delimited by whitespace)
1244 c6dc6f63 Andre Przywara
 */
1245 c6dc6f63 Andre Przywara
static void setfeatures(uint32_t *pval, const char *str,
1246 c6dc6f63 Andre Przywara
    const char **featureset, int *perr)
1247 c6dc6f63 Andre Przywara
{
1248 c6dc6f63 Andre Przywara
    const char *p, *q;
1249 c6dc6f63 Andre Przywara
1250 c6dc6f63 Andre Przywara
    for (q = p = str; *p || *q; q = p) {
1251 c6dc6f63 Andre Przywara
        while (iswhite(*p))
1252 c6dc6f63 Andre Przywara
            q = ++p;
1253 c6dc6f63 Andre Przywara
        while (*p && !iswhite(*p))
1254 c6dc6f63 Andre Przywara
            ++p;
1255 c6dc6f63 Andre Przywara
        if (!*q && !*p)
1256 c6dc6f63 Andre Przywara
            return;
1257 c6dc6f63 Andre Przywara
        if (!lookup_feature(pval, q, p, featureset)) {
1258 c6dc6f63 Andre Przywara
            fprintf(stderr, "error: feature \"%.*s\" not available in set\n",
1259 c6dc6f63 Andre Przywara
                (int)(p - q), q);
1260 c6dc6f63 Andre Przywara
            *perr = 1;
1261 c6dc6f63 Andre Przywara
            return;
1262 c6dc6f63 Andre Przywara
        }
1263 c6dc6f63 Andre Przywara
    }
1264 c6dc6f63 Andre Przywara
}
1265 c6dc6f63 Andre Przywara
1266 c6dc6f63 Andre Przywara
/* map config file options to x86_def_t form
1267 c6dc6f63 Andre Przywara
 */
1268 c6dc6f63 Andre Przywara
static int cpudef_setfield(const char *name, const char *str, void *opaque)
1269 c6dc6f63 Andre Przywara
{
1270 c6dc6f63 Andre Przywara
    x86_def_t *def = opaque;
1271 c6dc6f63 Andre Przywara
    int err = 0;
1272 c6dc6f63 Andre Przywara
1273 c6dc6f63 Andre Przywara
    if (!strcmp(name, "name")) {
1274 99e1dec0 Markus Armbruster
        g_free((void *)def->name);
1275 d3c481b3 Markus Armbruster
        def->name = g_strdup(str);
1276 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "model_id")) {
1277 c6dc6f63 Andre Przywara
        strncpy(def->model_id, str, sizeof (def->model_id));
1278 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "level")) {
1279 c6dc6f63 Andre Przywara
        setscalar(&def->level, str, &err)
1280 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "vendor")) {
1281 c6dc6f63 Andre Przywara
        cpyid(&str[0], &def->vendor1);
1282 c6dc6f63 Andre Przywara
        cpyid(&str[4], &def->vendor2);
1283 c6dc6f63 Andre Przywara
        cpyid(&str[8], &def->vendor3);
1284 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "family")) {
1285 c6dc6f63 Andre Przywara
        setscalar(&def->family, str, &err)
1286 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "model")) {
1287 c6dc6f63 Andre Przywara
        setscalar(&def->model, str, &err)
1288 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "stepping")) {
1289 c6dc6f63 Andre Przywara
        setscalar(&def->stepping, str, &err)
1290 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "feature_edx")) {
1291 c6dc6f63 Andre Przywara
        setfeatures(&def->features, str, feature_name, &err);
1292 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "feature_ecx")) {
1293 c6dc6f63 Andre Przywara
        setfeatures(&def->ext_features, str, ext_feature_name, &err);
1294 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "extfeature_edx")) {
1295 c6dc6f63 Andre Przywara
        setfeatures(&def->ext2_features, str, ext2_feature_name, &err);
1296 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "extfeature_ecx")) {
1297 c6dc6f63 Andre Przywara
        setfeatures(&def->ext3_features, str, ext3_feature_name, &err);
1298 c6dc6f63 Andre Przywara
    } else if (!strcmp(name, "xlevel")) {
1299 c6dc6f63 Andre Przywara
        setscalar(&def->xlevel, str, &err)
1300 c6dc6f63 Andre Przywara
    } else {
1301 c6dc6f63 Andre Przywara
        fprintf(stderr, "error: unknown option [%s = %s]\n", name, str);
1302 c6dc6f63 Andre Przywara
        return (1);
1303 c6dc6f63 Andre Przywara
    }
1304 c6dc6f63 Andre Przywara
    if (err) {
1305 c6dc6f63 Andre Przywara
        fprintf(stderr, "error: bad option value [%s = %s]\n", name, str);
1306 c6dc6f63 Andre Przywara
        return (1);
1307 c6dc6f63 Andre Przywara
    }
1308 c6dc6f63 Andre Przywara
    return (0);
1309 c6dc6f63 Andre Przywara
}
1310 c6dc6f63 Andre Przywara
1311 c6dc6f63 Andre Przywara
/* register config file entry as x86_def_t
1312 c6dc6f63 Andre Przywara
 */
1313 c6dc6f63 Andre Przywara
static int cpudef_register(QemuOpts *opts, void *opaque)
1314 c6dc6f63 Andre Przywara
{
1315 7267c094 Anthony Liguori
    x86_def_t *def = g_malloc0(sizeof (x86_def_t));
1316 c6dc6f63 Andre Przywara
1317 c6dc6f63 Andre Przywara
    qemu_opt_foreach(opts, cpudef_setfield, def, 1);
1318 c6dc6f63 Andre Przywara
    def->next = x86_defs;
1319 c6dc6f63 Andre Przywara
    x86_defs = def;
1320 c6dc6f63 Andre Przywara
    return (0);
1321 c6dc6f63 Andre Przywara
}
1322 0e26b7b8 Blue Swirl
1323 0e26b7b8 Blue Swirl
void cpu_clear_apic_feature(CPUX86State *env)
1324 0e26b7b8 Blue Swirl
{
1325 0e26b7b8 Blue Swirl
    env->cpuid_features &= ~CPUID_APIC;
1326 0e26b7b8 Blue Swirl
}
1327 0e26b7b8 Blue Swirl
1328 c6dc6f63 Andre Przywara
#endif /* !CONFIG_USER_ONLY */
1329 c6dc6f63 Andre Przywara
1330 c6dc6f63 Andre Przywara
/* register "cpudef" models defined in configuration file.  Here we first
1331 c6dc6f63 Andre Przywara
 * preload any built-in definitions
1332 c6dc6f63 Andre Przywara
 */
1333 c6dc6f63 Andre Przywara
void x86_cpudef_setup(void)
1334 c6dc6f63 Andre Przywara
{
1335 93bfef4c Crístian Viana
    int i, j;
1336 93bfef4c Crístian Viana
    static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
1337 c6dc6f63 Andre Przywara
1338 c6dc6f63 Andre Przywara
    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
1339 c6dc6f63 Andre Przywara
        builtin_x86_defs[i].next = x86_defs;
1340 c6dc6f63 Andre Przywara
        builtin_x86_defs[i].flags = 1;
1341 93bfef4c Crístian Viana
1342 93bfef4c Crístian Viana
        /* Look for specific "cpudef" models that */
1343 09faecf2 Stefan Weil
        /* have the QEMU version in .model_id */
1344 93bfef4c Crístian Viana
        for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
1345 93bfef4c Crístian Viana
            if (strcmp(model_with_versions[j], builtin_x86_defs[i].name) == 0) {
1346 93bfef4c Crístian Viana
                pstrcpy(builtin_x86_defs[i].model_id, sizeof(builtin_x86_defs[i].model_id), "QEMU Virtual CPU version ");
1347 93bfef4c Crístian Viana
                pstrcat(builtin_x86_defs[i].model_id, sizeof(builtin_x86_defs[i].model_id), qemu_get_version());
1348 93bfef4c Crístian Viana
                break;
1349 93bfef4c Crístian Viana
            }
1350 93bfef4c Crístian Viana
        }
1351 93bfef4c Crístian Viana
1352 c6dc6f63 Andre Przywara
        x86_defs = &builtin_x86_defs[i];
1353 c6dc6f63 Andre Przywara
    }
1354 c6dc6f63 Andre Przywara
#if !defined(CONFIG_USER_ONLY)
1355 3329f07b Gerd Hoffmann
    qemu_opts_foreach(qemu_find_opts("cpudef"), cpudef_register, NULL, 0);
1356 c6dc6f63 Andre Przywara
#endif
1357 c6dc6f63 Andre Przywara
}
1358 c6dc6f63 Andre Przywara
1359 c6dc6f63 Andre Przywara
static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
1360 c6dc6f63 Andre Przywara
                             uint32_t *ecx, uint32_t *edx)
1361 c6dc6f63 Andre Przywara
{
1362 c6dc6f63 Andre Przywara
    *ebx = env->cpuid_vendor1;
1363 c6dc6f63 Andre Przywara
    *edx = env->cpuid_vendor2;
1364 c6dc6f63 Andre Przywara
    *ecx = env->cpuid_vendor3;
1365 c6dc6f63 Andre Przywara
1366 c6dc6f63 Andre Przywara
    /* sysenter isn't supported on compatibility mode on AMD, syscall
1367 c6dc6f63 Andre Przywara
     * isn't supported in compatibility mode on Intel.
1368 c6dc6f63 Andre Przywara
     * Normally we advertise the actual cpu vendor, but you can override
1369 c6dc6f63 Andre Przywara
     * this if you want to use KVM's sysenter/syscall emulation
1370 c6dc6f63 Andre Przywara
     * in compatibility mode and when doing cross vendor migration
1371 c6dc6f63 Andre Przywara
     */
1372 89354998 Andre Przywara
    if (kvm_enabled() && ! env->cpuid_vendor_override) {
1373 c6dc6f63 Andre Przywara
        host_cpuid(0, 0, NULL, ebx, ecx, edx);
1374 c6dc6f63 Andre Przywara
    }
1375 c6dc6f63 Andre Przywara
}
1376 c6dc6f63 Andre Przywara
1377 c6dc6f63 Andre Przywara
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1378 c6dc6f63 Andre Przywara
                   uint32_t *eax, uint32_t *ebx,
1379 c6dc6f63 Andre Przywara
                   uint32_t *ecx, uint32_t *edx)
1380 c6dc6f63 Andre Przywara
{
1381 c6dc6f63 Andre Przywara
    /* test if maximum index reached */
1382 c6dc6f63 Andre Przywara
    if (index & 0x80000000) {
1383 b3baa152 brillywu@viatech.com.cn
        if (index > env->cpuid_xlevel) {
1384 b3baa152 brillywu@viatech.com.cn
            if (env->cpuid_xlevel2 > 0) {
1385 b3baa152 brillywu@viatech.com.cn
                /* Handle the Centaur's CPUID instruction. */
1386 b3baa152 brillywu@viatech.com.cn
                if (index > env->cpuid_xlevel2) {
1387 b3baa152 brillywu@viatech.com.cn
                    index = env->cpuid_xlevel2;
1388 b3baa152 brillywu@viatech.com.cn
                } else if (index < 0xC0000000) {
1389 b3baa152 brillywu@viatech.com.cn
                    index = env->cpuid_xlevel;
1390 b3baa152 brillywu@viatech.com.cn
                }
1391 b3baa152 brillywu@viatech.com.cn
            } else {
1392 b3baa152 brillywu@viatech.com.cn
                index =  env->cpuid_xlevel;
1393 b3baa152 brillywu@viatech.com.cn
            }
1394 b3baa152 brillywu@viatech.com.cn
        }
1395 c6dc6f63 Andre Przywara
    } else {
1396 c6dc6f63 Andre Przywara
        if (index > env->cpuid_level)
1397 c6dc6f63 Andre Przywara
            index = env->cpuid_level;
1398 c6dc6f63 Andre Przywara
    }
1399 c6dc6f63 Andre Przywara
1400 c6dc6f63 Andre Przywara
    switch(index) {
1401 c6dc6f63 Andre Przywara
    case 0:
1402 c6dc6f63 Andre Przywara
        *eax = env->cpuid_level;
1403 c6dc6f63 Andre Przywara
        get_cpuid_vendor(env, ebx, ecx, edx);
1404 c6dc6f63 Andre Przywara
        break;
1405 c6dc6f63 Andre Przywara
    case 1:
1406 c6dc6f63 Andre Przywara
        *eax = env->cpuid_version;
1407 c6dc6f63 Andre Przywara
        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
1408 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_ext_features;
1409 c6dc6f63 Andre Przywara
        *edx = env->cpuid_features;
1410 c6dc6f63 Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
1411 c6dc6f63 Andre Przywara
            *ebx |= (env->nr_cores * env->nr_threads) << 16;
1412 c6dc6f63 Andre Przywara
            *edx |= 1 << 28;    /* HTT bit */
1413 c6dc6f63 Andre Przywara
        }
1414 c6dc6f63 Andre Przywara
        break;
1415 c6dc6f63 Andre Przywara
    case 2:
1416 c6dc6f63 Andre Przywara
        /* cache info: needed for Pentium Pro compatibility */
1417 c6dc6f63 Andre Przywara
        *eax = 1;
1418 c6dc6f63 Andre Przywara
        *ebx = 0;
1419 c6dc6f63 Andre Przywara
        *ecx = 0;
1420 c6dc6f63 Andre Przywara
        *edx = 0x2c307d;
1421 c6dc6f63 Andre Przywara
        break;
1422 c6dc6f63 Andre Przywara
    case 4:
1423 c6dc6f63 Andre Przywara
        /* cache info: needed for Core compatibility */
1424 c6dc6f63 Andre Przywara
        if (env->nr_cores > 1) {
1425 2f7a21c4 Aurelien Jarno
            *eax = (env->nr_cores - 1) << 26;
1426 c6dc6f63 Andre Przywara
        } else {
1427 2f7a21c4 Aurelien Jarno
            *eax = 0;
1428 c6dc6f63 Andre Przywara
        }
1429 c6dc6f63 Andre Przywara
        switch (count) {
1430 c6dc6f63 Andre Przywara
            case 0: /* L1 dcache info */
1431 c6dc6f63 Andre Przywara
                *eax |= 0x0000121;
1432 c6dc6f63 Andre Przywara
                *ebx = 0x1c0003f;
1433 c6dc6f63 Andre Przywara
                *ecx = 0x000003f;
1434 c6dc6f63 Andre Przywara
                *edx = 0x0000001;
1435 c6dc6f63 Andre Przywara
                break;
1436 c6dc6f63 Andre Przywara
            case 1: /* L1 icache info */
1437 c6dc6f63 Andre Przywara
                *eax |= 0x0000122;
1438 c6dc6f63 Andre Przywara
                *ebx = 0x1c0003f;
1439 c6dc6f63 Andre Przywara
                *ecx = 0x000003f;
1440 c6dc6f63 Andre Przywara
                *edx = 0x0000001;
1441 c6dc6f63 Andre Przywara
                break;
1442 c6dc6f63 Andre Przywara
            case 2: /* L2 cache info */
1443 c6dc6f63 Andre Przywara
                *eax |= 0x0000143;
1444 c6dc6f63 Andre Przywara
                if (env->nr_threads > 1) {
1445 c6dc6f63 Andre Przywara
                    *eax |= (env->nr_threads - 1) << 14;
1446 c6dc6f63 Andre Przywara
                }
1447 c6dc6f63 Andre Przywara
                *ebx = 0x3c0003f;
1448 c6dc6f63 Andre Przywara
                *ecx = 0x0000fff;
1449 c6dc6f63 Andre Przywara
                *edx = 0x0000001;
1450 c6dc6f63 Andre Przywara
                break;
1451 c6dc6f63 Andre Przywara
            default: /* end of info */
1452 c6dc6f63 Andre Przywara
                *eax = 0;
1453 c6dc6f63 Andre Przywara
                *ebx = 0;
1454 c6dc6f63 Andre Przywara
                *ecx = 0;
1455 c6dc6f63 Andre Przywara
                *edx = 0;
1456 c6dc6f63 Andre Przywara
                break;
1457 c6dc6f63 Andre Przywara
        }
1458 c6dc6f63 Andre Przywara
        break;
1459 c6dc6f63 Andre Przywara
    case 5:
1460 c6dc6f63 Andre Przywara
        /* mwait info: needed for Core compatibility */
1461 c6dc6f63 Andre Przywara
        *eax = 0; /* Smallest monitor-line size in bytes */
1462 c6dc6f63 Andre Przywara
        *ebx = 0; /* Largest monitor-line size in bytes */
1463 c6dc6f63 Andre Przywara
        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
1464 c6dc6f63 Andre Przywara
        *edx = 0;
1465 c6dc6f63 Andre Przywara
        break;
1466 c6dc6f63 Andre Przywara
    case 6:
1467 c6dc6f63 Andre Przywara
        /* Thermal and Power Leaf */
1468 c6dc6f63 Andre Przywara
        *eax = 0;
1469 c6dc6f63 Andre Przywara
        *ebx = 0;
1470 c6dc6f63 Andre Przywara
        *ecx = 0;
1471 c6dc6f63 Andre Przywara
        *edx = 0;
1472 c6dc6f63 Andre Przywara
        break;
1473 f7911686 Yang, Wei Y
    case 7:
1474 13526728 Eduardo Habkost
        /* Structured Extended Feature Flags Enumeration Leaf */
1475 13526728 Eduardo Habkost
        if (count == 0) {
1476 13526728 Eduardo Habkost
            *eax = 0; /* Maximum ECX value for sub-leaves */
1477 13526728 Eduardo Habkost
            *ebx = env->cpuid_7_0_ebx; /* Feature flags */
1478 13526728 Eduardo Habkost
            *ecx = 0; /* Reserved */
1479 13526728 Eduardo Habkost
            *edx = 0; /* Reserved */
1480 f7911686 Yang, Wei Y
        } else {
1481 f7911686 Yang, Wei Y
            *eax = 0;
1482 f7911686 Yang, Wei Y
            *ebx = 0;
1483 f7911686 Yang, Wei Y
            *ecx = 0;
1484 f7911686 Yang, Wei Y
            *edx = 0;
1485 f7911686 Yang, Wei Y
        }
1486 f7911686 Yang, Wei Y
        break;
1487 c6dc6f63 Andre Przywara
    case 9:
1488 c6dc6f63 Andre Przywara
        /* Direct Cache Access Information Leaf */
1489 c6dc6f63 Andre Przywara
        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
1490 c6dc6f63 Andre Przywara
        *ebx = 0;
1491 c6dc6f63 Andre Przywara
        *ecx = 0;
1492 c6dc6f63 Andre Przywara
        *edx = 0;
1493 c6dc6f63 Andre Przywara
        break;
1494 c6dc6f63 Andre Przywara
    case 0xA:
1495 c6dc6f63 Andre Przywara
        /* Architectural Performance Monitoring Leaf */
1496 a0fa8208 Gleb Natapov
        if (kvm_enabled()) {
1497 a0fa8208 Gleb Natapov
            KVMState *s = env->kvm_state;
1498 a0fa8208 Gleb Natapov
1499 a0fa8208 Gleb Natapov
            *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
1500 a0fa8208 Gleb Natapov
            *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
1501 a0fa8208 Gleb Natapov
            *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
1502 a0fa8208 Gleb Natapov
            *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
1503 a0fa8208 Gleb Natapov
        } else {
1504 a0fa8208 Gleb Natapov
            *eax = 0;
1505 a0fa8208 Gleb Natapov
            *ebx = 0;
1506 a0fa8208 Gleb Natapov
            *ecx = 0;
1507 a0fa8208 Gleb Natapov
            *edx = 0;
1508 a0fa8208 Gleb Natapov
        }
1509 c6dc6f63 Andre Przywara
        break;
1510 51e49430 Sheng Yang
    case 0xD:
1511 51e49430 Sheng Yang
        /* Processor Extended State */
1512 51e49430 Sheng Yang
        if (!(env->cpuid_ext_features & CPUID_EXT_XSAVE)) {
1513 51e49430 Sheng Yang
            *eax = 0;
1514 51e49430 Sheng Yang
            *ebx = 0;
1515 51e49430 Sheng Yang
            *ecx = 0;
1516 51e49430 Sheng Yang
            *edx = 0;
1517 51e49430 Sheng Yang
            break;
1518 51e49430 Sheng Yang
        }
1519 51e49430 Sheng Yang
        if (kvm_enabled()) {
1520 ba9bc59e Jan Kiszka
            KVMState *s = env->kvm_state;
1521 ba9bc59e Jan Kiszka
1522 ba9bc59e Jan Kiszka
            *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX);
1523 ba9bc59e Jan Kiszka
            *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX);
1524 ba9bc59e Jan Kiszka
            *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX);
1525 ba9bc59e Jan Kiszka
            *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX);
1526 51e49430 Sheng Yang
        } else {
1527 51e49430 Sheng Yang
            *eax = 0;
1528 51e49430 Sheng Yang
            *ebx = 0;
1529 51e49430 Sheng Yang
            *ecx = 0;
1530 51e49430 Sheng Yang
            *edx = 0;
1531 51e49430 Sheng Yang
        }
1532 51e49430 Sheng Yang
        break;
1533 c6dc6f63 Andre Przywara
    case 0x80000000:
1534 c6dc6f63 Andre Przywara
        *eax = env->cpuid_xlevel;
1535 c6dc6f63 Andre Przywara
        *ebx = env->cpuid_vendor1;
1536 c6dc6f63 Andre Przywara
        *edx = env->cpuid_vendor2;
1537 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_vendor3;
1538 c6dc6f63 Andre Przywara
        break;
1539 c6dc6f63 Andre Przywara
    case 0x80000001:
1540 c6dc6f63 Andre Przywara
        *eax = env->cpuid_version;
1541 c6dc6f63 Andre Przywara
        *ebx = 0;
1542 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_ext3_features;
1543 c6dc6f63 Andre Przywara
        *edx = env->cpuid_ext2_features;
1544 c6dc6f63 Andre Przywara
1545 c6dc6f63 Andre Przywara
        /* The Linux kernel checks for the CMPLegacy bit and
1546 c6dc6f63 Andre Przywara
         * discards multiple thread information if it is set.
1547 c6dc6f63 Andre Przywara
         * So dont set it here for Intel to make Linux guests happy.
1548 c6dc6f63 Andre Przywara
         */
1549 c6dc6f63 Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
1550 c6dc6f63 Andre Przywara
            uint32_t tebx, tecx, tedx;
1551 c6dc6f63 Andre Przywara
            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
1552 c6dc6f63 Andre Przywara
            if (tebx != CPUID_VENDOR_INTEL_1 ||
1553 c6dc6f63 Andre Przywara
                tedx != CPUID_VENDOR_INTEL_2 ||
1554 c6dc6f63 Andre Przywara
                tecx != CPUID_VENDOR_INTEL_3) {
1555 c6dc6f63 Andre Przywara
                *ecx |= 1 << 1;    /* CmpLegacy bit */
1556 c6dc6f63 Andre Przywara
            }
1557 c6dc6f63 Andre Przywara
        }
1558 c6dc6f63 Andre Przywara
        break;
1559 c6dc6f63 Andre Przywara
    case 0x80000002:
1560 c6dc6f63 Andre Przywara
    case 0x80000003:
1561 c6dc6f63 Andre Przywara
    case 0x80000004:
1562 c6dc6f63 Andre Przywara
        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
1563 c6dc6f63 Andre Przywara
        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
1564 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
1565 c6dc6f63 Andre Przywara
        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
1566 c6dc6f63 Andre Przywara
        break;
1567 c6dc6f63 Andre Przywara
    case 0x80000005:
1568 c6dc6f63 Andre Przywara
        /* cache info (L1 cache) */
1569 c6dc6f63 Andre Przywara
        *eax = 0x01ff01ff;
1570 c6dc6f63 Andre Przywara
        *ebx = 0x01ff01ff;
1571 c6dc6f63 Andre Przywara
        *ecx = 0x40020140;
1572 c6dc6f63 Andre Przywara
        *edx = 0x40020140;
1573 c6dc6f63 Andre Przywara
        break;
1574 c6dc6f63 Andre Przywara
    case 0x80000006:
1575 c6dc6f63 Andre Przywara
        /* cache info (L2 cache) */
1576 c6dc6f63 Andre Przywara
        *eax = 0;
1577 c6dc6f63 Andre Przywara
        *ebx = 0x42004200;
1578 c6dc6f63 Andre Przywara
        *ecx = 0x02008140;
1579 c6dc6f63 Andre Przywara
        *edx = 0;
1580 c6dc6f63 Andre Przywara
        break;
1581 c6dc6f63 Andre Przywara
    case 0x80000008:
1582 c6dc6f63 Andre Przywara
        /* virtual & phys address size in low 2 bytes. */
1583 c6dc6f63 Andre Przywara
/* XXX: This value must match the one used in the MMU code. */
1584 c6dc6f63 Andre Przywara
        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
1585 c6dc6f63 Andre Przywara
            /* 64 bit processor */
1586 c6dc6f63 Andre Przywara
/* XXX: The physical address space is limited to 42 bits in exec.c. */
1587 c6dc6f63 Andre Przywara
            *eax = 0x00003028;        /* 48 bits virtual, 40 bits physical */
1588 c6dc6f63 Andre Przywara
        } else {
1589 c6dc6f63 Andre Przywara
            if (env->cpuid_features & CPUID_PSE36)
1590 c6dc6f63 Andre Przywara
                *eax = 0x00000024; /* 36 bits physical */
1591 c6dc6f63 Andre Przywara
            else
1592 c6dc6f63 Andre Przywara
                *eax = 0x00000020; /* 32 bits physical */
1593 c6dc6f63 Andre Przywara
        }
1594 c6dc6f63 Andre Przywara
        *ebx = 0;
1595 c6dc6f63 Andre Przywara
        *ecx = 0;
1596 c6dc6f63 Andre Przywara
        *edx = 0;
1597 c6dc6f63 Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
1598 c6dc6f63 Andre Przywara
            *ecx |= (env->nr_cores * env->nr_threads) - 1;
1599 c6dc6f63 Andre Przywara
        }
1600 c6dc6f63 Andre Przywara
        break;
1601 c6dc6f63 Andre Przywara
    case 0x8000000A:
1602 296acb64 Joerg Roedel
        if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
1603 296acb64 Joerg Roedel
                *eax = 0x00000001; /* SVM Revision */
1604 296acb64 Joerg Roedel
                *ebx = 0x00000010; /* nr of ASIDs */
1605 296acb64 Joerg Roedel
                *ecx = 0;
1606 296acb64 Joerg Roedel
                *edx = env->cpuid_svm_features; /* optional features */
1607 296acb64 Joerg Roedel
        } else {
1608 296acb64 Joerg Roedel
                *eax = 0;
1609 296acb64 Joerg Roedel
                *ebx = 0;
1610 296acb64 Joerg Roedel
                *ecx = 0;
1611 296acb64 Joerg Roedel
                *edx = 0;
1612 296acb64 Joerg Roedel
        }
1613 c6dc6f63 Andre Przywara
        break;
1614 b3baa152 brillywu@viatech.com.cn
    case 0xC0000000:
1615 b3baa152 brillywu@viatech.com.cn
        *eax = env->cpuid_xlevel2;
1616 b3baa152 brillywu@viatech.com.cn
        *ebx = 0;
1617 b3baa152 brillywu@viatech.com.cn
        *ecx = 0;
1618 b3baa152 brillywu@viatech.com.cn
        *edx = 0;
1619 b3baa152 brillywu@viatech.com.cn
        break;
1620 b3baa152 brillywu@viatech.com.cn
    case 0xC0000001:
1621 b3baa152 brillywu@viatech.com.cn
        /* Support for VIA CPU's CPUID instruction */
1622 b3baa152 brillywu@viatech.com.cn
        *eax = env->cpuid_version;
1623 b3baa152 brillywu@viatech.com.cn
        *ebx = 0;
1624 b3baa152 brillywu@viatech.com.cn
        *ecx = 0;
1625 b3baa152 brillywu@viatech.com.cn
        *edx = env->cpuid_ext4_features;
1626 b3baa152 brillywu@viatech.com.cn
        break;
1627 b3baa152 brillywu@viatech.com.cn
    case 0xC0000002:
1628 b3baa152 brillywu@viatech.com.cn
    case 0xC0000003:
1629 b3baa152 brillywu@viatech.com.cn
    case 0xC0000004:
1630 b3baa152 brillywu@viatech.com.cn
        /* Reserved for the future, and now filled with zero */
1631 b3baa152 brillywu@viatech.com.cn
        *eax = 0;
1632 b3baa152 brillywu@viatech.com.cn
        *ebx = 0;
1633 b3baa152 brillywu@viatech.com.cn
        *ecx = 0;
1634 b3baa152 brillywu@viatech.com.cn
        *edx = 0;
1635 b3baa152 brillywu@viatech.com.cn
        break;
1636 c6dc6f63 Andre Przywara
    default:
1637 c6dc6f63 Andre Przywara
        /* reserved values: zero */
1638 c6dc6f63 Andre Przywara
        *eax = 0;
1639 c6dc6f63 Andre Przywara
        *ebx = 0;
1640 c6dc6f63 Andre Przywara
        *ecx = 0;
1641 c6dc6f63 Andre Przywara
        *edx = 0;
1642 c6dc6f63 Andre Przywara
        break;
1643 c6dc6f63 Andre Przywara
    }
1644 c6dc6f63 Andre Przywara
}
1645 5fd2087a Andreas Färber
1646 5fd2087a Andreas Färber
/* CPUClass::reset() */
1647 5fd2087a Andreas Färber
static void x86_cpu_reset(CPUState *s)
1648 5fd2087a Andreas Färber
{
1649 5fd2087a Andreas Färber
    X86CPU *cpu = X86_CPU(s);
1650 5fd2087a Andreas Färber
    X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
1651 5fd2087a Andreas Färber
    CPUX86State *env = &cpu->env;
1652 c1958aea Andreas Färber
    int i;
1653 c1958aea Andreas Färber
1654 c1958aea Andreas Färber
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
1655 c1958aea Andreas Färber
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
1656 c1958aea Andreas Färber
        log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
1657 c1958aea Andreas Färber
    }
1658 5fd2087a Andreas Färber
1659 5fd2087a Andreas Färber
    xcc->parent_reset(s);
1660 5fd2087a Andreas Färber
1661 c1958aea Andreas Färber
1662 c1958aea Andreas Färber
    memset(env, 0, offsetof(CPUX86State, breakpoints));
1663 c1958aea Andreas Färber
1664 c1958aea Andreas Färber
    tlb_flush(env, 1);
1665 c1958aea Andreas Färber
1666 c1958aea Andreas Färber
    env->old_exception = -1;
1667 c1958aea Andreas Färber
1668 c1958aea Andreas Färber
    /* init to reset state */
1669 c1958aea Andreas Färber
1670 c1958aea Andreas Färber
#ifdef CONFIG_SOFTMMU
1671 c1958aea Andreas Färber
    env->hflags |= HF_SOFTMMU_MASK;
1672 c1958aea Andreas Färber
#endif
1673 c1958aea Andreas Färber
    env->hflags2 |= HF2_GIF_MASK;
1674 c1958aea Andreas Färber
1675 c1958aea Andreas Färber
    cpu_x86_update_cr0(env, 0x60000010);
1676 c1958aea Andreas Färber
    env->a20_mask = ~0x0;
1677 c1958aea Andreas Färber
    env->smbase = 0x30000;
1678 c1958aea Andreas Färber
1679 c1958aea Andreas Färber
    env->idt.limit = 0xffff;
1680 c1958aea Andreas Färber
    env->gdt.limit = 0xffff;
1681 c1958aea Andreas Färber
    env->ldt.limit = 0xffff;
1682 c1958aea Andreas Färber
    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
1683 c1958aea Andreas Färber
    env->tr.limit = 0xffff;
1684 c1958aea Andreas Färber
    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
1685 c1958aea Andreas Färber
1686 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
1687 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
1688 c1958aea Andreas Färber
                           DESC_R_MASK | DESC_A_MASK);
1689 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
1690 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1691 c1958aea Andreas Färber
                           DESC_A_MASK);
1692 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
1693 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1694 c1958aea Andreas Färber
                           DESC_A_MASK);
1695 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
1696 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1697 c1958aea Andreas Färber
                           DESC_A_MASK);
1698 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
1699 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1700 c1958aea Andreas Färber
                           DESC_A_MASK);
1701 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
1702 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1703 c1958aea Andreas Färber
                           DESC_A_MASK);
1704 c1958aea Andreas Färber
1705 c1958aea Andreas Färber
    env->eip = 0xfff0;
1706 c1958aea Andreas Färber
    env->regs[R_EDX] = env->cpuid_version;
1707 c1958aea Andreas Färber
1708 c1958aea Andreas Färber
    env->eflags = 0x2;
1709 c1958aea Andreas Färber
1710 c1958aea Andreas Färber
    /* FPU init */
1711 c1958aea Andreas Färber
    for (i = 0; i < 8; i++) {
1712 c1958aea Andreas Färber
        env->fptags[i] = 1;
1713 c1958aea Andreas Färber
    }
1714 c1958aea Andreas Färber
    env->fpuc = 0x37f;
1715 c1958aea Andreas Färber
1716 c1958aea Andreas Färber
    env->mxcsr = 0x1f80;
1717 c1958aea Andreas Färber
1718 c1958aea Andreas Färber
    env->pat = 0x0007040600070406ULL;
1719 c1958aea Andreas Färber
    env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
1720 c1958aea Andreas Färber
1721 c1958aea Andreas Färber
    memset(env->dr, 0, sizeof(env->dr));
1722 c1958aea Andreas Färber
    env->dr[6] = DR6_FIXED_1;
1723 c1958aea Andreas Färber
    env->dr[7] = DR7_FIXED_1;
1724 c1958aea Andreas Färber
    cpu_breakpoint_remove_all(env, BP_CPU);
1725 c1958aea Andreas Färber
    cpu_watchpoint_remove_all(env, BP_CPU);
1726 dd673288 Igor Mammedov
1727 dd673288 Igor Mammedov
#if !defined(CONFIG_USER_ONLY)
1728 dd673288 Igor Mammedov
    /* We hard-wire the BSP to the first CPU. */
1729 dd673288 Igor Mammedov
    if (env->cpu_index == 0) {
1730 dd673288 Igor Mammedov
        apic_designate_bsp(env->apic_state);
1731 dd673288 Igor Mammedov
    }
1732 dd673288 Igor Mammedov
1733 dd673288 Igor Mammedov
    env->halted = !cpu_is_bsp(cpu);
1734 dd673288 Igor Mammedov
#endif
1735 5fd2087a Andreas Färber
}
1736 5fd2087a Andreas Färber
1737 dd673288 Igor Mammedov
#ifndef CONFIG_USER_ONLY
1738 dd673288 Igor Mammedov
bool cpu_is_bsp(X86CPU *cpu)
1739 dd673288 Igor Mammedov
{
1740 dd673288 Igor Mammedov
    return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP;
1741 dd673288 Igor Mammedov
}
1742 65dee380 Igor Mammedov
1743 65dee380 Igor Mammedov
/* TODO: remove me, when reset over QOM tree is implemented */
1744 65dee380 Igor Mammedov
static void x86_cpu_machine_reset_cb(void *opaque)
1745 65dee380 Igor Mammedov
{
1746 65dee380 Igor Mammedov
    X86CPU *cpu = opaque;
1747 65dee380 Igor Mammedov
    cpu_reset(CPU(cpu));
1748 65dee380 Igor Mammedov
}
1749 dd673288 Igor Mammedov
#endif
1750 dd673288 Igor Mammedov
1751 de024815 Andreas Färber
static void mce_init(X86CPU *cpu)
1752 de024815 Andreas Färber
{
1753 de024815 Andreas Färber
    CPUX86State *cenv = &cpu->env;
1754 de024815 Andreas Färber
    unsigned int bank;
1755 de024815 Andreas Färber
1756 de024815 Andreas Färber
    if (((cenv->cpuid_version >> 8) & 0xf) >= 6
1757 de024815 Andreas Färber
        && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
1758 de024815 Andreas Färber
            (CPUID_MCE | CPUID_MCA)) {
1759 de024815 Andreas Färber
        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1760 de024815 Andreas Färber
        cenv->mcg_ctl = ~(uint64_t)0;
1761 de024815 Andreas Färber
        for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
1762 de024815 Andreas Färber
            cenv->mce_banks[bank * 4] = ~(uint64_t)0;
1763 de024815 Andreas Färber
        }
1764 de024815 Andreas Färber
    }
1765 de024815 Andreas Färber
}
1766 de024815 Andreas Färber
1767 7a059953 Andreas Färber
void x86_cpu_realize(Object *obj, Error **errp)
1768 7a059953 Andreas Färber
{
1769 7a059953 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1770 7a059953 Andreas Färber
1771 65dee380 Igor Mammedov
#ifndef CONFIG_USER_ONLY
1772 65dee380 Igor Mammedov
    qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
1773 65dee380 Igor Mammedov
#endif
1774 65dee380 Igor Mammedov
1775 7a059953 Andreas Färber
    mce_init(cpu);
1776 7a059953 Andreas Färber
    qemu_init_vcpu(&cpu->env);
1777 65dee380 Igor Mammedov
    cpu_reset(CPU(cpu));
1778 7a059953 Andreas Färber
}
1779 7a059953 Andreas Färber
1780 de024815 Andreas Färber
static void x86_cpu_initfn(Object *obj)
1781 de024815 Andreas Färber
{
1782 de024815 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1783 de024815 Andreas Färber
    CPUX86State *env = &cpu->env;
1784 d65e9815 Igor Mammedov
    static int inited;
1785 de024815 Andreas Färber
1786 de024815 Andreas Färber
    cpu_exec_init(env);
1787 71ad61d3 Andreas Färber
1788 71ad61d3 Andreas Färber
    object_property_add(obj, "family", "int",
1789 95b8519d Andreas Färber
                        x86_cpuid_version_get_family,
1790 71ad61d3 Andreas Färber
                        x86_cpuid_version_set_family, NULL, NULL, NULL);
1791 c5291a4f Andreas Färber
    object_property_add(obj, "model", "int",
1792 67e30c83 Andreas Färber
                        x86_cpuid_version_get_model,
1793 c5291a4f Andreas Färber
                        x86_cpuid_version_set_model, NULL, NULL, NULL);
1794 036e2222 Andreas Färber
    object_property_add(obj, "stepping", "int",
1795 35112e41 Andreas Färber
                        x86_cpuid_version_get_stepping,
1796 036e2222 Andreas Färber
                        x86_cpuid_version_set_stepping, NULL, NULL, NULL);
1797 8e1898bf Andreas Färber
    object_property_add(obj, "level", "int",
1798 8e1898bf Andreas Färber
                        x86_cpuid_get_level,
1799 8e1898bf Andreas Färber
                        x86_cpuid_set_level, NULL, NULL, NULL);
1800 16b93aa8 Andreas Färber
    object_property_add(obj, "xlevel", "int",
1801 16b93aa8 Andreas Färber
                        x86_cpuid_get_xlevel,
1802 16b93aa8 Andreas Färber
                        x86_cpuid_set_xlevel, NULL, NULL, NULL);
1803 d480e1af Andreas Färber
    object_property_add_str(obj, "vendor",
1804 d480e1af Andreas Färber
                            x86_cpuid_get_vendor,
1805 d480e1af Andreas Färber
                            x86_cpuid_set_vendor, NULL);
1806 938d4c25 Andreas Färber
    object_property_add_str(obj, "model-id",
1807 63e886eb Andreas Färber
                            x86_cpuid_get_model_id,
1808 938d4c25 Andreas Färber
                            x86_cpuid_set_model_id, NULL);
1809 89e48965 Andreas Färber
    object_property_add(obj, "tsc-frequency", "int",
1810 89e48965 Andreas Färber
                        x86_cpuid_get_tsc_freq,
1811 89e48965 Andreas Färber
                        x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
1812 71ad61d3 Andreas Färber
1813 de024815 Andreas Färber
    env->cpuid_apic_id = env->cpu_index;
1814 d65e9815 Igor Mammedov
1815 d65e9815 Igor Mammedov
    /* init various static tables used in TCG mode */
1816 d65e9815 Igor Mammedov
    if (tcg_enabled() && !inited) {
1817 d65e9815 Igor Mammedov
        inited = 1;
1818 d65e9815 Igor Mammedov
        optimize_flags_init();
1819 d65e9815 Igor Mammedov
#ifndef CONFIG_USER_ONLY
1820 d65e9815 Igor Mammedov
        cpu_set_debug_excp_handler(breakpoint_handler);
1821 d65e9815 Igor Mammedov
#endif
1822 d65e9815 Igor Mammedov
    }
1823 de024815 Andreas Färber
}
1824 de024815 Andreas Färber
1825 5fd2087a Andreas Färber
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
1826 5fd2087a Andreas Färber
{
1827 5fd2087a Andreas Färber
    X86CPUClass *xcc = X86_CPU_CLASS(oc);
1828 5fd2087a Andreas Färber
    CPUClass *cc = CPU_CLASS(oc);
1829 5fd2087a Andreas Färber
1830 5fd2087a Andreas Färber
    xcc->parent_reset = cc->reset;
1831 5fd2087a Andreas Färber
    cc->reset = x86_cpu_reset;
1832 5fd2087a Andreas Färber
}
1833 5fd2087a Andreas Färber
1834 5fd2087a Andreas Färber
static const TypeInfo x86_cpu_type_info = {
1835 5fd2087a Andreas Färber
    .name = TYPE_X86_CPU,
1836 5fd2087a Andreas Färber
    .parent = TYPE_CPU,
1837 5fd2087a Andreas Färber
    .instance_size = sizeof(X86CPU),
1838 de024815 Andreas Färber
    .instance_init = x86_cpu_initfn,
1839 5fd2087a Andreas Färber
    .abstract = false,
1840 5fd2087a Andreas Färber
    .class_size = sizeof(X86CPUClass),
1841 5fd2087a Andreas Färber
    .class_init = x86_cpu_common_class_init,
1842 5fd2087a Andreas Färber
};
1843 5fd2087a Andreas Färber
1844 5fd2087a Andreas Färber
static void x86_cpu_register_types(void)
1845 5fd2087a Andreas Färber
{
1846 5fd2087a Andreas Färber
    type_register_static(&x86_cpu_type_info);
1847 5fd2087a Andreas Färber
}
1848 5fd2087a Andreas Färber
1849 5fd2087a Andreas Färber
type_init(x86_cpu_register_types)