Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/powerpc fix ofppc/pegasosII (and maybe others).



details:   https://anonhg.NetBSD.org/src/rev/f784ff30ed0a
branches:  trunk
changeset: 829184:f784ff30ed0a
user:      mrg <mrg%NetBSD.org@localhost>
date:      Sun Jan 21 08:46:48 2018 +0000

description:
fix ofppc/pegasosII (and maybe others).

don't assume PPC_OEA64_BRIDGE means we have a 64 bit cpu (code
for 64 bit in bridge and normal 32 bit can co-exist due to
fixups the early boot code does has, and ofppc builds GENERIC
this way):
- fix mtmsr()/mfmsr() to use the right method based upon the
  actually cpu booted on.
- fix cpu_setup() to have 32 bit and 64 bit hid0 variables
  and operate on the right one based upon the current cpu.
  restore a minor optimisation of not writing hid0 if it
  didn't change.

in set_timebase() check if OF_finddevice("/cpus/@0") failed
and returned -1 before using it for OF_getprop().

diffstat:

 sys/arch/powerpc/include/spr.h        |  102 +++++++++++++++++++++++----------
 sys/arch/powerpc/oea/cpu_subr.c       |   79 +++++++++++++++++---------
 sys/arch/powerpc/oea/ofwoea_machdep.c |    9 +-
 3 files changed, 127 insertions(+), 63 deletions(-)

diffs (293 lines):

diff -r 29da84aef87d -r f784ff30ed0a sys/arch/powerpc/include/spr.h
--- a/sys/arch/powerpc/include/spr.h    Sun Jan 21 08:33:46 2018 +0000
+++ b/sys/arch/powerpc/include/spr.h    Sun Jan 21 08:46:48 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: spr.h,v 1.48 2018/01/20 03:50:28 simonb Exp $  */
+/*     $NetBSD: spr.h,v 1.49 2018/01/21 08:46:48 mrg Exp $     */
 
 /*
  * Copyright (c) 2001, The NetBSD Foundation, Inc.
@@ -29,50 +29,90 @@
 #define        _POWERPC_SPR_H_
 
 #ifndef _LOCORE
-#ifdef PPC_OEA64_BRIDGE
+
+#include <powerpc/oea/cpufeat.h>
 
+#if defined(PPC_OEA64_BRIDGE) || defined (_ARCH_PPC64)
 static inline uint64_t
-mfspr(int reg)
+mfspr64(int reg)
 {
        uint64_t ret;
        register_t h, l;
-       __asm volatile( "mfspr %0,%2;" \
-                       "srdi %1,%0,32;" \
+
+       __asm volatile( "mfspr %0,%2;"
+                       "srdi %1,%0,32;"
                         : "=r"(l), "=r"(h) : "K"(reg));
        ret = ((uint64_t)h << 32) | l;
        return ret;
 }
 
-#define mtspr(reg, v) \
-( {                                            \
-       volatile register_t h, l;               \
-       uint64_t val = v;                       \
-       h = (val >> 32);                        \
-       l = val & 0xffffffff;                   \
-       __asm volatile( \
-                       "sldi %2,%2,32;" \
-                       "or %2,%2,%1;" \
-                       "sync;" \
-                       "mtspr %0,%2;" \
-                       "mfspr %1,%0;" \
-                       "mfspr %1,%0;" \
-                       "mfspr %1,%0;" \
-                       "mfspr %1,%0;" \
-                       "mfspr %1,%0;" \
-                       "mfspr %1,%0;" \
-                        : : "K"(reg), "r"(l), "r"(h)); \
+/* This as an inline breaks as 'reg' ends up not being an immediate */
+#define mtspr64(reg, v)                                                \
+( {                                                            \
+       volatile register_t h, l;                               \
+                                                               \
+       uint64_t val = v;                                       \
+       h = (val >> 32);                                        \
+       l = val & 0xffffffff;                                   \
+       __asm volatile( "sldi %2,%2,32;"                        \
+                       "or %2,%2,%1;"                          \
+                       "sync;"                                 \
+                       "mtspr %0,%2;"                          \
+                       "mfspr %2,%0;"                          \
+                       "mfspr %2,%0;"                          \
+                       "mfspr %2,%0;"                          \
+                       "mfspr %2,%0;"                          \
+                       "mfspr %2,%0;"                          \
+                       "mfspr %2,%0;"                          \
+                        : : "K"(reg), "r"(l), "r"(h));         \
 } )
+#endif /* PPC_OEA64_BRIDGE || _ARCH_PPC64 */
 
