Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ f4918804

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 eaa728ee bellard
}
621 7e84c249 bellard
622 eaa728ee bellard
void cpu_x86_close(CPUX86State *env)
623 eaa728ee bellard
{
624 bb332cb2 balrog
    qemu_free(env);
625 eaa728ee bellard
}
626 7e84c249 bellard
627 eaa728ee bellard
/***********************************************************/
628 eaa728ee bellard
/* x86 debug */
629 3b46e624 ths
630 eaa728ee bellard
static const char *cc_op_str[] = {
631 eaa728ee bellard
    "DYNAMIC",
632 eaa728ee bellard
    "EFLAGS",
633 7e84c249 bellard
634 eaa728ee bellard
    "MULB",
635 eaa728ee bellard
    "MULW",
636 eaa728ee bellard
    "MULL",
637 eaa728ee bellard
    "MULQ",
638 3b46e624 ths
639 eaa728ee bellard
    "ADDB",
640 eaa728ee bellard
    "ADDW",
641 eaa728ee bellard
    "ADDL",
642 eaa728ee bellard
    "ADDQ",
643 3b46e624 ths
644 eaa728ee bellard
    "ADCB",
645 eaa728ee bellard
    "ADCW",
646 eaa728ee bellard
    "ADCL",
647 eaa728ee bellard
    "ADCQ",
648 3b46e624 ths
649 eaa728ee bellard
    "SUBB",
650 eaa728ee bellard
    "SUBW",
651 eaa728ee bellard
    "SUBL",
652 eaa728ee bellard
    "SUBQ",
653 7e84c249 bellard
654 eaa728ee bellard
    "SBBB",
655 eaa728ee bellard
    "SBBW",
656 eaa728ee bellard
    "SBBL",
657 eaa728ee bellard
    "SBBQ",
658 7e84c249 bellard
659 eaa728ee bellard
    "LOGICB",
660 eaa728ee bellard
    "LOGICW",
661 eaa728ee bellard
    "LOGICL",
662 eaa728ee bellard
    "LOGICQ",
663 7e84c249 bellard
664 eaa728ee bellard
    "INCB",
665 eaa728ee bellard
    "INCW",
666 eaa728ee bellard
    "INCL",
667 eaa728ee bellard
    "INCQ",
668 3b46e624 ths
669 eaa728ee bellard
    "DECB",
670 eaa728ee bellard
    "DECW",
671 eaa728ee bellard
    "DECL",
672 eaa728ee bellard
    "DECQ",
673 3b46e624 ths
674 eaa728ee bellard
    "SHLB",
675 eaa728ee bellard
    "SHLW",
676 eaa728ee bellard
    "SHLL",
677 eaa728ee bellard
    "SHLQ",
678 3b46e624 ths
679 eaa728ee bellard
    "SARB",
680 eaa728ee bellard
    "SARW",
681 eaa728ee bellard
    "SARL",
682 eaa728ee bellard
    "SARQ",
683 eaa728ee bellard
};
684 7e84c249 bellard
685 a3867ed2 aliguori
static void
686 a3867ed2 aliguori
cpu_x86_dump_seg_cache(CPUState *env, FILE *f,
687 a3867ed2 aliguori
                       int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
688 a3867ed2 aliguori
                       const char *name, struct SegmentCache *sc)
689 a3867ed2 aliguori
{
690 a3867ed2 aliguori
#ifdef TARGET_X86_64
691 a3867ed2 aliguori
    if (env->hflags & HF_CS64_MASK) {
692 a3867ed2 aliguori
        cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
693 a3867ed2 aliguori
                    sc->selector, sc->base, sc->limit, sc->flags);
694 a3867ed2 aliguori
    } else
695 a3867ed2 aliguori
#endif
696 a3867ed2 aliguori
    {
697 a3867ed2 aliguori
        cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
698 a3867ed2 aliguori
                    (uint32_t)sc->base, sc->limit, sc->flags);
699 a3867ed2 aliguori
    }
700 a3867ed2 aliguori
701 a3867ed2 aliguori
    if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
702 a3867ed2 aliguori
        goto done;
703 a3867ed2 aliguori
704 a3867ed2 aliguori
    cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
705 a3867ed2 aliguori
    if (sc->flags & DESC_S_MASK) {
706 a3867ed2 aliguori
        if (sc->flags & DESC_CS_MASK) {
707 a3867ed2 aliguori
            cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
708 a3867ed2 aliguori
                           ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
709 a3867ed2 aliguori
            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
710 a3867ed2 aliguori
                        (sc->flags & DESC_R_MASK) ? 'R' : '-');
711 a3867ed2 aliguori
        } else {
712 a3867ed2 aliguori
            cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS  " : "DS16");
713 a3867ed2 aliguori
            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
714 a3867ed2 aliguori
                        (sc->flags & DESC_W_MASK) ? 'W' : '-');
715 a3867ed2 aliguori
        }
716 a3867ed2 aliguori
        cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
717 a3867ed2 aliguori
    } else {
718 a3867ed2 aliguori
        static const char *sys_type_name[2][16] = {
719 a3867ed2 aliguori
            { /* 32 bit mode */
720 a3867ed2 aliguori
                "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
721 a3867ed2 aliguori
                "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
722 a3867ed2 aliguori
                "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
723 a3867ed2 aliguori
                "CallGate32", "Reserved", "IntGate32", "TrapGate32"
724 a3867ed2 aliguori
            },
725 a3867ed2 aliguori
            { /* 64 bit mode */
726 a3867ed2 aliguori
                "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
727 a3867ed2 aliguori
                "Reserved", "Reserved", "Reserved", "Reserved",
728 a3867ed2 aliguori
                "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
729 a3867ed2 aliguori
                "Reserved", "IntGate64", "TrapGate64"
730 a3867ed2 aliguori
            }
731 a3867ed2 aliguori
        };
732 a3867ed2 aliguori
        cpu_fprintf(f, sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
733 a3867ed2 aliguori
                                    [(sc->flags & DESC_TYPE_MASK)
734 a3867ed2 aliguori
                                     >> DESC_TYPE_SHIFT]);
735 a3867ed2 aliguori
    }
736 a3867ed2 aliguori
done:
737 a3867ed2 aliguori
    cpu_fprintf(f, "\n");
738 a3867ed2 aliguori
}
739 a3867ed2 aliguori
740 eaa728ee bellard
void cpu_dump_state(CPUState *env, FILE *f,
741 eaa728ee bellard
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
742 eaa728ee bellard
                    int flags)
743 eaa728ee bellard
{
744 eaa728ee bellard
    int eflags, i, nb;
745 eaa728ee bellard
    char cc_op_name[32];
746 eaa728ee bellard
    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
747 7e84c249 bellard
748 23054111 Jan Kiszka
    cpu_synchronize_state(env);
749 ff3c01ca balrog
750 eaa728ee bellard
    eflags = env->eflags;
751 eaa728ee bellard
#ifdef TARGET_X86_64
752 eaa728ee bellard
    if (env->hflags & HF_CS64_MASK) {
753 eaa728ee bellard
        cpu_fprintf(f,
754 eaa728ee bellard
                    "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
755 eaa728ee bellard
                    "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
756 eaa728ee bellard
                    "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
757 eaa728ee bellard
                    "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
758 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",
759 eaa728ee bellard
                    env->regs[R_EAX],
760 eaa728ee bellard
                    env->regs[R_EBX],
761 eaa728ee bellard
                    env->regs[R_ECX],
762 eaa728ee bellard
                    env->regs[R_EDX],
763 eaa728ee bellard
                    env->regs[R_ESI],
764 eaa728ee bellard
                    env->regs[R_EDI],
765 eaa728ee bellard
                    env->regs[R_EBP],
766 eaa728ee bellard
                    env->regs[R_ESP],
767 eaa728ee bellard
                    env->regs[8],
768 eaa728ee bellard
                    env->regs[9],
769 eaa728ee bellard
                    env->regs[10],
770 eaa728ee bellard
                    env->regs[11],
771 eaa728ee bellard
                    env->regs[12],
772 eaa728ee bellard
                    env->regs[13],
773 eaa728ee bellard
                    env->regs[14],
774 eaa728ee bellard
                    env->regs[15],
775 eaa728ee bellard
                    env->eip, eflags,
776 eaa728ee bellard
                    eflags & DF_MASK ? 'D' : '-',
777 eaa728ee bellard
                    eflags & CC_O ? 'O' : '-',
778 eaa728ee bellard
                    eflags & CC_S ? 'S' : '-',
779 eaa728ee bellard
                    eflags & CC_Z ? 'Z' : '-',
780 eaa728ee bellard
                    eflags & CC_A ? 'A' : '-',
781 eaa728ee bellard
                    eflags & CC_P ? 'P' : '-',
782 eaa728ee bellard
                    eflags & CC_C ? 'C' : '-',
783 eaa728ee bellard
                    env->hflags & HF_CPL_MASK,
784 eaa728ee bellard
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
785 5ee0ffaa Juan Quintela
                    (env->a20_mask >> 20) & 1,
786 eaa728ee bellard
                    (env->hflags >> HF_SMM_SHIFT) & 1,
787 ce5232c5 bellard
                    env->halted);
788 eaa728ee bellard
    } else
789 eaa728ee bellard
#endif
790 eaa728ee bellard
    {
791 eaa728ee bellard
        cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
792 eaa728ee bellard
                    "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
793 eaa728ee bellard
                    "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
794 eaa728ee bellard
                    (uint32_t)env->regs[R_EAX],
795 eaa728ee bellard
                    (uint32_t)env->regs[R_EBX],
796 eaa728ee bellard
                    (uint32_t)env->regs[R_ECX],
797 eaa728ee bellard
                    (uint32_t)env->regs[R_EDX],
798 eaa728ee bellard
                    (uint32_t)env->regs[R_ESI],
799 eaa728ee bellard
                    (uint32_t)env->regs[R_EDI],
800 eaa728ee bellard
                    (uint32_t)env->regs[R_EBP],
801 eaa728ee bellard
                    (uint32_t)env->regs[R_ESP],
802 eaa728ee bellard
                    (uint32_t)env->eip, eflags,
803 eaa728ee bellard
                    eflags & DF_MASK ? 'D' : '-',
804 eaa728ee bellard
                    eflags & CC_O ? 'O' : '-',
805 eaa728ee bellard
                    eflags & CC_S ? 'S' : '-',
806 eaa728ee bellard
                    eflags & CC_Z ? 'Z' : '-',
807 eaa728ee bellard
                    eflags & CC_A ? 'A' : '-',
808 eaa728ee bellard
                    eflags & CC_P ? 'P' : '-',
809 eaa728ee bellard
                    eflags & CC_C ? 'C' : '-',
810 eaa728ee bellard
                    env->hflags & HF_CPL_MASK,
811 eaa728ee bellard
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
812 5ee0ffaa Juan Quintela
                    (env->a20_mask >> 20) & 1,
813 eaa728ee bellard
                    (env->hflags >> HF_SMM_SHIFT) & 1,
814 ce5232c5 bellard
                    env->halted);
815 8145122b bellard
    }
