Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ 5a2e3c2e

History | View | Annotate | Download (62.6 kB)

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