Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ 3f2cbf0d

History | View | Annotate | Download (40.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

    
20
#include "cpu.h"
21
#include "kvm.h"
22
#ifndef CONFIG_USER_ONLY
23
#include "sysemu.h"
24
#include "monitor.h"
25
#endif
26

    
27
//#define DEBUG_MMU
28

    
29
/* NOTE: must be called outside the CPU execute loop */
30
void cpu_reset(CPUX86State *env)
31
{
32
    int i;
33

    
34
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
35
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
36
        log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
37
    }
38

    
39
    memset(env, 0, offsetof(CPUX86State, breakpoints));
40

    
41
    tlb_flush(env, 1);
42

    
43
    env->old_exception = -1;
44

    
45
    /* init to reset state */
46

    
47
#ifdef CONFIG_SOFTMMU
48
    env->hflags |= HF_SOFTMMU_MASK;
49
#endif
50
    env->hflags2 |= HF2_GIF_MASK;
51

    
52
    cpu_x86_update_cr0(env, 0x60000010);
53
    env->a20_mask = ~0x0;
54
    env->smbase = 0x30000;
55

    
56
    env->idt.limit = 0xffff;
57
    env->gdt.limit = 0xffff;
58
    env->ldt.limit = 0xffff;
59
    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
60
    env->tr.limit = 0xffff;
61
    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
62

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

    
82
    env->eip = 0xfff0;
83
    env->regs[R_EDX] = env->cpuid_version;
84

    
85
    env->eflags = 0x2;
86

    
87
    /* FPU init */
88
    for(i = 0;i < 8; i++)
89
        env->fptags[i] = 1;
90
    env->fpuc = 0x37f;
91

    
92
    env->mxcsr = 0x1f80;
93

    
94
    env->pat = 0x0007040600070406ULL;
95
    env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
96

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

    
104
void cpu_x86_close(CPUX86State *env)
105
{
106
    g_free(env);
107
}
108

    
109
static void cpu_x86_version(CPUState *env, int *family, int *model)
110
{
111
    int cpuver = env->cpuid_version;
112

    
113
    if (family == NULL || model == NULL) {
114
        return;
115
    }
116

    
117
    *family = (cpuver >> 8) & 0x0f;
118
    *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
119
}
120

    
121
/* Broadcast MCA signal for processor version 06H_EH and above */
122
int cpu_x86_support_mca_broadcast(CPUState *env)
123
{
124
    int family = 0;
125
    int model = 0;
126

    
127
    cpu_x86_version(env, &family, &model);
128
    if ((family == 6 && model >= 14) || family > 6) {
129
        return 1;
130
    }
131

    
132
    return 0;
133
}
134

    
135
/***********************************************************/
136
/* x86 debug */
137

    
138
static const char *cc_op_str[] = {
139
    "DYNAMIC",
140
    "EFLAGS",
141

    
142
    "MULB",
143
    "MULW",
144
    "MULL",
145
    "MULQ",
146

    
147
    "ADDB",
148
    "ADDW",
149
    "ADDL",
150
    "ADDQ",
151

    
152
    "ADCB",
153
    "ADCW",
154
    "ADCL",
155
    "ADCQ",
156

    
157
    "SUBB",
158
    "SUBW",
159
    "SUBL",
160
    "SUBQ",
161

    
162
    "SBBB",
163
    "SBBW",
164
    "SBBL",
165
    "SBBQ",
166

    
167
    "LOGICB",
168
    "LOGICW",
169
    "LOGICL",
170
    "LOGICQ",
171

    
172
    "INCB",
173
    "INCW",
174
    "INCL",
175
    "INCQ",
176

    
177
    "DECB",
178
    "DECW",
179
    "DECL",
180
    "DECQ",
181

    
182
    "SHLB",
183
    "SHLW",
184
    "SHLL",
185
    "SHLQ",
186

    
187
    "SARB",
188
    "SARW",
189
    "SARL",
190
    "SARQ",
191
};
192

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

    
208
    if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
209
        goto done;
210

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

    
248
#define DUMP_CODE_BYTES_TOTAL    50
249
#define DUMP_CODE_BYTES_BACKWARD 20
250

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

    
258
    cpu_synchronize_state(env);
259

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

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

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

    
431
        cpu_fprintf(f, "Code=");
432
        for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
433
            if (cpu_memory_rw_debug(env, base - offs + i, &code, 1, 0) == 0) {
434
                snprintf(codestr, sizeof(codestr), "%02x", code);
435
            } else {
436
                snprintf(codestr, sizeof(codestr), "??");
437
            }
438
            cpu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
439
                        i == offs ? "<" : "", codestr, i == offs ? ">" : "");
