Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ b5ec5ce0

History | View | Annotate | Download (74.6 kB)

1 2c0262af bellard
/*
2 eaa728ee bellard
 *  i386 helpers (without register variable usage)
3 5fafdf24 ths
 *
4 2c0262af bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 2c0262af bellard
 *
6 2c0262af bellard
 * This library is free software; you can redistribute it and/or
7 2c0262af bellard
 * modify it under the terms of the GNU Lesser General Public
8 2c0262af bellard
 * License as published by the Free Software Foundation; either
9 2c0262af bellard
 * version 2 of the License, or (at your option) any later version.
10 2c0262af bellard
 *
11 2c0262af bellard
 * This library is distributed in the hope that it will be useful,
12 2c0262af bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 2c0262af bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 2c0262af bellard
 * Lesser General Public License for more details.
15 2c0262af bellard
 *
16 2c0262af bellard
 * You should have received a copy of the GNU Lesser General Public
17 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 2c0262af bellard
 */
19 eaa728ee bellard
#include <stdarg.h>
20 eaa728ee bellard
#include <stdlib.h>
21 eaa728ee bellard
#include <stdio.h>
22 eaa728ee bellard
#include <string.h>
23 eaa728ee bellard
#include <inttypes.h>
24 eaa728ee bellard
#include <signal.h>
25 2c0262af bellard
26 eaa728ee bellard
#include "cpu.h"
27 eaa728ee bellard
#include "exec-all.h"
28 eaa728ee bellard
#include "qemu-common.h"
29 7ba1e619 aliguori
#include "kvm.h"
30 f3f2d9be bellard
31 eaa728ee bellard
//#define DEBUG_MMU
32 b5ec5ce0 john cooper
#include "qemu-option.h"
33 b5ec5ce0 john cooper
#include "qemu-config.h"
34 2c0262af bellard
35 c6fa82c4 Avi Kivity
/* feature flags taken from "Intel Processor Identification and the CPUID
36 b5ec5ce0 john cooper
 * Instruction" and AMD's "CPUID Specification".  In cases of disagreement
37 b5ec5ce0 john cooper
 * between feature naming conventions, aliases may be added.
38 b5ec5ce0 john cooper
 */
39 c6fa82c4 Avi Kivity
static const char *feature_name[] = {
40 b5ec5ce0 john cooper
    "fpu", "vme", "de", "pse",
41 b5ec5ce0 john cooper
    "tsc", "msr", "pae", "mce",
42 b5ec5ce0 john cooper
    "cx8", "apic", NULL, "sep",
43 b5ec5ce0 john cooper
    "mtrr", "pge", "mca", "cmov",
44 b5ec5ce0 john cooper
    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
45 b5ec5ce0 john cooper
    NULL, "ds" /* Intel dts */, "acpi", "mmx",
46 b5ec5ce0 john cooper
    "fxsr", "sse", "sse2", "ss",
47 b5ec5ce0 john cooper
    "ht" /* Intel htt */, "tm", "ia64", "pbe",
48 c6fa82c4 Avi Kivity
};
49 c6fa82c4 Avi Kivity
static const char *ext_feature_name[] = {
50 b5ec5ce0 john cooper
    "pni|sse3" /* Intel,AMD sse3 */, NULL, NULL, "monitor",
51 b5ec5ce0 john cooper
    "ds_cpl", "vmx", NULL /* Linux smx */, "est",
52 b5ec5ce0 john cooper
    "tm2", "ssse3", "cid", NULL,
53 b5ec5ce0 john cooper
    NULL, "cx16", "xtpr", NULL,
54 b5ec5ce0 john cooper
    NULL, NULL, "dca", "sse4.1|sse4_1",
55 b5ec5ce0 john cooper
    "sse4.2|sse4_2", "x2apic", NULL, "popcnt",
56 b5ec5ce0 john cooper
    NULL, NULL, NULL, NULL,
57 b5ec5ce0 john cooper
    NULL, NULL, NULL, "hypervisor",
58 c6fa82c4 Avi Kivity
};
59 c6fa82c4 Avi Kivity
static const char *ext2_feature_name[] = {
60 b5ec5ce0 john cooper
    "fpu", "vme", "de", "pse",
61 b5ec5ce0 john cooper
    "tsc", "msr", "pae", "mce",
62 b5ec5ce0 john cooper
    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall",
63 b5ec5ce0 john cooper
    "mtrr", "pge", "mca", "cmov",
64 b5ec5ce0 john cooper
    "pat", "pse36", NULL, NULL /* Linux mp */,
65 b5ec5ce0 john cooper
    "nx" /* Intel xd */, NULL, "mmxext", "mmx",
66 b5ec5ce0 john cooper
    "fxsr", "fxsr_opt" /* AMD ffxsr */, "pdpe1gb" /* AMD Page1GB */, "rdtscp",
67 b5ec5ce0 john cooper
    NULL, "lm" /* Intel 64 */, "3dnowext", "3dnow",
68 c6fa82c4 Avi Kivity
};
69 c6fa82c4 Avi Kivity
static const char *ext3_feature_name[] = {
70 b5ec5ce0 john cooper
    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
71 b5ec5ce0 john cooper
    "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
72 b5ec5ce0 john cooper
    "3dnowprefetch", "osvw", NULL /* Linux ibs */, NULL,
73 b5ec5ce0 john cooper
    "skinit", "wdt", NULL, NULL,
74 b5ec5ce0 john cooper
    NULL, NULL, NULL, NULL,
75 b5ec5ce0 john cooper
    NULL, NULL, NULL, NULL,
76 b5ec5ce0 john cooper
    NULL, NULL, NULL, NULL,
77 b5ec5ce0 john cooper
    NULL, NULL, NULL, NULL,
78 c6fa82c4 Avi Kivity
};
79 c6fa82c4 Avi Kivity
80 bb0300dc Gleb Natapov
static const char *kvm_feature_name[] = {
81 bb0300dc Gleb Natapov
    "kvmclock", "kvm_nopiodelay", "kvm_mmu", NULL, NULL, NULL, NULL, NULL,
82 bb0300dc Gleb Natapov
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
83 bb0300dc Gleb Natapov
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
84 bb0300dc Gleb Natapov
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
85 bb0300dc Gleb Natapov
};
86 bb0300dc Gleb Natapov
87 b5ec5ce0 john cooper
/* collects per-function cpuid data
88 b5ec5ce0 john cooper
 */
89 b5ec5ce0 john cooper
typedef struct model_features_t {
90 b5ec5ce0 john cooper
    uint32_t *guest_feat;
91 b5ec5ce0 john cooper
    uint32_t *host_feat;
92 b5ec5ce0 john cooper
    uint32_t check_feat;
93 b5ec5ce0 john cooper
    const char **flag_names;
94 b5ec5ce0 john cooper
    uint32_t cpuid;
95 b5ec5ce0 john cooper
    } model_features_t;
96 b5ec5ce0 john cooper
97 b5ec5ce0 john cooper
int check_cpuid = 0;
98 b5ec5ce0 john cooper
int enforce_cpuid = 0;
99 b5ec5ce0 john cooper
100 b5ec5ce0 john cooper
static void host_cpuid(uint32_t function, uint32_t count, uint32_t *eax,
101 b5ec5ce0 john cooper
                       uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
102 b5ec5ce0 john cooper
103 b5ec5ce0 john cooper
#define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
104 b5ec5ce0 john cooper
105 b5ec5ce0 john cooper
/* general substring compare of *[s1..e1) and *[s2..e2).  sx is start of
106 b5ec5ce0 john cooper
 * a substring.  ex if !NULL points to the first char after a substring,
107 b5ec5ce0 john cooper
 * otherwise the string is assumed to sized by a terminating nul.
108 b5ec5ce0 john cooper
 * Return lexical ordering of *s1:*s2.
109 b5ec5ce0 john cooper
 */
110 b5ec5ce0 john cooper
static int sstrcmp(const char *s1, const char *e1, const char *s2,
111 b5ec5ce0 john cooper
    const char *e2)
112 b5ec5ce0 john cooper
{
113 b5ec5ce0 john cooper
    for (;;) {
114 b5ec5ce0 john cooper
        if (!*s1 || !*s2 || *s1 != *s2)
115 b5ec5ce0 john cooper
            return (*s1 - *s2);
116 b5ec5ce0 john cooper
        ++s1, ++s2;
117 b5ec5ce0 john cooper
        if (s1 == e1 && s2 == e2)
118 b5ec5ce0 john cooper
            return (0);
119 b5ec5ce0 john cooper
        else if (s1 == e1)
120 b5ec5ce0 john cooper
            return (*s2);
121 b5ec5ce0 john cooper
        else if (s2 == e2)
122 b5ec5ce0 john cooper
            return (*s1);
123 b5ec5ce0 john cooper
    }
124 b5ec5ce0 john cooper
}
125 b5ec5ce0 john cooper
126 b5ec5ce0 john cooper
/* compare *[s..e) to *altstr.  *altstr may be a simple string or multiple
127 b5ec5ce0 john cooper
 * '|' delimited (possibly empty) strings in which case search for a match
128 b5ec5ce0 john cooper
 * within the alternatives proceeds left to right.  Return 0 for success,
129 b5ec5ce0 john cooper
 * non-zero otherwise.
130 b5ec5ce0 john cooper
 */
131 b5ec5ce0 john cooper
static int altcmp(const char *s, const char *e, const char *altstr)
132 b5ec5ce0 john cooper
{
133 b5ec5ce0 john cooper
    const char *p, *q;
134 b5ec5ce0 john cooper
135 b5ec5ce0 john cooper
    for (q = p = altstr; ; ) {
136 b5ec5ce0 john cooper
        while (*p && *p != '|')
137 b5ec5ce0 john cooper
            ++p;
138 b5ec5ce0 john cooper
        if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
139 b5ec5ce0 john cooper
            return (0);
140 b5ec5ce0 john cooper
        if (!*p)
141 b5ec5ce0 john cooper
            return (1);
142 b5ec5ce0 john cooper
        else
143 b5ec5ce0 john cooper
            q = ++p;
144 b5ec5ce0 john cooper
    }
145 b5ec5ce0 john cooper
}
146 b5ec5ce0 john cooper
147 b5ec5ce0 john cooper
/* search featureset for flag *[s..e), if found set corresponding bit in
148 b5ec5ce0 john cooper
 * *pval and return success, otherwise return zero
149 b5ec5ce0 john cooper
 */
150 b5ec5ce0 john cooper
static int lookup_feature(uint32_t *pval, const char *s, const char *e,
151 b5ec5ce0 john cooper
    const char **featureset)
152 b5ec5ce0 john cooper
{
153 b5ec5ce0 john cooper
    uint32_t mask;
154 b5ec5ce0 john cooper
    const char **ppc;
155 b5ec5ce0 john cooper
156 b5ec5ce0 john cooper
    for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc)
157 b5ec5ce0 john cooper
        if (*ppc && !altcmp(s, e, *ppc)) {
158 b5ec5ce0 john cooper
            *pval |= mask;
159 b5ec5ce0 john cooper
            break;
160 b5ec5ce0 john cooper
        }
161 b5ec5ce0 john cooper
    return (mask ? 1 : 0);
162 b5ec5ce0 john cooper
}
163 b5ec5ce0 john cooper
164 6d2edc43 Andre Przywara
static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
165 6d2edc43 Andre Przywara
                                    uint32_t *ext_features,
166 6d2edc43 Andre Przywara
                                    uint32_t *ext2_features,
167 bb0300dc Gleb Natapov
                                    uint32_t *ext3_features,
168 bb0300dc Gleb Natapov
                                    uint32_t *kvm_features)
169 eaa728ee bellard
{
170 b5ec5ce0 john cooper
    if (!lookup_feature(features, flagname, NULL, feature_name) &&
171 b5ec5ce0 john cooper
        !lookup_feature(ext_features, flagname, NULL, ext_feature_name) &&
172 b5ec5ce0 john cooper
        !lookup_feature(ext2_features, flagname, NULL, ext2_feature_name) &&
173 b5ec5ce0 john cooper
        !lookup_feature(ext3_features, flagname, NULL, ext3_feature_name) &&
174 b5ec5ce0 john cooper
        !lookup_feature(kvm_features, flagname, NULL, kvm_feature_name))
175 b5ec5ce0 john cooper
            fprintf(stderr, "CPU feature %s not found\n", flagname);
176 eaa728ee bellard
}
177 2c0262af bellard
178 c227f099 Anthony Liguori
typedef struct x86_def_t {
179 b5ec5ce0 john cooper
    struct x86_def_t *next;
180 eaa728ee bellard
    const char *name;
181 eaa728ee bellard
    uint32_t level;
182 eaa728ee bellard
    uint32_t vendor1, vendor2, vendor3;
183 eaa728ee bellard
    int family;
184 eaa728ee bellard
    int model;
185 eaa728ee bellard
    int stepping;
186 bb0300dc Gleb Natapov
    uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
187 eaa728ee bellard
    uint32_t xlevel;
188 40f8e2fa bellard
    char model_id[48];
189 ef768138 Andre Przywara
    int vendor_override;
190 b5ec5ce0 john cooper
    uint32_t flags;
191 c227f099 Anthony Liguori
} x86_def_t;
192 eaa728ee bellard
193 eaa728ee bellard
#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
194 eaa728ee bellard
#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
195 c84bd4f1 Gleb Natapov
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
196 eaa728ee bellard
#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
197 eaa728ee bellard
          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
198 eaa728ee bellard
          CPUID_PSE36 | CPUID_FXSR)
199 eaa728ee bellard
#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
200 eaa728ee bellard
#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
201 eaa728ee bellard
          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
202 eaa728ee bellard
          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
203 eaa728ee bellard
          CPUID_PAE | CPUID_SEP | CPUID_APIC)
204 b5ec5ce0 john cooper
205 b5ec5ce0 john cooper
/* maintains list of cpu model definitions
206 b5ec5ce0 john cooper
 */
207 b5ec5ce0 john cooper
static x86_def_t *x86_defs = {NULL};
208 b5ec5ce0 john cooper
209 b5ec5ce0 john cooper
/* built-in cpu model definitions (deprecated)
210 b5ec5ce0 john cooper
 */
211 b5ec5ce0 john cooper
static x86_def_t builtin_x86_defs[] = {
212 eaa728ee bellard
#ifdef TARGET_X86_64
213 eaa728ee bellard
    {
214 eaa728ee bellard
        .name = "qemu64",
215 ac72472b Andre Przywara
        .level = 4,
216 c5096daf balrog
        .vendor1 = CPUID_VENDOR_AMD_1,
217 c5096daf balrog
        .vendor2 = CPUID_VENDOR_AMD_2,
218 c5096daf balrog
        .vendor3 = CPUID_VENDOR_AMD_3,
219 eaa728ee bellard
        .family = 6,
220 eaa728ee bellard
        .model = 2,
221 eaa728ee bellard
        .stepping = 3,
222 eaa728ee bellard
        .features = PPRO_FEATURES | 
223 eaa728ee bellard
        /* these features are needed for Win64 and aren't fully implemented */
224 eaa728ee bellard
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
225 eaa728ee bellard
        /* this feature is needed for Solaris and isn't fully implemented */
226 eaa728ee bellard
            CPUID_PSE36,
227 f1e00a9c Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
228 eaa728ee bellard
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
229 09ac35ac Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
230 f1e00a9c Andre Przywara
        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
231 f1e00a9c Andre Przywara
            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
232 eaa728ee bellard
        .xlevel = 0x8000000A,
233 40f8e2fa bellard
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
234 eaa728ee bellard
    },
235 e737b32a balrog
    {
236 9bdba1b6 aliguori
        .name = "phenom",
237 9bdba1b6 aliguori
        .level = 5,
238 9bdba1b6 aliguori
        .vendor1 = CPUID_VENDOR_AMD_1,
239 9bdba1b6 aliguori
        .vendor2 = CPUID_VENDOR_AMD_2,
240 9bdba1b6 aliguori
        .vendor3 = CPUID_VENDOR_AMD_3,
241 9bdba1b6 aliguori
        .family = 16,
242 9bdba1b6 aliguori
        .model = 2,
243 9bdba1b6 aliguori
        .stepping = 3,
244 9bdba1b6 aliguori
        /* Missing: CPUID_VME, CPUID_HT */
245 9bdba1b6 aliguori
        .features = PPRO_FEATURES | 
246 9bdba1b6 aliguori
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
247 9bdba1b6 aliguori
            CPUID_PSE36,
248 f1e00a9c Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
249 f1e00a9c Andre Przywara
            CPUID_EXT_POPCNT,
250 9bdba1b6 aliguori
        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
251 9bdba1b6 aliguori
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | 
252 9bdba1b6 aliguori
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
253 9bdba1b6 aliguori
            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
254 9bdba1b6 aliguori
            CPUID_EXT2_FFXSR,
255 f1e00a9c Andre Przywara
        /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
256 f1e00a9c Andre Przywara
                    CPUID_EXT3_CR8LEG,
257 9bdba1b6 aliguori
                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
258 9bdba1b6 aliguori
                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
259 f1e00a9c Andre Przywara
        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
260 f1e00a9c Andre Przywara
            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
261 9bdba1b6 aliguori
        .xlevel = 0x8000001A,
262 9bdba1b6 aliguori
        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
263 9bdba1b6 aliguori
    },
264 9bdba1b6 aliguori
    {
265 e737b32a balrog
        .name = "core2duo",
266 558fa836 pbrook
        .level = 10,
267 e737b32a balrog
        .family = 6,
268 e737b32a balrog
        .model = 15,
269 e737b32a balrog
        .stepping = 11,
270 558fa836 pbrook
        /* The original CPU also implements these features:
271 558fa836 pbrook
               CPUID_VME, CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
272 558fa836 pbrook
               CPUID_TM, CPUID_PBE */
273 0086de1c balrog
        .features = PPRO_FEATURES |
274 e737b32a balrog
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
275 e737b32a balrog
            CPUID_PSE36,
276 558fa836 pbrook
        /* The original CPU also implements these ext features:
277 558fa836 pbrook
               CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
278 558fa836 pbrook
               CPUID_EXT_TM2, CPUID_EXT_CX16, CPUID_EXT_XTPR, CPUID_EXT_PDCM */
279 0086de1c balrog
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3,
280 558fa836 pbrook
        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
281 f1e00a9c Andre Przywara
        .ext3_features = CPUID_EXT3_LAHF_LM,
282 45fd08ef aurel32
        .xlevel = 0x80000008,
283 e737b32a balrog
        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
284 e737b32a balrog
    },
285 d1cd4bf4 Andre Przywara
    {
286 d1cd4bf4 Andre Przywara
        .name = "kvm64",
287 d1cd4bf4 Andre Przywara
        .level = 5,
288 d1cd4bf4 Andre Przywara
        .vendor1 = CPUID_VENDOR_INTEL_1,
289 d1cd4bf4 Andre Przywara
        .vendor2 = CPUID_VENDOR_INTEL_2,
290 d1cd4bf4 Andre Przywara
        .vendor3 = CPUID_VENDOR_INTEL_3,
291 d1cd4bf4 Andre Przywara
        .family = 15,
292 d1cd4bf4 Andre Przywara
        .model = 6,
293 d1cd4bf4 Andre Przywara
        .stepping = 1,
294 d1cd4bf4 Andre Przywara
        /* Missing: CPUID_VME, CPUID_HT */
295 d1cd4bf4 Andre Przywara
        .features = PPRO_FEATURES |
296 d1cd4bf4 Andre Przywara
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
297 d1cd4bf4 Andre Przywara
            CPUID_PSE36,
298 d1cd4bf4 Andre Przywara
        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
299 d1cd4bf4 Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
300 d1cd4bf4 Andre Przywara
        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
301 d1cd4bf4 Andre Przywara
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) |
302 d1cd4bf4 Andre Przywara
            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
303 d1cd4bf4 Andre Przywara
        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
304 d1cd4bf4 Andre Przywara
                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
305 d1cd4bf4 Andre Przywara
                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
306 d1cd4bf4 Andre Przywara
                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
307 d1cd4bf4 Andre Przywara
        .ext3_features = 0,
308 d1cd4bf4 Andre Przywara
        .xlevel = 0x80000008,
309 d1cd4bf4 Andre Przywara
        .model_id = "Common KVM processor"
310 d1cd4bf4 Andre Przywara
    },
