1 /* 2 * i386 helpers (without register variable usage) 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "qemu/osdep.h" 21 #include "cpu.h" 22 #include "exec/exec-all.h" 23 #include "sysemu/kvm.h" 24 #include "kvm_i386.h" 25 #ifndef CONFIG_USER_ONLY 26 #include "sysemu/sysemu.h" 27 #include "sysemu/hw_accel.h" 28 #include "monitor/monitor.h" 29 #include "hw/i386/apic_internal.h" 30 #endif 31 32 void 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 62 static 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 */ 75 int 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 91 static 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 157 static void 158 cpu_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 } 210 done: 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 */ 219 static 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 234 static 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 */ 260 static 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 268 static 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 275 static 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 285 static 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 337 static 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 354 void 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 402 void 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 411 void 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 609 void 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 629 void 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 */ 671 void 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 683 void 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) 726 hwaddr 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 840 out: 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 847 typedef 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 857 static 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 931 void 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(¶ms)); 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(¶ms)); 980 } 981 } 982 } 983 984 void 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()) { 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); 995 996 apic_handle_tpr_access_report(cpu->apic_state, env->eip, access); 997 } 998 } 999 #endif /* !CONFIG_USER_ONLY */ 1000 1001 int 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) 1033 void 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 1055 void do_cpu_sipi(X86CPU *cpu) 1056 { 1057 apic_sipi(cpu->apic_state); 1058 } 1059 #else 1060 void do_cpu_init(X86CPU *cpu) 1061 { 1062 } 1063 void do_cpu_sipi(X86CPU *cpu) 1064 { 1065 } 1066 #endif 1067 1068 /* Frob eflags into and out of the CPU temporary format. */ 1069 1070 void 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 1081 void 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 1090 uint8_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 1100 uint32_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 1110 uint32_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 1120 uint64_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 1130 void 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 1140 void 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 1150 void 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 1160 void 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 1170 void 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