summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-04-19 19:41:27 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-04-19 19:41:27 +0000
commitdc0eb867705a1c4785b8108ac893066d3cd2046f (patch)
tree3dad324d24c979f6fab5c749aacfd66cd3fd658a
parentf44631f6bc3da796269b8e15c9df671cbfb7daab (diff)
Better diagnostic messages in the MVME188 interrupt handler; also no need
to register an interrupt handler for the SYSCON board interrupts anymore, as we never trigger it.
-rw-r--r--sys/arch/mvme88k/dev/syscon.c10
-rw-r--r--sys/arch/mvme88k/mvme88k/m188_machdep.c77
2 files changed, 60 insertions, 27 deletions
diff --git a/sys/arch/mvme88k/dev/syscon.c b/sys/arch/mvme88k/dev/syscon.c
index 0d1111f5889..65a5c15497f 100644
--- a/sys/arch/mvme88k/dev/syscon.c
+++ b/sys/arch/mvme88k/dev/syscon.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscon.c,v 1.25 2006/04/17 18:27:30 miod Exp $ */
+/* $OpenBSD: syscon.c,v 1.26 2006/04/19 19:41:24 miod Exp $ */
/*
* Copyright (c) 1999 Steve Murphree, Jr.
* All rights reserved.
@@ -47,7 +47,9 @@ struct sysconsoftc {
struct intrhand sc_abih; /* `abort' switch */
struct intrhand sc_acih; /* `ac fail' */
struct intrhand sc_sfih; /* `sys fail' */
+#if 0
struct intrhand sc_m188ih; /* `m188 interrupt' */
+#endif
};
void sysconattach(struct device *, struct device *, void *);
@@ -152,15 +154,19 @@ sysconattach(parent, self, args)
sc->sc_sfih.ih_wantframe = 1;
sc->sc_sfih.ih_ipl = IPL_ABORT;
+#if 0
sc->sc_m188ih.ih_fn = sysconm188;
sc->sc_m188ih.ih_arg = 0;
sc->sc_m188ih.ih_wantframe = 1;
sc->sc_m188ih.ih_ipl = IPL_ABORT;
+#endif
sysconintr_establish(SYSCV_ABRT, &sc->sc_abih, "abort");
sysconintr_establish(SYSCV_ACF, &sc->sc_acih, "acfail");
sysconintr_establish(SYSCV_SYSF, &sc->sc_sfih, "sysfail");
+#if 0
intr_establish(M188_IVEC, &sc->sc_m188ih, self->dv_xname);
+#endif
config_search(syscon_scan, self, args);
}
@@ -203,6 +209,7 @@ sysconacfail(eframe)
return (1);
}
+#if 0
int
sysconm188(eframe)
void *eframe;
@@ -211,3 +218,4 @@ sysconm188(eframe)
printf("MVME188: self-inflicted interrupt\n");
return (1);
}
+#endif
diff --git a/sys/arch/mvme88k/mvme88k/m188_machdep.c b/sys/arch/mvme88k/mvme88k/m188_machdep.c
index 5257ff7488d..676993688d7 100644
--- a/sys/arch/mvme88k/mvme88k/m188_machdep.c
+++ b/sys/arch/mvme88k/mvme88k/m188_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: m188_machdep.c,v 1.15 2006/04/17 18:26:28 miod Exp $ */
+/* $OpenBSD: m188_machdep.c,v 1.16 2006/04/19 19:41:26 miod Exp $ */
/*
* Copyright (c) 1998, 1999, 2000, 2001 Steve Murphree, Jr.
* Copyright (c) 1996 Nivas Madhur
@@ -206,7 +206,6 @@ safe_level(u_int mask, u_int curlevel)
if ((int_mask_val[i] & mask) == 0)
return (i);
- /* NOTREACHED since int_mask_val[INT_LEVEL - 1] is zero */
return (INT_LEVEL - 1);
}
@@ -306,7 +305,7 @@ void
m188_ext_int(u_int v, struct trapframe *eframe)
{
int cpu = cpu_number();
- unsigned int cur_mask;
+ unsigned int cur_mask, ign_mask;
unsigned int level, old_spl;
struct intrhand *intr;
intrhand_t *list;
@@ -314,8 +313,12 @@ m188_ext_int(u_int v, struct trapframe *eframe)
vaddr_t ivec;
u_int vec;
int unmasked = 0;
+#ifdef DIAGNOSTIC
+ static int problems = 0;
+#endif
cur_mask = ISR_GET_CURRENT_MASK(cpu);
+ ign_mask = 0;
old_spl = m188_curspl[cpu];
eframe->tf_mask = old_spl;
@@ -358,12 +361,6 @@ m188_ext_int(u_int v, struct trapframe *eframe)
}
#endif
-#ifdef DEBUG
- if (level > 7 || (int)level < 0) {
- panic("int level (%x) is not between 0 and 7", level);
- }
-#endif
-
setipl(level);
/*
@@ -405,25 +402,45 @@ m188_ext_int(u_int v, struct trapframe *eframe)
ivec = MVME188_VIRQLV + (level << 2);
vec = *(volatile u_int32_t *)ivec & VME_VECTOR_MASK;
if (vec & VME_BERR_MASK) {
- printf("VME vec timeout, vec = %x, mask = 0x%b\n",
- vec, 1 << intbit, IST_STRING);
- continue;
+ /*
+ * This could be a self-inflicted interrupt.
+ * Except that we never write to VIRQV, so
+ * such things do not happen.
+
+ u_int src = 0x07 &
+ *(volatile u_int32_t *)MVME188_VIRQLV;
+ if (src == 0)
+ vec = 0xff &
+ *(volatile u_int32_t *)MVME188_VIRQV;
+ else
+
+ */
+ {
+ printf("%s: timeout getting VME "
+ "interrupt vector, "
+ "level %d, mask 0x%b\n",
+ __func__, level,
+ cur_mask, IST_STRING);
+ ign_mask |= 1 << intbit;
+ continue;
+ }
}
if (vec == 0) {
- panic("unknown vme interrupt: mask = 0x%b",
- 1 << intbit, IST_STRING);
+ panic("%s: invalid VME interrupt vector, "
+ "level %d, mask 0x%b",
+ __func__, level, cur_mask, IST_STRING);
}
} else {
- panic("unknown interrupt: level = %d intbit = 0x%x "
- "mask = 0x%b",
- level, intbit, 1 << intbit, IST_STRING);
+ panic("%s: unexpected interrupt source, "
+ "level %d, mask 0x%b",
+ __func__, level, cur_mask, IST_STRING);
}
list = &intr_handlers[vec];
if (SLIST_EMPTY(list)) {
- printf("Spurious interrupt: level = %d vec = 0x%x, "
- "intbit = %d mask = 0x%b\n",
- level, vec, intbit, 1 << intbit, IST_STRING);
+ printf("%s: spurious interrupt, "
+ "level %d, vec 0x%x, mask 0x%b\n",
+ __func__, level, vec, cur_mask, IST_STRING);
} else {
/*
* Walk through all interrupt handlers in the chain
@@ -442,14 +459,22 @@ m188_ext_int(u_int v, struct trapframe *eframe)
}
}
if (ret == 0) {
- printf("Unclaimed interrupt: level = %d "
- "vec = 0x%x, intbit = %d mask = 0x%b\n",
- level, vec, intbit,
- 1 << intbit, IST_STRING);
- break;
+ printf("%s: unclaimed interrupt, "
+ "level %d, vec 0x%x, mask 0x%b\n",
+ __func__, level, vec, cur_mask, IST_STRING);
+ ign_mask |= 1 << intbit;
+ continue;
}
}
- } while ((cur_mask = ISR_GET_CURRENT_MASK(cpu)) != 0);
+ } while (((cur_mask = ISR_GET_CURRENT_MASK(cpu)) & ~ign_mask) != 0);
+
+#ifdef DIAGNOSTIC
+ if (ign_mask != 0) {
+ if (++problems >= 10)
+ panic("%s: broken interrupt behaviour", __func__);
+ } else
+ problems = 0;
+#endif
/*
* process any remaining data access exceptions before