]> Git Repo - qemu.git/blob - target/i386/helper.c
target/i386: enable A20 automatically in system management mode
[qemu.git] / target / i386 / helper.c
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 "qemu/osdep.h"
21 #include "cpu.h"
22 #include "exec/exec-all.h"
23 #include "sysemu/kvm.h"
24 #include "kvm_i386.h"
25 #ifndef CONFIG_USER_ONLY
26 #include "sysemu/sysemu.h"
27 #include "sysemu/hw_accel.h"
28 #include "monitor/monitor.h"
29 #include "hw/i386/apic_internal.h"
30 #endif
31
32 static void cpu_x86_version(CPUX86State *env, int *family, int *model)
33 {
34     int cpuver = env->cpuid_version;
35
36     if (family == NULL || model == NULL) {
37         return;
38     }
39
40     *family = (cpuver >> 8) & 0x0f;
41     *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
42 }
43
44 /* Broadcast MCA signal for processor version 06H_EH and above */
45 int cpu_x86_support_mca_broadcast(CPUX86State *env)
46 {
47     int family = 0;
48     int model = 0;
49
50     cpu_x86_version(env, &family, &model);
51     if ((family == 6 && model >= 14) || family > 6) {
52         return 1;
53     }
54
55     return 0;
56 }
57
58 /***********************************************************/
59 /* x86 debug */
60
61 static const char *cc_op_str[CC_OP_NB] = {
62     "DYNAMIC",
63     "EFLAGS",
64
65     "MULB",
66     "MULW",
67     "MULL",
68     "MULQ",
69
70     "ADDB",
71     "ADDW",
72     "ADDL",
73     "ADDQ",
74
75     "ADCB",
76     "ADCW",
77     "ADCL",
78     "ADCQ",
79
80     "SUBB",
81     "SUBW",
82     "SUBL",
83     "SUBQ",
84
85     "SBBB",
86     "SBBW",
87     "SBBL",
88     "SBBQ",
89
90     "LOGICB",
91     "LOGICW",
92     "LOGICL",
93     "LOGICQ",
94
95     "INCB",
96     "INCW",
97     "INCL",
98     "INCQ",
99
100     "DECB",
101     "DECW",
102     "DECL",
103     "DECQ",
104
105     "SHLB",
106     "SHLW",
107     "SHLL",
108     "SHLQ",
109
110     "SARB",
111     "SARW",
112     "SARL",
113     "SARQ",
114
115     "BMILGB",
116     "BMILGW",
117     "BMILGL",
118     "BMILGQ",
119
120     "ADCX",
121     "ADOX",
122     "ADCOX",
123
124     "CLR",
125 };
126
127 static void
128 cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf,
129                        const char *name, struct SegmentCache *sc)
130 {
131 #ifdef TARGET_X86_64
132     if (env->hflags & HF_CS64_MASK) {
133         cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
134                     sc->selector, sc->base, sc->limit, sc->flags & 0x00ffff00);
135     } else
136 #endif
137     {
138         cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
139                     (uint32_t)sc->base, sc->limit, sc->flags & 0x00ffff00);
140     }
141
142     if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
143         goto done;
144
145     cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
146     if (sc->flags & DESC_S_MASK) {
147         if (sc->flags & DESC_CS_MASK) {
148             cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
149                            ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
150             cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
151                         (sc->flags & DESC_R_MASK) ? 'R' : '-');
152         } else {
153             cpu_fprintf(f,
154                         (sc->flags & DESC_B_MASK || env->hflags & HF_LMA_MASK)
155                         ? "DS  " : "DS16");
156             cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
157                         (sc->flags & DESC_W_MASK) ? 'W' : '-');
158         }
159         cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
160     } else {
161         static const char *sys_type_name[2][16] = {
162             { /* 32 bit mode */
163                 "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
164                 "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
165                 "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
166                 "CallGate32", "Reserved", "IntGate32", "TrapGate32"
167             },
168             { /* 64 bit mode */
169                 "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
170                 "Reserved", "Reserved", "Reserved", "Reserved",
171                 "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
172                 "Reserved", "IntGate64", "TrapGate64"
173             }
174         };
175         cpu_fprintf(f, "%s",
176                     sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
177                                  [(sc->flags & DESC_TYPE_MASK)
178                                   >> DESC_TYPE_SHIFT]);
179     }
180 done:
181     cpu_fprintf(f, "\n");
182 }
183
184 #ifndef CONFIG_USER_ONLY
185
186 /* ARRAY_SIZE check is not required because
187  * DeliveryMode(dm) has a size of 3 bit.
188  */
189 static inline const char *dm2str(uint32_t dm)
190 {
191     static const char *str[] = {
192         "Fixed",
193         "...",
194         "SMI",
195         "...",
196         "NMI",
197         "INIT",
198         "...",
199         "ExtINT"
200     };
201     return str[dm];
202 }
203
204 static void dump_apic_lvt(FILE *f, fprintf_function cpu_fprintf,
205                           const char *name, uint32_t lvt, bool is_timer)
206 {
207     uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT;
208     cpu_fprintf(f,
209                 "%s\t 0x%08x %s %-5s %-6s %-7s %-12s %-6s",
210                 name, lvt,
211                 lvt & APIC_LVT_INT_POLARITY ? "active-lo" : "active-hi",
212                 lvt & APIC_LVT_LEVEL_TRIGGER ? "level" : "edge",
213                 lvt & APIC_LVT_MASKED ? "masked" : "",
214                 lvt & APIC_LVT_DELIV_STS ? "pending" : "",
215                 !is_timer ?
216                     "" : lvt & APIC_LVT_TIMER_PERIODIC ?
217                             "periodic" : lvt & APIC_LVT_TIMER_TSCDEADLINE ?
218                                             "tsc-deadline" : "one-shot",
219                 dm2str(dm));
220     if (dm != APIC_DM_NMI) {
221         cpu_fprintf(f, " (vec %u)\n", lvt & APIC_VECTOR_MASK);
222     } else {
223         cpu_fprintf(f, "\n");
224     }
225 }
226
227 /* ARRAY_SIZE check is not required because
228  * destination shorthand has a size of 2 bit.
229  */
230 static inline const char *shorthand2str(uint32_t shorthand)
231 {
232     const char *str[] = {
233         "no-shorthand", "self", "all-self", "all"
234     };
235     return str[shorthand];
236 }
237
238 static inline uint8_t divider_conf(uint32_t divide_conf)
239 {
240     uint8_t divide_val = ((divide_conf & 0x8) >> 1) | (divide_conf & 0x3);
241
242     return divide_val == 7 ? 1 : 2 << divide_val;
243 }
244
245 static inline void mask2str(char *str, uint32_t val, uint8_t size)
246 {
247     while (size--) {
248         *str++ = (val >> size) & 1 ? '1' : '0';
249     }
250     *str = 0;
251 }
252
253 #define MAX_LOGICAL_APIC_ID_MASK_SIZE 16
254
255 static void dump_apic_icr(FILE *f, fprintf_function cpu_fprintf,
256                           APICCommonState *s, CPUX86State *env)
257 {
258     uint32_t icr = s->icr[0], icr2 = s->icr[1];
259     uint8_t dest_shorthand = \
260         (icr & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT;
261     bool logical_mod = icr & APIC_ICR_DEST_MOD;
262     char apic_id_str[MAX_LOGICAL_APIC_ID_MASK_SIZE + 1];
263     uint32_t dest_field;
264     bool x2apic;
265
266     cpu_fprintf(f, "ICR\t 0x%08x %s %s %s %s\n",
267                 icr,
268                 logical_mod ? "logical" : "physical",
269                 icr & APIC_ICR_TRIGGER_MOD ? "level" : "edge",
270                 icr & APIC_ICR_LEVEL ? "assert" : "de-assert",
271                 shorthand2str(dest_shorthand));
272
273     cpu_fprintf(f, "ICR2\t 0x%08x", icr2);
274     if (dest_shorthand != 0) {
275         cpu_fprintf(f, "\n");
276         return;
277     }
278     x2apic = env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC;
279     dest_field = x2apic ? icr2 : icr2 >> APIC_ICR_DEST_SHIFT;
280
281     if (!logical_mod) {
282         if (x2apic) {
283             cpu_fprintf(f, " cpu %u (X2APIC ID)\n", dest_field);
284         } else {
285             cpu_fprintf(f, " cpu %u (APIC ID)\n",
286                         dest_field & APIC_LOGDEST_XAPIC_ID);
287         }
288         return;
289     }
290
291     if (s->dest_mode == 0xf) { /* flat mode */
292         mask2str(apic_id_str, icr2 >> APIC_ICR_DEST_SHIFT, 8);
293         cpu_fprintf(f, " mask %s (APIC ID)\n", apic_id_str);
294     } else if (s->dest_mode == 0) { /* cluster mode */
295         if (x2apic) {
296             mask2str(apic_id_str, dest_field & APIC_LOGDEST_X2APIC_ID, 16);
297             cpu_fprintf(f, " cluster %u mask %s (X2APIC ID)\n",
298                         dest_field >> APIC_LOGDEST_X2APIC_SHIFT, apic_id_str);
299         } else {
300             mask2str(apic_id_str, dest_field & APIC_LOGDEST_XAPIC_ID, 4);
301             cpu_fprintf(f, " cluster %u mask %s (APIC ID)\n",
302                         dest_field >> APIC_LOGDEST_XAPIC_SHIFT, apic_id_str);
303         }
304     }
305 }
306
307 static void dump_apic_interrupt(FILE *f, fprintf_function cpu_fprintf,
308                                 const char *name, uint32_t *ireg_tab,
309                                 uint32_t *tmr_tab)
310 {
311     int i, empty = true;
312
313     cpu_fprintf(f, "%s\t ", name);
314     for (i = 0; i < 256; i++) {
315         if (apic_get_bit(ireg_tab, i)) {
316             cpu_fprintf(f, "%u%s ", i,
317                         apic_get_bit(tmr_tab, i) ? "(level)" : "");
318             empty = false;
319         }
320     }
321     cpu_fprintf(f, "%s\n", empty ? "(none)" : "");
322 }
323
324 void x86_cpu_dump_local_apic_state(CPUState *cs, FILE *f,
325                                    fprintf_function cpu_fprintf, int flags)
326 {
327     X86CPU *cpu = X86_CPU(cs);
328     APICCommonState *s = APIC_COMMON(cpu->apic_state);
329     if (!s) {
330         cpu_fprintf(f, "local apic state not available\n");
331         return;
332     }
333     uint32_t *lvt = s->lvt;
334
335     cpu_fprintf(f, "dumping local APIC state for CPU %-2u\n\n",
336                 CPU(cpu)->cpu_index);
337     dump_apic_lvt(f, cpu_fprintf, "LVT0", lvt[APIC_LVT_LINT0], false);
338     dump_apic_lvt(f, cpu_fprintf, "LVT1", lvt[APIC_LVT_LINT1], false);
339     dump_apic_lvt(f, cpu_fprintf, "LVTPC", lvt[APIC_LVT_PERFORM], false);
340     dump_apic_lvt(f, cpu_fprintf, "LVTERR", lvt[APIC_LVT_ERROR], false);
341     dump_apic_lvt(f, cpu_fprintf, "LVTTHMR", lvt[APIC_LVT_THERMAL], false);
342     dump_apic_lvt(f, cpu_fprintf, "LVTT", lvt[APIC_LVT_TIMER], true);
343
344     cpu_fprintf(f, "Timer\t DCR=0x%x (divide by %u) initial_count = %u\n",
345                 s->divide_conf & APIC_DCR_MASK,
346                 divider_conf(s->divide_conf),
347                 s->initial_count);
348
349     cpu_fprintf(f, "SPIV\t 0x%08x APIC %s, focus=%s, spurious vec %u\n",
350                 s->spurious_vec,
351                 s->spurious_vec & APIC_SPURIO_ENABLED ? "enabled" : "disabled",
352                 s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off",
353                 s->spurious_vec & APIC_VECTOR_MASK);
354
355     dump_apic_icr(f, cpu_fprintf, s, &cpu->env);
356
357     cpu_fprintf(f, "ESR\t 0x%08x\n", s->esr);
358
359     dump_apic_interrupt(f, cpu_fprintf, "ISR", s->isr, s->tmr);
360     dump_apic_interrupt(f, cpu_fprintf, "IRR", s->irr, s->tmr);
361
362     cpu_fprintf(f, "\nAPR 0x%02x TPR 0x%02x DFR 0x%02x LDR 0x%02x",
363                 s->arb_id, s->tpr, s->dest_mode, s->log_dest);
364     if (s->dest_mode == 0) {
365         cpu_fprintf(f, "(cluster %u: id %u)",
366                     s->log_dest >> APIC_LOGDEST_XAPIC_SHIFT,
367                     s->log_dest & APIC_LOGDEST_XAPIC_ID);
368     }
369     cpu_fprintf(f, " PPR 0x%02x\n", apic_get_ppr(s));
370 }
371 #else
372 void x86_cpu_dump_local_apic_state(CPUState *cs, FILE *f,
373                                    fprintf_function cpu_fprintf, int flags)
374 {
375 }
376 #endif /* !CONFIG_USER_ONLY */
377
378 #define DUMP_CODE_BYTES_TOTAL    50
379 #define DUMP_CODE_BYTES_BACKWARD 20
380
381 void x86_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
382                         int flags)
383 {
384     X86CPU *cpu = X86_CPU(cs);
385     CPUX86State *env = &cpu->env;
386     int eflags, i, nb;
387     char cc_op_name[32];
388     static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
389
390     eflags = cpu_compute_eflags(env);
391 #ifdef TARGET_X86_64
392     if (env->hflags & HF_CS64_MASK) {
393         cpu_fprintf(f,
394                     "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
395                     "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
396                     "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
397                     "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
398                     "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
399                     env->regs[R_EAX],
400                     env->regs[R_EBX],
401                     env->regs[R_ECX],
402                     env->regs[R_EDX],
403                     env->regs[R_ESI],
404                     env->regs[R_EDI],
405                     env->regs[R_EBP],
406                     env->regs[R_ESP],
407                     env->regs[8],
408                     env->regs[9],
409                     env->regs[10],
410                     env->regs[11],
411                     env->regs[12],
412                     env->regs[13],
413                     env->regs[14],
414                     env->regs[15],
415                     env->eip, eflags,
416                     eflags & DF_MASK ? 'D' : '-',
417                     eflags & CC_O ? 'O' : '-',
418                     eflags & CC_S ? 'S' : '-',
419                     eflags & CC_Z ? 'Z' : '-',
420                     eflags & CC_A ? 'A' : '-',
421                     eflags & CC_P ? 'P' : '-',
422                     eflags & CC_C ? 'C' : '-',
423                     env->hflags & HF_CPL_MASK,
424                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
425                     (env->a20_mask >> 20) & 1,
426                     (env->hflags >> HF_SMM_SHIFT) & 1,
427                     cs->halted);
428     } else
429 #endif
430     {
431         cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
432                     "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
433                     "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
434                     (uint32_t)env->regs[R_EAX],
435                     (uint32_t)env->regs[R_EBX],
436                     (uint32_t)env->regs[R_ECX],
437                     (uint32_t)env->regs[R_EDX],
438                     (uint32_t)env->regs[R_ESI],
439                     (uint32_t)env->regs[R_EDI],
440                     (uint32_t)env->regs[R_EBP],
441                     (uint32_t)env->regs[R_ESP],
442                     (uint32_t)env->eip, eflags,
443                     eflags & DF_MASK ? 'D' : '-',
444                     eflags & CC_O ? 'O' : '-',
445                     eflags & CC_S ? 'S' : '-',
446                     eflags & CC_Z ? 'Z' : '-',
447                     eflags & CC_A ? 'A' : '-',
448                     eflags & CC_P ? 'P' : '-',
449                     eflags & CC_C ? 'C' : '-',
450                     env->hflags & HF_CPL_MASK,
451                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
452                     (env->a20_mask >> 20) & 1,
453                     (env->hflags >> HF_SMM_SHIFT) & 1,
454                     cs->halted);
455     }
456
457     for(i = 0; i < 6; i++) {
458         cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
459                                &env->segs[i]);
460     }
461     cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
462     cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
463
464 #ifdef TARGET_X86_64
465     if (env->hflags & HF_LMA_MASK) {
466         cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
467                     env->gdt.base, env->gdt.limit);
468         cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
469                     env->idt.base, env->idt.limit);
470         cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
471                     (uint32_t)env->cr[0],
472                     env->cr[2],
473                     env->cr[3],
474                     (uint32_t)env->cr[4]);
475         for(i = 0; i < 4; i++)
476             cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
477         cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
478                     env->dr[6], env->dr[7]);
479     } else
480 #endif
481     {
482         cpu_fprintf(f, "GDT=     %08x %08x\n",
483                     (uint32_t)env->gdt.base, env->gdt.limit);
484         cpu_fprintf(f, "IDT=     %08x %08x\n",
485                     (uint32_t)env->idt.base, env->idt.limit);
486         cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
487                     (uint32_t)env->cr[0],
488                     (uint32_t)env->cr[2],
489                     (uint32_t)env->cr[3],
490                     (uint32_t)env->cr[4]);
491         for(i = 0; i < 4; i++) {
492             cpu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
493         }
494         cpu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
495                     env->dr[6], env->dr[7]);
496     }
497     if (flags & CPU_DUMP_CCOP) {
498         if ((unsigned)env->cc_op < CC_OP_NB)
499             snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
500         else
501             snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
502 #ifdef TARGET_X86_64
503         if (env->hflags & HF_CS64_MASK) {
504             cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
505                         env->cc_src, env->cc_dst,
506                         cc_op_name);
507         } else
508 #endif
509         {
510             cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
511                         (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
512                         cc_op_name);
513         }
514     }
515     cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
516     if (flags & CPU_DUMP_FPU) {
517         int fptag;
518         fptag = 0;
519         for(i = 0; i < 8; i++) {
520             fptag |= ((!env->fptags[i]) << i);
521         }
522         cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
523                     env->fpuc,
524                     (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
525                     env->fpstt,
526                     fptag,
527                     env->mxcsr);
528         for(i=0;i<8;i++) {
529             CPU_LDoubleU u;
530             u.d = env->fpregs[i].d;
531             cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
532                         i, u.l.lower, u.l.upper);
533             if ((i & 1) == 1)
534                 cpu_fprintf(f, "\n");
535             else
536                 cpu_fprintf(f, " ");
537         }
538         if (env->hflags & HF_CS64_MASK)
539             nb = 16;
540         else
541             nb = 8;
542         for(i=0;i<nb;i++) {
543             cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
544                         i,
545                         env->xmm_regs[i].ZMM_L(3),
546                         env->xmm_regs[i].ZMM_L(2),
547                         env->xmm_regs[i].ZMM_L(1),
548                         env->xmm_regs[i].ZMM_L(0));
549             if ((i & 1) == 1)
550                 cpu_fprintf(f, "\n");
551             else
552                 cpu_fprintf(f, " ");
553         }
554     }
555     if (flags & CPU_DUMP_CODE) {
556         target_ulong base = env->segs[R_CS].base + env->eip;
557         target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
558         uint8_t code;
559         char codestr[3];
560
561         cpu_fprintf(f, "Code=");
562         for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
563             if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
564                 snprintf(codestr, sizeof(codestr), "%02x", code);
565             } else {
566                 snprintf(codestr, sizeof(codestr), "??");
567             }
568             cpu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
569                         i == offs ? "<" : "", codestr, i == offs ? ">" : "");
570         }
571         cpu_fprintf(f, "\n");
572     }
573 }
574
575 /***********************************************************/
576 /* x86 mmu */
577 /* XXX: add PGE support */
578
579 void x86_cpu_set_a20(X86CPU *cpu, int a20_state)
580 {
581     CPUX86State *env = &cpu->env;
582
583     a20_state = (a20_state != 0);
584     if (a20_state != ((env->a20_mask >> 20) & 1)) {
585         CPUState *cs = CPU(cpu);
586
587         qemu_log_mask(CPU_LOG_MMU, "A20 update: a20=%d\n", a20_state);
588         /* if the cpu is currently executing code, we must unlink it and
589            all the potentially executing TB */
590         cpu_interrupt(cs, CPU_INTERRUPT_EXITTB);
591
592         /* when a20 is changed, all the MMU mappings are invalid, so
593            we must flush everything */
594         tlb_flush(cs);
595         env->a20_mask = ~(1 << 20) | (a20_state << 20);
596     }
597 }
598
599 void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
600 {
601     X86CPU *cpu = x86_env_get_cpu(env);
602     int pe_state;
603
604     qemu_log_mask(CPU_LOG_MMU, "CR0 update: CR0=0x%08x\n", new_cr0);
605     if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
606         (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
607         tlb_flush(CPU(cpu));
608     }
609
610 #ifdef TARGET_X86_64
611     if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
612         (env->efer & MSR_EFER_LME)) {
613         /* enter in long mode */
614         /* XXX: generate an exception */
615         if (!(env->cr[4] & CR4_PAE_MASK))
616             return;
617         env->efer |= MSR_EFER_LMA;
618         env->hflags |= HF_LMA_MASK;
619     } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
620                (env->efer & MSR_EFER_LMA)) {
621         /* exit long mode */
622         env->efer &= ~MSR_EFER_LMA;
623         env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
624         env->eip &= 0xffffffff;
625     }
626 #endif
627     env->cr[0] = new_cr0 | CR0_ET_MASK;
628
629     /* update PE flag in hidden flags */
630     pe_state = (env->cr[0] & CR0_PE_MASK);
631     env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
632     /* ensure that ADDSEG is always set in real mode */
633     env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
634     /* update FPU flags */
635     env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
636         ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
637 }
638
639 /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
640    the PDPT */
641 void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
642 {
643     X86CPU *cpu = x86_env_get_cpu(env);
644
645     env->cr[3] = new_cr3;
646     if (env->cr[0] & CR0_PG_MASK) {
647         qemu_log_mask(CPU_LOG_MMU,
648                         "CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
649         tlb_flush(CPU(cpu));
650     }
651 }
652
653 void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
654 {
655     X86CPU *cpu = x86_env_get_cpu(env);
656     uint32_t hflags;
657
658 #if defined(DEBUG_MMU)
659     printf("CR4 update: %08x -> %08x\n", (uint32_t)env->cr[4], new_cr4);
660 #endif
661     if ((new_cr4 ^ env->cr[4]) &
662         (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK |
663          CR4_SMEP_MASK | CR4_SMAP_MASK | CR4_LA57_MASK)) {
664         tlb_flush(CPU(cpu));
665     }
666
667     /* Clear bits we're going to recompute.  */
668     hflags = env->hflags & ~(HF_OSFXSR_MASK | HF_SMAP_MASK);
669
670     /* SSE handling */
671     if (!(env->features[FEAT_1_EDX] & CPUID_SSE)) {
672         new_cr4 &= ~CR4_OSFXSR_MASK;
673     }
674     if (new_cr4 & CR4_OSFXSR_MASK) {
675         hflags |= HF_OSFXSR_MASK;
676     }
677
678     if (!(env->features[FEAT_7_0_EBX] & CPUID_7_0_EBX_SMAP)) {
679         new_cr4 &= ~CR4_SMAP_MASK;
680     }
681     if (new_cr4 & CR4_SMAP_MASK) {
682         hflags |= HF_SMAP_MASK;
683     }
684
685     if (!(env->features[FEAT_7_0_ECX] & CPUID_7_0_ECX_PKU)) {
686         new_cr4 &= ~CR4_PKE_MASK;
687     }
688
689     env->cr[4] = new_cr4;
690     env->hflags = hflags;
691
692     cpu_sync_bndcs_hflags(env);
693 }
694
695 #if defined(CONFIG_USER_ONLY)
696
697 int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
698                              int is_write, int mmu_idx)
699 {
700     X86CPU *cpu = X86_CPU(cs);
701     CPUX86State *env = &cpu->env;
702
703     /* user mode only emulation */
704     is_write &= 1;
705     env->cr[2] = addr;
706     env->error_code = (is_write << PG_ERROR_W_BIT);
707     env->error_code |= PG_ERROR_U_MASK;
708     cs->exception_index = EXCP0E_PAGE;
709     env->exception_is_int = 0;
710     env->exception_next_eip = -1;
711     return 1;
712 }
713
714 #else
715
716 /* return value:
717  * -1 = cannot handle fault
718  * 0  = nothing more to do
719  * 1  = generate PF fault
720  */
721 int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
722                              int is_write1, int mmu_idx)
723 {
724     X86CPU *cpu = X86_CPU(cs);
725     CPUX86State *env = &cpu->env;
726     uint64_t ptep, pte;
727     int32_t a20_mask;
728     target_ulong pde_addr, pte_addr;
729     int error_code = 0;
730     int is_dirty, prot, page_size, is_write, is_user;
731     hwaddr paddr;
732     uint64_t rsvd_mask = PG_HI_RSVD_MASK;
733     uint32_t page_offset;
734     target_ulong vaddr;
735
736     is_user = mmu_idx == MMU_USER_IDX;
737 #if defined(DEBUG_MMU)
738     printf("MMU fault: addr=%" VADDR_PRIx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
739            addr, is_write1, is_user, env->eip);
740 #endif
741     is_write = is_write1 & 1;
742
743     a20_mask = x86_get_a20_mask(env);
744     if (!(env->cr[0] & CR0_PG_MASK)) {
745         pte = addr;
746 #ifdef TARGET_X86_64
747         if (!(env->hflags & HF_LMA_MASK)) {
748             /* Without long mode we can only address 32bits in real mode */
749             pte = (uint32_t)pte;
750         }
751 #endif
752         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
753         page_size = 4096;
754         goto do_mapping;
755     }
756
757     if (!(env->efer & MSR_EFER_NXE)) {
758         rsvd_mask |= PG_NX_MASK;
759     }
760
761     if (env->cr[4] & CR4_PAE_MASK) {
762         uint64_t pde, pdpe;
763         target_ulong pdpe_addr;
764
765 #ifdef TARGET_X86_64
766         if (env->hflags & HF_LMA_MASK) {
767             bool la57 = env->cr[4] & CR4_LA57_MASK;
768             uint64_t pml5e_addr, pml5e;
769             uint64_t pml4e_addr, pml4e;
770             int32_t sext;
771
772             /* test virtual address sign extension */
773             sext = la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47;
774             if (sext != 0 && sext != -1) {
775                 env->error_code = 0;
776                 cs->exception_index = EXCP0D_GPF;
777                 return 1;
778             }
779
780             if (la57) {
781                 pml5e_addr = ((env->cr[3] & ~0xfff) +
782                         (((addr >> 48) & 0x1ff) << 3)) & a20_mask;
783                 pml5e = x86_ldq_phys(cs, pml5e_addr);
784                 if (!(pml5e & PG_PRESENT_MASK)) {
785                     goto do_fault;
786                 }
787                 if (pml5e & (rsvd_mask | PG_PSE_MASK)) {
788                     goto do_fault_rsvd;
789                 }
790                 if (!(pml5e & PG_ACCESSED_MASK)) {
791                     pml5e |= PG_ACCESSED_MASK;
792                     x86_stl_phys_notdirty(cs, pml5e_addr, pml5e);
793                 }
794                 ptep = pml5e ^ PG_NX_MASK;
795             } else {
796                 pml5e = env->cr[3];
797                 ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
798             }
799
800             pml4e_addr = ((pml5e & PG_ADDRESS_MASK) +
801                     (((addr >> 39) & 0x1ff) << 3)) & a20_mask;
802             pml4e = x86_ldq_phys(cs, pml4e_addr);
803             if (!(pml4e & PG_PRESENT_MASK)) {
804                 goto do_fault;
805             }
806             if (pml4e & (rsvd_mask | PG_PSE_MASK)) {
807                 goto do_fault_rsvd;
808             }
809             if (!(pml4e & PG_ACCESSED_MASK)) {
810                 pml4e |= PG_ACCESSED_MASK;
811                 x86_stl_phys_notdirty(cs, pml4e_addr, pml4e);
812             }
813             ptep &= pml4e ^ PG_NX_MASK;
814             pdpe_addr = ((pml4e & PG_ADDRESS_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
815                 a20_mask;
816             pdpe = x86_ldq_phys(cs, pdpe_addr);
817             if (!(pdpe & PG_PRESENT_MASK)) {
818                 goto do_fault;
819             }
820             if (pdpe & rsvd_mask) {
821                 goto do_fault_rsvd;
822             }
823             ptep &= pdpe ^ PG_NX_MASK;
824             if (!(pdpe & PG_ACCESSED_MASK)) {
825                 pdpe |= PG_ACCESSED_MASK;
826                 x86_stl_phys_notdirty(cs, pdpe_addr, pdpe);
827             }
828             if (pdpe & PG_PSE_MASK) {
829                 /* 1 GB page */
830                 page_size = 1024 * 1024 * 1024;
831                 pte_addr = pdpe_addr;
832                 pte = pdpe;
833                 goto do_check_protect;
834             }
835         } else
836 #endif
837         {
838             /* XXX: load them when cr3 is loaded ? */
839             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
840                 a20_mask;
841             pdpe = x86_ldq_phys(cs, pdpe_addr);
842             if (!(pdpe & PG_PRESENT_MASK)) {
843                 goto do_fault;
844             }
845             rsvd_mask |= PG_HI_USER_MASK;
846             if (pdpe & (rsvd_mask | PG_NX_MASK)) {
847                 goto do_fault_rsvd;
848             }
849             ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
850         }
851
852         pde_addr = ((pdpe & PG_ADDRESS_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
853             a20_mask;
854         pde = x86_ldq_phys(cs, pde_addr);
855         if (!(pde & PG_PRESENT_MASK)) {
856             goto do_fault;
857         }
858         if (pde & rsvd_mask) {
859             goto do_fault_rsvd;
860         }
861         ptep &= pde ^ PG_NX_MASK;
862         if (pde & PG_PSE_MASK) {
863             /* 2 MB page */
864             page_size = 2048 * 1024;
865             pte_addr = pde_addr;
866             pte = pde;
867             goto do_check_protect;
868         }
869         /* 4 KB page */
870         if (!(pde & PG_ACCESSED_MASK)) {
871             pde |= PG_ACCESSED_MASK;
872             x86_stl_phys_notdirty(cs, pde_addr, pde);
873         }
874         pte_addr = ((pde & PG_ADDRESS_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
875             a20_mask;
876         pte = x86_ldq_phys(cs, pte_addr);
877         if (!(pte & PG_PRESENT_MASK)) {
878             goto do_fault;
879         }
880         if (pte & rsvd_mask) {
881             goto do_fault_rsvd;
882         }
883         /* combine pde and pte nx, user and rw protections */
884         ptep &= pte ^ PG_NX_MASK;
885         page_size = 4096;
886     } else {
887         uint32_t pde;
888
889         /* page directory entry */
890         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
891             a20_mask;
892         pde = x86_ldl_phys(cs, pde_addr);
893         if (!(pde & PG_PRESENT_MASK)) {
894             goto do_fault;
895         }
896         ptep = pde | PG_NX_MASK;
897
898         /* if PSE bit is set, then we use a 4MB page */
899         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
900             page_size = 4096 * 1024;
901             pte_addr = pde_addr;
902
903             /* Bits 20-13 provide bits 39-32 of the address, bit 21 is reserved.
904              * Leave bits 20-13 in place for setting accessed/dirty bits below.
905              */
906             pte = pde | ((pde & 0x1fe000LL) << (32 - 13));
907             rsvd_mask = 0x200000;
908             goto do_check_protect_pse36;
909         }
910
911         if (!(pde & PG_ACCESSED_MASK)) {
912             pde |= PG_ACCESSED_MASK;
913             x86_stl_phys_notdirty(cs, pde_addr, pde);
914         }
915
916         /* page directory entry */
917         pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
918             a20_mask;
919         pte = x86_ldl_phys(cs, pte_addr);
920         if (!(pte & PG_PRESENT_MASK)) {
921             goto do_fault;
922         }
923         /* combine pde and pte user and rw protections */
924         ptep &= pte | PG_NX_MASK;
925         page_size = 4096;
926         rsvd_mask = 0;
927     }
928
929 do_check_protect:
930     rsvd_mask |= (page_size - 1) & PG_ADDRESS_MASK & ~PG_PSE_PAT_MASK;
931 do_check_protect_pse36:
932     if (pte & rsvd_mask) {
933         goto do_fault_rsvd;
934     }
935     ptep ^= PG_NX_MASK;
936
937     /* can the page can be put in the TLB?  prot will tell us */
938     if (is_user && !(ptep & PG_USER_MASK)) {
939         goto do_fault_protect;
940     }
941
942     prot = 0;
943     if (mmu_idx != MMU_KSMAP_IDX || !(ptep & PG_USER_MASK)) {
944         prot |= PAGE_READ;
945         if ((ptep & PG_RW_MASK) || (!is_user && !(env->cr[0] & CR0_WP_MASK))) {
946             prot |= PAGE_WRITE;
947         }
948     }
949     if (!(ptep & PG_NX_MASK) &&
950         (mmu_idx == MMU_USER_IDX ||
951          !((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) {
952         prot |= PAGE_EXEC;
953     }
954     if ((env->cr[4] & CR4_PKE_MASK) && (env->hflags & HF_LMA_MASK) &&
955         (ptep & PG_USER_MASK) && env->pkru) {
956         uint32_t pk = (pte & PG_PKRU_MASK) >> PG_PKRU_BIT;
957         uint32_t pkru_ad = (env->pkru >> pk * 2) & 1;
958         uint32_t pkru_wd = (env->pkru >> pk * 2) & 2;
959         uint32_t pkru_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
960
961         if (pkru_ad) {
962             pkru_prot &= ~(PAGE_READ | PAGE_WRITE);
963         } else if (pkru_wd && (is_user || env->cr[0] & CR0_WP_MASK)) {
964             pkru_prot &= ~PAGE_WRITE;
965         }
966
967         prot &= pkru_prot;
968         if ((pkru_prot & (1 << is_write1)) == 0) {
969             assert(is_write1 != 2);
970             error_code |= PG_ERROR_PK_MASK;
971             goto do_fault_protect;
972         }
973     }
974
975     if ((prot & (1 << is_write1)) == 0) {
976         goto do_fault_protect;
977     }
978
979     /* yes, it can! */
980     is_dirty = is_write && !(pte & PG_DIRTY_MASK);
981     if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
982         pte |= PG_ACCESSED_MASK;
983         if (is_dirty) {
984             pte |= PG_DIRTY_MASK;
985         }
986         x86_stl_phys_notdirty(cs, pte_addr, pte);
987     }
988
989     if (!(pte & PG_DIRTY_MASK)) {
990         /* only set write access if already dirty... otherwise wait
991            for dirty access */
992         assert(!is_write);
993         prot &= ~PAGE_WRITE;
994     }
995
996  do_mapping:
997     pte = pte & a20_mask;
998
999     /* align to page_size */
1000     pte &= PG_ADDRESS_MASK & ~(page_size - 1);
1001
1002     /* Even if 4MB pages, we map only one 4KB page in the cache to
1003        avoid filling it too fast */
1004     vaddr = addr & TARGET_PAGE_MASK;
1005     page_offset = vaddr & (page_size - 1);
1006     paddr = pte + page_offset;
1007
1008     assert(prot & (1 << is_write1));
1009     tlb_set_page_with_attrs(cs, vaddr, paddr, cpu_get_mem_attrs(env),
1010                             prot, mmu_idx, page_size);
1011     return 0;
1012  do_fault_rsvd:
1013     error_code |= PG_ERROR_RSVD_MASK;
1014  do_fault_protect:
1015     error_code |= PG_ERROR_P_MASK;
1016  do_fault:
1017     error_code |= (is_write << PG_ERROR_W_BIT);
1018     if (is_user)
1019         error_code |= PG_ERROR_U_MASK;
1020     if (is_write1 == 2 &&
1021         (((env->efer & MSR_EFER_NXE) &&
1022           (env->cr[4] & CR4_PAE_MASK)) ||
1023          (env->cr[4] & CR4_SMEP_MASK)))
1024         error_code |= PG_ERROR_I_D_MASK;
1025     if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
1026         /* cr2 is not modified in case of exceptions */
1027         x86_stq_phys(cs,
1028                  env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),
1029                  addr);
1030     } else {
1031         env->cr[2] = addr;
1032     }
1033     env->error_code = error_code;
1034     cs->exception_index = EXCP0E_PAGE;
1035     return 1;
1036 }
1037
1038 hwaddr x86_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
1039 {
1040     X86CPU *cpu = X86_CPU(cs);
1041     CPUX86State *env = &cpu->env;
1042     target_ulong pde_addr, pte_addr;
1043     uint64_t pte;
1044     int32_t a20_mask;
1045     uint32_t page_offset;
1046     int page_size;
1047
1048     a20_mask = x86_get_a20_mask(env);
1049     if (!(env->cr[0] & CR0_PG_MASK)) {
1050         pte = addr & a20_mask;
1051         page_size = 4096;
1052     } else if (env->cr[4] & CR4_PAE_MASK) {
1053         target_ulong pdpe_addr;
1054         uint64_t pde, pdpe;
1055
1056 #ifdef TARGET_X86_64
1057         if (env->hflags & HF_LMA_MASK) {
1058             bool la57 = env->cr[4] & CR4_LA57_MASK;
1059             uint64_t pml5e_addr, pml5e;
1060             uint64_t pml4e_addr, pml4e;
1061             int32_t sext;
1062
1063             /* test virtual address sign extension */
1064             sext = la57 ? (int64_t)addr >> 56 : (int64_t)addr >> 47;
1065             if (sext != 0 && sext != -1) {
1066                 return -1;
1067             }
1068
1069             if (la57) {
1070                 pml5e_addr = ((env->cr[3] & ~0xfff) +
1071                         (((addr >> 48) & 0x1ff) << 3)) & a20_mask;
1072                 pml5e = x86_ldq_phys(cs, pml5e_addr);
1073                 if (!(pml5e & PG_PRESENT_MASK)) {
1074                     return -1;
1075                 }
1076             } else {
1077                 pml5e = env->cr[3];
1078             }
1079
1080             pml4e_addr = ((pml5e & PG_ADDRESS_MASK) +
1081                     (((addr >> 39) & 0x1ff) << 3)) & a20_mask;
1082             pml4e = x86_ldq_phys(cs, pml4e_addr);
1083             if (!(pml4e & PG_PRESENT_MASK)) {
1084                 return -1;
1085             }
1086             pdpe_addr = ((pml4e & PG_ADDRESS_MASK) +
1087                          (((addr >> 30) & 0x1ff) << 3)) & a20_mask;
1088             pdpe = x86_ldq_phys(cs, pdpe_addr);
1089             if (!(pdpe & PG_PRESENT_MASK)) {
1090                 return -1;
1091             }
1092             if (pdpe & PG_PSE_MASK) {
1093                 page_size = 1024 * 1024 * 1024;
1094                 pte = pdpe;
1095                 goto out;
1096             }
1097
1098         } else
1099 #endif
1100         {
1101             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
1102                 a20_mask;
1103             pdpe = x86_ldq_phys(cs, pdpe_addr);
1104             if (!(pdpe & PG_PRESENT_MASK))
1105                 return -1;
1106         }
1107
1108         pde_addr = ((pdpe & PG_ADDRESS_MASK) +
1109                     (((addr >> 21) & 0x1ff) << 3)) & a20_mask;
1110         pde = x86_ldq_phys(cs, pde_addr);
1111         if (!(pde & PG_PRESENT_MASK)) {
1112             return -1;
1113         }
1114         if (pde & PG_PSE_MASK) {
1115             /* 2 MB page */
1116             page_size = 2048 * 1024;
1117             pte = pde;
1118         } else {
1119             /* 4 KB page */
1120             pte_addr = ((pde & PG_ADDRESS_MASK) +
1121                         (((addr >> 12) & 0x1ff) << 3)) & a20_mask;
1122             page_size = 4096;
1123             pte = x86_ldq_phys(cs, pte_addr);
1124         }
1125         if (!(pte & PG_PRESENT_MASK)) {
1126             return -1;
1127         }
1128     } else {
1129         uint32_t pde;
1130
1131         /* page directory entry */
1132         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & a20_mask;
1133         pde = x86_ldl_phys(cs, pde_addr);
1134         if (!(pde & PG_PRESENT_MASK))
1135             return -1;
1136         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
1137             pte = pde | ((pde & 0x1fe000LL) << (32 - 13));
1138             page_size = 4096 * 1024;
1139         } else {
1140             /* page directory entry */
1141             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_mask;
1142             pte = x86_ldl_phys(cs, pte_addr);
1143             if (!(pte & PG_PRESENT_MASK)) {
1144                 return -1;
1145             }
1146             page_size = 4096;
1147         }
1148         pte = pte & a20_mask;
1149     }
1150
1151 #ifdef TARGET_X86_64
1152 out:
1153 #endif
1154     pte &= PG_ADDRESS_MASK & ~(page_size - 1);
1155     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
1156     return pte | page_offset;
1157 }
1158
1159 typedef struct MCEInjectionParams {
1160     Monitor *mon;
1161     int bank;
1162     uint64_t status;
1163     uint64_t mcg_status;
1164     uint64_t addr;
1165     uint64_t misc;
1166     int flags;
1167 } MCEInjectionParams;
1168
1169 static void do_inject_x86_mce(CPUState *cs, run_on_cpu_data data)
1170 {
1171     MCEInjectionParams *params = data.host_ptr;
1172     X86CPU *cpu = X86_CPU(cs);
1173     CPUX86State *cenv = &cpu->env;
1174     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
1175
1176     cpu_synchronize_state(cs);
1177
1178     /*
1179      * If there is an MCE exception being processed, ignore this SRAO MCE
1180      * unless unconditional injection was requested.
1181      */
1182     if (!(params->flags & MCE_INJECT_UNCOND_AO)
1183         && !(params->status & MCI_STATUS_AR)
1184         && (cenv->mcg_status & MCG_STATUS_MCIP)) {
1185         return;
1186     }
1187
1188     if (params->status & MCI_STATUS_UC) {
1189         /*
1190          * if MSR_MCG_CTL is not all 1s, the uncorrected error
1191          * reporting is disabled
1192          */
1193         if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
1194             monitor_printf(params->mon,
1195                            "CPU %d: Uncorrected error reporting disabled\n",
1196                            cs->cpu_index);
1197             return;
1198         }
1199
1200         /*
1201          * if MSR_MCi_CTL is not all 1s, the uncorrected error
1202          * reporting is disabled for the bank
1203          */
1204         if (banks[0] != ~(uint64_t)0) {
1205             monitor_printf(params->mon,
1206                            "CPU %d: Uncorrected error reporting disabled for"
1207                            " bank %d\n",
1208                            cs->cpu_index, params->bank);
1209             return;
1210         }
1211
1212         if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
1213             !(cenv->cr[4] & CR4_MCE_MASK)) {
1214             monitor_printf(params->mon,
1215                            "CPU %d: Previous MCE still in progress, raising"
1216                            " triple fault\n",
1217                            cs->cpu_index);
1218             qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
1219             qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
1220             return;
1221         }
1222         if (banks[1] & MCI_STATUS_VAL) {
1223             params->status |= MCI_STATUS_OVER;
1224         }
1225         banks[2] = params->addr;
1226         banks[3] = params->misc;
1227         cenv->mcg_status = params->mcg_status;
1228         banks[1] = params->status;
1229         cpu_interrupt(cs, CPU_INTERRUPT_MCE);
1230     } else if (!(banks[1] & MCI_STATUS_VAL)
1231                || !(banks[1] & MCI_STATUS_UC)) {
1232         if (banks[1] & MCI_STATUS_VAL) {
1233             params->status |= MCI_STATUS_OVER;
1234         }
1235         banks[2] = params->addr;
1236         banks[3] = params->misc;
1237         banks[1] = params->status;
1238     } else {
1239         banks[1] |= MCI_STATUS_OVER;
1240     }
1241 }
1242
1243 void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
1244                         uint64_t status, uint64_t mcg_status, uint64_t addr,
1245                         uint64_t misc, int flags)
1246 {
1247     CPUState *cs = CPU(cpu);
1248     CPUX86State *cenv = &cpu->env;
1249     MCEInjectionParams params = {
1250         .mon = mon,
1251         .bank = bank,
1252         .status = status,
1253         .mcg_status = mcg_status,
1254         .addr = addr,
1255         .misc = misc,
1256         .flags = flags,
1257     };
1258     unsigned bank_num = cenv->mcg_cap & 0xff;
1259
1260     if (!cenv->mcg_cap) {
1261         monitor_printf(mon, "MCE injection not supported\n");
1262         return;
1263     }
1264     if (bank >= bank_num) {
1265         monitor_printf(mon, "Invalid MCE bank number\n");
1266         return;
1267     }
1268     if (!(status & MCI_STATUS_VAL)) {
1269         monitor_printf(mon, "Invalid MCE status code\n");
1270         return;
1271     }
1272     if ((flags & MCE_INJECT_BROADCAST)
1273         && !cpu_x86_support_mca_broadcast(cenv)) {
1274         monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
1275         return;
1276     }
1277
1278     run_on_cpu(cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
1279     if (flags & MCE_INJECT_BROADCAST) {
1280         CPUState *other_cs;
1281
1282         params.bank = 1;
1283         params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
1284         params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
1285         params.addr = 0;
1286         params.misc = 0;
1287         CPU_FOREACH(other_cs) {
1288             if (other_cs == cs) {
1289                 continue;
1290             }
1291             run_on_cpu(other_cs, do_inject_x86_mce, RUN_ON_CPU_HOST_PTR(&params));
1292         }
1293     }
1294 }
1295
1296 void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
1297 {
1298     X86CPU *cpu = x86_env_get_cpu(env);
1299     CPUState *cs = CPU(cpu);
1300
1301     if (kvm_enabled()) {
1302         env->tpr_access_type = access;
1303
1304         cpu_interrupt(cs, CPU_INTERRUPT_TPR);
1305     } else {
1306         cpu_restore_state(cs, cs->mem_io_pc);
1307
1308         apic_handle_tpr_access_report(cpu->apic_state, env->eip, access);
1309     }
1310 }
1311 #endif /* !CONFIG_USER_ONLY */
1312
1313 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
1314                             target_ulong *base, unsigned int *limit,
1315                             unsigned int *flags)
1316 {
1317     X86CPU *cpu = x86_env_get_cpu(env);
1318     CPUState *cs = CPU(cpu);
1319     SegmentCache *dt;
1320     target_ulong ptr;
1321     uint32_t e1, e2;
1322     int index;
1323
1324     if (selector & 0x4)
1325         dt = &env->ldt;
1326     else
1327         dt = &env->gdt;
1328     index = selector & ~7;
1329     ptr = dt->base + index;
1330     if ((index + 7) > dt->limit
1331         || cpu_memory_rw_debug(cs, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
1332         || cpu_memory_rw_debug(cs, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
1333         return 0;
1334
1335     *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
1336     *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
1337     if (e2 & DESC_G_MASK)
1338         *limit = (*limit << 12) | 0xfff;
1339     *flags = e2;
1340
1341     return 1;
1342 }
1343
1344 #if !defined(CONFIG_USER_ONLY)
1345 void do_cpu_init(X86CPU *cpu)
1346 {
1347     CPUState *cs = CPU(cpu);
1348     CPUX86State *env = &cpu->env;
1349     CPUX86State *save = g_new(CPUX86State, 1);
1350     int sipi = cs->interrupt_request & CPU_INTERRUPT_SIPI;
1351
1352     *save = *env;
1353
1354     cpu_reset(cs);
1355     cs->interrupt_request = sipi;
1356     memcpy(&env->start_init_save, &save->start_init_save,
1357            offsetof(CPUX86State, end_init_save) -
1358            offsetof(CPUX86State, start_init_save));
1359     g_free(save);
1360
1361     if (kvm_enabled()) {
1362         kvm_arch_do_init_vcpu(cpu);
1363     }
1364     apic_init_reset(cpu->apic_state);
1365 }
1366
1367 void do_cpu_sipi(X86CPU *cpu)
1368 {
1369     apic_sipi(cpu->apic_state);
1370 }
1371 #else
1372 void do_cpu_init(X86CPU *cpu)
1373 {
1374 }
1375 void do_cpu_sipi(X86CPU *cpu)
1376 {
1377 }
1378 #endif
1379
1380 /* Frob eflags into and out of the CPU temporary format.  */
1381
1382 void x86_cpu_exec_enter(CPUState *cs)
1383 {
1384     X86CPU *cpu = X86_CPU(cs);
1385     CPUX86State *env = &cpu->env;
1386
1387     CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1388     env->df = 1 - (2 * ((env->eflags >> 10) & 1));
1389     CC_OP = CC_OP_EFLAGS;
1390     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
1391 }
1392
1393 void x86_cpu_exec_exit(CPUState *cs)
1394 {
1395     X86CPU *cpu = X86_CPU(cs);
1396     CPUX86State *env = &cpu->env;
1397
1398     env->eflags = cpu_compute_eflags(env);
1399 }
1400
1401 #ifndef CONFIG_USER_ONLY
1402 uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr)
1403 {
1404     X86CPU *cpu = X86_CPU(cs);
1405     CPUX86State *env = &cpu->env;
1406
1407     return address_space_ldub(cs->as, addr,
1408                               cpu_get_mem_attrs(env),
1409                               NULL);
1410 }
1411
1412 uint32_t x86_lduw_phys(CPUState *cs, hwaddr addr)
1413 {
1414     X86CPU *cpu = X86_CPU(cs);
1415     CPUX86State *env = &cpu->env;
1416
1417     return address_space_lduw(cs->as, addr,
1418                               cpu_get_mem_attrs(env),
1419                               NULL);
1420 }
1421
1422 uint32_t x86_ldl_phys(CPUState *cs, hwaddr addr)
1423 {
1424     X86CPU *cpu = X86_CPU(cs);
1425     CPUX86State *env = &cpu->env;
1426
1427     return address_space_ldl(cs->as, addr,
1428                              cpu_get_mem_attrs(env),
1429                              NULL);
1430 }
1431
1432 uint64_t x86_ldq_phys(CPUState *cs, hwaddr addr)
1433 {
1434     X86CPU *cpu = X86_CPU(cs);
1435     CPUX86State *env = &cpu->env;
1436
1437     return address_space_ldq(cs->as, addr,
1438                              cpu_get_mem_attrs(env),
1439                              NULL);
1440 }
1441
1442 void x86_stb_phys(CPUState *cs, hwaddr addr, uint8_t val)
1443 {
1444     X86CPU *cpu = X86_CPU(cs);
1445     CPUX86State *env = &cpu->env;
1446
1447     address_space_stb(cs->as, addr, val,
1448                       cpu_get_mem_attrs(env),
1449                       NULL);
1450 }
1451
1452 void x86_stl_phys_notdirty(CPUState *cs, hwaddr addr, uint32_t val)
1453 {
1454     X86CPU *cpu = X86_CPU(cs);
1455     CPUX86State *env = &cpu->env;
1456
1457     address_space_stl_notdirty(cs->as, addr, val,
1458                                cpu_get_mem_attrs(env),
1459                                NULL);
1460 }
1461
1462 void x86_stw_phys(CPUState *cs, hwaddr addr, uint32_t val)
1463 {
1464     X86CPU *cpu = X86_CPU(cs);
1465     CPUX86State *env = &cpu->env;
1466
1467     address_space_stw(cs->as, addr, val,
1468                       cpu_get_mem_attrs(env),
1469                       NULL);
1470 }
1471
1472 void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val)
1473 {
1474     X86CPU *cpu = X86_CPU(cs);
1475     CPUX86State *env = &cpu->env;
1476
1477     address_space_stl(cs->as, addr, val,
1478                       cpu_get_mem_attrs(env),
1479                       NULL);
1480 }
1481
1482 void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val)
1483 {
1484     X86CPU *cpu = X86_CPU(cs);
1485     CPUX86State *env = &cpu->env;
1486
1487     address_space_stq(cs->as, addr, val,
1488                       cpu_get_mem_attrs(env),
1489                       NULL);
1490 }
1491 #endif
This page took 0.108916 seconds and 4 git commands to generate.