1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include "qemu/osdep.h"
21#include "qemu/main-loop.h"
22#include "cpu.h"
23#include "exec/helper-proto.h"
24#include "exec/exec-all.h"
25#include "exec/cpu_ldst.h"
26#include "exec/address-spaces.h"
27#include "helper-tcg.h"
28
29
30
31
32
33void cpu_load_eflags(CPUX86State *env, int eflags, int update_mask)
34{
35 CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
36 CC_OP = CC_OP_EFLAGS;
37 env->df = 1 - (2 * ((eflags >> 10) & 1));
38 env->eflags = (env->eflags & ~update_mask) |
39 (eflags & update_mask) | 0x2;
40}
41
42void helper_outb(CPUX86State *env, uint32_t port, uint32_t data)
43{
44#ifdef CONFIG_USER_ONLY
45 fprintf(stderr, "outb: port=0x%04x, data=%02x\n", port, data);
46#else
47 address_space_stb(&address_space_io, port, data,
48 cpu_get_mem_attrs(env), NULL);
49#endif
50}
51
52target_ulong helper_inb(CPUX86State *env, uint32_t port)
53{
54#ifdef CONFIG_USER_ONLY
55 fprintf(stderr, "inb: port=0x%04x\n", port);
56 return 0;
57#else
58 return address_space_ldub(&address_space_io, port,
59 cpu_get_mem_attrs(env), NULL);
60#endif
61}
62
63void helper_outw(CPUX86State *env, uint32_t port, uint32_t data)
64{
65#ifdef CONFIG_USER_ONLY
66 fprintf(stderr, "outw: port=0x%04x, data=%04x\n", port, data);
67#else
68 address_space_stw(&address_space_io, port, data,
69 cpu_get_mem_attrs(env), NULL);
70#endif
71}
72
73target_ulong helper_inw(CPUX86State *env, uint32_t port)
74{
75#ifdef CONFIG_USER_ONLY
76 fprintf(stderr, "inw: port=0x%04x\n", port);
77 return 0;
78#else
79 return address_space_lduw(&address_space_io, port,
80 cpu_get_mem_attrs(env), NULL);
81#endif
82}
83
84void helper_outl(CPUX86State *env, uint32_t port, uint32_t data)
85{
86#ifdef CONFIG_USER_ONLY
87 fprintf(stderr, "outl: port=0x%04x, data=%08x\n", port, data);
88#else
89 address_space_stl(&address_space_io, port, data,
90 cpu_get_mem_attrs(env), NULL);
91#endif
92}
93
94target_ulong helper_inl(CPUX86State *env, uint32_t port)
95{
96#ifdef CONFIG_USER_ONLY
97 fprintf(stderr, "inl: port=0x%04x\n", port);
98 return 0;
99#else
100 return address_space_ldl(&address_space_io, port,
101 cpu_get_mem_attrs(env), NULL);
102#endif
103}
104
105void helper_into(CPUX86State *env, int next_eip_addend)
106{
107 int eflags;
108
109 eflags = cpu_cc_compute_all(env, CC_OP);
110 if (eflags & CC_O) {
111 raise_interrupt(env, EXCP04_INTO, 1, 0, next_eip_addend);
112 }
113}
114
115void helper_cpuid(CPUX86State *env)
116{
117 uint32_t eax, ebx, ecx, edx;
118
119 cpu_svm_check_intercept_param(env, SVM_EXIT_CPUID, 0, GETPC());
120
121 cpu_x86_cpuid(env, (uint32_t)env->regs[R_EAX], (uint32_t)env->regs[R_ECX],
122 &eax, &ebx, &ecx, &edx);
123 env->regs[R_EAX] = eax;
124 env->regs[R_EBX] = ebx;
125 env->regs[R_ECX] = ecx;
126 env->regs[R_EDX] = edx;
127}
128
129#if defined(CONFIG_USER_ONLY)
130target_ulong helper_read_crN(CPUX86State *env, int reg)
131{
132 return 0;
133}
134
135void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
136{
137}
138#else
139target_ulong helper_read_crN(CPUX86State *env, int reg)
140{
141 target_ulong val;
142
143 cpu_svm_check_intercept_param(env, SVM_EXIT_READ_CR0 + reg, 0, GETPC());
144 switch (reg) {
145 default:
146 val = env->cr[reg];
147 break;
148 case 8:
149 if (!(env->hflags2 & HF2_VINTR_MASK)) {
150 val = cpu_get_apic_tpr(env_archcpu(env)->apic_state);
151 } else {
152 val = env->v_tpr;
153 }
154 break;
155 }
156 return val;
157}
158
159void helper_write_crN(CPUX86State *env, int reg, target_ulong t0)
160{
161 cpu_svm_check_intercept_param(env, SVM_EXIT_WRITE_CR0 + reg, 0, GETPC());
162 switch (reg) {
163 case 0:
164 cpu_x86_update_cr0(env, t0);
165 break;
166 case 3:
167 cpu_x86_update_cr3(env, t0);
168 break;
169 case 4:
170 if (((t0 ^ env->cr[4]) & CR4_LA57_MASK) &&
171 (env->hflags & HF_CS64_MASK)) {
172 raise_exception_ra(env, EXCP0D_GPF, GETPC());
173 }
174 cpu_x86_update_cr4(env, t0);
175 break;
176 case 8:
177 if (!(env->hflags2 & HF2_VINTR_MASK)) {
178 qemu_mutex_lock_iothread();
179 cpu_set_apic_tpr(env_archcpu(env)->apic_state, t0);
180 qemu_mutex_unlock_iothread();
181 }
182 env->v_tpr = t0 & 0x0f;
183 break;
184 default:
185 env->cr[reg] = t0;
186 break;
187 }
188}
189#endif
190
191void helper_lmsw(CPUX86State *env, target_ulong t0)
192{
193
194
195 t0 = (env->cr[0] & ~0xe) | (t0 & 0xf);
196 helper_write_crN(env, 0, t0);
197}
198
199void helper_invlpg(CPUX86State *env, target_ulong addr)
200{
201 X86CPU *cpu = env_archcpu(env);
202
203 cpu_svm_check_intercept_param(env, SVM_EXIT_INVLPG, 0, GETPC());
204 tlb_flush_page(CPU(cpu), addr);
205}
206
207void helper_rdtsc(CPUX86State *env)
208{
209 uint64_t val;
210
211 if ((env->cr[4] & CR4_TSD_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
212 raise_exception_ra(env, EXCP0D_GPF, GETPC());
213 }
214 cpu_svm_check_intercept_param(env, SVM_EXIT_RDTSC, 0, GETPC());
215
216 val = cpu_get_tsc(env) + env->tsc_offset;
217 env->regs[R_EAX] = (uint32_t)(val);
218 env->regs[R_EDX] = (uint32_t)(val >> 32);
219}
220
221void helper_rdtscp(CPUX86State *env)
222{
223 helper_rdtsc(env);
224 env->regs[R_ECX] = (uint32_t)(env->tsc_aux);
225}
226
227void helper_rdpmc(CPUX86State *env)
228{
229 if (((env->cr[4] & CR4_PCE_MASK) == 0 ) &&
230 ((env->hflags & HF_CPL_MASK) != 0)) {
231 raise_exception_ra(env, EXCP0D_GPF, GETPC());
232 }
233 cpu_svm_check_intercept_param(env, SVM_EXIT_RDPMC, 0, GETPC());
234
235
236 qemu_log_mask(LOG_UNIMP, "x86: unimplemented rdpmc\n");
237 raise_exception_err(env, EXCP06_ILLOP, 0);
238}
239
240#if defined(CONFIG_USER_ONLY)
241void helper_wrmsr(CPUX86State *env)
242{
243}
244
245void helper_rdmsr(CPUX86State *env)
246{
247}
248#else
249void helper_wrmsr(CPUX86State *env)
250{
251 uint64_t val;
252 CPUState *cs = env_cpu(env);
253
254 cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 1, GETPC());
255
256 val = ((uint32_t)env->regs[R_EAX]) |
257 ((uint64_t)((uint32_t)env->regs[R_EDX]) << 32);
258
259 switch ((uint32_t)env->regs[R_ECX]) {
260 case MSR_IA32_SYSENTER_CS:
261 env->sysenter_cs = val & 0xffff;
262 break;
263 case MSR_IA32_SYSENTER_ESP:
264 env->sysenter_esp = val;
265 break;
266 case MSR_IA32_SYSENTER_EIP:
267 env->sysenter_eip = val;
268 break;
269 case MSR_IA32_APICBASE:
270 cpu_set_apic_base(env_archcpu(env)->apic_state, val);
271 break;
272 case MSR_EFER:
273 {
274 uint64_t update_mask;
275
276 update_mask = 0;
277 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_SYSCALL) {
278 update_mask |= MSR_EFER_SCE;
279 }
280 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
281 update_mask |= MSR_EFER_LME;
282 }
283 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
284 update_mask |= MSR_EFER_FFXSR;
285 }
286 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_NX) {
287 update_mask |= MSR_EFER_NXE;
288 }
289 if (env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_SVM) {
290 update_mask |= MSR_EFER_SVME;
291 }
292 if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_FFXSR) {
293 update_mask |= MSR_EFER_FFXSR;
294 }
295 cpu_load_efer(env, (env->efer & ~update_mask) |
296 (val & update_mask));
297 }
298 break;
299 case MSR_STAR:
300 env->star = val;
301 break;
302 case MSR_PAT:
303 env->pat = val;
304 break;
305 case MSR_IA32_PKRS:
306 if (val & 0xFFFFFFFF00000000ull) {
307 goto error;
308 }
309 env->pkrs = val;
310 tlb_flush(cs);
311 break;
312 case MSR_VM_HSAVE_PA:
313 env->vm_hsave = val;
314 break;
315#ifdef TARGET_X86_64
316 case MSR_LSTAR:
317 env->lstar = val;
318 break;
319 case MSR_CSTAR:
320 env->cstar = val;
321 break;
322 case MSR_FMASK:
323 env->fmask = val;
324 break;
325 case MSR_FSBASE:
326 env->segs[R_FS].base = val;
327 break;
328 case MSR_GSBASE:
329 env->segs[R_GS].base = val;
330 break;
331 case MSR_KERNELGSBASE:
332 env->kernelgsbase = val;
333 break;
334#endif
335 case MSR_MTRRphysBase(0):
336 case MSR_MTRRphysBase(1):
337 case MSR_MTRRphysBase(2):
338 case MSR_MTRRphysBase(3):
339 case MSR_MTRRphysBase(4):
340 case MSR_MTRRphysBase(5):
341 case MSR_MTRRphysBase(6):
342 case MSR_MTRRphysBase(7):
343 env->mtrr_var[((uint32_t)env->regs[R_ECX] -
344 MSR_MTRRphysBase(0)) / 2].base = val;
345 break;
346 case MSR_MTRRphysMask(0):
347 case MSR_MTRRphysMask(1):
348 case MSR_MTRRphysMask(2):
349 case MSR_MTRRphysMask(3):
350 case MSR_MTRRphysMask(4):
351 case MSR_MTRRphysMask(5):
352 case MSR_MTRRphysMask(6):
353 case MSR_MTRRphysMask(7):
354 env->mtrr_var[((uint32_t)env->regs[R_ECX] -
355 MSR_MTRRphysMask(0)) / 2].mask = val;
356 break;
357 case MSR_MTRRfix64K_00000:
358 env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
359 MSR_MTRRfix64K_00000] = val;
360 break;
361 case MSR_MTRRfix16K_80000:
362 case MSR_MTRRfix16K_A0000:
363 env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
364 MSR_MTRRfix16K_80000 + 1] = val;
365 break;
366 case MSR_MTRRfix4K_C0000:
367 case MSR_MTRRfix4K_C8000:
368 case MSR_MTRRfix4K_D0000:
369 case MSR_MTRRfix4K_D8000:
370 case MSR_MTRRfix4K_E0000:
371 case MSR_MTRRfix4K_E8000:
372 case MSR_MTRRfix4K_F0000:
373 case MSR_MTRRfix4K_F8000:
374 env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
375 MSR_MTRRfix4K_C0000 + 3] = val;
376 break;
377 case MSR_MTRRdefType:
378 env->mtrr_deftype = val;
379 break;
380 case MSR_MCG_STATUS:
381 env->mcg_status = val;
382 break;
383 case MSR_MCG_CTL:
384 if ((env->mcg_cap & MCG_CTL_P)
385 && (val == 0 || val == ~(uint64_t)0)) {
386 env->mcg_ctl = val;
387 }
388 break;
389 case MSR_TSC_AUX:
390 env->tsc_aux = val;
391 break;
392 case MSR_IA32_MISC_ENABLE:
393 env->msr_ia32_misc_enable = val;
394 break;
395 case MSR_IA32_BNDCFGS:
396
397
398 env->msr_bndcfgs = val;
399 cpu_sync_bndcs_hflags(env);
400 break;
401 default:
402 if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
403 && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
404 (4 * env->mcg_cap & 0xff)) {
405 uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
406 if ((offset & 0x3) != 0
407 || (val == 0 || val == ~(uint64_t)0)) {
408 env->mce_banks[offset] = val;
409 }
410 break;
411 }
412
413 break;
414 }
415 return;
416error:
417 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
418}
419
420void helper_rdmsr(CPUX86State *env)
421{
422 X86CPU *x86_cpu = env_archcpu(env);
423 uint64_t val;
424
425 cpu_svm_check_intercept_param(env, SVM_EXIT_MSR, 0, GETPC());
426
427 switch ((uint32_t)env->regs[R_ECX]) {
428 case MSR_IA32_SYSENTER_CS:
429 val = env->sysenter_cs;
430 break;
431 case MSR_IA32_SYSENTER_ESP:
432 val = env->sysenter_esp;
433 break;
434 case MSR_IA32_SYSENTER_EIP:
435 val = env->sysenter_eip;
436 break;
437 case MSR_IA32_APICBASE:
438 val = cpu_get_apic_base(env_archcpu(env)->apic_state);
439 break;
440 case MSR_EFER:
441 val = env->efer;
442 break;
443 case MSR_STAR:
444 val = env->star;
445 break;
446 case MSR_PAT:
447 val = env->pat;
448 break;
449 case MSR_IA32_PKRS:
450 val = env->pkrs;
451 break;
452 case MSR_VM_HSAVE_PA:
453 val = env->vm_hsave;
454 break;
455 case MSR_IA32_PERF_STATUS:
456
457 val = 1000ULL;
458
459 val |= (((uint64_t)4ULL) << 40);
460 break;
461#ifdef TARGET_X86_64
462 case MSR_LSTAR:
463 val = env->lstar;
464 break;
465 case MSR_CSTAR:
466 val = env->cstar;
467 break;
468 case MSR_FMASK:
469 val = env->fmask;
470 break;
471 case MSR_FSBASE:
472 val = env->segs[R_FS].base;
473 break;
474 case MSR_GSBASE:
475 val = env->segs[R_GS].base;
476 break;
477 case MSR_KERNELGSBASE:
478 val = env->kernelgsbase;
479 break;
480 case MSR_TSC_AUX:
481 val = env->tsc_aux;
482 break;
483#endif
484 case MSR_SMI_COUNT:
485 val = env->msr_smi_count;
486 break;
487 case MSR_MTRRphysBase(0):
488 case MSR_MTRRphysBase(1):
489 case MSR_MTRRphysBase(2):
490 case MSR_MTRRphysBase(3):
491 case MSR_MTRRphysBase(4):
492 case MSR_MTRRphysBase(5):
493 case MSR_MTRRphysBase(6):
494 case MSR_MTRRphysBase(7):
495 val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
496 MSR_MTRRphysBase(0)) / 2].base;
497 break;
498 case MSR_MTRRphysMask(0):
499 case MSR_MTRRphysMask(1):
500 case MSR_MTRRphysMask(2):
501 case MSR_MTRRphysMask(3):
502 case MSR_MTRRphysMask(4):
503 case MSR_MTRRphysMask(5):
504 case MSR_MTRRphysMask(6):
505 case MSR_MTRRphysMask(7):
506 val = env->mtrr_var[((uint32_t)env->regs[R_ECX] -
507 MSR_MTRRphysMask(0)) / 2].mask;
508 break;
509 case MSR_MTRRfix64K_00000:
510 val = env->mtrr_fixed[0];
511 break;
512 case MSR_MTRRfix16K_80000:
513 case MSR_MTRRfix16K_A0000:
514 val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
515 MSR_MTRRfix16K_80000 + 1];
516 break;
517 case MSR_MTRRfix4K_C0000:
518 case MSR_MTRRfix4K_C8000:
519 case MSR_MTRRfix4K_D0000:
520 case MSR_MTRRfix4K_D8000:
521 case MSR_MTRRfix4K_E0000:
522 case MSR_MTRRfix4K_E8000:
523 case MSR_MTRRfix4K_F0000:
524 case MSR_MTRRfix4K_F8000:
525 val = env->mtrr_fixed[(uint32_t)env->regs[R_ECX] -
526 MSR_MTRRfix4K_C0000 + 3];
527 break;
528 case MSR_MTRRdefType:
529 val = env->mtrr_deftype;
530 break;
531 case MSR_MTRRcap:
532 if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
533 val = MSR_MTRRcap_VCNT | MSR_MTRRcap_FIXRANGE_SUPPORT |
534 MSR_MTRRcap_WC_SUPPORTED;
535 } else {
536
537 val = 0;
538 }
539 break;
540 case MSR_MCG_CAP:
541 val = env->mcg_cap;
542 break;
543 case MSR_MCG_CTL:
544 if (env->mcg_cap & MCG_CTL_P) {
545 val = env->mcg_ctl;
546 } else {
547 val = 0;
548 }
549 break;
550 case MSR_MCG_STATUS:
551 val = env->mcg_status;
552 break;
553 case MSR_IA32_MISC_ENABLE:
554 val = env->msr_ia32_misc_enable;
555 break;
556 case MSR_IA32_BNDCFGS:
557 val = env->msr_bndcfgs;
558 break;
559 case MSR_IA32_UCODE_REV:
560 val = x86_cpu->ucode_rev;
561 break;
562 default:
563 if ((uint32_t)env->regs[R_ECX] >= MSR_MC0_CTL
564 && (uint32_t)env->regs[R_ECX] < MSR_MC0_CTL +
565 (4 * env->mcg_cap & 0xff)) {
566 uint32_t offset = (uint32_t)env->regs[R_ECX] - MSR_MC0_CTL;
567 val = env->mce_banks[offset];
568 break;
569 }
570
571 val = 0;
572 break;
573 }
574 env->regs[R_EAX] = (uint32_t)(val);
575 env->regs[R_EDX] = (uint32_t)(val >> 32);
576}
577#endif
578
579static void do_pause(X86CPU *cpu)
580{
581 CPUState *cs = CPU(cpu);
582
583
584 cs->exception_index = EXCP_INTERRUPT;
585 cpu_loop_exit(cs);
586}
587
588static void do_hlt(X86CPU *cpu)
589{
590 CPUState *cs = CPU(cpu);
591 CPUX86State *env = &cpu->env;
592
593 env->hflags &= ~HF_INHIBIT_IRQ_MASK;
594 cs->halted = 1;
595 cs->exception_index = EXCP_HLT;
596 cpu_loop_exit(cs);
597}
598
599void helper_hlt(CPUX86State *env, int next_eip_addend)
600{
601 X86CPU *cpu = env_archcpu(env);
602
603 cpu_svm_check_intercept_param(env, SVM_EXIT_HLT, 0, GETPC());
604 env->eip += next_eip_addend;
605
606 do_hlt(cpu);
607}
608
609void helper_monitor(CPUX86State *env, target_ulong ptr)
610{
611 if ((uint32_t)env->regs[R_ECX] != 0) {
612 raise_exception_ra(env, EXCP0D_GPF, GETPC());
613 }
614
615 cpu_svm_check_intercept_param(env, SVM_EXIT_MONITOR, 0, GETPC());
616}
617
618void helper_mwait(CPUX86State *env, int next_eip_addend)
619{
620 CPUState *cs = env_cpu(env);
621 X86CPU *cpu = env_archcpu(env);
622
623 if ((uint32_t)env->regs[R_ECX] != 0) {
624 raise_exception_ra(env, EXCP0D_GPF, GETPC());
625 }
626 cpu_svm_check_intercept_param(env, SVM_EXIT_MWAIT, 0, GETPC());
627 env->eip += next_eip_addend;
628
629
630 if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
631 do_pause(cpu);
632 } else {
633 do_hlt(cpu);
634 }
635}
636
637void helper_pause(CPUX86State *env, int next_eip_addend)
638{
639 X86CPU *cpu = env_archcpu(env);
640
641 cpu_svm_check_intercept_param(env, SVM_EXIT_PAUSE, 0, GETPC());
642 env->eip += next_eip_addend;
643
644 do_pause(cpu);
645}
646
647void helper_debug(CPUX86State *env)
648{
649 CPUState *cs = env_cpu(env);
650
651 cs->exception_index = EXCP_DEBUG;
652 cpu_loop_exit(cs);
653}
654
655uint64_t helper_rdpkru(CPUX86State *env, uint32_t ecx)
656{
657 if ((env->cr[4] & CR4_PKE_MASK) == 0) {
658 raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC());
659 }
660 if (ecx != 0) {
661 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
662 }
663
664 return env->pkru;
665}
666
667void helper_wrpkru(CPUX86State *env, uint32_t ecx, uint64_t val)
668{
669 CPUState *cs = env_cpu(env);
670
671 if ((env->cr[4] & CR4_PKE_MASK) == 0) {
672 raise_exception_err_ra(env, EXCP06_ILLOP, 0, GETPC());
673 }
674 if (ecx != 0 || (val & 0xFFFFFFFF00000000ull)) {
675 raise_exception_err_ra(env, EXCP0D_GPF, 0, GETPC());
676 }
677
678 env->pkru = val;
679 tlb_flush(cs);
680}
681