summaryrefslogtreecommitdiff
path: root/sys/arch/sgi/localbus/macebus.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/sgi/localbus/macebus.c')
-rw-r--r--sys/arch/sgi/localbus/macebus.c74
1 files changed, 48 insertions, 26 deletions
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) {