summaryrefslogtreecommitdiffstats
path: root/c/src/libchip
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1995-05-11 17:39:37 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1995-05-11 17:39:37 +0000
commitac7d5ef06a6d6e8d84abbd1f0b82162725f98326 (patch)
tree9304cf759a73f2a1c6fd3191948f00e870af3787 /c/src/libchip
downloadrtems-ac7d5ef06a6d6e8d84abbd1f0b82162725f98326.tar.bz2
Initial revision
Diffstat (limited to 'c/src/libchip')
-rw-r--r--c/src/libchip/shmdr/README9
-rw-r--r--c/src/libchip/shmdr/addlq.c43
-rw-r--r--c/src/libchip/shmdr/cnvpkt.c42
-rw-r--r--c/src/libchip/shmdr/dump.c50
-rw-r--r--c/src/libchip/shmdr/fatal.c37
-rw-r--r--c/src/libchip/shmdr/getlq.c46
-rw-r--r--c/src/libchip/shmdr/getpkt.c36
-rw-r--r--c/src/libchip/shmdr/init.c248
-rw-r--r--c/src/libchip/shmdr/initlq.c35
-rw-r--r--c/src/libchip/shmdr/intr.c58
-rw-r--r--c/src/libchip/shmdr/mpci.h59
-rw-r--r--c/src/libchip/shmdr/mpisr.c23
-rw-r--r--c/src/libchip/shmdr/poll.c40
-rw-r--r--c/src/libchip/shmdr/receive.c44
-rw-r--r--c/src/libchip/shmdr/retpkt.c32
-rw-r--r--c/src/libchip/shmdr/send.c61
-rw-r--r--c/src/libchip/shmdr/setckvec.c28
-rw-r--r--c/src/libchip/shmdr/shm_driver.h542
18 files changed, 1433 insertions, 0 deletions
diff --git a/c/src/libchip/shmdr/README b/c/src/libchip/shmdr/README
new file mode 100644
index 0000000000..5ed9e861b0
--- /dev/null
+++ b/c/src/libchip/shmdr/README
@@ -0,0 +1,9 @@
+#
+# $Id$
+#
+
+The mpci.h file provided in here is too simple for an MPCI with
+multiple ways to get to a node.
+
+This version of the shm driver needs to be reorganized to follow
+the better model of the Ada version.
diff --git a/c/src/libchip/shmdr/addlq.c b/c/src/libchip/shmdr/addlq.c
new file mode 100644
index 0000000000..2c2529c834
--- /dev/null
+++ b/c/src/libchip/shmdr/addlq.c
@@ -0,0 +1,43 @@
+/* void Shm_Locked_queue_Add( lq_cb, ecb )
+ *
+ * This routine adds an envelope control block to a shared memory queue.
+ *
+ * Input parameters:
+ * lq_cb - pointer to a locked queue control block
+ * ecb - pointer to an envelope control block
+ *
+ * Output parameters: NONE
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+
+void Shm_Locked_queue_Add(
+ Shm_Locked_queue_Control *lq_cb,
+ Shm_Envelope_control *ecb
+)
+{
+ rtems_unsigned32 index;
+
+ ecb->next = Shm_Locked_queue_End_of_list;
+ ecb->queue = lq_cb->owner;
+ index = ecb->index;
+
+ Shm_Lock( lq_cb );
+ if ( Shm_Convert(lq_cb->front) != Shm_Locked_queue_End_of_list )
+ Shm_Envelopes[ Shm_Convert(lq_cb->rear) ].next = index;
+ else
+ lq_cb->front = index;
+ lq_cb->rear = index;
+ Shm_Unlock( lq_cb );
+}
diff --git a/c/src/libchip/shmdr/cnvpkt.c b/c/src/libchip/shmdr/cnvpkt.c
new file mode 100644
index 0000000000..2c3a144167
--- /dev/null
+++ b/c/src/libchip/shmdr/cnvpkt.c
@@ -0,0 +1,42 @@
+/* void Shm_Convert_packet( &packet )
+ *
+ * This routine is the shared memory locked queue MPCI driver routine
+ * used to convert the RTEMS's information in a packet from non-native
+ * format to processor native format.
+ *
+ * Input parameters:
+ * packet - pointer to a packet
+ *
+ * Output parameters:
+ * *packet - packet in native format
+ *
+ * NOTE: Message buffers are not manipulated.
+ * Endian conversion is currently the only conversion.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+
+void Shm_Convert_packet(
+ rtems_packet_prefix *packet
+)
+{
+ rtems_unsigned32 *pkt, i;
+
+ pkt = (rtems_unsigned32 *) packet;
+ for ( i=RTEMS_MINIMUN_HETERO_CONVERSION ; i ; i--, pkt++ )
+ *pkt = CPU_swap_u32( *pkt );
+
+ for ( i=packet->to_convert ; i ; i--, pkt++ )
+ *pkt = CPU_swap_u32( *pkt );
+}
diff --git a/c/src/libchip/shmdr/dump.c b/c/src/libchip/shmdr/dump.c
new file mode 100644
index 0000000000..e028ab4204
--- /dev/null
+++ b/c/src/libchip/shmdr/dump.c
@@ -0,0 +1,50 @@
+/*
+ * This routine is invoked following a reset to report the statistics
+ * gathered during the previous execution.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include <stdio.h>
+#include <libcsupport.h>
+
+#include "shm.h"
+
+void
+Shm_Print_statistics(void)
+{
+ rtems_unsigned32 ticks;
+ rtems_unsigned32 ticks_per_second;
+ rtems_unsigned32 seconds;
+ int packets_per_second;
+
+ (void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &ticks );
+ (void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second );
+
+ seconds = ticks / ticks_per_second;
+
+ packets_per_second = Shm_Receive_message_count / seconds;
+ if ( (Shm_Receive_message_count % seconds) >= (seconds / 2) )
+ packets_per_second++;
+
+ printf( "\n\nSHMDR STATISTICS (NODE %d)\n", Shm_Local_node );
+ printf( "TICKS SINCE BOOT = %d\n", ticks );
+ printf( "TICKS PER SECOND = %d\n", ticks_per_second );
+ printf( "ISRs=%d\n", Shm_Interrupt_count );
+ printf( "RECV=%d\n", Shm_Receive_message_count );
+ printf( "NULL=%d\n", Shm_Null_message_count );
+ printf( "PKTS/SEC=%d\n", packets_per_second );
+}
diff --git a/c/src/libchip/shmdr/fatal.c b/c/src/libchip/shmdr/fatal.c
new file mode 100644
index 0000000000..fc1e9f8624
--- /dev/null
+++ b/c/src/libchip/shmdr/fatal.c
@@ -0,0 +1,37 @@
+/* void MPCI_Fatal( error )
+ *
+ * This routine is the shared memory driver fatal error handler.
+ *
+ * Input parameters:
+ * error - fatal error code
+ *
+ * Output parameters: NEVER RETURNS
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+
+void MPCI_Fatal(
+ rtems_unsigned32 error
+)
+{
+ /* Eventually need to attempt to broadcast a K_FATAL message
+ * without checking for all possible errors (do not want to
+ * recurse).
+ *
+ * Also need to avoid using Shm_Node_statuses if the driver has not been
+ * initialized.
+ */
+
+ Shm_Local_node_status->error = Shm_Convert(error);
+}
diff --git a/c/src/libchip/shmdr/getlq.c b/c/src/libchip/shmdr/getlq.c
new file mode 100644
index 0000000000..180c33ef00
--- /dev/null
+++ b/c/src/libchip/shmdr/getlq.c
@@ -0,0 +1,46 @@
+/* Shm_Envelope_control *Shm_Locked_queue_Get( lq_cb )
+ *
+ * This routine returns an envelope control block from a shared
+ * memory queue.
+ *
+ * Input parameters:
+ * lq_cb - pointer to a locked queue control block
+ *
+ * Output parameters:
+ * returns - pointer to an envelope control block
+ * - NULL if no envelopes on specified queue
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+
+Shm_Envelope_control *Shm_Locked_queue_Get(
+ Shm_Locked_queue_Control *lq_cb
+)
+{
+ Shm_Envelope_control *tmp_ecb;
+ rtems_unsigned32 tmpfront;
+
+ tmp_ecb = NULL;
+ Shm_Lock( lq_cb );
+ tmpfront = Shm_Convert(lq_cb->front);
+ if ( tmpfront != Shm_Locked_queue_End_of_list ) {
+ tmp_ecb = &Shm_Envelopes[ tmpfront ];
+ lq_cb->front = tmp_ecb->next;
+ if ( tmp_ecb->next == Shm_Locked_queue_End_of_list )
+ lq_cb->rear = Shm_Locked_queue_End_of_list;
+ tmp_ecb->next = Shm_Locked_queue_Not_on_list;
+ }
+ Shm_Unlock( lq_cb );
+ return( tmp_ecb );
+}
diff --git a/c/src/libchip/shmdr/getpkt.c b/c/src/libchip/shmdr/getpkt.c
new file mode 100644
index 0000000000..c80b3ed282
--- /dev/null
+++ b/c/src/libchip/shmdr/getpkt.c
@@ -0,0 +1,36 @@
+/* Shm_Get_packet
+ *
+ * This routine is the shared memory locked queue MPCI driver
+ * routine used to obtain an empty message packet.
+ *
+ * Input parameters:
+ * packet - address of pointer to packet
+ *
+ * Output parameters:
+ * *(cpb->get_packet) - address of allocated packet
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+
+rtems_mpci_entry Shm_Get_packet(
+ rtems_packet_prefix **packet
+)
+{
+ Shm_Envelope_control *ecb;
+
+ ecb = Shm_Allocate_envelope();
+ if ( !ecb )
+ rtems_fatal_error_occurred ( SHM_NO_FREE_PKTS );
+ *packet = Shm_Envelope_control_to_packet_prefix_pointer( ecb );
+}
diff --git a/c/src/libchip/shmdr/init.c b/c/src/libchip/shmdr/init.c
new file mode 100644
index 0000000000..b9de91d449
--- /dev/null
+++ b/c/src/libchip/shmdr/init.c
@@ -0,0 +1,248 @@
+/* Shm_Initialization
+ *
+ * This routine is the shared memory communications initerface
+ * driver initialization routine.
+ *
+ * Input parameters:
+ * configuration - address of configuration table
+ *
+ * Output parameters: NONE
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#define _SHM_INIT
+
+#include <rtems.h>
+#include "shm.h"
+
+/*
+ * Need a user extension control to install MPCI_Fatal as
+ * a fatal error handler extension
+ */
+
+rtems_extensions_table MPCI_Shm_extensions;
+
+rtems_mpci_entry Shm_Initialization(
+ rtems_configuration_table *configuration,
+ rtems_cpu_table *cpu_configuration,
+ rtems_multiprocessing_table *mp_configuration
+
+)
+{
+ rtems_unsigned32 i, *u32_ptr, *endshm, all_initialized;
+ rtems_unsigned32 interrupt_cause, interrupt_value;
+ void *interrupt_address;
+ Shm_Node_status_control *nscb;
+ rtems_unsigned32 extension_id; /* for installation of MPCI_Fatal */
+ rtems_unsigned32 remaining_memory;
+
+ Shm_RTEMS_Configuration = configuration;
+ Shm_RTEMS_MP_Configuration = mp_configuration;
+
+ Shm_Local_node = Shm_RTEMS_MP_Configuration->node;
+ Shm_Maximum_nodes = Shm_RTEMS_MP_Configuration->maximum_nodes;
+
+ Shm_Get_configuration( Shm_Local_node ,&Shm_Configuration );
+
+ Shm_Receive_message_count = 0;
+ Shm_Null_message_count = 0;
+ Shm_Interrupt_count = 0;
+
+ /*
+ * Set the Node Status indicators
+ */
+
+#define PEND Shm_Convert(rtems_build_name( 'P', 'E', 'N', 'D' ))
+#define COMP Shm_Convert(rtems_build_name( 'C', 'O', 'M', 'P' ))
+#define ACTV Shm_Convert(rtems_build_name( 'A', 'C', 'T', 'V' ))
+
+ Shm_Pending_initialization = PEND;
+ Shm_Initialization_complete = COMP;
+ Shm_Active_node = ACTV;
+
+ /*
+ * Initialize the constants used by the Locked Queue code.
+ */
+
+ Shm_Locked_queue_End_of_list = Shm_Convert( 0xffffffff );
+ Shm_Locked_queue_Not_on_list = Shm_Convert( 0xfffffffe );
+
+ /*
+ * Set the base addresses for the:
+ * + Node Status Table
+ * + Free Pool and Receive Queues
+ * + Envelopes
+ */
+
+ Shm_Node_statuses = (Shm_Node_status_control *) START_NS_CBS;
+ Shm_Locked_queues = (Shm_Locked_queue_Control *) START_LQ_CBS;
+ Shm_Envelopes = (Shm_Envelope_control *) START_ENVELOPES;
+
+ /*
+ * Calculate the maximum number of envelopes which can be
+ * placed the remaining shared memory.
+ */
+
+ remaining_memory =
+ ((void *)Shm_Configuration->base + Shm_Configuration->length) -
+ ((void *)Shm_Envelopes);
+
+ Shm_Maximum_envelopes = remaining_memory / sizeof( Shm_Envelope_control );
+ Shm_Maximum_envelopes -= 1;
+
+ /*
+ * Set the pointer to the receive queue for the local node.
+ * When we receive a node, we will get it from here before
+ * processing it.
+ */
+
+ Shm_Local_receive_queue = &Shm_Locked_queues[ Shm_Local_node ];
+ Shm_Local_node_status = &Shm_Node_statuses[ Shm_Local_node ];
+
+ /*
+ * Convert local interrupt cause information into the
+ * neutral format so other nodes will be able to
+ * understand it.
+ */
+
+ interrupt_address =
+ (void *) Shm_Convert( (rtems_unsigned32)Shm_Configuration->Intr.address );
+ interrupt_value = Shm_Convert( Shm_Configuration->Intr.value );
+ interrupt_cause = Shm_Convert( Shm_Configuration->Intr.length );
+
+ if ( Shm_Configuration->poll_intr == POLLED_MODE ) Shm_setclockvec();
+ else Shm_setvec();
+
+ if ( Shm_Is_master_node() ) {
+
+ /*
+ * Zero out the shared memory area.
+ */
+
+ for ( u32_ptr = (rtems_unsigned32 *)Shm_Configuration->base,
+ endshm = (rtems_unsigned32 *)END_SHARED_MEM ;
+ u32_ptr < endshm ; )
+ *u32_ptr++ = 0;
+
+ /*
+ * Initialize all of the locked queues (the free envelope
+ * pool and a receive queue per node) and set all of the
+ * node's status so they will be waiting to initialization
+ * to complete.
+ */
+
+ Shm_Locked_queue_Initialize( FREE_ENV_CB, FREE_ENV_POOL );
+
+ for ( i=SHM_FIRST_NODE ; i<=Shm_Maximum_nodes ; i++ ) {
+ Shm_Initialize_receive_queue( i );
+
+ Shm_Node_statuses[ i ].status = Shm_Pending_initialization;
+ Shm_Node_statuses[ i ].error = 0;
+ }
+
+ /*
+ * Initialize all of the envelopes and place them in the
+ * free pool.
+ */
+
+ for ( i=0 ; i<Shm_Maximum_envelopes ; i++ ) {
+ Shm_Envelopes[ i ].index = Shm_Convert(i);
+ Shm_Free_envelope( &Shm_Envelopes[ i ] );
+ }
+
+ /*
+ * Initialize this node's interrupt information in the
+ * shared area so other nodes can interrupt us.
+ */
+
+ Shm_Local_node_status->int_address = (rtems_unsigned32) interrupt_address;
+ Shm_Local_node_status->int_value = interrupt_value;
+ Shm_Local_node_status->int_length = interrupt_cause;
+
+ Shm_Local_node_status->status = Shm_Initialization_complete;
+
+ /*
+ * Loop until all nodes have completed initialization.
+ */
+
+ all_initialized = 0;
+
+ for ( ; ; ) {
+
+ if ( all_initialized == 1 ) break;
+
+ all_initialized = 1;
+
+ for ( i = SHM_FIRST_NODE ; i <= Shm_Maximum_nodes ; i++ )
+ if ( Shm_Node_statuses[ i ].status != Shm_Initialization_complete )
+ all_initialized = 0;
+ }
+
+ /*
+ * Tell the other nodes we think that the system is up.
+ */
+
+ for ( i = SHM_FIRST_NODE ; i <= Shm_Maximum_nodes ; i++ )
+ Shm_Node_statuses[ i ].status = Shm_Active_node;
+
+ } else { /* is not MASTER node */
+
+ /*
+ * Initialize the node status for the non-master nodes.
+ * Because the master node zeroes out memory, it is
+ * necessary for them to keep putting their values in
+ * the node status area until the master says they
+ * should become active.
+ */
+
+ Shm_Local_node_status->status = Shm_Pending_initialization;
+
+ do {
+
+ if ( Shm_Local_node_status->status == Shm_Pending_initialization ) {
+
+ /*
+ * Initialize this node's interrupt information in the
+ * shared area so other nodes can interrupt us.
+ */
+
+ Shm_Local_node_status->int_address =
+ (rtems_unsigned32) interrupt_address;
+ Shm_Local_node_status->int_value = interrupt_value;
+ Shm_Local_node_status->int_length = interrupt_cause;
+
+ Shm_Local_node_status->status = Shm_Initialization_complete;
+ }
+ } while ( Shm_Local_node_status->status != Shm_Active_node ) ;
+ }
+
+ /*
+ * Initialize the Interrupt Information Table
+ */
+
+ for ( i = SHM_FIRST_NODE ; i <= Shm_Maximum_nodes ; i++ ) {
+ nscb = &Shm_Node_statuses[ i ];
+
+ Shm_Interrupt_table[i].address = Shm_Convert_address(
+ (void *)Shm_Convert(((vol_u32) nscb->int_address))
+ );
+ Shm_Interrupt_table[i].value = Shm_Convert( nscb->int_value );
+ Shm_Interrupt_table[i].length = Shm_Convert( nscb->int_length );
+ }
+
+ MPCI_Shm_extensions.fatal = MPCI_Fatal;
+ (void) rtems_extension_create(
+ rtems_build_name( 'M', 'P', 'E', 'X' ),
+ &MPCI_Shm_extensions,
+ &extension_id
+ );
+}
diff --git a/c/src/libchip/shmdr/initlq.c b/c/src/libchip/shmdr/initlq.c
new file mode 100644
index 0000000000..3f44cf577d
--- /dev/null
+++ b/c/src/libchip/shmdr/initlq.c
@@ -0,0 +1,35 @@
+/* void Shm_Locked_queue_Initialize( lq_cb, owner )
+ *
+ * This routine initializes a shared memory locked queue.
+ *
+ * Input parameters:
+ * lq_cb - pointer to the control block of the queue
+ * to be initialized
+ * owner - unique idenitifier of who owns this queue.
+ *
+ * Output parameters: NONE
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+
+void Shm_Locked_queue_Initialize(
+ Shm_Locked_queue_Control *lq_cb,
+ rtems_unsigned32 owner
+)
+{
+ Shm_Initialize_lock( lq_cb );
+ lq_cb->front = Shm_Locked_queue_End_of_list;
+ lq_cb->rear = Shm_Locked_queue_End_of_list;
+ lq_cb->owner = Shm_Convert(owner);
+}
diff --git a/c/src/libchip/shmdr/intr.c b/c/src/libchip/shmdr/intr.c
new file mode 100644
index 0000000000..8982103227
--- /dev/null
+++ b/c/src/libchip/shmdr/intr.c
@@ -0,0 +1,58 @@
+/* void Shm_Cause_interrupt( node )
+ *
+ * This routine is the shared memory driver routine which
+ * generates interrupts to other CPUs.
+ *
+ * It uses the information placed in the node status control
+ * block by each node. For example, when used with the Motorola
+ * MVME136 board, the MPCSR is used.
+ *
+ * Input parameters:
+ * node - destination of this packet (0 = broadcast)
+ *
+ * Output parameters: NONE
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+
+void Shm_Cause_interrupt(
+ rtems_unsigned32 node
+)
+{
+ Shm_Interrupt_information *intr;
+ rtems_unsigned8 *u8;
+ rtems_unsigned16 *u16;
+ rtems_unsigned32 *u32;
+ rtems_unsigned32 value;
+
+ intr = &Shm_Interrupt_table[node];
+ value = intr->value;
+
+ switch ( intr->length ) {
+ case NO_INTERRUPT:
+ break;
+ case BYTE:
+ u8 = (rtems_unsigned8 *)intr->address;
+ *u8 = (rtems_unsigned8) value;
+ break;
+ case WORD:
+ u16 = (rtems_unsigned16 *)intr->address;
+ *u16 = (rtems_unsigned16) value;
+ break;
+ case LONG:
+ u32 = (rtems_unsigned32 *)intr->address;
+ *u32 = (rtems_unsigned32) value;
+ break;
+ }
+}
diff --git a/c/src/libchip/shmdr/mpci.h b/c/src/libchip/shmdr/mpci.h
new file mode 100644
index 0000000000..819349f96f
--- /dev/null
+++ b/c/src/libchip/shmdr/mpci.h
@@ -0,0 +1,59 @@
+/* mpci.h
+ *
+ * This include file contains all the renaming necessary to
+ * have an application use the Shared Memory Driver as its
+ * sole mechanism for MPCI.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#ifndef __MPCI_h
+#define __MPCI_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "shm.h"
+
+#define MPCI_Initialization( _configuration ) \
+ Shm_Initialization( _configuration )
+
+#define MPCI_Get_packet( _the_packet ) \
+ Shm_Get_packet( _the_packet )
+
+#define MPCI_Return_packet( _the_packet ) \
+ Shm_Return_packet( _the_packet )
+
+#define MPCI_Receive_packet( _the_packet ) \
+ Shm_Receive_packet( _the_packet )
+
+#define MPCI_Send_packet( _destination, _the_packet ) \
+ Shm_Send_packet( _destination, _the_packet )
+
+/* Unnecessary... mapped in shm.h
+#define MPCI_Fatal( _the_error ) \
+ Shm_Fatal( _the_error )
+*/
+
+#define MPCI_Enable_statistics()
+
+#define MPCI_Print_statistics() \
+ Shm_Print_statistics()
+
+/* no need to rename the MPCI_Table either */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/libchip/shmdr/mpisr.c b/c/src/libchip/shmdr/mpisr.c
new file mode 100644
index 0000000000..93ced3d351
--- /dev/null
+++ b/c/src/libchip/shmdr/mpisr.c
@@ -0,0 +1,23 @@
+/* _Shm_isr()
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+
+rtems_isr Shm_isr(
+ rtems_vector_number vector
+)
+{
+ Shm_Interrupt_count += 1;
+ rtems_multiprocessing_announce();
+}
diff --git a/c/src/libchip/shmdr/poll.c b/c/src/libchip/shmdr/poll.c
new file mode 100644
index 0000000000..43f6711ff9
--- /dev/null
+++ b/c/src/libchip/shmdr/poll.c
@@ -0,0 +1,40 @@
+/* void Shm_Poll()
+ *
+ * This routine polls to see if a packet has arrived. If one
+ * has it informs the executive. It is typically called from
+ * the clock tick interrupt service routine.
+ *
+ * Input parameters: NONE
+ *
+ * Output parameters: NONE
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+#include "clockdrv.h"
+
+void Shm_Poll()
+{
+ rtems_unsigned32 tmpfront;
+
+ Clock_isr( 0 ); /* invoke standard clock ISR */
+
+ /* enable_tracing(); */
+ /* ticks += 1; */
+ Shm_Lock( Shm_Local_receive_queue );
+ tmpfront = Shm_Local_receive_queue->front;
+ Shm_Unlock( Shm_Local_receive_queue );
+ if ( Shm_Convert(tmpfront) == Shm_Locked_queue_End_of_list ) return;
+ rtems_multiprocessing_announce();
+ Shm_Interrupt_count++;
+}
diff --git a/c/src/libchip/shmdr/receive.c b/c/src/libchip/shmdr/receive.c
new file mode 100644
index 0000000000..e094a2df6b
--- /dev/null
+++ b/c/src/libchip/shmdr/receive.c
@@ -0,0 +1,44 @@
+/* Shm_Receive_packet
+ *
+ * This routine is the shared memory locked queue MPCI driver routine
+ * used to obtain a packet containing a message from this node's
+ * receive queue.
+ *
+ * Input parameters:
+ * packet - address of a pointer to a packet
+ *
+ * Output parameters:
+ * *(rpb->packet) - pointer to packet
+ * NULL if no packet currently available
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+
+rtems_mpci_entry Shm_Receive_packet(
+ rtems_packet_prefix **packet
+)
+{
+ Shm_Envelope_control *ecb;
+
+ ecb = Shm_Locked_queue_Get( Shm_Local_receive_queue );
+ if ( ecb ) {
+ *(packet) = Shm_Envelope_control_to_packet_prefix_pointer( ecb );
+ if ( ecb->Preamble.endian != Shm_Configuration->format )
+ Shm_Convert_packet( *packet );
+ Shm_Receive_message_count++;
+ } else {
+ *(packet) = NULL;
+ Shm_Null_message_count++;
+ }
+}
diff --git a/c/src/libchip/shmdr/retpkt.c b/c/src/libchip/shmdr/retpkt.c
new file mode 100644
index 0000000000..973b84ab0d
--- /dev/null
+++ b/c/src/libchip/shmdr/retpkt.c
@@ -0,0 +1,32 @@
+/* Shm_Return_packet
+ *
+ * This routine is the shared memory locked queue MPCI driver
+ * routine used to return a message packet to a free envelope
+ * pool accessible by this node.
+ *
+ * Input parameters:
+ * packet - address of pointer to packet
+ *
+ * Output parameters: NONE
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+
+rtems_mpci_entry Shm_Return_packet(
+ rtems_packet_prefix *packet
+)
+{
+ Shm_Free_envelope( Shm_Packet_prefix_to_envelope_control_pointer(packet) );
+}
+
diff --git a/c/src/libchip/shmdr/send.c b/c/src/libchip/shmdr/send.c
new file mode 100644
index 0000000000..58a5bb93b9
--- /dev/null
+++ b/c/src/libchip/shmdr/send.c
@@ -0,0 +1,61 @@
+/* Shm_Send_packet
+ *
+ * This routine is the shared memory driver locked queue write
+ * MPCI driver routine. This routine sends the specified packet
+ * to the destination specified by "node". A "node" value of
+ * zero designates that this packet is to be broadcasted.
+ *
+ * Input parameters:
+ * node - destination of this packet (0 = broadcast)
+ * packet - address of packet
+ *
+ * Output parameters: NONE
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+
+struct pkt_cpy {
+ rtems_unsigned32 packet[MAX_PACKET_SIZE/4];
+};
+
+rtems_mpci_entry Shm_Send_packet(
+ rtems_unsigned32 node,
+ rtems_packet_prefix *packet
+)
+{
+ Shm_Envelope_control *ecb, *tmp_ecb;
+ rtems_unsigned32 nnum;
+
+ ecb = Shm_Packet_prefix_to_envelope_control_pointer( packet );
+ if ( node ) {
+ Shm_Build_preamble( ecb, node );
+ Shm_Build_postamble( ecb );
+ Shm_Append_to_receive_queue( node, ecb );
+ (*Shm_Configuration->cause_intr)( node );
+ }
+ else {
+ for( nnum = SHM_FIRST_NODE ; nnum <= Shm_Maximum_nodes ; nnum++ )
+ if ( Shm_Local_node != nnum ) {
+ tmp_ecb = Shm_Allocate_envelope();
+ if ( !tmp_ecb )
+ rtems_fatal_error_occurred( SHM_NO_FREE_PKTS );
+ Shm_Build_preamble( tmp_ecb, nnum );
+ *((struct pkt_cpy *)tmp_ecb->packet) = *((struct pkt_cpy *)packet);
+ Shm_Build_postamble( tmp_ecb );
+ Shm_Append_to_receive_queue( nnum, tmp_ecb );
+ (*Shm_Configuration->cause_intr)( nnum );
+ }
+ Shm_Free_envelope( ecb );
+ }
+}
diff --git a/c/src/libchip/shmdr/setckvec.c b/c/src/libchip/shmdr/setckvec.c
new file mode 100644
index 0000000000..0b5e306dab
--- /dev/null
+++ b/c/src/libchip/shmdr/setckvec.c
@@ -0,0 +1,28 @@
+/* Shm_setclockvec
+ *
+ * This routines installs the shared memory clock interrupt handler
+ * used when the driver is used in polling mode.
+ *
+ * INPUT PARAMETERS: NONE
+ *
+ * OUTPUT PARAMETERS: NONE
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#include <rtems.h>
+#include "shm.h"
+#include "clockdrv.h"
+
+rtems_isr Shm_setclockvec()
+{
+ ReInstall_clock( Shm_Poll );
+}
diff --git a/c/src/libchip/shmdr/shm_driver.h b/c/src/libchip/shmdr/shm_driver.h
new file mode 100644
index 0000000000..bee930138c
--- /dev/null
+++ b/c/src/libchip/shmdr/shm_driver.h
@@ -0,0 +1,542 @@
+/* shm.h
+ *
+ * This include file contains all the constants, structures,
+ * and global variables for this RTEMS based shared memory
+ * communications interface driver.
+ *
+ * Processor board dependencies are in other files.
+ *
+ * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
+ * On-Line Applications Research Corporation (OAR).
+ * All rights assigned to U.S. Government, 1994.
+ *
+ * This material may be reproduced by or for the U.S. Government pursuant
+ * to the copyright license under the clause at DFARS 252.227-7013. This
+ * notice must appear in all copies of this file and its derivatives.
+ *
+ * $Id$
+ */
+
+#ifndef __SHM_h
+#define __SHM_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <cpu.h>
+
+/* The information contained in the Node Status, Locked Queue, and
+ * Envelope Control Blocks must be maintained in a NEUTRAL format.
+ * Currently the neutral format may be selected as big or little
+ * endian by simply defining either NEUTRAL_BIG or NEUTRAL_LITTLE.
+ *
+ * It is CRITICAL to note that the neutral format can ONLY be
+ * changed by modifying this file and recompiling the ENTIRE
+ * SHM driver including ALL target specific support files.
+ *
+ * The following table details the memory contents for the endian
+ * field of the Node Status Control Block in the various
+ * data format configurations (data is in hexadecimal):
+ *
+ * NEUTRAL NATIVE BYTE 0 BYTE 1 BYTE 2 BYTE 3
+ * ======= ====== ====== ====== ====== ======
+ * BIG BIG 00 00 00 01
+ * BIG LITTLE 10 00 00 00
+ * LITTLE BIG 01 00 00 00
+ * LITTLE LITTLE 00 00 00 10
+ *
+ *
+ * NOTE: XXX
+ * PORTABILITY OF LOCKING INSTRUCTIONS
+ * ===================================
+ * The locking mechanism described below is not
+ * general enough. Where the hardware supports
+ * it we should use "atomic swap" instructions
+ * so the values in the lock can be tailored to
+ * support a CPU with only weak atomic memory
+ * instructions. There are combinations of
+ * CPUs with inflexible atomic memory instructions
+ * which appear to be incompatible. For example,
+ * the SPARClite instruction uses a byte which is
+ * 0xFF when locked. The PA-RISC uses 1 to indicate
+ * locked and 0 when unlocked. These CPUs appear to
+ * have incompatible lock instructions. But
+ * they could be used in a heterogenous system
+ * with does not mix SPARCs and PA-RISCs. For
+ * example, the i386 and SPARC or i386 and SPARC
+ * could work together. The bottom line is that
+ * not every CPU will work together using this
+ * locking scheme. There are supposed to be
+ * algorithms to do this without hardware assist
+ * and one of these should be incorporated into
+ * the shared memory driver.
+ *
+ * The most flexible scheme using the instructions
+ * of the various CPUs for efficiency would be to use
+ * "atomic swaps" wherever possible. Make the lock
+ * and unlock configurable much like BIG vs LITTLE
+ * endian use of shared memory is now. The values
+ * of the lock could then reflect the "worst"
+ * CPU in a system. This still results in mixes
+ * of CPUs which are incompatible.
+ *
+ * The current locking mechanism is based upon the MC68020
+ * "tas" instruction which is atomic. All ports to other CPUs
+ * comply with the restrictive placement of lock bit by this
+ * instruction. The lock bit is the most significant bit in a
+ * big-endian rtems_unsigned32. On other processors, the lock is
+ * typically implemented via an atomic swap or atomic modify
+ * bits type instruction.
+ */
+
+#define NEUTRAL_BIG
+
+#ifdef NEUTRAL_BIG
+#define SHM_BIG 0x00000001
+#define SHM_LITTLE 0x10000000
+#endif
+
+#ifdef NEUTRAL_LITTLE
+#define SHM_BIG 0x01000000
+#define SHM_LITTLE 0x00000010
+#endif
+
+/*
+ * The following are the values used to fill in the lock field. Some CPUs
+ * are able to write only a single value into field. By making the
+ * lock and unlock values configurable, CPUs which support "atomic swap"
+ * instructions can generally be made to work in any heterogeneous
+ * configuration. However, it is possible for two CPUs to be incompatible
+ * in regards to the lock field values. This occurs when two CPUs
+ * which write only a single value to the field are used in a system
+ * but the two CPUs write different incompatible values.
+ *
+ * NOTE: The following is a first attempt at defining values which
+ * have a chance at working together. The m68k should use
+ * chk2 instead of tas to be less restrictive. Target endian
+ * problems (like the Force CPU386 which has (broken) big endian
+ * view of the VMEbus address space) are not addressed yet.
+ */
+
+#if defined(i960)
+#define SHM_LOCK_VALUE 0x00000080
+#define SHM_UNLOCK_VALUE 0
+#elif defined(m68k)
+#define SHM_LOCK_VALUE 0x80000000
+#define SHM_UNLOCK_VALUE 0
+#define SHM_LOCK_VALUE 0x80000000
+#define SHM_UNLOCK_VALUE 0
+#elif defined(i386)
+#define SHM_LOCK_VALUE 0x80000000
+#define SHM_UNLOCK_VALUE 0
+#elif defined(hppa1_1)
+#define SHM_LOCK_VALUE 0
+#define SHM_UNLOCK_VALUE 1
+#elif defined(unix)
+#define SHM_LOCK_VALUE 0
+#define SHM_UNLOCK_VALUE 1
+#elif defined(no_cpu) /* for this values are irrelevant */
+#define SHM_LOCK_VALUE 1
+#define SHM_UNLOCK_VALUE 0
+#endif
+
+#define Shm_Convert( value ) \
+ ((Shm_Configuration->convert) ? \
+ (*Shm_Configuration->convert)(value) : (value))
+
+/* constants */
+
+#define SHM_MASTER 1 /* master initialization node */
+#define SHM_FIRST_NODE 1
+
+/* size constants */
+
+#define KILOBYTE (1024)
+#define MEGABYTE (1024*1024)
+
+/* inter-node interrupt values */
+
+#define NO_INTERRUPT 0 /* used for polled nodes */
+#define BYTE 1
+#define WORD 2
+#define LONG 4
+
+/* operational mode constants -- used in SHM Configuration Table */
+#define POLLED_MODE 0
+#define INTR_MODE 1
+
+/* error codes */
+
+#define NO_ERROR 0
+#define SHM_NO_FREE_PKTS 0xf0000
+
+/* null pointers of different types */
+
+#define NULL_ENV_CB ((Shm_Envelope_control *) 0)
+#define NULL_SHM_INFO ((struct shm_info *) 0)
+#define NULL_CONVERT 0
+#if 0
+#define NULL_CONVERT (((rtems_unsigned32 *)())0) /* we want this */
+#endif
+
+/* The following is adjusted so envelopes are 0x80 bytes long. */
+/* It should be >= MIN_PKT_SIZE in rtems.h */
+
+#define MAX_PACKET_SIZE (80)
+
+/* constants pertinent to Locked Queue routines */
+
+#define LQ_UNLOCKED SHM_UNLOCK_VALUE
+#define LQ_LOCKED SHM_LOCK_VALUE
+
+/* constants related to the Free Envelope Pool */
+
+#define FREE_ENV_POOL 0
+#define FREE_ENV_CB (&Shm_Locked_queues[ FREE_ENV_POOL ])
+
+/* The following are important when dealing with
+ * the shared memory communications interface area.
+ *
+ * NOTE: The starting address and length of the shared memory
+ * is defined in a system dependent file.
+ */
+
+#if 0
+#define START_NS_CBS ( (rtems_unsigned8 *) START_SHARED_MEM )
+#define START_LQ_CBS ( ((rtems_unsigned8 *) START_NS_CBS) + \
+ ( (sizeof (Shm_Node_status_control)) * (Shm_Maximum_nodes + 1) ) )
+#define START_ENVELOPES ( ((rtems_unsigned8 *) START_LQ_CBS) + \
+ ( (sizeof (Shm_Locked_queue_Control)) * (Shm_Maximum_nodes + 1) ) )
+#define END_SHMCI_AREA ( (rtems_unsigned8 *) START_ENVELOPES + \
+ ( (sizeof (Shm_Envelope_control)) * Shm_Maximum_envelopes ) )
+#define END_SHARED_MEM ((rtems_unsigned32)START_SHARED_MEM+SHARED_MEM_LEN)
+#endif
+
+#define START_NS_CBS ((void *)Shm_Configuration->base)
+#define START_LQ_CBS ((START_NS_CBS) + \
+ ( (sizeof (Shm_Node_status_control)) * (Shm_Maximum_nodes + 1) ) )
+#define START_ENVELOPES ( ((void *) START_LQ_CBS) + \
+ ( (sizeof (Shm_Locked_queue_Control)) * (Shm_Maximum_nodes + 1) ) )
+#define END_SHMCI_AREA ( (void *) START_ENVELOPES + \
+ ( (sizeof (Shm_Envelope_control)) * Shm_Maximum_envelopes ) )
+#define END_SHARED_MEM (START_NS_CBS+Shm_Configuration->length)
+
+/* macros */
+
+#define Shm_Is_master_node() \
+ ( SHM_MASTER == Shm_Local_node )
+
+#define Shm_Free_envelope( ecb ) \
+ Shm_Locked_queue_Add( FREE_ENV_CB, (ecb) )
+#define Shm_Allocate_envelope() \
+ Shm_Locked_queue_Get(FREE_ENV_CB)
+
+#define Shm_Initialize_receive_queue(node) \
+ Shm_Locked_queue_Initialize( &Shm_Locked_queues[node], node )
+
+#define Shm_Append_to_receive_queue(node, ecb) \
+ Shm_Locked_queue_Add( &Shm_Locked_queues[node], (ecb) )
+
+#define Shm_Envelope_control_to_packet_prefix_pointer(ecb) \
+ ((void *)(ecb)->packet)
+
+#define Shm_Packet_prefix_to_envelope_control_pointer( pkt ) \
+ ((Shm_Envelope_control *)((rtems_unsigned8 *)(pkt) - \
+ (sizeof(Shm_Envelope_preamble) + 4*sizeof(vol_u32))))
+
+#define Shm_Build_preamble(ecb, node) \
+ (ecb)->Preamble.endian = Shm_Configuration->format
+
+#define Shm_Build_postamble( ecb )
+
+/* structures */
+
+typedef volatile rtems_unsigned8 vol_u8;
+typedef volatile rtems_unsigned32 vol_u32;
+
+/* shm control information */
+
+struct shm_info {
+ vol_u32 not_currently_used_0;
+ vol_u32 not_currently_used_1;
+ vol_u32 not_currently_used_2;
+ vol_u32 not_currently_used_3;
+};
+
+typedef struct {
+ /*byte start_of_text;*/
+ vol_u32 endian;
+ vol_u32 not_currently_used_0;
+ vol_u32 not_currently_used_1;
+ vol_u32 not_currently_used_2;
+} Shm_Envelope_preamble;
+
+typedef struct {
+ vol_u32 not_currently_used_0;
+ vol_u32 not_currently_used_1;
+ vol_u32 not_currently_used_2;
+ vol_u32 not_currently_used_3;
+ /*byte end_of_text;*/
+} Shm_Envelope_postable;
+
+/* WARNING! If you change this structure, don't forget to change
+ * Shm_Envelope_control_to_packet_prefix_pointer() and
+ * Shm_Packet_prefix_to_envelope_control_pointer() above.
+ */
+
+/* This comment block describes the contents of each field
+ * of the Envelope Control Block:
+ *
+ * next - The index of the next envelope on this queue.
+ * queue - The index of the queue this envelope is on.
+ * index - The index of this envelope.
+ * Preamble - Generic packet preamble. One day this structure
+ * could be enhanced to contain routing information.
+ * packet - RTEMS MPCI packet. Untouched by SHM Driver
+ * other than copying and format conversion as
+ * documented in the RTEMS User's Guide.
+ * Postamble - Generic packet postamble. One day this structure
+ * could be enhanced to contain checksum information.
+ */
+
+typedef struct {
+ vol_u32 next; /* next envelope on queue */
+ vol_u32 queue; /* queue on which this resides */
+ vol_u32 index; /* index into array of envelopes*/
+ vol_u32 pad0; /* insure the next one is aligned */
+ Shm_Envelope_preamble Preamble; /* header information */
+ vol_u8 packet[MAX_PACKET_SIZE]; /* RTEMS INFO */
+ Shm_Envelope_postable Postamble;/* trailer information */
+} Shm_Envelope_control;
+
+/* This comment block describes the contents of each field
+ * of the Locked Queue Control Block:
+ *
+ * lock - Lock used to insure mutually exclusive access.
+ * front - Index of first envelope on queue. This field
+ * is used to remove head of queue (receive).
+ * rear - Index of last envelope on queue. This field
+ * is used to add evelope to queue (send).
+ * owner - The node number of the recipient (owning) node.
+ * RTEMS does not use the node number zero (0).
+ * The zero node is used by the SHM Driver for the
+ * Free Envelope Queue shared by all nodes.
+ */
+
+typedef struct {
+ vol_u32 lock; /* lock field for this queue */
+ vol_u32 front; /* first envelope on queue */
+ vol_u32 rear; /* last envelope on queue */
+ vol_u32 owner; /* receiving (i.e. owning) node */
+} Shm_Locked_queue_Control;
+
+/* This comment block describes the contents of each field
+ * of the Node Status Control Block:
+ *
+ * status - Node status. Current values are Pending Initialization,
+ * Initialization Complete, and Active Node. Other values
+ * could be added to enhance fault tolerance.
+ * error - Zero if the node has not failed. Otherwise,
+ * this field contains a status indicating the
+ * failure reason.
+ * int_address, int_value, and int_length
+ * - These field are the Interrupt Information table
+ * for this node in neutral format. This is how
+ * each node knows how to generate interrupts.
+ */
+
+typedef struct {
+ vol_u32 status; /* node status information */
+ vol_u32 error; /* fatal error code */
+ vol_u32 int_address; /* write here for interrupt */
+ vol_u32 int_value; /* this value causes interrupt */
+ vol_u32 int_length; /* for this length (0,1,2,4) */
+ vol_u32 not_currently_used_0;
+ vol_u32 not_currently_used_1;
+ vol_u32 not_currently_used_2;
+} Shm_Node_status_control;
+
+/* This comment block describes the contents of each field
+ * of the Interrupt Information Table. This table describes
+ * how another node can generate an interrupt to this node.
+ * This information is target board dependent. If the
+ * SHM Driver is in POLLED_MODE, then all fields should
+ * be initialized to NO_INTERRUPT.
+ *
+ * address - The address to which another node should
+ * write to cause an interrupt.
+ * value - The value which must be written
+ * length - The size of the value to write. Valid
+ * values are BYTE, WORD, and LONG.
+ *
+ * NOTE: The Node Status Control Block contains this
+ * information in neutral format and not in a
+ * structure to avoid potential alignment problems.
+ */
+
+typedef struct {
+ vol_u32 *address; /* write here for interrupt */
+ vol_u32 value; /* this value causes interrupt */
+ vol_u32 length; /* for this length (0,1,2,4) */
+} Shm_Interrupt_information;
+
+/* SHM Configuration Table
+ *
+ * This comment block describes the contents of each field
+ * of the SHM Configuration Table.
+ *
+ * base - The base address of the shared memory. This
+ * address may be specific to this node.
+ * length - The length of the shared memory in bytes.
+ * format - The natural format for rtems_unsigned32's in the
+ * shared memory. Valid values are currently
+ * only SHM_LITTLE and SHM_BIG.
+ * convert - The address of the routine which converts
+ * between neutral and local format.
+ * poll_intr - The operational mode of the driver. Some
+ * target boards may not provide hardware for
+ * an interprocessor interrupt. If POLLED_MODE
+ * is selected, the SHM driver will install a
+ * wrapper around the Clock_isr() to poll for
+ * incoming packets. Throughput is dependent
+ * on the time between clock interrupts.
+ * Valid values are POLLED_MODE and INTR_MODE.
+ * cause_intr - This is the address of the routine used to
+ * write to a particular address and cause an
+ * interrupt on another node. This routine
+ * may need to be target dependent if something
+ * other than a normal write from C does not work.
+ * Intr - This structure describes the operation required
+ * to cause an interrupt to this node. The actual
+ * contents of this structure are described above.
+ */
+
+struct shm_config_info {
+ vol_u32 *base; /* base address of SHM */
+ vol_u32 length; /* length (in bytes) of SHM */
+ vol_u32 format; /* SHM is big or little endian */
+ vol_u32 (*convert)();/* neutral conversion routine */
+ vol_u32 poll_intr;/* POLLED or INTR driven mode */
+ void (*cause_intr)( rtems_unsigned32 );
+ Shm_Interrupt_information Intr; /* cause intr information */
+};
+
+typedef struct shm_config_info shm_config_table;
+
+/* global variables */
+
+#ifdef _SHM_INIT
+#define SHM_EXTERN
+#else
+#define SHM_EXTERN extern
+#endif
+
+SHM_EXTERN shm_config_table *Shm_Configuration;
+SHM_EXTERN Shm_Interrupt_information Shm_Interrupt_table[16];
+SHM_EXTERN Shm_Node_status_control *Shm_Node_statuses;
+SHM_EXTERN Shm_Locked_queue_Control *Shm_Locked_queues;
+SHM_EXTERN Shm_Envelope_control *Shm_Envelopes;
+SHM_EXTERN rtems_configuration_table *Shm_RTEMS_Configuration;
+SHM_EXTERN rtems_multiprocessing_table *Shm_RTEMS_MP_Configuration;
+SHM_EXTERN rtems_unsigned32 Shm_Receive_message_count;
+SHM_EXTERN rtems_unsigned32 Shm_Null_message_count;
+SHM_EXTERN rtems_unsigned32 Shm_Interrupt_count;
+SHM_EXTERN rtems_unsigned32 Shm_Local_node;
+SHM_EXTERN Shm_Locked_queue_Control *Shm_Local_receive_queue;
+SHM_EXTERN Shm_Node_status_control *Shm_Local_node_status;
+SHM_EXTERN rtems_unsigned32 Shm_isrstat;
+ /* reported by shmdr */
+
+SHM_EXTERN rtems_unsigned32 Shm_Pending_initialization;
+SHM_EXTERN rtems_unsigned32 Shm_Initialization_complete;
+SHM_EXTERN rtems_unsigned32 Shm_Active_node;
+
+SHM_EXTERN rtems_unsigned32 Shm_Maximum_nodes;
+SHM_EXTERN rtems_unsigned32 Shm_Maximum_envelopes;
+
+SHM_EXTERN rtems_unsigned32 Shm_Locked_queue_End_of_list;
+SHM_EXTERN rtems_unsigned32 Shm_Locked_queue_Not_on_list;
+
+/* functions */
+
+/* locked queue routines */
+void Shm_Locked_queue_Add(
+ Shm_Locked_queue_Control *, Shm_Envelope_control * );
+Shm_Envelope_control *Shm_Locked_queue_Get( Shm_Locked_queue_Control * );
+void Shm_Locked_queue_Initialize(
+ Shm_Locked_queue_Control *, rtems_unsigned32 );
+ /* Shm_Initialize_lock is CPU dependent */
+ /* Shm_Lock is CPU dependent */
+ /* Shm_Unlock is CPU dependent */
+
+/* portable routines */
+void Init_env_pool();
+void Shm_Print_statistics( void );
+void MPCI_Fatal( rtems_unsigned32 );
+rtems_task Shm_Cause_interrupt( rtems_unsigned32 );
+void Shm_Poll();
+void Shm_setclockvec();
+void Shm_Convert_packet( rtems_packet_prefix * );
+
+/* CPU specific routines are inlined in shmcpu.h */
+
+/* target specific routines */
+void *Shm_Convert_address( void * );
+void Shm_Get_configuration( rtems_unsigned32, shm_config_table ** );
+void Shm_isr();
+void Shm_setvec( void );
+
+void Shm_Initialize_lock( Shm_Locked_queue_Control * );
+void Shm_Lock( Shm_Locked_queue_Control * );
+void Shm_Unlock( Shm_Locked_queue_Control * );
+
+/* MPCI entry points */
+rtems_mpci_entry Shm_Get_packet(
+ rtems_packet_prefix **
+);
+
+rtems_mpci_entry Shm_Initialization(
+ rtems_configuration_table *configuration,
+ rtems_cpu_table *cpu_configuration,
+ rtems_multiprocessing_table *mp_configuration
+);
+
+rtems_mpci_entry Shm_Receive_packet(
+ rtems_packet_prefix **
+);
+
+rtems_mpci_entry Shm_Return_packet(
+ rtems_packet_prefix *
+);
+
+rtems_mpci_entry Shm_Send_packet(
+ rtems_unsigned32,
+ rtems_packet_prefix *
+);
+
+#ifdef _SHM_INIT
+
+/* multiprocessor communications interface (MPCI) table */
+
+rtems_mpci_table MPCI_table = {
+ 100000, /* default timeout value in ticks */
+ Shm_Initialization, /* initialization procedure */
+ Shm_Get_packet, /* get packet procedure */
+ Shm_Return_packet, /* return packet procedure */
+ Shm_Send_packet, /* packet send procedure */
+ Shm_Receive_packet /* packet receive procedure */
+};
+
+#else
+
+extern rtems_mpci_table MPCI_table;
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */