Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ 29057492

History | View | Annotate | Download (39.3 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
#include "kvm_x86.h"
31

    
32
//#define DEBUG_MMU
33

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

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

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

    
46
    tlb_flush(env, 1);
47

    
48
    env->old_exception = -1;
49

    
50
    /* init to reset state */
51

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

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

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

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

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

    
90
    env->eflags = 0x2;
91

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

    
97
    env->mxcsr = 0x1f80;
98

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

    
105
    env->mcg_status = 0;
106
}
107

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

    
113
static void cpu_x86_version(CPUState *env, int *family, int *model)
114
{
115
    int cpuver = env->cpuid_version;
116

    
117
    if (family == NULL || model == NULL) {
118
        return;
119
    }
120

    
121
    *family = (cpuver >> 8) & 0x0f;
122
    *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
123
}
124

    
125
/* Broadcast MCA signal for processor version 06H_EH and above */
126
int cpu_x86_support_mca_broadcast(CPUState *env)
127
{
128
    int family = 0;
129
    int model = 0;
130

    
131
    cpu_x86_version(env, &family, &model);
132
    if ((family == 6 && model >= 14) || family > 6) {
133
        return 1;
134
    }
135

    
136
    return 0;
137
}
138

    
139
/***********************************************************/
140
/* x86 debug */
141

    
142
static const char *cc_op_str[] = {
143
    "DYNAMIC",
144
    "EFLAGS",
145

    
146
    "MULB",
147
    "MULW",
148
    "MULL",
149
    "MULQ",
150

    
151
    "ADDB",
152
    "ADDW",
153
    "ADDL",
154
    "ADDQ",
155

    
156
    "ADCB",
157
    "ADCW",
158
    "ADCL",
159
    "ADCQ",
160

    
161
    "SUBB",
162
    "SUBW",
163
    "SUBL",
164
    "SUBQ",
165

    
166
    "SBBB",
167
    "SBBW",
168
    "SBBL",
169
    "SBBQ",
170

    
171
    "LOGICB",
172
    "LOGICW",
173
    "LOGICL",
174
    "LOGICQ",
175

    
176
    "INCB",
177
    "INCW",
178
    "INCL",
179
    "INCQ",
180

    
181
    "DECB",
182
    "DECW",
183
    "DECL",
184
    "DECQ",
185

    
186
    "SHLB",
187
    "SHLW",
188
    "SHLL",
189
    "SHLQ",
190

    
191
    "SARB",
192
    "SARW",
193
    "SARL",
194
    "SARQ",
195
};
196

    
197
static void
198
cpu_x86_dump_seg_cache(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
199
                       const char *name, struct SegmentCache *sc)
200
{
201
#ifdef TARGET_X86_64
202
    if (env->hflags & HF_CS64_MASK) {
203
        cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
204
                    sc->selector, sc->base, sc->limit, sc->flags & 0x00ffff00);
205
    } else
206
#endif
207
    {
208
        cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
209
                    (uint32_t)sc->base, sc->limit, sc->flags & 0x00ffff00);
210
    }
211

    
212
    if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
213
        goto done;
214

    
215
    cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
216
    if (sc->flags & DESC_S_MASK) {
217
        if (sc->flags & DESC_CS_MASK) {
218
            cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
219
                           ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
220
            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
221
                        (sc->flags & DESC_R_MASK) ? 'R' : '-');
222
        } else {
223
            cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS  " : "DS16");
224
            cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
225
                        (sc->flags & DESC_W_MASK) ? 'W' : '-');
226
        }
227
        cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
228
    } else {
229
        static const char *sys_type_name[2][16] = {
230
            { /* 32 bit mode */
231
                "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
232
                "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
233
                "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
234
                "CallGate32", "Reserved", "IntGate32", "TrapGate32"
235
            },
236
            { /* 64 bit mode */
237
                "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
238
                "Reserved", "Reserved", "Reserved", "Reserved",
239
                "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
240
                "Reserved", "IntGate64", "TrapGate64"
241
            }
242
        };
243
        cpu_fprintf(f, "%s",
244
                    sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
245
                                 [(sc->flags & DESC_TYPE_MASK)
246
                                  >> DESC_TYPE_SHIFT]);
247
    }
248
done:
249
    cpu_fprintf(f, "\n");
250
}
251

    
252
#define DUMP_CODE_BYTES_TOTAL    50
253
#define DUMP_CODE_BYTES_BACKWARD 20
254

    
255
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
256
                    int flags)