816 3b46e624 ths
817 a3867ed2 aliguori
    for(i = 0; i < 6; i++) {
818 a3867ed2 aliguori
        cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
819 a3867ed2 aliguori
                               &env->segs[i]);
820 a3867ed2 aliguori
    }
821 a3867ed2 aliguori
    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
822 a3867ed2 aliguori
    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
823 a3867ed2 aliguori
824 eaa728ee bellard
#ifdef TARGET_X86_64
825 eaa728ee bellard
    if (env->hflags & HF_LMA_MASK) {
826 eaa728ee bellard
        cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
827 eaa728ee bellard
                    env->gdt.base, env->gdt.limit);
828 eaa728ee bellard
        cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
829 eaa728ee bellard
                    env->idt.base, env->idt.limit);
830 eaa728ee bellard
        cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
831 eaa728ee bellard
                    (uint32_t)env->cr[0],
832 eaa728ee bellard
                    env->cr[2],
833 eaa728ee bellard
                    env->cr[3],
834 eaa728ee bellard
                    (uint32_t)env->cr[4]);
835 a59cb4e0 aliguori
        for(i = 0; i < 4; i++)
836 a59cb4e0 aliguori
            cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
837 a59cb4e0 aliguori
        cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
838 d4b55be5 aliguori
                    env->dr[6], env->dr[7]);
839 eaa728ee bellard
    } else
840 eaa728ee bellard
#endif
841 eaa728ee bellard
    {
842 eaa728ee bellard
        cpu_fprintf(f, "GDT=     %08x %08x\n",
843 eaa728ee bellard
                    (uint32_t)env->gdt.base, env->gdt.limit);
844 eaa728ee bellard
        cpu_fprintf(f, "IDT=     %08x %08x\n",
845 eaa728ee bellard
                    (uint32_t)env->idt.base, env->idt.limit);
846 eaa728ee bellard
        cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
847 eaa728ee bellard
                    (uint32_t)env->cr[0],
848 eaa728ee bellard
                    (uint32_t)env->cr[2],
849 eaa728ee bellard
                    (uint32_t)env->cr[3],
850 eaa728ee bellard
                    (uint32_t)env->cr[4]);
851 a59cb4e0 aliguori
        for(i = 0; i < 4; i++)
852 a59cb4e0 aliguori
            cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]);
853 d4b55be5 aliguori
        cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]);
854 eaa728ee bellard
    }
855 eaa728ee bellard
    if (flags & X86_DUMP_CCOP) {
856 eaa728ee bellard
        if ((unsigned)env->cc_op < CC_OP_NB)
857 eaa728ee bellard
            snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
858 eaa728ee bellard
        else
859 eaa728ee bellard
            snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
860 eaa728ee bellard
#ifdef TARGET_X86_64
861 eaa728ee bellard
        if (env->hflags & HF_CS64_MASK) {
862 eaa728ee bellard
            cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
863 eaa728ee bellard
                        env->cc_src, env->cc_dst,
864 eaa728ee bellard
                        cc_op_name);
865 eaa728ee bellard
        } else
866 eaa728ee bellard
#endif
867 eaa728ee bellard
        {
868 eaa728ee bellard
            cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
869 eaa728ee bellard
                        (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
870 eaa728ee bellard
                        cc_op_name);
871 eaa728ee bellard
        }
872 7e84c249 bellard
    }
873 eaa728ee bellard
    if (flags & X86_DUMP_FPU) {
874 eaa728ee bellard
        int fptag;
875 eaa728ee bellard
        fptag = 0;
876 eaa728ee bellard
        for(i = 0; i < 8; i++) {
877 eaa728ee bellard
            fptag |= ((!env->fptags[i]) << i);
878 eaa728ee bellard
        }
879 eaa728ee bellard
        cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
880 eaa728ee bellard
                    env->fpuc,
881 eaa728ee bellard
                    (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
882 eaa728ee bellard
                    env->fpstt,
883 eaa728ee bellard
                    fptag,
884 eaa728ee bellard
                    env->mxcsr);
885 eaa728ee bellard
        for(i=0;i<8;i++) {
886 eaa728ee bellard
#if defined(USE_X86LDOUBLE)
887 eaa728ee bellard
            union {
888 eaa728ee bellard
                long double d;
889 eaa728ee bellard
                struct {
890 eaa728ee bellard
                    uint64_t lower;
891 eaa728ee bellard
                    uint16_t upper;
892 eaa728ee bellard
                } l;
893 eaa728ee bellard
            } tmp;
894 eaa728ee bellard
            tmp.d = env->fpregs[i].d;
895 eaa728ee bellard
            cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
896 eaa728ee bellard
                        i, tmp.l.lower, tmp.l.upper);
897 eaa728ee bellard
#else
898 eaa728ee bellard
            cpu_fprintf(f, "FPR%d=%016" PRIx64,
899 eaa728ee bellard
                        i, env->fpregs[i].mmx.q);
900 eaa728ee bellard
#endif
901 eaa728ee bellard
            if ((i & 1) == 1)
902 eaa728ee bellard
                cpu_fprintf(f, "\n");
903 eaa728ee bellard
            else
904 eaa728ee bellard
                cpu_fprintf(f, " ");
905 eaa728ee bellard
        }
906 eaa728ee bellard
        if (env->hflags & HF_CS64_MASK)
907 eaa728ee bellard
            nb = 16;
908 eaa728ee bellard
        else
909 eaa728ee bellard
            nb = 8;
910 eaa728ee bellard
        for(i=0;i<nb;i++) {
911 eaa728ee bellard
            cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
912 eaa728ee bellard
                        i,
913 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(3),
914 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(2),
915 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(1),
916 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(0));
917 eaa728ee bellard
            if ((i & 1) == 1)
918 eaa728ee bellard
                cpu_fprintf(f, "\n");
919 eaa728ee bellard
            else
920 eaa728ee bellard
                cpu_fprintf(f, " ");
921 eaa728ee bellard
        }
922 7e84c249 bellard
    }
923 2c0262af bellard
}
924 7e84c249 bellard
925 eaa728ee bellard
/***********************************************************/
926 eaa728ee bellard
/* x86 mmu */
927 eaa728ee bellard
/* XXX: add PGE support */
928 eaa728ee bellard
929 eaa728ee bellard
void cpu_x86_set_a20(CPUX86State *env, int a20_state)
930 2c0262af bellard
{
931 eaa728ee bellard
    a20_state = (a20_state != 0);
932 eaa728ee bellard
    if (a20_state != ((env->a20_mask >> 20) & 1)) {
933 eaa728ee bellard
#if defined(DEBUG_MMU)
934 eaa728ee bellard
        printf("A20 update: a20=%d\n", a20_state);
935 eaa728ee bellard
#endif
936 eaa728ee bellard
        /* if the cpu is currently executing code, we must unlink it and
937 eaa728ee bellard
           all the potentially executing TB */
938 eaa728ee bellard
        cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
939 3b46e624 ths
940 eaa728ee bellard
        /* when a20 is changed, all the MMU mappings are invalid, so
941 eaa728ee bellard
           we must flush everything */
942 eaa728ee bellard
        tlb_flush(env, 1);
943 5ee0ffaa Juan Quintela
        env->a20_mask = ~(1 << 20) | (a20_state << 20);
944 7e84c249 bellard
    }
945 2c0262af bellard
}
946 2c0262af bellard
947 eaa728ee bellard
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
948 2c0262af bellard
{
949 eaa728ee bellard
    int pe_state;
950 2c0262af bellard
951 eaa728ee bellard
#if defined(DEBUG_MMU)
952 eaa728ee bellard
    printf("CR0 update: CR0=0x%08x\n", new_cr0);
953 eaa728ee bellard
#endif
954 eaa728ee bellard
    if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
955 eaa728ee bellard
        (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
956 eaa728ee bellard
        tlb_flush(env, 1);
957 eaa728ee bellard
    }
958 2c0262af bellard
959 eaa728ee bellard
#ifdef TARGET_X86_64
960 eaa728ee bellard
    if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
961 eaa728ee bellard
        (env->efer & MSR_EFER_LME)) {
962 eaa728ee bellard
        /* enter in long mode */
963 eaa728ee bellard
        /* XXX: generate an exception */
964 eaa728ee bellard
        if (!(env->cr[4] & CR4_PAE_MASK))
965 eaa728ee bellard
            return;
966 eaa728ee bellard
        env->efer |= MSR_EFER_LMA;
967 eaa728ee bellard
        env->hflags |= HF_LMA_MASK;
968 eaa728ee bellard
    } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
