Module Name:    src
Committed By:   dsl
Date:           Sat Feb 22 17:48:08 UTC 2014

Modified Files:
        src/sys/arch/x86/include: cpu.h
        src/sys/arch/x86/x86: cpu_topology.c identcpu.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.63 -r1.64 src/sys/arch/x86/include/cpu.h
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/x86/x86/cpu_topology.c
cvs rdiff -u -r1.39 -r1.40 src/sys/arch/x86/x86/identcpu.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/include/cpu.h
diff -u src/sys/arch/x86/include/cpu.h:1.63 src/sys/arch/x86/include/cpu.h:1.64
--- src/sys/arch/x86/include/cpu.h:1.63	Thu Feb 20 18:14:11 2014
+++ src/sys/arch/x86/include/cpu.h	Sat Feb 22 17:48:08 2014
@@ -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 @@ struct cpu_info {
 	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;

Index: src/sys/arch/x86/x86/cpu_topology.c
diff -u src/sys/arch/x86/x86/cpu_topology.c:1.8 src/sys/arch/x86/x86/cpu_topology.c:1.9
--- src/sys/arch/x86/x86/cpu_topology.c:1.8	Fri Nov 15 08:47:55 2013
+++ src/sys/arch/x86/x86/cpu_topology.c	Sat Feb 22 17:48:08 2014
@@ -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 @@ x86_cpu_topology(struct cpu_info *ci)
 	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 @@ x86_cpu_topology(struct cpu_info *ci)
 		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 @@ x86_cpu_topology(struct cpu_info *ci)
 	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 @@ x86_cpu_topology(struct cpu_info *ci)
 			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;
 		}

Index: src/sys/arch/x86/x86/identcpu.c
diff -u src/sys/arch/x86/x86/identcpu.c:1.39 src/sys/arch/x86/x86/identcpu.c:1.40
--- src/sys/arch/x86/x86/identcpu.c:1.39	Mon Dec 23 11:40:57 2013
+++ src/sys/arch/x86/x86/identcpu.c	Sat Feb 22 17:48:08 2014
@@ -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 @@ cpu_probe_intel_cache(struct cpu_info *c
 		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 @@ cpu_probe_k5(struct cpu_info *ci)
 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 @@ cpu_probe_c3(struct cpu_info *ci)
 	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 @@ cpu_probe_c3(struct cpu_info *ci)
 			msr = rdmsr(MSR_VIA_ACE);
 			wrmsr(MSR_VIA_ACE, msr | MSR_VIA_ACE_ENABLE);
 		    }
-			
+
 		}
 	}
 
@@ -616,7 +601,7 @@ cpu_probe_c3(struct cpu_info *ci)
 		/* Erratum: stepping 8 reports 4 when it should be 2 */
 		cai->cai_associativity = 2;
 	}
-	
+
 	/*
 	 * Determine L2 cache/TLB info.
 	 */
@@ -712,6 +697,8 @@ cpu_probe(struct cpu_info *ci)
 
 	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 @@ cpu_probe(struct cpu_info *ci)
 	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 @@ cpu_probe(struct cpu_info *ci)
 		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 @@ cpu_identify(struct cpu_info *ci)
 			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 */
 }

Reply via email to