From 1efa1c8389604dcf303b9acfa26c0ae60db9d9b4 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 20 Apr 2018 13:38:33 +0200 Subject: bsps: Move MPCI support to bsps This patch is a part of the BSP source reorganization. Update #3285. --- bsps/m68k/mvme147s/mpci/addrconv.c | 33 ++ bsps/m68k/mvme147s/mpci/getcfg.c | 84 ++++ bsps/m68k/mvme147s/mpci/lock.c | 71 +++ bsps/m68k/mvme147s/mpci/mpisr.c | 41 ++ bsps/no_cpu/no_bsp/mpci/addrconv.c | 28 ++ bsps/no_cpu/no_bsp/mpci/getcfg.c | 73 +++ bsps/no_cpu/no_bsp/mpci/lock.c | 84 ++++ bsps/no_cpu/no_bsp/mpci/mpisr.c | 44 ++ bsps/powerpc/psim/mpci/README | 3 + bsps/powerpc/psim/mpci/addrconv.c | 28 ++ bsps/powerpc/psim/mpci/getcfg.c | 63 +++ bsps/powerpc/psim/mpci/lock.c | 64 +++ bsps/powerpc/psim/mpci/mpisr.c | 30 ++ bsps/powerpc/qoriq/mpci/intercom-mpci.c | 124 +++++ bsps/powerpc/qoriq/mpci/intercom.c | 498 +++++++++++++++++++++ bsps/powerpc/qoriq/mpci/lock.S | 52 +++ bsps/sparc/leon3/mpci/README | 4 + bsps/sparc/leon3/mpci/addrconv.c | 28 ++ bsps/sparc/leon3/mpci/getcfg.c | 76 ++++ bsps/sparc/leon3/mpci/lock.c | 90 ++++ bsps/sparc/leon3/mpci/mpisr.c | 50 +++ c/src/aclocal/check-multiprocessing.m4 | 2 +- c/src/lib/libbsp/m68k/mvme147s/Makefile.am | 8 +- c/src/lib/libbsp/m68k/mvme147s/shmsupp/addrconv.c | 33 -- c/src/lib/libbsp/m68k/mvme147s/shmsupp/getcfg.c | 84 ---- c/src/lib/libbsp/m68k/mvme147s/shmsupp/lock.c | 71 --- c/src/lib/libbsp/m68k/mvme147s/shmsupp/mpisr.c | 41 -- c/src/lib/libbsp/no_cpu/no_bsp/Makefile.am | 8 +- c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/addrconv.c | 28 -- c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/getcfg.c | 73 --- c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/lock.c | 84 ---- c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/mpisr.c | 44 -- c/src/lib/libbsp/powerpc/psim/Makefile.am | 8 +- c/src/lib/libbsp/powerpc/psim/shmsupp/README | 3 - c/src/lib/libbsp/powerpc/psim/shmsupp/addrconv.c | 28 -- c/src/lib/libbsp/powerpc/psim/shmsupp/getcfg.c | 63 --- c/src/lib/libbsp/powerpc/psim/shmsupp/lock.c | 64 --- c/src/lib/libbsp/powerpc/psim/shmsupp/mpisr.c | 30 -- c/src/lib/libbsp/powerpc/qoriq/Makefile.am | 6 +- .../libbsp/powerpc/qoriq/shmsupp/intercom-mpci.c | 124 ----- c/src/lib/libbsp/powerpc/qoriq/shmsupp/intercom.c | 498 --------------------- c/src/lib/libbsp/powerpc/qoriq/shmsupp/lock.S | 52 --- c/src/lib/libbsp/sparc/leon3/Makefile.am | 8 +- c/src/lib/libbsp/sparc/leon3/shmsupp/README | 4 - c/src/lib/libbsp/sparc/leon3/shmsupp/addrconv.c | 28 -- c/src/lib/libbsp/sparc/leon3/shmsupp/getcfg.c | 76 ---- c/src/lib/libbsp/sparc/leon3/shmsupp/lock.c | 90 ---- c/src/lib/libbsp/sparc/leon3/shmsupp/mpisr.c | 50 --- 48 files changed, 1588 insertions(+), 1588 deletions(-) create mode 100644 bsps/m68k/mvme147s/mpci/addrconv.c create mode 100644 bsps/m68k/mvme147s/mpci/getcfg.c create mode 100644 bsps/m68k/mvme147s/mpci/lock.c create mode 100644 bsps/m68k/mvme147s/mpci/mpisr.c create mode 100644 bsps/no_cpu/no_bsp/mpci/addrconv.c create mode 100644 bsps/no_cpu/no_bsp/mpci/getcfg.c create mode 100644 bsps/no_cpu/no_bsp/mpci/lock.c create mode 100644 bsps/no_cpu/no_bsp/mpci/mpisr.c create mode 100644 bsps/powerpc/psim/mpci/README create mode 100644 bsps/powerpc/psim/mpci/addrconv.c create mode 100644 bsps/powerpc/psim/mpci/getcfg.c create mode 100644 bsps/powerpc/psim/mpci/lock.c create mode 100644 bsps/powerpc/psim/mpci/mpisr.c create mode 100644 bsps/powerpc/qoriq/mpci/intercom-mpci.c create mode 100644 bsps/powerpc/qoriq/mpci/intercom.c create mode 100644 bsps/powerpc/qoriq/mpci/lock.S create mode 100644 bsps/sparc/leon3/mpci/README create mode 100644 bsps/sparc/leon3/mpci/addrconv.c create mode 100644 bsps/sparc/leon3/mpci/getcfg.c create mode 100644 bsps/sparc/leon3/mpci/lock.c create mode 100644 bsps/sparc/leon3/mpci/mpisr.c delete mode 100644 c/src/lib/libbsp/m68k/mvme147s/shmsupp/addrconv.c delete mode 100644 c/src/lib/libbsp/m68k/mvme147s/shmsupp/getcfg.c delete mode 100644 c/src/lib/libbsp/m68k/mvme147s/shmsupp/lock.c delete mode 100644 c/src/lib/libbsp/m68k/mvme147s/shmsupp/mpisr.c delete mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/addrconv.c delete mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/getcfg.c delete mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/lock.c delete mode 100644 c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/mpisr.c delete mode 100644 c/src/lib/libbsp/powerpc/psim/shmsupp/README delete mode 100644 c/src/lib/libbsp/powerpc/psim/shmsupp/addrconv.c delete mode 100644 c/src/lib/libbsp/powerpc/psim/shmsupp/getcfg.c delete mode 100644 c/src/lib/libbsp/powerpc/psim/shmsupp/lock.c delete mode 100644 c/src/lib/libbsp/powerpc/psim/shmsupp/mpisr.c delete mode 100644 c/src/lib/libbsp/powerpc/qoriq/shmsupp/intercom-mpci.c delete mode 100644 c/src/lib/libbsp/powerpc/qoriq/shmsupp/intercom.c delete mode 100644 c/src/lib/libbsp/powerpc/qoriq/shmsupp/lock.S delete mode 100644 c/src/lib/libbsp/sparc/leon3/shmsupp/README delete mode 100644 c/src/lib/libbsp/sparc/leon3/shmsupp/addrconv.c delete mode 100644 c/src/lib/libbsp/sparc/leon3/shmsupp/getcfg.c delete mode 100644 c/src/lib/libbsp/sparc/leon3/shmsupp/lock.c delete mode 100644 c/src/lib/libbsp/sparc/leon3/shmsupp/mpisr.c diff --git a/bsps/m68k/mvme147s/mpci/addrconv.c b/bsps/m68k/mvme147s/mpci/addrconv.c new file mode 100644 index 0000000000..0ed0fdbed1 --- /dev/null +++ b/bsps/m68k/mvme147s/mpci/addrconv.c @@ -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 +#include +#include + +void *Shm_Convert_address( + void *address +) +{ + return ( address ); +} diff --git a/bsps/m68k/mvme147s/mpci/getcfg.c b/bsps/m68k/mvme147s/mpci/getcfg.c new file mode 100644 index 0000000000..c549a9fcea --- /dev/null +++ b/bsps/m68k/mvme147s/mpci/getcfg.c @@ -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 +#include +#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; + +} diff --git a/bsps/m68k/mvme147s/mpci/lock.c b/bsps/m68k/mvme147s/mpci/lock.c new file mode 100644 index 0000000000..129de01fd0 --- /dev/null +++ b/bsps/m68k/mvme147s/mpci/lock.c @@ -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 +#include +#include + +/* + * 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 ); +} diff --git a/bsps/m68k/mvme147s/mpci/mpisr.c b/bsps/m68k/mvme147s/mpci/mpisr.c new file mode 100644 index 0000000000..0669538e1b --- /dev/null +++ b/bsps/m68k/mvme147s/mpci/mpisr.c @@ -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 +#include +#include + +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 ); +} diff --git a/bsps/no_cpu/no_bsp/mpci/addrconv.c b/bsps/no_cpu/no_bsp/mpci/addrconv.c new file mode 100644 index 0000000000..2656bc1ccf --- /dev/null +++ b/bsps/no_cpu/no_bsp/mpci/addrconv.c @@ -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 +#include +#include + +void *Shm_Convert_address( + void *address +) +{ + return ( address ); +} diff --git a/bsps/no_cpu/no_bsp/mpci/getcfg.c b/bsps/no_cpu/no_bsp/mpci/getcfg.c new file mode 100644 index 0000000000..2179838b4b --- /dev/null +++ b/bsps/no_cpu/no_bsp/mpci/getcfg.c @@ -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 +#include +#include + +/* + * 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; +} diff --git a/bsps/no_cpu/no_bsp/mpci/lock.c b/bsps/no_cpu/no_bsp/mpci/lock.c new file mode 100644 index 0000000000..5b53df8d38 --- /dev/null +++ b/bsps/no_cpu/no_bsp/mpci/lock.c @@ -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 +#include +#include + +/* + * 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 ); +} diff --git a/bsps/no_cpu/no_bsp/mpci/mpisr.c b/bsps/no_cpu/no_bsp/mpci/mpisr.c new file mode 100644 index 0000000000..19939ec81c --- /dev/null +++ b/bsps/no_cpu/no_bsp/mpci/mpisr.c @@ -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 +#include +#include + +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!!! */ +} diff --git a/bsps/powerpc/psim/mpci/README b/bsps/powerpc/psim/mpci/README new file mode 100644 index 0000000000..ba2d67752f --- /dev/null +++ b/bsps/powerpc/psim/mpci/README @@ -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. diff --git a/bsps/powerpc/psim/mpci/addrconv.c b/bsps/powerpc/psim/mpci/addrconv.c new file mode 100644 index 0000000000..2656bc1ccf --- /dev/null +++ b/bsps/powerpc/psim/mpci/addrconv.c @@ -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 +#include +#include + +void *Shm_Convert_address( + void *address +) +{ + return ( address ); +} diff --git a/bsps/powerpc/psim/mpci/getcfg.c b/bsps/powerpc/psim/mpci/getcfg.c new file mode 100644 index 0000000000..6be42f8b9c --- /dev/null +++ b/bsps/powerpc/psim/mpci/getcfg.c @@ -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 +#include +#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; + +} diff --git a/bsps/powerpc/psim/mpci/lock.c b/bsps/powerpc/psim/mpci/lock.c new file mode 100644 index 0000000000..6c0907e30f --- /dev/null +++ b/bsps/powerpc/psim/mpci/lock.c @@ -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 +#include +#include +#include + +/* + * 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 ); +} diff --git a/bsps/powerpc/psim/mpci/mpisr.c b/bsps/powerpc/psim/mpci/mpisr.c new file mode 100644 index 0000000000..8987a5a272 --- /dev/null +++ b/bsps/powerpc/psim/mpci/mpisr.c @@ -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 +#include +#include + +/* 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 */ +} diff --git a/bsps/powerpc/qoriq/mpci/intercom-mpci.c b/bsps/powerpc/qoriq/mpci/intercom-mpci.c new file mode 100644 index 0000000000..2cc45dd079 --- /dev/null +++ b/bsps/powerpc/qoriq/mpci/intercom-mpci.c @@ -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 + * + * + * 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 + +#include + +#include + +#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 */ diff --git a/bsps/powerpc/qoriq/mpci/intercom.c b/bsps/powerpc/qoriq/mpci/intercom.c new file mode 100644 index 0000000000..e7e0d5650f --- /dev/null +++ b/bsps/powerpc/qoriq/mpci/intercom.c @@ -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 + * + * + * 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 +#include + +#include + +#include + +#include +#include +#include +#include + +#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 */ diff --git a/bsps/powerpc/qoriq/mpci/lock.S b/bsps/powerpc/qoriq/mpci/lock.S new file mode 100644 index 0000000000..c6e72a7533 --- /dev/null +++ b/bsps/powerpc/qoriq/mpci/lock.S @@ -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 + * + * + * 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 + + .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 diff --git a/bsps/sparc/leon3/mpci/README b/bsps/sparc/leon3/mpci/README new file mode 100644 index 0000000000..9ad11538b7 --- /dev/null +++ b/bsps/sparc/leon3/mpci/README @@ -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. diff --git a/bsps/sparc/leon3/mpci/addrconv.c b/bsps/sparc/leon3/mpci/addrconv.c new file mode 100644 index 0000000000..2656bc1ccf --- /dev/null +++ b/bsps/sparc/leon3/mpci/addrconv.c @@ -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 +#include +#include + +void *Shm_Convert_address( + void *address +) +{ + return ( address ); +} diff --git a/bsps/sparc/leon3/mpci/getcfg.c b/bsps/sparc/leon3/mpci/getcfg.c new file mode 100644 index 0000000000..fc67cf8e3a --- /dev/null +++ b/bsps/sparc/leon3/mpci/getcfg.c @@ -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 +#include +#include + +/* 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; +} diff --git a/bsps/sparc/leon3/mpci/lock.c b/bsps/sparc/leon3/mpci/lock.c new file mode 100644 index 0000000000..5b118f24b6 --- /dev/null +++ b/bsps/sparc/leon3/mpci/lock.c @@ -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 +#include +#include + + +/* + * 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 ); +} + diff --git a/bsps/sparc/leon3/mpci/mpisr.c b/bsps/sparc/leon3/mpci/mpisr.c new file mode 100644 index 0000000000..cdf05293f1 --- /dev/null +++ b/bsps/sparc/leon3/mpci/mpisr.c @@ -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 +#include +#include + +#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); +} diff --git a/c/src/aclocal/check-multiprocessing.m4 b/c/src/aclocal/check-multiprocessing.m4 index 5959f345d1..ee2ea3a75c 100644 --- a/c/src/aclocal/check-multiprocessing.m4 +++ b/c/src/aclocal/check-multiprocessing.m4 @@ -22,7 +22,7 @@ AS_IF([test "$rtems_cv_want_multiprocessing" = "yes"], [ AC_CACHE_CHECK([whether BSP supports multiprocessing], [rtems_cv_HAS_MP],[ - if test -d "$srcdir/${RTEMS_TOPdir}/c/src/lib/libbsp/${RTEMS_CPU}/${RTEMS_BSP_FAMILY}/shmsupp"; then + if test -d "${RTEMS_SOURCE_ROOT}/bsps/${RTEMS_CPU}/${RTEMS_BSP_FAMILY}/mpci"; then rtems_cv_HAS_MP="yes" ; else rtems_cv_HAS_MP="no"; diff --git a/c/src/lib/libbsp/m68k/mvme147s/Makefile.am b/c/src/lib/libbsp/m68k/mvme147s/Makefile.am index 72ba5c5213..b709b9f6d6 100644 --- a/c/src/lib/libbsp/m68k/mvme147s/Makefile.am +++ b/c/src/lib/libbsp/m68k/mvme147s/Makefile.am @@ -39,10 +39,10 @@ librtemsbsp_a_SOURCES += ../mvme147/timer/timerisr.S if HAS_MP # shmsupp -librtemsbsp_a_SOURCES += shmsupp/addrconv.c -librtemsbsp_a_SOURCES += shmsupp/getcfg.c -librtemsbsp_a_SOURCES += shmsupp/lock.c -librtemsbsp_a_SOURCES += shmsupp/mpisr.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme147s/mpci/addrconv.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme147s/mpci/getcfg.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme147s/mpci/lock.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme147s/mpci/mpisr.c endif librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/cache/cache.c diff --git a/c/src/lib/libbsp/m68k/mvme147s/shmsupp/addrconv.c b/c/src/lib/libbsp/m68k/mvme147s/shmsupp/addrconv.c deleted file mode 100644 index 0ed0fdbed1..0000000000 --- a/c/src/lib/libbsp/m68k/mvme147s/shmsupp/addrconv.c +++ /dev/null @@ -1,33 +0,0 @@ -/* 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 -#include -#include - -void *Shm_Convert_address( - void *address -) -{ - return ( address ); -} diff --git a/c/src/lib/libbsp/m68k/mvme147s/shmsupp/getcfg.c b/c/src/lib/libbsp/m68k/mvme147s/shmsupp/getcfg.c deleted file mode 100644 index c549a9fcea..0000000000 --- a/c/src/lib/libbsp/m68k/mvme147s/shmsupp/getcfg.c +++ /dev/null @@ -1,84 +0,0 @@ -/* 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 -#include -#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; - -} diff --git a/c/src/lib/libbsp/m68k/mvme147s/shmsupp/lock.c b/c/src/lib/libbsp/m68k/mvme147s/shmsupp/lock.c deleted file mode 100644 index 129de01fd0..0000000000 --- a/c/src/lib/libbsp/m68k/mvme147s/shmsupp/lock.c +++ /dev/null @@ -1,71 +0,0 @@ -/* 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 -#include -#include - -/* - * 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 ); -} diff --git a/c/src/lib/libbsp/m68k/mvme147s/shmsupp/mpisr.c b/c/src/lib/libbsp/m68k/mvme147s/shmsupp/mpisr.c deleted file mode 100644 index 0669538e1b..0000000000 --- a/c/src/lib/libbsp/m68k/mvme147s/shmsupp/mpisr.c +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @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 -#include -#include - -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 ); -} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/Makefile.am b/c/src/lib/libbsp/no_cpu/no_bsp/Makefile.am index e0d7676fe6..e4c11f6f5a 100644 --- a/c/src/lib/libbsp/no_cpu/no_bsp/Makefile.am +++ b/c/src/lib/libbsp/no_cpu/no_bsp/Makefile.am @@ -28,10 +28,10 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/no_cpu/no_bsp/console/console.c librtemsbsp_a_SOURCES += ../../../../../../bsps/no_cpu/no_bsp/btimer/btimer.c librtemsbsp_a_SOURCES += ../../../../../../bsps/no_cpu/no_bsp/btimer/timerisr.c # shmsupp -librtemsbsp_a_SOURCES += shmsupp/addrconv.c -librtemsbsp_a_SOURCES += shmsupp/getcfg.c -librtemsbsp_a_SOURCES += shmsupp/lock.c -librtemsbsp_a_SOURCES += shmsupp/mpisr.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/no_cpu/no_bsp/mpci/addrconv.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/no_cpu/no_bsp/mpci/getcfg.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/no_cpu/no_bsp/mpci/lock.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/no_cpu/no_bsp/mpci/mpisr.c include $(top_srcdir)/../../../../automake/local.am diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/addrconv.c b/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/addrconv.c deleted file mode 100644 index 2656bc1ccf..0000000000 --- a/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/addrconv.c +++ /dev/null @@ -1,28 +0,0 @@ -/* 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 -#include -#include - -void *Shm_Convert_address( - void *address -) -{ - return ( address ); -} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/getcfg.c b/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/getcfg.c deleted file mode 100644 index 2179838b4b..0000000000 --- a/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/getcfg.c +++ /dev/null @@ -1,73 +0,0 @@ -/* 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 -#include -#include - -/* - * 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; -} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/lock.c b/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/lock.c deleted file mode 100644 index 5b53df8d38..0000000000 --- a/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/lock.c +++ /dev/null @@ -1,84 +0,0 @@ -/* 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 -#include -#include - -/* - * 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 ); -} diff --git a/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/mpisr.c b/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/mpisr.c deleted file mode 100644 index 19939ec81c..0000000000 --- a/c/src/lib/libbsp/no_cpu/no_bsp/shmsupp/mpisr.c +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @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 -#include -#include - -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!!! */ -} diff --git a/c/src/lib/libbsp/powerpc/psim/Makefile.am b/c/src/lib/libbsp/powerpc/psim/Makefile.am index ba26ca315d..c9560601cb 100644 --- a/c/src/lib/libbsp/powerpc/psim/Makefile.am +++ b/c/src/lib/libbsp/powerpc/psim/Makefile.am @@ -48,10 +48,10 @@ librtemsbsp_a_SOURCES += vectors/align_h.S if HAS_MP # shmdr -librtemsbsp_a_SOURCES += shmsupp/addrconv.c -librtemsbsp_a_SOURCES += shmsupp/getcfg.c -librtemsbsp_a_SOURCES += shmsupp/lock.c -librtemsbsp_a_SOURCES += shmsupp/mpisr.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/psim/mpci/addrconv.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/psim/mpci/getcfg.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/psim/mpci/lock.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/psim/mpci/mpisr.c endif if HAS_NETWORKING diff --git a/c/src/lib/libbsp/powerpc/psim/shmsupp/README b/c/src/lib/libbsp/powerpc/psim/shmsupp/README deleted file mode 100644 index ba2d67752f..0000000000 --- a/c/src/lib/libbsp/powerpc/psim/shmsupp/README +++ /dev/null @@ -1,3 +0,0 @@ -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. diff --git a/c/src/lib/libbsp/powerpc/psim/shmsupp/addrconv.c b/c/src/lib/libbsp/powerpc/psim/shmsupp/addrconv.c deleted file mode 100644 index 2656bc1ccf..0000000000 --- a/c/src/lib/libbsp/powerpc/psim/shmsupp/addrconv.c +++ /dev/null @@ -1,28 +0,0 @@ -/* 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 -#include -#include - -void *Shm_Convert_address( - void *address -) -{ - return ( address ); -} diff --git a/c/src/lib/libbsp/powerpc/psim/shmsupp/getcfg.c b/c/src/lib/libbsp/powerpc/psim/shmsupp/getcfg.c deleted file mode 100644 index 6be42f8b9c..0000000000 --- a/c/src/lib/libbsp/powerpc/psim/shmsupp/getcfg.c +++ /dev/null @@ -1,63 +0,0 @@ -/* 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 -#include -#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; - -} diff --git a/c/src/lib/libbsp/powerpc/psim/shmsupp/lock.c b/c/src/lib/libbsp/powerpc/psim/shmsupp/lock.c deleted file mode 100644 index 6c0907e30f..0000000000 --- a/c/src/lib/libbsp/powerpc/psim/shmsupp/lock.c +++ /dev/null @@ -1,64 +0,0 @@ -/* 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 -#include -#include -#include - -/* - * 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 ); -} diff --git a/c/src/lib/libbsp/powerpc/psim/shmsupp/mpisr.c b/c/src/lib/libbsp/powerpc/psim/shmsupp/mpisr.c deleted file mode 100644 index 8987a5a272..0000000000 --- a/c/src/lib/libbsp/powerpc/psim/shmsupp/mpisr.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 -#include -#include - -/* 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 */ -} diff --git a/c/src/lib/libbsp/powerpc/qoriq/Makefile.am b/c/src/lib/libbsp/powerpc/qoriq/Makefile.am index d64191285f..6f6972ca2b 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/Makefile.am +++ b/c/src/lib/libbsp/powerpc/qoriq/Makefile.am @@ -76,9 +76,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/dev/rtc/rtc-support.c librtemsbsp_a_SOURCES += rtc/rtc-config.c # MPCI -librtemsbsp_a_SOURCES += shmsupp/lock.S -librtemsbsp_a_SOURCES += shmsupp/intercom.c -librtemsbsp_a_SOURCES += shmsupp/intercom-mpci.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/qoriq/mpci/lock.S +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/qoriq/mpci/intercom.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/qoriq/mpci/intercom-mpci.c librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/cache/cache.c librtemsbsp_a_SOURCES += ../../../../../../bsps/powerpc/shared/mmu/e500-mmu.c diff --git a/c/src/lib/libbsp/powerpc/qoriq/shmsupp/intercom-mpci.c b/c/src/lib/libbsp/powerpc/qoriq/shmsupp/intercom-mpci.c deleted file mode 100644 index 2cc45dd079..0000000000 --- a/c/src/lib/libbsp/powerpc/qoriq/shmsupp/intercom-mpci.c +++ /dev/null @@ -1,124 +0,0 @@ -/** - * @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 - * - * - * 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 - -#include - -#include - -#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 */ diff --git a/c/src/lib/libbsp/powerpc/qoriq/shmsupp/intercom.c b/c/src/lib/libbsp/powerpc/qoriq/shmsupp/intercom.c deleted file mode 100644 index e7e0d5650f..0000000000 --- a/c/src/lib/libbsp/powerpc/qoriq/shmsupp/intercom.c +++ /dev/null @@ -1,498 +0,0 @@ -/** - * @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 - * - * - * 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 -#include - -#include - -#include - -#include -#include -#include -#include - -#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 */ diff --git a/c/src/lib/libbsp/powerpc/qoriq/shmsupp/lock.S b/c/src/lib/libbsp/powerpc/qoriq/shmsupp/lock.S deleted file mode 100644 index c6e72a7533..0000000000 --- a/c/src/lib/libbsp/powerpc/qoriq/shmsupp/lock.S +++ /dev/null @@ -1,52 +0,0 @@ -/** - * @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 - * - * - * 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 - - .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 diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am index cd5d1dfa46..c64bec2458 100644 --- a/c/src/lib/libbsp/sparc/leon3/Makefile.am +++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am @@ -186,10 +186,10 @@ endif if HAS_MP # shmsupp -librtemsbsp_a_SOURCES += shmsupp/addrconv.c -librtemsbsp_a_SOURCES += shmsupp/getcfg.c -librtemsbsp_a_SOURCES += shmsupp/lock.c -librtemsbsp_a_SOURCES += shmsupp/mpisr.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/mpci/addrconv.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/mpci/getcfg.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/mpci/lock.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/sparc/leon3/mpci/mpisr.c endif diff --git a/c/src/lib/libbsp/sparc/leon3/shmsupp/README b/c/src/lib/libbsp/sparc/leon3/shmsupp/README deleted file mode 100644 index 9ad11538b7..0000000000 --- a/c/src/lib/libbsp/sparc/leon3/shmsupp/README +++ /dev/null @@ -1,4 +0,0 @@ -This should describe how to use SHM in a multiprocessor LEON3 -configuration. - -Especially useful would be how to test this on tsim-leon3. diff --git a/c/src/lib/libbsp/sparc/leon3/shmsupp/addrconv.c b/c/src/lib/libbsp/sparc/leon3/shmsupp/addrconv.c deleted file mode 100644 index 2656bc1ccf..0000000000 --- a/c/src/lib/libbsp/sparc/leon3/shmsupp/addrconv.c +++ /dev/null @@ -1,28 +0,0 @@ -/* 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 -#include -#include - -void *Shm_Convert_address( - void *address -) -{ - return ( address ); -} diff --git a/c/src/lib/libbsp/sparc/leon3/shmsupp/getcfg.c b/c/src/lib/libbsp/sparc/leon3/shmsupp/getcfg.c deleted file mode 100644 index fc67cf8e3a..0000000000 --- a/c/src/lib/libbsp/sparc/leon3/shmsupp/getcfg.c +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @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 -#include -#include - -/* 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; -} diff --git a/c/src/lib/libbsp/sparc/leon3/shmsupp/lock.c b/c/src/lib/libbsp/sparc/leon3/shmsupp/lock.c deleted file mode 100644 index 5b118f24b6..0000000000 --- a/c/src/lib/libbsp/sparc/leon3/shmsupp/lock.c +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @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 -#include -#include - - -/* - * 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 ); -} - diff --git a/c/src/lib/libbsp/sparc/leon3/shmsupp/mpisr.c b/c/src/lib/libbsp/sparc/leon3/shmsupp/mpisr.c deleted file mode 100644 index cdf05293f1..0000000000 --- a/c/src/lib/libbsp/sparc/leon3/shmsupp/mpisr.c +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @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 -#include -#include - -#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); -} -- cgit v1.2.3