Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ b5e5a934

History | View | Annotate | Download (36.9 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, "%s",
218
                    sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
219
                                 [(sc->flags & DESC_TYPE_MASK)
220
                                  >> DESC_TYPE_SHIFT]);
221
    }
222
done:
223
    cpu_fprintf(f, "\n");
224
}
225

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

    
234
    cpu_synchronize_state(env);
235

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

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

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

    
412
/***********************************************************/
413
/* x86 mmu */
414
/* XXX: add PGE support */
415

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

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

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

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

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

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

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

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

    
505
    env->cr[4] = new_cr4;
506
}
507

    
508
#if defined(CONFIG_USER_ONLY)
509

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

    
522
#else
523

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
990
static CPUDebugExcpHandler *prev_debug_excp_handler;
991

    
992
void raise_exception_env(int exception_index, CPUState *env);
993

    
994
static void breakpoint_handler(CPUState *env)
995
{
996
    CPUBreakpoint *bp;
997

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

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

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

    
1030
    if (bank >= bank_num || !(status & MCI_STATUS_VAL))
1031
        return;
1032

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

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

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

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

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

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

    
1115
    return 1;
1116
}
1117

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

    
1123
    env = qemu_mallocz(sizeof(CPUX86State));
1124
    cpu_exec_init(env);
1125
    env->cpu_model_str = cpu_model;
1126

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

    
1142
    qemu_init_vcpu(env);
1143

    
1144
    return env;
1145
}
1146

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

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