Statistics
| Branch: | Revision:

root / target-i386 / cpu.c @ ebe8b9c6

History | View | Annotate | Download (75.7 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 9c17d615 Paolo Bonzini
#include "sysemu/kvm.h"
26 c6dc6f63 Andre Przywara
27 1de7afc9 Paolo Bonzini
#include "qemu/option.h"
28 1de7afc9 Paolo Bonzini
#include "qemu/config-file.h"
29 7b1b5d19 Paolo Bonzini
#include "qapi/qmp/qerror.h"
30 c6dc6f63 Andre Przywara
31 7b1b5d19 Paolo Bonzini
#include "qapi/visitor.h"
32 9c17d615 Paolo Bonzini
#include "sysemu/arch_init.h"
33 71ad61d3 Andreas Färber
34 28f52cc0 Vadim Rozenfeld
#include "hyperv.h"
35 28f52cc0 Vadim Rozenfeld
36 65dee380 Igor Mammedov
#include "hw/hw.h"
37 b834b508 Stefan Weil
#if defined(CONFIG_KVM)
38 ef8621b1 Anthony Liguori
#include <linux/kvm_para.h>
39 b834b508 Stefan Weil
#endif
40 65dee380 Igor Mammedov
41 9c17d615 Paolo Bonzini
#include "sysemu/sysemu.h"
42 bdeec802 Igor Mammedov
#ifndef CONFIG_USER_ONLY
43 bdeec802 Igor Mammedov
#include "hw/xen.h"
44 bdeec802 Igor Mammedov
#include "hw/sysbus.h"
45 449994eb Andreas Färber
#include "hw/apic_internal.h"
46 bdeec802 Igor Mammedov
#endif
47 bdeec802 Igor Mammedov
48 c6dc6f63 Andre Przywara
/* feature flags taken from "Intel Processor Identification and the CPUID
49 c6dc6f63 Andre Przywara
 * Instruction" and AMD's "CPUID Specification".  In cases of disagreement
50 c6dc6f63 Andre Przywara
 * between feature naming conventions, aliases may be added.
51 c6dc6f63 Andre Przywara
 */
52 c6dc6f63 Andre Przywara
static const char *feature_name[] = {
53 c6dc6f63 Andre Przywara
    "fpu", "vme", "de", "pse",
54 c6dc6f63 Andre Przywara
    "tsc", "msr", "pae", "mce",
55 c6dc6f63 Andre Przywara
    "cx8", "apic", NULL, "sep",
56 c6dc6f63 Andre Przywara
    "mtrr", "pge", "mca", "cmov",
57 c6dc6f63 Andre Przywara
    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
58 c6dc6f63 Andre Przywara
    NULL, "ds" /* Intel dts */, "acpi", "mmx",
59 c6dc6f63 Andre Przywara
    "fxsr", "sse", "sse2", "ss",
60 c6dc6f63 Andre Przywara
    "ht" /* Intel htt */, "tm", "ia64", "pbe",
61 c6dc6f63 Andre Przywara
};
62 c6dc6f63 Andre Przywara
static const char *ext_feature_name[] = {
63 f370be3c Eduardo Habkost
    "pni|sse3" /* Intel,AMD sse3 */, "pclmulqdq|pclmuldq", "dtes64", "monitor",
64 e117f772 Andre Przywara
    "ds_cpl", "vmx", "smx", "est",
65 c6dc6f63 Andre Przywara
    "tm2", "ssse3", "cid", NULL,
66 e117f772 Andre Przywara
    "fma", "cx16", "xtpr", "pdcm",
67 434acb81 Mao, Junjie
    NULL, "pcid", "dca", "sse4.1|sse4_1",
68 e117f772 Andre Przywara
    "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
69 eaf3f097 Eduardo Habkost
    "tsc-deadline", "aes", "xsave", "osxsave",
70 c8acc380 Andre Przywara
    "avx", "f16c", "rdrand", "hypervisor",
71 c6dc6f63 Andre Przywara
};
72 3b671a40 Eduardo Habkost
/* Feature names that are already defined on feature_name[] but are set on
73 3b671a40 Eduardo Habkost
 * CPUID[8000_0001].EDX on AMD CPUs don't have their names on
74 3b671a40 Eduardo Habkost
 * ext2_feature_name[]. They are copied automatically to cpuid_ext2_features
75 3b671a40 Eduardo Habkost
 * if and only if CPU vendor is AMD.
76 3b671a40 Eduardo Habkost
 */
77 c6dc6f63 Andre Przywara
static const char *ext2_feature_name[] = {
78 3b671a40 Eduardo Habkost
    NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
79 3b671a40 Eduardo Habkost
    NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
80 3b671a40 Eduardo Habkost
    NULL /* cx8 */ /* AMD CMPXCHG8B */, NULL /* apic */, NULL, "syscall",
81 3b671a40 Eduardo Habkost
    NULL /* mtrr */, NULL /* pge */, NULL /* mca */, NULL /* cmov */,
82 3b671a40 Eduardo Habkost
    NULL /* pat */, NULL /* pse36 */, NULL, NULL /* Linux mp */,
83 3b671a40 Eduardo Habkost
    "nx|xd", NULL, "mmxext", NULL /* mmx */,
84 3b671a40 Eduardo Habkost
    NULL /* fxsr */, "fxsr_opt|ffxsr", "pdpe1gb" /* AMD Page1GB */, "rdtscp",
85 01f590d5 Eduardo Habkost
    NULL, "lm|i64", "3dnowext", "3dnow",
86 c6dc6f63 Andre Przywara
};
87 c6dc6f63 Andre Przywara
static const char *ext3_feature_name[] = {
88 c6dc6f63 Andre Przywara
    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
89 c6dc6f63 Andre Przywara
    "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
90 e117f772 Andre Przywara
    "3dnowprefetch", "osvw", "ibs", "xop",
91 c8acc380 Andre Przywara
    "skinit", "wdt", NULL, "lwp",
92 c8acc380 Andre Przywara
    "fma4", "tce", NULL, "nodeid_msr",
93 c8acc380 Andre Przywara
    NULL, "tbm", "topoext", "perfctr_core",
94 c8acc380 Andre Przywara
    "perfctr_nb", NULL, NULL, NULL,
95 c6dc6f63 Andre Przywara
    NULL, NULL, NULL, NULL,
96 c6dc6f63 Andre Przywara
};
97 c6dc6f63 Andre Przywara
98 c6dc6f63 Andre Przywara
static const char *kvm_feature_name[] = {
99 c3d39807 Don Slutz
    "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock",
100 c3d39807 Don Slutz
    "kvm_asyncpf", "kvm_steal_time", "kvm_pv_eoi", NULL,
101 c3d39807 Don Slutz
    NULL, NULL, NULL, NULL,
102 c3d39807 Don Slutz
    NULL, NULL, NULL, NULL,
103 c3d39807 Don Slutz
    NULL, NULL, NULL, NULL,
104 c3d39807 Don Slutz
    NULL, NULL, NULL, NULL,
105 c3d39807 Don Slutz
    NULL, NULL, NULL, NULL,
106 c3d39807 Don Slutz
    NULL, NULL, NULL, NULL,
107 c6dc6f63 Andre Przywara
};
108 c6dc6f63 Andre Przywara
109 296acb64 Joerg Roedel
static const char *svm_feature_name[] = {
110 296acb64 Joerg Roedel
    "npt", "lbrv", "svm_lock", "nrip_save",
111 296acb64 Joerg Roedel
    "tsc_scale", "vmcb_clean",  "flushbyasid", "decodeassists",
112 296acb64 Joerg Roedel
    NULL, NULL, "pause_filter", NULL,
113 296acb64 Joerg Roedel
    "pfthreshold", NULL, NULL, NULL,
114 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
115 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
116 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
117 296acb64 Joerg Roedel
    NULL, NULL, NULL, NULL,
118 296acb64 Joerg Roedel
};
119 296acb64 Joerg Roedel
120 a9321a4d H. Peter Anvin
static const char *cpuid_7_0_ebx_feature_name[] = {
121 811a8ae0 Eduardo Habkost
    "fsgsbase", NULL, NULL, "bmi1", "hle", "avx2", NULL, "smep",
122 811a8ae0 Eduardo Habkost
    "bmi2", "erms", "invpcid", "rtm", NULL, NULL, NULL, NULL,
123 c8acc380 Andre Przywara
    NULL, NULL, "rdseed", "adx", "smap", NULL, NULL, NULL,
124 a9321a4d H. Peter Anvin
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
125 a9321a4d H. Peter Anvin
};
126 a9321a4d H. Peter Anvin
127 8b4beddc Eduardo Habkost
const char *get_register_name_32(unsigned int reg)
128 8b4beddc Eduardo Habkost
{
129 8b4beddc Eduardo Habkost
    static const char *reg_names[CPU_NB_REGS32] = {
130 8b4beddc Eduardo Habkost
        [R_EAX] = "EAX",
131 8b4beddc Eduardo Habkost
        [R_ECX] = "ECX",
132 8b4beddc Eduardo Habkost
        [R_EDX] = "EDX",
133 8b4beddc Eduardo Habkost
        [R_EBX] = "EBX",
134 8b4beddc Eduardo Habkost
        [R_ESP] = "ESP",
135 8b4beddc Eduardo Habkost
        [R_EBP] = "EBP",
136 8b4beddc Eduardo Habkost
        [R_ESI] = "ESI",
137 8b4beddc Eduardo Habkost
        [R_EDI] = "EDI",
138 8b4beddc Eduardo Habkost
    };
139 8b4beddc Eduardo Habkost
140 8b4beddc Eduardo Habkost
    if (reg > CPU_NB_REGS32) {
141 8b4beddc Eduardo Habkost
        return NULL;
142 8b4beddc Eduardo Habkost
    }
143 8b4beddc Eduardo Habkost
    return reg_names[reg];
144 8b4beddc Eduardo Habkost
}
145 8b4beddc Eduardo Habkost
146 c6dc6f63 Andre Przywara
/* collects per-function cpuid data
147 c6dc6f63 Andre Przywara
 */
148 c6dc6f63 Andre Przywara
typedef struct model_features_t {
149 c6dc6f63 Andre Przywara
    uint32_t *guest_feat;
150 c6dc6f63 Andre Przywara
    uint32_t *host_feat;
151 c6dc6f63 Andre Przywara
    const char **flag_names;
152 c6dc6f63 Andre Przywara
    uint32_t cpuid;
153 8b4beddc Eduardo Habkost
    int reg;
154 8b4beddc Eduardo Habkost
} model_features_t;
155 c6dc6f63 Andre Przywara
156 c6dc6f63 Andre Przywara
int check_cpuid = 0;
157 c6dc6f63 Andre Przywara
int enforce_cpuid = 0;
158 c6dc6f63 Andre Przywara
159 dc59944b Michael S. Tsirkin
#if defined(CONFIG_KVM)
160 dc59944b Michael S. Tsirkin
static uint32_t kvm_default_features = (1 << KVM_FEATURE_CLOCKSOURCE) |
161 dc59944b Michael S. Tsirkin
        (1 << KVM_FEATURE_NOP_IO_DELAY) |
162 dc59944b Michael S. Tsirkin
        (1 << KVM_FEATURE_MMU_OP) |
163 dc59944b Michael S. Tsirkin
        (1 << KVM_FEATURE_CLOCKSOURCE2) |
164 dc59944b Michael S. Tsirkin
        (1 << KVM_FEATURE_ASYNC_PF) |
165 dc59944b Michael S. Tsirkin
        (1 << KVM_FEATURE_STEAL_TIME) |
166 dc59944b Michael S. Tsirkin
        (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
167 dc59944b Michael S. Tsirkin
static const uint32_t kvm_pv_eoi_features = (0x1 << KVM_FEATURE_PV_EOI);
168 dc59944b Michael S. Tsirkin
#else
169 dc59944b Michael S. Tsirkin
static uint32_t kvm_default_features = 0;
170 dc59944b Michael S. Tsirkin
static const uint32_t kvm_pv_eoi_features = 0;
171 dc59944b Michael S. Tsirkin
#endif
172 dc59944b Michael S. Tsirkin
173 dc59944b Michael S. Tsirkin
void enable_kvm_pv_eoi(void)
174 dc59944b Michael S. Tsirkin
{
175 dc59944b Michael S. Tsirkin
    kvm_default_features |= kvm_pv_eoi_features;
176 dc59944b Michael S. Tsirkin
}
177 dc59944b Michael S. Tsirkin
178 bb44e0d1 Jan Kiszka
void host_cpuid(uint32_t function, uint32_t count,
179 bb44e0d1 Jan Kiszka
                uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
180 bdde476a Andre Przywara
{
181 bdde476a Andre Przywara
#if defined(CONFIG_KVM)
182 a1fd24af Anthony Liguori
    uint32_t vec[4];
183 a1fd24af Anthony Liguori
184 a1fd24af Anthony Liguori
#ifdef __x86_64__
185 a1fd24af Anthony Liguori
    asm volatile("cpuid"
186 a1fd24af Anthony Liguori
                 : "=a"(vec[0]), "=b"(vec[1]),
187 a1fd24af Anthony Liguori
                   "=c"(vec[2]), "=d"(vec[3])
188 a1fd24af Anthony Liguori
                 : "0"(function), "c"(count) : "cc");
189 a1fd24af Anthony Liguori
#else
190 a1fd24af Anthony Liguori
    asm volatile("pusha \n\t"
191 a1fd24af Anthony Liguori
                 "cpuid \n\t"
192 a1fd24af Anthony Liguori
                 "mov %%eax, 0(%2) \n\t"
193 a1fd24af Anthony Liguori
                 "mov %%ebx, 4(%2) \n\t"
194 a1fd24af Anthony Liguori
                 "mov %%ecx, 8(%2) \n\t"
195 a1fd24af Anthony Liguori
                 "mov %%edx, 12(%2) \n\t"
196 a1fd24af Anthony Liguori
                 "popa"
197 a1fd24af Anthony Liguori
                 : : "a"(function), "c"(count), "S"(vec)
198 a1fd24af Anthony Liguori
                 : "memory", "cc");
199 a1fd24af Anthony Liguori
#endif
200 a1fd24af Anthony Liguori
201 bdde476a Andre Przywara
    if (eax)
202 a1fd24af Anthony Liguori
        *eax = vec[0];
203 bdde476a Andre Przywara
    if (ebx)
204 a1fd24af Anthony Liguori
        *ebx = vec[1];
205 bdde476a Andre Przywara
    if (ecx)
206 a1fd24af Anthony Liguori
        *ecx = vec[2];
207 bdde476a Andre Przywara
    if (edx)
208 a1fd24af Anthony Liguori
        *edx = vec[3];
209 bdde476a Andre Przywara
#endif
210 bdde476a Andre Przywara
}
211 c6dc6f63 Andre Przywara
212 c6dc6f63 Andre Przywara
#define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
213 c6dc6f63 Andre Przywara
214 c6dc6f63 Andre Przywara
/* general substring compare of *[s1..e1) and *[s2..e2).  sx is start of
215 c6dc6f63 Andre Przywara
 * a substring.  ex if !NULL points to the first char after a substring,
216 c6dc6f63 Andre Przywara
 * otherwise the string is assumed to sized by a terminating nul.
217 c6dc6f63 Andre Przywara
 * Return lexical ordering of *s1:*s2.
218 c6dc6f63 Andre Przywara
 */
219 c6dc6f63 Andre Przywara
static int sstrcmp(const char *s1, const char *e1, const char *s2,
220 c6dc6f63 Andre Przywara
    const char *e2)
221 c6dc6f63 Andre Przywara
{
222 c6dc6f63 Andre Przywara
    for (;;) {
223 c6dc6f63 Andre Przywara
        if (!*s1 || !*s2 || *s1 != *s2)
224 c6dc6f63 Andre Przywara
            return (*s1 - *s2);
225 c6dc6f63 Andre Przywara
        ++s1, ++s2;
226 c6dc6f63 Andre Przywara
        if (s1 == e1 && s2 == e2)
227 c6dc6f63 Andre Przywara
            return (0);
228 c6dc6f63 Andre Przywara
        else if (s1 == e1)
229 c6dc6f63 Andre Przywara
            return (*s2);
230 c6dc6f63 Andre Przywara
        else if (s2 == e2)
231 c6dc6f63 Andre Przywara
            return (*s1);
232 c6dc6f63 Andre Przywara
    }
233 c6dc6f63 Andre Przywara
}
234 c6dc6f63 Andre Przywara
235 c6dc6f63 Andre Przywara
/* compare *[s..e) to *altstr.  *altstr may be a simple string or multiple
236 c6dc6f63 Andre Przywara
 * '|' delimited (possibly empty) strings in which case search for a match
237 c6dc6f63 Andre Przywara
 * within the alternatives proceeds left to right.  Return 0 for success,
238 c6dc6f63 Andre Przywara
 * non-zero otherwise.
239 c6dc6f63 Andre Przywara
 */
240 c6dc6f63 Andre Przywara
static int altcmp(const char *s, const char *e, const char *altstr)
241 c6dc6f63 Andre Przywara
{
242 c6dc6f63 Andre Przywara
    const char *p, *q;
243 c6dc6f63 Andre Przywara
244 c6dc6f63 Andre Przywara
    for (q = p = altstr; ; ) {
245 c6dc6f63 Andre Przywara
        while (*p && *p != '|')
246 c6dc6f63 Andre Przywara
            ++p;
247 c6dc6f63 Andre Przywara
        if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
248 c6dc6f63 Andre Przywara
            return (0);
249 c6dc6f63 Andre Przywara
        if (!*p)
250 c6dc6f63 Andre Przywara
            return (1);
251 c6dc6f63 Andre Przywara
        else
252 c6dc6f63 Andre Przywara
            q = ++p;
253 c6dc6f63 Andre Przywara
    }
254 c6dc6f63 Andre Przywara
}
255 c6dc6f63 Andre Przywara
256 c6dc6f63 Andre Przywara
/* search featureset for flag *[s..e), if found set corresponding bit in
257 e41e0fc6 Jan Kiszka
 * *pval and return true, otherwise return false
258 c6dc6f63 Andre Przywara
 */
259 e41e0fc6 Jan Kiszka
static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
260 e41e0fc6 Jan Kiszka
                           const char **featureset)
261 c6dc6f63 Andre Przywara
{
262 c6dc6f63 Andre Przywara
    uint32_t mask;
263 c6dc6f63 Andre Przywara
    const char **ppc;
264 e41e0fc6 Jan Kiszka
    bool found = false;
265 c6dc6f63 Andre Przywara
266 e41e0fc6 Jan Kiszka
    for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
267 c6dc6f63 Andre Przywara
        if (*ppc && !altcmp(s, e, *ppc)) {
268 c6dc6f63 Andre Przywara
            *pval |= mask;
269 e41e0fc6 Jan Kiszka
            found = true;
270 c6dc6f63 Andre Przywara
        }
271 e41e0fc6 Jan Kiszka
    }
272 e41e0fc6 Jan Kiszka
    return found;
273 c6dc6f63 Andre Przywara
}
274 c6dc6f63 Andre Przywara
275 c6dc6f63 Andre Przywara
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
276 c6dc6f63 Andre Przywara
                                    uint32_t *ext_features,
277 c6dc6f63 Andre Przywara
                                    uint32_t *ext2_features,
278 c6dc6f63 Andre Przywara
                                    uint32_t *ext3_features,
279 296acb64 Joerg Roedel
                                    uint32_t *kvm_features,
280 a9321a4d H. Peter Anvin
                                    uint32_t *svm_features,
281 a9321a4d H. Peter Anvin
                                    uint32_t *cpuid_7_0_ebx_features)
