Source-Changes-HG archive

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

[src/trunk]: src/sys Fix "hard reboot" problem reported by Rhialto weeks ago ...



details:   https://anonhg.NetBSD.org/src/rev/cc276329e55e
branches:  trunk
changeset: 587757:cc276329e55e
user:      xtraeme <xtraeme%NetBSD.org@localhost>
date:      Fri Feb 03 02:37:57 2006 +0000

description:
Fix "hard reboot" problem reported by Rhialto weeks ago on current-users@.
The problem was that pnowk7_init() was called too early in the boot
process, at this point the required calls were not available.

Thanks to Rhialto for testing and cube/christos for comments.

diffstat:

 sys/arch/i386/i386/identcpu.c                 |  11 +++-
 sys/arch/i386/i386/powernow_k7.c              |  63 +++++++++++++-------------
 sys/arch/i386/include/cpu.h                   |   5 +-
 sys/lkm/arch/i386/powernow/lkminit_powernow.c |  11 ++--
 4 files changed, 49 insertions(+), 41 deletions(-)

diffs (249 lines):

diff -r 25d75852a4cc -r cc276329e55e sys/arch/i386/i386/identcpu.c
--- a/sys/arch/i386/i386/identcpu.c     Fri Feb 03 02:01:19 2006 +0000
+++ b/sys/arch/i386/i386/identcpu.c     Fri Feb 03 02:37:57 2006 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: identcpu.c,v 1.27 2006/01/15 04:14:31 xtraeme Exp $    */
+/*     $NetBSD: identcpu.c,v 1.28 2006/02/03 02:37:57 xtraeme Exp $    */
 
 /*-
  * Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.27 2006/01/15 04:14:31 xtraeme Exp $");
+__KERNEL_RCSID(0, "$NetBSD: identcpu.c,v 1.28 2006/02/03 02:37:57 xtraeme Exp $");
 
 #include "opt_cputype.h"
 #include "opt_enhanced_speedstep.h"
@@ -882,7 +882,7 @@
        }
 
 #ifdef POWERNOW_K7
-       pnowk7_init(ci);
+       pnowk7_probe(ci);
 #endif
 
        if (*cpu_brand_string == '\0')
@@ -1434,4 +1434,9 @@
                            cpuname);
        }
 #endif /* ENHANCED_SPEEDSTEP */
+
+#ifdef POWERNOW_K7
+       pnowk7_init(ci);
+#endif /* POWERNOW_k7 */
+
 }
diff -r 25d75852a4cc -r cc276329e55e sys/arch/i386/i386/powernow_k7.c
--- a/sys/arch/i386/i386/powernow_k7.c  Fri Feb 03 02:01:19 2006 +0000
+++ b/sys/arch/i386/i386/powernow_k7.c  Fri Feb 03 02:37:57 2006 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: powernow_k7.c,v 1.5 2006/01/19 23:28:12 xtraeme Exp $ */
+/* $NetBSD: powernow_k7.c,v 1.6 2006/02/03 02:37:57 xtraeme Exp $ */
 
 /*
  * Copyright (c) 2004 Martin Végiard.
@@ -32,7 +32,7 @@
 /* Sysctl related code was adapted from NetBSD's i386/est.c for compatibility */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: powernow_k7.c,v 1.5 2006/01/19 23:28:12 xtraeme Exp $");
+__KERNEL_RCSID(0, "$NetBSD: powernow_k7.c,v 1.6 2006/02/03 02:37:57 xtraeme Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -122,8 +122,9 @@
 static int             powernow_node_target, powernow_node_current;
 static char            *freq_names;
 static size_t          freq_names_len;
+static int             powernow_cpu;
 
-#if defined(_LKM)
+#ifdef _LKM
 #define SYSCTLLOG      &sysctllog
 #else
 #define SYSCTLLOG      NULL
@@ -133,7 +134,6 @@
 struct state_s *pnowk7_getstates(cpuid_t cpuid);
 int pnowk7_setstate(unsigned int freq);
 static int powernow_sysctl_helper(SYSCTLFN_PROTO);
-uint8_t pnowk7_probe(struct cpu_info *);
 void pnowk7_destroy(void);
 
 static int
@@ -283,36 +283,24 @@
        return 0;
 }
 