440
        }
441
        cpu_fprintf(f, "\n");
442
    }
443
}
444

    
445
/***********************************************************/
446
/* x86 mmu */
447
/* XXX: add PGE support */
448

    
449
void cpu_x86_set_a20(CPUX86State *env, int a20_state)
450
{
451
    a20_state = (a20_state != 0);
452
    if (a20_state != ((env->a20_mask >> 20) & 1)) {
453
#if defined(DEBUG_MMU)
454
        printf("A20 update: a20=%d\n", a20_state);
455
#endif
456
        /* if the cpu is currently executing code, we must unlink it and
457
           all the potentially executing TB */
458
        cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
459

    
460
        /* when a20 is changed, all the MMU mappings are invalid, so
461
           we must flush everything */
462
        tlb_flush(env, 1);
463
        env->a20_mask = ~(1 << 20) | (a20_state << 20);
464
    }
465
}
466

    
467
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
468
{
469
    int pe_state;
470

    
471
#if defined(DEBUG_MMU)
472
    printf("CR0 update: CR0=0x%08x\n", new_cr0);
473
#endif
474
    if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
475
        (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
476
        tlb_flush(env, 1);
477
    }
478

    
479
#ifdef TARGET_X86_64
480
    if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
481
        (env->efer & MSR_EFER_LME)) {
482
        /* enter in long mode */
483
        /* XXX: generate an exception */
484
        if (!(env->cr[4] & CR4_PAE_MASK))
485
            return;
486
        env->efer |= MSR_EFER_LMA;
487
        env->hflags |= HF_LMA_MASK;
488
    } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
489
               (env->efer & MSR_EFER_LMA)) {
490
        /* exit long mode */
491
        env->efer &= ~MSR_EFER_LMA;
492
        env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
493
        env->eip &= 0xffffffff;
494
    }
495
#endif
496
    env->cr[0] = new_cr0 | CR0_ET_MASK;
497

    
498
    /* update PE flag in hidden flags */
499
    pe_state = (env->cr[0] & CR0_PE_MASK);
500
    env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
501
    /* ensure that ADDSEG is always set in real mode */
502
    env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
503
    /* update FPU flags */
504
    env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
505
        ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
506
}
507

    
508
/* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
509
   the PDPT */
510
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
511
{
512
    env->cr[3] = new_cr3;
513
    if (env->cr[0] & CR0_PG_MASK) {
514
#if defined(DEBUG_MMU)
515
        printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
516
#endif
517
        tlb_flush(env, 0);
518
    }
519
}
520

    
521
void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
522
{
523
#if defined(DEBUG_MMU)
524
    printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
525
#endif
526
    if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
527
        (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
528
        tlb_flush(env, 1);
529
    }
530
    /* SSE handling */
531
    if (!(env->cpuid_features & CPUID_SSE))
532
        new_cr4 &= ~CR4_OSFXSR_MASK;
533
    if (new_cr4 & CR4_OSFXSR_MASK)
534
        env->hflags |= HF_OSFXSR_MASK;
535
    else
536
        env->hflags &= ~HF_OSFXSR_MASK;
537

    
538
    env->cr[4] = new_cr4;
539
}
540

    
541
#if defined(CONFIG_USER_ONLY)
542

    
543
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
544
                             int is_write, int mmu_idx)