+static inline uint64_t
+mfspr32(int reg)
+{
+       register_t val;
+
+       __asm volatile("mfspr %0,%1" : "=r"(val) : "K"(reg));
+       return val;
+}
+
+static inline void
+mtspr32(int reg, uint32_t val)
+{
+
+       __asm volatile("mtspr %0,%1" : : "K"(reg), "r"(val));
+}
+
+#if (defined(PPC_OEA) + defined(PPC_OEA64) + defined(PPC_OEA64_BRIDGE)) > 1
+static inline uint64_t
+mfspr(int reg)
+{
+       if ((oeacpufeat & OEACPU_64_BRIDGE) != 0)
+               return mfspr64(reg);
+       return mfspr32(reg);
+}
+
+/* This as an inline breaks as 'reg' ends up not being an immediate */
+#define mtspr(reg, val)                                                \
+( {                                                            \
+       if ((oeacpufeat & OEACPU_64_BRIDGE) != 0)               \
+               mtspr64(reg, (uint64_t)val);                    \
+       else                                                    \
+               mtspr32(reg, val);                              \
+} )
+#else /* PPC_OEA + PPC_OEA64 + PPC_OEA64_BRIDGE != 1 */
+
+#if defined (PPC_OEA) || defined (PPC_OEA64_BRIDGE)
+#define mfspr(r) mfspr32(r)
+#define mtspr(r,v) mtspr32(r,v)
 #else
-#define        mtspr(reg, val)                                                 \
-       __asm volatile("mtspr %0,%1" : : "K"(reg), "r"(val))
-#ifdef __GNUC__
-#define        mfspr(reg)                                                      \
-       ( { register_t val;                                             \
-         __asm volatile("mfspr %0,%1" : "=r"(val) : "K"(reg)); \
-         val; } )
+#define mfspr(r) mfspr64(r)
+#define mtspr(r,v) mtspr64(r,v)
 #endif
-#endif /* PPC_OEA64_BRIDGE */
+
+#endif /* PPC_OEA + PPC_OEA64 + PPC_OEA64_BRIDGE > 1 */
+
 #endif /* _LOCORE */
 
 /*
diff -r 29da84aef87d -r f784ff30ed0a sys/arch/powerpc/oea/cpu_subr.c
--- a/sys/arch/powerpc/oea/cpu_subr.c   Sun Jan 21 08:33:46 2018 +0000
+++ b/sys/arch/powerpc/oea/cpu_subr.c   Sun Jan 21 08:46:48 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cpu_subr.c,v 1.87 2018/01/06 09:46:22 snj Exp $        */
+/*     $NetBSD: cpu_subr.c,v 1.88 2018/01/21 08:46:48 mrg Exp $        */
 
 /*-
  * Copyright (c) 2001 Matt Thomas.
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.87 2018/01/06 09:46:22 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.88 2018/01/21 08:46:48 mrg Exp $");
 
 #include "opt_ppcparam.h"
 #include "opt_ppccache.h"
@@ -498,11 +498,10 @@
 #if defined(PPC_OEA64_BRIDGE) || defined(_ARCH_PPC64)
        char hidbuf_u[128];
        const char *bitmasku = NULL;
+       volatile uint64_t hid64_0, hid64_0_save;
 #endif
-#if defined(PPC_OEA64_BRIDGE)
-       volatile uint64_t hid0;
-#else
-       register_t hid0;
+#if !defined(_ARCH_PPC64)
+       register_t hid0 = 0, hid0_save = 0;
 #endif
 
        pvr = mfpvr();
@@ -516,10 +515,17 @@
        /* set the cpu number */
        ci->ci_cpuid = cpu_number();
 #if defined(_ARCH_PPC64)
-       __asm volatile("mfspr %0,%1" : "=r"(hid0) : "K"(SPR_HID0));
+       __asm volatile("mfspr %0,%1" : "=r"(hid64_0) : "K"(SPR_HID0));
+       hid64_0_save = hid64_0;
 #else
-       hid0 = mfspr(SPR_HID0);
+#if defined(PPC_OEA64_BRIDGE)
+       if ((oeacpufeat & OEACPU_64_BRIDGE) != 0)
+               hid64_0_save = hid64_0 = mfspr(SPR_HID0);
+       else
 #endif
+               hid0_save = hid0 = mfspr(SPR_HID0);
+#endif
+
 
        cpu_probe_cache();
 
@@ -581,9 +587,12 @@
        case IBM970FX:
        case IBM970MP:
 #if defined(_ARCH_PPC64) || defined (PPC_OEA64_BRIDGE)