282 c6dc6f63 Andre Przywara
{
283 c6dc6f63 Andre Przywara
    if (!lookup_feature(features, flagname, NULL, feature_name) &&
284 c6dc6f63 Andre Przywara
        !lookup_feature(ext_features, flagname, NULL, ext_feature_name) &&
285 c6dc6f63 Andre Przywara
        !lookup_feature(ext2_features, flagname, NULL, ext2_feature_name) &&
286 c6dc6f63 Andre Przywara
        !lookup_feature(ext3_features, flagname, NULL, ext3_feature_name) &&
287 296acb64 Joerg Roedel
        !lookup_feature(kvm_features, flagname, NULL, kvm_feature_name) &&
288 a9321a4d H. Peter Anvin
        !lookup_feature(svm_features, flagname, NULL, svm_feature_name) &&
289 a9321a4d H. Peter Anvin
        !lookup_feature(cpuid_7_0_ebx_features, flagname, NULL,
290 a9321a4d H. Peter Anvin
                        cpuid_7_0_ebx_feature_name))
291 c6dc6f63 Andre Przywara
            fprintf(stderr, "CPU feature %s not found\n", flagname);
292 c6dc6f63 Andre Przywara
}
293 c6dc6f63 Andre Przywara
294 c6dc6f63 Andre Przywara
typedef struct x86_def_t {
295 c6dc6f63 Andre Przywara
    struct x86_def_t *next;
296 c6dc6f63 Andre Przywara
    const char *name;
297 c6dc6f63 Andre Przywara
    uint32_t level;
298 c6dc6f63 Andre Przywara
    uint32_t vendor1, vendor2, vendor3;
299 c6dc6f63 Andre Przywara
    int family;
300 c6dc6f63 Andre Przywara
    int model;
301 c6dc6f63 Andre Przywara
    int stepping;
302 b862d1fe Joerg Roedel
    int tsc_khz;
303 296acb64 Joerg Roedel
    uint32_t features, ext_features, ext2_features, ext3_features;
304 296acb64 Joerg Roedel
    uint32_t kvm_features, svm_features;
305 c6dc6f63 Andre Przywara
    uint32_t xlevel;
306 c6dc6f63 Andre Przywara
    char model_id[48];
307 c6dc6f63 Andre Przywara
    int vendor_override;
308 b3baa152 brillywu@viatech.com.cn
    /* Store the results of Centaur's CPUID instructions */
309 b3baa152 brillywu@viatech.com.cn
    uint32_t ext4_features;
310 b3baa152 brillywu@viatech.com.cn
    uint32_t xlevel2;
311 13526728 Eduardo Habkost
    /* The feature bits on CPUID[EAX=7,ECX=0].EBX */
312 13526728 Eduardo Habkost
    uint32_t cpuid_7_0_ebx_features;
313 c6dc6f63 Andre Przywara
} x86_def_t;
314 c6dc6f63 Andre Przywara
315 c6dc6f63 Andre Przywara
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
316 c6dc6f63 Andre Przywara
#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
317 c6dc6f63 Andre Przywara
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
318 c6dc6f63 Andre Przywara
#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
319 c6dc6f63 Andre Przywara
          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
320 c6dc6f63 Andre Przywara
          CPUID_PSE36 | CPUID_FXSR)
321 c6dc6f63 Andre Przywara
#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
322 c6dc6f63 Andre Przywara
#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
323 c6dc6f63 Andre Przywara
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
324 c6dc6f63 Andre Przywara
          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
325 c6dc6f63 Andre Przywara
          CPUID_PAE | CPUID_SEP | CPUID_APIC)
326 c6dc6f63 Andre Przywara
327 551a2dec Andre Przywara
#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
328 551a2dec Andre Przywara
          CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
329 551a2dec Andre Przywara
          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
330 551a2dec Andre Przywara
          CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
331 551a2dec Andre Przywara
          CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
332 8560efed Aurelien Jarno
          /* partly implemented:
333 8560efed Aurelien Jarno
          CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
334 8560efed Aurelien Jarno
          CPUID_PSE36 (needed for Solaris) */
335 8560efed Aurelien Jarno
          /* missing:
336 8560efed Aurelien Jarno
          CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
337 551a2dec Andre Przywara
#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | \
338 a0a70681 Aurelien Jarno
          CPUID_EXT_SSSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT | \
339 551a2dec Andre Przywara
          CPUID_EXT_HYPERVISOR)
340 8560efed Aurelien Jarno
          /* missing:
341 8560efed Aurelien Jarno
          CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
342 8713f8ff Andi Kleen
          CPUID_EXT_TM2, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_XSAVE */
343 60032ac0 Eduardo Habkost
#define TCG_EXT2_FEATURES ((TCG_FEATURES & CPUID_EXT2_AMD_ALIASES) | \
344 551a2dec Andre Przywara
          CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
345 551a2dec Andre Przywara
          CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
346 8560efed Aurelien Jarno
          /* missing:
347 8560efed Aurelien Jarno
          CPUID_EXT2_PDPE1GB */
348 551a2dec Andre Przywara
#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
349 551a2dec Andre Przywara
          CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
350 296acb64 Joerg Roedel
#define TCG_SVM_FEATURES 0
351 a9321a4d H. Peter Anvin
#define TCG_7_0_EBX_FEATURES (CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_SMAP)
352 551a2dec Andre Przywara
353 c6dc6f63 Andre Przywara
/* maintains list of cpu model definitions
354 c6dc6f63 Andre Przywara
 */
355 c6dc6f63 Andre Przywara
static x86_def_t *x86_defs = {NULL};
356 c6dc6f63 Andre Przywara
357 c6dc6f63 Andre Przywara
/* built-in cpu model definitions (deprecated)
358 c6dc6f63 Andre Przywara
 */
