Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ 250b086e

History | View | Annotate | Download (40.9 kB)

1 2c0262af bellard
/*
2 eaa728ee bellard
 *  i386 helpers (without register variable usage)
3 5fafdf24 ths
 *
4 2c0262af bellard
 *  Copyright (c) 2003 Fabrice Bellard
5 2c0262af bellard
 *
6 2c0262af bellard
 * This library is free software; you can redistribute it and/or
7 2c0262af bellard
 * modify it under the terms of the GNU Lesser General Public
8 2c0262af bellard
 * License as published by the Free Software Foundation; either
9 2c0262af bellard
 * version 2 of the License, or (at your option) any later version.
10 2c0262af bellard
 *
11 2c0262af bellard
 * This library is distributed in the hope that it will be useful,
12 2c0262af bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 2c0262af bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 2c0262af bellard
 * Lesser General Public License for more details.
15 2c0262af bellard
 *
16 2c0262af bellard
 * You should have received a copy of the GNU Lesser General Public
17 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 2c0262af bellard
 */
19 2c0262af bellard
20 eaa728ee bellard
#include "cpu.h"
21 7ba1e619 aliguori
#include "kvm.h"
22 2fa11da0 Jan Kiszka
#ifndef CONFIG_USER_ONLY
23 2fa11da0 Jan Kiszka
#include "sysemu.h"
24 316378e4 Jan Kiszka
#include "monitor.h"
25 2fa11da0 Jan Kiszka
#endif
26 f3f2d9be bellard
27 eaa728ee bellard
//#define DEBUG_MMU
28 b5ec5ce0 john cooper
29 eaa728ee bellard
/* NOTE: must be called outside the CPU execute loop */
30 eaa728ee bellard
void cpu_reset(CPUX86State *env)
31 7e84c249 bellard
{
32 eaa728ee bellard
    int i;
33 7e84c249 bellard
34 eca1bdf4 aliguori
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
35 eca1bdf4 aliguori
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
36 eca1bdf4 aliguori
        log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
37 eca1bdf4 aliguori
    }
38 eca1bdf4 aliguori
39 eaa728ee bellard
    memset(env, 0, offsetof(CPUX86State, breakpoints));
40 7e84c249 bellard
41 eaa728ee bellard
    tlb_flush(env, 1);
42 7e84c249 bellard
43 eaa728ee bellard
    env->old_exception = -1;
44 7e84c249 bellard
45 eaa728ee bellard
    /* init to reset state */
46 3b46e624 ths
47 eaa728ee bellard
#ifdef CONFIG_SOFTMMU
48 eaa728ee bellard
    env->hflags |= HF_SOFTMMU_MASK;
49 2c0262af bellard
#endif
50 db620f46 bellard
    env->hflags2 |= HF2_GIF_MASK;
51 2c0262af bellard
52 eaa728ee bellard
    cpu_x86_update_cr0(env, 0x60000010);
53 eaa728ee bellard
    env->a20_mask = ~0x0;
54 eaa728ee bellard
    env->smbase = 0x30000;
55 7e84c249 bellard
56 eaa728ee bellard
    env->idt.limit = 0xffff;
57 eaa728ee bellard
    env->gdt.limit = 0xffff;
58 eaa728ee bellard
    env->ldt.limit = 0xffff;
59 262ffdae bellard
    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
60 eaa728ee bellard
    env->tr.limit = 0xffff;
61 23e6c399 aliguori
    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
62 262ffdae bellard
63 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
64 538f3686 Nitin A Kamble
                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
65 538f3686 Nitin A Kamble
                           DESC_R_MASK | DESC_A_MASK);
66 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
67 538f3686 Nitin A Kamble
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
68 538f3686 Nitin A Kamble
                           DESC_A_MASK);
69 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
70 538f3686 Nitin A Kamble
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
71 538f3686 Nitin A Kamble
                           DESC_A_MASK);
72 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
73 538f3686 Nitin A Kamble
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
74 538f3686 Nitin A Kamble
                           DESC_A_MASK);
75 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
76 538f3686 Nitin A Kamble
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
77 538f3686 Nitin A Kamble
                           DESC_A_MASK);
78 262ffdae bellard
    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
79 538f3686 Nitin A Kamble
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
80 538f3686 Nitin A Kamble
                           DESC_A_MASK);
81 7e84c249 bellard
82 eaa728ee bellard
    env->eip = 0xfff0;
83 eaa728ee bellard
    env->regs[R_EDX] = env->cpuid_version;
84 2c0262af bellard
85 eaa728ee bellard
    env->eflags = 0x2;
86 7e84c249 bellard
87 eaa728ee bellard
    /* FPU init */
88 eaa728ee bellard
    for(i = 0;i < 8; i++)
89 eaa728ee bellard
        env->fptags[i] = 1;
90 eaa728ee bellard
    env->fpuc = 0x37f;
91 7e84c249 bellard
92 eaa728ee bellard
    env->mxcsr = 0x1f80;
93 01df040b aliguori
94 ebda377f Jan Kiszka
    env->pat = 0x0007040600070406ULL;
95 21e87c46 Avi Kivity
    env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
96 ebda377f Jan Kiszka
97 01df040b aliguori
    memset(env->dr, 0, sizeof(env->dr));
98 01df040b aliguori
    env->dr[6] = DR6_FIXED_1;
99 01df040b aliguori
    env->dr[7] = DR7_FIXED_1;
100 01df040b aliguori
    cpu_breakpoint_remove_all(env, BP_CPU);
101 01df040b aliguori
    cpu_watchpoint_remove_all(env, BP_CPU);
102 eaa728ee bellard
}
103 7e84c249 bellard
104 eaa728ee bellard
void cpu_x86_close(CPUX86State *env)
105 eaa728ee bellard
{
106 7267c094 Anthony Liguori
    g_free(env);
107 eaa728ee bellard
}
108 7e84c249 bellard
109 2bd3e04c Jin Dongming
static void cpu_x86_version(CPUState *env, int *family, int *model)
110 2bd3e04c Jin Dongming
{
111 2bd3e04c Jin Dongming
    int cpuver = env->cpuid_version;
112 2bd3e04c Jin Dongming
113 2bd3e04c Jin Dongming
    if (family == NULL || model == NULL) {
114 2bd3e04c Jin Dongming
        return;
115 2bd3e04c Jin Dongming
    }
116 2bd3e04c Jin Dongming
117 2bd3e04c Jin Dongming
    *family = (cpuver >> 8) & 0x0f;
118 2bd3e04c Jin Dongming
    *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
119 2bd3e04c Jin Dongming
}
120 2bd3e04c Jin Dongming
121 2bd3e04c Jin Dongming
/* Broadcast MCA signal for processor version 06H_EH and above */
122 2bd3e04c Jin Dongming
int cpu_x86_support_mca_broadcast(CPUState *env)
123 2bd3e04c Jin Dongming
{
124 2bd3e04c Jin Dongming
    int family = 0;
125 2bd3e04c Jin Dongming
    int model = 0;
126 2bd3e04c Jin Dongming
127 2bd3e04c Jin Dongming
    cpu_x86_version(env, &family, &model);
128 2bd3e04c Jin Dongming
    if ((family == 6 && model >= 14) || family > 6) {
129 2bd3e04c Jin Dongming
        return 1;
130 2bd3e04c Jin Dongming
    }
131 2bd3e04c Jin Dongming
132 2bd3e04c Jin Dongming
    return 0;
133 2bd3e04c Jin Dongming
}
134 2bd3e04c Jin Dongming
135 eaa728ee bellard
/***********************************************************/
136 eaa728ee bellard
/* x86 debug */
137 3b46e624 ths
138 eaa728ee bellard
static const char *cc_op_str[] = {
139 eaa728ee bellard
    "DYNAMIC",
140 eaa728ee bellard
    "EFLAGS",
141 7e84c249 bellard
142 eaa728ee bellard
    "MULB",
143 eaa728ee bellard
    "MULW",
144 eaa728ee bellard
    "MULL",
145 eaa728ee bellard
    "MULQ",
146 3b46e624 ths
147 eaa728ee bellard
    "ADDB",
148 eaa728ee bellard
    "ADDW",
149 eaa728ee bellard
    "ADDL",
150 eaa728ee bellard
    "ADDQ",
151 3b46e624 ths
152 eaa728ee bellard
    "ADCB",
153 eaa728ee bellard
    "ADCW",
154 eaa728ee bellard
    "ADCL",
155 eaa728ee bellard
    "ADCQ",
156 3b46e624 ths
157 eaa728ee bellard
    "SUBB",
158 eaa728ee bellard
    "SUBW",
159 eaa728ee bellard
    "SUBL",
160 eaa728ee bellard
    "SUBQ",
161 7e84c249 bellard
162 eaa728ee bellard
    "SBBB",
163 eaa728ee bellard
    "SBBW",
164 eaa728ee bellard
    "SBBL",
165 eaa728ee bellard
    "SBBQ",
166 7e84c249 bellard
167 eaa728ee bellard
    "LOGICB",
168 eaa728ee bellard
    "LOGICW",
169 eaa728ee bellard
    "LOGICL",
170 eaa728ee bellard
    "LOGICQ",
171 7e84c249 bellard
172 eaa728ee bellard
    "INCB",
173 eaa728ee bellard
    "INCW",
174 eaa728ee bellard
    "INCL",
175 eaa728ee bellard
    "INCQ",
176 3b46e624 ths
177 eaa728ee bellard
    "DECB",
178 eaa728ee bellard
    "DECW",
179 eaa728ee bellard
    "DECL",
180 eaa728ee bellard
    "DECQ",
181 3b46e624 ths
182 eaa728ee bellard
    "SHLB",
183 eaa728ee bellard
    "SHLW",
184 eaa728ee bellard
    "SHLL",
185 eaa728ee bellard
    "SHLQ",
186 3b46e624 ths
187 eaa728ee bellard
    "SARB",
188 eaa728ee bellard
    "SARW",
189 eaa728ee bellard
    "SARL",
190 eaa728ee bellard
    "SARQ",
191 eaa728ee bellard
};
192 7e84c249 bellard
193 a3867ed2 aliguori
static void
194 9a78eead Stefan Weil
cpu_x86_dump_seg_cache(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
195 a3867ed2 aliguori
                       const char *name, struct SegmentCache *sc)