311 eaa728ee bellard
#endif
312 eaa728ee bellard
    {
313 eaa728ee bellard
        .name = "qemu32",
314 ac72472b Andre Przywara
        .level = 4,
315 eaa728ee bellard
        .family = 6,
316 eaa728ee bellard
        .model = 3,
317 eaa728ee bellard
        .stepping = 3,
318 eaa728ee bellard
        .features = PPRO_FEATURES,
319 f1e00a9c Andre Przywara
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
320 eaa728ee bellard
        .xlevel = 0,
321 40f8e2fa bellard
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
322 eaa728ee bellard
    },
323 eaa728ee bellard
    {
324 45fd08ef aurel32
        .name = "coreduo",
325 45fd08ef aurel32
        .level = 10,
326 45fd08ef aurel32
        .family = 6,
327 45fd08ef aurel32
        .model = 14,
328 45fd08ef aurel32
        .stepping = 8,
329 45fd08ef aurel32
        /* The original CPU also implements these features:
330 45fd08ef aurel32
               CPUID_DTS, CPUID_ACPI, CPUID_SS, CPUID_HT,
331 45fd08ef aurel32
               CPUID_TM, CPUID_PBE */
332 45fd08ef aurel32
        .features = PPRO_FEATURES | CPUID_VME |
333 45fd08ef aurel32
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA,
334 45fd08ef aurel32
        /* The original CPU also implements these ext features:
335 45fd08ef aurel32
               CPUID_EXT_VMX, CPUID_EXT_EST, CPUID_EXT_TM2, CPUID_EXT_XTPR,
336 45fd08ef aurel32
               CPUID_EXT_PDCM */
337 45fd08ef aurel32
        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR,
338 45fd08ef aurel32
        .ext2_features = CPUID_EXT2_NX,
339 45fd08ef aurel32
        .xlevel = 0x80000008,
340 45fd08ef aurel32
        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
341 45fd08ef aurel32
    },
342 45fd08ef aurel32
    {
343 eaa728ee bellard
        .name = "486",
344 eaa728ee bellard
        .level = 0,
345 eaa728ee bellard
        .family = 4,
346 eaa728ee bellard
        .model = 0,
347 eaa728ee bellard
        .stepping = 0,
348 eaa728ee bellard
        .features = I486_FEATURES,
349 eaa728ee bellard
        .xlevel = 0,
350 eaa728ee bellard
    },
351 eaa728ee bellard
    {
352 eaa728ee bellard
        .name = "pentium",
353 eaa728ee bellard
        .level = 1,
354 eaa728ee bellard
        .family = 5,
355 eaa728ee bellard
        .model = 4,
356 eaa728ee bellard
        .stepping = 3,
357 eaa728ee bellard
        .features = PENTIUM_FEATURES,
358 eaa728ee bellard
        .xlevel = 0,
359 eaa728ee bellard
    },
360 eaa728ee bellard
    {
361 eaa728ee bellard
        .name = "pentium2",
362 eaa728ee bellard
        .level = 2,
363 eaa728ee bellard
        .family = 6,
364 eaa728ee bellard
        .model = 5,
365 eaa728ee bellard
        .stepping = 2,
366 eaa728ee bellard
        .features = PENTIUM2_FEATURES,
367 eaa728ee bellard
        .xlevel = 0,
368 eaa728ee bellard
    },
369 eaa728ee bellard
    {
370 eaa728ee bellard
        .name = "pentium3",
371 eaa728ee bellard
        .level = 2,
372 eaa728ee bellard
        .family = 6,
373 eaa728ee bellard
        .model = 7,
374 eaa728ee bellard
        .stepping = 3,
375 eaa728ee bellard
        .features = PENTIUM3_FEATURES,
376 eaa728ee bellard
        .xlevel = 0,
377 eaa728ee bellard
    },
378 eaa728ee bellard
    {
379 eaa728ee bellard
        .name = "athlon",
380 eaa728ee bellard
        .level = 2,
381 fe4bce09 Andre Przywara
        .vendor1 = CPUID_VENDOR_AMD_1,
382 fe4bce09 Andre Przywara
        .vendor2 = CPUID_VENDOR_AMD_2,
383 fe4bce09 Andre Przywara
        .vendor3 = CPUID_VENDOR_AMD_3,
384 eaa728ee bellard
        .family = 6,
385 eaa728ee bellard
        .model = 2,
386 eaa728ee bellard
        .stepping = 3,
387 558fa836 pbrook
        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
388 eaa728ee bellard
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
389 eaa728ee bellard
        .xlevel = 0x80000008,
390 40f8e2fa bellard
        /* XXX: put another string ? */
391 40f8e2fa bellard
        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
392 eaa728ee bellard
    },
393 0086de1c balrog
    {
394 c0d82995 balrog
        .name = "n270",
395 0086de1c balrog
        /* original is on level 10 */
396 0086de1c balrog
        .level = 5,
397 0086de1c balrog
        .family = 6,
398 0086de1c balrog
        .model = 28,
399 0086de1c balrog
        .stepping = 2,
400 0086de1c balrog
        .features = PPRO_FEATURES |
401 0086de1c balrog
            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME,
402 0086de1c balrog
            /* Missing: CPUID_DTS | CPUID_ACPI | CPUID_SS |
403 0086de1c balrog
             * CPUID_HT | CPUID_TM | CPUID_PBE */
404 0086de1c balrog
            /* Some CPUs got no CPUID_SEP */
405 0086de1c balrog
        .ext_features = CPUID_EXT_MONITOR |
406 853f6931 balrog
            CPUID_EXT_SSE3 /* PNI */ | CPUID_EXT_SSSE3,
407 0086de1c balrog
            /* Missing: CPUID_EXT_DSCPL | CPUID_EXT_EST |
408 0086de1c balrog
             * CPUID_EXT_TM2 | CPUID_EXT_XTPR */
409 0086de1c balrog
        .ext2_features = (PPRO_FEATURES & 0x0183F3FF) | CPUID_EXT2_NX,
410 0086de1c balrog
        /* Missing: .ext3_features = CPUID_EXT3_LAHF_LM */
411 0086de1c balrog
        .xlevel = 0x8000000A,
412 0086de1c balrog
        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
413 0086de1c balrog
    },
414 eaa728ee bellard
};
415 2c0262af bellard
416 fe4bce09 Andre Przywara
static int cpu_x86_fill_model_id(char *str)
417 fe4bce09 Andre Przywara
{
418 e6f9e6b4 Anthony Liguori
    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
419 fe4bce09 Andre Przywara
    int i;
420 fe4bce09 Andre Przywara
421 fe4bce09 Andre Przywara
    for (i = 0; i < 3; i++) {
422 fe4bce09 Andre Przywara
        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
423 fe4bce09 Andre Przywara
        memcpy(str + i * 16 +  0, &eax, 4);
424 fe4bce09 Andre Przywara
        memcpy(str + i * 16 +  4, &ebx, 4);
425 fe4bce09 Andre Przywara
        memcpy(str + i * 16 +  8, &ecx, 4);
426 fe4bce09 Andre Przywara
        memcpy(str + i * 16 + 12, &edx, 4);
427 fe4bce09 Andre Przywara
    }
428 fe4bce09 Andre Przywara
    return 0;
429 fe4bce09 Andre Przywara
}
430 fe4bce09 Andre Przywara
431 c227f099 Anthony Liguori
static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
432 fe4bce09 Andre Przywara
{
433 97b35e35 Blue Swirl
    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
434 fe4bce09 Andre Przywara
435 fe4bce09 Andre Przywara
    x86_cpu_def->name = "host";
436 fe4bce09 Andre Przywara
    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
437 fe4bce09 Andre Przywara
    x86_cpu_def->level = eax;
438 fe4bce09 Andre Przywara
    x86_cpu_def->vendor1 = ebx;
439 fe4bce09 Andre Przywara
    x86_cpu_def->vendor2 = edx;
440 fe4bce09 Andre Przywara
    x86_cpu_def->vendor3 = ecx;
441 fe4bce09 Andre Przywara
442 fe4bce09 Andre Przywara
    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
443 fe4bce09 Andre Przywara
    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
444 fe4bce09 Andre Przywara
    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
445 fe4bce09 Andre Przywara
    x86_cpu_def->stepping = eax & 0x0F;
446 fe4bce09 Andre Przywara
    x86_cpu_def->ext_features = ecx;
447 fe4bce09 Andre Przywara
    x86_cpu_def->features = edx;
448 fe4bce09 Andre Przywara
449 fe4bce09 Andre Przywara
    host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
450 fe4bce09 Andre Przywara
    x86_cpu_def->xlevel = eax;
451 fe4bce09 Andre Przywara
452 fe4bce09 Andre Przywara
    host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
453 fe4bce09 Andre Przywara
    x86_cpu_def->ext2_features = edx;
454 fe4bce09 Andre Przywara
    x86_cpu_def->ext3_features = ecx;
455 fe4bce09 Andre Przywara
    cpu_x86_fill_model_id(x86_cpu_def->model_id);
456 fe4bce09 Andre Przywara
    x86_cpu_def->vendor_override = 0;
457 fe4bce09 Andre Przywara
458 fe4bce09 Andre Przywara
    return 0;
459 fe4bce09 Andre Przywara
}
460 fe4bce09 Andre Przywara
461 b5ec5ce0 john cooper
static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
462 b5ec5ce0 john cooper
{
463 b5ec5ce0 john cooper
    int i;
464 b5ec5ce0 john cooper
465 b5ec5ce0 john cooper
    for (i = 0; i < 32; ++i)
466 b5ec5ce0 john cooper
        if (1 << i & mask) {
467 b5ec5ce0 john cooper
            fprintf(stderr, "warning: host cpuid %04x_%04x lacks requested"
468 b5ec5ce0 john cooper
                " flag '%s' [0x%08x]\n",
469 b5ec5ce0 john cooper
                f->cpuid >> 16, f->cpuid & 0xffff,
470 b5ec5ce0 john cooper
                f->flag_names[i] ? f->flag_names[i] : "[reserved]", mask);
471 b5ec5ce0 john cooper
            break;
472 b5ec5ce0 john cooper
        }
473 b5ec5ce0 john cooper
    return 0;
474 b5ec5ce0 john cooper
}
475 b5ec5ce0 john cooper
476 b5ec5ce0 john cooper
/* best effort attempt to inform user requested cpu flags aren't making
477 b5ec5ce0 john cooper
 * their way to the guest.  Note: ft[].check_feat ideally should be
478 b5ec5ce0 john cooper
 * specified via a guest_def field to suppress report of extraneous flags.
479 b5ec5ce0 john cooper
 */
480 b5ec5ce0 john cooper
static int check_features_against_host(x86_def_t *guest_def)
481 b5ec5ce0 john cooper
{
482 b5ec5ce0 john cooper
    x86_def_t host_def;
483 b5ec5ce0 john cooper
    uint32_t mask;
484 b5ec5ce0 john cooper
    int rv, i;
485 b5ec5ce0 john cooper
    struct model_features_t ft[] = {
486 b5ec5ce0 john cooper
        {&guest_def->features, &host_def.features,
487 b5ec5ce0 john cooper
            ~0, feature_name, 0x00000000},
488 b5ec5ce0 john cooper
        {&guest_def->ext_features, &host_def.ext_features,
489 b5ec5ce0 john cooper
            ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},
490 b5ec5ce0 john cooper
        {&guest_def->ext2_features, &host_def.ext2_features,
491 b5ec5ce0 john cooper
            ~PPRO_FEATURES, ext2_feature_name, 0x80000000},
492 b5ec5ce0 john cooper
        {&guest_def->ext3_features, &host_def.ext3_features,
493 b5ec5ce0 john cooper
            ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};
494 b5ec5ce0 john cooper
495 b5ec5ce0 john cooper
    cpu_x86_fill_host(&host_def);
496 b5ec5ce0 john cooper
    for (rv = 0, i = 0; i < sizeof (ft) / sizeof (ft[0]); ++i)
497 b5ec5ce0 john cooper
        for (mask = 1; mask; mask <<= 1)
498 b5ec5ce0 john cooper
            if (ft[i].check_feat & mask && *ft[i].guest_feat & mask &&
499 b5ec5ce0 john cooper
                !(*ft[i].host_feat & mask)) {
500 b5ec5ce0 john cooper
                    unavailable_host_feature(&ft[i], mask);
501 b5ec5ce0 john cooper
                    rv = 1;
502 b5ec5ce0 john cooper
                }
503 b5ec5ce0 john cooper
    return rv;
504 b5ec5ce0 john cooper
}
505 b5ec5ce0 john cooper
506 c227f099 Anthony Liguori
static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
507 2c0262af bellard
{
508 eaa728ee bellard
    unsigned int i;
509 c227f099 Anthony Liguori
    x86_def_t *def;
510 2c0262af bellard
511 eaa728ee bellard
    char *s = strdup(cpu_model);
512 eaa728ee bellard
    char *featurestr, *name = strtok(s, ",");
513 bb0300dc Gleb Natapov
    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
514 bb0300dc Gleb Natapov
    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0, minus_kvm_features = 0;
515 a8a358bf Andre Przywara
    uint32_t numvalue;
516 2c0262af bellard
517 b5ec5ce0 john cooper
    for (def = x86_defs; def; def = def->next)
518 b5ec5ce0 john cooper
        if (!strcmp(name, def->name))
519 eaa728ee bellard
            break;
520 5e650002 Anthony Liguori
    if (kvm_enabled() && strcmp(name, "host") == 0) {
521 fe4bce09 Andre Przywara
        cpu_x86_fill_host(x86_cpu_def);
522 5e650002 Anthony Liguori
    } else if (!def) {
523 5e650002 Anthony Liguori
        goto error;
524 fe4bce09 Andre Przywara
    } else {
525 fe4bce09 Andre Przywara
        memcpy(x86_cpu_def, def, sizeof(*def));
526 fe4bce09 Andre Przywara
    }
527 eaa728ee bellard
528 bb0300dc Gleb Natapov
    plus_kvm_features = ~0; /* not supported bits will be filtered out later */
529 bb0300dc Gleb Natapov
530 6d2edc43 Andre Przywara
    add_flagname_to_bitmaps("hypervisor", &plus_features,
531 bb0300dc Gleb Natapov
        &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
532 bb0300dc Gleb Natapov
        &plus_kvm_features);
533 6d2edc43 Andre Przywara
534 eaa728ee bellard
    featurestr = strtok(NULL, ",");
535 eaa728ee bellard
536 eaa728ee bellard
    while (featurestr) {
537 eaa728ee bellard
        char *val;
538 eaa728ee bellard
        if (featurestr[0] == '+') {
539 bb0300dc Gleb Natapov
            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features, &plus_kvm_features);
540 eaa728ee bellard
        } else if (featurestr[0] == '-') {
541 bb0300dc Gleb Natapov
            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features, &minus_kvm_features);
542 eaa728ee bellard
        } else if ((val = strchr(featurestr, '='))) {
543 eaa728ee bellard
            *val = 0; val++;
544 eaa728ee bellard
            if (!strcmp(featurestr, "family")) {
545 eaa728ee bellard
                char *err;
546 a8a358bf Andre Przywara
                numvalue = strtoul(val, &err, 0);
547 a8a358bf Andre Przywara
                if (!*val || *err) {
548 eaa728ee bellard
                    fprintf(stderr, "bad numerical value %s\n", val);
549 eaa728ee bellard
                    goto error;
550 eaa728ee bellard
                }
551 a8a358bf Andre Przywara
                x86_cpu_def->family = numvalue;
552 eaa728ee bellard
            } else if (!strcmp(featurestr, "model")) {
553 eaa728ee bellard
                char *err;
554 a8a358bf Andre Przywara
                numvalue = strtoul(val, &err, 0);
555 a8a358bf Andre Przywara
                if (!*val || *err || numvalue > 0xff) {
556 eaa728ee bellard
                    fprintf(stderr, "bad numerical value %s\n", val);
557 eaa728ee bellard
                    goto error;
558 eaa728ee bellard
                }
559 a8a358bf Andre Przywara
                x86_cpu_def->model = numvalue;
560 eaa728ee bellard
            } else if (!strcmp(featurestr, "stepping")) {
561 eaa728ee bellard
                char *err;
562 a8a358bf Andre Przywara
                numvalue = strtoul(val, &err, 0);
563 a8a358bf Andre Przywara
                if (!*val || *err || numvalue > 0xf) {
564 eaa728ee bellard
                    fprintf(stderr, "bad numerical value %s\n", val);
565 eaa728ee bellard
                    goto error;
566 eaa728ee bellard
                }
567 a8a358bf Andre Przywara
                x86_cpu_def->stepping = numvalue ;
568 a8a358bf Andre Przywara
            } else if (!strcmp(featurestr, "level")) {
569 a8a358bf Andre Przywara
                char *err;
570 a8a358bf Andre Przywara
                numvalue = strtoul(val, &err, 0);
571 a8a358bf Andre Przywara
                if (!*val || *err) {
572 a8a358bf Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
573 a8a358bf Andre Przywara
                    goto error;
574 a8a358bf Andre Przywara
                }
575 a8a358bf Andre Przywara
                x86_cpu_def->level = numvalue;
576 a8a358bf Andre Przywara
            } else if (!strcmp(featurestr, "xlevel")) {
577 a8a358bf Andre Przywara
                char *err;
578 a8a358bf Andre Przywara
                numvalue = strtoul(val, &err, 0);
579 a8a358bf Andre Przywara
                if (!*val || *err) {
580 a8a358bf Andre Przywara
                    fprintf(stderr, "bad numerical value %s\n", val);
581 a8a358bf Andre Przywara
                    goto error;
582 a8a358bf Andre Przywara
                }
583 a8a358bf Andre Przywara
                if (numvalue < 0x80000000) {
584 a8a358bf Andre Przywara
                        numvalue += 0x80000000;
585 a8a358bf Andre Przywara
                }
586 a8a358bf Andre Przywara
                x86_cpu_def->xlevel = numvalue;
587 40f8e2fa bellard
            } else if (!strcmp(featurestr, "vendor")) {
588 40f8e2fa bellard
                if (strlen(val) != 12) {
589 40f8e2fa bellard
                    fprintf(stderr, "vendor string must be 12 chars long\n");
590 40f8e2fa bellard
                    goto error;
591 40f8e2fa bellard
                }
592 40f8e2fa bellard
                x86_cpu_def->vendor1 = 0;
593 40f8e2fa bellard
                x86_cpu_def->vendor2 = 0;
594 40f8e2fa bellard
                x86_cpu_def->vendor3 = 0;
595 40f8e2fa bellard
                for(i = 0; i < 4; i++) {
596 40f8e2fa bellard
                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
597 40f8e2fa bellard
                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
598 40f8e2fa bellard
                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
599 40f8e2fa bellard
                }
600 ef768138 Andre Przywara
                x86_cpu_def->vendor_override = 1;
601 40f8e2fa bellard
            } else if (!strcmp(featurestr, "model_id")) {
602 40f8e2fa bellard
                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
603 40f8e2fa bellard
                        val);
604 eaa728ee bellard
            } else {
605 eaa728ee bellard
                fprintf(stderr, "unrecognized feature %s\n", featurestr);
606 eaa728ee bellard
                goto error;
607 eaa728ee bellard
            }
608 b5ec5ce0 john cooper
        } else if (!strcmp(featurestr, "check")) {
609 b5ec5ce0 john cooper
            check_cpuid = 1;
610 b5ec5ce0 john cooper
        } else if (!strcmp(featurestr, "enforce")) {
611 b5ec5ce0 john cooper
            check_cpuid = enforce_cpuid = 1;
612 eaa728ee bellard
        } else {
613 eaa728ee bellard
            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
614 eaa728ee bellard
            goto error;
615 eaa728ee bellard
        }