359 c6dc6f63 Andre Przywara
static x86_def_t builtin_x86_defs[] = {
360 c6dc6f63 Andre Przywara
    {
361 c6dc6f63 Andre Przywara
        .name = "qemu64",
362 c6dc6f63 Andre Przywara
        .level = 4,
363 c6dc6f63 Andre Przywara
        .vendor1 = CPUID_VENDOR_AMD_1,
364 c6dc6f63 Andre Przywara
        .vendor2 = CPUID_VENDOR_AMD_2,
365 c6dc6f63 Andre Przywara
        .vendor3 = CPUID_VENDOR_AMD_3,
366 c6dc6f63 Andre Przywara
        .family = 6,
367 c6dc6f63 Andre Przywara
        .model = 2,
368 c6dc6f63 Andre Przywara
        .stepping = 3,
369 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
370 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
371 c6dc6f63 Andre Przywara
            CPUID_PSE36,
372 c6dc6f63 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
373 60032ac0 Eduardo Habkost
        .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
374 c6dc6f63 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
375 c6dc6f63 Andre Przywara
        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
376 c6dc6f63 Andre Przywara
            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
377 c6dc6f63 Andre Przywara
        .xlevel = 0x8000000A,
378 c6dc6f63 Andre Przywara
    },
379 c6dc6f63 Andre Przywara
    {
380 c6dc6f63 Andre Przywara
        .name = "phenom",
381 c6dc6f63 Andre Przywara
        .level = 5,
382 c6dc6f63 Andre Przywara
        .vendor1 = CPUID_VENDOR_AMD_1,
383 c6dc6f63 Andre Przywara
        .vendor2 = CPUID_VENDOR_AMD_2,
384 c6dc6f63 Andre Przywara
        .vendor3 = CPUID_VENDOR_AMD_3,
385 c6dc6f63 Andre Przywara
        .family = 16,
386 c6dc6f63 Andre Przywara
        .model = 2,
387 c6dc6f63 Andre Przywara
        .stepping = 3,
388 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
389 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
390 8560efed Aurelien Jarno
            CPUID_PSE36 | CPUID_VME | CPUID_HT,
391 c6dc6f63 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
392 c6dc6f63 Andre Przywara
            CPUID_EXT_POPCNT,
393 60032ac0 Eduardo Habkost
        .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
394 c6dc6f63 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
395 c6dc6f63 Andre Przywara
            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
396 8560efed Aurelien Jarno
            CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
397 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
398 c6dc6f63 Andre Przywara
                    CPUID_EXT3_CR8LEG,
399 c6dc6f63 Andre Przywara
                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
400 c6dc6f63 Andre Przywara
                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
401 c6dc6f63 Andre Przywara
        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
402 c6dc6f63 Andre Przywara
            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
403 296acb64 Joerg Roedel
        .svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV,
404 c6dc6f63 Andre Przywara
        .xlevel = 0x8000001A,
405 c6dc6f63 Andre Przywara
        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
406 c6dc6f63 Andre Przywara
    },
407 c6dc6f63 Andre Przywara
    {
408 c6dc6f63 Andre Przywara
        .name = "core2duo",
409 c6dc6f63 Andre Przywara
        .level = 10,
410 ebe8b9c6 Igor Mammedov
        .vendor1 = CPUID_VENDOR_INTEL_1,
411 ebe8b9c6 Igor Mammedov
        .vendor2 = CPUID_VENDOR_INTEL_2,
412 ebe8b9c6 Igor Mammedov
        .vendor3 = CPUID_VENDOR_INTEL_3,
413 c6dc6f63 Andre Przywara
        .family = 6,
414 c6dc6f63 Andre Przywara
        .model = 15,
415 c6dc6f63 Andre Przywara
        .stepping = 11,
416 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
417 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
418 8560efed Aurelien Jarno
            CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
419 8560efed Aurelien Jarno
            CPUID_HT | CPUID_TM | CPUID_PBE,
420 8560efed Aurelien Jarno
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
421 8560efed Aurelien Jarno
            CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
422 8560efed Aurelien Jarno
            CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
423 c6dc6f63 Andre Przywara
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
424 c6dc6f63 Andre Przywara
        .ext3_features = CPUID_EXT3_LAHF_LM,
425 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
426 c6dc6f63 Andre Przywara
        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
427 c6dc6f63 Andre Przywara
    },
428 c6dc6f63 Andre Przywara
    {
429 c6dc6f63 Andre Przywara
        .name = "kvm64",
430 c6dc6f63 Andre Przywara
        .level = 5,
431 c6dc6f63 Andre Przywara
        .vendor1 = CPUID_VENDOR_INTEL_1,
432 c6dc6f63 Andre Przywara
        .vendor2 = CPUID_VENDOR_INTEL_2,
433 c6dc6f63 Andre Przywara
        .vendor3 = CPUID_VENDOR_INTEL_3,
434 c6dc6f63 Andre Przywara
        .family = 15,
435 c6dc6f63 Andre Przywara
        .model = 6,
436 c6dc6f63 Andre Przywara
        .stepping = 1,
437 c6dc6f63 Andre Przywara
        /* Missing: CPUID_VME, CPUID_HT */
438 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
439 c6dc6f63 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
440 c6dc6f63 Andre Przywara
            CPUID_PSE36,
441 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
442 c6dc6f63 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
443 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
444 60032ac0 Eduardo Habkost
        .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
445 c6dc6f63 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
446 c6dc6f63 Andre Przywara
        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
447 c6dc6f63 Andre Przywara
                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
448 c6dc6f63 Andre Przywara
                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
449 c6dc6f63 Andre Przywara
                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
450 c6dc6f63 Andre Przywara
        .ext3_features = 0,
451 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
452 c6dc6f63 Andre Przywara
        .model_id = "Common KVM processor"
453 c6dc6f63 Andre Przywara
    },
454 c6dc6f63 Andre Przywara
    {
455 c6dc6f63 Andre Przywara
        .name = "qemu32",
456 c6dc6f63 Andre Przywara
        .level = 4,
457 ebe8b9c6 Igor Mammedov
        .vendor1 = CPUID_VENDOR_INTEL_1,
458 ebe8b9c6 Igor Mammedov
        .vendor2 = CPUID_VENDOR_INTEL_2,
459 ebe8b9c6 Igor Mammedov
        .vendor3 = CPUID_VENDOR_INTEL_3,
460 c6dc6f63 Andre Przywara
        .family = 6,
461 c6dc6f63 Andre Przywara
        .model = 3,
462 c6dc6f63 Andre Przywara
        .stepping = 3,
463 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES,
464 c6dc6f63 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
465 58012d66 Andre Przywara
        .xlevel = 0x80000004,
466 c6dc6f63 Andre Przywara
    },
467 c6dc6f63 Andre Przywara
    {
468 eafaf1e5 Andre Przywara
        .name = "kvm32",
469 eafaf1e5 Andre Przywara
        .level = 5,
470 ebe8b9c6 Igor Mammedov
        .vendor1 = CPUID_VENDOR_INTEL_1,
471 ebe8b9c6 Igor Mammedov
        .vendor2 = CPUID_VENDOR_INTEL_2,
472 ebe8b9c6 Igor Mammedov
        .vendor3 = CPUID_VENDOR_INTEL_3,
473 eafaf1e5 Andre Przywara
        .family = 15,
474 eafaf1e5 Andre Przywara
        .model = 6,
475 eafaf1e5 Andre Przywara
        .stepping = 1,
476 eafaf1e5 Andre Przywara
        .features = PPRO_FEATURES |
477 eafaf1e5 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
478 eafaf1e5 Andre Przywara
        .ext_features = CPUID_EXT_SSE3,
479 60032ac0 Eduardo Habkost
        .ext2_features = PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES,
480 eafaf1e5 Andre Przywara
        .ext3_features = 0,
481 eafaf1e5 Andre Przywara
        .xlevel = 0x80000008,
482 eafaf1e5 Andre Przywara
        .model_id = "Common 32-bit KVM processor"
483 eafaf1e5 Andre Przywara
    },
484 eafaf1e5 Andre Przywara
    {
485 c6dc6f63 Andre Przywara
        .name = "coreduo",
486 c6dc6f63 Andre Przywara
        .level = 10,
487 ebe8b9c6 Igor Mammedov
        .vendor1 = CPUID_VENDOR_INTEL_1,
488 ebe8b9c6 Igor Mammedov
        .vendor2 = CPUID_VENDOR_INTEL_2,
489 ebe8b9c6 Igor Mammedov
        .vendor3 = CPUID_VENDOR_INTEL_3,
490 c6dc6f63 Andre Przywara
        .family = 6,
491 c6dc6f63 Andre Przywara
        .model = 14,
492 c6dc6f63 Andre Przywara
        .stepping = 8,
493 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES | CPUID_VME |
494 8560efed Aurelien Jarno
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
495 8560efed Aurelien Jarno
            CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
496 8560efed Aurelien Jarno
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
497 8560efed Aurelien Jarno
            CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
498 c6dc6f63 Andre Przywara
        .ext2_features = CPUID_EXT2_NX,
499 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
500 c6dc6f63 Andre Przywara
        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
501 c6dc6f63 Andre Przywara
    },
502 c6dc6f63 Andre Przywara
    {
503 c6dc6f63 Andre Przywara
        .name = "486",
504 58012d66 Andre Przywara
        .level = 1,
505 ebe8b9c6 Igor Mammedov
        .vendor1 = CPUID_VENDOR_INTEL_1,
506 ebe8b9c6 Igor Mammedov
        .vendor2 = CPUID_VENDOR_INTEL_2,
507 ebe8b9c6 Igor Mammedov
        .vendor3 = CPUID_VENDOR_INTEL_3,
508 c6dc6f63 Andre Przywara
        .family = 4,
509 c6dc6f63 Andre Przywara
        .model = 0,
510 c6dc6f63 Andre Przywara
        .stepping = 0,
511 c6dc6f63 Andre Przywara
        .features = I486_FEATURES,
512 c6dc6f63 Andre Przywara
        .xlevel = 0,
513 c6dc6f63 Andre Przywara
    },
514 c6dc6f63 Andre Przywara
    {
515 c6dc6f63 Andre Przywara
        .name = "pentium",
516 c6dc6f63 Andre Przywara
        .level = 1,
517 ebe8b9c6 Igor Mammedov
        .vendor1 = CPUID_VENDOR_INTEL_1,
518 ebe8b9c6 Igor Mammedov
        .vendor2 = CPUID_VENDOR_INTEL_2,
519 ebe8b9c6 Igor Mammedov
        .vendor3 = CPUID_VENDOR_INTEL_3,
520 c6dc6f63 Andre Przywara
        .family = 5,
521 c6dc6f63 Andre Przywara
        .model = 4,
522 c6dc6f63 Andre Przywara
        .stepping = 3,
523 c6dc6f63 Andre Przywara
        .features = PENTIUM_FEATURES,
524 c6dc6f63 Andre Przywara
        .xlevel = 0,
525 c6dc6f63 Andre Przywara
    },
526 c6dc6f63 Andre Przywara
    {
527 c6dc6f63 Andre Przywara
        .name = "pentium2",
528 c6dc6f63 Andre Przywara
        .level = 2,
529 ebe8b9c6 Igor Mammedov
        .vendor1 = CPUID_VENDOR_INTEL_1,
530 ebe8b9c6 Igor Mammedov
        .vendor2 = CPUID_VENDOR_INTEL_2,
531 ebe8b9c6 Igor Mammedov
        .vendor3 = CPUID_VENDOR_INTEL_3,
532 c6dc6f63 Andre Przywara
        .family = 6,
533 c6dc6f63 Andre Przywara
        .model = 5,
534 c6dc6f63 Andre Przywara
        .stepping = 2,
535 c6dc6f63 Andre Przywara
        .features = PENTIUM2_FEATURES,
536 c6dc6f63 Andre Przywara
        .xlevel = 0,
537 c6dc6f63 Andre Przywara
    },
538 c6dc6f63 Andre Przywara
    {
539 c6dc6f63 Andre Przywara
        .name = "pentium3",
540 c6dc6f63 Andre Przywara
        .level = 2,
541 ebe8b9c6 Igor Mammedov
        .vendor1 = CPUID_VENDOR_INTEL_1,
542 ebe8b9c6 Igor Mammedov
        .vendor2 = CPUID_VENDOR_INTEL_2,
543 ebe8b9c6 Igor Mammedov
        .vendor3 = CPUID_VENDOR_INTEL_3,
544 c6dc6f63 Andre Przywara
        .family = 6,
545 c6dc6f63 Andre Przywara
        .model = 7,
546 c6dc6f63 Andre Przywara
        .stepping = 3,
547 c6dc6f63 Andre Przywara
        .features = PENTIUM3_FEATURES,
548 c6dc6f63 Andre Przywara
        .xlevel = 0,
549 c6dc6f63 Andre Przywara
    },
550 c6dc6f63 Andre Przywara
    {
551 c6dc6f63 Andre Przywara
        .name = "athlon",
552 c6dc6f63 Andre Przywara
        .level = 2,
553 c6dc6f63 Andre Przywara
        .vendor1 = CPUID_VENDOR_AMD_1,
554 c6dc6f63 Andre Przywara
        .vendor2 = CPUID_VENDOR_AMD_2,
555 c6dc6f63 Andre Przywara
        .vendor3 = CPUID_VENDOR_AMD_3,
556 c6dc6f63 Andre Przywara
        .family = 6,
557 c6dc6f63 Andre Przywara
        .model = 2,
558 c6dc6f63 Andre Przywara
        .stepping = 3,
559 60032ac0 Eduardo Habkost
        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR |
560 60032ac0 Eduardo Habkost
            CPUID_MCA,
561 60032ac0 Eduardo Habkost
        .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
562 60032ac0 Eduardo Habkost
            CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
563 c6dc6f63 Andre Przywara
        .xlevel = 0x80000008,
564 c6dc6f63 Andre Przywara
    },
565 c6dc6f63 Andre Przywara
    {
566 c6dc6f63 Andre Przywara
        .name = "n270",
567 c6dc6f63 Andre Przywara
        /* original is on level 10 */
568 c6dc6f63 Andre Przywara
        .level = 5,
569 ebe8b9c6 Igor Mammedov
        .vendor1 = CPUID_VENDOR_INTEL_1,
570 ebe8b9c6 Igor Mammedov
        .vendor2 = CPUID_VENDOR_INTEL_2,
571 ebe8b9c6 Igor Mammedov
        .vendor3 = CPUID_VENDOR_INTEL_3,
572 c6dc6f63 Andre Przywara
        .family = 6,
573 c6dc6f63 Andre Przywara
        .model = 28,
574 c6dc6f63 Andre Przywara
        .stepping = 2,
575 c6dc6f63 Andre Przywara
        .features = PPRO_FEATURES |
576 8560efed Aurelien Jarno
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
577 8560efed Aurelien Jarno
            CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
578 c6dc6f63 Andre Przywara
            /* Some CPUs got no CPUID_SEP */
579 8560efed Aurelien Jarno
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
580 8560efed Aurelien Jarno
            CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR,
581 60032ac0 Eduardo Habkost
        .ext2_features = (PPRO_FEATURES & CPUID_EXT2_AMD_ALIASES) |
582 60032ac0 Eduardo Habkost
            CPUID_EXT2_NX,
583 8560efed Aurelien Jarno
        .ext3_features = CPUID_EXT3_LAHF_LM,
584 c6dc6f63 Andre Przywara
        .xlevel = 0x8000000A,
585 c6dc6f63 Andre Przywara
        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
586 c6dc6f63 Andre Przywara
    },
587 3eca4642 Eduardo Habkost
    {
588 3eca4642 Eduardo Habkost
        .name = "Conroe",
589 3eca4642 Eduardo Habkost
        .level = 2,
590 3eca4642 Eduardo Habkost
        .vendor1 = CPUID_VENDOR_INTEL_1,
591 3eca4642 Eduardo Habkost
        .vendor2 = CPUID_VENDOR_INTEL_2,
592 3eca4642 Eduardo Habkost
        .vendor3 = CPUID_VENDOR_INTEL_3,
593 3eca4642 Eduardo Habkost
        .family = 6,
594 3eca4642 Eduardo Habkost
        .model = 2,
595 3eca4642 Eduardo Habkost
        .stepping = 3,
596 3eca4642 Eduardo Habkost
        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
597 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
598 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
599 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
600 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
601 3eca4642 Eduardo Habkost
        .ext_features = CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
602 3eca4642 Eduardo Habkost
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
603 3eca4642 Eduardo Habkost
        .ext3_features = CPUID_EXT3_LAHF_LM,
604 3eca4642 Eduardo Habkost
        .xlevel = 0x8000000A,
605 3eca4642 Eduardo Habkost
        .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
606 3eca4642 Eduardo Habkost
    },
607 3eca4642 Eduardo Habkost
    {
608 3eca4642 Eduardo Habkost
        .name = "Penryn",
609 3eca4642 Eduardo Habkost
        .level = 2,
610 3eca4642 Eduardo Habkost
        .vendor1 = CPUID_VENDOR_INTEL_1,
611 3eca4642 Eduardo Habkost
        .vendor2 = CPUID_VENDOR_INTEL_2,
612 3eca4642 Eduardo Habkost
        .vendor3 = CPUID_VENDOR_INTEL_3,
613 3eca4642 Eduardo Habkost
        .family = 6,
614 3eca4642 Eduardo Habkost
        .model = 2,
615 3eca4642 Eduardo Habkost
        .stepping = 3,
616 3eca4642 Eduardo Habkost
        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
617 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
618 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
619 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
620 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
621 3eca4642 Eduardo Habkost
        .ext_features = CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
622 3eca4642 Eduardo Habkost
             CPUID_EXT_SSE3,
623 3eca4642 Eduardo Habkost
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
624 3eca4642 Eduardo Habkost
        .ext3_features = CPUID_EXT3_LAHF_LM,
625 3eca4642 Eduardo Habkost
        .xlevel = 0x8000000A,
626 3eca4642 Eduardo Habkost
        .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
627 3eca4642 Eduardo Habkost
    },
628 3eca4642 Eduardo Habkost
    {
629 3eca4642 Eduardo Habkost
        .name = "Nehalem",
630 3eca4642 Eduardo Habkost
        .level = 2,
631 3eca4642 Eduardo Habkost
        .vendor1 = CPUID_VENDOR_INTEL_1,
632 3eca4642 Eduardo Habkost
        .vendor2 = CPUID_VENDOR_INTEL_2,
633 3eca4642 Eduardo Habkost
        .vendor3 = CPUID_VENDOR_INTEL_3,
634 3eca4642 Eduardo Habkost
        .family = 6,
635 3eca4642 Eduardo Habkost
        .model = 2,
636 3eca4642 Eduardo Habkost
        .stepping = 3,
637 3eca4642 Eduardo Habkost
        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
638 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
639 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
640 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
641 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
642 3eca4642 Eduardo Habkost
        .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
643 3eca4642 Eduardo Habkost
             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
644 3eca4642 Eduardo Habkost
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
645 3eca4642 Eduardo Habkost
        .ext3_features = CPUID_EXT3_LAHF_LM,
646 3eca4642 Eduardo Habkost
        .xlevel = 0x8000000A,
647 3eca4642 Eduardo Habkost
        .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
648 3eca4642 Eduardo Habkost
    },
649 3eca4642 Eduardo Habkost
    {
650 3eca4642 Eduardo Habkost
        .name = "Westmere",
651 3eca4642 Eduardo Habkost
        .level = 11,
652 3eca4642 Eduardo Habkost
        .vendor1 = CPUID_VENDOR_INTEL_1,
653 3eca4642 Eduardo Habkost
        .vendor2 = CPUID_VENDOR_INTEL_2,
654 3eca4642 Eduardo Habkost
        .vendor3 = CPUID_VENDOR_INTEL_3,
655 3eca4642 Eduardo Habkost
        .family = 6,
656 3eca4642 Eduardo Habkost
        .model = 44,
657 3eca4642 Eduardo Habkost
        .stepping = 1,
658 3eca4642 Eduardo Habkost
        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
659 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
660 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
661 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
662 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
663 3eca4642 Eduardo Habkost
        .ext_features = CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
664 3eca4642 Eduardo Habkost
             CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
665 3eca4642 Eduardo Habkost
             CPUID_EXT_SSE3,
666 3eca4642 Eduardo Habkost
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
667 3eca4642 Eduardo Habkost
        .ext3_features = CPUID_EXT3_LAHF_LM,
668 3eca4642 Eduardo Habkost
        .xlevel = 0x8000000A,
669 3eca4642 Eduardo Habkost
        .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
670 3eca4642 Eduardo Habkost
    },
671 3eca4642 Eduardo Habkost
    {
672 3eca4642 Eduardo Habkost
        .name = "SandyBridge",
673 3eca4642 Eduardo Habkost
        .level = 0xd,
674 3eca4642 Eduardo Habkost
        .vendor1 = CPUID_VENDOR_INTEL_1,
675 3eca4642 Eduardo Habkost
        .vendor2 = CPUID_VENDOR_INTEL_2,
676 3eca4642 Eduardo Habkost
        .vendor3 = CPUID_VENDOR_INTEL_3,
677 3eca4642 Eduardo Habkost
        .family = 6,
678 3eca4642 Eduardo Habkost
        .model = 42,
679 3eca4642 Eduardo Habkost
        .stepping = 1,
680 3eca4642 Eduardo Habkost
        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
681 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
682 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
683 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
684 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
685 3eca4642 Eduardo Habkost
        .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
686 3eca4642 Eduardo Habkost
             CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
687 3eca4642 Eduardo Habkost
             CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
688 3eca4642 Eduardo Habkost
             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
689 3eca4642 Eduardo Habkost
             CPUID_EXT_SSE3,
690 3eca4642 Eduardo Habkost
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
691 3eca4642 Eduardo Habkost
             CPUID_EXT2_SYSCALL,
692 3eca4642 Eduardo Habkost
        .ext3_features = CPUID_EXT3_LAHF_LM,
693 3eca4642 Eduardo Habkost
        .xlevel = 0x8000000A,
694 3eca4642 Eduardo Habkost
        .model_id = "Intel Xeon E312xx (Sandy Bridge)",
695 3eca4642 Eduardo Habkost
    },
696 3eca4642 Eduardo Habkost
    {
697 37507094 Eduardo Habkost
        .name = "Haswell",
698 37507094 Eduardo Habkost
        .level = 0xd,
699 37507094 Eduardo Habkost
        .vendor1 = CPUID_VENDOR_INTEL_1,
700 37507094 Eduardo Habkost
        .vendor2 = CPUID_VENDOR_INTEL_2,
701 37507094 Eduardo Habkost
        .vendor3 = CPUID_VENDOR_INTEL_3,
702 37507094 Eduardo Habkost
        .family = 6,
703 37507094 Eduardo Habkost
        .model = 60,
704 37507094 Eduardo Habkost
        .stepping = 1,
705 37507094 Eduardo Habkost
        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
706 37507094 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
707 80ae4160 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
708 37507094 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
709 37507094 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
710 37507094 Eduardo Habkost
        .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
711 37507094 Eduardo Habkost
             CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
712 37507094 Eduardo Habkost
             CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
713 37507094 Eduardo Habkost
             CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
714 37507094 Eduardo Habkost
             CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
715 37507094 Eduardo Habkost
             CPUID_EXT_PCID,
716 80ae4160 Eduardo Habkost
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
717 80ae4160 Eduardo Habkost
             CPUID_EXT2_SYSCALL,
718 37507094 Eduardo Habkost
        .ext3_features = CPUID_EXT3_LAHF_LM,
719 37507094 Eduardo Habkost
        .cpuid_7_0_ebx_features = CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
720 37507094 Eduardo Habkost
            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
721 37507094 Eduardo Habkost
            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
722 37507094 Eduardo Habkost
            CPUID_7_0_EBX_RTM,
723 37507094 Eduardo Habkost
        .xlevel = 0x8000000A,
724 37507094 Eduardo Habkost
        .model_id = "Intel Core Processor (Haswell)",
725 37507094 Eduardo Habkost
    },
726 37507094 Eduardo Habkost
    {
727 3eca4642 Eduardo Habkost
        .name = "Opteron_G1",
728 3eca4642 Eduardo Habkost
        .level = 5,
729 3eca4642 Eduardo Habkost
        .vendor1 = CPUID_VENDOR_AMD_1,
730 3eca4642 Eduardo Habkost
        .vendor2 = CPUID_VENDOR_AMD_2,
731 3eca4642 Eduardo Habkost
        .vendor3 = CPUID_VENDOR_AMD_3,
732 3eca4642 Eduardo Habkost
        .family = 15,
733 3eca4642 Eduardo Habkost
        .model = 6,
734 3eca4642 Eduardo Habkost
        .stepping = 1,
735 3eca4642 Eduardo Habkost
        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
736 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
737 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
738 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
739 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
740 3eca4642 Eduardo Habkost
        .ext_features = CPUID_EXT_SSE3,
741 3eca4642 Eduardo Habkost
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
742 3eca4642 Eduardo Habkost
             CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
743 3eca4642 Eduardo Habkost
             CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
744 3eca4642 Eduardo Habkost
             CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
745 3eca4642 Eduardo Habkost
             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
746 3eca4642 Eduardo Habkost
             CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
747 3eca4642 Eduardo Habkost
        .xlevel = 0x80000008,
748 3eca4642 Eduardo Habkost
        .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
749 3eca4642 Eduardo Habkost
    },
750 3eca4642 Eduardo Habkost
    {
751 3eca4642 Eduardo Habkost
        .name = "Opteron_G2",
752 3eca4642 Eduardo Habkost
        .level = 5,
753 3eca4642 Eduardo Habkost
        .vendor1 = CPUID_VENDOR_AMD_1,
754 3eca4642 Eduardo Habkost
        .vendor2 = CPUID_VENDOR_AMD_2,
755 3eca4642 Eduardo Habkost
        .vendor3 = CPUID_VENDOR_AMD_3,
756 3eca4642 Eduardo Habkost
        .family = 15,
757 3eca4642 Eduardo Habkost
        .model = 6,
758 3eca4642 Eduardo Habkost
        .stepping = 1,
759 3eca4642 Eduardo Habkost
        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
760 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
761 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
762 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
763 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
764 3eca4642 Eduardo Habkost
        .ext_features = CPUID_EXT_CX16 | CPUID_EXT_SSE3,
765 3eca4642 Eduardo Habkost
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
766 3eca4642 Eduardo Habkost
             CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
767 3eca4642 Eduardo Habkost
             CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
768 3eca4642 Eduardo Habkost
             CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
769 3eca4642 Eduardo Habkost
             CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
770 3eca4642 Eduardo Habkost
             CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
771 3eca4642 Eduardo Habkost
             CPUID_EXT2_DE | CPUID_EXT2_FPU,
772 3eca4642 Eduardo Habkost
        .ext3_features = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
773 3eca4642 Eduardo Habkost
        .xlevel = 0x80000008,
774 3eca4642 Eduardo Habkost
        .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
775 3eca4642 Eduardo Habkost
    },
776 3eca4642 Eduardo Habkost
    {
777 3eca4642 Eduardo Habkost
        .name = "Opteron_G3",
778 3eca4642 Eduardo Habkost
        .level = 5,
779 3eca4642 Eduardo Habkost
        .vendor1 = CPUID_VENDOR_AMD_1,
780 3eca4642 Eduardo Habkost
        .vendor2 = CPUID_VENDOR_AMD_2,
781 3eca4642 Eduardo Habkost
        .vendor3 = CPUID_VENDOR_AMD_3,
782 3eca4642 Eduardo Habkost
        .family = 15,
783 3eca4642 Eduardo Habkost
        .model = 6,
784 3eca4642 Eduardo Habkost
        .stepping = 1,
785 3eca4642 Eduardo Habkost
        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
786 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
787 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
788 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
789 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
790 3eca4642 Eduardo Habkost
        .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
791 3eca4642 Eduardo Habkost
             CPUID_EXT_SSE3,
792 3eca4642 Eduardo Habkost
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
793 3eca4642 Eduardo Habkost
             CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
794 3eca4642 Eduardo Habkost
             CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
795 3eca4642 Eduardo Habkost
             CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
796 3eca4642 Eduardo Habkost
             CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
797 3eca4642 Eduardo Habkost
             CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
798 3eca4642 Eduardo Habkost
             CPUID_EXT2_DE | CPUID_EXT2_FPU,
799 3eca4642 Eduardo Habkost
        .ext3_features = CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
800 3eca4642 Eduardo Habkost
             CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
801 3eca4642 Eduardo Habkost
        .xlevel = 0x80000008,
802 3eca4642 Eduardo Habkost
        .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
803 3eca4642 Eduardo Habkost
    },
804 3eca4642 Eduardo Habkost
    {
805 3eca4642 Eduardo Habkost
        .name = "Opteron_G4",
806 3eca4642 Eduardo Habkost
        .level = 0xd,
807 3eca4642 Eduardo Habkost
        .vendor1 = CPUID_VENDOR_AMD_1,
808 3eca4642 Eduardo Habkost
        .vendor2 = CPUID_VENDOR_AMD_2,
809 3eca4642 Eduardo Habkost
        .vendor3 = CPUID_VENDOR_AMD_3,
810 3eca4642 Eduardo Habkost
        .family = 21,
811 3eca4642 Eduardo Habkost
        .model = 1,
812 3eca4642 Eduardo Habkost
        .stepping = 2,
813 3eca4642 Eduardo Habkost
        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
814 3eca4642 Eduardo Habkost
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
815 3eca4642 Eduardo Habkost
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
816 3eca4642 Eduardo Habkost
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
817 3eca4642 Eduardo Habkost
             CPUID_DE | CPUID_FP87,
818 3eca4642 Eduardo Habkost
        .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
819 3eca4642 Eduardo Habkost
             CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
820 3eca4642 Eduardo Habkost
             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
821 3eca4642 Eduardo Habkost
             CPUID_EXT_SSE3,
822 3eca4642 Eduardo Habkost
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
823 3eca4642 Eduardo Habkost
             CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
824 3eca4642 Eduardo Habkost
             CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
825 3eca4642 Eduardo Habkost
             CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
826 3eca4642 Eduardo Habkost
             CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
827 3eca4642 Eduardo Habkost
             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
828 3eca4642 Eduardo Habkost
             CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
829 3eca4642 Eduardo Habkost
        .ext3_features = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
830 3eca4642 Eduardo Habkost
             CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
831 3eca4642 Eduardo Habkost
             CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
832 3eca4642 Eduardo Habkost
             CPUID_EXT3_LAHF_LM,
833 3eca4642 Eduardo Habkost
        .xlevel = 0x8000001A,
834 3eca4642 Eduardo Habkost
        .model_id = "AMD Opteron 62xx class CPU",
835 3eca4642 Eduardo Habkost
    },
836 021941b9 Andre Przywara
    {
837 021941b9 Andre Przywara
        .name = "Opteron_G5",
838 021941b9 Andre Przywara
        .level = 0xd,
839 021941b9 Andre Przywara
        .vendor1 = CPUID_VENDOR_AMD_1,
840 021941b9 Andre Przywara
        .vendor2 = CPUID_VENDOR_AMD_2,
841 021941b9 Andre Przywara
        .vendor3 = CPUID_VENDOR_AMD_3,
842 021941b9 Andre Przywara
        .family = 21,
843 021941b9 Andre Przywara
        .model = 2,
844 021941b9 Andre Przywara
        .stepping = 0,
845 021941b9 Andre Przywara
        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
846 021941b9 Andre Przywara
             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
847 021941b9 Andre Przywara
             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
848 021941b9 Andre Przywara
             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
849 021941b9 Andre Przywara
             CPUID_DE | CPUID_FP87,
850 021941b9 Andre Przywara
        .ext_features = CPUID_EXT_F16C | CPUID_EXT_AVX | CPUID_EXT_XSAVE |
851 021941b9 Andre Przywara
             CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
852 021941b9 Andre Przywara
             CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_FMA |
853 021941b9 Andre Przywara
             CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
854 021941b9 Andre Przywara
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
855 021941b9 Andre Przywara
             CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
856 021941b9 Andre Przywara
             CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
857 021941b9 Andre Przywara
             CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
858 021941b9 Andre Przywara
             CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
859 021941b9 Andre Przywara
             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
860 021941b9 Andre Przywara
             CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
861 021941b9 Andre Przywara
        .ext3_features = CPUID_EXT3_TBM | CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
862 021941b9 Andre Przywara
             CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
863 021941b9 Andre Przywara
             CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
864 021941b9 Andre Przywara
             CPUID_EXT3_LAHF_LM,
865 021941b9 Andre Przywara
        .xlevel = 0x8000001A,
866 021941b9 Andre Przywara
        .model_id = "AMD Opteron 63xx class CPU",
867 021941b9 Andre Przywara
    },
868 c6dc6f63 Andre Przywara
};
869 c6dc6f63 Andre Przywara
870 e4ab0d6b Eduardo Habkost
#ifdef CONFIG_KVM
871 c6dc6f63 Andre Przywara
static int cpu_x86_fill_model_id(char *str)
872 c6dc6f63 Andre Przywara
{
873 c6dc6f63 Andre Przywara
    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
874 c6dc6f63 Andre Przywara
    int i;
875 c6dc6f63 Andre Przywara
876 c6dc6f63 Andre Przywara
    for (i = 0; i < 3; i++) {
877 c6dc6f63 Andre Przywara
        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
878 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 +  0, &eax, 4);
879 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 +  4, &ebx, 4);
880 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 +  8, &ecx, 4);
881 c6dc6f63 Andre Przywara
        memcpy(str + i * 16 + 12, &edx, 4);
