diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2004-05-14 18:29:40 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2004-05-14 18:29:40 +0000 |
commit | 01c6fb100737e690fff3589215185bab71a22597 (patch) | |
tree | 8c961b2190adb5604633d90f7b877b42e158a4c0 /sys/arch/mvmeppc/dev/openpic.c | |
parent | c3658d497737978c16ec807a0b1a46bbe6d62b58 (diff) |
Really working interrupt engine, at least on both 2600 flavours.
Diffstat (limited to 'sys/arch/mvmeppc/dev/openpic.c')
-rw-r--r-- | sys/arch/mvmeppc/dev/openpic.c | 69 |
1 files changed, 36 insertions, 33 deletions
diff --git a/sys/arch/mvmeppc/dev/openpic.c b/sys/arch/mvmeppc/dev/openpic.c index 4143f888390..849687e289d 100644 --- a/sys/arch/mvmeppc/dev/openpic.c +++ b/sys/arch/mvmeppc/dev/openpic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: openpic.c,v 1.14 2004/05/08 20:10:12 miod Exp $ */ +/* $OpenBSD: openpic.c,v 1.15 2004/05/14 18:29:39 miod Exp $ */ /*- * Copyright (c) 1995 Per Fogelstrom @@ -66,6 +66,8 @@ #define ICU_OFFSET 0 #define PIC_OFFSET 16 +#define PIC_SPURIOUS 0xff + unsigned char icu1_val = 0xff; unsigned char icu2_val = 0xff; unsigned char elcr1_val = 0x00; @@ -95,7 +97,7 @@ void openpic_enable_irq(int, int); void openpic_disable_irq(int); void openpic_init(void); void openpic_set_priority(int, int); -static __inline int openpic_read_irq(int); +static __inline int openpic_iack(int); static __inline void openpic_eoi(int); void openpic_initirq(int, int, int); @@ -543,11 +545,12 @@ intr_calculatemasks() else i8259_disable_irq(hwirq[irq]); } - imen = ~irqs; } /* always enable the chained 8259 interrupt */ i8259_enable_irq(IRQ_SLAVE, IST_EDGE); + + imen = ~irqs; i8259_set_irq_mask(); } @@ -572,8 +575,8 @@ mapirq(irq) hwirq[v] = irq; virq[irq] = v; -#if 0 - printf("\nmapirq %x to %x\n", irq, v); +#ifdef DEBUG + printf("mapirq %x to %x\n", irq, v); #endif return v; @@ -605,10 +608,10 @@ openpic_do_pending_int() if (processing) return; - s = ppc_intr_disable(); processing = 1; - pcpl = splhigh(); /* Turn off all */ + s = ppc_intr_disable(); + hwpend = ipending & ~pcpl; /* Do now unmasked pendings */ imen &= ~hwpend; openpic_enable_irq_mask(~imen); @@ -651,8 +654,8 @@ openpic_do_pending_int() i8259_set_irq_mask(); #endif - processing = 0; ppc_intr_enable(s); + processing = 0; } u_int @@ -710,7 +713,7 @@ openpic_enable_irq(irq, type) irq -= PIC_OFFSET; while ((x = openpic_read(OPENPIC_SRC_VECTOR(irq))) & OPENPIC_ACTIVITY) { - x = openpic_read_irq(0); + x = openpic_iack(0); openpic_eoi(0); } @@ -765,7 +768,7 @@ i8259_disable_irq(irq) { #ifdef DIAGNOSTIC /* skip invalid irqs */ - if (irq < 0 || irq > 15) + if (irq < 0 || irq >= PIC_OFFSET) return; #endif @@ -785,7 +788,7 @@ i8259_enable_irq(irq, type) { #ifdef DIAGNOSTIC /* skip invalid irqs */ - if (irq < 0 || irq > 15) + if (irq < 0 || irq >= PIC_OFFSET) return; #endif @@ -810,7 +813,7 @@ i8259_eoi(int irq) { #ifdef DIAGNOSTIC /* skip invalid irqs */ - if (irq < 0 || irq > 15) + if (irq < 0 || irq >= PIC_OFFSET) return; #endif if (irq < 8) @@ -834,7 +837,7 @@ openpic_set_priority(cpu, pri) } int -openpic_read_irq(cpu) +openpic_iack(cpu) int cpu; { return openpic_read(OPENPIC_IACK(cpu)) & OPENPIC_VECTOR_MASK; @@ -893,9 +896,13 @@ i8259_intr(void) */ outb(IO_ICU1, 0x0b); if ((inb(IO_ICU1) & 0x80) == 0) { - return 0xff; +#ifdef DIAGNOSTIC + printf("spurious interrupt on ICU1\n"); +#endif + return PIC_SPURIOUS; } } + return (ICU_OFFSET + irq); } @@ -909,14 +916,19 @@ ext_intr_openpic() pcpl = cpl; - realirq = openpic_read_irq(0); + realirq = openpic_iack(0); - while (realirq != 0xff) { + while (realirq != PIC_SPURIOUS) { if (realirq == 0x00) { + /* + * Interrupt from the PCI/ISA bridge. PCI interrupts + * are shadowed on the ISA PIC for compatibility with + * MVME1600, so simply handle the ISA PIC. + */ realirq = i8259_intr(); openpic_eoi(0); - if (realirq == 0xff) - continue; + if (realirq == PIC_SPURIOUS) + break; } else { realirq += PIC_OFFSET; } @@ -941,26 +953,16 @@ ext_intr_openpic() } else { if (realirq >= PIC_OFFSET) { openpic_disable_irq(realirq); - openpic_eoi(0); } else { i8259_disable_irq(realirq); i8259_set_irq_mask(); - i8259_eoi(realirq); } ocpl = splraise(intrmask[irq]); ih = intrhand[irq]; while (ih) { -#if 0 - ppc_intr_enable(1); -#endif - (*ih->ih_fun)(ih->ih_arg); - -#if 0 - ppc_intr_disable(); -#endif ih = ih->ih_next; } @@ -971,17 +973,18 @@ ext_intr_openpic() #if 0 evirq[realirq].ev_count++; #endif - if (realirq >= PIC_OFFSET) + if (realirq >= PIC_OFFSET) { + openpic_eoi(0); openpic_enable_irq(realirq, intrtype[irq]); - else { + } else { + i8259_eoi(realirq); i8259_enable_irq(realirq, intrtype[irq]); i8259_set_irq_mask(); } } - realirq = openpic_read_irq(0); + realirq = openpic_iack(0); } - ppc_intr_enable(1); splx(pcpl); /* Process pendings. */ @@ -1042,7 +1045,7 @@ openpic_init() /* clear all pending interrunts */ /* < ICU_LEN ? */ for (irq = 0; irq < PIC_OFFSET; irq++) { - openpic_read_irq(0); + openpic_iack(0); openpic_eoi(0); } |