Module Name:    src
Committed By:   dsl
Date:           Sat Jan  5 15:27:46 UTC 2013

Modified Files:
        src/usr.sbin/cpuctl/arch: i386-asm.S i386.c
Added Files:
        src/usr.sbin/cpuctl/arch: cpuctl_i386.h

Log Message:
Change the i386 asm x86_identify() so it returns a value instead of writing
into global data.
Fix a stack alignment fubar that would cause a crash on a cirix 486.
Refactor identify code to common setup for normal identify and ucode
identify - which was missing a memset().


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/usr.sbin/cpuctl/arch/cpuctl_i386.h
cvs rdiff -u -r1.1 -r1.2 src/usr.sbin/cpuctl/arch/i386-asm.S
cvs rdiff -u -r1.33 -r1.34 src/usr.sbin/cpuctl/arch/i386.c

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

Modified files:

Index: src/usr.sbin/cpuctl/arch/i386-asm.S
diff -u src/usr.sbin/cpuctl/arch/i386-asm.S:1.1 src/usr.sbin/cpuctl/arch/i386-asm.S:1.2
--- src/usr.sbin/cpuctl/arch/i386-asm.S:1.1	Mon May  5 17:54:14 2008
+++ src/usr.sbin/cpuctl/arch/i386-asm.S	Sat Jan  5 15:27:45 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: i386-asm.S,v 1.1 2008/05/05 17:54:14 ad Exp $	*/
+/*	$NetBSD: i386-asm.S,v 1.2 2013/01/05 15:27:45 dsl Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2004, 2006, 2007 The NetBSD Foundation, Inc.
@@ -30,15 +30,6 @@
 #include <machine/cputypes.h>
 #include <machine/psl.h>
 
-	.data
-
-_C_LABEL(cpu):
-	.long	0
-	.globl	_C_LABEL(cpu)
-_C_LABEL(cpu_info_level):
-	.long	-1
-	.globl	_C_LABEL(cpu_info_level)
-
 	.text
 
 ENTRY(x86_cpuid2)
@@ -58,7 +49,6 @@ ENTRY(x86_cpuid2)
 END(x86_cpuid2)
 
 ENTRY(x86_identify)
-	pushl	%ebx
 	/* Try to toggle alignment check flag; does not exist on 386. */
 	pushfl
 	popl	%eax
@@ -91,11 +81,11 @@ isnx586:
 	 * Don't try cpuid, as Nx586s reportedly don't support the
 	 * PSL_ID bit.
 	 */
-	movl	$CPU_NX586,_C_LABEL(cpu)
-	jmp	2f
+	movl	$CPU_NX586,%eax
+	ret
 is386:
-	movl	$CPU_386,_C_LABEL(cpu)
-	jmp	2f
+	movl	$CPU_386,%eax
+	ret
 
 try486:	/* Try to toggle identification flag; does not exist on early 486s. */
 	pushfl
@@ -112,8 +102,13 @@ try486:	/* Try to toggle identification 
 	popfl
 
 	testl	%eax,%eax
-	jnz	try586
-is486:	movl	$CPU_486,_C_LABEL(cpu)
+	jz	is486
+
+	/* Later cpu, caller will use cpuid instruction */
+	movl	$-1,%eax
+	ret
+
+is486:
 	/*
 	 * Check Cyrix CPU
 	 * Cyrix CPUs do not change the undefined flags following
@@ -129,9 +124,11 @@ is486:	movl	$CPU_486,_C_LABEL(cpu)
 	divl	%ecx
 	jnc	trycyrix486
 	popfl
-	jmp 2f
+	movl	$CPU_486,%eax
+	ret
+
 trycyrix486:
-	movl	$CPU_6x86,_C_LABEL(cpu)	# set CPU type
+	popfl
 	/*
 	 * Check for Cyrix 486 CPU by seeing if the flags change during a
 	 * divide. This is documented in the Cx486SLC/e SMM Programmer's
@@ -139,6 +136,7 @@ trycyrix486:
 	 */
 	xorl	%edx,%edx
 	cmpl	%edx,%edx		# set flags to known state