882 c6dc6f63 Andre Przywara
    }
883 c6dc6f63 Andre Przywara
    return 0;
884 c6dc6f63 Andre Przywara
}
885 e4ab0d6b Eduardo Habkost
#endif
886 c6dc6f63 Andre Przywara
887 6e746f30 Eduardo Habkost
/* Fill a x86_def_t struct with information about the host CPU, and
888 6e746f30 Eduardo Habkost
 * the CPU features supported by the host hardware + host kernel
889 6e746f30 Eduardo Habkost
 *
890 6e746f30 Eduardo Habkost
 * This function may be called only if KVM is enabled.
891 6e746f30 Eduardo Habkost
 */
892 6e746f30 Eduardo Habkost
static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def)
893 c6dc6f63 Andre Przywara
{
894 e4ab0d6b Eduardo Habkost
#ifdef CONFIG_KVM
895 12869995 Eduardo Habkost
    KVMState *s = kvm_state;
896 c6dc6f63 Andre Przywara
    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
897 c6dc6f63 Andre Przywara
898 6e746f30 Eduardo Habkost
    assert(kvm_enabled());
899 6e746f30 Eduardo Habkost
900 c6dc6f63 Andre Przywara
    x86_cpu_def->name = "host";
901 c6dc6f63 Andre Przywara
    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
902 c6dc6f63 Andre Przywara
    x86_cpu_def->vendor1 = ebx;
903 c6dc6f63 Andre Przywara
    x86_cpu_def->vendor2 = edx;
904 c6dc6f63 Andre Przywara
    x86_cpu_def->vendor3 = ecx;
905 c6dc6f63 Andre Przywara
906 c6dc6f63 Andre Przywara
    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
907 c6dc6f63 Andre Przywara
    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
908 c6dc6f63 Andre Przywara
    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
909 c6dc6f63 Andre Przywara
    x86_cpu_def->stepping = eax & 0x0F;
910 c6dc6f63 Andre Przywara
911 12869995 Eduardo Habkost
    x86_cpu_def->level = kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
912 12869995 Eduardo Habkost
    x86_cpu_def->features = kvm_arch_get_supported_cpuid(s, 0x1, 0, R_EDX);
913 12869995 Eduardo Habkost
    x86_cpu_def->ext_features = kvm_arch_get_supported_cpuid(s, 0x1, 0, R_ECX);
914 c6dc6f63 Andre Przywara
915 6e746f30 Eduardo Habkost
    if (x86_cpu_def->level >= 7) {
916 12869995 Eduardo Habkost
        x86_cpu_def->cpuid_7_0_ebx_features =
917 12869995 Eduardo Habkost
                    kvm_arch_get_supported_cpuid(s, 0x7, 0, R_EBX);
918 13526728 Eduardo Habkost
    } else {
919 13526728 Eduardo Habkost
        x86_cpu_def->cpuid_7_0_ebx_features = 0;
920 13526728 Eduardo Habkost
    }
921 13526728 Eduardo Habkost
922 12869995 Eduardo Habkost
    x86_cpu_def->xlevel = kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
923 12869995 Eduardo Habkost
    x86_cpu_def->ext2_features =
924 12869995 Eduardo Habkost
                kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX);
925 12869995 Eduardo Habkost
    x86_cpu_def->ext3_features =
926 12869995 Eduardo Habkost
                kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX);
927 c6dc6f63 Andre Przywara
928 c6dc6f63 Andre Przywara
    cpu_x86_fill_model_id(x86_cpu_def->model_id);
929 c6dc6f63 Andre Przywara
    x86_cpu_def->vendor_override = 0;
930 c6dc6f63 Andre Przywara
931 b3baa152 brillywu@viatech.com.cn
    /* Call Centaur's CPUID instruction. */
932 b3baa152 brillywu@viatech.com.cn
    if (x86_cpu_def->vendor1 == CPUID_VENDOR_VIA_1 &&
933 b3baa152 brillywu@viatech.com.cn
        x86_cpu_def->vendor2 == CPUID_VENDOR_VIA_2 &&
934 b3baa152 brillywu@viatech.com.cn
        x86_cpu_def->vendor3 == CPUID_VENDOR_VIA_3) {
935 b3baa152 brillywu@viatech.com.cn
        host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
936 12869995 Eduardo Habkost
        eax = kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
937 b3baa152 brillywu@viatech.com.cn
        if (eax >= 0xC0000001) {
938 b3baa152 brillywu@viatech.com.cn
            /* Support VIA max extended level */
939 b3baa152 brillywu@viatech.com.cn
            x86_cpu_def->xlevel2 = eax;
940 b3baa152 brillywu@viatech.com.cn
            host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
941 12869995 Eduardo Habkost
            x86_cpu_def->ext4_features =
942 12869995 Eduardo Habkost
                    kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
943 b3baa152 brillywu@viatech.com.cn
        }
944 b3baa152 brillywu@viatech.com.cn
    }
945 296acb64 Joerg Roedel
946 fcb93c03 Eduardo Habkost
    /* Other KVM-specific feature fields: */
947 fcb93c03 Eduardo Habkost
    x86_cpu_def->svm_features =
948 fcb93c03 Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX);
949 bd004bef Eduardo Habkost
    x86_cpu_def->kvm_features =
950 bd004bef Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
951 fcb93c03 Eduardo Habkost
952 e4ab0d6b Eduardo Habkost
#endif /* CONFIG_KVM */
953 c6dc6f63 Andre Przywara
}
954 c6dc6f63 Andre Przywara
955 c6dc6f63 Andre Przywara
static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
956 c6dc6f63 Andre Przywara
{
957 c6dc6f63 Andre Przywara
    int i;
958 c6dc6f63 Andre Przywara
959 c6dc6f63 Andre Przywara
    for (i = 0; i < 32; ++i)
960 c6dc6f63 Andre Przywara
        if (1 << i & mask) {
961 8b4beddc Eduardo Habkost
            const char *reg = get_register_name_32(f->reg);
962 8b4beddc Eduardo Habkost
            assert(reg);
963 8b4beddc Eduardo Habkost
            fprintf(stderr, "warning: host doesn't support requested feature: "
964 8b4beddc Eduardo Habkost
                "CPUID.%02XH:%s%s%s [bit %d]\n",
965 8b4beddc Eduardo Habkost
                f->cpuid, reg,
966 8b4beddc Eduardo Habkost
                f->flag_names[i] ? "." : "",
967 8b4beddc Eduardo Habkost
                f->flag_names[i] ? f->flag_names[i] : "", i);
968 c6dc6f63 Andre Przywara
            break;
969 c6dc6f63 Andre Przywara
        }
970 c6dc6f63 Andre Przywara
    return 0;
971 c6dc6f63 Andre Przywara
}
972 c6dc6f63 Andre Przywara
973 c6dc6f63 Andre Przywara
/* best effort attempt to inform user requested cpu flags aren't making
974 e8beac00 Eduardo Habkost
 * their way to the guest.
975 6e746f30 Eduardo Habkost
 *
976 6e746f30 Eduardo Habkost
 * This function may be called only if KVM is enabled.
977 c6dc6f63 Andre Przywara
 */
978 6e746f30 Eduardo Habkost
static int kvm_check_features_against_host(x86_def_t *guest_def)
979 c6dc6f63 Andre Przywara
{
980 c6dc6f63 Andre Przywara
    x86_def_t host_def;
981 c6dc6f63 Andre Przywara
    uint32_t mask;
982 c6dc6f63 Andre Przywara
    int rv, i;
983 c6dc6f63 Andre Przywara
    struct model_features_t ft[] = {
984 c6dc6f63 Andre Przywara
        {&guest_def->features, &host_def.features,
985 e8beac00 Eduardo Habkost
            feature_name, 0x00000001, R_EDX},
986 c6dc6f63 Andre Przywara
        {&guest_def->ext_features, &host_def.ext_features,
987 e8beac00 Eduardo Habkost
            ext_feature_name, 0x00000001, R_ECX},
988 c6dc6f63 Andre Przywara
        {&guest_def->ext2_features, &host_def.ext2_features,
989 e8beac00 Eduardo Habkost
            ext2_feature_name, 0x80000001, R_EDX},
990 c6dc6f63 Andre Przywara
        {&guest_def->ext3_features, &host_def.ext3_features,
991 e8beac00 Eduardo Habkost
            ext3_feature_name, 0x80000001, R_ECX}
992 8b4beddc Eduardo Habkost
    };
993 c6dc6f63 Andre Przywara
994 6e746f30 Eduardo Habkost
    assert(kvm_enabled());
995 6e746f30 Eduardo Habkost
996 6e746f30 Eduardo Habkost
    kvm_cpu_fill_host(&host_def);
997 66fe09ee Blue Swirl
    for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i)
998 c6dc6f63 Andre Przywara
        for (mask = 1; mask; mask <<= 1)
999 e8beac00 Eduardo Habkost
            if (*ft[i].guest_feat & mask &&
1000 c6dc6f63 Andre Przywara
                !(*ft[i].host_feat & mask)) {
1001 c6dc6f63 Andre Przywara
                    unavailable_host_feature(&ft[i], mask);
1002 c6dc6f63 Andre Przywara
                    rv = 1;
1003 c6dc6f63 Andre Przywara
                }
1004 c6dc6f63 Andre Przywara
    return rv;
1005 c6dc6f63 Andre Przywara
}
1006 c6dc6f63 Andre Przywara
1007 95b8519d Andreas Färber
static void x86_cpuid_version_get_family(Object *obj, Visitor *v, void *opaque,
1008 95b8519d Andreas Färber
                                         const char *name, Error **errp)
1009 95b8519d Andreas Färber
{
1010 95b8519d Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1011 95b8519d Andreas Färber
    CPUX86State *env = &cpu->env;
1012 95b8519d Andreas Färber
    int64_t value;
1013 95b8519d Andreas Färber
1014 95b8519d Andreas Färber
    value = (env->cpuid_version >> 8) & 0xf;
1015 95b8519d Andreas Färber
    if (value == 0xf) {
1016 95b8519d Andreas Färber
        value += (env->cpuid_version >> 20) & 0xff;
1017 95b8519d Andreas Färber
    }
1018 95b8519d Andreas Färber
    visit_type_int(v, &value, name, errp);
1019 95b8519d Andreas Färber
}
1020 95b8519d Andreas Färber
1021 71ad61d3 Andreas Färber
static void x86_cpuid_version_set_family(Object *obj, Visitor *v, void *opaque,
1022 71ad61d3 Andreas Färber
                                         const char *name, Error **errp)
1023 ed5e1ec3 Andreas Färber
{
1024 71ad61d3 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1025 71ad61d3 Andreas Färber
    CPUX86State *env = &cpu->env;
1026 71ad61d3 Andreas Färber
    const int64_t min = 0;
1027 71ad61d3 Andreas Färber
    const int64_t max = 0xff + 0xf;
1028 71ad61d3 Andreas Färber
    int64_t value;
1029 71ad61d3 Andreas Färber
1030 71ad61d3 Andreas Färber
    visit_type_int(v, &value, name, errp);
1031 71ad61d3 Andreas Färber
    if (error_is_set(errp)) {
1032 71ad61d3 Andreas Färber
        return;
1033 71ad61d3 Andreas Färber
    }
1034 71ad61d3 Andreas Färber
    if (value < min || value > max) {
1035 71ad61d3 Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1036 71ad61d3 Andreas Färber
                  name ? name : "null", value, min, max);
1037 71ad61d3 Andreas Färber
        return;
1038 71ad61d3 Andreas Färber
    }
1039 71ad61d3 Andreas Färber
1040 ed5e1ec3 Andreas Färber
    env->cpuid_version &= ~0xff00f00;
1041 71ad61d3 Andreas Färber
    if (value > 0x0f) {
1042 71ad61d3 Andreas Färber
        env->cpuid_version |= 0xf00 | ((value - 0x0f) << 20);
1043 ed5e1ec3 Andreas Färber
    } else {
1044 71ad61d3 Andreas Färber
        env->cpuid_version |= value << 8;
1045 ed5e1ec3 Andreas Färber
    }
1046 ed5e1ec3 Andreas Färber
}
1047 ed5e1ec3 Andreas Färber
1048 67e30c83 Andreas Färber
static void x86_cpuid_version_get_model(Object *obj, Visitor *v, void *opaque,
1049 67e30c83 Andreas Färber
                                        const char *name, Error **errp)
1050 67e30c83 Andreas Färber
{
1051 67e30c83 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1052 67e30c83 Andreas Färber
    CPUX86State *env = &cpu->env;
1053 67e30c83 Andreas Färber
    int64_t value;
1054 67e30c83 Andreas Färber
1055 67e30c83 Andreas Färber
    value = (env->cpuid_version >> 4) & 0xf;
1056 67e30c83 Andreas Färber
    value |= ((env->cpuid_version >> 16) & 0xf) << 4;
1057 67e30c83 Andreas Färber
    visit_type_int(v, &value, name, errp);
1058 67e30c83 Andreas Färber
}
1059 67e30c83 Andreas Färber
1060 c5291a4f Andreas Färber
static void x86_cpuid_version_set_model(Object *obj, Visitor *v, void *opaque,
1061 c5291a4f Andreas Färber
                                        const char *name, Error **errp)
1062 b0704cbd Andreas Färber
{
1063 c5291a4f Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1064 c5291a4f Andreas Färber
    CPUX86State *env = &cpu->env;
1065 c5291a4f Andreas Färber
    const int64_t min = 0;
1066 c5291a4f Andreas Färber
    const int64_t max = 0xff;
1067 c5291a4f Andreas Färber
    int64_t value;
1068 c5291a4f Andreas Färber
1069 c5291a4f Andreas Färber
    visit_type_int(v, &value, name, errp);
1070 c5291a4f Andreas Färber
    if (error_is_set(errp)) {
1071 c5291a4f Andreas Färber
        return;
1072 c5291a4f Andreas Färber
    }
1073 c5291a4f Andreas Färber
    if (value < min || value > max) {
1074 c5291a4f Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1075 c5291a4f Andreas Färber
                  name ? name : "null", value, min, max);
1076 c5291a4f Andreas Färber
        return;
1077 c5291a4f Andreas Färber
    }
1078 c5291a4f Andreas Färber
1079 b0704cbd Andreas Färber
    env->cpuid_version &= ~0xf00f0;
1080 c5291a4f Andreas Färber
    env->cpuid_version |= ((value & 0xf) << 4) | ((value >> 4) << 16);
1081 b0704cbd Andreas Färber
}
1082 b0704cbd Andreas Färber
1083 35112e41 Andreas Färber
static void x86_cpuid_version_get_stepping(Object *obj, Visitor *v,
1084 35112e41 Andreas Färber
                                           void *opaque, const char *name,
1085 35112e41 Andreas Färber
                                           Error **errp)
1086 35112e41 Andreas Färber
{
1087 35112e41 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1088 35112e41 Andreas Färber
    CPUX86State *env = &cpu->env;
1089 35112e41 Andreas Färber
    int64_t value;
1090 35112e41 Andreas Färber
1091 35112e41 Andreas Färber
    value = env->cpuid_version & 0xf;
1092 35112e41 Andreas Färber
    visit_type_int(v, &value, name, errp);
1093 35112e41 Andreas Färber
}
1094 35112e41 Andreas Färber
1095 036e2222 Andreas Färber
static void x86_cpuid_version_set_stepping(Object *obj, Visitor *v,
1096 036e2222 Andreas Färber
                                           void *opaque, const char *name,
1097 036e2222 Andreas Färber
                                           Error **errp)
1098 38c3dc46 Andreas Färber
{
1099 036e2222 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1100 036e2222 Andreas Färber
    CPUX86State *env = &cpu->env;
1101 036e2222 Andreas Färber
    const int64_t min = 0;
1102 036e2222 Andreas Färber
    const int64_t max = 0xf;
1103 036e2222 Andreas Färber
    int64_t value;
1104 036e2222 Andreas Färber
1105 036e2222 Andreas Färber
    visit_type_int(v, &value, name, errp);
1106 036e2222 Andreas Färber
    if (error_is_set(errp)) {
1107 036e2222 Andreas Färber
        return;
1108 036e2222 Andreas Färber
    }
1109 036e2222 Andreas Färber
    if (value < min || value > max) {
1110 036e2222 Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1111 036e2222 Andreas Färber
                  name ? name : "null", value, min, max);
1112 036e2222 Andreas Färber
        return;
1113 036e2222 Andreas Färber
    }
1114 036e2222 Andreas Färber
1115 38c3dc46 Andreas Färber
    env->cpuid_version &= ~0xf;
1116 036e2222 Andreas Färber
    env->cpuid_version |= value & 0xf;
1117 38c3dc46 Andreas Färber
}
1118 38c3dc46 Andreas Färber
1119 8e1898bf Andreas Färber
static void x86_cpuid_get_level(Object *obj, Visitor *v, void *opaque,
1120 8e1898bf Andreas Färber
                                const char *name, Error **errp)
1121 8e1898bf Andreas Färber
{
1122 8e1898bf Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1123 8e1898bf Andreas Färber
1124 fa029887 Andreas Färber
    visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
1125 8e1898bf Andreas Färber
}
1126 8e1898bf Andreas Färber
1127 8e1898bf Andreas Färber
static void x86_cpuid_set_level(Object *obj, Visitor *v, void *opaque,
1128 8e1898bf Andreas Färber
                                const char *name, Error **errp)
1129 8e1898bf Andreas Färber
{
1130 8e1898bf Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1131 8e1898bf Andreas Färber
1132 fa029887 Andreas Färber
    visit_type_uint32(v, &cpu->env.cpuid_level, name, errp);
1133 8e1898bf Andreas Färber
}
1134 8e1898bf Andreas Färber
1135 16b93aa8 Andreas Färber
static void x86_cpuid_get_xlevel(Object *obj, Visitor *v, void *opaque,
1136 16b93aa8 Andreas Färber
                                 const char *name, Error **errp)
1137 16b93aa8 Andreas Färber
{
1138 16b93aa8 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1139 16b93aa8 Andreas Färber
1140 fa029887 Andreas Färber
    visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
1141 16b93aa8 Andreas Färber
}
1142 16b93aa8 Andreas Färber
1143 16b93aa8 Andreas Färber
static void x86_cpuid_set_xlevel(Object *obj, Visitor *v, void *opaque,
1144 16b93aa8 Andreas Färber
                                 const char *name, Error **errp)
