Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/powerpc Add a machine splhist command to give (a in...



details:   https://anonhg.NetBSD.org/src/rev/1617eca8142a
branches:  trunk
changeset: 780649:1617eca8142a
user:      matt <matt%NetBSD.org@localhost>
date:      Wed Aug 01 21:30:21 2012 +0000

description:
Add a machine splhist command to give (a incomplete) spl history.
(only the most recent are going to be accurate).

splraise(6) from 0 at 549214603
splraise(7) from 6 at 549214643 (+40)
splx(6) from 7 at 549214691 (+48)
splx(0) from 6 at 549214730 (+39)

diffstat:

 sys/arch/powerpc/booke/booke_machdep.c  |  103 +++++++++++++++++++++++++++++++-
 sys/arch/powerpc/booke/e500_intr.c      |   55 +++++++++--------
 sys/arch/powerpc/booke/trap.c           |   47 +++++++------
 sys/arch/powerpc/include/booke/cpuvar.h |    5 +-
 sys/arch/powerpc/powerpc/db_interface.c |   30 ++++----
 5 files changed, 174 insertions(+), 66 deletions(-)

diffs (truncated from 566 to 300 lines):

diff -r 32b08c38cfba -r 1617eca8142a sys/arch/powerpc/booke/booke_machdep.c
--- a/sys/arch/powerpc/booke/booke_machdep.c    Wed Aug 01 20:35:52 2012 +0000
+++ b/sys/arch/powerpc/booke/booke_machdep.c    Wed Aug 01 21:30:21 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: booke_machdep.c,v 1.15 2012/07/18 18:51:59 matt Exp $  */
+/*     $NetBSD: booke_machdep.c,v 1.16 2012/08/01 21:30:21 matt Exp $  */
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -38,7 +38,7 @@
 #define        _POWERPC_BUS_DMA_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: booke_machdep.c,v 1.15 2012/07/18 18:51:59 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: booke_machdep.c,v 1.16 2012/08/01 21:30:21 matt Exp $");
 
 #include "opt_modular.h"
 
@@ -570,3 +570,102 @@
        mtspr(SPR_DBCR1, dbcr1);
        mtspr(SPR_DBCR0, dbcr0);
 }
+
+#ifdef DIAGNOSTIC
+static inline void
+swap_data(uint64_t *data, size_t a, size_t b)
+{
+       uint64_t swap = data[a];
+       data[a] = data[b];
+       data[b] = swap;
+}
+
+static void
+sort_data(uint64_t *data, size_t count)
+{
+#if 0
+       /*
+        * Mostly classic bubble sort
+        */
+       do {
+               size_t new_count = 0;
+               for (size_t i = 1; i < count; i++) {
+                       if (tbs[i - 1] > tbs[i]) {
+                               swap_tbs(tbs, i - 1, i);
+                               new_count = i;
+                       }
+               }
+               count = new_count;
+       } while (count > 0);
+#else
+       /*
+        * Comb sort
+        */
+       size_t gap = count;
+       bool swapped = false;
+       while (gap > 1 || swapped) {
+               if (gap > 1) {
+                       /*
+                        * phi = (1 + sqrt(5)) / 2 [golden ratio]
+                        * N = 1 / (1 - e^-phi)) = 1.247330950103979
+                        *
+                        * We want to but can't use floating point to calculate
+                        *      gap = (size_t)((double)gap / N)
+                        *
+                        * So we will use the multicative inverse of N
+                        * (module 65536) to achieve the division.
+                        *
+                        * iN = 2^16 / 1.24733... = 52540
+                        * x / N == (x * iN) / 65536 
+                        */
+                       gap = (gap * 52540) / 65536;
+               }
+
+               swapped = false;
+
+               for (size_t i = 0; gap + i < count; i++) {
+                       if (data[i] > data[i + gap]) {
+                               swap_data(data, i, i + gap);
+                               swapped = true;
+                       }
+               }
+       }
+#endif
+}
+#endif
+
+void
+dump_splhist(struct cpu_info *ci, void (*pr)(const char *, ...))
+{
+#ifdef DIAGNOSTIC
+       struct cpu_softc * const cpu = ci->ci_softc;
+       uint64_t tbs[NIPL*NIPL];
+       size_t ntbs = 0;
+       for (size_t to = 0; to < NIPL; to++) {
+               for (size_t from = 0; from < NIPL; from++) {
+                       uint64_t tb = cpu->cpu_spl_tb[to][from];
+                       if (tb == 0)
+                               continue;
+                       tbs[ntbs++] = (tb << 8) | (to << 4) | from;
+               }
+       }
+       sort_data(tbs, ntbs);
+
+       if (pr == NULL)
+               pr = printf;
+       uint64_t last_tb = 0;
+       for (size_t i = 0; i < ntbs; i++) {
+               uint64_t tb = tbs[i];
+               size_t from = tb & 15;
+               size_t to = (tb >> 4) & 15;
+               tb >>= 8;
+               (*pr)("%s(%zu) from %zu at %"PRId64"",
+                    from < to ? "splraise" : "splx",
+                    to, from, tb);
+               if (last_tb && from != IPL_NONE)
+                       (*pr)(" (+%"PRId64")", tb - last_tb);
+               (*pr)("\n");
+               last_tb = tb;
+       }
+#endif
+}
diff -r 32b08c38cfba -r 1617eca8142a sys/arch/powerpc/booke/e500_intr.c
--- a/sys/arch/powerpc/booke/e500_intr.c        Wed Aug 01 20:35:52 2012 +0000
+++ b/sys/arch/powerpc/booke/e500_intr.c        Wed Aug 01 21:30:21 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: e500_intr.c,v 1.20 2012/07/18 16:45:33 matt Exp $      */
+/*     $NetBSD: e500_intr.c,v 1.21 2012/08/01 21:30:22 matt Exp $      */
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -39,7 +39,7 @@
 #define __INTR_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: e500_intr.c,v 1.20 2012/07/18 16:45:33 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: e500_intr.c,v 1.21 2012/08/01 21:30:22 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -419,6 +419,8 @@
 #endif
 };
 