196 a3867ed2 aliguori
{
197 a3867ed2 aliguori
#ifdef TARGET_X86_64
198 a3867ed2 aliguori
    if (env->hflags & HF_CS64_MASK) {
199 a3867ed2 aliguori
        cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
200 4058fd98 Jan Kiszka
                    sc->selector, sc->base, sc->limit, sc->flags & 0x00ffff00);
201 a3867ed2 aliguori
    } else
202 a3867ed2 aliguori
#endif
203 a3867ed2 aliguori
    {
204 a3867ed2 aliguori
        cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
205 4058fd98 Jan Kiszka
                    (uint32_t)sc->base, sc->limit, sc->flags & 0x00ffff00);
206 a3867ed2 aliguori
    }
207 a3867ed2 aliguori
208 a3867ed2 aliguori
    if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
209 a3867ed2 aliguori
        goto done;
210 a3867ed2 aliguori
211 a3867ed2 aliguori
    cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
212 a3867ed2 aliguori
    if (sc->flags & DESC_S_MASK) {
213 a3867ed2 aliguori
        if (sc->flags & DESC_CS_MASK) {
214 a3867ed2 aliguori
            cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
215 a3867ed2 aliguori
                           ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
216 a3867ed2 aliguori
            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
217 a3867ed2 aliguori
                        (sc->flags & DESC_R_MASK) ? 'R' : '-');
218 a3867ed2 aliguori
        } else {
219 a3867ed2 aliguori
            cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS  " : "DS16");
220 a3867ed2 aliguori
            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
221 a3867ed2 aliguori
                        (sc->flags & DESC_W_MASK) ? 'W' : '-');
222 a3867ed2 aliguori
        }
223 a3867ed2 aliguori
        cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
224 a3867ed2 aliguori
    } else {
225 a3867ed2 aliguori
        static const char *sys_type_name[2][16] = {
226 a3867ed2 aliguori
            { /* 32 bit mode */
227 a3867ed2 aliguori
                "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
228 a3867ed2 aliguori
                "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
229 a3867ed2 aliguori
                "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
230 a3867ed2 aliguori
                "CallGate32", "Reserved", "IntGate32", "TrapGate32"
231 a3867ed2 aliguori
            },
232 a3867ed2 aliguori
            { /* 64 bit mode */
233 a3867ed2 aliguori
                "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
234 a3867ed2 aliguori
                "Reserved", "Reserved", "Reserved", "Reserved",
235 a3867ed2 aliguori
                "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
236 a3867ed2 aliguori
                "Reserved", "IntGate64", "TrapGate64"
237 a3867ed2 aliguori
            }
238 a3867ed2 aliguori
        };
239 e5c15eff Stefan Weil
        cpu_fprintf(f, "%s",
240 e5c15eff Stefan Weil
                    sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
241 e5c15eff Stefan Weil
                                 [(sc->flags & DESC_TYPE_MASK)
242 e5c15eff Stefan Weil
                                  >> DESC_TYPE_SHIFT]);
243 a3867ed2 aliguori
    }
244 a3867ed2 aliguori
done:
245 a3867ed2 aliguori
    cpu_fprintf(f, "\n");
246 a3867ed2 aliguori
}
247 a3867ed2 aliguori
248 f5c848ee Jan Kiszka
#define DUMP_CODE_BYTES_TOTAL    50
249 f5c848ee Jan Kiszka
#define DUMP_CODE_BYTES_BACKWARD 20
250 f5c848ee Jan Kiszka
251 9a78eead Stefan Weil
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
252 eaa728ee bellard
                    int flags)
253 eaa728ee bellard
{
254 eaa728ee bellard
    int eflags, i, nb;
255 eaa728ee bellard
    char cc_op_name[32];
256 eaa728ee bellard
    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
257 7e84c249 bellard
258 23054111 Jan Kiszka
    cpu_synchronize_state(env);
259 ff3c01ca balrog
260 eaa728ee bellard
    eflags = env->eflags;
261 eaa728ee bellard
#ifdef TARGET_X86_64
262 eaa728ee bellard
    if (env->hflags & HF_CS64_MASK) {
263 eaa728ee bellard
        cpu_fprintf(f,
264 eaa728ee bellard
                    "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
265 eaa728ee bellard
                    "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
266 eaa728ee bellard
                    "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
267 eaa728ee bellard
                    "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
268 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",
269 eaa728ee bellard
                    env->regs[R_EAX],
270 eaa728ee bellard
                    env->regs[R_EBX],
271 eaa728ee bellard
                    env->regs[R_ECX],
272 eaa728ee bellard
                    env->regs[R_EDX],
273 eaa728ee bellard
                    env->regs[R_ESI],
274 eaa728ee bellard
                    env->regs[R_EDI],
275 eaa728ee bellard
                    env->regs[R_EBP],
276 eaa728ee bellard
                    env->regs[R_ESP],
277 eaa728ee bellard
                    env->regs[8],
278 eaa728ee bellard
                    env->regs[9],
279 eaa728ee bellard
                    env->regs[10],
280 eaa728ee bellard
                    env->regs[11],
281 eaa728ee bellard
                    env->regs[12],
282 eaa728ee bellard
                    env->regs[13],
283 eaa728ee bellard
                    env->regs[14],
284 eaa728ee bellard
                    env->regs[15],
285 eaa728ee bellard
                    env->eip, eflags,
286 eaa728ee bellard
                    eflags & DF_MASK ? 'D' : '-',
287 eaa728ee bellard
                    eflags & CC_O ? 'O' : '-',
288 eaa728ee bellard
                    eflags & CC_S ? 'S' : '-',
289 eaa728ee bellard
                    eflags & CC_Z ? 'Z' : '-',
290 eaa728ee bellard
                    eflags & CC_A ? 'A' : '-',
291 eaa728ee bellard
                    eflags & CC_P ? 'P' : '-',
292 eaa728ee bellard
                    eflags & CC_C ? 'C' : '-',
293 eaa728ee bellard
                    env->hflags & HF_CPL_MASK,
294 eaa728ee bellard
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
295 5ee0ffaa Juan Quintela
                    (env->a20_mask >> 20) & 1,
296 eaa728ee bellard
                    (env->hflags >> HF_SMM_SHIFT) & 1,
297 ce5232c5 bellard
                    env->halted);
298 eaa728ee bellard
    } else
299 eaa728ee bellard
#endif
300 eaa728ee bellard
    {
301 eaa728ee bellard
        cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
302 eaa728ee bellard
                    "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
303 eaa728ee bellard
                    "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
304 eaa728ee bellard
                    (uint32_t)env->regs[R_EAX],
305 eaa728ee bellard
                    (uint32_t)env->regs[R_EBX],
306 eaa728ee bellard
                    (uint32_t)env->regs[R_ECX],
307 eaa728ee bellard
                    (uint32_t)env->regs[R_EDX],
308 eaa728ee bellard
                    (uint32_t)env->regs[R_ESI],
309 eaa728ee bellard
                    (uint32_t)env->regs[R_EDI],
310 eaa728ee bellard
                    (uint32_t)env->regs[R_EBP],
311 eaa728ee bellard
                    (uint32_t)env->regs[R_ESP],
312 eaa728ee bellard
                    (uint32_t)env->eip, eflags,
313 eaa728ee bellard
                    eflags & DF_MASK ? 'D' : '-',
314 eaa728ee bellard
                    eflags & CC_O ? 'O' : '-',
315 eaa728ee bellard
                    eflags & CC_S ? 'S' : '-',
316 eaa728ee bellard
                    eflags & CC_Z ? 'Z' : '-',
317 eaa728ee bellard
                    eflags & CC_A ? 'A' : '-',
318 eaa728ee bellard
                    eflags & CC_P ? 'P' : '-',
319 eaa728ee bellard
                    eflags & CC_C ? 'C' : '-',
320 eaa728ee bellard
                    env->hflags & HF_CPL_MASK,
321 eaa728ee bellard
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
322 5ee0ffaa Juan Quintela
                    (env->a20_mask >> 20) & 1,
323 eaa728ee bellard
                    (env->hflags >> HF_SMM_SHIFT) & 1,
324 ce5232c5 bellard
                    env->halted);
325 8145122b bellard
    }
326 3b46e624 ths
327 a3867ed2 aliguori
    for(i = 0; i < 6; i++) {
328 a3867ed2 aliguori
        cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
329 a3867ed2 aliguori
                               &env->segs[i]);
330 a3867ed2 aliguori
    }
331 a3867ed2 aliguori
    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
332 a3867ed2 aliguori
    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
333 a3867ed2 aliguori
334 eaa728ee bellard
#ifdef TARGET_X86_64
335 eaa728ee bellard
    if (env->hflags & HF_LMA_MASK) {
336 eaa728ee bellard
        cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
337 eaa728ee bellard
                    env->gdt.base, env->gdt.limit);
338 eaa728ee bellard
        cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
339 eaa728ee bellard
                    env->idt.base, env->idt.limit);
340 eaa728ee bellard
        cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
