summaryrefslogtreecommitdiff
path: root/sys/arch/powerpc/isa/isabus.c
diff options
context:
space:
mode:
authorDale S. Rahn <rahnds@cvs.openbsd.org>1998-10-12 04:05:47 +0000
committerDale S. Rahn <rahnds@cvs.openbsd.org>1998-10-12 04:05:47 +0000
commit72dfe69c46fb0ea4e34814f9221cd6a2622db624 (patch)
tree54d93163a9e3eb6474affe3db9ceb61acc2cc4ef /sys/arch/powerpc/isa/isabus.c
parent4fd11aadb20cc6e0f36fe5362af85ad6e0e12a9d (diff)
While It would be a really nice thing to have nested interrupts,
getting all of the complexities captured in the code before release is not going to be possible, maybe after release this will be fixed. Regressing to 1.8 (version before allowing nested interrupts).
Diffstat (limited to 'sys/arch/powerpc/isa/isabus.c')
-rw-r--r--sys/arch/powerpc/isa/isabus.c129
1 files changed, 33 insertions, 96 deletions
diff --git a/sys/arch/powerpc/isa/isabus.c b/sys/arch/powerpc/isa/isabus.c
index 721b12e13ad..c234c043b8c 100644
--- a/sys/arch/powerpc/isa/isabus.c
+++ b/sys/arch/powerpc/isa/isabus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: isabus.c,v 1.9 1998/10/09 02:19:12 rahnds Exp $ */
+/* $OpenBSD: isabus.c,v 1.10 1998/10/12 04:05:46 rahnds Exp $ */
/*-
* Copyright (c) 1995 Per Fogelstrom
@@ -241,11 +241,6 @@ isabrprint(aux, pnp)
int imen = 0xffffffff;
int intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN];
-struct {
- int irq;
- int o_imen;
-} pending_intr_stack[ICU_LEN];
-int pending_intr_index = 0;
struct intrhand *intrhand[ICU_LEN];
int fakeintr(void *a) {return 0;}
@@ -436,62 +431,32 @@ isa_do_pending_int()
int pcpl;
int hwpend;
int emsr, dmsr;
- int oldsint;
static int processing;
- ppc_intr_disable();
- if(processing) {
- ppc_intr_enable();
+ if(processing)
return;
- }
processing = 1;
+ __asm__ volatile("mfmsr %0" : "=r"(emsr));
+ dmsr = emsr & ~PSL_EE;
+ __asm__ volatile("mtmsr %0" :: "r"(dmsr));
pcpl = splhigh(); /* Turn off all */
-
-
- while(ipending & 0xffff) {
- pending_intr_index--;
- vector = pending_intr_stack[pending_intr_index].irq;
- if (pcpl & (1L << vector)) {
- /* this, and presumably all lower pri, are blocked */
- break;
- }
- cpl = pcpl | imen | intrmask[vector];
-#if 1
- ppc_intr_enable();
-#endif
+ hwpend = ipending & ~pcpl; /* Do now unmasked pendings */
+ hwpend &= ((1L << ICU_LEN) - 1);
+ ipending &= ~hwpend;
+ imen &= ~hwpend;
+ while(hwpend) {
evirq[ICU_LEN].ev_count++;
- evirq[ICU_LEN+vector].ev_count++;
+ vector = ffs(hwpend) - 1;
+ hwpend &= ~(1L << vector);
ih = intrhand[vector];
+ evirq[ICU_LEN+vector].ev_count++;
while(ih) {
(*ih->ih_fun)(ih->ih_arg);
ih = ih->ih_next;
}
-#if 1
- ppc_intr_disable();
-#endif
- imen = pending_intr_stack[pending_intr_index].o_imen;
- ipending &= ~(1 << vector);
-
- /* interrupt taken care of, reenable */
- /* imen does not deal with spurious interrupts in any manner */
- isa_outb(IO_ICU1 + 1, imen);
- isa_outb(IO_ICU2 + 1, imen >> 8);
-#ifdef NO_SPECIAL_MASK_MODE
- isa_outb(IO_ICU1, 0x20);
- isa_outb(IO_ICU2, 0x20);
-#else
- if(vector > 7) {
- isa_outb(IO_ICU2, 0x60 | vector & 0x07);
- }
- isa_outb(IO_ICU1, 0x60 | (vector > 7 ? 2 : vector));
-#endif
-
}
-#if 1
- ppc_intr_enable();
-#endif
if((ipending & SINT_CLOCK) & ~pcpl) {
ipending &= ~SINT_CLOCK;
softclock();
@@ -503,15 +468,13 @@ static int processing;
ipending &= ~SINT_NET;
softnet(pisr);
}
-#if 1
- ppc_intr_disable();
-#endif
cpl = pcpl; /* Don't use splx... we are here already! */
+ isa_outb(IO_ICU1 + 1, imen);
+ isa_outb(IO_ICU2 + 1, imen >> 8);
+
+ __asm__ volatile("mtmsr %0" :: "r"(emsr));
processing = 0;
-#if 1
- ppc_intr_enable();
-#endif
}
/*
@@ -541,40 +504,17 @@ isabr_iointr(mask, cf)
o_imen = imen;
r_imen = 1 << isa_vector;
- imen |= r_imen | intrmask[isa_vector];
+ imen |= r_imen;
isa_outb(IO_ICU1 + 1, imen);
isa_outb(IO_ICU2 + 1, imen >> 8);
if((pcpl & r_imen) != 0) {
- if ((ipending & (1 << isa_vector)) == 0) {
- ipending |= (1 << isa_vector);
- pending_intr_stack[pending_intr_index].irq = isa_vector;
- pending_intr_stack[pending_intr_index].o_imen = o_imen;
- pending_intr_index++;
-
- /*
- evirq[isa_vector].ev_count++;
- */
- } else {
- evirq[7].ev_count++;
- }
-
-#if 1
- ppc_intr_enable();
-#endif
- } else {
+ ipending |= r_imen; /* Masked! Mark this as pending */
evirq[isa_vector].ev_count++;
-
-#if 1
- /* dont mask other interrupts and yet,
- * we dont want to run end of interrupt processing
- * either
- */
- cpl = pcpl | r_imen;
- ppc_intr_enable();
-#endif
-
+ }
+ else {
ih = intrhand[isa_vector];
+ evirq[isa_vector].ev_count++;
if(ih == NULL)
printf("isa: spurious interrupt %d\n", isa_vector);
@@ -583,25 +523,21 @@ isabr_iointr(mask, cf)
ih = ih->ih_next;
}
imen = o_imen;
- /* interrupt taken care of, reenable */
- isa_outb(IO_ICU1 + 1, imen);
- isa_outb(IO_ICU2 + 1, imen >> 8);
+ }
+ isa_outb(IO_ICU1 + 1, imen);
+ isa_outb(IO_ICU2 + 1, imen >> 8);
#ifdef NO_SPECIAL_MASK_MODE
- isa_outb(IO_ICU1, 0x20);
- isa_outb(IO_ICU2, 0x20);
+ isa_outb(IO_ICU1, 0x20);
+ isa_outb(IO_ICU2, 0x20);
#else
- if(isa_vector > 7) {
- isa_outb(IO_ICU2, 0x60 | isa_vector & 0x07);
- }
- isa_outb(IO_ICU1, 0x60 | (isa_vector > 7 ? 2 : isa_vector));
-#endif
-
+ if(isa_vector > 7) {
+ isa_outb(IO_ICU2, 0x60 | isa_vector & 0x07);
}
- splx(pcpl); /* allow other interrupts */
-#if 1
- ppc_intr_disable();
+ isa_outb(IO_ICU1, 0x60 | (isa_vector > 7 ? 2 : isa_vector));
#endif
+
+ splx(pcpl); /* Process pendings. */
}
@@ -650,3 +586,4 @@ isabr_initicu()
#endif
isa_outb(IO_ICU2, 0x0a); /* Read IRR by default */
}
+