Index: bsps/m68k/mvme147s/mpci/addrconv.c
===================================================================
--- bsps/m68k/mvme147s/mpci/addrconv.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/m68k/mvme147s/mpci/addrconv.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,33 @@
+/*  Shm_Convert_address
+ *
+ *  This MVME147 has a "normal" view of the VME address space.
+ *  No address range conversion is required.
+ *
+ *  Input parameters:
+ *    address - address to convert
+ *
+ *  Output parameters:
+ *    returns - converted address
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  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.
+ *
+ *  MVME147 port for TNI - Telecom Bretagne
+ *  by Dominique LE CAMPION (Dominique.LECAMPION@enst-bretagne.fr)
+ *  June 1996
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <shm_driver.h>
+
+void *Shm_Convert_address(
+  void *address
+)
+{
+  return ( address );
+}
Index: bsps/m68k/mvme147s/mpci/getcfg.c
===================================================================
--- bsps/m68k/mvme147s/mpci/getcfg.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/m68k/mvme147s/mpci/getcfg.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,84 @@
+/*  void Shm_Get_configuration( localnode, &shmcfg )
+ *
+ *  This routine initializes, if necessary, and returns a pointer
+ *  to the Shared Memory Configuration Table for the MVME147.
+ *
+ *  INPUT PARAMETERS:
+ *    localnode - local node number
+ *    shmcfg    - address of pointer to SHM Config Table
+ *
+ *  OUTPUT PARAMETERS:
+ *    *shmcfg   - pointer to SHM Config Table
+ *
+ *  NOTES:  The SIGLP interrupt on the MVME147 is used as an interprocessor
+ *          interrupt.
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  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.
+ *
+ *  MVME147 port for TNI - Telecom Bretagne
+ *  by Dominique LE CAMPION (Dominique.LECAMPION@enst-bretagne.fr)
+ *  June 1996
+ */
+
+#include <bsp.h>
+#include <rtems.h>
+#include "shm_driver.h"
+
+#define INTERRUPT 1                   /* MVME147 target supports both */
+#define POLLING   0                   /* polling and interrupt modes  */
+
+shm_config_table BSP_shm_cfgtbl;
+
+static uint32_t *BSP_int_address(void)
+{
+  uint32_t         id, offset;
+
+  id      = (uint32_t) vme_lcsr->gcsr_base_address;
+  offset  = (id << 4) & 0xF0;
+  offset |= 0xffff0003; /* points to GCSR global 1 */
+  return( (uint32_t         * ) offset );
+}
+
+void Shm_Get_configuration(
+  uint32_t           localnode,
+  shm_config_table **shmcfg
+)
+{
+  /* A shared mem space has bee left between RAM_END and DRAM_END
+   on the first node*/
+  if (localnode == 1)
+    BSP_shm_cfgtbl.base       = (vol_u32 *) RAM_END;
+  else
+    BSP_shm_cfgtbl.base       = (vol_u32 *) (DRAM_END + RAM_END);
+
+  BSP_shm_cfgtbl.length       = DRAM_END - RAM_END;
+  BSP_shm_cfgtbl.format       = SHM_BIG;
+
+  BSP_shm_cfgtbl.cause_intr   = Shm_Cause_interrupt;
+
+#ifdef NEUTRAL_BIG
+  BSP_shm_cfgtbl.convert      = NULL_CONVERT;
+#else
+  BSP_shm_cfgtbl.convert      = CPU_swap_u32;
+#endif
+
+#if (POLLING==1)
+  BSP_shm_cfgtbl.poll_intr    = POLLED_MODE;
+  BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT;
+  BSP_shm_cfgtbl.Intr.value   = NO_INTERRUPT;
+  BSP_shm_cfgtbl.Intr.length  = NO_INTERRUPT;
+#else
+  BSP_shm_cfgtbl.poll_intr    = INTR_MODE;
+  BSP_shm_cfgtbl.Intr.address = BSP_int_address(); /* GCSR global 1 */
+  BSP_shm_cfgtbl.Intr.value   = 0x01; /* SIGLP */
+  BSP_shm_cfgtbl.Intr.length  = BYTE;
+#endif
+
+  *shmcfg = &BSP_shm_cfgtbl;
+
+}
Index: bsps/m68k/mvme147s/mpci/lock.c
===================================================================
--- bsps/m68k/mvme147s/mpci/lock.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/m68k/mvme147s/mpci/lock.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,71 @@
+/*  Shared Memory Lock Routines
+ *
+ *  This shared memory locked queue support routine need to be
+ *  able to lock the specified locked queue.  Interrupts are
+ *  disabled while the queue is locked to prevent preemption
+ *  and deadlock when two tasks poll for the same lock.
+ *  previous level.
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  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 <bsp.h>
+#include <shm_driver.h>
+
+/*
+ *  Shm_Initialize_lock
+ *
+ *  Initialize the lock for the specified locked queue.
+ */
+
+void Shm_Initialize_lock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  lq_cb->lock = LQ_UNLOCKED;
+}
+
+/*  void _Shm_Lock( &lq_cb )
+ *
+ *  This shared memory locked queue support routine locks the
+ *  specified locked queue.  It disables interrupts to prevent
+ *  a deadlock condition.
+ */
+
+void Shm_Lock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  uint32_t         isr_level;
+  uint32_t         *lockptr = (uint32_t*)&lq_cb->lock;
+
+  rtems_interrupt_disable( isr_level );
+    Shm_isrstat = isr_level;
+    __asm__ volatile( "lockit:"    : : );
+    __asm__ volatile( "tas %0@"    : "=a" (lockptr) : "0" (lockptr) );
+    __asm__ volatile( "bne lockit" : : );
+/* should delay */
+}
+
+/*
+ *  Shm_Unlock
+ *
+ *  Unlock the lock for the specified locked queue.
+ */
+
+void Shm_Unlock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  uint32_t         isr_level;
+
+  lq_cb->lock = SHM_UNLOCK_VALUE;
+  isr_level = Shm_isrstat;
+  rtems_interrupt_enable( isr_level );
+}
Index: bsps/m68k/mvme147s/mpci/mpisr.c
===================================================================
--- bsps/m68k/mvme147s/mpci/mpisr.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/m68k/mvme147s/mpci/mpisr.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,41 @@
+/**
+ * @file
+ *
+ *  NOTE: This routine is not used when in polling mode.  Either
+ *        this routine OR Shm_clockisr is used in a particular system.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-1999, 2016.
+ *  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.
+ *
+ *  MVME147 port for TNI - Telecom Bretagne
+ *  by Dominique LE CAMPION (Dominique.LECAMPION@enst-bretagne.fr)
+ *  June 1996
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <shm_driver.h>
+
+static rtems_isr Shm_isr_mvme147(rtems_vector_number vector)
+{
+  (void) vector;
+  Shm_Interrupt_count += 1;
+  rtems_multiprocessing_announce();
+  vme_gcsr->global_1 = 1; /* clear SIGLP intr */
+}
+
+/*
+ *  This driver routine sets the SHM interrupt vector to point to the
+ *  driver's SHM interrupt service routine.
+ */
+void Shm_setvec(void)
+{
+  /* may need to disable intr */
+  set_vector( Shm_isr_mvme147, VME_SIGLP_VECTOR, 1 );
+}
Index: bsps/no_cpu/no_bsp/mpci/addrconv.c
===================================================================
--- bsps/no_cpu/no_bsp/mpci/addrconv.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/no_cpu/no_bsp/mpci/addrconv.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,28 @@
+/*  Shm_Convert_address
+ *
+ *  No address range conversion is required.
+ *
+ *  Input parameters:
+ *    address - address to convert
+ *
+ *  Output parameters:
+ *    returns - converted address
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  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 <bsp.h>
+#include <shm_driver.h>
+
+void *Shm_Convert_address(
+  void *address
+)
+{
+  return ( address );
+}
Index: bsps/no_cpu/no_bsp/mpci/getcfg.c
===================================================================
--- bsps/no_cpu/no_bsp/mpci/getcfg.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/no_cpu/no_bsp/mpci/getcfg.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,73 @@
+/*  void Shm_Get_configuration( localnode, &shmcfg )
+ *
+ *  This routine initializes, if necessary, and returns a pointer
+ *  to the Shared Memory Configuration Table for the XXX target.
+ *
+ *  INPUT PARAMETERS:
+ *    localnode - local node number
+ *    shmcfg    - address of pointer to SHM Config Table
+ *
+ *  OUTPUT PARAMETERS:
+ *    *shmcfg   - pointer to SHM Config Table
+ *
+XXX: FIX THE COMMENTS BELOW WHEN THE CPU IS KNOWN
+ *  NOTES:  The XYZ does not have an interprocessor interrupt.
+ *
+ *          The following table illustrates the configuration limitations:
+ *
+ *                                   BUS     MAX
+ *                          MODE    ENDIAN  NODES
+ *                        ========= ====== =======
+ *                         POLLED    BIG    2+
+ *                        INTERRUPT **** NOT SUPPORTED ****
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  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 <bsp.h>
+#include <shm_driver.h>
+
+/*
+ *  configured if currently polling of interrupt driven
+ */
+
+#define INTERRUPT 0        /* XXX: */
+#define POLLING   1        /* XXX: fix me -- is polling ONLY!!! */
+
+shm_config_table BSP_shm_cfgtbl;
+
+void Shm_Get_configuration(
+  uint32_t           localnode,
+  shm_config_table **shmcfg
+)
+{
+   BSP_shm_cfgtbl.base         = 0x0;
+   BSP_shm_cfgtbl.length       = 1 * MEGABYTE;
+   BSP_shm_cfgtbl.format       = SHM_BIG;
+
+   /*
+    *  Override cause_intr or shm_isr if your target has
+    *  special requirements.
+    */
+
+   BSP_shm_cfgtbl.cause_intr   = Shm_Cause_interrupt;
+
+#ifdef NEUTRAL_BIG
+   BSP_shm_cfgtbl.convert      = NULL_CONVERT;
+#else
+   BSP_shm_cfgtbl.convert      = CPU_swap_u32;
+#endif
+
+   BSP_shm_cfgtbl.poll_intr    = POLLED_MODE;
+   BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT;
+   BSP_shm_cfgtbl.Intr.value   = NO_INTERRUPT;
+   BSP_shm_cfgtbl.Intr.length  = NO_INTERRUPT;
+
+   *shmcfg = &BSP_shm_cfgtbl;
+}
Index: bsps/no_cpu/no_bsp/mpci/lock.c
===================================================================
--- bsps/no_cpu/no_bsp/mpci/lock.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/no_cpu/no_bsp/mpci/lock.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,84 @@
+/*  Shared Memory Lock Routines
+ *
+ *  This shared memory locked queue support routine need to be
+ *  able to lock the specified locked queue.  Interrupts are
+ *  disabled while the queue is locked to prevent preemption
+ *  and deadlock when two tasks poll for the same lock.
+ *  previous level.
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  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 <bsp.h>
+#include <shm_driver.h>
+
+/*
+ *  Shm_Initialize_lock
+ *
+ *  Initialize the lock for the specified locked queue.
+ */
+
+void Shm_Initialize_lock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  lq_cb->lock = LQ_UNLOCKED;
+}
+
+/*  void _Shm_Lock( &lq_cb )
+ *
+ *  This shared memory locked queue support routine locks the
+ *  specified locked queue.  It disables interrupts to prevent
+ *  a deadlock condition.
+ */
+
+void Shm_Lock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  uint32_t         isr_level;
+  uint32_t         *lockptr = (uint32_t*) &lq_cb->lock;
+  uint32_t         lock_value;
+
+  lock_value = 0x80000000;
+  rtems_interrupt_disable( isr_level );
+
+    Shm_isrstat = isr_level;
+    while ( lock_value ) {
+      __asm__ volatile( ""
+                         : "=r" (lockptr), "=r" (lock_value)
+                         : "0" (lockptr),  "1" (lock_value)
+                  );
+      /*
+       *  If not available, then may want to delay to reduce load on lock.
+       *
+       *  NOTE: BSP must initialize the counter facility. Delay value is BSP
+       *        dependent.
+       */
+      if ( lock_value )
+        rtems_counter_delay_nanoseconds( 100 );
+   }
+}
+
+/*
+ *  Shm_Unlock
+ *
+ *  Unlock the lock for the specified locked queue.
+ */
+
+void Shm_Unlock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  uint32_t         isr_level;
+
+  lq_cb->lock = SHM_UNLOCK_VALUE;
+  isr_level = Shm_isrstat;
+  rtems_interrupt_enable( isr_level );
+}
Index: bsps/no_cpu/no_bsp/mpci/mpisr.c
===================================================================
--- bsps/no_cpu/no_bsp/mpci/mpisr.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/no_cpu/no_bsp/mpci/mpisr.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,44 @@
+/**
+ *  @file
+ *
+ *  Template for Shared Memory Driver Interrupt Support
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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 <bsp.h>
+#include <shm_driver.h>
+
+rtems_isr Shm_isr_nobsp(rtems_vector_number ignored)
+{
+  /*
+   *  If this routine has to do anything other than the mpisr.c
+   *  found in the generic driver, then copy the contents of the generic
+   *  mpisr.c and augment it to satisfy this particular board.  Typically,
+   *  you need to have a board specific mpisr.c when the interrupt
+   *  must be cleared.
+   *
+   *  If the generic mpisr.c satisifies your requirements, then
+   *  remove this routine from your target's shmsupp/mpisr.c file.
+   *  Then simply install the generic Shm_isr in the Shm_setvec
+   *  routine below.
+   */
+}
+
+/* 
+ *  This driver routine sets the SHM interrupt vector to point to the
+ *  driver's SHM interrupt service routine.
+ */
+
+void Shm_setvec( void )
+{
+  /* XXX: FIX ME!!! */
+}
Index: bsps/powerpc/psim/mpci/README
===================================================================
--- bsps/powerpc/psim/mpci/README	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/powerpc/psim/mpci/README	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,3 @@
+This shared memory driver support code works with a modified version
+of the PowerPC Simulator.  The modifications are not yet merged
+into the mainsteam distribution.
Index: bsps/powerpc/psim/mpci/addrconv.c
===================================================================
--- bsps/powerpc/psim/mpci/addrconv.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/powerpc/psim/mpci/addrconv.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,28 @@
+/*  Shm_Convert_address
+ *
+ *  No address range conversion is required.
+ *
+ *  Input parameters:
+ *    address - address to convert
+ *
+ *  Output parameters:
+ *    returns - converted address
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  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 <bsp.h>
+#include <shm_driver.h>
+
+void *Shm_Convert_address(
+  void *address
+)
+{
+  return ( address );
+}
Index: bsps/powerpc/psim/mpci/getcfg.c
===================================================================
--- bsps/powerpc/psim/mpci/getcfg.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/powerpc/psim/mpci/getcfg.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,63 @@
+/*  void Shm_Get_configuration( localnode, &shmcfg )
+ *
+ *  This routine initializes, if necessary, and returns a pointer
+ *  to the Shared Memory Configuration Table for the PowerPC PSIM.
+ *
+ *  INPUT PARAMETERS:
+ *    localnode - local node number
+ *    shmcfg    - address of pointer to SHM Config Table
+ *
+ *  OUTPUT PARAMETERS:
+ *    *shmcfg   - pointer to SHM Config Table
+ *
+ *  NOTES:  No interrupt support.
+ *
+ *  COPYRIGHT (c) 1989-2008.
+ *  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 <psim.h>
+#include "shm_driver.h"
+
+#define INTERRUPT 0                   /* PSIM target supports only */
+#define POLLING   1                   /* polling mode. */
+
+shm_config_table BSP_shm_cfgtbl;
+
+void Shm_Get_configuration(
+  uint32_t           localnode,
+  shm_config_table **shmcfg
+)
+{
+   BSP_shm_cfgtbl.base         = (uint32_t*)PSIM.SharedMemory;
+   BSP_shm_cfgtbl.length       = sizeof(PSIM.SharedMemory);
+   BSP_shm_cfgtbl.format       = SHM_BIG;
+
+   BSP_shm_cfgtbl.cause_intr   = Shm_Cause_interrupt;
+
+#ifdef NEUTRAL_BIG
+   BSP_shm_cfgtbl.convert      = NULL_CONVERT;
+#else
+   BSP_shm_cfgtbl.convert      = CPU_swap_u32;
+#endif
+
+#if (POLLING==1)
+   BSP_shm_cfgtbl.poll_intr    = POLLED_MODE;
+   BSP_shm_cfgtbl.Intr.address = NO_INTERRUPT;
+   BSP_shm_cfgtbl.Intr.value   = NO_INTERRUPT;
+   BSP_shm_cfgtbl.Intr.length  = NO_INTERRUPT;
+#else
+   BSP_shm_cfgtbl.poll_intr    = INTR_MODE;
+   BSP_shm_cfgtbl.Intr.address = 0;
+   BSP_shm_cfgtbl.Intr.value   = 0;
+   BSP_shm_cfgtbl.Intr.length  = BYTE;
+#endif
+
+   *shmcfg = &BSP_shm_cfgtbl;
+
+}
Index: bsps/powerpc/psim/mpci/lock.c
===================================================================
--- bsps/powerpc/psim/mpci/lock.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/powerpc/psim/mpci/lock.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,64 @@
+/*  Shared Memory Lock Routines
+ *
+ *  This shared memory locked queue support routine need to be
+ *  able to lock the specified locked queue.  Interrupts are
+ *  disabled while the queue is locked to prevent preemption
+ *  and deadlock when two tasks poll for the same lock.
+ *  previous level.
+ *
+ *  COPYRIGHT (c) 1989-2008.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may in
+ *  the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <shm_driver.h>
+#include <psim.h>
+
+/*
+ *  Shm_Initialize_lock
+ *
+ *  Initialize the lock for the specified locked queue.
+ */
+
+void Shm_Initialize_lock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  /* nothing required -- done implicitly by device tree */
+}
+
+/*  void _Shm_Lock( &lq_cb )
+ *
+ *  This shared memory locked queue support routine locks the
+ *  specified locked queue.  It disables interrupts to prevent
+ *  a deadlock condition.
+ */
+
+static rtems_interrupt_level level;
+
+void Shm_Lock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  rtems_interrupt_disable( level );
+    (void) PSIM.Semaphore.lock;
+}
+
+/*
+ *  Shm_Unlock
+ *
+ *  Unlock the lock for the specified locked queue.
+ */
+
+void Shm_Unlock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+    (void) PSIM.Semaphore.unlock;
+  rtems_interrupt_enable( level );
+}
Index: bsps/powerpc/psim/mpci/mpisr.c
===================================================================
--- bsps/powerpc/psim/mpci/mpisr.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/powerpc/psim/mpci/mpisr.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,30 @@
+/*
+ *  NOTE: This routine is not used when in polling mode.  Either
+ *        this routine OR Shm_clockisr is used in a particular system.
+ *
+ *  COPYRIGHT (c) 1989-1997.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may in
+ *  the file LICENSE in this distribution or at
+ *  http://www.rtems.org/license/LICENSE.
+ */
+
+#include <rtems.h>
+#include <bsp.h>
+#include <shm_driver.h>
+
+/*  void _Shm_setvec( )
+ *
+ *  This driver routine sets the SHM interrupt vector to point to the
+ *  driver's SHM interrupt service routine.
+ *
+ *  Input parameters:  NONE
+ *
+ *  Output parameters: NONE
+ */
+
+void Shm_setvec()
+{
+  /* not supported */
+}
Index: bsps/powerpc/qoriq/mpci/intercom-mpci.c
===================================================================
--- bsps/powerpc/qoriq/mpci/intercom-mpci.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/powerpc/qoriq/mpci/intercom-mpci.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,124 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQInterCom
+ *
+ * @brief Inter-Processor Communication implementation.
+ */
+
+/*
+ * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * 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 <assert.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bsp/intercom.h>
+
+#ifdef RTEMS_MULTIPROCESSING
+
+typedef struct {
+	intercom_packet *head;
+	intercom_packet *tail;
+} mpic_fifo;
+
+static mpic_fifo fifo;
+
+static void mpci_service(intercom_packet *packet, void *arg)
+{
+	rtems_interrupt_level level;
+
+	rtems_interrupt_disable(level);
+	packet->glue.next = NULL;
+	if (fifo.head != NULL) {
+		fifo.tail->glue.next = packet;
+	} else {
+		fifo.head = packet;
+	}
+	fifo.tail = packet;
+	rtems_interrupt_enable(level);
+
+	rtems_multiprocessing_announce();
+}
+
+static void mpci_init(void)
+{
+	qoriq_intercom_service_install(INTERCOM_TYPE_MPCI, mpci_service, NULL);
+}
+
+static intercom_packet *packet_of_prefix(rtems_packet_prefix *prefix)
+{
+	return (intercom_packet *) ((char *) prefix - sizeof(intercom_packet));
+}
+
+static rtems_packet_prefix *prefix_of_packet(intercom_packet *packet)
+{
+	return (rtems_packet_prefix *) packet->data;
+}
+
+static void mpci_get_packet(rtems_packet_prefix **prefix_ptr)
+{
+	intercom_packet *packet = qoriq_intercom_allocate_packet(
+		INTERCOM_TYPE_MPCI,
+		INTERCOM_SIZE_512
+	);
+	*prefix_ptr = prefix_of_packet(packet);
+}
+
+static void mpci_return_packet(rtems_packet_prefix *prefix)
+{
+	intercom_packet *packet = packet_of_prefix(prefix);
+
+	qoriq_intercom_free_packet(packet);
+}
+
+static void mpci_send_packet(uint32_t destination_node, rtems_packet_prefix *prefix)
+{
+	intercom_packet *packet = packet_of_prefix(prefix);
+	if (destination_node != MPCI_ALL_NODES) {
+		qoriq_intercom_send_packet((int) destination_node - 1, packet);
+	} else {
+		uint32_t self = ppc_processor_id();
+		int other = self == 0 ? 1 : 0;
+
+		qoriq_intercom_send_packet(other, packet);
+	}
+}
+
+static void mpci_receive_packet(rtems_packet_prefix **prefix_ptr)
+{
+	rtems_interrupt_level level;
+
+	rtems_interrupt_disable(level);
+	intercom_packet *packet = fifo.head;
+	if (packet != NULL) {
+		fifo.head = packet->glue.next;
+		*prefix_ptr = prefix_of_packet(packet);
+	} else {
+		*prefix_ptr = NULL;
+	}
+	rtems_interrupt_enable(level);
+}
+
+rtems_mpci_table qoriq_intercom_mpci = {
+	.default_timeout = UINT32_MAX,
+	.maximum_packet_size = 512,
+	.initialization = mpci_init,
+	.get_packet = mpci_get_packet,
+	.return_packet = mpci_return_packet,
+	.send_packet = mpci_send_packet,
+	.receive_packet = mpci_receive_packet
+};
+
+#endif /* RTEMS_MULTIPROCESSING */
Index: bsps/powerpc/qoriq/mpci/intercom.c
===================================================================
--- bsps/powerpc/qoriq/mpci/intercom.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/powerpc/qoriq/mpci/intercom.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,498 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQInterCom
+ *
+ * @brief Inter-Processor Communication implementation.
+ */
+
+/*
+ * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * 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 <assert.h>
+#include <string.h>
+
+#include <rtems.h>
+
+#include <libcpu/powerpc-utility.h>
+
+#include <bspopts.h>
+#include <bsp/irq.h>
+#include <bsp/qoriq.h>
+#include <bsp/intercom.h>
+
+#ifndef QORIQ_IS_HYPERVISOR_GUEST
+
+#define INTERCOM_EVENT_IPI RTEMS_EVENT_13
+#define INTERCOM_EVENT_WAKE_UP RTEMS_EVENT_14
+
+#define PACKET_SIZE_COUNT 4
+
+#define ONE_CORE(core) (1U << (core))
+#define ALL_CORES ((1U << INTERCOM_CORE_COUNT) - 1U)
+#define OTHER_CORES(core) (ALL_CORES & ~ONE_CORE(core))
+
+#define IPI_INDEX 0
+
+typedef struct consumer {
+	struct consumer *next;
+	rtems_id task;
+} consumer;
+
+typedef struct {
+	consumer *head;
+	uint32_t cache_line_alignment [7];
+} consumer_list;
+
+typedef struct {
+	uint32_t lock;
+	intercom_packet *head;
+	size_t size;
+	uint32_t cores_to_notify;
+	uint32_t cache_line_alignment [4];
+	consumer_list waiting_consumers [INTERCOM_CORE_COUNT];
+} free_list;
+
+typedef struct {
+	uint32_t lock;
+	intercom_packet *head;
+	intercom_packet *tail;
+	uint32_t cache_line_alignment [5];
+} core_fifo;
+
+typedef struct {
+	free_list free_lists [PACKET_SIZE_COUNT];
+	core_fifo core_fifos [INTERCOM_CORE_COUNT];
+	intercom_service services [INTERCOM_CORE_COUNT][INTERCOM_SERVICE_COUNT];
+	void *service_args [INTERCOM_CORE_COUNT][INTERCOM_SERVICE_COUNT];
+	uint32_t ready_lock;
+	uint32_t ready;
+	uint32_t cache_line_alignment [6];
+} control;
+
+static control *const intercom = (control *) QORIQ_INTERCOM_AREA_BEGIN;
+
+static const size_t packet_sizes [PACKET_SIZE_COUNT] = {
+	64,
+	512,
+	2048,
+	4096
+};
+
+static void send_event(rtems_id task, rtems_event_set event)
+{
+	rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+	sc = rtems_event_send(task, event);
+	assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void wait_for_event(rtems_event_set in)
+{
+	rtems_status_code sc = RTEMS_SUCCESSFUL;
+	rtems_event_set out;
+
+	sc = rtems_event_receive(
+		in,
+		RTEMS_EVENT_ALL | RTEMS_WAIT,
+		RTEMS_NO_TIMEOUT,
+		&out
+	);
+	assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void intercom_handler(void *arg)
+{
+	rtems_id task = (rtems_id) (uintptr_t) arg;
+	send_event(task, INTERCOM_EVENT_IPI);
+}
+
+static void notify_core_by_index(int core)
+{
+	uint32_t self = ppc_processor_id();
+	qoriq.pic.per_cpu [self].ipidr [IPI_INDEX].reg = ONE_CORE(core);
+}
+
+static void notify_cores(uint32_t cores)
+{
+	uint32_t self = ppc_processor_id();
+	qoriq.pic.per_cpu [self].ipidr [IPI_INDEX].reg = cores;
+}
+
+void qoriq_intercom_free_packet(intercom_packet *packet)
+{
+	free_list *list = &intercom->free_lists [packet->size_index];
+
+	uint32_t msr = qoriq_spin_lock(&list->lock);
+	intercom_packet *first = list->head;
+	list->head = packet;
+	packet->glue.next = first;
+	uint32_t cores = list->cores_to_notify;
+	if (cores != 0) {
+		list->cores_to_notify = 0;
+		notify_cores(cores);
+	}
+	qoriq_spin_unlock(&list->lock, msr);
+}
+
+static void default_service(intercom_packet *packet, void *arg)
+{
+	qoriq_intercom_free_packet(packet);
+}
+
+static void process_free_lists(free_list *free_lists, uint32_t self)
+{
+	int i = 0;
+
+	for (i = 0; i < PACKET_SIZE_COUNT; ++i) {
+		free_list *list = &free_lists [i];
+
+		uint32_t msr = qoriq_spin_lock(&list->lock);
+		consumer *waiting_consumer = list->waiting_consumers [self].head;
+		list->waiting_consumers [self].head = NULL;
+		qoriq_spin_unlock(&list->lock, msr);
+
+		while (waiting_consumer != NULL) {
+			send_event(waiting_consumer->task, INTERCOM_EVENT_WAKE_UP);
+			waiting_consumer = waiting_consumer->next;
+		}
+	}
+}
+
+static void process_core_fifo(core_fifo *fifo, intercom_service *services, void **service_args)
+{
+	uint32_t msr = qoriq_spin_lock(&fifo->lock);
+	intercom_packet *packet = fifo->head;
+	fifo->head = NULL;
+	qoriq_spin_unlock(&fifo->lock, msr);
+
+	while (packet != NULL) {
+		intercom_packet *current = packet;
+		intercom_type type_index = current->type_index;
+		packet = current->glue.next;
+		(*services [type_index])(current, service_args [type_index]);
+	}
+}
+
+static void intercom_task(rtems_task_argument arg)
+{
+	uint32_t self = ppc_processor_id();
+	free_list *free_lists = &intercom->free_lists [0];
+	intercom_service *services = &intercom->services [self][0];
+	void **service_args = &intercom->service_args [self][0];
+	core_fifo *fifo = &intercom->core_fifos [self];
+
+	while (true) {
+		process_free_lists(free_lists, self);
+		process_core_fifo(fifo, services, service_args);
+		wait_for_event(INTERCOM_EVENT_IPI);
+	}
+}
+
+static intercom_packet *free_list_and_packet_init(
+	free_list *list,
+	size_t count,
+	intercom_packet *current,
+	intercom_size size_index,
+	size_t size
+)
+{
+	intercom_packet *last = current;
+	size_t inc = 1 + size / sizeof(*current);
+	size_t i = 0;
+
+	assert(count > 0);
+	assert(size % sizeof(*current) == 0);
+
+	list->size = size;
+	list->head = current;
+	for (i = 0; i < count; ++i) {
+		intercom_packet *next = current + inc;
+		current->glue.next = next;
+		current->size_index = size_index;
+		last = current;
+		current = next;
+	}
+	last->glue.next = NULL;
+
+	return current;
+}
+
+static void basic_init(void)
+{
+	char *begin = (char *) QORIQ_INTERCOM_AREA_BEGIN;
+	size_t size = QORIQ_INTERCOM_AREA_SIZE;
+	int i = 0;
+
+	memset(begin, 0, size);
+
+	assert(size % packet_sizes [PACKET_SIZE_COUNT - 1] == 0);
+
+	/* Calculate data area sizes */
+	size_t data_sizes [PACKET_SIZE_COUNT];
+	data_sizes [PACKET_SIZE_COUNT - 1] = size / 2;
+	for (i = PACKET_SIZE_COUNT - 2; i > 0; --i) {
+		data_sizes [i] = data_sizes [i + 1] / 2;
+	}
+	data_sizes [i] = data_sizes [i + 1];
+
+	/* Calculate packet counts */
+	size_t packet_counts [PACKET_SIZE_COUNT];
+	size_t count = 0;
+	for (i = 1; i < PACKET_SIZE_COUNT; ++i) {
+		packet_counts [i] = data_sizes [i] / packet_sizes [i];
+		count += packet_counts [i];
+	}
+	packet_counts [0] = (data_sizes [0] - sizeof(control) - count * sizeof(intercom_packet))
+		/ (sizeof(intercom_packet) + packet_sizes [0]);
+
+	/* Initialize free lists and packets */
+	intercom_packet *packet = (intercom_packet *) (begin + sizeof(control));
+	for (i = 0; i < PACKET_SIZE_COUNT; ++i) {
+		packet = free_list_and_packet_init(
+			&intercom->free_lists [i],
+			packet_counts [i],
+			packet,
+			i,
+			packet_sizes [i]
+		);
+	}
+
+	rtems_cache_flush_multiple_data_lines(begin, size);
+	ppc_synchronize_data();
+}
+
+static void services_init(uint32_t self)
+{
+	int i = 0;
+
+	for (i = 0; i < INTERCOM_SERVICE_COUNT; ++i) {
+		if (intercom->services [self][i] == NULL) {
+			intercom->services [self][i] = default_service;
+		}
+	}
+}
+
+void qoriq_intercom_init(void)
+{
+	rtems_status_code sc = RTEMS_SUCCESSFUL;
+	rtems_id task = RTEMS_ID_NONE;
+	uint32_t self = ppc_processor_id();
+
+	sc = rtems_task_create(
+		rtems_build_name('I', 'C', 'O', 'M'),
+		10,
+		0,
+		RTEMS_DEFAULT_MODES,
+		RTEMS_DEFAULT_ATTRIBUTES,
+		&task
+	);
+	assert(sc == RTEMS_SUCCESSFUL);
+
+	sc = qoriq_pic_set_priority(
+		QORIQ_IRQ_IPI_0,
+		QORIQ_PIC_PRIORITY_LOWEST,
+		NULL
+	);
+	assert(sc == RTEMS_SUCCESSFUL);
+
+	sc = rtems_interrupt_handler_install(
+		QORIQ_IRQ_IPI_0,
+		"INTERCOM",
+		RTEMS_INTERRUPT_UNIQUE,
+		intercom_handler,
+		(void *) (uintptr_t) task
+	);
+	assert(sc == RTEMS_SUCCESSFUL);
+
+	if (self == 0) {
+		basic_init();
+	}
+
+	services_init(self);
+
+	sc = rtems_task_start(task, intercom_task, 0);
+	assert(sc == RTEMS_SUCCESSFUL);
+}
+
+void qoriq_intercom_start(void)
+{
+	uint32_t self = ppc_processor_id();
+	uint32_t ready = 0;
+
+	while (ready != ALL_CORES) {
+		uint32_t msr = qoriq_spin_lock(&intercom->ready_lock);
+		ready = intercom->ready;
+		intercom->ready = ready | ONE_CORE(self);
+		qoriq_spin_unlock(&intercom->ready_lock, msr);
+	}
+}
+
+static intercom_packet *allocate(intercom_type type, free_list *list)
+{
+	uint32_t self = ppc_processor_id();
+	intercom_packet *packet = NULL;
+	consumer poor = {
+		.task = rtems_task_self()
+	};
+
+	while (packet == NULL) {
+		uint32_t msr = qoriq_spin_lock(&list->lock);
+		packet = list->head;
+		if (packet != NULL) {
+			list->head = packet->glue.next;
+		} else {
+			consumer *first = list->waiting_consumers [self].head;
+			list->waiting_consumers [self].head = &poor;
+			poor.next = first;
+			if (first == NULL) {
+				list->cores_to_notify |= ONE_CORE(self);
+			}
+		}
+		qoriq_spin_unlock(&list->lock, msr);
+
+		if (packet == NULL) {
+			wait_for_event(INTERCOM_EVENT_WAKE_UP);
+		}
+	}
+
+	packet->glue.next = NULL;
+	packet->type_index = type;
+	packet->flags = 0;
+	packet->size = list->size;
+
+	return packet;
+}
+
+intercom_packet *qoriq_intercom_allocate_packet(intercom_type type, intercom_size size)
+{
+	assert((unsigned) type < INTERCOM_SERVICE_COUNT);
+	assert((unsigned) size < PACKET_SIZE_COUNT);
+
+	return allocate(type, &intercom->free_lists [size]);
+}
+
+void qoriq_intercom_send_packets(int destination_core, intercom_packet *first, intercom_packet *last)
+{
+	assert(destination_core >= 0);
+	assert(destination_core < INTERCOM_CORE_COUNT);
+
+	core_fifo *fifo = &intercom->core_fifos [destination_core];
+
+	uint32_t msr = qoriq_spin_lock(&fifo->lock);
+	last->glue.next = NULL;
+	if (fifo->head != NULL) {
+		fifo->tail->glue.next = first;
+	} else {
+		fifo->head = first;
+		notify_core_by_index(destination_core);
+	}
+	fifo->tail = last;
+	qoriq_spin_unlock(&fifo->lock, msr);
+}
+
+void qoriq_intercom_broadcast_packets(intercom_packet *first, intercom_packet *last)
+{
+	int i = 0;
+
+	for (i = 1; i < INTERCOM_CORE_COUNT; ++i) {
+		intercom_packet *clone_first = NULL;
+		intercom_packet *clone_last = NULL;
+
+		intercom_packet *current = first;
+		while (current != NULL) {
+			intercom_packet *clone = qoriq_intercom_clone_packet(current);
+			if (clone_first == NULL) {
+				clone_first = clone;
+			}
+			if (clone_last != NULL) {
+				clone_last->glue.next = clone;
+			}
+			clone_last = clone;
+			current = current->glue.next;
+		}
+
+		qoriq_intercom_send_packets(i, clone_first, clone_last);
+	}
+
+	qoriq_intercom_send_packets(0, first, last);
+}
+
+void qoriq_intercom_send(int destination_core, intercom_type type, intercom_size size, const void *buf, size_t n)
+{
+	assert((unsigned) size < PACKET_SIZE_COUNT);
+
+	size_t remaining = n;
+	size_t packet_size = packet_sizes [size];
+	const char *src = buf;
+	intercom_packet *first = NULL;
+	intercom_packet *last = NULL;
+
+	do {
+		intercom_packet *packet = qoriq_intercom_allocate_packet(
+			type,
+			size
+		);
+		if (first == NULL) {
+			first = packet;
+		}
+		if (last != NULL) {
+			last->glue.next = packet;
+		}
+		last = packet;
+		size_t current_size = remaining < packet_size ? remaining : packet_size;
+		remaining -= current_size;
+		packet->size = current_size;
+		const char *current = src;
+		src += current_size;
+		memcpy(packet->data, current, current_size);
+	} while (remaining > 0);
+
+	qoriq_intercom_send_packets(destination_core, first, last);
+}
+
+void qoriq_intercom_service_install(intercom_type type, intercom_service service, void *arg)
+{
+	assert((unsigned) type < INTERCOM_SERVICE_COUNT);
+
+	uint32_t self = ppc_processor_id();
+	intercom->service_args [self][type] = arg;
+	ppc_enforce_in_order_execution_of_io();
+	intercom->services [self][type] = service;
+}
+
+void qoriq_intercom_service_remove(intercom_type type)
+{
+	assert((unsigned) type < INTERCOM_SERVICE_COUNT);
+
+	uint32_t self = ppc_processor_id();
+	intercom->services [self][type] = default_service;
+	ppc_enforce_in_order_execution_of_io();
+	intercom->service_args [self][type] = NULL;
+}
+
+intercom_packet *qoriq_intercom_clone_packet(const intercom_packet *packet)
+{
+	intercom_packet *clone = qoriq_intercom_allocate_packet(
+		packet->type_index,
+		packet->size_index
+	);
+
+	clone->size = packet->size;
+	memcpy(clone->data, packet->data, clone->size);
+
+	return clone;
+}
+
+#endif /* !QORIQ_IS_HYPERVISOR_GUEST */
Index: bsps/powerpc/qoriq/mpci/lock.S
===================================================================
--- bsps/powerpc/qoriq/mpci/lock.S	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/powerpc/qoriq/mpci/lock.S	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,52 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQInterCom
+ *
+ * @brief qoriq_spin_lock() and qoriq_spin_unlock() implementation.
+ */
+
+/*
+ * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems@embedded-brains.de>
+ *
+ * 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 <libcpu/powerpc-utility.h>
+
+	.global qoriq_spin_lock
+	.global qoriq_spin_unlock
+
+qoriq_spin_lock:
+	li	r0, 1
+	mfmsr	r4
+	GET_INTERRUPT_MASK r5
+	andc	r5, r4, r5
+	b	2f
+1:
+	mtmsr	r4
+2:
+	lwarx	r6, r0, r3
+	cmpwi	r6, 0
+	bne	2b
+	mtmsr	r5
+	stwcx.	r0, r0, r3
+	bne	1b
+	isync
+	mr	r3, r4
+	blr
+
+qoriq_spin_unlock:
+	msync
+	li	r0, 0
+	stw	r0, 0(r3)
+	mtmsr	r4
+	blr
Index: bsps/sparc/leon3/mpci/README
===================================================================
--- bsps/sparc/leon3/mpci/README	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/sparc/leon3/mpci/README	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,4 @@
+This should describe how to use SHM in a multiprocessor LEON3
+configuration.
+
+Especially useful would be how to test this on tsim-leon3.
Index: bsps/sparc/leon3/mpci/addrconv.c
===================================================================
--- bsps/sparc/leon3/mpci/addrconv.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/sparc/leon3/mpci/addrconv.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,28 @@
+/*  Shm_Convert_address
+ *
+ *  No address range conversion is required.
+ *
+ *  Input parameters:
+ *    address - address to convert
+ *
+ *  Output parameters:
+ *    returns - converted address
+ *
+ *  COPYRIGHT (c) 1989-1999.
+ *  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 <bsp.h>
+#include <shm_driver.h>
+
+void *Shm_Convert_address(
+  void *address
+)
+{
+  return ( address );
+}
Index: bsps/sparc/leon3/mpci/getcfg.c
===================================================================
--- bsps/sparc/leon3/mpci/getcfg.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/sparc/leon3/mpci/getcfg.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,76 @@
+/**
+ *  @file
+ *
+ *  LEON3 Shared Memory Driver Support - Configuration
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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 <bsp.h>
+#include <shm_driver.h>
+
+/* Let user override this configuration by declaring this a weak variable */
+shm_config_table BSP_shm_cfgtbl __attribute__((weak)) =
+{
+  (vol_u32 *)0x40000000,    /* USER OVERRIDABLE */
+  0x00001000,               /* USER OVERRIDABLE */
+  SHM_BIG,
+  NULL_CONVERT,
+  INTR_MODE,
+  Shm_Cause_interrupt,
+  {
+    NULL,
+    0,                      /* USER OVERRIDABLE - Uses default MP-IRQ if 0 */
+    4,
+  },
+};
+
+void Shm_Get_configuration(
+  uint32_t   localnode,
+  shm_config_table **shmcfg
+)
+{
+  int i;
+  unsigned int tmp;
+  rtems_multiprocessing_table *mptable;
+
+  BSP_shm_cfgtbl.format       = SHM_BIG;
+
+  /*
+   *  Override cause_intr or shm_isr if your target has
+   *  special requirements.
+   */
+
+  BSP_shm_cfgtbl.cause_intr   = Shm_Cause_interrupt;
+
+#ifdef NEUTRAL_BIG
+  BSP_shm_cfgtbl.convert      = NULL_CONVERT;
+#else
+  BSP_shm_cfgtbl.convert      = CPU_swap_u32;
+#endif
+
+  BSP_shm_cfgtbl.poll_intr    = INTR_MODE;
+  BSP_shm_cfgtbl.Intr.address =
+     (vol_u32 *) &(LEON3_IrqCtrl_Regs->force[LEON3_Cpu_Index]);
+  if (BSP_shm_cfgtbl.Intr.value == 0)
+    BSP_shm_cfgtbl.Intr.value = 1 << LEON3_mp_irq; /* Use default MP-IRQ */
+  BSP_shm_cfgtbl.Intr.length  = 4;
+
+  if (LEON3_Cpu_Index == 0) {
+    tmp = 0;
+    mptable = rtems_configuration_get_user_multiprocessing_table();
+    for (i = 1; i < mptable->maximum_nodes; i++)
+      tmp |= (1 << i);
+    LEON3_IrqCtrl_Regs->mpstat = tmp;
+  }
+
+  *shmcfg = &BSP_shm_cfgtbl;
+}
Index: bsps/sparc/leon3/mpci/lock.c
===================================================================
--- bsps/sparc/leon3/mpci/lock.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/sparc/leon3/mpci/lock.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,90 @@
+/**
+ *  @file
+ *
+ *  LEON3 Shared Memory Lock Routines
+ *
+ *  This shared memory locked queue support routine need to be
+ *  able to lock the specified locked queue.  Interrupts are
+ *  disabled while the queue is locked to prevent preemption
+ *  and deadlock when two tasks poll for the same lock.
+ *  previous level.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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 <bsp.h>
+#include <shm_driver.h>
+
+
+/*
+ *  Initialize the lock for the specified locked queue.
+ */
+void Shm_Initialize_lock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  lq_cb->lock = LQ_UNLOCKED;
+}
+
+/*
+ *  This shared memory locked queue support routine locks the
+ *  specified locked queue.  It disables interrupts to prevent
+ *  a deadlock condition.
+ */
+extern unsigned int LEON3_Atomic_Swap(uint32_t value, uint32_t *address);
+
+__asm__ (
+    ".text\n"
+    ".align 4\n"
+    "LEON3_Atomic_Swap:\n"
+    "  retl\n"
+    "  swapa [%o1] 1, %o0\n"
+);
+
+
+
+void Shm_Lock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  uint32_t isr_level;
+  uint32_t *lockptr = (uint32_t *) &lq_cb->lock;
+  uint32_t lock_value;
+
+  lock_value = SHM_LOCK_VALUE;
+  rtems_interrupt_disable( isr_level );
+
+    Shm_isrstat = isr_level;
+    while ( lock_value ) {
+      lock_value = LEON3_Atomic_Swap(lock_value, lockptr);
+      /*
+       *  If not available, then may want to delay to reduce load on lock.
+       */
+   }
+}
+
+/*
+ *  Shm_Unlock
+ *
+ *  Unlock the lock for the specified locked queue.
+ */
+
+void Shm_Unlock(
+  Shm_Locked_queue_Control *lq_cb
+)
+{
+  uint32_t isr_level;
+
+  lq_cb->lock = SHM_UNLOCK_VALUE;
+  isr_level = Shm_isrstat;
+  rtems_interrupt_enable( isr_level );
+}
+
Index: bsps/sparc/leon3/mpci/mpisr.c
===================================================================
--- bsps/sparc/leon3/mpci/mpisr.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
+++ bsps/sparc/leon3/mpci/mpisr.c	(revision 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4)
@@ -0,0 +1,50 @@
+/**
+ *  @file
+ *
+ *  LEON3 Shared Memory Driver Interrupt Support
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  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 <bsp.h>
+#include <shm_driver.h>
+
+#if 0
+void Shm_isr(void)
+{
+  /*
+   *  If this routine has to do anything other than the mpisr.c
+   *  found in the generic driver, then copy the contents of the generic
+   *  mpisr.c and augment it to satisfy this particular board.  Typically,
+   *  you need to have a board specific mpisr.c when the interrupt
+   *  must be cleared.
+   *
+   *  If the generic mpisr.c satisifies your requirements, then
+   *  remove this routine from your target's shmsupp/mpisr.c file.
+   *  Then simply install the generic Shm_isr in the Shm_setvec
+   *  routine below.
+   */
+}
+#endif
+
+/*
+ *  This driver routine sets the SHM interrupt vector to point to the
+ *  driver's SHM interrupt service routine.
+ */
+void Shm_setvec( void )
+{
+  /*
+   * Interrupt driven mode is not currently supported.
+   * This is thought to be the interrupt to use.
+   */
+  LEON_Unmask_interrupt(LEON3_mp_irq);
+  set_vector((rtems_isr_entry) Shm_isr, LEON_TRAP_TYPE(LEON3_mp_irq), 1);
+}
