source: rtems-docs/bsp-howto/shared_memory_support.rst @ 12dccfe

5
Last change on this file since 12dccfe was 12dccfe, checked in by Sebastian Huber <sebastian.huber@…>, on 01/09/19 at 15:14:05

Remove superfluous "All rights reserved."

  • Property mode set to 100644
File size: 7.8 KB
Line 
1.. comment SPDX-License-Identifier: CC-BY-SA-4.0
2
3.. Copyright (C) 1988, 2009 On-Line Applications Research Corporation (OAR)
4
5Shared Memory Support Driver
6****************************
7
8The Shared Memory Support Driver is responsible for providing glue routines and
9configuration information required by the Shared Memory Multiprocessor
10Communications Interface (MPCI).  The Shared Memory Support Driver tailors the
11portable Shared Memory Driver to a particular target platform.
12
13This driver is only required in shared memory multiprocessing systems that use
14the RTEMS mulitprocessing support.  For more information on RTEMS
15multiprocessing capabilities and the MPCI, refer to the *Multiprocessing
16Manager* chapter of the *RTEMS Application C User's Guide*.
17
18Shared Memory Configuration Table
19=================================
20
21The Shared Memory Configuration Table is defined in the following structure:
22
23.. code-block:: c
24
25    typedef volatile uint32_t vol_u32;
26
27    typedef struct {
28      vol_u32 *address;        /* write here for interrupt    */
29      vol_u32  value;          /* this value causes interrupt */
30      vol_u32  length;         /* for this length (0,1,2,4)   */
31    } Shm_Interrupt_information;
32
33    struct shm_config_info {
34      vol_u32           *base;                     /* base address of SHM         */
35      vol_u32            length;                   /* length (in bytes) of SHM    */
36      vol_u32            format;                   /* SHM is big or little endian */
37      vol_u32          (*convert)();               /* neutral conversion routine  */
38      vol_u32            poll_intr;                /* POLLED or INTR driven mode  */
39      void             (*cause_intr)( uint32_t );
40      Shm_Interrupt_information Intr;              /* cause intr information      */
41    };
42
43    typedef struct shm_config_info shm_config_table;
44
45where the fields are defined as follows:
46
47``base``
48    is the base address of the shared memory buffer used to pass messages
49    between the nodes in the system.
50
51``length``
52    is the length (in bytes) of the shared memory buffer used to pass messages
53    between the nodes in the system.
54
55``format``
56    is either ``SHM_BIG`` or ``SHM_LITTLE`` to indicate that the neutral format
57    of the shared memory area is big or little endian.  The format of the
58    memory should be chosen to match most of the inter-node traffic.
59
60``convert``
61    is the address of a routine which converts from native format to neutral
62    format.  Ideally, the neutral format is the same as the native format so
63    this routine is quite simple.
64
65``poll_intr``, ``cause_intr``
66    is either ``INTR_MODE`` or ``POLLED_MODE`` to indicate how the node will be
67    informed of incoming messages.
68
69``Intr``
70    is the information required to cause an interrupt on a node.  This
71    structure contains the following fields:
72
73    ``address``
74        is the address to write at to cause an interrupt on that node.  For a
75        polled node, this should be NULL.
76
77    ``value``
78        is the value to write to cause an interrupt.
79
80    ``length``
81        is the length of the entity to write on the node to cause an interrupt.
82        This can be 0 to indicate polled operation, 1 to write a byte, 2 to
83        write a sixteen-bit entity, and 4 to write a thirty-two bit entity.
84
85Primitives
86==========
87
88Convert Address
89---------------
90
91The ``Shm_Convert_address`` is responsible for converting an address of an
92entity in the shared memory area into the address that should be used from this
93node.  Most targets will simply return the address passed to this routine.
94However, some target boards will have a special window onto the shared memory.
95For example, some VMEbus boards have special address windows to access
96addresses that are normally reserved in the CPU's address space.
97
98.. code-block:: c
99
100    void *Shm_Convert_address( void *address )
101    {
102      return the local address version of this bus address
103    }
104
105Get Configuration
106-----------------
107
108The ``Shm_Get_configuration`` routine is responsible for filling in the Shared
109Memory Configuration Table passed to it.
110
111.. code-block:: c
112
113    void Shm_Get_configuration(
114      uint32_t           localnode,
115      shm_config_table **shmcfg
116    )
117    {
118      fill in the Shared Memory Configuration Table
119    }
120
121Locking Primitives
122------------------
123
124This is a collection of routines that are invoked by the portable part of the
125Shared Memory Driver to manage locks in the shared memory buffer area.
126Accesses to the shared memory must be atomic.  Two nodes in a multiprocessor
127system must not be manipulating the shared data structures simultaneously.  The
128locking primitives are used to insure this.
129
130To avoid deadlock, local processor interrupts should be disabled the entire
131time the locked queue is locked.
132
133The locking primitives operate on the lock ``field`` of the
134``Shm_Locked_queue_Control`` data structure.  This structure is defined as
135follows:
136
137.. code-block:: c
138
139    typedef struct {
140      vol_u32 lock;  /* lock field for this queue    */
141      vol_u32 front; /* first envelope on queue      */
142      vol_u32 rear;  /* last envelope on queue       */
143      vol_u32 owner; /* receiving (i.e. owning) node */
144    } Shm_Locked_queue_Control;
145
146where each field is defined as follows:
147
148``lock``
149    is the lock field.  Every node in the system must agree on how this field
150    will be used.  Many processor families provide an atomic "test and set"
151    instruction that is used to manage this field.
152
153``front``
154    is the index of the first message on this locked queue.
155
156``rear``
157    is the index of the last message on this locked queue.
158
159``owner``
160    is the node number of the node that currently has this structure locked.
161
162Initializing a Shared Lock
163~~~~~~~~~~~~~~~~~~~~~~~~~~
164
165The ``Shm_Initialize_lock`` routine is responsible for initializing the lock
166field.  This routines usually is implemented as follows:
167
168.. code-block:: c
169
170    void Shm_Initialize_lock(
171      Shm_Locked_queue_Control *lq_cb
172    )
173    {
174      lq_cb->lock = LQ_UNLOCKED;
175    }
176
177Acquiring a Shared Lock
178~~~~~~~~~~~~~~~~~~~~~~~
179
180The ``Shm_Lock`` routine is responsible for acquiring the lock field.
181Interrupts should be disabled while that lock is acquired.  If the lock is
182currently unavailble, then the locking routine should delay a few microseconds
183to allow the other node to release the lock.  Doing this reduces bus contention
184for the lock.  This routines usually is implemented as follows:
185
186.. code-block:: c
187
188    void Shm_Lock(
189      Shm_Locked_queue_Control *lq_cb
190    )
191    {
192      disable processor interrupts
193        set Shm_isrstat to previous interrupt disable level
194
195      while ( TRUE ) {
196        atomically attempt to acquire the lock
197        if the lock was acquired
198          return
199        delay some small period of time
200      }
201    }
202
203Releasing a Shared Lock
204~~~~~~~~~~~~~~~~~~~~~~~
205
206The ``Shm_Unlock`` routine is responsible for releasing the lock field and
207reenabling processor interrupts.  This routines usually is implemented as
208follows:
209
210.. code-block:: c
211
212    void Shm_Unlock(
213      Shm_Locked_queue_Control *lq_cb
214    )
215    {
216      set the lock to the unlocked value
217      reenable processor interrupts to their level prior
218        to the lock being acquired.  This value was saved
219        in the global variable Shm_isrstat
220    }
221
222Installing the MPCI ISR
223=======================
224
225The ``Shm_setvec`` is invoked by the portable portion of the shared memory to
226install the interrupt service routine that is invoked when an incoming message
227is announced.  Some target boards support an interprocessor interrupt or
228mailbox scheme and this is where the ISR for that interrupt would be installed.
229
230On an interrupt driven node, this routine would be implemented
231as follows:
232
233.. code-block:: c
234
235    void Shm_setvec( void )
236    {
237      install the interprocessor communications ISR
238    }
239
240On a polled node, this routine would be empty.
Note: See TracBrowser for help on using the repository browser.