public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Fwd: [PATCH] Detect L2 cache size for x86
       [not found] <5787cf470803202311k73b77370ie4ee507a96ea102f@mail.gmail.com>
@ 2008-03-21  9:57 ` Uros Bizjak
  2008-03-23  3:44   ` Zuxy Meng
  0 siblings, 1 reply; 9+ messages in thread
From: Uros Bizjak @ 2008-03-21  9:57 UTC (permalink / raw)
  To: GCC Patches; +Cc: Zuxy Meng

Hello!

 >>    The attached patch detects automatically the L2 cache size of a host x86
 >>    CPU, following what has already been done for L1 cache. Two schemes are
 >>    utilized in the detection: AMD CPUs will use CPUID function
0x80000006, and
 >>    Intel CPUs will try both CPUID function 0x2 and 0x80000006.
CPUID function
 >>    0x2 is a bit complex to decode and IMHO Intel is unlikely to abandon
 >>    function 0x80000006 for its future products. By trying both for
Intel we can
 >>    avoid adding more L2 cache descriptors to the decoding function.

 > Ping...

 -ENOCHANGELOG, -ENOTESTINFO.

 OK for mainline with appropriate ChangeLog and testing info.

 Thanks,
 Uros.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Detect L2 cache size for x86
  2008-03-21  9:57 ` Fwd: [PATCH] Detect L2 cache size for x86 Uros Bizjak
@ 2008-03-23  3:44   ` Zuxy Meng
  2008-04-03 16:35     ` Zuxy
  0 siblings, 1 reply; 9+ messages in thread
From: Zuxy Meng @ 2008-03-23  3:44 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 914 bytes --]

"Uros Bizjak" <ubizjak@gmail.com> 写入消息新闻:5787cf470803202312k156d4dbbnff0f13b1ff36ff43@mail.gmail.com...
> Hello!
>
> >>    The attached patch detects automatically the L2 cache size of a host 
> >> x86
> >>    CPU, following what has already been done for L1 cache. Two schemes 
> >> are
> >>    utilized in the detection: AMD CPUs will use CPUID function
> 0x80000006, and
> >>    Intel CPUs will try both CPUID function 0x2 and 0x80000006.
> CPUID function
> >>    0x2 is a bit complex to decode and IMHO Intel is unlikely to abandon
> >>    function 0x80000006 for its future products. By trying both for
> Intel we can
> >>    avoid adding more L2 cache descriptors to the decoding function.
>
> > Ping...
>
> -ENOCHANGELOG, -ENOTESTINFO.
>


        *config/i386/driver-i386.c: Add runtime L2 cache size detection

Patch is bootstrapped and tested on i386-pc-mingw32.

-- 
Zuxy 

[-- Attachment #2: l2cache.diff --]
[-- Type: application/octet-stream, Size: 7141 bytes --]

--- gcc\config\i386\driver-i386.c.orig	Tue Mar 18 17:13:09 2008
+++ gcc\config\i386\driver-i386.c	Fri Mar 21 17:48:24 2008
@@ -33,17 +33,39 @@ const char *host_detect_local_cpu (int a
 
 static char *
 describe_cache (unsigned l1_sizekb, unsigned l1_line,
-		unsigned l1_assoc ATTRIBUTE_UNUSED)
+		unsigned l1_assoc ATTRIBUTE_UNUSED, unsigned l2_sizekb)
 {
-  char size[100], line[100];
+  char size[100], line[100], size2[100];
 
   /* At the moment, gcc middle-end does not use the information about the
      associativity of the cache.  */
 
   sprintf (size, "--param l1-cache-size=%u", l1_sizekb);
   sprintf (line, "--param l1-cache-line-size=%u", l1_line);
+  sprintf (size2, "--param l2-cache-size=%u", l2_sizekb);
 
-  return concat (size, " ", line, " ", NULL);
+  return concat (size, " ", line, " ", size2, " ", NULL);
+}
+
+static void
+decode_l2_caches_amd (unsigned *l2_size, unsigned *l2_line, unsigned *l2_assoc)
+{
+  unsigned eax, ebx, ecx, edx, assoc;
+
+  __cpuid (0x80000006, eax, ebx, ecx, edx);
+
+  *l2_size = (ecx >> 16) & 0xffff;
+  *l2_line = ecx & 0xff;
+  assoc = (ecx >> 12) & 0xf;
+  if (assoc == 6)
+    assoc = 8;
+  else if (assoc == 8)
+    assoc = 16;
+  else if (assoc >= 0xa && assoc <= 0xc)
+    assoc = 32 + (assoc - 0xa) * 16;
+  else if (assoc >= 0xd && assoc <= 0xe)
+    assoc = 96 + (assoc - 0xd) * 32;
+  *l2_assoc = assoc;
 }
 
 /* Returns the description of caches for an AMD processor.  */
@@ -53,6 +75,7 @@ detect_caches_amd (unsigned max_ext_leve
 {
   unsigned eax, ebx, ecx, edx;
   unsigned l1_sizekb, l1_line, l1_assoc;
+  unsigned l2_sizekb, l2_line, l2_assoc;
 
   if (max_ext_level < 0x80000005)
     return (char *) "";
@@ -63,15 +86,20 @@ detect_caches_amd (unsigned max_ext_leve
   l1_sizekb = (ecx >> 24) & 0xff;
   l1_assoc = (ecx >> 16) & 0xff;
 
-  return describe_cache (l1_sizekb, l1_line, l1_assoc);
+  if (max_ext_level >= 0x80000006)
+    decode_l2_caches_amd (&l2_sizekb, &l2_line, &l2_assoc);
+
+  return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
 }
 
-/* Stores the size of the L1 cache and cache line, and the associativity
-   of the cache according to REG to L1_SIZEKB, L1_LINE and L1_ASSOC.  */
+/* Stores the size of the L1/2 cache and cache line, and the associativity
+   of the cache according to REG to L1_SIZEKB, L1_LINE, L1_ASSOC and
+   L2_SIZEKB. */
 
 static void
 decode_caches_intel (unsigned reg, unsigned *l1_sizekb, unsigned *l1_line,
-		     unsigned *l1_assoc)
+		     unsigned *l1_assoc, unsigned *l2_sizekb,
+		     unsigned *l2_line, unsigned *l2_assoc)
 {
   unsigned i, val;
 
@@ -100,6 +128,66 @@ decode_caches_intel (unsigned reg, unsig
 	  *l1_line = 64;
 	  *l1_assoc = 8;
 	  break;
+	case 0x39:
+	  *l2_sizekb = 128;
+	  *l2_line = 64;
+	  *l2_assoc = 4;
+	  break;
+	case 0x3a:
+	  *l2_sizekb = 192;
+	  *l2_line = 64;
+	  *l2_assoc = 6;
+	  break;
+	case 0x3b:
+	  *l2_sizekb = 128;
+	  *l2_line = 64;
+	  *l2_assoc = 2;
+	  break;
+	case 0x3c:
+	  *l2_sizekb = 256;
+	  *l2_line = 64;
+	  *l2_assoc = 4;
+	  break;
+	case 0x3d:
+	  *l2_sizekb = 384;
+	  *l2_line = 64;
+	  *l2_assoc = 6;
+	  break;
+	case 0x3e:
+	  *l2_sizekb = 512;
+	  *l2_line = 64;
+	  *l2_assoc = 4;
+	  break;
+	case 0x41:
+	  *l2_sizekb = 128;
+	  *l2_line = 32;
+	  *l2_assoc = 4;
+	  break;
+	case 0x42:
+	  *l2_sizekb = 256;
+	  *l2_line = 32;
+	  *l2_assoc = 4;
+	  break;
+	case 0x43:
+	  *l2_sizekb = 512;
+	  *l2_line = 32;
+	  *l2_assoc = 4;
+	  break;
+	case 0x44:
+	  *l2_sizekb = 1024;
+	  *l2_line = 32;
+	  *l2_assoc = 4;
+	  break;
+	case 0x45:
+	  *l2_sizekb = 2048;
+	  *l2_line = 32;
+	  *l2_assoc = 4;
+	  break;
+	case 0x49:
+	  *l2_sizekb = 4096;
+	  *l2_line = 64;
+	  *l2_assoc = 16;
+	  break;
 	case 0x60:
 	  *l1_sizekb = 16;
 	  *l1_line = 64;
@@ -120,6 +208,71 @@ decode_caches_intel (unsigned reg, unsig
 	  *l1_line = 64;
 	  *l1_assoc = 4;
 	  break;
+	case 0x78:
+	  *l2_sizekb = 1024;
+	  *l2_line = 64;
+	  *l2_assoc = 4;
+	  break;
+	case 0x79:
+	  *l2_sizekb = 128;
+	  *l2_line = 64;
+	  *l2_assoc = 8;
+	  break;
+	case 0x7a:
+	  *l2_sizekb = 256;
+	  *l2_line = 64;
+	  *l2_assoc = 8;
+	  break;
+	case 0x7b:
+	  *l2_sizekb = 512;
+	  *l2_line = 64;
+	  *l2_assoc = 8;
+	  break;
+	case 0x7c:
+	  *l2_sizekb = 1024;
+	  *l2_line = 64;
+	  *l2_assoc = 8;
+	  break;
+	case 0x7d:
+	  *l2_sizekb = 2048;
+	  *l2_line = 64;
+	  *l2_assoc = 8;
+	  break;
+	case 0x7f:
+	  *l2_sizekb = 512;
+	  *l2_line = 64;
+	  *l2_assoc = 2;
+	  break;
+	case 0x82:
+	  *l2_sizekb = 256;
+	  *l2_line = 32;
+	  *l2_assoc = 8;
+	  break;
+	case 0x83:
+	  *l2_sizekb = 512;
+	  *l2_line = 32;
+	  *l2_assoc = 8;
+	  break;
+	case 0x84:
+	  *l2_sizekb = 1024;
+	  *l2_line = 32;
+	  *l2_assoc = 8;
+	  break;
+	case 0x85:
+	  *l2_sizekb = 2048;
+	  *l2_line = 32;
+	  *l2_assoc = 8;
+	  break;
+	case 0x86:
+	  *l2_sizekb = 512;
+	  *l2_line = 64;
+	  *l2_assoc = 4;
+	  break;
+	case 0x87:
+	  *l2_sizekb = 1024;
+	  *l2_line = 64;
+	  *l2_assoc = 8;
+	  break;
 
 	default:
 	  break;
@@ -130,25 +283,33 @@ decode_caches_intel (unsigned reg, unsig
 /* Returns the description of caches for an intel processor.  */
 
 static char *
-detect_caches_intel (unsigned max_level)
+detect_caches_intel (unsigned max_level, unsigned max_ext_level)
 {
   unsigned eax, ebx, ecx, edx;
   unsigned l1_sizekb = 0, l1_line = 0, assoc = 0;
+  unsigned l2_sizekb = 0, l2_line = 0, l2_assoc = 0;
 
   if (max_level < 2)
     return (char *) "";
 
   __cpuid (2, eax, ebx, ecx, edx);
 
-  decode_caches_intel (eax, &l1_sizekb, &l1_line, &assoc);
-  decode_caches_intel (ebx, &l1_sizekb, &l1_line, &assoc);
-  decode_caches_intel (ecx, &l1_sizekb, &l1_line, &assoc);
-  decode_caches_intel (edx, &l1_sizekb, &l1_line, &assoc);
+  decode_caches_intel (eax, &l1_sizekb, &l1_line, &assoc,
+      &l2_sizekb, &l2_line, &l2_assoc);
+  decode_caches_intel (ebx, &l1_sizekb, &l1_line, &assoc,
+      &l2_sizekb, &l2_line, &l2_assoc);
+  decode_caches_intel (ecx, &l1_sizekb, &l1_line, &assoc,
+      &l2_sizekb, &l2_line, &l2_assoc);
+  decode_caches_intel (edx, &l1_sizekb, &l1_line, &assoc,
+      &l2_sizekb, &l2_line, &l2_assoc);
 
   if (!l1_sizekb)
     return (char *) "";
 
-  return describe_cache (l1_sizekb, l1_line, assoc);
+  /* Newer Intel CPUs are equipped with AMD style L2 cache info */
+  if (max_ext_level >= 0x80000006)
+    decode_l2_caches_amd (&l2_sizekb, &l2_line, &l2_assoc);
+  return describe_cache (l1_sizekb, l1_line, assoc, l2_sizekb);
 }
 
 /* This will be called by the spec parser in gcc.c when it sees
@@ -234,7 +395,7 @@ const char *host_detect_local_cpu (int a
       if (vendor == *(unsigned int*) "Auth")
 	cache = detect_caches_amd (ext_level);
       else if (vendor == *(unsigned int*) "Genu")
-	cache = detect_caches_intel (max_level);
+	cache = detect_caches_intel (max_level, ext_level);
     }
 
   if (vendor == *(unsigned int*) "Auth")

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Detect L2 cache size for x86
  2008-03-23  3:44   ` Zuxy Meng
