OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [lib/] [libbsp/] [shmdr/] [shm_driver.h] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.