Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ af364b41

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