Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ d4c430a8

History | View | Annotate | Download (36.8 kB)

1
/*
2
 *  i386 helpers (without register variable usage)
3
 *
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
#include <stdarg.h>
20
#include <stdlib.h>
21
#include <stdio.h>
22
#include <string.h>
23
#include <inttypes.h>
24
#include <signal.h>
25

    
26
#include "cpu.h"
27
#include "exec-all.h"
28
#include "qemu-common.h"
29
#include "kvm.h"
30

    
31
//#define DEBUG_MMU
32

    
33
/* NOTE: must be called outside the CPU execute loop */
34
void cpu_reset(CPUX86State *env)
35
{
36
    int i;
37

    
38
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
39
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
40
        log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
41
    }
42

    
43
    memset(env, 0, offsetof(CPUX86State, breakpoints));
44

    
45
    tlb_flush(env, 1);
46

    
47
    env->old_exception = -1;
48

    
49
    /* init to reset state */
50

    
51
#ifdef CONFIG_SOFTMMU
52
    env->hflags |= HF_SOFTMMU_MASK;
53
#endif
54
    env->hflags2 |= HF2_GIF_MASK;
55

    
56
    cpu_x86_update_cr0(env, 0x60000010);
57
    env->a20_mask = ~0x0;
58
    env->smbase = 0x30000;
59

    
60
    env->idt.limit = 0xffff;
61
    env->gdt.limit = 0xffff;
62
    env->ldt.limit = 0xffff;
63
    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
64
    env->tr.limit = 0xffff;
65
    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
66

    
67
    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
68
                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
69
                           DESC_R_MASK | DESC_A_MASK);
70
    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
71
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
72
                           DESC_A_MASK);
73
    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
74
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
75
                           DESC_A_MASK);
76
    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
77
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
78
                           DESC_A_MASK);
79
    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
80
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
81
                           DESC_A_MASK);
82
    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
83
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
84
                           DESC_A_MASK);
85

    
86
    env->eip = 0xfff0;
87
    env->regs[R_EDX] = env->cpuid_version;
88

    
89
    env->eflags = 0x2;
90

    
91
    /* FPU init */
92
    for(i = 0;i < 8; i++)
93
        env->fptags[i] = 1;
94
    env->fpuc = 0x37f;
95

    
96
    env->mxcsr = 0x1f80;
97

    
98
    memset(env->dr, 0, sizeof(env->dr));
99
    env->dr[6] = DR6_FIXED_1;
100
    env->dr[7] = DR7_FIXED_1;
101
    cpu_breakpoint_remove_all(env, BP_CPU);
102
    cpu_watchpoint_remove_all(env, BP_CPU);
103

    
104
    env->mcg_status = 0;
105
}
106

    
107
void cpu_x86_close(CPUX86State *env)
108
{
109
    qemu_free(env);
110
}
111

    
112
/***********************************************************/
113
/* x86 debug */
114

    
115
static const char *cc_op_str[] = {
116
    "DYNAMIC",
117
    "EFLAGS",
118

    
119
    "MULB",
120
    "MULW",
121
    "MULL",
122
    "MULQ",
123

    
124
    "ADDB",
125
    "ADDW",
126
    "ADDL",
127
    "ADDQ",
128

    
129
    "ADCB",
130
    "ADCW",
131
    "ADCL",
132
    "ADCQ",
133

    
134
    "SUBB",
135
    "SUBW",
136
    "SUBL",
137
    "SUBQ",
138

    
139
    "SBBB",
140
    "SBBW",
141
    "SBBL",
142
    "SBBQ",
143

    
144
    "LOGICB",
145
    "LOGICW",
146
    "LOGICL",
147
    "LOGICQ",
148

    
149
    "INCB",
150
    "INCW",
151
    "INCL",
152
    "INCQ",
153

    
154
    "DECB",
155
    "DECW",
156
    "DECL",
157
    "DECQ",
158

    
159
    "SHLB",
160
    "SHLW",
161
    "SHLL",
162
    "SHLQ",
163

    
164
    "SARB",
165
    "SARW",
166
    "SARL",
167
    "SARQ",
168
};
169

    
170
static void
171
cpu_x86_dump_seg_cache(CPUState *env, FILE *f,
172
                       int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
173
                       const char *name, struct SegmentCache *sc)
174
{
175
#ifdef TARGET_X86_64
176
    if (env->hflags & HF_CS64_MASK) {
177
        cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
178
                    sc->selector, sc->base, sc->limit, sc->flags);
179
    } else
180
#endif
181
    {
182
        cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
183
                    (uint32_t)sc->base, sc->limit, sc->flags);
184
    }
185

    
186
    if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
187
        goto done;
188

    
189
    cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
