Implemented CR4 register for Winchip. Currently only Time Stamp Disable (TSD) has an effect.

Fixed stupid bug in WRMSR - MSRs can now be written with values other than zero.
This commit is contained in:
TomW 2014-08-23 16:28:16 +01:00
commit 262b188790
6 changed files with 49 additions and 2 deletions

View file

@ -630,6 +630,7 @@ void resetx86()
pc=0;
msw=0;
cr0=0;
cr4 = 0;
eflags=0;
cgate32=0;
loadcs(0xFFFF);
@ -660,6 +661,7 @@ void softresetx86()
pc=0;
msw=0;
cr0=0;
cr4 = 0;
eflags=0;
cgate32=0;
loadcs(0xFFFF);

View file

@ -20,6 +20,10 @@ int cpu_16bitbus;
int cpu_busspeed;
int cpu_hasrdtsc;
int cpu_hasMMX, cpu_hasMSR;
int cpu_hasCR4;
uint64_t cpu_CR4_mask;
uint64_t tsc = 0;
int timing_rr;
@ -267,6 +271,7 @@ void cpu_set()
cpu_hasrdtsc = 0;
cpu_hasMMX = 0;
cpu_hasMSR = 0;
cpu_hasCR4 = 0;
if (cpu_iscyrix)
io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
@ -413,6 +418,8 @@ void cpu_set()
cpu_hasrdtsc = 1;
msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) | (1 << 16) | (1 << 19) | (1 << 21);
cpu_hasMMX = cpu_hasMSR = 1;
cpu_hasCR4 = 1;
cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
break;
default:
@ -549,7 +556,6 @@ void cpu_WRMSR()
switch (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type)
{
case CPU_WINCHIP:
EAX = EDX = 0;
switch (ECX)
{
case 0x02:

View file

@ -74,6 +74,14 @@ extern int cpu_multi;
extern int cpu_hasrdtsc;
extern int cpu_hasMSR;
extern int cpu_hasMMX;
extern int cpu_hasCR4;
#define CR4_TSD (1 << 2)
#define CR4_DE (1 << 3)
#define CR4_MCE (1 << 6)
#define CR4_PCE (1 << 8)
extern uint64_t cpu_CR4_mask;
extern uint64_t tsc;

View file

@ -154,7 +154,7 @@ union
#define cr0 CR0.l
#define msw CR0.w
uint32_t cr2,cr3;
uint32_t cr2, cr3, cr4;
#define C_FLAG 0x0001
#define P_FLAG 0x0004

View file

@ -19,6 +19,12 @@ static int opMOV_r_CRx_a16(uint32_t fetchdat)
case 3:
regs[rm].l = cr3;
break;
case 4:
if (cpu_hasCR4)
{
regs[rm].l = cr4;
break;
}
default:
pclog("Bad read of CR%i %i\n",rmdat&7,reg);
pc = oldpc;
@ -49,6 +55,12 @@ static int opMOV_r_CRx_a32(uint32_t fetchdat)
case 3:
regs[rm].l = cr3;
break;
case 4:
if (cpu_hasCR4)
{
regs[rm].l = cr4;
break;
}
default:
pclog("Bad read of CR%i %i\n",rmdat&7,reg);
pc = oldpc;
@ -110,6 +122,13 @@ static int opMOV_CRx_r_a16(uint32_t fetchdat)
cr3 = regs[rm].l;
flushmmucache();
break;
case 4:
if (cpu_hasCR4)
{
cr4 = regs[rm].l & cpu_CR4_mask;
break;
}
default:
pclog("Bad load CR%i\n", reg);
pc = oldpc;
@ -143,6 +162,13 @@ static int opMOV_CRx_r_a32(uint32_t fetchdat)
cr3 = regs[rm].l;
flushmmucache();
break;
case 4:
if (cpu_hasCR4)
{
cr4 = regs[rm].l & cpu_CR4_mask;
break;
}
default:
pclog("Bad load CR%i\n", reg);
pc = oldpc;

View file

@ -6,6 +6,11 @@ static int opRDTSC(uint32_t fetchdat)
x86illegal();
return 0;
}
if ((cr4 & CR4_TSD) && CPL)
{
x86gpf("RDTSC when TSD set and CPL != 0", 0);
return 0;
}
EAX = tsc & 0xffffffff;
EDX = tsc >> 32;
cycles--;