summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.c
diff options
context:
space:
mode:
authorRalf Corsepius <ralf.corsepius@rtems.org>2004-03-08 15:36:03 +0000
committerRalf Corsepius <ralf.corsepius@rtems.org>2004-03-08 15:36:03 +0000
commit0aee2be50e93ea3e719102e6f0e59d8364f8ba0c (patch)
treef16e0ae9765416f62e4f512b10cad61d57cf2c02 /c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.c
parentUnused (diff)
downloadrtems-0aee2be50e93ea3e719102e6f0e59d8364f8ba0c.tar.bz2
2004-03-08 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* mpc5xx/.cvsignore, mpc5xx/Makefile.am: New. * mpc5xx/exceptions/asm_utils.S, mpc5xx/exceptions/raw_exception.c, mpc5xx/exceptions/raw_exception.h, mpc5xx/ictrl/ictrl.c, mpc5xx/ictrl/ictrl.h, mpc5xx/timer/timer.c: New (Submission from Wilfried Busalski <w.busalski@lancier-monitoring.de>).
Diffstat (limited to 'c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.c')
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.c b/c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.c
new file mode 100644
index 0000000000..9590e5ba1a
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/ictrl/ictrl.c
@@ -0,0 +1,68 @@
+/*
+ * mpc505/509 external interrupt controller management.
+ */
+
+#include "ictrl.h"
+
+#include <rtems.h>
+#include <rtems/score/ppc.h>
+
+/*
+ * Internal routines.
+ */
+
+static unsigned long volatile *const IRQAND =
+ (unsigned long volatile *const)0x8007EFA4;
+
+static void nullHandler()
+{
+}
+
+/* Interrupt dispatch table. */
+static ExtIsrHandler extIrqHandlers[NUM_IRQS] =
+{
+ nullHandler,
+ nullHandler,
+ nullHandler,
+ nullHandler,
+ nullHandler,
+ nullHandler,
+ nullHandler
+};
+
+
+/* RTEMS external interrupt handler. Calls installed external interrupt
+ handlers for every pending external interrupt in turn. */
+static rtems_isr extIsr_( rtems_vector_number i )
+{
+#define BIT_NUMBER(val, bit) \
+ asm volatile ( "cntlzw %0, %1; srawi %0, %0, 1": "=r" (bit) : "r" (val) );
+
+ int bit;
+ (void)i;
+
+ BIT_NUMBER(*IRQAND & IMASK_ALL, bit);
+ while ( bit < NUM_IRQS ) {
+ extIrqHandlers[bit]();
+ BIT_NUMBER(*IRQAND & IMASK_ALL, bit);
+ }
+}
+
+/*
+ * Public routines
+ */
+
+void extIrqSetHandler(ExtInt interrupt,ExtIsrHandler handler)
+{
+ extIrqHandlers[interrupt] = handler;
+}
+
+void extIsrInit( void )
+{
+ int i = 0;
+
+ extIrqDisable(IMASK_ALL);
+ for( i = 0; i < NUM_IRQS; i++)
+ extIrqHandlers[i] = nullHandler;
+ set_vector(extIsr_,PPC_IRQ_EXTERNAL,1);
+}