190
    if (sc->flags & DESC_S_MASK) {
191
        if (sc->flags & DESC_CS_MASK) {
192
            cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
193
                           ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
194
            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
195
                        (sc->flags & DESC_R_MASK) ? 'R' : '-');
196
        } else {
197
            cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS  " : "DS16");
198
            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
199
                        (sc->flags & DESC_W_MASK) ? 'W' : '-');
200
        }
201
        cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
202
    } else {
203
        static const char *sys_type_name[2][16] = {
204
            { /* 32 bit mode */
205
                "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
206
                "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
207
                "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
208
                "CallGate32", "Reserved", "IntGate32", "TrapGate32"
209
            },
210
            { /* 64 bit mode */
211
                "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
212
                "Reserved", "Reserved", "Reserved", "Reserved",
213
                "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
214
                "Reserved", "IntGate64", "TrapGate64"
215
            }
216
        };
217
        cpu_fprintf(f, sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
218
                                    [(sc->flags & DESC_TYPE_MASK)
219
                                     >> DESC_TYPE_SHIFT]);
220
    }
221
done:
222
    cpu_fprintf(f, "\n");
223
}
224

    
225
void cpu_dump_state(CPUState *env, FILE *f,
226
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
227
                    int flags)
228
{
229
    int eflags, i, nb;
230
    char cc_op_name[32];
231
    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
232

    
233
    cpu_synchronize_state(env);
234

    
235
    eflags = env->eflags;
236
#ifdef TARGET_X86_64
237
    if (env->hflags & HF_CS64_MASK) {
238
        cpu_fprintf(f,
239
                    "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
240
                    "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
241
                    "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
242
                    "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
243
                    "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
244
                    env->regs[R_EAX],
245
                    env->regs[R_EBX],
246
                    env->regs[R_ECX],
247
                    env->regs[R_EDX],
248
                    env->regs[R_ESI],
249
                    env->regs[R_EDI],
250
                    env->regs[R_EBP],
251
                    env->regs[R_ESP],
252
                    env->regs[8],
253
                    env->regs[9],
254
                    env->regs[10],
255
                    env->regs[11],
256
                    env->regs[12],
257
                    env->regs[13],
258
                    env->regs[14],
259
                    env->regs[15],
260
                    env->eip, eflags,
261
                    eflags & DF_MASK ? 'D' : '-',
262
                    eflags & CC_O ? 'O' : '-',
263
                    eflags & CC_S ? 'S' : '-',
264
                    eflags & CC_Z ? 'Z' : '-',
265
                    eflags & CC_A ? 'A' : '-',
266
                    eflags & CC_P ? 'P' : '-',
267
                    eflags & CC_C ? 'C' : '-',
268
                    env->hflags & HF_CPL_MASK,
269
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
270
                    (env->a20_mask >> 20) & 1,
271
                    (env->hflags >> HF_SMM_SHIFT) & 1,
272
                    env->halted);
273
    } else
274
#endif
275
    {
276
        cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
277
                    "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
278
                    "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
279
                    (uint32_t)env->regs[R_EAX],
280
                    (uint32_t)env->regs[R_EBX],
281
                    (uint32_t)env->regs[R_ECX],
282
                    (uint32_t)env->regs[R_EDX],
283
                    (uint32_t)env->regs[R_ESI],
284
                    (uint32_t)env->regs[R_EDI],
285
                    (uint32_t)env->regs[R_EBP],
286
                    (uint32_t)env->regs[R_ESP],
287
                    (uint32_t)env->eip, eflags,
288
                    eflags & DF_MASK ? 'D' : '-',
289
                    eflags & CC_O ? 'O' : '-',
290
                    eflags & CC_S ? 'S' : '-',
291
                    eflags & CC_Z ? 'Z' : '-',
292
                    eflags & CC_A ? 'A' : '-',
293
                    eflags & CC_P ? 'P' : '-',
294
                    eflags & CC_C ? 'C' : '-',
295
                    env->hflags & HF_CPL_MASK,
296
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
297
                    (env->a20_mask >> 20) & 1,
298
                    (env->hflags >> HF_SMM_SHIFT) & 1,
299
                    env->halted);
300
    }
301

    
302
    for(i = 0; i < 6; i++) {
303
        cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
304
                               &env->segs[i]);
305
    }
306
    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
307
    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
308

    
309
#ifdef TARGET_X86_64
310
    if (env->hflags & HF_LMA_MASK) {
311
        cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
312
                    env->gdt.base, env->gdt.limit);
313
        cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
314
                    env->idt.base, env->idt.limit);
315
        cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
316
                    (uint32_t)env->cr[0],
317
                    env->cr[2],
318
                    env->cr[3],
319
                    (uint32_t)env->cr[4]);
320
        for(i = 0; i < 4; i++)
321
            cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
322
        cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
323
                    env->dr[6], env->dr[7]);
324
    } else
