Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/x86 Re-use the unused ci_cpu_serial[3] to save the ...



details:   https://anonhg.NetBSD.org/src/rev/ff6caa861d87
branches:  trunk
changeset: 793669:ff6caa861d87
user:      dsl <dsl%NetBSD.org@localhost>
date:      Sat Feb 22 17:48:08 2014 +0000

description:
Re-use the unused ci_cpu_serial[3] to save the highest cpuid values
  for the normal and extended leafs.
(The 'normal' one might be luring in the global cpulevel.)
Read the 'extended feature' from cpuid.80000001.%ecx/edx into
    ci_feat_val[3/2] just after saving cpuid.1.%ecx/dx in ci_feat_val[1/0]
    instead of doing it separately for amd k678 and via c3 processors
    in their probe functions and repeating it for all cpus a few instructions
    later when x86_cpu_topology() is called.
x86_cpu_topology() is only called from cpu_probe() and really doesn't
  deserve its own source file. Chasing the setup code is bad enough anyway.

diffstat:

 sys/arch/x86/include/cpu.h      |  22 ++++++-----
 sys/arch/x86/x86/cpu_topology.c |  20 ++-------
 sys/arch/x86/x86/identcpu.c     |  77 +++++++++++++++++++++++-----------------
 3 files changed, 61 insertions(+), 58 deletions(-)

diffs (260 lines):

diff -r c50cdfdd4f80 -r ff6caa861d87 sys/arch/x86/include/cpu.h
--- a/sys/arch/x86/include/cpu.h        Sat Feb 22 17:29:13 2014 +0000
+++ b/sys/arch/x86/include/cpu.h        Sat Feb 22 17:48:08 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.63 2014/02/20 18:14:11 dsl Exp $     */
+/*     $NetBSD: cpu.h,v 1.64 2014/02/22 17:48:08 dsl Exp $     */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -150,18 +150,20 @@
        uint32_t ci_ipis;               /* interprocessor interrupts pending */
        uint32_t sc_apic_version;       /* local APIC version */
 
-       uint32_t        ci_signature;    /* X86 cpuid type */
+       uint32_t        ci_signature;    /* X86 cpuid type (cpuid.1.%eax) */
        uint32_t        ci_vendor[4];    /* vendor string */
-       uint32_t        ci_cpu_serial[3]; /* PIII serial number */
+       uint32_t        _unused2;
+       uint32_t        ci_max_cpuid;   /* cpuid.0:%eax */
+       uint32_t        ci_max_ext_cpuid; /* cpuid.80000000:%eax */
        volatile uint32_t       ci_lapic_counter;
 
-       uint32_t        ci_feat_val[5]; /* X86 CPUID feature bits
-                                        *      [0] basic features %edx
-                                        *      [1] basic features %ecx
-                                        *      [2] extended features %edx
-                                        *      [3] extended features %ecx
-                                        *      [4] VIA padlock features
-                                        */
+       uint32_t        ci_feat_val[5]; /* X86 CPUID feature bits */
+                       /* [0] basic features cpuid.1:%edx
+                        * [1] basic features cpuid.1:%ecx (CPUID2_xxx bits)
+                        * [2] extended features cpuid:80000001:%edx
+                        * [3] extended features cpuid:80000001:%ecx
+                        * [4] VIA padlock features
+                        */
        
        const struct cpu_functions *ci_func;  /* start/stop functions */
        struct trapframe *ci_ddb_regs;
