mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-09 23:00:07 +00:00
Implement x86 cpuid handling of leaf4 for cache information.
This commit is contained in:
parent
042c49c681
commit
2a11560107
@ -1,3 +1,10 @@
|
||||
2011-03-20 Ulrich Drepper <drepper@gmail.com>
|
||||
|
||||
[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@gmail.com>
|
||||
|
||||
[BZ #12583]
|
||||
|
4
NEWS
4
NEWS
@ -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 @@ Version 2.14
|
||||
|
||||
* 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
|
||||
|
||||
|
@ -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 @@ intel_check_word (int name, unsigned int value, bool *has_level_2,
|
||||
/* 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 @@ handle_amd (int name)
|
||||
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 @@ handle_amd (int name)
|
||||
return (ecx << 6) & 0x3fffc00;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
case _SC_LEVEL2_CACHE_LINESIZE:
|
||||
return (ecx & 0xf000) == 0 ? 0 : ecx & 0xff;
|
||||
default:
|
||||
|
@ -181,6 +181,55 @@ intel_check_word (int name, unsigned int value, bool *has_level_2,
|
||||
/* 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))
|
||||
|
Loading…
Reference in New Issue
Block a user