Statistics
| Branch: | Revision:

root / target-i386 / helper.c @ ebda377f

History | View | Annotate | Download (40.8 kB)

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

    
26
#include "cpu.h"
27
#include "exec-all.h"
28
#include "qemu-common.h"
29
#include "kvm.h"
30
#ifndef CONFIG_USER_ONLY
31
#include "sysemu.h"
32
#include "monitor.h"
33
#endif
34

    
35
//#define DEBUG_MMU
36

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

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

    
47
    memset(env, 0, offsetof(CPUX86State, breakpoints));
48

    
49
    tlb_flush(env, 1);
50

    
51
    env->old_exception = -1;
52

    
53
    /* init to reset state */
54

    
55
#ifdef CONFIG_SOFTMMU
56
    env->hflags |= HF_SOFTMMU_MASK;
57
#endif
58
    env->hflags2 |= HF2_GIF_MASK;
59

    
60
    cpu_x86_update_cr0(env, 0x60000010);
61
    env->a20_mask = ~0x0;
62
    env->smbase = 0x30000;
63

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

    
71
    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
72
                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
73
                           DESC_R_MASK | DESC_A_MASK);
74
    cpu_x86_load_seg_cache(env, R_DS, 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_ES, 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_SS, 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_FS, 0, 0, 0xffff,
84
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
85
                           DESC_A_MASK);
86
    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
87
                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
88
                           DESC_A_MASK);
89

    
90
    env->eip = 0xfff0;
91
    env->regs[R_EDX] = env->cpuid_version;
92

    
93
    env->eflags = 0x2;
94

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

    
100
    env->mxcsr = 0x1f80;
101

    
102
    env->pat = 0x0007040600070406ULL;
103

    
104
    memset(env->dr, 0, sizeof(env->dr));
105
    env->dr[6] = DR6_FIXED_1;
106
    env->dr[7] = DR7_FIXED_1;
107
    cpu_breakpoint_remove_all(env, BP_CPU);
108
    cpu_watchpoint_remove_all(env, BP_CPU);
109
}
110

    
111
void cpu_x86_close(CPUX86State *env)
112
{
113
    qemu_free(env);
114
}
115

    
116
static void cpu_x86_version(CPUState *env, int *family, int *model)
117
{
118
    int cpuver = env->cpuid_version;
119

    
120
    if (family == NULL || model == NULL) {
121
        return;
122
    }
123

    
124
    *family = (cpuver >> 8) & 0x0f;
125
    *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
126
}
127

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

    
134
    cpu_x86_version(env, &family, &model);
135
    if ((family == 6 && model >= 14) || family > 6) {
136
        return 1;
137
    }
138

    
139
    return 0;
140
}
141

    
142
/***********************************************************/
143
/* x86 debug */
144

    
145
static const char *cc_op_str[] = {
146
    "DYNAMIC",
147
    "EFLAGS",
148

    
149
    "MULB",
150
    "MULW",
151
    "MULL",
152
    "MULQ",
153

    
154
    "ADDB",
155
    "ADDW",
156
    "ADDL",
157
    "ADDQ",
158

    
159
    "ADCB",
160
    "ADCW",
161
    "ADCL",
162
    "ADCQ",
163

    
164
    "SUBB",
165
    "SUBW",
166
    "SUBL",
167
    "SUBQ",
168

    
169
    "SBBB",
170
    "SBBW",
171
    "SBBL",
172
    "SBBQ",
173

    
174
    "LOGICB",
175
    "LOGICW",
176
    "LOGICL",
177
    "LOGICQ",
178

    
179
    "INCB",
180
    "INCW",
181
    "INCL",
182
    "INCQ",
183

    
184
    "DECB",
185
    "DECW",
186
    "DECL",
187
    "DECQ",
188

    
189
    "SHLB",
190
    "SHLW",
191
    "SHLL",
192
    "SHLQ",
193

    
194
    "SARB",
195
    "SARW",
196
    "SARL",
197
    "SARQ",
198
};
199

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

    
215
    if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
216
        goto done;
217

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

    
255
#define DUMP_CODE_BYTES_TOTAL    50
256
#define DUMP_CODE_BYTES_BACKWARD 20
257

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

    
265
    cpu_synchronize_state(env);