1145 16b93aa8 Andreas Färber
{
1146 16b93aa8 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1147 16b93aa8 Andreas Färber
1148 fa029887 Andreas Färber
    visit_type_uint32(v, &cpu->env.cpuid_xlevel, name, errp);
1149 16b93aa8 Andreas Färber
}
1150 16b93aa8 Andreas Färber
1151 d480e1af Andreas Färber
static char *x86_cpuid_get_vendor(Object *obj, Error **errp)
1152 d480e1af Andreas Färber
{
1153 d480e1af Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1154 d480e1af Andreas Färber
    CPUX86State *env = &cpu->env;
1155 d480e1af Andreas Färber
    char *value;
1156 d480e1af Andreas Färber
    int i;
1157 d480e1af Andreas Färber
1158 9df694ee Igor Mammedov
    value = (char *)g_malloc(CPUID_VENDOR_SZ + 1);
1159 d480e1af Andreas Färber
    for (i = 0; i < 4; i++) {
1160 d480e1af Andreas Färber
        value[i    ] = env->cpuid_vendor1 >> (8 * i);
1161 d480e1af Andreas Färber
        value[i + 4] = env->cpuid_vendor2 >> (8 * i);
1162 d480e1af Andreas Färber
        value[i + 8] = env->cpuid_vendor3 >> (8 * i);
1163 d480e1af Andreas Färber
    }
1164 9df694ee Igor Mammedov
    value[CPUID_VENDOR_SZ] = '\0';
1165 d480e1af Andreas Färber
    return value;
1166 d480e1af Andreas Färber
}
1167 d480e1af Andreas Färber
1168 d480e1af Andreas Färber
static void x86_cpuid_set_vendor(Object *obj, const char *value,
1169 d480e1af Andreas Färber
                                 Error **errp)
1170 d480e1af Andreas Färber
{
1171 d480e1af Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1172 d480e1af Andreas Färber
    CPUX86State *env = &cpu->env;
1173 d480e1af Andreas Färber
    int i;
1174 d480e1af Andreas Färber
1175 9df694ee Igor Mammedov
    if (strlen(value) != CPUID_VENDOR_SZ) {
1176 d480e1af Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_BAD, "",
1177 d480e1af Andreas Färber
                  "vendor", value);
1178 d480e1af Andreas Färber
        return;
1179 d480e1af Andreas Färber
    }
1180 d480e1af Andreas Färber
1181 d480e1af Andreas Färber
    env->cpuid_vendor1 = 0;
1182 d480e1af Andreas Färber
    env->cpuid_vendor2 = 0;
1183 d480e1af Andreas Färber
    env->cpuid_vendor3 = 0;
1184 d480e1af Andreas Färber
    for (i = 0; i < 4; i++) {
1185 d480e1af Andreas Färber
        env->cpuid_vendor1 |= ((uint8_t)value[i    ]) << (8 * i);
1186 d480e1af Andreas Färber
        env->cpuid_vendor2 |= ((uint8_t)value[i + 4]) << (8 * i);
1187 d480e1af Andreas Färber
        env->cpuid_vendor3 |= ((uint8_t)value[i + 8]) << (8 * i);
1188 d480e1af Andreas Färber
    }
1189 d480e1af Andreas Färber
    env->cpuid_vendor_override = 1;
1190 d480e1af Andreas Färber
}
1191 d480e1af Andreas Färber
1192 63e886eb Andreas Färber
static char *x86_cpuid_get_model_id(Object *obj, Error **errp)
1193 63e886eb Andreas Färber
{
1194 63e886eb Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1195 63e886eb Andreas Färber
    CPUX86State *env = &cpu->env;
1196 63e886eb Andreas Färber
    char *value;
1197 63e886eb Andreas Färber
    int i;
1198 63e886eb Andreas Färber
1199 63e886eb Andreas Färber
    value = g_malloc(48 + 1);
1200 63e886eb Andreas Färber
    for (i = 0; i < 48; i++) {
1201 63e886eb Andreas Färber
        value[i] = env->cpuid_model[i >> 2] >> (8 * (i & 3));
1202 63e886eb Andreas Färber
    }
1203 63e886eb Andreas Färber
    value[48] = '\0';
1204 63e886eb Andreas Färber
    return value;
1205 63e886eb Andreas Färber
}
1206 63e886eb Andreas Färber
1207 938d4c25 Andreas Färber
static void x86_cpuid_set_model_id(Object *obj, const char *model_id,
1208 938d4c25 Andreas Färber
                                   Error **errp)
1209 dcce6675 Andreas Färber
{
1210 938d4c25 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1211 938d4c25 Andreas Färber
    CPUX86State *env = &cpu->env;
1212 dcce6675 Andreas Färber
    int c, len, i;
1213 dcce6675 Andreas Färber
1214 dcce6675 Andreas Färber
    if (model_id == NULL) {
1215 dcce6675 Andreas Färber
        model_id = "";
1216 dcce6675 Andreas Färber
    }
1217 dcce6675 Andreas Färber
    len = strlen(model_id);
1218 d0a6acf4 Andreas Färber
    memset(env->cpuid_model, 0, 48);
1219 dcce6675 Andreas Färber
    for (i = 0; i < 48; i++) {
1220 dcce6675 Andreas Färber
        if (i >= len) {
1221 dcce6675 Andreas Färber
            c = '\0';
1222 dcce6675 Andreas Färber
        } else {
1223 dcce6675 Andreas Färber
            c = (uint8_t)model_id[i];
1224 dcce6675 Andreas Färber
        }
1225 dcce6675 Andreas Färber
        env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
1226 dcce6675 Andreas Färber
    }
1227 dcce6675 Andreas Färber
}
1228 dcce6675 Andreas Färber
1229 89e48965 Andreas Färber
static void x86_cpuid_get_tsc_freq(Object *obj, Visitor *v, void *opaque,
1230 89e48965 Andreas Färber
                                   const char *name, Error **errp)
1231 89e48965 Andreas Färber
{
1232 89e48965 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1233 89e48965 Andreas Färber
    int64_t value;
1234 89e48965 Andreas Färber
1235 89e48965 Andreas Färber
    value = cpu->env.tsc_khz * 1000;
1236 89e48965 Andreas Färber
    visit_type_int(v, &value, name, errp);
1237 89e48965 Andreas Färber
}
1238 89e48965 Andreas Färber
1239 89e48965 Andreas Färber
static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
1240 89e48965 Andreas Färber
                                   const char *name, Error **errp)
1241 89e48965 Andreas Färber
{
1242 89e48965 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
1243 89e48965 Andreas Färber
    const int64_t min = 0;
1244 2e84849a Don Slutz
    const int64_t max = INT64_MAX;
1245 89e48965 Andreas Färber
    int64_t value;
1246 89e48965 Andreas Färber
1247 89e48965 Andreas Färber
    visit_type_int(v, &value, name, errp);
1248 89e48965 Andreas Färber
    if (error_is_set(errp)) {
1249 89e48965 Andreas Färber
        return;
1250 89e48965 Andreas Färber
    }
1251 89e48965 Andreas Färber
    if (value < min || value > max) {
1252 89e48965 Andreas Färber
        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, "",
1253 89e48965 Andreas Färber
                  name ? name : "null", value, min, max);
1254 89e48965 Andreas Färber
        return;
1255 89e48965 Andreas Färber
    }
1256 89e48965 Andreas Färber
1257 89e48965 Andreas Färber
    cpu->env.tsc_khz = value / 1000;
1258 89e48965 Andreas Färber
}
1259 89e48965 Andreas Färber
1260 8f961357 Eduardo Habkost
static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *name)
1261 c6dc6f63 Andre Przywara
{
1262 c6dc6f63 Andre Przywara
    x86_def_t *def;
1263 c6dc6f63 Andre Przywara
1264 9f3fb565 Eduardo Habkost
    for (def = x86_defs; def; def = def->next) {
1265 9f3fb565 Eduardo Habkost
        if (name && !strcmp(name, def->name)) {
1266 c6dc6f63 Andre Przywara
            break;
1267 9f3fb565 Eduardo Habkost
        }
1268 9f3fb565 Eduardo Habkost
    }
1269 04c5b17a Markus Armbruster
    if (kvm_enabled() && name && strcmp(name, "host") == 0) {
1270 6e746f30 Eduardo Habkost
        kvm_cpu_fill_host(x86_cpu_def);
1271 c6dc6f63 Andre Przywara
    } else if (!def) {
1272 8f961357 Eduardo Habkost
        return -1;
1273 c6dc6f63 Andre Przywara
    } else {
1274 c6dc6f63 Andre Przywara
        memcpy(x86_cpu_def, def, sizeof(*def));
1275 c6dc6f63 Andre Przywara
    }
1276 c6dc6f63 Andre Przywara
1277 8f961357 Eduardo Habkost
    return 0;
1278 8f961357 Eduardo Habkost
}
1279 8f961357 Eduardo Habkost
1280 8f961357 Eduardo Habkost
/* Parse "+feature,-feature,feature=foo" CPU feature string
1281 8f961357 Eduardo Habkost
 */
1282 8f961357 Eduardo Habkost
static int cpu_x86_parse_featurestr(x86_def_t *x86_cpu_def, char *features)
1283 8f961357 Eduardo Habkost
{
1284 8f961357 Eduardo Habkost
    unsigned int i;
1285 8f961357 Eduardo Habkost
    char *featurestr; /* Single 'key=value" string being parsed */
1286 8f961357 Eduardo Habkost
    /* Features to be added */
1287 8f961357 Eduardo Habkost
    uint32_t plus_features = 0, plus_ext_features = 0;
1288 8f961357 Eduardo Habkost
    uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
1289 8f961357 Eduardo Habkost
    uint32_t plus_kvm_features = kvm_default_features, plus_svm_features = 0;
1290 8f961357 Eduardo Habkost
    uint32_t plus_7_0_ebx_features = 0;
1291 8f961357 Eduardo Habkost
    /* Features to be removed */
1292 8f961357 Eduardo Habkost
    uint32_t minus_features = 0, minus_ext_features = 0;
1293 8f961357 Eduardo Habkost
    uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
1294 8f961357 Eduardo Habkost
    uint32_t minus_kvm_features = 0, minus_svm_features = 0;
1295 8f961357 Eduardo Habkost
    uint32_t minus_7_0_ebx_features = 0;
1296 8f961357 Eduardo Habkost
    uint32_t numvalue;
1297 8f961357 Eduardo Habkost
1298 c6dc6f63 Andre Przywara
    add_flagname_to_bitmaps("hypervisor", &plus_features,
1299 a9321a4d H. Peter Anvin
            &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
1300 a9321a4d H. Peter Anvin
            &plus_kvm_features, &plus_svm_features,  &plus_7_0_ebx_features);
1301 c6dc6f63 Andre Przywara
1302 8f961357 Eduardo Habkost
    featurestr = features ? strtok(features, ",") : NULL;
1303 c6dc6f63 Andre Przywara
1304 c6dc6f63 Andre Przywara
    while (featurestr) {
1305 c6dc6f63 Andre Przywara
        char *val;
1306 c6dc6f63 Andre Przywara
        if (featurestr[0] == '+') {
1307 296acb64 Joerg Roedel
            add_flagname_to_bitmaps(featurestr + 1, &plus_features,
1308 296acb64 Joerg Roedel
                            &plus_ext_features, &plus_ext2_features,
1309 296acb64 Joerg Roedel
                            &plus_ext3_features, &plus_kvm_features,
1310 a9321a4d H. Peter Anvin
                            &plus_svm_features, &plus_7_0_ebx_features);
1311 c6dc6f63 Andre Przywara
        } else if (featurestr[0] == '-') {
1312 296acb64 Joerg Roedel
            add_flagname_to_bitmaps(featurestr + 1, &minus_features,
1313 296acb64 Joerg Roedel
                            &minus_ext_features, &minus_ext2_features,
1314 296acb64 Joerg Roedel
                            &minus_ext3_features, &minus_kvm_features,
1315 a9321a4d H. Peter Anvin
                            &minus_svm_features, &minus_7_0_ebx_features);
1316 c6dc6f63 Andre Przywara
        } else if ((val = strchr(featurestr, '='))) {
1317 c6dc6f63 Andre Przywara
            *val = 0; val++;
1318 c6dc6f63 Andre Przywara
            if (!strcmp(featurestr, "family")) {
1319 c6dc6f63 Andre Przywara
                char *err;
1320 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
1321 a88a677f Andreas Färber
                if (!*val || *err || numvalue > 0xff + 0xf) {
1322 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
1323 c6dc6f63 Andre Przywara
                    goto error;
1324 c6dc6f63 Andre Przywara
                }
1325 c6dc6f63 Andre Przywara
                x86_cpu_def->family = numvalue;
1326 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "model")) {
1327 c6dc6f63 Andre Przywara
                char *err;
1328 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
1329 c6dc6f63 Andre Przywara
                if (!*val || *err || numvalue > 0xff) {
1330 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
1331 c6dc6f63 Andre Przywara
                    goto error;
1332 c6dc6f63 Andre Przywara
                }
1333 c6dc6f63 Andre Przywara
                x86_cpu_def->model = numvalue;
1334 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "stepping")) {
1335 c6dc6f63 Andre Przywara
                char *err;
1336 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
1337 c6dc6f63 Andre Przywara
                if (!*val || *err || numvalue > 0xf) {
1338 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
1339 c6dc6f63 Andre Przywara
                    goto error;
1340 c6dc6f63 Andre Przywara
                }
1341 c6dc6f63 Andre Przywara
                x86_cpu_def->stepping = numvalue ;
1342 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "level")) {
1343 c6dc6f63 Andre Przywara
                char *err;
1344 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
1345 c6dc6f63 Andre Przywara
                if (!*val || *err) {
1346 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
1347 c6dc6f63 Andre Przywara
                    goto error;
1348 c6dc6f63 Andre Przywara
                }
1349 c6dc6f63 Andre Przywara
                x86_cpu_def->level = numvalue;
1350 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "xlevel")) {
1351 c6dc6f63 Andre Przywara
                char *err;
1352 c6dc6f63 Andre Przywara
                numvalue = strtoul(val, &err, 0);
1353 c6dc6f63 Andre Przywara
                if (!*val || *err) {
1354 c6dc6f63 Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
1355 c6dc6f63 Andre Przywara
                    goto error;
1356 c6dc6f63 Andre Przywara
                }
1357 c6dc6f63 Andre Przywara
                if (numvalue < 0x80000000) {
1358 2f7a21c4 Aurelien Jarno
                    numvalue += 0x80000000;
1359 c6dc6f63 Andre Przywara
                }
1360 c6dc6f63 Andre Przywara
                x86_cpu_def->xlevel = numvalue;
1361 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "vendor")) {
1362 c6dc6f63 Andre Przywara
                if (strlen(val) != 12) {
1363 c6dc6f63 Andre Przywara
                    fprintf(stderr, "vendor string must be 12 chars long\n");
1364 c6dc6f63 Andre Przywara
                    goto error;
1365 c6dc6f63 Andre Przywara
                }
1366 c6dc6f63 Andre Przywara
                x86_cpu_def->vendor1 = 0;
1367 c6dc6f63 Andre Przywara
                x86_cpu_def->vendor2 = 0;
1368 c6dc6f63 Andre Przywara
                x86_cpu_def->vendor3 = 0;
1369 c6dc6f63 Andre Przywara
                for(i = 0; i < 4; i++) {
1370 c6dc6f63 Andre Przywara
                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
1371 c6dc6f63 Andre Przywara
                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
1372 c6dc6f63 Andre Przywara
                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
1373 c6dc6f63 Andre Przywara
                }
1374 c6dc6f63 Andre Przywara
                x86_cpu_def->vendor_override = 1;
1375 c6dc6f63 Andre Przywara
            } else if (!strcmp(featurestr, "model_id")) {
1376 c6dc6f63 Andre Przywara
                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
1377 c6dc6f63 Andre Przywara
                        val);
1378 b862d1fe Joerg Roedel
            } else if (!strcmp(featurestr, "tsc_freq")) {
1379 b862d1fe Joerg Roedel
                int64_t tsc_freq;
1380 b862d1fe Joerg Roedel
                char *err;
1381 b862d1fe Joerg Roedel
1382 b862d1fe Joerg Roedel
                tsc_freq = strtosz_suffix_unit(val, &err,
1383 b862d1fe Joerg Roedel
                                               STRTOSZ_DEFSUFFIX_B, 1000);
1384 45009a30 Markus Armbruster
                if (tsc_freq < 0 || *err) {
1385 b862d1fe Joerg Roedel
                    fprintf(stderr, "bad numerical value %s\n", val);
1386 b862d1fe Joerg Roedel
                    goto error;
1387 b862d1fe Joerg Roedel
                }
1388 b862d1fe Joerg Roedel
                x86_cpu_def->tsc_khz = tsc_freq / 1000;
1389 28f52cc0 Vadim Rozenfeld
            } else if (!strcmp(featurestr, "hv_spinlocks")) {
1390 28f52cc0 Vadim Rozenfeld
                char *err;
1391 28f52cc0 Vadim Rozenfeld
                numvalue = strtoul(val, &err, 0);
1392 28f52cc0 Vadim Rozenfeld
                if (!*val || *err) {
1393 28f52cc0 Vadim Rozenfeld
                    fprintf(stderr, "bad numerical value %s\n", val);
1394 28f52cc0 Vadim Rozenfeld
                    goto error;
1395 28f52cc0 Vadim Rozenfeld
                }
1396 28f52cc0 Vadim Rozenfeld
                hyperv_set_spinlock_retries(numvalue);
1397 c6dc6f63 Andre Przywara
            } else {
1398 c6dc6f63 Andre Przywara
                fprintf(stderr, "unrecognized feature %s\n", featurestr);
1399 c6dc6f63 Andre Przywara
                goto error;
1400 c6dc6f63 Andre Przywara
            }
1401 c6dc6f63 Andre Przywara
        } else if (!strcmp(featurestr, "check")) {
1402 c6dc6f63 Andre Przywara
            check_cpuid = 1;
1403 c6dc6f63 Andre Przywara
        } else if (!strcmp(featurestr, "enforce")) {
1404 c6dc6f63 Andre Przywara
            check_cpuid = enforce_cpuid = 1;
1405 28f52cc0 Vadim Rozenfeld
        } else if (!strcmp(featurestr, "hv_relaxed")) {
1406 28f52cc0 Vadim Rozenfeld
            hyperv_enable_relaxed_timing(true);
1407 28f52cc0 Vadim Rozenfeld
        } else if (!strcmp(featurestr, "hv_vapic")) {
1408 28f52cc0 Vadim Rozenfeld
            hyperv_enable_vapic_recommended(true);
1409 c6dc6f63 Andre Przywara
        } else {
1410 c6dc6f63 Andre Przywara
            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
1411 c6dc6f63 Andre Przywara
            goto error;
1412 c6dc6f63 Andre Przywara
        }
1413 c6dc6f63 Andre Przywara
        featurestr = strtok(NULL, ",");
1414 c6dc6f63 Andre Przywara
    }
1415 c6dc6f63 Andre Przywara
    x86_cpu_def->features |= plus_features;
1416 c6dc6f63 Andre Przywara
    x86_cpu_def->ext_features |= plus_ext_features;
1417 c6dc6f63 Andre Przywara
    x86_cpu_def->ext2_features |= plus_ext2_features;
1418 c6dc6f63 Andre Przywara
    x86_cpu_def->ext3_features |= plus_ext3_features;
1419 c6dc6f63 Andre Przywara
    x86_cpu_def->kvm_features |= plus_kvm_features;
1420 296acb64 Joerg Roedel
    x86_cpu_def->svm_features |= plus_svm_features;