diff -r c50cdfdd4f80 -r ff6caa861d87 sys/arch/x86/x86/cpu_topology.c
--- a/sys/arch/x86/x86/cpu_topology.c   Sat Feb 22 17:29:13 2014 +0000
+++ b/sys/arch/x86/x86/cpu_topology.c   Sat Feb 22 17:48:08 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu_topology.c,v 1.8 2013/11/15 08:47:55 msaitoh Exp $ */
+/*     $NetBSD: cpu_topology.c,v 1.9 2014/02/22 17:48:08 dsl Exp $     */
 
 /*-
  * Copyright (c) 2009 Mindaugas Rasiukevicius <rmind at NetBSD org>,
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_topology.c,v 1.8 2013/11/15 08:47:55 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_topology.c,v 1.9 2014/02/22 17:48:08 dsl Exp $");
 
 #include <sys/param.h>
 #include <sys/bitops.h>
@@ -54,7 +54,7 @@
        u_int lp_max;           /* Logical processors per package (node) */
        u_int core_max;         /* Core per package */
        int n, cpu_family, apic_id, smt_bits, core_bits = 0;
-       uint32_t descs[4], lextmode;
+       uint32_t descs[4];
 
        apic_id = ci->ci_initapicid;
        cpu_family = CPUID_TO_FAMILY(ci->ci_signature);
@@ -77,15 +77,6 @@
                return;
        }
 
