Current-Users archive

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

Re: AMD Phenom - need to enable L3 cache?



You wrote:

Actually the table amd_cpuid_l2cache_assoc_info needs an update,
it needs extending to support extra values for L3 caches.

Yup, thanks for the hint. Adding in the additional values from src/sys/arch/x86/x86/identcpu.c gives me the following output:

speedy {101} /build/obj/amd64/usr.sbin/cpuctl/cpuctl identify 0
cpu0: AMD Family 10h (686-class), 2310.80 MHz, id 0x100f22
cpu0: features ffdbfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR>
cpu0: features ffdbfbff<PGE,MCA,CMOV,PAT,PSE36,MPC,NOX,MMXX,MMX>
cpu0: features ffdbfbff<FXSR,SSE,SSE2,RDTSCP,HTT,LONG,3DNOW2,3DNOW>
cpu0: features2 802009<SSE3,MONITOR,CX16,POPCNT>
cpu0: "AMD Phenom(tm) 9600 Quad-Core Processor"
cpu0: I-cache 64KB 64B/line 2-way, D-cache 64KB 64B/line 2-way
cpu0: L2 cache 1MB 64B/line 16-way
cpu0: ITLB 32 4KB entries fully associative, 16 4MB entries fully associative
cpu0: DTLB 48 4KB entries fully associative, 48 4MB entries fully associative
cpu0: L3 cache 2MB 64B/line 32-way
cpu0: Initial APIC ID 2
cpu0: family 0f model 02 extfamily 01 extmodel 00
speedy {102}

The attached patch supersedes the patch in PR bin/38679. In addition to decoding the L3 cache stuff on AMD, it uses humanize_number(3) to display cache sizes (rather than hardcoding everything to multiples of 1KB) and properly displays 'Family 10h' for Phenom and Barcelona.

BTW, wouldn't it be nice if cpuctl/arch/i386 used the same sources as sys/arch/x86/x86/identcpu.c rather than having to duplicate them and having to keep changes in synch? :)


