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