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