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