source: rtems-docs/bsp-howto/shared_memory_support.rst @ 969e60e

5
Last change on this file since 969e60e was cc1d3fa, checked in by Chris Johns <chrisj@…>, on 11/09/16 at 01:33:08

bsp-howto: Fix header levels.

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