From ac7d5ef06a6d6e8d84abbd1f0b82162725f98326 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 11 May 1995 17:39:37 +0000 Subject: Initial revision --- c/src/libchip/shmdr/README | 9 + c/src/libchip/shmdr/addlq.c | 43 ++++ c/src/libchip/shmdr/cnvpkt.c | 42 +++ c/src/libchip/shmdr/dump.c | 50 ++++ c/src/libchip/shmdr/fatal.c | 37 +++ c/src/libchip/shmdr/getlq.c | 46 ++++ c/src/libchip/shmdr/getpkt.c | 36 +++ c/src/libchip/shmdr/init.c | 248 ++++++++++++++++++ c/src/libchip/shmdr/initlq.c | 35 +++ c/src/libchip/shmdr/intr.c | 58 +++++ c/src/libchip/shmdr/mpci.h | 59 +++++ c/src/libchip/shmdr/mpisr.c | 23 ++ c/src/libchip/shmdr/poll.c | 40 +++ c/src/libchip/shmdr/receive.c | 44 ++++ c/src/libchip/shmdr/retpkt.c | 32 +++ c/src/libchip/shmdr/send.c | 61 +++++ c/src/libchip/shmdr/setckvec.c | 28 ++ c/src/libchip/shmdr/shm_driver.h | 542 +++++++++++++++++++++++++++++++++++++++ 18 files changed, 1433 insertions(+) create mode 100644 c/src/libchip/shmdr/README create mode 100644 c/src/libchip/shmdr/addlq.c create mode 100644 c/src/libchip/shmdr/cnvpkt.c create mode 100644 c/src/libchip/shmdr/dump.c create mode 100644 c/src/libchip/shmdr/fatal.c create mode 100644 c/src/libchip/shmdr/getlq.c create mode 100644 c/src/libchip/shmdr/getpkt.c create mode 100644 c/src/libchip/shmdr/init.c create mode 100644 c/src/libchip/shmdr/initlq.c create mode 100644 c/src/libchip/shmdr/intr.c create mode 100644 c/src/libchip/shmdr/mpci.h create mode 100644 c/src/libchip/shmdr/mpisr.c create mode 100644 c/src/libchip/shmdr/poll.c create mode 100644 c/src/libchip/shmdr/receive.c create mode 100644 c/src/libchip/shmdr/retpkt.c create mode 100644 c/src/libchip/shmdr/send.c create mode 100644 c/src/libchip/shmdr/setckvec.c create mode 100644 c/src/libchip/shmdr/shm_driver.h (limited to 'c/src/libchip') 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 +#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 +#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 +#include +#include + +#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 +#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 +#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 +#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 +#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 ; iint_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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 +#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 + +/* 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 */ -- cgit v1.2.3