summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2007-08-25 17:07:47 +0000
committerUlrich Drepper <drepper@redhat.com>2007-08-25 17:07:47 +0000
commit80e7d6a6d3c2894c281480f3131966fccdf881b7 (patch)
treedbe37116639e88b51dfa9f7b5a9882f0f9e7f244
parent1ae07d48d411e9d45678ec06d8d905c01b1f3d62 (diff)
* sysdeps/x86_64/cacheinfo.c (handle_amd): Handle L3 cache
requests. Fill on more associativity values for L2. Patch mostly by Evandro Menezes.
-rw-r--r--ChangeLog6
-rw-r--r--sysdeps/x86_64/cacheinfo.c58
2 files changed, 62 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index b87026ccdb..7de59d8f68 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-08-25 Ulrich Drepper <drepper@redhat.com>
+
+ * sysdeps/x86_64/cacheinfo.c (handle_amd): Handle L3 cache
+ requests. Fill on more associativity values for L2.
+ Patch mostly by Evandro Menezes.
+
2007-08-24 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/x86_64/init-first.c
diff --git a/sysdeps/x86_64/cacheinfo.c b/sysdeps/x86_64/cacheinfo.c
index 8855b6d45f..eef7fa8726 100644
--- a/sysdeps/x86_64/cacheinfo.c
+++ b/sysdeps/x86_64/cacheinfo.c
@@ -259,7 +259,8 @@ handle_amd (int name)
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
: "0" (0x80000000));
- if (name >= _SC_LEVEL3_CACHE_SIZE)
+ /* No level 4 cache (yet). */
+ if (name > _SC_LEVEL3_CACHE_LINESIZE)
return 0;
unsigned int fn = 0x80000005 + (name >= _SC_LEVEL2_CACHE_SIZE);
@@ -280,16 +281,20 @@ handle_amd (int name)
{
case _SC_LEVEL1_DCACHE_SIZE:
return (ecx >> 14) & 0x3fc00;
+
case _SC_LEVEL1_DCACHE_ASSOC:
ecx >>= 16;
if ((ecx & 0xff) == 0xff)
/* Fully associative. */
return (ecx << 2) & 0x3fc00;
return ecx & 0xff;
+
case _SC_LEVEL1_DCACHE_LINESIZE:
return ecx & 0xff;
+
case _SC_LEVEL2_CACHE_SIZE:
return (ecx & 0xf000) == 0 ? 0 : (ecx >> 6) & 0x3fffc00;
+
case _SC_LEVEL2_CACHE_ASSOC:
ecx >>= 12;
switch (ecx & 0xf)
@@ -303,13 +308,62 @@ handle_amd (int name)
return 8;
case 8:
return 16;
- case 0xf:
+ case 10:
+ return 32;
+ case 11:
+ return 48;
+ case 12:
+ return 64;
+ case 13:
+ return 96;
+ case 14:
+ return 128;
+ case 15:
return (ecx << 6) & 0x3fffc00;
default:
return 0;
}
+ /* NOTREACHED */
+
case _SC_LEVEL2_CACHE_LINESIZE:
return (ecx & 0xf000) == 0 ? 0 : ecx & 0xff;
+
+ case _SC_LEVEL3_CACHE_SIZE:
+ return (edx & 0xf000) == 0 ? 0 : (edx & 0x3ffc0000) << 1;
+
+ case _SC_LEVEL3_CACHE_ASSOC:
+ edx >>= 12;
+ switch (edx & 0xf)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ return edx & 0xf;
+ case 6:
+ return 8;
+ case 8:
+ return 16;
+ case 10:
+ return 32;
+ case 11:
+ return 48;
+ case 12:
+ return 64;
+ case 13:
+ return 96;
+ case 14:
+ return 128;
+ case 15:
+ return (edx & 0x3ffc0) << 13;
+ default:
+ return 0;
+ }
+ /* NOTREACHED */
+
+ case _SC_LEVEL3_CACHE_LINESIZE:
+ return (edx & 0xf000) == 0 ? 0 : edx & 0xff;
+
default:
assert (! "cannot happen");
}