@ 2008-04-03 16:35     ` Zuxy
  0 siblings, 0 replies; 9+ messages in thread
From: Zuxy @ 2008-04-03 16:35 UTC (permalink / raw)
  To: gcc-patches

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1040 bytes --]

"Zuxy Meng" <zuxy.meng@gmail.com> дÈëÏûÏ¢ 
news:fs4bkl$evr$2@ger.gmane.org...
> "Uros Bizjak" <ubizjak@gmail.com> дÈëÏûÏ¢ÐÂÎÅ:5787cf470803202312k156d4dbbnff0f13b1ff36ff43@mail.gmail.com...
>> Hello!
>>
>> >>    The attached patch detects automatically the L2 cache size of a 
>> >> host
>> >> x86
>> >>    CPU, following what has already been done for L1 cache. Two schemes
>> >> are
>> >>    utilized in the detection: AMD CPUs will use CPUID function
>> 0x80000006, and
>> >>    Intel CPUs will try both CPUID function 0x2 and 0x80000006.
>> CPUID function
>> >>    0x2 is a bit complex to decode and IMHO Intel is unlikely to 
>> >> abandon
>> >>    function 0x80000006 for its future products. By trying both for
>> Intel we can
>> >>    avoid adding more L2 cache descriptors to the decoding function.
>>
>> > Ping...
>>
>> -ENOCHANGELOG, -ENOTESTINFO.
>>
>
>
>        *config/i386/driver-i386.c: Add runtime L2 cache size detection
>
> Patch is bootstrapped and tested on i386-pc-mingw32.

Ping....

-- 
Zuxy 



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Detect L2 cache size for x86
  2008-04-04  6:24   ` H.J. Lu
