summaryrefslogtreecommitdiffstats
path: root/sys/sparc64
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2008-11-19 22:12:32 +0000
committermarius <marius@FreeBSD.org>2008-11-19 22:12:32 +0000
commiteef5d34a4a2068d2acca5684fb421f1d775f8047 (patch)
tree3ee9262cea0688338c836311460a58d9fde7763a /sys/sparc64
parentfd213ef8e29e5b912cedf5f66e5eb00c96893c00 (diff)
downloadFreeBSD-src-eef5d34a4a2068d2acca5684fb421f1d775f8047.zip
FreeBSD-src-eef5d34a4a2068d2acca5684fb421f1d775f8047.tar.gz
Use the interrupt level right below PIL_FAST for executing interrupt
filters instead of PIL_FAST and allow special filters and handlers for interrupts which need to be able to interrupt even filters, f.e. bus error interrupts, to be registered with the revived INTR_FAST at PIL_FAST.
Diffstat (limited to 'sys/sparc64')
-rw-r--r--sys/sparc64/include/intr_machdep.h3
-rw-r--r--sys/sparc64/sparc64/intr_machdep.c26
2 files changed, 19 insertions, 10 deletions
diff --git a/sys/sparc64/include/intr_machdep.h b/sys/sparc64/include/intr_machdep.h
index 7f29808..ef24d18 100644
--- a/sys/sparc64/include/intr_machdep.h
+++ b/sys/sparc64/include/intr_machdep.h
@@ -47,8 +47,9 @@
#define PIL_AST 4 /* ast ipi */
#define PIL_STOP 5 /* stop cpu ipi */
#define PIL_PREEMPT 6 /* preempt idle thread cpu ipi */
+#define PIL_FILTER 12 /* filter interrupts */
#define PIL_FAST 13 /* fast interrupts */
-#define PIL_TICK 14
+#define PIL_TICK 14 /* tick interrupts */
#ifndef LOCORE
diff --git a/sys/sparc64/sparc64/intr_machdep.c b/sys/sparc64/sparc64/intr_machdep.c
index 60c3e4f..9f9df1b 100644
--- a/sys/sparc64/sparc64/intr_machdep.c
+++ b/sys/sparc64/sparc64/intr_machdep.c
@@ -88,7 +88,7 @@ struct intr_vector intr_vectors[IV_MAX];
uint16_t intr_countp[IV_MAX];
static u_long intr_stray_count[IV_MAX];
-static const char *pil_names[] = {
+static const char *const pil_names[] = {
"stray",
"low", /* PIL_LOW */
"ithrd", /* PIL_ITHREAD */
@@ -96,7 +96,8 @@ static const char *pil_names[] = {
"ast", /* PIL_AST */
"stop", /* PIL_STOP */
"preempt", /* PIL_PREEMPT */
- "stray", "stray", "stray", "stray", "stray", "stray",
+ "stray", "stray", "stray", "stray", "stray",
+ "filter", /* PIL_FILTER */
"fast", /* PIL_FAST */
"tick", /* PIL_TICK */
};
@@ -321,10 +322,16 @@ inthand_add(const char *name, int vec, driver_filter_t *filt,
struct intr_event *ie;
struct intr_handler *ih;
struct intr_vector *iv;
- int error, fast;
+ int error, filter;
if (vec < 0 || vec >= IV_MAX)
return (EINVAL);
+ /*
+ * INTR_FAST filters/handlers are special purpose only, allowing
+ * them to be shared just would complicate things unnecessarily.
+ */
+ if ((flags & INTR_FAST) != 0 && (flags & INTR_EXCL) == 0)
+ return (EINVAL);
sx_xlock(&intr_table_lock);
iv = &intr_vectors[vec];
ic = iv->iv_ic;
@@ -341,24 +348,25 @@ inthand_add(const char *name, int vec, driver_filter_t *filt,
ic->ic_disable(iv);
iv->iv_refcnt++;
if (iv->iv_refcnt == 1)
- intr_setup(filt != NULL ? PIL_FAST : PIL_ITHREAD, intr_fast,
+ intr_setup((flags & INTR_FAST) != 0 ? PIL_FAST :
+ filt != NULL ? PIL_FILTER : PIL_ITHREAD, intr_fast,
vec, intr_execute_handlers, iv);
else if (filt != NULL) {
/*
- * Check if we need to upgrade from PIL_ITHREAD to PIL_FAST.
+ * Check if we need to upgrade from PIL_ITHREAD to PIL_FILTER.
* Given that apart from the on-board SCCs and UARTs shared
* interrupts are rather uncommon on sparc64 this sould be
* pretty rare in practice.
*/
- fast = 0;
+ filter = 0;
TAILQ_FOREACH(ih, &ie->ie_handlers, ih_next) {
if (ih->ih_filter != NULL && ih->ih_filter != filt) {
- fast = 1;
+ filter = 1;
break;
}
}
- if (fast == 0)
- intr_setup(PIL_FAST, intr_fast, vec,
+ if (filter == 0)
+ intr_setup(PIL_FILTER, intr_fast, vec,
intr_execute_handlers, iv);
}
intr_stray_count[vec] = 0;
OpenPOWER on IntegriCloud