325
#endif
326
    {
327
        cpu_fprintf(f, "GDT=     %08x %08x\n",
328
                    (uint32_t)env->gdt.base, env->gdt.limit);
329
        cpu_fprintf(f, "IDT=     %08x %08x\n",
330
                    (uint32_t)env->idt.base, env->idt.limit);
331
        cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
332
                    (uint32_t)env->cr[0],
333
                    (uint32_t)env->cr[2],
334
                    (uint32_t)env->cr[3],
335
                    (uint32_t)env->cr[4]);
336
        for(i = 0; i < 4; i++)
337
            cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]);
338
        cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]);
339
    }
340
    if (flags & X86_DUMP_CCOP) {
341
        if ((unsigned)env->cc_op < CC_OP_NB)
342
            snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
343
        else
344
            snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
345
#ifdef TARGET_X86_64
346
        if (env->hflags & HF_CS64_MASK) {
347
            cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
348
                        env->cc_src, env->cc_dst,
349
                        cc_op_name);
350
        } else
351
#endif
352
        {
353
            cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
354
                        (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
355
                        cc_op_name);
356
        }
357
    }
358
    if (flags & X86_DUMP_FPU) {
359
        int fptag;
360
        fptag = 0;
361
        for(i = 0; i < 8; i++) {
362
            fptag |= ((!env->fptags[i]) << i);
363
        }
364
        cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
365
                    env->fpuc,
366
                    (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
367
                    env->fpstt,
368
                    fptag,
369
                    env->mxcsr);
370
        for(i=0;i<8;i++) {
371
#if defined(USE_X86LDOUBLE)
372
            union {
373
                long double d;
374
                struct {
375
                    uint64_t lower;
376
                    uint16_t upper;
377
                } l;
378
            } tmp;
379
            tmp.d = env->fpregs[i].d;
380
            cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
381
                        i, tmp.l.lower, tmp.l.upper);
382
#else
383
            cpu_fprintf(f, "FPR%d=%016" PRIx64,
384
                        i, env->fpregs[i].mmx.q);
385
#endif
386
            if ((i & 1) == 1)
387
                cpu_fprintf(f, "\n");
388
            else
389
                cpu_fprintf(f, " ");
390
        }
391
        if (env->hflags & HF_CS64_MASK)
392
            nb = 16;
393
        else
394
            nb = 8;
395
        for(i=0;i<nb;i++) {
396
            cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
397
                        i,
398
                        env->xmm_regs[i].XMM_L(3),
399
                        env->xmm_regs[i].XMM_L(2),
400
                        env->xmm_regs[i].XMM_L(1),
401
                        env->xmm_regs[i].XMM_L(0));
402
            if ((i & 1) == 1)
403
                cpu_fprintf(f, "\n");
404
            else
405
                cpu_fprintf(f, " ");
406
        }
407
    }
408
}
409

    
410
/***********************************************************/
411
/* x86 mmu */
412
/* XXX: add PGE support */
413

    
414
void cpu_x86_set_a20(CPUX86State *env, int a20_state)
415
{
416
    a20_state = (a20_state != 0);
417
    if (a20_state != ((env->a20_mask >> 20) & 1)) {
418
#if defined(DEBUG_MMU)
419
        printf("A20 update: a20=%d\n", a20_state);
420
#endif
421
        /* if the cpu is currently executing code, we must unlink it and
422
           all the potentially executing TB */
423
        cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
424

    
425
        /* when a20 is changed, all the MMU mappings are invalid, so
426
           we must flush everything */
427
        tlb_flush(env, 1);
428
        env->a20_mask = ~(1 << 20) | (a20_state << 20);
429
    }
430
}
431

    
432
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
433
{
434
    int pe_state;
435

    
436
#if defined(DEBUG_MMU)
437
    printf("CR0 update: CR0=0x%08x\n", new_cr0);
438
#endif
439
    if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
440
        (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
441
        tlb_flush(env, 1);
442
    }
443

    
444
#ifdef TARGET_X86_64
445
    if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
446
        (env->efer & MSR_EFER_LME)) {
447
        /* enter in long mode */
448
        /* XXX: generate an exception */
449
        if (!(env->cr[4] & CR4_PAE_MASK))
450
            return;
451
        env->efer |= MSR_EFER_LMA;
452
        env->hflags |= HF_LMA_MASK;
453
    } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
454
               (env->efer & MSR_EFER_LMA)) {
455
        /* exit long mode */
456
        env->efer &= ~MSR_EFER_LMA;
457
        env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
458
        env->eip &= 0xffffffff;
459
    }
460
#endif
461
    env->cr[0] = new_cr0 | CR0_ET_MASK;
462

    
463
    /* update PE flag in hidden flags */
464
    pe_state = (env->cr[0] & CR0_PE_MASK);
465
    env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
466
    /* ensure that ADDSEG is always set in real mode */
