source: rtems/c/src/lib/libbsp/shmdr/shm_driver.h @ a858910

4.104.114.84.95
Last change on this file since a858910 was 98e4ebf5, checked in by Joel Sherrill <joel.sherrill@…>, on 10/08/97 at 15:45:54

Fixed typo in the pointer to the license terms.

  • Property mode set to 100644
File size: 19.6 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-1997.
10 *  On-Line Applications Research Corporation (OAR).
11 *  Copyright assigned to U.S. Government, 1994.
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.OARcorp.com/rtems/license.html.
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(mips64orion)
134#define SHM_LOCK_VALUE    0x80000000
135#define SHM_UNLOCK_VALUE  0
136#elif defined(hppa1_1)
137#define SHM_LOCK_VALUE    0
138#define SHM_UNLOCK_VALUE  1
139#elif defined(ppc)
140#define SHM_LOCK_VALUE    1
141#define SHM_UNLOCK_VALUE  0
142#elif defined(unix)
143#define SHM_LOCK_VALUE    0
144#define SHM_UNLOCK_VALUE  1
145#elif defined(no_cpu)               /* for this values are irrelevant */
146#define SHM_LOCK_VALUE    1
147#define SHM_UNLOCK_VALUE  0
148#else
149#error "shm.h - no SHM_LOCK_VALUE defined for this CPU architecture"
150#endif
151
152#define Shm_Convert( value ) \
153  ((Shm_Configuration->convert) ? \
154    (*Shm_Configuration->convert)(value) : (value))
155
156/* constants */
157
158#define SHM_MASTER                  1     /* master initialization node */
159#define SHM_FIRST_NODE              1
160
161/* size constants */
162
163#define KILOBYTE          (1024)
164#define MEGABYTE          (1024*1024)
165
166/* inter-node interrupt values */
167
168#define NO_INTERRUPT            0     /* used for polled nodes */
169#define BYTE                    1
170#define WORD                    2
171#define LONG                    4
172
173/* operational mode constants -- used in SHM Configuration Table */
174#define POLLED_MODE             0
175#define INTR_MODE               1
176
177/* error codes */
178
179#define NO_ERROR                0
180#define SHM_NO_FREE_PKTS        0xf0000
181
182/* null pointers of different types */
183
184#define NULL_ENV_CB             ((Shm_Envelope_control *) 0)
185#define NULL_CONVERT            0
186
187/*
188 * size of stuff before preamble in envelope.
189 * It must be a constant since we will use it to generate MAX_PACKET_SIZE
190 */
191 
192#define SHM_ENVELOPE_PREFIX_OVERHEAD    (4 * sizeof(vol_u32))
193
194/*
195 *  The following is adjusted so envelopes are MAX_ENVELOPE_SIZE bytes long.
196 *  It must be >= RTEMS_MINIMUM_PACKET_SIZE in mppkt.h.
197 */
198 
199#ifndef MAX_ENVELOPE_SIZE
200#define MAX_ENVELOPE_SIZE 0x180
201#endif
202
203#define MAX_PACKET_SIZE  (MAX_ENVELOPE_SIZE -               \
204                          SHM_ENVELOPE_PREFIX_OVERHEAD +    \
205                          sizeof(Shm_Envelope_preamble) +   \
206                          sizeof(Shm_Envelope_postamble))
207
208
209/* constants pertinent to Locked Queue routines */
210
211#define LQ_UNLOCKED              SHM_UNLOCK_VALUE
212#define LQ_LOCKED                SHM_LOCK_VALUE
213
214/* constants related to the Free Envelope Pool */
215
216#define FREE_ENV_POOL            0
217#define FREE_ENV_CB              (&Shm_Locked_queues[ FREE_ENV_POOL ])
218
219/*  The following are important when dealing with
220 *  the shared memory communications interface area.
221 *
222 *  NOTE: The starting address and length of the shared memory
223 *        is defined in a system dependent file.
224 */
225
226#define START_NS_CBS     ((void *)Shm_Configuration->base)
227#define START_LQ_CBS     ((START_NS_CBS) + \
228        ( (sizeof (Shm_Node_status_control)) * (Shm_Maximum_nodes + 1) ) )
229#define START_ENVELOPES  ( ((void *) START_LQ_CBS) + \
230        ( (sizeof (Shm_Locked_queue_Control)) * (Shm_Maximum_nodes + 1) ) )
231#define END_SHMCI_AREA    ( (void *) START_ENVELOPES + \
232        ( (sizeof (Shm_Envelope_control)) * Shm_Maximum_envelopes ) )
233#define END_SHARED_MEM   (START_NS_CBS+Shm_Configuration->length)
234
235/* macros */
236
237#define Shm_Is_master_node()  \
238  ( SHM_MASTER == Shm_Local_node )
239
240#define Shm_Free_envelope( ecb ) \
241  Shm_Locked_queue_Add( FREE_ENV_CB, (ecb) )
242#define Shm_Allocate_envelope() \
243  Shm_Locked_queue_Get(FREE_ENV_CB)
244
245#define Shm_Initialize_receive_queue(node) \
246  Shm_Locked_queue_Initialize( &Shm_Locked_queues[node], node )
247
248#define Shm_Append_to_receive_queue(node, ecb) \
249  Shm_Locked_queue_Add( &Shm_Locked_queues[node], (ecb) )
250
251#define Shm_Envelope_control_to_packet_prefix_pointer(ecb)  \
252   ((void *)(ecb)->packet)
253
254#define Shm_Packet_prefix_to_envelope_control_pointer( pkt )   \
255   ((Shm_Envelope_control *)((rtems_unsigned8 *)(pkt) - \
256   (sizeof(Shm_Envelope_preamble) + SHM_ENVELOPE_PREFIX_OVERHEAD)))
257
258#define Shm_Build_preamble(ecb, node) \
259       (ecb)->Preamble.endian = Shm_Configuration->format
260
261#define Shm_Build_postamble( ecb )
262
263/* volatile types */
264
265typedef volatile rtems_unsigned8  vol_u8;
266typedef volatile rtems_unsigned32 vol_u32;
267
268/* shm control information */
269
270struct shm_info {
271  vol_u32 not_currently_used_0;
272  vol_u32 not_currently_used_1;
273  vol_u32 not_currently_used_2;
274  vol_u32 not_currently_used_3;
275};
276
277typedef struct {
278  /*byte start_of_text;*/
279  vol_u32 endian;
280  vol_u32 not_currently_used_0;
281  vol_u32 not_currently_used_1;
282  vol_u32 not_currently_used_2;
283} Shm_Envelope_preamble;
284
285typedef struct {
286} Shm_Envelope_postamble;
287
288/* WARNING! If you change this structure, don't forget to change
289 *          SHM_ENVELOPE_PREFIX_OVERHEAD and
290 *          Shm_Packet_prefix_to_envelope_control_pointer() above.
291 */
292
293/*  This comment block describes the contents of each field
294 *  of the Envelope Control Block:
295 *
296 *  next      - The index of the next envelope on this queue.
297 *  queue     - The index of the queue this envelope is on.
298 *  index     - The index of this envelope.
299 *  Preamble  - Generic packet preamble.  One day this structure
300 *              could be enhanced to contain routing information.
301 *  packet    - RTEMS MPCI packet.  Untouched by SHM Driver
302 *              other than copying and format conversion as
303 *              documented in the RTEMS User's Guide.
304 *  Postamble - Generic packet postamble.  One day this structure
305 *              could be enhanced to contain checksum information.
306 */
307
308typedef struct {
309  vol_u32           next;     /* next envelope on queue       */
310  vol_u32           queue;    /* queue on which this resides  */
311  vol_u32           index;    /* index into array of envelopes*/
312  vol_u32           pad0;     /* insure the next one is aligned */
313  Shm_Envelope_preamble    Preamble; /* header information           */
314  vol_u8            packet[MAX_PACKET_SIZE]; /* RTEMS INFO    */
315  Shm_Envelope_postamble   Postamble;/* trailer information          */
316} Shm_Envelope_control;
317
318/*  This comment block describes the contents of each field
319 *  of the Locked Queue Control Block:
320 *
321 *  lock      - Lock used to insure mutually exclusive access.
322 *  front     - Index of first envelope on queue.  This field
323 *              is used to remove head of queue (receive).
324 *  rear      - Index of last envelope on queue.  This field
325 *              is used to add evelope to queue (send).
326 *  owner     - The node number of the recipient (owning) node.
327 *              RTEMS does not use the node number zero (0).
328 *              The zero node is used by the SHM Driver for the
329 *              Free Envelope Queue shared by all nodes.
330 */
331
332typedef struct {
333  vol_u32 lock;  /* lock field for this queue    */
334  vol_u32 front; /* first envelope on queue      */
335  vol_u32 rear;  /* last envelope on queue       */
336  vol_u32 owner; /* receiving (i.e. owning) node */
337} Shm_Locked_queue_Control;
338
339/*  This comment block describes the contents of each field
340 *  of the Node Status Control Block:
341 *
342 *  status    - Node status.  Current values are Pending Initialization,
343 *              Initialization Complete, and Active Node.  Other values
344 *              could be added to enhance fault tolerance.
345 *  error     - Zero if the node has not failed.  Otherwise,
346 *              this field contains a status indicating the
347 *              failure reason.
348 *  int_address, int_value, and int_length
349 *            - These field are the Interrupt Information table
350 *              for this node in neutral format.  This is how
351 *              each node knows how to generate interrupts.
352 */
353
354typedef struct {
355  vol_u32  status;         /* node status information     */
356  vol_u32  error;          /* fatal error code            */
357  vol_u32  int_address;    /* write here for interrupt    */
358  vol_u32  int_value;      /* this value causes interrupt */
359  vol_u32  int_length;     /* for this length (0,1,2,4)   */
360  vol_u32  not_currently_used_0;
361  vol_u32  not_currently_used_1;
362  vol_u32  not_currently_used_2;
363} Shm_Node_status_control;
364
365/*  This comment block describes the contents of each field
366 *  of the Interrupt Information Table.  This table describes
367 *  how another node can generate an interrupt to this node.
368 *  This information is target board dependent.  If the
369 *  SHM Driver is in POLLED_MODE, then all fields should
370 *  be initialized to NO_INTERRUPT.
371 *
372 *  address   - The address to which another node should
373 *              write to cause an interrupt.
374 *  value     - The value which must be written
375 *  length    - The size of the value to write.  Valid
376 *              values are BYTE, WORD, and LONG.
377 *
378 *  NOTE:  The Node Status Control Block contains this
379 *         information in neutral format and not in a
380 *         structure to avoid potential alignment problems.
381 */
382
383typedef struct {
384  vol_u32 *address;        /* write here for interrupt    */
385  vol_u32  value;          /* this value causes interrupt */
386  vol_u32  length;         /* for this length (0,1,2,4)   */
387} Shm_Interrupt_information;
388
389/*  SHM Configuration Table
390 *
391 *  This comment block describes the contents of each field
392 *  of the SHM Configuration Table.
393 *
394 *  base       - The base address of the shared memory.  This
395 *               address may be specific to this node.
396 *  length     - The length of the shared memory in bytes.
397 *  format     - The natural format for rtems_unsigned32's in the
398 *               shared memory.  Valid values are currently
399 *               only SHM_LITTLE and SHM_BIG.
400 *  convert    - The address of the routine which converts
401 *               between neutral and local format.
402 *  poll_intr  - The operational mode of the driver.  Some
403 *               target boards may not provide hardware for
404 *               an interprocessor interrupt.  If POLLED_MODE
405 *               is selected, the SHM driver will install a
406 *               wrapper around the Clock_isr() to poll for
407 *               incoming packets.  Throughput is dependent
408 *               on the time between clock interrupts.
409 *               Valid values are POLLED_MODE and INTR_MODE.
410 *  cause_intr - This is the address of the routine used to
411 *               write to a particular address and cause an
412 *               interrupt on another node.  This routine
413 *               may need to be target dependent if something
414 *               other than a normal write from C does not work.
415 *  Intr       - This structure describes the operation required
416 *               to cause an interrupt to this node.  The actual
417 *               contents of this structure are described above.
418 */
419
420struct shm_config_info {
421  vol_u32           *base;     /* base address of SHM         */
422  vol_u32            length;   /* length (in bytes) of SHM    */
423  vol_u32            format;   /* SHM is big or little endian */
424  vol_u32          (*convert)();/* neutral conversion routine */
425  vol_u32            poll_intr;/* POLLED or INTR driven mode  */
426  void             (*cause_intr)( rtems_unsigned32 );
427  Shm_Interrupt_information   Intr;     /* cause intr information      */
428};
429
430typedef struct shm_config_info shm_config_table;
431
432/* global variables */
433
434#ifdef _SHM_INIT
435#define SHM_EXTERN
436#else
437#define SHM_EXTERN extern
438#endif
439
440SHM_EXTERN shm_config_table             *Shm_Configuration;
441SHM_EXTERN Shm_Interrupt_information    *Shm_Interrupt_table;
442SHM_EXTERN Shm_Node_status_control      *Shm_Node_statuses;
443SHM_EXTERN Shm_Locked_queue_Control     *Shm_Locked_queues;
444SHM_EXTERN Shm_Envelope_control         *Shm_Envelopes;
445SHM_EXTERN rtems_configuration_table    *Shm_RTEMS_Configuration;
446SHM_EXTERN rtems_multiprocessing_table  *Shm_RTEMS_MP_Configuration;
447SHM_EXTERN rtems_unsigned32              Shm_Receive_message_count;
448SHM_EXTERN rtems_unsigned32              Shm_Null_message_count;
449SHM_EXTERN rtems_unsigned32              Shm_Interrupt_count;
450SHM_EXTERN rtems_unsigned32              Shm_Local_node;
451SHM_EXTERN Shm_Locked_queue_Control      *Shm_Local_receive_queue;
452SHM_EXTERN Shm_Node_status_control       *Shm_Local_node_status;
453SHM_EXTERN rtems_unsigned32              Shm_isrstat;
454                                                     /* reported by shmdr */
455
456SHM_EXTERN rtems_unsigned32 Shm_Pending_initialization;
457SHM_EXTERN rtems_unsigned32 Shm_Initialization_complete;
458SHM_EXTERN rtems_unsigned32 Shm_Active_node;
459
460SHM_EXTERN rtems_unsigned32 Shm_Maximum_nodes;
461SHM_EXTERN rtems_unsigned32 Shm_Maximum_envelopes;
462
463SHM_EXTERN rtems_unsigned32 Shm_Locked_queue_End_of_list;
464SHM_EXTERN rtems_unsigned32 Shm_Locked_queue_Not_on_list;
465
466/* functions */
467
468/* locked queue routines */
469void           Shm_Locked_queue_Add(
470                  Shm_Locked_queue_Control *, Shm_Envelope_control * );
471Shm_Envelope_control *Shm_Locked_queue_Get( Shm_Locked_queue_Control * );
472void           Shm_Locked_queue_Initialize(
473                  Shm_Locked_queue_Control *, rtems_unsigned32 );
474            /* Shm_Initialize_lock is CPU dependent */
475            /* Shm_Lock is CPU dependent */
476            /* Shm_Unlock is CPU dependent */
477
478/* portable routines */
479void           Init_env_pool();
480void           Shm_Print_statistics( void );
481void           MPCI_Fatal( Internal_errors_Source, boolean, rtems_unsigned32 );
482rtems_task     Shm_Cause_interrupt( rtems_unsigned32 );
483void           Shm_Poll();
484void           Shm_setclockvec();
485void           Shm_Convert_packet( rtems_packet_prefix * );
486
487/* CPU specific routines are inlined in shmcpu.h */
488
489/* target specific routines */
490void          *Shm_Convert_address( void * );
491void           Shm_Get_configuration( rtems_unsigned32, shm_config_table ** );
492void           Shm_isr();
493void           Shm_setvec( void );
494
495void           Shm_Initialize_lock( Shm_Locked_queue_Control * );
496void           Shm_Lock( Shm_Locked_queue_Control * );
497void           Shm_Unlock( Shm_Locked_queue_Control * );
498
499/* MPCI entry points */
500rtems_mpci_entry Shm_Get_packet(
501  rtems_packet_prefix **
502);
503
504rtems_mpci_entry Shm_Initialization( void );
505
506rtems_mpci_entry Shm_Receive_packet(
507  rtems_packet_prefix **
508);
509
510rtems_mpci_entry Shm_Return_packet(
511  rtems_packet_prefix *
512);
513
514rtems_mpci_entry Shm_Send_packet(
515  rtems_unsigned32,
516  rtems_packet_prefix *
517);
518
519extern rtems_mpci_table MPCI_table;
520
521#ifdef _SHM_INIT
522
523/* multiprocessor communications interface (MPCI) table */
524
525rtems_mpci_table MPCI_table  = {
526  100000,                     /* default timeout value in ticks */
527  MAX_PACKET_SIZE,            /* maximum packet size */
528  Shm_Initialization,         /* initialization procedure   */
529  Shm_Get_packet,             /* get packet procedure       */
530  Shm_Return_packet,          /* return packet procedure    */
531  Shm_Send_packet,            /* packet send procedure      */
532  Shm_Receive_packet          /* packet receive procedure   */
533};
534
535#endif
536
537#ifdef __cplusplus
538}
539#endif
540
541#endif
542/* end of include file */
Note: See TracBrowser for help on using the repository browser.