summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/nested_irq_test.c
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2007-12-08 23:43:24 +0000
committerTill Straumann <strauman@slac.stanford.edu>2007-12-08 23:43:24 +0000
commit94e1931c5b8ce7e34c4293efbb8dcc106a532ac9 (patch)
tree3723b8eeed0bb1cdf8905c4ba89a8b25720243da /c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/nested_irq_test.c
parent2007-12-08 Till Straumann <strauman@slac.stanford.edu> (diff)
downloadrtems-94e1931c5b8ce7e34c4293efbb8dcc106a532ac9.tar.bz2
2007-12-08 Till Straumann <strauman@slac.stanford.edu>
* new-exceptions/bspsupport/, new-exceptions/bspsupport/ppc_exc.S, new-exceptions/bspsupport/ppc_exc_test.c, new-exceptions/bspsupport/vectors.h, new-exceptions/bspsupport/vectors_init.c, new-exceptions/bspsupport/irq.c, new-exceptions/bspsupport/ppc_exc_bspsupp.h, new-exceptions/bspsupport/ppc_exc_hdl.c, new-exceptions/bspsupport/ppc_exc_asm_macros.h, new-exceptions/bspsupport/nested_irq_test.c: New files. Added 'middleware' code for helping BSPs implement exception and interrupt handling and implementing the 'new' RTEMS IRQ API (which I personally dislike).
Diffstat (limited to 'c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/nested_irq_test.c')
-rw-r--r--c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/nested_irq_test.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/nested_irq_test.c b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/nested_irq_test.c
new file mode 100644
index 0000000000..999563d12a
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/nested_irq_test.c
@@ -0,0 +1,107 @@
+/*
+ * Test nested interrupts.
+ *
+ * Author: Till Straumann <strauman@slac.stanford.edu>, 2007
+ *
+ * The license and distribution terms for this file may be
+ * found in found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+
+/*
+ * Needs board with 2 available openpic timers
+ *
+ * 'timer_instdis(timer, install, period)'
+ *
+ * installs 'timer_isr' to openpic timer # 'timer'.
+ * The interrupt priority is set to 8 + timer#
+ *
+ * The timer_isr prints a message then polls
+ * the variable 'timer_poll' while it has the value
+ * of the timer # then sets it to -1 and prints
+ * the 'leave' message.
+ *
+ * To test nested interrupts:
+ *
+ * timer_instdis(0, 1, period)
+ * wait_a_bit()
+ * timer_instdis(1, 1, period)
+ * timer_poll = 0;
+ *
+ * As soon as timer 0's IRQ fires the
+ * isr prints
+ * TIMER ISR (0) ...
+ * then starts polling (since timer_poll == 0 )
+ * eventually, timer 1 goes off, interrupts (because
+ * it's priority is 9 (i.e., higher than timer 0's priority)
+ * and prints
+ * TIMER ISR (1)
+ * it skips polling since timer_poll is 0, not 1 but
+ * resets timer_poll -1 and prints
+ * Leaving ISR (1)
+ * timer 0 isr resumes polling and finds timer_poll == -1
+ * so it also writes -1 to timer_poll and exits, printing
+ * Leaving ISR (0)
+ *
+ * The timer IRQs can be unhooked with
+ * timer_instdis( 0, 0, period );
+ * timer_instdis( 1, 0, period );
+ */
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <bsp/openpic.h>
+#include <bsp/irq.h>
+#include <inttypes.h>
+#include <stdio.h>
+
+volatile int timer_poll=-1;
+
+static void timer_isr(rtems_irq_hdl_param p)
+{
+uint32_t top;
+uint32_t r1;
+uint32_t lat = (OpenPIC->Global.Timer[(int)p].Current_Count & 0x7fffffff);
+
+ lat = OpenPIC->Global.Timer[(int)p].Base_Count - lat;
+
+ asm volatile("mfspr %0, %2; mr %1, 1":"=r"(top),"=r"(r1):"i"(SPRG1));
+ printk("Timer ISR (%i): LAT: 0x%08x, TOP 0x%08x, BOT 0x%08x, SP 0x%08x\n",
+ (int)p, lat, top, top-rtems_configuration_get_interrupt_stack_size(), r1);
+ printk("_ISR_Nest_level %i\n", _ISR_Nest_level);
+ while ( timer_poll == (int)p )
+ ;
+ timer_poll = -1;
+
+ printk("Leaving ISR (%i)\n",(int)p);
+}
+
+int timer_instdis(int t, int inst, unsigned period)
+{
+rtems_irq_connect_data xx;
+ xx.name = BSP_MISC_IRQ_LOWEST_OFFSET + t;
+ xx.hdl = timer_isr;
+ xx.handle = (rtems_irq_hdl_param)t;
+ xx.on = 0;
+ xx.off = 0;
+ xx.isOn = 0;
+ if ( !inst ) {
+ openpic_maptimer(t, 0);
+ openpic_inittimer(t, 0, 0);
+ }
+ if ( ! ( inst ? BSP_install_rtems_irq_handler(&xx) : BSP_remove_rtems_irq_handler(&xx) ) ) {
+ openpic_maptimer(t, 0);
+ openpic_inittimer(t, 0, 0);
+ fprintf(stderr,"unable to %s timer ISR #%i\n", inst ? "install" : "remove", t);
+ return -1;
+ }
+ if ( inst ) {
+ openpic_maptimer( t, 1 );
+ openpic_inittimer( t, 8 + t, OPENPIC_VEC_SOURCE + xx.name );
+ openpic_settimer( t, period, 1 );
+ }
+ return 0;
+}
+