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:
parent
531fd682f7
commit
8f3c0c67f1
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user