545
{
546
    /* user mode only emulation */
547
    is_write &= 1;
548
    env->cr[2] = addr;
549
    env->error_code = (is_write << PG_ERROR_W_BIT);
550
    env->error_code |= PG_ERROR_U_MASK;
551
    env->exception_index = EXCP0E_PAGE;
552
    return 1;
553
}
554

    
555
#else
556

    
557
/* XXX: This value should match the one returned by CPUID
558
 * and in exec.c */
559
# if defined(TARGET_X86_64)
560
# define PHYS_ADDR_MASK 0xfffffff000LL
561
# else
562
# define PHYS_ADDR_MASK 0xffffff000LL
563
# endif
564

    
565
/* return value:
566
   -1 = cannot handle fault
567
   0  = nothing more to do
568
   1  = generate PF fault
569
*/
570
int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
571
                             int is_write1, int mmu_idx)
572
{
573
    uint64_t ptep, pte;
574
    target_ulong pde_addr, pte_addr;
575
    int error_code, is_dirty, prot, page_size, is_write, is_user;
576
    target_phys_addr_t paddr;
577
    uint32_t page_offset;
578
    target_ulong vaddr, virt_addr;
579

    
580
    is_user = mmu_idx == MMU_USER_IDX;
581
#if defined(DEBUG_MMU)
582
    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
583
           addr, is_write1, is_user, env->eip);
584
#endif
585
    is_write = is_write1 & 1;
586

    
587
    if (!(env->cr[0] & CR0_PG_MASK)) {
588
        pte = addr;
589
        virt_addr = addr & TARGET_PAGE_MASK;
590
        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
591
        page_size = 4096;
592
        goto do_mapping;
593
    }
594

    
595
    if (env->cr[4] & CR4_PAE_MASK) {
596
        uint64_t pde, pdpe;
597
        target_ulong pdpe_addr;
598

    
599
#ifdef TARGET_X86_64
600
        if (env->hflags & HF_LMA_MASK) {
601
            uint64_t pml4e_addr, pml4e;
602
            int32_t sext;
603

    
604
            /* test virtual address sign extension */
605
            sext = (int64_t)addr >> 47;
606
            if (sext != 0 && sext != -1) {
607
                env->error_code = 0;
608
                env->exception_index = EXCP0D_GPF;
609
                return 1;
610
            }
611

    
612
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
613
                env->a20_mask;
614
            pml4e = ldq_phys(pml4e_addr);
615
            if (!(pml4e & PG_PRESENT_MASK)) {
616
                error_code = 0;
617
                goto do_fault;
618
            }
619
            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
620
                error_code = PG_ERROR_RSVD_MASK;
621
                goto do_fault;
622
            }
623
            if (!(pml4e & PG_ACCESSED_MASK)) {
624
                pml4e |= PG_ACCESSED_MASK;
625
                stl_phys_notdirty(pml4e_addr, pml4e);
626
            }
627
            ptep = pml4e ^ PG_NX_MASK;
628
            pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
629
                env->a20_mask;
630
            pdpe = ldq_phys(pdpe_addr);
631
            if (!(pdpe & PG_PRESENT_MASK)) {
632
                error_code = 0;
633
                goto do_fault;
634
            }
635
            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
636
                error_code = PG_ERROR_RSVD_MASK;
637
                goto do_fault;
638
            }
639
            ptep &= pdpe ^ PG_NX_MASK;
640
            if (!(pdpe & PG_ACCESSED_MASK)) {
641
                pdpe |= PG_ACCESSED_MASK;
642
                stl_phys_notdirty(pdpe_addr, pdpe);
643
            }
644
        } else
645
#endif
646
        {
647
            /* XXX: load them when cr3 is loaded ? */
648
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
649
                env->a20_mask;
650
            pdpe = ldq_phys(pdpe_addr);
651
            if (!(pdpe & PG_PRESENT_MASK)) {
652
                error_code = 0;
653
                goto do_fault;
654
            }
655
            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
656
        }
