summaryrefslogtreecommitdiff
path: root/sys/arch/sgi
diff options
context:
space:
mode:
authorPer Fogelstrom <pefo@cvs.openbsd.org>2004-09-27 19:20:50 +0000
committerPer Fogelstrom <pefo@cvs.openbsd.org>2004-09-27 19:20:50 +0000
commitebb4c30d0ba37fca21a45b416ade8714393b0ac0 (patch)
tree659762f6cdfca5b38da2a5d042378b63c78bae41 /sys/arch/sgi
parent23ce51ea125bb5370965cf6b3d4a6c95f8954d4b (diff)
Rewrite parts of the interrupt system to achive:
o Remove do_pending code and take a real int instead. The performance impact seems to be very low and it simplifies the code considerably. o Allow interrupt nesting at first level. Run softints with HW ints enabled.
Diffstat (limited to 'sys/arch/sgi')
-rw-r--r--sys/arch/sgi/include/intr.h37
-rw-r--r--sys/arch/sgi/localbus/macebus.c74
2 files changed, 67 insertions, 44 deletions
diff --git a/sys/arch/sgi/include/intr.h b/sys/arch/sgi/include/intr.h
index 7e9a3a847f1..ff245ca9ad1 100644
--- a/sys/arch/sgi/include/intr.h
+++ b/sys/arch/sgi/include/intr.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.h,v 1.8 2004/09/24 14:22:48 deraadt Exp $ */
+/* $OpenBSD: intr.h,v 1.9 2004/09/27 19:20:49 pefo Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -107,9 +107,9 @@
#define spllowersoftclock() spllower(SINT_CLOCKMASK)
-#define setsoftclock() set_sint(SINT_CLOCKMASK);
-#define setsoftnet() set_sint(SINT_NETMASK);
-#define setsofttty() set_sint(SINT_TTYMASK);
+#define setsoftclock() set_ipending(SINT_CLOCKMASK);
+#define setsoftnet() set_ipending(SINT_NETMASK);
+#define setsofttty() set_ipending(SINT_TTYMASK);
void splinit(void);
@@ -149,15 +149,15 @@ extern intrmask_t imask[NIPLS];
*/
/* Inlines */
-static __inline void register_pending_int_handler(void (*)(void));
+static __inline void register_pending_int_handler(void (*)(int));
static __inline void splx(int newcpl);
static __inline int spllower(int newcpl);
-typedef void (void_f) (void);
-extern void_f *pending_hand;
+typedef void (int_f) (int);
+extern int_f *pending_hand;
static __inline void
-register_pending_int_handler(void(*pending)(void))
+register_pending_int_handler(void(*pending)(int))
{
pending_hand = pending;
}
@@ -184,10 +184,10 @@ int splraise(int newcpl);
static __inline void
splx(int newcpl)
{
- cpl = newcpl;
- if ((ipending & ~newcpl) && (pending_hand != NULL)) {
- (*pending_hand)();
- }
+ if (ipending & ~newcpl)
+ (*pending_hand)(newcpl);
+ else
+ cpl = newcpl;
}
static __inline int
@@ -196,17 +196,18 @@ spllower(int newcpl)
int oldcpl;
oldcpl = cpl;
- cpl = newcpl;
- if ((ipending & ~newcpl) && (pending_hand != NULL)) {
- (*pending_hand)();
- }
+ if (ipending & ~newcpl)
+ (*pending_hand)(newcpl);
+ else
+ cpl = newcpl;
return (oldcpl);
}
/*
* Atomically update ipending.
*/
-void set_sint(int pending);
+void set_ipending(int);
+void clr_ipending(int);
/*
* Interrupt control struct used by interrupt dispatchers
@@ -255,7 +256,7 @@ void *generic_intr_establish(void *, u_long, int, int,
int (*) __P((void *)), void *, char *);
void generic_intr_disestablish(void *, void *);
void generic_intr_makemasks(void);
-void generic_do_pending_int(void);
+void generic_do_pending_int(int);
intrmask_t generic_iointr(intrmask_t, struct trap_frame *);
#endif /* _LOCORE */
diff --git a/sys/arch/sgi/localbus/macebus.c b/sys/arch/sgi/localbus/macebus.c
index b4686226f0e..2510a7eb819 100644
--- a/sys/arch/sgi/localbus/macebus.c
+++ b/sys/arch/sgi/localbus/macebus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: macebus.c,v 1.9 2004/09/24 14:22:49 deraadt Exp $ */
+/* $OpenBSD: macebus.c,v 1.10 2004/09/27 19:20:49 pefo Exp $ */
/*
* Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se)
@@ -64,7 +64,7 @@ void *macebus_intr_establish(void *, u_long, int, int,
int (*)(void *), void *, char *);
void macebus_intr_disestablish(void *, void *);
void macebus_intr_makemasks(void);
-void macebus_do_pending_int(void);
+void macebus_do_pending_int(int);
intrmask_t macebus_iointr(intrmask_t, struct trap_frame *);
intrmask_t macebus_aux(intrmask_t, struct trap_frame *);
@@ -73,8 +73,6 @@ long crime_ext_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof (long)];
int maceticks; /* Time tracker for special events */
-u_int64_t crimestat;
-
struct cfattach macebus_ca = {
sizeof(struct device), macebusmatch, macebusattach
};
@@ -597,31 +595,40 @@ macebus_intr_makemasks(void)
}
void
-macebus_do_pending_int(void)
+macebus_do_pending_int(int newcpl)
{
+#ifdef _USE_SILLY_OVERWORKED_HW_INT_PENDING_HANDLER_
struct intrhand *ih;
int vector;
- intrmask_t pcpl;
intrmask_t hwpend;
struct trap_frame cf;
static volatile int processing;
- /* Don't recurse... */
- if (processing)
+ /* Don't recurse... but change the mask */
+ if (processing) {
+ cpl = newcpl;
return;
+ }
processing = 1;
- /* XXX interrupt vulnerable when changing ipending */
- pcpl = splhigh(); /* Turn off all */
/* XXX Fake a trapframe for clock pendings... */
cf.pc = (int)&macebus_do_pending_int;
cf.sr = 0;
- cf.cpl = pcpl;
+ cf.cpl = cpl;
+
+ /* Hard mask current cpl so we don't get any new pendings */
+ hw_setintrmask(cpl);
+
+ /* Get what interrupt we should process */
+ hwpend = ipending & ~newcpl;
+ hwpend &= ~SINT_ALLMASK;
+ clr_ipending(hwpend);
+
+ /* Enable all non pending non masked hardware interrupts */
+ cpl = (cpl & SINT_ALLMASK) | (newcpl & ~SINT_ALLMASK) | hwpend;
+ hw_setintrmask(cpl);
- hwpend = ipending & ~pcpl; /* Do now unmasked pendings */
- hwpend &= ~(SINT_ALLMASK);
- ipending &= ~hwpend;
while (hwpend) {
vector = ffs(hwpend) - 1;
hwpend &= ~(1L << vector);
@@ -634,30 +641,44 @@ macebus_do_pending_int(void)
ih = ih->ih_next;
}
}
- if ((ipending & SINT_CLOCKMASK) & ~pcpl) {
- ipending &= ~SINT_CLOCKMASK;
+
+ /* Enable all processed pending hardware interrupts */
+ cpl &= ~hwpend;
+ hw_setintrmask(cpl);
+
+ if ((ipending & SINT_CLOCKMASK) & ~newcpl) {
+ clr_ipending(SINT_CLOCKMASK);
softclock();
}
- if ((ipending & SINT_NETMASK) & ~pcpl) {
+ if ((ipending & SINT_NETMASK) & ~newcpl) {
extern int netisr;
int isr = netisr;
netisr = 0;
- ipending &= ~SINT_NETMASK;
+ clr_ipending(SINT_NETMASK);
#define DONETISR(b,f) if (isr & (1 << (b))) f();
#include <net/netisr_dispatch.h>
}
#ifdef NOTYET
- if ((ipending & SINT_TTYMASK) & ~pcpl) {
- ipending &= ~SINT_TTYMASK;
+ if ((ipending & SINT_TTYMASK) & ~newcpl) {
+ clr_ipending(SINT_TTYMASK);
compoll(NULL);
}
#endif
- cpl = pcpl; /* Don't use splx... we are here already! */
- hw_setintrmask(pcpl);
+ /* Update masks to new cpl. Order highly important! */
+ cpl = newcpl;
+ hw_setintrmask(newcpl);
processing = 0;
+#else
+ /* Update masks to new cpl. Order highly important! */
+ cpl = newcpl;
+ hw_setintrmask(newcpl);
+ /* If we still have softints pending trigg processing */
+ if (ipending & SINT_ALLMASK & ~cpl)
+ setsoftintr0();
+#endif
}
/*
@@ -673,22 +694,23 @@ macebus_iointr(intrmask_t hwpend, struct trap_frame *cf)
u_int64_t intstat, isastat, mask;
intstat = bus_space_read_8(&crimebus_tag, crime_h, CRIME_INT_STAT);
-crimestat=intstat;
- intstat &= 0x0000ffff;
+ intstat &= 0xffff;
+
isastat = bus_space_read_8(&macebus_tag, mace_h, MACE_ISA_INT_STAT);
catched = 0;
/* Mask off masked interrupts and save them as pending */
if (intstat & cf->cpl) {
- ipending |= intstat & cf->cpl;
+ set_ipending(intstat & cf->cpl);
mask = bus_space_read_8(&crimebus_tag, crime_h, CRIME_INT_MASK);
mask &= ~ipending;
bus_space_write_8(&crimebus_tag, crime_h, CRIME_INT_MASK, mask);
catched++;
}
- /* Scan the first 16 for now */
+ /* Scan all unmasked. Scan the first 16 for now */
pending = intstat & ~cf->cpl;
+ clr_ipending(pending);
for (v = 0, vm = 1; pending != 0 && v < 16 ; v++, vm <<= 1) {
if (pending & vm) {