969 eaa728ee bellard
               (env->efer & MSR_EFER_LMA)) {
970 eaa728ee bellard
        /* exit long mode */
971 eaa728ee bellard
        env->efer &= ~MSR_EFER_LMA;
972 eaa728ee bellard
        env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
973 eaa728ee bellard
        env->eip &= 0xffffffff;
974 eaa728ee bellard
    }
975 eaa728ee bellard
#endif
976 eaa728ee bellard
    env->cr[0] = new_cr0 | CR0_ET_MASK;
977 7e84c249 bellard
978 eaa728ee bellard
    /* update PE flag in hidden flags */
979 eaa728ee bellard
    pe_state = (env->cr[0] & CR0_PE_MASK);
980 eaa728ee bellard
    env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
981 eaa728ee bellard
    /* ensure that ADDSEG is always set in real mode */
982 eaa728ee bellard
    env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
983 eaa728ee bellard
    /* update FPU flags */
984 eaa728ee bellard
    env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
985 eaa728ee bellard
        ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
986 7e84c249 bellard
}
987 7e84c249 bellard
988 eaa728ee bellard
/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
989 eaa728ee bellard
   the PDPT */
990 eaa728ee bellard
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
991 7e84c249 bellard
{
992 eaa728ee bellard
    env->cr[3] = new_cr3;
993 eaa728ee bellard
    if (env->cr[0] & CR0_PG_MASK) {
994 eaa728ee bellard
#if defined(DEBUG_MMU)
995 eaa728ee bellard
        printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
996 eaa728ee bellard
#endif
997 eaa728ee bellard
        tlb_flush(env, 0);
998 eaa728ee bellard
    }
999 7e84c249 bellard
}
1000 7e84c249 bellard
1001 eaa728ee bellard
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
1002 7e84c249 bellard
{
1003 eaa728ee bellard
#if defined(DEBUG_MMU)
1004 eaa728ee bellard
    printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
1005 eaa728ee bellard
#endif
1006 eaa728ee bellard
    if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
1007 eaa728ee bellard
        (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
1008 eaa728ee bellard
        tlb_flush(env, 1);
1009 eaa728ee bellard
    }
1010 eaa728ee bellard
    /* SSE handling */
1011 eaa728ee bellard
    if (!(env->cpuid_features & CPUID_SSE))
1012 eaa728ee bellard
        new_cr4 &= ~CR4_OSFXSR_MASK;
1013 eaa728ee bellard
    if (new_cr4 & CR4_OSFXSR_MASK)
1014 eaa728ee bellard
        env->hflags |= HF_OSFXSR_MASK;
1015 eaa728ee bellard
    else
1016 eaa728ee bellard
        env->hflags &= ~HF_OSFXSR_MASK;
1017 b8b6a50b bellard
1018 eaa728ee bellard
    env->cr[4] = new_cr4;
1019 b8b6a50b bellard
}
1020 b8b6a50b bellard
1021 eaa728ee bellard
#if defined(CONFIG_USER_ONLY)
1022 eaa728ee bellard
1023 eaa728ee bellard
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
1024 eaa728ee bellard
                             int is_write, int mmu_idx, int is_softmmu)
1025 b8b6a50b bellard
{
1026 eaa728ee bellard
    /* user mode only emulation */
1027 eaa728ee bellard
    is_write &= 1;
1028 eaa728ee bellard
    env->cr[2] = addr;
1029 eaa728ee bellard
    env->error_code = (is_write << PG_ERROR_W_BIT);
1030 eaa728ee bellard
    env->error_code |= PG_ERROR_U_MASK;
1031 eaa728ee bellard
    env->exception_index = EXCP0E_PAGE;
1032 eaa728ee bellard
    return 1;
1033 2c0262af bellard
}
1034 2c0262af bellard
1035 c227f099 Anthony Liguori
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1036 891b38e4 bellard
{
1037 eaa728ee bellard
    return addr;
1038 891b38e4 bellard
}
1039 891b38e4 bellard
1040 8d7b0fbb bellard
#else
1041 891b38e4 bellard
1042 eaa728ee bellard
/* XXX: This value should match the one returned by CPUID
1043 eaa728ee bellard
 * and in exec.c */
1044 eaa728ee bellard
# if defined(TARGET_X86_64)
1045 2c90d794 ths
# define PHYS_ADDR_MASK 0xfffffff000LL
1046 eaa728ee bellard
# else
1047 2c90d794 ths
# define PHYS_ADDR_MASK 0xffffff000LL
1048 eaa728ee bellard
# endif
1049 eaa728ee bellard
1050 eaa728ee bellard
/* return value:
1051 eaa728ee bellard
   -1 = cannot handle fault
1052 eaa728ee bellard
   0  = nothing more to do
1053 eaa728ee bellard
   1  = generate PF fault
1054 eaa728ee bellard
   2  = soft MMU activation required for this block
1055 eaa728ee bellard
*/
1056 eaa728ee bellard
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
1057 eaa728ee bellard
                             int is_write1, int mmu_idx, int is_softmmu)
1058 eaa728ee bellard
{
1059 eaa728ee bellard
    uint64_t ptep, pte;
1060 eaa728ee bellard
    target_ulong pde_addr, pte_addr;
1061 eaa728ee bellard
    int error_code, is_dirty, prot, page_size, ret, is_write, is_user;
1062 c227f099 Anthony Liguori
    target_phys_addr_t paddr;
1063 eaa728ee bellard
    uint32_t page_offset;
1064 eaa728ee bellard
    target_ulong vaddr, virt_addr;
1065 eaa728ee bellard
1066 eaa728ee bellard
    is_user = mmu_idx == MMU_USER_IDX;
1067 eaa728ee bellard
#if defined(DEBUG_MMU)
1068 eaa728ee bellard
    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
1069 eaa728ee bellard
           addr, is_write1, is_user, env->eip);
1070 eaa728ee bellard
#endif
1071 eaa728ee bellard
    is_write = is_write1 & 1;
1072 eaa728ee bellard
1073 eaa728ee bellard
    if (!(env->cr[0] & CR0_PG_MASK)) {
1074 eaa728ee bellard
        pte = addr;
1075 eaa728ee bellard
        virt_addr = addr & TARGET_PAGE_MASK;
1076 eaa728ee bellard
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
1077 eaa728ee bellard
        page_size = 4096;
1078 eaa728ee bellard
        goto do_mapping;
1079 eaa728ee bellard
    }
1080 eaa728ee bellard
1081 eaa728ee bellard
    if (env->cr[4] & CR4_PAE_MASK) {
1082 eaa728ee bellard
        uint64_t pde, pdpe;
1083 eaa728ee bellard
        target_ulong pdpe_addr;
1084 2c0262af bellard
1085 eaa728ee bellard
#ifdef TARGET_X86_64
1086 eaa728ee bellard
        if (env->hflags & HF_LMA_MASK) {
1087 eaa728ee bellard
            uint64_t pml4e_addr, pml4e;
1088 eaa728ee bellard
            int32_t sext;
1089 eaa728ee bellard
1090 eaa728ee bellard
            /* test virtual address sign extension */
1091 eaa728ee bellard
            sext = (int64_t)addr >> 47;
1092 eaa728ee bellard
            if (sext != 0 && sext != -1) {
1093 eaa728ee bellard
                env->error_code = 0;
1094 eaa728ee bellard
                env->exception_index = EXCP0D_GPF;
1095 eaa728ee bellard
                return 1;
1096 eaa728ee bellard
            }
1097 0573fbfc ths
1098 eaa728ee bellard
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
1099 eaa728ee bellard
                env->a20_mask;
1100 eaa728ee bellard
            pml4e = ldq_phys(pml4e_addr);
1101 eaa728ee bellard
            if (!(pml4e & PG_PRESENT_MASK)) {
1102 eaa728ee bellard
                error_code = 0;
1103 eaa728ee bellard
                goto do_fault;
1104 eaa728ee bellard
            }
1105 eaa728ee bellard
            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
1106 eaa728ee bellard
                error_code = PG_ERROR_RSVD_MASK;
1107 eaa728ee bellard
                goto do_fault;
1108 eaa728ee bellard
            }
1109 eaa728ee bellard
            if (!(pml4e & PG_ACCESSED_MASK)) {
1110 eaa728ee bellard
                pml4e |= PG_ACCESSED_MASK;
1111 eaa728ee bellard
                stl_phys_notdirty(pml4e_addr, pml4e);
1112 eaa728ee bellard
            }
1113 eaa728ee bellard
            ptep = pml4e ^ PG_NX_MASK;
1114 eaa728ee bellard
            pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
1115 eaa728ee bellard
                env->a20_mask;
1116 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
1117 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK)) {
1118 eaa728ee bellard
                error_code = 0;
1119 eaa728ee bellard
                goto do_fault;
1120 eaa728ee bellard
            }
1121 eaa728ee bellard
            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
1122 eaa728ee bellard
                error_code = PG_ERROR_RSVD_MASK;
1123 eaa728ee bellard
                goto do_fault;
1124 eaa728ee bellard
            }
1125 eaa728ee bellard
            ptep &= pdpe ^ PG_NX_MASK;
1126 eaa728ee bellard
            if (!(pdpe & PG_ACCESSED_MASK)) {
1127 eaa728ee bellard
                pdpe |= PG_ACCESSED_MASK;
1128 eaa728ee bellard
                stl_phys_notdirty(pdpe_addr, pdpe);
1129 eaa728ee bellard
            }
1130 eaa728ee bellard
        } else
1131 eaa728ee bellard
#endif
1132 eaa728ee bellard
        {
1133 eaa728ee bellard
            /* XXX: load them when cr3 is loaded ? */
1134 eaa728ee bellard
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1135 eaa728ee bellard
                env->a20_mask;
1136 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
1137 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK)) {
1138 eaa728ee bellard
                error_code = 0;
1139 eaa728ee bellard
                goto do_fault;
1140 eaa728ee bellard
            }