@ 2008-04-04  8:41     ` Uros Bizjak
  0 siblings, 0 replies; 9+ messages in thread
From: Uros Bizjak @ 2008-04-04  8:41 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Zuxy Meng, gcc-patches

On Fri, Apr 4, 2008 at 7:28 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> Your ChangeLog entry doesn't document what you changed. Can you rename
>  decode_l2_caches_amd to decode_l2_caches since it isn't AMD specific?

Committed [1] with requested changes and following ChangeLog entry:

2008-04-04  Zuxy Meng <zuxy.meng@gmail.com>

	* config/i386/driver-i386.c (describe_cache): Add l2_sizekb argument.
	Pass L2 size as "--param l2-cache-size" to the compiler.
	(decode_l2_cache): New function to decode L2 cache parameters using
	0x8000006 extended cpuid function.
	(detect_caches_amd): Determine parameters of L2 cache using
	decode_l2_caches function.
	(decode_caches_intel): Decode L2 cache parameters.
	(detect_caches_intel): Determine L2 cache parameters using
	decode_caches_intel and decode_l2_caches functions.


[1] http://gcc.gnu.org/viewcvs?view=rev&revision=133890

Thanks,
Uros.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Detect L2 cache size for x86
  2008-04-04  5:28 ` Zuxy Meng
