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