257
{
258
    int eflags, i, nb;
259
    char cc_op_name[32];
260
    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
261

    
262
    cpu_synchronize_state(env);
263

    
264
    eflags = env->eflags;
265
#ifdef TARGET_X86_64
266
    if (env->hflags & HF_CS64_MASK) {
267
        cpu_fprintf(f,
268
                    "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
269
                    "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
270
                    "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
271
                    "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
272
                    "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
273
                    env->regs[R_EAX],
274
                    env->regs[R_EBX],
275
                    env->regs[R_ECX],
276
                    env->regs[R_EDX],
277
                    env->regs[R_ESI],
278
                    env->regs[R_EDI],
279
                    env->regs[R_EBP],
280
                    env->regs[R_ESP],
281
                    env->regs[8],
282
                    env->regs[9],
283
                    env->regs[10],
284
                    env->regs[11],
285
                    env->regs[12],
286
                    env->regs[13],
287
                    env->regs[14],
288
                    env->regs[15],
289
                    env->eip, eflags,
290
                    eflags & DF_MASK ? 'D' : '-',
291
                    eflags & CC_O ? 'O' : '-',
292
                    eflags & CC_S ? 'S' : '-',
293
                    eflags & CC_Z ? 'Z' : '-',
294
                    eflags & CC_A ? 'A' : '-',
295
                    eflags & CC_P ? 'P' : '-',
296
                    eflags & CC_C ? 'C' : '-',
297
                    env->hflags & HF_CPL_MASK,
298
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
299
                    (env->a20_mask >> 20) & 1,
300
                    (env->hflags >> HF_SMM_SHIFT) & 1,
301
                    env->halted);
302
    } else
303
#endif
304
    {
305
        cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
306
                    "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
307
                    "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
308
                    (uint32_t)env->regs[R_EAX],
309
                    (uint32_t)env->regs[R_EBX],
310
                    (uint32_t)env->regs[R_ECX],
311
                    (uint32_t)env->regs[R_EDX],
312
                    (uint32_t)env->regs[R_ESI],
313
                    (uint32_t)env->regs[R_EDI],
314
                    (uint32_t)env->regs[R_EBP],
315
                    (uint32_t)env->regs[R_ESP],
316
                    (uint32_t)env->eip, eflags,
317
                    eflags & DF_MASK ? 'D' : '-',
318
                    eflags & CC_O ? 'O' : '-',
319
                    eflags & CC_S ? 'S' : '-',
320
                    eflags & CC_Z ? 'Z' : '-',
321
                    eflags & CC_A ? 'A' : '-',
322
                    eflags & CC_P ? 'P' : '-',
323
                    eflags & CC_C ? 'C' : '-',
324
                    env->hflags & HF_CPL_MASK,
325
                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
326
                    (env->a20_mask >> 20) & 1,
327
                    (env->hflags >> HF_SMM_SHIFT) & 1,
328
                    env->halted);
329
    }
330

    
331
    for(i = 0; i < 6; i++) {
332
        cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
333
                               &env->segs[i]);
334
    }
335
    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
336
    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
337

    
338
#ifdef TARGET_X86_64
339
    if (env->hflags & HF_LMA_MASK) {
340
        cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
341
                    env->gdt.base, env->gdt.limit);
342
        cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
343
                    env->idt.base, env->idt.limit);
344
        cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
345
                    (uint32_t)env->cr[0],
346
                    env->cr[2],
347
                    env->cr[3],
348
                    (uint32_t)env->cr[4]);
349
        for(i = 0; i < 4; i++)
350
            cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
351
        cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
352
                    env->dr[6], env->dr[7]);
353
    } else
354
#endif
355
    {
356
        cpu_fprintf(f, "GDT=     %08x %08x\n",
357
                    (uint32_t)env->gdt.base, env->gdt.limit);
358
        cpu_fprintf(f, "IDT=     %08x %08x\n",
359
                    (uint32_t)env->idt.base, env->idt.limit);
360
        cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
361
                    (uint32_t)env->cr[0],
362
                    (uint32_t)env->cr[2],
363
                    (uint32_t)env->cr[3],
364
                    (uint32_t)env->cr[4]);
365
        for(i = 0; i < 4; i++) {
366
            cpu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
367
        }
368
        cpu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
369
                    env->dr[6], env->dr[7]);
370
    }
371
    if (flags & X86_DUMP_CCOP) {
372
        if ((unsigned)env->cc_op < CC_OP_NB)
373
            snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
374
        else
375
            snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
376
#ifdef TARGET_X86_64
377
        if (env->hflags & HF_CS64_MASK) {
378
            cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
379
                        env->cc_src, env->cc_dst,
380
                        cc_op_name);
381
        } else
382
#endif
383
        {
384
            cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
385
                        (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
386
                        cc_op_name);
387
        }
388
    }
389
    cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
