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