341 eaa728ee bellard
                    (uint32_t)env->cr[0],
342 eaa728ee bellard
                    env->cr[2],
343 eaa728ee bellard
                    env->cr[3],
344 eaa728ee bellard
                    (uint32_t)env->cr[4]);
345 a59cb4e0 aliguori
        for(i = 0; i < 4; i++)
346 a59cb4e0 aliguori
            cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
347 a59cb4e0 aliguori
        cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
348 d4b55be5 aliguori
                    env->dr[6], env->dr[7]);
349 eaa728ee bellard
    } else
350 eaa728ee bellard
#endif
351 eaa728ee bellard
    {
352 eaa728ee bellard
        cpu_fprintf(f, "GDT=     %08x %08x\n",
353 eaa728ee bellard
                    (uint32_t)env->gdt.base, env->gdt.limit);
354 eaa728ee bellard
        cpu_fprintf(f, "IDT=     %08x %08x\n",
355 eaa728ee bellard
                    (uint32_t)env->idt.base, env->idt.limit);
356 eaa728ee bellard
        cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
357 eaa728ee bellard
                    (uint32_t)env->cr[0],
358 eaa728ee bellard
                    (uint32_t)env->cr[2],
359 eaa728ee bellard
                    (uint32_t)env->cr[3],
360 eaa728ee bellard
                    (uint32_t)env->cr[4]);
361 9a78eead Stefan Weil
        for(i = 0; i < 4; i++) {
362 9a78eead Stefan Weil
            cpu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
363 9a78eead Stefan Weil
        }
364 9a78eead Stefan Weil
        cpu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
365 9a78eead Stefan Weil
                    env->dr[6], env->dr[7]);
366 eaa728ee bellard
    }
367 eaa728ee bellard
    if (flags & X86_DUMP_CCOP) {
368 eaa728ee bellard
        if ((unsigned)env->cc_op < CC_OP_NB)
369 eaa728ee bellard
            snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
370 eaa728ee bellard
        else
371 eaa728ee bellard
            snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
372 eaa728ee bellard
#ifdef TARGET_X86_64
373 eaa728ee bellard
        if (env->hflags & HF_CS64_MASK) {
374 eaa728ee bellard
            cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
375 eaa728ee bellard
                        env->cc_src, env->cc_dst,
376 eaa728ee bellard
                        cc_op_name);
377 eaa728ee bellard
        } else
378 eaa728ee bellard
#endif
379 eaa728ee bellard
        {
380 eaa728ee bellard
            cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
381 eaa728ee bellard
                        (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
382 eaa728ee bellard
                        cc_op_name);
383 eaa728ee bellard
        }
384 7e84c249 bellard
    }
385 b5e5a934 Marcelo Tosatti
    cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
386 eaa728ee bellard
    if (flags & X86_DUMP_FPU) {
387 eaa728ee bellard
        int fptag;
388 eaa728ee bellard
        fptag = 0;
389 eaa728ee bellard
        for(i = 0; i < 8; i++) {
390 eaa728ee bellard
            fptag |= ((!env->fptags[i]) << i);
391 eaa728ee bellard
        }
392 eaa728ee bellard
        cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
393 eaa728ee bellard
                    env->fpuc,
394 eaa728ee bellard
                    (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
395 eaa728ee bellard
                    env->fpstt,
396 eaa728ee bellard
                    fptag,
397 eaa728ee bellard
                    env->mxcsr);
398 eaa728ee bellard
        for(i=0;i<8;i++) {
399 1ffd41ee Aurelien Jarno
            CPU_LDoubleU u;
400 1ffd41ee Aurelien Jarno
            u.d = env->fpregs[i].d;
401 eaa728ee bellard
            cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
402 1ffd41ee Aurelien Jarno
                        i, u.l.lower, u.l.upper);
403 eaa728ee bellard
            if ((i & 1) == 1)
404 eaa728ee bellard
                cpu_fprintf(f, "\n");
405 eaa728ee bellard
            else
406 eaa728ee bellard
                cpu_fprintf(f, " ");
407 eaa728ee bellard
        }
408 eaa728ee bellard
        if (env->hflags & HF_CS64_MASK)
409 eaa728ee bellard
            nb = 16;
410 eaa728ee bellard
        else
411 eaa728ee bellard
            nb = 8;
412 eaa728ee bellard
        for(i=0;i<nb;i++) {
413 eaa728ee bellard
            cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
414 eaa728ee bellard
                        i,
415 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(3),
416 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(2),
417 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(1),
418 eaa728ee bellard
                        env->xmm_regs[i].XMM_L(0));
419 eaa728ee bellard
            if ((i & 1) == 1)
420 eaa728ee bellard
                cpu_fprintf(f, "\n");
421 eaa728ee bellard
            else
422 eaa728ee bellard
                cpu_fprintf(f, " ");
423 eaa728ee bellard
        }
424 7e84c249 bellard
    }
425 f5c848ee Jan Kiszka
    if (flags & CPU_DUMP_CODE) {
426 f5c848ee Jan Kiszka
        target_ulong base = env->segs[R_CS].base + env->eip;
427 f5c848ee Jan Kiszka
        target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
428 f5c848ee Jan Kiszka
        uint8_t code;
429 f5c848ee Jan Kiszka
        char codestr[3];
430 f5c848ee Jan Kiszka
431 f5c848ee Jan Kiszka
        cpu_fprintf(f, "Code=");
432 f5c848ee Jan Kiszka
        for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
433 f5c848ee Jan Kiszka
            if (cpu_memory_rw_debug(env, base - offs + i, &code, 1, 0) == 0) {
434 f5c848ee Jan Kiszka
                snprintf(codestr, sizeof(codestr), "%02x", code);
435 f5c848ee Jan Kiszka
            } else {
436 f5c848ee Jan Kiszka
                snprintf(codestr, sizeof(codestr), "??");
437 f5c848ee Jan Kiszka
            }
438 f5c848ee Jan Kiszka
            cpu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
439 f5c848ee Jan Kiszka
                        i == offs ? "<" : "", codestr, i == offs ? ">" : "");
440 f5c848ee Jan Kiszka
        }
441 f5c848ee Jan Kiszka
        cpu_fprintf(f, "\n");
442 f5c848ee Jan Kiszka
    }
443 2c0262af bellard
}
444 7e84c249 bellard
445 eaa728ee bellard
/***********************************************************/
446 eaa728ee bellard
/* x86 mmu */
447 eaa728ee bellard
/* XXX: add PGE support */
448 eaa728ee bellard
449 eaa728ee bellard
void cpu_x86_set_a20(CPUX86State *env, int a20_state)
450 2c0262af bellard
{
451 eaa728ee bellard
    a20_state = (a20_state != 0);
452 eaa728ee bellard
    if (a20_state != ((env->a20_mask >> 20) & 1)) {
453 eaa728ee bellard
#if defined(DEBUG_MMU)
454 eaa728ee bellard
        printf("A20 update: a20=%d\n", a20_state);
455 eaa728ee bellard
#endif
456 eaa728ee bellard
        /* if the cpu is currently executing code, we must unlink it and
457 eaa728ee bellard
           all the potentially executing TB */
458 eaa728ee bellard
        cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
459 3b46e624 ths
460 eaa728ee bellard
        /* when a20 is changed, all the MMU mappings are invalid, so
461 eaa728ee bellard
           we must flush everything */
462 eaa728ee bellard
        tlb_flush(env, 1);
463 5ee0ffaa Juan Quintela
        env->a20_mask = ~(1 << 20) | (a20_state << 20);
464 7e84c249 bellard
    }
465 2c0262af bellard
}
466 2c0262af bellard
467 eaa728ee bellard
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
468 2c0262af bellard
{
469 eaa728ee bellard
    int pe_state;
470 2c0262af bellard
471 eaa728ee bellard
#if defined(DEBUG_MMU)
472 eaa728ee bellard
    printf("CR0 update: CR0=0x%08x\n", new_cr0);
473 eaa728ee bellard
#endif
474 eaa728ee bellard
    if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
475 eaa728ee bellard
        (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
476 eaa728ee bellard
        tlb_flush(env, 1);
477 eaa728ee bellard
    }
478 2c0262af bellard
479 eaa728ee bellard
#ifdef TARGET_X86_64
480 eaa728ee bellard
    if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
481 eaa728ee bellard
        (env->efer & MSR_EFER_LME)) {
482 eaa728ee bellard
        /* enter in long mode */
483 eaa728ee bellard
        /* XXX: generate an exception */
484 eaa728ee bellard
        if (!(env->cr[4] & CR4_PAE_MASK))
485 eaa728ee bellard
            return;
486 eaa728ee bellard
        env->efer |= MSR_EFER_LMA;
487 eaa728ee bellard
        env->hflags |= HF_LMA_MASK;
488 eaa728ee bellard
    } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
489 eaa728ee bellard
               (env->efer & MSR_EFER_LMA)) {
490 eaa728ee bellard
        /* exit long mode */
491 eaa728ee bellard
        env->efer &= ~MSR_EFER_LMA;
492 eaa728ee bellard
        env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
493 eaa728ee bellard
        env->eip &= 0xffffffff;
494 eaa728ee bellard
    }
495 eaa728ee bellard
#endif
496 eaa728ee bellard
    env->cr[0] = new_cr0 | CR0_ET_MASK;
497 7e84c249 bellard
498 eaa728ee bellard
    /* update PE flag in hidden flags */
499 eaa728ee bellard
    pe_state = (env->cr[0] & CR0_PE_MASK);
500 eaa728ee bellard
    env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
501 eaa728ee bellard
    /* ensure that ADDSEG is always set in real mode */
502 eaa728ee bellard
    env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