+	pushl	%ebx
 	pushfl
 	popl	%ecx			# store flags in ecx
 	movl	$-1,%eax
@@ -146,15 +144,13 @@ trycyrix486:
 	divl	%ebx			# do a long division
 	pushfl
 	popl	%eax
+	popl	%ebx
 	xorl	%ecx,%eax		# are the flags different?
 	testl	$0x8d5,%eax		# only check C|PF|AF|Z|N|V
-	jne	2f			# yes; must be Cyrix 6x86 CPU
-	movl	$CPU_486DLC,_C_LABEL(cpu)# set CPU type
-	jmp	2f
-try586:	/* Use the `cpuid' instruction. */
-	xorl	%eax,%eax
-	cpuid
-	movl	%eax,_C_LABEL(cpu_info_level)
-2:
-	popl	%ebx
+	je	is486dlc		# yes => must be Cyrix 6x86 CPU
+	movl	$CPU_6x86,%eax
+	ret
+
+is486dlc:
+	movl	$CPU_486DLC,%eax
 	ret

Index: src/usr.sbin/cpuctl/arch/i386.c
diff -u src/usr.sbin/cpuctl/arch/i386.c:1.33 src/usr.sbin/cpuctl/arch/i386.c:1.34
--- src/usr.sbin/cpuctl/arch/i386.c:1.33	Wed Jan  2 19:24:30 2013
+++ src/usr.sbin/cpuctl/arch/i386.c	Sat Jan  5 15:27:45 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: i386.c,v 1.33 2013/01/02 19:24:30 dsl Exp $	*/
+/*	$NetBSD: i386.c,v 1.34 2013/01/05 15:27:45 dsl Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: i386.c,v 1.33 2013/01/02 19:24:30 dsl Exp $");
+__RCSID("$NetBSD: i386.c,v 1.34 2013/01/05 15:27:45 dsl Exp $");
 #endif /* not lint */
 
 #include <sys/types.h>
@@ -84,18 +84,15 @@ __RCSID("$NetBSD: i386.c,v 1.33 2013/01/
 #include <x86/cpu_ucode.h>
 
 #include "../cpuctl.h"
+#include "cpuctl_i386.h"
 
 /* Size of buffer for printing humanized numbers */
 #define HUMAN_BUFSIZE sizeof("999KB")
 
-#define       x86_cpuid(a,b)  x86_cpuid2((a),0,(b))
-
-void	x86_cpuid2(uint32_t, uint32_t, uint32_t *);
-void	x86_identify(void);
-
 struct cpu_info {
 	const char	*ci_dev;
-	int32_t		ci_cpuid_level;
+	int32_t		ci_cpu_type;     /* for cpu's without cpuid */
+	int32_t		ci_cpuid_level;	 /* highest cpuid supported */
 	uint32_t	ci_signature;	 /* X86 cpuid type */
 	uint32_t	ci_feat_val[5];	 /* X86 CPUID feature bits
 					  *	[0] basic features %edx
@@ -985,7 +982,7 @@ amd_amd64_name(struct cpu_info *ci)
 }
 
 static void
-cpu_probe_base_features(struct cpu_info *ci)
+cpu_probe_base_features(struct cpu_info *ci, const char *cpuname)
 {
 	const struct x86_cache_info *cai;
 	u_int descs[4];
@@ -994,8 +991,15 @@ cpu_probe_base_features(struct cpu_info 
 	uint32_t miscbytes;
 	uint32_t brand[12];
 
-	if (ci->ci_cpuid_level < 0)
+	memset(ci, 0, sizeof(*ci));
+	ci->ci_dev = cpuname;
+
+	ci->ci_cpu_type = x86_identify();
+	if (ci->ci_cpu_type >= 0) {
+		/* Old pre-cpuid instruction cpu */
+		ci->ci_cpuid_level = -1;
 		return;
+	}
 
 	x86_cpuid(0, descs);
 	ci->ci_cpuid_level = descs[0];
@@ -1078,8 +1082,6 @@ cpu_probe_features(struct cpu_info *ci)
 	const struct cpu_cpuid_nameclass *cpup = NULL;
 	int i, xmax, family;
 
-	cpu_probe_base_features(ci);
-
 	if (ci->ci_cpuid_level < 1)
 		return;
 
@@ -1246,8 +1248,6 @@ identifycpu(int fd, const char *cpuname)
 	const struct cpu_cpuid_family *cpufam;
 	const char *feature_str[5];
 	struct cpu_info *ci, cistore;
-	extern int cpu;
-	extern int cpu_info_level;
 	size_t sz;
 	char buf[512];
 	char *bp;
@@ -1258,21 +1258,17 @@ identifycpu(int fd, const char *cpuname)
 	} ucvers;
 
 	ci = &cistore;