390
    if (flags & X86_DUMP_FPU) {
391
        int fptag;
392
        fptag = 0;
393
        for(i = 0; i < 8; i++) {
394
            fptag |= ((!env->fptags[i]) << i);
395
        }
396
        cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
397
                    env->fpuc,
398
                    (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
399
                    env->fpstt,
400
                    fptag,
401
                    env->mxcsr);
402
        for(i=0;i<8;i++) {
403
#if defined(USE_X86LDOUBLE)
404
            union {
405
                long double d;
406
                struct {
407
                    uint64_t lower;
408
                    uint16_t upper;
409
                } l;
410
            } tmp;
411
            tmp.d = env->fpregs[i].d;
412
            cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
413
                        i, tmp.l.lower, tmp.l.upper);
414
#else
415
            cpu_fprintf(f, "FPR%d=%016" PRIx64,
416
                        i, env->fpregs[i].mmx.q);
417
#endif
418
            if ((i & 1) == 1)
419
                cpu_fprintf(f, "\n");
420
            else
421
                cpu_fprintf(f, " ");
422
        }
423
        if (env->hflags & HF_CS64_MASK)
424
            nb = 16;
425
        else
426
            nb = 8;
427
        for(i=0;i<nb;i++) {
428
            cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
429
                        i,
430
                        env->xmm_regs[i].XMM_L(3),
431
                        env->xmm_regs[i].XMM_L(2),
432
                        env->xmm_regs[i].XMM_L(1),
433
                        env->xmm_regs[i].XMM_L(0));
434
            if ((i & 1) == 1)
435
                cpu_fprintf(f, "\n");
436
            else
437
                cpu_fprintf(f, " ");
438
        }
439
    }
440
    if (flags & CPU_DUMP_CODE) {
441
        target_ulong base = env->segs[R_CS].base + env->eip;
442
        target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
443
        uint8_t code;
444
        char codestr[3];
445

    
446
        cpu_fprintf(f, "Code=");
447
        for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
448
            if (cpu_memory_rw_debug(env, base - offs + i, &code, 1, 0) == 0) {
449
                snprintf(codestr, sizeof(codestr), "%02x", code);
450
            } else {
451
                snprintf(codestr, sizeof(codestr), "??");
452
            }
453
            cpu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
454
                        i == offs ? "<" : "", codestr, i == offs ? ">" : "");
455
        }
456
        cpu_fprintf(f, "\n");
457
    }
458
}
459

    
460
/***********************************************************/
461
/* x86 mmu */
462
/* XXX: add PGE support */
463

    
464
void cpu_x86_set_a20(CPUX86State *env, int a20_state)
465
{
466
    a20_state = (a20_state != 0);
467
    if (a20_state != ((env->a20_mask >> 20) & 1)) {
468
#if defined(DEBUG_MMU)
469
        printf("A20 update: a20=%d\n", a20_state);
470
#endif
471
        /* if the cpu is currently executing code, we must unlink it and
472
           all the potentially executing TB */
473
        cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
474

    
475
        /* when a20 is changed, all the MMU mappings are invalid, so
476
           we must flush everything */
477
        tlb_flush(env, 1);
478
        env->a20_mask = ~(1 << 20) | (a20_state << 20);
479
    }
480
}
481

    
482
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
483
{
484
    int pe_state;
485

    
486
#if defined(DEBUG_MMU)
487
    printf("CR0 update: CR0=0x%08x\n", new_cr0);
488
#endif
489
    if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
490
        (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
491
        tlb_flush(env, 1);
492
    }
493

    
494
#ifdef TARGET_X86_64
495
    if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
496
        (env->efer & MSR_EFER_LME)) {
497
        /* enter in long mode */
498
        /* XXX: generate an exception */
499
        if (!(env->cr[4] & CR4_PAE_MASK))
500
            return;
501
        env->efer |= MSR_EFER_LMA;
502
        env->hflags |= HF_LMA_MASK;
503
    } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
504
               (env->efer & MSR_EFER_LMA)) {
505
        /* exit long mode */
506
        env->efer &= ~MSR_EFER_LMA;
507
        env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
508
        env->eip &= 0xffffffff;
509
    }
510
#endif
511
    env->cr[0] = new_cr0 | CR0_ET_MASK;
512

    
513
    /* update PE flag in hidden flags */
514
    pe_state = (env->cr[0] & CR0_PE_MASK);
515
    env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
516
    /* ensure that ADDSEG is always set in real mode */
517
    env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
518
    /* update FPU flags */
519
    env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
520
        ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
521
}
522

    
523
/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
524
   the PDPT */
525
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
526
{
527
    env->cr[3] = new_cr3;
528
    if (env->cr[0] & CR0_PG_MASK) {
529
#if defined(DEBUG_MMU)
530
        printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
531
#endif
532
        tlb_flush(env, 0);
533
    }
534
}
535

    
536
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
537
{
538
#if defined(DEBUG_MMU)
539
    printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
540
#endif
541
    if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
542
        (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
543
        tlb_flush(env, 1);
544
    }
545
    /* SSE handling */
546
    if (!(env->cpuid_features & CPUID_SSE))
547
        new_cr4 &= ~CR4_OSFXSR_MASK;
548
    if (new_cr4 & CR4_OSFXSR_MASK)
549
        env->hflags |= HF_OSFXSR_MASK;
550
    else
551
        env->hflags &= ~HF_OSFXSR_MASK;
552

    
553
    env->cr[4] = new_cr4;
554
}
555

    
556
#if defined(CONFIG_USER_ONLY)
557

    
558
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
559
                             int is_write, int mmu_idx, int is_softmmu)
