File:  [Qemu by Fabrice Bellard] / qemu / target-i386 / helper.c
Revision 1.1.1.16 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:31:08 2018 UTC (3 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu1001, HEAD
qemu 1.0.1

    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: 
   25: #include "cpu.h"
   26: #include "qemu-common.h"
   27: #include "kvm.h"
   28: #ifndef CONFIG_USER_ONLY
   29: #include "sysemu.h"
   30: #include "monitor.h"
   31: #endif
   32: 
   33: //#define DEBUG_MMU
   34: 
   35: /* NOTE: must be called outside the CPU execute loop */
   36: void cpu_reset(CPUX86State *env)
   37: {
   38:     int i;
   39: 
   40:     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
   41:         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
   42:         log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
   43:     }
   44: 
   45:     memset(env, 0, offsetof(CPUX86State, breakpoints));
   46: 
   47:     tlb_flush(env, 1);
   48: 
   49:     env->old_exception = -1;
   50: 
   51:     /* init to reset state */
   52: 
   53: #ifdef CONFIG_SOFTMMU
   54:     env->hflags |= HF_SOFTMMU_MASK;
   55: #endif
   56:     env->hflags2 |= HF2_GIF_MASK;
   57: 
   58:     cpu_x86_update_cr0(env, 0x60000010);
   59:     env->a20_mask = ~0x0;
   60:     env->smbase = 0x30000;
   61: 
   62:     env->idt.limit = 0xffff;
   63:     env->gdt.limit = 0xffff;
   64:     env->ldt.limit = 0xffff;
   65:     env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
   66:     env->tr.limit = 0xffff;
   67:     env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
   68: 
   69:     cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
   70:                            DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
   71:                            DESC_R_MASK | DESC_A_MASK);
   72:     cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
   73:                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
   74:                            DESC_A_MASK);
   75:     cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
   76:                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
   77:                            DESC_A_MASK);
   78:     cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
   79:                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
   80:                            DESC_A_MASK);
   81:     cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
   82:                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
   83:                            DESC_A_MASK);
   84:     cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
   85:                            DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
   86:                            DESC_A_MASK);
   87: 
   88:     env->eip = 0xfff0;
   89:     env->regs[R_EDX] = env->cpuid_version;
   90: 
   91:     env->eflags = 0x2;
   92: 
   93:     /* FPU init */
   94:     for(i = 0;i < 8; i++)
   95:         env->fptags[i] = 1;
   96:     env->fpuc = 0x37f;
   97: 
   98:     env->mxcsr = 0x1f80;
   99: 
  100:     env->pat = 0x0007040600070406ULL;
  101:     env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
  102: 
  103:     memset(env->dr, 0, sizeof(env->dr));
  104:     env->dr[6] = DR6_FIXED_1;
  105:     env->dr[7] = DR7_FIXED_1;
  106:     cpu_breakpoint_remove_all(env, BP_CPU);
  107:     cpu_watchpoint_remove_all(env, BP_CPU);
  108: }
  109: 
  110: void cpu_x86_close(CPUX86State *env)
  111: {
  112:     g_free(env);
  113: }
  114: 
  115: static void cpu_x86_version(CPUState *env, int *family, int *model)
  116: {
  117:     int cpuver = env->cpuid_version;
  118: 
  119:     if (family == NULL || model == NULL) {
  120:         return;
  121:     }
  122: 
  123:     *family = (cpuver >> 8) & 0x0f;
  124:     *model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0x0f);
  125: }
  126: 
  127: /* Broadcast MCA signal for processor version 06H_EH and above */
  128: int cpu_x86_support_mca_broadcast(CPUState *env)
  129: {
  130:     int family = 0;
  131:     int model = 0;
  132: 
  133:     cpu_x86_version(env, &family, &model);
  134:     if ((family == 6 && model >= 14) || family > 6) {
  135:         return 1;
  136:     }
  137: 
  138:     return 0;
  139: }
  140: 
  141: /***********************************************************/
  142: /* x86 debug */
  143: 
  144: static const char *cc_op_str[] = {
  145:     "DYNAMIC",
  146:     "EFLAGS",
  147: 
  148:     "MULB",
  149:     "MULW",
  150:     "MULL",
  151:     "MULQ",
  152: 
  153:     "ADDB",
  154:     "ADDW",
  155:     "ADDL",
  156:     "ADDQ",
  157: 
  158:     "ADCB",
  159:     "ADCW",
  160:     "ADCL",
  161:     "ADCQ",
  162: 
  163:     "SUBB",
  164:     "SUBW",
  165:     "SUBL",
  166:     "SUBQ",
  167: 
  168:     "SBBB",
  169:     "SBBW",
  170:     "SBBL",
  171:     "SBBQ",
  172: 
  173:     "LOGICB",
  174:     "LOGICW",
  175:     "LOGICL",
  176:     "LOGICQ",
  177: 
  178:     "INCB",
  179:     "INCW",
  180:     "INCL",
  181:     "INCQ",
  182: 
  183:     "DECB",
  184:     "DECW",
  185:     "DECL",
  186:     "DECQ",
  187: 
  188:     "SHLB",
  189:     "SHLW",
  190:     "SHLL",
  191:     "SHLQ",
  192: 
  193:     "SARB",
  194:     "SARW",
  195:     "SARL",
  196:     "SARQ",
  197: };
  198: 
  199: static void
  200: cpu_x86_dump_seg_cache(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
  201:                        const char *name, struct SegmentCache *sc)
  202: {
  203: #ifdef TARGET_X86_64
  204:     if (env->hflags & HF_CS64_MASK) {
  205:         cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
  206:                     sc->selector, sc->base, sc->limit, sc->flags & 0x00ffff00);
  207:     } else
  208: #endif
  209:     {
  210:         cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
  211:                     (uint32_t)sc->base, sc->limit, sc->flags & 0x00ffff00);
  212:     }
  213: 
  214:     if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
  215:         goto done;
  216: 
  217:     cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
  218:     if (sc->flags & DESC_S_MASK) {
  219:         if (sc->flags & DESC_CS_MASK) {
  220:             cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
  221:                            ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
  222:             cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
  223:                         (sc->flags & DESC_R_MASK) ? 'R' : '-');
  224:         } else {
  225:             cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS  " : "DS16");
  226:             cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
  227:                         (sc->flags & DESC_W_MASK) ? 'W' : '-');
  228:         }
  229:         cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
  230:     } else {
  231:         static const char *sys_type_name[2][16] = {
  232:             { /* 32 bit mode */
  233:                 "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
  234:                 "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
  235:                 "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
  236:                 "CallGate32", "Reserved", "IntGate32", "TrapGate32"
  237:             },
  238:             { /* 64 bit mode */
  239:                 "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
  240:                 "Reserved", "Reserved", "Reserved", "Reserved",
  241:                 "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
  242:                 "Reserved", "IntGate64", "TrapGate64"
  243:             }
  244:         };
  245:         cpu_fprintf(f, "%s",
  246:                     sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
  247:                                  [(sc->flags & DESC_TYPE_MASK)
  248:                                   >> DESC_TYPE_SHIFT]);
  249:     }
  250: done:
  251:     cpu_fprintf(f, "\n");
  252: }
  253: 
  254: #define DUMP_CODE_BYTES_TOTAL    50
  255: #define DUMP_CODE_BYTES_BACKWARD 20
  256: 
  257: void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
  258:                     int flags)
  259: {
  260:     int eflags, i, nb;
  261:     char cc_op_name[32];
  262:     static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
  263: 
  264:     cpu_synchronize_state(env);
  265: 
  266:     eflags = env->eflags;
  267: #ifdef TARGET_X86_64
  268:     if (env->hflags & HF_CS64_MASK) {
  269:         cpu_fprintf(f,
  270:                     "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
  271:                     "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
  272:                     "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
  273:                     "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
  274:                     "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
  275:                     env->regs[R_EAX],
  276:                     env->regs[R_EBX],
  277:                     env->regs[R_ECX],
  278:                     env->regs[R_EDX],
  279:                     env->regs[R_ESI],
  280:                     env->regs[R_EDI],
  281:                     env->regs[R_EBP],
  282:                     env->regs[R_ESP],
  283:                     env->regs[8],
  284:                     env->regs[9],
  285:                     env->regs[10],
  286:                     env->regs[11],
  287:                     env->regs[12],
  288:                     env->regs[13],
  289:                     env->regs[14],
  290:                     env->regs[15],
  291:                     env->eip, eflags,
  292:                     eflags & DF_MASK ? 'D' : '-',
  293:                     eflags & CC_O ? 'O' : '-',
  294:                     eflags & CC_S ? 'S' : '-',
  295:                     eflags & CC_Z ? 'Z' : '-',
  296:                     eflags & CC_A ? 'A' : '-',
  297:                     eflags & CC_P ? 'P' : '-',
  298:                     eflags & CC_C ? 'C' : '-',
  299:                     env->hflags & HF_CPL_MASK,
  300:                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
  301:                     (env->a20_mask >> 20) & 1,
  302:                     (env->hflags >> HF_SMM_SHIFT) & 1,
  303:                     env->halted);
  304:     } else
  305: #endif
  306:     {
  307:         cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
  308:                     "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
  309:                     "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
  310:                     (uint32_t)env->regs[R_EAX],
  311:                     (uint32_t)env->regs[R_EBX],
  312:                     (uint32_t)env->regs[R_ECX],
  313:                     (uint32_t)env->regs[R_EDX],
  314:                     (uint32_t)env->regs[R_ESI],
  315:                     (uint32_t)env->regs[R_EDI],
  316:                     (uint32_t)env->regs[R_EBP],
  317:                     (uint32_t)env->regs[R_ESP],
  318:                     (uint32_t)env->eip, eflags,
  319:                     eflags & DF_MASK ? 'D' : '-',
  320:                     eflags & CC_O ? 'O' : '-',
  321:                     eflags & CC_S ? 'S' : '-',
  322:                     eflags & CC_Z ? 'Z' : '-',
  323:                     eflags & CC_A ? 'A' : '-',
  324:                     eflags & CC_P ? 'P' : '-',
  325:                     eflags & CC_C ? 'C' : '-',
  326:                     env->hflags & HF_CPL_MASK,
  327:                     (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
  328:                     (env->a20_mask >> 20) & 1,
  329:                     (env->hflags >> HF_SMM_SHIFT) & 1,
  330:                     env->halted);
  331:     }
  332: 
  333:     for(i = 0; i < 6; i++) {
  334:         cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],
  335:                                &env->segs[i]);
  336:     }
  337:     cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);
  338:     cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);
  339: 
  340: #ifdef TARGET_X86_64
  341:     if (env->hflags & HF_LMA_MASK) {
  342:         cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",
  343:                     env->gdt.base, env->gdt.limit);
  344:         cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",
  345:                     env->idt.base, env->idt.limit);
  346:         cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
  347:                     (uint32_t)env->cr[0],
  348:                     env->cr[2],
  349:                     env->cr[3],
  350:                     (uint32_t)env->cr[4]);
  351:         for(i = 0; i < 4; i++)
  352:             cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
  353:         cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
  354:                     env->dr[6], env->dr[7]);
  355:     } else
  356: #endif
  357:     {
  358:         cpu_fprintf(f, "GDT=     %08x %08x\n",
  359:                     (uint32_t)env->gdt.base, env->gdt.limit);
  360:         cpu_fprintf(f, "IDT=     %08x %08x\n",
  361:                     (uint32_t)env->idt.base, env->idt.limit);
  362:         cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
  363:                     (uint32_t)env->cr[0],
  364:                     (uint32_t)env->cr[2],
  365:                     (uint32_t)env->cr[3],
  366:                     (uint32_t)env->cr[4]);
  367:         for(i = 0; i < 4; i++) {
  368:             cpu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
  369:         }
  370:         cpu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
  371:                     env->dr[6], env->dr[7]);
  372:     }
  373:     if (flags & X86_DUMP_CCOP) {
  374:         if ((unsigned)env->cc_op < CC_OP_NB)
  375:             snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
  376:         else
  377:             snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
  378: #ifdef TARGET_X86_64
  379:         if (env->hflags & HF_CS64_MASK) {
  380:             cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
  381:                         env->cc_src, env->cc_dst,
  382:                         cc_op_name);
  383:         } else
  384: #endif
  385:         {
  386:             cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
  387:                         (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
  388:                         cc_op_name);
  389:         }
  390:     }
  391:     cpu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
  392:     if (flags & X86_DUMP_FPU) {
  393:         int fptag;
  394:         fptag = 0;
  395:         for(i = 0; i < 8; i++) {
  396:             fptag |= ((!env->fptags[i]) << i);
  397:         }
  398:         cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
  399:                     env->fpuc,
  400:                     (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
  401:                     env->fpstt,
  402:                     fptag,
  403:                     env->mxcsr);
  404:         for(i=0;i<8;i++) {
  405:             CPU_LDoubleU u;
  406:             u.d = env->fpregs[i].d;
  407:             cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
  408:                         i, u.l.lower, u.l.upper);
  409:             if ((i & 1) == 1)
  410:                 cpu_fprintf(f, "\n");
  411:             else
  412:                 cpu_fprintf(f, " ");
  413:         }
  414:         if (env->hflags & HF_CS64_MASK)
  415:             nb = 16;
  416:         else
  417:             nb = 8;
  418:         for(i=0;i<nb;i++) {
  419:             cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
  420:                         i,
  421:                         env->xmm_regs[i].XMM_L(3),
  422:                         env->xmm_regs[i].XMM_L(2),
  423:                         env->xmm_regs[i].XMM_L(1),
  424:                         env->xmm_regs[i].XMM_L(0));
  425:             if ((i & 1) == 1)
  426:                 cpu_fprintf(f, "\n");
  427:             else
  428:                 cpu_fprintf(f, " ");
  429:         }
  430:     }
  431:     if (flags & CPU_DUMP_CODE) {
  432:         target_ulong base = env->segs[R_CS].base + env->eip;
  433:         target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
  434:         uint8_t code;
  435:         char codestr[3];
  436: 
  437:         cpu_fprintf(f, "Code=");
  438:         for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
  439:             if (cpu_memory_rw_debug(env, base - offs + i, &code, 1, 0) == 0) {
  440:                 snprintf(codestr, sizeof(codestr), "%02x", code);
  441:             } else {
  442:                 snprintf(codestr, sizeof(codestr), "??");
  443:             }
  444:             cpu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
  445:                         i == offs ? "<" : "", codestr, i == offs ? ">" : "");
  446:         }
  447:         cpu_fprintf(f, "\n");
  448:     }
  449: }
  450: 
  451: /***********************************************************/
  452: /* x86 mmu */
  453: /* XXX: add PGE support */
  454: 
  455: void cpu_x86_set_a20(CPUX86State *env, int a20_state)
  456: {
  457:     a20_state = (a20_state != 0);
  458:     if (a20_state != ((env->a20_mask >> 20) & 1)) {
  459: #if defined(DEBUG_MMU)
  460:         printf("A20 update: a20=%d\n", a20_state);
  461: #endif
  462:         /* if the cpu is currently executing code, we must unlink it and
  463:            all the potentially executing TB */
  464:         cpu_interrupt(env, CPU_INTERRUPT_EXITTB);
  465: 
  466:         /* when a20 is changed, all the MMU mappings are invalid, so
  467:            we must flush everything */
  468:         tlb_flush(env, 1);
  469:         env->a20_mask = ~(1 << 20) | (a20_state << 20);
  470:     }
  471: }
  472: 
  473: void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0)
  474: {
  475:     int pe_state;
  476: 
  477: #if defined(DEBUG_MMU)
  478:     printf("CR0 update: CR0=0x%08x\n", new_cr0);
  479: #endif
  480:     if ((new_cr0 & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK)) !=
  481:         (env->cr[0] & (CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK))) {
  482:         tlb_flush(env, 1);
  483:     }
  484: 
  485: #ifdef TARGET_X86_64
  486:     if (!(env->cr[0] & CR0_PG_MASK) && (new_cr0 & CR0_PG_MASK) &&
  487:         (env->efer & MSR_EFER_LME)) {
  488:         /* enter in long mode */
  489:         /* XXX: generate an exception */
  490:         if (!(env->cr[4] & CR4_PAE_MASK))
  491:             return;
  492:         env->efer |= MSR_EFER_LMA;
  493:         env->hflags |= HF_LMA_MASK;
  494:     } else if ((env->cr[0] & CR0_PG_MASK) && !(new_cr0 & CR0_PG_MASK) &&
  495:                (env->efer & MSR_EFER_LMA)) {
  496:         /* exit long mode */
  497:         env->efer &= ~MSR_EFER_LMA;
  498:         env->hflags &= ~(HF_LMA_MASK | HF_CS64_MASK);
  499:         env->eip &= 0xffffffff;
  500:     }
  501: #endif
  502:     env->cr[0] = new_cr0 | CR0_ET_MASK;
  503: 
  504:     /* update PE flag in hidden flags */
  505:     pe_state = (env->cr[0] & CR0_PE_MASK);
  506:     env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);
  507:     /* ensure that ADDSEG is always set in real mode */
  508:     env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);
  509:     /* update FPU flags */
  510:     env->hflags = (env->hflags & ~(HF_MP_MASK | HF_EM_MASK | HF_TS_MASK)) |
  511:         ((new_cr0 << (HF_MP_SHIFT - 1)) & (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK));
  512: }
  513: 
  514: /* XXX: in legacy PAE mode, generate a GPF if reserved bits are set in
  515:    the PDPT */
  516: void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3)
  517: {
  518:     env->cr[3] = new_cr3;
  519:     if (env->cr[0] & CR0_PG_MASK) {
  520: #if defined(DEBUG_MMU)
  521:         printf("CR3 update: CR3=" TARGET_FMT_lx "\n", new_cr3);
  522: #endif
  523:         tlb_flush(env, 0);
  524:     }
  525: }
  526: 
  527: void cpu_x86_update_cr4(CPUX86State *env, uint32_t new_cr4)
  528: {
  529: #if defined(DEBUG_MMU)
  530:     printf("CR4 update: CR4=%08x\n", (uint32_t)env->cr[4]);
  531: #endif
  532:     if ((new_cr4 & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK)) !=
  533:         (env->cr[4] & (CR4_PGE_MASK | CR4_PAE_MASK | CR4_PSE_MASK))) {
  534:         tlb_flush(env, 1);
  535:     }
  536:     /* SSE handling */
  537:     if (!(env->cpuid_features & CPUID_SSE))
  538:         new_cr4 &= ~CR4_OSFXSR_MASK;
  539:     if (new_cr4 & CR4_OSFXSR_MASK)
  540:         env->hflags |= HF_OSFXSR_MASK;
  541:     else
  542:         env->hflags &= ~HF_OSFXSR_MASK;
  543: 
  544:     env->cr[4] = new_cr4;
  545: }
  546: 
  547: #if defined(CONFIG_USER_ONLY)
  548: 
  549: int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
  550:                              int is_write, int mmu_idx)
  551: {
  552:     /* user mode only emulation */
  553:     is_write &= 1;
  554:     env->cr[2] = addr;
  555:     env->error_code = (is_write << PG_ERROR_W_BIT);
  556:     env->error_code |= PG_ERROR_U_MASK;
  557:     env->exception_index = EXCP0E_PAGE;
  558:     return 1;
  559: }
  560: 
  561: #else
  562: 
  563: /* XXX: This value should match the one returned by CPUID
  564:  * and in exec.c */
  565: # if defined(TARGET_X86_64)
  566: # define PHYS_ADDR_MASK 0xfffffff000LL
  567: # else
  568: # define PHYS_ADDR_MASK 0xffffff000LL
  569: # endif
  570: 
  571: /* return value:
  572:    -1 = cannot handle fault
  573:    0  = nothing more to do
  574:    1  = generate PF fault
  575: */
  576: int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
  577:                              int is_write1, int mmu_idx)
  578: {
  579:     uint64_t ptep, pte;
  580:     target_ulong pde_addr, pte_addr;
  581:     int error_code, is_dirty, prot, page_size, is_write, is_user;
  582:     target_phys_addr_t paddr;
  583:     uint32_t page_offset;
  584:     target_ulong vaddr, virt_addr;
  585: 
  586:     is_user = mmu_idx == MMU_USER_IDX;
  587: #if defined(DEBUG_MMU)
  588:     printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",
  589:            addr, is_write1, is_user, env->eip);
  590: #endif
  591:     is_write = is_write1 & 1;
  592: 
  593:     if (!(env->cr[0] & CR0_PG_MASK)) {
  594:         pte = addr;
  595:         virt_addr = addr & TARGET_PAGE_MASK;
  596:         prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
  597:         page_size = 4096;
  598:         goto do_mapping;
  599:     }
  600: 
  601:     if (env->cr[4] & CR4_PAE_MASK) {
  602:         uint64_t pde, pdpe;
  603:         target_ulong pdpe_addr;
  604: 
  605: #ifdef TARGET_X86_64
  606:         if (env->hflags & HF_LMA_MASK) {
  607:             uint64_t pml4e_addr, pml4e;
  608:             int32_t sext;
  609: 
  610:             /* test virtual address sign extension */
  611:             sext = (int64_t)addr >> 47;
  612:             if (sext != 0 && sext != -1) {
  613:                 env->error_code = 0;
  614:                 env->exception_index = EXCP0D_GPF;
  615:                 return 1;
  616:             }
  617: 
  618:             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
  619:                 env->a20_mask;
  620:             pml4e = ldq_phys(pml4e_addr);
  621:             if (!(pml4e & PG_PRESENT_MASK)) {
  622:                 error_code = 0;
  623:                 goto do_fault;
  624:             }
  625:             if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {
  626:                 error_code = PG_ERROR_RSVD_MASK;
  627:                 goto do_fault;
  628:             }
  629:             if (!(pml4e & PG_ACCESSED_MASK)) {
  630:                 pml4e |= PG_ACCESSED_MASK;
  631:                 stl_phys_notdirty(pml4e_addr, pml4e);
  632:             }
  633:             ptep = pml4e ^ PG_NX_MASK;
  634:             pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &
  635:                 env->a20_mask;
  636:             pdpe = ldq_phys(pdpe_addr);
  637:             if (!(pdpe & PG_PRESENT_MASK)) {
  638:                 error_code = 0;
  639:                 goto do_fault;
  640:             }
  641:             if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {
  642:                 error_code = PG_ERROR_RSVD_MASK;
  643:                 goto do_fault;
  644:             }
  645:             ptep &= pdpe ^ PG_NX_MASK;
  646:             if (!(pdpe & PG_ACCESSED_MASK)) {
  647:                 pdpe |= PG_ACCESSED_MASK;
  648:                 stl_phys_notdirty(pdpe_addr, pdpe);
  649:             }
  650:         } else
  651: #endif
  652:         {
  653:             /* XXX: load them when cr3 is loaded ? */
  654:             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
  655:                 env->a20_mask;
  656:             pdpe = ldq_phys(pdpe_addr);
  657:             if (!(pdpe & PG_PRESENT_MASK)) {
  658:                 error_code = 0;
  659:                 goto do_fault;
  660:             }
  661:             ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
  662:         }
  663: 
  664:         pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &
  665:             env->a20_mask;
  666:         pde = ldq_phys(pde_addr);
  667:         if (!(pde & PG_PRESENT_MASK)) {
  668:             error_code = 0;
  669:             goto do_fault;
  670:         }
  671:         if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {
  672:             error_code = PG_ERROR_RSVD_MASK;
  673:             goto do_fault;
  674:         }
  675:         ptep &= pde ^ PG_NX_MASK;
  676:         if (pde & PG_PSE_MASK) {
  677:             /* 2 MB page */
  678:             page_size = 2048 * 1024;
  679:             ptep ^= PG_NX_MASK;
  680:             if ((ptep & PG_NX_MASK) && is_write1 == 2)
  681:                 goto do_fault_protect;
  682:             if (is_user) {
  683:                 if (!(ptep & PG_USER_MASK))
  684:                     goto do_fault_protect;
  685:                 if (is_write && !(ptep & PG_RW_MASK))
  686:                     goto do_fault_protect;
  687:             } else {
  688:                 if ((env->cr[0] & CR0_WP_MASK) &&
  689:                     is_write && !(ptep & PG_RW_MASK))
  690:                     goto do_fault_protect;
  691:             }
  692:             is_dirty = is_write && !(pde & PG_DIRTY_MASK);
  693:             if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
  694:                 pde |= PG_ACCESSED_MASK;
  695:                 if (is_dirty)
  696:                     pde |= PG_DIRTY_MASK;
  697:                 stl_phys_notdirty(pde_addr, pde);
  698:             }
  699:             /* align to page_size */
  700:             pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);
  701:             virt_addr = addr & ~(page_size - 1);
  702:         } else {
  703:             /* 4 KB page */
  704:             if (!(pde & PG_ACCESSED_MASK)) {
  705:                 pde |= PG_ACCESSED_MASK;
  706:                 stl_phys_notdirty(pde_addr, pde);
  707:             }
  708:             pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &
  709:                 env->a20_mask;
  710:             pte = ldq_phys(pte_addr);
  711:             if (!(pte & PG_PRESENT_MASK)) {
  712:                 error_code = 0;
  713:                 goto do_fault;
  714:             }
  715:             if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {
  716:                 error_code = PG_ERROR_RSVD_MASK;
  717:                 goto do_fault;
  718:             }
  719:             /* combine pde and pte nx, user and rw protections */
  720:             ptep &= pte ^ PG_NX_MASK;
  721:             ptep ^= PG_NX_MASK;
  722:             if ((ptep & PG_NX_MASK) && is_write1 == 2)
  723:                 goto do_fault_protect;
  724:             if (is_user) {
  725:                 if (!(ptep & PG_USER_MASK))
  726:                     goto do_fault_protect;
  727:                 if (is_write && !(ptep & PG_RW_MASK))
  728:                     goto do_fault_protect;
  729:             } else {
  730:                 if ((env->cr[0] & CR0_WP_MASK) &&
  731:                     is_write && !(ptep & PG_RW_MASK))
  732:                     goto do_fault_protect;
  733:             }
  734:             is_dirty = is_write && !(pte & PG_DIRTY_MASK);
  735:             if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
  736:                 pte |= PG_ACCESSED_MASK;
  737:                 if (is_dirty)
  738:                     pte |= PG_DIRTY_MASK;
  739:                 stl_phys_notdirty(pte_addr, pte);
  740:             }
  741:             page_size = 4096;
  742:             virt_addr = addr & ~0xfff;
  743:             pte = pte & (PHYS_ADDR_MASK | 0xfff);
  744:         }
  745:     } else {
  746:         uint32_t pde;
  747: 
  748:         /* page directory entry */
  749:         pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &
  750:             env->a20_mask;
  751:         pde = ldl_phys(pde_addr);
  752:         if (!(pde & PG_PRESENT_MASK)) {
  753:             error_code = 0;
  754:             goto do_fault;
  755:         }
  756:         /* if PSE bit is set, then we use a 4MB page */
  757:         if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
  758:             page_size = 4096 * 1024;
  759:             if (is_user) {
  760:                 if (!(pde & PG_USER_MASK))
  761:                     goto do_fault_protect;
  762:                 if (is_write && !(pde & PG_RW_MASK))
  763:                     goto do_fault_protect;
  764:             } else {
  765:                 if ((env->cr[0] & CR0_WP_MASK) &&
  766:                     is_write && !(pde & PG_RW_MASK))
  767:                     goto do_fault_protect;
  768:             }
  769:             is_dirty = is_write && !(pde & PG_DIRTY_MASK);
  770:             if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
  771:                 pde |= PG_ACCESSED_MASK;
  772:                 if (is_dirty)
  773:                     pde |= PG_DIRTY_MASK;
  774:                 stl_phys_notdirty(pde_addr, pde);
  775:             }
  776: 
  777:             pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
  778:             ptep = pte;
  779:             virt_addr = addr & ~(page_size - 1);
  780:         } else {
  781:             if (!(pde & PG_ACCESSED_MASK)) {
  782:                 pde |= PG_ACCESSED_MASK;
  783:                 stl_phys_notdirty(pde_addr, pde);
  784:             }
  785: 
  786:             /* page directory entry */
  787:             pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &
  788:                 env->a20_mask;
  789:             pte = ldl_phys(pte_addr);
  790:             if (!(pte & PG_PRESENT_MASK)) {
  791:                 error_code = 0;
  792:                 goto do_fault;
  793:             }
  794:             /* combine pde and pte user and rw protections */
  795:             ptep = pte & pde;
  796:             if (is_user) {
  797:                 if (!(ptep & PG_USER_MASK))
  798:                     goto do_fault_protect;
  799:                 if (is_write && !(ptep & PG_RW_MASK))
  800:                     goto do_fault_protect;
  801:             } else {
  802:                 if ((env->cr[0] & CR0_WP_MASK) &&
  803:                     is_write && !(ptep & PG_RW_MASK))
  804:                     goto do_fault_protect;
  805:             }
  806:             is_dirty = is_write && !(pte & PG_DIRTY_MASK);
  807:             if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
  808:                 pte |= PG_ACCESSED_MASK;
  809:                 if (is_dirty)
  810:                     pte |= PG_DIRTY_MASK;
  811:                 stl_phys_notdirty(pte_addr, pte);
  812:             }
  813:             page_size = 4096;
  814:             virt_addr = addr & ~0xfff;
  815:         }
  816:     }
  817:     /* the page can be put in the TLB */
  818:     prot = PAGE_READ;
  819:     if (!(ptep & PG_NX_MASK))
  820:         prot |= PAGE_EXEC;
  821:     if (pte & PG_DIRTY_MASK) {
  822:         /* only set write access if already dirty... otherwise wait
  823:            for dirty access */
  824:         if (is_user) {
  825:             if (ptep & PG_RW_MASK)
  826:                 prot |= PAGE_WRITE;
  827:         } else {
  828:             if (!(env->cr[0] & CR0_WP_MASK) ||
  829:                 (ptep & PG_RW_MASK))
  830:                 prot |= PAGE_WRITE;
  831:         }
  832:     }
  833:  do_mapping:
  834:     pte = pte & env->a20_mask;
  835: 
  836:     /* Even if 4MB pages, we map only one 4KB page in the cache to
  837:        avoid filling it too fast */
  838:     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
  839:     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
  840:     vaddr = virt_addr + page_offset;
  841: 
  842:     tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
  843:     return 0;
  844:  do_fault_protect:
  845:     error_code = PG_ERROR_P_MASK;
  846:  do_fault:
  847:     error_code |= (is_write << PG_ERROR_W_BIT);
  848:     if (is_user)
  849:         error_code |= PG_ERROR_U_MASK;
  850:     if (is_write1 == 2 &&
  851:         (env->efer & MSR_EFER_NXE) &&
  852:         (env->cr[4] & CR4_PAE_MASK))
  853:         error_code |= PG_ERROR_I_D_MASK;
  854:     if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {
  855:         /* cr2 is not modified in case of exceptions */
  856:         stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 
  857:                  addr);
  858:     } else {
  859:         env->cr[2] = addr;
  860:     }
  861:     env->error_code = error_code;
  862:     env->exception_index = EXCP0E_PAGE;
  863:     return 1;
  864: }
  865: 
  866: target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
  867: {
  868:     target_ulong pde_addr, pte_addr;
  869:     uint64_t pte;
  870:     target_phys_addr_t paddr;
  871:     uint32_t page_offset;
  872:     int page_size;
  873: 
  874:     if (env->cr[4] & CR4_PAE_MASK) {
  875:         target_ulong pdpe_addr;
  876:         uint64_t pde, pdpe;
  877: 
  878: #ifdef TARGET_X86_64
  879:         if (env->hflags & HF_LMA_MASK) {
  880:             uint64_t pml4e_addr, pml4e;
  881:             int32_t sext;
  882: 
  883:             /* test virtual address sign extension */
  884:             sext = (int64_t)addr >> 47;
  885:             if (sext != 0 && sext != -1)
  886:                 return -1;
  887: 
  888:             pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &
  889:                 env->a20_mask;
  890:             pml4e = ldq_phys(pml4e_addr);
  891:             if (!(pml4e & PG_PRESENT_MASK))
  892:                 return -1;
  893: 
  894:             pdpe_addr = ((pml4e & ~0xfff) + (((addr >> 30) & 0x1ff) << 3)) &
  895:                 env->a20_mask;
  896:             pdpe = ldq_phys(pdpe_addr);
  897:             if (!(pdpe & PG_PRESENT_MASK))
  898:                 return -1;
  899:         } else
  900: #endif
  901:         {
  902:             pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &
  903:                 env->a20_mask;
  904:             pdpe = ldq_phys(pdpe_addr);
  905:             if (!(pdpe & PG_PRESENT_MASK))
  906:                 return -1;
  907:         }
  908: 
  909:         pde_addr = ((pdpe & ~0xfff) + (((addr >> 21) & 0x1ff) << 3)) &
  910:             env->a20_mask;
  911:         pde = ldq_phys(pde_addr);
  912:         if (!(pde & PG_PRESENT_MASK)) {
  913:             return -1;
  914:         }
  915:         if (pde & PG_PSE_MASK) {
  916:             /* 2 MB page */
  917:             page_size = 2048 * 1024;
  918:             pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */
  919:         } else {
  920:             /* 4 KB page */
  921:             pte_addr = ((pde & ~0xfff) + (((addr >> 12) & 0x1ff) << 3)) &
  922:                 env->a20_mask;
  923:             page_size = 4096;
  924:             pte = ldq_phys(pte_addr);
  925:         }
  926:         if (!(pte & PG_PRESENT_MASK))
  927:             return -1;
  928:     } else {
  929:         uint32_t pde;
  930: 
  931:         if (!(env->cr[0] & CR0_PG_MASK)) {
  932:             pte = addr;
  933:             page_size = 4096;
  934:         } else {
  935:             /* page directory entry */
  936:             pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask;
  937:             pde = ldl_phys(pde_addr);
  938:             if (!(pde & PG_PRESENT_MASK))
  939:                 return -1;
  940:             if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
  941:                 pte = pde & ~0x003ff000; /* align to 4MB */
  942:                 page_size = 4096 * 1024;
  943:             } else {
  944:                 /* page directory entry */
  945:                 pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask;
  946:                 pte = ldl_phys(pte_addr);
  947:                 if (!(pte & PG_PRESENT_MASK))
  948:                     return -1;
  949:                 page_size = 4096;
  950:             }
  951:         }
  952:         pte = pte & env->a20_mask;
  953:     }
  954: 
  955:     page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);
  956:     paddr = (pte & TARGET_PAGE_MASK) + page_offset;
  957:     return paddr;
  958: }
  959: 
  960: void hw_breakpoint_insert(CPUState *env, int index)
  961: {
  962:     int type, err = 0;
  963: 
  964:     switch (hw_breakpoint_type(env->dr[7], index)) {
  965:     case 0:
  966:         if (hw_breakpoint_enabled(env->dr[7], index))
  967:             err = cpu_breakpoint_insert(env, env->dr[index], BP_CPU,
  968:                                         &env->cpu_breakpoint[index]);
  969:         break;
  970:     case 1:
  971:         type = BP_CPU | BP_MEM_WRITE;
  972:         goto insert_wp;
  973:     case 2:
  974:          /* No support for I/O watchpoints yet */
  975:         break;
  976:     case 3:
  977:         type = BP_CPU | BP_MEM_ACCESS;
  978:     insert_wp:
  979:         err = cpu_watchpoint_insert(env, env->dr[index],
  980:                                     hw_breakpoint_len(env->dr[7], index),
  981:                                     type, &env->cpu_watchpoint[index]);
  982:         break;
  983:     }
  984:     if (err)
  985:         env->cpu_breakpoint[index] = NULL;
  986: }
  987: 
  988: void hw_breakpoint_remove(CPUState *env, int index)
  989: {
  990:     if (!env->cpu_breakpoint[index])
  991:         return;
  992:     switch (hw_breakpoint_type(env->dr[7], index)) {
  993:     case 0:
  994:         if (hw_breakpoint_enabled(env->dr[7], index))
  995:             cpu_breakpoint_remove_by_ref(env, env->cpu_breakpoint[index]);
  996:         break;
  997:     case 1:
  998:     case 3:
  999:         cpu_watchpoint_remove_by_ref(env, env->cpu_watchpoint[index]);
 1000:         break;
 1001:     case 2:
 1002:         /* No support for I/O watchpoints yet */
 1003:         break;
 1004:     }
 1005: }
 1006: 
 1007: int check_hw_breakpoints(CPUState *env, int force_dr6_update)
 1008: {
 1009:     target_ulong dr6;
 1010:     int reg, type;
 1011:     int hit_enabled = 0;
 1012: 
 1013:     dr6 = env->dr[6] & ~0xf;
 1014:     for (reg = 0; reg < 4; reg++) {
 1015:         type = hw_breakpoint_type(env->dr[7], reg);
 1016:         if ((type == 0 && env->dr[reg] == env->eip) ||
 1017:             ((type & 1) && env->cpu_watchpoint[reg] &&
 1018:              (env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT))) {
 1019:             dr6 |= 1 << reg;
 1020:             if (hw_breakpoint_enabled(env->dr[7], reg))
 1021:                 hit_enabled = 1;
 1022:         }
 1023:     }
 1024:     if (hit_enabled || force_dr6_update)
 1025:         env->dr[6] = dr6;
 1026:     return hit_enabled;
 1027: }
 1028: 
 1029: static CPUDebugExcpHandler *prev_debug_excp_handler;
 1030: 
 1031: static void breakpoint_handler(CPUState *env)
 1032: {
 1033:     CPUBreakpoint *bp;
 1034: 
 1035:     if (env->watchpoint_hit) {
 1036:         if (env->watchpoint_hit->flags & BP_CPU) {
 1037:             env->watchpoint_hit = NULL;
 1038:             if (check_hw_breakpoints(env, 0))
 1039:                 raise_exception_env(EXCP01_DB, env);
 1040:             else
 1041:                 cpu_resume_from_signal(env, NULL);
 1042:         }
 1043:     } else {
 1044:         QTAILQ_FOREACH(bp, &env->breakpoints, entry)
 1045:             if (bp->pc == env->eip) {
 1046:                 if (bp->flags & BP_CPU) {
 1047:                     check_hw_breakpoints(env, 1);
 1048:                     raise_exception_env(EXCP01_DB, env);
 1049:                 }
 1050:                 break;
 1051:             }
 1052:     }
 1053:     if (prev_debug_excp_handler)
 1054:         prev_debug_excp_handler(env);
 1055: }
 1056: 
 1057: typedef struct MCEInjectionParams {
 1058:     Monitor *mon;
 1059:     CPUState *env;
 1060:     int bank;
 1061:     uint64_t status;
 1062:     uint64_t mcg_status;
 1063:     uint64_t addr;
 1064:     uint64_t misc;
 1065:     int flags;
 1066: } MCEInjectionParams;
 1067: 
 1068: static void do_inject_x86_mce(void *data)
 1069: {
 1070:     MCEInjectionParams *params = data;
 1071:     CPUState *cenv = params->env;
 1072:     uint64_t *banks = cenv->mce_banks + 4 * params->bank;
 1073: 
 1074:     cpu_synchronize_state(cenv);
 1075: 
 1076:     /*
 1077:      * If there is an MCE exception being processed, ignore this SRAO MCE
 1078:      * unless unconditional injection was requested.
 1079:      */
 1080:     if (!(params->flags & MCE_INJECT_UNCOND_AO)
 1081:         && !(params->status & MCI_STATUS_AR)
 1082:         && (cenv->mcg_status & MCG_STATUS_MCIP)) {
 1083:         return;
 1084:     }
 1085: 
 1086:     if (params->status & MCI_STATUS_UC) {
 1087:         /*
 1088:          * if MSR_MCG_CTL is not all 1s, the uncorrected error
 1089:          * reporting is disabled
 1090:          */
 1091:         if ((cenv->mcg_cap & MCG_CTL_P) && cenv->mcg_ctl != ~(uint64_t)0) {
 1092:             monitor_printf(params->mon,
 1093:                            "CPU %d: Uncorrected error reporting disabled\n",
 1094:                            cenv->cpu_index);
 1095:             return;
 1096:         }
 1097: 
 1098:         /*
 1099:          * if MSR_MCi_CTL is not all 1s, the uncorrected error
 1100:          * reporting is disabled for the bank
 1101:          */
 1102:         if (banks[0] != ~(uint64_t)0) {
 1103:             monitor_printf(params->mon,
 1104:                            "CPU %d: Uncorrected error reporting disabled for"
 1105:                            " bank %d\n",
 1106:                            cenv->cpu_index, params->bank);
 1107:             return;
 1108:         }
 1109: 
 1110:         if ((cenv->mcg_status & MCG_STATUS_MCIP) ||
 1111:             !(cenv->cr[4] & CR4_MCE_MASK)) {
 1112:             monitor_printf(params->mon,
 1113:                            "CPU %d: Previous MCE still in progress, raising"
 1114:                            " triple fault\n",
 1115:                            cenv->cpu_index);
 1116:             qemu_log_mask(CPU_LOG_RESET, "Triple fault\n");
 1117:             qemu_system_reset_request();
 1118:             return;
 1119:         }
 1120:         if (banks[1] & MCI_STATUS_VAL) {
 1121:             params->status |= MCI_STATUS_OVER;
 1122:         }
 1123:         banks[2] = params->addr;
 1124:         banks[3] = params->misc;
 1125:         cenv->mcg_status = params->mcg_status;
 1126:         banks[1] = params->status;
 1127:         cpu_interrupt(cenv, CPU_INTERRUPT_MCE);
 1128:     } else if (!(banks[1] & MCI_STATUS_VAL)
 1129:                || !(banks[1] & MCI_STATUS_UC)) {
 1130:         if (banks[1] & MCI_STATUS_VAL) {
 1131:             params->status |= MCI_STATUS_OVER;
 1132:         }
 1133:         banks[2] = params->addr;
 1134:         banks[3] = params->misc;
 1135:         banks[1] = params->status;
 1136:     } else {
 1137:         banks[1] |= MCI_STATUS_OVER;
 1138:     }
 1139: }
 1140: 
 1141: void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank,
 1142:                         uint64_t status, uint64_t mcg_status, uint64_t addr,
 1143:                         uint64_t misc, int flags)
 1144: {
 1145:     MCEInjectionParams params = {
 1146:         .mon = mon,
 1147:         .env = cenv,
 1148:         .bank = bank,
 1149:         .status = status,
 1150:         .mcg_status = mcg_status,
 1151:         .addr = addr,
 1152:         .misc = misc,
 1153:         .flags = flags,
 1154:     };
 1155:     unsigned bank_num = cenv->mcg_cap & 0xff;
 1156:     CPUState *env;
 1157: 
 1158:     if (!cenv->mcg_cap) {
 1159:         monitor_printf(mon, "MCE injection not supported\n");
 1160:         return;
 1161:     }
 1162:     if (bank >= bank_num) {
 1163:         monitor_printf(mon, "Invalid MCE bank number\n");
 1164:         return;
 1165:     }
 1166:     if (!(status & MCI_STATUS_VAL)) {
 1167:         monitor_printf(mon, "Invalid MCE status code\n");
 1168:         return;
 1169:     }
 1170:     if ((flags & MCE_INJECT_BROADCAST)
 1171:         && !cpu_x86_support_mca_broadcast(cenv)) {
 1172:         monitor_printf(mon, "Guest CPU does not support MCA broadcast\n");
 1173:         return;
 1174:     }
 1175: 
 1176:     run_on_cpu(cenv, do_inject_x86_mce, &params);
 1177:     if (flags & MCE_INJECT_BROADCAST) {
 1178:         params.bank = 1;
 1179:         params.status = MCI_STATUS_VAL | MCI_STATUS_UC;
 1180:         params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
 1181:         params.addr = 0;
 1182:         params.misc = 0;
 1183:         for (env = first_cpu; env != NULL; env = env->next_cpu) {
 1184:             if (cenv == env) {
 1185:                 continue;
 1186:             }
 1187:             params.env = env;
 1188:             run_on_cpu(cenv, do_inject_x86_mce, &params);
 1189:         }
 1190:     }
 1191: }
 1192: #endif /* !CONFIG_USER_ONLY */
 1193: 
 1194: static void mce_init(CPUX86State *cenv)
 1195: {
 1196:     unsigned int bank;
 1197: 
 1198:     if (((cenv->cpuid_version >> 8) & 0xf) >= 6
 1199:         && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
 1200:             (CPUID_MCE | CPUID_MCA)) {
 1201:         cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
 1202:         cenv->mcg_ctl = ~(uint64_t)0;
 1203:         for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
 1204:             cenv->mce_banks[bank * 4] = ~(uint64_t)0;
 1205:         }
 1206:     }
 1207: }
 1208: 
 1209: int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
 1210:                             target_ulong *base, unsigned int *limit,
 1211:                             unsigned int *flags)
 1212: {
 1213:     SegmentCache *dt;
 1214:     target_ulong ptr;
 1215:     uint32_t e1, e2;
 1216:     int index;
 1217: 
 1218:     if (selector & 0x4)
 1219:         dt = &env->ldt;
 1220:     else
 1221:         dt = &env->gdt;
 1222:     index = selector & ~7;
 1223:     ptr = dt->base + index;
 1224:     if ((index + 7) > dt->limit
 1225:         || cpu_memory_rw_debug(env, ptr, (uint8_t *)&e1, sizeof(e1), 0) != 0
 1226:         || cpu_memory_rw_debug(env, ptr+4, (uint8_t *)&e2, sizeof(e2), 0) != 0)
 1227:         return 0;
 1228: 
 1229:     *base = ((e1 >> 16) | ((e2 & 0xff) << 16) | (e2 & 0xff000000));
 1230:     *limit = (e1 & 0xffff) | (e2 & 0x000f0000);
 1231:     if (e2 & DESC_G_MASK)
 1232:         *limit = (*limit << 12) | 0xfff;
 1233:     *flags = e2;
 1234: 
 1235:     return 1;
 1236: }
 1237: 
 1238: CPUX86State *cpu_x86_init(const char *cpu_model)
 1239: {
 1240:     CPUX86State *env;
 1241:     static int inited;
 1242: 
 1243:     env = g_malloc0(sizeof(CPUX86State));
 1244:     cpu_exec_init(env);
 1245:     env->cpu_model_str = cpu_model;
 1246: 
 1247:     /* init various static tables used in TCG mode */
 1248:     if (tcg_enabled() && !inited) {
 1249:         inited = 1;
 1250:         optimize_flags_init();
 1251: #ifndef CONFIG_USER_ONLY
 1252:         prev_debug_excp_handler =
 1253:             cpu_set_debug_excp_handler(breakpoint_handler);
 1254: #endif
 1255:     }
 1256:     if (cpu_x86_register(env, cpu_model) < 0) {
 1257:         cpu_x86_close(env);
 1258:         return NULL;
 1259:     }
 1260:     env->cpuid_apic_id = env->cpu_index;
 1261:     mce_init(env);
 1262: 
 1263:     qemu_init_vcpu(env);
 1264: 
 1265:     return env;
 1266: }
 1267: 
 1268: #if !defined(CONFIG_USER_ONLY)
 1269: void do_cpu_init(CPUState *env)
 1270: {
 1271:     int sipi = env->interrupt_request & CPU_INTERRUPT_SIPI;
 1272:     uint64_t pat = env->pat;
 1273: 
 1274:     cpu_reset(env);
 1275:     env->interrupt_request = sipi;
 1276:     env->pat = pat;
 1277:     apic_init_reset(env->apic_state);
 1278:     env->halted = !cpu_is_bsp(env);
 1279: }
 1280: 
 1281: void do_cpu_sipi(CPUState *env)
 1282: {
 1283:     apic_sipi(env->apic_state);
 1284: }
 1285: #else
 1286: void do_cpu_init(CPUState *env)
 1287: {
 1288: }
 1289: void do_cpu_sipi(CPUState *env)
 1290: {
 1291: }
 1292: #endif

unix.superglobalmegacorp.com