----------------------------------------------------------------------
|   Paul Goyette   | PGP DSS Key fingerprint: |  E-mail addresses:   |
| Customer Service | FA29 0E3B 35AF E8AE 6651 |  paul%whooppee.com@localhost   |
| Network Engineer | 0786 F758 55DE 53BA 7731 | pgoyette%juniper.net@localhost |
----------------------------------------------------------------------
Index: i386.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/cpuctl/arch/i386.c,v
retrieving revision 1.4
diff -u -p -r1.4 i386.c
--- i386.c      17 May 2008 13:20:27 -0000      1.4
+++ i386.c      20 May 2008 00:03:58 -0000
@@ -80,6 +80,9 @@ __RCSID("$NetBSD: i386.c,v 1.4 2008/05/1
 
 #include "../cpuctl.h"
 
+/* Size of buffer for printing humanized numbers */
+#define _HUMAN_BUFSIZE 5
+
 #define       x86_cpuid(a,b)  x86_cpuid2((a),0,(b))
 
 void   x86_cpuid2(uint32_t, uint32_t, uint32_t *);
@@ -101,8 +104,9 @@ struct x86_cache_info {
 #define        CAI_ICACHE      4               /* Instruction cache */
 #define        CAI_DCACHE      5               /* Data cache */
 #define        CAI_L2CACHE     6               /* Level 2 cache */
+#define        CAI_L3CACHE     7               /* Level 3 cache */
 
-#define        CAI_COUNT       7
+#define        CAI_COUNT       8
 
 /*
  * AMD Cache Info:
@@ -182,6 +186,12 @@ struct x86_cache_info {
 #define        AMD_L2_ECX_C_LPT(x)              (((x) >> 8)  & 0xf)
 #define        AMD_L2_ECX_C_LS(x)               ( (x)        & 0xff)
 
+/* L3 Cache */
+#define        AMD_L3_EDX_C_SIZE(x)            ((((x) >> 18) & 0x3fff) * 512 * 
1024)
+#define        AMD_L3_EDX_C_ASSOC(x)            (((x) >> 12) & 0xf)
+#define        AMD_L3_EDX_C_LPT(x)              (((x) >> 8)  & 0xf)
+#define        AMD_L3_EDX_C_LS(x)               ( (x)        & 0xff)
+
 /*
  * VIA Cache Info:
  *
@@ -997,7 +1007,8 @@ amd_amd64_name(struct cpu_info *ci)
        extfamily = CPUID2EXTFAMILY(ci->ci_signature);
        extmodel  = CPUID2EXTMODEL(ci->ci_signature);
 
-       if (extfamily == 0x00) {
+       switch (extfamily) {
+       case 0x00:
                switch (model) {
                case 0x1:
                        switch (extmodel) {
@@ -1107,6 +1118,17 @@ amd_amd64_name(struct cpu_info *ci)
                default:
                        ret = "Unknown AMD64 CPU";
                }
+               break;
+       case 0x01:
+               switch (model) {
+                       case 0x02:
+                               ret = "Family 10h";
+                               break;
+                       default:
+                               ret = "Unknown AMD64 CPU";
+                               break;
+               }
+               break;
        }
 
        return ret;
@@ -1631,6 +1653,7 @@ print_cache_config(struct cpu_info *ci, 
     const char *sep)
 {
        struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag];
+       char human_num[_HUMAN_BUFSIZE];
 
        if (cai->cai_totalsize == 0)
                return sep;
@@ -1645,8 +1668,9 @@ print_cache_config(struct cpu_info *ci, 
        if (cai->cai_string != NULL) {
                aprint_verbose("%s ", cai->cai_string);
        } else {
-               aprint_verbose("%dkB %dB/line ", cai->cai_totalsize / 1024,
-                   cai->cai_linesize);
+               (void)humanize_number(human_num, _HUMAN_BUFSIZE,
+                       cai->cai_totalsize, "B", HN_AUTOSCALE, HN_NOSPACE);
+               aprint_verbose("%s %dB/line ", human_num, cai->cai_linesize);
        }
        switch (cai->cai_associativity) {
        case    0:
@@ -1670,6 +1694,7 @@ print_tlb_config(struct cpu_info *ci, in
     const char *sep)
 {
        struct x86_cache_info *cai = &ci->ci_cinfo[cache_tag];
+       char human_num[_HUMAN_BUFSIZE];
 
        if (cai->cai_totalsize == 0)
                return sep;
@@ -1684,8 +1709,10 @@ print_tlb_config(struct cpu_info *ci, in
        if (cai->cai_string != NULL) {
                aprint_verbose("%s", cai->cai_string);
        } else {
-               aprint_verbose("%d %dB entries ", cai->cai_totalsize,
-                   cai->cai_linesize);
+               (void)humanize_number(human_num, _HUMAN_BUFSIZE,
+                       cai->cai_linesize, "B", HN_AUTOSCALE, HN_NOSPACE);
+               aprint_verbose("%d %s entries ", cai->cai_totalsize,
+                   human_num);
                switch (cai->cai_associativity) {
                case 0:
                        aprint_verbose("disabled");
@@ -1724,6 +1751,26 @@ static const struct x86_cache_info amd_c
        { 0, 0x04,    4, 0, 0, NULL },
        { 0, 0x06,    8, 0, 0, NULL },
        { 0, 0x08,   16, 0, 0, NULL },
+       { 0, 0x0a,   32, 0, 0, NULL },
+       { 0, 0x0b,   48, 0, 0, NULL },
+       { 0, 0x0c,   64, 0, 0, NULL },
+       { 0, 0x0d,   96, 0, 0, NULL },
+       { 0, 0x0e,  128, 0, 0, NULL },
+       { 0, 0x0f, 0xff, 0, 0, NULL },
+       { 0, 0x00,    0, 0, 0, NULL },
+};
+
+static const struct x86_cache_info amd_cpuid_l3cache_assoc_info[] = {
+       { 0, 0x01,    1, 0, 0, NULL },
+       { 0, 0x02,    2, 0, 0, NULL },
+       { 0, 0x04,    4, 0, 0, NULL },
+       { 0, 0x06,    8, 0, 0, NULL },
+       { 0, 0x08,   16, 0, 0, NULL },
+       { 0, 0x0a,   32, 0, 0, NULL },
+       { 0, 0x0b,   48, 0, 0, NULL },
+       { 0, 0x0c,   64, 0, 0, NULL },
+       { 0, 0x0d,   96, 0, 0, NULL },
+       { 0, 0x0e,  128, 0, 0, NULL },
        { 0, 0x0f, 0xff, 0, 0, NULL },
        { 0, 0x00,    0, 0, 0, NULL },
 };
@@ -1826,6 +1873,23 @@ amd_cpu_cacheinfo(struct cpu_info *ci)
                cai->cai_associativity = cp->cai_associativity;
        else
                cai->cai_associativity = 0;     /* XXX Unknown/reserved */
+
+       /*
+        * Determine L3 cache info on AMD Family 10h processors
+        */
+       if (family == 0x10) {
+               cai = &ci->ci_cinfo[CAI_L3CACHE];
+               cai->cai_totalsize = AMD_L3_EDX_C_SIZE(descs[3]);
+               cai->cai_associativity = AMD_L3_EDX_C_ASSOC(descs[3]);
+               cai->cai_linesize = AMD_L3_EDX_C_LS(descs[3]);
+
+               cp = cache_info_lookup(amd_cpuid_l3cache_assoc_info,
+                   cai->cai_associativity);
+               if (cp != NULL)
+                       cai->cai_associativity = cp->cai_associativity;
+               else
+                       cai->cai_associativity = 0;     /* XXX Unkn/Rsvd */
+       }
 }
 
 static void
@@ -1935,4 +1999,9 @@ x86_print_cacheinfo(struct cpu_info *ci)
                if (sep != NULL)
                        aprint_verbose("\n");
        }
+       if (ci->ci_cinfo[CAI_L3CACHE].cai_totalsize != 0) {
+               sep = print_cache_config(ci, CAI_L3CACHE, "L3 cache", NULL);
+               if (sep != NULL)
+                       aprint_verbose("\n");
+       }
 }


Home | Main Index | Thread Index | Old Index