[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r13208 - in /fsf/trunk/libc: ChangeLog NEWS sysdeps/unix/sysv/linux/i386/sysconf.c sysdeps/x86_64/cacheinfo.c



Author: eglibc
Date: Mon Mar 21 00:03:39 2011
New Revision: 13208

Log:
Import glibc-mainline for 2011-03-21

Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/NEWS
    fsf/trunk/libc/sysdeps/unix/sysv/linux/i386/sysconf.c
    fsf/trunk/libc/sysdeps/x86_64/cacheinfo.c

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Mon Mar 21 00:03:39 2011
@@ -1,3 +1,10 @@
+2011-03-20  Ulrich Drepper  <drepper@xxxxxxxxx>
+
+	[BZ #12587]
+	* sysdeps/unix/sysv/linux/i386/sysconf.c (intel_check_word):
+	Handle cache information in CPU leaf 4.
+	* sysdeps/x86_64/cacheinfo.c (intel_check_word): Likewise.
+
 2011-03-18  Ulrich Drepper  <drepper@xxxxxxxxx>
 
 	[BZ #12583]

Modified: fsf/trunk/libc/NEWS
==============================================================================
--- fsf/trunk/libc/NEWS (original)
+++ fsf/trunk/libc/NEWS Mon Mar 21 00:03:39 2011
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes.  2011-3-18
+GNU C Library NEWS -- history of user-visible changes.  2011-3-20
 Copyright (C) 1992-2009, 2010, 2011 Free Software Foundation, Inc.
 See the end for copying conditions.
 
@@ -9,7 +9,7 @@
 
 * The following bugs are resolved with this release:
 
-  11724, 12445, 12454, 12460, 12469, 12489, 12509, 12510, 12583
+  11724, 12445, 12454, 12460, 12469, 12489, 12509, 12510, 12583, 12587
 
 Version 2.13
 

Modified: fsf/trunk/libc/sysdeps/unix/sysv/linux/i386/sysconf.c
==============================================================================
--- fsf/trunk/libc/sysdeps/unix/sysv/linux/i386/sysconf.c (original)
+++ fsf/trunk/libc/sysdeps/unix/sysv/linux/i386/sysconf.c Mon Mar 21 00:03:39 2011
@@ -1,5 +1,5 @@
 /* Get file-specific information about a file.  Linux version.
-   Copyright (C) 2003, 2004, 2006, 2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2006, 2007, 2009, 2011 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -186,6 +186,55 @@
 	    /* No need to look further.  */
 	    break;
 	}
+      else if (byte == 0xff)
+	{
+	  /* CPUID leaf 0x4 contains all the information.  We need to
+	     iterate over it.  */
+	  unsigned int eax;
+	  unsigned int ebx;
+	  unsigned int ecx;
+	  unsigned int edx;
+
+	  unsigned int round = 0;
+	  while (1)
+	    {
+	      asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+			    : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+			    : "0" (4), "2" (round));
+
+	      enum { null = 0, data = 1, inst = 2, uni = 3 } type = eax & 0x1f;
+	      if (type == null)
+		/* That was the end.  */
+		break;
+
+	      unsigned int level = (eax >> 5) & 0x7;
+
+	      if ((level == 1 && type == data
+		   && folded_rel_name == M(_SC_LEVEL1_DCACHE_SIZE))
+		  || (level == 1 && type == inst
+		      && folded_rel_name == M(_SC_LEVEL1_ICACHE_SIZE))
+		  || (level == 2 && folded_rel_name == M(_SC_LEVEL2_CACHE_SIZE))
+		  || (level == 3 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
+		  || (level == 4 && folded_rel_name == M(_SC_LEVEL4_CACHE_SIZE)))
+		{
+		  unsigned int offset = M(name) - folded_rel_name;
+
+		  if (offset == 0)
+		    /* Cache size.  */
+		    return (((ebx >> 22) + 1)
+			    * (((ebx >> 12) & 0x3ff) + 1)
+			    * ((ebx & 0xfff) + 1)
+			    * (ecx + 1));
+		  if (offset == 1)
+		    return (ebx >> 22) + 1;
+
+		  assert (offset == 2);
+		  return (ebx & 0xfff) + 1;
+		}
+	    }
+	  /* There is no other cache information anywhere else.  */
+	  break;
+	}
       else
 	{
 	  if (byte == 0x49 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
@@ -358,11 +407,11 @@
     case _SC_LEVEL2_CACHE_ASSOC:
       ecx >>= 12;
       switch (ecx & 0xf)
-        {
-        case 0:
-        case 1:
-        case 2:
-        case 4:
+	{
+	case 0:
+	case 1:
+	case 2:
+	case 4:
 	  return ecx & 0xf;
 	case 6:
 	  return 8;
@@ -372,7 +421,7 @@
 	  return (ecx << 6) & 0x3fffc00;
 	default:
 	  return 0;
-        }
+	}
     case _SC_LEVEL2_CACHE_LINESIZE:
       return (ecx & 0xf000) == 0 ? 0 : ecx & 0xff;
     default:

Modified: fsf/trunk/libc/sysdeps/x86_64/cacheinfo.c
==============================================================================
--- fsf/trunk/libc/sysdeps/x86_64/cacheinfo.c (original)
+++ fsf/trunk/libc/sysdeps/x86_64/cacheinfo.c Mon Mar 21 00:03:39 2011
@@ -181,6 +181,55 @@
 	    /* No need to look further.  */
 	    break;
 	}
+      else if (byte == 0xff)
+	{
+	  /* CPUID leaf 0x4 contains all the information.  We need to
+	     iterate over it.  */
+	  unsigned int eax;
+	  unsigned int ebx;
+	  unsigned int ecx;
+	  unsigned int edx;
+
+	  unsigned int round = 0;
+	  while (1)
+	    {
+	      asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
+			    : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
+			    : "0" (4), "2" (round));
+
+	      enum { null = 0, data = 1, inst = 2, uni = 3 } type = eax & 0x1f;
+	      if (type == null)
+		/* That was the end.  */
+		break;
+
+	      unsigned int level = (eax >> 5) & 0x7;
+
+	      if ((level == 1 && type == data
+		   && folded_rel_name == M(_SC_LEVEL1_DCACHE_SIZE))
+		  || (level == 1 && type == inst
+		      && folded_rel_name == M(_SC_LEVEL1_ICACHE_SIZE))
+		  || (level == 2 && folded_rel_name == M(_SC_LEVEL2_CACHE_SIZE))
+		  || (level == 3 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
+		  || (level == 4 && folded_rel_name == M(_SC_LEVEL4_CACHE_SIZE)))
+		{
+		  unsigned int offset = M(name) - folded_rel_name;
+
+		  if (offset == 0)
+		    /* Cache size.  */
+		    return (((ebx >> 22) + 1)
+			    * (((ebx >> 12) & 0x3ff) + 1)
+			    * ((ebx & 0xfff) + 1)
+			    * (ecx + 1));
+		  if (offset == 1)
+		    return (ebx >> 22) + 1;
+
+		  assert (offset == 2);
+		  return (ebx & 0xfff) + 1;
+		}
+	    }
+	  /* There is no other cache information anywhere else.  */
+	  break;
+	}
       else
 	{
 	  if (byte == 0x49 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))