616 eaa728ee bellard
        featurestr = strtok(NULL, ",");
617 eaa728ee bellard
    }
618 eaa728ee bellard
    x86_cpu_def->features |= plus_features;
619 eaa728ee bellard
    x86_cpu_def->ext_features |= plus_ext_features;
620 eaa728ee bellard
    x86_cpu_def->ext2_features |= plus_ext2_features;
621 eaa728ee bellard
    x86_cpu_def->ext3_features |= plus_ext3_features;
622 bb0300dc Gleb Natapov
    x86_cpu_def->kvm_features |= plus_kvm_features;
623 eaa728ee bellard
    x86_cpu_def->features &= ~minus_features;
624 eaa728ee bellard
    x86_cpu_def->ext_features &= ~minus_ext_features;
625 eaa728ee bellard
    x86_cpu_def->ext2_features &= ~minus_ext2_features;
626 eaa728ee bellard
    x86_cpu_def->ext3_features &= ~minus_ext3_features;
627 bb0300dc Gleb Natapov
    x86_cpu_def->kvm_features &= ~minus_kvm_features;
628 b5ec5ce0 john cooper
    if (check_cpuid) {
629 b5ec5ce0 john cooper
        if (check_features_against_host(x86_cpu_def) && enforce_cpuid)
630 b5ec5ce0 john cooper
            goto error;
631 b5ec5ce0 john cooper
    }
632 eaa728ee bellard
    free(s);
633 eaa728ee bellard
    return 0;
634 eaa728ee bellard
635 eaa728ee bellard
error:
636 eaa728ee bellard
    free(s);
637 eaa728ee bellard
    return -1;
638 bd7a7b33 bellard
}
639 bd7a7b33 bellard
640 b5ec5ce0 john cooper
/* generate a composite string into buf of all cpuid names in featureset
641 b5ec5ce0 john cooper
 * selected by fbits.  indicate truncation at bufsize in the event of overflow.
642 b5ec5ce0 john cooper
 * if flags, suppress names undefined in featureset.
643 b5ec5ce0 john cooper
 */
644 b5ec5ce0 john cooper
static void listflags(char *buf, int bufsize, uint32_t fbits,
645 b5ec5ce0 john cooper
    const char **featureset, uint32_t flags)
646 bd7a7b33 bellard
{
647 b5ec5ce0 john cooper
    const char **p = &featureset[31];
648 b5ec5ce0 john cooper
    char *q, *b, bit;
649 b5ec5ce0 john cooper
    int nc;
650 b5ec5ce0 john cooper
651 b5ec5ce0 john cooper
    b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
652 b5ec5ce0 john cooper
    *buf = '\0';
653 b5ec5ce0 john cooper
    for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
654 b5ec5ce0 john cooper
        if (fbits & 1 << bit && (*p || !flags)) {
655 b5ec5ce0 john cooper
            if (*p)
656 b5ec5ce0 john cooper
                nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
657 b5ec5ce0 john cooper
            else
658 b5ec5ce0 john cooper
                nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
659 b5ec5ce0 john cooper
            if (bufsize <= nc) {
660 b5ec5ce0 john cooper
                if (b)
661 b5ec5ce0 john cooper
                    sprintf(b, "...");
662 b5ec5ce0 john cooper
                return;
663 b5ec5ce0 john cooper
            }
664 b5ec5ce0 john cooper
            q += nc;
665 b5ec5ce0 john cooper
            bufsize -= nc;
666 b5ec5ce0 john cooper
        }
667 b5ec5ce0 john cooper
}
668 eaa728ee bellard
669 b5ec5ce0 john cooper
/* generate CPU information:
670 b5ec5ce0 john cooper
 * -?        list model names
671 b5ec5ce0 john cooper
 * -?model   list model names/IDs
672 b5ec5ce0 john cooper
 * -?dump    output all model (x86_def_t) data
673 b5ec5ce0 john cooper
 * -?cpuid   list all recognized cpuid flag names
674 b5ec5ce0 john cooper
 */ 
675 b5ec5ce0 john cooper
void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
676 b5ec5ce0 john cooper
                  const char *optarg)
677 b5ec5ce0 john cooper
{
678 b5ec5ce0 john cooper
    unsigned char model = !strcmp("?model", optarg);
679 b5ec5ce0 john cooper
    unsigned char dump = !strcmp("?dump", optarg);
680 b5ec5ce0 john cooper
    unsigned char cpuid = !strcmp("?cpuid", optarg);
681 b5ec5ce0 john cooper
    x86_def_t *def;
682 b5ec5ce0 john cooper
    char buf[256];
683 b5ec5ce0 john cooper
684 b5ec5ce0 john cooper
    if (cpuid) {
685 b5ec5ce0 john cooper
        (*cpu_fprintf)(f, "Recognized CPUID flags:\n");
686 b5ec5ce0 john cooper
        listflags(buf, sizeof (buf), (uint32_t)~0, feature_name, 1);
687 b5ec5ce0 john cooper
        (*cpu_fprintf)(f, "  f_edx: %s\n", buf);
688 b5ec5ce0 john cooper
        listflags(buf, sizeof (buf), (uint32_t)~0, ext_feature_name, 1);
689 b5ec5ce0 john cooper
        (*cpu_fprintf)(f, "  f_ecx: %s\n", buf);
690 b5ec5ce0 john cooper
        listflags(buf, sizeof (buf), (uint32_t)~0, ext2_feature_name, 1);
691 b5ec5ce0 john cooper
        (*cpu_fprintf)(f, "  extf_edx: %s\n", buf);
692 b5ec5ce0 john cooper
        listflags(buf, sizeof (buf), (uint32_t)~0, ext3_feature_name, 1);
693 b5ec5ce0 john cooper
        (*cpu_fprintf)(f, "  extf_ecx: %s\n", buf);
694 b5ec5ce0 john cooper
        return;
695 b5ec5ce0 john cooper
    }
696 b5ec5ce0 john cooper
    for (def = x86_defs; def; def = def->next) {
697 b5ec5ce0 john cooper
        snprintf(buf, sizeof (buf), def->flags ? "[%s]": "%s", def->name);
698 b5ec5ce0 john cooper
        if (model || dump) {
699 b5ec5ce0 john cooper
            (*cpu_fprintf)(f, "x86 %16s  %-48s\n", buf, def->model_id);
700 b5ec5ce0 john cooper
        } else {
701 b5ec5ce0 john cooper
            (*cpu_fprintf)(f, "x86 %16s\n", buf);
702 b5ec5ce0 john cooper
        }
703 b5ec5ce0 john cooper
        if (dump) {
704 b5ec5ce0 john cooper
            memcpy(buf, &def->vendor1, sizeof (def->vendor1));
705 b5ec5ce0 john cooper
            memcpy(buf + 4, &def->vendor2, sizeof (def->vendor2));
706 b5ec5ce0 john cooper
            memcpy(buf + 8, &def->vendor3, sizeof (def->vendor3));
707 b5ec5ce0 john cooper
            buf[12] = '\0';
708 b5ec5ce0 john cooper
            (*cpu_fprintf)(f,
709 b5ec5ce0 john cooper
                "  family %d model %d stepping %d level %d xlevel 0x%x"
710 b5ec5ce0 john cooper
                " vendor \"%s\"\n",
711 b5ec5ce0 john cooper
                def->family, def->model, def->stepping, def->level,
712 b5ec5ce0 john cooper
                def->xlevel, buf);
713 b5ec5ce0 john cooper
            listflags(buf, sizeof (buf), def->features, feature_name, 0);
714 b5ec5ce0 john cooper
            (*cpu_fprintf)(f, "  feature_edx %08x (%s)\n", def->features,
715 b5ec5ce0 john cooper
                buf);
716 b5ec5ce0 john cooper
            listflags(buf, sizeof (buf), def->ext_features, ext_feature_name,
717 b5ec5ce0 john cooper
                0);
718 b5ec5ce0 john cooper
            (*cpu_fprintf)(f, "  feature_ecx %08x (%s)\n", def->ext_features,
719 b5ec5ce0 john cooper
                buf);
720 b5ec5ce0 john cooper
            listflags(buf, sizeof (buf), def->ext2_features, ext2_feature_name,
721 b5ec5ce0 john cooper
                0);
722 b5ec5ce0 john cooper
            (*cpu_fprintf)(f, "  extfeature_edx %08x (%s)\n",
723 b5ec5ce0 john cooper
                def->ext2_features, buf);
724 b5ec5ce0 john cooper
            listflags(buf, sizeof (buf), def->ext3_features, ext3_feature_name,
725 b5ec5ce0 john cooper
                0);
726 b5ec5ce0 john cooper
            (*cpu_fprintf)(f, "  extfeature_ecx %08x (%s)\n",
727 b5ec5ce0 john cooper
                def->ext3_features, buf);
728 b5ec5ce0 john cooper
            (*cpu_fprintf)(f, "\n");
729 b5ec5ce0 john cooper
        }
730 b5ec5ce0 john cooper
    }
731 bd7a7b33 bellard
}
732 bd7a7b33 bellard
733 eaa728ee bellard
static int cpu_x86_register (CPUX86State *env, const char *cpu_model)
734 7e84c249 bellard
{
735 c227f099 Anthony Liguori
    x86_def_t def1, *def = &def1;
736 7e84c249 bellard
737 eaa728ee bellard
    if (cpu_x86_find_by_name(def, cpu_model) < 0)
738 7e84c249 bellard
        return -1;
739 eaa728ee bellard
    if (def->vendor1) {
740 eaa728ee bellard
        env->cpuid_vendor1 = def->vendor1;
741 eaa728ee bellard
        env->cpuid_vendor2 = def->vendor2;
742 eaa728ee bellard
        env->cpuid_vendor3 = def->vendor3;
743 eaa728ee bellard
    } else {
744 c5096daf balrog
        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
745 c5096daf balrog
        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
746 c5096daf balrog
        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
747 eaa728ee bellard
    }
748 ef768138 Andre Przywara
    env->cpuid_vendor_override = def->vendor_override;
749 eaa728ee bellard
    env->cpuid_level = def->level;
750 59795a1f balrog
    if (def->family > 0x0f)
751 59795a1f balrog
        env->cpuid_version = 0xf00 | ((def->family - 0x0f) << 20);
752 59795a1f balrog
    else
753 59795a1f balrog
        env->cpuid_version = def->family << 8;
754 59795a1f balrog
    env->cpuid_version |= ((def->model & 0xf) << 4) | ((def->model >> 4) << 16);
755 59795a1f balrog
    env->cpuid_version |= def->stepping;
756 eaa728ee bellard
    env->cpuid_features = def->features;
757 eaa728ee bellard
    env->pat = 0x0007040600070406ULL;
758 eaa728ee bellard
    env->cpuid_ext_features = def->ext_features;
759 eaa728ee bellard
    env->cpuid_ext2_features = def->ext2_features;
760 eaa728ee bellard
    env->cpuid_xlevel = def->xlevel;
761 bb0300dc Gleb Natapov
    env->cpuid_kvm_features = def->kvm_features;
762 eaa728ee bellard
    {
763 40f8e2fa bellard
        const char *model_id = def->model_id;
764 eaa728ee bellard
        int c, len, i;
765 40f8e2fa bellard
        if (!model_id)
766 40f8e2fa bellard
            model_id = "";
767 eaa728ee bellard
        len = strlen(model_id);
768 eaa728ee bellard
        for(i = 0; i < 48; i++) {
769 eaa728ee bellard
            if (i >= len)
770 eaa728ee bellard
                c = '\0';
771 eaa728ee bellard
            else
772 40f8e2fa bellard
                c = (uint8_t)model_id[i];
773 eaa728ee bellard
            env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
774 eaa728ee bellard
        }
775 eaa728ee bellard
    }
776 7e84c249 bellard
    return 0;
777 7e84c249 bellard
}
778 3b46e624 ths
779 b5ec5ce0 john cooper
#if !defined(CONFIG_LINUX_USER)
780 b5ec5ce0 john cooper
/* copy vendor id string to 32 bit register, nul pad as needed
781 b5ec5ce0 john cooper
 */
782 b5ec5ce0 john cooper
static void cpyid(const char *s, uint32_t *id)
783 b5ec5ce0 john cooper
{
784 b5ec5ce0 john cooper
    char *d = (char *)id;
785 b5ec5ce0 john cooper
    char i;
786 b5ec5ce0 john cooper
787 b5ec5ce0 john cooper
    for (i = sizeof (*id); i--; )
788 b5ec5ce0 john cooper
        *d++ = *s ? *s++ : '\0';
789 b5ec5ce0 john cooper
}
790 b5ec5ce0 john cooper
791 b5ec5ce0 john cooper
/* interpret radix and convert from string to arbitrary scalar,
792 b5ec5ce0 john cooper
 * otherwise flag failure
793 b5ec5ce0 john cooper
 */
794 b5ec5ce0 john cooper
#define setscalar(pval, str, perr)                      \
795 b5ec5ce0 john cooper
{                                                       \
796 b5ec5ce0 john cooper
    char *pend;                                         \
797 b5ec5ce0 john cooper
    unsigned long ul;                                   \
798 b5ec5ce0 john cooper
                                                        \
799 b5ec5ce0 john cooper
    ul = strtoul(str, &pend, 0);                        \
800 b5ec5ce0 john cooper
    *str && !*pend ? (*pval = ul) : (*perr = 1);        \
801 b5ec5ce0 john cooper
}
802 b5ec5ce0 john cooper
803 b5ec5ce0 john cooper
/* map cpuid options to feature bits, otherwise return failure
804 b5ec5ce0 john cooper
 * (option tags in *str are delimited by whitespace)
805 b5ec5ce0 john cooper
 */