503 eaa728ee bellard
    /* update FPU flags */
504 eaa728ee bellard
    env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
505 eaa728ee bellard
        ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
506 7e84c249 bellard
}
507 7e84c249 bellard
508 eaa728ee bellard
/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
509 eaa728ee bellard
   the PDPT */
510 eaa728ee bellard
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
511 7e84c249 bellard
{
512 eaa728ee bellard
    env->cr[3] = new_cr3;
513 eaa728ee bellard
    if (env->cr[0] & CR0_PG_MASK) {
514 eaa728ee bellard
#if defined(DEBUG_MMU)
515 eaa728ee bellard
        printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
516 eaa728ee bellard
#endif
517 eaa728ee bellard
        tlb_flush(env, 0);
518 eaa728ee bellard
    }
519 7e84c249 bellard
}
520 7e84c249 bellard
521 eaa728ee bellard
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
522 7e84c249 bellard
{
523 eaa728ee bellard
#if defined(DEBUG_MMU)
524 eaa728ee bellard
    printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
525 eaa728ee bellard
#endif
526 eaa728ee bellard
    if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
527 eaa728ee bellard
        (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
528 eaa728ee bellard
        tlb_flush(env, 1);
529 eaa728ee bellard
    }
530 eaa728ee bellard
    /* SSE handling */
531 eaa728ee bellard
    if (!(env->cpuid_features & CPUID_SSE))
532 eaa728ee bellard
        new_cr4 &= ~CR4_OSFXSR_MASK;
533 eaa728ee bellard
    if (new_cr4 & CR4_OSFXSR_MASK)
534 eaa728ee bellard
        env->hflags |= HF_OSFXSR_MASK;
535 eaa728ee bellard
    else
536 eaa728ee bellard
        env->hflags &= ~HF_OSFXSR_MASK;
537 b8b6a50b bellard
538 eaa728ee bellard
    env->cr[4] = new_cr4;
539 b8b6a50b bellard
}
540 b8b6a50b bellard
541 eaa728ee bellard
#if defined(CONFIG_USER_ONLY)
542 eaa728ee bellard
543 eaa728ee bellard
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
544 97b348e7 Blue Swirl
                             int is_write, int mmu_idx)
545 b8b6a50b bellard
{
546 eaa728ee bellard
    /* user mode only emulation */
547 eaa728ee bellard
    is_write &= 1;
548 eaa728ee bellard
    env->cr[2] = addr;
549 eaa728ee bellard
    env->error_code = (is_write << PG_ERROR_W_BIT);
550 eaa728ee bellard
    env->error_code |= PG_ERROR_U_MASK;
551 eaa728ee bellard
    env->exception_index = EXCP0E_PAGE;
552 eaa728ee bellard
    return 1;
553 2c0262af bellard
}
554 2c0262af bellard
555 8d7b0fbb bellard
#else
556 891b38e4 bellard
557 eaa728ee bellard
/* XXX: This value should match the one returned by CPUID
558 eaa728ee bellard
 * and in exec.c */
559 eaa728ee bellard
# if defined(TARGET_X86_64)
560 2c90d794 ths
# define PHYS_ADDR_MASK 0xfffffff000LL
561 eaa728ee bellard
# else
562 2c90d794 ths
# define PHYS_ADDR_MASK 0xffffff000LL
563 eaa728ee bellard
# endif
564 eaa728ee bellard
565 eaa728ee bellard
/* return value:
566 eaa728ee bellard
   -1 = cannot handle fault
567 eaa728ee bellard
   0  = nothing more to do
568 eaa728ee bellard
   1  = generate PF fault
569 eaa728ee bellard
*/
570 eaa728ee bellard
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
571 97b348e7 Blue Swirl
                             int is_write1, int mmu_idx)
572 eaa728ee bellard
{
573 eaa728ee bellard
    uint64_t ptep, pte;
574 eaa728ee bellard
    target_ulong pde_addr, pte_addr;
575 d4c430a8 Paul Brook
    int error_code, is_dirty, prot, page_size, is_write, is_user;
576 c227f099 Anthony Liguori
    target_phys_addr_t paddr;
577 eaa728ee bellard
    uint32_t page_offset;
578 eaa728ee bellard
    target_ulong vaddr, virt_addr;
579 eaa728ee bellard
580 eaa728ee bellard
    is_user = mmu_idx == MMU_USER_IDX;
581 eaa728ee bellard
#if defined(DEBUG_MMU)
582 eaa728ee bellard
    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
583 eaa728ee bellard
           addr, is_write1, is_user, env->eip);
584 eaa728ee bellard
#endif
585 eaa728ee bellard
    is_write = is_write1 & 1;
586 eaa728ee bellard
587 eaa728ee bellard
    if (!(env->cr[0] & CR0_PG_MASK)) {
588 eaa728ee bellard
        pte = addr;
589 eaa728ee bellard
        virt_addr = addr & TARGET_PAGE_MASK;
590 eaa728ee bellard
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
591 eaa728ee bellard
        page_size = 4096;
592 eaa728ee bellard
        goto do_mapping;
593 eaa728ee bellard
    }
594 eaa728ee bellard
595 eaa728ee bellard
    if (env->cr[4] & CR4_PAE_MASK) {
596 eaa728ee bellard
        uint64_t pde, pdpe;
597 eaa728ee bellard
        target_ulong pdpe_addr;
598 2c0262af bellard
599 eaa728ee bellard
#ifdef TARGET_X86_64
600 eaa728ee bellard
        if (env->hflags & HF_LMA_MASK) {
601 eaa728ee bellard
            uint64_t pml4e_addr, pml4e;
602 eaa728ee bellard
            int32_t sext;
603 eaa728ee bellard
604 eaa728ee bellard
            /* test virtual address sign extension */
605 eaa728ee bellard
            sext = (int64_t)addr >> 47;
606 eaa728ee bellard
            if (sext != 0 && sext != -1) {
607 eaa728ee bellard
                env->error_code = 0;
608 eaa728ee bellard
                env->exception_index = EXCP0D_GPF;
609 eaa728ee bellard
                return 1;
610 eaa728ee bellard
            }
611 0573fbfc ths
612 eaa728ee bellard
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
613 eaa728ee bellard
                env->a20_mask;
614 eaa728ee bellard
            pml4e = ldq_phys(pml4e_addr);
615 eaa728ee bellard
            if (!(pml4e & PG_PRESENT_MASK)) {
616 eaa728ee bellard
                error_code = 0;
617 eaa728ee bellard
                goto do_fault;
618 eaa728ee bellard
            }
619 eaa728ee bellard
            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
620 eaa728ee bellard
                error_code = PG_ERROR_RSVD_MASK;
621 eaa728ee bellard
                goto do_fault;
622 eaa728ee bellard
            }
623 eaa728ee bellard
            if (!(pml4e & PG_ACCESSED_MASK)) {
624 eaa728ee bellard
                pml4e |= PG_ACCESSED_MASK;
625 eaa728ee bellard
                stl_phys_notdirty(pml4e_addr, pml4e);
626 eaa728ee bellard
            }
627 eaa728ee bellard
            ptep = pml4e ^ PG_NX_MASK;
628 eaa728ee bellard
            pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
629 eaa728ee bellard
                env->a20_mask;
630 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
631 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK)) {
632 eaa728ee bellard
                error_code = 0;
633 eaa728ee bellard
                goto do_fault;
634 eaa728ee bellard
            }
635 eaa728ee bellard
            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
636 eaa728ee bellard
                error_code = PG_ERROR_RSVD_MASK;
637 eaa728ee bellard
                goto do_fault;
638 eaa728ee bellard
            }
639 eaa728ee bellard
            ptep &= pdpe ^ PG_NX_MASK;
640 eaa728ee bellard
            if (!(pdpe & PG_ACCESSED_MASK)) {
641 eaa728ee bellard
                pdpe |= PG_ACCESSED_MASK;
642 eaa728ee bellard
                stl_phys_notdirty(pdpe_addr, pdpe);
643 eaa728ee bellard
            }
644 eaa728ee bellard
        } else
645 eaa728ee bellard
#endif
646 eaa728ee bellard
        {
647 eaa728ee bellard
            /* XXX: load them when cr3 is loaded ? */
648 eaa728ee bellard
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
649 eaa728ee bellard
                env->a20_mask;
650 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
651 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK)) {
652 eaa728ee bellard
                error_code = 0;
653 eaa728ee bellard
                goto do_fault;
654 eaa728ee bellard
            }
655 eaa728ee bellard
            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
656 7e84c249 bellard
        }
657 7e84c249 bellard
658 eaa728ee bellard
        pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
659 eaa728ee bellard
            env->a20_mask;
660 eaa728ee bellard
        pde = ldq_phys(pde_addr);
661 eaa728ee bellard
        if (!(pde & PG_PRESENT_MASK)) {
662 eaa728ee bellard
            error_code = 0;
663 eaa728ee bellard
            goto do_fault;
664 eaa728ee bellard
        }
665 eaa728ee bellard
        if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
666 eaa728ee bellard
            error_code = PG_ERROR_RSVD_MASK;
667 eaa728ee bellard
            goto do_fault;
668 eaa728ee bellard
        }
669 eaa728ee bellard
        ptep &= pde ^ PG_NX_MASK;