1141 eaa728ee bellard
            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
1142 7e84c249 bellard
        }
1143 7e84c249 bellard
1144 eaa728ee bellard
        pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
1145 eaa728ee bellard
            env->a20_mask;
1146 eaa728ee bellard
        pde = ldq_phys(pde_addr);
1147 eaa728ee bellard
        if (!(pde & PG_PRESENT_MASK)) {
1148 eaa728ee bellard
            error_code = 0;
1149 eaa728ee bellard
            goto do_fault;
1150 eaa728ee bellard
        }
1151 eaa728ee bellard
        if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
1152 eaa728ee bellard
            error_code = PG_ERROR_RSVD_MASK;
1153 eaa728ee bellard
            goto do_fault;
1154 eaa728ee bellard
        }
1155 eaa728ee bellard
        ptep &= pde ^ PG_NX_MASK;
1156 eaa728ee bellard
        if (pde & PG_PSE_MASK) {
1157 eaa728ee bellard
            /* 2 MB page */
1158 eaa728ee bellard
            page_size = 2048 * 1024;
1159 eaa728ee bellard
            ptep ^= PG_NX_MASK;
1160 eaa728ee bellard
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
1161 eaa728ee bellard
                goto do_fault_protect;
1162 eaa728ee bellard
            if (is_user) {
1163 eaa728ee bellard
                if (!(ptep & PG_USER_MASK))
1164 eaa728ee bellard
                    goto do_fault_protect;
1165 eaa728ee bellard
                if (is_write && !(ptep & PG_RW_MASK))
1166 eaa728ee bellard
                    goto do_fault_protect;
1167 eaa728ee bellard
            } else {
1168 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
1169 eaa728ee bellard
                    is_write && !(ptep & PG_RW_MASK))
1170 eaa728ee bellard
                    goto do_fault_protect;
1171 eaa728ee bellard
            }
1172 eaa728ee bellard
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
1173 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
1174 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
1175 eaa728ee bellard
                if (is_dirty)
1176 eaa728ee bellard
                    pde |= PG_DIRTY_MASK;
1177 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
1178 eaa728ee bellard
            }
1179 eaa728ee bellard
            /* align to page_size */
1180 eaa728ee bellard
            pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
1181 eaa728ee bellard
            virt_addr = addr & ~(page_size - 1);
1182 eaa728ee bellard
        } else {
1183 eaa728ee bellard
            /* 4 KB page */
1184 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK)) {
1185 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
1186 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
1187 eaa728ee bellard
            }
1188 eaa728ee bellard
            pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
1189 eaa728ee bellard
                env->a20_mask;
1190 eaa728ee bellard
            pte = ldq_phys(pte_addr);
1191 eaa728ee bellard
            if (!(pte & PG_PRESENT_MASK)) {
1192 eaa728ee bellard
                error_code = 0;
1193 eaa728ee bellard
                goto do_fault;
1194 eaa728ee bellard
            }
1195 eaa728ee bellard
            if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
1196 eaa728ee bellard
                error_code = PG_ERROR_RSVD_MASK;
1197 eaa728ee bellard
                goto do_fault;
1198 eaa728ee bellard
            }
1199 eaa728ee bellard
            /* combine pde and pte nx, user and rw protections */
1200 eaa728ee bellard
            ptep &= pte ^ PG_NX_MASK;
1201 eaa728ee bellard
            ptep ^= PG_NX_MASK;
1202 eaa728ee bellard
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
1203 eaa728ee bellard
                goto do_fault_protect;
1204 eaa728ee bellard
            if (is_user) {
1205 eaa728ee bellard
                if (!(ptep & PG_USER_MASK))
1206 eaa728ee bellard
                    goto do_fault_protect;
1207 eaa728ee bellard
                if (is_write && !(ptep & PG_RW_MASK))
1208 eaa728ee bellard
                    goto do_fault_protect;
1209 eaa728ee bellard
            } else {
1210 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
1211 eaa728ee bellard
                    is_write && !(ptep & PG_RW_MASK))
1212 eaa728ee bellard
                    goto do_fault_protect;
1213 eaa728ee bellard
            }
1214 eaa728ee bellard
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1215 eaa728ee bellard
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1216 eaa728ee bellard
                pte |= PG_ACCESSED_MASK;
1217 eaa728ee bellard
                if (is_dirty)
1218 eaa728ee bellard
                    pte |= PG_DIRTY_MASK;
1219 eaa728ee bellard
                stl_phys_notdirty(pte_addr, pte);
1220 eaa728ee bellard
            }
1221 eaa728ee bellard
            page_size = 4096;
1222 eaa728ee bellard
            virt_addr = addr & ~0xfff;
1223 eaa728ee bellard
            pte = pte & (PHYS_ADDR_MASK | 0xfff);
1224 7e84c249 bellard
        }
1225 2c0262af bellard
    } else {
1226 eaa728ee bellard
        uint32_t pde;
1227 eaa728ee bellard
1228 eaa728ee bellard
        /* page directory entry */
1229 eaa728ee bellard
        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
1230 eaa728ee bellard
            env->a20_mask;
1231 eaa728ee bellard
        pde = ldl_phys(pde_addr);
1232 eaa728ee bellard
        if (!(pde & PG_PRESENT_MASK)) {
1233 eaa728ee bellard
            error_code = 0;
1234 eaa728ee bellard
            goto do_fault;
1235 eaa728ee bellard
        }
1236 eaa728ee bellard
        /* if PSE bit is set, then we use a 4MB page */
1237 eaa728ee bellard
        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1238 eaa728ee bellard
            page_size = 4096 * 1024;
1239 eaa728ee bellard
            if (is_user) {
1240 eaa728ee bellard
                if (!(pde & PG_USER_MASK))
1241 eaa728ee bellard
                    goto do_fault_protect;
1242 eaa728ee bellard
                if (is_write && !(pde & PG_RW_MASK))
1243 eaa728ee bellard
                    goto do_fault_protect;
1244 eaa728ee bellard
            } else {
1245 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
1246 eaa728ee bellard
                    is_write && !(pde & PG_RW_MASK))
1247 eaa728ee bellard
                    goto do_fault_protect;
1248 eaa728ee bellard
            }
1249 eaa728ee bellard
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
1250 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
1251 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
1252 eaa728ee bellard
                if (is_dirty)
1253 eaa728ee bellard
                    pde |= PG_DIRTY_MASK;
1254 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
1255 eaa728ee bellard
            }
1256 2c0262af bellard
1257 eaa728ee bellard
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1258 eaa728ee bellard
            ptep = pte;
1259 eaa728ee bellard
            virt_addr = addr & ~(page_size - 1);
1260 eaa728ee bellard
        } else {
1261 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK)) {
1262 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
1263 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
1264 eaa728ee bellard
            }
1265 891b38e4 bellard
1266 eaa728ee bellard
            /* page directory entry */
1267 eaa728ee bellard
            pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
1268 eaa728ee bellard
                env->a20_mask;
1269 eaa728ee bellard
            pte = ldl_phys(pte_addr);
1270 eaa728ee bellard
            if (!(pte & PG_PRESENT_MASK)) {
1271 eaa728ee bellard
                error_code = 0;
1272 eaa728ee bellard
                goto do_fault;
1273 8e682019 bellard
            }
1274 eaa728ee bellard
            /* combine pde and pte user and rw protections */
1275 eaa728ee bellard
            ptep = pte & pde;
1276 eaa728ee bellard
            if (is_user) {
1277 eaa728ee bellard
                if (!(ptep & PG_USER_MASK))
1278 eaa728ee bellard
                    goto do_fault_protect;
1279 eaa728ee bellard
                if (is_write && !(ptep & PG_RW_MASK))
1280 eaa728ee bellard
                    goto do_fault_protect;
1281 eaa728ee bellard
            } else {
1282 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
1283 eaa728ee bellard
                    is_write && !(ptep & PG_RW_MASK))
1284 eaa728ee bellard
                    goto do_fault_protect;
1285 8e682019 bellard
            }
1286 eaa728ee bellard
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
1287 eaa728ee bellard
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
1288 eaa728ee bellard
                pte |= PG_ACCESSED_MASK;
1289 eaa728ee bellard
                if (is_dirty)
1290 eaa728ee bellard
                    pte |= PG_DIRTY_MASK;
1291 eaa728ee bellard
                stl_phys_notdirty(pte_addr, pte);
1292 eaa728ee bellard
            }
1293 eaa728ee bellard
            page_size = 4096;
1294 eaa728ee bellard
            virt_addr = addr & ~0xfff;
1295 2c0262af bellard
        }
1296 2c0262af bellard
    }
1297 eaa728ee bellard
    /* the page can be put in the TLB */
1298 eaa728ee bellard
    prot = PAGE_READ;
1299 eaa728ee bellard
    if (!(ptep & PG_NX_MASK))
1300 eaa728ee bellard
        prot |= PAGE_EXEC;
1301 eaa728ee bellard
    if (pte & PG_DIRTY_MASK) {
1302 eaa728ee bellard
        /* only set write access if already dirty... otherwise wait
1303 eaa728ee bellard
           for dirty access */
1304 eaa728ee bellard
        if (is_user) {
1305 eaa728ee bellard
            if (ptep & PG_RW_MASK)
1306 eaa728ee bellard
                prot |= PAGE_WRITE;
1307 eaa728ee bellard
        } else {
1308 eaa728ee bellard
            if (!(env->cr[0] & CR0_WP_MASK) ||
1309 eaa728ee bellard
                (ptep & PG_RW_MASK))
1310 eaa728ee bellard
                prot |= PAGE_WRITE;
1311 8e682019 bellard
        }
1312 891b38e4 bellard
    }