-               hid0 &= ~(HID0_64_DOZE | HID0_64_NAP | HID0_64_DEEPNAP);
-               hid0 |= HID0_64_DOZE | HID0_64_DPM | HID0_64_EX_TBEN |
-                       HID0_64_TB_CTRL | HID0_64_EN_MCHK;
+#if !defined(_ARCH_PPC64)
+               KASSERT((oeacpufeat & OEACPU_64_BRIDGE) != 0);
+#endif
+               hid64_0 &= ~(HID0_64_DOZE | HID0_64_NAP | HID0_64_DEEPNAP);
+               hid64_0 |= HID0_64_DOZE | HID0_64_DPM | HID0_64_EX_TBEN |
+                          HID0_64_TB_CTRL | HID0_64_EN_MCHK;
                powersave = 1;
                break;
 #endif
@@ -630,23 +639,37 @@
                hid0 |= HID0_ABE;
        }
 
-#if defined(_ARCH_PPC64)
-       /* ppc970 needs extra goop around writes to HID0 */
-       __asm volatile( "sync;" \
-                       "mtspr %0,%1;" \
-                       "mfspr %1,%0;" \
-                       "mfspr %1,%0;" \
-                       "mfspr %1,%0;" \
-                       "mfspr %1,%0;" \
-                       "mfspr %1,%0;" \
-                       "mfspr %1,%0;" \
-                        : : "K"(SPR_HID0), "r"(hid0));
-#else
-       mtspr(SPR_HID0, hid0);
+#if defined(_ARCH_PPC64) || defined(PPC_OEA64_BRIDGE)
+#if defined(PPC_OEA64_BRIDGE)
+       if ((oeacpufeat & OEACPU_64_BRIDGE) != 0) {
 #endif
-       __asm volatile("sync;isync");
-       
+               if (hid64_0 != hid64_0_save) {
+                       /* ppc970 needs extra goop around writes to HID0 */
+                       __asm volatile( "sync;" \
+                                       "mtspr %0,%1;" \
+                                       "mfspr %1,%0;" \
+                                       "mfspr %1,%0;" \
+                                       "mfspr %1,%0;" \
+                                       "mfspr %1,%0;" \
+                                       "mfspr %1,%0;" \
+                                       "mfspr %1,%0;" \
+                                        : : "K"(SPR_HID0), "r"(hid64_0));
+                       __asm volatile("sync;isync");
+               }
+#if defined(PPC_OEA64_BRIDGE)
+       } else {
+#endif
+#endif
 
+#if !defined(_ARCH_PPC64)
+               if (hid0 != hid0_save) {
+                       mtspr(SPR_HID0, hid0);
+                       __asm volatile("sync;isync");
+               }
+#endif
+#if defined(PPC_OEA64_BRIDGE)
+       }
+#endif
 
        switch (vers) {
        case MPC601:
@@ -674,8 +697,8 @@
        
 #if defined(PPC_OEA64_BRIDGE) || defined(_ARCH_PPC64)
        if (bitmasku != NULL) {
-               snprintb(hidbuf, sizeof hidbuf, bitmask, hid0 & 0xffffffff);
-               snprintb(hidbuf_u, sizeof hidbuf_u, bitmasku, hid0 >> 32);
+               snprintb(hidbuf, sizeof hidbuf, bitmask, hid64_0 & 0xffffffff);
+               snprintb(hidbuf_u, sizeof hidbuf_u, bitmasku, hid64_0 >> 32);
                aprint_normal_dev(self, "HID0 %s %s, powersave: %d\n",
                    hidbuf_u, hidbuf, powersave);
        } else
diff -r 29da84aef87d -r f784ff30ed0a sys/arch/powerpc/oea/ofwoea_machdep.c
--- a/sys/arch/powerpc/oea/ofwoea_machdep.c     Sun Jan 21 08:33:46 2018 +0000
+++ b/sys/arch/powerpc/oea/ofwoea_machdep.c     Sun Jan 21 08:46:48 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ofwoea_machdep.c,v 1.41 2017/09/22 04:45:56 macallan Exp $ */
+/* $NetBSD: ofwoea_machdep.c,v 1.42 2018/01/21 08:46:48 mrg Exp $ */
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ofwoea_machdep.c,v 1.41 2017/09/22 04:45:56 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ofwoea_machdep.c,v 1.42 2018/01/21 08:46:48 mrg Exp $");
 
 #include "opt_ppcarch.h"
 #include "opt_compat_netbsd.h"
@@ -318,8 +318,9 @@
        }
 
        node = OF_finddevice("/cpus/@0");
-       if (OF_getprop(node, "timebase-frequency",
-                       &ticks_per_sec, sizeof ticks_per_sec) > 0) {
+       if (node != -1 &&
+           OF_getprop(node, "timebase-frequency", &ticks_per_sec,
+                      sizeof ticks_per_sec) > 0) {
                goto found;
        }
 



Home | Main Index | Thread Index | Old Index