560
{
561
    /* user mode only emulation */
562
    is_write &= 1;
563
    env->cr[2] = addr;
564
    env->error_code = (is_write << PG_ERROR_W_BIT);
565
    env->error_code |= PG_ERROR_U_MASK;
566
    env->exception_index = EXCP0E_PAGE;
567
    return 1;
568
}
569

    
570
#else
571

    
572
/* XXX: This value should match the one returned by CPUID
573
 * and in exec.c */
574
# if defined(TARGET_X86_64)
575
# define PHYS_ADDR_MASK 0xfffffff000LL
576
# else
577
# define PHYS_ADDR_MASK 0xffffff000LL
578
# endif
579

    
580
/* return value:
581
   -1 = cannot handle fault
582
   0  = nothing more to do
583
   1  = generate PF fault
584
*/
585
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
586
                             int is_write1, int mmu_idx, int is_softmmu)
587
{
588
    uint64_t ptep, pte;
589
    target_ulong pde_addr, pte_addr;
590
    int error_code, is_dirty, prot, page_size, is_write, is_user;
591
    target_phys_addr_t paddr;
592
    uint32_t page_offset;
593
    target_ulong vaddr, virt_addr;
594

    
595
    is_user = mmu_idx == MMU_USER_IDX;
596
#if defined(DEBUG_MMU)
597
    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
598
           addr, is_write1, is_user, env->eip);
599
#endif
600
    is_write = is_write1 & 1;
601

    
602
    if (!(env->cr[0] & CR0_PG_MASK)) {
603
        pte = addr;
604
        virt_addr = addr & TARGET_PAGE_MASK;
605
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
606
        page_size = 4096;
607
        goto do_mapping;
608
    }
609

    
610
    if (env->cr[4] & CR4_PAE_MASK) {
611
        uint64_t pde, pdpe;
612
        target_ulong pdpe_addr;
613

    
614
#ifdef TARGET_X86_64
615
        if (env->hflags & HF_LMA_MASK) {
616
            uint64_t pml4e_addr, pml4e;
617
            int32_t sext;
618

    
619
            /* test virtual address sign extension */
620
            sext = (int64_t)addr >> 47;
621
            if (sext != 0 && sext != -1) {
622
                env->error_code = 0;
623
                env->exception_index = EXCP0D_GPF;
624
                return 1;
625
            }
626

    
627
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
628
                env->a20_mask;
629
            pml4e = ldq_phys(pml4e_addr);
630
            if (!(pml4e & PG_PRESENT_MASK)) {
631
                error_code = 0;
632
                goto do_fault;
633
            }
634
            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
635
                error_code = PG_ERROR_RSVD_MASK;
636
                goto do_fault;
637
            }
638
            if (!(pml4e & PG_ACCESSED_MASK)) {
639
                pml4e |= PG_ACCESSED_MASK;
640
                stl_phys_notdirty(pml4e_addr, pml4e);
641
            }
642
            ptep = pml4e ^ PG_NX_MASK;
643
            pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
644
                env->a20_mask;
645
            pdpe = ldq_phys(pdpe_addr);
646
            if (!(pdpe & PG_PRESENT_MASK)) {
647
                error_code = 0;
648
                goto do_fault;
649
            }
650
            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
651
                error_code = PG_ERROR_RSVD_MASK;
652
                goto do_fault;
653
            }
654
            ptep &= pdpe ^ PG_NX_MASK;
655
            if (!(pdpe & PG_ACCESSED_MASK)) {
656
                pdpe |= PG_ACCESSED_MASK;
657
                stl_phys_notdirty(pdpe_addr, pdpe);
658
            }
659
        } else
660
#endif
661
        {
662
            /* XXX: load them when cr3 is loaded ? */
663
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
664
                env->a20_mask;
665
            pdpe = ldq_phys(pdpe_addr);
666
            if (!(pdpe & PG_PRESENT_MASK)) {
667
                error_code = 0;
668
                goto do_fault;
669
            }
670
            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
671
        }
672

    
673
        pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
674
            env->a20_mask;
675
        pde = ldq_phys(pde_addr);
676
        if (!(pde & PG_PRESENT_MASK)) {
677
            error_code = 0;
678
            goto do_fault;
679
        }
680
        if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
681
            error_code = PG_ERROR_RSVD_MASK;
682
            goto do_fault;
683
        }
684
        ptep &= pde ^ PG_NX_MASK;