1421 a9321a4d H. Peter Anvin
    x86_cpu_def->cpuid_7_0_ebx_features |= plus_7_0_ebx_features;
1422 c6dc6f63 Andre Przywara
    x86_cpu_def->features &= ~minus_features;
1423 c6dc6f63 Andre Przywara
    x86_cpu_def->ext_features &= ~minus_ext_features;
1424 c6dc6f63 Andre Przywara
    x86_cpu_def->ext2_features &= ~minus_ext2_features;
1425 c6dc6f63 Andre Przywara
    x86_cpu_def->ext3_features &= ~minus_ext3_features;
1426 c6dc6f63 Andre Przywara
    x86_cpu_def->kvm_features &= ~minus_kvm_features;
1427 296acb64 Joerg Roedel
    x86_cpu_def->svm_features &= ~minus_svm_features;
1428 a9321a4d H. Peter Anvin
    x86_cpu_def->cpuid_7_0_ebx_features &= ~minus_7_0_ebx_features;
1429 6e746f30 Eduardo Habkost
    if (check_cpuid && kvm_enabled()) {
1430 6e746f30 Eduardo Habkost
        if (kvm_check_features_against_host(x86_cpu_def) && enforce_cpuid)
1431 c6dc6f63 Andre Przywara
            goto error;
1432 c6dc6f63 Andre Przywara
    }
1433 c6dc6f63 Andre Przywara
    return 0;
1434 c6dc6f63 Andre Przywara
1435 c6dc6f63 Andre Przywara
error:
1436 c6dc6f63 Andre Przywara
    return -1;
1437 c6dc6f63 Andre Przywara
}
1438 c6dc6f63 Andre Przywara
1439 c6dc6f63 Andre Przywara
/* generate a composite string into buf of all cpuid names in featureset
1440 c6dc6f63 Andre Przywara
 * selected by fbits.  indicate truncation at bufsize in the event of overflow.
1441 c6dc6f63 Andre Przywara
 * if flags, suppress names undefined in featureset.
1442 c6dc6f63 Andre Przywara
 */
1443 c6dc6f63 Andre Przywara
static void listflags(char *buf, int bufsize, uint32_t fbits,
1444 c6dc6f63 Andre Przywara
    const char **featureset, uint32_t flags)
1445 c6dc6f63 Andre Przywara
{
1446 c6dc6f63 Andre Przywara
    const char **p = &featureset[31];
1447 c6dc6f63 Andre Przywara
    char *q, *b, bit;
1448 c6dc6f63 Andre Przywara
    int nc;
1449 c6dc6f63 Andre Przywara
1450 c6dc6f63 Andre Przywara
    b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
1451 c6dc6f63 Andre Przywara
    *buf = '\0';
1452 c6dc6f63 Andre Przywara
    for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
1453 c6dc6f63 Andre Przywara
        if (fbits & 1 << bit && (*p || !flags)) {
1454 c6dc6f63 Andre Przywara
            if (*p)
1455 c6dc6f63 Andre Przywara
                nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
1456 c6dc6f63 Andre Przywara
            else
1457 c6dc6f63 Andre Przywara
                nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
1458 c6dc6f63 Andre Przywara
            if (bufsize <= nc) {
1459 c6dc6f63 Andre Przywara
                if (b) {
1460 c6dc6f63 Andre Przywara
                    memcpy(b, "...", sizeof("..."));
1461 c6dc6f63 Andre Przywara
                }
1462 c6dc6f63 Andre Przywara
                return;
1463 c6dc6f63 Andre Przywara
            }
1464 c6dc6f63 Andre Przywara
            q += nc;
1465 c6dc6f63 Andre Przywara
            bufsize -= nc;
1466 c6dc6f63 Andre Przywara
        }
1467 c6dc6f63 Andre Przywara
}
1468 c6dc6f63 Andre Przywara
1469 e916cbf8 Peter Maydell
/* generate CPU information. */
1470 e916cbf8 Peter Maydell
void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
1471 c6dc6f63 Andre Przywara
{
1472 c6dc6f63 Andre Przywara
    x86_def_t *def;
1473 c6dc6f63 Andre Przywara
    char buf[256];
1474 c6dc6f63 Andre Przywara
1475 c6dc6f63 Andre Przywara
    for (def = x86_defs; def; def = def->next) {
1476 c04321b3 Eduardo Habkost
        snprintf(buf, sizeof(buf), "%s", def->name);
1477 6cdf8854 Peter Maydell
        (*cpu_fprintf)(f, "x86 %16s  %-48s\n", buf, def->model_id);
1478 c6dc6f63 Andre Przywara
    }
1479 ed2c54d4 Andre Przywara
    if (kvm_enabled()) {
1480 ed2c54d4 Andre Przywara
        (*cpu_fprintf)(f, "x86 %16s\n", "[host]");
1481 ed2c54d4 Andre Przywara
    }
1482 6cdf8854 Peter Maydell
    (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
1483 6cdf8854 Peter Maydell
    listflags(buf, sizeof(buf), (uint32_t)~0, feature_name, 1);
1484 4a19e505 Eduardo Habkost
    (*cpu_fprintf)(f, "  %s\n", buf);
1485 6cdf8854 Peter Maydell
    listflags(buf, sizeof(buf), (uint32_t)~0, ext_feature_name, 1);
1486 4a19e505 Eduardo Habkost
    (*cpu_fprintf)(f, "  %s\n", buf);
1487 6cdf8854 Peter Maydell
    listflags(buf, sizeof(buf), (uint32_t)~0, ext2_feature_name, 1);
1488 4a19e505 Eduardo Habkost
    (*cpu_fprintf)(f, "  %s\n", buf);
1489 6cdf8854 Peter Maydell
    listflags(buf, sizeof(buf), (uint32_t)~0, ext3_feature_name, 1);
1490 4a19e505 Eduardo Habkost
    (*cpu_fprintf)(f, "  %s\n", buf);
1491 c6dc6f63 Andre Przywara
}
1492 c6dc6f63 Andre Przywara
1493 76b64a7a Anthony Liguori
CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
1494 e3966126 Anthony Liguori
{
1495 e3966126 Anthony Liguori
    CpuDefinitionInfoList *cpu_list = NULL;
1496 e3966126 Anthony Liguori
    x86_def_t *def;
1497 e3966126 Anthony Liguori
1498 e3966126 Anthony Liguori
    for (def = x86_defs; def; def = def->next) {
1499 e3966126 Anthony Liguori
        CpuDefinitionInfoList *entry;
1500 e3966126 Anthony Liguori
        CpuDefinitionInfo *info;
1501 e3966126 Anthony Liguori
1502 e3966126 Anthony Liguori
        info = g_malloc0(sizeof(*info));
1503 e3966126 Anthony Liguori
        info->name = g_strdup(def->name);
1504 e3966126 Anthony Liguori
1505 e3966126 Anthony Liguori
        entry = g_malloc0(sizeof(*entry));
1506 e3966126 Anthony Liguori
        entry->value = info;
1507 e3966126 Anthony Liguori
        entry->next = cpu_list;
1508 e3966126 Anthony Liguori
        cpu_list = entry;
1509 e3966126 Anthony Liguori
    }
1510 e3966126 Anthony Liguori
1511 e3966126 Anthony Liguori
    return cpu_list;
1512 e3966126 Anthony Liguori
}
1513 e3966126 Anthony Liguori
1514 bc74b7db Eduardo Habkost
#ifdef CONFIG_KVM
1515 bc74b7db Eduardo Habkost
static void filter_features_for_kvm(X86CPU *cpu)
1516 bc74b7db Eduardo Habkost
{
1517 bc74b7db Eduardo Habkost
    CPUX86State *env = &cpu->env;
1518 bc74b7db Eduardo Habkost
    KVMState *s = kvm_state;
1519 bc74b7db Eduardo Habkost
1520 b8091f24 Eduardo Habkost
    env->cpuid_features &=
1521 b8091f24 Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
1522 b8091f24 Eduardo Habkost
    env->cpuid_ext_features &=
1523 b8091f24 Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX);
1524 b8091f24 Eduardo Habkost
    env->cpuid_ext2_features &=
1525 b8091f24 Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_EDX);
1526 b8091f24 Eduardo Habkost
    env->cpuid_ext3_features &=
1527 b8091f24 Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, 0x80000001, 0, R_ECX);
1528 b8091f24 Eduardo Habkost
    env->cpuid_svm_features  &=
1529 b8091f24 Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, 0x8000000A, 0, R_EDX);
1530 ffa8c11f Eduardo Habkost
    env->cpuid_7_0_ebx_features &=
1531 ffa8c11f Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, 7, 0, R_EBX);
1532 bc74b7db Eduardo Habkost
    env->cpuid_kvm_features &=
1533 b8091f24 Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
1534 b8091f24 Eduardo Habkost
    env->cpuid_ext4_features &=
1535 b8091f24 Eduardo Habkost
        kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
1536 bc74b7db Eduardo Habkost
1537 bc74b7db Eduardo Habkost
}
1538 bc74b7db Eduardo Habkost
#endif
1539 bc74b7db Eduardo Habkost
1540 61dcd775 Andreas Färber
int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
1541 c6dc6f63 Andre Przywara
{
1542 61dcd775 Andreas Färber
    CPUX86State *env = &cpu->env;
1543 c6dc6f63 Andre Przywara
    x86_def_t def1, *def = &def1;
1544 71ad61d3 Andreas Färber
    Error *error = NULL;
1545 8f961357 Eduardo Habkost
    char *name, *features;
1546 8f961357 Eduardo Habkost
    gchar **model_pieces;
1547 c6dc6f63 Andre Przywara
1548 db0ad1ba Joerg Roedel
    memset(def, 0, sizeof(*def));
1549 db0ad1ba Joerg Roedel
1550 8f961357 Eduardo Habkost
    model_pieces = g_strsplit(cpu_model, ",", 2);
1551 8f961357 Eduardo Habkost
    if (!model_pieces[0]) {
1552 8f961357 Eduardo Habkost
        goto error;
1553 8f961357 Eduardo Habkost
    }
1554 8f961357 Eduardo Habkost
    name = model_pieces[0];
1555 8f961357 Eduardo Habkost
    features = model_pieces[1];
1556 8f961357 Eduardo Habkost
1557 8f961357 Eduardo Habkost
    if (cpu_x86_find_by_name(def, name) < 0) {
1558 8f961357 Eduardo Habkost
        goto error;
1559 8f961357 Eduardo Habkost
    }
1560 8f961357 Eduardo Habkost
1561 8f961357 Eduardo Habkost
    if (cpu_x86_parse_featurestr(def, features) < 0) {
1562 8f961357 Eduardo Habkost
        goto error;
1563 8f961357 Eduardo Habkost
    }
1564 ebe8b9c6 Igor Mammedov
    assert(def->vendor1);
1565 ebe8b9c6 Igor Mammedov
    env->cpuid_vendor1 = def->vendor1;
1566 ebe8b9c6 Igor Mammedov
    env->cpuid_vendor2 = def->vendor2;
1567 ebe8b9c6 Igor Mammedov
    env->cpuid_vendor3 = def->vendor3;
1568 c6dc6f63 Andre Przywara
    env->cpuid_vendor_override = def->vendor_override;
1569 8e1898bf Andreas Färber
    object_property_set_int(OBJECT(cpu), def->level, "level", &error);
1570 71ad61d3 Andreas Färber
    object_property_set_int(OBJECT(cpu), def->family, "family", &error);
1571 c5291a4f Andreas Färber
    object_property_set_int(OBJECT(cpu), def->model, "model", &error);
1572 036e2222 Andreas Färber
    object_property_set_int(OBJECT(cpu), def->stepping, "stepping", &error);
1573 c6dc6f63 Andre Przywara
    env->cpuid_features = def->features;
1574 c6dc6f63 Andre Przywara
    env->cpuid_ext_features = def->ext_features;
1575 c6dc6f63 Andre Przywara
    env->cpuid_ext2_features = def->ext2_features;
1576 4d067ed7 Andre Przywara
    env->cpuid_ext3_features = def->ext3_features;
1577 16b93aa8 Andreas Färber
    object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", &error);
1578 c6dc6f63 Andre Przywara
    env->cpuid_kvm_features = def->kvm_features;
1579 296acb64 Joerg Roedel
    env->cpuid_svm_features = def->svm_features;
1580 b3baa152 brillywu@viatech.com.cn
    env->cpuid_ext4_features = def->ext4_features;
1581 a9321a4d H. Peter Anvin
    env->cpuid_7_0_ebx_features = def->cpuid_7_0_ebx_features;
1582 b3baa152 brillywu@viatech.com.cn
    env->cpuid_xlevel2 = def->xlevel2;
1583 89e48965 Andreas Färber
    object_property_set_int(OBJECT(cpu), (int64_t)def->tsc_khz * 1000,
1584 89e48965 Andreas Färber
                            "tsc-frequency", &error);
1585 3b671a40 Eduardo Habkost
1586 938d4c25 Andreas Färber
    object_property_set_str(OBJECT(cpu), def->model_id, "model-id", &error);
1587 18eb473f Igor Mammedov
    if (error) {
1588 18eb473f Igor Mammedov
        fprintf(stderr, "%s\n", error_get_pretty(error));
1589 71ad61d3 Andreas Färber
        error_free(error);
1590 8f961357 Eduardo Habkost
        goto error;
1591 71ad61d3 Andreas Färber
    }
1592 8f961357 Eduardo Habkost
1593 8f961357 Eduardo Habkost
    g_strfreev(model_pieces);
1594 c6dc6f63 Andre Przywara
    return 0;
1595 8f961357 Eduardo Habkost
error:
1596 8f961357 Eduardo Habkost
    g_strfreev(model_pieces);
1597 8f961357 Eduardo Habkost
    return -1;
1598 c6dc6f63 Andre Przywara
}
1599 c6dc6f63 Andre Przywara
1600 c6dc6f63 Andre Przywara
#if !defined(CONFIG_USER_ONLY)
1601 c6dc6f63 Andre Przywara
1602 0e26b7b8 Blue Swirl
void cpu_clear_apic_feature(CPUX86State *env)
1603 0e26b7b8 Blue Swirl
{
1604 0e26b7b8 Blue Swirl
    env->cpuid_features &= ~CPUID_APIC;
1605 0e26b7b8 Blue Swirl
}
1606 0e26b7b8 Blue Swirl
1607 c6dc6f63 Andre Przywara
#endif /* !CONFIG_USER_ONLY */
1608 c6dc6f63 Andre Przywara
1609 c04321b3 Eduardo Habkost
/* Initialize list of CPU models, filling some non-static fields if necessary
1610 c6dc6f63 Andre Przywara
 */
1611 c6dc6f63 Andre Przywara
void x86_cpudef_setup(void)
1612 c6dc6f63 Andre Przywara
{
1613 93bfef4c Crístian Viana
    int i, j;
1614 93bfef4c Crístian Viana
    static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
1615 c6dc6f63 Andre Przywara
1616 c6dc6f63 Andre Przywara
    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
1617 bc3e1291 Eduardo Habkost
        x86_def_t *def = &builtin_x86_defs[i];
1618 bc3e1291 Eduardo Habkost
        def->next = x86_defs;
1619 93bfef4c Crístian Viana
1620 93bfef4c Crístian Viana
        /* Look for specific "cpudef" models that */
1621 09faecf2 Stefan Weil
        /* have the QEMU version in .model_id */
1622 93bfef4c Crístian Viana
        for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
1623 bc3e1291 Eduardo Habkost
            if (strcmp(model_with_versions[j], def->name) == 0) {
1624 bc3e1291 Eduardo Habkost
                pstrcpy(def->model_id, sizeof(def->model_id),
1625 bc3e1291 Eduardo Habkost
                        "QEMU Virtual CPU version ");
1626 bc3e1291 Eduardo Habkost
                pstrcat(def->model_id, sizeof(def->model_id),
1627 bc3e1291 Eduardo Habkost
                        qemu_get_version());
1628 93bfef4c Crístian Viana
                break;
1629 93bfef4c Crístian Viana
            }
1630 93bfef4c Crístian Viana
        }
1631 93bfef4c Crístian Viana
1632 bc3e1291 Eduardo Habkost
        x86_defs = def;
1633 c6dc6f63 Andre Przywara
    }
1634 c6dc6f63 Andre Przywara
}
1635 c6dc6f63 Andre Przywara
1636 c6dc6f63 Andre Przywara
static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
1637 c6dc6f63 Andre Przywara
                             uint32_t *ecx, uint32_t *edx)
1638 c6dc6f63 Andre Przywara
{
1639 c6dc6f63 Andre Przywara
    *ebx = env->cpuid_vendor1;
1640 c6dc6f63 Andre Przywara
    *edx = env->cpuid_vendor2;
1641 c6dc6f63 Andre Przywara
    *ecx = env->cpuid_vendor3;
1642 c6dc6f63 Andre Przywara
1643 c6dc6f63 Andre Przywara
    /* sysenter isn't supported on compatibility mode on AMD, syscall
1644 c6dc6f63 Andre Przywara
     * isn't supported in compatibility mode on Intel.
1645 c6dc6f63 Andre Przywara
     * Normally we advertise the actual cpu vendor, but you can override
1646 c6dc6f63 Andre Przywara
     * this if you want to use KVM's sysenter/syscall emulation
1647 c6dc6f63 Andre Przywara
     * in compatibility mode and when doing cross vendor migration
1648 c6dc6f63 Andre Przywara
     */
1649 89354998 Andre Przywara
    if (kvm_enabled() && ! env->cpuid_vendor_override) {
1650 c6dc6f63 Andre Przywara
        host_cpuid(0, 0, NULL, ebx, ecx, edx);
1651 c6dc6f63 Andre Przywara
    }
1652 c6dc6f63 Andre Przywara
}
1653 c6dc6f63 Andre Przywara
1654 c6dc6f63 Andre Przywara
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1655 c6dc6f63 Andre Przywara
                   uint32_t *eax, uint32_t *ebx,
1656 c6dc6f63 Andre Przywara
                   uint32_t *ecx, uint32_t *edx)
