Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ d2d979c6

History | View | Annotate | Download (40.6 kB)

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