[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    valgrind/coregrind
From:       Jeremy Fitzhardinge <jeremy () goop ! org>
Date:       2004-01-26 21:11:51
Message-ID: 20040126211151.A4FEF8FEA () office ! kde ! org
[Download RAW message or body]

CVS commit by fitzhardinge: 

Rearrange CPUID again.  Moved most of the helper logic into C, since
the assember was getting fiddly.  It now masks out only the undefined
or unimplemented parts of the feature set bits, so it now passes through
all the non-ISA-related feature bits to clients.

It also leaves the vendor ID string unmolested, so that clients can
extract vendor-specific information like extended brand strings and
cache/TLB configuration info.

It does, however, implement some Valgrind-specific requests at 0xd8000000,
though at present the only functionality is the ValgrindVCPU signature.


  M +61 -44    vg_constants.h   1.17
  M +23 -56    vg_helpers.S   1.30
  M +179 -4    vg_to_ucode.c   1.128


--- valgrind/coregrind/vg_constants.h  #1.16:1.17
@@ -95,50 +95,67 @@
 #define VG_USERREQ__SIGNAL_RETURNS          0x4001
 
-/* CPU features */
-#define VG_X86_FEAT_FPU         (0*32 + 0)
-#define VG_X86_FEAT_VME         (0*32 + 1)
-#define VG_X86_FEAT_DE          (0*32 + 2)
-#define VG_X86_FEAT_PSE         (0*32 + 3)
-#define VG_X86_FEAT_TSC         (0*32 + 4)
-#define VG_X86_FEAT_MSR         (0*32 + 5)
-#define VG_X86_FEAT_PAE         (0*32 + 6)
-#define VG_X86_FEAT_MCE         (0*32 + 7)
-#define VG_X86_FEAT_CX8         (0*32 + 8)
-#define VG_X86_FEAT_APIC        (0*32 + 9)
-#define VG_X86_FEAT_SEP         (0*32 + 11)
-#define VG_X86_FEAT_MTRR        (0*32 + 12)
-#define VG_X86_FEAT_PGE         (0*32 + 13)
-#define VG_X86_FEAT_MCA         (0*32 + 14)
-#define VG_X86_FEAT_CMOV        (0*32 + 15)
-#define VG_X86_FEAT_PAT         (0*32 + 16)
-#define VG_X86_FEAT_PSE36       (0*32 + 17)
-#define VG_X86_FEAT_CLFSH       (0*32 + 19)
-#define VG_X86_FEAT_DS          (0*32 + 21)
-#define VG_X86_FEAT_ACPI        (0*32 + 22)
-#define VG_X86_FEAT_MMX         (0*32 + 23)
-#define VG_X86_FEAT_FXSR        (0*32 + 24)
-#define VG_X86_FEAT_SSE         (0*32 + 25)
-#define VG_X86_FEAT_SSE2        (0*32 + 26)
-#define VG_X86_FEAT_SS          (0*32 + 27)
-#define VG_X86_FEAT_HT          (0*32 + 28)
-#define VG_X86_FEAT_TM          (0*32 + 29)
-#define VG_X86_FEAT_PBE         (0*32 + 31)
+/* 
+   0 - standard feature flags
+   1 - Intel extended flags
+   2 - Valgrind internal flags
+   3 - AMD-specific flags
+ */
+#define VG_N_FEATURE_WORDS      4
 
-#define VG_X86_FEAT_EST         (1*32 + 7)
-#define VG_X86_FEAT_TM2         (1*32 + 8)
-#define VG_X86_FEAT_CNXTID      (1*32 + 10)
+#define VG_X86_FEAT             0
+#define VG_EXT_FEAT             1
+#define VG_INT_FEAT             2
+#define VG_AMD_FEAT             3
+
+/* CPU features (generic) */
+#define VG_X86_FEAT_FPU         (VG_X86_FEAT*32 + 0)
+#define VG_X86_FEAT_VME         (VG_X86_FEAT*32 + 1)
+#define VG_X86_FEAT_DE          (VG_X86_FEAT*32 + 2)
+#define VG_X86_FEAT_PSE         (VG_X86_FEAT*32 + 3)
+#define VG_X86_FEAT_TSC         (VG_X86_FEAT*32 + 4)
+#define VG_X86_FEAT_MSR         (VG_X86_FEAT*32 + 5)
+#define VG_X86_FEAT_PAE         (VG_X86_FEAT*32 + 6)
+#define VG_X86_FEAT_MCE         (VG_X86_FEAT*32 + 7)
+#define VG_X86_FEAT_CX8         (VG_X86_FEAT*32 + 8)
+#define VG_X86_FEAT_APIC        (VG_X86_FEAT*32 + 9)
+#define VG_X86_FEAT_SEP         (VG_X86_FEAT*32 + 11)
+#define VG_X86_FEAT_MTRR        (VG_X86_FEAT*32 + 12)
+#define VG_X86_FEAT_PGE         (VG_X86_FEAT*32 + 13)
+#define VG_X86_FEAT_MCA         (VG_X86_FEAT*32 + 14)
+#define VG_X86_FEAT_CMOV        (VG_X86_FEAT*32 + 15)
+#define VG_X86_FEAT_PAT         (VG_X86_FEAT*32 + 16)
+#define VG_X86_FEAT_PSE36       (VG_X86_FEAT*32 + 17)
+#define VG_X86_FEAT_CLFSH       (VG_X86_FEAT*32 + 19)
+#define VG_X86_FEAT_DS          (VG_X86_FEAT*32 + 21)
+#define VG_X86_FEAT_ACPI        (VG_X86_FEAT*32 + 22)
+#define VG_X86_FEAT_MMX         (VG_X86_FEAT*32 + 23)
+#define VG_X86_FEAT_FXSR        (VG_X86_FEAT*32 + 24)
+#define VG_X86_FEAT_SSE         (VG_X86_FEAT*32 + 25)
+#define VG_X86_FEAT_SSE2        (VG_X86_FEAT*32 + 26)
+#define VG_X86_FEAT_SS          (VG_X86_FEAT*32 + 27)
+#define VG_X86_FEAT_HT          (VG_X86_FEAT*32 + 28)
+#define VG_X86_FEAT_TM          (VG_X86_FEAT*32 + 29)
+#define VG_X86_FEAT_IA64        (VG_X86_FEAT*32 + 30)
+#define VG_X86_FEAT_PBE         (VG_X86_FEAT*32 + 31)
+
+/* Intel extended feature word */
+#define VG_X86_FEAT_SSE3        (VG_EXT_FEAT*32 + 0)
+#define VG_X86_FEAT_MON         (VG_EXT_FEAT*32 + 3)
+#define VG_X86_FEAT_DSCPL       (VG_EXT_FEAT*32 + 4)
+#define VG_X86_FEAT_EST         (VG_EXT_FEAT*32 + 7)
+#define VG_X86_FEAT_TM2         (VG_EXT_FEAT*32 + 8)
+#define VG_X86_FEAT_CNXTID      (VG_EXT_FEAT*32 + 10)
 
 /* Used internally to mark whether CPUID is even implemented */
-#define VG_X86_FEAT_CPUID       (2*32 + 0)
+#define VG_X86_FEAT_CPUID       (VG_INT_FEAT*32 + 0)
 
-/* The set of features we're willing to support for the client */
-#define VG_SUPPORTED_FEATURES                   \
-        ((1 << VG_X86_FEAT_FPU)  |              \
-         (1 << VG_X86_FEAT_TSC)  |              \
-         (1 << VG_X86_FEAT_CMOV) |              \
-         (1 << VG_X86_FEAT_MMX)  |              \
-         (1 << VG_X86_FEAT_FXSR) |              \
-         (1 << VG_X86_FEAT_SSE)  |              \
-         (1 << VG_X86_FEAT_SSE2))
+/* AMD special features */
+#define VG_AMD_FEAT_SYSCALL     (VG_AMD_FEAT*32 + 11)
+#define VG_AMD_FEAT_NXP         (VG_AMD_FEAT*32 + 20)
+#define VG_AMD_FEAT_MMXEXT      (VG_AMD_FEAT*32 + 22)
+#define VG_AMD_FEAT_FFXSR       (VG_AMD_FEAT*32 + 25)
+#define VG_AMD_FEAT_LONGMODE    (VG_AMD_FEAT*32 + 29)
+#define VG_AMD_FEAT_3DNOWEXT    (VG_AMD_FEAT*32 + 30)
+#define VG_AMD_FEAT_3DNOW       (VG_AMD_FEAT*32 + 31)
  
 /* Various environment variables we pay attention to */

--- valgrind/coregrind/vg_helpers.S  #1.29:1.30
@@ -191,74 +191,41 @@
         RA   <- %esp
 
-   For simulating the cpuid instruction, we will
-   issue a "real" cpuid instruction and then mask out
-   the bits of the features we do not support currently (3dnow mostly).
-   We also claim to not support most CPUID operations.
-        
-   Dirk Mueller <mueller@kde.org>
-
-   http://www.sandpile.org/ia32/cpuid.htm
-
-   references: 
-
-   pre-MMX pentium:
-
-   <werner> cpuid words (0): 0x1 0x756e6547 0x6c65746e 0x49656e69
-   <werner> cpuid words (1): 0x52b 0x0 0x0 0x1bf
+   We save registers and package up the args so we can call a C helper
+   for all this.
 */
 .global VG_(helper_CPUID)
 VG_(helper_CPUID):
+        pushl   %ebp
+        movl    %esp,%ebp
         pushl   %eax
         pushl   %ebx
         pushl   %ecx
         pushl   %edx
-        movl    32(%esp), %eax
+        pushl   %esi
+        pushl   %edi
+        pushf
+        
+        lea     2*4(%ebp),%eax  /* &edx */
+        pushl   %eax
+        addl    $4,%eax         /* &ecx */
+        pushl   %eax
+        addl    $4,%eax         /* &ebx */
+        pushl   %eax
+        addl    $4,%eax         /* &eax */
+        pushl   %eax
+        pushl   (%eax)          /* eax */
 
-        /* eax==0 - max valid request+processor vendor */
-        cmpl    $0, %eax
-        jne     1f
-
-        movl    $1, %eax        /* only support request 1 */
-        movl    valgrind_brand+0, %ebx
-        movl    valgrind_brand+4, %edx
-        movl    valgrind_brand+8, %ecx
-        jmp     99f
-
-        /* eax==1 - CPU features and model ID */
-1:      cmpl    $1, %eax
-        jne     2f
-
-        cpuid   /* get host CPU's capabilities */
-
-        movl    $0111, %eax
-        movl    $0, %ebx                        /* clear APIC id, CLFLUSH size, Brand ID */
-        movl    $0, %ecx                        /* clear extended feature bits */
-        andl    $VG_SUPPORTED_FEATURES, %edx    /* mask off feature bits we don't support */
-        jmp     99f
-
-        /* eax=0x80000000 - extended cpuid functions */
-2:      cmpl    $0x80000000, %eax
-        jne     99f
-
-        /* leave eax==0x80000000 - we don't support any other extended operations */
-        movl    valgrind_brand+0, %ebx  /* AMD load the brand string again - */
-        movl    valgrind_brand+4, %edx  /* Intel leaves them "reserved" */
-        movl    valgrind_brand+8, %ecx
-        
-        
-99:     movl    %edx, 20(%esp)
-        movl    %ecx, 24(%esp)
-        movl    %ebx, 28(%esp)
-        movl    %eax, 32(%esp)
+        call    VG_(helperc_CPUID)
+        addl    $20,%esp
 
+        popf
+        popl    %edi
+        popl    %esi
         popl    %edx
         popl    %ecx
         popl    %ebx
         popl    %eax
+        popl    %ebp
         ret
-.data
-valgrind_brand:
-        .ascii "ValgrindVCPU"
-.text
 
 /* Fetch the FPU status register.

--- valgrind/coregrind/vg_to_ucode.c  #1.127:1.128
@@ -51,5 +51,17 @@
 /*------------------------------------------------------------*/
 
-#define VG_N_FEATURE_WORDS      3
+#define VG_CPU_VENDOR_GENERIC   0
+#define VG_CPU_VENDOR_INTEL     1
+#define VG_CPU_VENDOR_AMD       2
+
+static Int cpu_vendor = VG_CPU_VENDOR_GENERIC;
+
+static const struct cpu_vendor {
+        const Char *vendorstr;
+        Int         vendorid;
+} cpu_vendors[] = {
+        { "GenuineIntel", VG_CPU_VENDOR_INTEL },
+        { "AuthenticAMD", VG_CPU_VENDOR_AMD },
+};
 
 static Int cpuid_level = -2;    /* -2 -> not initialized */
@@ -109,4 +121,7 @@ static inline void cpuid(UInt eax, 
 static void get_cpu_features(void)
 {
+   Char vendorstr[13];
+   Int i;
+
    if (!has_cpuid()) {
       cpuid_level = -1;
@@ -114,10 +129,27 @@ static void get_cpu_features(void)
    }
 
-   cpu_features[2] |= (1 << (VG_X86_FEAT_CPUID%32));
+   cpu_features[VG_INT_FEAT] |= (1 << (VG_X86_FEAT_CPUID%32));
 
-   cpuid_level = cpuid_eax(0);
+   cpuid(0, &cpuid_level, (UInt *)&vendorstr[0], (UInt *)&vendorstr[8], (UInt *)&vendorstr[4]);
+   vendorstr[12] = '\0';
+
+   for(i = 0; i < sizeof(cpu_vendors)/sizeof(*cpu_vendors); i++)
+      if (VG_(memcmp)(vendorstr, cpu_vendors[i].vendorstr, 12) == 0) {
+         cpu_vendor = cpu_vendors[i].vendorid;
+         break;
+      }
 
    if (cpuid_level >= 1)
-      cpuid(1, NULL, NULL, &cpu_features[1], &cpu_features[0]);
+      cpuid(1, NULL, NULL, &cpu_features[VG_EXT_FEAT], &cpu_features[VG_X86_FEAT]);
+
+   switch(cpu_vendor) {
+   case VG_CPU_VENDOR_AMD:
+      /* get AMD-specific flags */
+      cpuid(0x80000001, NULL, NULL, NULL, &cpu_features[VG_AMD_FEAT]);
+      break;
+
+   default:
+      break;
+   }
 }
 
@@ -135,4 +167,147 @@ Bool VG_(cpu_has_feature)(UInt feature)
 }
 
+/* The set of features we're willing to support for the client
+   
+   This includes supported instruction set extensions, plus any
+   extensions which don't have any user-mode visible effect (but the
+   client may find interesting).
+ */
+#define VG_X86_SUPPORTED_FEATURES               \
+         ((1 << VG_X86_FEAT_FPU)        |       \
+          (1 << VG_X86_FEAT_VME)        |       \
+          (1 << VG_X86_FEAT_DE)         |       \
+          (1 << VG_X86_FEAT_PSE)        |       \
+          (1 << VG_X86_FEAT_TSC)        |       \
+          (0 << VG_X86_FEAT_MSR)        |       \
+          (1 << VG_X86_FEAT_PAE)        |       \
+          (1 << VG_X86_FEAT_MCE)        |       \
+          (1 << VG_X86_FEAT_CX8)        |       \
+          (1 << VG_X86_FEAT_APIC)       |       \
+          (0 << VG_X86_FEAT_SEP)        |       \
+          (1 << VG_X86_FEAT_MTRR)       |       \
+          (1 << VG_X86_FEAT_PGE)        |       \
+          (1 << VG_X86_FEAT_MCA)        |       \
+          (1 << VG_X86_FEAT_CMOV)       |       \
+          (1 << VG_X86_FEAT_PAT)        |       \
+          (1 << VG_X86_FEAT_PSE36)      |       \
+          (0 << VG_X86_FEAT_CLFSH)      |       \
+          (1 << VG_X86_FEAT_DS)         |       \
+          (1 << VG_X86_FEAT_ACPI)       |       \
+          (1 << VG_X86_FEAT_MMX)        |       \
+          (1 << VG_X86_FEAT_FXSR)       |       \
+          (1 << VG_X86_FEAT_SSE)        |       \
+          (1 << VG_X86_FEAT_SSE2)       |       \
+          (1 << VG_X86_FEAT_SS)         |       \
+          (1 << VG_X86_FEAT_HT)         |       \
+          (1 << VG_X86_FEAT_TM)         |       \
+          (0 << VG_X86_FEAT_IA64)       |       \
+          (1 << VG_X86_FEAT_PBE))
+
+#define VG_AMD_SUPPORTED_FEATURES                                       \
+        ((0 << (VG_AMD_FEAT_SYSCALL % 32))      |                       \
+         (0 << (VG_AMD_FEAT_NXP % 32))          |                       \
+         (1 << (VG_AMD_FEAT_MMXEXT % 32))       |                       \
+         (0 << (VG_AMD_FEAT_FFXSR % 32))        |                       \
+         (0 << (VG_AMD_FEAT_LONGMODE % 32))     |                       \
+         (0 << (VG_AMD_FEAT_3DNOWEXT % 32))     |                       \
+         (0 << (VG_AMD_FEAT_3DNOW % 32))        |                       \
+         /* Common bits between standard features and AMD features */   \
+         (1 << VG_X86_FEAT_FPU)         |                               \
+         (1 << VG_X86_FEAT_VME)         |                               \
+         (1 << VG_X86_FEAT_DE)          |                               \
+         (1 << VG_X86_FEAT_PSE)         |                               \
+         (1 << VG_X86_FEAT_TSC)         |                               \
+         (0 << VG_X86_FEAT_MSR)         |                               \
+         (1 << VG_X86_FEAT_PAE)         |                               \
+         (1 << VG_X86_FEAT_MCE)         |                               \
+         (1 << VG_X86_FEAT_CX8)         |                               \
+         (1 << VG_X86_FEAT_APIC)        |                               \
+         (1 << VG_X86_FEAT_MTRR)        |                               \
+         (1 << VG_X86_FEAT_PGE)         |                               \
+         (1 << VG_X86_FEAT_MCA)         |                               \
+         (1 << VG_X86_FEAT_CMOV)        |                               \
+         (1 << VG_X86_FEAT_PAT)         |                               \
+         (1 << VG_X86_FEAT_PSE36)       |                               \
+         (1 << VG_X86_FEAT_MMX)         |                               \
+         (1 << VG_X86_FEAT_FXSR))
+
+
+/*      
+   For simulating the cpuid instruction, we will
+   issue a "real" cpuid instruction and then mask out
+   the bits of the features we do not support currently (3dnow mostly).
+   We also claim to not support most CPUID operations.
+        
+   Dirk Mueller <mueller@kde.org>
+
+   http://www.sandpile.org/ia32/cpuid.htm
+
+   references: 
+
+   pre-MMX pentium:
+
+   <werner> cpuid words (0): 0x1 0x756e6547 0x6c65746e 0x49656e69
+   <werner> cpuid words (1): 0x52b 0x0 0x0 0x1bf
+
+   Updated to be more extensible about future vendor extensions and
+   vendor-specific parts of CPUID.
+*/
+void VG_(helperc_CPUID)(UInt op, UInt *eax_ret, UInt *ebx_ret, UInt *ecx_ret, UInt *edx_ret)
+{
+   UInt eax, ebx, ecx, edx;
+
+   if (cpuid_level == -2)
+      get_cpu_features();       /* for cpu_vendor */
+
+   cpuid(op, &eax, &ebx, &ecx, &edx);
+
+   /* Common mangling */
+   switch(op) {
+   case 1:
+      edx &= VG_X86_SUPPORTED_FEATURES;
+      break;
+
+   case 0xd8000000: {
+      /* Implement some private information at 0xd8000000 */
+      static const Char valgrind_vendor[] = "ValgrindVCPU";
+
+      eax = 0xd8000000;         /* max request */
+      ebx = *(UInt *)&valgrind_vendor[0];
+      ecx = *(UInt *)&valgrind_vendor[8];
+      edx = *(UInt *)&valgrind_vendor[4];
+   }
+      break;
+   }
+
+   /* Vendor-specific mangling of the results */
+   switch(cpu_vendor) {
+   case VG_CPU_VENDOR_INTEL:
+      switch(op) {
+      case 1:
+         ecx = 0;               /* mask out all extended features for now */
+         break;
+
+      case 0x80000001:
+         ebx = ecx = edx = 0;
+         break;
+      }
+      break;
+
+   case VG_CPU_VENDOR_AMD:
+      switch(op) {
+      case 0x80000001:
+         edx &= VG_AMD_SUPPORTED_FEATURES;
+         break;
+      }
+      break;
+   }
+
+   *eax_ret = eax;
+   *ebx_ret = ebx;
+   *ecx_ret = ecx;
+   *edx_ret = edx;
+}
+
+
 /*------------------------------------------------------------*/
 /*--- Here so it can be inlined everywhere.                ---*/


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic