summaryrefslogtreecommitdiffstats
path: root/sys/sparc64
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2001-10-20 16:03:41 +0000
committerjake <jake@FreeBSD.org>2001-10-20 16:03:41 +0000
commit21fd58664dc89376f0ffdc3776d8febdcd12b36c (patch)
tree72d78be332c715f67ae5951e37f9d475b006b19b /sys/sparc64
parentc2c8a8c21ac2bb655b852cee3f1bce43666b2019 (diff)
downloadFreeBSD-src-21fd58664dc89376f0ffdc3776d8febdcd12b36c.zip
FreeBSD-src-21fd58664dc89376f0ffdc3776d8febdcd12b36c.tar.gz
Change the stray count in struct intr_vector to a vector number that can
be used to index tables of counters. Remove intr_dispatch() inline, it is implemented directly in tl*_intr now. Count stray interrupts in a table of counters like intrcnt. Disable interrupts briefly when setting up the interrupt vector table. We must disable interrupts completely, not just raise the pil. Pass pointers to the intr_vector structures rather than a vector number to sched_ithd and intr_stray.
Diffstat (limited to 'sys/sparc64')
-rw-r--r--sys/sparc64/include/intr_machdep.h10
-rw-r--r--sys/sparc64/sparc64/intr_machdep.c74
2 files changed, 42 insertions, 42 deletions
diff --git a/sys/sparc64/include/intr_machdep.h b/sys/sparc64/include/intr_machdep.h
index 8f1f938..01546e4 100644
--- a/sys/sparc64/include/intr_machdep.h
+++ b/sys/sparc64/include/intr_machdep.h
@@ -68,23 +68,17 @@ struct intr_queue {
struct ithd;
struct intr_vector {
- iv_func_t *iv_func; /* must be first */
+ iv_func_t *iv_func;
void *iv_arg;
struct ithd *iv_ithd;
u_int iv_pri;
- int iv_stray;
+ u_int iv_vec;
};
extern struct intr_handler intr_handlers[];
extern struct intr_queue intr_queues[];
extern struct intr_vector intr_vectors[];
-static __inline void
-intr_dispatch(int level, struct trapframe *tf)
-{
- intr_handlers[level].ih_func(tf);
-}
-
void intr_setup(int level, ih_func_t *ihf, int pri, iv_func_t *ivf,
void *iva);
void intr_init(void);
diff --git a/sys/sparc64/sparc64/intr_machdep.c b/sys/sparc64/sparc64/intr_machdep.c
index 3c26be0..40186a1 100644
--- a/sys/sparc64/sparc64/intr_machdep.c
+++ b/sys/sparc64/sparc64/intr_machdep.c
@@ -74,20 +74,18 @@
#include <sys/pcpu.h>
#include <sys/vmmeter.h>
-
#include <machine/frame.h>
#include <machine/globals.h>
#include <machine/intr_machdep.h>
-
-#define NCPU MAXCPU
-
#define MAX_STRAY_LOG 5
struct intr_handler intr_handlers[NPIL];
-struct intr_queue intr_queues[NCPU];
+struct intr_queue intr_queues[MAXCPU];
struct intr_vector intr_vectors[NIV];
+u_long intr_stray_count[NIV];
+
/* protect the intr_vectors table */
static struct mtx intr_table_lock;
@@ -104,14 +102,14 @@ intr_dequeue(struct trapframe *tf)
u_long tail;
crit = critical_enter();
- iq = PCPU_GET(iq);
+ iq = PCPU_PTR(iq);
for (head = iq->iq_head;; head = next) {
for (tail = iq->iq_tail; tail != head;) {
iqe = &iq->iq_queue[tail];
- /* XXX: add per-vector counts... */
- atomic_add_int(&cnt.v_intr, 1);
- if (iqe->iqe_func != NULL)
- iqe->iqe_func(iqe->iqe_arg);
+ atomic_add_long(&intrcnt[iqe->iqe_vec], 1);
+ KASSERT(iqe->iqe_func != NULL,
+ ("intr_dequeue: iqe->iqe_func NULL"));
+ iqe->iqe_func(iqe->iqe_arg);
tail = (tail + 1) & IQ_MASK;
}
iq->iq_tail = tail;
@@ -125,26 +123,33 @@ intr_dequeue(struct trapframe *tf)
void
intr_setup(int pri, ih_func_t *ihf, int vec, iv_func_t *ivf, void *iva)
{
+ u_long ps;
+
+ ps = rdpr(pstate);
+ if (ps & PSTATE_IE)
+ wrpr(pstate, ps, PSTATE_IE);
if (vec != -1) {
intr_vectors[vec].iv_func = ivf;
intr_vectors[vec].iv_arg = iva;
intr_vectors[vec].iv_pri = pri;
+ intr_vectors[vec].iv_vec = vec;
}
intr_handlers[pri].ih_func = ihf;
+ wrpr(pstate, ps, 0);
}
static void
intr_stray(void *cookie)
{
- int vec;
+ struct intr_vector *iv;
- vec = (int)(uintptr_t)cookie;
- if (intr_vectors[vec].iv_stray < MAX_STRAY_LOG) {
- printf("stray interrupt %d\n", vec);
- atomic_add_int(&intr_vectors[vec].iv_stray, 1);
- if (intr_vectors[vec].iv_stray == MAX_STRAY_LOG)
+ iv = cookie;
+ if (intr_stray_count[iv->iv_vec] < MAX_STRAY_LOG) {
+ printf("stray interrupt %d\n", iv->iv_vec);
+ atomic_add_long(&intr_stray_count[iv->iv_vec], 1);
+ if (intr_stray_count[iv->iv_vec] >= MAX_STRAY_LOG)
printf("got %d stray interrupt %d's: not logging "
- "anymore\n", MAX_STRAY_LOG, vec);
+ "anymore\n", MAX_STRAY_LOG, iv->iv_vec);
}
}
@@ -164,23 +169,24 @@ intr_init()
static void
sched_ithd(void *cookie)
{
- int vec;
+ struct intr_vector *iv;
int error;
- vec = (uintptr_t)cookie;
+ iv = cookie;
#ifdef notyet
- error = ithread_schedule(intr_vectors[vec].iv_ithd);
+ error = ithread_schedule(iv->iv_ithd);
#else
- error = ithread_schedule(intr_vectors[vec].iv_ithd, 0);
+ error = ithread_schedule(iv->iv_ithd, 0);
#endif
if (error == EINVAL)
- intr_stray(cookie);
+ intr_stray(iv);
}
int
inthand_add(const char *name, int vec, void (*handler)(void *), void *arg,
int flags, void **cookiep)
{
+ struct intr_vector *iv;
struct ithd *ithd; /* descriptor for the IRQ */
int errcode = 0;
int created_ithd = 0;
@@ -189,8 +195,9 @@ inthand_add(const char *name, int vec, void (*handler)(void *), void *arg,
* Work around a race where more than one CPU may be registering
* handlers on the same IRQ at the same time.
*/
+ iv = &intr_vectors[vec];
mtx_lock_spin(&intr_table_lock);
- ithd = intr_vectors[vec].iv_ithd;
+ ithd = iv->iv_ithd;
mtx_unlock_spin(&intr_table_lock);
if (ithd == NULL) {
errcode = ithread_create(&ithd, vec, 0, NULL, NULL, "intr%d:",
@@ -198,15 +205,15 @@ inthand_add(const char *name, int vec, void (*handler)(void *), void *arg,
if (errcode)
return (errcode);
mtx_lock_spin(&intr_table_lock);
- if (intr_vectors[vec].iv_ithd == NULL) {
- intr_vectors[vec].iv_ithd = ithd;
+ if (iv->iv_ithd == NULL) {
+ iv->iv_ithd = ithd;
created_ithd++;
mtx_unlock_spin(&intr_table_lock);
} else {
struct ithd *orphan;
orphan = ithd;
- ithd = intr_vectors[vec].iv_ithd;
+ ithd = iv->iv_ithd;
mtx_unlock_spin(&intr_table_lock);
ithread_destroy(orphan);
}
@@ -216,8 +223,7 @@ inthand_add(const char *name, int vec, void (*handler)(void *), void *arg,
ithread_priority(flags), flags, cookiep);
if ((flags & INTR_FAST) == 0 || errcode) {
- intr_setup(PIL_ITHREAD, intr_dequeue, vec, sched_ithd,
- (void *)(uintptr_t)vec);
+ intr_setup(PIL_ITHREAD, intr_dequeue, vec, sched_ithd, iv);
errcode = 0;
}
@@ -227,7 +233,7 @@ inthand_add(const char *name, int vec, void (*handler)(void *), void *arg,
if (flags & INTR_FAST)
intr_setup(PIL_FAST, intr_dequeue, vec, handler, arg);
- intr_vectors[vec].iv_stray = 0;
+ intr_stray_count[vec] = 0;
/* XXX: name is not yet used. */
return (0);
}
@@ -235,6 +241,7 @@ inthand_add(const char *name, int vec, void (*handler)(void *), void *arg,
int
inthand_remove(int vec, void *cookie)
{
+ struct intr_vector *iv;
int error;
error = ithread_remove_handler(cookie);
@@ -243,13 +250,12 @@ inthand_remove(int vec, void *cookie)
* XXX: maybe this should be done regardless of whether
* ithread_remove_handler() succeeded?
*/
+ iv = &intr_vectors[vec];
mtx_lock_spin(&intr_table_lock);
- if (intr_vectors[vec].iv_ithd == NULL) {
- intr_setup(PIL_ITHREAD, intr_dequeue, vec, intr_stray,
- (void *)(uintptr_t)vec);
+ if (iv->iv_ithd == NULL) {
+ intr_setup(PIL_ITHREAD, intr_dequeue, vec, intr_stray, iv);
} else {
- intr_setup(PIL_LOW, intr_dequeue, vec, sched_ithd,
- (void *)(uintptr_t)vec);
+ intr_setup(PIL_LOW, intr_dequeue, vec, sched_ithd, iv);
}
mtx_unlock_spin(&intr_table_lock);
}
OpenPOWER on IntegriCloud