+static bool wdog_barked;
+
 static inline uint32_t 
 openpic_read(struct cpu_softc *cpu, bus_size_t offset)
 {
@@ -474,21 +476,14 @@
 {
        struct cpu_softc * const cpu = ci->ci_softc;
 
-       //KASSERT(!cpu_intr_p() || ipl >= IPL_VM);
        KASSERT((curlwp->l_pflag & LP_INTR) == 0 || ipl != IPL_NONE);
-#if 0
-       u_int ctpr = ipl;
-       KASSERT(openpic_read(cpu, OPENPIC_CTPR) == ci->ci_cpl);
-#elif 0
-       u_int old_ctpr = (ci->ci_cpl >= IPL_VM ? 15 : ci->ci_cpl);
-       u_int ctpr = (ipl >= IPL_VM ? 15 : ipl);
-       KASSERT(openpic_read(cpu, OPENPIC_CTPR) == old_ctpr);
-#else
        const u_int ctpr = IPL2CTPR(ipl);
        KASSERT(openpic_read(cpu, OPENPIC_CTPR) == IPL2CTPR(ci->ci_cpl));
-#endif
        openpic_write(cpu, OPENPIC_CTPR, ctpr);
        KASSERT(openpic_read(cpu, OPENPIC_CTPR) == ctpr);
+#ifdef DIAGNOSTIC
+       cpu->cpu_spl_tb[ipl][ci->ci_cpl] = mftb();
+#endif
        ci->ci_cpl = ipl;
 }
 
@@ -502,8 +497,10 @@
 #ifdef __HAVE_FAST_SOFTINTS
        if (__predict_false(ci->ci_data.cpu_softints != 0)) {
                e500_splset(ci, IPL_HIGH);
+               wrtee(PSL_EE);
                powerpc_softint(ci, IPL_NONE,
                    (vaddr_t)__builtin_return_address(0));
+               wrtee(0);
        }
 #endif /* __HAVE_FAST_SOFTINTS */
        e500_splset(ci, IPL_NONE);
@@ -518,7 +515,7 @@
        const int old_ipl = ci->ci_cpl;
 
        /* if we paniced because of watchdog, PSL_CE will be clear.  */
-       KASSERT(panicstr != NULL || (mfmsr() & PSL_CE));
+       KASSERT(wdog_barked || (mfmsr() & PSL_CE));
 
        if (ipl == old_ipl)
                return;
@@ -536,8 +533,10 @@
        const u_int softints = ci->ci_data.cpu_softints & (IPL_SOFTMASK << ipl);
        if (__predict_false(softints != 0)) {
                e500_splset(ci, IPL_HIGH);
+               wrtee(msr);
                powerpc_softint(ci, ipl,
                    (vaddr_t)__builtin_return_address(0));
+               wrtee(0);
        }
 #endif /* __HAVE_FAST_SOFTINTS */
        e500_splset(ci, ipl);
@@ -555,13 +554,13 @@
        const int old_ipl = ci->ci_cpl;
 
        /* if we paniced because of watchdog, PSL_CE will be clear.  */
-       KASSERT(panicstr != NULL || (mfmsr() & PSL_CE));
+       KASSERT(wdog_barked || (mfmsr() & PSL_CE));
 
        if (old_ipl < ipl) {
                //const
                register_t msr = wrtee(0);
                e500_splset(ci, ipl);
-#if 1
+#if 0
                if (old_ipl < IPL_VM && ipl >= IPL_VM)
                        msr = 0;
 #endif
@@ -830,9 +829,15 @@
 static void
 e500_wdogintr(struct trapframe *tf)
 {
+       struct cpu_info * const ci = curcpu();
        mtspr(SPR_TSR, TSR_ENW|TSR_WIS);
-       panic("%s: tf=%p tb=%"PRId64" srr0/srr1=%#lx/%#lx", __func__, tf,
-           mftb(), tf->tf_srr0, tf->tf_srr1);
+       wdog_barked = true;
+       dump_splhist(ci, NULL);
+       dump_trapframe(tf, NULL);
+       panic("%s: tf=%p tb=%"PRId64" srr0/srr1=%#lx/%#lx"
+           " cpl=%d idepth=%d, mtxcount=%d",
+           __func__, tf, mftb(), tf->tf_srr0, tf->tf_srr1,
+           ci->ci_cpl, ci->ci_idepth, ci->ci_mtx_count);
 }
 
 static void
@@ -843,7 +848,7 @@
        const int old_ipl = ci->ci_cpl;
 
        /* if we paniced because of watchdog, PSL_CE will be clear.  */
-       KASSERT(panicstr != NULL || (mfmsr() & PSL_CE));
+       KASSERT(wdog_barked || (mfmsr() & PSL_CE));
 
 #if 0
 //     printf("%s(%p): idepth=%d enter\n", __func__, tf, ci->ci_idepth);
@@ -878,8 +883,8 @@
                /*
                 * Find out the pending interrupt.
                 */
-       if (mfmsr() & PSL_EE)
-               panic("%s(%p): MSR[EE] turned on (%#lx)!", __func__, tf, mfmsr());
+               KASSERTMSG((mfmsr() & PSL_EE) == 0,
+                   "%s(%p): MSR[EE] left on (%#lx)!", __func__, tf, mfmsr());
                if (IPL2CTPR(old_ipl) != openpic_read(cpu, OPENPIC_CTPR))
                        panic("%s(%p): %d: old_ipl(%u) + %u != OPENPIC_CTPR (%u)",
                            __func__, tf, __LINE__, old_ipl, 
@@ -947,8 +952,8 @@
                 * because the loop we interrupted will complete looking
                 * for interrupts.
                 */
-       if (mfmsr() & PSL_EE)
-               panic("%s(%p): MSR[EE] left on (%#lx)!", __func__, tf, mfmsr());
+               KASSERTMSG((mfmsr() & PSL_EE) == 0,
+                   "%s(%p): MSR[EE] left on (%#lx)!", __func__, tf, mfmsr());
                if (IPL2CTPR(old_ipl) != openpic_read(cpu, OPENPIC_CTPR))
                        panic("%s(%p): %d: old_ipl(%u) + %u != OPENPIC_CTPR (%u)",
                            __func__, tf, __LINE__, old_ipl, 
@@ -973,16 +978,14 @@
        if (__predict_false(softints != 0)) {
                KASSERT(old_ipl < IPL_VM);
                e500_splset(ci, IPL_HIGH);      /* pop to high */
+               wrtee(PSL_EE);                  /* reenable interrupts */
                powerpc_softint(ci, old_ipl,    /* deal with them */
                    tf->tf_srr0);
+               wrtee(0);                       /* disable interrupts */
                e500_splset(ci, old_ipl);       /* and drop back */
        }
 #endif /* __HAVE_FAST_SOFTINTS */
-#if 1
        KASSERT(ci->ci_cpl == old_ipl);
-#else
-       e500_splset(ci, old_ipl);               /* and drop back */
-#endif
 
        /*
         * If we interrupted while power-saving and we need to exit idle,
diff -r 32b08c38cfba -r 1617eca8142a sys/arch/powerpc/booke/trap.c
--- a/sys/arch/powerpc/booke/trap.c     Wed Aug 01 20:35:52 2012 +0000
+++ b/sys/arch/powerpc/booke/trap.c     Wed Aug 01 21:30:21 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: trap.c,v 1.19 2012/08/01 16:35:50 matt Exp $   */
+/*     $NetBSD: trap.c,v 1.20 2012/08/01 21:30:22 matt Exp $   */
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -38,7 +38,7 @@
 
 #include <sys/cdefs.h>



Home | Main Index | Thread Index | Old Index