1313 eaa728ee bellard
 do_mapping:
1314 eaa728ee bellard
    pte = pte & env->a20_mask;
1315 eaa728ee bellard
1316 eaa728ee bellard
    /* Even if 4MB pages, we map only one 4KB page in the cache to
1317 eaa728ee bellard
       avoid filling it too fast */
1318 eaa728ee bellard
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1319 eaa728ee bellard
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1320 eaa728ee bellard
    vaddr = virt_addr + page_offset;
1321 eaa728ee bellard
1322 eaa728ee bellard
    ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
1323 eaa728ee bellard
    return ret;
1324 eaa728ee bellard
 do_fault_protect:
1325 eaa728ee bellard
    error_code = PG_ERROR_P_MASK;
1326 eaa728ee bellard
 do_fault:
1327 eaa728ee bellard
    error_code |= (is_write << PG_ERROR_W_BIT);
1328 eaa728ee bellard
    if (is_user)
1329 eaa728ee bellard
        error_code |= PG_ERROR_U_MASK;
1330 eaa728ee bellard
    if (is_write1 == 2 &&
1331 eaa728ee bellard
        (env->efer & MSR_EFER_NXE) &&
1332 eaa728ee bellard
        (env->cr[4] & CR4_PAE_MASK))
1333 eaa728ee bellard
        error_code |= PG_ERROR_I_D_MASK;
1334 872929aa bellard
    if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
1335 872929aa bellard
        /* cr2 is not modified in case of exceptions */
1336 872929aa bellard
        stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 
1337 872929aa bellard
                 addr);
1338 eaa728ee bellard
    } else {
1339 eaa728ee bellard
        env->cr[2] = addr;
1340 2c0262af bellard
    }
1341 eaa728ee bellard
    env->error_code = error_code;
1342 eaa728ee bellard
    env->exception_index = EXCP0E_PAGE;
1343 eaa728ee bellard
    return 1;
1344 14ce26e7 bellard
}
1345 14ce26e7 bellard
1346 c227f099 Anthony Liguori
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1347 14ce26e7 bellard
{
1348 eaa728ee bellard
    target_ulong pde_addr, pte_addr;
1349 eaa728ee bellard
    uint64_t pte;
1350 c227f099 Anthony Liguori
    target_phys_addr_t paddr;
1351 eaa728ee bellard
    uint32_t page_offset;
1352 eaa728ee bellard
    int page_size;
1353 14ce26e7 bellard
1354 eaa728ee bellard
    if (env->cr[4] & CR4_PAE_MASK) {
1355 eaa728ee bellard
        target_ulong pdpe_addr;
1356 eaa728ee bellard
        uint64_t pde, pdpe;
1357 14ce26e7 bellard
1358 eaa728ee bellard
#ifdef TARGET_X86_64
1359 eaa728ee bellard
        if (env->hflags & HF_LMA_MASK) {
1360 eaa728ee bellard
            uint64_t pml4e_addr, pml4e;
1361 eaa728ee bellard
            int32_t sext;
1362 eaa728ee bellard
1363 eaa728ee bellard
            /* test virtual address sign extension */
1364 eaa728ee bellard
            sext = (int64_t)addr >> 47;
1365 eaa728ee bellard
            if (sext != 0 && sext != -1)
1366 eaa728ee bellard
                return -1;
1367 eaa728ee bellard
1368 eaa728ee bellard
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
1369 eaa728ee bellard
                env->a20_mask;
1370 eaa728ee bellard
            pml4e = ldq_phys(pml4e_addr);
1371 eaa728ee bellard
            if (!(pml4e & PG_PRESENT_MASK))
1372 eaa728ee bellard
                return -1;
1373 eaa728ee bellard
1374 eaa728ee bellard
            pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
1375 eaa728ee bellard
                env->a20_mask;
1376 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
1377 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK))
1378 eaa728ee bellard
                return -1;
1379 eaa728ee bellard
        } else
1380 eaa728ee bellard
#endif
1381 eaa728ee bellard
        {
1382 eaa728ee bellard
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1383 eaa728ee bellard
                env->a20_mask;
1384 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
1385 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK))
1386 eaa728ee bellard
                return -1;
1387 14ce26e7 bellard
        }
1388 14ce26e7 bellard
1389 eaa728ee bellard
        pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
1390 eaa728ee bellard
            env->a20_mask;
1391 eaa728ee bellard
        pde = ldq_phys(pde_addr);
1392 eaa728ee bellard
        if (!(pde & PG_PRESENT_MASK)) {
1393 eaa728ee bellard
            return -1;
1394 eaa728ee bellard
        }
1395 eaa728ee bellard
        if (pde & PG_PSE_MASK) {
1396 eaa728ee bellard
            /* 2 MB page */
1397 eaa728ee bellard
            page_size = 2048 * 1024;
1398 eaa728ee bellard
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
1399 eaa728ee bellard
        } else {
1400 eaa728ee bellard
            /* 4 KB page */
1401 eaa728ee bellard
            pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
1402 eaa728ee bellard
                env->a20_mask;
1403 eaa728ee bellard
            page_size = 4096;
1404 eaa728ee bellard
            pte = ldq_phys(pte_addr);
1405 eaa728ee bellard
        }
1406 ca1c9e15 aliguori
        if (!(pte & PG_PRESENT_MASK))
1407 ca1c9e15 aliguori
            return -1;
1408 14ce26e7 bellard
    } else {
1409 eaa728ee bellard
        uint32_t pde;
1410 3b46e624 ths
1411 eaa728ee bellard
        if (!(env->cr[0] & CR0_PG_MASK)) {
1412 eaa728ee bellard
            pte = addr;
1413 eaa728ee bellard
            page_size = 4096;
1414 eaa728ee bellard
        } else {
1415 eaa728ee bellard
            /* page directory entry */
1416 eaa728ee bellard
            pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
1417 eaa728ee bellard
            pde = ldl_phys(pde_addr);
1418 eaa728ee bellard
            if (!(pde & PG_PRESENT_MASK))
1419 eaa728ee bellard
                return -1;
1420 eaa728ee bellard
            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1421 eaa728ee bellard
                pte = pde & ~0x003ff000; /* align to 4MB */
1422 eaa728ee bellard
                page_size = 4096 * 1024;
1423 eaa728ee bellard
            } else {
1424 eaa728ee bellard
                /* page directory entry */
1425 eaa728ee bellard
                pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
1426 eaa728ee bellard
                pte = ldl_phys(pte_addr);
1427 eaa728ee bellard
                if (!(pte & PG_PRESENT_MASK))
1428 eaa728ee bellard
                    return -1;
1429 eaa728ee bellard
                page_size = 4096;
1430 eaa728ee bellard
            }
1431 eaa728ee bellard
        }
1432 eaa728ee bellard
        pte = pte & env->a20_mask;
1433 14ce26e7 bellard
    }
1434 14ce26e7 bellard
1435 eaa728ee bellard
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1436 eaa728ee bellard
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
1437 eaa728ee bellard
    return paddr;
1438 3b21e03e bellard
}
1439 01df040b aliguori
1440 01df040b aliguori
void hw_breakpoint_insert(CPUState *env, int index)
1441 01df040b aliguori
{
1442 01df040b aliguori
    int type, err = 0;
1443 01df040b aliguori
1444 01df040b aliguori
    switch (hw_breakpoint_type(env->dr[7], index)) {
1445 01df040b aliguori
    case 0:
1446 01df040b aliguori
        if (hw_breakpoint_enabled(env->dr[7], index))
1447 01df040b aliguori
            err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
1448 01df040b aliguori
                                        &env->cpu_breakpoint[index]);
1449 01df040b aliguori
        break;
1450 01df040b aliguori
    case 1:
1451 01df040b aliguori
        type = BP_CPU | BP_MEM_WRITE;
1452 01df040b aliguori
        goto insert_wp;
1453 01df040b aliguori
    case 2:
1454 01df040b aliguori
         /* No support for I/O watchpoints yet */
1455 01df040b aliguori
        break;
1456 01df040b aliguori
    case 3:
1457 01df040b aliguori
        type = BP_CPU | BP_MEM_ACCESS;
1458 01df040b aliguori
    insert_wp:
1459 01df040b aliguori
        err = cpu_watchpoint_insert(env, env->dr[index],
1460 01df040b aliguori
                                    hw_breakpoint_len(env->dr[7], index),
1461 01df040b aliguori
                                    type, &env->cpu_watchpoint[index]);
1462 01df040b aliguori
        break;
1463 01df040b aliguori
    }
1464 01df040b aliguori
    if (err)
1465 01df040b aliguori
        env->cpu_breakpoint[index] = NULL;
