Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.sbin/cpuctl/arch Change the i386 asm x86_identify() so i...
details: https://anonhg.NetBSD.org/src/rev/c711f7516d1b
branches: trunk
changeset: 783711:c711f7516d1b
user: dsl <dsl%NetBSD.org@localhost>
date: Sat Jan 05 15:27:45 2013 +0000
description:
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().
diffstat:
usr.sbin/cpuctl/arch/cpuctl_i386.h | 8 +++++
usr.sbin/cpuctl/arch/i386-asm.S | 52 +++++++++++++++------------------
usr.sbin/cpuctl/arch/i386.c | 58 +++++++++++++++++--------------------
3 files changed, 58 insertions(+), 60 deletions(-)
diffs (260 lines):
diff -r f22a25f4e4ce -r c711f7516d1b usr.sbin/cpuctl/arch/cpuctl_i386.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr.sbin/cpuctl/arch/cpuctl_i386.h Sat Jan 05 15:27:45 2013 +0000
@@ -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);
diff -r f22a25f4e4ce -r c711f7516d1b usr.sbin/cpuctl/arch/i386-asm.S
--- a/usr.sbin/cpuctl/arch/i386-asm.S Sat Jan 05 15:26:59 2013 +0000
+++ b/usr.sbin/cpuctl/arch/i386-asm.S Sat Jan 05 15:27:45 2013 +0000
@@ -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 @@
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 @@
* 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 @@
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 @@
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 @@
*/
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 @@
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
diff -r f22a25f4e4ce -r c711f7516d1b usr.sbin/cpuctl/arch/i386.c
--- a/usr.sbin/cpuctl/arch/i386.c Sat Jan 05 15:26:59 2013 +0000
+++ b/usr.sbin/cpuctl/arch/i386.c Sat Jan 05 15:27:45 2013 +0000
@@ -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 @@
#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 @@
}
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 @@
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 @@
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 @@
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 @@
} 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 @@
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 @@
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"))
Home |
Main Index |
Thread Index |
Old Index