657

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

    
742
        /* page directory entry */
743
        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
744
            env->a20_mask;
745
        pde = ldl_phys(pde_addr);
746
        if (!(pde & PG_PRESENT_MASK)) {
747
            error_code = 0;
748
            goto do_fault;
749
        }
750
        /* if PSE bit is set, then we use a 4MB page */
751
        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
752
            page_size = 4096 * 1024;
753
            if (is_user) {
754
                if (!(pde & PG_USER_MASK))
755
                    goto do_fault_protect;
756
                if (is_write && !(pde & PG_RW_MASK))
757
                    goto do_fault_protect;
758
            } else {
759
                if ((env->cr[0] & CR0_WP_MASK) &&
760
                    is_write && !(pde & PG_RW_MASK))
761
                    goto do_fault_protect;
762
            }
763
            is_dirty = is_write && !(pde & PG_DIRTY_MASK);
764
            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
765
                pde |= PG_ACCESSED_MASK;
766
                if (is_dirty)
767
                    pde |= PG_DIRTY_MASK;
768
                stl_phys_notdirty(pde_addr, pde);
769
            }
770

    
771
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
772
            ptep = pte;
773
            virt_addr = addr & ~(page_size - 1);
774
        } else {
775
            if (!(pde & PG_ACCESSED_MASK)) {
776
                pde |= PG_ACCESSED_MASK;
777
                stl_phys_notdirty(pde_addr, pde);
778
            }
779

    
780
            /* page directory entry */
781
            pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
782
                env->a20_mask;
783
            pte = ldl_phys(pte_addr);
784
            if (!(pte & PG_PRESENT_MASK)) {
785
                error_code = 0;
786
                goto do_fault;
787
            }
788
            /* combine pde and pte user and rw protections */
789
            ptep = pte & pde;
790
            if (is_user) {
791
                if (!(ptep & PG_USER_MASK))
792
                    goto do_fault_protect;
793
                if (is_write && !(ptep & PG_RW_MASK))
794
                    goto do_fault_protect;
795
            } else {
796
                if ((env->cr[0] & CR0_WP_MASK) &&
797
                    is_write && !(ptep & PG_RW_MASK))
798
                    goto do_fault_protect;
799
            }
800
            is_dirty = is_write && !(pte & PG_DIRTY_MASK);
801
            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
802
                pte |= PG_ACCESSED_MASK;
803
                if (is_dirty)
804
                    pte |= PG_DIRTY_MASK;
805
                stl_phys_notdirty(pte_addr, pte);
806
            }
807
            page_size = 4096;
808
            virt_addr = addr & ~0xfff;
809
        }
810
    }
811
    /* the page can be put in the TLB */
812
    prot = PAGE_READ;
813
    if (!(ptep & PG_NX_MASK))
814
        prot |= PAGE_EXEC;
815
    if (pte & PG_DIRTY_MASK) {
816
        /* only set write access if already dirty... otherwise wait
817
           for dirty access */
818
        if (is_user) {
819
            if (ptep & PG_RW_MASK)
820
                prot |= PAGE_WRITE;
821
        } else {
822
            if (!(env->cr[0] & CR0_WP_MASK) ||
823
                (ptep & PG_RW_MASK))
824
                prot |= PAGE_WRITE;
825
        }
826
    }
827
 do_mapping:
828
    pte = pte & env->a20_mask;
829

    
830
    /* Even if 4MB pages, we map only one 4KB page in the cache to
831
       avoid filling it too fast */
832
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
833
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
834
    vaddr = virt_addr + page_offset;
835

    
836
    tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
837
    return 0;
838
 do_fault_protect:
839
    error_code = PG_ERROR_P_MASK;
840
 do_fault:
841
    error_code |= (is_write << PG_ERROR_W_BIT);
842
    if (is_user)
843
        error_code |= PG_ERROR_U_MASK;
844
    if (is_write1 == 2 &&
845
        (env->efer & MSR_EFER_NXE) &&
846
        (env->cr[4] & CR4_PAE_MASK))