467
    env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
468
    /* update FPU flags */
469
    env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
470
        ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
471
}
472

    
473
/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
474
   the PDPT */
475
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
476
{
477
    env->cr[3] = new_cr3;
478
    if (env->cr[0] & CR0_PG_MASK) {
479
#if defined(DEBUG_MMU)
480
        printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
481
#endif
482
        tlb_flush(env, 0);
483
    }
484
}
485

    
486
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
487
{
488
#if defined(DEBUG_MMU)
489
    printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
490
#endif
491
    if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
492
        (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
493
        tlb_flush(env, 1);
494
    }
495
    /* SSE handling */
496
    if (!(env->cpuid_features & CPUID_SSE))
497
        new_cr4 &= ~CR4_OSFXSR_MASK;
498
    if (new_cr4 & CR4_OSFXSR_MASK)
499
        env->hflags |= HF_OSFXSR_MASK;
500
    else
501
        env->hflags &= ~HF_OSFXSR_MASK;
502

    
503
    env->cr[4] = new_cr4;
504
}
505

    
506
#if defined(CONFIG_USER_ONLY)
507

    
508
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
509
                             int is_write, int mmu_idx, int is_softmmu)
510
{
511
    /* user mode only emulation */
512
    is_write &= 1;
513
    env->cr[2] = addr;
514
    env->error_code = (is_write << PG_ERROR_W_BIT);
515
    env->error_code |= PG_ERROR_U_MASK;
516
    env->exception_index = EXCP0E_PAGE;
517
    return 1;
518
}
519

    
520
#else
521

    
522
/* XXX: This value should match the one returned by CPUID
523
 * and in exec.c */
524
# if defined(TARGET_X86_64)
525
# define PHYS_ADDR_MASK 0xfffffff000LL
526
# else
527
# define PHYS_ADDR_MASK 0xffffff000LL
528
# endif
529

    
530
/* return value:
531
   -1 = cannot handle fault
532
   0  = nothing more to do
533
   1  = generate PF fault
534
*/
535
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
536
                             int is_write1, int mmu_idx, int is_softmmu)
537
{
538
    uint64_t ptep, pte;
539
    target_ulong pde_addr, pte_addr;
540
    int error_code, is_dirty, prot, page_size, is_write, is_user;
541
    target_phys_addr_t paddr;
542
    uint32_t page_offset;
543
    target_ulong vaddr, virt_addr;
544

    
545
    is_user = mmu_idx == MMU_USER_IDX;
546
#if defined(DEBUG_MMU)
547
    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
548
           addr, is_write1, is_user, env->eip);
549
#endif
550
    is_write = is_write1 & 1;
551

    
552
    if (!(env->cr[0] & CR0_PG_MASK)) {
553
        pte = addr;
554
        virt_addr = addr & TARGET_PAGE_MASK;
555
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
556
        page_size = 4096;
557
        goto do_mapping;
558
    }
559

    
560
    if (env->cr[4] & CR4_PAE_MASK) {
561
        uint64_t pde, pdpe;
562
        target_ulong pdpe_addr;
563

    
564
#ifdef TARGET_X86_64
565
        if (env->hflags & HF_LMA_MASK) {
566
            uint64_t pml4e_addr, pml4e;
567
            int32_t sext;
568

    
569
            /* test virtual address sign extension */
570
            sext = (int64_t)addr >> 47;
571
            if (sext != 0 && sext != -1) {
572
                env->error_code = 0;
573
                env->exception_index = EXCP0D_GPF;
574
                return 1;
575
            }
576

    
577
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
578
                env->a20_mask;
579
            pml4e = ldq_phys(pml4e_addr);
580
            if (!(pml4e & PG_PRESENT_MASK)) {
581
                error_code = 0;
582
                goto do_fault;
583
            }
584
            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
585
                error_code = PG_ERROR_RSVD_MASK;
586
                goto do_fault;
587
            }
588
            if (!(pml4e & PG_ACCESSED_MASK)) {
589
                pml4e |= PG_ACCESSED_MASK;
590
                stl_phys_notdirty(pml4e_addr, pml4e);
591
            }
592
            ptep = pml4e ^ PG_NX_MASK;
593
            pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
594
                env->a20_mask;
595
            pdpe = ldq_phys(pdpe_addr);
596
            if (!(pdpe & PG_PRESENT_MASK)) {
597
                error_code = 0;
598
                goto do_fault;
599
            }
600
            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
601
                error_code = PG_ERROR_RSVD_MASK;
602
                goto do_fault;
603
            }
604
            ptep &= pdpe ^ PG_NX_MASK;
605
            if (!(pdpe & PG_ACCESSED_MASK)) {
606
                pdpe |= PG_ACCESSED_MASK;
607
                stl_phys_notdirty(pdpe_addr, pdpe);
608
            }
