Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ a88790a1

History | View | Annotate | Download (37 kB)

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