-uint8_t
+void
 pnowk7_probe(struct cpu_info *ci)
 {
-       uint32_t lfunc, descs[4];
-       unsigned int i;
-       char *cpuname;
+       uint32_t descs[4];
 
-       ci = curcpu();
-       cpuname = ci->ci_dev->dv_xname;
+       CPUID(0x80000000, descs[0], descs[1], descs[2], descs[3]);
 
-       CPUID(0x80000000, lfunc, descs[1], descs[2], descs[3]);
-
-       if (lfunc >= 0x80000007) {
+       if (descs[0] >= 0x80000007) {
                CPUID(0x80000007, descs[0], descs[1], descs[2], descs[3]);
                if (descs[3] & 0x06) {
-                       aprint_normal("%s: AMD PowerNow! Technology.\n",
-                           cpuname);
-                       aprint_normal("%s: AMD features:", cpuname);
-                       for (i = 0; pnow_extflag[i].name != NULL; i++) {
-                               if (descs[3] & pnow_extflag[i].mask)
-                                       aprint_normal(" %s",
-                                           pnow_extflag[i].name);
+                       if ((ci->ci_signature & 0xF00) == 0x600) {
+                               powernow_cpu = descs[3]; /* found */
+                               return;
                        }
-                       aprint_normal("\n");
-                       if ((ci->ci_signature & 0xF00) == 0x600)
-                               return 1; /* found */
                }
        }
 
-       return 0; /* not compatible */
+       powernow_cpu = 0; /* not compatible */
 }
 
 
@@ -321,7 +309,7 @@
 {
        const struct sysctlnode *node, *pnownode, *freqnode;
        struct state_s *s;
-       unsigned int i;
+       unsigned int i, j;
        int rc;
        char *cpuname;
        size_t len;
@@ -329,11 +317,20 @@
        len = freq_names_len = 0;
        s = NULL;
 
-       if (pnowk7_probe(ci) == 0)
+       if (powernow_cpu == 0)
                return;
 
+       cpuname = ci->ci_dev->dv_xname;
+
+       aprint_normal("%s: AMD Power Management features:", cpuname);
+       for (j = 0; pnow_extflag[j].name != NULL; j++) {
+               if (powernow_cpu & pnow_extflag[j].mask)
+                       aprint_normal(" %s", pnow_extflag[j].name);
+       }
+
+       powernow_cpu = 0;
+
        s = pnowk7_getstates(ci->ci_signature);
-       cpuname = ci->ci_dev->dv_xname;
 
        freq_names_len =  n_states * (sizeof("9999 ")-1) + 1;
        freq_names = malloc(freq_names_len, M_SYSCTLDATA, M_WAITOK);
@@ -405,6 +402,8 @@
            CTL_CREATE, CTL_EOL)) != 0)
                 goto err;
 
+       aprint_normal("\n");
+       aprint_normal("%s: AMD PowerNow! Technology\n", cpuname);
        aprint_normal("%s: available frequencies (Mhz): %s\n",
            cpuname, freq_names);
         aprint_normal("%s: current frequency (Mhz): %d\n", cpuname, cur_freq);
@@ -419,12 +418,14 @@
 void
 pnowk7_destroy(void)
 {
-       sysctl_teardown(&sysctllog);
-#if defined(_LKM)
-       if (freq_names != NULL)
+#ifdef _LKM
+       sysctl_teardown(SYSCTLLOG);
+#endif
+       if (freq_names)
                free(freq_names, M_SYSCTLDATA);
 
-       if (freq_table != NULL) 
+#ifdef _LKM
+       if (freq_table) 
                free(freq_table, M_TEMP);
 #endif
 }
diff -r 25d75852a4cc -r cc276329e55e sys/arch/i386/include/cpu.h
--- a/sys/arch/i386/include/cpu.h       Fri Feb 03 02:01:19 2006 +0000
+++ b/sys/arch/i386/include/cpu.h       Fri Feb 03 02:37:57 2006 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu.h,v 1.121 2005/12/31 17:55:55 xtraeme Exp $        */
+/*     $NetBSD: cpu.h,v 1.122 2006/02/03 02:37:57 xtraeme Exp $        */
 
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
@@ -425,7 +425,8 @@
 /* est.c */
 void   est_init(struct cpu_info *);
 
-/* pnow_k7.c */
+/* powernow_k7.c */
+void   pnowk7_probe(struct cpu_info *);
 void   pnowk7_init(struct cpu_info *);
 
 #endif /* _KERNEL */
diff -r 25d75852a4cc -r cc276329e55e sys/lkm/arch/i386/powernow/lkminit_powernow.c
--- a/sys/lkm/arch/i386/powernow/lkminit_powernow.c     Fri Feb 03 02:01:19 2006 +0000
+++ b/sys/lkm/arch/i386/powernow/lkminit_powernow.c     Fri Feb 03 02:37:57 2006 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lkminit_powernow.c,v 1.2 2006/01/15 04:12:09 xtraeme Exp $     */
+/*     $NetBSD: lkminit_powernow.c,v 1.3 2006/02/03 02:37:57 xtraeme Exp $     */
 
 /*
  * Derived from:
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lkminit_powernow.c,v 1.2 2006/01/15 04:12:09 xtraeme Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lkminit_powernow.c,v 1.3 2006/02/03 02:37:57 xtraeme Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -47,11 +47,10 @@
 
 int powernow_lkmentry(struct lkm_table *, int, int);
 static int powernow_mod_handle(struct lkm_table *, int);
+void pnowk7_destroy(void);
 
 MOD_MISC("powernow");
 
-void pnowk7_destroy(void);
-
 /*
  * This function is called each time the module is loaded or unloaded.
  * Since we are a miscellaneous module, we have to provide whatever
@@ -65,8 +64,8 @@
 static int
 powernow_mod_handle(struct lkm_table *lkmtp, int cmd)
 {
+       struct cpu_info *ci;
        int err = 0;    /* default = success */
-       struct cpu_info *ci;
 
        switch (cmd) {
        case LKM_E_LOAD:
@@ -77,7 +76,9 @@
                        return EEXIST;
        
                ci = curcpu();
+               pnowk7_probe(ci);
                pnowk7_init(ci);
+
                break;          /* Success */
 
        case LKM_E_UNLOAD:



Home | Main Index | Thread Index | Old Index