@ 2008-04-04  6:24   ` H.J. Lu
  2008-04-04  8:41     ` Uros Bizjak
  0 siblings, 1 reply; 9+ messages in thread
From: H.J. Lu @ 2008-04-04  6:24 UTC (permalink / raw)
  To: Zuxy Meng; +Cc: Uros Bizjak, gcc-patches

Your ChangeLog entry doesn't document what you changed. Can you rename
decode_l2_caches_amd to decode_l2_caches since it isn't AMD specific?

Thanks.


H.J.
On Thu, Apr 3, 2008 at 10:11 PM, Zuxy Meng <zuxy.meng@gmail.com> wrote:
> Hi,
>
>  2008/4/4, Uros Bizjak <ubizjak@gmail.com>:
>
>
> > Hello!
>  >
>  > > > >>    The attached patch detects automatically the L2 cache size of a >>
>  > >> host
>  > > >> >> x86
>  > > >> >>    CPU, following what has already been done for L1 cache. Two
>  > schemes
>  > > >> >> are
>  > > >> >>    utilized in the detection: AMD CPUs will use CPUID function
>  > > >> 0x80000006, and
>  > > >> >>    Intel CPUs will try both CPUID function 0x2 and 0x80000006.
>  > > >> CPUID function
>  > > >> >>    0x2 is a bit complex to decode and IMHO Intel is unlikely to >>
>  > >> abandon
>  > > >> >>    function 0x80000006 for its future products. By trying both for
>  > > >> Intel we can
>  > > >> >>    avoid adding more L2 cache descriptors to the decoding function.
>  > > >>
>  > > >> > Ping...
>  > > >>
>  > > >> -ENOCHANGELOG, -ENOTESTINFO.
>  > > >>
>  > > >
>  > > >
>  > > >        *config/i386/driver-i386.c: Add runtime L2 cache size detection
>  > > >
>  > > > Patch is bootstrapped and tested on i386-pc-mingw32.
>  > >
>  > > Ping....
>  > >
>  >
>  > Uh, I was under impression that the patch was already approved.
>  >
>  > The patch is OK for mainline.
>
>  Thanks! Could someone apply it please?
>
>  --
>  Zuxy
>  Beauty is truth,
>  While truth is beauty.
>  PGP KeyID: E8555ED6
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Detect L2 cache size for x86
  2008-04-03 17:57 Uros Bizjak