670 eaa728ee bellard
        if (pde & PG_PSE_MASK) {
671 eaa728ee bellard
            /* 2 MB page */
672 eaa728ee bellard
            page_size = 2048 * 1024;
673 eaa728ee bellard
            ptep ^= PG_NX_MASK;
674 eaa728ee bellard
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
675 eaa728ee bellard
                goto do_fault_protect;
676 eaa728ee bellard
            if (is_user) {
677 eaa728ee bellard
                if (!(ptep & PG_USER_MASK))
678 eaa728ee bellard
                    goto do_fault_protect;
679 eaa728ee bellard
                if (is_write && !(ptep & PG_RW_MASK))
680 eaa728ee bellard
                    goto do_fault_protect;
681 eaa728ee bellard
            } else {
682 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
683 eaa728ee bellard
                    is_write && !(ptep & PG_RW_MASK))
684 eaa728ee bellard
                    goto do_fault_protect;
685 eaa728ee bellard
            }
686 eaa728ee bellard
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
687 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
688 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
689 eaa728ee bellard
                if (is_dirty)
690 eaa728ee bellard
                    pde |= PG_DIRTY_MASK;
691 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
692 eaa728ee bellard
            }
693 eaa728ee bellard
            /* align to page_size */
694 eaa728ee bellard
            pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
695 eaa728ee bellard
            virt_addr = addr & ~(page_size - 1);
696 eaa728ee bellard
        } else {
697 eaa728ee bellard
            /* 4 KB page */
698 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK)) {
699 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
700 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
701 eaa728ee bellard
            }
702 eaa728ee bellard
            pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
703 eaa728ee bellard
                env->a20_mask;
704 eaa728ee bellard
            pte = ldq_phys(pte_addr);
705 eaa728ee bellard
            if (!(pte & PG_PRESENT_MASK)) {
706 eaa728ee bellard
                error_code = 0;
707 eaa728ee bellard
                goto do_fault;
708 eaa728ee bellard
            }
709 eaa728ee bellard
            if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
710 eaa728ee bellard
                error_code = PG_ERROR_RSVD_MASK;
711 eaa728ee bellard
                goto do_fault;
712 eaa728ee bellard
            }
713 eaa728ee bellard
            /* combine pde and pte nx, user and rw protections */
714 eaa728ee bellard
            ptep &= pte ^ PG_NX_MASK;
715 eaa728ee bellard
            ptep ^= PG_NX_MASK;
716 eaa728ee bellard
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
717 eaa728ee bellard
                goto do_fault_protect;
718 eaa728ee bellard
            if (is_user) {
719 eaa728ee bellard
                if (!(ptep & PG_USER_MASK))
720 eaa728ee bellard
                    goto do_fault_protect;
721 eaa728ee bellard
                if (is_write && !(ptep & PG_RW_MASK))
722 eaa728ee bellard
                    goto do_fault_protect;
723 eaa728ee bellard
            } else {
724 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
725 eaa728ee bellard
                    is_write && !(ptep & PG_RW_MASK))
726 eaa728ee bellard
                    goto do_fault_protect;
727 eaa728ee bellard
            }
728 eaa728ee bellard
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
729 eaa728ee bellard
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
730 eaa728ee bellard
                pte |= PG_ACCESSED_MASK;
731 eaa728ee bellard
                if (is_dirty)
732 eaa728ee bellard
                    pte |= PG_DIRTY_MASK;
733 eaa728ee bellard
                stl_phys_notdirty(pte_addr, pte);
734 eaa728ee bellard
            }
735 eaa728ee bellard
            page_size = 4096;
736 eaa728ee bellard
            virt_addr = addr & ~0xfff;
737 eaa728ee bellard
            pte = pte & (PHYS_ADDR_MASK | 0xfff);
738 7e84c249 bellard
        }
739 2c0262af bellard
    } else {
740 eaa728ee bellard
        uint32_t pde;
741 eaa728ee bellard
742 eaa728ee bellard
        /* page directory entry */
743 eaa728ee bellard
        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
744 eaa728ee bellard
            env->a20_mask;
745 eaa728ee bellard
        pde = ldl_phys(pde_addr);
746 eaa728ee bellard
        if (!(pde & PG_PRESENT_MASK)) {
747 eaa728ee bellard
            error_code = 0;
748 eaa728ee bellard
            goto do_fault;
749 eaa728ee bellard
        }
750 eaa728ee bellard
        /* if PSE bit is set, then we use a 4MB page */
751 eaa728ee bellard
        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
752 eaa728ee bellard
            page_size = 4096 * 1024;
753 eaa728ee bellard
            if (is_user) {
754 eaa728ee bellard
                if (!(pde & PG_USER_MASK))
755 eaa728ee bellard
                    goto do_fault_protect;
756 eaa728ee bellard
                if (is_write && !(pde & PG_RW_MASK))
757 eaa728ee bellard
                    goto do_fault_protect;
758 eaa728ee bellard
            } else {
759 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
760 eaa728ee bellard
                    is_write && !(pde & PG_RW_MASK))
761 eaa728ee bellard
                    goto do_fault_protect;
762 eaa728ee bellard
            }
763 eaa728ee bellard
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
764 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
765 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
766 eaa728ee bellard
                if (is_dirty)
767 eaa728ee bellard
                    pde |= PG_DIRTY_MASK;
768 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
769 eaa728ee bellard
            }
770 2c0262af bellard
771 eaa728ee bellard
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
772 eaa728ee bellard
            ptep = pte;
773 eaa728ee bellard
            virt_addr = addr & ~(page_size - 1);
774 eaa728ee bellard
        } else {
775 eaa728ee bellard
            if (!(pde & PG_ACCESSED_MASK)) {
776 eaa728ee bellard
                pde |= PG_ACCESSED_MASK;
777 eaa728ee bellard
                stl_phys_notdirty(pde_addr, pde);
778 eaa728ee bellard
            }
779 891b38e4 bellard
780 eaa728ee bellard
            /* page directory entry */
781 eaa728ee bellard
            pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
782 eaa728ee bellard
                env->a20_mask;
783 eaa728ee bellard
            pte = ldl_phys(pte_addr);
784 eaa728ee bellard
            if (!(pte & PG_PRESENT_MASK)) {
785 eaa728ee bellard
                error_code = 0;
786 eaa728ee bellard
                goto do_fault;
787 8e682019 bellard
            }
788 eaa728ee bellard
            /* combine pde and pte user and rw protections */
789 eaa728ee bellard
            ptep = pte & pde;
790 eaa728ee bellard
            if (is_user) {
791 eaa728ee bellard
                if (!(ptep & PG_USER_MASK))
792 eaa728ee bellard
                    goto do_fault_protect;
793 eaa728ee bellard
                if (is_write && !(ptep & PG_RW_MASK))
794 eaa728ee bellard
                    goto do_fault_protect;
795 eaa728ee bellard
            } else {
796 eaa728ee bellard
                if ((env->cr[0] & CR0_WP_MASK) &&
797 eaa728ee bellard
                    is_write && !(ptep & PG_RW_MASK))
798 eaa728ee bellard
                    goto do_fault_protect;
799 8e682019 bellard
            }
800 eaa728ee bellard
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
801 eaa728ee bellard
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
802 eaa728ee bellard
                pte |= PG_ACCESSED_MASK;
803 eaa728ee bellard
                if (is_dirty)
804 eaa728ee bellard
                    pte |= PG_DIRTY_MASK;
805 eaa728ee bellard
                stl_phys_notdirty(pte_addr, pte);
806 eaa728ee bellard
            }
807 eaa728ee bellard
            page_size = 4096;
808 eaa728ee bellard
            virt_addr = addr & ~0xfff;
809 2c0262af bellard
        }
810 2c0262af bellard
    }
811 eaa728ee bellard
    /* the page can be put in the TLB */
812 eaa728ee bellard
    prot = PAGE_READ;
813 eaa728ee bellard
    if (!(ptep & PG_NX_MASK))
814 eaa728ee bellard
        prot |= PAGE_EXEC;
815 eaa728ee bellard
    if (pte & PG_DIRTY_MASK) {
816 eaa728ee bellard
        /* only set write access if already dirty... otherwise wait
817 eaa728ee bellard
           for dirty access */
818 eaa728ee bellard
        if (is_user) {
819 eaa728ee bellard
            if (ptep & PG_RW_MASK)
820 eaa728ee bellard
                prot |= PAGE_WRITE;
821 eaa728ee bellard
        } else {
822 eaa728ee bellard
            if (!(env->cr[0] & CR0_WP_MASK) ||
823 eaa728ee bellard
                (ptep & PG_RW_MASK))
824 eaa728ee bellard
                prot |= PAGE_WRITE;
825 8e682019 bellard
        }
826 891b38e4 bellard
    }
827 eaa728ee bellard
 do_mapping:
828 eaa728ee bellard
    pte = pte & env->a20_mask;
829 eaa728ee bellard
830 eaa728ee bellard
    /* Even if 4MB pages, we map only one 4KB page in the cache to
831 eaa728ee bellard
       avoid filling it too fast */
832 eaa728ee bellard
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
833 eaa728ee bellard
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
834 eaa728ee bellard
    vaddr = virt_addr + page_offset;
835 eaa728ee bellard
836 d4c430a8 Paul Brook
    tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
837 d4c430a8 Paul Brook
    return 0;
838 eaa728ee bellard
 do_fault_protect:
839 eaa728ee bellard
    error_code = PG_ERROR_P_MASK;
840 eaa728ee bellard
 do_fault:
841 eaa728ee bellard
    error_code |= (is_write << PG_ERROR_W_BIT);
842 eaa728ee bellard
    if (is_user)
843 eaa728ee bellard
        error_code |= PG_ERROR_U_MASK;
844 eaa728ee bellard
    if (is_write1 == 2 &&
845 eaa728ee bellard
        (env->efer & MSR_EFER_NXE) &&
846 eaa728ee bellard
        (env->cr[4] & CR4_PAE_MASK))
847 eaa728ee bellard
        error_code |= PG_ERROR_I_D_MASK;