1466 01df040b aliguori
}
1467 01df040b aliguori
1468 01df040b aliguori
void hw_breakpoint_remove(CPUState *env, int index)
1469 01df040b aliguori
{
1470 01df040b aliguori
    if (!env->cpu_breakpoint[index])
1471 01df040b aliguori
        return;
1472 01df040b aliguori
    switch (hw_breakpoint_type(env->dr[7], index)) {
1473 01df040b aliguori
    case 0:
1474 01df040b aliguori
        if (hw_breakpoint_enabled(env->dr[7], index))
1475 01df040b aliguori
            cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
1476 01df040b aliguori
        break;
1477 01df040b aliguori
    case 1:
1478 01df040b aliguori
    case 3:
1479 01df040b aliguori
        cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
1480 01df040b aliguori
        break;
1481 01df040b aliguori
    case 2:
1482 01df040b aliguori
        /* No support for I/O watchpoints yet */
1483 01df040b aliguori
        break;
1484 01df040b aliguori
    }
1485 01df040b aliguori
}
1486 01df040b aliguori
1487 01df040b aliguori
int check_hw_breakpoints(CPUState *env, int force_dr6_update)
1488 01df040b aliguori
{
1489 01df040b aliguori
    target_ulong dr6;
1490 01df040b aliguori
    int reg, type;
1491 01df040b aliguori
    int hit_enabled = 0;
1492 01df040b aliguori
1493 01df040b aliguori
    dr6 = env->dr[6] & ~0xf;
1494 01df040b aliguori
    for (reg = 0; reg < 4; reg++) {
1495 01df040b aliguori
        type = hw_breakpoint_type(env->dr[7], reg);
1496 01df040b aliguori
        if ((type == 0 && env->dr[reg] == env->eip) ||
1497 01df040b aliguori
            ((type & 1) && env->cpu_watchpoint[reg] &&
1498 01df040b aliguori
             (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
1499 01df040b aliguori
            dr6 |= 1 << reg;
1500 01df040b aliguori
            if (hw_breakpoint_enabled(env->dr[7], reg))
1501 01df040b aliguori
                hit_enabled = 1;
1502 01df040b aliguori
        }
1503 01df040b aliguori
    }
1504 01df040b aliguori
    if (hit_enabled || force_dr6_update)
1505 01df040b aliguori
        env->dr[6] = dr6;
1506 01df040b aliguori
    return hit_enabled;
1507 01df040b aliguori
}
1508 01df040b aliguori
1509 01df040b aliguori
static CPUDebugExcpHandler *prev_debug_excp_handler;
1510 01df040b aliguori
1511 01df040b aliguori
void raise_exception(int exception_index);
1512 01df040b aliguori
1513 01df040b aliguori
static void breakpoint_handler(CPUState *env)
1514 01df040b aliguori
{
1515 01df040b aliguori
    CPUBreakpoint *bp;
1516 01df040b aliguori
1517 01df040b aliguori
    if (env->watchpoint_hit) {
1518 01df040b aliguori
        if (env->watchpoint_hit->flags & BP_CPU) {
1519 01df040b aliguori
            env->watchpoint_hit = NULL;
1520 01df040b aliguori
            if (check_hw_breakpoints(env, 0))
1521 01df040b aliguori
                raise_exception(EXCP01_DB);
1522 01df040b aliguori
            else
1523 01df040b aliguori
                cpu_resume_from_signal(env, NULL);
1524 01df040b aliguori
        }
1525 01df040b aliguori
    } else {
1526 72cf2d4f Blue Swirl
        QTAILQ_FOREACH(bp, &env->breakpoints, entry)
1527 01df040b aliguori
            if (bp->pc == env->eip) {
1528 01df040b aliguori
                if (bp->flags & BP_CPU) {
1529 01df040b aliguori
                    check_hw_breakpoints(env, 1);
1530 01df040b aliguori
                    raise_exception(EXCP01_DB);
1531 01df040b aliguori
                }
1532 01df040b aliguori
                break;
1533 01df040b aliguori
            }
1534 01df040b aliguori
    }
1535 01df040b aliguori
    if (prev_debug_excp_handler)
1536 01df040b aliguori
        prev_debug_excp_handler(env);
1537 01df040b aliguori
}
1538 79c4f6b0 Huang Ying
1539 79c4f6b0 Huang Ying
/* This should come from sysemu.h - if we could include it here... */
1540 79c4f6b0 Huang Ying
void qemu_system_reset_request(void);
1541 79c4f6b0 Huang Ying
1542 79c4f6b0 Huang Ying
void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
1543 79c4f6b0 Huang Ying
                        uint64_t mcg_status, uint64_t addr, uint64_t misc)
1544 79c4f6b0 Huang Ying
{
1545 79c4f6b0 Huang Ying
    uint64_t mcg_cap = cenv->mcg_cap;
1546 79c4f6b0 Huang Ying
    unsigned bank_num = mcg_cap & 0xff;
1547 79c4f6b0 Huang Ying
    uint64_t *banks = cenv->mce_banks;
1548 79c4f6b0 Huang Ying
1549 79c4f6b0 Huang Ying
    if (bank >= bank_num || !(status & MCI_STATUS_VAL))
1550 79c4f6b0 Huang Ying
        return;
1551 79c4f6b0 Huang Ying
1552 79c4f6b0 Huang Ying
    /*
1553 79c4f6b0 Huang Ying
     * if MSR_MCG_CTL is not all 1s, the uncorrected error
1554 79c4f6b0 Huang Ying
     * reporting is disabled
1555 79c4f6b0 Huang Ying
     */
1556 79c4f6b0 Huang Ying
    if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
1557 79c4f6b0 Huang Ying
        cenv->mcg_ctl != ~(uint64_t)0)
1558 79c4f6b0 Huang Ying
        return;
1559 79c4f6b0 Huang Ying
    banks += 4 * bank;
1560 79c4f6b0 Huang Ying
    /*
1561 79c4f6b0 Huang Ying
     * if MSR_MCi_CTL is not all 1s, the uncorrected error
1562 79c4f6b0 Huang Ying
     * reporting is disabled for the bank
1563 79c4f6b0 Huang Ying
     */
1564 79c4f6b0 Huang Ying
    if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0)
1565 79c4f6b0 Huang Ying
        return;
1566 79c4f6b0 Huang Ying
    if (status & MCI_STATUS_UC) {
1567 79c4f6b0 Huang Ying
        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1568 79c4f6b0 Huang Ying
            !(cenv->cr[4] & CR4_MCE_MASK)) {
1569 79c4f6b0 Huang Ying
            fprintf(stderr, "injects mce exception while previous "
1570 79c4f6b0 Huang Ying
                    "one is in progress!\n");
1571 79c4f6b0 Huang Ying
            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1572 79c4f6b0 Huang Ying
            qemu_system_reset_request();
1573 79c4f6b0 Huang Ying
            return;
1574 79c4f6b0 Huang Ying
        }
1575 79c4f6b0 Huang Ying
        if (banks[1] & MCI_STATUS_VAL)
1576 79c4f6b0 Huang Ying
            status |= MCI_STATUS_OVER;
1577 79c4f6b0 Huang Ying
        banks[2] = addr;
1578 79c4f6b0 Huang Ying
        banks[3] = misc;
1579 79c4f6b0 Huang Ying
        cenv->mcg_status = mcg_status;
1580 79c4f6b0 Huang Ying
        banks[1] = status;
1581 79c4f6b0 Huang Ying
        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
1582 79c4f6b0 Huang Ying
    } else if (!(banks[1] & MCI_STATUS_VAL)
1583 79c4f6b0 Huang Ying
               || !(banks[1] & MCI_STATUS_UC)) {
1584 79c4f6b0 Huang Ying
        if (banks[1] & MCI_STATUS_VAL)
1585 79c4f6b0 Huang Ying
            status |= MCI_STATUS_OVER;
1586 79c4f6b0 Huang Ying
        banks[2] = addr;
1587 79c4f6b0 Huang Ying
        banks[3] = misc;
1588 79c4f6b0 Huang Ying
        banks[1] = status;
1589 79c4f6b0 Huang Ying
    } else
1590 79c4f6b0 Huang Ying
        banks[1] |= MCI_STATUS_OVER;
1591 79c4f6b0 Huang Ying
}
1592 74ce674f bellard
#endif /* !CONFIG_USER_ONLY */
1593 6fd805e1 aliguori
1594 79c4f6b0 Huang Ying
static void mce_init(CPUX86State *cenv)
1595 79c4f6b0 Huang Ying
{
1596 79c4f6b0 Huang Ying
    unsigned int bank, bank_num;
1597 79c4f6b0 Huang Ying
1598 79c4f6b0 Huang Ying
    if (((cenv->cpuid_version >> 8)&0xf) >= 6
1599 79c4f6b0 Huang Ying
        && (cenv->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)) {
1600 79c4f6b0 Huang Ying
        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1601 79c4f6b0 Huang Ying
        cenv->mcg_ctl = ~(uint64_t)0;
1602 ac74d0f1 Juan Quintela
        bank_num = MCE_BANKS_DEF;
1603 79c4f6b0 Huang Ying
        for (bank = 0; bank < bank_num; bank++)
1604 79c4f6b0 Huang Ying
            cenv->mce_banks[bank*4] = ~(uint64_t)0;
1605 79c4f6b0 Huang Ying
    }
1606 79c4f6b0 Huang Ying
}
1607 79c4f6b0 Huang Ying
1608 e00b6f80 aliguori
static void host_cpuid(uint32_t function, uint32_t count,
1609 e00b6f80 aliguori
                       uint32_t *eax, uint32_t *ebx,
1610 7ba1e619 aliguori
                       uint32_t *ecx, uint32_t *edx)
1611 7ba1e619 aliguori
{
1612 10781c09 aliguori
#if defined(CONFIG_KVM)
1613 7ba1e619 aliguori
    uint32_t vec[4];
1614 7ba1e619 aliguori
1615 7ba1e619 aliguori
#ifdef __x86_64__
1616 7ba1e619 aliguori
    asm volatile("cpuid"
1617 e00b6f80 aliguori
                 : "=a"(vec[0]), "=b"(vec[1]),
1618 e00b6f80 aliguori
                   "=c"(vec[2]), "=d"(vec[3])
1619 e00b6f80 aliguori
                 : "0"(function), "c"(count) : "cc");
1620 7ba1e619 aliguori
#else
1621 7ba1e619 aliguori
    asm volatile("pusha \n\t"
1622 e00b6f80 aliguori
                 "cpuid \n\t"
1623 b36d24b6 aliguori
                 "mov %%eax, 0(%2) \n\t"
1624 b36d24b6 aliguori
                 "mov %%ebx, 4(%2) \n\t"
1625 b36d24b6 aliguori
                 "mov %%ecx, 8(%2) \n\t"
1626 b36d24b6 aliguori
                 "mov %%edx, 12(%2) \n\t"
1627 e00b6f80 aliguori
                 "popa"
1628 e00b6f80 aliguori
                 : : "a"(function), "c"(count), "S"(vec)
1629 e00b6f80 aliguori
                 : "memory", "cc");
1630 7ba1e619 aliguori
#endif
1631 7ba1e619 aliguori
1632 7ba1e619 aliguori
    if (eax)
1633 7ba1e619 aliguori
        *eax = vec[0];
1634 7ba1e619 aliguori
    if (ebx)
1635 7ba1e619 aliguori
        *ebx = vec[1];
1636 7ba1e619 aliguori
    if (ecx)
1637 7ba1e619 aliguori
        *ecx = vec[2];
1638 7ba1e619 aliguori
    if (edx)
1639 7ba1e619 aliguori
        *edx = vec[3];
1640 7ba1e619 aliguori
#endif
1641 10781c09 aliguori
}
1642 7ba1e619 aliguori
1643 6d9fef1a Andre Przywara
static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
1644 6d9fef1a Andre Przywara
                             uint32_t *ecx, uint32_t *edx)
