Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ 109819e0

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