609
        } else
610
#endif
611
        {
612
            /* XXX: load them when cr3 is loaded ? */
613
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
614
                env->a20_mask;
615
            pdpe = ldq_phys(pdpe_addr);
616
            if (!(pdpe & PG_PRESENT_MASK)) {
617
                error_code = 0;
618
                goto do_fault;
619
            }
620
            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
621
        }
622

    
623
        pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
624
            env->a20_mask;
625
        pde = ldq_phys(pde_addr);
626
        if (!(pde & PG_PRESENT_MASK)) {
627
            error_code = 0;
628
            goto do_fault;
629
        }
630
        if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
631
            error_code = PG_ERROR_RSVD_MASK;
632
            goto do_fault;
633
        }
634
        ptep &= pde ^ PG_NX_MASK;
635
        if (pde & PG_PSE_MASK) {
636
            /* 2 MB page */
637
            page_size = 2048 * 1024;
638
            ptep ^= PG_NX_MASK;
639
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
640
                goto do_fault_protect;
641
            if (is_user) {
642
                if (!(ptep & PG_USER_MASK))
643
                    goto do_fault_protect;
644
                if (is_write && !(ptep & PG_RW_MASK))
645
                    goto do_fault_protect;
646
            } else {
647
                if ((env->cr[0] & CR0_WP_MASK) &&
648
                    is_write && !(ptep & PG_RW_MASK))
649
                    goto do_fault_protect;
650
            }
651
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
652
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
653
                pde |= PG_ACCESSED_MASK;
654
                if (is_dirty)
655
                    pde |= PG_DIRTY_MASK;
656
                stl_phys_notdirty(pde_addr, pde);
657
            }
658
            /* align to page_size */
659
            pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
660
            virt_addr = addr & ~(page_size - 1);
661
        } else {
662
            /* 4 KB page */
663
            if (!(pde & PG_ACCESSED_MASK)) {
664
                pde |= PG_ACCESSED_MASK;
665
                stl_phys_notdirty(pde_addr, pde);
666
            }
667
            pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
668
                env->a20_mask;
669
            pte = ldq_phys(pte_addr);
670
            if (!(pte & PG_PRESENT_MASK)) {
671
                error_code = 0;
672
                goto do_fault;
673
            }
674
            if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
675
                error_code = PG_ERROR_RSVD_MASK;
676
                goto do_fault;
677
            }
678
            /* combine pde and pte nx, user and rw protections */
679
            ptep &= pte ^ PG_NX_MASK;
680
            ptep ^= PG_NX_MASK;
681
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
682
                goto do_fault_protect;
683
            if (is_user) {
684
                if (!(ptep & PG_USER_MASK))
685
                    goto do_fault_protect;
686
                if (is_write && !(ptep & PG_RW_MASK))
687
                    goto do_fault_protect;
688
            } else {
689
                if ((env->cr[0] & CR0_WP_MASK) &&
690
                    is_write && !(ptep & PG_RW_MASK))
691
                    goto do_fault_protect;
692
            }
693
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
694
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
695
                pte |= PG_ACCESSED_MASK;
696
                if (is_dirty)
697
                    pte |= PG_DIRTY_MASK;
698
                stl_phys_notdirty(pte_addr, pte);
699
            }
700
            page_size = 4096;
701
            virt_addr = addr & ~0xfff;
702
            pte = pte & (PHYS_ADDR_MASK | 0xfff);
703
        }
704
    } else {
705
        uint32_t pde;
706

    
707
        /* page directory entry */
708
        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
709
            env->a20_mask;
710
        pde = ldl_phys(pde_addr);
711
        if (!(pde & PG_PRESENT_MASK)) {
712
            error_code = 0;
713
            goto do_fault;
714
        }
715
        /* if PSE bit is set, then we use a 4MB page */
716
        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
717
            page_size = 4096 * 1024;
718
            if (is_user) {
719
                if (!(pde & PG_USER_MASK))
720
                    goto do_fault_protect;
721
                if (is_write && !(pde & PG_RW_MASK))
722
                    goto do_fault_protect;
723
            } else {
724
                if ((env->cr[0] & CR0_WP_MASK) &&
725
                    is_write && !(pde & PG_RW_MASK))
726
                    goto do_fault_protect;
727
            }
728
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
729
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
730
                pde |= PG_ACCESSED_MASK;
731
                if (is_dirty)
732
                    pde |= PG_DIRTY_MASK;
733
                stl_phys_notdirty(pde_addr, pde);
734
            }
735

    
736
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
737
            ptep = pte;
738
            virt_addr = addr & ~(page_size - 1);
