source: rtems/bsps/include/shm_driver.h @ 2afb22b

5
Last change on this file since 2afb22b was 2afb22b, checked in by Chris Johns <chrisj@…>, on Dec 23, 2017 at 7:18:56 AM

Remove make preinstall

A speciality of the RTEMS build system was the make preinstall step. It
copied header files from arbitrary locations into the build tree. The
header files were included via the -Bsome/build/tree/path GCC command
line option.

This has at least seven problems:

  • The make preinstall step itself needs time and disk space.
  • Errors in header files show up in the build tree copy. This makes it hard for editors to open the right file to fix the error.
  • There is no clear relationship between source and build tree header files. This makes an audit of the build process difficult.
  • The visibility of all header files in the build tree makes it difficult to enforce API barriers. For example it is discouraged to use BSP-specifics in the cpukit.
  • An introduction of a new build system is difficult.
  • Include paths specified by the -B option are system headers. This may suppress warnings.
  • The parallel build had sporadic failures on some hosts.

This patch removes the make preinstall step. All installed header
files are moved to dedicated include directories in the source tree.
Let @RTEMS_CPU@ be the target architecture, e.g. arm, powerpc, sparc,
etc. Let @RTEMS_BSP_FAMILIY@ be a BSP family base directory, e.g.
erc32, imx, qoriq, etc.

The new cpukit include directories are:

  • cpukit/include
  • cpukit/score/cpu/@RTEMS_CPU@/include
  • cpukit/libnetworking

The new BSP include directories are:

  • bsps/include
  • bsps/@RTEMS_CPU@/include
  • bsps/@RTEMS_CPU@/@RTEMS_BSP_FAMILIY@/include

There are build tree include directories for generated files.

The include directory order favours the most general header file, e.g.
it is not possible to override general header files via the include path
order.

The "bootstrap -p" option was removed. The new "bootstrap -H" option
should be used to regenerate the "headers.am" files.

Update #3254.

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