-       /* Determine the extended feature flags. */
-       x86_cpuid(0x80000000, descs);
-       lextmode = descs[0];
-       if (lextmode >= 0x80000001) {
-               x86_cpuid(0x80000001, descs);
-               ci->ci_feat_val[2] = descs[3]; /* edx */
-               ci->ci_feat_val[3] = descs[2]; /* ecx */
-       }
-
        /* Check for HTT support.  See notes below regarding AMD. */
        if ((ci->ci_feat_val[0] & CPUID_HTT) != 0) {
                /* Maximum number of LPs sharing a cache (ebx[23:16]). */
@@ -98,8 +89,7 @@
        switch (cpu_vendor) {
        case CPUVENDOR_INTEL:
                /* Check for leaf 4 support. */
-               x86_cpuid(0, descs);
-               if (descs[0] >= 4) {
+               if (ci->ci_max_cpuid >= 4) {
                        /* Maximum number of Cores per package (eax[31:26]). */
                        x86_cpuid2(4, 0, descs);
                        core_max = (descs[0] >> 26) + 1;
@@ -114,7 +104,7 @@
                        break;
                }
                /* Legacy Method, LPs represent Cores. */
-               if (cpu_family < 0x10 || lextmode < 0x80000008) {
+               if (cpu_family < 0x10 || ci->ci_max_ext_cpuid < 0x80000008) {
                        core_max = lp_max;
                        break;
                }
diff -r c50cdfdd4f80 -r ff6caa861d87 sys/arch/x86/x86/identcpu.c
--- a/sys/arch/x86/x86/identcpu.c       Sat Feb 22 17:29:13 2014 +0000
+++ b/sys/arch/x86/x86/identcpu.c       Sat Feb 22 17:48:08 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: identcpu.c,v 1.39 2013/12/23 11:40:57 msaitoh Exp $    */
+/*     $NetBSD: identcpu.c,v 1.40 2014/02/22 17:48:08 dsl Exp $        */
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.39 2013/12/23 11:40:57 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.40 2014/02/22 17:48:08 dsl Exp $");
 
 #include "opt_xen.h"
 
@@ -135,7 +135,7 @@
                int ways, partitions, linesize, sets;
                int caitype = -1;
                int totalsize;
-               
+
                /* Parse the cache info from `cpuid leaf 4', if we have it. */
                for (i = 0; ; i++) {
                        x86_cpuid2(4, i, descs);
@@ -359,20 +359,11 @@
 static void
 cpu_probe_k678(struct cpu_info *ci)
 {
-       uint32_t descs[4];
 
        if (cpu_vendor != CPUVENDOR_AMD ||
            CPUID_TO_FAMILY(ci->ci_signature) < 6)
                return;
 
-       /* Determine the extended feature flags. */
-       x86_cpuid(0x80000000, descs);
-       if (descs[0] >= 0x80000001) {
-               x86_cpuid(0x80000001, descs);
-               ci->ci_feat_val[3] = descs[2]; /* %ecx */
-               ci->ci_feat_val[2] = descs[3]; /* %edx */
-       }
-
        cpu_probe_amd_cache(ci);
 }
 
@@ -515,12 +506,6 @@
        x86_cpuid(0x80000000, descs);
        lfunc = descs[0];
 
-       /* Determine the extended feature flags. */
-       if (lfunc >= 0x80000001) {
-               x86_cpuid(0x80000001, descs);
-               ci->ci_feat_val[2] = descs[3];
-       }
-
        if (family > 6 || model > 0x9 || (model == 0x9 && stepping >= 3)) {
                /* Nehemiah or Esther */
                x86_cpuid(0xc0000000, descs);
@@ -575,7 +560,7 @@
                        msr = rdmsr(MSR_VIA_ACE);
                        wrmsr(MSR_VIA_ACE, msr | MSR_VIA_ACE_ENABLE);
                    }
-                       
+
                }
        }
 
@@ -616,7 +601,7 @@
                /* Erratum: stepping 8 reports 4 when it should be 2 */
                cai->cai_associativity = 2;
        }
-       
+
        /*
         * Determine L2 cache/TLB info.
         */
@@ -712,6 +697,8 @@
 
        x86_cpuid(0, descs);
        cpuid_level = descs[0];
+       ci->ci_max_cpuid = descs[0];
+
        ci->ci_vendor[0] = descs[1];
        ci->ci_vendor[2] = descs[2];
        ci->ci_vendor[1] = descs[3];
@@ -734,18 +721,6 @@
        else
                cpu_vendor = CPUVENDOR_UNKNOWN;
 
-       x86_cpuid(0x80000000, brand);
-       if (brand[0] >= 0x80000004) {
-               x86_cpuid(0x80000002, brand);
-               x86_cpuid(0x80000003, brand + 4);
-               x86_cpuid(0x80000004, brand + 8);
-               for (i = 0; i < 48; i++) {
-                       if (((char *) brand)[i] != ' ')
-                               break;
-               }
-               memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i);
-       }
-
        if (cpuid_level >= 1) {
                x86_cpuid(1, descs);
                ci->ci_signature = descs[0];
@@ -765,6 +740,36 @@
                ci->ci_initapicid = (miscbytes >> 24) & 0xff;
        }
 
+       /*
+        * Get the basic information from the extended cpuid leafs.
+        * These were first implemented by amd, but most of the values
+        * match with those generated by modern intel cpus.
+        */
+       x86_cpuid(0x80000000, descs);
+       if (descs[0] == 0x80000000)
+               ci->ci_max_ext_cpuid = descs[0];
+       else
+               ci->ci_max_ext_cpuid = 0;
+
+       if (ci->ci_max_ext_cpuid >= 0x80000001) {
+               /* Determine the extended feature flags. */
+               x86_cpuid(0x80000001, descs);
+               ci->ci_feat_val[3] = descs[2]; /* %ecx */
+               ci->ci_feat_val[2] = descs[3]; /* %edx */
+       }
+
+       if (ci->ci_max_ext_cpuid >= 0x80000004) {
+               x86_cpuid(0x80000002, brand);
+               x86_cpuid(0x80000003, brand + 4);
+               x86_cpuid(0x80000004, brand + 8);
+               /* Skip leading spaces on brand */
+               for (i = 0; i < 48; i++) {
+                       if (((char *) brand)[i] != ' ')
+                               break;
+               }
+               memcpy(cpu_brand_string, ((char *) brand) + i, 48 - i);
+       }
+
        cpu_probe_intel(ci);
        cpu_probe_k5(ci);
        cpu_probe_k678(ci);
@@ -873,7 +878,13 @@
                        i386_has_sse = 1;
                if (cpu_feature[0] & CPUID_SSE2)
                        i386_has_sse2 = 1;
-       } else
+       } else {
                i386_use_fxsave = 0;
+       }
+#else
+       /*
+        * i386_use_fxsave, i386_has_sse and i386_has_sse2 are
+        * #defined to 1.
+        */
 #endif /* i386 */
 }



Home | Main Index | Thread Index | Old Index