Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ 49a945a3

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