806 b5ec5ce0 john cooper
static void setfeatures(uint32_t *pval, const char *str,
807 b5ec5ce0 john cooper
    const char **featureset, int *perr)
808 b5ec5ce0 john cooper
{
809 b5ec5ce0 john cooper
    const char *p, *q;
810 b5ec5ce0 john cooper
811 b5ec5ce0 john cooper
    for (q = p = str; *p || *q; q = p) {
812 b5ec5ce0 john cooper
        while (iswhite(*p))
813 b5ec5ce0 john cooper
            q = ++p; 
814 b5ec5ce0 john cooper
        while (*p && !iswhite(*p))
815 b5ec5ce0 john cooper
            ++p;
816 b5ec5ce0 john cooper
        if (!*q && !*p)
817 b5ec5ce0 john cooper
            return;
818 b5ec5ce0 john cooper
        if (!lookup_feature(pval, q, p, featureset)) {
819 b5ec5ce0 john cooper
            fprintf(stderr, "error: feature \"%.*s\" not available in set\n",
820 b5ec5ce0 john cooper
                (int)(p - q), q);
821 b5ec5ce0 john cooper
            *perr = 1;
822 b5ec5ce0 john cooper
            return;
823 b5ec5ce0 john cooper
        }
824 b5ec5ce0 john cooper
    }
825 b5ec5ce0 john cooper
}
826 b5ec5ce0 john cooper
827 b5ec5ce0 john cooper
/* map config file options to x86_def_t form
828 b5ec5ce0 john cooper
 */
829 b5ec5ce0 john cooper
static int cpudef_setfield(const char *name, const char *str, void *opaque)
830 b5ec5ce0 john cooper
{
831 b5ec5ce0 john cooper
    x86_def_t *def = opaque;
832 b5ec5ce0 john cooper
    int err = 0;
833 b5ec5ce0 john cooper
834 b5ec5ce0 john cooper
    if (!strcmp(name, "name")) {
835 b5ec5ce0 john cooper
        def->name = strdup(str);
836 b5ec5ce0 john cooper
    } else if (!strcmp(name, "model_id")) {
837 b5ec5ce0 john cooper
        strncpy(def->model_id, str, sizeof (def->model_id));
838 b5ec5ce0 john cooper
    } else if (!strcmp(name, "level")) {
839 b5ec5ce0 john cooper
        setscalar(&def->level, str, &err)
840 b5ec5ce0 john cooper
    } else if (!strcmp(name, "vendor")) {
841 b5ec5ce0 john cooper
        cpyid(&str[0], &def->vendor1);
842 b5ec5ce0 john cooper
        cpyid(&str[4], &def->vendor2);
843 b5ec5ce0 john cooper
        cpyid(&str[8], &def->vendor3);
844 b5ec5ce0 john cooper
    } else if (!strcmp(name, "family")) {
845 b5ec5ce0 john cooper
        setscalar(&def->family, str, &err)
846 b5ec5ce0 john cooper
    } else if (!strcmp(name, "model")) {
847 b5ec5ce0 john cooper
        setscalar(&def->model, str, &err)
848 b5ec5ce0 john cooper
    } else if (!strcmp(name, "stepping")) {
849 b5ec5ce0 john cooper
        setscalar(&def->stepping, str, &err)
850 b5ec5ce0 john cooper
    } else if (!strcmp(name, "feature_edx")) {
851 b5ec5ce0 john cooper
        setfeatures(&def->features, str, feature_name, &err);
852 b5ec5ce0 john cooper
    } else if (!strcmp(name, "feature_ecx")) {
853 b5ec5ce0 john cooper
        setfeatures(&def->ext_features, str, ext_feature_name, &err);
854 b5ec5ce0 john cooper
    } else if (!strcmp(name, "extfeature_edx")) {
855 b5ec5ce0 john cooper
        setfeatures(&def->ext2_features, str, ext2_feature_name, &err);
856 b5ec5ce0 john cooper
    } else if (!strcmp(name, "extfeature_ecx")) {
857 b5ec5ce0 john cooper
        setfeatures(&def->ext3_features, str, ext3_feature_name, &err);
858 b5ec5ce0 john cooper
    } else if (!strcmp(name, "xlevel")) {
859 b5ec5ce0 john cooper
        setscalar(&def->xlevel, str, &err)
860 b5ec5ce0 john cooper
    } else {
861 b5ec5ce0 john cooper
        fprintf(stderr, "error: unknown option [%s = %s]\n", name, str);
862 b5ec5ce0 john cooper
        return (1);
863 b5ec5ce0 john cooper
    }
864 b5ec5ce0 john cooper
    if (err) {
865 b5ec5ce0 john cooper
        fprintf(stderr, "error: bad option value [%s = %s]\n", name, str);
866 b5ec5ce0 john cooper
        return (1);
867 b5ec5ce0 john cooper
    }
868 b5ec5ce0 john cooper
    return (0);
869 b5ec5ce0 john cooper
}
870 b5ec5ce0 john cooper
871 b5ec5ce0 john cooper
/* register config file entry as x86_def_t
872 b5ec5ce0 john cooper
 */
873 b5ec5ce0 john cooper
static int cpudef_register(QemuOpts *opts, void *opaque)
874 b5ec5ce0 john cooper
{
875 b5ec5ce0 john cooper
    x86_def_t *def = qemu_mallocz(sizeof (x86_def_t));
876 b5ec5ce0 john cooper
877 b5ec5ce0 john cooper
    qemu_opt_foreach(opts, cpudef_setfield, def, 1);
878 b5ec5ce0 john cooper
    def->next = x86_defs;
879 b5ec5ce0 john cooper
    x86_defs = def;
880 b5ec5ce0 john cooper
    return (0);
881 b5ec5ce0 john cooper
}
882 b5ec5ce0 john cooper
#endif        /* !CONFIG_LINUX_USER */
883 b5ec5ce0 john cooper
884 b5ec5ce0 john cooper
/* register "cpudef" models defined in configuration file.  Here we first
885 b5ec5ce0 john cooper
 * preload any built-in definitions
886 b5ec5ce0 john cooper
 */
887 b5ec5ce0 john cooper
void x86_cpudef_setup(void)
888 b5ec5ce0 john cooper
{
889 b5ec5ce0 john cooper
    int i;
890 b5ec5ce0 john cooper
891 b5ec5ce0 john cooper
    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
892 b5ec5ce0 john cooper
        builtin_x86_defs[i].next = x86_defs;
893 b5ec5ce0 john cooper
        builtin_x86_defs[i].flags = 1;
894 b5ec5ce0 john cooper
        x86_defs = &builtin_x86_defs[i];
895 b5ec5ce0 john cooper
    }
896 b5ec5ce0 john cooper
#if !defined(CONFIG_LINUX_USER)
897 b5ec5ce0 john cooper
    qemu_opts_foreach(&qemu_cpudef_opts, cpudef_register, NULL, 0);
898 b5ec5ce0 john cooper
#endif
899 b5ec5ce0 john cooper
}
900 b5ec5ce0 john cooper
901 eaa728ee bellard
/* NOTE: must be called outside the CPU execute loop */
902 eaa728ee bellard
void cpu_reset(CPUX86State *env)
903 7e84c249 bellard
{
904 eaa728ee bellard
    int i;
905 7e84c249 bellard
906 eca1bdf4 aliguori
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
907 eca1bdf4 aliguori
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
908 eca1bdf4 aliguori
        log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
909 eca1bdf4 aliguori
    }
910 eca1bdf4 aliguori
911 eaa728ee bellard
    memset(env, 0, offsetof(CPUX86State, breakpoints));
912 7e84c249 bellard
913 eaa728ee bellard
    tlb_flush(env, 1);
914 7e84c249 bellard
915 eaa728ee bellard
    env->old_exception = -1;
916 7e84c249 bellard
917 eaa728ee bellard
    /* init to reset state */
918 3b46e624 ths
919 eaa728ee bellard
#ifdef CONFIG_SOFTMMU
920 eaa728ee bellard
    env->hflags |= HF_SOFTMMU_MASK;
921 2c0262af bellard
#endif
922 db620f46 bellard
    env->hflags2 |= HF2_GIF_MASK;
923 2c0262af bellard
924 eaa728ee bellard
    cpu_x86_update_cr0(env, 0x60000010);
925 eaa728ee bellard
    env->a20_mask = ~0x0;
926 eaa728ee bellard
    env->smbase = 0x30000;
927 7e84c249 bellard
928 eaa728ee bellard
    env->idt.limit = 0xffff;
929 eaa728ee bellard
    env->gdt.limit = 0xffff;
930 eaa728ee bellard
    env->ldt.limit = 0xffff;
931 262ffdae bellard
    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
932 eaa728ee bellard
    env->tr.limit = 0xffff;
933 23e6c399 aliguori
    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
934 262ffdae bellard
935 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
936 538f3686 Nitin A Kamble
                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
937 538f3686 Nitin A Kamble
                           DESC_R_MASK | DESC_A_MASK);
938 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
939 538f3686 Nitin A Kamble
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
940 538f3686 Nitin A Kamble
                           DESC_A_MASK);
941 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
942 538f3686 Nitin A Kamble
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
943 538f3686 Nitin A Kamble
                           DESC_A_MASK);
944 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
945 538f3686 Nitin A Kamble
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
946 538f3686 Nitin A Kamble
                           DESC_A_MASK);
947 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
948 538f3686 Nitin A Kamble
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
949 538f3686 Nitin A Kamble
                           DESC_A_MASK);
950 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
951 538f3686 Nitin A Kamble
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
952 538f3686 Nitin A Kamble
                           DESC_A_MASK);
953 7e84c249 bellard
954 eaa728ee bellard
    env->eip = 0xfff0;
955 eaa728ee bellard
    env->regs[R_EDX] = env->cpuid_version;
956 2c0262af bellard
957 eaa728ee bellard
    env->eflags = 0x2;
958 7e84c249 bellard
959 eaa728ee bellard
    /* FPU init */
960 eaa728ee bellard
    for(i = 0;i < 8; i++)
961 eaa728ee bellard
        env->fptags[i] = 1;
962 eaa728ee bellard
    env->fpuc = 0x37f;
963 7e84c249 bellard
964 eaa728ee bellard
    env->mxcsr = 0x1f80;
965 01df040b aliguori
966 01df040b aliguori
    memset(env->dr, 0, sizeof(env->dr));
967 01df040b aliguori
    env->dr[6] = DR6_FIXED_1;
968 01df040b aliguori
    env->dr[7] = DR7_FIXED_1;
969 01df040b aliguori
    cpu_breakpoint_remove_all(env, BP_CPU);
970 01df040b aliguori
    cpu_watchpoint_remove_all(env, BP_CPU);
971 af364b41 Huang Ying
972 af364b41 Huang Ying
    env->mcg_status = 0;
973 eaa728ee bellard
}
974 7e84c249 bellard
975 eaa728ee bellard
void cpu_x86_close(CPUX86State *env)
976 eaa728ee bellard
{
977 bb332cb2 balrog
    qemu_free(env);
978 eaa728ee bellard
}
979 7e84c249 bellard
980 eaa728ee bellard
/***********************************************************/
981 eaa728ee bellard
/* x86 debug */
982 3b46e624 ths
983 eaa728ee bellard
static const char *cc_op_str[] = {
984 eaa728ee bellard
    "DYNAMIC",
985 eaa728ee bellard
    "EFLAGS",
986 7e84c249 bellard
987 eaa728ee bellard
    "MULB",
988 eaa728ee bellard
    "MULW",
989 eaa728ee bellard
    "MULL",
990 eaa728ee bellard
    "MULQ",
991 3b46e624 ths
992 eaa728ee bellard
    "ADDB",
993 eaa728ee bellard
    "ADDW",
994 eaa728ee bellard
    "ADDL",
995 eaa728ee bellard
    "ADDQ",
996 3b46e624 ths
997 eaa728ee bellard
    "ADCB",
998 eaa728ee bellard
    "ADCW",
999 eaa728ee bellard
    "ADCL",
1000 eaa728ee bellard
    "ADCQ",
1001 3b46e624 ths
1002 eaa728ee bellard
    "SUBB",
1003 eaa728ee bellard
    "SUBW",
1004 eaa728ee bellard
    "SUBL",
1005 eaa728ee bellard
    "SUBQ",
1006 7e84c249 bellard
1007 eaa728ee bellard
    "SBBB",
1008 eaa728ee bellard
    "SBBW",
1009 eaa728ee bellard
    "SBBL",
1010 eaa728ee bellard
    "SBBQ",
1011 7e84c249 bellard
1012 eaa728ee bellard
    "LOGICB",
1013 eaa728ee bellard
    "LOGICW",
1014 eaa728ee bellard
    "LOGICL",
1015 eaa728ee bellard
    "LOGICQ",
1016 7e84c249 bellard
1017 eaa728ee bellard
    "INCB",
1018 eaa728ee bellard
    "INCW",
1019 eaa728ee bellard
    "INCL",
1020 eaa728ee bellard
    "INCQ",
1021 3b46e624 ths
1022 eaa728ee bellard
    "DECB",
1023 eaa728ee bellard
    "DECW",
1024 eaa728ee bellard
    "DECL",
1025 eaa728ee bellard
    "DECQ",
1026 3b46e624 ths
1027 eaa728ee bellard
    "SHLB",
1028 eaa728ee bellard
    "SHLW",
1029 eaa728ee bellard
    "SHLL",
1030 eaa728ee bellard
    "SHLQ",
1031 3b46e624 ths
1032 eaa728ee bellard
    "SARB",
1033 eaa728ee bellard
    "SARW",
1034 eaa728ee bellard
    "SARL",
1035 eaa728ee bellard
    "SARQ",
1036 eaa728ee bellard
};
1037 7e84c249 bellard
1038 a3867ed2 aliguori
static void
1039 a3867ed2 aliguori
cpu_x86_dump_seg_cache(CPUState *env, FILE *f,
1040 a3867ed2 aliguori
                       int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
1041 a3867ed2 aliguori
                       const char *name, struct SegmentCache *sc)
1042 a3867ed2 aliguori
{
1043 a3867ed2 aliguori
#ifdef TARGET_X86_64
1044 a3867ed2 aliguori
    if (env->hflags & HF_CS64_MASK) {
1045 a3867ed2 aliguori
        cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
1046 a3867ed2 aliguori
                    sc->selector, sc->base, sc->limit, sc->flags);
1047 a3867ed2 aliguori
    } else
1048 a3867ed2 aliguori
#endif
1049 a3867ed2 aliguori
    {
1050 a3867ed2 aliguori
        cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
1051 a3867ed2 aliguori
                    (uint32_t)sc->base, sc->limit, sc->flags);
1052 a3867ed2 aliguori
    }
1053 a3867ed2 aliguori
1054 a3867ed2 aliguori
    if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
1055 a3867ed2 aliguori
        goto done;
1056 a3867ed2 aliguori
1057 a3867ed2 aliguori
    cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
1058 a3867ed2 aliguori
    if (sc->flags & DESC_S_MASK) {
1059 a3867ed2 aliguori
        if (sc->flags & DESC_CS_MASK) {
1060 a3867ed2 aliguori
            cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
1061 a3867ed2 aliguori
                           ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
1062 a3867ed2 aliguori
            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
1063 a3867ed2 aliguori
                        (sc->flags & DESC_R_MASK) ? 'R' : '-');
1064 a3867ed2 aliguori
        } else {
1065 a3867ed2 aliguori
            cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS  " : "DS16");
1066 a3867ed2 aliguori
            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
1067 a3867ed2 aliguori
                        (sc->flags & DESC_W_MASK) ? 'W' : '-');
1068 a3867ed2 aliguori
        }
1069 a3867ed2 aliguori
        cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
1070 a3867ed2 aliguori
    } else {
1071 a3867ed2 aliguori
        static const char *sys_type_name[2][16] = {
1072 a3867ed2 aliguori
            { /* 32 bit mode */
1073 a3867ed2 aliguori
                "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
1074 a3867ed2 aliguori
                "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
1075 a3867ed2 aliguori
                "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
1076 a3867ed2 aliguori
                "CallGate32", "Reserved", "IntGate32", "TrapGate32"
1077 a3867ed2 aliguori
            },
1078 a3867ed2 aliguori
            { /* 64 bit mode */
1079 a3867ed2 aliguori
                "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
1080 a3867ed2 aliguori
                "Reserved", "Reserved", "Reserved", "Reserved",
1081 a3867ed2 aliguori
                "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
1082 a3867ed2 aliguori
                "Reserved", "IntGate64", "TrapGate64"
1083 a3867ed2 aliguori
            }
1084 a3867ed2 aliguori
        };
1085 a3867ed2 aliguori
        cpu_fprintf(f, sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
1086 a3867ed2 aliguori
                                    [(sc->flags & DESC_TYPE_MASK)
1087 a3867ed2 aliguori
                                     >> DESC_TYPE_SHIFT]);
1088 a3867ed2 aliguori
    }
1089 a3867ed2 aliguori
done:
1090 a3867ed2 aliguori
    cpu_fprintf(f, "\n");
1091 a3867ed2 aliguori
}
1092 a3867ed2 aliguori
1093 eaa728ee bellard
void cpu_dump_state(CPUState *env, FILE *f,
1094 eaa728ee bellard
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
1095 eaa728ee bellard
                    int flags)
