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

4.104.114.84.95
Last change on this file since 5b9d6ddf was 88d594a, checked in by Joel Sherrill <joel.sherrill@…>, on 05/24/95 at 21:39:42

Fully tested on all in-house targets

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