Implemented RDTSCP instruction
This commit is contained in:
parent
3e310fea90
commit
8be190d848
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.233 2005-08-04 19:38:49 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.234 2005-08-05 12:47:28 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -172,6 +172,7 @@
|
||||
#define MSR_CSTAR (BX_CPU_THIS_PTR msr.cstar)
|
||||
#define MSR_FMASK (BX_CPU_THIS_PTR msr.fmask)
|
||||
#define MSR_KERNELGSBASE (BX_CPU_THIS_PTR msr.kernelgsbase)
|
||||
#define MSR_TSC_AUX (BX_CPU_THIS_PTR msr.tsc_aux)
|
||||
|
||||
#endif
|
||||
|
||||
@ -326,6 +327,7 @@
|
||||
#define BX_MSR_FSBASE 0xc0000100
|
||||
#define BX_MSR_GSBASE 0xc0000101
|
||||
#define BX_MSR_KERNELGSBASE 0xc0000102
|
||||
#define BX_MSR_TSC_AUX 0xc0000103
|
||||
#endif
|
||||
|
||||
#define BX_MODE_IA32_REAL 0x0 // CR0.PE=0 |
|
||||
@ -645,6 +647,8 @@ typedef struct {
|
||||
Bit64u cstar;
|
||||
Bit64u fmask;
|
||||
Bit64u kernelgsbase;
|
||||
|
||||
Bit32u tsc_aux;
|
||||
#endif
|
||||
|
||||
/* TODO finish of the others */
|
||||
@ -2458,6 +2462,7 @@ public: // for now...
|
||||
BX_SMF void LOOP64_Jb(bxInstruction_c *);
|
||||
BX_SMF void JCXZ64_Jb(bxInstruction_c *);
|
||||
|
||||
BX_SMF void RDTSCP(bxInstruction_c *);
|
||||
BX_SMF void CMPXCHG16B(bxInstruction_c *);
|
||||
#endif // #if BX_SUPPORT_X86_64
|
||||
|
||||
|
@ -325,12 +325,16 @@ void BX_CPU_C::CPUID(bxInstruction_c *i)
|
||||
// [21:21] Reserved
|
||||
// [22:22] AMD MMX Extensions
|
||||
// [25:25] Fast FXSAVE/FXRSTOR mode support
|
||||
// [25:28] Reserved
|
||||
// [26:26] Reserved
|
||||
// [27:27] Support RDTSCP Instruction
|
||||
// [28:28] Reserved
|
||||
// [29:29] Long Mode
|
||||
// [30:30] AMD 3DNow! Extensions
|
||||
// [31:31] AMD 3DNow! Instructions
|
||||
features = features & 0x00003F3FF;
|
||||
RDX = features | (1 << 29) | (1 << 25) | (1 << 22) | (1 << 20) | (1 << 11);
|
||||
|
||||
RDX = features | (1 << 29) | (1 << 27) | (1 << 25) |
|
||||
(1 << 22) | (1 << 20) | (1 << 11);
|
||||
RBX = 0;
|
||||
RCX = 0;
|
||||
break;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: fetchdecode.cc,v 1.82 2005-07-31 17:57:25 sshwarts Exp $
|
||||
// $Id: fetchdecode.cc,v 1.83 2005-08-05 12:47:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1218,19 +1218,13 @@ static BxOpcodeInfo_t BxOpcodeInfo[512*2] = {
|
||||
/* 0F 02 */ { BxAnother, &BX_CPU_C::LAR_GvEw },
|
||||
/* 0F 03 */ { BxAnother, &BX_CPU_C::LSL_GvEw },
|
||||
/* 0F 04 */ { 0, &BX_CPU_C::BxError },
|
||||
#if BX_SUPPORT_X86_64
|
||||
/* 0F 05 */ { 0, &BX_CPU_C::SYSCALL },
|
||||
#elif BX_CPU_LEVEL == 2
|
||||
#if BX_CPU_LEVEL == 2
|
||||
/* 0F 05 */ { 0, &BX_CPU_C::LOADALL },
|
||||
#else
|
||||
/* 0F 05 */ { 0, &BX_CPU_C::BxError },
|
||||
/* 0F 05 */ { 0, &BX_CPU_C::BxError }, // SYSCALL is invalid in legacy mode
|
||||
#endif
|
||||
/* 0F 06 */ { 0, &BX_CPU_C::CLTS },
|
||||
#if BX_SUPPORT_X86_64
|
||||
/* 0F 07 */ { 0, &BX_CPU_C::SYSRET },
|
||||
#else
|
||||
/* 0F 07 */ { 0, &BX_CPU_C::BxError },
|
||||
#endif
|
||||
/* 0F 07 */ { 0, &BX_CPU_C::BxError }, // SYSRET is invalid in legacy mode
|
||||
/* 0F 08 */ { 0, &BX_CPU_C::INVD },
|
||||
/* 0F 09 */ { 0, &BX_CPU_C::WBINVD },
|
||||
/* 0F 0A */ { 0, &BX_CPU_C::BxError },
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: paging.cc,v 1.60 2005-06-14 20:55:57 sshwarts Exp $
|
||||
// $Id: paging.cc,v 1.61 2005-08-05 12:47:31 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -582,12 +582,22 @@ void BX_CPU_C::INVLPG(bxInstruction_c* i)
|
||||
// ----------------------------------------------------
|
||||
// MOD <> 11 7 --- | INVLPG | INVLPG
|
||||
// MOD == 11 7 0 | #UD | SWAPGS
|
||||
// MOD == 11 7 1-7 | #UD | #UD
|
||||
// MOD == 11 7 1 | #UD | RDTSCP
|
||||
// MOD == 11 7 2-7 | #UD | #UD
|
||||
|
||||
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
|
||||
if ((i->rm() == 0) && (i->nnn() == 7)) {
|
||||
BX_CPU_THIS_PTR SWAPGS(i);
|
||||
return;
|
||||
if (i->nnn() == 7) {
|
||||
switch(i->rm()) {
|
||||
case 0:
|
||||
BX_CPU_THIS_PTR SWAPGS(i);
|
||||
return;
|
||||
case 1:
|
||||
BX_CPU_THIS_PTR RDTSCP(i);
|
||||
return;
|
||||
default:
|
||||
BX_INFO(("INVLPG: 0F 01 /7 RM=%d opcode is undefined !", i->rm()));
|
||||
UndefinedOpcode(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -604,7 +614,6 @@ void BX_CPU_C::INVLPG(bxInstruction_c* i)
|
||||
// Protected instruction: CPL0 only
|
||||
if (BX_CPU_THIS_PTR cr0.pe) {
|
||||
if (CPL!=0) {
|
||||
BX_INFO(("INVLPG: CPL!=0"));
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
}
|
||||
@ -620,6 +629,7 @@ void BX_CPU_C::INVLPG(bxInstruction_c* i)
|
||||
|
||||
#else
|
||||
// not supported on < 486
|
||||
BX_INFO(("INVLPG: required i486, use --enable-cpu=4 option"));
|
||||
UndefinedOpcode(i);
|
||||
#endif
|
||||
}
|
||||
@ -703,8 +713,8 @@ BX_CPU_C::translate_linear(bx_address laddr, unsigned pl, unsigned rw, unsigned
|
||||
}
|
||||
|
||||
// Get PDP entry
|
||||
pdp_addr = (pml4 & 0xfffff000) |
|
||||
((laddr & BX_CONST64(0x0000007fc0000000)) >> 27);
|
||||
pdp_addr = (pml4 & 0xfffff000) |
|
||||
((laddr & BX_CONST64(0x0000007fc0000000)) >> 27);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@ -1284,7 +1294,6 @@ BX_CPU_C::access_linear(bx_address laddr, unsigned length, unsigned pl,
|
||||
BX_CPU_THIS_PTR address_xlation.len2, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.111 2005-07-31 17:57:27 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.112 2005-08-05 12:47:33 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -1506,17 +1506,25 @@ void BX_CPU_C::RDTSC(bxInstruction_c *i)
|
||||
Bit64u ticks = bx_pc_system.time_ticks ();
|
||||
RAX = (Bit32u) (ticks & 0xffffffff);
|
||||
RDX = (Bit32u) ((ticks >> 32) & 0xffffffff);
|
||||
//BX_INFO(("RDTSC: returning EDX:EAX = %08x:%08x", EDX, EAX));
|
||||
} else {
|
||||
// not allowed to use RDTSC!
|
||||
BX_ERROR(("RDTSC: incorrect usage of RDTSC instruction !"));
|
||||
exception (BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
#else
|
||||
BX_INFO(("RDTSC: Pentium CPU required"));
|
||||
BX_INFO(("RDTSC: Pentium CPU required, use --enable-cpu=5"));
|
||||
UndefinedOpcode(i);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
void BX_CPU_C::RDTSCP(bxInstruction_c *i)
|
||||
{
|
||||
RDTSC(i);
|
||||
RCX = MSR_TSC_AUX;
|
||||
}
|
||||
#endif
|
||||
|
||||
void BX_CPU_C::RDMSR(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_CPU_LEVEL >= 5
|
||||
@ -1524,21 +1532,32 @@ void BX_CPU_C::RDMSR(bxInstruction_c *i)
|
||||
|
||||
if (v8086_mode()) {
|
||||
BX_INFO(("RDMSR: Invalid in virtual 8086 mode"));
|
||||
goto do_exception;
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
if (CPL!= 0) {
|
||||
if (protected_mode() && CPL != 0) {
|
||||
BX_INFO(("RDMSR: CPL != 0"));
|
||||
goto do_exception;
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
/* We have the requested MSR register in ECX */
|
||||
switch(ECX) {
|
||||
|
||||
#if BX_SUPPORT_SEP
|
||||
case BX_MSR_SYSENTER_CS: { EAX = BX_CPU_THIS_PTR sysenter_cs_msr; EDX = 0; return; }
|
||||
case BX_MSR_SYSENTER_ESP: { EAX = BX_CPU_THIS_PTR sysenter_esp_msr; EDX = 0; return; }
|
||||
case BX_MSR_SYSENTER_EIP: { EAX = BX_CPU_THIS_PTR sysenter_eip_msr; EDX = 0; return; }
|
||||
case BX_MSR_SYSENTER_CS:
|
||||
RAX = BX_CPU_THIS_PTR sysenter_cs_msr;
|
||||
RDX = 0;
|
||||
return;
|
||||
|
||||
case BX_MSR_SYSENTER_ESP:
|
||||
RAX = BX_CPU_THIS_PTR sysenter_esp_msr;
|
||||
RDX = 0;
|
||||
return;
|
||||
|
||||
case BX_MSR_SYSENTER_EIP:
|
||||
RAX = BX_CPU_THIS_PTR sysenter_eip_msr;
|
||||
RDX = 0;
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if BX_CPU_LEVEL == 5
|
||||
@ -1565,8 +1584,11 @@ void BX_CPU_C::RDMSR(bxInstruction_c *i)
|
||||
goto do_exception;
|
||||
#endif /* BX_CPU_LEVEL == 5 */
|
||||
|
||||
case BX_MSR_TSC:
|
||||
RDTSC(i);
|
||||
case BX_MSR_TSC: {
|
||||
Bit64u ticks = bx_pc_system.time_ticks ();
|
||||
RAX = (Bit32u) (ticks & 0xffffffff);
|
||||
RDX = (Bit32u) ((ticks >> 32) & 0xffffffff);
|
||||
}
|
||||
return;
|
||||
|
||||
/* MSR_APICBASE
|
||||
@ -1585,47 +1607,54 @@ void BX_CPU_C::RDMSR(bxInstruction_c *i)
|
||||
return;
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
case BX_MSR_EFER:
|
||||
RAX = (BX_CPU_THIS_PTR msr.sce << 0)
|
||||
| (BX_CPU_THIS_PTR msr.lme << 8)
|
||||
| (BX_CPU_THIS_PTR msr.lma << 10);
|
||||
RDX = 0;
|
||||
return;
|
||||
case BX_MSR_EFER:
|
||||
RAX = (BX_CPU_THIS_PTR msr.sce << 0)
|
||||
| (BX_CPU_THIS_PTR msr.lme << 8)
|
||||
| (BX_CPU_THIS_PTR msr.lma << 10)
|
||||
| (BX_CPU_THIS_PTR msr.nxe << 11)
|
||||
| (BX_CPU_THIS_PTR msr.ffxsr << 14);
|
||||
RDX = 0;
|
||||
return;
|
||||
|
||||
case BX_MSR_STAR:
|
||||
RAX = MSR_STAR;
|
||||
RDX = MSR_STAR >> 32;
|
||||
return;
|
||||
case BX_MSR_STAR:
|
||||
RAX = MSR_STAR & 0xffffffff;
|
||||
RDX = MSR_STAR >> 32;
|
||||
return;
|
||||
|
||||
case BX_MSR_LSTAR:
|
||||
RAX = MSR_LSTAR;
|
||||
RDX = MSR_LSTAR >> 32;
|
||||
return;
|
||||
case BX_MSR_LSTAR:
|
||||
RAX = MSR_LSTAR & 0xffffffff;
|
||||
RDX = MSR_LSTAR >> 32;
|
||||
return;
|
||||
|
||||
case BX_MSR_CSTAR:
|
||||
RAX = MSR_CSTAR;
|
||||
RDX = MSR_CSTAR >> 32;
|
||||
return;
|
||||
case BX_MSR_CSTAR:
|
||||
RAX = MSR_CSTAR & 0xffffffff;
|
||||
RDX = MSR_CSTAR >> 32;
|
||||
return;
|
||||
|
||||
case BX_MSR_FMASK:
|
||||
RAX = MSR_FMASK;
|
||||
RDX = MSR_FMASK >> 32;
|
||||
return;
|
||||
case BX_MSR_FMASK:
|
||||
RAX = MSR_FMASK & 0xffffffff;
|
||||
RDX = MSR_FMASK >> 32;
|
||||
return;
|
||||
|
||||
case BX_MSR_FSBASE:
|
||||
RAX = MSR_FSBASE;
|
||||
RDX = MSR_FSBASE >> 32;
|
||||
return;
|
||||
case BX_MSR_FSBASE:
|
||||
RAX = MSR_FSBASE & 0xffffffff;
|
||||
RDX = MSR_FSBASE >> 32;
|
||||
return;
|
||||
|
||||
case BX_MSR_GSBASE:
|
||||
RAX = MSR_GSBASE;
|
||||
RDX = MSR_GSBASE >> 32;
|
||||
return;
|
||||
case BX_MSR_GSBASE:
|
||||
RAX = MSR_GSBASE & 0xffffffff;
|
||||
RDX = MSR_GSBASE >> 32;
|
||||
return;
|
||||
|
||||
case BX_MSR_KERNELGSBASE:
|
||||
RAX = MSR_KERNELGSBASE;
|
||||
RDX = MSR_KERNELGSBASE >> 32;
|
||||
return;
|
||||
case BX_MSR_KERNELGSBASE:
|
||||
RAX = MSR_KERNELGSBASE & 0xffffffff;
|
||||
RDX = MSR_KERNELGSBASE >> 32;
|
||||
return;
|
||||
|
||||
case BX_MSR_TSC_AUX:
|
||||
RAX = MSR_TSC_AUX; // 32 bit MSR
|
||||
RDX = 0;
|
||||
return;
|
||||
#endif // #if BX_SUPPORT_X86_64
|
||||
|
||||
default:
|
||||
@ -1653,12 +1682,12 @@ void BX_CPU_C::WRMSR(bxInstruction_c *i)
|
||||
|
||||
if (v8086_mode()) {
|
||||
BX_INFO(("WRMSR: Invalid in virtual 8086 mode"));
|
||||
goto do_exception;
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
if (CPL!= 0) {
|
||||
if (protected_mode() && CPL != 0) {
|
||||
BX_INFO(("WDMSR: CPL != 0"));
|
||||
goto do_exception;
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
|
||||
BX_INSTR_WRMSR(BX_CPU_ID, ECX, ((Bit64u) EDX << 32) + EAX);
|
||||
@ -1667,13 +1696,20 @@ void BX_CPU_C::WRMSR(bxInstruction_c *i)
|
||||
switch(ECX) {
|
||||
|
||||
#if BX_SUPPORT_SEP
|
||||
case BX_MSR_SYSENTER_CS: {
|
||||
if (EAX & 3) BX_PANIC (("writing sysenter_cs_msr with non-kernel mode selector %X", EAX)); // not a bug according to book
|
||||
BX_CPU_THIS_PTR sysenter_cs_msr = EAX; // ... but very stOOpid
|
||||
case BX_MSR_SYSENTER_CS: {
|
||||
// not a bug according to book ... but very stOOpid
|
||||
if (EAX & 3) BX_PANIC(("writing sysenter_cs_msr with non-kernel mode selector %X", EAX));
|
||||
BX_CPU_THIS_PTR sysenter_cs_msr = EAX;
|
||||
return;
|
||||
}
|
||||
case BX_MSR_SYSENTER_ESP: { BX_CPU_THIS_PTR sysenter_esp_msr = EAX; return; }
|
||||
case BX_MSR_SYSENTER_EIP: { BX_CPU_THIS_PTR sysenter_eip_msr = EAX; return; }
|
||||
|
||||
case BX_MSR_SYSENTER_ESP:
|
||||
BX_CPU_THIS_PTR sysenter_esp_msr = EAX;
|
||||
return;
|
||||
|
||||
case BX_MSR_SYSENTER_EIP:
|
||||
BX_CPU_THIS_PTR sysenter_eip_msr = EAX;
|
||||
return;
|
||||
#endif
|
||||
|
||||
#if BX_CPU_LEVEL == 5
|
||||
@ -1724,38 +1760,51 @@ void BX_CPU_C::WRMSR(bxInstruction_c *i)
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_X86_64
|
||||
case BX_MSR_EFER:
|
||||
// GPF #0 if lme 0->1 and cr0.pg = 1
|
||||
// GPF #0 if lme 1->0 and cr0.pg = 1
|
||||
if ((BX_CPU_THIS_PTR msr.lme != ((EAX >> 8) & 1)) &&
|
||||
(BX_CPU_THIS_PTR cr0.pg == 1))
|
||||
{
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
BX_CPU_THIS_PTR msr.sce = (EAX >> 0) & 1;
|
||||
BX_CPU_THIS_PTR msr.lme = (EAX >> 8) & 1;
|
||||
return;
|
||||
case BX_MSR_STAR:
|
||||
MSR_STAR = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
case BX_MSR_LSTAR:
|
||||
MSR_LSTAR = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
case BX_MSR_CSTAR:
|
||||
MSR_CSTAR = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
case BX_MSR_FMASK:
|
||||
MSR_FMASK = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
case BX_MSR_FSBASE:
|
||||
MSR_FSBASE = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
case BX_MSR_GSBASE:
|
||||
MSR_GSBASE = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
case BX_MSR_KERNELGSBASE:
|
||||
MSR_KERNELGSBASE = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
case BX_MSR_EFER:
|
||||
// GPF #0 if lme 0->1 and cr0.pg = 1
|
||||
// GPF #0 if lme 1->0 and cr0.pg = 1
|
||||
if ((BX_CPU_THIS_PTR msr.lme != ((EAX >> 8) & 1)) &&
|
||||
(BX_CPU_THIS_PTR cr0.pg == 1))
|
||||
{
|
||||
exception(BX_GP_EXCEPTION, 0, 0);
|
||||
}
|
||||
BX_CPU_THIS_PTR msr.sce = (EAX >> 0) & 1;
|
||||
BX_CPU_THIS_PTR msr.lme = (EAX >> 8) & 1;
|
||||
BX_CPU_THIS_PTR msr.nxe = (EAX >> 11) & 1;
|
||||
BX_CPU_THIS_PTR msr.ffxsr = (EAX >> 14) & 1;
|
||||
return;
|
||||
|
||||
case BX_MSR_STAR:
|
||||
MSR_STAR = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
|
||||
case BX_MSR_LSTAR:
|
||||
MSR_LSTAR = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
|
||||
case BX_MSR_CSTAR:
|
||||
MSR_CSTAR = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
|
||||
case BX_MSR_FMASK:
|
||||
MSR_FMASK = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
|
||||
case BX_MSR_FSBASE:
|
||||
MSR_FSBASE = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
|
||||
case BX_MSR_GSBASE:
|
||||
MSR_GSBASE = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
|
||||
case BX_MSR_KERNELGSBASE:
|
||||
MSR_KERNELGSBASE = ((Bit64u) EDX << 32) + EAX;
|
||||
return;
|
||||
|
||||
case BX_MSR_TSC_AUX:
|
||||
MSR_TSC_AUX = EAX;
|
||||
return;
|
||||
#endif // #if BX_SUPPORT_X86_64
|
||||
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user