739
        } else {
740
            if (!(pde & PG_ACCESSED_MASK)) {
741
                pde |= PG_ACCESSED_MASK;
742
                stl_phys_notdirty(pde_addr, pde);
743
            }
744

    
745
            /* page directory entry */
746
            pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
747
                env->a20_mask;
748
            pte = ldl_phys(pte_addr);
749
            if (!(pte & PG_PRESENT_MASK)) {
750
                error_code = 0;
751
                goto do_fault;
752
            }
753
            /* combine pde and pte user and rw protections */
754
            ptep = pte & pde;
755
            if (is_user) {
756
                if (!(ptep & PG_USER_MASK))
757
                    goto do_fault_protect;
758
                if (is_write && !(ptep & PG_RW_MASK))
759
                    goto do_fault_protect;
760
            } else {
761
                if ((env->cr[0] & CR0_WP_MASK) &&
762
                    is_write && !(ptep & PG_RW_MASK))
763
                    goto do_fault_protect;
764
            }
765
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
766
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
767
                pte |= PG_ACCESSED_MASK;
768
                if (is_dirty)
769
                    pte |= PG_DIRTY_MASK;
770
                stl_phys_notdirty(pte_addr, pte);
771
            }
772
            page_size = 4096;
773
            virt_addr = addr & ~0xfff;
774
        }
775
    }
776
    /* the page can be put in the TLB */
777
    prot = PAGE_READ;
778
    if (!(ptep & PG_NX_MASK))
779
        prot |= PAGE_EXEC;
780
    if (pte & PG_DIRTY_MASK) {
781
        /* only set write access if already dirty... otherwise wait
782
           for dirty access */
783
        if (is_user) {
784
            if (ptep & PG_RW_MASK)
785
                prot |= PAGE_WRITE;
786
        } else {
787
            if (!(env->cr[0] & CR0_WP_MASK) ||
788
                (ptep & PG_RW_MASK))
789
                prot |= PAGE_WRITE;
790
        }
791
    }
792
 do_mapping:
793
    pte = pte & env->a20_mask;
794

    
795
    /* Even if 4MB pages, we map only one 4KB page in the cache to
796
       avoid filling it too fast */
797
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
798
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
799
    vaddr = virt_addr + page_offset;
800

    
801
    tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
802
    return 0;
803
 do_fault_protect:
804
    error_code = PG_ERROR_P_MASK;
805
 do_fault:
806
    error_code |= (is_write << PG_ERROR_W_BIT);
807
    if (is_user)
808
        error_code |= PG_ERROR_U_MASK;
809
    if (is_write1 == 2 &&
810
        (env->efer & MSR_EFER_NXE) &&
811
        (env->cr[4] & CR4_PAE_MASK))
812
        error_code |= PG_ERROR_I_D_MASK;
813
    if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
814
        /* cr2 is not modified in case of exceptions */
815
        stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 
816
                 addr);
817
    } else {
818
        env->cr[2] = addr;
819
    }
820
    env->error_code = error_code;
821
    env->exception_index = EXCP0E_PAGE;
822
    return 1;
823
}
824

    
825
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
826
{
827
    target_ulong pde_addr, pte_addr;
828
    uint64_t pte;
829
    target_phys_addr_t paddr;
830
    uint32_t page_offset;
831
    int page_size;
832

    
833
    if (env->cr[4] & CR4_PAE_MASK) {
834
        target_ulong pdpe_addr;
835
        uint64_t pde, pdpe;
836

    
837
#ifdef TARGET_X86_64
838
        if (env->hflags & HF_LMA_MASK) {
839
            uint64_t pml4e_addr, pml4e;
840
            int32_t sext;
841

    
842
            /* test virtual address sign extension */
843
            sext = (int64_t)addr >> 47;
844
            if (sext != 0 && sext != -1)
845
                return -1;
846

    
847
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
848
                env->a20_mask;
849
            pml4e = ldq_phys(pml4e_addr);
850
            if (!(pml4e & PG_PRESENT_MASK))
851
                return -1;
852

    
853
            pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
854
                env->a20_mask;
855
            pdpe = ldq_phys(pdpe_addr);
856
            if (!(pdpe & PG_PRESENT_MASK))
857
                return -1;
858
        } else
859
#endif
860
        {
861
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
862
                env->a20_mask;
863
            pdpe = ldq_phys(pdpe_addr);
864
            if (!(pdpe & PG_PRESENT_MASK))
865
                return -1;
866
        }
867

    
868
        pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
869
            env->a20_mask;
870
        pde = ldq_phys(pde_addr);
871
        if (!(pde & PG_PRESENT_MASK)) {
872
            return -1;
873
        }
874
        if (pde & PG_PSE_MASK) {
875
            /* 2 MB page */
876
            page_size = 2048 * 1024;
877
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
878
        } else {
879
            /* 4 KB page */
880
            pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
881
                env->a20_mask;
882
            page_size = 4096;
883
            pte = ldq_phys(pte_addr);
884
        }
885
        if (!(pte & PG_PRESENT_MASK))
886
            return -1;
887
    } else {
888
        uint32_t pde;
889

    
890
        if (!(env->cr[0] & CR0_PG_MASK)) {
891
            pte = addr;
892
            page_size = 4096;
893
        } else {
894
            /* page directory entry */
895
            pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
896
            pde = ldl_phys(pde_addr);
897
            if (!(pde & PG_PRESENT_MASK))
898
                return -1;
899
            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
900
                pte = pde & ~0x003ff000; /* align to 4MB */
901
                page_size = 4096 * 1024;
902
            } else {
903
                /* page directory entry */
904
                pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
905
                pte = ldl_phys(pte_addr);
906
                if (!(pte & PG_PRESENT_MASK))
907
                    return -1;
908
                page_size = 4096;
909
            }
910
        }
911
        pte = pte & env->a20_mask;
912
    }
