Statistics
| Branch: | Revision:

root / target-i386 / cpu.c @ 09faecf2

History | View | Annotate | Download (58.5 kB)

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