#define MSR_FSBASE 0xc0000100
#define MSR_GSBASE 0xc0000101
#define MSR_KERNELGSBASE 0xc0000102
+#define MSR_TSC_AUX 0xc0000103
#define MSR_VM_HSAVE_PA 0xc0010117
uint64 mcg_status;
uint64 mcg_ctl;
uint64 *mce_banks;
+
+ uint64_t tsc_aux;
} CPUX86State;
CPUX86State *cpu_x86_init(const char *cpu_model);
#define cpu_signal_handler cpu_x86_signal_handler
#define cpu_list x86_cpu_list
-#define CPU_SAVE_VERSION 10
+#define CPU_SAVE_VERSION 11
/* MMU modes definitions */
#define MMU_MODE0_SUFFIX _kernel
DEF_HELPER_0(single_step, void)
DEF_HELPER_0(cpuid, void)
DEF_HELPER_0(rdtsc, void)
+DEF_HELPER_0(rdtscp, void)
DEF_HELPER_0(rdpmc, void)
DEF_HELPER_0(rdmsr, void)
DEF_HELPER_0(wrmsr, void)
EDX = (uint32_t)(val >> 32);
}
+void helper_rdtscp(void)
+{
+ helper_rdtsc();
+ ECX = (uint32_t)(env->tsc_aux);
+}
+
void helper_rdpmc(void)
{
if ((env->cr[4] & CR4_PCE_MASK) && ((env->hflags & HF_CPL_MASK) != 0)) {
&& (val == 0 || val == ~(uint64_t)0))
env->mcg_ctl = val;
break;
+ case MSR_TSC_AUX:
+ env->tsc_aux = val;
+ break;
default:
if ((uint32_t)ECX >= MSR_MC0_CTL
&& (uint32_t)ECX < MSR_MC0_CTL + (4 * env->mcg_cap & 0xff)) {
case MSR_KERNELGSBASE:
val = env->kernelgsbase;
break;
+ case MSR_TSC_AUX:
+ val = env->tsc_aux;
+ break;
#endif
case MSR_MTRRphysBase(0):
case MSR_MTRRphysBase(1):
gen_eob(s);
}
break;
- case 7: /* invlpg */
- if (s->cpl != 0) {
- gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+ case 7:
+ if (mod != 3) { /* invlpg */
+ if (s->cpl != 0) {
+ gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+ } else {
+ if (s->cc_op != CC_OP_DYNAMIC)
+ gen_op_set_cc_op(s->cc_op);
+ gen_jmp_im(pc_start - s->cs_base);
+ gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
+ gen_helper_invlpg(cpu_A0);
+ gen_jmp_im(s->pc - s->cs_base);
+ gen_eob(s);
+ }
} else {
- if (mod == 3) {
+ switch (rm) {
+ case 0: /* swapgs */
#ifdef TARGET_X86_64
- if (CODE64(s) && rm == 0) {
- /* swapgs */
- tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
- tcg_gen_ld_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,kernelgsbase));
- tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUX86State,segs[R_GS].base));
- tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,kernelgsbase));
+ if (CODE64(s)) {
+ if (s->cpl != 0) {
+ gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
+ } else {
+ tcg_gen_ld_tl(cpu_T[0], cpu_env,
+ offsetof(CPUX86State,segs[R_GS].base));
+ tcg_gen_ld_tl(cpu_T[1], cpu_env,
+ offsetof(CPUX86State,kernelgsbase));
+ tcg_gen_st_tl(cpu_T[1], cpu_env,
+ offsetof(CPUX86State,segs[R_GS].base));
+ tcg_gen_st_tl(cpu_T[0], cpu_env,
+ offsetof(CPUX86State,kernelgsbase));
+ }
} else
#endif
{
goto illegal_op;
}
- } else {
+ break;
+ case 1: /* rdtscp */
+ if (!(s->cpuid_ext2_features & CPUID_EXT2_RDTSCP))
+ goto illegal_op;
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_jmp_im(pc_start - s->cs_base);
- gen_lea_modrm(s, modrm, ®_addr, &offset_addr);
- gen_helper_invlpg(cpu_A0);
- gen_jmp_im(s->pc - s->cs_base);
- gen_eob(s);
+ if (use_icount)
+ gen_io_start();
+ gen_helper_rdtscp();
+ if (use_icount) {
+ gen_io_end();
+ gen_jmp(s, s->pc - s->cs_base);
+ }
+ break;
+ default:
+ goto illegal_op;
}
}
break;