913

    
914
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
915
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
916
    return paddr;
917
}
918

    
919
void hw_breakpoint_insert(CPUState *env, int index)
920
{
921
    int type, err = 0;
922

    
923
    switch (hw_breakpoint_type(env->dr[7], index)) {
924
    case 0:
925
        if (hw_breakpoint_enabled(env->dr[7], index))
926
            err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
927
                                        &env->cpu_breakpoint[index]);
928
        break;
929
    case 1:
930
        type = BP_CPU | BP_MEM_WRITE;
931
        goto insert_wp;
932
    case 2:
933
         /* No support for I/O watchpoints yet */
934
        break;
935
    case 3:
936
        type = BP_CPU | BP_MEM_ACCESS;
937
    insert_wp:
938
        err = cpu_watchpoint_insert(env, env->dr[index],
939
                                    hw_breakpoint_len(env->dr[7], index),
940
                                    type, &env->cpu_watchpoint[index]);
941
        break;
942
    }
943
    if (err)
944
        env->cpu_breakpoint[index] = NULL;
945
}
946

    
947
void hw_breakpoint_remove(CPUState *env, int index)
948
{
949
    if (!env->cpu_breakpoint[index])
950
        return;
951
    switch (hw_breakpoint_type(env->dr[7], index)) {
952
    case 0:
953
        if (hw_breakpoint_enabled(env->dr[7], index))
954
            cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
955
        break;
956
    case 1:
957
    case 3:
958
        cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
959
        break;
960
    case 2:
961
        /* No support for I/O watchpoints yet */
962
        break;
963
    }
964
}
965

    
966
int check_hw_breakpoints(CPUState *env, int force_dr6_update)
967
{
968
    target_ulong dr6;
969
    int reg, type;
970
    int hit_enabled = 0;
971

    
972
    dr6 = env->dr[6] & ~0xf;
973
    for (reg = 0; reg < 4; reg++) {
974
        type = hw_breakpoint_type(env->dr[7], reg);
975
        if ((type == 0 && env->dr[reg] == env->eip) ||
976
            ((type & 1) && env->cpu_watchpoint[reg] &&
977
             (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
978
            dr6 |= 1 << reg;
979
            if (hw_breakpoint_enabled(env->dr[7], reg))
980
                hit_enabled = 1;
981
        }
982
    }
983
    if (hit_enabled || force_dr6_update)
984
        env->dr[6] = dr6;
985
    return hit_enabled;
986
}
987

    
988
static CPUDebugExcpHandler *prev_debug_excp_handler;
989

    
990
void raise_exception_env(int exception_index, CPUState *env);
991

    
992
static void breakpoint_handler(CPUState *env)
993
{
994
    CPUBreakpoint *bp;
995

    
996
    if (env->watchpoint_hit) {
997
        if (env->watchpoint_hit->flags & BP_CPU) {
998
            env->watchpoint_hit = NULL;
999
            if (check_hw_breakpoints(env, 0))
1000
                raise_exception_env(EXCP01_DB, env);
1001
            else
1002
                cpu_resume_from_signal(env, NULL);
1003
        }
1004
    } else {
1005
        QTAILQ_FOREACH(bp, &env->breakpoints, entry)
1006
            if (bp->pc == env->eip) {
1007
                if (bp->flags & BP_CPU) {
1008
                    check_hw_breakpoints(env, 1);
1009
                    raise_exception_env(EXCP01_DB, env);
1010
                }
1011
                break;
1012
            }
1013
    }
1014
    if (prev_debug_excp_handler)
1015
        prev_debug_excp_handler(env);
1016
}
1017

    
1018
/* This should come from sysemu.h - if we could include it here... */
1019
void qemu_system_reset_request(void);
1020

    
1021
void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
1022
                        uint64_t mcg_status, uint64_t addr, uint64_t misc)
1023
{
1024
    uint64_t mcg_cap = cenv->mcg_cap;
1025
    unsigned bank_num = mcg_cap & 0xff;
1026
    uint64_t *banks = cenv->mce_banks;
1027

    
1028
    if (bank >= bank_num || !(status & MCI_STATUS_VAL))
1029
        return;
1030

    
1031
    /*
1032
     * if MSR_MCG_CTL is not all 1s, the uncorrected error
1033
     * reporting is disabled
1034
     */
1035
    if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
1036
        cenv->mcg_ctl != ~(uint64_t)0)
1037
        return;
1038
    banks += 4 * bank;
1039
    /*
1040
     * if MSR_MCi_CTL is not all 1s, the uncorrected error
1041
     * reporting is disabled for the bank
1042
     */
1043
    if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0)