@ 2008-04-04  5:28 ` Zuxy Meng
  2008-04-04  6:24   ` H.J. Lu
  0 siblings, 1 reply; 9+ messages in thread
From: Zuxy Meng @ 2008-04-04  5:28 UTC (permalink / raw)
  To: Uros Bizjak; +Cc: gcc-patches

Hi,

2008/4/4, Uros Bizjak <ubizjak@gmail.com>:
> Hello!
>
> > > >>    The attached patch detects automatically the L2 cache size of a >>
> >> host
> > >> >> x86
> > >> >>    CPU, following what has already been done for L1 cache. Two
> schemes
> > >> >> are
> > >> >>    utilized in the detection: AMD CPUs will use CPUID function
> > >> 0x80000006, and
> > >> >>    Intel CPUs will try both CPUID function 0x2 and 0x80000006.
> > >> CPUID function
> > >> >>    0x2 is a bit complex to decode and IMHO Intel is unlikely to >>
> >> abandon
> > >> >>    function 0x80000006 for its future products. By trying both for
> > >> Intel we can
> > >> >>    avoid adding more L2 cache descriptors to the decoding function.
> > >>
> > >> > Ping...
> > >>
> > >> -ENOCHANGELOG, -ENOTESTINFO.
> > >>
> > >
> > >
> > >        *config/i386/driver-i386.c: Add runtime L2 cache size detection
> > >
> > > Patch is bootstrapped and tested on i386-pc-mingw32.
> >
> > Ping....
> >
>
> Uh, I was under impression that the patch was already approved.
>
> The patch is OK for mainline.

Thanks! Could someone apply it please?

-- 
Zuxy
Beauty is truth,
While truth is beauty.
PGP KeyID: E8555ED6

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Detect L2 cache size for x86
@ 2008-04-03 17:57 Uros Bizjak
  2008-04-04  5:28 ` Zuxy Meng
  0 siblings, 1 reply; 9+ messages in thread
From: Uros Bizjak @ 2008-04-03 17:57 UTC (permalink / raw)
  To: GCC Patches; +Cc: Zuxy Meng

Hello!

> > >>    The attached patch detects automatically the L2 cache size of a 
> >> >> host
> >> >> x86
> >> >>    CPU, following what has already been done for L1 cache. Two schemes
> >> >> are
> >> >>    utilized in the detection: AMD CPUs will use CPUID function
> >> 0x80000006, and
> >> >>    Intel CPUs will try both CPUID function 0x2 and 0x80000006.
> >> CPUID function
> >> >>    0x2 is a bit complex to decode and IMHO Intel is unlikely to 
> >> >> abandon
> >> >>    function 0x80000006 for its future products. By trying both for
> >> Intel we can
> >> >>    avoid adding more L2 cache descriptors to the decoding function.
> >>
> >> > Ping...
> >>
> >> -ENOCHANGELOG, -ENOTESTINFO.
> >>
> >
> >
> >        *config/i386/driver-i386.c: Add runtime L2 cache size detection
> >
> > Patch is bootstrapped and tested on i386-pc-mingw32.
>
> Ping....

Uh, I was under impression that the patch was already approved.

The patch is OK for mainline.

Thanks,
Uros.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Detect L2 cache size for x86
  2008-03-18 15:16 Zuxy Meng
@ 2008-03-21  5:11 ` Zuxy Meng
  0 siblings, 0 replies; 9+ messages in thread