1645 6d9fef1a Andre Przywara
{
1646 6d9fef1a Andre Przywara
    *ebx = env->cpuid_vendor1;
1647 6d9fef1a Andre Przywara
    *edx = env->cpuid_vendor2;
1648 6d9fef1a Andre Przywara
    *ecx = env->cpuid_vendor3;
1649 6d9fef1a Andre Przywara
1650 6d9fef1a Andre Przywara
    /* sysenter isn't supported on compatibility mode on AMD, syscall
1651 6d9fef1a Andre Przywara
     * isn't supported in compatibility mode on Intel.
1652 6d9fef1a Andre Przywara
     * Normally we advertise the actual cpu vendor, but you can override
1653 6d9fef1a Andre Przywara
     * this if you want to use KVM's sysenter/syscall emulation
1654 6d9fef1a Andre Przywara
     * in compatibility mode and when doing cross vendor migration
1655 6d9fef1a Andre Przywara
     */
1656 6d9fef1a Andre Przywara
    if (kvm_enabled() && env->cpuid_vendor_override) {
1657 6d9fef1a Andre Przywara
        host_cpuid(0, 0, NULL, ebx, ecx, edx);
1658 6d9fef1a Andre Przywara
    }
1659 6d9fef1a Andre Przywara
}
1660 6d9fef1a Andre Przywara
1661 e00b6f80 aliguori
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
1662 6fd805e1 aliguori
                   uint32_t *eax, uint32_t *ebx,
1663 6fd805e1 aliguori
                   uint32_t *ecx, uint32_t *edx)
1664 6fd805e1 aliguori
{
1665 6fd805e1 aliguori
    /* test if maximum index reached */
1666 6fd805e1 aliguori
    if (index & 0x80000000) {
1667 6fd805e1 aliguori
        if (index > env->cpuid_xlevel)
1668 6fd805e1 aliguori
            index = env->cpuid_level;
1669 6fd805e1 aliguori
    } else {
1670 6fd805e1 aliguori
        if (index > env->cpuid_level)
1671 6fd805e1 aliguori
            index = env->cpuid_level;
1672 6fd805e1 aliguori
    }
1673 6fd805e1 aliguori
1674 6fd805e1 aliguori
    switch(index) {
1675 6fd805e1 aliguori
    case 0:
1676 6fd805e1 aliguori
        *eax = env->cpuid_level;
1677 6d9fef1a Andre Przywara
        get_cpuid_vendor(env, ebx, ecx, edx);
1678 6fd805e1 aliguori
        break;
1679 6fd805e1 aliguori
    case 1:
1680 6fd805e1 aliguori
        *eax = env->cpuid_version;
1681 6fd805e1 aliguori
        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
1682 6fd805e1 aliguori
        *ecx = env->cpuid_ext_features;
1683 6fd805e1 aliguori
        *edx = env->cpuid_features;
1684 400281af Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
1685 400281af Andre Przywara
            *ebx |= (env->nr_cores * env->nr_threads) << 16;
1686 400281af Andre Przywara
            *edx |= 1 << 28;    /* HTT bit */
1687 400281af Andre Przywara
        }
1688 6fd805e1 aliguori
        break;
1689 6fd805e1 aliguori
    case 2:
1690 6fd805e1 aliguori
        /* cache info: needed for Pentium Pro compatibility */
1691 6fd805e1 aliguori
        *eax = 1;
1692 6fd805e1 aliguori
        *ebx = 0;
1693 6fd805e1 aliguori
        *ecx = 0;
1694 6fd805e1 aliguori
        *edx = 0x2c307d;
1695 6fd805e1 aliguori
        break;
1696 6fd805e1 aliguori
    case 4:
1697 6fd805e1 aliguori
        /* cache info: needed for Core compatibility */
1698 400281af Andre Przywara
        if (env->nr_cores > 1) {
1699 400281af Andre Przywara
                *eax = (env->nr_cores - 1) << 26;
1700 400281af Andre Przywara
        } else {
1701 400281af Andre Przywara
                *eax = 0;
1702 400281af Andre Przywara
        }
1703 e00b6f80 aliguori
        switch (count) {
1704 6fd805e1 aliguori
            case 0: /* L1 dcache info */
1705 400281af Andre Przywara
                *eax |= 0x0000121;
1706 6fd805e1 aliguori
                *ebx = 0x1c0003f;
1707 6fd805e1 aliguori
                *ecx = 0x000003f;
1708 6fd805e1 aliguori
                *edx = 0x0000001;
1709 6fd805e1 aliguori
                break;
1710 6fd805e1 aliguori
            case 1: /* L1 icache info */
1711 400281af Andre Przywara
                *eax |= 0x0000122;
1712 6fd805e1 aliguori
                *ebx = 0x1c0003f;
1713 6fd805e1 aliguori
                *ecx = 0x000003f;
1714 6fd805e1 aliguori
                *edx = 0x0000001;
1715 6fd805e1 aliguori
                break;
1716 6fd805e1 aliguori
            case 2: /* L2 cache info */
1717 400281af Andre Przywara
                *eax |= 0x0000143;
1718 400281af Andre Przywara
                if (env->nr_threads > 1) {
1719 400281af Andre Przywara
                    *eax |= (env->nr_threads - 1) << 14;
1720 400281af Andre Przywara
                }
1721 6fd805e1 aliguori
                *ebx = 0x3c0003f;
1722 6fd805e1 aliguori
                *ecx = 0x0000fff;
1723 6fd805e1 aliguori
                *edx = 0x0000001;
1724 6fd805e1 aliguori
                break;
1725 6fd805e1 aliguori
            default: /* end of info */
1726 6fd805e1 aliguori
                *eax = 0;
1727 6fd805e1 aliguori
                *ebx = 0;
1728 6fd805e1 aliguori
                *ecx = 0;
1729 6fd805e1 aliguori
                *edx = 0;
1730 6fd805e1 aliguori
                break;
1731 6fd805e1 aliguori
        }
1732 6fd805e1 aliguori
        break;
1733 6fd805e1 aliguori
    case 5:
1734 6fd805e1 aliguori
        /* mwait info: needed for Core compatibility */
1735 6fd805e1 aliguori
        *eax = 0; /* Smallest monitor-line size in bytes */
1736 6fd805e1 aliguori
        *ebx = 0; /* Largest monitor-line size in bytes */
1737 6fd805e1 aliguori
        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
1738 6fd805e1 aliguori
        *edx = 0;
1739 6fd805e1 aliguori
        break;
1740 6fd805e1 aliguori
    case 6:
1741 6fd805e1 aliguori
        /* Thermal and Power Leaf */
1742 6fd805e1 aliguori
        *eax = 0;
1743 6fd805e1 aliguori
        *ebx = 0;
1744 6fd805e1 aliguori
        *ecx = 0;
1745 6fd805e1 aliguori
        *edx = 0;
1746 6fd805e1 aliguori
        break;
1747 6fd805e1 aliguori
    case 9:
1748 6fd805e1 aliguori
        /* Direct Cache Access Information Leaf */
1749 6fd805e1 aliguori
        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
1750 6fd805e1 aliguori
        *ebx = 0;
1751 6fd805e1 aliguori
        *ecx = 0;
1752 6fd805e1 aliguori
        *edx = 0;
1753 6fd805e1 aliguori
        break;
1754 6fd805e1 aliguori
    case 0xA:
1755 6fd805e1 aliguori
        /* Architectural Performance Monitoring Leaf */
1756 6fd805e1 aliguori
        *eax = 0;
1757 6fd805e1 aliguori
        *ebx = 0;
1758 6fd805e1 aliguori
        *ecx = 0;
1759 6fd805e1 aliguori
        *edx = 0;
1760 6fd805e1 aliguori
        break;
1761 6fd805e1 aliguori
    case 0x80000000:
1762 6fd805e1 aliguori
        *eax = env->cpuid_xlevel;
1763 6fd805e1 aliguori
        *ebx = env->cpuid_vendor1;
1764 6fd805e1 aliguori
        *edx = env->cpuid_vendor2;
1765 6fd805e1 aliguori
        *ecx = env->cpuid_vendor3;
1766 6fd805e1 aliguori
        break;
1767 6fd805e1 aliguori
    case 0x80000001:
1768 f441bee8 Andre Przywara
        *eax = env->cpuid_version;
1769 6fd805e1 aliguori
        *ebx = 0;
1770 6fd805e1 aliguori
        *ecx = env->cpuid_ext3_features;
1771 6fd805e1 aliguori
        *edx = env->cpuid_ext2_features;
1772 7ba1e619 aliguori
1773 6d9fef1a Andre Przywara
        /* The Linux kernel checks for the CMPLegacy bit and
1774 6d9fef1a Andre Przywara
         * discards multiple thread information if it is set.
1775 6d9fef1a Andre Przywara
         * So dont set it here for Intel to make Linux guests happy.
1776 6d9fef1a Andre Przywara
         */
1777 6d9fef1a Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
1778 6d9fef1a Andre Przywara
            uint32_t tebx, tecx, tedx;
1779 6d9fef1a Andre Przywara
            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
1780 6d9fef1a Andre Przywara
            if (tebx != CPUID_VENDOR_INTEL_1 ||
1781 6d9fef1a Andre Przywara
                tedx != CPUID_VENDOR_INTEL_2 ||
1782 6d9fef1a Andre Przywara
                tecx != CPUID_VENDOR_INTEL_3) {
1783 6d9fef1a Andre Przywara
                *ecx |= 1 << 1;    /* CmpLegacy bit */
1784 6d9fef1a Andre Przywara
            }
1785 400281af Andre Przywara
        }