1657 c6dc6f63 Andre Przywara
{
1658 a60f24b5 Andreas Färber
    X86CPU *cpu = x86_env_get_cpu(env);
1659 a60f24b5 Andreas Färber
    CPUState *cs = CPU(cpu);
1660 a60f24b5 Andreas Färber
1661 c6dc6f63 Andre Przywara
    /* test if maximum index reached */
1662 c6dc6f63 Andre Przywara
    if (index & 0x80000000) {
1663 b3baa152 brillywu@viatech.com.cn
        if (index > env->cpuid_xlevel) {
1664 b3baa152 brillywu@viatech.com.cn
            if (env->cpuid_xlevel2 > 0) {
1665 b3baa152 brillywu@viatech.com.cn
                /* Handle the Centaur's CPUID instruction. */
1666 b3baa152 brillywu@viatech.com.cn
                if (index > env->cpuid_xlevel2) {
1667 b3baa152 brillywu@viatech.com.cn
                    index = env->cpuid_xlevel2;
1668 b3baa152 brillywu@viatech.com.cn
                } else if (index < 0xC0000000) {
1669 b3baa152 brillywu@viatech.com.cn
                    index = env->cpuid_xlevel;
1670 b3baa152 brillywu@viatech.com.cn
                }
1671 b3baa152 brillywu@viatech.com.cn
            } else {
1672 57f26ae7 Eduardo Habkost
                /* Intel documentation states that invalid EAX input will
1673 57f26ae7 Eduardo Habkost
                 * return the same information as EAX=cpuid_level
1674 57f26ae7 Eduardo Habkost
                 * (Intel SDM Vol. 2A - Instruction Set Reference - CPUID)
1675 57f26ae7 Eduardo Habkost
                 */
1676 57f26ae7 Eduardo Habkost
                index =  env->cpuid_level;
1677 b3baa152 brillywu@viatech.com.cn
            }
1678 b3baa152 brillywu@viatech.com.cn
        }
1679 c6dc6f63 Andre Przywara
    } else {
1680 c6dc6f63 Andre Przywara
        if (index > env->cpuid_level)
1681 c6dc6f63 Andre Przywara
            index = env->cpuid_level;
1682 c6dc6f63 Andre Przywara
    }
1683 c6dc6f63 Andre Przywara
1684 c6dc6f63 Andre Przywara
    switch(index) {
1685 c6dc6f63 Andre Przywara
    case 0:
1686 c6dc6f63 Andre Przywara
        *eax = env->cpuid_level;
1687 c6dc6f63 Andre Przywara
        get_cpuid_vendor(env, ebx, ecx, edx);
1688 c6dc6f63 Andre Przywara
        break;
1689 c6dc6f63 Andre Przywara
    case 1:
1690 c6dc6f63 Andre Przywara
        *eax = env->cpuid_version;
1691 c6dc6f63 Andre Przywara
        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
1692 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_ext_features;
1693 c6dc6f63 Andre Przywara
        *edx = env->cpuid_features;
1694 c6dc6f63 Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
1695 c6dc6f63 Andre Przywara
            *ebx |= (env->nr_cores * env->nr_threads) << 16;
1696 c6dc6f63 Andre Przywara
            *edx |= 1 << 28;    /* HTT bit */
1697 c6dc6f63 Andre Przywara
        }
1698 c6dc6f63 Andre Przywara
        break;
1699 c6dc6f63 Andre Przywara
    case 2:
1700 c6dc6f63 Andre Przywara
        /* cache info: needed for Pentium Pro compatibility */
1701 c6dc6f63 Andre Przywara
        *eax = 1;
1702 c6dc6f63 Andre Przywara
        *ebx = 0;
1703 c6dc6f63 Andre Przywara
        *ecx = 0;
1704 c6dc6f63 Andre Przywara
        *edx = 0x2c307d;
1705 c6dc6f63 Andre Przywara
        break;
1706 c6dc6f63 Andre Przywara
    case 4:
1707 c6dc6f63 Andre Przywara
        /* cache info: needed for Core compatibility */
1708 c6dc6f63 Andre Przywara
        if (env->nr_cores > 1) {
1709 2f7a21c4 Aurelien Jarno
            *eax = (env->nr_cores - 1) << 26;
1710 c6dc6f63 Andre Przywara
        } else {
1711 2f7a21c4 Aurelien Jarno
            *eax = 0;
1712 c6dc6f63 Andre Przywara
        }
1713 c6dc6f63 Andre Przywara
        switch (count) {
1714 c6dc6f63 Andre Przywara
            case 0: /* L1 dcache info */
1715 c6dc6f63 Andre Przywara
                *eax |= 0x0000121;
1716 c6dc6f63 Andre Przywara
                *ebx = 0x1c0003f;
1717 c6dc6f63 Andre Przywara
                *ecx = 0x000003f;
1718 c6dc6f63 Andre Przywara
                *edx = 0x0000001;
1719 c6dc6f63 Andre Przywara
                break;
1720 c6dc6f63 Andre Przywara
            case 1: /* L1 icache info */
1721 c6dc6f63 Andre Przywara
                *eax |= 0x0000122;
1722 c6dc6f63 Andre Przywara
                *ebx = 0x1c0003f;
1723 c6dc6f63 Andre Przywara
                *ecx = 0x000003f;
1724 c6dc6f63 Andre Przywara
                *edx = 0x0000001;
1725 c6dc6f63 Andre Przywara
                break;
1726 c6dc6f63 Andre Przywara
            case 2: /* L2 cache info */
1727 c6dc6f63 Andre Przywara
                *eax |= 0x0000143;
1728 c6dc6f63 Andre Przywara
                if (env->nr_threads > 1) {
1729 c6dc6f63 Andre Przywara
                    *eax |= (env->nr_threads - 1) << 14;
1730 c6dc6f63 Andre Przywara
                }
1731 c6dc6f63 Andre Przywara
                *ebx = 0x3c0003f;
1732 c6dc6f63 Andre Przywara
                *ecx = 0x0000fff;
1733 c6dc6f63 Andre Przywara
                *edx = 0x0000001;
1734 c6dc6f63 Andre Przywara
                break;
1735 c6dc6f63 Andre Przywara
            default: /* end of info */
1736 c6dc6f63 Andre Przywara
                *eax = 0;
1737 c6dc6f63 Andre Przywara
                *ebx = 0;
1738 c6dc6f63 Andre Przywara
                *ecx = 0;
1739 c6dc6f63 Andre Przywara
                *edx = 0;
1740 c6dc6f63 Andre Przywara
                break;
1741 c6dc6f63 Andre Przywara
        }
1742 c6dc6f63 Andre Przywara
        break;
1743 c6dc6f63 Andre Przywara
    case 5:
1744 c6dc6f63 Andre Przywara
        /* mwait info: needed for Core compatibility */
1745 c6dc6f63 Andre Przywara
        *eax = 0; /* Smallest monitor-line size in bytes */
1746 c6dc6f63 Andre Przywara
        *ebx = 0; /* Largest monitor-line size in bytes */
1747 c6dc6f63 Andre Przywara
        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
1748 c6dc6f63 Andre Przywara
        *edx = 0;
1749 c6dc6f63 Andre Przywara
        break;
1750 c6dc6f63 Andre Przywara
    case 6:
1751 c6dc6f63 Andre Przywara
        /* Thermal and Power Leaf */
1752 c6dc6f63 Andre Przywara
        *eax = 0;
1753 c6dc6f63 Andre Przywara
        *ebx = 0;
1754 c6dc6f63 Andre Przywara
        *ecx = 0;
1755 c6dc6f63 Andre Przywara
        *edx = 0;
1756 c6dc6f63 Andre Przywara
        break;
1757 f7911686 Yang, Wei Y
    case 7:
1758 13526728 Eduardo Habkost
        /* Structured Extended Feature Flags Enumeration Leaf */
1759 13526728 Eduardo Habkost
        if (count == 0) {
1760 13526728 Eduardo Habkost
            *eax = 0; /* Maximum ECX value for sub-leaves */
1761 a9321a4d H. Peter Anvin
            *ebx = env->cpuid_7_0_ebx_features; /* Feature flags */
1762 13526728 Eduardo Habkost
            *ecx = 0; /* Reserved */
1763 13526728 Eduardo Habkost
            *edx = 0; /* Reserved */
1764 f7911686 Yang, Wei Y
        } else {
1765 f7911686 Yang, Wei Y
            *eax = 0;
1766 f7911686 Yang, Wei Y
            *ebx = 0;
1767 f7911686 Yang, Wei Y
            *ecx = 0;
1768 f7911686 Yang, Wei Y
            *edx = 0;
1769 f7911686 Yang, Wei Y
        }
1770 f7911686 Yang, Wei Y
        break;
1771 c6dc6f63 Andre Przywara
    case 9:
1772 c6dc6f63 Andre Przywara
        /* Direct Cache Access Information Leaf */
1773 c6dc6f63 Andre Przywara
        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
1774 c6dc6f63 Andre Przywara
        *ebx = 0;
1775 c6dc6f63 Andre Przywara
        *ecx = 0;
1776 c6dc6f63 Andre Przywara
        *edx = 0;
1777 c6dc6f63 Andre Przywara
        break;
1778 c6dc6f63 Andre Przywara
    case 0xA:
1779 c6dc6f63 Andre Przywara
        /* Architectural Performance Monitoring Leaf */
1780 a0fa8208 Gleb Natapov
        if (kvm_enabled()) {
1781 a60f24b5 Andreas Färber
            KVMState *s = cs->kvm_state;
1782 a0fa8208 Gleb Natapov
1783 a0fa8208 Gleb Natapov
            *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
1784 a0fa8208 Gleb Natapov
            *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
1785 a0fa8208 Gleb Natapov
            *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
1786 a0fa8208 Gleb Natapov
            *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
1787 a0fa8208 Gleb Natapov
        } else {
1788 a0fa8208 Gleb Natapov
            *eax = 0;
1789 a0fa8208 Gleb Natapov
            *ebx = 0;
1790 a0fa8208 Gleb Natapov
            *ecx = 0;
1791 a0fa8208 Gleb Natapov
            *edx = 0;
1792 a0fa8208 Gleb Natapov
        }
1793 c6dc6f63 Andre Przywara
        break;
1794 51e49430 Sheng Yang
    case 0xD:
1795 51e49430 Sheng Yang
        /* Processor Extended State */
1796 51e49430 Sheng Yang
        if (!(env->cpuid_ext_features & CPUID_EXT_XSAVE)) {
1797 51e49430 Sheng Yang
            *eax = 0;
1798 51e49430 Sheng Yang
            *ebx = 0;
1799 51e49430 Sheng Yang
            *ecx = 0;
1800 51e49430 Sheng Yang
            *edx = 0;
1801 51e49430 Sheng Yang
            break;
1802 51e49430 Sheng Yang
        }
1803 51e49430 Sheng Yang
        if (kvm_enabled()) {
1804 a60f24b5 Andreas Färber
            KVMState *s = cs->kvm_state;
1805 ba9bc59e Jan Kiszka
1806 ba9bc59e Jan Kiszka
            *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX);
1807 ba9bc59e Jan Kiszka
            *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX);
1808 ba9bc59e Jan Kiszka
            *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX);
1809 ba9bc59e Jan Kiszka
            *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX);
1810 51e49430 Sheng Yang
        } else {
1811 51e49430 Sheng Yang
            *eax = 0;
1812 51e49430 Sheng Yang
            *ebx = 0;
1813 51e49430 Sheng Yang
            *ecx = 0;
1814 51e49430 Sheng Yang
            *edx = 0;
1815 51e49430 Sheng Yang
        }
1816 51e49430 Sheng Yang
        break;
1817 c6dc6f63 Andre Przywara
    case 0x80000000:
1818 c6dc6f63 Andre Przywara
        *eax = env->cpuid_xlevel;
1819 c6dc6f63 Andre Przywara
        *ebx = env->cpuid_vendor1;
1820 c6dc6f63 Andre Przywara
        *edx = env->cpuid_vendor2;
1821 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_vendor3;
1822 c6dc6f63 Andre Przywara
        break;
1823 c6dc6f63 Andre Przywara
    case 0x80000001:
1824 c6dc6f63 Andre Przywara
        *eax = env->cpuid_version;
1825 c6dc6f63 Andre Przywara
        *ebx = 0;
1826 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_ext3_features;
1827 c6dc6f63 Andre Przywara
        *edx = env->cpuid_ext2_features;
1828 c6dc6f63 Andre Przywara
1829 c6dc6f63 Andre Przywara
        /* The Linux kernel checks for the CMPLegacy bit and
1830 c6dc6f63 Andre Przywara
         * discards multiple thread information if it is set.
1831 c6dc6f63 Andre Przywara
         * So dont set it here for Intel to make Linux guests happy.
1832 c6dc6f63 Andre Przywara
         */
1833 c6dc6f63 Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
1834 c6dc6f63 Andre Przywara
            uint32_t tebx, tecx, tedx;
1835 c6dc6f63 Andre Przywara
            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
1836 c6dc6f63 Andre Przywara
            if (tebx != CPUID_VENDOR_INTEL_1 ||
1837 c6dc6f63 Andre Przywara
                tedx != CPUID_VENDOR_INTEL_2 ||
1838 c6dc6f63 Andre Przywara
                tecx != CPUID_VENDOR_INTEL_3) {
1839 c6dc6f63 Andre Przywara
                *ecx |= 1 << 1;    /* CmpLegacy bit */
1840 c6dc6f63 Andre Przywara
            }
1841 c6dc6f63 Andre Przywara
        }
1842 c6dc6f63 Andre Przywara
        break;
1843 c6dc6f63 Andre Przywara
    case 0x80000002:
1844 c6dc6f63 Andre Przywara
    case 0x80000003:
1845 c6dc6f63 Andre Przywara
    case 0x80000004:
1846 c6dc6f63 Andre Przywara
        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
1847 c6dc6f63 Andre Przywara
        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
1848 c6dc6f63 Andre Przywara
        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
1849 c6dc6f63 Andre Przywara
        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
1850 c6dc6f63 Andre Przywara
        break;
1851 c6dc6f63 Andre Przywara
    case 0x80000005:
1852 c6dc6f63 Andre Przywara
        /* cache info (L1 cache) */
1853 c6dc6f63 Andre Przywara
        *eax = 0x01ff01ff;
1854 c6dc6f63 Andre Przywara
        *ebx = 0x01ff01ff;
1855 c6dc6f63 Andre Przywara
        *ecx = 0x40020140;
1856 c6dc6f63 Andre Przywara
        *edx = 0x40020140;
1857 c6dc6f63 Andre Przywara
        break;
1858 c6dc6f63 Andre Przywara
    case 0x80000006:
1859 c6dc6f63 Andre Przywara
        /* cache info (L2 cache) */
1860 c6dc6f63 Andre Przywara
        *eax = 0;
1861 c6dc6f63 Andre Przywara
        *ebx = 0x42004200;
1862 c6dc6f63 Andre Przywara
        *ecx = 0x02008140;
1863 c6dc6f63 Andre Przywara
        *edx = 0;
1864 c6dc6f63 Andre Przywara
        break;
1865 c6dc6f63 Andre Przywara
    case 0x80000008:
1866 c6dc6f63 Andre Przywara
        /* virtual & phys address size in low 2 bytes. */
1867 c6dc6f63 Andre Przywara
/* XXX: This value must match the one used in the MMU code. */
1868 c6dc6f63 Andre Przywara
        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
1869 c6dc6f63 Andre Przywara
            /* 64 bit processor */
1870 c6dc6f63 Andre Przywara
/* XXX: The physical address space is limited to 42 bits in exec.c. */
1871 c6dc6f63 Andre Przywara
            *eax = 0x00003028;        /* 48 bits virtual, 40 bits physical */
1872 c6dc6f63 Andre Przywara
        } else {
1873 c6dc6f63 Andre Przywara
            if (env->cpuid_features & CPUID_PSE36)
1874 c6dc6f63 Andre Przywara
                *eax = 0x00000024; /* 36 bits physical */
1875 c6dc6f63 Andre Przywara
            else
1876 c6dc6f63 Andre Przywara
                *eax = 0x00000020; /* 32 bits physical */
1877 c6dc6f63 Andre Przywara
        }
1878 c6dc6f63 Andre Przywara
        *ebx = 0;
1879 c6dc6f63 Andre Przywara
        *ecx = 0;
1880 c6dc6f63 Andre Przywara
        *edx = 0;
1881 c6dc6f63 Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
1882 c6dc6f63 Andre Przywara
            *ecx |= (env->nr_cores * env->nr_threads) - 1;
1883 c6dc6f63 Andre Przywara
        }
1884 c6dc6f63 Andre Przywara
        break;
1885 c6dc6f63 Andre Przywara
    case 0x8000000A:
1886 9f3fb565 Eduardo Habkost
        if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
1887 9f3fb565 Eduardo Habkost
            *eax = 0x00000001; /* SVM Revision */
1888 9f3fb565 Eduardo Habkost
            *ebx = 0x00000010; /* nr of ASIDs */
1889 9f3fb565 Eduardo Habkost
            *ecx = 0;
1890 9f3fb565 Eduardo Habkost
            *edx = env->cpuid_svm_features; /* optional features */
1891 9f3fb565 Eduardo Habkost
        } else {
1892 9f3fb565 Eduardo Habkost
            *eax = 0;
1893 9f3fb565 Eduardo Habkost
            *ebx = 0;
1894 9f3fb565 Eduardo Habkost
            *ecx = 0;
1895 9f3fb565 Eduardo Habkost
            *edx = 0;
1896 9f3fb565 Eduardo Habkost
        }
1897 c6dc6f63 Andre Przywara
        break;
1898 b3baa152 brillywu@viatech.com.cn
    case 0xC0000000:
1899 b3baa152 brillywu@viatech.com.cn
        *eax = env->cpuid_xlevel2;
1900 b3baa152 brillywu@viatech.com.cn
        *ebx = 0;
1901 b3baa152 brillywu@viatech.com.cn
        *ecx = 0;
1902 b3baa152 brillywu@viatech.com.cn
        *edx = 0;
1903 b3baa152 brillywu@viatech.com.cn
        break;
1904 b3baa152 brillywu@viatech.com.cn
    case 0xC0000001:
1905 b3baa152 brillywu@viatech.com.cn
        /* Support for VIA CPU's CPUID instruction */
1906 b3baa152 brillywu@viatech.com.cn
        *eax = env->cpuid_version;
1907 b3baa152 brillywu@viatech.com.cn
        *ebx = 0;
1908 b3baa152 brillywu@viatech.com.cn
        *ecx = 0;
1909 b3baa152 brillywu@viatech.com.cn
        *edx = env->cpuid_ext4_features;
1910 b3baa152 brillywu@viatech.com.cn
        break;
1911 b3baa152 brillywu@viatech.com.cn
    case 0xC0000002:
1912 b3baa152 brillywu@viatech.com.cn
    case 0xC0000003:
1913 b3baa152 brillywu@viatech.com.cn
    case 0xC0000004:
1914 b3baa152 brillywu@viatech.com.cn
        /* Reserved for the future, and now filled with zero */
1915 b3baa152 brillywu@viatech.com.cn
        *eax = 0;
1916 b3baa152 brillywu@viatech.com.cn
        *ebx = 0;
1917 b3baa152 brillywu@viatech.com.cn
        *ecx = 0;
1918 b3baa152 brillywu@viatech.com.cn
        *edx = 0;
1919 b3baa152 brillywu@viatech.com.cn
        break;
1920 c6dc6f63 Andre Przywara
    default:
1921 c6dc6f63 Andre Przywara
        /* reserved values: zero */
1922 c6dc6f63 Andre Przywara
        *eax = 0;
1923 c6dc6f63 Andre Przywara
        *ebx = 0;
1924 c6dc6f63 Andre Przywara
        *ecx = 0;
1925 c6dc6f63 Andre Przywara
        *edx = 0;
1926 c6dc6f63 Andre Przywara
        break;
1927 c6dc6f63 Andre Przywara
    }
1928 c6dc6f63 Andre Przywara
}
1929 5fd2087a Andreas Färber
1930 5fd2087a Andreas Färber
/* CPUClass::reset() */
1931 5fd2087a Andreas Färber
static void x86_cpu_reset(CPUState *s)
1932 5fd2087a Andreas Färber
{
1933 5fd2087a Andreas Färber
    X86CPU *cpu = X86_CPU(s);
1934 5fd2087a Andreas Färber
    X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
1935 5fd2087a Andreas Färber
    CPUX86State *env = &cpu->env;
1936 c1958aea Andreas Färber
    int i;
1937 c1958aea Andreas Färber
1938 c1958aea Andreas Färber
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
1939 c1958aea Andreas Färber
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
1940 6fd2a026 Peter Maydell
        log_cpu_state(env, CPU_DUMP_FPU | CPU_DUMP_CCOP);
1941 c1958aea Andreas Färber
    }
