Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/sparc/sparc Hanlde NMI on microSPARC-IIep.



details:   https://anonhg.NetBSD.org/src/rev/2b4eec1a19db
branches:  trunk
changeset: 584148:2b4eec1a19db
user:      uwe <uwe%NetBSD.org@localhost>
date:      Sat Sep 10 01:27:54 2005 +0000

description:
Hanlde NMI on microSPARC-IIep.

We don't do much useful except reporting, but that's better than to
stupidly use sun4m handler and wedge the machine.  May need to revisit
what's fatal.

Prodding by macallan@

diffstat:

 sys/arch/sparc/sparc/genassym.cf |    6 +-
 sys/arch/sparc/sparc/intr.c      |  105 +++++++++++++++++++++++++++++++++++++-
 sys/arch/sparc/sparc/locore.s    |   65 +++++++++++++++++++++++-
 3 files changed, 171 insertions(+), 5 deletions(-)

diffs (241 lines):

diff -r ae5b5e9fd4bc -r 2b4eec1a19db sys/arch/sparc/sparc/genassym.cf
--- a/sys/arch/sparc/sparc/genassym.cf  Sat Sep 10 01:23:19 2005 +0000
+++ b/sys/arch/sparc/sparc/genassym.cf  Sat Sep 10 01:27:54 2005 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: genassym.cf,v 1.45 2005/07/10 17:02:19 christos Exp $
+#      $NetBSD: genassym.cf,v 1.46 2005/09/10 01:27:54 uwe Exp $
 
 #
 # Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -198,6 +198,10 @@
 define PCIC_SOFT_INTR_SET_REG  offsetof(struct msiiep_pcic_reg, pcic_soft_intr_set)
 define PCIC_SCCR_REG           offsetof(struct msiiep_pcic_reg, pcic_sccr)
 
+define PCIC_SYS_ITMR_CLR_REG   offsetof(struct msiiep_pcic_reg, pcic_sys_itmr_clr)
+define PCIC_SYS_ITMR_SET_REG   offsetof(struct msiiep_pcic_reg, pcic_sys_itmr_set)
+define MSIIEP_SYS_ITMR_ALL     MSIIEP_SYS_ITMR_ALL
+
 # errno
 define EFAULT          EFAULT
 define ENAMETOOLONG    ENAMETOOLONG
diff -r ae5b5e9fd4bc -r 2b4eec1a19db sys/arch/sparc/sparc/intr.c
--- a/sys/arch/sparc/sparc/intr.c       Sat Sep 10 01:23:19 2005 +0000
+++ b/sys/arch/sparc/sparc/intr.c       Sat Sep 10 01:27:54 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: intr.c,v 1.87 2005/06/16 04:17:49 briggs Exp $ */
+/*     $NetBSD: intr.c,v 1.88 2005/09/10 01:27:54 uwe Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.87 2005/06/16 04:17:49 briggs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.88 2005/09/10 01:27:54 uwe Exp $");
 
 #include "opt_multiprocessor.h"
 #include "opt_sparc_arch.h"
@@ -202,7 +202,7 @@
 #undef DONETISR
 }
 
-#if defined(SUN4M) || defined(SUN4D)
+#if (defined(SUN4M) && !defined(MSIIEP)) || defined(SUN4D)
 void   nmi_hard __P((void));
 void   nmi_soft __P((struct trapframe *));
 
@@ -384,6 +384,105 @@
 #endif /* MULTIPROCESSOR */
 #endif /* SUN4M || SUN4D */
 