685
        if (pde & PG_PSE_MASK) {
686
            /* 2 MB page */
687
            page_size = 2048 * 1024;
688
            ptep ^= PG_NX_MASK;
689
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
690
                goto do_fault_protect;
691
            if (is_user) {
692
                if (!(ptep & PG_USER_MASK))
693
                    goto do_fault_protect;
694
                if (is_write && !(ptep & PG_RW_MASK))
695
                    goto do_fault_protect;
696
            } else {
697
                if ((env->cr[0] & CR0_WP_MASK) &&
698
                    is_write && !(ptep & PG_RW_MASK))
699
                    goto do_fault_protect;
700
            }
701
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
702
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
703
                pde |= PG_ACCESSED_MASK;
704
                if (is_dirty)
705
                    pde |= PG_DIRTY_MASK;
706
                stl_phys_notdirty(pde_addr, pde);
707
            }
708
            /* align to page_size */
709
            pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
710
            virt_addr = addr & ~(page_size - 1);
711
        } else {
712
            /* 4 KB page */
713
            if (!(pde & PG_ACCESSED_MASK)) {
714
                pde |= PG_ACCESSED_MASK;
715
                stl_phys_notdirty(pde_addr, pde);
716
            }
717
            pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
718
                env->a20_mask;
719
            pte = ldq_phys(pte_addr);
720
            if (!(pte & PG_PRESENT_MASK)) {
721
                error_code = 0;
722
                goto do_fault;
723
            }
724
            if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
725
                error_code = PG_ERROR_RSVD_MASK;
726
                goto do_fault;
727
            }
728
            /* combine pde and pte nx, user and rw protections */
729
            ptep &= pte ^ PG_NX_MASK;
730
            ptep ^= PG_NX_MASK;
731
            if ((ptep & PG_NX_MASK) && is_write1 == 2)
732
                goto do_fault_protect;
733
            if (is_user) {
734
                if (!(ptep & PG_USER_MASK))
735
                    goto do_fault_protect;
736
                if (is_write && !(ptep & PG_RW_MASK))
737
                    goto do_fault_protect;
738
            } else {
739
                if ((env->cr[0] & CR0_WP_MASK) &&
740
                    is_write && !(ptep & PG_RW_MASK))
741
                    goto do_fault_protect;
742
            }
743
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
744
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
745
                pte |= PG_ACCESSED_MASK;
746
                if (is_dirty)
747
                    pte |= PG_DIRTY_MASK;
748
                stl_phys_notdirty(pte_addr, pte);
749
            }
750
            page_size = 4096;
751
            virt_addr = addr & ~0xfff;
752
            pte = pte & (PHYS_ADDR_MASK | 0xfff);
753
        }
754
    } else {
755
        uint32_t pde;
756

    
757
        /* page directory entry */
758
        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
759
            env->a20_mask;
760
        pde = ldl_phys(pde_addr);
761
        if (!(pde & PG_PRESENT_MASK)) {
762
            error_code = 0;
763
            goto do_fault;
764
        }
765
        /* if PSE bit is set, then we use a 4MB page */
766
        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
767
            page_size = 4096 * 1024;
768
            if (is_user) {
769
                if (!(pde & PG_USER_MASK))
770
                    goto do_fault_protect;
771
                if (is_write && !(pde & PG_RW_MASK))
772
                    goto do_fault_protect;
773
            } else {
774
                if ((env->cr[0] & CR0_WP_MASK) &&
775
                    is_write && !(pde & PG_RW_MASK))
776
                    goto do_fault_protect;
777
            }
778
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
779
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
780
                pde |= PG_ACCESSED_MASK;
781
                if (is_dirty)
782
                    pde |= PG_DIRTY_MASK;
783
                stl_phys_notdirty(pde_addr, pde);
784
            }
785

    
786
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
787
            ptep = pte;
788
            virt_addr = addr & ~(page_size - 1);
789
        } else {
790
            if (!(pde & PG_ACCESSED_MASK)) {
791
                pde |= PG_ACCESSED_MASK;
792
                stl_phys_notdirty(pde_addr, pde);
793
            }
794

    
795
            /* page directory entry */
796
            pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
797
                env->a20_mask;
798
            pte = ldl_phys(pte_addr);
799
            if (!(pte & PG_PRESENT_MASK)) {
800
                error_code = 0;
801
                goto do_fault;
802
            }
803
            /* combine pde and pte user and rw protections */
804
            ptep = pte & pde;
805
            if (is_user) {
806
                if (!(ptep & PG_USER_MASK))
807
                    goto do_fault_protect;
808
                if (is_write && !(ptep & PG_RW_MASK))
809
                    goto do_fault_protect;
810
            } else {
811
                if ((env->cr[0] & CR0_WP_MASK) &&
812
                    is_write && !(ptep & PG_RW_MASK))
813
                    goto do_fault_protect;
814
            }
815
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
816
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
817
                pte |= PG_ACCESSED_MASK;
818
                if (is_dirty)
819
                    pte |= PG_DIRTY_MASK;
820
                stl_phys_notdirty(pte_addr, pte);
821
            }
822
            page_size = 4096;
823
            virt_addr = addr & ~0xfff;
824
        }