848 872929aa bellard
    if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
849 872929aa bellard
        /* cr2 is not modified in case of exceptions */
850 872929aa bellard
        stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 
851 872929aa bellard
                 addr);
852 eaa728ee bellard
    } else {
853 eaa728ee bellard
        env->cr[2] = addr;
854 2c0262af bellard
    }
855 eaa728ee bellard
    env->error_code = error_code;
856 eaa728ee bellard
    env->exception_index = EXCP0E_PAGE;
857 eaa728ee bellard
    return 1;
858 14ce26e7 bellard
}
859 14ce26e7 bellard
860 c227f099 Anthony Liguori
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
861 14ce26e7 bellard
{
862 eaa728ee bellard
    target_ulong pde_addr, pte_addr;
863 eaa728ee bellard
    uint64_t pte;
864 c227f099 Anthony Liguori
    target_phys_addr_t paddr;
865 eaa728ee bellard
    uint32_t page_offset;
866 eaa728ee bellard
    int page_size;
867 14ce26e7 bellard
868 eaa728ee bellard
    if (env->cr[4] & CR4_PAE_MASK) {
869 eaa728ee bellard
        target_ulong pdpe_addr;
870 eaa728ee bellard
        uint64_t pde, pdpe;
871 14ce26e7 bellard
872 eaa728ee bellard
#ifdef TARGET_X86_64
873 eaa728ee bellard
        if (env->hflags & HF_LMA_MASK) {
874 eaa728ee bellard
            uint64_t pml4e_addr, pml4e;
875 eaa728ee bellard
            int32_t sext;
876 eaa728ee bellard
877 eaa728ee bellard
            /* test virtual address sign extension */
878 eaa728ee bellard
            sext = (int64_t)addr >> 47;
879 eaa728ee bellard
            if (sext != 0 && sext != -1)
880 eaa728ee bellard
                return -1;
881 eaa728ee bellard
882 eaa728ee bellard
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
883 eaa728ee bellard
                env->a20_mask;
884 eaa728ee bellard
            pml4e = ldq_phys(pml4e_addr);
885 eaa728ee bellard
            if (!(pml4e & PG_PRESENT_MASK))
886 eaa728ee bellard
                return -1;
887 eaa728ee bellard
888 3f2cbf0d Jan Kiszka
            pdpe_addr = ((pml4e & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
889 3f2cbf0d Jan Kiszka
                         (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
890 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
891 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK))
892 eaa728ee bellard
                return -1;
893 eaa728ee bellard
        } else
894 eaa728ee bellard
#endif
895 eaa728ee bellard
        {
896 eaa728ee bellard
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
897 eaa728ee bellard
                env->a20_mask;
898 eaa728ee bellard
            pdpe = ldq_phys(pdpe_addr);
899 eaa728ee bellard
            if (!(pdpe & PG_PRESENT_MASK))
900 eaa728ee bellard
                return -1;
901 14ce26e7 bellard
        }
902 14ce26e7 bellard
903 3f2cbf0d Jan Kiszka
        pde_addr = ((pdpe & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
904 3f2cbf0d Jan Kiszka
                    (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
905 eaa728ee bellard
        pde = ldq_phys(pde_addr);
906 eaa728ee bellard
        if (!(pde & PG_PRESENT_MASK)) {
907 eaa728ee bellard
            return -1;
908 eaa728ee bellard
        }
909 eaa728ee bellard
        if (pde & PG_PSE_MASK) {
910 eaa728ee bellard
            /* 2 MB page */
911 eaa728ee bellard
            page_size = 2048 * 1024;
912 eaa728ee bellard
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
913 eaa728ee bellard
        } else {
914 eaa728ee bellard
            /* 4 KB page */
915 3f2cbf0d Jan Kiszka
            pte_addr = ((pde & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
916 3f2cbf0d Jan Kiszka
                        (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
917 eaa728ee bellard
            page_size = 4096;
918 eaa728ee bellard
            pte = ldq_phys(pte_addr);
919 eaa728ee bellard
        }
920 3f2cbf0d Jan Kiszka
        pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
921 ca1c9e15 aliguori
        if (!(pte & PG_PRESENT_MASK))
922 ca1c9e15 aliguori
            return -1;
923 14ce26e7 bellard
    } else {
924 eaa728ee bellard
        uint32_t pde;
925 3b46e624 ths
926 eaa728ee bellard
        if (!(env->cr[0] & CR0_PG_MASK)) {
927 eaa728ee bellard
            pte = addr;
928 eaa728ee bellard
            page_size = 4096;
929 eaa728ee bellard
        } else {
930 eaa728ee bellard
            /* page directory entry */
931 eaa728ee bellard
            pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
932 eaa728ee bellard
            pde = ldl_phys(pde_addr);
933 eaa728ee bellard
            if (!(pde & PG_PRESENT_MASK))
934 eaa728ee bellard
                return -1;
935 eaa728ee bellard
            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
936 eaa728ee bellard
                pte = pde & ~0x003ff000; /* align to 4MB */
937 eaa728ee bellard
                page_size = 4096 * 1024;
938 eaa728ee bellard
            } else {
939 eaa728ee bellard
                /* page directory entry */
940 eaa728ee bellard
                pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
941 eaa728ee bellard
                pte = ldl_phys(pte_addr);
942 eaa728ee bellard
                if (!(pte & PG_PRESENT_MASK))
943 eaa728ee bellard
                    return -1;
944 eaa728ee bellard
                page_size = 4096;
945 eaa728ee bellard
            }
946 eaa728ee bellard
        }
947 eaa728ee bellard
        pte = pte & env->a20_mask;
948 14ce26e7 bellard
    }
949 14ce26e7 bellard
950 eaa728ee bellard
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
951 eaa728ee bellard
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
952 eaa728ee bellard
    return paddr;
953 3b21e03e bellard
}
954 01df040b aliguori
955 01df040b aliguori
void hw_breakpoint_insert(CPUState *env, int index)
956 01df040b aliguori
{
957 01df040b aliguori
    int type, err = 0;
958 01df040b aliguori
959 01df040b aliguori
    switch (hw_breakpoint_type(env->dr[7], index)) {
960 01df040b aliguori
    case 0:
961 01df040b aliguori
        if (hw_breakpoint_enabled(env->dr[7], index))
962 01df040b aliguori
            err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
963 01df040b aliguori
                                        &env->cpu_breakpoint[index]);
964 01df040b aliguori
        break;
965 01df040b aliguori
    case 1:
966 01df040b aliguori
        type = BP_CPU | BP_MEM_WRITE;
967 01df040b aliguori
        goto insert_wp;
968 01df040b aliguori
    case 2:
969 01df040b aliguori
         /* No support for I/O watchpoints yet */
970 01df040b aliguori
        break;
971 01df040b aliguori
    case 3:
972 01df040b aliguori
        type = BP_CPU | BP_MEM_ACCESS;
973 01df040b aliguori
    insert_wp:
974 01df040b aliguori
        err = cpu_watchpoint_insert(env, env->dr[index],
975 01df040b aliguori
                                    hw_breakpoint_len(env->dr[7], index),
976 01df040b aliguori
                                    type, &env->cpu_watchpoint[index]);
977 01df040b aliguori
        break;
978 01df040b aliguori
    }
979 01df040b aliguori
    if (err)
980 01df040b aliguori
        env->cpu_breakpoint[index] = NULL;
981 01df040b aliguori
}
982 01df040b aliguori
983 01df040b aliguori
void hw_breakpoint_remove(CPUState *env, int index)
984 01df040b aliguori
{
985 01df040b aliguori
    if (!env->cpu_breakpoint[index])
986 01df040b aliguori
        return;
987 01df040b aliguori
    switch (hw_breakpoint_type(env->dr[7], index)) {
988 01df040b aliguori
    case 0:
989 01df040b aliguori
        if (hw_breakpoint_enabled(env->dr[7], index))
990 01df040b aliguori
            cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
991 01df040b aliguori
        break;
992 01df040b aliguori
    case 1:
993 01df040b aliguori
    case 3:
994 01df040b aliguori
        cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
995 01df040b aliguori
        break;
996 01df040b aliguori
    case 2:
997 01df040b aliguori
        /* No support for I/O watchpoints yet */
998 01df040b aliguori
        break;
999 01df040b aliguori
    }
1000 01df040b aliguori
}
1001 01df040b aliguori
1002 01df040b aliguori
int check_hw_breakpoints(CPUState *env, int force_dr6_update)
1003 01df040b aliguori
{
1004 01df040b aliguori
    target_ulong dr6;
1005 01df040b aliguori
    int reg, type;
1006 01df040b aliguori
    int hit_enabled = 0;
1007 01df040b aliguori
1008 01df040b aliguori
    dr6 = env->dr[6] & ~0xf;
1009 01df040b aliguori
    for (reg = 0; reg < 4; reg++) {
1010 01df040b aliguori
        type = hw_breakpoint_type(env->dr[7], reg);
1011 01df040b aliguori
        if ((type == 0 && env->dr[reg] == env->eip) ||
1012 01df040b aliguori
            ((type & 1) && env->cpu_watchpoint[reg] &&
1013 01df040b aliguori
             (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
1014 01df040b aliguori
            dr6 |= 1 << reg;
1015 01df040b aliguori
            if (hw_breakpoint_enabled(env->dr[7], reg))
1016 01df040b aliguori
                hit_enabled = 1;
1017 01df040b aliguori
        }
1018 01df040b aliguori
    }
1019 01df040b aliguori
    if (hit_enabled || force_dr6_update)
1020 01df040b aliguori
        env->dr[6] = dr6;
1021 01df040b aliguori
    return hit_enabled;
1022 01df040b aliguori
}
1023 01df040b aliguori
1024 01df040b aliguori
static CPUDebugExcpHandler *prev_debug_excp_handler;
1025 01df040b aliguori
1026 01df040b aliguori
static void breakpoint_handler(CPUState *env)
1027 01df040b aliguori
{
1028 01df040b aliguori
    CPUBreakpoint *bp;
1029 01df040b aliguori
1030 01df040b aliguori
    if (env->watchpoint_hit) {
1031 01df040b aliguori
        if (env->watchpoint_hit->flags & BP_CPU) {
1032 01df040b aliguori
            env->watchpoint_hit = NULL;
1033 01df040b aliguori
            if (check_hw_breakpoints(env, 0))
1034 63a54736 Jason Wessel
                raise_exception_env(EXCP01_DB, env);
1035 01df040b aliguori
            else
1036 01df040b aliguori
                cpu_resume_from_signal(env, NULL);
1037 01df040b aliguori
        }
1038 01df040b aliguori
    } else {
1039 72cf2d4f Blue Swirl
        QTAILQ_FOREACH(bp, &env->breakpoints, entry)
1040 01df040b aliguori
            if (bp->pc == env->eip) {
1041 01df040b aliguori
                if (bp->flags & BP_CPU) {
1042 01df040b aliguori
                    check_hw_breakpoints(env, 1);
1043 63a54736 Jason Wessel
                    raise_exception_env(EXCP01_DB, env);
1044 01df040b aliguori
                }
1045 01df040b aliguori
                break;
1046 01df040b aliguori
            }
1047 01df040b aliguori
    }
1048 01df040b aliguori
    if (prev_debug_excp_handler)
1049 01df040b aliguori
        prev_debug_excp_handler(env);
1050 01df040b aliguori
}
1051 79c4f6b0 Huang Ying
1052 d5bfda33 Jan Kiszka
typedef struct MCEInjectionParams {
1053 d5bfda33 Jan Kiszka
    Monitor *mon;
1054 d5bfda33 Jan Kiszka
    CPUState *env;
1055 d5bfda33 Jan Kiszka
    int bank;
1056 d5bfda33 Jan Kiszka
    uint64_t status;
1057 d5bfda33 Jan Kiszka
    uint64_t mcg_status;
1058 d5bfda33 Jan Kiszka
    uint64_t addr;
1059 d5bfda33 Jan Kiszka
    uint64_t misc;
1060 d5bfda33 Jan Kiszka
    int flags;
1061 d5bfda33 Jan Kiszka
} MCEInjectionParams;
1062 d5bfda33 Jan Kiszka
1063 d5bfda33 Jan Kiszka
static void do_inject_x86_mce(void *data)
1064 79c4f6b0 Huang Ying
{
1065 d5bfda33 Jan Kiszka
    MCEInjectionParams *params = data;
1066 d5bfda33 Jan Kiszka
    CPUState *cenv = params->env;
1067 d5bfda33 Jan Kiszka
    uint64_t *banks = cenv->mce_banks + 4 * params->bank;
1068 d5bfda33 Jan Kiszka
1069 d5bfda33 Jan Kiszka
    cpu_synchronize_state(cenv);
1070 316378e4 Jan Kiszka
1071 747461c7 Jan Kiszka
    /*
1072 747461c7 Jan Kiszka
     * If there is an MCE exception being processed, ignore this SRAO MCE
1073 747461c7 Jan Kiszka
     * unless unconditional injection was requested.
1074 747461c7 Jan Kiszka
     */
1075 d5bfda33 Jan Kiszka
    if (!(params->flags & MCE_INJECT_UNCOND_AO)
1076 d5bfda33 Jan Kiszka
        && !(params->status & MCI_STATUS_AR)
1077 747461c7 Jan Kiszka
        && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1078 747461c7 Jan Kiszka
        return;
1079 747461c7 Jan Kiszka
    }
1080 d5bfda33 Jan Kiszka
1081 d5bfda33 Jan Kiszka
    if (params->status & MCI_STATUS_UC) {
1082 316378e4 Jan Kiszka
        /*
1083 316378e4 Jan Kiszka
         * if MSR_MCG_CTL is not all 1s, the uncorrected error
1084 316378e4 Jan Kiszka
         * reporting is disabled
1085 316378e4 Jan Kiszka
         */
1086 d5bfda33 Jan Kiszka
        if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1087 d5bfda33 Jan Kiszka
            monitor_printf(params->mon,
1088 316378e4 Jan Kiszka
                           "CPU %d: Uncorrected error reporting disabled\n",
1089 316378e4 Jan Kiszka
                           cenv->cpu_index);
1090 316378e4 Jan Kiszka
            return;
1091 316378e4 Jan Kiszka
        }
1092 316378e4 Jan Kiszka
1093 316378e4 Jan Kiszka
        /*
1094 316378e4 Jan Kiszka
         * if MSR_MCi_CTL is not all 1s, the uncorrected error
1095 316378e4 Jan Kiszka
         * reporting is disabled for the bank
1096 316378e4 Jan Kiszka
         */
1097 316378e4 Jan Kiszka
        if (banks[0] != ~(uint64_t)0) {
1098 d5bfda33 Jan Kiszka
            monitor_printf(params->mon,
1099 d5bfda33 Jan Kiszka
                           "CPU %d: Uncorrected error reporting disabled for"
1100 d5bfda33 Jan Kiszka
                           " bank %d\n",
1101 d5bfda33 Jan Kiszka
                           cenv->cpu_index, params->bank);
1102 316378e4 Jan Kiszka
            return;
1103 316378e4 Jan Kiszka
        }
1104 316378e4 Jan Kiszka
1105 79c4f6b0 Huang Ying
        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1106 79c4f6b0 Huang Ying
            !(cenv->cr[4] & CR4_MCE_MASK)) {
1107 d5bfda33 Jan Kiszka
            monitor_printf(params->mon,
1108 d5bfda33 Jan Kiszka
                           "CPU %d: Previous MCE still in progress, raising"
1109 d5bfda33 Jan Kiszka
                           " triple fault\n",
1110 d5bfda33 Jan Kiszka
                           cenv->cpu_index);
1111 79c4f6b0 Huang Ying
            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1112 79c4f6b0 Huang Ying
            qemu_system_reset_request();
1113 79c4f6b0 Huang Ying
            return;
1114 79c4f6b0 Huang Ying
        }
1115 2fa11da0 Jan Kiszka
        if (banks[1] & MCI_STATUS_VAL) {
1116 d5bfda33 Jan Kiszka
            params->status |= MCI_STATUS_OVER;
1117 2fa11da0 Jan Kiszka
        }
1118 d5bfda33 Jan Kiszka
        banks[2] = params->addr;
1119 d5bfda33 Jan Kiszka
        banks[3] = params->misc;
1120 d5bfda33 Jan Kiszka
        cenv->mcg_status = params->mcg_status;
1121 d5bfda33 Jan Kiszka
        banks[1] = params->status;
1122 79c4f6b0 Huang Ying
        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
1123 79c4f6b0 Huang Ying
    } else if (!(banks[1] & MCI_STATUS_VAL)
1124 79c4f6b0 Huang Ying
               || !(banks[1] & MCI_STATUS_UC)) {
1125 2fa11da0 Jan Kiszka
        if (banks[1] & MCI_STATUS_VAL) {
1126 d5bfda33 Jan Kiszka
            params->status |= MCI_STATUS_OVER;
1127 2fa11da0 Jan Kiszka
        }
1128 d5bfda33 Jan Kiszka
        banks[2] = params->addr;
1129 d5bfda33 Jan Kiszka
        banks[3] = params->misc;
1130 d5bfda33 Jan Kiszka
        banks[1] = params->status;
1131 2fa11da0 Jan Kiszka
    } else {
1132 79c4f6b0 Huang Ying
        banks[1] |= MCI_STATUS_OVER;
1133 2fa11da0 Jan Kiszka
    }
1134 79c4f6b0 Huang Ying
}
1135 b3cd24e0 Jin Dongming
1136 316378e4 Jan Kiszka
void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank,
1137 316378e4 Jan Kiszka
                        uint64_t status, uint64_t mcg_status, uint64_t addr,
1138 747461c7 Jan Kiszka
                        uint64_t misc, int flags)
1139 b3cd24e0 Jin Dongming
{
1140 d5bfda33 Jan Kiszka
    MCEInjectionParams params = {
1141 d5bfda33 Jan Kiszka
        .mon = mon,
1142 d5bfda33 Jan Kiszka
        .env = cenv,
1143 d5bfda33 Jan Kiszka
        .bank = bank,
1144 d5bfda33 Jan Kiszka
        .status = status,
1145 d5bfda33 Jan Kiszka
        .mcg_status = mcg_status,
1146 d5bfda33 Jan Kiszka
        .addr = addr,
1147 d5bfda33 Jan Kiszka
        .misc = misc,
1148 d5bfda33 Jan Kiszka
        .flags = flags,
1149 d5bfda33 Jan Kiszka
    };
1150 b3cd24e0 Jin Dongming
    unsigned bank_num = cenv->mcg_cap & 0xff;
1151 31ce5e0c Jin Dongming
    CPUState *env;
1152 b3cd24e0 Jin Dongming
1153 316378e4 Jan Kiszka
    if (!cenv->mcg_cap) {
1154 316378e4 Jan Kiszka
        monitor_printf(mon, "MCE injection not supported\n");
1155 b3cd24e0 Jin Dongming
        return;
1156 b3cd24e0 Jin Dongming
    }
1157 316378e4 Jan Kiszka
    if (bank >= bank_num) {
1158 316378e4 Jan Kiszka
        monitor_printf(mon, "Invalid MCE bank number\n");
1159 316378e4 Jan Kiszka
        return;
1160 316378e4 Jan Kiszka
    }
1161 316378e4 Jan Kiszka
    if (!(status & MCI_STATUS_VAL)) {
1162 316378e4 Jan Kiszka
        monitor_printf(mon, "Invalid MCE status code\n");
1163 316378e4 Jan Kiszka
        return;
1164 316378e4 Jan Kiszka
    }
1165 747461c7 Jan Kiszka
    if ((flags & MCE_INJECT_BROADCAST)
1166 747461c7 Jan Kiszka
        && !cpu_x86_support_mca_broadcast(cenv)) {
1167 316378e4 Jan Kiszka
        monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
1168 316378e4 Jan Kiszka
        return;
1169 2bd3e04c Jin Dongming
    }
1170 2bd3e04c Jin Dongming
1171 c34d440a Jan Kiszka
    run_on_cpu(cenv, do_inject_x86_mce, &params);
1172 c34d440a Jan Kiszka
    if (flags & MCE_INJECT_BROADCAST) {
1173 c34d440a Jan Kiszka
        params.bank = 1;
1174 c34d440a Jan Kiszka
        params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
1175 c34d440a Jan Kiszka
        params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
1176 c34d440a Jan Kiszka
        params.addr = 0;
1177 c34d440a Jan Kiszka
        params.misc = 0;
1178 c34d440a Jan Kiszka
        for (env = first_cpu; env != NULL; env = env->next_cpu) {
1179 c34d440a Jan Kiszka
            if (cenv == env) {
1180 c34d440a Jan Kiszka
                continue;
1181 31ce5e0c Jin Dongming
            }
1182 c34d440a Jan Kiszka
            params.env = env;
1183 c34d440a Jan Kiszka
            run_on_cpu(cenv, do_inject_x86_mce, &params);
1184 31ce5e0c Jin Dongming
        }
1185 b3cd24e0 Jin Dongming
    }
1186 b3cd24e0 Jin Dongming
}
1187 d362e757 Jan Kiszka
1188 d362e757 Jan Kiszka
void cpu_report_tpr_access(CPUState *env, TPRAccess access)
1189 d362e757 Jan Kiszka
{
1190 d362e757 Jan Kiszka
    TranslationBlock *tb;
1191 d362e757 Jan Kiszka
1192 d362e757 Jan Kiszka
    if (kvm_enabled()) {
1193 d362e757 Jan Kiszka
        env->tpr_access_type = access;
1194 d362e757 Jan Kiszka
1195 d362e757 Jan Kiszka
        cpu_interrupt(env, CPU_INTERRUPT_TPR);
1196 d362e757 Jan Kiszka
    } else {
1197 d362e757 Jan Kiszka
        tb = tb_find_pc(env->mem_io_pc);
1198 d362e757 Jan Kiszka
        cpu_restore_state(tb, env, env->mem_io_pc);
1199 d362e757 Jan Kiszka
1200 d362e757 Jan Kiszka
        apic_handle_tpr_access_report(env->apic_state, env->eip, access);
1201 d362e757 Jan Kiszka
    }
1202 d362e757 Jan Kiszka
}
1203 74ce674f bellard
#endif /* !CONFIG_USER_ONLY */
1204 6fd805e1 aliguori
1205 79c4f6b0 Huang Ying
static void mce_init(CPUX86State *cenv)
1206 79c4f6b0 Huang Ying
{
1207 2fa11da0 Jan Kiszka
    unsigned int bank;
1208 79c4f6b0 Huang Ying
1209 2fa11da0 Jan Kiszka
    if (((cenv->cpuid_version >> 8) & 0xf) >= 6
1210 2fa11da0 Jan Kiszka
        && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
1211 2fa11da0 Jan Kiszka
            (CPUID_MCE | CPUID_MCA)) {
1212 79c4f6b0 Huang Ying
        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1213 79c4f6b0 Huang Ying
        cenv->mcg_ctl = ~(uint64_t)0;
1214 2fa11da0 Jan Kiszka
        for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
1215 2fa11da0 Jan Kiszka
            cenv->mce_banks[bank * 4] = ~(uint64_t)0;
1216 2fa11da0 Jan Kiszka
        }
1217 79c4f6b0 Huang Ying
    }
1218 79c4f6b0 Huang Ying
}
1219 79c4f6b0 Huang Ying
1220 84273177 Jan Kiszka
int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1221 84273177 Jan Kiszka
                            target_ulong *base, unsigned int *limit,
1222 84273177 Jan Kiszka
                            unsigned int *flags)
1223 84273177 Jan Kiszka
{
1224 84273177 Jan Kiszka
    SegmentCache *dt;
1225 84273177 Jan Kiszka
    target_ulong ptr;
1226 84273177 Jan Kiszka
    uint32_t e1, e2;
1227 84273177 Jan Kiszka
    int index;
1228 84273177 Jan Kiszka
1229 84273177 Jan Kiszka
    if (selector & 0x4)
1230 84273177 Jan Kiszka
        dt = &env->ldt;
1231 84273177 Jan Kiszka
    else
1232 84273177 Jan Kiszka
        dt = &env->gdt;
1233 84273177 Jan Kiszka
    index = selector & ~7;
1234 84273177 Jan Kiszka
    ptr = dt->base + index;
1235 84273177 Jan Kiszka
    if ((index + 7) > dt->limit
1236 84273177 Jan Kiszka
        || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1237 84273177 Jan Kiszka
        || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1238 84273177 Jan Kiszka
        return 0;
1239 84273177 Jan Kiszka
1240 84273177 Jan Kiszka
    *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1241 84273177 Jan Kiszka
    *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1242 84273177 Jan Kiszka
    if (e2 & DESC_G_MASK)
1243 84273177 Jan Kiszka
        *limit = (*limit << 12) | 0xfff;
1244 84273177 Jan Kiszka
    *flags = e2;
1245 84273177 Jan Kiszka
1246 84273177 Jan Kiszka
    return 1;
1247 84273177 Jan Kiszka
}
1248 84273177 Jan Kiszka
1249 01df040b aliguori
CPUX86State *cpu_x86_init(const char *cpu_model)
1250 01df040b aliguori
{
1251 01df040b aliguori
    CPUX86State *env;
1252 01df040b aliguori
    static int inited;
1253 01df040b aliguori
1254 7267c094 Anthony Liguori
    env = g_malloc0(sizeof(CPUX86State));
1255 01df040b aliguori
    cpu_exec_init(env);
1256 01df040b aliguori
    env->cpu_model_str = cpu_model;
1257 01df040b aliguori
1258 d5ab9713 Jan Kiszka
    /* init various static tables used in TCG mode */
1259 d5ab9713 Jan Kiszka
    if (tcg_enabled() && !inited) {
1260 01df040b aliguori
        inited = 1;
1261 01df040b aliguori
        optimize_flags_init();
1262 01df040b aliguori
#ifndef CONFIG_USER_ONLY
1263 01df040b aliguori
        prev_debug_excp_handler =
1264 01df040b aliguori
            cpu_set_debug_excp_handler(breakpoint_handler);
1265 01df040b aliguori
#endif
1266 01df040b aliguori
    }
1267 01df040b aliguori
    if (cpu_x86_register(env, cpu_model) < 0) {
1268 01df040b aliguori
        cpu_x86_close(env);
1269 01df040b aliguori
        return NULL;
1270 01df040b aliguori
    }
1271 f2209eb8 Bharata B Rao
    env->cpuid_apic_id = env->cpu_index;
1272 79c4f6b0 Huang Ying
    mce_init(env);
1273 0bf46a40 aliguori
1274 0bf46a40 aliguori
    qemu_init_vcpu(env);
1275 0bf46a40 aliguori
1276 01df040b aliguori
    return env;
1277 01df040b aliguori
}
1278 b09ea7d5 Gleb Natapov
1279 b09ea7d5 Gleb Natapov
#if !defined(CONFIG_USER_ONLY)
1280 b09ea7d5 Gleb Natapov
void do_cpu_init(CPUState *env)
1281 b09ea7d5 Gleb Natapov
{
1282 b09ea7d5 Gleb Natapov
    int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
1283 ebda377f Jan Kiszka
    uint64_t pat = env->pat;
1284 ebda377f Jan Kiszka
1285 b09ea7d5 Gleb Natapov
    cpu_reset(env);
1286 b09ea7d5 Gleb Natapov
    env->interrupt_request = sipi;
1287 ebda377f Jan Kiszka
    env->pat = pat;
1288 4a942cea Blue Swirl
    apic_init_reset(env->apic_state);
1289 052be86b Jan Kiszka
    env->halted = !cpu_is_bsp(env);
1290 b09ea7d5 Gleb Natapov
}
1291 b09ea7d5 Gleb Natapov
1292 b09ea7d5 Gleb Natapov
void do_cpu_sipi(CPUState *env)
1293 b09ea7d5 Gleb Natapov
{
1294 4a942cea Blue Swirl
    apic_sipi(env->apic_state);
1295 b09ea7d5 Gleb Natapov
}
1296 b09ea7d5 Gleb Natapov
#else
1297 b09ea7d5 Gleb Natapov
void do_cpu_init(CPUState *env)
1298 b09ea7d5 Gleb Natapov
{
1299 b09ea7d5 Gleb Natapov
}
1300 b09ea7d5 Gleb Natapov
void do_cpu_sipi(CPUState *env)
1301 b09ea7d5 Gleb Natapov
{
1302 b09ea7d5 Gleb Natapov
}
1303 b09ea7d5 Gleb Natapov
#endif