1096 eaa728ee bellard
{
1097 eaa728ee bellard
    int eflags, i, nb;
1098 eaa728ee bellard
    char cc_op_name[32];
1099 eaa728ee bellard
    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
1100 7e84c249 bellard
1101 23054111 Jan Kiszka
    cpu_synchronize_state(env);
1102 ff3c01ca balrog
1103 eaa728ee bellard
    eflags = env->eflags;
1104 eaa728ee bellard
#ifdef TARGET_X86_64
1105 eaa728ee bellard
    if (env->hflags & HF_CS64_MASK) {
1106 eaa728ee bellard
        cpu_fprintf(f,
1107 eaa728ee bellard
                    "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
1108 eaa728ee bellard
                    "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
1109 eaa728ee bellard
                    "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
1110 eaa728ee bellard
                    "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
1111 eaa728ee bellard
                    "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
1112 eaa728ee bellard
                    env->regs[R_EAX],
1113 eaa728ee bellard
                    env->regs[R_EBX],
1114 eaa728ee bellard
                    env->regs[R_ECX],
1115 eaa728ee bellard
                    env->regs[R_EDX],
1116 eaa728ee bellard
                    env->regs[R_ESI],
1117 eaa728ee bellard
                    env->regs[R_EDI],
1118 eaa728ee bellard
                    env->regs[R_EBP],
1119 eaa728ee bellard
                    env->regs[R_ESP],
1120 eaa728ee bellard
                    env->regs[8],
1121 eaa728ee bellard
                    env->regs[9],
1122 eaa728ee bellard
                    env->regs[10],
1123 eaa728ee bellard
                    env->regs[11],
1124 eaa728ee bellard
                    env->regs[12],
1125 eaa728ee bellard
                    env->regs[13],
1126 eaa728ee bellard
                    env->regs[14],
1127 eaa728ee bellard
                    env->regs[15],
1128 eaa728ee bellard
                    env->eip, eflags,
1129 eaa728ee bellard
                    eflags & DF_MASK ? 'D' : '-',
1130 eaa728ee bellard
                    eflags & CC_O ? 'O' : '-',
1131 eaa728ee bellard
                    eflags & CC_S ? 'S' : '-',
1132 eaa728ee bellard
                    eflags & CC_Z ? 'Z' : '-',
1133 eaa728ee bellard
                    eflags & CC_A ? 'A' : '-',
1134 eaa728ee bellard
                    eflags & CC_P ? 'P' : '-',
1135 eaa728ee bellard
                    eflags & CC_C ? 'C' : '-',
1136 eaa728ee bellard
                    env->hflags & HF_CPL_MASK,
1137 eaa728ee bellard
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
1138 5ee0ffaa Juan Quintela
                    (env->a20_mask >> 20) & 1,
1139 eaa728ee bellard
                    (env->hflags >> HF_SMM_SHIFT) & 1,
1140 ce5232c5 bellard
                    env->halted);
1141 eaa728ee bellard
    } else
1142 eaa728ee bellard
#endif
1143 eaa728ee bellard
    {
1144 eaa728ee bellard
        cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
1145 eaa728ee bellard
                    "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
1146 eaa728ee bellard
                    "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
1147 eaa728ee bellard
                    (uint32_t)env->regs[R_EAX],
1148 eaa728ee bellard
                    (uint32_t)env->regs[R_EBX],
1149 eaa728ee bellard
                    (uint32_t)env->regs[R_ECX],
1150 eaa728ee bellard
                    (uint32_t)env->regs[R_EDX],
1151 eaa728ee bellard
                    (uint32_t)env->regs[R_ESI],
1152 eaa728ee bellard
                    (uint32_t)env->regs[R_EDI],
1153 eaa728ee bellard
                    (uint32_t)env->regs[R_EBP],
1154 eaa728ee bellard
                    (uint32_t)env->regs[R_ESP],
1155 eaa728ee bellard
                    (uint32_t)env->eip, eflags,
1156 eaa728ee bellard
                    eflags & DF_MASK ? 'D' : '-',
1157 eaa728ee bellard
                    eflags & CC_O ? 'O' : '-',
1158 eaa728ee bellard
                    eflags & CC_S ? 'S' : '-',
1159 eaa728ee bellard
                    eflags & CC_Z ? 'Z' : '-',
1160 eaa728ee bellard
                    eflags & CC_A ? 'A' : '-',
1161 eaa728ee bellard
                    eflags & CC_P ? 'P' : '-',
1162 eaa728ee bellard
                    eflags & CC_C ? 'C' : '-',
1163 eaa728ee bellard
                    env->hflags & HF_CPL_MASK,
1164 eaa728ee bellard
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
1165 5ee0ffaa Juan Quintela
                    (env->a20_mask >> 20) & 1,
1166 eaa728ee bellard
                    (env->hflags >> HF_SMM_SHIFT) & 1,
1167 ce5232c5 bellard
                    env->halted);
1168 8145122b bellard
    }
1169 3b46e624 ths
1170 a3867ed2 aliguori
    for(i = 0; i < 6; i++) {
1171 a3867ed2 aliguori
        cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
1172 a3867ed2 aliguori
                               &env->segs[i]);
1173 a3867ed2 aliguori
    }
1174 a3867ed2 aliguori
    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
1175 a3867ed2 aliguori
    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
1176 a3867ed2 aliguori
1177 eaa728ee bellard
#ifdef TARGET_X86_64
1178 eaa728ee bellard
    if (env->hflags & HF_LMA_MASK) {
1179 eaa728ee bellard
        cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
1180 eaa728ee bellard
                    env->gdt.base, env->gdt.limit);
1181 eaa728ee bellard
        cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
1182 eaa728ee bellard
                    env->idt.base, env->idt.limit);
1183 eaa728ee bellard
        cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
1184 eaa728ee bellard
                    (uint32_t)env->cr[0],
1185 eaa728ee bellard
                    env->cr[2],
1186 eaa728ee bellard
                    env->cr[3],
1187 eaa728ee bellard
                    (uint32_t)env->cr[4]);
1188 a59cb4e0 aliguori
        for(i = 0; i < 4; i++)
1189 a59cb4e0 aliguori
            cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
1190 a59cb4e0 aliguori
        cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
1191 d4b55be5 aliguori
                    env->dr[6], env->dr[7]);
1192 eaa728ee bellard
    } else
1193 eaa728ee bellard
#endif
1194 eaa728ee bellard
    {
1195 eaa728ee bellard
        cpu_fprintf(f, "GDT=     %08x %08x\n",
1196 eaa728ee bellard
                    (uint32_t)env->gdt.base, env->gdt.limit);
1197 eaa728ee bellard
        cpu_fprintf(f, "IDT=     %08x %08x\n",
1198 eaa728ee bellard
                    (uint32_t)env->idt.base, env->idt.limit);
1199 eaa728ee bellard
        cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
1200 eaa728ee bellard
                    (uint32_t)env->cr[0],
1201 eaa728ee bellard
                    (uint32_t)env->cr[2],
1202 eaa728ee bellard
                    (uint32_t)env->cr[3],
1203 eaa728ee bellard
                    (uint32_t)env->cr[4]);
1204 a59cb4e0 aliguori
        for(i = 0; i < 4; i++)
1205 a59cb4e0 aliguori
            cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]);
1206 d4b55be5 aliguori
        cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]);
1207 eaa728ee bellard
    }
1208 eaa728ee bellard
    if (flags & X86_DUMP_CCOP) {
1209 eaa728ee bellard
        if ((unsigned)env->cc_op < CC_OP_NB)
1210 eaa728ee bellard
            snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
1211 eaa728ee bellard
        else
1212 eaa728ee bellard
            snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
1213 eaa728ee bellard
#ifdef TARGET_X86_64
1214 eaa728ee bellard
        if (env->hflags & HF_CS64_MASK) {
1215 eaa728ee bellard
            cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
1216 eaa728ee bellard
                        env->cc_src, env->cc_dst,
1217 eaa728ee bellard
                        cc_op_name);
1218 eaa728ee bellard
        } else
1219 eaa728ee bellard
#endif
1220 eaa728ee bellard
        {
1221 eaa728ee bellard
            cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
1222 eaa728ee bellard
                        (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
1223 eaa728ee bellard
                        cc_op_name);
1224 eaa728ee bellard
        }
1225 7e84c249 bellard
    }
1226 eaa728ee bellard
    if (flags & X86_DUMP_FPU) {
1227 eaa728ee bellard
        int fptag;
1228 eaa728ee bellard
        fptag = 0;
1229 eaa728ee bellard
        for(i = 0; i < 8; i++) {
1230 eaa728ee bellard
            fptag |= ((!env->fptags[i]) << i);
1231 eaa728ee bellard
        }
1232 eaa728ee bellard
        cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
1233 eaa728ee bellard
                    env->fpuc,
1234 eaa728ee bellard
                    (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
1235 eaa728ee bellard
                    env->fpstt,
1236 eaa728ee bellard
                    fptag,
1237 eaa728ee bellard
                    env->mxcsr);
1238 eaa728ee bellard
        for(i=0;i<8;i++) {
1239 eaa728ee bellard
#if defined(USE_X86LDOUBLE)
1240 eaa728ee bellard
            union {
1241 eaa728ee bellard
                long double d;
1242 eaa728ee bellard
                struct {
1243 eaa728ee bellard
                    uint64_t lower;
1244 eaa728ee bellard
                    uint16_t upper;
1245 eaa728ee bellard
                } l;
1246 eaa728ee bellard
            } tmp;
1247 eaa728ee bellard
            tmp.d = env->fpregs[i].d;
1248 eaa728ee bellard
            cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
1249 eaa728ee bellard
                        i, tmp.l.lower, tmp.l.upper);
1250 eaa728ee bellard
#else
1251 eaa728ee bellard
            cpu_fprintf(f, "FPR%d=%016" PRIx64,
1252 eaa728ee bellard
                        i, env->fpregs[i].mmx.q);
1253 eaa728ee bellard
#endif
1254 eaa728ee bellard
            if ((i & 1) == 1)
1255 eaa728ee bellard
                cpu_fprintf(f, "\n");
1256 eaa728ee bellard
            else
1257 eaa728ee bellard
                cpu_fprintf(f, " ");
1258 eaa728ee bellard
        }
1259 eaa728ee bellard
        if (env->hflags & HF_CS64_MASK)
1260 eaa728ee bellard
            nb = 16;
1261 eaa728ee bellard
        else
1262 eaa728ee bellard
            nb = 8;
1263 eaa728ee bellard
        for(i=0;i<nb;i++) {
1264 eaa728ee bellard
            cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
1265 eaa728ee bellard
                        i,
1266 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(3),
1267 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(2),
1268 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(1),
1269 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(0));
1270 eaa728ee bellard
            if ((i & 1) == 1)
1271 eaa728ee bellard
                cpu_fprintf(f, "\n");
1272 eaa728ee bellard
            else
1273 eaa728ee bellard
                cpu_fprintf(f, " ");
1274 eaa728ee bellard
        }
1275 7e84c249 bellard
    }
1276 2c0262af bellard
}
1277 7e84c249 bellard
1278 eaa728ee bellard
/***********************************************************/
1279 eaa728ee bellard
/* x86 mmu */
1280 eaa728ee bellard
/* XXX: add PGE support */
1281 eaa728ee bellard
1282 eaa728ee bellard
void cpu_x86_set_a20(CPUX86State *env, int a20_state)
1283 2c0262af bellard
{
1284 eaa728ee bellard
    a20_state = (a20_state != 0);
1285 eaa728ee bellard
    if (a20_state != ((env->a20_mask >> 20) & 1)) {
1286 eaa728ee bellard
#if defined(DEBUG_MMU)
1287 eaa728ee bellard
        printf("A20 update: a20=%d\n", a20_state);
1288 eaa728ee bellard
#endif
1289 eaa728ee bellard
        /* if the cpu is currently executing code, we must unlink it and
1290 eaa728ee bellard
           all the potentially executing TB */
1291 eaa728ee bellard
        cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
1292 3b46e624 ths
1293 eaa728ee bellard
        /* when a20 is changed, all the MMU mappings are invalid, so
1294 eaa728ee bellard
           we must flush everything */
1295 eaa728ee bellard
        tlb_flush(env, 1);
1296 5ee0ffaa Juan Quintela
        env->a20_mask = ~(1 << 20) | (a20_state << 20);
1297 7e84c249 bellard
    }
1298 2c0262af bellard
}
1299 2c0262af bellard
1300 eaa728ee bellard
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
1301 2c0262af bellard
{
1302 eaa728ee bellard
    int pe_state;
1303 2c0262af bellard
1304 eaa728ee bellard
#if defined(DEBUG_MMU)
1305 eaa728ee bellard
    printf("CR0 update: CR0=0x%08x\n", new_cr0);
1306 eaa728ee bellard
#endif
1307 eaa728ee bellard
    if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
1308 eaa728ee bellard
        (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
1309 eaa728ee bellard
        tlb_flush(env, 1);
1310 eaa728ee bellard
    }
1311 2c0262af bellard
1312 eaa728ee bellard
#ifdef TARGET_X86_64
1313 eaa728ee bellard
    if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
1314 eaa728ee bellard
        (env->efer & MSR_EFER_LME)) {
1315 eaa728ee bellard
        /* enter in long mode */
1316 eaa728ee bellard
        /* XXX: generate an exception */
1317 eaa728ee bellard
        if (!(env->cr[4] & CR4_PAE_MASK))
1318 eaa728ee bellard
            return;
1319 eaa728ee bellard
        env->efer |= MSR_EFER_LMA;
1320 eaa728ee bellard
        env->hflags |= HF_LMA_MASK;
1321 eaa728ee bellard
    } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
1322 eaa728ee bellard
               (env->efer & MSR_EFER_LMA)) {
1323 eaa728ee bellard
        /* exit long mode */
1324 eaa728ee bellard
        env->efer &= ~MSR_EFER_LMA;
1325 eaa728ee bellard
        env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
1326 eaa728ee bellard
        env->eip &= 0xffffffff;
1327 eaa728ee bellard
    }
1328 eaa728ee bellard
#endif
1329 eaa728ee bellard
    env->cr[0] = new_cr0 | CR0_ET_MASK;
1330 7e84c249 bellard
1331 eaa728ee bellard
    /* update PE flag in hidden flags */
1332 eaa728ee bellard
    pe_state = (env->cr[0] & CR0_PE_MASK);
1333 eaa728ee bellard
    env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
1334 eaa728ee bellard
    /* ensure that ADDSEG is always set in real mode */
1335 eaa728ee bellard
    env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
1336 eaa728ee bellard
    /* update FPU flags */
1337 eaa728ee bellard
    env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
1338 eaa728ee bellard
        ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
1339 7e84c249 bellard
}
1340 7e84c249 bellard
1341 eaa728ee bellard
/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
1342 eaa728ee bellard
   the PDPT */
1343 eaa728ee bellard
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
1344 7e84c249 bellard
{
1345 eaa728ee bellard
    env->cr[3] = new_cr3;
1346 eaa728ee bellard
    if (env->cr[0] & CR0_PG_MASK) {
1347 eaa728ee bellard
#if defined(DEBUG_MMU)
1348 eaa728ee bellard
        printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
1349 eaa728ee bellard
#endif
1350 eaa728ee bellard
        tlb_flush(env, 0);
1351 eaa728ee bellard
    }
1352 7e84c249 bellard
}
1353 7e84c249 bellard
1354 eaa728ee bellard
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
1355 7e84c249 bellard
{
1356 eaa728ee bellard
#if defined(DEBUG_MMU)
1357 eaa728ee bellard
    printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
1358 eaa728ee bellard
#endif
1359 eaa728ee bellard
    if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
1360 eaa728ee bellard
        (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
1361 eaa728ee bellard
        tlb_flush(env, 1);
1362 eaa728ee bellard
    }
1363 eaa728ee bellard
    /* SSE handling */
1364 eaa728ee bellard
    if (!(env->cpuid_features & CPUID_SSE))
1365 eaa728ee bellard
        new_cr4 &= ~CR4_OSFXSR_MASK;
1366 eaa728ee bellard
    if (new_cr4 & CR4_OSFXSR_MASK)
1367 eaa728ee bellard
        env->hflags |= HF_OSFXSR_MASK;
1368 eaa728ee bellard
    else
1369 eaa728ee bellard
        env->hflags &= ~HF_OSFXSR_MASK;
1370 b8b6a50b bellard
1371 eaa728ee bellard
    env->cr[4] = new_cr4;
1372 b8b6a50b bellard
}
1373 b8b6a50b bellard
1374 eaa728ee bellard
#if defined(CONFIG_USER_ONLY)
1375 eaa728ee bellard
1376 eaa728ee bellard
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
1377 eaa728ee bellard
                             int is_write, int mmu_idx, int is_softmmu)
1378 b8b6a50b bellard
{
1379 eaa728ee bellard
    /* user mode only emulation */
1380 eaa728ee bellard
    is_write &= 1;
1381 eaa728ee bellard
    env->cr[2] = addr;
1382 eaa728ee bellard
    env->error_code = (is_write << PG_ERROR_W_BIT);
1383 eaa728ee bellard
    env->error_code |= PG_ERROR_U_MASK;
1384 eaa728ee bellard
    env->exception_index = EXCP0E_PAGE;
1385 eaa728ee bellard
    return 1;
1386 2c0262af bellard
}
1387 2c0262af bellard
1388 c227f099 Anthony Liguori
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1389 891b38e4 bellard
{
1390 eaa728ee bellard
    return addr;
1391 891b38e4 bellard
}
1392 891b38e4 bellard
1393 8d7b0fbb bellard
#else
1394 891b38e4 bellard
1395 eaa728ee bellard
/* XXX: This value should match the one returned by CPUID
1396 eaa728ee bellard
 * and in exec.c */
