Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ c0532a76

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