# HG changeset patch # User TomW # Date 1408807696 -3600 # Node ID 871b132c615843b3b575f67ea4aac1cba3e95278 # Parent 82d7f693029b49b63b4bcafe9b2367fb218f55bf 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. diff -r 82d7f693029b -r 871b132c6158 src/808x.c --- a/src/808x.c Fri Aug 22 19:58:17 2014 +0100 +++ b/src/808x.c Sat Aug 23 16:28:16 2014 +0100 @@ -630,6 +630,7 @@ pc=0; msw=0; cr0=0; + cr4 = 0; eflags=0; cgate32=0; loadcs(0xFFFF); @@ -660,6 +661,7 @@ pc=0; msw=0; cr0=0; + cr4 = 0; eflags=0; cgate32=0; loadcs(0xFFFF); diff -r 82d7f693029b -r 871b132c6158 src/cpu.c --- a/src/cpu.c Fri Aug 22 19:58:17 2014 +0100 +++ b/src/cpu.c Sat Aug 23 16:28:16 2014 +0100 @@ -20,6 +20,10 @@ 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 @@ 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 @@ 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 @@ switch (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type) { case CPU_WINCHIP: - EAX = EDX = 0; switch (ECX) { case 0x02: diff -r 82d7f693029b -r 871b132c6158 src/cpu.h --- a/src/cpu.h Fri Aug 22 19:58:17 2014 +0100 +++ b/src/cpu.h Sat Aug 23 16:28:16 2014 +0100 @@ -74,6 +74,14 @@ 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; diff -r 82d7f693029b -r 871b132c6158 src/ibm.h --- a/src/ibm.h Fri Aug 22 19:58:17 2014 +0100 +++ b/src/ibm.h Sat Aug 23 16:28:16 2014 +0100 @@ -154,7 +154,7 @@ #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 diff -r 82d7f693029b -r 871b132c6158 src/x86_ops_mov_ctrl.h --- a/src/x86_ops_mov_ctrl.h Fri Aug 22 19:58:17 2014 +0100 +++ b/src/x86_ops_mov_ctrl.h Sat Aug 23 16:28:16 2014 +0100 @@ -19,6 +19,12 @@ 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 @@ 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 @@ 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 @@ 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; diff -r 82d7f693029b -r 871b132c6158 src/x86_ops_msr.h --- a/src/x86_ops_msr.h Fri Aug 22 19:58:17 2014 +0100 +++ b/src/x86_ops_msr.h Sat Aug 23 16:28:16 2014 +0100 @@ -6,6 +6,11 @@ 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--;