summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc/mpc5xx
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2004-04-12 22:04:28 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2004-04-12 22:04:28 +0000
commit8430205c224c1bfcb67156e5b97dd44ecd81fd7d (patch)
tree5ce5170ec6f228407d7ebfab0c1efbf17c495595 /c/src/lib/libcpu/powerpc/mpc5xx
parent2004-04-12 David Querbach <querbach@realtime.bc.ca> (diff)
downloadrtems-8430205c224c1bfcb67156e5b97dd44ecd81fd7d.tar.bz2
2004-04-12 David Querbach <querbach@realtime.bc.ca>
* README, configure.ac, mpc5xx/Makefile.am, mpc5xx/exceptions/raw_exception.c, mpc5xx/exceptions/raw_exception.h, mpc5xx/timer/timer.c, shared/include/cpuIdent.h: addition of a significant amount of MPC5xx support as part of the addition of the SS555 BSP. * mpc5xx/README, mpc5xx/clock/clock.c, mpc5xx/console-generic/console-generic.c, mpc5xx/include/console.h, mpc5xx/include/mpc5xx.h, mpc5xx/irq/irq.c, mpc5xx/irq/irq.h, mpc5xx/irq/irq_asm.S, mpc5xx/irq/irq_init.c, mpc5xx/vectors/vectors.S, mpc5xx/vectors/vectors.h, mpc5xx/vectors/vectors_init.c: New files. * mpc5xx/exceptions/asm_utils.S: Removed.
Diffstat (limited to 'c/src/lib/libcpu/powerpc/mpc5xx')
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/Makefile.am112
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/README27
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/clock/clock.c196
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/console-generic/console-generic.c347
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/exceptions/asm_utils.S64
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.c226
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.h102
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/include/console.h37
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/include/mpc5xx.h621
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/irq/irq.c495
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/irq/irq.h358
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/irq/irq_asm.S325
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/irq/irq_init.c152
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/timer/timer.c128
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.S203
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.h156
-rw-r--r--c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors_init.c137
17 files changed, 3377 insertions, 309 deletions
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/Makefile.am b/c/src/lib/libcpu/powerpc/mpc5xx/Makefile.am
index 582a354de6..2e035eac11 100644
--- a/c/src/lib/libcpu/powerpc/mpc5xx/Makefile.am
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/Makefile.am
@@ -10,14 +10,49 @@ noinst_DATA =
include $(top_srcdir)/../../../automake/compile.am
if mpc5xx
+include_mpc5xxdir = $(includedir)/mpc5xx
include_libcpudir = $(includedir)/libcpu
-# exceptions
+include_HEADERS = include/mpc5xx.h
+
+## clock
+EXTRA_PROGRAMS += clock.rel
+CLEANFILES += clock.rel
+clock_rel_SOURCES = clock/clock.c
+clock_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+clock_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+EXTRA_PROGRAMS += clock_g.rel
+CLEANFILES += clock_g.rel
+clock_g_rel_SOURCES = $(clock_rel_SOURCES)
+clock_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+clock_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_DATA += clock$(LIB_VARIANT).rel
+
+## console-generic
+include_mpc5xx_HEADERS = include/console.h
+
+EXTRA_PROGRAMS += console-generic.rel
+CLEANFILES += console-generic.rel
+console_generic_rel_SOURCES = console-generic/console-generic.c
+console_generic_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+console_generic_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+EXTRA_PROGRAMS += console-generic_g.rel
+CLEANFILES += console-generic_g.rel
+console_generic_g_rel_SOURCES = $(console_generic_rel_SOURCES)
+console_generic_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+console_generic_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_DATA += console-generic$(LIB_VARIANT).rel
+
+## exceptions
include_libcpu_HEADERS = exceptions/raw_exception.h
EXTRA_PROGRAMS += exceptions.rel
CLEANFILES += exceptions.rel
-exceptions_rel_SOURCES = exceptions/raw_exception.c exceptions/asm_utils.S
+exceptions_rel_SOURCES = exceptions/raw_exception.c
exceptions_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
exceptions_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
@@ -29,24 +64,24 @@ exceptions_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_DATA += exceptions$(LIB_VARIANT).rel
-# ictrl
-include_HEADERS = ictrl/ictrl.h
+## irq
+include_libcpu_HEADERS += irq/irq.h
-EXTRA_PROGRAMS += ictrl.rel
-CLEANFILES += ictrl.rel
-ictrl_rel_SOURCES = ictrl/ictrl.c ictrl/ictrl.h
-ictrl_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
-ictrl_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+EXTRA_PROGRAMS += irq.rel
+CLEANFILES += irq.rel
+irq_rel_SOURCES = irq/irq.c irq/irq_init.c irq/irq_asm.S
+irq_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+irq_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
-EXTRA_PROGRAMS += ictrl_g.rel
-CLEANFILES += ictrl_g.rel
-ictrl_g_rel_SOURCES = $(ictrl_rel_SOURCES)
-ictrl_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
-ictrl_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+EXTRA_PROGRAMS += irq_g.rel
+CLEANFILES += irq_g.rel
+irq_g_rel_SOURCES = $(irq_rel_SOURCES)
+irq_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+irq_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
-noinst_DATA += ictrl$(LIB_VARIANT).rel
+noinst_DATA += irq$(LIB_VARIANT).rel
-# timer
+## timer
EXTRA_PROGRAMS += timer.rel
CLEANFILES += timer.rel
timer_rel_SOURCES = timer/timer.c
@@ -60,8 +95,28 @@ timer_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
timer_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
noinst_DATA += timer$(LIB_VARIANT).rel
+
+## vectors
+include_libcpu_HEADERS += vectors/vectors.h
+
+EXTRA_PROGRAMS += vectors.rel
+CLEANFILES += vectors.rel
+vectors_rel_SOURCES = vectors/vectors_init.c vectors/vectors.S
+vectors_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_OPTIMIZE_V)
+vectors_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+EXTRA_PROGRAMS += vectors_g.rel
+CLEANFILES += vectors_g.rel
+vectors_g_rel_SOURCES = $(vectors_rel_SOURCES)
+vectors_g_rel_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_DEBUG_V)
+vectors_g_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
+
+noinst_DATA += vectors$(LIB_VARIANT).rel
endif
+## --
+all-local: $(PREINSTALL_FILES)
+
PREINSTALL_DIRS =
PREINSTALL_FILES =
@@ -71,21 +126,38 @@ $(PROJECT_INCLUDE)/$(dirstamp):
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/$(dirstamp)
if mpc5xx
+$(PROJECT_INCLUDE)/mpc5xx/$(dirstamp):
+ @$(mkdir_p) $(PROJECT_INCLUDE)/mpc5xx
+ @: > $(PROJECT_INCLUDE)/mpc5xx/$(dirstamp)
+PREINSTALL_DIRS += $(PROJECT_INCLUDE)/mpc5xx/$(dirstamp)
+
$(PROJECT_INCLUDE)/libcpu/$(dirstamp):
@$(mkdir_p) $(PROJECT_INCLUDE)/libcpu
@: > $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
PREINSTALL_DIRS += $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
+$(PROJECT_INCLUDE)/mpc5xx.h: include/mpc5xx.h $(PROJECT_INCLUDE)/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc5xx.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc5xx.h
+
+$(PROJECT_INCLUDE)/mpc5xx/console.h: include/console.h $(PROJECT_INCLUDE)/mpc5xx/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/mpc5xx/console.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/mpc5xx/console.h
+
$(PROJECT_INCLUDE)/libcpu/raw_exception.h: exceptions/raw_exception.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/raw_exception.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/raw_exception.h
-$(PROJECT_INCLUDE)/ictrl.h: ictrl/ictrl.h $(PROJECT_INCLUDE)/$(dirstamp)
- $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/ictrl.h
-PREINSTALL_FILES += $(PROJECT_INCLUDE)/ictrl.h
+$(PROJECT_INCLUDE)/libcpu/irq.h: irq/irq.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/irq.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/irq.h
+
+$(PROJECT_INCLUDE)/libcpu/vectors.h: vectors/vectors.h $(PROJECT_INCLUDE)/libcpu/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/libcpu/vectors.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/libcpu/vectors.h
endif
CLEANFILES += $(PREINSTALL_FILES)
DISTCLEANFILES = $(PREINSTALL_DIRS)
-include $(top_srcdir)/../../../../../automake/local.am
+include $(top_srcdir)/../../../automake/local.am
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/README b/c/src/lib/libcpu/powerpc/mpc5xx/README
new file mode 100644
index 0000000000..47b9a7b9be
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/README
@@ -0,0 +1,27 @@
+#
+# $Id$
+#
+
+Various non-BSP-dependent support routines.
+
+timer - Support for the RTEMS timer tick, using the Programmable
+ Interval Timer (PIT).
+
+console-generic - Console support via the on-chip dual SCI port in the QSMCM
+ module.
+
+exception - Installation and deinstallation of exception handlers, by
+ manipulation of exception vector table.
+
+irq - Exception handler for all external and decrementer interrupts.
+ Generalized interrupt handler which calls specific handlers
+ via entries in the interrupt connection table. Interrupt
+ connection table maintenance routines. USIU and UIMB
+ interrupt masking and level control.
+
+timer - Support for RTEMS timer tests, using the PowerPC timebase
+ (TB) registers.
+
+vectors - Compressed MPC5XX exception vector table, exception handler
+ prologues, default exception handler. Code to initialize
+ table with default handlers.
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/clock/clock.c b/c/src/lib/libcpu/powerpc/mpc5xx/clock/clock.c
new file mode 100644
index 0000000000..eac471218e
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/clock/clock.c
@@ -0,0 +1,196 @@
+/* clock.c
+ *
+ * This routine initializes the PIT on the MPC5xx.
+ * The tick frequency is specified by the bsp.
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c:
+ *
+ * Author: Jay Monkman (jmonkman@frasca.com)
+ * Copyright (C) 1998 by Frasca International, Inc.
+ *
+ * Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <clockdrv.h>
+#include <rtems/libio.h>
+#include <libcpu/irq.h>
+
+#include <stdlib.h> /* for atexit() */
+#include <mpc5xx.h>
+
+volatile rtems_unsigned32 Clock_driver_ticks;
+extern int BSP_connect_clock_handler(rtems_isr_entry);
+extern int BSP_disconnect_clock_handler();
+
+void Clock_exit( void );
+
+/*
+ * These are set by clock driver during its init
+ */
+
+rtems_device_major_number rtems_clock_major = ~0;
+rtems_device_minor_number rtems_clock_minor;
+
+/*
+ * ISR Handler
+ */
+rtems_isr Clock_isr(rtems_vector_number vector)
+{
+ usiu.piscrk = USIU_UNLOCK_KEY;
+ usiu.piscr |= USIU_PISCR_PS; /* acknowledge interrupt */
+ usiu.piscrk = 0;
+
+ Clock_driver_ticks++;
+ rtems_clock_tick();
+}
+
+void clockOn(void* unused)
+{
+ unsigned desiredLevel;
+ rtems_unsigned32 pit_value;
+
+ /* calculate and set modulus */
+ pit_value = (rtems_configuration_get_microseconds_per_tick() *
+ rtems_cpu_configuration_get_clicks_per_usec()) - 1 ;
+
+ if (pit_value > 0xffff) { /* pit is only 16 bits long */
+ rtems_fatal_error_occurred(-1);
+ }
+ usiu.sccrk = USIU_UNLOCK_KEY;
+ usiu.sccr &= ~USIU_SCCR_RTDIV; /* RTC and PIT clock is divided by 4 */
+ usiu.sccrk = 0;
+
+ usiu.pitck = USIU_UNLOCK_KEY;
+ usiu.pitc = pit_value;
+ usiu.pitck = 0;
+
+ /* set PIT irq level, enable PIT, PIT interrupts */
+ /* and clear int. status */
+ desiredLevel = CPU_irq_level_from_symbolic_name(CPU_PERIODIC_TIMER);
+
+ usiu.piscrk = USIU_UNLOCK_KEY;
+ usiu.piscr = USIU_PISCR_PIRQ(desiredLevel) /* set interrupt priority */
+ | USIU_PISCR_PS /* acknowledge interrupt */
+ | USIU_PISCR_PIE /* enable interrupt */
+ | USIU_PISCR_PITF /* freeze during debug */
+ | USIU_PISCR_PTE; /* enable timer */
+ usiu.piscrk = 0;
+}
+
+void
+clockOff(void* unused)
+{
+ /* disable PIT and PIT interrupts */
+ usiu.piscrk = USIU_UNLOCK_KEY;
+ usiu.piscr &= ~(USIU_PISCR_PTE | USIU_PISCR_PIE);
+ usiu.piscrk = 0;
+}
+
+int clockIsOn(void* unused)
+{
+ if (usiu.piscr & USIU_PISCR_PIE)
+ return 1;
+ return 0;
+}
+
+/*
+ * Called via atexit()
+ * Remove the clock interrupt handler by setting handler to NULL
+ */
+void
+Clock_exit(void)
+{
+ (void) BSP_disconnect_clock_handler ();
+}
+
+void Install_clock(rtems_isr_entry clock_isr)
+{
+ Clock_driver_ticks = 0;
+
+ BSP_connect_clock_handler (clock_isr);
+ atexit(Clock_exit);
+}
+
+void
+ReInstall_clock(rtems_isr_entry new_clock_isr)
+{
+ BSP_connect_clock_handler (new_clock_isr);
+}
+
+
+rtems_device_driver Clock_initialize(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ Install_clock( Clock_isr );
+
+ /*
+ * make major/minor avail to others such as shared memory driver
+ */
+
+ rtems_clock_major = major;
+ rtems_clock_minor = minor;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+rtems_device_driver Clock_control(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *pargp
+)
+{
+ rtems_libio_ioctl_args_t *args = pargp;
+
+ if (args == 0)
+ goto done;
+
+ /*
+ * This is hokey, but until we get a defined interface
+ * to do this, it will just be this simple...
+ */
+
+ if (args->command == rtems_build_name('I', 'S', 'R', ' ')) {
+ Clock_isr(0); /* vector number ignored */
+ }
+ else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) {
+ ReInstall_clock(args->buffer);
+ }
+
+ done:
+ return RTEMS_SUCCESSFUL;
+}
+
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/console-generic/console-generic.c b/c/src/lib/libcpu/powerpc/mpc5xx/console-generic/console-generic.c
new file mode 100644
index 0000000000..89282506a7
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/console-generic/console-generic.c
@@ -0,0 +1,347 @@
+/*
+ * General Serial I/O functions.
+ *
+ * This file contains the functions for performing serial I/O. The actual
+ * system calls (console_*) should be in the BSP part of the source tree.
+ * That way different BSPs can use whichever SCI they wish for /dev/console.
+ *
+ * On-chip resources used:
+ * resource minor note
+ * SCI1 0
+ * SCI2 1
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from
+ * c/src/lib/libcpu/powerpc/mpc8xx/console_generic/console_generic.c:
+ * Author: Jay Monkman (jmonkman@frasca.com)
+ * Copyright (C) 1998 by Frasca International, Inc.
+ *
+ * Derived from c/src/lib/libbsp/m68k/gen360/console/console.c written by:
+ * W. Eric Norum
+ * Saskatchewan Accelerator Laboratory
+ * University of Saskatchewan
+ * Saskatoon, Saskatchewan, CANADA
+ * eric@skatter.usask.ca
+ *
+ * COPYRIGHT (c) 1989-1998.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * Modifications by Darlene Stewart <Darlene.Stewart@iit.nrc.ca>
+ * and Charles-Antoine Gauthier <charles.gauthier@iit.nrc.ca>
+ * Copyright (c) 1999, National Research Council of Canada
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ *
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <termios.h>
+#include <rtems.h>
+#include <rtems/libio.h>
+#include <rtems/bspIo.h> /* for printk */
+#include <mpc5xx.h>
+#include <mpc5xx/console.h>
+#include <libcpu/irq.h>
+
+
+extern rtems_cpu_table Cpu_table; /* for CPU clock speed */
+
+/*
+ * SCI port descriptor table.
+ */
+typedef struct
+{
+ volatile m5xxSCIRegisters_t *regs; /* hardware registers */
+ struct rtems_termios_tty *ttyp; /* termios data for this port */
+} sci_desc;
+
+static sci_desc sci_descs[] = {
+ { &imb.qsmcm.sci1, 0 }, /* SCI 1 */
+ { &imb.qsmcm.sci2, 0 }, /* SCI 2 */
+};
+
+/*
+ * Number of SCI port initialization calls made so far. Used to avoid
+ * installing the common interrupt handler more than once.
+ */
+int init_calls = 0;
+
+/*
+ * Default configuration.
+ */
+static struct termios default_termios = {
+ 0, /* input mode flags */
+ 0, /* output mode flags */
+ CS8 | CREAD | CLOCAL | B9600, /* control mode flags */
+ 0, /* local mode flags */
+ 0, /* line discipline */
+ { 0 } /* control characters */
+};
+
+
+/*
+ * Termios callback functions
+ */
+
+int
+m5xx_uart_firstOpen(
+ int major,
+ int minor,
+ void *arg
+)
+{
+ rtems_libio_open_close_args_t *args = arg;
+ sci_desc* desc = &sci_descs[minor];
+ struct rtems_termios_tty *tty = args->iop->data1;
+
+ desc->ttyp = tty; /* connect tty */
+ if ( tty->device.outputUsesInterrupts == TERMIOS_IRQ_DRIVEN)
+ desc->regs->sccr1 |= QSMCM_SCI_RIE; /* enable rx interrupt */
+
+ return RTEMS_SUCCESSFUL;
+}
+
+int
+m5xx_uart_lastClose(
+ int major,
+ int minor,
+ void* arg
+)
+{
+ sci_desc* desc = &sci_descs[minor];
+
+ desc->regs->sccr1 &= ~(QSMCM_SCI_RIE | QSMCM_SCI_TIE); /* disable all */
+ desc->ttyp = NULL; /* disconnect tty */
+
+ return RTEMS_SUCCESSFUL;
+}
+
+int
+m5xx_uart_pollRead(
+ int minor
+)
+{
+ volatile m5xxSCIRegisters_t *regs = sci_descs[minor].regs;
+ int c = -1;
+
+ if ( regs ) {
+ while ( (regs->scsr & QSMCM_SCI_RDRF) == 0 )
+ ;
+ c = regs->scdr;
+ }
+
+ return c;
+}
+
+int
+m5xx_uart_write(
+ int minor,
+ const char *buf,
+ int len
+)
+{
+ volatile m5xxSCIRegisters_t *regs = sci_descs[minor].regs;
+
+ regs->scdr = *buf; /* start transmission */
+ regs->sccr1 |= QSMCM_SCI_TIE; /* enable interrupt */
+ return 0;
+}
+
+int
+m5xx_uart_pollWrite(
+ int minor,
+ const char *buf,
+ int len
+)
+{
+ volatile m5xxSCIRegisters_t *regs = sci_descs[minor].regs;
+
+ while ( len-- ) {
+ while ( (regs->scsr & QSMCM_SCI_TDRE) == 0 )
+ ;
+ regs->scdr = *buf++;
+ }
+ return 0;
+}
+
+void
+m5xx_uart_reserve_resources(
+ rtems_configuration_table *configuration
+)
+{
+ rtems_termios_reserve_resources (configuration, NUM_PORTS);
+}
+
+int
+m5xx_uart_setAttributes(
+ int minor,
+ const struct termios *t
+)
+{
+ rtems_unsigned16 sccr0 = sci_descs[minor].regs->sccr0;
+ rtems_unsigned16 sccr1 = sci_descs[minor].regs->sccr1;
+ int baud;
+
+ /*
+ * Check that port number is valid
+ */
+ if ( (minor < SCI1_MINOR) || (minor > SCI2_MINOR) )
+ return RTEMS_INVALID_NUMBER;
+
+ /* Baud rate */
+ switch (t->c_cflag & CBAUD) {
+ default: baud = -1; break;
+ case B50: baud = 50; break;
+ case B75: baud = 75; break;
+ case B110: baud = 110; break;
+ case B134: baud = 134; break;
+ case B150: baud = 150; break;
+ case B200: baud = 200; break;
+ case B300: baud = 300; break;
+ case B600: baud = 600; break;
+ case B1200: baud = 1200; break;
+ case B1800: baud = 1800; break;
+ case B2400: baud = 2400; break;
+ case B4800: baud = 4800; break;
+ case B9600: baud = 9600; break;
+ case B19200: baud = 19200; break;
+ case B38400: baud = 38400; break;
+ case B57600: baud = 57600; break;
+ case B115200: baud = 115200; break;
+ case B230400: baud = 230400; break;
+ case B460800: baud = 460800; break;
+ }
+ if (baud > 0) {
+ sccr0 &= ~QSMCM_SCI_BAUD(-1);
+ sccr0 |=
+ QSMCM_SCI_BAUD((Cpu_table.clock_speed + (16 * baud)) / (32 * baud));
+ }
+
+ /* Number of data bits -- not available with MPC5xx SCI */
+ switch ( t->c_cflag & CSIZE ) {
+ case CS5: break;
+ case CS6: break;
+ case CS7: break;
+ case CS8: break;
+ }
+
+ /* Stop bits -- not easily available with MPC5xx SCI */
+ if ( t->c_cflag & CSTOPB ) {
+ /* Two stop bits */
+ } else {
+ /* One stop bit */
+ }
+
+ /* Parity */
+ if ( t->c_cflag & PARENB )
+ sccr1 |= QSMCM_SCI_PE;
+ else
+ sccr1 &= ~QSMCM_SCI_PE;
+
+ if ( t->c_cflag & PARODD )
+ sccr1 |= QSMCM_SCI_PT;
+ else
+ sccr1 &= ~QSMCM_SCI_PT;
+
+ /* Transmitter and receiver enable */
+ sccr1 |= QSMCM_SCI_TE;
+ if ( t->c_cflag & CREAD )
+ sccr1 |= QSMCM_SCI_RE;
+ else
+ sccr1 &= ~QSMCM_SCI_RE;
+
+ /* Write hardware registers */
+ sci_descs[minor].regs->sccr0 = sccr0;
+ sci_descs[minor].regs->sccr1 = sccr1;
+
+ return RTEMS_SUCCESSFUL;
+}
+
+
+/*
+ * Interrupt handling.
+ */
+static void
+m5xx_sci_interrupt_handler (void)
+{
+ int minor;
+
+ for ( minor = 0; minor < NUM_PORTS; minor++ ) {
+ sci_desc *desc = &sci_descs[minor];
+ int sccr1 = desc->regs->sccr1;
+ int scsr = desc->regs->scsr;
+
+ /*
+ * Character received?
+ */
+ if ((sccr1 & QSMCM_SCI_RIE) && (scsr & QSMCM_SCI_RDRF)) {
+ char c = desc->regs->scdr;
+ rtems_termios_enqueue_raw_characters(desc->ttyp, &c, 1);
+ }
+ /*
+ * Transmitter empty?
+ */
+ if ((sccr1 & QSMCM_SCI_TIE) && (scsr & QSMCM_SCI_TDRE)) {
+ desc->regs->sccr1 &= ~QSMCM_SCI_TIE;
+ rtems_termios_dequeue_characters (desc->ttyp, 1);
+ }
+ }
+}
+
+void m5xx_sci_nop(const rtems_irq_connect_data* ptr)
+{
+}
+
+int m5xx_sci_isOn(const rtems_irq_connect_data* ptr)
+{
+ return 1;
+}
+
+/*
+ * Basic initialization.
+ */
+
+void
+m5xx_uart_initialize (int minor)
+{
+ /*
+ * Check that minor number is valid.
+ */
+ if ( (minor < SCI1_MINOR) || (minor > SCI2_MINOR) )
+ return;
+
+ /*
+ * Configure and enable receiver and transmitter.
+ */
+ m5xx_uart_setAttributes(minor, &default_termios);
+
+ /*
+ * Connect interrupt if not yet done.
+ */
+ if ( init_calls++ == 0 ) {
+ rtems_irq_connect_data irq_data;
+
+ irq_data.name = CPU_IRQ_SCI;
+ irq_data.hdl = m5xx_sci_interrupt_handler;
+ irq_data.on = m5xx_sci_nop; /* can't enable both channels here */
+ irq_data.off = m5xx_sci_nop; /* can't disable both channels here */
+ irq_data.isOn = m5xx_sci_isOn;
+
+ if (!CPU_install_rtems_irq_handler (&irq_data)) {
+ printk("Unable to connect SCI Irq handler\n");
+ rtems_fatal_error_occurred(1);
+ }
+
+ imb.qsmcm.qdsci_il = /* set interrupt level in port */
+ QSMCM_ILDSCI(CPU_irq_level_from_symbolic_name(CPU_IRQ_SCI));
+ }
+}
+
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/asm_utils.S b/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/asm_utils.S
deleted file mode 100644
index 36d9748c6b..0000000000
--- a/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/asm_utils.S
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * asm_utils.s
- *
- * asm_utils.S,v 1.2 2002/04/18 20:55:37 joel Exp
- *
- * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
- *
- * This file contains the low-level support for moving exception
- * exception code to appropriate location.
- *
- * Adapted for MPC5XX Wilfried Busalski (w.busalski@lancier-monitoring.de)
- * (C) Lancier Monitoring GmbH
- */
-
-#include <rtems/asm.h>
-#include <rtems/score/cpu.h>
-#include <libcpu/io.h>
-
-//SPR defines
-#define SPR_ICCST 560
-
-
- .globl codemove
-codemove:
- .type codemove,@function
-/* r3 dest, r4 src, r5 length in bytes, r6 cachelinesize */
- cmplw cr1,r3,r4
- addi r0,r5,3
- srwi. r0,r0,2
- beq cr1,4f /* In place copy is not necessary */
- beq 7f /* Protect against 0 count */
- mtctr r0
- bge cr1,2f
-
- la r8,-4(r4)
- la r7,-4(r3)
-1: lwzu r0,4(r8)
- stwu r0,4(r7)
- bdnz 1b
- b 4f
-
-2: slwi r0,r0,2
- add r8,r4,r0
- add r7,r3,r0
-3: lwzu r0,-4(r8)
- stwu r0,-4(r7)
- bdnz 3b
-
-/* Now flush the cache: note that we must start from a cache aligned
- * address. Otherwise we might miss one cache line.
- */
-
-4: lis r0, 0x0A00 // Command Unlock All
- mtspr SPR_ICCST, r0 // Cache Unlock ALL
-
- lis r0, 0x0C00 // Command Invalidate All
- mtspr SPR_ICCST, r0 // Cache Invalidate ALL
-
- lis r0, 0x0200 // Command Enable All
- mtspr SPR_ICCST, r0 // Cache Enable ALL
-
-7: sync /* Wait for all icbi to complete on bus */
- isync
- blr
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.c b/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.c
index 649ec0b956..12fff2394e 100644
--- a/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.c
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.c
@@ -1,24 +1,26 @@
/*
- * raw_exception.c - This file contains implementation of C function to
- * Instanciate 8xx ppc primary exception entries.
- * More detailled information can be found on motorola
- * site and more precisely in the following book :
+ * raw_exception.c - This file contains implementation of C functions to
+ * Instantiate mpc5xx primary exception entries.
+ * More detailled information can be found on the Motorola
+ * site and more precisely in the following book:
*
- * MPC860
- * Risc Microporcessor User's Manual
- * Motorola REF : MPC860UM/AD
+ * MPC555/MPC556 User's Manual
+ * Motorola REF : MPC555UM/D Rev. 3, 2000 October 15
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from libcpu/powerpc/mpc8xx/exceptions/raw_exception.c:
*
* Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
* Canon Centre Recherche France.
*
- * Changes for MPC5XX Wilfried Busalski (w.busalski@lancier-monitoring.de)
- * Copyright (C) 2003 Lancier Monitoring GmbH
- *
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
- * http://www.OARcorp.com/rtems/license.html.
+ * http://www.rtems.com/license/LICENSE.
*
- * raw_exception.c,v 1.5 2002/11/04 14:29:02 joel Exp
+ * $Id$
*/
#include <rtems/system.h>
@@ -29,88 +31,76 @@
#include <rtems/bspIo.h> /* for printk */
#include <string.h>
-void * codemove(void *, const void *, unsigned int, unsigned long);
-
static rtems_raw_except_connect_data* raw_except_table;
static rtems_raw_except_connect_data default_raw_except_entry;
static rtems_raw_except_global_settings* local_settings;
-int mpc565_vector_is_valid(rtems_vector vector)
-{
- switch(vector) {
- case ASM_RESET_VECTOR: /* fall through */
- case ASM_MACH_VECTOR:
- case ASM_PROT_VECTOR:
- case ASM_ISI_VECTOR:
- case ASM_EXT_VECTOR:
- case ASM_ALIGN_VECTOR:
- case ASM_PROG_VECTOR:
- case ASM_FLOAT_VECTOR:
- case ASM_DEC_VECTOR:
-
- case ASM_SYS_VECTOR:
- case ASM_TRACE_VECTOR:
- case ASM_FLOATASSIST_VECTOR:
-
- case ASM_SOFTEMUL_VECTOR:
-
- case ASM_ITLBERROR_VECTOR:
- case ASM_DTLBERROR_VECTOR:
-
- case ASM_DBREAK_VECTOR:
- case ASM_IBREAK_VECTOR:
- case ASM_PERIFBREAK_VECTOR:
- case ASM_DEVPORT_VECTOR:
- return 1;
- default: return 0;
- }
-}
-
int mpc5xx_vector_is_valid(rtems_vector vector)
{
- switch (current_ppc_cpu) {
- case MPC_5XX:
- if (!mpc565_vector_is_valid(vector)) {
- return 0;
- }
- break;
- default:
- printk("Please complete libcpu/powerpc/mpc5xx/exceptions/raw_exception.c\n");
- printk("current_ppc_cpu = %x\n", current_ppc_cpu);
- return 0;
- }
- return 1;
+ switch (current_ppc_cpu) {
+ case PPC_5XX:
+ switch(vector) {
+ case ASM_RESET_VECTOR:
+ case ASM_MACH_VECTOR:
+
+ case ASM_EXT_VECTOR:
+ case ASM_ALIGN_VECTOR:
+ case ASM_PROG_VECTOR:
+ case ASM_FLOAT_VECTOR:
+ case ASM_DEC_VECTOR:
+
+ case ASM_SYS_VECTOR:
+ case ASM_TRACE_VECTOR:
+ case ASM_FLOATASSIST_VECTOR:
+
+ case ASM_SOFTEMUL_VECTOR:
+
+ case ASM_IPROT_VECTOR:
+ case ASM_DPROT_VECTOR:
+
+ case ASM_DBREAK_VECTOR:
+ case ASM_IBREAK_VECTOR:
+ case ASM_MEBREAK_VECTOR:
+ case ASM_NMEBREAK_VECTOR:
+ return 1;
+ default:
+ return 0;
+ }
+ default:
+ printk("Please complete libcpu/powerpc/mpc5xx/exceptions/raw_exception.c\n");
+ printk("current_ppc_cpu = %x\n", current_ppc_cpu);
+ return 0;
+ }
}
int mpc5xx_set_exception (const rtems_raw_except_connect_data* except)
{
- unsigned int level;
+ unsigned int level;
- if (!mpc5xx_vector_is_valid(except->exceptIndex)) {
- return 0;
- }
- /*
- * Check if default handler is actually connected. If not issue an error.
- * You must first get the current handler via mpc5xx_get_current_exception
- * and then disconnect it using mpc5xx_delete_exception.
- * RATIONALE : to always have the same transition by forcing the user
- * to get the previous handler before accepting to disconnect.
- */
- if (memcmp(mpc5xx_get_vector_addr(except->exceptIndex), (void*)default_raw_except_entry.hdl.raw_hdl,default_raw_except_entry.hdl.raw_hdl_size)) {
- return 0;
- }
+ if (!mpc5xx_vector_is_valid(except->exceptIndex)) {
+ return 0;
+ }
+ /*
+ * Check if default handler is actually connected. If not issue an error.
+ * You must first get the current handler via mpc5xx_get_current_exception
+ * and then disconnect it using mpc5xx_delete_exception.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+ if (exception_handler_table[except->exceptIndex] !=
+ default_raw_except_entry.hdl.raw_hdl) {
+ return 0;
+ }
- _CPU_ISR_Disable(level);
-
- raw_except_table [except->exceptIndex] = *except;
- codemove((void*)mpc5xx_get_vector_addr(except->exceptIndex),
- except->hdl.raw_hdl,
- except->hdl.raw_hdl_size,
- PPC_CACHE_ALIGNMENT);
- except->on(except);
-
- _CPU_ISR_Enable(level);
- return 1;
+ _CPU_ISR_Disable(level);
+
+ raw_except_table[except->exceptIndex] = *except;
+
+ exception_handler_table[except->exceptIndex] = except->hdl.raw_hdl;
+ except->on(except);
+
+ _CPU_ISR_Enable(level);
+ return 1;
}
int mpc5xx_get_current_exception (rtems_raw_except_connect_data* except)
@@ -119,7 +109,7 @@ int mpc5xx_get_current_exception (rtems_raw_except_connect_data* except)
return 0;
}
- *except = raw_except_table [except->exceptIndex];
+ *except = raw_except_table[except->exceptIndex];
return 1;
}
@@ -138,20 +128,16 @@ int mpc5xx_delete_exception (const rtems_raw_except_connect_data* except)
* RATIONALE : to always have the same transition by forcing the user
* to get the previous handler before accepting to disconnect.
*/
- if (memcmp(mpc5xx_get_vector_addr(except->exceptIndex),
- (void*)except->hdl.raw_hdl,
- except->hdl.raw_hdl_size)) {
- return 0;
+ if (exception_handler_table[except->exceptIndex] != except->hdl.raw_hdl) {
+ return 0;
}
+
_CPU_ISR_Disable(level);
except->off(except);
- codemove((void*)mpc5xx_get_vector_addr(except->exceptIndex),
- default_raw_except_entry.hdl.raw_hdl,
- default_raw_except_entry.hdl.raw_hdl_size,
- PPC_CACHE_ALIGNMENT);
-
-
+ exception_handler_table[except->exceptIndex] =
+ default_raw_except_entry.hdl.raw_hdl;
+
raw_except_table[except->exceptIndex] = default_raw_except_entry;
raw_except_table[except->exceptIndex].exceptIndex = except->exceptIndex;
@@ -162,39 +148,37 @@ int mpc5xx_delete_exception (const rtems_raw_except_connect_data* except)
/*
* Exception global init.
+ *
+ * Install exception handler pointers from the raw exception table into the
+ * exception handler table.
*/
int mpc5xx_init_exceptions (rtems_raw_except_global_settings* config)
{
- unsigned i;
- unsigned int level;
-
- /*
- * store various accelerators
- */
- raw_except_table = config->rawExceptHdlTbl;
- local_settings = config;
- default_raw_except_entry = config->defaultRawEntry;
-
- _CPU_ISR_Disable(level);
-
- for (i=0; i <= LAST_VALID_EXC; i++) {
- if (!mpc5xx_vector_is_valid(i)){
- continue;
- }
- codemove((void*)mpc5xx_get_vector_addr(i),
- raw_except_table[i].hdl.raw_hdl,
- raw_except_table[i].hdl.raw_hdl_size,
- PPC_CACHE_ALIGNMENT);
- if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) {
- raw_except_table[i].on(&raw_except_table[i]);
- }
- else {
- raw_except_table[i].off(&raw_except_table[i]);
- }
+ unsigned i;
+ unsigned int level;
+
+ /*
+ * store various accelerators
+ */
+ raw_except_table = config->rawExceptHdlTbl;
+ local_settings = config;
+ default_raw_except_entry = config->defaultRawEntry;
+
+ _CPU_ISR_Disable(level);
+
+ for (i = 0; i < NUM_EXCEPTIONS; i++) {
+ exception_handler_table[i] = raw_except_table[i].hdl.raw_hdl;
+
+ if (raw_except_table[i].hdl.raw_hdl != default_raw_except_entry.hdl.raw_hdl) {
+ raw_except_table[i].on(&raw_except_table[i]);
+ }
+ else {
+ raw_except_table[i].off(&raw_except_table[i]);
}
- _CPU_ISR_Enable(level);
+ }
+ _CPU_ISR_Enable(level);
- return 1;
+ return 1;
}
int mpc5xx_get_exception_config (rtems_raw_except_global_settings** config)
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.h b/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.h
index 515a84a201..3b7e6783af 100644
--- a/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.h
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/exceptions/raw_exception.h
@@ -2,88 +2,62 @@
* raw_execption.h
*
* This file contains implementation of C function to
- * Instanciate 8xx ppc primary exception entries.
- * More detailled information can be found on motorola
- * site and more precisely in the following book :
+ * Instantiate mpc5xx primary exception entries.
+ * More detailled information can be found on the Motorola
+ * site and more precisely in the following book:
*
- * MPC860
- * Risc Microporcessor User's Manual
- * Motorola REF : MPC860UM/AD 07/98 Rev .1
+ * MPC555/MPC556 User's Manual
+ * Motorola REF : MPC555UM/D Rev. 3, 2000 October 15
*
- * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
- * Canon Centre Recherche France.
*
- * Changes for MPC5XX Wilfried Busalski (w.busalski@lancier-monitoring.de)
- * Copyright (C) 2003 Lancier Monitoring GmbH
-
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from libcpu/powerpc/mpc8xx/exceptions/raw_exception.h:
+ *
+ * Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
+ * Canon Centre Recherche France.
*
* The license and distribution terms for this file may be
* found in found in the file LICENSE in this distribution or at
- * http://www.OARcorp.com/rtems/license.html.
+ * http://www.rtems.com/license/LICENSE.
*
- * raw_exception.h,v 1.1 2001/04/06 15:54:18 joel Exp
+ * $Id$
*/
#ifndef _LIBCPU_MPC5XX_EXCEPTION_RAW_EXCEPTION_H
#define _LIBCPU_MPC5XX_EXCEPTION_RAW_EXCEPTION_H
+#include <libcpu/vectors.h>
+
/*
- * Exception Vectors as defined in the MCP750 manual
+ * Exception Vectors as defined in the MPC555 User's Manual
*/
-#define ASM_RESET_VECTOR 0x01
-#define ASM_MACH_VECTOR 0x02
-#define ASM_PROT_VECTOR 0x03
-#define ASM_ISI_VECTOR 0x04
-#define ASM_EXT_VECTOR 0x05
-#define ASM_ALIGN_VECTOR 0x06
-#define ASM_PROG_VECTOR 0x07
-#define ASM_FLOAT_VECTOR 0x08
-#define ASM_DEC_VECTOR 0x09
-
-#define ASM_SYS_VECTOR 0x0C
-#define ASM_TRACE_VECTOR 0x0D
-#define ASM_FLOATASSIST_VECTOR 0x0E
-
-#define ASM_SOFTEMUL_VECTOR 0x10
+#define ASM_RESET_VECTOR 0x01
+#define ASM_MACH_VECTOR 0x02
-#define ASM_ITLBERROR_VECTOR 0x13
-#define ASM_DTLBERROR_VECTOR 0x14
+#define ASM_EXT_VECTOR 0x05
+#define ASM_ALIGN_VECTOR 0x06
+#define ASM_PROG_VECTOR 0x07
+#define ASM_FLOAT_VECTOR 0x08
+#define ASM_DEC_VECTOR 0x09
-#define ASM_DBREAK_VECTOR 0x1C
-#define ASM_IBREAK_VECTOR 0x1D
-#define ASM_PERIFBREAK_VECTOR 0x1E
-#define ASM_DEVPORT_VECTOR 0x1F
-
-#define LAST_VALID_EXC ASM_DEVPORT_VECTOR
-
-/*
- * Vector offsets as defined in the MPC860 manual
- */
-
-#define ASM_RESET_VECTOR_OFFSET (ASM_RESET_VECTOR << 8)
-#define ASM_MACH_VECTOR_OFFSET (ASM_MACH_VECTOR << 8)
-#define ASM_PROT_VECTOR_OFFSET (ASM_PROT_VECTOR << 8)
-#define ASM_ISI_VECTOR_OFFSET (ASM_ISI_VECTOR << 8)
-#define ASM_EXT_VECTOR_OFFSET (ASM_EXT_VECTOR << 8)
-#define ASM_ALIGN_VECTOR_OFFSET (ASM_ALIGN_VECTOR << 8)
-#define ASM_PROG_VECTOR_OFFSET (ASM_PROG_VECTOR << 8)
-#define ASM_FLOAT_VECTOR_OFFSET (ASM_FLOAT_VECTOR << 8)
-#define ASM_DEC_VECTOR_OFFSET (ASM_DEC_VECTOR << 8)
+#define ASM_SYS_VECTOR 0x0C
+#define ASM_TRACE_VECTOR 0x0D
+#define ASM_FLOATASSIST_VECTOR 0x0E
-#define ASM_SYS_VECTOR_OFFSET (ASM_SYS_VECTOR << 8)
-#define ASM_TRACE_VECTOR_OFFSET (ASM_TRACE_VECTOR << 8)
-#define ASM_FLOATASSIST_VECTOR_OFFSET (ASM_FLOATASSIST_VECTOR << 8)
+#define ASM_SOFTEMUL_VECTOR 0x10
-#define ASM_SOFTEMUL_VECTOR_OFFSET (ASM_SOFTEMUL_VECTOR << 8)
+#define ASM_IPROT_VECTOR 0x13
+#define ASM_DPROT_VECTOR 0x14
-#define ASM_ITLBERROR_VECTOR_OFFSET (ASM_ITLBERROR_VECTOR << 8)
-#define ASM_DTLBERROR_VECTOR_OFFSET (ASM_DTLBERROR_VECTOR << 8)
+#define ASM_DBREAK_VECTOR 0x1C
+#define ASM_IBREAK_VECTOR 0x1D
+#define ASM_MEBREAK_VECTOR 0x1E
+#define ASM_NMEBREAK_VECTOR 0x1F
-#define ASM_DBREAK_VECTOR_OFFSET (ASM_DBREAK_VECTOR << 8)
-#define ASM_IBREAK_VECTOR_OFFSET (ASM_IBREAK_VECTOR << 8)
-#define ASM_PERIFBREAK_VECTOR_OFFSET (ASM_PERIFBREAK_VECTOR << 8)
-#define ASM_DEVPORT_VECTOR_OFFSET (ASM_DEVPORT_VECTOR_OFFSET << 8)
+#define LAST_VALID_EXC ASM_NMEBREAK_VECTOR
#ifndef ASM
@@ -93,13 +67,11 @@
typedef unsigned char rtems_vector;
struct __rtems_raw_except_connect_data__;
-typedef void (*rtems_raw_except_func) (void);
typedef unsigned char rtems_raw_except_hdl_size;
typedef struct {
rtems_vector vector;
- rtems_raw_except_func raw_hdl;
- rtems_raw_except_hdl_size raw_hdl_size;
+ rtems_exception_handler_t* raw_hdl;
}rtems_raw_except_hdl;
typedef void (*rtems_raw_except_enable) (const struct __rtems_raw_except_connect_data__*);
@@ -186,5 +158,7 @@ extern int mpc5xx_get_exception_config (rtems_raw_except_global_settings** confi
# endif /* ASM */
+#define SIZEOF_
+
#endif
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/include/console.h b/c/src/lib/libcpu/powerpc/mpc5xx/include/console.h
new file mode 100644
index 0000000000..83dbe8b7f3
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/include/console.h
@@ -0,0 +1,37 @@
+/*
+ * Console declarations
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * 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$
+ */
+
+#ifndef _M5xx_CONSOLE_H_
+#define _M5xx_CONSOLE_H_
+
+#include <rtems/libio.h>
+#include <rtems/termiostypes.h>
+
+void m5xx_uart_reserve_resources(rtems_configuration_table *configuration);
+void m5xx_uart_initialize(int minor);
+
+/* Termios callbacks */
+int m5xx_uart_firstOpen(int maj, int min, void *arg);
+int m5xx_uart_lastClose(int maj, int min, void *arg);
+int m5xx_uart_pollRead(int minor);
+int m5xx_uart_pollWrite(int minor, const char* buf, int len);
+int m5xx_uart_write(int minor, const char *buf, int len);
+int m5xx_uart_setAttributes(int, const struct termios* t);
+
+#define NUM_PORTS 2 /* number of serial ports */
+
+#define SCI1_MINOR 0
+#define SCI2_MINOR 1
+
+#endif /* _M5xx_CONSOLE_H_ */
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/include/mpc5xx.h b/c/src/lib/libcpu/powerpc/mpc5xx/include/mpc5xx.h
new file mode 100644
index 0000000000..2ec40702ea
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/include/mpc5xx.h
@@ -0,0 +1,621 @@
+/*
+ * mpc5xx.h
+ *
+ * MPC5xx Internal I/O Definitions
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from c/src/lib/libcpu/powerpc/mpc8xx/include/mpc8xx.h:
+ *
+ * Submitted By: *
+ * *
+ * W. Eric Norum *
+ * Saskatchewan Accelerator Laboratory *
+ * University of Saskatchewan *
+ * 107 North Road *
+ * Saskatoon, Saskatchewan, CANADA *
+ * S7N 5C6 *
+ * *
+ * eric@skatter.usask.ca *
+ * *
+ * Modified for use with the MPC860 (original code was for MC68360) *
+ * by *
+ * Jay Monkman *
+ * Frasca International, Inc. *
+ * 906 E. Airport Rd. *
+ * Urbana, IL, 61801 *
+ * *
+ * jmonkman@frasca.com *
+ * *
+ * Modified further for use with the MPC821 by: *
+ * Andrew Bray <andy@chaos.org.uk> *
+ * *
+ * With some corrections/additions by: *
+ * Darlene A. Stewart and *
+ * Charles-Antoine Gauthier *
+ * Institute for Information Technology *
+ * National Research Council of Canada *
+ * Ottawa, ON K1A 0R6 *
+ * *
+ * Darlene.Stewart@iit.nrc.ca *
+ * charles.gauthier@iit.nrc.ca *
+ * *
+ * Corrections/additions: *
+ * Copyright (c) 1999, National Research Council of Canada *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * 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$
+ */
+
+#ifndef _MPC5xx_h
+#define _MPC5xx_h
+
+#include <libcpu/spr.h>
+
+
+#ifndef ASM
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Macros for accessing Special Purpose Registers (SPRs)
+ */
+
+#define _eieio __asm__ volatile ("eieio\n"::)
+#define _sync __asm__ volatile ("sync\n"::)
+#define _isync __asm__ volatile ("isync\n"::)
+
+/*
+ * Core Registers (SPRs)
+ */
+#define DER 149 /* Debug Enable Register */
+#define IMMR 638 /* Internal Memory Map Register */
+#define IMMR_FLEN (1<<11) /* Internal flash ROM enabled */
+
+/*
+ * Interrupt Control Registers (SPRs)
+ */
+#define EIE 80 /* External Interrupt Enable Register */
+#define EID 81 /* External Interrupt Disable Register */
+#define NRI 82 /* Non-Recoverable Interrupt Register */
+
+#define ECR 148 /* Exception Cause Register */
+
+/*
+ * Bus Control Registers (SPRs)
+ */
+#define LCTRL1 156 /* L-Bus Support Control Register 1 */
+#define LCTRL2 157 /* L-Bus Support Control Register 2 */
+#define ICTRL 158 /* I-Bus Support Control Register */
+
+/*
+ * Burst Buffer Control Registers (SPRs)
+ */
+#define BBCMCR 560 /* Burst Buffer Configuration Register */
+#define BBCMCR_BE (1<<13) /* Burst enable */
+#define BBCMCR_ETRE (1<<12) /* Exception table relocation enable */
+
+#define MI_RBA0 784 /* Region 0 Address Register */
+#define MI_RBA1 785 /* Region 1 Address Register */
+#define MI_RBA2 786 /* Region 2 Address Register */
+#define MI_RBA3 787 /* Region 3 Address Register */
+
+#define MI_RA0 816 /* Region 0 Attribute Register */
+#define MI_RA1 817 /* Region 1 Attribute Register */
+#define MI_RA2 818 /* Region 2 Attribute Register */
+#define MI_RA3 819 /* Region 3 Attribute Register */
+#define MI_GRA 528 /* Region Global Attribute Register */
+#define MI_RA_PP (3 << 10) /* Protection bits: */
+#define MI_RA_PP_SUPV (1 << 10) /* Supervisor */
+#define MI_RA_PP_USER (2 << 10) /* User */
+#define MI_RA_G (1 << 6) /* Guarded region */
+
+
+/*
+ * L-Bus to U-Bus Interface (L2U) Registers (SPRs)
+ */
+#define L2U_MCR 568 /* L2U Module Configuration Register */
+
+#define L2U_RBA0 792 /* L2U Region 0 Address Register */
+#define L2U_RBA1 793 /* L2U Region 1 Address Register */
+#define L2U_RBA2 794 /* L2U Region 2 Address Register */
+#define L2U_RBA3 795 /* L2U Region 3 Address Register */
+
+#define L2U_RA0 824 /* L2U Region 0 Attribute Register */
+#define L2U_RA1 825 /* L2U Region 1 Attribute Register */
+#define L2U_RA2 826 /* L2U Region 2 Attribute Register */
+#define L2U_RA3 827 /* L2U Region 3 Attribute Register */
+#define L2U_GRA 536 /* L2U Global Region Attribute Register */
+#define L2U_RA_PP (3 << 10) /* Protection bits: */
+#define L2U_RA_PP_SUPV (1 << 10) /* Supervisor */
+#define L2U_RA_PP_USER (2 << 10) /* User */
+#define L2U_RA_G (1 << 6) /* Guarded region */
+
+
+/*
+ *************************************************************************
+ * REGISTER SUBBLOCKS *
+ *************************************************************************
+ */
+
+/*
+ *************************************************************************
+ * System Protection Control Register (SYPCR) *
+ *************************************************************************
+ */
+#define USIU_SYPCR_SWTC(x) ((x)<<16) /* Software watchdog timer count */
+#define USIU_SYPCR_BMT(x) ((x)<<8) /* Bus monitor timing */
+#define USIU_SYPCR_BME (1<<7) /* Bus monitor enable */
+#define USIU_SYPCR_SWF (1<<3) /* Software watchdog freeze */
+#define USIU_SYPCR_SWE (1<<2) /* Software watchdog enable */
+#define USIU_SYPCR_SWRI (1<<1) /* Watchdog reset/interrupt sel. */
+#define USIU_SYPCR_SWP (1<<0) /* Software watchdog prescale */
+
+#define USIU_SYPCR_BMT(x) ((x)<<8) /* Bus monitor timing */
+#define USIU_SYPCR_BME (1<<7) /* Bus monitor enable */
+#define USIU_SYPCR_SWF (1<<3) /* Software watchdog freeze */
+#define USIU_SYPCR_SWE (1<<2) /* Software watchdog enable */
+#define USIU_SYPCR_SWRI (1<<1) /* Watchdog reset/interrupt sel. */
+#define USIU_SYPCR_SWP (1<<0) /* Software watchdog prescale */
+
+/*
+ *************************************************************************
+ * Software Service Register (SWSR) *
+ *************************************************************************
+ */
+#define TICKLE_WATCHDOG() \
+do { \
+ usiu.swsr = 0x556C; \
+ usiu.swsr = 0xAA39; \
+} while (0) \
+
+/*
+ *************************************************************************
+ * Memory Control Registers *
+ *************************************************************************
+ */
+#define USIU_MEMC_BR_BA(x) (((rtems_unsigned32)x)&0xffff8000)
+ /* Base address */
+#define USIU_MEMC_BR_AT(x) ((x)<<12) /* Address type */
+#define USIU_MEMC_BR_PS8 (1<<10) /* 8 bit port */
+#define USIU_MEMC_BR_PS16 (2<<10) /* 16 bit port */
+#define USIU_MEMC_BR_PS32 (0<<10) /* 32 bit port */
+#define USIU_MEMC_BR_WP (1<<8) /* Write protect */
+#define USIU_MEMC_BR_WEBS (1<<5) /* Write enable/byte select */
+#define USIU_MEMC_BR_TBDIP (1<<4) /* Toggle-Burst data in progress*/
+#define USIU_MEMC_BR_LBDIP (1<<3) /* Late-burst data in progress */
+#define USIU_MEMC_BR_SETA (1<<2) /* External transfer acknowledge */
+#define USIU_MEMC_BR_BI (1<<1) /* Burst inhibit */
+#define USIU_MEMC_BR_V (1<<0) /* Base/Option register are valid */
+
+#define USIU_MEMC_OR_32K 0xffff8000 /* Address range */
+#define USIU_MEMC_OR_64K 0xffff0000
+#define USIU_MEMC_OR_128K 0xfffe0000
+#define USIU_MEMC_OR_256K 0xfffc0000
+#define USIU_MEMC_OR_512K 0xfff80000
+#define USIU_MEMC_OR_1M 0xfff00000
+#define USIU_MEMC_OR_2M 0xffe00000
+#define USIU_MEMC_OR_4M 0xffc00000
+#define USIU_MEMC_OR_8M 0xff800000
+#define USIU_MEMC_OR_16M 0xff000000
+#define USIU_MEMC_OR_32M 0xfe000000
+#define USIU_MEMC_OR_64M 0xfc000000
+#define USIU_MEMC_OR_128 0xf8000000
+#define USIU_MEMC_OR_256M 0xf0000000
+#define USIU_MEMC_OR_512M 0xe0000000
+#define USIU_MEMC_OR_1G 0xc0000000
+#define USIU_MEMC_OR_2G 0x80000000
+#define USIU_MEMC_OR_4G 0x00000000
+#define USIU_MEMC_OR_ATM(x) ((x)<<12) /* Address type mask */
+#define USIU_MEMC_OR_CSNT (1<<11) /* Chip select is negated early */
+#define USIU_MEMC_OR_ACS_NORM (0<<9) /* *CS asserted with addr lines */
+#define USIU_MEMC_OR_ACS_QRTR (2<<9) /* *CS asserted 1/4 after addr */
+#define USIU_MEMC_OR_ACS_HALF (3<<9) /* *CS asserted 1/2 after addr */
+#define USIU_MEMC_OR_ETHR (1<<8) /* Extended hold time on reads */
+#define USIU_MEMC_OR_SCY(x) ((x)<<4) /* Cycle length in clocks */
+#define USIU_MEMC_OR_BSCY(x) ((x)<<1) /* Burst beat length in clocks */
+#define USIU_MEMC_OR_TRLX (1<<0) /* Relaxed timing in GPCM */
+
+/*
+ *************************************************************************
+ * Clocks and Reset Controlmer *
+ *************************************************************************
+ */
+
+#define USIU_SCCR_DBCT (1<<31) /* Disable backup clock for timers */
+#define USIU_SCCR_COM(x) ((x)<<29) /* Clock output mode */
+#define USIU_SCCR_RTDIV (1<<24) /* RTC, PIT divide by 256, not 4 */
+#define USIU_PRQEN (1<<21) /* MSR[POW] controls frequency */
+#define USIU_SCCR_EBDF(x) ((x)<<17) /* External bus division factor */
+#define USIU_LME (1<<16) /* Enable limp mode */
+#define USIU_ENGDIV(x) ((x)<<9) /* Set engineering clock divisor */
+
+#define USIU_PLPRCR_MF(x) (((x)-1)<<20) /* PLL mult. factor (true) */
+#define USIU_PLPRCR_SPLS (1<<16) /* System PLL locked */
+#define USIU_PLPRCR_TEXPS (1<<14) /* Assert TEXP always */
+
+/*
+ *************************************************************************
+ * Programmable Interval Timer *
+ *************************************************************************
+ */
+#define USIU_PISCR_PIRQ(x) (1<<(15-x)) /* PIT interrupt level */
+#define USIU_PISCR_PS (1<<7) /* PIT Interrupt state */
+#define USIU_PISCR_PIE (1<<2) /* PIT interrupt enable */
+#define USIU_PISCR_PITF (1<<1) /* Stop timer when freeze asserted */
+#define USIU_PISCR_PTE (1<<0) /* PIT enable */
+
+/*
+ *************************************************************************
+ * Time Base *
+ *************************************************************************
+ */
+#define USIU_TBSCR_TBIRQ(x) (1<<(15-x)) /* TB interrupt level */
+#define USIU_TBSCR_REFA (1<<7) /* TB matches TBREFF0 */
+#define USIU_TBSCR_REFB (1<<6) /* TB matches TBREFF1 */
+#define USIU_TBSCR_REFAE (1<<3) /* Enable ints for REFA */
+#define USIU_TBSCR_REFBE (1<<2) /* Enable ints for REFB */
+#define USIU_TBSCR_TBF (1<<1) /* TB stops on FREEZE */
+#define USIU_TBSCR_TBE (1<<0) /* enable TB and decrementer */
+
+/*
+ *************************************************************************
+ * SIU Interrupt Mask *
+ *************************************************************************
+ */
+#define USIU_SIMASK_IRM0 (1<<31)
+#define USIU_SIMASK_LVM0 (1<<30)
+#define USIU_SIMASK_IRM1 (1<<29)
+#define USIU_SIMASK_LVM1 (1<<28)
+#define USIU_SIMASK_IRM2 (1<<27)
+#define USIU_SIMASK_LVM2 (1<<26)
+#define USIU_SIMASK_IRM3 (1<<25)
+#define USIU_SIMASK_LVM3 (1<<24)
+#define USIU_SIMASK_IRM4 (1<<23)
+#define USIU_SIMASK_LVM4 (1<<22)
+#define USIU_SIMASK_IRM5 (1<<21)
+#define USIU_SIMASK_LVM5 (1<<20)
+#define USIU_SIMASK_IRM6 (1<<19)
+#define USIU_SIMASK_LVM6 (1<<18)
+#define USIU_SIMASK_IRM7 (1<<17)
+#define USIU_SIMASK_LVM7 (1<<16)
+
+/*
+ *************************************************************************
+ * SIU Module Control *
+ *************************************************************************
+ */
+#define USIU_SIUMCR_EARB (1<<31)
+#define USIU_SIUMCR_EARP0 (0<<28)
+#define USIU_SIUMCR_EARP1 (1<<28)
+#define USIU_SIUMCR_EARP2 (2<<28)
+#define USIU_SIUMCR_EARP3 (3<<28)
+#define USIU_SIUMCR_EARP4 (4<<28)
+#define USIU_SIUMCR_EARP5 (5<<28)
+#define USIU_SIUMCR_EARP6 (6<<28)
+#define USIU_SIUMCR_EARP7 (7<<28)
+#define USIU_SIUMCR_DSHW (1<<23)
+#define USIU_SIUMCR_DBGC0 (0<<21)
+#define USIU_SIUMCR_DBGC1 (1<<21)
+#define USIU_SIUMCR_DBGC2 (2<<21)
+#define USIU_SIUMCR_DBGC3 (3<<21)
+#define USIU_SIUMCR_DBPC (1<<20)
+#define USIU_SIUMCR_ATWC (1<<19)
+#define USIU_SIUMCR_GPC0 (0<<17)
+#define USIU_SIUMCR_GPC1 (1<<17)
+#define USIU_SIUMCR_GPC2 (2<<17)
+#define USIU_SIUMCR_GPC3 (3<<17)
+#define USIU_SIUMCR_DLK (1<<16)
+#define USIU_SIUMCR_SC0 (0<<13)
+#define USIU_SIUMCR_SC1 (1<<13)
+#define USIU_SIUMCR_SC2 (2<<13)
+#define USIU_SIUMCR_SC3 (3<<13)
+#define USIU_SIUMCR_RCTX (1<<12)
+#define USIU_SIUMCR_MLRC0 (0<<10)
+#define USIU_SIUMCR_MLRC1 (1<<10)
+#define USIU_SIUMCR_MLRC2 (2<<10)
+#define USIU_SIUMCR_MLRC3 (3<<10)
+#define USIU_SIUMCR_MTSC (1<<7)
+
+/*
+ * Value to write to a key register to unlock the corresponding SIU register
+ */
+#define USIU_UNLOCK_KEY 0x55CCAA33
+
+/*
+ *************************************************************************
+ * UIMB Module Control *
+ *************************************************************************
+ */
+#define UIMB_UMCR_STOP (1<<31)
+#define UIMB_UMCR_IRQMUX(x) ((x)<<29)
+#define UIMB_UMCR_HSPEED (1<<28)
+
+/*
+ *************************************************************************
+ * QSMCM Serial Communications Interface (SCI) *
+ *************************************************************************
+ */
+
+
+#define QSMCM_ILDSCI(x) ((x)<<8) /* SCI interrupt level */
+
+#define QSMCM_SCI_BAUD(x) ((x)&0x1FFF) /* Baud rate field */
+
+#define QSMCM_SCI_LOOPS (1<<14) /* Loopback test mode */
+#define QSMCM_SCI_WOMS (1<<13) /* Wire-or mode select */
+#define QSMCM_SCI_ILT (1<<12) /* Idle-line detect type */
+#define QSMCM_SCI_PT (1<<11) /* Parity type */
+#define QSMCM_SCI_PE (1<<10) /* Parity enable */
+#define QSMCM_SCI_M (1<<9) /* 11-bit mode */
+#define QSMCM_SCI_WAKE (1<<8) /* Wakeup mode */
+
+#define QSMCM_SCI_TIE (1<<7) /* Transmitter interrupt enable */
+#define QSMCM_SCI_TCIE (1<<6) /* Transmit complete intr. enable */
+#define QSMCM_SCI_RIE (1<<5) /* Receiver interrupt enable */
+#define QSMCM_SCI_ILIE (1<<4) /* Idle line interrupt enable */
+#define QSMCM_SCI_TE (1<<3) /* Transmitter enable */
+#define QSMCM_SCI_RE (1<<2) /* Receiver enable */
+#define QSMCM_SCI_RWU (1<<1) /* Receiver wake-up enable */
+#define QSMCM_SCI_SBK (1<<0) /* Send break */
+
+#define QSMCM_SCI_TDRE (1<<8) /* Transmit data register empty */
+#define QSMCM_SCI_TC (1<<7) /* Transmit complete */
+#define QSMCM_SCI_RDRF (1<<6) /* Receive data register full */
+#define QSMCM_SCI_RAF (1<<5) /* Receiver active flag */
+#define QSMCM_SCI_IDLE (1<<4) /* Idle line detected */
+#define QSMCM_SCI_OR (1<<3) /* Receiver overrun error */
+#define QSMCM_SCI_NF (1<<2) /* Receiver noise error flag */
+#define QSMCM_SCI_FE (1<<1) /* Receiver framing error */
+#define QSMCM_SCI_PF (1<<0) /* Receiver parity error */
+
+/*
+ *************************************************************************
+ * Unified System Interface Unit *
+ *************************************************************************
+ */
+
+/*
+ * Memory controller registers
+ */
+typedef struct m5xxMEMCRegisters_ {
+ rtems_unsigned32 _br;
+ rtems_unsigned32 _or; /* Used to be called 'or'; reserved ANSI C++ keyword */
+} m5xxMEMCRegisters_t;
+
+/*
+ * USIU itself
+ */
+typedef struct usiu_ {
+ /*
+ * SIU Block
+ */
+ rtems_unsigned32 siumcr;
+ rtems_unsigned32 sypcr;
+ rtems_unsigned32 _pad70;
+ rtems_unsigned16 _pad0;
+ rtems_unsigned16 swsr;
+ rtems_unsigned32 sipend;
+ rtems_unsigned32 simask;
+ rtems_unsigned32 siel;
+ rtems_unsigned32 sivec;
+ rtems_unsigned32 tesr;
+ rtems_unsigned32 sgpiodt1;
+ rtems_unsigned32 sgpiodt2;
+ rtems_unsigned32 sgpiocr;
+ rtems_unsigned32 emcr;
+ rtems_unsigned8 _pad71[0x03C-0x034];
+ rtems_unsigned32 pdmcr;
+ rtems_unsigned8 _pad2[0x100-0x40];
+
+ /*
+ * MEMC Block
+ */
+ m5xxMEMCRegisters_t memc[4];
+ rtems_unsigned8 _pad7[0x140-0x120];
+ rtems_unsigned32 dmbr;
+ rtems_unsigned32 dmor;
+ rtems_unsigned8 _pad8[0x178-0x148];
+ rtems_unsigned16 mstat;
+ rtems_unsigned8 _pad9[0x200-0x17A];
+
+ /*
+ * System integration timers
+ */
+ rtems_unsigned16 tbscr;
+ rtems_unsigned16 _pad10;
+ rtems_unsigned32 tbreff0;
+ rtems_unsigned32 tbreff1;
+ rtems_unsigned8 _pad11[0x220-0x20c];
+ rtems_unsigned16 rtcsc;
+ rtems_unsigned16 _pad12;
+ rtems_unsigned32 rtc;
+ rtems_unsigned32 rtsec;
+ rtems_unsigned32 rtcal;
+ rtems_unsigned32 _pad13[4];
+ rtems_unsigned16 piscr;
+ rtems_unsigned16 _pad14;
+ rtems_unsigned16 pitc;
+ rtems_unsigned16 _pad_14_1;
+ rtems_unsigned16 pitr;
+ rtems_unsigned16 _pad_14_2;
+ rtems_unsigned8 _pad15[0x280-0x24c];
+
+ /*
+ * Clocks and Reset
+ */
+ rtems_unsigned32 sccr;
+ rtems_unsigned32 plprcr;
+ rtems_unsigned16 rsr;
+ rtems_unsigned16 _pad72;
+ rtems_unsigned16 colir;
+ rtems_unsigned16 _pad73;
+ rtems_unsigned16 vsrmcr;
+ rtems_unsigned8 _pad16[0x300-0x292];
+
+ /*
+ * System integration timers keys
+ */
+ rtems_unsigned32 tbscrk;
+ rtems_unsigned32 tbreff0k;
+ rtems_unsigned32 tbreff1k;
+ rtems_unsigned32 tbk;
+ rtems_unsigned32 _pad17[4];
+ rtems_unsigned32 rtcsk;
+ rtems_unsigned32 rtck;
+ rtems_unsigned32 rtseck;
+ rtems_unsigned32 rtcalk;
+ rtems_unsigned32 _pad18[4];
+ rtems_unsigned32 piscrk;
+ rtems_unsigned32 pitck;
+ rtems_unsigned8 _pad19[0x380-0x348];
+
+ /*
+ * Clocks and Reset Keys
+ */
+ rtems_unsigned32 sccrk;
+ rtems_unsigned32 plprck;
+ rtems_unsigned32 rsrk;
+ rtems_unsigned8 _pad20[0x400-0x38c];
+} usiu_t;
+
+extern volatile usiu_t usiu; /* defined in linkcmds */
+
+/*
+ *************************************************************************
+ * Inter-Module Bus and Devices *
+ *************************************************************************
+ */
+
+/*
+ * Dual-Port TPU RAM (DPTRAM)
+ */
+typedef struct m5xxDPTRAMRegisters_ {
+ rtems_unsigned8 pad[0x4000]; /* define later */
+} m5xxDPTRAMRegisters_t;
+
+/*
+ * Time Processor Unit (TPU)
+ */
+typedef struct m5xxTPU3Registers_ {
+ rtems_unsigned8 pad[0x400]; /* define later */
+} m5xxTPU3Registers_t;
+
+/*
+ * Queued A/D Converter (QADC)
+ */
+typedef struct m5xxQADC64Registers_ {
+ rtems_unsigned8 pad[0x400]; /* define later */
+} m5xxQADC64Registers_t;
+
+/*
+ * Serial Communications Interface (SCI)
+ */
+typedef struct m5xxSCIRegisters_ {
+ rtems_unsigned16 sccr0;
+ rtems_unsigned16 sccr1;
+ rtems_unsigned16 scsr;
+ rtems_unsigned16 scdr;
+} m5xxSCIRegisters_t;
+
+/*
+ * Serial Peripheral Interface (SPI)
+ */
+typedef struct m5xxSPIRegisters_ {
+ rtems_unsigned16 spcr0;
+ rtems_unsigned16 spcr1;
+ rtems_unsigned16 spcr2;
+ rtems_unsigned8 spcr3;
+ rtems_unsigned8 spsr;
+} m5xxSPIRegisters_t;
+
+/*
+ * Queued Serial Multi-Channel Module (QSMCM)
+ */
+typedef struct m5xxQSMCMRegisters_ {
+ rtems_unsigned16 qsmcmmcr;
+ rtems_unsigned16 qtest;
+ rtems_unsigned16 qdsci_il;
+ rtems_unsigned16 qspi_il;
+
+ m5xxSCIRegisters_t sci1;
+
+ rtems_unsigned8 _pad10[0x14-0x10];
+
+ rtems_unsigned16 portqs;
+ rtems_unsigned16 pqspar;
+ m5xxSPIRegisters_t spi;
+
+ m5xxSCIRegisters_t sci2;
+
+ rtems_unsigned16 qsci1cr;
+ rtems_unsigned16 qsci1sr;
+ rtems_unsigned16 sctq[0x10];
+ rtems_unsigned16 scrq[0x10];
+
+ rtems_unsigned8 _pad6C[0x140-0x06C];
+
+ rtems_unsigned16 recram[0x20];
+ rtems_unsigned16 tranram[0x20];
+ rtems_unsigned16 comdram[0x20];
+} m5xxQSMCMRegisters_t;
+
+/*
+ * Modular Input/Output System (MIOS)
+ */
+typedef struct m5xxMIOS1Registers_ {
+ rtems_unsigned8 pad[0x1000]; /* define later */
+} m5xxMIOS1Registers_t;
+
+/*
+ * Can 2.0B Controller (TouCAN)
+ */
+typedef struct m5xxTouCANRegisters_ {
+ rtems_unsigned8 pad[0x400]; /* define later */
+} m5xxTouCANRegisters_t;
+
+/*
+ * U-Bus to IMB3 Bus Interface Module (UIMB)
+ */
+typedef struct m5xxUIMBRegisters_ {
+ rtems_unsigned32 umcr;
+ rtems_unsigned32 utstcreg;
+ rtems_unsigned32 uipend;
+} m5xxUIMBRegisters_t;
+
+/*
+ * IMB itself
+ */
+typedef struct imb_ {
+ m5xxDPTRAMRegisters_t dptram;
+ m5xxTPU3Registers_t tpu[2];
+ m5xxQADC64Registers_t qadc[2];
+ m5xxQSMCMRegisters_t qsmcm;
+ rtems_unsigned8 _pad5200[0x6000-0x5200];
+ m5xxMIOS1Registers_t mios;
+ m5xxTouCANRegisters_t toucan[2];
+ rtems_unsigned8 _pad7800[0x7F80-0x7800];
+ m5xxUIMBRegisters_t uimb;
+} imb_t;
+
+extern volatile imb_t imb; /* defined in linkcmds */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ASM */
+
+#endif /* _MPC5xx_h */
+
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/irq/irq.c b/c/src/lib/libcpu/powerpc/mpc5xx/irq/irq.c
new file mode 100644
index 0000000000..40bf8341bc
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/irq/irq.c
@@ -0,0 +1,495 @@
+/*
+ * irq.c
+ *
+ * This file contains the implementation of the function described in irq.h
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from libbsp/powerpc/mbx8xx/irq/irq.c:
+ *
+ * Copyright (C) 1998, 1999 valette@crf.canon.fr
+ *
+ * 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$
+ */
+
+#include <rtems.h>
+#include <rtems/score/apiext.h>
+#include <mpc5xx.h>
+#include <libcpu/vectors.h>
+#include <libcpu/raw_exception.h>
+#include <libcpu/irq.h>
+
+/*
+ * Convert an rtems_irq_symbolic_name constant to an interrupt level
+ * suitable for programming into an I/O device's interrupt level field.
+ */
+
+int CPU_irq_level_from_symbolic_name(const rtems_irq_symbolic_name name)
+{
+ if (CPU_USIU_EXT_IRQ_0 <= name && name <= CPU_USIU_INT_IRQ_7)
+ return (name - CPU_USIU_EXT_IRQ_0) / 2;
+
+ if (CPU_UIMB_IRQ_8 <= name && name <= CPU_UIMB_IRQ_31)
+ return 8 + (name - CPU_UIMB_IRQ_8);
+
+ return 31; /* reasonable default */
+}
+
+/*
+ * default handler connected on each irq after bsp initialization
+ */
+static rtems_irq_connect_data default_rtems_entry;
+
+/*
+ * location used to store initial tables used for interrupt
+ * management.
+ */
+static rtems_irq_global_settings* internal_config;
+static rtems_irq_connect_data* rtems_hdl_tbl;
+
+/*
+ * Check if symbolic IRQ name is an USIU IRQ
+ */
+static inline int is_usiu_irq(const rtems_irq_symbolic_name irqLine)
+{
+ return (((int) irqLine <= CPU_USIU_IRQ_MAX_OFFSET) &&
+ ((int) irqLine >= CPU_USIU_IRQ_MIN_OFFSET)
+ );
+}
+
+/*
+ * Check if symbolic IRQ name is an UIMB IRQ
+ */
+static inline int is_uimb_irq(const rtems_irq_symbolic_name irqLine)
+{
+ return (((int) irqLine <= CPU_UIMB_IRQ_MAX_OFFSET) &&
+ ((int) irqLine >= CPU_UIMB_IRQ_MIN_OFFSET)
+ );
+}
+
+/*
+ * Check if symbolic IRQ name is a Processor IRQ
+ */
+static inline int is_proc_irq(const rtems_irq_symbolic_name irqLine)
+{
+ return (((int) irqLine <= CPU_PROC_IRQ_MAX_OFFSET) &&
+ ((int) irqLine >= CPU_PROC_IRQ_MIN_OFFSET)
+ );
+}
+
+
+/*
+ * Masks used to mask off the interrupts. For exmaple, for ILVL2, the
+ * mask is used to mask off interrupts ILVL2, IRQ3, ILVL3, ... IRQ7
+ * and ILVL7.
+ *
+ */
+const static unsigned int USIU_IvectMask[CPU_USIU_IRQ_COUNT] =
+{
+ 0, /* external IRQ 0 */
+ 0xFFFFFFFF << 31, /* internal level 0 */
+ 0xFFFFFFFF << 30, /* external IRQ 1 */
+ 0xFFFFFFFF << 29, /* internal level 1 */
+ 0xFFFFFFFF << 28, /* external IRQ 2 */
+ 0xFFFFFFFF << 27, /* internal level 2 */
+ 0xFFFFFFFF << 26, /* external IRQ 3 */
+ 0xFFFFFFFF << 25, /* internal level 3 */
+ 0xFFFFFFFF << 24, /* external IRQ 4 */
+ 0xFFFFFFFF << 23, /* internal level 4 */
+ 0xFFFFFFFF << 22, /* external IRQ 5 */
+ 0xFFFFFFFF << 21, /* internal level 5 */
+ 0xFFFFFFFF << 20, /* external IRQ 6 */
+ 0xFFFFFFFF << 19, /* internal level 6 */
+ 0xFFFFFFFF << 18, /* external IRQ 7 */
+ 0xFFFFFFFF << 17 /* internal level 7 */
+};
+
+
+/*
+ * ------------------------ RTEMS Irq helper functions ----------------
+ */
+
+/*
+ * Caution : this function assumes the variable "internal_config"
+ * is already set and that the tables it contains are still valid
+ * and accessible.
+ */
+static void compute_USIU_IvectMask_from_prio ()
+{
+ /*
+ * In theory this is feasible. No time to code it yet. See i386/shared/irq.c
+ * for an example based on 8259 controller mask. The actual masks defined
+ * correspond to the priorities defined for the USIU in irq_init.c.
+ */
+}
+
+/*
+ * This function check that the value given for the irq line
+ * is valid.
+ */
+static int isValidInterrupt(int irq)
+{
+ if ( (irq < CPU_MIN_OFFSET) || (irq > CPU_MAX_OFFSET)
+ || (irq == CPU_UIMB_INTERRUPT) )
+ return 0;
+ return 1;
+}
+
+int CPU_irq_enable_at_uimb(const rtems_irq_symbolic_name irqLine)
+{
+ if (!is_uimb_irq(irqLine))
+ return 1;
+ return 0;
+}
+
+int CPU_irq_disable_at_uimb(const rtems_irq_symbolic_name irqLine)
+{
+ if (!is_uimb_irq(irqLine))
+ return 1;
+ return 0;
+}
+
+int CPU_irq_enabled_at_uimb(const rtems_irq_symbolic_name irqLine)
+{
+ if (!is_uimb_irq(irqLine))
+ return 0;
+ return 1;
+}
+
+int CPU_irq_enable_at_usiu(const rtems_irq_symbolic_name irqLine)
+{
+ int usiu_irq_index;
+
+ if (!is_usiu_irq(irqLine))
+ return 1;
+
+ usiu_irq_index = ((int) (irqLine) - CPU_USIU_IRQ_MIN_OFFSET);
+ ppc_cached_irq_mask |= (1 << (31-usiu_irq_index));
+ usiu.simask = ppc_cached_irq_mask;
+
+ return 0;
+}
+
+int CPU_irq_disable_at_usiu(const rtems_irq_symbolic_name irqLine)
+{
+ int usiu_irq_index;
+
+ if (!is_usiu_irq(irqLine))
+ return 1;
+
+ usiu_irq_index = ((int) (irqLine) - CPU_USIU_IRQ_MIN_OFFSET);
+ ppc_cached_irq_mask &= ~(1 << (31-usiu_irq_index));
+ usiu.simask = ppc_cached_irq_mask;
+
+ return 0;
+}
+
+int CPU_irq_enabled_at_usiu(const rtems_irq_symbolic_name irqLine)
+{
+ int usiu_irq_index;
+
+ if (!is_usiu_irq(irqLine))
+ return 0;
+
+ usiu_irq_index = ((int) (irqLine) - CPU_USIU_IRQ_MIN_OFFSET);
+ return ppc_cached_irq_mask & (1 << (31-usiu_irq_index));
+}
+
+/*
+ * --------------- RTEMS Single Irq Handler Mngt Routines ----------------
+ */
+
+int CPU_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+
+ if (!isValidInterrupt(irq->name)) {
+ return 0;
+ }
+ /*
+ * Check if default handler is actually connected. If not issue an error.
+ * You must first get the current handler via CPU_get_current_idt_entry
+ * and then disconnect it using CPU_delete_idt_entry.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+ if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) {
+ return 0;
+ }
+
+ _CPU_ISR_Disable(level);
+
+ /*
+ * store the data provided by user
+ */
+ rtems_hdl_tbl[irq->name] = *irq;
+
+ if (is_uimb_irq(irq->name)) {
+ /*
+ * Enable interrupt at UIMB level
+ */
+ CPU_irq_enable_at_uimb (irq->name);
+ }
+
+ if (is_usiu_irq(irq->name)) {
+ /*
+ * Enable interrupt at USIU level
+ */
+ CPU_irq_enable_at_usiu (irq->name);
+ }
+
+ if (is_proc_irq(irq->name)) {
+ /*
+ * Should Enable exception at processor level but not needed. Will restore
+ * EE flags at the end of the routine anyway.
+ */
+ }
+ /*
+ * Enable interrupt on device
+ */
+ irq->on(irq);
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+
+int CPU_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
+{
+ if (!isValidInterrupt(irq->name)) {
+ return 0;
+ }
+ *irq = rtems_hdl_tbl[irq->name];
+ return 1;
+}
+
+int CPU_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
+{
+ unsigned int level;
+
+ if (!isValidInterrupt(irq->name)) {
+ return 0;
+ }
+ /*
+ * Check if default handler is actually connected. If not issue an error.
+ * You must first get the current handler via CPU_get_current_idt_entry
+ * and then disconnect it using CPU_delete_idt_entry.
+ * RATIONALE : to always have the same transition by forcing the user
+ * to get the previous handler before accepting to disconnect.
+ */
+ if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
+ return 0;
+ }
+ _CPU_ISR_Disable(level);
+
+ /*
+ * Disable interrupt on device
+ */
+ irq->off(irq);
+
+ if (is_uimb_irq(irq->name)) {
+ /*
+ * disable interrupt at UIMB level
+ */
+ CPU_irq_disable_at_uimb (irq->name);
+ }
+ if (is_usiu_irq(irq->name)) {
+ /*
+ * disable interrupt at USIU level
+ */
+ CPU_irq_disable_at_usiu (irq->name);
+ }
+ if (is_proc_irq(irq->name)) {
+ /*
+ * disable exception at processor level
+ */
+ }
+
+ /*
+ * restore the default irq value
+ */
+ rtems_hdl_tbl[irq->name] = default_rtems_entry;
+
+ _CPU_ISR_Enable(level);
+
+ return 1;
+}
+
+/*
+ * ---------------- RTEMS Global Irq Handler Mngt Routines ----------------
+ */
+
+int CPU_rtems_irq_mngt_set (rtems_irq_global_settings* config)
+{
+ int i;
+ unsigned int level;
+
+ /*
+ * Store various code accelerators
+ */
+ internal_config = config;
+ default_rtems_entry = config->defaultEntry;
+ rtems_hdl_tbl = config->irqHdlTbl;
+
+ _CPU_ISR_Disable(level);
+
+ /*
+ * Start with UIMB IRQ
+ */
+ for (i = CPU_UIMB_IRQ_MIN_OFFSET; i <= CPU_UIMB_IRQ_MAX_OFFSET ; i++) {
+ if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
+ CPU_irq_enable_at_uimb (i);
+ rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
+ }
+ else {
+ rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
+ CPU_irq_disable_at_uimb (i);
+ }
+ }
+
+ /*
+ * Continue with USIU IRQ
+ * Set up internal tables used by rtems interrupt prologue
+ */
+ compute_USIU_IvectMask_from_prio ();
+
+ for (i = CPU_USIU_IRQ_MIN_OFFSET; i <= CPU_USIU_IRQ_MAX_OFFSET ; i++) {
+ if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
+ CPU_irq_enable_at_usiu (i);
+ rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
+ }
+ else {
+ rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
+ CPU_irq_disable_at_usiu (i);
+ }
+ }
+
+ /*
+ * Enable all UIMB interrupt lines, then enable at USIU.
+ */
+ imb.uimb.umcr |= UIMB_UMCR_IRQMUX(3);
+ CPU_irq_enable_at_usiu (CPU_UIMB_INTERRUPT);
+
+ /*
+ * finish with Processor exceptions handled like IRQ
+ */
+ for (i = CPU_PROC_IRQ_MIN_OFFSET; i <= CPU_PROC_IRQ_MAX_OFFSET; i++) {
+ if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
+ rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
+ }
+ else {
+ rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
+ }
+ }
+ _CPU_ISR_Enable(level);
+ return 1;
+}
+
+int CPU_rtems_irq_mngt_get(rtems_irq_global_settings** config)
+{
+ *config = internal_config;
+ return 0;
+}
+
+
+/*
+ * High level IRQ handler called from shared_raw_irq_code_entry
+ */
+void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
+{
+ register unsigned int irq;
+ register unsigned uimbIntr; /* boolean */
+ register unsigned oldMask; /* old siu pic masks */
+ register unsigned msr;
+ register unsigned new_msr;
+
+ /*
+ * Handle decrementer interrupt
+ */
+ if (excNum == ASM_DEC_VECTOR) {
+ _CPU_MSR_GET(msr);
+ new_msr = msr | MSR_EE;
+ _CPU_MSR_SET(new_msr);
+
+ rtems_hdl_tbl[CPU_DECREMENTER].hdl();
+
+ _CPU_MSR_SET(msr);
+ return;
+ }
+
+ /*
+ * Handle external interrupt generated by USIU on PPC core
+ */
+ while ((ppc_cached_irq_mask & usiu.sipend) != 0) {
+ irq = (usiu.sivec >> 26);
+ uimbIntr = (irq == CPU_UIMB_INTERRUPT);
+ /*
+ * Disable the interrupt of the same and lower priority.
+ */
+ oldMask = ppc_cached_irq_mask;
+ ppc_cached_irq_mask = oldMask & USIU_IvectMask[irq];
+ usiu.simask = ppc_cached_irq_mask;
+ /*
+ * Acknowledge current interrupt. This has no effect on internal level
+ * interrupts.
+ */
+ usiu.sipend = (1 << (31 - irq));
+
+ if (uimbIntr) {
+ /*
+ * Look at the bits set in the UIMB interrupt-pending register. The
+ * highest-order set bit indicates the handler we will run.
+ *
+ * Unfortunately, we can't easily mask individual UIMB interrupts
+ * unless they use USIU levels 0 to 6, so we must mask all low-level
+ * (level > 7) UIMB interrupts while we service any interrupt.
+ */
+ int uipend = imb.uimb.uipend << 8;
+
+ if (uipend == 0) { /* spurious interrupt? use last vector */
+ irq = CPU_UIMB_IRQ_MAX_OFFSET;
+ }
+ else {
+ irq = CPU_UIMB_IRQ_MIN_OFFSET;
+ for ( ; (uipend & 0x8000000) == 0; uipend <<= 1) {
+ irq++;
+ }
+ }
+ }
+ _CPU_MSR_GET(msr);
+ new_msr = msr | MSR_EE;
+ _CPU_MSR_SET(new_msr);
+
+ rtems_hdl_tbl[irq].hdl();
+
+ _CPU_MSR_SET(msr);
+
+ ppc_cached_irq_mask = oldMask;
+ usiu.simask = ppc_cached_irq_mask;
+ }
+}
+
+void _ThreadProcessSignalsFromIrq (CPU_Exception_frame* ctx)
+{
+ /*
+ * Process pending signals that have not already been
+ * processed by _Thread_Displatch. This happens quite
+ * unfrequently : the ISR must have posted an action
+ * to the current running thread.
+ */
+ if ( _Thread_Do_post_task_switch_extension ||
+ _Thread_Executing->do_post_task_switch_extension ) {
+ _Thread_Executing->do_post_task_switch_extension = FALSE;
+ _API_extensions_Run_postswitch();
+ }
+ /*
+ * I plan to process other thread related events here.
+ * This will include DEBUG session requested from keyboard...
+ */
+}
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/irq/irq.h b/c/src/lib/libcpu/powerpc/mpc5xx/irq/irq.h
new file mode 100644
index 0000000000..dd4f9948e1
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/irq/irq.h
@@ -0,0 +1,358 @@
+/*
+ * irq.h
+ *
+ * This include file describe the data structure and the functions implemented
+ * by rtems to write interrupt handlers.
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from libbsp/powerpc/mbx8xx/irq/irq.h:
+ *
+ * CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ * This code is heavilly inspired by the public specification of STREAM V2
+ * that can be found at :
+ *
+ * <http://www.chorus.com/Documentation/index.html> by following
+ * the STREAM API Specification Document link.
+ *
+ * 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$
+ */
+
+#ifndef LIBCPU_POWERPC_MBX8XX_IRQ_IRQ_H
+#define LIBCPU_POWERPC_MBX8XX_IRQ_IRQ_H
+
+
+#define CPU_ASM_IRQ_VECTOR_BASE 0x0
+
+#ifndef ASM
+
+extern volatile unsigned int ppc_cached_irq_mask;
+
+/*
+ * Symblolic IRQ names and related definitions.
+ */
+
+typedef enum {
+ /*
+ * Base vector for our USIU IRQ handlers.
+ */
+ CPU_USIU_VECTOR_BASE = CPU_ASM_IRQ_VECTOR_BASE,
+ /*
+ * USIU IRQ handler related definitions
+ */
+ CPU_USIU_IRQ_COUNT = 16, /* 16 reserved but in the future... */
+ CPU_USIU_IRQ_MIN_OFFSET = 0,
+ CPU_USIU_IRQ_MAX_OFFSET = CPU_USIU_IRQ_MIN_OFFSET + CPU_USIU_IRQ_COUNT - 1,
+ /*
+ * UIMB IRQ handlers related definitions
+ */
+ CPU_UIMB_IRQ_COUNT = 32 - 8, /* first 8 overlap USIU */
+ CPU_UIMB_IRQ_MIN_OFFSET = CPU_USIU_IRQ_COUNT + CPU_USIU_VECTOR_BASE,
+ CPU_UIMB_IRQ_MAX_OFFSET = CPU_UIMB_IRQ_MIN_OFFSET + CPU_UIMB_IRQ_COUNT - 1,
+ /*
+ * PowerPc exceptions handled as interrupt where a rtems managed interrupt
+ * handler might be connected
+ */
+ CPU_PROC_IRQ_COUNT = 1,
+ CPU_PROC_IRQ_MIN_OFFSET = CPU_UIMB_IRQ_MAX_OFFSET + 1,
+ CPU_PROC_IRQ_MAX_OFFSET = CPU_PROC_IRQ_MIN_OFFSET + CPU_PROC_IRQ_COUNT - 1,
+ /*
+ * Summary
+ */
+ CPU_IRQ_COUNT = CPU_PROC_IRQ_MAX_OFFSET + 1,
+ CPU_MIN_OFFSET = CPU_USIU_IRQ_MIN_OFFSET,
+ CPU_MAX_OFFSET = CPU_PROC_IRQ_MAX_OFFSET,
+ /*
+ * USIU IRQ symbolic name definitions.
+ */
+ CPU_USIU_EXT_IRQ_0 = CPU_USIU_IRQ_MIN_OFFSET,
+ CPU_USIU_INT_IRQ_0,
+
+ CPU_USIU_EXT_IRQ_1,
+ CPU_USIU_INT_IRQ_1,
+
+ CPU_USIU_EXT_IRQ_2,
+ CPU_USIU_INT_IRQ_2,
+
+ CPU_USIU_EXT_IRQ_3,
+ CPU_USIU_INT_IRQ_3,
+
+ CPU_USIU_EXT_IRQ_4,
+ CPU_USIU_INT_IRQ_4,
+
+ CPU_USIU_EXT_IRQ_5,
+ CPU_USIU_INT_IRQ_5,
+
+ CPU_USIU_EXT_IRQ_6,
+ CPU_USIU_INT_IRQ_6,
+
+ CPU_USIU_EXT_IRQ_7,
+ CPU_USIU_INT_IRQ_7,
+
+ /*
+ * Symbolic names for UISU interrupt sources.
+ */
+ CPU_PERIODIC_TIMER = CPU_USIU_INT_IRQ_6,
+ CPU_UIMB_INTERRUPT = CPU_USIU_INT_IRQ_7,
+
+ /*
+ * UIMB IRQ symbolic name definitions. The first 8 sources are aliases to
+ * the USIU interrupts of the same number, because they are detected in
+ * the USIU pending register rather than the UIMB pending register.
+ */
+ CPU_UIMB_IRQ_0 = CPU_USIU_INT_IRQ_0,
+ CPU_UIMB_IRQ_1 = CPU_USIU_INT_IRQ_1,
+ CPU_UIMB_IRQ_2 = CPU_USIU_INT_IRQ_2,
+ CPU_UIMB_IRQ_3 = CPU_USIU_INT_IRQ_3,
+ CPU_UIMB_IRQ_4 = CPU_USIU_INT_IRQ_4,
+ CPU_UIMB_IRQ_5 = CPU_USIU_INT_IRQ_5,
+ CPU_UIMB_IRQ_6 = CPU_USIU_INT_IRQ_6,
+ CPU_UIMB_IRQ_7 = CPU_USIU_INT_IRQ_7,
+
+ CPU_UIMB_IRQ_8 = CPU_UIMB_IRQ_MIN_OFFSET,
+ CPU_UIMB_IRQ_9,
+ CPU_UIMB_IRQ_10,
+ CPU_UIMB_IRQ_11,
+ CPU_UIMB_IRQ_12,
+ CPU_UIMB_IRQ_13,
+ CPU_UIMB_IRQ_14,
+ CPU_UIMB_IRQ_15,
+ CPU_UIMB_IRQ_16,
+ CPU_UIMB_IRQ_17,
+ CPU_UIMB_IRQ_18,
+ CPU_UIMB_IRQ_19,
+ CPU_UIMB_IRQ_20,
+ CPU_UIMB_IRQ_21,
+ CPU_UIMB_IRQ_22,
+ CPU_UIMB_IRQ_23,
+ CPU_UIMB_IRQ_24,
+ CPU_UIMB_IRQ_25,
+ CPU_UIMB_IRQ_26,
+ CPU_UIMB_IRQ_27,
+ CPU_UIMB_IRQ_28,
+ CPU_UIMB_IRQ_29,
+ CPU_UIMB_IRQ_30,
+ CPU_UIMB_IRQ_31,
+
+ /*
+ * Symbolic names for UIMB interrupt sources.
+ */
+ CPU_IRQ_SCI = CPU_UIMB_IRQ_5,
+
+ /*
+ * Processor exceptions handled as rtems IRQ symbolic name definitions.
+ */
+ CPU_DECREMENTER = CPU_PROC_IRQ_MIN_OFFSET
+
+}rtems_irq_symbolic_name;
+
+/*
+ * Convert an rtems_irq_symbolic_name constant to an interrupt level
+ * suitable for programming into an I/O device's interrupt level field.
+ */
+int CPU_irq_level_from_symbolic_name(const rtems_irq_symbolic_name name);
+
+/*
+ * Type definition for RTEMS managed interrupts
+ */
+typedef unsigned char rtems_irq_prio;
+struct __rtems_irq_connect_data__; /* forward declaratiuon */
+
+typedef void (*rtems_irq_hdl) (void);
+typedef void (*rtems_irq_enable) (const struct __rtems_irq_connect_data__*);
+typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*);
+typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*);
+
+typedef struct __rtems_irq_connect_data__ {
+ /*
+ * IRQ line
+ */
+ rtems_irq_symbolic_name name;
+ /*
+ * Handler. See comment on handler properties below in function prototype.
+ */
+ rtems_irq_hdl hdl;
+ /*
+ * Function for enabling interrupts at device level (ONLY!).
+ * The CPU code will automatically enable it at USIU level and UIMB level.
+ * RATIONALE : anyway such code has to exist in current driver code.
+ * It is usually called immediately AFTER connecting the interrupt handler.
+ * RTEMS may well need such a function when restoring normal interrupt
+ * processing after a debug session.
+ *
+ */
+ rtems_irq_enable on;
+ /*
+ * Function for disabling interrupts at device level (ONLY!).
+ * The code will disable it at USIU and UIMB level. RATIONALE : anyway
+ * such code has to exist for clean shutdown. It is usually called
+ * BEFORE disconnecting the interrupt. RTEMS may well need such
+ * a function when disabling normal interrupt processing for
+ * a debug session. May well be a NOP function.
+ */
+ rtems_irq_disable off;
+ /*
+ * Function enabling to know what interrupt may currently occur
+ * if someone manipulates the USIU and UIMB interrupt mask without care...
+ */
+ rtems_irq_is_enabled isOn;
+}rtems_irq_connect_data;
+
+typedef struct {
+ /*
+ * size of all the table fields (*Tbl) described below.
+ */
+ unsigned int irqNb;
+ /*
+ * Default handler used when disconnecting interrupts.
+ */
+ rtems_irq_connect_data defaultEntry;
+ /*
+ * Table containing initials/current value.
+ */
+ rtems_irq_connect_data* irqHdlTbl;
+ /*
+ * actual value of CPU_USIU_IRQ_VECTOR_BASE...
+ */
+ rtems_irq_symbolic_name irqBase;
+ /*
+ * software priorities associated with interrupts.
+ * if irqPrio [i] > intrPrio [j] it means that
+ * interrupt handler hdl connected for interrupt name i
+ * will not be interrupted by the handler connected for interrupt j
+ * The interrupt source will be physically masked at USIU and UIMB level.
+ */
+ rtems_irq_prio* irqPrioTbl;
+}rtems_irq_global_settings;
+
+
+/*-------------------------------------------------------------------------+
+| Function Prototypes.
++--------------------------------------------------------------------------*/
+
+#if 0
+/*
+ * -------------------- MPC5xx USIU Management Routines -----------------
+ */
+/*
+ * Function to disable a particular irq at USIU level. After calling
+ * this function, even if the device asserts the interrupt line it will
+ * not be propagated further to the processor
+ */
+int CPU_irq_disable_at_usiu (const rtems_irq_symbolic_name irqLine);
+/*
+ * Function to enable a particular irq at USIU level. After calling
+ * this function, if the device asserts the interrupt line it will
+ * be propagated further to the processor
+ */
+int CPU_irq_enable_at_usiu (const rtems_irq_symbolic_name irqLine);
+/*
+ * Function to acknowledge a particular irq at USIU level. After calling
+ * this function, if a device asserts an enabled interrupt line it will
+ * be propagated further to the processor. Mainly useful for people
+ * writing raw handlers as this is automagically done for rtems managed
+ * handlers.
+ */
+int CPU_irq_ack_at_siu (const rtems_irq_symbolic_name irqLine);
+/*
+ * function to check if a particular irq is enabled at USIU level.
+ */
+int CPU_irq_enabled_at_siu (const rtems_irq_symbolic_name irqLine);
+
+#endif
+
+/*
+ * ------------ RTEMS Single Irq Handler Management Routines ----------------
+ */
+/*
+ * Function to connect a particular irq handler. This handler will NOT be
+ * called directly as the result of the corresponding interrupt. Instead, a
+ * RTEMS irq prologue will be called that will :
+ *
+ * 1) save the C scratch registers,
+ * 2) switch to a interrupt stack if the interrupt is not nested,
+ * 4) modify them to disable the current interrupt at USIU level (and
+ * maybe others depending on software priorities)
+ * 5) aknowledge the USIU',
+ * 6) demask the processor,
+ * 7) call the application handler
+ *
+ * As a result the hdl function provided
+ *
+ * a) can perfectly be written is C,
+ * b) may also well directly call the part of the RTEMS API that can be
+ * used from interrupt level,
+ * c) It only responsible for handling the jobs that need to be done at
+ * the device level including (aknowledging/re-enabling the
+ * interrupt at device, level, getting the data,...)
+ *
+ * When returning from the function, the following will be performed by
+ * the RTEMS irq epilogue :
+ *
+ * 1) masks the interrupts again,
+ * 2) restore the original USIU interrupt masks
+ * 3) switch back on the orinal stack if needed,
+ * 4) perform rescheduling when necessary,
+ * 5) restore the C scratch registers...
+ * 6) restore initial execution flow
+ *
+ */
+int CPU_install_rtems_irq_handler (const rtems_irq_connect_data*);
+/*
+ * Function to connect an RTEMS irq handler for ptr->name.
+ */
+int CPU_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr);
+/*
+ * Function to get the RTEMS irq handler for ptr->name.
+ */
+int CPU_remove_rtems_irq_handler (const rtems_irq_connect_data*);
+/*
+ * Function to disconnect the RTEMS irq handler for ptr->name. This
+ * function checks that the value given is the current one for safety
+ * reason. The user can use the previous function to get it.
+ */
+
+/*
+ * ------------ RTEMS Global Irq Handler Management Routines ----------------
+ */
+/*
+ * (Re) Initialize the RTEMS interrupt management.
+ *
+ * The result of calling this function will be the same as if each
+ * individual handler (config->irqHdlTbl[i].hdl) different from
+ * "config->defaultEntry.hdl" has been individualy connected via
+ *
+ * CPU_install_rtems_irq_handler(&config->irqHdlTbl[i])
+ *
+ * and each handler currently equal to config->defaultEntry.hdl
+ * has been previously disconnected via
+ *
+ * CPU_remove_rtems_irq_handler (&config->irqHdlTbl[i])
+ *
+ * This is to say that all information given will be used and not just
+ * only the space.
+ *
+ * CAUTION : the various table address contained in config will be used
+ * directly by the interrupt mangement code in order to save
+ * data size so they must stay valid after the call => they should
+ * not be modified or declared on a stack.
+ */
+
+int CPU_rtems_irq_mngt_set(rtems_irq_global_settings* config);
+/*
+ * (Re) get info on current RTEMS interrupt management.
+ */
+int CPU_rtems_irq_mngt_get(rtems_irq_global_settings**);
+
+extern void CPU_rtems_irq_mng_init(unsigned cpuId);
+
+#endif
+
+#endif
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/irq/irq_asm.S b/c/src/lib/libcpu/powerpc/mpc5xx/irq/irq_asm.S
new file mode 100644
index 0000000000..2908509bfc
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/irq/irq_asm.S
@@ -0,0 +1,325 @@
+/*
+ * irq_asm.S
+ *
+ * This file contains the assembly code for the PowerPC
+ * IRQ veneers for RTEMS.
+ *
+ * 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.
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from libbsp/powerpc/mbx8xx/irq/irq_asm.S:
+ *
+ * Modified to support the MCP750.
+ * Modifications Copyright (C) 1999 Eric Valette. valette@crf.canon.fr
+ *
+ * Till Straumann <strauman@slac.stanford.edu>, 2003/7:
+ * - store isr nesting level in _ISR_Nest_level rather than
+ * SPRG0 - RTEMS relies on that variable.
+ *
+ * $Id$
+ */
+
+#include <asm.h>
+#include <rtems/score/cpu.h>
+#include <libcpu/vectors.h>
+#include <libcpu/raw_exception.h>
+
+
+#define SYNC \
+ sync; \
+ isync
+
+/*
+ * Common handler for interrupt exceptions.
+ *
+ * The function CPU_rtems_irq_mng_init() initializes the decrementer and
+ * external interrupt entries in the exception handler table with pointers
+ * to this routine, which saves the remainder of the interrupted code's
+ * state, then calls C_dispatch_irq_handler().
+ *
+ * On entry, R1 points to a new exception stack frame in which R3, R4, and
+ * LR have been saved. R4 holds the exception number.
+ */
+ PUBLIC_VAR(C_dispatch_irq_handler)
+
+ PUBLIC_VAR(dispatch_irq_handler)
+SYM (dispatch_irq_handler):
+ /*
+ * Save SRR0/SRR1 As soon As possible as it is the minimal needed
+ * to re-enable exception processing.
+ *
+ * Note that R2 should never change (it's the EABI pointer to
+ * .sdata2), but we save it just in case.
+ */
+ stw r0, GPR0_OFFSET(r1)
+ stw r2, GPR2_OFFSET(r1)
+
+ mfsrr0 r0
+ mfsrr1 r3
+
+ stw r0, SRR0_FRAME_OFFSET(r1)
+ stw r3, SRR1_FRAME_OFFSET(r1)
+
+ /*
+ * Enable exception recovery. Also enable FP so that FP context
+ * can be saved and restored (using FP instructions).
+ */
+ mfmsr r3
+ ori r3, r3, MSR_RI | MSR_FP
+ mtmsr r3
+ SYNC
+
+ /*
+ * Push C scratch registers on the current stack. It may actually be
+ * the thread stack or the interrupt stack. Anyway we have to make
+ * it in order to be able to call C/C++ functions. Depending on the
+ * nesting interrupt level, we will switch to the right stack later.
+ */
+ stw r5, GPR5_OFFSET(r1)
+ stw r6, GPR6_OFFSET(r1)
+ stw r7, GPR7_OFFSET(r1)
+ stw r8, GPR8_OFFSET(r1)
+ stw r9, GPR9_OFFSET(r1)
+ stw r10, GPR10_OFFSET(r1)
+ stw r11, GPR11_OFFSET(r1)
+ stw r12, GPR12_OFFSET(r1)
+ stw r13, GPR13_OFFSET(r1)
+
+ mfcr r5
+ mfctr r6
+ mfxer r7
+
+ stw r5, EXC_CR_OFFSET(r1)
+ stw r6, EXC_CTR_OFFSET(r1)
+ stw r7, EXC_XER_OFFSET(r1)
+
+ /*
+ * Add some non volatile registers to store information that will be
+ * used when returning from C handler.
+ */
+ stw r14, GPR14_OFFSET(r1)
+ stw r15, GPR15_OFFSET(r1)
+
+ /*
+ * Save current stack pointer location in R14.
+ */
+ addi r14, r1, 0
+
+ /*
+ * store part of _Thread_Dispatch_disable_level address in R15
+ */
+ addis r15, 0, _Thread_Dispatch_disable_level@ha
+
+ /*
+ * Retrieve current nesting level from _ISR_Nest_level
+ */
+ lis r7, _ISR_Nest_level@ha
+ lwz r3, _ISR_Nest_level@l(r7)
+
+ /*
+ * Check if stack switch is necessary
+ */
+ cmpwi r3, 0
+ bne nested
+
+ mfspr r1, SPRG1 /* switch to interrupt stack */
+nested:
+
+ /*
+ * Start Incrementing nesting level in R3
+ */
+ addi r3, r3, 1
+
+ /*
+ * Start Incrementing _Thread_Dispatch_disable_level R4 = _Thread_Dispatch_disable_level
+ */
+ lwz r6, _Thread_Dispatch_disable_level@l(r15)
+
+ /* store new nesting level in _ISR_Nest_level */
+ stw r3, _ISR_Nest_level@l(r7)
+
+ addi r6, r6, 1
+
+ /*
+ * store new _Thread_Dispatch_disable_level value
+ */
+ stw r6, _Thread_Dispatch_disable_level@l(r15)
+
+ /*
+ * We are now running on the interrupt stack. External and decrementer
+ * exceptions are still disabled. I see no purpose trying to optimize
+ * further assembler code.
+ */
+
+ /*
+ * Call C exception handler for decrementer or external interrupt.
+ * Pass frame along just in case..
+ *
+ * C_dispatch_irq_handler(cpu_interrupt_frame* r3, vector r4)
+ */
+ addi r3, r14, 0x8
+ bl C_dispatch_irq_handler
+
+ /*
+ * start decrementing nesting level. Note : do not test result against 0
+ * value as an easy exit condition because if interrupt nesting level > 1
+ * then _Thread_Dispatch_disable_level > 1
+ */
+ lis r7, _ISR_Nest_level@ha
+ lwz r4, _ISR_Nest_level@l(r7)
+
+ /*
+ * start decrementing _Thread_Dispatch_disable_level
+ */
+ lwz r3,_Thread_Dispatch_disable_level@l(r15)
+
+ addi r4, r4, -1 /* Continue decrementing nesting level */
+ addi r3, r3, -1 /* Continue decrementing _Thread_Dispatch_disable_level */
+
+ stw r4, _ISR_Nest_level@l(r7) /* End decrementing nesting level */
+ stw r3,_Thread_Dispatch_disable_level@l(r15) /* End decrementing _Thread_Dispatch_disable_level */
+
+ cmpwi r3, 0
+
+ /*
+ * switch back to original stack (done here just optimize registers
+ * contention. Could have been done before...)
+ */
+ addi r1, r14, 0
+ bne easy_exit /* if (_Thread_Dispatch_disable_level != 0) goto easy_exit */
+
+ /*
+ * Here we are running again on the thread system stack.
+ * We have interrupt nesting level = _Thread_Dispatch_disable_level = 0.
+ * Interrupt are still disabled. Time to check if scheduler request to
+ * do something with the current thread...
+ */
+ addis r4, 0, _Context_Switch_necessary@ha
+ lwz r5, _Context_Switch_necessary@l(r4)
+ cmpwi r5, 0
+ bne switch
+
+ addis r6, 0, _ISR_Signals_to_thread_executing@ha
+ lwz r7, _ISR_Signals_to_thread_executing@l(r6)
+ cmpwi r7, 0
+ li r8, 0
+ beq easy_exit
+
+ stw r8, _ISR_Signals_to_thread_executing@l(r6)
+
+ /*
+ * going to call _ThreadProcessSignalsFromIrq
+ * Push a complete exception like frame...
+ */
+ stmw r16, GPR16_OFFSET(r1)
+ addi r3, r1, 0x8
+
+ /*
+ * compute SP at exception entry
+ */
+ addi r4, r1, EXCEPTION_FRAME_END
+
+ /*
+ * store it at the right place
+ */
+ stw r4, GPR1_OFFSET(r1)
+
+ /*
+ * Call High Level signal handling code
+ */
+ bl _ThreadProcessSignalsFromIrq
+
+ /*
+ * start restoring exception like frame
+ */
+ lwz r31, EXC_CTR_OFFSET(r1)
+ lwz r30, EXC_XER_OFFSET(r1)
+ lwz r29, EXC_CR_OFFSET(r1)
+ lwz r28, EXC_LR_OFFSET(r1)
+
+ mtctr r31
+ mtxer r30
+ mtcr r29
+ mtlr r28
+
+ lmw r4, GPR4_OFFSET(r1)
+ lwz r2, GPR2_OFFSET(r1)
+ lwz r0, GPR0_OFFSET(r1)
+
+ /*
+ * Make path non recoverable...
+ */
+ mtspr nri, r0
+ SYNC
+
+ /*
+ * Restore rfi related settings
+ */
+
+ lwz r3, SRR1_FRAME_OFFSET(r1)
+ mtsrr1 r3
+ lwz r3, SRR0_FRAME_OFFSET(r1)
+ mtsrr0 r3
+
+ lwz r3, GPR3_OFFSET(r1)
+ addi r1,r1, EXCEPTION_FRAME_END
+ SYNC
+ rfi
+
+
+switch:
+ bl SYM (_Thread_Dispatch)
+
+easy_exit:
+ /*
+ * start restoring interrupt frame
+ */
+ lwz r3, EXC_CTR_OFFSET(r1)
+ lwz r4, EXC_XER_OFFSET(r1)
+ lwz r5, EXC_CR_OFFSET(r1)
+ lwz r6, EXC_LR_OFFSET(r1)
+
+ mtctr r3
+ mtxer r4
+ mtcr r5
+ mtlr r6
+
+ lwz r15, GPR15_OFFSET(r1)
+ lwz r14, GPR14_OFFSET(r1)
+ lwz r13, GPR13_OFFSET(r1)
+ lwz r12, GPR12_OFFSET(r1)
+ lwz r11, GPR11_OFFSET(r1)
+ lwz r10, GPR10_OFFSET(r1)
+ lwz r9, GPR9_OFFSET(r1)
+ lwz r8, GPR8_OFFSET(r1)
+ lwz r7, GPR7_OFFSET(r1)
+ lwz r6, GPR6_OFFSET(r1)
+ lwz r5, GPR5_OFFSET(r1)
+
+ /*
+ * Disable nested exception processing.
+ */
+ mtspr nri, r0
+ SYNC
+
+ /*
+ * Restore rfi related settings
+ */
+ lwz r4, SRR1_FRAME_OFFSET(r1)
+ lwz r3, SRR0_FRAME_OFFSET(r1)
+ lwz r2, GPR2_OFFSET(r1)
+ lwz r0, GPR0_OFFSET(r1)
+
+ mtsrr1 r4
+ mtsrr0 r3
+ lwz r4, GPR4_OFFSET(r1)
+ lwz r3, GPR3_OFFSET(r1)
+ addi r1,r1, EXCEPTION_FRAME_END
+ SYNC
+ rfi
+
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/irq/irq_init.c b/c/src/lib/libcpu/powerpc/mpc5xx/irq/irq_init.c
new file mode 100644
index 0000000000..bc2a3043f1
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/irq/irq_init.c
@@ -0,0 +1,152 @@
+/*
+ * irq_init.c
+ *
+ * This file contains the implementation of rtems initialization
+ * related to interrupt handling.
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from libbsp/powerpc/mbx8xx/irq/irq_init.c:
+ *
+ * CopyRight (C) 2001 valette@crf.canon.fr
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <mpc5xx.h>
+#include <libcpu/vectors.h>
+#include <libcpu/raw_exception.h>
+#include <libcpu/irq.h>
+
+
+extern rtems_exception_handler_t dispatch_irq_handler;
+
+volatile unsigned int ppc_cached_irq_mask;
+
+/*
+ * default on/off function
+ */
+static void nop_func(){}
+
+/*
+ * default isOn function
+ */
+static int not_connected() {return 0;}
+
+/*
+ * default possible isOn function
+ */
+static int connected() {return 1;}
+
+static rtems_irq_connect_data rtemsIrq[CPU_IRQ_COUNT];
+static rtems_irq_global_settings initial_config;
+static rtems_irq_connect_data defaultIrq = {
+ /* vector, hdl , on , off , isOn */
+ 0, nop_func , nop_func , nop_func , not_connected
+};
+
+static rtems_irq_prio irqPrioTable[CPU_IRQ_COUNT]={
+ /*
+ * actual priorities for interrupt :
+ * 0 means that only current interrupt is masked
+ * 255 means all other interrupts are masked
+ */
+ /*
+ * USIU interrupts.
+ */
+ 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1, 0,0,
+ /*
+ * UIMB Interrupts
+ *
+ * Note that the first 8 UIMB interrupts overlap the 8 external USIU
+ * interrupts.
+ */
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /*
+ * Processor exceptions handled as interrupts
+ */
+ 0
+};
+
+void CPU_USIU_irq_init()
+{
+ /*
+ * In theory we should initialize two registers at least : SIMASK and
+ * SIEL. SIMASK is reset at 0 value meaning no interrupts. If someone
+ * find a reasonnable value for SIEL, and the need to change it, please
+ * feel free to add it here.
+ */
+ ppc_cached_irq_mask = 0;
+ usiu.simask = ppc_cached_irq_mask;
+ usiu.sipend = 0xffff0000;
+ usiu.siel = usiu.siel;
+}
+
+/*
+ * Initialize UIMB interrupt management
+ */
+void
+CPU_UIMB_irq_init(void)
+{
+}
+
+void CPU_rtems_irq_mng_init(unsigned cpuId)
+{
+ rtems_raw_except_connect_data vectorDesc;
+ int i;
+
+ CPU_USIU_irq_init();
+ CPU_UIMB_irq_init();
+ /*
+ * Initialize Rtems management interrupt table
+ */
+ /*
+ * re-init the rtemsIrq table
+ */
+ for (i = 0; i < CPU_IRQ_COUNT; i++) {
+ rtemsIrq[i] = defaultIrq;
+ rtemsIrq[i].name = i;
+ }
+ /*
+ * Init initial Interrupt management config
+ */
+ initial_config.irqNb = CPU_IRQ_COUNT;
+ initial_config.defaultEntry = defaultIrq;
+ initial_config.irqHdlTbl = rtemsIrq;
+ initial_config.irqBase = CPU_ASM_IRQ_VECTOR_BASE;
+ initial_config.irqPrioTbl = irqPrioTable;
+
+ if (!CPU_rtems_irq_mngt_set(&initial_config)) {
+ /*
+ * put something here that will show the failure...
+ */
+ BSP_panic("Unable to initialize RTEMS interrupt Management\n");
+ }
+
+ /*
+ * We must connect the raw irq handler for the two
+ * expected interrupt sources : decrementer and external interrupts.
+ */
+ vectorDesc.exceptIndex = ASM_DEC_VECTOR;
+ vectorDesc.hdl.vector = ASM_DEC_VECTOR;
+ vectorDesc.hdl.raw_hdl = dispatch_irq_handler;
+ vectorDesc.on = nop_func;
+ vectorDesc.off = nop_func;
+ vectorDesc.isOn = connected;
+ if (!mpc5xx_set_exception (&vectorDesc)) {
+ BSP_panic("Unable to initialize RTEMS decrementer raw exception\n");
+ }
+ vectorDesc.exceptIndex = ASM_EXT_VECTOR;
+ vectorDesc.hdl.vector = ASM_EXT_VECTOR;
+ if (!mpc5xx_set_exception (&vectorDesc)) {
+ BSP_panic("Unable to initialize RTEMS external raw exception\n");
+ }
+}
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/timer/timer.c b/c/src/lib/libcpu/powerpc/mpc5xx/timer/timer.c
index 3139e62d6d..5a1ce5e2a6 100644
--- a/c/src/lib/libcpu/powerpc/mpc5xx/timer/timer.c
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/timer/timer.c
@@ -1,70 +1,118 @@
/* timer.c
*
- * This file manages the benchmark timer used by the RTEMS Timing Test
- * Suite. Each measured time period is demarcated by calls to
- * Timer_initialize() and Read_timer(). Read_timer() usually returns
- * the number of microseconds since Timer_initialize() exitted.
+ * This file manages the interval timer on the PowerPC MPC5xx.
+ * NOTE: This is not the PIT, but rather the RTEMS interval
+ * timer
+ * We shall use the bottom 32 bits of the timebase register,
*
+ * The following was in the 403 version of this file. I don't
+ * know what it means. JTM 5/19/98
* NOTE: It is important that the timer start/stop overhead be
* determined when porting or modifying this code.
*
- * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from c/src/lib/libcpu/powerpc/mpc8xx/timer/timer.c:
+ *
+ * Author: Jay Monkman (jmonkman@frasca.com)
+ * Copywright (C) 1998 by Frasca International, Inc.
+ *
+ * Derived from c/src/lib/libcpu/ppc/ppc403/timer/timer.c:
+ *
+ * Author: Andrew Bray <andy@i-cubed.co.uk>
+ *
+ * COPYRIGHT (c) 1995 by i-cubed ltd.
+ *
+ * To anyone who acknowledges that this file is provided "AS IS"
+ * without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this file
+ * for any purpose is hereby granted without fee, provided that
+ * the above copyright notice and this notice appears in all
+ * copies, and that the name of i-cubed limited not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * i-cubed limited makes no representations about the suitability
+ * of this software for any purpose.
+ *
+ * Derived from c/src/lib/libcpu/hppa1_1/timer/timer.c:
+ *
+ * COPYRIGHT (c) 1989-1998.
* On-Line Applications Research Corporation (OAR).
- * All rights assigned to U.S. Government, 1994.
*
- * This material may be reproduced by or for the U.S. Government pursuant
- * to the copyright license under the clause at DFARS 252.227-7013. This
- * notice must appear in all copies of this file and its derivatives.
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
*
- * timer.c,v 1.2 1995/05/31 16:56:39 joel Exp
+ * $Id$
*/
#include <rtems.h>
+#include <mpc5xx.h>
+
+static volatile rtems_unsigned32 Timer_starting;
+static rtems_boolean Timer_driver_Find_average_overhead;
+
+/*
+ * This is so small that this code will be reproduced where needed.
+ */
+static inline rtems_unsigned32 get_itimer(void)
+{
+ rtems_unsigned32 ret;
-rtems_boolean Timer_driver_Find_average_overhead;
+ asm volatile ("mftb %0" : "=r" ((ret))); /* TBLO */
-static unsigned int volatile lastInitValue;
+ return ret;
+}
-void Timer_initialize( void )
+void Timer_initialize(void)
{
- asm volatile( " mftb %0": "=r" (lastInitValue) );
+ /* set interrupt level and enable timebase. This should never */
+ /* generate an interrupt however. */
+ usiu.tbscrk = USIU_UNLOCK_KEY;
+ usiu.tbscr |= USIU_TBSCR_TBIRQ(4) /* interrupt priority level */
+ | USIU_TBSCR_TBF /* freeze timebase during debug */
+ | USIU_TBSCR_TBE; /* enable timebase */
+ usiu.tbscrk = 0;
+
+ Timer_starting = get_itimer();
}
-/*
- * The following controls the behavior of Read_timer().
- *
- * AVG_OVEREHAD is the overhead for starting and stopping the timer. It
- * is usually deducted from the number returned.
- *
- * LEAST_VALID is the lowest number this routine should trust. Numbers
- * below this are "noise" and zero is returned.
- */
+#ifndef rtems_cpu_configuration_get_timer_least_valid
+#define rtems_cpu_configuration_get_timer_least_valid() 0
+#endif
-#define AVG_OVERHEAD 0 /* It typically takes X.X microseconds */
- /* (Y countdowns) to start/stop the timer. */
- /* This value is in microseconds. */
-#define LEAST_VALID 1 /* Don't trust a clicks value lower than this */
+#ifndef rtems_cpu_configuration_get_timer_average_overhead
+#define rtems_cpu_configuration_get_timer_average_overhead() 0
+#endif
-int Read_timer( void )
+int Read_timer(void)
{
- uint32_t value;
- asm volatile ( " mftb %0": "=r" (value) );
- return value - lastInitValue;
-}
+ rtems_unsigned32 clicks;
+ rtems_unsigned32 total;
-/*
- * Empty function call used in loops to measure basic cost of looping
- * in Timing Test Suite.
- */
+ clicks = get_itimer();
+
+ total = clicks - Timer_starting;
+
+ if ( Timer_driver_Find_average_overhead == 1 )
+ return total; /* in XXX microsecond units */
+
+ else {
+ if ( total < rtems_cpu_configuration_get_timer_least_valid() ) {
+ return 0; /* below timer resolution */
+ }
+ return (total - rtems_cpu_configuration_get_timer_average_overhead());
+ }
+}
-rtems_status_code Empty_function( void )
+rtems_status_code Empty_function(void)
{
return RTEMS_SUCCESSFUL;
}
-void Set_find_average_overhead(
- rtems_boolean find_flag
-)
+void Set_find_average_overhead(rtems_boolean find_flag)
{
Timer_driver_Find_average_overhead = find_flag;
}
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.S b/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.S
new file mode 100644
index 0000000000..125e3f60a4
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.S
@@ -0,0 +1,203 @@
+/*
+ * vectors.S
+ *
+ * This file contains the assembly code for the PowerPC exception veneers
+ * for RTEMS.
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from libbsp/powerpc/mbx8xx/vectors/vectors.S,
+ *
+ * (c) 1999, Eric Valette valette@crf.canon.fr
+ *
+ * $Id$
+ */
+
+#include <asm.h>
+#include <rtems/score/cpu.h>
+#include <libcpu/vectors.h>
+
+#define SYNC \
+ sync; \
+ isync
+
+
+/*
+ * Hardware exception vector table.
+ *
+ * The MPC555 can be configured to use a compressed vector table with 8
+ * bytes per entry, rather than the usual 0x100 bytes of other PowerPC
+ * devices. The following macro uses this feature to save the better part
+ * of 8 kbytes of flash ROM.
+ *
+ * Each vector table entry has room for only a simple branch instruction
+ * which branches to a prologue specific to that exception. This
+ * exception-specific prologue begins the context save, loads the exception
+ * number into a register, and jumps to a common exception prologue, below.
+ */
+
+ .macro vectors num=0, total=NUM_EXCEPTIONS /* create vector table */
+
+/* vector table entry */
+ .section .vectors, "ax"
+
+ ba specific_prologue\@ /* run specific prologue */
+ .long 0 /* each entry is 8 bytes */
+
+/* exception-specific prologue */
+ .text
+
+specific_prologue\@:
+ stwu r1, -EXCEPTION_FRAME_END(r1) /* open stack frame */
+ stw r4, GPR4_OFFSET(r1) /* preserve register */
+ li r4, \num /* get exception number */
+ b common_prologue /* run common prologue */
+
+/* invoke macro recursively to create remainder of table */
+ .if \total - (\num + 1)
+ vectors "(\num + 1)", \total
+ .endif
+
+ .endm
+
+
+/* invoke macro to create entire vector table */
+ vectors
+
+
+/*
+ * Common exception prologue.
+ *
+ * Because the MPC555 vector table is in flash ROM, it's not possible to
+ * change the exception handlers by overwriting them at run-time, so this
+ * common exception prologue uses a table of exception handler pointers to
+ * provide equivalent flexibility.
+ *
+ * When the actual exception handler is run, R1 points to the base of a new
+ * exception stack frame, in which R3, R4 and LR have been saved. R4 holds
+ * the exception number.
+ */
+ .text
+
+common_prologue:
+ stw r3, GPR3_OFFSET(r1) /* preserve registers */
+ mflr r3
+ stw r3, EXC_LR_OFFSET(r1)
+
+ slwi r3, r4, 2 /* make table offset */
+ addis r3, r3, exception_handler_table@ha /* point to entry */
+ addi r3, r3, exception_handler_table@l
+ lwz r3, 0(r3) /* get entry */
+ mtlr r3 /* run it */
+ blr
+
+
+/*
+ * Default exception handler.
+ *
+ * The function initialize_exceptions() initializes all of the entries in
+ * the exception handler table with pointers to this routine, which saves
+ * the remainder of the interrupted code's state, then calls
+ * C_default_exception_handler() to dump registers.
+ *
+ * On entry, R1 points to a new exception stack frame in which R3, R4, and
+ * LR have been saved. R4 holds the exception number.
+ */
+ .text
+
+PUBLIC_VAR(default_exception_handler)
+SYM (default_exception_handler):
+ /*
+ * Save the interrupted code's program counter and MSR. Beyond this
+ * point, all exceptions are recoverable. Use an RCPU-specific SPR
+ * to set the RI bit in the MSR to indicate the recoverable state.
+ */
+ mfsrr0 r3
+ stw r3, SRR0_FRAME_OFFSET(r1)
+ mfsrr1 r3
+ stw r3, SRR1_FRAME_OFFSET(r1)
+
+ mtspr eid, r3 /* set MSR[RI], clear MSR[EE] */
+ SYNC
+
+ /*
+ * Save the remainder of the general-purpose registers.
+ *
+ * Compute the value of R1 at exception entry before storing it in
+ * the frame.
+ *
+ * Note that R2 should never change (it's the EABI pointer to
+ * .sdata2), but we save it just in case.
+ *
+ * Recall that R3 and R4 were saved by the specific- and
+ * common-exception handlers before entry to this routine.
+ */
+ stw r0, GPR0_OFFSET(r1)
+ addi r0, r1, EXCEPTION_FRAME_END
+ stw r0, GPR1_OFFSET(r1)
+ stw r2, GPR2_OFFSET(r1)
+ stmw r5, GPR5_OFFSET(r1) /* save R5 to R31 */
+
+ /*
+ * Save the remainder of the UISA special-purpose registers. Recall
+ * that LR was saved before entry.
+ */
+ mfcr r0
+ stw r0, EXC_CR_OFFSET(r1)
+ mfctr r0
+ stw r0, EXC_CTR_OFFSET(r1)
+ mfxer r0
+ stw r0, EXC_XER_OFFSET(r1)
+
+ /*
+ * Call C-language portion of the default exception handler, passing
+ * in the address of the frame.
+ *
+ * To simplify things a bit, we assume that the target routine is
+ * within +/- 32 Mbyte from here, which is a reasonable assumption
+ * on the MPC555.
+ */
+ stw r4, EXCEPTION_NUMBER_OFFSET(r1) /* save exception number */
+ addi r3, r1, 0x8 /* get frame address */
+ bl C_default_exception_handler /* call handler */
+
+ /*
+ * Restore UISA special-purpose registers.
+ */
+ lwz r0, EXC_XER_OFFSET(r1)
+ mtxer r0
+ lwz r0, EXC_CTR_OFFSET(r1)
+ mtctr r0
+ lwz r0, EXC_CR_OFFSET(r1)
+ mtcr r0
+ lwz r0, EXC_LR_OFFSET(r1)
+ mtlr r0
+
+ /*
+ * Restore most general-purpose registers.
+ */
+ lmw r2, GPR2_OFFSET(r1)
+
+ /*
+ * Restore the interrupted code's program counter and MSR, but first
+ * use an RCPU-specific special-purpose register to clear the RI
+ * bit, indicating that exceptions are temporarily non-recoverable.
+ */
+ mtspr nri, r0 /* clear MSR[RI] */
+ SYNC
+
+ lwz r0, SRR1_FRAME_OFFSET(r1)
+ mtsrr1 r0
+ lwz r0, SRR0_FRAME_OFFSET(r1)
+ mtsrr0 r0
+
+ /*
+ * Restore the final GPR, close the stack frame, and return to the
+ * interrupted code.
+ */
+ lwz r0, GPR0_OFFSET(r1)
+ addi r1, r1, EXCEPTION_FRAME_END
+ SYNC
+ rfi
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.h b/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.h
new file mode 100644
index 0000000000..ce1d3fca17
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors.h
@@ -0,0 +1,156 @@
+/*
+ * vectors.h Exception frame related contant and API.
+ *
+ * This include file describe the data structure and the functions implemented
+ * by rtems to handle exceptions.
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from libbsp/powerpc/mbx8xx/vectors/vectors.h:
+ *
+ * CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ * 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$
+ */
+#ifndef LIBCPU_POWERPC_MBX5XX_VECTORS_H
+#define LIBCPU_POWERPC_MBX5XX_VECTORS_H
+
+
+/*
+ * Size of hardware vector table.
+ */
+#define NUM_EXCEPTIONS 0x20
+
+/*
+ * The callee (high level exception code written in C)
+ * will store the Link Registers (return address) at entry r1 + 4 !!!.
+ * So let room for it!!!.
+ */
+#define LINK_REGISTER_CALLEE_UPDATE_ROOM 4
+#define SRR0_FRAME_OFFSET 8
+#define SRR1_FRAME_OFFSET 12
+#define EXCEPTION_NUMBER_OFFSET 16
+#define GPR0_OFFSET 20
+#define GPR1_OFFSET 24
+#define GPR2_OFFSET 28
+#define GPR3_OFFSET 32
+#define GPR4_OFFSET 36
+#define GPR5_OFFSET 40
+#define GPR6_OFFSET 44
+#define GPR7_OFFSET 48
+#define GPR8_OFFSET 52
+#define GPR9_OFFSET 56
+#define GPR10_OFFSET 60
+#define GPR11_OFFSET 64
+#define GPR12_OFFSET 68
+#define GPR13_OFFSET 72
+#define GPR14_OFFSET 76
+#define GPR15_OFFSET 80
+#define GPR16_OFFSET 84
+#define GPR17_OFFSET 88
+#define GPR18_OFFSET 92
+#define GPR19_OFFSET 96
+#define GPR20_OFFSET 100
+#define GPR21_OFFSET 104
+#define GPR22_OFFSET 108
+#define GPR23_OFFSET 112
+#define GPR24_OFFSET 116
+#define GPR25_OFFSET 120
+#define GPR26_OFFSET 124
+#define GPR27_OFFSET 128
+#define GPR28_OFFSET 132
+#define GPR29_OFFSET 136
+#define GPR30_OFFSET 140
+#define GPR31_OFFSET 144
+#define EXC_CR_OFFSET 148
+#define EXC_CTR_OFFSET 152
+#define EXC_XER_OFFSET 156
+#define EXC_LR_OFFSET 160
+#define EXC_DAR_OFFSET 164
+/*
+ * maintain the EABI requested 8 bytes aligment
+ * As SVR4 ABI requires 16, make it 16 (as some
+ * exception may need more registers to be processed...)
+ */
+#define EXCEPTION_FRAME_END 176
+
+#ifndef ASM
+/*
+ * default raw exception handlers
+ */
+
+extern void default_exception_vector_code_prolog();
+extern int default_exception_vector_code_prolog_size;
+extern void initialize_exceptions();
+
+typedef struct {
+ unsigned EXC_SRR0;
+ unsigned EXC_SRR1;
+ unsigned _EXC_number;
+ unsigned GPR0;
+ unsigned GPR1;
+ unsigned GPR2;
+ unsigned GPR3;
+ unsigned GPR4;
+ unsigned GPR5;
+ unsigned GPR6;
+ unsigned GPR7;
+ unsigned GPR8;
+ unsigned GPR9;
+ unsigned GPR10;
+ unsigned GPR11;
+ unsigned GPR12;
+ unsigned GPR13;
+ unsigned GPR14;
+ unsigned GPR15;
+ unsigned GPR16;
+ unsigned GPR17;
+ unsigned GPR18;
+ unsigned GPR19;
+ unsigned GPR20;
+ unsigned GPR21;
+ unsigned GPR22;
+ unsigned GPR23;
+ unsigned GPR24;
+ unsigned GPR25;
+ unsigned GPR26;
+ unsigned GPR27;
+ unsigned GPR28;
+ unsigned GPR29;
+ unsigned GPR30;
+ unsigned GPR31;
+ unsigned EXC_CR;
+ unsigned EXC_CTR;
+ unsigned EXC_XER;
+ unsigned EXC_LR;
+ unsigned EXC_MSR;
+ unsigned EXC_DAR;
+}CPU_Exception_frame;
+
+
+typedef void rtems_exception_handler_t (CPU_Exception_frame* excPtr);
+/*DEBUG typedef rtems_exception_handler_t cpuExcHandlerType; */
+
+/*
+ * Exception handler table.
+ *
+ * This table contains pointers to assembly-language exception handlers.
+ * The common exception prologue in vectors.S looks up an entry in this
+ * table and jumps to it. No return address is saved, so the handlers in
+ * this table must return directly to the interrupted code.
+ *
+ * On entry to an exception handler, R1 points to a new exception stack
+ * frame in which R3, R4, and LR have been saved. R4 holds the exception
+ * number.
+ */
+extern rtems_exception_handler_t* exception_handler_table[NUM_EXCEPTIONS];
+
+#endif /* ASM */
+
+#endif /* LIBCPU_POWERPC_MPC5XX_VECTORS_H */
diff --git a/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors_init.c b/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors_init.c
new file mode 100644
index 0000000000..e5314ee50a
--- /dev/null
+++ b/c/src/lib/libcpu/powerpc/mpc5xx/vectors/vectors_init.c
@@ -0,0 +1,137 @@
+/*
+ * vectors_init.c Exception hanlding initialisation (and generic handler).
+ *
+ * This include file describe the data structure and the functions implemented
+ * by rtems to handle exceptions.
+ *
+ *
+ * MPC5xx port sponsored by Defence Research and Development Canada - Suffield
+ * Copyright (C) 2004, Real-Time Systems Inc. (querbach@realtime.bc.ca)
+ *
+ * Derived from libbsp/powerpc/mbx8xx/vectors/vectors_init.c:
+ *
+ * CopyRight (C) 1999 valette@crf.canon.fr
+ *
+ * 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$
+ */
+#include <rtems/bspIo.h>
+#include <libcpu/vectors.h>
+#include <libcpu/raw_exception.h>
+
+extern rtems_exception_handler_t default_exception_handler;
+
+static rtems_raw_except_global_settings exception_config;
+static rtems_raw_except_connect_data exception_table[NUM_EXCEPTIONS];
+rtems_exception_handler_t* exception_handler_table[NUM_EXCEPTIONS];
+
+
+void C_default_exception_handler(CPU_Exception_frame* excPtr)
+{
+ int recoverable = 0;
+
+ printk("exception handler called for exception %d\n", excPtr->_EXC_number);
+ printk("\t Next PC or Address of fault = %x\n", excPtr->EXC_SRR0);
+ printk("\t Saved MSR = %x\n", excPtr->EXC_SRR1);
+ printk("\t R0 = %x\n", excPtr->GPR0);
+ printk("\t R1 = %x\n", excPtr->GPR1);
+ printk("\t R2 = %x\n", excPtr->GPR2);
+ printk("\t R3 = %x\n", excPtr->GPR3);
+ printk("\t R4 = %x\n", excPtr->GPR4);
+ printk("\t R5 = %x\n", excPtr->GPR5);
+ printk("\t R6 = %x\n", excPtr->GPR6);
+ printk("\t R7 = %x\n", excPtr->GPR7);
+ printk("\t R8 = %x\n", excPtr->GPR8);
+ printk("\t R9 = %x\n", excPtr->GPR9);
+ printk("\t R10 = %x\n", excPtr->GPR10);
+ printk("\t R11 = %x\n", excPtr->GPR11);
+ printk("\t R12 = %x\n", excPtr->GPR12);
+ printk("\t R13 = %x\n", excPtr->GPR13);
+ printk("\t R14 = %x\n", excPtr->GPR14);
+ printk("\t R15 = %x\n", excPtr->GPR15);
+ printk("\t R16 = %x\n", excPtr->GPR16);
+ printk("\t R17 = %x\n", excPtr->GPR17);
+ printk("\t R18 = %x\n", excPtr->GPR18);
+ printk("\t R19 = %x\n", excPtr->GPR19);
+ printk("\t R20 = %x\n", excPtr->GPR20);
+ printk("\t R21 = %x\n", excPtr->GPR21);
+ printk("\t R22 = %x\n", excPtr->GPR22);
+ printk("\t R23 = %x\n", excPtr->GPR23);
+ printk("\t R24 = %x\n", excPtr->GPR24);
+ printk("\t R25 = %x\n", excPtr->GPR25);
+ printk("\t R26 = %x\n", excPtr->GPR26);
+ printk("\t R27 = %x\n", excPtr->GPR27);
+ printk("\t R28 = %x\n", excPtr->GPR28);
+ printk("\t R29 = %x\n", excPtr->GPR29);
+ printk("\t R30 = %x\n", excPtr->GPR30);
+ printk("\t R31 = %x\n", excPtr->GPR31);
+ printk("\t CR = %x\n", excPtr->EXC_CR);
+ printk("\t CTR = %x\n", excPtr->EXC_CTR);
+ printk("\t XER = %x\n", excPtr->EXC_XER);
+ printk("\t LR = %x\n", excPtr->EXC_LR);
+ printk("\t MSR = %x\n", excPtr->EXC_MSR);
+ if (excPtr->_EXC_number == ASM_DEC_VECTOR)
+ recoverable = 1;
+ if (excPtr->_EXC_number == ASM_SYS_VECTOR)
+#ifdef TEST_RAW_EXCEPTION_CODE
+ recoverable = 1;
+#else
+ recoverable = 0;
+#endif
+ if (!recoverable) {
+ printk("unrecoverable exception!!! Push reset button\n");
+ while(1);
+ }
+}
+
+void nop_except_enable(const rtems_raw_except_connect_data* ptr)
+{
+}
+
+int except_always_enabled(const rtems_raw_except_connect_data* ptr)
+{
+ return 1;
+}
+
+void initialize_exceptions()
+{
+ int i;
+
+ /*
+ * Initialize all entries of the exception table with a description of the
+ * default exception handler.
+ */
+ exception_config.exceptSize = NUM_EXCEPTIONS;
+ exception_config.rawExceptHdlTbl = &exception_table[0];
+ exception_config.defaultRawEntry.exceptIndex = 0;
+ exception_config.defaultRawEntry.hdl.vector = 0;
+ exception_config.defaultRawEntry.hdl.raw_hdl = default_exception_handler;
+
+ for (i = 0; i < exception_config.exceptSize; i++) {
+ printk("installing exception number %d\n", i);
+ exception_table[i].exceptIndex = i;
+ exception_table[i].hdl = exception_config.defaultRawEntry.hdl;
+ exception_table[i].hdl.vector = i;
+ exception_table[i].on = nop_except_enable;
+ exception_table[i].off = nop_except_enable;
+ exception_table[i].isOn = except_always_enabled;
+ }
+
+ /*
+ * Now pass the initialized exception table to the exceptions module which
+ * will install the handler pointers in the exception handler table.
+ */
+ if (!mpc5xx_init_exceptions(&exception_config)) {
+ /*
+ * At this stage we may not call CPU_Panic because it uses exceptions!!!
+ */
+ printk("Exception handling initialization failed\n");
+ printk("System locked\n"); while(1);
+ }
+ else {
+ printk("Exception handling initialization done\n");
+ }
+}