#include <commproc.h>
#include "vecnum.h"
+DECLARE_GLOBAL_DATA_PTR;
+
/****************************************************************************/
/*
};
static struct irq_action irq_vecs[32];
+void uic0_interrupt( void * parms); /* UIC0 handler */
#if defined(CONFIG_440)
static struct irq_action irq_vecs1[32]; /* For UIC1 */
void uic1_interrupt( void * parms); /* UIC1 handler */
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
static struct irq_action irq_vecs2[32]; /* For UIC2 */
-
-void uic0_interrupt( void * parms); /* UIC0 handler */
void uic2_interrupt( void * parms); /* UIC2 handler */
-#endif /* CONFIG_440GX */
+#endif /* CONFIG_440GX CONFIG_440SPE */
+
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+static struct irq_action irq_vecs3[32]; /* For UIC3 */
+void uic3_interrupt( void * parms); /* UIC3 handler */
+#endif /* CONFIG_440SPE */
#endif /* CONFIG_440 */
int interrupt_init_cpu (unsigned *decrementer_count)
{
- DECLARE_GLOBAL_DATA_PTR;
-
int vec;
unsigned long val;
irq_vecs1[vec].handler = NULL;
irq_vecs1[vec].arg = NULL;
irq_vecs1[vec].count = 0;
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
irq_vecs2[vec].handler = NULL;
irq_vecs2[vec].arg = NULL;
irq_vecs2[vec].count = 0;
#endif /* CONFIG_440GX */
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+ irq_vecs3[vec].handler = NULL;
+ irq_vecs3[vec].arg = NULL;
+ irq_vecs3[vec].count = 0;
+#endif /* CONFIG_440SPE */
#endif
}
} /* external_interrupt CONFIG_440GX */
+#elif defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+void external_interrupt(struct pt_regs *regs)
+{
+ ulong uic_msr;
+
+ /*
+ * Read masked interrupt status register to determine interrupt source
+ */
+ /* 440 SPe uses base uic register */
+ uic_msr = mfdcr(uic0msr);
+
+ if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) )
+ uic1_interrupt(0);
+
+ if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) )
+ uic2_interrupt(0);
+
+ if (uic_msr & ~(UICB0_ALL))
+ uic0_interrupt(0);
+
+ mtdcr(uic0sr, uic_msr);
+
+ return;
+
+} /* external_interrupt CONFIG_440EPX & CONFIG_440GRX */
+
+#elif defined(CONFIG_440SPE)
+void external_interrupt(struct pt_regs *regs)
+{
+ ulong uic_msr;
+
+ /*
+ * Read masked interrupt status register to determine interrupt source
+ */
+ /* 440 SPe uses base uic register */
+ uic_msr = mfdcr(uic0msr);
+
+ if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) )
+ uic1_interrupt(0);
+
+ if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) )
+ uic2_interrupt(0);
+
+ if ( (UICB0_UIC3CI & uic_msr) || (UICB0_UIC3NCI & uic_msr) )
+ uic3_interrupt(0);
+
+ if (uic_msr & ~(UICB0_ALL))
+ uic0_interrupt(0);
+
+ mtdcr(uic0sr, uic_msr);
+
+ return;
+} /* external_interrupt CONFIG_440SPE */
+
#else
void external_interrupt(struct pt_regs *regs)
}
#endif
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
/* Handler for UIC0 interrupt */
void uic0_interrupt( void * parms)
{
}
#endif /* defined(CONFIG_440) */
-#if defined(CONFIG_440GX)
-/* Handler for UIC1 interrupt */
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+/* Handler for UIC2 interrupt */
void uic2_interrupt( void * parms)
{
ulong uic2_msr;
(*irq_vecs2[vec].handler)(irq_vecs2[vec].arg);
} else {
mtdcr(uic2er, mfdcr(uic2er) & ~(0x80000000 >> vec));
- printf ("Masking bogus interrupt vector (uic1) 0x%x\n", vec);
+ printf ("Masking bogus interrupt vector (uic2) 0x%x\n", vec);
}
/*
}
#endif /* defined(CONFIG_440GX) */
+#if defined(CONFIG_440SPE)
+/* Handler for UIC3 interrupt */
+void uic3_interrupt( void * parms)
+{
+ ulong uic3_msr;
+ ulong msr_shift;
+ int vec;
+
+ /*
+ * Read masked interrupt status register to determine interrupt source
+ */
+ uic3_msr = mfdcr(uic3msr);
+ msr_shift = uic3_msr;
+ vec = 0;
+
+ while (msr_shift != 0) {
+ if (msr_shift & 0x80000000) {
+ /*
+ * Increment irq counter (for debug purpose only)
+ */
+ irq_vecs3[vec].count++;
+
+ if (irq_vecs3[vec].handler != NULL) {
+ /* call isr */
+ (*irq_vecs3[vec].handler)(irq_vecs3[vec].arg);
+ } else {
+ mtdcr(uic3er, mfdcr(uic3er) & ~(0x80000000 >> vec));
+ printf ("Masking bogus interrupt vector (uic3) 0x%x\n", vec);
+ }
+
+ /*
+ * After servicing the interrupt, we have to remove the status indicator.
+ */
+ mtdcr(uic3sr, (0x80000000 >> vec));
+ }
+
+ /*
+ * Shift msr to next position and increment vector
+ */
+ msr_shift <<= 1;
+ vec++;
+ }
+}
+#endif /* defined(CONFIG_440SPE) */
+
/****************************************************************************/
/*
int i = vec;
#if defined(CONFIG_440)
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64)) {
i = vec - 32;
irqa = irq_vecs1;
irqa[i].arg = arg;
#if defined(CONFIG_440)
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64))
mtdcr (uic1er, mfdcr (uic1er) | (0x80000000 >> i));
else if (vec > 63)
int i = vec;
#if defined(CONFIG_440)
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64)) {
irqa = irq_vecs1;
i = vec - 32;
#endif
#if defined(CONFIG_440)
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
if ((vec > 31) && (vec < 64))
mtdcr (uic1er, mfdcr (uic1er) & ~(0x80000000 >> i));
else if (vec > 63)
printf("\n");
#endif
-#if defined(CONFIG_440GX)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+ defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
printf ("\nUIC 2\n");
printf ("Nr Routine Arg Count\n");
printf("\n");
#endif
+#if defined(CONFIG_440SPE)
+ printf ("\nUIC 3\n");
+ printf ("Nr Routine Arg Count\n");
+
+ for (vec=0; vec<32; vec++) {
+ if (irq_vecs3[vec].handler != NULL)
+ printf ("%02d %08lx %08lx %d\n",
+ vec+63, (ulong)irq_vecs3[vec].handler,
+ (ulong)irq_vecs3[vec].arg, irq_vecs3[vec].count);
+ }
+ printf("\n");
+#endif
+
return 0;
}
#endif /* CONFIG_COMMANDS & CFG_CMD_IRQ */