1397 eaa728ee bellard
# if defined(TARGET_X86_64)
1398 2c90d794 ths
# define PHYS_ADDR_MASK 0xfffffff000LL
1399 eaa728ee bellard
# else
1400 2c90d794 ths
# define PHYS_ADDR_MASK 0xffffff000LL
1401 eaa728ee bellard
# endif
1402 eaa728ee bellard
1403 eaa728ee bellard
/* return value:
1404 eaa728ee bellard
   -1 = cannot handle fault
1405 eaa728ee bellard
   0  = nothing more to do
1406 eaa728ee bellard
   1  = generate PF fault
1407 eaa728ee bellard
   2  = soft MMU activation required for this block
1408 eaa728ee bellard
*/
1409 eaa728ee bellard
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
1410 eaa728ee bellard
                             int is_write1, int mmu_idx, int is_softmmu)
1411 eaa728ee bellard
{
1412 eaa728ee bellard
    uint64_t ptep, pte;
1413 eaa728ee bellard
    target_ulong pde_addr, pte_addr;
1414 eaa728ee bellard
    int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
1415 c227f099 Anthony Liguori
    target_phys_addr_t paddr;
1416 eaa728ee bellard
    uint32_t page_offset;
1417 eaa728ee bellard
    target_ulong vaddr, virt_addr;
1418 eaa728ee bellard
1419 eaa728ee bellard
    is_user = mmu_idx == MMU_USER_IDX;
1420 eaa728ee bellard
#if defined(DEBUG_MMU)
1421 eaa728ee bellard
    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
1422 eaa728ee bellard
           addr, is_write1, is_user, env->eip);
1423 eaa728ee bellard
#endif
1424 eaa728ee bellard
    is_write = is_write1 & 1;
1425 eaa728ee bellard
1426 eaa728ee bellard
    if (!(env->cr[0] & CR0_PG_MASK)) {
1427 eaa728ee bellard
        pte = addr;
1428 eaa728ee bellard
        virt_addr = addr & TARGET_PAGE_MASK;
1429 eaa728ee bellard
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1430 eaa728ee bellard
        page_size = 4096;
1431 eaa728ee bellard
        goto do_mapping;
1432 eaa728ee bellard
    }
1433 eaa728ee bellard
1434 eaa728ee bellard
    if (env->cr[4] & CR4_PAE_MASK) {
1435 eaa728ee bellard
        uint64_t pde, pdpe;
1436 eaa728ee bellard
        target_ulong pdpe_addr;
1437 2c0262af bellard
1438 eaa728ee bellard
#ifdef TARGET_X86_64
1439 eaa728ee bellard
        if (env->hflags & HF_LMA_MASK) {
1440 eaa728ee bellard
            uint64_t pml4e_addr, pml4e;
1441 eaa728ee bellard
            int32_t sext;
1442 eaa728ee bellard
1443 eaa728ee bellard
            /* test virtual address sign extension */
1444 eaa728ee bellard
            sext = (int64_t)addr >> 47;
1445 eaa728ee bellard
            if (sext != 0 && sext != -1) {
1446 eaa728ee bellard
                env->error_code = 0;
1447 eaa728ee bellard
                env->exception_index = EXCP0D_GPF;
1448 eaa728ee bellard
                return 1;
1449 eaa728ee bellard
            }
1450 0573fbfc ths
1451 eaa728ee bellard
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
1452 eaa728ee bellard
                env->a20_mask;
1453 eaa728ee bellard
            pml4e = ldq_phys(pml4e_addr);
1454 eaa728ee bellard
            if (!(pml4e & PG_PRESENT_MASK)) {
1455 eaa728ee bellard
                error_code = 0;
1456 eaa728ee bellard
                goto do_fault;
1457 eaa728ee bellard
            }
1458 eaa728ee bellard
            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
1459 eaa728ee bellard
                error_code = PG_ERROR_RSVD_MASK;
1460 eaa728ee bellard
                goto do_fault;
1461 eaa728ee bellard
            }
1462 eaa728ee bellard
            if (!(pml4e & PG_ACCESSED_MASK)) {
1463 eaa728ee bellard
                pml4e |= PG_ACCESSED_MASK;
1464 eaa728ee bellard
                stl_phys_notdirty(pml4e_addr, pml4e);
1465 eaa728ee bellard
            }
1466 eaa728ee bellard
            ptep = pml4e ^ PG_NX_MASK;
1467 eaa728ee bellard
            pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
1468 eaa728ee bellard
                env->a20_mask;
1469 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
1470 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK)) {
1471 eaa728ee bellard
                error_code = 0;
1472 eaa728ee bellard
                goto do_fault;
1473 eaa728ee bellard
            }
1474 eaa728ee bellard
            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
1475 eaa728ee bellard
                error_code = PG_ERROR_RSVD_MASK;
1476 eaa728ee bellard
                goto do_fault;
1477 eaa728ee bellard
            }
1478 eaa728ee bellard
            ptep &= pdpe ^ PG_NX_MASK;
1479 eaa728ee bellard
            if (!(pdpe & PG_ACCESSED_MASK)) {
1480 eaa728ee bellard
                pdpe |= PG_ACCESSED_MASK;
1481 eaa728ee bellard
                stl_phys_notdirty(pdpe_addr, pdpe);
1482 eaa728ee bellard
            }
1483 eaa728ee bellard
        } else
1484 eaa728ee bellard
#endif
1485 eaa728ee bellard
        {
1486 eaa728ee bellard
            /* XXX: load them when cr3 is loaded ? */
1487 eaa728ee bellard
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1488 eaa728ee bellard
                env->a20_mask;
1489 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
1490 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK)) {
1491 eaa728ee bellard
                error_code = 0;
1492 eaa728ee bellard
                goto do_fault;
1493 eaa728ee bellard
            }
1494 eaa728ee bellard
            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
1495 7e84c249 bellard
        }
1496 7e84c249 bellard
1497 eaa728ee bellard
        pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
1498 eaa728ee bellard
            env->a20_mask;
1499 eaa728ee bellard
        pde = ldq_phys(pde_addr);
1500 eaa728ee bellard
        if (!(pde & PG_PRESENT_MASK)) {
1501 eaa728ee bellard
            error_code = 0;
1502 eaa728ee bellard
            goto do_fault;
1503 eaa728ee bellard
        }
1504 eaa728ee bellard
        if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
1505 eaa728ee bellard
            error_code = PG_ERROR_RSVD_MASK;
1506 eaa728ee bellard
            goto do_fault;
1507 eaa728ee bellard
        }
1508 eaa728ee bellard
        ptep &= pde ^ PG_NX_MASK;
1509 eaa728ee bellard
        if (pde & PG_PSE_MASK) {
1510 eaa728ee bellard
            /* 2 MB page */
1511 eaa728ee bellard
            page_size = 2048 * 1024;
1512 eaa728ee bellard
            ptep ^= PG_NX_MASK;
1513 eaa728ee bellard
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
1514 eaa728ee bellard
                goto do_fault_protect;
1515 eaa728ee bellard
            if (is_user) {
1516 eaa728ee bellard
                if (!(ptep & PG_USER_MASK))
1517 eaa728ee bellard
                    goto do_fault_protect;
1518 eaa728ee bellard
                if (is_write && !(ptep & PG_RW_MASK))
1519 eaa728ee bellard
                    goto do_fault_protect;
1520 eaa728ee bellard
            } else {
1521 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
1522 eaa728ee bellard
                    is_write && !(ptep & PG_RW_MASK))
1523 eaa728ee bellard
                    goto do_fault_protect;
1524 eaa728ee bellard
            }
1525 eaa728ee bellard
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
1526 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
1527 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
1528 eaa728ee bellard
                if (is_dirty)
1529 eaa728ee bellard
                    pde |= PG_DIRTY_MASK;
1530 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
1531 eaa728ee bellard
            }
1532 eaa728ee bellard
            /* align to page_size */
1533 eaa728ee bellard
            pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
1534 eaa728ee bellard
            virt_addr = addr & ~(page_size - 1);
1535 eaa728ee bellard
        } else {
1536 eaa728ee bellard
            /* 4 KB page */
1537 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK)) {
1538 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
1539 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
1540 eaa728ee bellard
            }
1541 eaa728ee bellard
            pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
1542 eaa728ee bellard
                env->a20_mask;
1543 eaa728ee bellard
            pte = ldq_phys(pte_addr);
1544 eaa728ee bellard
            if (!(pte & PG_PRESENT_MASK)) {
1545 eaa728ee bellard
                error_code = 0;
1546 eaa728ee bellard
                goto do_fault;
1547 eaa728ee bellard
            }
1548 eaa728ee bellard
            if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
1549 eaa728ee bellard
                error_code = PG_ERROR_RSVD_MASK;
1550 eaa728ee bellard
                goto do_fault;
1551 eaa728ee bellard
            }
1552 eaa728ee bellard
            /* combine pde and pte nx, user and rw protections */
1553 eaa728ee bellard
            ptep &= pte ^ PG_NX_MASK;
1554 eaa728ee bellard
            ptep ^= PG_NX_MASK;
1555 eaa728ee bellard
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
1556 eaa728ee bellard
                goto do_fault_protect;
1557 eaa728ee bellard
            if (is_user) {
1558 eaa728ee bellard
                if (!(ptep & PG_USER_MASK))
1559 eaa728ee bellard
                    goto do_fault_protect;
1560 eaa728ee bellard
                if (is_write && !(ptep & PG_RW_MASK))
1561 eaa728ee bellard
                    goto do_fault_protect;
1562 eaa728ee bellard
            } else {
1563 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
1564 eaa728ee bellard
                    is_write && !(ptep & PG_RW_MASK))
1565 eaa728ee bellard
                    goto do_fault_protect;
1566 eaa728ee bellard
            }
1567 eaa728ee bellard
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1568 eaa728ee bellard
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1569 eaa728ee bellard
                pte |= PG_ACCESSED_MASK;
1570 eaa728ee bellard
                if (is_dirty)
1571 eaa728ee bellard
                    pte |= PG_DIRTY_MASK;
1572 eaa728ee bellard
                stl_phys_notdirty(pte_addr, pte);
1573 eaa728ee bellard
            }
1574 eaa728ee bellard
            page_size = 4096;
1575 eaa728ee bellard
            virt_addr = addr & ~0xfff;
1576 eaa728ee bellard
            pte = pte & (PHYS_ADDR_MASK | 0xfff);
1577 7e84c249 bellard
        }
1578 2c0262af bellard
    } else {
1579 eaa728ee bellard
        uint32_t pde;
1580 eaa728ee bellard
1581 eaa728ee bellard
        /* page directory entry */
1582 eaa728ee bellard
        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
1583 eaa728ee bellard
            env->a20_mask;
1584 eaa728ee bellard
        pde = ldl_phys(pde_addr);
1585 eaa728ee bellard
        if (!(pde & PG_PRESENT_MASK)) {
1586 eaa728ee bellard
            error_code = 0;
1587 eaa728ee bellard
            goto do_fault;
1588 eaa728ee bellard
        }
1589 eaa728ee bellard
        /* if PSE bit is set, then we use a 4MB page */
1590 eaa728ee bellard
        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1591 eaa728ee bellard
            page_size = 4096 * 1024;
1592 eaa728ee bellard
            if (is_user) {
1593 eaa728ee bellard
                if (!(pde & PG_USER_MASK))
1594 eaa728ee bellard
                    goto do_fault_protect;
1595 eaa728ee bellard
                if (is_write && !(pde & PG_RW_MASK))
1596 eaa728ee bellard
                    goto do_fault_protect;
1597 eaa728ee bellard
            } else {
1598 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
1599 eaa728ee bellard
                    is_write && !(pde & PG_RW_MASK))
1600 eaa728ee bellard
                    goto do_fault_protect;
1601 eaa728ee bellard
            }
1602 eaa728ee bellard
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
1603 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
1604 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
1605 eaa728ee bellard
                if (is_dirty)
1606 eaa728ee bellard
                    pde |= PG_DIRTY_MASK;
1607 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
1608 eaa728ee bellard
            }
1609 2c0262af bellard
1610 eaa728ee bellard
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1611 eaa728ee bellard
            ptep = pte;
1612 eaa728ee bellard
            virt_addr = addr & ~(page_size - 1);
1613 eaa728ee bellard
        } else {
1614 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK)) {
1615 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
1616 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
1617 eaa728ee bellard
            }
1618 891b38e4 bellard
1619 eaa728ee bellard
            /* page directory entry */
1620 eaa728ee bellard
            pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
1621 eaa728ee bellard
                env->a20_mask;
1622 eaa728ee bellard
            pte = ldl_phys(pte_addr);
1623 eaa728ee bellard
            if (!(pte & PG_PRESENT_MASK)) {
1624 eaa728ee bellard
                error_code = 0;
1625 eaa728ee bellard
                goto do_fault;
1626 8e682019 bellard
            }
1627 eaa728ee bellard
            /* combine pde and pte user and rw protections */
1628 eaa728ee bellard
            ptep = pte & pde;
1629 eaa728ee bellard
            if (is_user) {
1630 eaa728ee bellard
                if (!(ptep & PG_USER_MASK))
1631 eaa728ee bellard
                    goto do_fault_protect;
1632 eaa728ee bellard
                if (is_write && !(ptep & PG_RW_MASK))
1633 eaa728ee bellard
                    goto do_fault_protect;
1634 eaa728ee bellard
            } else {
1635 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
1636 eaa728ee bellard
                    is_write && !(ptep & PG_RW_MASK))
1637 eaa728ee bellard
                    goto do_fault_protect;
1638 8e682019 bellard
            }
1639 eaa728ee bellard
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1640 eaa728ee bellard
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1641 eaa728ee bellard
                pte |= PG_ACCESSED_MASK;
1642 eaa728ee bellard
                if (is_dirty)
1643 eaa728ee bellard
                    pte |= PG_DIRTY_MASK;
1644 eaa728ee bellard
                stl_phys_notdirty(pte_addr, pte);
1645 eaa728ee bellard
            }
1646 eaa728ee bellard
            page_size = 4096;
1647 eaa728ee bellard
            virt_addr = addr & ~0xfff;
1648 2c0262af bellard
        }
1649 2c0262af bellard
    }
1650 eaa728ee bellard
    /* the page can be put in the TLB */
1651 eaa728ee bellard
    prot = PAGE_READ;
1652 eaa728ee bellard
    if (!(ptep & PG_NX_MASK))
1653 eaa728ee bellard
        prot |= PAGE_EXEC;
1654 eaa728ee bellard
    if (pte & PG_DIRTY_MASK) {
1655 eaa728ee bellard
        /* only set write access if already dirty... otherwise wait
1656 eaa728ee bellard
           for dirty access */
1657 eaa728ee bellard
        if (is_user) {
1658 eaa728ee bellard
            if (ptep & PG_RW_MASK)
1659 eaa728ee bellard
                prot |= PAGE_WRITE;
1660 eaa728ee bellard
        } else {
1661 eaa728ee bellard
            if (!(env->cr[0] & CR0_WP_MASK) ||
1662 eaa728ee bellard
                (ptep & PG_RW_MASK))
1663 eaa728ee bellard
                prot |= PAGE_WRITE;
1664 8e682019 bellard
        }
1665 891b38e4 bellard
    }
1666 eaa728ee bellard
 do_mapping:
1667 eaa728ee bellard
    pte = pte & env->a20_mask;
1668 eaa728ee bellard
1669 eaa728ee bellard
    /* Even if 4MB pages, we map only one 4KB page in the cache to
1670 eaa728ee bellard
       avoid filling it too fast */
1671 eaa728ee bellard
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1672 eaa728ee bellard
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1673 eaa728ee bellard
    vaddr = virt_addr + page_offset;
1674 eaa728ee bellard
1675 eaa728ee bellard
    ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
1676 eaa728ee bellard
    return ret;
1677 eaa728ee bellard
 do_fault_protect:
1678 eaa728ee bellard
    error_code = PG_ERROR_P_MASK;
1679 eaa728ee bellard
 do_fault:
1680 eaa728ee bellard
    error_code |= (is_write << PG_ERROR_W_BIT);
1681 eaa728ee bellard
    if (is_user)
1682 eaa728ee bellard
        error_code |= PG_ERROR_U_MASK;
1683 eaa728ee bellard
    if (is_write1 == 2 &&
1684 eaa728ee bellard
        (env->efer & MSR_EFER_NXE) &&
1685 eaa728ee bellard
        (env->cr[4] & CR4_PAE_MASK))
1686 eaa728ee bellard
        error_code |= PG_ERROR_I_D_MASK;
1687 872929aa bellard
    if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
1688 872929aa bellard
        /* cr2 is not modified in case of exceptions */
1689 872929aa bellard
        stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 
1690 872929aa bellard
                 addr);
1691 eaa728ee bellard
    } else {
1692 eaa728ee bellard
        env->cr[2] = addr;
1693 2c0262af bellard
    }
1694 eaa728ee bellard
    env->error_code = error_code;
1695 eaa728ee bellard
    env->exception_index = EXCP0E_PAGE;
1696 eaa728ee bellard
    return 1;
1697 14ce26e7 bellard
}
1698 14ce26e7 bellard
1699 c227f099 Anthony Liguori
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1700 14ce26e7 bellard
{
1701 eaa728ee bellard
    target_ulong pde_addr, pte_addr;
1702 eaa728ee bellard
    uint64_t pte;
1703 c227f099 Anthony Liguori
    target_phys_addr_t paddr;
1704 eaa728ee bellard
    uint32_t page_offset;
1705 eaa728ee bellard
    int page_size;
1706 14ce26e7 bellard
1707 eaa728ee bellard
    if (env->cr[4] & CR4_PAE_MASK) {
1708 eaa728ee bellard
        target_ulong pdpe_addr;
1709 eaa728ee bellard
        uint64_t pde, pdpe;
1710 14ce26e7 bellard
1711 eaa728ee bellard
#ifdef TARGET_X86_64
1712 eaa728ee bellard
        if (env->hflags & HF_LMA_MASK) {
1713 eaa728ee bellard
            uint64_t pml4e_addr, pml4e;
1714 eaa728ee bellard
            int32_t sext;
1715 eaa728ee bellard
1716 eaa728ee bellard
            /* test virtual address sign extension */
1717 eaa728ee bellard
            sext = (int64_t)addr >> 47;
1718 eaa728ee bellard
            if (sext != 0 && sext != -1)
1719 eaa728ee bellard
                return -1;
1720 eaa728ee bellard
1721 eaa728ee bellard
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
1722 eaa728ee bellard
                env->a20_mask;
1723 eaa728ee bellard
            pml4e = ldq_phys(pml4e_addr);
1724 eaa728ee bellard
            if (!(pml4e & PG_PRESENT_MASK))
1725 eaa728ee bellard
                return -1;
1726 eaa728ee bellard
1727 eaa728ee bellard
            pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
1728 eaa728ee bellard
                env->a20_mask;
1729 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
1730 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK))
1731 eaa728ee bellard
                return -1;
1732 eaa728ee bellard
        } else