+
+#ifdef MSIIEP
+/*
+ * It's easier to make this separate so that not to further obscure
+ * SUN4M case with more ifdefs.  There's no common functionality
+ * anyway.
+ */
+
+#include <sparc/sparc/msiiepreg.h>
+
+/* ms-IIep PCIC registers are mapped at fixed VA */
+#define mspcic ((volatile struct msiiep_pcic_reg *)MSIIEP_PCIC_VA)
+
+void   nmi_hard_msiiep(void);
+void   nmi_soft_msiiep(void);
+
+
+void
+nmi_hard_msiiep(void)
+{
+       uint32_t si;
+       int byteswap;
+       char bits[128];
+       int fatal = 0;
+
+       si = mspcic->pcic_sys_ipr;
+       printf("NMI: system interrupts: %s\n",
+              bitmask_snprintf(si, MSIIEP_SYS_IPR_BITS, bits, sizeof(bits)));
+
+       if (si & MSIIEP_SYS_IPR_MEM_FAULT) {
+               uint32_t afsr, afar, mfsr, mfar;
+
+               afar = *(volatile uint32_t *)MSIIEP_AFAR;
+               afsr = *(volatile uint32_t *)MSIIEP_AFSR;
+
+               mfar = *(volatile uint32_t *)MSIIEP_MFAR;
+               mfsr = *(volatile uint32_t *)MSIIEP_MFSR;
+
+               if (afsr & MSIIEP_AFSR_ERR)
+                       printf("async fault: afsr=%s; afar=%08x\n",
+                              bitmask_snprintf(afsr, MSIIEP_AFSR_BITS,
+                                               bits, sizeof(bits)),
+                              afar);
+
+               if (mfsr & MSIIEP_MFSR_ERR)
+                       printf("mem fault: mfsr=%s; mfar=%08x\n",
+                              bitmask_snprintf(mfsr, MSIIEP_MFSR_BITS,
+                                               bits, sizeof(bits)),
+                              mfar);
+
+               fatal = 0;
+       }
+
+       byteswap = mspcic->pcic_pio_ctrl & MSIIEP_PIO_CTRL_BIG_ENDIAN;
+
+       if (si & MSIIEP_SYS_IPR_SERR) { /* XXX */
+               printf("serr#\n");
+               fatal = 0;
+       }
+
+       if (si & MSIIEP_SYS_IPR_DMA_ERR) {
+               uint32_t iotlb_err_addr = mspcic->pcic_iotlb_err_addr;
+
+               if (byteswap)
+                       iotlb_err_addr = bswap32(iotlb_err_addr);
+
+               printf("dma: %08x\n", iotlb_err_addr);
+               fatal = 0;
+       }
+
+       if (si & MSIIEP_SYS_IPR_PIO_ERR) {
+               uint32_t pio_err_addr = mspcic->pcic_pio_err_addr;
+
+               if (byteswap)
+                       pio_err_addr = bswap32(pio_err_addr);
+
+               printf("pio: addr=%08x, cmd=%x\n",
+                      pio_err_addr, mspcic->pcic_pio_err_cmd);
+               fatal = 0;
+       }
+
+       if (fatal)
+               panic("nmi");
+
+       /* Clear the NMI if it was PCIC related */
+       mspcic->pcic_sys_ipr_clr = MSIIEP_SYS_IPR_CLR_ALL;
+}
+
+
+void
+nmi_soft_msiiep(void)
+{
+       panic("soft nmi");
+}
+
+
+#endif /* MSIIEP */
+
+
 /*
  * Level 15 interrupts are special, and not vectored here.
  * Only `prewired' interrupts appear here; boot-time configured devices
diff -r ae5b5e9fd4bc -r 2b4eec1a19db sys/arch/sparc/sparc/locore.s
--- a/sys/arch/sparc/sparc/locore.s     Sat Sep 10 01:23:19 2005 +0000
+++ b/sys/arch/sparc/sparc/locore.s     Sat Sep 10 01:27:54 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: locore.s,v 1.216 2005/07/10 17:02:19 christos Exp $    */
+/*     $NetBSD: locore.s,v 1.217 2005/09/10 01:27:54 uwe Exp $ */
 
 /*
  * Copyright (c) 1996 Paul Kranenburg
@@ -3103,6 +3103,8 @@
        INTR_SETUP(-CCFSZ-80)
        INCR(_C_LABEL(uvmexp)+V_INTR)   ! cnt.v_intr++; (clobbers %o0,%o1)
 
+#if !defined(MSIIEP) /* normal sun4m */
+
        /* Read the Pending Interrupts register */
        sethi   %hi(CPUINFO_VA+CPUINFO_INTREG), %l6
        ld      [%l6 + %lo(CPUINFO_VA+CPUINFO_INTREG)], %l6
@@ -3194,8 +3196,69 @@
 4:
        b       return_from_trap
         wr     %l4, 0, %y              ! restore y
+
+#else /* MSIIEP*/
+       sethi   %hi(MSIIEP_PCIC_VA), %l6
+
+       /* Read the Processor Interrupt Pending register */
+       ld      [%l6 + PCIC_PROC_IPR_REG], %l5
+
+       /*
+        * Level 15 interrupts are nonmaskable, so with traps off,
+        * disable all interrupts to prevent recursion.
+        */
+       set     MSIIEP_SYS_ITMR_ALL, %l4
+       st      %l4, [%l6 + PCIC_SYS_ITMR_SET_REG]
+
+       set     (1 << 15), %l4
+       btst    %l4, %l5        ! has pending level 15 hw intr?
+       bz      1f
+        nop
+
+       /* hard level 15 interrupt */
+       sethi   %hi(_C_LABEL(nmi_hard_msiiep)), %o3
+       b       2f
+        or     %o3, %lo(_C_LABEL(nmi_hard_msiiep)), %o3
+
+1:     /* soft level 15 interrupt */
+       sth     %l4, [%l6 + PCIC_SOFT_INTR_CLEAR_REG]
+       set     _C_LABEL(nmi_soft_msiiep), %o3
+2:
+
+       /* XXX: call sequence is identical to sun4m case above. merge? */
+       or      %l0, PSR_PIL, %o4       ! splhigh()
+       wr      %o4, 0, %psr            !
+       wr      %o4, PSR_ET, %psr       ! turn traps on again
+
+       std     %g2, [%sp + CCFSZ + 80] ! save g2, g3
+       rd      %y, %l4                 ! save y
+       std     %g4, [%sp + CCFSZ + 88] ! save g4, g5
+
+       /* Finish stackframe, call C trap handler */
+       mov     %g1, %l5                ! save g1, g6, g7
+       mov     %g6, %l6
+
+       call    %o3                     ! nmi_hard(0) or nmi_soft(&tf)
+        mov    %g7, %l7
+
+       mov     %l5, %g1                ! restore g1 through g7
+       ldd     [%sp + CCFSZ + 80], %g2
+       ldd     [%sp + CCFSZ + 88], %g4
+       wr      %l0, 0, %psr            ! re-disable traps
+       mov     %l6, %g6
+       mov     %l7, %g7
+
+       ! enable interrupts again (safe, we disabled traps again above)
+       sethi   %hi(MSIIEP_PCIC_VA), %o0
+       set     MSIIEP_SYS_ITMR_ALL, %o1
+       st      %o1, [%o0 + PCIC_SYS_ITMR_CLR_REG]
+
+       b       return_from_trap
+        wr     %l4, 0, %y              ! restore y
+#endif /* MSIIEP */
 #endif /* SUN4M */
 
+
 #ifdef GPROF
        .globl  window_of, winof_user
        .globl  window_uf, winuf_user, winuf_ok, winuf_invalid



Home | Main Index | Thread Index | Old Index