266

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

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

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

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

    
463
/***********************************************************/
464
/* x86 mmu */
465
/* XXX: add PGE support */
466

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

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

    
485
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
486
{
487
    int pe_state;
488

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

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

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

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

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

    
556
    env->cr[4] = new_cr4;
557
}
558

    
559
#if defined(CONFIG_USER_ONLY)
560

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

    
573
#else
574

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

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

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

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

    
613
    if (env->cr[4] & CR4_PAE_MASK) {
614
        uint64_t pde, pdpe;
615
        target_ulong pdpe_addr;
616

    
617
#ifdef TARGET_X86_64
618
        if (env->hflags & HF_LMA_MASK) {
619
            uint64_t pml4e_addr, pml4e;
620
            int32_t sext;
621

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

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

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

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

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

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

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

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

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

    
886
    if (env->cr[4] & CR4_PAE_MASK) {
887
        target_ulong pdpe_addr;
888
        uint64_t pde, pdpe;
889

    
890
#ifdef TARGET_X86_64
891
        if (env->hflags & HF_LMA_MASK) {
892
            uint64_t pml4e_addr, pml4e;
893
            int32_t sext;
894

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

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

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

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

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

    
967
    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
968
    paddr = (pte & TARGET_PAGE_MASK) + page_offset;
969
    return paddr;
970
}
971

    
972
void hw_breakpoint_insert(CPUState *env, int index)
973
{
974
    int type, err = 0;
975

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

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

    
1019
int check_hw_breakpoints(CPUState *env, int force_dr6_update)
1020
{
1021
    target_ulong dr6;
1022
    int reg, type;
1023
    int hit_enabled = 0;
1024

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

    
1041
static CPUDebugExcpHandler *prev_debug_excp_handler;
1042

    
1043
void raise_exception_env(int exception_index, CPUState *env);
1044

    
1045
static void breakpoint_handler(CPUState *env)
1046
{
1047
    CPUBreakpoint *bp;
1048

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

    
1071
typedef struct MCEInjectionParams {
1072
    Monitor *mon;
1073
    CPUState *env;
1074
    int bank;
1075
    uint64_t status;
1076
    uint64_t mcg_status;
1077
    uint64_t addr;
1078
    uint64_t misc;
1079
    int flags;
1080
} MCEInjectionParams;
1081

    
1082
static void do_inject_x86_mce(void *data)
1083
{
1084
    MCEInjectionParams *params = data;
1085
    CPUState *cenv = params->env;
1086
    uint64_t *banks = cenv->mce_banks + 4 * params->bank;
1087

    
1088
    cpu_synchronize_state(cenv);
1089

    
1090
    /*
1091
     * If there is an MCE exception being processed, ignore this SRAO MCE
1092
     * unless unconditional injection was requested.
1093
     */
1094
    if (!(params->flags & MCE_INJECT_UNCOND_AO)
1095
        && !(params->status & MCI_STATUS_AR)
1096
        && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1097
        return;
1098
    }
1099

    
1100
    if (params->status & MCI_STATUS_UC) {
1101
        /*
1102
         * if MSR_MCG_CTL is not all 1s, the uncorrected error
1103
         * reporting is disabled
1104
         */
1105
        if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1106
            monitor_printf(params->mon,
1107
                           "CPU %d: Uncorrected error reporting disabled\n",
1108
                           cenv->cpu_index);
1109
            return;
1110
        }
1111

    
1112
        /*
1113
         * if MSR_MCi_CTL is not all 1s, the uncorrected error
1114
         * reporting is disabled for the bank
1115
         */
1116
        if (banks[0] != ~(uint64_t)0) {
1117
            monitor_printf(params->mon,
1118
                           "CPU %d: Uncorrected error reporting disabled for"
1119
                           " bank %d\n",
1120
                           cenv->cpu_index, params->bank);
1121
            return;
1122
        }
1123

    
1124
        if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1125
            !(cenv->cr[4] & CR4_MCE_MASK)) {
1126
            monitor_printf(params->mon,
1127
                           "CPU %d: Previous MCE still in progress, raising"
1128
                           " triple fault\n",
1129
                           cenv->cpu_index);
1130
            qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1131
            qemu_system_reset_request();
1132
            return;
1133
        }
1134
        if (banks[1] & MCI_STATUS_VAL) {
1135
            params->status |= MCI_STATUS_OVER;
1136
        }
1137
        banks[2] = params->addr;
1138
        banks[3] = params->misc;
1139
        cenv->mcg_status = params->mcg_status;
1140
        banks[1] = params->status;
1141
        cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
1142
    } else if (!(banks[1] & MCI_STATUS_VAL)
1143
               || !(banks[1] & MCI_STATUS_UC)) {
1144
        if (banks[1] & MCI_STATUS_VAL) {
1145
            params->status |= MCI_STATUS_OVER;
1146
        }
1147
        banks[2] = params->addr;
1148
        banks[3] = params->misc;
1149
        banks[1] = params->status;
1150
    } else {
1151
        banks[1] |= MCI_STATUS_OVER;
1152
    }
1153
}
1154

    
1155
void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank,
1156
                        uint64_t status, uint64_t mcg_status, uint64_t addr,
1157
                        uint64_t misc, int flags)
1158
{
1159
    MCEInjectionParams params = {
1160
        .mon = mon,
1161
        .env = cenv,
1162
        .bank = bank,
1163
        .status = status,
1164
        .mcg_status = mcg_status,
1165
        .addr = addr,
1166
        .misc = misc,
1167
        .flags = flags,
1168
    };
1169
    unsigned bank_num = cenv->mcg_cap & 0xff;
1170
    CPUState *env;
1171

    
1172
    if (!cenv->mcg_cap) {
1173
        monitor_printf(mon, "MCE injection not supported\n");
1174
        return;
1175
    }
1176
    if (bank >= bank_num) {
1177
        monitor_printf(mon, "Invalid MCE bank number\n");
1178
        return;
1179
    }
1180
    if (!(status & MCI_STATUS_VAL)) {
1181
        monitor_printf(mon, "Invalid MCE status code\n");
1182
        return;
1183
    }
1184
    if ((flags & MCE_INJECT_BROADCAST)
1185
        && !cpu_x86_support_mca_broadcast(cenv)) {
1186
        monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
1187
        return;
1188
    }
1189

    
1190
    run_on_cpu(cenv, do_inject_x86_mce, &params);
1191
    if (flags & MCE_INJECT_BROADCAST) {
1192
        params.bank = 1;
1193
        params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
1194
        params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
1195
        params.addr = 0;
1196
        params.misc = 0;
1197
        for (env = first_cpu; env != NULL; env = env->next_cpu) {
1198
            if (cenv == env) {
1199
                continue;
1200
            }
1201
            params.env = env;
1202
            run_on_cpu(cenv, do_inject_x86_mce, &params);
1203
        }
1204
    }
1205
}
1206
#endif /* !CONFIG_USER_ONLY */
1207

    
1208
static void mce_init(CPUX86State *cenv)
1209
{
1210
    unsigned int bank;
1211

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

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

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

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

    
1249
    return 1;
1250
}
1251

    
1252
CPUX86State *cpu_x86_init(const char *cpu_model)
1253
{
1254
    CPUX86State *env;
1255
    static int inited;
1256

    
1257
    env = qemu_mallocz(sizeof(CPUX86State));
1258
    cpu_exec_init(env);
1259
    env->cpu_model_str = cpu_model;
1260

    
1261
    /* init various static tables */
1262
    if (!inited) {
1263
        inited = 1;
1264
        optimize_flags_init();
1265
#ifndef CONFIG_USER_ONLY
1266
        prev_debug_excp_handler =
1267
            cpu_set_debug_excp_handler(breakpoint_handler);
1268
#endif
1269
    }
1270
    if (cpu_x86_register(env, cpu_model) < 0) {
1271
        cpu_x86_close(env);
1272
        return NULL;
1273
    }
1274
    mce_init(env);
1275

    
1276
    qemu_init_vcpu(env);
1277

    
1278
    return env;
1279
}
1280

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

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

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