1733 eaa728ee bellard
#endif
1734 eaa728ee bellard
        {
1735 eaa728ee bellard
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1736 eaa728ee bellard
                env->a20_mask;
1737 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
1738 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK))
1739 eaa728ee bellard
                return -1;
1740 14ce26e7 bellard
        }
1741 14ce26e7 bellard
1742 eaa728ee bellard
        pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
1743 eaa728ee bellard
            env->a20_mask;
1744 eaa728ee bellard
        pde = ldq_phys(pde_addr);
1745 eaa728ee bellard
        if (!(pde & PG_PRESENT_MASK)) {
1746 eaa728ee bellard
            return -1;
1747 eaa728ee bellard
        }
1748 eaa728ee bellard
        if (pde & PG_PSE_MASK) {
1749 eaa728ee bellard
            /* 2 MB page */
1750 eaa728ee bellard
            page_size = 2048 * 1024;
1751 eaa728ee bellard
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1752 eaa728ee bellard
        } else {
1753 eaa728ee bellard
            /* 4 KB page */
1754 eaa728ee bellard
            pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
1755 eaa728ee bellard
                env->a20_mask;
1756 eaa728ee bellard
            page_size = 4096;
1757 eaa728ee bellard
            pte = ldq_phys(pte_addr);
1758 eaa728ee bellard
        }
1759 ca1c9e15 aliguori
        if (!(pte & PG_PRESENT_MASK))
1760 ca1c9e15 aliguori
            return -1;
1761 14ce26e7 bellard
    } else {
1762 eaa728ee bellard
        uint32_t pde;
1763 3b46e624 ths
1764 eaa728ee bellard
        if (!(env->cr[0] & CR0_PG_MASK)) {
1765 eaa728ee bellard
            pte = addr;
1766 eaa728ee bellard
            page_size = 4096;
1767 eaa728ee bellard
        } else {
1768 eaa728ee bellard
            /* page directory entry */
1769 eaa728ee bellard
            pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
1770 eaa728ee bellard
            pde = ldl_phys(pde_addr);
1771 eaa728ee bellard
            if (!(pde & PG_PRESENT_MASK))
1772 eaa728ee bellard
                return -1;
1773 eaa728ee bellard
            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1774 eaa728ee bellard
                pte = pde & ~0x003ff000; /* align to 4MB */
1775 eaa728ee bellard
                page_size = 4096 * 1024;
1776 eaa728ee bellard
            } else {
1777 eaa728ee bellard
                /* page directory entry */
1778 eaa728ee bellard
                pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
1779 eaa728ee bellard
                pte = ldl_phys(pte_addr);
1780 eaa728ee bellard
                if (!(pte & PG_PRESENT_MASK))
1781 eaa728ee bellard
                    return -1;
1782 eaa728ee bellard
                page_size = 4096;
1783 eaa728ee bellard
            }
1784 eaa728ee bellard
        }
1785 eaa728ee bellard
        pte = pte & env->a20_mask;
1786 14ce26e7 bellard
    }
1787 14ce26e7 bellard
1788 eaa728ee bellard
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1789 eaa728ee bellard
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1790 eaa728ee bellard
    return paddr;
1791 3b21e03e bellard
}
1792 01df040b aliguori
1793 01df040b aliguori
void hw_breakpoint_insert(CPUState *env, int index)
1794 01df040b aliguori
{
1795 01df040b aliguori
    int type, err = 0;
1796 01df040b aliguori
1797 01df040b aliguori
    switch (hw_breakpoint_type(env->dr[7], index)) {
1798 01df040b aliguori
    case 0:
1799 01df040b aliguori
        if (hw_breakpoint_enabled(env->dr[7], index))
1800 01df040b aliguori
            err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
1801 01df040b aliguori
                                        &env->cpu_breakpoint[index]);
1802 01df040b aliguori
        break;
1803 01df040b aliguori
    case 1:
1804 01df040b aliguori
        type = BP_CPU | BP_MEM_WRITE;
1805 01df040b aliguori
        goto insert_wp;
1806 01df040b aliguori
    case 2:
1807 01df040b aliguori
         /* No support for I/O watchpoints yet */
1808 01df040b aliguori
        break;
1809 01df040b aliguori
    case 3:
1810 01df040b aliguori
        type = BP_CPU | BP_MEM_ACCESS;
1811 01df040b aliguori
    insert_wp:
1812 01df040b aliguori
        err = cpu_watchpoint_insert(env, env->dr[index],
1813 01df040b aliguori
                                    hw_breakpoint_len(env->dr[7], index),
1814 01df040b aliguori
                                    type, &env->cpu_watchpoint[index]);
1815 01df040b aliguori
        break;
1816 01df040b aliguori
    }
1817 01df040b aliguori
    if (err)
1818 01df040b aliguori
        env->cpu_breakpoint[index] = NULL;
1819 01df040b aliguori
}
1820 01df040b aliguori
1821 01df040b aliguori
void hw_breakpoint_remove(CPUState *env, int index)
1822 01df040b aliguori
{
1823 01df040b aliguori
    if (!env->cpu_breakpoint[index])
1824 01df040b aliguori
        return;
1825 01df040b aliguori
    switch (hw_breakpoint_type(env->dr[7], index)) {
1826 01df040b aliguori
    case 0:
1827 01df040b aliguori
        if (hw_breakpoint_enabled(env->dr[7], index))
1828 01df040b aliguori
            cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
1829 01df040b aliguori
        break;
1830 01df040b aliguori
    case 1:
1831 01df040b aliguori
    case 3:
1832 01df040b aliguori
        cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
1833 01df040b aliguori
        break;
1834 01df040b aliguori
    case 2:
1835 01df040b aliguori
        /* No support for I/O watchpoints yet */
1836 01df040b aliguori
        break;
1837 01df040b aliguori
    }
1838 01df040b aliguori
}
1839 01df040b aliguori
1840 01df040b aliguori
int check_hw_breakpoints(CPUState *env, int force_dr6_update)
1841 01df040b aliguori
{
1842 01df040b aliguori
    target_ulong dr6;
1843 01df040b aliguori
    int reg, type;
1844 01df040b aliguori
    int hit_enabled = 0;
1845 01df040b aliguori
1846 01df040b aliguori
    dr6 = env->dr[6] & ~0xf;
1847 01df040b aliguori
    for (reg = 0; reg < 4; reg++) {
1848 01df040b aliguori
        type = hw_breakpoint_type(env->dr[7], reg);
1849 01df040b aliguori
        if ((type == 0 && env->dr[reg] == env->eip) ||
1850 01df040b aliguori
            ((type & 1) && env->cpu_watchpoint[reg] &&
1851 01df040b aliguori
             (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
1852 01df040b aliguori
            dr6 |= 1 << reg;
1853 01df040b aliguori
            if (hw_breakpoint_enabled(env->dr[7], reg))
1854 01df040b aliguori
                hit_enabled = 1;
1855 01df040b aliguori
        }
1856 01df040b aliguori
    }
1857 01df040b aliguori
    if (hit_enabled || force_dr6_update)
1858 01df040b aliguori
        env->dr[6] = dr6;
1859 01df040b aliguori
    return hit_enabled;
1860 01df040b aliguori
}
1861 01df040b aliguori
1862 01df040b aliguori
static CPUDebugExcpHandler *prev_debug_excp_handler;
1863 01df040b aliguori
1864 01df040b aliguori
void raise_exception(int exception_index);
1865 01df040b aliguori
1866 01df040b aliguori
static void breakpoint_handler(CPUState *env)
1867 01df040b aliguori
{
1868 01df040b aliguori
    CPUBreakpoint *bp;
1869 01df040b aliguori
1870 01df040b aliguori
    if (env->watchpoint_hit) {
1871 01df040b aliguori
        if (env->watchpoint_hit->flags & BP_CPU) {
1872 01df040b aliguori
            env->watchpoint_hit = NULL;
1873 01df040b aliguori
            if (check_hw_breakpoints(env, 0))
1874 01df040b aliguori
                raise_exception(EXCP01_DB);
1875 01df040b aliguori
            else
1876 01df040b aliguori
                cpu_resume_from_signal(env, NULL);
1877 01df040b aliguori
        }
1878 01df040b aliguori
    } else {
1879 72cf2d4f Blue Swirl
        QTAILQ_FOREACH(bp, &env->breakpoints, entry)
1880 01df040b aliguori
            if (bp->pc == env->eip) {
1881 01df040b aliguori
                if (bp->flags & BP_CPU) {
1882 01df040b aliguori
                    check_hw_breakpoints(env, 1);
1883 01df040b aliguori
                    raise_exception(EXCP01_DB);
1884 01df040b aliguori
                }
1885 01df040b aliguori
                break;
1886 01df040b aliguori
            }
1887 01df040b aliguori
    }
1888 01df040b aliguori
    if (prev_debug_excp_handler)
1889 01df040b aliguori
        prev_debug_excp_handler(env);
1890 01df040b aliguori
}
1891 79c4f6b0 Huang Ying
1892 79c4f6b0 Huang Ying
/* This should come from sysemu.h - if we could include it here... */
1893 79c4f6b0 Huang Ying
void qemu_system_reset_request(void);
1894 79c4f6b0 Huang Ying
1895 79c4f6b0 Huang Ying
void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
1896 79c4f6b0 Huang Ying
                        uint64_t mcg_status, uint64_t addr, uint64_t misc)
1897 79c4f6b0 Huang Ying
{
1898 79c4f6b0 Huang Ying
    uint64_t mcg_cap = cenv->mcg_cap;
1899 79c4f6b0 Huang Ying
    unsigned bank_num = mcg_cap & 0xff;
1900 79c4f6b0 Huang Ying
    uint64_t *banks = cenv->mce_banks;
1901 79c4f6b0 Huang Ying
1902 79c4f6b0 Huang Ying
    if (bank >= bank_num || !(status & MCI_STATUS_VAL))
1903 79c4f6b0 Huang Ying
        return;
1904 79c4f6b0 Huang Ying
1905 79c4f6b0 Huang Ying
    /*
1906 79c4f6b0 Huang Ying
     * if MSR_MCG_CTL is not all 1s, the uncorrected error
1907 79c4f6b0 Huang Ying
     * reporting is disabled
1908 79c4f6b0 Huang Ying
     */
1909 79c4f6b0 Huang Ying
    if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
1910 79c4f6b0 Huang Ying
        cenv->mcg_ctl != ~(uint64_t)0)
1911 79c4f6b0 Huang Ying
        return;
1912 79c4f6b0 Huang Ying
    banks += 4 * bank;
1913 79c4f6b0 Huang Ying
    /*
1914 79c4f6b0 Huang Ying
     * if MSR_MCi_CTL is not all 1s, the uncorrected error
1915 79c4f6b0 Huang Ying
     * reporting is disabled for the bank
1916 79c4f6b0 Huang Ying
     */
1917 79c4f6b0 Huang Ying
    if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0)
1918 79c4f6b0 Huang Ying
        return;
1919 79c4f6b0 Huang Ying
    if (status & MCI_STATUS_UC) {
1920 79c4f6b0 Huang Ying
        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1921 79c4f6b0 Huang Ying
            !(cenv->cr[4] & CR4_MCE_MASK)) {
1922 79c4f6b0 Huang Ying
            fprintf(stderr, "injects mce exception while previous "
1923 79c4f6b0 Huang Ying
                    "one is in progress!\n");
1924 79c4f6b0 Huang Ying
            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1925 79c4f6b0 Huang Ying
            qemu_system_reset_request();
1926 79c4f6b0 Huang Ying
            return;
1927 79c4f6b0 Huang Ying
        }
1928 79c4f6b0 Huang Ying
        if (banks[1] & MCI_STATUS_VAL)
1929 79c4f6b0 Huang Ying
            status |= MCI_STATUS_OVER;
1930 79c4f6b0 Huang Ying
        banks[2] = addr;
1931 79c4f6b0 Huang Ying
        banks[3] = misc;
1932 79c4f6b0 Huang Ying
        cenv->mcg_status = mcg_status;
1933 79c4f6b0 Huang Ying
        banks[1] = status;
1934 79c4f6b0 Huang Ying
        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
1935 79c4f6b0 Huang Ying
    } else if (!(banks[1] & MCI_STATUS_VAL)
1936 79c4f6b0 Huang Ying
               || !(banks[1] & MCI_STATUS_UC)) {
1937 79c4f6b0 Huang Ying
        if (banks[1] & MCI_STATUS_VAL)
1938 79c4f6b0 Huang Ying
            status |= MCI_STATUS_OVER;
1939 79c4f6b0 Huang Ying
        banks[2] = addr;
1940 79c4f6b0 Huang Ying
        banks[3] = misc;
1941 79c4f6b0 Huang Ying
        banks[1] = status;
1942 79c4f6b0 Huang Ying
    } else
1943 79c4f6b0 Huang Ying
        banks[1] |= MCI_STATUS_OVER;
1944 79c4f6b0 Huang Ying
}
1945 74ce674f bellard
#endif /* !CONFIG_USER_ONLY */
1946 6fd805e1 aliguori
1947 79c4f6b0 Huang Ying
static void mce_init(CPUX86State *cenv)
1948 79c4f6b0 Huang Ying
{
1949 79c4f6b0 Huang Ying
    unsigned int bank, bank_num;
1950 79c4f6b0 Huang Ying
1951 79c4f6b0 Huang Ying
    if (((cenv->cpuid_version >> 8)&0xf) >= 6
1952 79c4f6b0 Huang Ying
        && (cenv->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)) {
1953 79c4f6b0 Huang Ying
        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1954 79c4f6b0 Huang Ying
        cenv->mcg_ctl = ~(uint64_t)0;
1955 ac74d0f1 Juan Quintela
        bank_num = MCE_BANKS_DEF;
1956 79c4f6b0 Huang Ying
        for (bank = 0; bank < bank_num; bank++)
1957 79c4f6b0 Huang Ying
            cenv->mce_banks[bank*4] = ~(uint64_t)0;
1958 79c4f6b0 Huang Ying
    }
1959 79c4f6b0 Huang Ying
}
1960 79c4f6b0 Huang Ying
1961 e00b6f80 aliguori
static void host_cpuid(uint32_t function, uint32_t count,
1962 e00b6f80 aliguori
                       uint32_t *eax, uint32_t *ebx,
1963 7ba1e619 aliguori
                       uint32_t *ecx, uint32_t *edx)
1964 7ba1e619 aliguori
{
1965 10781c09 aliguori
#if defined(CONFIG_KVM)
1966 7ba1e619 aliguori
    uint32_t vec[4];
1967 7ba1e619 aliguori
1968 7ba1e619 aliguori
#ifdef __x86_64__
1969 7ba1e619 aliguori
    asm volatile("cpuid"
1970 e00b6f80 aliguori
                 : "=a"(vec[0]), "=b"(vec[1]),
1971 e00b6f80 aliguori
                   "=c"(vec[2]), "=d"(vec[3])
1972 e00b6f80 aliguori
                 : "0"(function), "c"(count) : "cc");
1973 7ba1e619 aliguori
#else
1974 7ba1e619 aliguori
    asm volatile("pusha \n\t"
1975 e00b6f80 aliguori
                 "cpuid \n\t"
1976 b36d24b6 aliguori
                 "mov %%eax, 0(%2) \n\t"
1977 b36d24b6 aliguori
                 "mov %%ebx, 4(%2) \n\t"
1978 b36d24b6 aliguori
                 "mov %%ecx, 8(%2) \n\t"
1979 b36d24b6 aliguori
                 "mov %%edx, 12(%2) \n\t"
1980 e00b6f80 aliguori
                 "popa"
1981 e00b6f80 aliguori
                 : : "a"(function), "c"(count), "S"(vec)
1982 e00b6f80 aliguori
                 : "memory", "cc");
1983 7ba1e619 aliguori
#endif
1984 7ba1e619 aliguori
1985 7ba1e619 aliguori
    if (eax)
1986 7ba1e619 aliguori
        *eax = vec[0];
1987 7ba1e619 aliguori
    if (ebx)
1988 7ba1e619 aliguori
        *ebx = vec[1];
1989 7ba1e619 aliguori
    if (ecx)
1990 7ba1e619 aliguori
        *ecx = vec[2];
1991 7ba1e619 aliguori
    if (edx)
1992 7ba1e619 aliguori
        *edx = vec[3];
1993 7ba1e619 aliguori
#endif
1994 10781c09 aliguori
}
1995 7ba1e619 aliguori
1996 6d9fef1a Andre Przywara
static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
1997 6d9fef1a Andre Przywara
                             uint32_t *ecx, uint32_t *edx)
