Implemented generic functions for RDMSR and WRMSR opcodes in Pentium CPU core (i.e. no MSR is actually hooked up so far) [Angelo Salese]

This commit is contained in:
Angelo Salese 2011-12-31 16:19:04 +00:00
parent fa7878b5bb
commit e869f846ad
3 changed files with 55 additions and 6 deletions

View File

@ -3243,7 +3243,7 @@ CPU_GET_INFO( pentium )
case CPUINFO_INT_REGISTER + X87_ST7: info->i = ST(7).f; break;
case DEVINFO_STR_NAME: strcpy(info->s, "PENTIUM"); break;
case DEVINFO_STR_FAMILY: strcpy(info->s, "Intel Pentium"); break;
case DEVINFO_STR_FAMILY: strcpy(info->s, "Intel Pentium"); break;
case CPUINFO_STR_REGISTER + X87_CTRL: sprintf(info->s, "FPU_CW: %04X", cpustate->fpu_control_word); break;
case CPUINFO_STR_REGISTER + X87_STATUS: sprintf(info->s, "FPU_SW: %04X", cpustate->fpu_status_word); break;
case CPUINFO_STR_REGISTER + X87_ST0: sprintf(info->s, "ST0: %f", ST(0).f); break;

View File

@ -989,5 +989,39 @@ INLINE void WRITEPORT32(i386_state *cpustate, offs_t port, UINT32 value)
}
}
/***********************************************************************************
MSR ACCESS
***********************************************************************************/
INLINE UINT64 MSR_READ(i386_state *cpustate, UINT32 offset,UINT8 *valid_msr)
{
UINT64 res;
*valid_msr = 0;
switch(offset)
{
default:
logerror("RDMSR: unimplemented register called %08x at %08x\n",offset,cpustate->pc-2);
res = -1;
*valid_msr = 1;
break;
}
return res;
}
INLINE void MSR_WRITE(i386_state *cpustate, UINT32 offset, UINT64 data, UINT8 *valid_msr)
{
*valid_msr = 0;
switch(offset)
{
default:
logerror("WRMSR: unimplemented register called %08x (%08x%08x) at %08x\n",offset,(UINT32)(data >> 32),(UINT32)data,cpustate->pc-2);
*valid_msr = 1;
break;
}
}
#endif /* __I386_H__ */

View File

@ -2,18 +2,33 @@
static void PENTIUMOP(rdmsr)(i386_state *cpustate) // Opcode 0x0f 32
{
// TODO
logerror("Unemulated RDMSR opcode called\n");
UINT64 data;
UINT8 valid_msr = 0;
data = MSR_READ(cpustate,REG32(ECX),&valid_msr);
REG32(EDX) = data >> 32;
REG32(EAX) = data & 0xffffffff;
if(cpustate->CPL != 0 || valid_msr == 0) // if current privilege level isn't 0 or the register isn't recognized ...
FAULT(FAULT_GP,0) // ... throw a general exception fault
CYCLES(cpustate,CYCLES_RDMSR);
}
static void PENTIUMOP(wrmsr)(i386_state *cpustate) // Opcode 0x0f 30
{
// TODO
logerror("Unemulated WRMSR opcode called\n");
UINT64 data;
UINT8 valid_msr = 0;
CYCLES(cpustate,1); // TODO: correct cycle count
data = (UINT64)REG32(EAX);
data |= (UINT64)(REG32(EDX)) << 32;
MSR_WRITE(cpustate,REG32(ECX),data,&valid_msr);
if(cpustate->CPL != 0 || valid_msr == 0) // if current privilege level isn't 0 or the register isn't recognized
FAULT(FAULT_GP,0) // ... throw a general exception fault
CYCLES(cpustate,1); // TODO: correct cycle count (~30-45)
}
static void PENTIUMOP(rdtsc)(i386_state *cpustate) // Opcode 0x0f 31