Index: bsps/powerpc/ss555/dev/clock.c
===================================================================
--- bsps/powerpc/ss555/dev/clock.c	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
+++ bsps/powerpc/ss555/dev/clock.c	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
@@ -0,0 +1,144 @@
+/*
+ *  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-2007.
+ *  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.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/clockdrv.h>
+#include <rtems/libio.h>
+#include <libcpu/irq.h>
+
+#include <stdlib.h>                     /* for atexit() */
+#include <mpc5xx.h>
+
+volatile uint32_t Clock_driver_ticks;
+extern int BSP_connect_clock_handler(rtems_isr_entry);
+extern int BSP_disconnect_clock_handler(void);
+extern uint32_t bsp_clicks_per_usec;
+
+void Clock_exit( void );
+
+/*
+ *  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;
+  uint32_t pit_value;
+
+  /* calculate and set modulus */
+  pit_value = (rtems_configuration_get_microseconds_per_tick() *
+               bsp_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 ();
+}
+
+static void Install_clock(rtems_isr_entry clock_isr)
+{
+  Clock_driver_ticks = 0;
+
+  BSP_connect_clock_handler (clock_isr);
+  atexit(Clock_exit);
+}
+
+rtems_device_driver Clock_initialize(
+  rtems_device_major_number major,
+  rtems_device_minor_number minor,
+  void *pargp
+)
+{
+  Install_clock( Clock_isr );
+
+  return RTEMS_SUCCESSFUL;
+}
Index: bsps/powerpc/ss555/dev/console-generic.c
===================================================================
--- bsps/powerpc/ss555/dev/console-generic.c	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
+++ bsps/powerpc/ss555/dev/console-generic.c	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
@@ -0,0 +1,317 @@
+/*
+ *  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.org/license/LICENSE.
+ */
+
+#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 <bsp/irq.h>
+
+
+/*
+ * 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 */
+  0, 					/* local mode flags */
+  0,					/* line discipline */
+  { 0 },				/* control characters */
+  CS8 | CREAD | CLOCAL | B9600, 	/* control mode flags */
+};
+
+
+extern uint32_t bsp_clock_speed;
+
+/*
+ * 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;
+}
+
+ssize_t m5xx_uart_write(
+  int minor,
+  const char *buf,
+  size_t len
+)
+{
+  if (len > 0) {
+    volatile m5xxSCIRegisters_t *regs = sci_descs[minor].regs;
+
+    regs->scdr = *buf;			/* start transmission */
+    regs->sccr1 |= QSMCM_SCI_TIE;		/* enable interrupt */
+  }
+
+  return 0;
+}
+
+ssize_t m5xx_uart_pollWrite(
+  int minor,
+  const char *buf,
+  size_t len
+)
+{
+  volatile m5xxSCIRegisters_t *regs = sci_descs[minor].regs;
+  size_t retval = len;
+
+  while ( len-- ) {
+    while ( (regs->scsr & QSMCM_SCI_TDRE) == 0 )
+      ;
+    regs->scdr = *buf++;
+  }
+
+  return retval;
+}
+
+int
+m5xx_uart_setAttributes(
+  int minor,
+  const struct termios *t
+)
+{
+  uint16_t sccr0 = sci_descs[minor].regs->sccr0;
+  uint16_t 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 */
+  baud = rtems_termios_baud_to_number( t->c_ospeed );
+  if (baud > 0) {
+    sccr0 &= ~QSMCM_SCI_BAUD(-1);
+    sccr0 |= QSMCM_SCI_BAUD((bsp_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 (rtems_irq_hdl_param unused)
+{
+  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);
+    }
+  }
+}
+
+static void m5xx_sci_nop(const rtems_irq_connect_data* ptr)
+{
+}
+
+static 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));
+  }
+}
Index: bsps/powerpc/ss555/dev/timer.c
===================================================================
--- bsps/powerpc/ss555/dev/timer.c	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
+++ bsps/powerpc/ss555/dev/timer.c	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
@@ -0,0 +1,104 @@
+/**
+ *  @file
+ *  @brief Timer Driver for the PowerPC MPC5xx.
+ *
+ *  This file manages the interval timer on the PowerPC MPC5xx.
+ *  @noe This is not the PIT, but rather the RTEMS interval timer.
+ *  We shall use the bottom 32 bits of the timebase register,
+ */
+
+/*
+ *  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-2007.
+ *  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.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <rtems/btimer.h>
+#include <mpc5xx.h>
+
+static volatile uint32_t Timer_starting;
+static bool benchmark_timer_find_average_overhead;
+
+extern uint32_t bsp_timer_least_valid;
+extern uint32_t bsp_timer_average_overhead;
+
+/*
+ *  This is so small that this code will be reproduced where needed.
+ */
+static inline uint32_t get_itimer(void)
+{
+   uint32_t ret;
+
+   __asm__ volatile ("mftb %0" : "=r" ((ret))); /* TBLO */
+
+   return ret;
+}
+
+void benchmark_timer_initialize(void)
+{
+  /* 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();
+}
+
+benchmark_timer_t benchmark_timer_read(void)
+{
+  uint32_t clicks;
+  uint32_t total;
+
+  clicks = get_itimer();
+
+  total = clicks - Timer_starting;
+
+  if ( benchmark_timer_find_average_overhead == 1 )
+    return total;          /* in XXX microsecond units */
+
+  else {
+    if ( total < bsp_timer_least_valid ) {
+      return 0;            /* below timer resolution */
+    }
+    return (total - bsp_timer_average_overhead);
+  }
+}
+
+void benchmark_timer_disable_subtracting_average_overhead(bool find_flag)
+{
+  benchmark_timer_find_average_overhead = find_flag;
+}
Index: bsps/powerpc/ss555/start/irq.c
===================================================================
--- bsps/powerpc/ss555/start/irq.c	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
+++ bsps/powerpc/ss555/start/irq.c	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
@@ -0,0 +1,463 @@
+/*
+ *  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 the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <mpc5xx.h>
+#include <libcpu/vectors.h>
+#include <libcpu/raw_exception.h>
+#include <libcpu/irq.h>
+#include <bsp/irq.h>
+
+/*
+ * Convert an rtems_irq_number 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_number 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_number 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_number 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_number 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 (void)
+{
+  /*
+   * 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;
+}
+
+static int CPU_irq_enable_at_uimb(const rtems_irq_number irqLine)
+{
+  if (!is_uimb_irq(irqLine))
+    return 1;
+  return 0;
+}
+
+static int CPU_irq_disable_at_uimb(const rtems_irq_number irqLine)
+{
+  if (!is_uimb_irq(irqLine))
+    return 1;
+  return 0;
+}
+
+static int CPU_irq_enable_at_usiu(const rtems_irq_number 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;
+}
+
+static int CPU_irq_disable_at_usiu(const rtems_irq_number 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;
+}
+
+/*
+ * --------------- RTEMS Single Irq Handler Mngt Routines ----------------
+ */
+
+int CPU_install_rtems_irq_handler	(const rtems_irq_connect_data* irq)
+{
+    rtems_interrupt_level       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;
+    }
+
+    rtems_interrupt_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
+     */
+	if (irq->on)
+    	irq->on(irq);
+
+    rtems_interrupt_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)
+{
+    rtems_interrupt_level       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;
+    }
+    rtems_interrupt_disable(level);
+
+    /*
+     * Disable interrupt on device
+     */
+	if (irq->off)
+    	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;
+
+    rtems_interrupt_enable(level);
+
+    return 1;
+}
+
+/*
+ * ---------------- RTEMS Global Irq Handler Mngt Routines ----------------
+ */
+
+int CPU_rtems_irq_mngt_set	(rtems_irq_global_settings* config)
+{
+    int                    i;
+    rtems_interrupt_level  level;
+
+   /*
+    * Store various code accelerators
+    */
+    internal_config 		= config;
+    default_rtems_entry 	= config->defaultEntry;
+    rtems_hdl_tbl 		= config->irqHdlTbl;
+
+    rtems_interrupt_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);
+	if (rtems_hdl_tbl[i].on)
+		rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
+      }
+      else {
+	if (rtems_hdl_tbl[i].off)
+		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);
+	if (rtems_hdl_tbl[i].on)
+		rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
+      }
+      else {
+	if (rtems_hdl_tbl[i].off)
+		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) {
+	if (rtems_hdl_tbl[i].on)
+		rtems_hdl_tbl[i].on(&rtems_hdl_tbl[i]);
+      }
+      else {
+	if (rtems_hdl_tbl[i].off)
+		rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]);
+      }
+    }
+    rtems_interrupt_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 (MPC5XX_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(rtems_hdl_tbl[CPU_DECREMENTER].handle);
+
+    _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(rtems_hdl_tbl[irq].handle);
+
+    _CPU_MSR_SET(msr);
+
+    ppc_cached_irq_mask = oldMask;
+    usiu.simask = ppc_cached_irq_mask;
+  }
+}
Index: bsps/powerpc/ss555/start/irq_asm.S
===================================================================
--- bsps/powerpc/ss555/start/irq_asm.S	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
+++ bsps/powerpc/ss555/start/irq_asm.S	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
@@ -0,0 +1,312 @@
+/*
+ * 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 the file LICENSE in this distribution or at
+ *  http://www.rtems.org/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.
+ */
+
+#include <rtems/asm.h>
+#include <rtems/score/cpu.h>
+#include <rtems/score/percpu.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, DISPATCH_NEEDED@ha
+	lbz	r5, DISPATCH_NEEDED@l(r4)
+	cmpwi	r5, 0
+	beq	easy_exit
+
+	/*
+	 * going to call _Thread_Dispatch
+	 * 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	_Thread_Dispatch
+
+	/*
+	 * 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
+
+
+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
Index: bsps/powerpc/ss555/start/irq_init.c
===================================================================
--- bsps/powerpc/ss555/start/irq_init.c	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
+++ bsps/powerpc/ss555/start/irq_init.c	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
@@ -0,0 +1,165 @@
+/*
+ * 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.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <mpc5xx.h>
+#include <libcpu/vectors.h>
+#include <libcpu/raw_exception.h>
+#include <bsp/irq.h>
+
+extern rtems_exception_handler_t dispatch_irq_handler;
+
+volatile unsigned int ppc_cached_irq_mask;
+
+/*
+ * default methods
+ */
+static void nop_hdl(rtems_irq_hdl_param ignored)
+{
+}
+
+static void nop_irq_enable(const struct __rtems_irq_connect_data__*ignored)
+{
+}
+
+static void nop_raw_enable(
+  const struct __rtems_raw_except_connect_data__*ignored
+)
+{
+}
+
+static int irq_is_connected(const struct __rtems_irq_connect_data__*ignored)
+{
+  return 0;
+}
+
+static int raw_is_connected(const struct __rtems_raw_except_connect_data__*ignored)
+{
+  return 0;
+}
+
+static rtems_irq_connect_data     rtemsIrq[CPU_IRQ_COUNT];
+static rtems_irq_global_settings  initial_config;
+static rtems_irq_connect_data     defaultIrq = {
+  0,                /* vector */
+  nop_hdl,          /* hdl */
+  NULL,             /* handle */
+  nop_irq_enable,   /* on */
+  nop_irq_enable,   /* off */
+  irq_is_connected  /* isOn */
+};
+
+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
+};
+
+static void CPU_USIU_irq_init(void)
+{
+  /*
+   * 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
+ */
+static 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...
+       */
+      rtems_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_raw_enable;
+    vectorDesc.off         = nop_raw_enable;
+    vectorDesc.isOn        = raw_is_connected;
+    if (!mpc5xx_set_exception (&vectorDesc)) {
+      rtems_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)) {
+      rtems_panic("Unable to initialize RTEMS external raw exception\n");
+    }
+}
Index: bsps/powerpc/ss555/start/raw_exception.c
===================================================================
--- bsps/powerpc/ss555/start/raw_exception.c	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
+++ bsps/powerpc/ss555/start/raw_exception.c	(revision 09dd82a5974d01525402e32f47d66ff1fe1b6a67)
@@ -0,0 +1,190 @@
+/*
+ * 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:
+ *
+ *		     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.
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ *
+ */
+
+#include <rtems.h>
+#include <rtems/score/powerpc.h>
+#include <libcpu/raw_exception.h>
+#include <libcpu/cpuIdent.h>
+#include <rtems/bspIo.h>	/* for printk */
+#include <string.h>
+
+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 mpc5xx_vector_is_valid(rtems_vector vector)
+{
+  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)
+{
+  rtems_interrupt_level 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 (exception_handler_table[except->exceptIndex] !=
+      default_raw_except_entry.hdl.raw_hdl) {
+    return 0;
+  }
+
+  rtems_interrupt_disable(level);
+
+  raw_except_table[except->exceptIndex] = *except;
+
+  exception_handler_table[except->exceptIndex] = except->hdl.raw_hdl;
+  if (except->on)
+  	except->on(except);
+
+  rtems_interrupt_enable(level);
+  return 1;
+}
+
+int mpc5xx_get_current_exception (rtems_raw_except_connect_data* except)
+{
+  if (!mpc5xx_vector_is_valid(except->exceptIndex)){
+    return 0;
+  }
+
+  *except = raw_except_table[except->exceptIndex];
+
+  return 1;
+}
+
+int mpc5xx_delete_exception (const rtems_raw_except_connect_data* except)
+{
+  rtems_interrupt_level level;
+
+  if (!mpc5xx_vector_is_valid(except->exceptIndex)){
+    return 0;
+  }
+  /*
+   * Check if handler passed 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] != except->hdl.raw_hdl) {
+    return 0;
+  }
+
+  rtems_interrupt_disable(level);
+
+  if (except->off)
+  	except->off(except);
+  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;
+
+  rtems_interrupt_enable(level);
+
+  return 1;
+}
+
+/*
+ * 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;
+  rtems_interrupt_level level;
+
+  /*
+   * store various accelerators
+   */
+  raw_except_table 		= config->rawExceptHdlTbl;
+  local_settings 		= config;
+  default_raw_except_entry 	= config->defaultRawEntry;
+
+  rtems_interrupt_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) {
+      if (raw_except_table[i].on)
+      	raw_except_table[i].on(&raw_except_table[i]);
+    }
+    else {
+      if (raw_except_table[i].off)
+      	raw_except_table[i].off(&raw_except_table[i]);
+    }
+  }
+  rtems_interrupt_enable(level);
+
+  return 1;
+}
+
+int mpc5xx_get_exception_config (rtems_raw_except_global_settings** config)
+{
+  *config = local_settings;
+  return 1;
+}
