]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Cachegrind/Callgrind: Fix cache parameter detection
authorJosef Weidendorfer <Josef.Weidendorfer@gmx.de>
Thu, 23 Nov 2006 13:04:30 +0000 (13:04 +0000)
committerJosef Weidendorfer <Josef.Weidendorfer@gmx.de>
Thu, 23 Nov 2006 13:04:30 +0000 (13:04 +0000)
On Intel processors, CPUIDs cache parameter code 0x49 is
reused both for L2 and L3 parameters.
Thanks to Ulrich Drepper.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6369

cachegrind/cg-amd64.c
cachegrind/cg-x86.c

index f714bbafc4890b77560763274b55496259355726..3e3e3e49a328986ba873d68a0a5e83a8a584f7fb 100644 (file)
@@ -52,11 +52,16 @@ static void micro_ops_warn(Int actual_size, Int used_size, Int line_size)
 
 /* Intel method is truly wretched.  We have to do an insane indexing into an
  * array of pre-defined configurations for various parts of the memory
- * hierarchy. 
+ * hierarchy.
+ * According to Intel Processor Identification, App Note 485.
  */
 static
 Int Intel_cache_info(Int level, cache_t* I1c, cache_t* D1c, cache_t* L2c)
 {
+   Int cpuid1_eax;
+   Int cpuid1_ignore;
+   Int family;
+   Int model;
    UChar info[16];
    Int   i, trials;
    Bool  L2_found = False;
@@ -68,6 +73,12 @@ Int Intel_cache_info(Int level, cache_t* I1c, cache_t* D1c, cache_t* L2c)
       return -1;
    }
 
+   /* family/model needed to distinguish code reuse (currently 0x49) */
+   VG_(cpuid)(1, &cpuid1_eax, &cpuid1_ignore,
+             &cpuid1_ignore, &cpuid1_ignore);
+   family = (((cpuid1_eax >> 20) & 0xff) << 4) + ((cpuid1_eax >> 8) & 0xf);
+   model =  (((cpuid1_eax >> 16) & 0xf) << 4) + ((cpuid1_eax >> 4) & 0xf);
+
    VG_(cpuid)(2, (Int*)&info[0], (Int*)&info[4], 
                  (Int*)&info[8], (Int*)&info[12]);
    trials  = info[0] - 1;   /* AL register - bits 0..7 of %eax */
@@ -110,7 +121,7 @@ Int Intel_cache_info(Int level, cache_t* I1c, cache_t* D1c, cache_t* L2c)
 
       case 0x22: case 0x23: case 0x25: case 0x29: case 0x46: case 0x47:
           VG_(message)(Vg_DebugMsg, 
-             "warning: L3 cache detected but ignored\n");
+             "warning: L3 cache detected but ignored");
           break;
 
       /* These are sectored, whatever that means */
@@ -129,7 +140,14 @@ Int Intel_cache_info(Int level, cache_t* I1c, cache_t* D1c, cache_t* L2c)
       case 0x43: *L2c = (cache_t) {  512, 4, 32 }; L2_found = True; break;
       case 0x44: *L2c = (cache_t) { 1024, 4, 32 }; L2_found = True; break;
       case 0x45: *L2c = (cache_t) { 2048, 4, 32 }; L2_found = True; break;
-      case 0x49: *L2c = (cache_t) { 4096,16, 64 }; L2_found = True; break;
+      case 0x49:
+         if ((family == 15) && (model == 6))
+             /* On Xeon MP (family F, model 6), this is for L3 */
+             VG_(message)(Vg_DebugMsg, 
+                          "warning: L3 cache detected but ignored\n");
+         else
+             *L2c = (cache_t) { 4096, 16, 64 }; L2_found = True;
+         break;
 
       /* These are sectored, whatever that means */
       case 0x60: *D1c = (cache_t) { 16, 8, 64 };  break;      /* sectored */
index 3ddbd64ae80491869947804de62265c5c9ff5d8d..eb17b9925c476cb1cb0e99bfe31b313e76213a2b 100644 (file)
@@ -52,11 +52,16 @@ static void micro_ops_warn(Int actual_size, Int used_size, Int line_size)
 
 /* Intel method is truly wretched.  We have to do an insane indexing into an
  * array of pre-defined configurations for various parts of the memory
- * hierarchy. 
+ * hierarchy.
+ * According to Intel Processor Identification, App Note 485.
  */
 static
 Int Intel_cache_info(Int level, cache_t* I1c, cache_t* D1c, cache_t* L2c)
 {
+   Int cpuid1_eax;
+   Int cpuid1_ignore;
+   Int family;
+   Int model;
    UChar info[16];
    Int   i, trials;
    Bool  L2_found = False;
@@ -68,6 +73,12 @@ Int Intel_cache_info(Int level, cache_t* I1c, cache_t* D1c, cache_t* L2c)
       return -1;
    }
 
+   /* family/model needed to distinguish code reuse (currently 0x49) */
+   VG_(cpuid)(1, &cpuid1_eax, &cpuid1_ignore,
+             &cpuid1_ignore, &cpuid1_ignore);
+   family = (((cpuid1_eax >> 20) & 0xff) << 4) + ((cpuid1_eax >> 8) & 0xf);
+   model =  (((cpuid1_eax >> 16) & 0xf) << 4) + ((cpuid1_eax >> 4) & 0xf);
+
    VG_(cpuid)(2, (Int*)&info[0], (Int*)&info[4], 
                  (Int*)&info[8], (Int*)&info[12]);
    trials  = info[0] - 1;   /* AL register - bits 0..7 of %eax */
@@ -109,7 +120,8 @@ Int Intel_cache_info(Int level, cache_t* I1c, cache_t* D1c, cache_t* L2c)
          VG_(tool_panic)("IA-64 cache detected?!");
 
       case 0x22: case 0x23: case 0x25: case 0x29: case 0x46: case 0x47:
-          VG_(message)(Vg_DebugMsg, "warning: L3 cache detected but ignored");
+          VG_(message)(Vg_DebugMsg,
+             "warning: L3 cache detected but ignored");
           break;
 
       /* These are sectored, whatever that means */
@@ -128,7 +140,14 @@ Int Intel_cache_info(Int level, cache_t* I1c, cache_t* D1c, cache_t* L2c)
       case 0x43: *L2c = (cache_t) {  512, 4, 32 }; L2_found = True; break;
       case 0x44: *L2c = (cache_t) { 1024, 4, 32 }; L2_found = True; break;
       case 0x45: *L2c = (cache_t) { 2048, 4, 32 }; L2_found = True; break;
-      case 0x49: *L2c = (cache_t) { 4096,16, 64 }; L2_found = True; break;
+      case 0x49:
+         if ((family == 15) && (model == 6))
+             /* On Xeon MP (family F, model 6), this is for L3 */
+             VG_(message)(Vg_DebugMsg, 
+                          "warning: L3 cache detected but ignored\n");
+         else
+             *L2c = (cache_t) { 4096, 16, 64 }; L2_found = True;
+         break;
 
       /* These are sectored, whatever that means */
       case 0x60: *D1c = (cache_t) { 16, 8, 64 };  break;      /* sectored */