825
    }
826
    /* the page can be put in the TLB */
827
    prot = PAGE_READ;
828
    if (!(ptep & PG_NX_MASK))
829
        prot |= PAGE_EXEC;
830
    if (pte & PG_DIRTY_MASK) {
831
        /* only set write access if already dirty... otherwise wait
832
           for dirty access */
833
        if (is_user) {
834
            if (ptep & PG_RW_MASK)
835
                prot |= PAGE_WRITE;
836
        } else {
837
            if (!(env->cr[0] & CR0_WP_MASK) ||
838
                (ptep & PG_RW_MASK))
839
                prot |= PAGE_WRITE;
840
        }
841
    }
842
 do_mapping:
843
    pte = pte & env->a20_mask;
844

    
845
    /* Even if 4MB pages, we map only one 4KB page in the cache to
846
       avoid filling it too fast */
847
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
848
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
849
    vaddr = virt_addr + page_offset;
850

    
851
    tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
852
    return 0;
853
 do_fault_protect:
854
    error_code = PG_ERROR_P_MASK;
855
 do_fault:
856
    error_code |= (is_write << PG_ERROR_W_BIT);
857
    if (is_user)
858
        error_code |= PG_ERROR_U_MASK;
859
    if (is_write1 == 2 &&
860
        (env->efer & MSR_EFER_NXE) &&
861
        (env->cr[4] & CR4_PAE_MASK))
862
        error_code |= PG_ERROR_I_D_MASK;
863
    if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
864
        /* cr2 is not modified in case of exceptions */
865
        stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 
866
                 addr);
867
    } else {
868
        env->cr[2] = addr;
869
    }
870
    env->error_code = error_code;
871
    env->exception_index = EXCP0E_PAGE;
872
    return 1;
873
}
874

    
875
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
876
{
877
    target_ulong pde_addr, pte_addr;
878
    uint64_t pte;
879
    target_phys_addr_t paddr;
880
    uint32_t page_offset;
881
    int page_size;
882

    
883
    if (env->cr[4] & CR4_PAE_MASK) {
884
        target_ulong pdpe_addr;
885
        uint64_t pde, pdpe;
886

    
887
#ifdef TARGET_X86_64
888
        if (env->hflags & HF_LMA_MASK) {
889
            uint64_t pml4e_addr, pml4e;
890
            int32_t sext;
891

    
892
            /* test virtual address sign extension */
893
            sext = (int64_t)addr >> 47;
894
            if (sext != 0 && sext != -1)
895
                return -1;
896

    
897
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
898
                env->a20_mask;
899
            pml4e = ldq_phys(pml4e_addr);
900
            if (!(pml4e & PG_PRESENT_MASK))
901
                return -1;
902

    
903
            pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
904
                env->a20_mask;
905
            pdpe = ldq_phys(pdpe_addr);
906
            if (!(pdpe & PG_PRESENT_MASK))
907
                return -1;
908
        } else
909
#endif
910
        {
911
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
912
                env->a20_mask;
913
            pdpe = ldq_phys(pdpe_addr);
914
            if (!(pdpe & PG_PRESENT_MASK))
915
                return -1;
916
        }
917

    
918
        pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
919
            env->a20_mask;
920
        pde = ldq_phys(pde_addr);
921
        if (!(pde & PG_PRESENT_MASK)) {
922
            return -1;
923
        }
924
        if (pde & PG_PSE_MASK) {
925
            /* 2 MB page */
926
            page_size = 2048 * 1024;
927
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
928
        } else {
929
            /* 4 KB page */
930
            pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
931
                env->a20_mask;
932
            page_size = 4096;
933
            pte = ldq_phys(pte_addr);
934
        }
935
        if (!(pte & PG_PRESENT_MASK))
936
            return -1;
937
    } else {
938
        uint32_t pde;
939

    
940
        if (!(env->cr[0] & CR0_PG_MASK)) {
941
            pte = addr;
942
            page_size = 4096;
943
        } else {
944
            /* page directory entry */
945
            pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
946
            pde = ldl_phys(pde_addr);
947
            if (!(pde & PG_PRESENT_MASK))
948
                return -1;
949
            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
950
                pte = pde & ~0x003ff000; /* align to 4MB */
951
                page_size = 4096 * 1024;
952
            } else {
953
                /* page directory entry */
954
                pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
955
                pte = ldl_phys(pte_addr);
956
                if (!(pte & PG_PRESENT_MASK))
957
                    return -1;
958
                page_size = 4096;
959
            }
960
        }
961
        pte = pte & env->a20_mask;
962
    }
963

    
964
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
965
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
966
    return paddr;