1786 400281af Andre Przywara
1787 7ba1e619 aliguori
        if (kvm_enabled()) {
1788 f1e00a9c Andre Przywara
            /* Nested SVM not yet supported in upstream QEMU */
1789 671e4676 Andre Przywara
            *ecx &= ~CPUID_EXT3_SVM;
1790 7ba1e619 aliguori
        }
1791 6fd805e1 aliguori
        break;
1792 6fd805e1 aliguori
    case 0x80000002:
1793 6fd805e1 aliguori
    case 0x80000003:
1794 6fd805e1 aliguori
    case 0x80000004:
1795 6fd805e1 aliguori
        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
1796 6fd805e1 aliguori
        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
1797 6fd805e1 aliguori
        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
1798 6fd805e1 aliguori
        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
1799 6fd805e1 aliguori
        break;
1800 6fd805e1 aliguori
    case 0x80000005:
1801 6fd805e1 aliguori
        /* cache info (L1 cache) */
1802 6fd805e1 aliguori
        *eax = 0x01ff01ff;
1803 6fd805e1 aliguori
        *ebx = 0x01ff01ff;
1804 6fd805e1 aliguori
        *ecx = 0x40020140;
1805 6fd805e1 aliguori
        *edx = 0x40020140;
1806 6fd805e1 aliguori
        break;
1807 6fd805e1 aliguori
    case 0x80000006:
1808 6fd805e1 aliguori
        /* cache info (L2 cache) */
1809 6fd805e1 aliguori
        *eax = 0;
1810 6fd805e1 aliguori
        *ebx = 0x42004200;
1811 6fd805e1 aliguori
        *ecx = 0x02008140;
1812 6fd805e1 aliguori
        *edx = 0;
1813 6fd805e1 aliguori
        break;
1814 6fd805e1 aliguori
    case 0x80000008:
1815 6fd805e1 aliguori
        /* virtual & phys address size in low 2 bytes. */
1816 6fd805e1 aliguori
/* XXX: This value must match the one used in the MMU code. */ 
1817 6fd805e1 aliguori
        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
1818 6fd805e1 aliguori
            /* 64 bit processor */
1819 6fd805e1 aliguori
/* XXX: The physical address space is limited to 42 bits in exec.c. */
1820 6fd805e1 aliguori
            *eax = 0x00003028;        /* 48 bits virtual, 40 bits physical */
1821 6fd805e1 aliguori
        } else {
1822 6fd805e1 aliguori
            if (env->cpuid_features & CPUID_PSE36)
1823 6fd805e1 aliguori
                *eax = 0x00000024; /* 36 bits physical */
1824 6fd805e1 aliguori
            else
1825 6fd805e1 aliguori
                *eax = 0x00000020; /* 32 bits physical */
1826 6fd805e1 aliguori
        }
1827 6fd805e1 aliguori
        *ebx = 0;
1828 6fd805e1 aliguori
        *ecx = 0;
1829 6fd805e1 aliguori
        *edx = 0;
1830 400281af Andre Przywara
        if (env->nr_cores * env->nr_threads > 1) {
1831 400281af Andre Przywara
            *ecx |= (env->nr_cores * env->nr_threads) - 1;
1832 400281af Andre Przywara
        }
1833 6fd805e1 aliguori
        break;
1834 6fd805e1 aliguori
    case 0x8000000A:
1835 6fd805e1 aliguori
        *eax = 0x00000001; /* SVM Revision */
1836 6fd805e1 aliguori
        *ebx = 0x00000010; /* nr of ASIDs */
1837 6fd805e1 aliguori
        *ecx = 0;
1838 6fd805e1 aliguori
        *edx = 0; /* optional features */
1839 6fd805e1 aliguori
        break;
1840 6fd805e1 aliguori
    default:
1841 6fd805e1 aliguori
        /* reserved values: zero */
1842 6fd805e1 aliguori
        *eax = 0;
1843 6fd805e1 aliguori
        *ebx = 0;
1844 6fd805e1 aliguori
        *ecx = 0;
1845 6fd805e1 aliguori
        *edx = 0;
1846 6fd805e1 aliguori
        break;
1847 6fd805e1 aliguori
    }
1848 6fd805e1 aliguori
}
1849 01df040b aliguori
1850 84273177 Jan Kiszka
1851 84273177 Jan Kiszka
int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1852 84273177 Jan Kiszka
                            target_ulong *base, unsigned int *limit,
1853 84273177 Jan Kiszka
                            unsigned int *flags)
1854 84273177 Jan Kiszka
{
1855 84273177 Jan Kiszka
    SegmentCache *dt;
1856 84273177 Jan Kiszka
    target_ulong ptr;
1857 84273177 Jan Kiszka
    uint32_t e1, e2;
1858 84273177 Jan Kiszka
    int index;
1859 84273177 Jan Kiszka
1860 84273177 Jan Kiszka
    if (selector & 0x4)
1861 84273177 Jan Kiszka
        dt = &env->ldt;
1862 84273177 Jan Kiszka
    else
1863 84273177 Jan Kiszka
        dt = &env->gdt;
1864 84273177 Jan Kiszka
    index = selector & ~7;
1865 84273177 Jan Kiszka
    ptr = dt->base + index;
1866 84273177 Jan Kiszka
    if ((index + 7) > dt->limit
1867 84273177 Jan Kiszka
        || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1868 84273177 Jan Kiszka
        || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1869 84273177 Jan Kiszka
        return 0;
1870 84273177 Jan Kiszka
1871 84273177 Jan Kiszka
    *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1872 84273177 Jan Kiszka
    *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1873 84273177 Jan Kiszka
    if (e2 & DESC_G_MASK)
1874 84273177 Jan Kiszka
        *limit = (*limit << 12) | 0xfff;
1875 84273177 Jan Kiszka
    *flags = e2;
1876 84273177 Jan Kiszka
1877 84273177 Jan Kiszka
    return 1;
1878 84273177 Jan Kiszka
}
1879 84273177 Jan Kiszka
1880 01df040b aliguori
CPUX86State *cpu_x86_init(const char *cpu_model)
1881 01df040b aliguori
{
1882 01df040b aliguori
    CPUX86State *env;
1883 01df040b aliguori
    static int inited;
1884 01df040b aliguori
1885 01df040b aliguori
    env = qemu_mallocz(sizeof(CPUX86State));
1886 01df040b aliguori
    cpu_exec_init(env);
1887 01df040b aliguori
    env->cpu_model_str = cpu_model;
1888 01df040b aliguori
1889 01df040b aliguori
    /* init various static tables */
1890 01df040b aliguori
    if (!inited) {
1891 01df040b aliguori
        inited = 1;
1892 01df040b aliguori
        optimize_flags_init();
1893 01df040b aliguori
#ifndef CONFIG_USER_ONLY
1894 01df040b aliguori
        prev_debug_excp_handler =
1895 01df040b aliguori
            cpu_set_debug_excp_handler(breakpoint_handler);
1896 01df040b aliguori
#endif
1897 01df040b aliguori
    }
1898 01df040b aliguori
    if (cpu_x86_register(env, cpu_model) < 0) {
1899 01df040b aliguori
        cpu_x86_close(env);
1900 01df040b aliguori
        return NULL;
1901 01df040b aliguori
    }
1902 79c4f6b0 Huang Ying
    mce_init(env);
1903 0bf46a40 aliguori
1904 0bf46a40 aliguori
    qemu_init_vcpu(env);
1905 0bf46a40 aliguori
1906 01df040b aliguori
    return env;
1907 01df040b aliguori
}
1908 b09ea7d5 Gleb Natapov
1909 b09ea7d5 Gleb Natapov
#if !defined(CONFIG_USER_ONLY)
1910 b09ea7d5 Gleb Natapov
void do_cpu_init(CPUState *env)
1911 b09ea7d5 Gleb Natapov
{
1912 b09ea7d5 Gleb Natapov
    int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
1913 b09ea7d5 Gleb Natapov
    cpu_reset(env);
1914 b09ea7d5 Gleb Natapov
    env->interrupt_request = sipi;
1915 b09ea7d5 Gleb Natapov
    apic_init_reset(env);
1916 b09ea7d5 Gleb Natapov
}
1917 b09ea7d5 Gleb Natapov
1918 b09ea7d5 Gleb Natapov
void do_cpu_sipi(CPUState *env)
1919 b09ea7d5 Gleb Natapov
{
1920 b09ea7d5 Gleb Natapov
    apic_sipi(env);
1921 b09ea7d5 Gleb Natapov
}
1922 b09ea7d5 Gleb Natapov
#else
1923 b09ea7d5 Gleb Natapov
void do_cpu_init(CPUState *env)
1924 b09ea7d5 Gleb Natapov
{
1925 b09ea7d5 Gleb Natapov
}
1926 b09ea7d5 Gleb Natapov
void do_cpu_sipi(CPUState *env)
1927 b09ea7d5 Gleb Natapov
{
1928 b09ea7d5 Gleb Natapov
}
1929 b09ea7d5 Gleb Natapov
#endif