-	memset(ci, 0, sizeof(*ci));
-	ci->ci_dev = cpuname;
-
-	x86_identify();
-	ci->ci_cpuid_level = cpu_info_level;
+	cpu_probe_base_features(ci, cpuname);
 	cpu_probe_features(ci);
 
-	if (ci->ci_cpuid_level == -1) {
-		if ((size_t)cpu >= __arraycount(i386_nocpuid_cpus))
-			errx(1, "unknown cpu type %d", cpu);
-		name = i386_nocpuid_cpus[cpu].cpu_name;
-		cpu_vendor = i386_nocpuid_cpus[cpu].cpu_vendor;
-		vendorname = i386_nocpuid_cpus[cpu].cpu_vendorname;
-		class = i386_nocpuid_cpus[cpu].cpu_class;
-		ci->ci_info = i386_nocpuid_cpus[cpu].cpu_info;
+	if (ci->ci_cpu_type >= 0) {
+		if (ci->ci_cpu_type >= (int)__arraycount(i386_nocpuid_cpus))
+			errx(1, "unknown cpu type %d", ci->ci_cpu_type);
+		name = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_name;
+		cpu_vendor = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_vendor;
+		vendorname = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_vendorname;
+		class = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_class;
+		ci->ci_info = i386_nocpuid_cpus[ci->ci_cpu_type].cpu_info;
 		modifier = "";
 	} else {
 		xmax = __arraycount(i386_cpuid_cpus);
@@ -1468,7 +1464,7 @@ identifycpu(int fd, const char *cpuname)
 		errx(1, "NetBSD requires an 80486 or later processor");
 	}
 
-	if (cpu == CPU_486DLC) {
+	if (ci->ci_cpu_type == CPU_486DLC) {
 #ifndef CYRIX_CACHE_WORKS
 		aprint_error("WARNING: CYRIX 486DLC CACHE UNCHANGED.\n");
 #else
@@ -2026,11 +2022,9 @@ ucodeupdate_check(int fd, struct cpu_uco
 	struct cpu_info ci;
 	int loader_version, res;
 	struct cpu_ucode_version versreq;
-	extern int cpu_info_level;
 
-	x86_identify();
-	ci.ci_cpuid_level = cpu_info_level;
-	cpu_probe_base_features(&ci);
+	cpu_probe_base_features(&ci, "unknown");
+
 	if (!strcmp((char *)ci.ci_vendor, "AuthenticAMD"))
 		loader_version = CPU_UCODE_LOADER_AMD;
 	else if (!strcmp((char *)ci.ci_vendor, "GenuineIntel"))

Added files:

Index: src/usr.sbin/cpuctl/arch/cpuctl_i386.h
diff -u /dev/null src/usr.sbin/cpuctl/arch/cpuctl_i386.h:1.1
--- /dev/null	Sat Jan  5 15:27:46 2013
+++ src/usr.sbin/cpuctl/arch/cpuctl_i386.h	Sat Jan  5 15:27:45 2013
@@ -0,0 +1,8 @@
+/*      $NetBSD: cpuctl_i386.h,v 1.1 2013/01/05 15:27:45 dsl Exp $      */
+
+/* Interfaces to code in i386-asm.S */
+
+#define	x86_cpuid(a,b)	x86_cpuid2((a),0,(b))
+
+void x86_cpuid2(uint32_t, uint32_t, uint32_t *);
+uint32_t x86_identify(void);

Reply via email to