From: Zuxy Meng @ 2008-03-21  5:11 UTC (permalink / raw)
  To: gcc-patches

"Zuxy Meng" <zuxy.meng@gmail.com> 写入消息新闻:frolpo$13o$1@ger.gmane.org...
> Hello,
>
> The attached patch detects automatically the L2 cache size of a host x86
> CPU, following what has already been done for L1 cache. Two schemes are
> utilized in the detection: AMD CPUs will use CPUID function 0x80000006, 
> and
> Intel CPUs will try both CPUID function 0x2 and 0x80000006. CPUID function
> 0x2 is a bit complex to decode and IMHO Intel is unlikely to abandon
> function 0x80000006 for its future products. By trying both for Intel we 
> can
> avoid adding more L2 cache descriptors to the decoding function.


Ping...
-- 
Zuxy 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH] Detect L2 cache size for x86
@ 2008-03-18 15:16 Zuxy Meng
  2008-03-21  5:11 ` Zuxy Meng
  0 siblings, 1 reply; 9+ messages in thread
From: Zuxy Meng @ 2008-03-18 15:16 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 532 bytes --]

Hello,

The attached patch detects automatically the L2 cache size of a host x86 
CPU, following what has already been done for L1 cache. Two schemes are 
utilized in the detection: AMD CPUs will use CPUID function 0x80000006, and 
Intel CPUs will try both CPUID function 0x2 and 0x80000006. CPUID function 
0x2 is a bit complex to decode and IMHO Intel is unlikely to abandon 
function 0x80000006 for its future products. By trying both for Intel we can 
avoid adding more L2 cache descriptors to the decoding function.

-- 
Zuxy 

[-- Attachment #2: l2detect.diff --]
[-- Type: application/octet-stream, Size: 6822 bytes --]

--- driver-i386.c.orig	Tue Mar 18 17:13:09 2008
+++ driver-i386.c	Tue Mar 18 21:22:32 2008
@@ -33,17 +33,39 @@
 
 static char *
 describe_cache (unsigned l1_sizekb, unsigned l1_line,
-		unsigned l1_assoc ATTRIBUTE_UNUSED)
+		unsigned l1_assoc ATTRIBUTE_UNUSED, unsigned l2_sizekb)
 {
-  char size[100], line[100];
+  char size[100], line[100], size2[100];
 
   /* At the moment, gcc middle-end does not use the information about the
      associativity of the cache.  */
 
   sprintf (size, "--param l1-cache-size=%u", l1_sizekb);
   sprintf (line, "--param l1-cache-line-size=%u", l1_line);
+  sprintf (size2, "--param l2-cache-size=%u", l2_sizekb);
 
-  return concat (size, " ", line, " ", NULL);
+  return concat (size, " ", line, " ", size2, " ", NULL);
+}
+
+static void
+decode_l2_caches_amd (unsigned *l2_size, unsigned *l2_line, unsigned *l2_assoc)
+{
+  unsigned eax, ebx, ecx, edx, assoc;
+
+  __cpuid (0x80000006, eax, ebx, ecx, edx);
+
+  *l2_size = (ecx >> 16) & 0xffff;
+  *l2_line = ecx & 0xff;
+  assoc = (ecx >> 12) & 0xf;
+  if (assoc == 6)
+    assoc = 8;
+  else if (assoc == 8)
+    assoc = 16;
+  else if (assoc >= 0xa && assoc <= 0xc)
+    assoc = 32 + (assoc - 0xa) * 16;
+  else if (assoc >= 0xd && assoc <= 0xe)
+    assoc = 96 + (assoc - 0xd) * 32;
+  *l2_assoc = assoc;
 }
 
 /* Returns the description of caches for an AMD processor.  */
@@ -53,6 +75,7 @@
 {
   unsigned eax, ebx, ecx, edx;
   unsigned l1_sizekb, l1_line, l1_assoc;
+  unsigned l2_sizekb, l2_line, l2_assoc;
 
   if (max_ext_level < 0x80000005)
     return (char *) "";
@@ -63,15 +86,20 @@
   l1_sizekb = (ecx >> 24) & 0xff;
   l1_assoc = (ecx >> 16) & 0xff;
 
-  return describe_cache (l1_sizekb, l1_line, l1_assoc);
+  if (max_ext_level >= 0x80000006)
+    decode_l2_caches_amd (&l2_sizekb, &l2_line, &l2_assoc);
+
+  return describe_cache (l1_sizekb, l1_line, l1_assoc, l2_sizekb);
 }
 
-/* Stores the size of the L1 cache and cache line, and the associativity
-   of the cache according to REG to L1_SIZEKB, L1_LINE and L1_ASSOC.  */
+/* Stores the size of the L1/2 cache and cache line, and the associativity
+   of the cache according to REG to L1_SIZEKB, L1_LINE, L1_ASSOC and
+   L2_SIZEKB. */
 
 static void
 decode_caches_intel (unsigned reg, unsigned *l1_sizekb, unsigned *l1_line,
-		     unsigned *l1_assoc)
+		     unsigned *l1_assoc, unsigned *l2_sizekb,
+		     unsigned *l2_line, unsigned *l2_assoc)
 {
   unsigned i, val;
 
@@ -100,6 +128,66 @@
 	  *l1_line = 64;
 	  *l1_assoc = 8;
 	  break;
+	case 0x39:
+	  *l2_sizekb = 128;
+	  *l2_line = 64;
+	  *l2_assoc = 4;
+	  break;
+	case 0x3a:
+	  *l2_sizekb = 192;
+	  *l2_line = 64;
+	  *l2_assoc = 6;
+	  break;
+	case 0x3b:
+	  *l2_sizekb = 128;
+	  *l2_line = 64;
+	  *l2_assoc = 2;
+	  break;
+	case 0x3c:
+	  *l2_sizekb = 256;
+	  *l2_line = 64;
+	  *l2_assoc = 4;
+	  break;
+	case 0x3d:
+	  *l2_sizekb = 384;
+	  *l2_line = 64;
+	  *l2_assoc = 6;
+	  break;
+	case 0x3e:
+	  *l2_sizekb = 512;
+	  *l2_line = 64;
+	  *l2_assoc = 4;
+	  break;
+	case 0x41:
+	  *l2_sizekb = 128;
+	  *l2_line = 32;
+	  *l2_assoc = 4;
+	  break;
+	case 0x42:
+	  *l2_sizekb = 256;
+	  *l2_line = 32;
+	  *l2_assoc = 4;
+	  break;
+	case 0x43:
+	  *l2_sizekb = 512;
+	  *l2_line = 32;
+	  *l2_assoc = 4;
+	  break;
+	case 0x44:
+	  *l2_sizekb = 1024;
+	  *l2_line = 32;
+	  *l2_assoc = 4;
+	  break;
+	case 0x45:
+	  *l2_sizekb = 2048;
+	  *l2_line = 32;
+	  *l2_assoc = 4;
+	  break;
+	case 0x49:
+	  *l2_sizekb = 4096;
+	  *l2_line = 64;
+	  *l2_assoc = 16;
+	  break;
 	case 0x60:
 	  *l1_sizekb = 16;
 	  *l1_line = 64;
@@ -120,6 +208,71 @@
 	  *l1_line = 64;
 	  *l1_assoc = 4;
 	  break;
+	case 0x78:
+	  *l2_sizekb = 1024;
+	  *l2_line = 64;
+	  *l2_assoc = 4;
+	  break;
+	case 0x79:
+	  *l2_sizekb = 128;
+	  *l2_line = 64;
+	  *l2_assoc = 8;
+	  break;
+	case 0x7a:
+	  *l2_sizekb = 256;
+	  *l2_line = 64;
+	  *l2_assoc = 8;
+	  break;
+	case 0x7b:
+	  *l2_sizekb = 512;
+	  *l2_line = 64;
+	  *l2_assoc = 8;
+	  break;
+	case 0x7c:
+	  *l2_sizekb = 1024;
+	  *l2_line = 64;
+	  *l2_assoc = 8;
+	  break;
+	case 0x7d:
+	  *l2_sizekb = 2048;
+	  *l2_line = 64;
+	  *l2_assoc = 8;
+	  break;
+	case 0x7f:
+	  *l2_sizekb = 512;
+	  *l2_line = 64;
+	  *l2_assoc = 2;
+	  break;
+	case 0x82:
+	  *l2_sizekb = 256;
+	  *l2_line = 32;
+	  *l2_assoc = 8;
+	  break;
+	case 0x83:
+	  *l2_sizekb = 512;
+	  *l2_line = 32;
+	  *l2_assoc = 8;
+	  break;
+	case 0x84:
+	  *l2_sizekb = 1024;
+	  *l2_line = 32;
+	  *l2_assoc = 8;
+	  break;
+	case 0x85:
+	  *l2_sizekb = 2048;
+	  *l2_line = 32;
+	  *l2_assoc = 8;
+	  break;
+	case 0x86:
+	  *l2_sizekb = 512;
+	  *l2_line = 64;
+	  *l2_assoc = 4;
+	  break;
+	case 0x87:
+	  *l2_sizekb = 1024;
+	  *l2_line = 64;
+	  *l2_assoc = 8;
+	  break;
 
 	default:
 	  break;
@@ -130,25 +283,33 @@
 /* Returns the description of caches for an intel processor.  */
 
 static char *
-detect_caches_intel (unsigned max_level)
+detect_caches_intel (unsigned max_level, unsigned max_ext_level)
 {
   unsigned eax, ebx, ecx, edx;
   unsigned l1_sizekb = 0, l1_line = 0, assoc = 0;
+  unsigned l2_sizekb = 0, l2_line = 0, l2_assoc = 0;
 
   if (max_level < 2)
     return (char *) "";
 
   __cpuid (2, eax, ebx, ecx, edx);
 
-  decode_caches_intel (eax, &l1_sizekb, &l1_line, &assoc);
-  decode_caches_intel (ebx, &l1_sizekb, &l1_line, &assoc);
-  decode_caches_intel (ecx, &l1_sizekb, &l1_line, &assoc);
-  decode_caches_intel (edx, &l1_sizekb, &l1_line, &assoc);
+  decode_caches_intel (eax, &l1_sizekb, &l1_line, &assoc,
+      &l2_sizekb, &l2_line, &l2_assoc);
+  decode_caches_intel (ebx, &l1_sizekb, &l1_line, &assoc,
+      &l2_sizekb, &l2_line, &l2_assoc);
+  decode_caches_intel (ecx, &l1_sizekb, &l1_line, &assoc,
+      &l2_sizekb, &l2_line, &l2_assoc);
+  decode_caches_intel (edx, &l1_sizekb, &l1_line, &assoc,
+      &l2_sizekb, &l2_line, &l2_assoc);
 
   if (!l1_sizekb)
     return (char *) "";
 
-  return describe_cache (l1_sizekb, l1_line, assoc);
+  /* Newer Intel CPUs are equipped with AMD style L2 cache info */
+  if (max_ext_level >= 0x80000006)
+    decode_l2_caches_amd (&l2_sizekb, &l2_line, &l2_assoc);
+  return describe_cache (l1_sizekb, l1_line, assoc, l2_sizekb);
 }
 
 /* This will be called by the spec parser in gcc.c when it sees
@@ -234,7 +395,7 @@
       if (vendor == *(unsigned int*) "Auth")
 	cache = detect_caches_amd (ext_level);
       else if (vendor == *(unsigned int*) "Genu")
-	cache = detect_caches_intel (max_level);
+	cache = detect_caches_intel (max_level, ext_level);
     }
 
   if (vendor == *(unsigned int*) "Auth")

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2008-04-04  8:16 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <5787cf470803202311k73b77370ie4ee507a96ea102f@mail.gmail.com>
2008-03-21  9:57 ` Fwd: [PATCH] Detect L2 cache size for x86 Uros Bizjak
2008-03-23  3:44   ` Zuxy Meng
2008-04-03 16:35     ` Zuxy
2008-04-03 17:57 Uros Bizjak
2008-04-04  5:28 ` Zuxy Meng
2008-04-04  6:24   ` H.J. Lu
2008-04-04  8:41     ` Uros Bizjak
  -- strict thread matches above, loose matches on Subject: below --
2008-03-18 15:16 Zuxy Meng
2008-03-21  5:11 ` Zuxy Meng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).