xref: /openbmc/qemu/target/i386/helper.c (revision a37eaa53)
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(&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 
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() || 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);
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