1942 5fd2087a Andreas Färber
1943 5fd2087a Andreas Färber
    xcc->parent_reset(s);
1944 5fd2087a Andreas Färber
1945 c1958aea Andreas Färber
1946 c1958aea Andreas Färber
    memset(env, 0, offsetof(CPUX86State, breakpoints));
1947 c1958aea Andreas Färber
1948 c1958aea Andreas Färber
    tlb_flush(env, 1);
1949 c1958aea Andreas Färber
1950 c1958aea Andreas Färber
    env->old_exception = -1;
1951 c1958aea Andreas Färber
1952 c1958aea Andreas Färber
    /* init to reset state */
1953 c1958aea Andreas Färber
1954 c1958aea Andreas Färber
#ifdef CONFIG_SOFTMMU
1955 c1958aea Andreas Färber
    env->hflags |= HF_SOFTMMU_MASK;
1956 c1958aea Andreas Färber
#endif
1957 c1958aea Andreas Färber
    env->hflags2 |= HF2_GIF_MASK;
1958 c1958aea Andreas Färber
1959 c1958aea Andreas Färber
    cpu_x86_update_cr0(env, 0x60000010);
1960 c1958aea Andreas Färber
    env->a20_mask = ~0x0;
1961 c1958aea Andreas Färber
    env->smbase = 0x30000;
1962 c1958aea Andreas Färber
1963 c1958aea Andreas Färber
    env->idt.limit = 0xffff;
1964 c1958aea Andreas Färber
    env->gdt.limit = 0xffff;
1965 c1958aea Andreas Färber
    env->ldt.limit = 0xffff;
1966 c1958aea Andreas Färber
    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
1967 c1958aea Andreas Färber
    env->tr.limit = 0xffff;
1968 c1958aea Andreas Färber
    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
1969 c1958aea Andreas Färber
1970 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
1971 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
1972 c1958aea Andreas Färber
                           DESC_R_MASK | DESC_A_MASK);
1973 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
1974 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1975 c1958aea Andreas Färber
                           DESC_A_MASK);
1976 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
1977 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1978 c1958aea Andreas Färber
                           DESC_A_MASK);
1979 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
1980 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1981 c1958aea Andreas Färber
                           DESC_A_MASK);
1982 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
1983 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1984 c1958aea Andreas Färber
                           DESC_A_MASK);
1985 c1958aea Andreas Färber
    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
1986 c1958aea Andreas Färber
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
1987 c1958aea Andreas Färber
                           DESC_A_MASK);
1988 c1958aea Andreas Färber
1989 c1958aea Andreas Färber
    env->eip = 0xfff0;
1990 c1958aea Andreas Färber
    env->regs[R_EDX] = env->cpuid_version;
1991 c1958aea Andreas Färber
1992 c1958aea Andreas Färber
    env->eflags = 0x2;
1993 c1958aea Andreas Färber
1994 c1958aea Andreas Färber
    /* FPU init */
1995 c1958aea Andreas Färber
    for (i = 0; i < 8; i++) {
1996 c1958aea Andreas Färber
        env->fptags[i] = 1;
1997 c1958aea Andreas Färber
    }
1998 c1958aea Andreas Färber
    env->fpuc = 0x37f;
1999 c1958aea Andreas Färber
2000 c1958aea Andreas Färber
    env->mxcsr = 0x1f80;
2001 c1958aea Andreas Färber
2002 c1958aea Andreas Färber
    env->pat = 0x0007040600070406ULL;
2003 c1958aea Andreas Färber
    env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
2004 c1958aea Andreas Färber
2005 c1958aea Andreas Färber
    memset(env->dr, 0, sizeof(env->dr));
2006 c1958aea Andreas Färber
    env->dr[6] = DR6_FIXED_1;
2007 c1958aea Andreas Färber
    env->dr[7] = DR7_FIXED_1;
2008 c1958aea Andreas Färber
    cpu_breakpoint_remove_all(env, BP_CPU);
2009 c1958aea Andreas Färber
    cpu_watchpoint_remove_all(env, BP_CPU);
2010 dd673288 Igor Mammedov
2011 dd673288 Igor Mammedov
#if !defined(CONFIG_USER_ONLY)
2012 dd673288 Igor Mammedov
    /* We hard-wire the BSP to the first CPU. */
2013 dd673288 Igor Mammedov
    if (env->cpu_index == 0) {
2014 dd673288 Igor Mammedov
        apic_designate_bsp(env->apic_state);
2015 dd673288 Igor Mammedov
    }
2016 dd673288 Igor Mammedov
2017 dd673288 Igor Mammedov
    env->halted = !cpu_is_bsp(cpu);
2018 dd673288 Igor Mammedov
#endif
2019 5fd2087a Andreas Färber
}
2020 5fd2087a Andreas Färber
2021 dd673288 Igor Mammedov
#ifndef CONFIG_USER_ONLY
2022 dd673288 Igor Mammedov
bool cpu_is_bsp(X86CPU *cpu)
2023 dd673288 Igor Mammedov
{
2024 dd673288 Igor Mammedov
    return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP;
2025 dd673288 Igor Mammedov
}
2026 65dee380 Igor Mammedov
2027 65dee380 Igor Mammedov
/* TODO: remove me, when reset over QOM tree is implemented */
2028 65dee380 Igor Mammedov
static void x86_cpu_machine_reset_cb(void *opaque)
2029 65dee380 Igor Mammedov
{
2030 65dee380 Igor Mammedov
    X86CPU *cpu = opaque;
2031 65dee380 Igor Mammedov
    cpu_reset(CPU(cpu));
2032 65dee380 Igor Mammedov
}
2033 dd673288 Igor Mammedov
#endif
2034 dd673288 Igor Mammedov
2035 de024815 Andreas Färber
static void mce_init(X86CPU *cpu)
2036 de024815 Andreas Färber
{
2037 de024815 Andreas Färber
    CPUX86State *cenv = &cpu->env;
2038 de024815 Andreas Färber
    unsigned int bank;
2039 de024815 Andreas Färber
2040 de024815 Andreas Färber
    if (((cenv->cpuid_version >> 8) & 0xf) >= 6
2041 de024815 Andreas Färber
        && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
2042 de024815 Andreas Färber
            (CPUID_MCE | CPUID_MCA)) {
2043 de024815 Andreas Färber
        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
2044 de024815 Andreas Färber
        cenv->mcg_ctl = ~(uint64_t)0;
2045 de024815 Andreas Färber
        for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
2046 de024815 Andreas Färber
            cenv->mce_banks[bank * 4] = ~(uint64_t)0;
2047 de024815 Andreas Färber
        }
2048 de024815 Andreas Färber
    }
2049 de024815 Andreas Färber
}
2050 de024815 Andreas Färber
2051 bdeec802 Igor Mammedov
#define MSI_ADDR_BASE 0xfee00000
2052 bdeec802 Igor Mammedov
2053 bdeec802 Igor Mammedov
#ifndef CONFIG_USER_ONLY
2054 bdeec802 Igor Mammedov
static void x86_cpu_apic_init(X86CPU *cpu, Error **errp)
2055 bdeec802 Igor Mammedov
{
2056 bdeec802 Igor Mammedov
    static int apic_mapped;
2057 bdeec802 Igor Mammedov
    CPUX86State *env = &cpu->env;
2058 449994eb Andreas Färber
    APICCommonState *apic;
2059 bdeec802 Igor Mammedov
    const char *apic_type = "apic";
2060 bdeec802 Igor Mammedov
2061 bdeec802 Igor Mammedov
    if (kvm_irqchip_in_kernel()) {
2062 bdeec802 Igor Mammedov
        apic_type = "kvm-apic";
2063 bdeec802 Igor Mammedov
    } else if (xen_enabled()) {
2064 bdeec802 Igor Mammedov
        apic_type = "xen-apic";
2065 bdeec802 Igor Mammedov
    }
2066 bdeec802 Igor Mammedov
2067 bdeec802 Igor Mammedov
    env->apic_state = qdev_try_create(NULL, apic_type);
2068 bdeec802 Igor Mammedov
    if (env->apic_state == NULL) {
2069 bdeec802 Igor Mammedov
        error_setg(errp, "APIC device '%s' could not be created", apic_type);
2070 bdeec802 Igor Mammedov
        return;
2071 bdeec802 Igor Mammedov
    }
2072 bdeec802 Igor Mammedov
2073 bdeec802 Igor Mammedov
    object_property_add_child(OBJECT(cpu), "apic",
2074 bdeec802 Igor Mammedov
                              OBJECT(env->apic_state), NULL);
2075 bdeec802 Igor Mammedov
    qdev_prop_set_uint8(env->apic_state, "id", env->cpuid_apic_id);
2076 bdeec802 Igor Mammedov
    /* TODO: convert to link<> */
2077 449994eb Andreas Färber
    apic = APIC_COMMON(env->apic_state);
2078 60671e58 Andreas Färber
    apic->cpu = cpu;
2079 bdeec802 Igor Mammedov
2080 bdeec802 Igor Mammedov
    if (qdev_init(env->apic_state)) {
2081 bdeec802 Igor Mammedov
        error_setg(errp, "APIC device '%s' could not be initialized",
2082 bdeec802 Igor Mammedov
                   object_get_typename(OBJECT(env->apic_state)));
2083 bdeec802 Igor Mammedov
        return;
2084 bdeec802 Igor Mammedov
    }
2085 bdeec802 Igor Mammedov
2086 bdeec802 Igor Mammedov
    /* XXX: mapping more APICs at the same memory location */
2087 bdeec802 Igor Mammedov
    if (apic_mapped == 0) {
2088 bdeec802 Igor Mammedov
        /* NOTE: the APIC is directly connected to the CPU - it is not
2089 bdeec802 Igor Mammedov
           on the global memory bus. */
2090 bdeec802 Igor Mammedov
        /* XXX: what if the base changes? */
2091 bdeec802 Igor Mammedov
        sysbus_mmio_map(sysbus_from_qdev(env->apic_state), 0, MSI_ADDR_BASE);
2092 bdeec802 Igor Mammedov
        apic_mapped = 1;
2093 bdeec802 Igor Mammedov
    }
2094 bdeec802 Igor Mammedov
}
2095 bdeec802 Igor Mammedov
#endif
2096 bdeec802 Igor Mammedov
2097 7a059953 Andreas Färber
void x86_cpu_realize(Object *obj, Error **errp)
2098 7a059953 Andreas Färber
{
2099 7a059953 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
2100 b34d12d1 Igor Mammedov
    CPUX86State *env = &cpu->env;
2101 b34d12d1 Igor Mammedov
2102 b34d12d1 Igor Mammedov
    if (env->cpuid_7_0_ebx_features && env->cpuid_level < 7) {
2103 b34d12d1 Igor Mammedov
        env->cpuid_level = 7;
2104 b34d12d1 Igor Mammedov
    }
2105 7a059953 Andreas Färber
2106 9b15cd9e Igor Mammedov
    /* On AMD CPUs, some CPUID[8000_0001].EDX bits must match the bits on
2107 9b15cd9e Igor Mammedov
     * CPUID[1].EDX.
2108 9b15cd9e Igor Mammedov
     */
2109 9b15cd9e Igor Mammedov
    if (env->cpuid_vendor1 == CPUID_VENDOR_AMD_1 &&
2110 9b15cd9e Igor Mammedov
        env->cpuid_vendor2 == CPUID_VENDOR_AMD_2 &&
2111 9b15cd9e Igor Mammedov
        env->cpuid_vendor3 == CPUID_VENDOR_AMD_3) {
2112 9b15cd9e Igor Mammedov
        env->cpuid_ext2_features &= ~CPUID_EXT2_AMD_ALIASES;
2113 9b15cd9e Igor Mammedov
        env->cpuid_ext2_features |= (env->cpuid_features
2114 9b15cd9e Igor Mammedov
           & CPUID_EXT2_AMD_ALIASES);
2115 9b15cd9e Igor Mammedov
    }
2116 9b15cd9e Igor Mammedov
2117 4586f157 Igor Mammedov
    if (!kvm_enabled()) {
2118 4586f157 Igor Mammedov
        env->cpuid_features &= TCG_FEATURES;
2119 4586f157 Igor Mammedov
        env->cpuid_ext_features &= TCG_EXT_FEATURES;
2120 4586f157 Igor Mammedov
        env->cpuid_ext2_features &= (TCG_EXT2_FEATURES
2121 4586f157 Igor Mammedov
#ifdef TARGET_X86_64
2122 4586f157 Igor Mammedov
            | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
2123 4586f157 Igor Mammedov
#endif
2124 4586f157 Igor Mammedov
            );
2125 4586f157 Igor Mammedov
        env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
2126 4586f157 Igor Mammedov
        env->cpuid_svm_features &= TCG_SVM_FEATURES;
2127 4586f157 Igor Mammedov
    } else {
2128 4586f157 Igor Mammedov
#ifdef CONFIG_KVM
2129 4586f157 Igor Mammedov
        filter_features_for_kvm(cpu);
2130 4586f157 Igor Mammedov
#endif
2131 4586f157 Igor Mammedov
    }
2132 4586f157 Igor Mammedov
2133 65dee380 Igor Mammedov
#ifndef CONFIG_USER_ONLY
2134 65dee380 Igor Mammedov
    qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
2135 bdeec802 Igor Mammedov
2136 bdeec802 Igor Mammedov
    if (cpu->env.cpuid_features & CPUID_APIC || smp_cpus > 1) {
2137 bdeec802 Igor Mammedov
        x86_cpu_apic_init(cpu, errp);
2138 bdeec802 Igor Mammedov
        if (error_is_set(errp)) {
2139 bdeec802 Igor Mammedov
            return;
2140 bdeec802 Igor Mammedov
        }
2141 bdeec802 Igor Mammedov
    }
2142 65dee380 Igor Mammedov
#endif
2143 65dee380 Igor Mammedov
2144 7a059953 Andreas Färber
    mce_init(cpu);
2145 7a059953 Andreas Färber
    qemu_init_vcpu(&cpu->env);
2146 65dee380 Igor Mammedov
    cpu_reset(CPU(cpu));
2147 7a059953 Andreas Färber
}
2148 7a059953 Andreas Färber
2149 de024815 Andreas Färber
static void x86_cpu_initfn(Object *obj)
2150 de024815 Andreas Färber
{
2151 de024815 Andreas Färber
    X86CPU *cpu = X86_CPU(obj);
2152 de024815 Andreas Färber
    CPUX86State *env = &cpu->env;
2153 d65e9815 Igor Mammedov
    static int inited;
2154 de024815 Andreas Färber
2155 de024815 Andreas Färber
    cpu_exec_init(env);
2156 71ad61d3 Andreas Färber
2157 71ad61d3 Andreas Färber
    object_property_add(obj, "family", "int",
2158 95b8519d Andreas Färber
                        x86_cpuid_version_get_family,
2159 71ad61d3 Andreas Färber
                        x86_cpuid_version_set_family, NULL, NULL, NULL);
2160 c5291a4f Andreas Färber
    object_property_add(obj, "model", "int",
2161 67e30c83 Andreas Färber
                        x86_cpuid_version_get_model,
2162 c5291a4f Andreas Färber
                        x86_cpuid_version_set_model, NULL, NULL, NULL);
2163 036e2222 Andreas Färber
    object_property_add(obj, "stepping", "int",
2164 35112e41 Andreas Färber
                        x86_cpuid_version_get_stepping,
2165 036e2222 Andreas Färber
                        x86_cpuid_version_set_stepping, NULL, NULL, NULL);
2166 8e1898bf Andreas Färber
    object_property_add(obj, "level", "int",
2167 8e1898bf Andreas Färber
                        x86_cpuid_get_level,
2168 8e1898bf Andreas Färber
                        x86_cpuid_set_level, NULL, NULL, NULL);
2169 16b93aa8 Andreas Färber
    object_property_add(obj, "xlevel", "int",
2170 16b93aa8 Andreas Färber
                        x86_cpuid_get_xlevel,
2171 16b93aa8 Andreas Färber
                        x86_cpuid_set_xlevel, NULL, NULL, NULL);
2172 d480e1af Andreas Färber
    object_property_add_str(obj, "vendor",
2173 d480e1af Andreas Färber
                            x86_cpuid_get_vendor,
2174 d480e1af Andreas Färber
                            x86_cpuid_set_vendor, NULL);
2175 938d4c25 Andreas Färber
    object_property_add_str(obj, "model-id",
2176 63e886eb Andreas Färber
                            x86_cpuid_get_model_id,
2177 938d4c25 Andreas Färber
                            x86_cpuid_set_model_id, NULL);
2178 89e48965 Andreas Färber
    object_property_add(obj, "tsc-frequency", "int",
2179 89e48965 Andreas Färber
                        x86_cpuid_get_tsc_freq,
2180 89e48965 Andreas Färber
                        x86_cpuid_set_tsc_freq, NULL, NULL, NULL);
2181 71ad61d3 Andreas Färber
2182 de024815 Andreas Färber
    env->cpuid_apic_id = env->cpu_index;
2183 d65e9815 Igor Mammedov
2184 d65e9815 Igor Mammedov
    /* init various static tables used in TCG mode */
2185 d65e9815 Igor Mammedov
    if (tcg_enabled() && !inited) {
2186 d65e9815 Igor Mammedov
        inited = 1;
2187 d65e9815 Igor Mammedov
        optimize_flags_init();
2188 d65e9815 Igor Mammedov
#ifndef CONFIG_USER_ONLY
2189 d65e9815 Igor Mammedov
        cpu_set_debug_excp_handler(breakpoint_handler);
2190 d65e9815 Igor Mammedov
#endif
2191 d65e9815 Igor Mammedov
    }
2192 de024815 Andreas Färber
}
2193 de024815 Andreas Färber
2194 5fd2087a Andreas Färber
static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
2195 5fd2087a Andreas Färber
{
2196 5fd2087a Andreas Färber
    X86CPUClass *xcc = X86_CPU_CLASS(oc);
2197 5fd2087a Andreas Färber
    CPUClass *cc = CPU_CLASS(oc);
2198 5fd2087a Andreas Färber
2199 5fd2087a Andreas Färber
    xcc->parent_reset = cc->reset;
2200 5fd2087a Andreas Färber
    cc->reset = x86_cpu_reset;
2201 5fd2087a Andreas Färber
}
2202 5fd2087a Andreas Färber
2203 5fd2087a Andreas Färber
static const TypeInfo x86_cpu_type_info = {
2204 5fd2087a Andreas Färber
    .name = TYPE_X86_CPU,
2205 5fd2087a Andreas Färber
    .parent = TYPE_CPU,
2206 5fd2087a Andreas Färber
    .instance_size = sizeof(X86CPU),
2207 de024815 Andreas Färber
    .instance_init = x86_cpu_initfn,
2208 5fd2087a Andreas Färber
    .abstract = false,
2209 5fd2087a Andreas Färber
    .class_size = sizeof(X86CPUClass),
2210 5fd2087a Andreas Färber
    .class_init = x86_cpu_common_class_init,
2211 5fd2087a Andreas Färber
};
2212 5fd2087a Andreas Färber
2213 5fd2087a Andreas Färber
static void x86_cpu_register_types(void)
2214 5fd2087a Andreas Färber
{
2215 5fd2087a Andreas Färber
    type_register_static(&x86_cpu_type_info);
2216 5fd2087a Andreas Färber
}
2217 5fd2087a Andreas Färber
2218 5fd2087a Andreas Färber
type_init(x86_cpu_register_types)