Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ b072a3c8

History | View | Annotate | Download (40.5 kB)

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