1044
        return;
1045
    if (status & MCI_STATUS_UC) {
1046
        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1047
            !(cenv->cr[4] & CR4_MCE_MASK)) {
1048
            fprintf(stderr, "injects mce exception while previous "
1049
                    "one is in progress!\n");
1050
            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1051
            qemu_system_reset_request();
1052
            return;
1053
        }
1054
        if (banks[1] & MCI_STATUS_VAL)
1055
            status |= MCI_STATUS_OVER;
1056
        banks[2] = addr;
1057
        banks[3] = misc;
1058
        cenv->mcg_status = mcg_status;
1059
        banks[1] = status;
1060
        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
1061
    } else if (!(banks[1] & MCI_STATUS_VAL)
1062
               || !(banks[1] & MCI_STATUS_UC)) {
1063
        if (banks[1] & MCI_STATUS_VAL)
1064
            status |= MCI_STATUS_OVER;
1065
        banks[2] = addr;
1066
        banks[3] = misc;
1067
        banks[1] = status;
1068
    } else
1069
        banks[1] |= MCI_STATUS_OVER;
1070
}
1071
#endif /* !CONFIG_USER_ONLY */
1072

    
1073
static void mce_init(CPUX86State *cenv)
1074
{
1075
    unsigned int bank, bank_num;
1076

    
1077
    if (((cenv->cpuid_version >> 8)&0xf) >= 6
1078
        && (cenv->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)) {
1079
        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1080
        cenv->mcg_ctl = ~(uint64_t)0;
1081
        bank_num = MCE_BANKS_DEF;
1082
        for (bank = 0; bank < bank_num; bank++)
1083
            cenv->mce_banks[bank*4] = ~(uint64_t)0;
1084
    }
1085
}
1086

    
1087
int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1088
                            target_ulong *base, unsigned int *limit,
1089
                            unsigned int *flags)
1090
{
1091
    SegmentCache *dt;
1092
    target_ulong ptr;
1093
    uint32_t e1, e2;
1094
    int index;
1095

    
1096
    if (selector & 0x4)
1097
        dt = &env->ldt;
1098
    else
1099
        dt = &env->gdt;
1100
    index = selector & ~7;
1101
    ptr = dt->base + index;
1102
    if ((index + 7) > dt->limit
1103
        || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1104
        || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1105
        return 0;
1106

    
1107
    *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1108
    *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1109
    if (e2 & DESC_G_MASK)
1110
        *limit = (*limit << 12) | 0xfff;
1111
    *flags = e2;
1112

    
1113
    return 1;
1114
}
1115

    
1116
CPUX86State *cpu_x86_init(const char *cpu_model)
1117
{
1118
    CPUX86State *env;
1119
    static int inited;
1120

    
1121
    env = qemu_mallocz(sizeof(CPUX86State));
1122
    cpu_exec_init(env);
1123
    env->cpu_model_str = cpu_model;
1124

    
1125
    /* init various static tables */
1126
    if (!inited) {
1127
        inited = 1;
1128
        optimize_flags_init();
1129
#ifndef CONFIG_USER_ONLY
1130
        prev_debug_excp_handler =
1131
            cpu_set_debug_excp_handler(breakpoint_handler);
1132
#endif
1133
    }
1134
    if (cpu_x86_register(env, cpu_model) < 0) {
1135
        cpu_x86_close(env);
1136
        return NULL;
1137
    }
1138
    mce_init(env);
1139

    
1140
    qemu_init_vcpu(env);
1141

    
1142
    return env;
1143
}
1144

    
1145
#if !defined(CONFIG_USER_ONLY)
1146
void do_cpu_init(CPUState *env)
1147
{
1148
    int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
1149
    cpu_reset(env);
1150
    env->interrupt_request = sipi;
1151
    apic_init_reset(env);
1152
}
1153

    
1154
void do_cpu_sipi(CPUState *env)
1155
{
1156
    apic_sipi(env);
1157
}
1158
#else
1159
void do_cpu_init(CPUState *env)
1160
{
1161
}
1162
void do_cpu_sipi(CPUState *env)
1163
{
1164
}
1165
#endif