PCem

changeset 150:871b132c6158

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.
author TomW
date Sat Aug 23 16:28:16 2014 +0100
parents 82d7f693029b
children 55564c65aa15
files src/808x.c src/cpu.c src/cpu.h src/ibm.h src/x86_ops_mov_ctrl.h src/x86_ops_msr.h
diffstat 6 files changed, 49 insertions(+), 2 deletions(-) [+]
line diff
     1.1 --- a/src/808x.c	Fri Aug 22 19:58:17 2014 +0100
     1.2 +++ b/src/808x.c	Sat Aug 23 16:28:16 2014 +0100
     1.3 @@ -630,6 +630,7 @@
     1.4          pc=0;
     1.5          msw=0;
     1.6          cr0=0;
     1.7 +        cr4 = 0;
     1.8          eflags=0;
     1.9          cgate32=0;
    1.10          loadcs(0xFFFF);
    1.11 @@ -660,6 +661,7 @@
    1.12          pc=0;
    1.13          msw=0;
    1.14          cr0=0;
    1.15 +        cr4 = 0;
    1.16          eflags=0;
    1.17          cgate32=0;
    1.18          loadcs(0xFFFF);
     2.1 --- a/src/cpu.c	Fri Aug 22 19:58:17 2014 +0100
     2.2 +++ b/src/cpu.c	Sat Aug 23 16:28:16 2014 +0100
     2.3 @@ -20,6 +20,10 @@
     2.4  int cpu_busspeed;
     2.5  int cpu_hasrdtsc;
     2.6  int cpu_hasMMX, cpu_hasMSR;
     2.7 +int cpu_hasCR4;
     2.8 +
     2.9 +uint64_t cpu_CR4_mask;
    2.10 +
    2.11  uint64_t tsc = 0;
    2.12  
    2.13  int timing_rr;
    2.14 @@ -267,6 +271,7 @@
    2.15          cpu_hasrdtsc = 0;
    2.16          cpu_hasMMX = 0;
    2.17          cpu_hasMSR = 0;
    2.18 +        cpu_hasCR4 = 0;
    2.19  
    2.20          if (cpu_iscyrix)
    2.21             io_sethandler(0x0022, 0x0002, cyrix_read, NULL, NULL, cyrix_write, NULL, NULL, NULL);
    2.22 @@ -413,6 +418,8 @@
    2.23                  cpu_hasrdtsc = 1;
    2.24                  msr.fcr = (1 << 8) | (1 << 9) | (1 << 12) |  (1 << 16) | (1 << 19) | (1 << 21);
    2.25                  cpu_hasMMX = cpu_hasMSR = 1;
    2.26 +                cpu_hasCR4 = 1;
    2.27 +                cpu_CR4_mask = CR4_TSD | CR4_DE | CR4_MCE | CR4_PCE;
    2.28                  break;
    2.29                  
    2.30                  default:
    2.31 @@ -549,7 +556,6 @@
    2.32          switch (models[model].cpu[cpu_manufacturer].cpus[cpu].cpu_type)
    2.33          {
    2.34                  case CPU_WINCHIP:
    2.35 -                EAX = EDX = 0;
    2.36                  switch (ECX)
    2.37                  {
    2.38                          case 0x02:
     3.1 --- a/src/cpu.h	Fri Aug 22 19:58:17 2014 +0100
     3.2 +++ b/src/cpu.h	Sat Aug 23 16:28:16 2014 +0100
     3.3 @@ -74,6 +74,14 @@
     3.4  extern int cpu_hasrdtsc;
     3.5  extern int cpu_hasMSR;
     3.6  extern int cpu_hasMMX;
     3.7 +extern int cpu_hasCR4;
     3.8 +
     3.9 +#define CR4_TSD  (1 << 2)
    3.10 +#define CR4_DE   (1 << 3)
    3.11 +#define CR4_MCE  (1 << 6)
    3.12 +#define CR4_PCE  (1 << 8)
    3.13 +
    3.14 +extern uint64_t cpu_CR4_mask;
    3.15  
    3.16  extern uint64_t tsc;
    3.17  
     4.1 --- a/src/ibm.h	Fri Aug 22 19:58:17 2014 +0100
     4.2 +++ b/src/ibm.h	Sat Aug 23 16:28:16 2014 +0100
     4.3 @@ -154,7 +154,7 @@
     4.4  #define cr0 CR0.l
     4.5  #define msw CR0.w
     4.6  
     4.7 -uint32_t cr2,cr3;
     4.8 +uint32_t cr2, cr3, cr4;
     4.9  
    4.10  #define C_FLAG  0x0001
    4.11  #define P_FLAG  0x0004
     5.1 --- a/src/x86_ops_mov_ctrl.h	Fri Aug 22 19:58:17 2014 +0100
     5.2 +++ b/src/x86_ops_mov_ctrl.h	Sat Aug 23 16:28:16 2014 +0100
     5.3 @@ -19,6 +19,12 @@
     5.4                  case 3:
     5.5                  regs[rm].l = cr3;
     5.6                  break;
     5.7 +                case 4:
     5.8 +                if (cpu_hasCR4)
     5.9 +                {
    5.10 +                        regs[rm].l = cr4;
    5.11 +                        break;
    5.12 +                }
    5.13                  default:
    5.14                  pclog("Bad read of CR%i %i\n",rmdat&7,reg);
    5.15                  pc = oldpc;
    5.16 @@ -49,6 +55,12 @@
    5.17                  case 3:
    5.18                  regs[rm].l = cr3;
    5.19                  break;
    5.20 +                case 4:
    5.21 +                if (cpu_hasCR4)
    5.22 +                {
    5.23 +                        regs[rm].l = cr4;
    5.24 +                        break;
    5.25 +                }
    5.26                  default:
    5.27                  pclog("Bad read of CR%i %i\n",rmdat&7,reg);
    5.28                  pc = oldpc;
    5.29 @@ -110,6 +122,13 @@
    5.30                  cr3 = regs[rm].l;
    5.31                  flushmmucache();
    5.32                  break;
    5.33 +                case 4:
    5.34 +                if (cpu_hasCR4)
    5.35 +                {
    5.36 +                        cr4 = regs[rm].l & cpu_CR4_mask;
    5.37 +                        break;
    5.38 +                }
    5.39 +
    5.40                  default:
    5.41                  pclog("Bad load CR%i\n", reg);
    5.42                  pc = oldpc;
    5.43 @@ -143,6 +162,13 @@
    5.44                  cr3 = regs[rm].l;
    5.45                  flushmmucache();
    5.46                  break;
    5.47 +                case 4:
    5.48 +                if (cpu_hasCR4)
    5.49 +                {
    5.50 +                        cr4 = regs[rm].l & cpu_CR4_mask;
    5.51 +                        break;
    5.52 +                }
    5.53 +
    5.54                  default:
    5.55                  pclog("Bad load CR%i\n", reg);
    5.56                  pc = oldpc;
     6.1 --- a/src/x86_ops_msr.h	Fri Aug 22 19:58:17 2014 +0100
     6.2 +++ b/src/x86_ops_msr.h	Sat Aug 23 16:28:16 2014 +0100
     6.3 @@ -6,6 +6,11 @@
     6.4                  x86illegal();
     6.5                  return 0;
     6.6          }
     6.7 +        if ((cr4 & CR4_TSD) && CPL)
     6.8 +        {
     6.9 +                x86gpf("RDTSC when TSD set and CPL != 0", 0);
    6.10 +                return 0;
    6.11 +        }
    6.12          EAX = tsc & 0xffffffff;
    6.13          EDX = tsc >> 32;
    6.14          cycles--;