847
        error_code |= PG_ERROR_I_D_MASK;
848
    if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
849
        /* cr2 is not modified in case of exceptions */
850
        stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 
851
                 addr);
852
    } else {
853
        env->cr[2] = addr;
854
    }
855
    env->error_code = error_code;
856
    env->exception_index = EXCP0E_PAGE;
857
    return 1;
858
}
859

    
860
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
861
{
862
    target_ulong pde_addr, pte_addr;
863
    uint64_t pte;
864
    target_phys_addr_t paddr;
865
    uint32_t page_offset;
866
    int page_size;
867

    
868
    if (env->cr[4] & CR4_PAE_MASK) {
869
        target_ulong pdpe_addr;
870
        uint64_t pde, pdpe;
871

    
872
#ifdef TARGET_X86_64
873
        if (env->hflags & HF_LMA_MASK) {
874
            uint64_t pml4e_addr, pml4e;
875
            int32_t sext;
876

    
877
            /* test virtual address sign extension */
878
            sext = (int64_t)addr >> 47;
879
            if (sext != 0 && sext != -1)
880
                return -1;
881

    
882
            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
883
                env->a20_mask;
884
            pml4e = ldq_phys(pml4e_addr);
885
            if (!(pml4e & PG_PRESENT_MASK))
886
                return -1;
887

    
888
            pdpe_addr = ((pml4e & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
889
                         (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask;
890
            pdpe = ldq_phys(pdpe_addr);
891
            if (!(pdpe & PG_PRESENT_MASK))
892
                return -1;
893
        } else
894
#endif
895
        {
896
            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
897
                env->a20_mask;
898
            pdpe = ldq_phys(pdpe_addr);
899
            if (!(pdpe & PG_PRESENT_MASK))
900
                return -1;
901
        }
902

    
903
        pde_addr = ((pdpe & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
904
                    (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask;
905
        pde = ldq_phys(pde_addr);
906
        if (!(pde & PG_PRESENT_MASK)) {
907
            return -1;
908
        }
909
        if (pde & PG_PSE_MASK) {
910
            /* 2 MB page */
911
            page_size = 2048 * 1024;
912
            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
913
        } else {
914
            /* 4 KB page */
915
            pte_addr = ((pde & ~0xfff & ~(PG_NX_MASK | PG_HI_USER_MASK)) +
916
                        (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask;
917
            page_size = 4096;
918
            pte = ldq_phys(pte_addr);
919
        }
920
        pte &= ~(PG_NX_MASK | PG_HI_USER_MASK);
921
        if (!(pte & PG_PRESENT_MASK))
922
            return -1;
923
    } else {
924
        uint32_t pde;
925

    
926
        if (!(env->cr[0] & CR0_PG_MASK)) {
927
            pte = addr;
928
            page_size = 4096;
929
        } else {
930
            /* page directory entry */
931
            pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
932
            pde = ldl_phys(pde_addr);
933
            if (!(pde & PG_PRESENT_MASK))
934
                return -1;
935
            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
936
                pte = pde & ~0x003ff000; /* align to 4MB */
937
                page_size = 4096 * 1024;
938
            } else {
939
                /* page directory entry */
940
                pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
941
                pte = ldl_phys(pte_addr);
942
                if (!(pte & PG_PRESENT_MASK))
943
                    return -1;
944
                page_size = 4096;
945
            }
946
        }
947
        pte = pte & env->a20_mask;
948
    }
949

    
950
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
951
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
952
    return paddr;
953
}
954

    
955
void hw_breakpoint_insert(CPUState *env, int index)
956
{
957
    int type, err = 0;
958

    
959
    switch (hw_breakpoint_type(env->dr[7], index)) {
960
    case 0:
961
        if (hw_breakpoint_enabled(env->dr[7], index))
962
            err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
963
                                        &env->cpu_breakpoint[index]);
964
        break;
965
    case 1:
966
        type = BP_CPU | BP_MEM_WRITE;
967
        goto insert_wp;
968
    case 2:
969
         /* No support for I/O watchpoints yet */
970
        break;
971
    case 3:
972
        type = BP_CPU | BP_MEM_ACCESS;
973
    insert_wp:
974
        err = cpu_watchpoint_insert(env, env->dr[index],
975
                                    hw_breakpoint_len(env->dr[7], index),
976
                                    type, &env->cpu_watchpoint[index]);
977
        break;
978
    }
979
    if (err)
980
        env->cpu_breakpoint[index] = NULL;
981
}
982

    
983
void hw_breakpoint_remove(CPUState *env, int index)
984
{
985
    if (!env->cpu_breakpoint[index])
986
        return;
987
    switch (hw_breakpoint_type(env->dr[7], index)) {
988
    case 0:
989
        if (hw_breakpoint_enabled(env->dr[7], index))
990
            cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
991
        break;
992
    case 1:
993
    case 3:
994
        cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
995
        break;
996
    case 2:
997
        /* No support for I/O watchpoints yet */
998
        break;
999
    }
1000
}
1001

    
1002
int check_hw_breakpoints(CPUState *env, int force_dr6_update)
1003
{
1004
    target_ulong dr6;
1005
    int reg, type;
1006
    int hit_enabled = 0;
1007

    
1008
    dr6 = env->dr[6] & ~0xf;
1009
    for (reg = 0; reg < 4; reg++) {
1010
        type = hw_breakpoint_type(env->dr[7], reg);
1011
        if ((type == 0 && env->dr[reg] == env->eip) ||
1012
            ((type & 1) && env->cpu_watchpoint[reg] &&
1013
             (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
1014
            dr6 |= 1 << reg;
1015
            if (hw_breakpoint_enabled(env->dr[7], reg))
1016
                hit_enabled = 1;
1017
        }
1018
    }
1019
    if (hit_enabled || force_dr6_update)
1020
        env->dr[6] = dr6;
1021
    return hit_enabled;
1022
}
1023

    
1024
static CPUDebugExcpHandler *prev_debug_excp_handler;
1025

    
1026
static void breakpoint_handler(CPUState *env)
1027
{
1028
    CPUBreakpoint *bp;
1029

    
1030
    if (env->watchpoint_hit) {
1031
        if (env->watchpoint_hit->flags & BP_CPU) {
1032
            env->watchpoint_hit = NULL;
1033
            if (check_hw_breakpoints(env, 0))
1034
                raise_exception_env(EXCP01_DB, env);
1035
            else
1036
                cpu_resume_from_signal(env, NULL);
1037
        }
1038
    } else {
1039
        QTAILQ_FOREACH(bp, &env->breakpoints, entry)
1040
            if (bp->pc == env->eip) {
1041
                if (bp->flags & BP_CPU) {
1042
                    check_hw_breakpoints(env, 1);
1043
                    raise_exception_env(EXCP01_DB, env);
1044
                }
1045
                break;
1046
            }
1047
    }
1048
    if (prev_debug_excp_handler)
1049
        prev_debug_excp_handler(env);
1050
}
1051

    
1052
typedef struct MCEInjectionParams {
1053
    Monitor *mon;
1054
    CPUState *env;
1055
    int bank;
1056
    uint64_t status;
1057
    uint64_t mcg_status;
1058
    uint64_t addr;
1059
    uint64_t misc;
1060
    int flags;
1061
} MCEInjectionParams;
1062

    
1063
static void do_inject_x86_mce(void *data)
1064
{
1065
    MCEInjectionParams *params = data;
1066
    CPUState *cenv = params->env;
1067
    uint64_t *banks = cenv->mce_banks + 4 * params->bank;
1068

    
1069
    cpu_synchronize_state(cenv);
1070

    
1071
    /*
1072
     * If there is an MCE exception being processed, ignore this SRAO MCE
1073
     * unless unconditional injection was requested.
1074
     */
1075
    if (!(params->flags & MCE_INJECT_UNCOND_AO)
1076
        && !(params->status & MCI_STATUS_AR)
1077
        && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1078
        return;
1079
    }
1080

    
1081
    if (params->status & MCI_STATUS_UC) {
1082
        /*
1083
         * if MSR_MCG_CTL is not all 1s, the uncorrected error
1084
         * reporting is disabled
1085
         */
1086
        if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1087
            monitor_printf(params->mon,
1088
                           "CPU %d: Uncorrected error reporting disabled\n",
1089
                           cenv->cpu_index);
1090
            return;
1091
        }
1092

    
1093
        /*
1094
         * if MSR_MCi_CTL is not all 1s, the uncorrected error
1095
         * reporting is disabled for the bank
1096
         */
1097
        if (banks[0] != ~(uint64_t)0) {
1098
            monitor_printf(params->mon,
1099
                           "CPU %d: Uncorrected error reporting disabled for"
1100
                           " bank %d\n",
1101
                           cenv->cpu_index, params->bank);
1102
            return;
1103
        }
1104

    
1105
        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1106
            !(cenv->cr[4] & CR4_MCE_MASK)) {
1107
            monitor_printf(params->mon,
1108
                           "CPU %d: Previous MCE still in progress, raising"
1109
                           " triple fault\n",
1110
                           cenv->cpu_index);
1111
            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1112
            qemu_system_reset_request();
1113
            return;
1114
        }
1115
        if (banks[1] & MCI_STATUS_VAL) {
1116
            params->status |= MCI_STATUS_OVER;
1117
        }
1118
        banks[2] = params->addr;
1119
        banks[3] = params->misc;
1120
        cenv->mcg_status = params->mcg_status;
1121
        banks[1] = params->status;
1122
        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
1123
    } else if (!(banks[1] & MCI_STATUS_VAL)
1124
               || !(banks[1] & MCI_STATUS_UC)) {
1125
        if (banks[1] & MCI_STATUS_VAL) {
1126
            params->status |= MCI_STATUS_OVER;
1127
        }
1128
        banks[2] = params->addr;
1129
        banks[3] = params->misc;
1130
        banks[1] = params->status;
1131
    } else {
1132
        banks[1] |= MCI_STATUS_OVER;
1133
    }
1134
}
1135

    
1136
void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank,
1137
                        uint64_t status, uint64_t mcg_status, uint64_t addr,
1138
                        uint64_t misc, int flags)
1139
{
1140
    MCEInjectionParams params = {
1141
        .mon = mon,
1142
        .env = cenv,
1143
        .bank = bank,
1144
        .status = status,
1145
        .mcg_status = mcg_status,
1146
        .addr = addr,
1147
        .misc = misc,
1148
        .flags = flags,
1149
    };
1150
    unsigned bank_num = cenv->mcg_cap & 0xff;
1151
    CPUState *env;
1152

    
1153
    if (!cenv->mcg_cap) {
1154
        monitor_printf(mon, "MCE injection not supported\n");
1155
        return;
1156
    }
1157
    if (bank >= bank_num) {
1158
        monitor_printf(mon, "Invalid MCE bank number\n");
1159
        return;
1160
    }
1161
    if (!(status & MCI_STATUS_VAL)) {
1162
        monitor_printf(mon, "Invalid MCE status code\n");
1163
        return;
1164
    }
1165
    if ((flags & MCE_INJECT_BROADCAST)
1166
        && !cpu_x86_support_mca_broadcast(cenv)) {
1167
        monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
1168
        return;
1169
    }
1170

    
1171
    run_on_cpu(cenv, do_inject_x86_mce, &params);
1172
    if (flags & MCE_INJECT_BROADCAST) {
1173
        params.bank = 1;
1174
        params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
1175
        params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
1176
        params.addr = 0;
1177
        params.misc = 0;
1178
        for (env = first_cpu; env != NULL; env = env->next_cpu) {
1179
            if (cenv == env) {
1180
                continue;
1181
            }
1182
            params.env = env;
1183
            run_on_cpu(cenv, do_inject_x86_mce, &params);
1184
        }
1185
    }
1186
}
1187

    
1188
void cpu_report_tpr_access(CPUState *env, TPRAccess access)
1189
{
1190
    TranslationBlock *tb;
1191

    
1192
    if (kvm_enabled()) {
1193
        env->tpr_access_type = access;
1194

    
1195
        cpu_interrupt(env, CPU_INTERRUPT_TPR);
1196
    } else {
1197
        tb = tb_find_pc(env->mem_io_pc);
1198
        cpu_restore_state(tb, env, env->mem_io_pc);
1199

    
1200
        apic_handle_tpr_access_report(env->apic_state, env->eip, access);
1201
    }
1202
}
1203
#endif /* !CONFIG_USER_ONLY */
1204

    
1205
static void mce_init(CPUX86State *cenv)
1206
{
1207
    unsigned int bank;
1208

    
1209
    if (((cenv->cpuid_version >> 8) & 0xf) >= 6
1210
        && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
1211
            (CPUID_MCE | CPUID_MCA)) {
1212
        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
1213
        cenv->mcg_ctl = ~(uint64_t)0;
1214
        for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
1215
            cenv->mce_banks[bank * 4] = ~(uint64_t)0;
1216
        }
1217
    }
1218
}
1219

    
1220
int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1221
                            target_ulong *base, unsigned int *limit,
1222
                            unsigned int *flags)
1223
{
1224
    SegmentCache *dt;
1225
    target_ulong ptr;
1226
    uint32_t e1, e2;
1227
    int index;
1228

    
1229
    if (selector & 0x4)
1230
        dt = &env->ldt;
1231
    else
1232
        dt = &env->gdt;
1233
    index = selector & ~7;
1234
    ptr = dt->base + index;
1235
    if ((index + 7) > dt->limit
1236
        || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1237
        || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1238
        return 0;
1239

    
1240
    *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1241
    *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1242
    if (e2 & DESC_G_MASK)
1243
        *limit = (*limit << 12) | 0xfff;
1244
    *flags = e2;
1245

    
1246
    return 1;
1247
}
1248

    
1249
CPUX86State *cpu_x86_init(const char *cpu_model)
1250
{
1251
    CPUX86State *env;
1252
    static int inited;
1253

    
1254
    env = g_malloc0(sizeof(CPUX86State));
1255
    cpu_exec_init(env);
1256
    env->cpu_model_str = cpu_model;
1257

    
1258
    /* init various static tables used in TCG mode */
1259
    if (tcg_enabled() && !inited) {
1260
        inited = 1;
1261
        optimize_flags_init();
1262
#ifndef CONFIG_USER_ONLY
1263
        prev_debug_excp_handler =
1264
            cpu_set_debug_excp_handler(breakpoint_handler);
1265
#endif
1266
    }
1267
    if (cpu_x86_register(env, cpu_model) < 0) {
1268
        cpu_x86_close(env);
1269
        return NULL;
1270
    }
1271
    env->cpuid_apic_id = env->cpu_index;
1272
    mce_init(env);
1273

    
1274
    qemu_init_vcpu(env);
1275

    
1276
    return env;
1277
}
1278

    
1279
#if !defined(CONFIG_USER_ONLY)
1280
void do_cpu_init(CPUState *env)
1281
{
1282
    int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
1283
    uint64_t pat = env->pat;
1284

    
1285
    cpu_reset(env);
1286
    env->interrupt_request = sipi;
1287
    env->pat = pat;
1288
    apic_init_reset(env->apic_state);
1289
    env->halted = !cpu_is_bsp(env);
1290
}
1291

    
1292
void do_cpu_sipi(CPUState *env)
1293
{
1294
    apic_sipi(env->apic_state);
1295
}
1296
#else
1297
void do_cpu_init(CPUState *env)
1298
{
1299
}
1300
void do_cpu_sipi(CPUState *env)
1301
{
1302
}
1303
#endif