Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/i386 Rearrange the cache info fetching code some mo...



details:   https://anonhg.NetBSD.org/src/rev/72884c54a70f
branches:  trunk
changeset: 509385:72884c54a70f
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Thu May 03 00:35:37 2001 +0000

description:
Rearrange the cache info fetching code some more, and add support
for fetching cache info for AMD processors.

diffstat:

 sys/arch/i386/i386/machdep.c |  422 ++++++++++++++++++++++++++++++++++--------
 sys/arch/i386/include/cpu.h  |   29 ++-
 2 files changed, 357 insertions(+), 94 deletions(-)

diffs (truncated from 539 to 300 lines):

diff -r 9aba8e9e1f9f -r 72884c54a70f sys/arch/i386/i386/machdep.c
--- a/sys/arch/i386/i386/machdep.c      Wed May 02 21:23:03 2001 +0000
+++ b/sys/arch/i386/i386/machdep.c      Thu May 03 00:35:37 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.437 2001/05/02 21:07:01 thorpej Exp $    */
+/*     $NetBSD: machdep.c,v 1.438 2001/05/03 00:35:37 thorpej Exp $    */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc.
@@ -238,73 +238,6 @@
 void   add_mem_cluster __P((u_int64_t, u_int64_t, u_int32_t));
 #endif /* !defnied(REALBASEMEM) && !defined(REALEXTMEM) */
 
-struct i386_cache_info {
-       size_t          cai_offset;
-       u_int32_t       cai_desc;
-       const char      *cai_string;
-       u_int           cai_totalsize;
-       u_int           cai_associativity;
-       u_int           cai_linesize;
-};
-
-static const struct i386_cache_info intel_cpuid_cache_info[] = {
-       { offsetof(struct cpu_info, ci_itlb_info),
-         0x01,         "4K: 32 entries 4-way",
-         32,           4,                      4 * 1024 },
-       { offsetof(struct cpu_info, ci_itlb2_info),
-         0x02,         "4M: 2 entries",
-         2,            1,                      4 * 1024 * 1024 },
-       { offsetof(struct cpu_info, ci_dtlb_info),
-         0x03,         "4K: 64 entries 4-way",
-         64,           4,                      4 * 1024 },
-       { offsetof(struct cpu_info, ci_dtlb2_info),
-         0x04,         "4M: 8 entries 4-way",
-         8,            4,                      4 * 1024 * 1024 },
-       { offsetof(struct cpu_info, ci_icache_info),
-         0x06,         "8K 32b/line 4-way",
-         8 * 1024,     4,                      32 },
-       { offsetof(struct cpu_info, ci_icache_info),
-         0x08,         "16K 32b/line 4-way",
-         16 * 1024,    4,                      32 },
-       { offsetof(struct cpu_info, ci_dcache_info),
-         0x0a,         "8K 32b/line 2-way",
-         8 * 1024,     2,                      32 },
-       { offsetof(struct cpu_info, ci_dcache_info),
-         0x0c,         "16K 32b/line 2/4-way",
-         16 * 1024,    2,                      32 },
-       { offsetof(struct cpu_info, ci_l2cache_info),
-         0x40,         "not present",
-         0,            1,                      0 },
-       { offsetof(struct cpu_info, ci_l2cache_info),
-         0x41,         "128K 32b/line 4-way",
-         128 * 1024,   4,                      32 },
-       { offsetof(struct cpu_info, ci_l2cache_info),
-         0x42,         "256K 32b/line 4-way",
-         256 * 1024,   4,                      32 },
-       { offsetof(struct cpu_info, ci_l2cache_info),
-         0x43,         "512K 32b/line 4-way",
-         512 * 1024,   4,                      32 },
-       { offsetof(struct cpu_info, ci_l2cache_info),
-         0x44,         "1M 32b/line 4-way",
-         1 * 1024 * 1024, 4,                   32 },
-       { offsetof(struct cpu_info, ci_l2cache_info),
-         0x45,         "2M 32b/line 4-way",
-         2 * 1024 * 1024, 4,                   32 },
-       { offsetof(struct cpu_info, ci_l2cache_info),
-         0x82,         "256K 32b/line 8-way",
-         256 * 1024,   8,                      32 },
-       { offsetof(struct cpu_info, ci_l2cache_info),
-         0x84,         "1M 32b/line 8-way",
-         1 * 1024 * 1024, 8,                   32 },
-       { offsetof(struct cpu_info, ci_l2cache_info),
-         0x85,         "2M 32b/line 8-way",
-         2 * 1024 * 1024, 8,                   32 },
-
-       { 0,
-         0,            NULL,
-         0,            1,                      0 },
-};
-
 /*
  * Map Brand ID from cpuid instruction to brand name.
  * Source: Intel Processor Identification and the CPUID Instruction, AP-485
@@ -324,6 +257,7 @@
 void winchip_cpu_setup __P((void));
 
 void intel_cpuid_cpu_cacheinfo __P((struct cpu_info *));
+void amd_cpuid_cpu_cacheinfo __P((struct cpu_info *));
 
 static __inline u_char
 cyrix_read_reg(u_char reg)
@@ -352,6 +286,7 @@
        vsize_t size;
        char buf[160];                          /* about 2 line */
        char pbuf[9];