967
}
968

    
969
void hw_breakpoint_insert(CPUState *env, int index)
970
{
971
    int type, err = 0;
972

    
973
    switch (hw_breakpoint_type(env->dr[7], index)) {
974
    case 0:
975
        if (hw_breakpoint_enabled(env->dr[7], index))
976
            err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
977
                                        &env->cpu_breakpoint[index]);
978
        break;
979
    case 1:
980
        type = BP_CPU | BP_MEM_WRITE;
981
        goto insert_wp;
982
    case 2:
983
         /* No support for I/O watchpoints yet */
984
        break;
985
    case 3:
986
        type = BP_CPU | BP_MEM_ACCESS;
987
    insert_wp:
988
        err = cpu_watchpoint_insert(env, env->dr[index],
989
                                    hw_breakpoint_len(env->dr[7], index),
990
                                    type, &env->cpu_watchpoint[index]);
991
        break;
992
    }
993
    if (err)
994
        env->cpu_breakpoint[index] = NULL;
995
}
996

    
997
void hw_breakpoint_remove(CPUState *env, int index)
998
{
999
    if (!env->cpu_breakpoint[index])
1000
        return;
1001
    switch (hw_breakpoint_type(env->dr[7], index)) {
1002
    case 0:
1003
        if (hw_breakpoint_enabled(env->dr[7], index))
1004
            cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
1005
        break;
1006
    case 1:
1007
    case 3:
1008
        cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
1009
        break;
1010
    case 2:
1011
        /* No support for I/O watchpoints yet */
1012
        break;
1013
    }
1014
}
1015

    
1016
int check_hw_breakpoints(CPUState *env, int force_dr6_update)
1017
{
1018
    target_ulong dr6;
1019
    int reg, type;
1020
    int hit_enabled = 0;
1021

    
1022
    dr6 = env->dr[6] & ~0xf;
1023
    for (reg = 0; reg < 4; reg++) {
1024
        type = hw_breakpoint_type(env->dr[7], reg);
1025
        if ((type == 0 && env->dr[reg] == env->eip) ||
1026
            ((type & 1) && env->cpu_watchpoint[reg] &&
1027
             (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
1028
            dr6 |= 1 << reg;
1029
            if (hw_breakpoint_enabled(env->dr[7], reg))
1030
                hit_enabled = 1;
1031
        }
1032
    }
1033
    if (hit_enabled || force_dr6_update)
1034
        env->dr[6] = dr6;
1035
    return hit_enabled;
1036
}
1037

    
1038
static CPUDebugExcpHandler *prev_debug_excp_handler;
1039

    
1040
void raise_exception_env(int exception_index, CPUState *env);
1041

    
1042
static void breakpoint_handler(CPUState *env)
1043
{
1044
    CPUBreakpoint *bp;
1045

    
1046
    if (env->watchpoint_hit) {
1047
        if (env->watchpoint_hit->flags & BP_CPU) {
1048
            env->watchpoint_hit = NULL;
1049
            if (check_hw_breakpoints(env, 0))
1050
                raise_exception_env(EXCP01_DB, env);
1051
            else
1052
                cpu_resume_from_signal(env, NULL);
1053
        }
1054
    } else {
1055
        QTAILQ_FOREACH(bp, &env->breakpoints, entry)
1056
            if (bp->pc == env->eip) {
1057
                if (bp->flags & BP_CPU) {
1058
                    check_hw_breakpoints(env, 1);
1059
                    raise_exception_env(EXCP01_DB, env);
1060
                }
1061
                break;
1062
            }
1063
    }
1064
    if (prev_debug_excp_handler)
1065
        prev_debug_excp_handler(env);
1066
}
1067

    
1068
/* This should come from sysemu.h - if we could include it here... */
1069
void qemu_system_reset_request(void);
1070

    
1071
static void qemu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
1072
                        uint64_t mcg_status, uint64_t addr, uint64_t misc)
1073
{
1074
    uint64_t mcg_cap = cenv->mcg_cap;
1075
    uint64_t *banks = cenv->mce_banks;
1076

    
1077
    /*
1078
     * if MSR_MCG_CTL is not all 1s, the uncorrected error
1079
     * reporting is disabled
1080
     */
1081
    if ((status & MCI_STATUS_UC) && (mcg_cap & MCG_CTL_P) &&
1082
        cenv->mcg_ctl != ~(uint64_t)0)
1083
        return;
1084
    banks += 4 * bank;
1085
    /*
1086
     * if MSR_MCi_CTL is not all 1s, the uncorrected error
1087
     * reporting is disabled for the bank
1088
     */
1089
    if ((status & MCI_STATUS_UC) && banks[0] != ~(uint64_t)0)
1090
        return;
1091
    if (status & MCI_STATUS_UC) {
1092
        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1093
            !(cenv->cr[4] & CR4_MCE_MASK)) {
1094
            fprintf(stderr, "injects mce exception while previous "
1095
                    "one is in progress!\n");
1096
            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1097
            qemu_system_reset_request();
1098
            return;
1099
        }
1100
        if (banks[1] & MCI_STATUS_VAL)
1101
            status |= MCI_STATUS_OVER;
1102
        banks[2] = addr;
1103
        banks[3] = misc;
1104
        cenv->mcg_status = mcg_status;
1105
        banks[1] = status;
1106
        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
1107
    } else if (!(banks[1] & MCI_STATUS_VAL)
1108
               || !(banks[1] & MCI_STATUS_UC)) {
1109
        if (banks[1] & MCI_STATUS_VAL)
1110
            status |= MCI_STATUS_OVER;
1111
        banks[2] = addr;
1112
        banks[3] = misc;
1113
        banks[1] = status;
1114
    } else
1115
        banks[1] |= MCI_STATUS_OVER;
1116
}
1117

    
1118
void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
1119
                        uint64_t mcg_status, uint64_t addr, uint64_t misc,