1998 6d9fef1a Andre Przywara
{
1999 6d9fef1a Andre Przywara
    *ebx = env->cpuid_vendor1;
2000 6d9fef1a Andre Przywara
    *edx = env->cpuid_vendor2;
2001 6d9fef1a Andre Przywara
    *ecx = env->cpuid_vendor3;
2002 6d9fef1a Andre Przywara
2003 6d9fef1a Andre Przywara
    /* sysenter isn't supported on compatibility mode on AMD, syscall
2004 6d9fef1a Andre Przywara
     * isn't supported in compatibility mode on Intel.
2005 6d9fef1a Andre Przywara
     * Normally we advertise the actual cpu vendor, but you can override
2006 6d9fef1a Andre Przywara
     * this if you want to use KVM's sysenter/syscall emulation
2007 6d9fef1a Andre Przywara
     * in compatibility mode and when doing cross vendor migration
2008 6d9fef1a Andre Przywara
     */
2009 6d9fef1a Andre Przywara
    if (kvm_enabled() && env->cpuid_vendor_override) {
2010 6d9fef1a Andre Przywara
        host_cpuid(0, 0, NULL, ebx, ecx, edx);
2011 6d9fef1a Andre Przywara
    }
2012 6d9fef1a Andre Przywara
}
2013 6d9fef1a Andre Przywara
2014 e00b6f80 aliguori
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
2015 6fd805e1 aliguori
                   uint32_t *eax, uint32_t *ebx,
2016 6fd805e1 aliguori
                   uint32_t *ecx, uint32_t *edx)
2017 6fd805e1 aliguori
{
2018 6fd805e1 aliguori
    /* test if maximum index reached */
2019 6fd805e1 aliguori
    if (index & 0x80000000) {
2020 6fd805e1 aliguori
        if (index > env->cpuid_xlevel)
2021 6fd805e1 aliguori
            index = env->cpuid_level;
2022 6fd805e1 aliguori
    } else {
2023 6fd805e1 aliguori
        if (index > env->cpuid_level)
2024 6fd805e1 aliguori
            index = env->cpuid_level;
2025 6fd805e1 aliguori
    }
2026 6fd805e1 aliguori
2027 6fd805e1 aliguori
    switch(index) {
2028 6fd805e1 aliguori
    case 0:
2029 6fd805e1 aliguori
        *eax = env->cpuid_level;
2030 6d9fef1a Andre Przywara
        get_cpuid_vendor(env, ebx, ecx, edx);
2031 6fd805e1 aliguori
        break;
2032 6fd805e1 aliguori
    case 1:
2033 6fd805e1 aliguori
        *eax = env->cpuid_version;
2034 6fd805e1 aliguori
        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
2035 6fd805e1 aliguori
        *ecx = env->cpuid_ext_features;
2036 6fd805e1 aliguori
        *edx = env->cpuid_features;
2037 400281af Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
2038 400281af Andre Przywara
            *ebx |= (env->nr_cores * env->nr_threads) << 16;
2039 400281af Andre Przywara
            *edx |= 1 << 28;    /* HTT bit */
2040 400281af Andre Przywara
        }
2041 6fd805e1 aliguori
        break;
2042 6fd805e1 aliguori
    case 2:
2043 6fd805e1 aliguori
        /* cache info: needed for Pentium Pro compatibility */
2044 6fd805e1 aliguori
        *eax = 1;
2045 6fd805e1 aliguori
        *ebx = 0;
2046 6fd805e1 aliguori
        *ecx = 0;
2047 6fd805e1 aliguori
        *edx = 0x2c307d;
2048 6fd805e1 aliguori
        break;
2049 6fd805e1 aliguori
    case 4:
2050 6fd805e1 aliguori
        /* cache info: needed for Core compatibility */
2051 400281af Andre Przywara
        if (env->nr_cores > 1) {
2052 400281af Andre Przywara
                *eax = (env->nr_cores - 1) << 26;
2053 400281af Andre Przywara
        } else {
2054 400281af Andre Przywara
                *eax = 0;
2055 400281af Andre Przywara
        }
2056 e00b6f80 aliguori
        switch (count) {
2057 6fd805e1 aliguori
            case 0: /* L1 dcache info */
2058 400281af Andre Przywara
                *eax |= 0x0000121;
2059 6fd805e1 aliguori
                *ebx = 0x1c0003f;
2060 6fd805e1 aliguori
                *ecx = 0x000003f;
2061 6fd805e1 aliguori
                *edx = 0x0000001;
2062 6fd805e1 aliguori
                break;
2063 6fd805e1 aliguori
            case 1: /* L1 icache info */
2064 400281af Andre Przywara
                *eax |= 0x0000122;
2065 6fd805e1 aliguori
                *ebx = 0x1c0003f;
2066 6fd805e1 aliguori
                *ecx = 0x000003f;
2067 6fd805e1 aliguori
                *edx = 0x0000001;
2068 6fd805e1 aliguori
                break;
2069 6fd805e1 aliguori
            case 2: /* L2 cache info */
2070 400281af Andre Przywara
                *eax |= 0x0000143;
2071 400281af Andre Przywara
                if (env->nr_threads > 1) {
2072 400281af Andre Przywara
                    *eax |= (env->nr_threads - 1) << 14;
2073 400281af Andre Przywara
                }
2074 6fd805e1 aliguori
                *ebx = 0x3c0003f;
2075 6fd805e1 aliguori
                *ecx = 0x0000fff;
2076 6fd805e1 aliguori
                *edx = 0x0000001;
2077 6fd805e1 aliguori
                break;
2078 6fd805e1 aliguori
            default: /* end of info */
2079 6fd805e1 aliguori
                *eax = 0;
2080 6fd805e1 aliguori
                *ebx = 0;
2081 6fd805e1 aliguori
                *ecx = 0;
2082 6fd805e1 aliguori
                *edx = 0;
2083 6fd805e1 aliguori
                break;
2084 6fd805e1 aliguori
        }
2085 6fd805e1 aliguori
        break;
2086 6fd805e1 aliguori
    case 5:
2087 6fd805e1 aliguori
        /* mwait info: needed for Core compatibility */
2088 6fd805e1 aliguori
        *eax = 0; /* Smallest monitor-line size in bytes */
2089 6fd805e1 aliguori
        *ebx = 0; /* Largest monitor-line size in bytes */
2090 6fd805e1 aliguori
        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
2091 6fd805e1 aliguori
        *edx = 0;
2092 6fd805e1 aliguori
        break;
2093 6fd805e1 aliguori
    case 6:
2094 6fd805e1 aliguori
        /* Thermal and Power Leaf */
2095 6fd805e1 aliguori
        *eax = 0;
2096 6fd805e1 aliguori
        *ebx = 0;
2097 6fd805e1 aliguori
        *ecx = 0;
2098 6fd805e1 aliguori
        *edx = 0;
2099 6fd805e1 aliguori
        break;
2100 6fd805e1 aliguori
    case 9:
2101 6fd805e1 aliguori
        /* Direct Cache Access Information Leaf */
2102 6fd805e1 aliguori
        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
2103 6fd805e1 aliguori
        *ebx = 0;
2104 6fd805e1 aliguori
        *ecx = 0;
2105 6fd805e1 aliguori
        *edx = 0;
2106 6fd805e1 aliguori
        break;
2107 6fd805e1 aliguori
    case 0xA:
2108 6fd805e1 aliguori
        /* Architectural Performance Monitoring Leaf */
2109 6fd805e1 aliguori
        *eax = 0;
2110 6fd805e1 aliguori
        *ebx = 0;
2111 6fd805e1 aliguori
        *ecx = 0;
2112 6fd805e1 aliguori
        *edx = 0;
2113 6fd805e1 aliguori
        break;
2114 6fd805e1 aliguori
    case 0x80000000:
2115 6fd805e1 aliguori
        *eax = env->cpuid_xlevel;
2116 6fd805e1 aliguori
        *ebx = env->cpuid_vendor1;
2117 6fd805e1 aliguori
        *edx = env->cpuid_vendor2;
2118 6fd805e1 aliguori
        *ecx = env->cpuid_vendor3;
2119 6fd805e1 aliguori
        break;
2120 6fd805e1 aliguori
    case 0x80000001:
2121 f441bee8 Andre Przywara
        *eax = env->cpuid_version;
2122 6fd805e1 aliguori
        *ebx = 0;
2123 6fd805e1 aliguori
        *ecx = env->cpuid_ext3_features;
2124 6fd805e1 aliguori
        *edx = env->cpuid_ext2_features;
2125 7ba1e619 aliguori
2126 6d9fef1a Andre Przywara
        /* The Linux kernel checks for the CMPLegacy bit and
2127 6d9fef1a Andre Przywara
         * discards multiple thread information if it is set.
2128 6d9fef1a Andre Przywara
         * So dont set it here for Intel to make Linux guests happy.
2129 6d9fef1a Andre Przywara
         */
2130 6d9fef1a Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
2131 6d9fef1a Andre Przywara
            uint32_t tebx, tecx, tedx;
2132 6d9fef1a Andre Przywara
            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
2133 6d9fef1a Andre Przywara
            if (tebx != CPUID_VENDOR_INTEL_1 ||
2134 6d9fef1a Andre Przywara
                tedx != CPUID_VENDOR_INTEL_2 ||
2135 6d9fef1a Andre Przywara
                tecx != CPUID_VENDOR_INTEL_3) {
2136 6d9fef1a Andre Przywara
                *ecx |= 1 << 1;    /* CmpLegacy bit */
2137 6d9fef1a Andre Przywara
            }
2138 400281af Andre Przywara
        }
2139 400281af Andre Przywara
2140 7ba1e619 aliguori
        if (kvm_enabled()) {
2141 f1e00a9c Andre Przywara
            /* Nested SVM not yet supported in upstream QEMU */
2142 671e4676 Andre Przywara
            *ecx &= ~CPUID_EXT3_SVM;
2143 7ba1e619 aliguori
        }
2144 6fd805e1 aliguori
        break;
2145 6fd805e1 aliguori
    case 0x80000002:
2146 6fd805e1 aliguori
    case 0x80000003:
2147 6fd805e1 aliguori
    case 0x80000004:
2148 6fd805e1 aliguori
        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
2149 6fd805e1 aliguori
        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
2150 6fd805e1 aliguori
        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
2151 6fd805e1 aliguori
        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
2152 6fd805e1 aliguori
        break;
2153 6fd805e1 aliguori
    case 0x80000005:
2154 6fd805e1 aliguori
        /* cache info (L1 cache) */
2155 6fd805e1 aliguori
        *eax = 0x01ff01ff;
2156 6fd805e1 aliguori
        *ebx = 0x01ff01ff;
2157 6fd805e1 aliguori
        *ecx = 0x40020140;
2158 6fd805e1 aliguori
        *edx = 0x40020140;
2159 6fd805e1 aliguori
        break;
2160 6fd805e1 aliguori
    case 0x80000006:
2161 6fd805e1 aliguori
        /* cache info (L2 cache) */
2162 6fd805e1 aliguori
        *eax = 0;
2163 6fd805e1 aliguori
        *ebx = 0x42004200;
2164 6fd805e1 aliguori
        *ecx = 0x02008140;
2165 6fd805e1 aliguori
        *edx = 0;
2166 6fd805e1 aliguori
        break;
2167 6fd805e1 aliguori
    case 0x80000008:
2168 6fd805e1 aliguori
        /* virtual & phys address size in low 2 bytes. */
2169 6fd805e1 aliguori
/* XXX: This value must match the one used in the MMU code. */ 
2170 6fd805e1 aliguori
        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
2171 6fd805e1 aliguori
            /* 64 bit processor */
2172 6fd805e1 aliguori
/* XXX: The physical address space is limited to 42 bits in exec.c. */
2173 6fd805e1 aliguori
            *eax = 0x00003028;        /* 48 bits virtual, 40 bits physical */
2174 6fd805e1 aliguori
        } else {
2175 6fd805e1 aliguori
            if (env->cpuid_features & CPUID_PSE36)
2176 6fd805e1 aliguori
                *eax = 0x00000024; /* 36 bits physical */
2177 6fd805e1 aliguori
            else
2178 6fd805e1 aliguori
                *eax = 0x00000020; /* 32 bits physical */
2179 6fd805e1 aliguori
        }
2180 6fd805e1 aliguori
        *ebx = 0;
2181 6fd805e1 aliguori
        *ecx = 0;
2182 6fd805e1 aliguori
        *edx = 0;
2183 400281af Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
2184 400281af Andre Przywara
            *ecx |= (env->nr_cores * env->nr_threads) - 1;
2185 400281af Andre Przywara
        }
2186 6fd805e1 aliguori
        break;
2187 6fd805e1 aliguori
    case 0x8000000A:
2188 6fd805e1 aliguori
        *eax = 0x00000001; /* SVM Revision */
2189 6fd805e1 aliguori
        *ebx = 0x00000010; /* nr of ASIDs */
2190 6fd805e1 aliguori
        *ecx = 0;
2191 6fd805e1 aliguori
        *edx = 0; /* optional features */
2192 6fd805e1 aliguori
        break;
2193 6fd805e1 aliguori
    default:
2194 6fd805e1 aliguori
        /* reserved values: zero */
2195 6fd805e1 aliguori
        *eax = 0;
2196 6fd805e1 aliguori
        *ebx = 0;
2197 6fd805e1 aliguori
        *ecx = 0;
2198 6fd805e1 aliguori
        *edx = 0;
2199 6fd805e1 aliguori
        break;
2200 6fd805e1 aliguori
    }
2201 6fd805e1 aliguori
}
2202 01df040b aliguori
2203 84273177 Jan Kiszka
2204 84273177 Jan Kiszka
int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
2205 84273177 Jan Kiszka
                            target_ulong *base, unsigned int *limit,
2206 84273177 Jan Kiszka
                            unsigned int *flags)
2207 84273177 Jan Kiszka
{
2208 84273177 Jan Kiszka
    SegmentCache *dt;
2209 84273177 Jan Kiszka
    target_ulong ptr;
2210 84273177 Jan Kiszka
    uint32_t e1, e2;
2211 84273177 Jan Kiszka
    int index;
2212 84273177 Jan Kiszka
2213 84273177 Jan Kiszka
    if (selector & 0x4)
2214 84273177 Jan Kiszka
        dt = &env->ldt;
2215 84273177 Jan Kiszka
    else
2216 84273177 Jan Kiszka
        dt = &env->gdt;
2217 84273177 Jan Kiszka
    index = selector & ~7;
2218 84273177 Jan Kiszka
    ptr = dt->base + index;
2219 84273177 Jan Kiszka
    if ((index + 7) > dt->limit
2220 84273177 Jan Kiszka
        || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
2221 84273177 Jan Kiszka
        || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
2222 84273177 Jan Kiszka
        return 0;
2223 84273177 Jan Kiszka
2224 84273177 Jan Kiszka
    *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
2225 84273177 Jan Kiszka
    *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
2226 84273177 Jan Kiszka
    if (e2 & DESC_G_MASK)
2227 84273177 Jan Kiszka
        *limit = (*limit << 12) | 0xfff;
2228 84273177 Jan Kiszka
    *flags = e2;
2229 84273177 Jan Kiszka
2230 84273177 Jan Kiszka
    return 1;
2231 84273177 Jan Kiszka
}
2232 84273177 Jan Kiszka
2233 01df040b aliguori
CPUX86State *cpu_x86_init(const char *cpu_model)
2234 01df040b aliguori
{
2235 01df040b aliguori
    CPUX86State *env;
2236 01df040b aliguori
    static int inited;
2237 01df040b aliguori
2238 01df040b aliguori
    env = qemu_mallocz(sizeof(CPUX86State));
2239 01df040b aliguori
    cpu_exec_init(env);
2240 01df040b aliguori
    env->cpu_model_str = cpu_model;
2241 01df040b aliguori
2242 01df040b aliguori
    /* init various static tables */
2243 01df040b aliguori
    if (!inited) {
2244 01df040b aliguori
        inited = 1;
2245 01df040b aliguori
        optimize_flags_init();
2246 01df040b aliguori
#ifndef CONFIG_USER_ONLY
2247 01df040b aliguori
        prev_debug_excp_handler =
2248 01df040b aliguori
            cpu_set_debug_excp_handler(breakpoint_handler);
2249 01df040b aliguori
#endif
2250 01df040b aliguori
    }
2251 01df040b aliguori
    if (cpu_x86_register(env, cpu_model) < 0) {
2252 01df040b aliguori
        cpu_x86_close(env);
2253 01df040b aliguori
        return NULL;
2254 01df040b aliguori
    }
2255 79c4f6b0 Huang Ying
    mce_init(env);
2256 0bf46a40 aliguori
2257 0bf46a40 aliguori
    qemu_init_vcpu(env);
2258 0bf46a40 aliguori
2259 01df040b aliguori
    return env;
2260 01df040b aliguori
}
2261 b09ea7d5 Gleb Natapov
2262 b09ea7d5 Gleb Natapov
#if !defined(CONFIG_USER_ONLY)
2263 b09ea7d5 Gleb Natapov
void do_cpu_init(CPUState *env)
2264 b09ea7d5 Gleb Natapov
{
2265 b09ea7d5 Gleb Natapov
    int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
2266 b09ea7d5 Gleb Natapov
    cpu_reset(env);
2267 b09ea7d5 Gleb Natapov
    env->interrupt_request = sipi;
2268 b09ea7d5 Gleb Natapov
    apic_init_reset(env);
2269 b09ea7d5 Gleb Natapov
}
2270 b09ea7d5 Gleb Natapov
2271 b09ea7d5 Gleb Natapov
void do_cpu_sipi(CPUState *env)
2272 b09ea7d5 Gleb Natapov
{
2273 b09ea7d5 Gleb Natapov
    apic_sipi(env);
2274 b09ea7d5 Gleb Natapov
}
2275 b09ea7d5 Gleb Natapov
#else
2276 b09ea7d5 Gleb Natapov
void do_cpu_init(CPUState *env)
2277 b09ea7d5 Gleb Natapov
{
2278 b09ea7d5 Gleb Natapov
}
2279 b09ea7d5 Gleb Natapov
void do_cpu_sipi(CPUState *env)
2280 b09ea7d5 Gleb Natapov
{
2281 b09ea7d5 Gleb Natapov
}
2282 b09ea7d5 Gleb Natapov
#endif