source: rtems/c/src/libchip/shmdr/shm_driver.h @ 5250ff39

4.104.114.84.95
Last change on this file since 5250ff39 was 3235ad9, checked in by Joel Sherrill <joel.sherrill@…>, on 08/23/95 at 19:30:23

Support for variable length names added to Object Handler. This supports
both fixed length "raw" names and strings from the API's point of view.

Both inline and macro implementations were tested.

  • Property mode set to 100644
File size: 19.5 KB
Line 
1/*  shm.h
2 *
3 *  This include file contains all the constants, structures,
4 *  and global variables for this RTEMS based shared memory
5 *  communications interface driver.
6 *
7 *  Processor board dependencies are in other files.
8 *
9 *  COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994.
10 *  On-Line Applications Research Corporation (OAR).
11 *  All rights assigned to U.S. Government, 1994.
12 *
13 *  This material may be reproduced by or for the U.S. Government pursuant
14 *  to the copyright license under the clause at DFARS 252.227-7013.  This
15 *  notice must appear in all copies of this file and its derivatives.
16 *
17 *  $Id$
18 */
19
20#ifndef __SHM_h
21#define __SHM_h
22
23#include <clockdrv.h>
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29/*  The information contained in the Node Status, Locked Queue, and
30 *  Envelope Control Blocks must be maintained in a NEUTRAL format.
31 *  Currently the neutral format may be selected as big or little
32 *  endian by simply defining either NEUTRAL_BIG or NEUTRAL_LITTLE.
33 *
34 *  It is CRITICAL to note that the neutral format can ONLY be
35 *  changed by modifying this file and recompiling the ENTIRE
36 *  SHM driver including ALL target specific support files.
37 *
38 *  The following table details the memory contents for the endian
39 *  field of the Node Status Control Block in the various
40 *  data format configurations (data is in hexadecimal):
41 *
42 *   NEUTRAL NATIVE BYTE 0  BYTE 1  BYTE 2  BYTE 3
43 *   ======= ====== ======  ======  ======  ======
44 *    BIG     BIG     00      00      00      01
45 *    BIG    LITTLE   10      00      00      00
46 *   LITTLE   BIG     01      00      00      00
47 *   LITTLE  LITTLE   00      00      00      10
48 *
49 *
50 *  NOTE: XXX
51 *                PORTABILITY OF LOCKING INSTRUCTIONS
52 *                ===================================
53 *            The locking mechanism described below is not
54 *            general enough.  Where the hardware supports
55 *            it we should use "atomic swap" instructions
56 *            so the values in the lock can be tailored to
57 *            support a CPU with only weak atomic memory
58 *            instructions.  There are combinations of
59 *            CPUs with inflexible atomic memory instructions
60 *            which appear to be incompatible.  For example,
61 *            the SPARClite instruction uses a byte which is
62 *            0xFF when locked.  The PA-RISC uses 1 to indicate
63 *            locked and 0 when unlocked.  These CPUs appear to
64 *            have incompatible lock instructions.  But
65 *            they could be used in a heterogenous system
66 *            with does not mix SPARCs and PA-RISCs.  For
67 *            example, the i386 and SPARC or i386 and SPARC
68 *            could work together.  The bottom line is that
69 *            not every CPU will work together using this
70 *            locking scheme.  There are supposed to be
71 *            algorithms to do this without hardware assist
72 *            and one of these should be incorporated into
73 *            the shared memory driver.
74 *
75 *            The most flexible scheme using the instructions
76 *            of the various CPUs for efficiency would be to use
77 *            "atomic swaps" wherever possible.  Make the lock
78 *            and unlock configurable much like BIG vs LITTLE
79 *            endian use of shared memory is now.  The values
80 *            of the lock could then reflect the "worst"
81 *            CPU in a system.  This still results in mixes
82 *            of CPUs which are incompatible.
83 *
84 *  The current locking mechanism is based upon the MC68020
85 *  "tas" instruction which is atomic.  All ports to other CPUs
86 *  comply with the restrictive placement of lock bit by this
87 *  instruction.  The lock bit is the most significant bit in a
88 *  big-endian rtems_unsigned32.  On other processors, the lock is
89 *  typically implemented via an atomic swap or atomic modify
90 *  bits type instruction.
91 */
92
93#define NEUTRAL_BIG
94
95#ifdef NEUTRAL_BIG
96#define SHM_BIG       0x00000001
97#define SHM_LITTLE    0x10000000
98#endif
99
100#ifdef NEUTRAL_LITTLE
101#define SHM_BIG       0x01000000
102#define SHM_LITTLE    0x00000010
103#endif
104
105/*
106 *  The following are the values used to fill in the lock field.  Some CPUs
107 *  are able to write only a single value into field.  By making the
108 *  lock and unlock values configurable, CPUs which support "atomic swap"
109 *  instructions can generally be made to work in any heterogeneous
110 *  configuration.  However, it is possible for two CPUs to be incompatible
111 *  in regards to the lock field values.  This occurs when two CPUs
112 *  which write only a single value to the field are used in a system
113 *  but the two CPUs write different incompatible values.
114 *
115 *  NOTE:  The following is a first attempt at defining values which
116 *         have a chance at working together.  The m68k should use
117 *         chk2 instead of tas to be less restrictive.  Target endian
118 *         problems (like the Force CPU386 which has (broken) big endian
119 *         view of the VMEbus address space) are not addressed yet.
120 */
121
122#if defined(i960)
123#define SHM_LOCK_VALUE    0x00000080
124#define SHM_UNLOCK_VALUE  0
125#elif defined(m68k)
126#define SHM_LOCK_VALUE    0x80000000
127#define SHM_UNLOCK_VALUE  0
128#define SHM_LOCK_VALUE    0x80000000
129#define SHM_UNLOCK_VALUE  0
130#elif defined(i386)
131#define SHM_LOCK_VALUE    0x80000000
132#define SHM_UNLOCK_VALUE  0
133#elif defined(hppa1_1)
134#define SHM_LOCK_VALUE    0
135#define SHM_UNLOCK_VALUE  1
136#elif defined(unix)
137#define SHM_LOCK_VALUE    0
138#define SHM_UNLOCK_VALUE  1
139#elif defined(no_cpu)               /* for this values are irrelevant */
140#define SHM_LOCK_VALUE    1
141#define SHM_UNLOCK_VALUE  0
142#endif
143
144#define Shm_Convert( value ) \
145  ((Shm_Configuration->convert) ? \
146    (*Shm_Configuration->convert)(value) : (value))
147
148/* constants */
149
150#define SHM_MASTER                  1     /* master initialization node */
151#define SHM_FIRST_NODE              1
152
153/* size constants */
154
155#define KILOBYTE          (1024)
156#define MEGABYTE          (1024*1024)
157
158/* inter-node interrupt values */
159
160#define NO_INTERRUPT            0     /* used for polled nodes */
161#define BYTE                    1
162#define WORD                    2
163#define LONG                    4
164
165/* operational mode constants -- used in SHM Configuration Table */
166#define POLLED_MODE             0
167#define INTR_MODE               1
168
169/* error codes */
170
171#define NO_ERROR                0
172#define SHM_NO_FREE_PKTS        0xf0000
173
174/* null pointers of different types */
175
176#define NULL_ENV_CB             ((Shm_Envelope_control *) 0)
177#define NULL_CONVERT            0
178
179/*
180 * size of stuff before preamble in envelope.
181 * It must be a constant since we will use it to generate MAX_PACKET_SIZE
182 */
183 
184#define SHM_ENVELOPE_PREFIX_OVERHEAD    (4 * sizeof(vol_u32))
185
186/*
187 *  The following is adjusted so envelopes are MAX_ENVELOPE_SIZE bytes long.
188 *  It must be >= RTEMS_MINIMUM_PACKET_SIZE in mppkt.h.
189 */
190 
191#ifndef MAX_ENVELOPE_SIZE
192#define MAX_ENVELOPE_SIZE 0x180
193#endif
194
195#define MAX_PACKET_SIZE  (MAX_ENVELOPE_SIZE -               \
196                          SHM_ENVELOPE_PREFIX_OVERHEAD +    \
197                          sizeof(Shm_Envelope_preamble) +   \
198                          sizeof(Shm_Envelope_postamble))
199
200
201/* constants pertinent to Locked Queue routines */
202
203#define LQ_UNLOCKED              SHM_UNLOCK_VALUE
204#define LQ_LOCKED                SHM_LOCK_VALUE
205
206/* constants related to the Free Envelope Pool */
207
208#define FREE_ENV_POOL            0
209#define FREE_ENV_CB              (&Shm_Locked_queues[ FREE_ENV_POOL ])
210
211/*  The following are important when dealing with
212 *  the shared memory communications interface area.
213 *
214 *  NOTE: The starting address and length of the shared memory
215 *        is defined in a system dependent file.
216 */
217
218#define START_NS_CBS     ((void *)Shm_Configuration->base)
219#define START_LQ_CBS     ((START_NS_CBS) + \
220        ( (sizeof (Shm_Node_status_control)) * (Shm_Maximum_nodes + 1) ) )
221#define START_ENVELOPES  ( ((void *) START_LQ_CBS) + \
222        ( (sizeof (Shm_Locked_queue_Control)) * (Shm_Maximum_nodes + 1) ) )
223#define END_SHMCI_AREA    ( (void *) START_ENVELOPES + \
224        ( (sizeof (Shm_Envelope_control)) * Shm_Maximum_envelopes ) )
225#define END_SHARED_MEM   (START_NS_CBS+Shm_Configuration->length)
226
227/* macros */
228
229#define Shm_Is_master_node()  \
230  ( SHM_MASTER == Shm_Local_node )
231
232#define Shm_Free_envelope( ecb ) \
233  Shm_Locked_queue_Add( FREE_ENV_CB, (ecb) )
234#define Shm_Allocate_envelope() \
235  Shm_Locked_queue_Get(FREE_ENV_CB)
236
237#define Shm_Initialize_receive_queue(node) \
238  Shm_Locked_queue_Initialize( &Shm_Locked_queues[node], node )
239
240#define Shm_Append_to_receive_queue(node, ecb) \
241  Shm_Locked_queue_Add( &Shm_Locked_queues[node], (ecb) )
242
243#define Shm_Envelope_control_to_packet_prefix_pointer(ecb)  \
244   ((void *)(ecb)->packet)
245
246#define Shm_Packet_prefix_to_envelope_control_pointer( pkt )   \
247   ((Shm_Envelope_control *)((rtems_unsigned8 *)(pkt) - \
248   (sizeof(Shm_Envelope_preamble) + SHM_ENVELOPE_PREFIX_OVERHEAD)))
249
250#define Shm_Build_preamble(ecb, node) \
251       (ecb)->Preamble.endian = Shm_Configuration->format
252
253#define Shm_Build_postamble( ecb )
254
255/* volatile types */
256
257typedef volatile rtems_unsigned8  vol_u8;
258typedef volatile rtems_unsigned32 vol_u32;
259
260/* shm control information */
261
262struct shm_info {
263  vol_u32 not_currently_used_0;
264  vol_u32 not_currently_used_1;
265  vol_u32 not_currently_used_2;
266  vol_u32 not_currently_used_3;
267};
268
269typedef struct {
270  /*byte start_of_text;*/
271  vol_u32 endian;
272  vol_u32 not_currently_used_0;
273  vol_u32 not_currently_used_1;
274  vol_u32 not_currently_used_2;
275} Shm_Envelope_preamble;
276
277typedef struct {
278} Shm_Envelope_postamble;
279
280/* WARNING! If you change this structure, don't forget to change
281 *          SHM_ENVELOPE_PREFIX_OVERHEAD and
282 *          Shm_Packet_prefix_to_envelope_control_pointer() above.
283 */
284
285/*  This comment block describes the contents of each field
286 *  of the Envelope Control Block:
287 *
288 *  next      - The index of the next envelope on this queue.
289 *  queue     - The index of the queue this envelope is on.
290 *  index     - The index of this envelope.
291 *  Preamble  - Generic packet preamble.  One day this structure
292 *              could be enhanced to contain routing information.
293 *  packet    - RTEMS MPCI packet.  Untouched by SHM Driver
294 *              other than copying and format conversion as
295 *              documented in the RTEMS User's Guide.
296 *  Postamble - Generic packet postamble.  One day this structure
297 *              could be enhanced to contain checksum information.
298 */
299
300typedef struct {
301  vol_u32           next;     /* next envelope on queue       */
302  vol_u32           queue;    /* queue on which this resides  */
303  vol_u32           index;    /* index into array of envelopes*/
304  vol_u32           pad0;     /* insure the next one is aligned */
305  Shm_Envelope_preamble    Preamble; /* header information           */
306  vol_u8            packet[MAX_PACKET_SIZE]; /* RTEMS INFO    */
307  Shm_Envelope_postamble   Postamble;/* trailer information          */
308} Shm_Envelope_control;
309
310/*  This comment block describes the contents of each field
311 *  of the Locked Queue Control Block:
312 *
313 *  lock      - Lock used to insure mutually exclusive access.
314 *  front     - Index of first envelope on queue.  This field
315 *              is used to remove head of queue (receive).
316 *  rear      - Index of last envelope on queue.  This field
317 *              is used to add evelope to queue (send).
318 *  owner     - The node number of the recipient (owning) node.
319 *              RTEMS does not use the node number zero (0).
320 *              The zero node is used by the SHM Driver for the
321 *              Free Envelope Queue shared by all nodes.
322 */
323
324typedef struct {
325  vol_u32 lock;  /* lock field for this queue    */
326  vol_u32 front; /* first envelope on queue      */
327  vol_u32 rear;  /* last envelope on queue       */
328  vol_u32 owner; /* receiving (i.e. owning) node */
329} Shm_Locked_queue_Control;
330
331/*  This comment block describes the contents of each field
332 *  of the Node Status Control Block:
333 *
334 *  status    - Node status.  Current values are Pending Initialization,
335 *              Initialization Complete, and Active Node.  Other values
336 *              could be added to enhance fault tolerance.
337 *  error     - Zero if the node has not failed.  Otherwise,
338 *              this field contains a status indicating the
339 *              failure reason.
340 *  int_address, int_value, and int_length
341 *            - These field are the Interrupt Information table
342 *              for this node in neutral format.  This is how
343 *              each node knows how to generate interrupts.
344 */
345
346typedef struct {
347  vol_u32  status;         /* node status information     */
348  vol_u32  error;          /* fatal error code            */
349  vol_u32  int_address;    /* write here for interrupt    */
350  vol_u32  int_value;      /* this value causes interrupt */
351  vol_u32  int_length;     /* for this length (0,1,2,4)   */
352  vol_u32  not_currently_used_0;
353  vol_u32  not_currently_used_1;
354  vol_u32  not_currently_used_2;
355} Shm_Node_status_control;
356
357/*  This comment block describes the contents of each field
358 *  of the Interrupt Information Table.  This table describes
359 *  how another node can generate an interrupt to this node.
360 *  This information is target board dependent.  If the
361 *  SHM Driver is in POLLED_MODE, then all fields should
362 *  be initialized to NO_INTERRUPT.
363 *
364 *  address   - The address to which another node should
365 *              write to cause an interrupt.
366 *  value     - The value which must be written
367 *  length    - The size of the value to write.  Valid
368 *              values are BYTE, WORD, and LONG.
369 *
370 *  NOTE:  The Node Status Control Block contains this
371 *         information in neutral format and not in a
372 *         structure to avoid potential alignment problems.
373 */
374
375typedef struct {
376  vol_u32 *address;        /* write here for interrupt    */
377  vol_u32  value;          /* this value causes interrupt */
378  vol_u32  length;         /* for this length (0,1,2,4)   */
379} Shm_Interrupt_information;
380
381/*  SHM Configuration Table
382 *
383 *  This comment block describes the contents of each field
384 *  of the SHM Configuration Table.
385 *
386 *  base       - The base address of the shared memory.  This
387 *               address may be specific to this node.
388 *  length     - The length of the shared memory in bytes.
389 *  format     - The natural format for rtems_unsigned32's in the
390 *               shared memory.  Valid values are currently
391 *               only SHM_LITTLE and SHM_BIG.
392 *  convert    - The address of the routine which converts
393 *               between neutral and local format.
394 *  poll_intr  - The operational mode of the driver.  Some
395 *               target boards may not provide hardware for
396 *               an interprocessor interrupt.  If POLLED_MODE
397 *               is selected, the SHM driver will install a
398 *               wrapper around the Clock_isr() to poll for
399 *               incoming packets.  Throughput is dependent
400 *               on the time between clock interrupts.
401 *               Valid values are POLLED_MODE and INTR_MODE.
402 *  cause_intr - This is the address of the routine used to
403 *               write to a particular address and cause an
404 *               interrupt on another node.  This routine
405 *               may need to be target dependent if something
406 *               other than a normal write from C does not work.
407 *  Intr       - This structure describes the operation required
408 *               to cause an interrupt to this node.  The actual
409 *               contents of this structure are described above.
410 */
411
412struct shm_config_info {
413  vol_u32           *base;     /* base address of SHM         */
414  vol_u32            length;   /* length (in bytes) of SHM    */
415  vol_u32            format;   /* SHM is big or little endian */
416  vol_u32          (*convert)();/* neutral conversion routine */
417  vol_u32            poll_intr;/* POLLED or INTR driven mode  */
418  void             (*cause_intr)( rtems_unsigned32 );
419  Shm_Interrupt_information   Intr;     /* cause intr information      */
420};
421
422typedef struct shm_config_info shm_config_table;
423
424/* global variables */
425
426#ifdef _SHM_INIT
427#define SHM_EXTERN
428#else
429#define SHM_EXTERN extern
430#endif
431
432SHM_EXTERN shm_config_table             *Shm_Configuration;
433SHM_EXTERN Shm_Interrupt_information     Shm_Interrupt_table[16];
434SHM_EXTERN Shm_Node_status_control      *Shm_Node_statuses;
435SHM_EXTERN Shm_Locked_queue_Control     *Shm_Locked_queues;
436SHM_EXTERN Shm_Envelope_control         *Shm_Envelopes;
437SHM_EXTERN rtems_configuration_table    *Shm_RTEMS_Configuration;
438SHM_EXTERN rtems_multiprocessing_table  *Shm_RTEMS_MP_Configuration;
439SHM_EXTERN rtems_unsigned32              Shm_Receive_message_count;
440SHM_EXTERN rtems_unsigned32              Shm_Null_message_count;
441SHM_EXTERN rtems_unsigned32              Shm_Interrupt_count;
442SHM_EXTERN rtems_unsigned32              Shm_Local_node;
443SHM_EXTERN Shm_Locked_queue_Control      *Shm_Local_receive_queue;
444SHM_EXTERN Shm_Node_status_control       *Shm_Local_node_status;
445SHM_EXTERN rtems_unsigned32              Shm_isrstat;
446                                                     /* reported by shmdr */
447
448SHM_EXTERN rtems_unsigned32 Shm_Pending_initialization;
449SHM_EXTERN rtems_unsigned32 Shm_Initialization_complete;
450SHM_EXTERN rtems_unsigned32 Shm_Active_node;
451
452SHM_EXTERN rtems_unsigned32 Shm_Maximum_nodes;
453SHM_EXTERN rtems_unsigned32 Shm_Maximum_envelopes;
454
455SHM_EXTERN rtems_unsigned32 Shm_Locked_queue_End_of_list;
456SHM_EXTERN rtems_unsigned32 Shm_Locked_queue_Not_on_list;
457
458/* functions */
459
460/* locked queue routines */
461void           Shm_Locked_queue_Add(
462                  Shm_Locked_queue_Control *, Shm_Envelope_control * );
463Shm_Envelope_control *Shm_Locked_queue_Get( Shm_Locked_queue_Control * );
464void           Shm_Locked_queue_Initialize(
465                  Shm_Locked_queue_Control *, rtems_unsigned32 );
466            /* Shm_Initialize_lock is CPU dependent */
467            /* Shm_Lock is CPU dependent */
468            /* Shm_Unlock is CPU dependent */
469
470/* portable routines */
471void           Init_env_pool();
472void           Shm_Print_statistics( void );
473void           MPCI_Fatal( rtems_unsigned32 );
474rtems_task     Shm_Cause_interrupt( rtems_unsigned32 );
475void           Shm_Poll();
476void           Shm_setclockvec();
477void           Shm_Convert_packet( rtems_packet_prefix * );
478
479/* CPU specific routines are inlined in shmcpu.h */
480
481/* target specific routines */
482void          *Shm_Convert_address( void * );
483void           Shm_Get_configuration( rtems_unsigned32, shm_config_table ** );
484void           Shm_isr();
485void           Shm_setvec( void );
486
487void           Shm_Initialize_lock( Shm_Locked_queue_Control * );
488void           Shm_Lock( Shm_Locked_queue_Control * );
489void           Shm_Unlock( Shm_Locked_queue_Control * );
490
491/* MPCI entry points */
492rtems_mpci_entry Shm_Get_packet(
493  rtems_packet_prefix **
494);
495
496rtems_mpci_entry Shm_Initialization(
497  rtems_configuration_table   *configuration,
498  rtems_cpu_table             *cpu_configuration,
499  rtems_multiprocessing_table *mp_configuration
500);
501
502rtems_mpci_entry Shm_Receive_packet(
503  rtems_packet_prefix **
504);
505
506rtems_mpci_entry Shm_Return_packet(
507  rtems_packet_prefix *
508);
509
510rtems_mpci_entry Shm_Send_packet(
511  rtems_unsigned32,
512  rtems_packet_prefix *
513);
514
515extern rtems_mpci_table MPCI_table;
516
517#ifdef _SHM_INIT
518
519/* multiprocessor communications interface (MPCI) table */
520
521rtems_mpci_table MPCI_table  = {
522  100000,                     /* default timeout value in ticks */
523  MAX_PACKET_SIZE,            /* maximum packet size */
524  Shm_Initialization,         /* initialization procedure   */
525  Shm_Get_packet,             /* get packet procedure       */
526  Shm_Return_packet,          /* return packet procedure    */
527  Shm_Send_packet,            /* packet send procedure      */
528  Shm_Receive_packet          /* packet receive procedure   */
529};
530
531#endif
532
533#ifdef __cplusplus
534}
535#endif
536
537#endif
538/* end of include file */
Note: See TracBrowser for help on using the repository browser.