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