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@
This commit is contained in:
uwe 2005-09-10 01:27:54 +00:00
parent 531fd682f7
commit 8f3c0c67f1
3 changed files with 171 additions and 5 deletions

View File

@ -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_CLEAR_REG offsetof(struct msiiep_pcic_reg, pcic_soft_intr_
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

View File

@ -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 @@ softnet(fp)
#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 @@ static void xcallintr(void *v)
#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

View File

@ -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 @@ nmi_sun4m:
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 @@ nmi_sun4m:
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