+       char cbuf[7];
 
        /*
         * Initialize error message buffer (et end of core).
@@ -375,18 +310,77 @@
                printf(", %qd.%02qd MHz", (cpu_tsc_freq + 4999) / 1000000,
                    ((cpu_tsc_freq + 4999) / 10000) % 100);
        printf("\n");
-       if (ci->ci_icache_info != NULL || ci->ci_dcache_info != NULL) {
+       if (ci->ci_cinfo[CAI_ICACHE].cai_totalsize != 0 ||
+           ci->ci_cinfo[CAI_DCACHE].cai_totalsize != 0) {
                printf("cpu0:");
-               if (ci->ci_icache_info)
-                       printf(" I-cache %s", ci->ci_icache_info->cai_string);
-               if (ci->ci_dcache_info)
-                       printf("%sD-cache %s",
-                           (ci->ci_icache_info != NULL) ? ", " : " ",
-                           ci->ci_dcache_info->cai_string);
+               if (ci->ci_cinfo[CAI_ICACHE].cai_totalsize) {
+                       format_bytes(cbuf, sizeof(cbuf),
+                           ci->ci_cinfo[CAI_ICACHE].cai_totalsize);
+                       printf(" I-cache %s %db/line ", cbuf,
+                           ci->ci_cinfo[CAI_ICACHE].cai_linesize);
+                       switch (ci->ci_cinfo[CAI_ICACHE].cai_associativity) {
+                       case 0:
+                               printf("disabled");
+                               break;
+                       case 1:
+                               printf("direct-mapped");
+                               break;
+                       case ~0:
+                               printf("fully associative");
+                               break;
+                       default:
+                               printf("%d-way",
+                                   ci->ci_cinfo[CAI_ICACHE].cai_associativity);
+                               break;
+                       }
+               }
+               if (ci->ci_cinfo[CAI_DCACHE].cai_totalsize) {
+                       format_bytes(cbuf, sizeof(cbuf),
+                           ci->ci_cinfo[CAI_DCACHE].cai_totalsize);
+                       printf("%sD-cache %s %db/line ",
+                           (ci->ci_cinfo[CAI_ICACHE].cai_totalsize != 0) ?
+                           ", " : " ",
+                           cbuf, ci->ci_cinfo[CAI_DCACHE].cai_linesize);
+                       switch (ci->ci_cinfo[CAI_DCACHE].cai_associativity) {
+                       case 0:
+                               printf("disabled");
+                               break;
+                       case 1:
+                               printf("direct-mapped");
+                               break;
+                       case ~0:
+                               printf("fully associative");
+                               break;
+                       default:
+                               printf("%d-way",
+                                   ci->ci_cinfo[CAI_DCACHE].cai_associativity);
+                               break;
+                       }
+               }
                printf("\n");
        }
-       if (ci->ci_l2cache_info)
-               printf("cpu0: L2 cache %s\n", ci->ci_l2cache_info->cai_string);
+       if (ci->ci_cinfo[CAI_L2CACHE].cai_totalsize) {
+               format_bytes(cbuf, sizeof(cbuf),
+                   ci->ci_cinfo[CAI_L2CACHE].cai_totalsize);
+               printf("cpu0: L2 cache %s %db/line ", cbuf,
+                   ci->ci_cinfo[CAI_L2CACHE].cai_linesize);
+               switch (ci->ci_cinfo[CAI_L2CACHE].cai_associativity) {
+               case 0:
+                       printf("disabled");
+                       break;
+               case 1:
+                       printf("direct-mapped");
+                       break;
+               case ~0:
+                       printf("fully associative");
+                       break;
+               default:
+                       printf("%d-way",
+                           ci->ci_cinfo[CAI_L2CACHE].cai_associativity);
+                       break;
+               }
+               printf("\n");
+       }
        if ((cpu_feature & CPUID_MASK1) != 0) {
                bitmask_snprintf(cpu_feature, CPUID_FLAGS1,
                    buf, sizeof(buf));
@@ -885,17 +879,74 @@
 }
 
 static const struct i386_cache_info *
-cache_info_lookup(const struct i386_cache_info *cai, u_int8_t desc)
+cache_info_lookup(const struct i386_cache_info *cai, int count, u_int8_t desc)
 {
+       int i;
 
-       for (; cai->cai_string != NULL; cai++) {
-               if (cai->cai_desc == desc)
-                       return (cai);
+       for (i = 0; i < count; i++) {
+               if (cai[i].cai_desc == desc)
+                       return (&cai[i]);
        }
 
        return (NULL);
 }
 
+static const struct i386_cache_info intel_cpuid_cache_info[] = {
+       { CAI_ITLB,
+         0x01,
+         32,           4,                      4 * 1024 },
+       { CAI_ITLB2,
+         0x02,
+         2,            1,                      4 * 1024 * 1024 },
+       { CAI_DTLB,
+         0x03,
+         64,           4,                      4 * 1024 },
+       { CAI_DTLB2,
+         0x04,
+         8,            4,                      4 * 1024 * 1024 },
+       { CAI_ICACHE,
+         0x06,
+         8 * 1024,     4,                      32 },
+       { CAI_ICACHE,
+         0x08,
+         16 * 1024,    4,                      32 },
+       { CAI_DCACHE,
+         0x0a,
+         8 * 1024,     2,                      32 },
+       { CAI_DCACHE,
+         0x0c,
+         16 * 1024,    2,                      32 },
+       { CAI_L2CACHE,
+         0x40,
+         0,            1,                      0 },
+       { CAI_L2CACHE,
+         0x41,
+         128 * 1024,   4,                      32 },
+       { CAI_L2CACHE,
+         0x42,
+         256 * 1024,   4,                      32 },
+       { CAI_L2CACHE,
+         0x43,
+         512 * 1024,   4,                      32 },
+       { CAI_L2CACHE,
+         0x44,
+         1 * 1024 * 1024, 4,                   32 },
+       { CAI_L2CACHE,
+         0x45,
+         2 * 1024 * 1024, 4,                   32 },
+       { CAI_L2CACHE,
+         0x82,
+         256 * 1024,   8,                      32 },
+       { CAI_L2CACHE,
+         0x84,
+         1 * 1024 * 1024, 8,                   32 },
+       { CAI_L2CACHE,
+         0x85,
+         2 * 1024 * 1024, 8,                   32 },
+};
+static const int intel_cpuid_cache_info_count =
+    sizeof(intel_cpuid_cache_info) / sizeof(intel_cpuid_cache_info[0]);
+
 void
 intel_cpuid_cpu_cacheinfo(struct cpu_info *ci)
 {
@@ -920,12 +971,11 @@
                                        continue;
                                desc = (descs[i] >> (j * 8)) & 0xff;
                                cai = cache_info_lookup(intel_cpuid_cache_info,
-                                   desc);
+                                   intel_cpuid_cache_info_count, desc);
                                if (cai != NULL) {
-                                       const struct i386_cache_info **cp;
-                                       cp = (const struct i386_cache_info **)
-                                           (((uint8_t *)ci) + cai->cai_offset);
-                                       *cp = cai;
+                                       memcpy(&ci->ci_cinfo[cai->cai_index],
+                                           cai,
+                                           sizeof(struct i386_cache_info));
                                }
                        }
                }
@@ -933,6 +983,206 @@
        }
 }
 
+/*
+ * AMD Cache Info:
+ *
+ *     Athlon, Duron:
+ *
+ *             Function 8000.0005 L1 TLB/Cache Information
+ *             EAX -- L1 TLB 2/4MB pages
+ *             EBX -- L1 TLB 4K pages
+ *             ECX -- L1 D-cache
+ *             EDX -- L1 I-cache
+ *
+ *             Function 8000.0006 L2 TLB/Cache Information
+ *             EAX -- L2 TLB 2/4MB pages
+ *             EBX -- L2 TLB 4K pages



Home | Main Index | Thread Index | Old Index