1120
                        int broadcast)
1121
{
1122
    unsigned bank_num = cenv->mcg_cap & 0xff;
1123
    CPUState *env;
1124
    int flag = 0;
1125

    
1126
    if (bank >= bank_num || !(status & MCI_STATUS_VAL)) {
1127
        return;
1128
    }
1129

    
1130
    if (broadcast) {
1131
        if (!cpu_x86_support_mca_broadcast(cenv)) {
1132
            fprintf(stderr, "Current CPU does not support broadcast\n");
1133
            return;
1134
        }
1135
    }
1136

    
1137
    if (kvm_enabled()) {
1138
        if (broadcast) {
1139
            flag |= MCE_BROADCAST;
1140
        }
1141

    
1142
        kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, flag);
1143
    } else {
1144
        qemu_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
1145
        if (broadcast) {
1146
            for (env = first_cpu; env != NULL; env = env->next_cpu) {
1147
                if (cenv == env) {
1148
                    continue;
1149
                }
1150
                qemu_inject_x86_mce(env, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
1151
                                    MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0);
1152
            }
1153
        }
1154
    }
1155
}
1156
#endif /* !CONFIG_USER_ONLY */
1157

    
1158
static void mce_init(CPUX86State *cenv)
1159
{
1160
    unsigned int bank, bank_num;
1161

    
1162
    if (((cenv->cpuid_version >> 8)&0xf) >= 6
1163
        && (cenv->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)) {
1164
        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1165
        cenv->mcg_ctl = ~(uint64_t)0;
1166
        bank_num = MCE_BANKS_DEF;
1167
        for (bank = 0; bank < bank_num; bank++)
1168
            cenv->mce_banks[bank*4] = ~(uint64_t)0;
1169
    }
1170
}
1171

    
1172
int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1173
                            target_ulong *base, unsigned int *limit,
1174
                            unsigned int *flags)
1175
{
1176
    SegmentCache *dt;
1177
    target_ulong ptr;
1178
    uint32_t e1, e2;
1179
    int index;
1180

    
1181
    if (selector & 0x4)
1182
        dt = &env->ldt;
1183
    else
1184
        dt = &env->gdt;
1185
    index = selector & ~7;
1186
    ptr = dt->base + index;
1187
    if ((index + 7) > dt->limit
1188
        || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1189
        || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1190
        return 0;
1191

    
1192
    *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1193
    *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1194
    if (e2 & DESC_G_MASK)
1195
        *limit = (*limit << 12) | 0xfff;
1196
    *flags = e2;
1197

    
1198
    return 1;
1199
}
1200

    
1201
CPUX86State *cpu_x86_init(const char *cpu_model)
1202
{
1203
    CPUX86State *env;
1204
    static int inited;
1205

    
1206
    env = qemu_mallocz(sizeof(CPUX86State));
1207
    cpu_exec_init(env);
1208
    env->cpu_model_str = cpu_model;
1209

    
1210
    /* init various static tables */
1211
    if (!inited) {
1212
        inited = 1;
1213
        optimize_flags_init();
1214
#ifndef CONFIG_USER_ONLY
1215
        prev_debug_excp_handler =
1216
            cpu_set_debug_excp_handler(breakpoint_handler);
1217
#endif
1218
    }
1219
    if (cpu_x86_register(env, cpu_model) < 0) {
1220
        cpu_x86_close(env);
1221
        return NULL;
1222
    }
1223
    mce_init(env);
1224

    
1225
    qemu_init_vcpu(env);
1226

    
1227
    return env;
1228
}
1229

    
1230
#if !defined(CONFIG_USER_ONLY)
1231
void do_cpu_init(CPUState *env)
1232
{
1233
    int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
1234
    cpu_reset(env);
1235
    env->interrupt_request = sipi;
1236
    apic_init_reset(env->apic_state);
1237
    env->halted = !cpu_is_bsp(env);
1238
}
1239

    
1240
void do_cpu_sipi(CPUState *env)
1241
{
1242
    apic_sipi(env->apic_state);
1243
}
1244
#else
1245
void do_cpu_init(CPUState *env)
1246
{
1247
}
1248
void do_cpu_sipi(CPUState *env)
1249
{
1250
}
1251
#endif