Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:43

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*  shm_driver.h
0004  *
0005  *  This include file contains all the constants, structures,
0006  *  and global variables for this RTEMS based shared memory
0007  *  communications interface driver.
0008  *
0009  *  Processor board dependencies are in other files.
0010  *
0011  *  COPYRIGHT (c) 1989-2007.
0012  *  On-Line Applications Research Corporation (OAR).
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifndef __SHM_h
0037 #define __SHM_h
0038 
0039 #include <rtems.h>
0040 #include <rtems/clockdrv.h>
0041 
0042 #ifdef __cplusplus
0043 extern "C" {
0044 #endif
0045 
0046 /*  The information contained in the Node Status, Locked Queue, and
0047  *  Envelope Control Blocks must be maintained in a NEUTRAL format.
0048  *  Currently the neutral format may be selected as big or little
0049  *  endian by simply defining either NEUTRAL_BIG or NEUTRAL_LITTLE.
0050  *
0051  *  It is CRITICAL to note that the neutral format can ONLY be
0052  *  changed by modifying this file and recompiling the ENTIRE
0053  *  SHM driver including ALL target specific support files.
0054  *
0055  *  The following table details the memory contents for the endian
0056  *  field of the Node Status Control Block in the various
0057  *  data format configurations (data is in hexadecimal):
0058  *
0059  *   NEUTRAL NATIVE BYTE 0  BYTE 1  BYTE 2  BYTE 3
0060  *   ======= ====== ======  ======  ======  ======
0061  *    BIG     BIG     00      00      00      01
0062  *    BIG    LITTLE   10      00      00      00
0063  *   LITTLE   BIG     01      00      00      00
0064  *   LITTLE  LITTLE   00      00      00      10
0065  *
0066  *
0067  *  NOTE: XXX
0068  *                PORTABILITY OF LOCKING INSTRUCTIONS
0069  *                ===================================
0070  *            The locking mechanism described below is not
0071  *            general enough.  Where the hardware supports
0072  *            it we should use "atomic swap" instructions
0073  *            so the values in the lock can be tailored to
0074  *            support a CPU with only weak atomic memory
0075  *            instructions.  There are combinations of
0076  *            CPUs with inflexible atomic memory instructions
0077  *            which appear to be incompatible.  For example,
0078  *            the SPARClite instruction uses a byte which is
0079  *            0xFF when locked.  The PA-RISC uses 1 to indicate
0080  *            locked and 0 when unlocked.  These CPUs appear to
0081  *            have incompatible lock instructions.  But
0082  *            they could be used in a heterogenous system
0083  *            with does not mix SPARCs and PA-RISCs.  For
0084  *            example, the i386 and SPARC or i386 and SPARC
0085  *            could work together.  The bottom line is that
0086  *            not every CPU will work together using this
0087  *            locking scheme.  There are supposed to be
0088  *            algorithms to do this without hardware assist
0089  *            and one of these should be incorporated into
0090  *            the shared memory driver.
0091  *
0092  *            The most flexible scheme using the instructions
0093  *            of the various CPUs for efficiency would be to use
0094  *            "atomic swaps" wherever possible.  Make the lock
0095  *            and unlock configurable much like BIG vs LITTLE
0096  *            endian use of shared memory is now.  The values
0097  *            of the lock could then reflect the "worst"
0098  *            CPU in a system.  This still results in mixes
0099  *            of CPUs which are incompatible.
0100  *
0101  *  The current locking mechanism is based upon the MC68020
0102  *  "tas" instruction which is atomic.  All ports to other CPUs
0103  *  comply with the restrictive placement of lock bit by this
0104  *  instruction.  The lock bit is the most significant bit in a
0105  *  big-endian uint32_t  .  On other processors, the lock is
0106  *  typically implemented via an atomic swap or atomic modify
0107  *  bits type instruction.
0108  */
0109 
0110 #define NEUTRAL_BIG
0111 
0112 #ifdef NEUTRAL_BIG
0113 #define SHM_BIG       0x00000001
0114 #define SHM_LITTLE    0x10000000
0115 #endif
0116 
0117 #ifdef NEUTRAL_LITTLE
0118 #define SHM_BIG       0x01000000
0119 #define SHM_LITTLE    0x00000010
0120 #endif
0121 
0122 /*
0123  *  The following are the values used to fill in the lock field.  Some CPUs
0124  *  are able to write only a single value into field.  By making the
0125  *  lock and unlock values configurable, CPUs which support "atomic swap"
0126  *  instructions can generally be made to work in any heterogeneous
0127  *  configuration.  However, it is possible for two CPUs to be incompatible
0128  *  in regards to the lock field values.  This occurs when two CPUs
0129  *  which write only a single value to the field are used in a system
0130  *  but the two CPUs write different incompatible values.
0131  *
0132  *  NOTE:  The following is a first attempt at defining values which
0133  *         have a chance at working together.  The m68k should use
0134  *         chk2 instead of tas to be less restrictive.  Target endian
0135  *         problems (like the Force CPU386 which has (broken) big endian
0136  *         view of the VMEbus address space) are not addressed yet.
0137  */
0138 
0139 #if defined(__mc68000__)
0140 #define SHM_LOCK_VALUE    0x80000000
0141 #define SHM_UNLOCK_VALUE  0
0142 #define SHM_LOCK_VALUE    0x80000000
0143 #define SHM_UNLOCK_VALUE  0
0144 #elif defined(__i386__)
0145 #define SHM_LOCK_VALUE    0x80000000
0146 #define SHM_UNLOCK_VALUE  0
0147 #elif defined(__mips__)
0148 #define SHM_LOCK_VALUE    0x80000000
0149 #define SHM_UNLOCK_VALUE  0
0150 #elif defined(__hppa__)
0151 #define SHM_LOCK_VALUE    0
0152 #define SHM_UNLOCK_VALUE  1
0153 #elif defined(__PPC__)
0154 #define SHM_LOCK_VALUE    1
0155 #define SHM_UNLOCK_VALUE  0
0156 #elif defined(__unix__)
0157 #define SHM_LOCK_VALUE    0
0158 #define SHM_UNLOCK_VALUE  1
0159 #elif defined(_AM29K)
0160 #define SHM_LOCK_VALUE    0
0161 #define SHM_UNLOCK_VALUE  1
0162 #elif defined(__nios2__)
0163 #define SHM_LOCK_VALUE    1
0164 #define SHM_UNLOCK_VALUE  0
0165 #elif defined(__sparc__)
0166 #define SHM_LOCK_VALUE    1
0167 #define SHM_UNLOCK_VALUE  0
0168 #elif defined(no_cpu)               /* for this values are irrelevant */
0169 #define SHM_LOCK_VALUE    1
0170 #define SHM_UNLOCK_VALUE  0
0171 #else
0172 #error "shm_driver.h - no SHM_LOCK_VALUE defined for this CPU architecture"
0173 #endif
0174 
0175 #define Shm_Convert( value ) \
0176   ((Shm_Configuration->convert) ? \
0177     (*Shm_Configuration->convert)(value) : (value))
0178 
0179 /* constants */
0180 
0181 #define SHM_MASTER                  1     /* master initialization node */
0182 #define SHM_FIRST_NODE              1
0183 
0184 /* size constants */
0185 
0186 #define KILOBYTE          (1024)
0187 #define MEGABYTE          (1024*1024)
0188 
0189 /* inter-node interrupt values */
0190 
0191 #define NO_INTERRUPT            0     /* used for polled nodes */
0192 #define BYTE                    1
0193 #define WORD                    2
0194 #define LONG                    4
0195 
0196 /* operational mode constants -- used in SHM Configuration Table */
0197 #define POLLED_MODE             0
0198 #define INTR_MODE               1
0199 
0200 /* error codes */
0201 
0202 #define NO_ERROR                0
0203 #define SHM_NO_FREE_PKTS        0xf0000
0204 
0205 /* null pointers of different types */
0206 
0207 #define NULL_ENV_CB             ((Shm_Envelope_control *) 0)
0208 #define NULL_CONVERT            0
0209 
0210 /*
0211  * size of stuff before preamble in envelope.
0212  * It must be a constant since we will use it to generate MAX_PACKET_SIZE
0213  */
0214 
0215 #define SHM_ENVELOPE_PREFIX_OVERHEAD    (4 * sizeof(vol_u32))
0216 
0217 /*
0218  *  The following is adjusted so envelopes are MAX_ENVELOPE_SIZE bytes long.
0219  *  It must be >= RTEMS_MINIMUM_PACKET_SIZE in mppkt.h.
0220  */
0221 
0222 #ifndef MAX_ENVELOPE_SIZE
0223 #define MAX_ENVELOPE_SIZE 0x180
0224 #endif
0225 
0226 #define MAX_PACKET_SIZE  (MAX_ENVELOPE_SIZE -               \
0227                           SHM_ENVELOPE_PREFIX_OVERHEAD +    \
0228                           sizeof(Shm_Envelope_preamble) +   \
0229                           sizeof(Shm_Envelope_postamble))
0230 
0231 
0232 /* constants pertinent to Locked Queue routines */
0233 
0234 #define LQ_UNLOCKED              SHM_UNLOCK_VALUE
0235 #define LQ_LOCKED                SHM_LOCK_VALUE
0236 
0237 /* constants related to the Free Envelope Pool */
0238 
0239 #define FREE_ENV_POOL            0
0240 #define FREE_ENV_CB              (&Shm_Locked_queues[ FREE_ENV_POOL ])
0241 
0242 /*  The following are important when dealing with
0243  *  the shared memory communications interface area.
0244  *
0245  *  NOTE: The starting address and length of the shared memory
0246  *        is defined in a system dependent file.
0247  */
0248 
0249 #define START_NS_CBS     ((void *)Shm_Configuration->base)
0250 #define START_LQ_CBS     ((START_NS_CBS) + \
0251         ( (sizeof (Shm_Node_status_control)) * (SHM_MAXIMUM_NODES + 1) ) )
0252 #define START_ENVELOPES  ( ((void *) START_LQ_CBS) + \
0253         ( (sizeof (Shm_Locked_queue_Control)) * (SHM_MAXIMUM_NODES + 1) ) )
0254 #define END_SHMCI_AREA    ( (void *) START_ENVELOPES + \
0255         ( (sizeof (Shm_Envelope_control)) * Shm_Maximum_envelopes ) )
0256 #define END_SHARED_MEM   (START_NS_CBS+Shm_Configuration->length)
0257 
0258 /* macros */
0259 
0260 #define Shm_Is_master_node()  \
0261   ( SHM_MASTER == rtems_object_get_local_node() )
0262 
0263 #define Shm_Free_envelope( ecb ) \
0264   Shm_Locked_queue_Add( FREE_ENV_CB, (ecb) )
0265 #define Shm_Allocate_envelope() \
0266   Shm_Locked_queue_Get(FREE_ENV_CB)
0267 
0268 #define Shm_Initialize_receive_queue(node) \
0269   Shm_Locked_queue_Initialize( &Shm_Locked_queues[node], node )
0270 
0271 #define Shm_Append_to_receive_queue(node, ecb) \
0272   Shm_Locked_queue_Add( &Shm_Locked_queues[node], (ecb) )
0273 
0274 #define Shm_Envelope_control_to_packet_prefix_pointer(ecb)  \
0275    ((void *)(ecb)->packet)
0276 
0277 #define Shm_Packet_prefix_to_envelope_control_pointer( pkt )   \
0278    ((Shm_Envelope_control *)((uint8_t*)(pkt) - \
0279    (sizeof(Shm_Envelope_preamble) + SHM_ENVELOPE_PREFIX_OVERHEAD)))
0280 
0281 #define Shm_Build_preamble(ecb, node) \
0282        (ecb)->Preamble.endian = Shm_Configuration->format
0283 
0284 #define Shm_Build_postamble( ecb )
0285 
0286 /* volatile types */
0287 
0288 typedef volatile uint8_t    vol_u8;
0289 typedef volatile uint32_t   vol_u32;
0290 
0291 /* shm control information */
0292 
0293 struct shm_info {
0294   vol_u32 not_currently_used_0;
0295   vol_u32 not_currently_used_1;
0296   vol_u32 not_currently_used_2;
0297   vol_u32 not_currently_used_3;
0298 };
0299 
0300 typedef struct {
0301   /*byte start_of_text;*/
0302   vol_u32 endian;
0303   vol_u32 not_currently_used_0;
0304   vol_u32 not_currently_used_1;
0305   vol_u32 not_currently_used_2;
0306 } Shm_Envelope_preamble;
0307 
0308 typedef struct {
0309 } Shm_Envelope_postamble;
0310 
0311 /* WARNING! If you change this structure, don't forget to change
0312  *          SHM_ENVELOPE_PREFIX_OVERHEAD and
0313  *          Shm_Packet_prefix_to_envelope_control_pointer() above.
0314  */
0315 
0316 /*  This comment block describes the contents of each field
0317  *  of the Envelope Control Block:
0318  *
0319  *  next      - The index of the next envelope on this queue.
0320  *  queue     - The index of the queue this envelope is on.
0321  *  index     - The index of this envelope.
0322  *  Preamble  - Generic packet preamble.  One day this structure
0323  *              could be enhanced to contain routing information.
0324  *  packet    - RTEMS MPCI packet.  Untouched by SHM Driver
0325  *              other than copying and format conversion as
0326  *              documented in the RTEMS User's Guide.
0327  *  Postamble - Generic packet postamble.  One day this structure
0328  *              could be enhanced to contain checksum information.
0329  */
0330 
0331 typedef struct {
0332   vol_u32           next;     /* next envelope on queue       */
0333   vol_u32           queue;    /* queue on which this resides  */
0334   vol_u32           index;    /* index into array of envelopes*/
0335   vol_u32           pad0;     /* insure the next one is aligned */
0336   Shm_Envelope_preamble    Preamble; /* header information           */
0337   vol_u8            packet[MAX_PACKET_SIZE]; /* RTEMS INFO    */
0338   Shm_Envelope_postamble   Postamble;/* trailer information          */
0339 } Shm_Envelope_control;
0340 
0341 /*  This comment block describes the contents of each field
0342  *  of the Locked Queue Control Block:
0343  *
0344  *  lock      - Lock used to insure mutually exclusive access.
0345  *  front     - Index of first envelope on queue.  This field
0346  *              is used to remove head of queue (receive).
0347  *  rear      - Index of last envelope on queue.  This field
0348  *              is used to add evelope to queue (send).
0349  *  owner     - The node number of the recipient (owning) node.
0350  *              RTEMS does not use the node number zero (0).
0351  *              The zero node is used by the SHM Driver for the
0352  *              Free Envelope Queue shared by all nodes.
0353  */
0354 
0355 typedef struct {
0356   vol_u32 lock;  /* lock field for this queue    */
0357   vol_u32 front; /* first envelope on queue      */
0358   vol_u32 rear;  /* last envelope on queue       */
0359   vol_u32 owner; /* receiving (i.e. owning) node */
0360 } Shm_Locked_queue_Control;
0361 
0362 /*  This comment block describes the contents of each field
0363  *  of the Node Status Control Block:
0364  *
0365  *  status    - Node status.  Current values are Pending Initialization,
0366  *              Initialization Complete, and Active Node.  Other values
0367  *              could be added to enhance fault tolerance.
0368  *  error     - Zero if the node has not failed.  Otherwise,
0369  *              this field contains a status indicating the
0370  *              failure reason.
0371  *  int_address, int_value, and int_length
0372  *            - These field are the Interrupt Information table
0373  *              for this node in neutral format.  This is how
0374  *              each node knows how to generate interrupts.
0375  */
0376 
0377 typedef struct {
0378   vol_u32  status;         /* node status information     */
0379   vol_u32  error;          /* fatal error code            */
0380   vol_u32  int_address;    /* write here for interrupt    */
0381   vol_u32  int_value;      /* this value causes interrupt */
0382   vol_u32  int_length;     /* for this length (0,1,2,4)   */
0383   vol_u32  not_currently_used_0;
0384   vol_u32  not_currently_used_1;
0385   vol_u32  not_currently_used_2;
0386 } Shm_Node_status_control;
0387 
0388 /*  This comment block describes the contents of each field
0389  *  of the Interrupt Information Table.  This table describes
0390  *  how another node can generate an interrupt to this node.
0391  *  This information is target board dependent.  If the
0392  *  SHM Driver is in POLLED_MODE, then all fields should
0393  *  be initialized to NO_INTERRUPT.
0394  *
0395  *  address   - The address to which another node should
0396  *              write to cause an interrupt.
0397  *  value     - The value which must be written
0398  *  length    - The size of the value to write.  Valid
0399  *              values are BYTE, WORD, and LONG.
0400  *
0401  *  NOTE:  The Node Status Control Block contains this
0402  *         information in neutral format and not in a
0403  *         structure to avoid potential alignment problems.
0404  */
0405 
0406 typedef struct {
0407   vol_u32 *address;        /* write here for interrupt    */
0408   vol_u32  value;          /* this value causes interrupt */
0409   vol_u32  length;         /* for this length (0,1,2,4)   */
0410 } Shm_Interrupt_information;
0411 
0412 /*  SHM Configuration Table
0413  *
0414  *  This comment block describes the contents of each field
0415  *  of the SHM Configuration Table.
0416  *
0417  *  base       - The base address of the shared memory.  This
0418  *               address may be specific to this node.
0419  *  length     - The length of the shared memory in bytes.
0420  *  format     - The natural format for uint32_t  's in the
0421  *               shared memory.  Valid values are currently
0422  *               only SHM_LITTLE and SHM_BIG.
0423  *  convert    - The address of the routine which converts
0424  *               between neutral and local format.
0425  *  poll_intr  - The operational mode of the driver.  Some
0426  *               target boards may not provide hardware for
0427  *               an interprocessor interrupt.  If POLLED_MODE
0428  *               is selected, the SHM driver will use a
0429  *               Classiv API Timer instance to poll for
0430  *               incoming packets.  Throughput is dependent
0431  *               on the time between clock interrupts.
0432  *               Valid values are POLLED_MODE and INTR_MODE.
0433  *  cause_intr - This is the address of the routine used to
0434  *               write to a particular address and cause an
0435  *               interrupt on another node.  This routine
0436  *               may need to be target dependent if something
0437  *               other than a normal write from C does not work.
0438  *  Intr       - This structure describes the operation required
0439  *               to cause an interrupt to this node.  The actual
0440  *               contents of this structure are described above.
0441  */
0442 
0443 struct shm_config_info {
0444   vol_u32           *base;     /* base address of SHM         */
0445   vol_u32            length;   /* length (in bytes) of SHM    */
0446   vol_u32            format;   /* SHM is big or little endian */
0447   uint32_t         (*convert)( uint32_t );/* neutral conversion routine */
0448   vol_u32            poll_intr;/* POLLED or INTR driven mode  */
0449   void             (*cause_intr)( uint32_t);
0450   Shm_Interrupt_information   Intr;     /* cause intr information      */
0451 };
0452 
0453 typedef struct shm_config_info shm_config_table;
0454 
0455 #define SHM_MAXIMUM_NODES _MPCI_Configuration.maximum_nodes
0456 
0457 /* global variables */
0458 
0459 #ifdef _SHM_INIT
0460 #define SHM_EXTERN
0461 #else
0462 #define SHM_EXTERN extern
0463 #endif
0464 
0465 SHM_EXTERN shm_config_table             *Shm_Configuration;
0466 SHM_EXTERN Shm_Interrupt_information    *Shm_Interrupt_table;
0467 SHM_EXTERN Shm_Node_status_control      *Shm_Node_statuses;
0468 SHM_EXTERN Shm_Locked_queue_Control     *Shm_Locked_queues;
0469 SHM_EXTERN Shm_Envelope_control         *Shm_Envelopes;
0470 SHM_EXTERN uint32_t                      Shm_Receive_message_count;
0471 SHM_EXTERN uint32_t                      Shm_Null_message_count;
0472 SHM_EXTERN uint32_t                      Shm_Interrupt_count;
0473 SHM_EXTERN Shm_Locked_queue_Control     *Shm_Local_receive_queue;
0474 SHM_EXTERN Shm_Node_status_control      *Shm_Local_node_status;
0475 SHM_EXTERN uint32_t                      Shm_isrstat;
0476                                                      /* reported by shmdr */
0477 
0478 SHM_EXTERN uint32_t   Shm_Pending_initialization;
0479 SHM_EXTERN uint32_t   Shm_Initialization_complete;
0480 SHM_EXTERN uint32_t   Shm_Active_node;
0481 
0482 SHM_EXTERN uint32_t   Shm_Maximum_envelopes;
0483 
0484 SHM_EXTERN uint32_t   Shm_Locked_queue_End_of_list;
0485 SHM_EXTERN uint32_t   Shm_Locked_queue_Not_on_list;
0486 
0487 /* functions */
0488 
0489 /* locked queue routines */
0490 void           Shm_Locked_queue_Add(
0491                   Shm_Locked_queue_Control *, Shm_Envelope_control * );
0492 Shm_Envelope_control *Shm_Locked_queue_Get( Shm_Locked_queue_Control * );
0493 void           Shm_Locked_queue_Initialize(
0494                   Shm_Locked_queue_Control *, uint32_t);
0495             /* Shm_Initialize_lock is CPU dependent */
0496             /* Shm_Lock is CPU dependent */
0497             /* Shm_Unlock is CPU dependent */
0498 
0499 /* portable routines */
0500 void           Init_env_pool( void );
0501 void           Shm_Print_statistics( void );
0502 void           MPCI_Fatal( rtems_fatal_source, bool, rtems_fatal_code );
0503 rtems_task     Shm_Cause_interrupt( uint32_t );
0504 void           Shm_install_timer( void );
0505 void           Shm_Convert_packet( rtems_packet_prefix * );
0506 
0507 /* CPU specific routines are inlined in shmcpu.h */
0508 
0509 /* target specific routines */
0510 void          *Shm_Convert_address( void * );
0511 void           Shm_Get_configuration( uint32_t, shm_config_table ** );
0512 void           Shm_isr( void );
0513 void           Shm_setvec( void );
0514 
0515 void           Shm_Initialize_lock( Shm_Locked_queue_Control * );
0516 void           Shm_Lock( Shm_Locked_queue_Control * );
0517 void           Shm_Unlock( Shm_Locked_queue_Control * );
0518 
0519 /* MPCI entry points */
0520 rtems_mpci_entry Shm_Get_packet(
0521   rtems_packet_prefix **
0522 );
0523 
0524 rtems_mpci_entry Shm_Initialization( void );
0525 
0526 rtems_mpci_entry Shm_Receive_packet(
0527   rtems_packet_prefix **
0528 );
0529 
0530 rtems_mpci_entry Shm_Return_packet(
0531   rtems_packet_prefix *
0532 );
0533 
0534 rtems_mpci_entry Shm_Send_packet(
0535   uint32_t,
0536   rtems_packet_prefix *
0537 );
0538 
0539 extern rtems_mpci_table MPCI_table;
0540 
0541 #ifdef _SHM_INIT
0542 
0543 /* multiprocessor communications interface (MPCI) table */
0544 
0545 rtems_mpci_table MPCI_table  = {
0546   100000,                     /* default timeout value in ticks */
0547   MAX_PACKET_SIZE,            /* maximum packet size */
0548   Shm_Initialization,         /* initialization procedure   */
0549   Shm_Get_packet,             /* get packet procedure       */
0550   Shm_Return_packet,          /* return packet procedure    */
0551   Shm_Send_packet,            /* packet send procedure      */
0552   Shm_Receive_packet          /* packet receive procedure   */
0553 };
0554 
0555 #endif
0556 
0557 #ifdef __cplusplus
0558 }
0559 #endif
0560 
0561 #endif
0562 /* end of include file */