Initial commit
[ipc/ipcdev.git] / packages / ti / ipc / Ipc.h
1 /*
2  * Copyright (c) 2012-2013, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /** ===========================================================================
33  *  @file       Ipc.h
34  *
35  *  @brief      Ipc Manager.
36  *
37  *  This module is primarily used to configure IPC, synchronize processors, and
38  *  initialize the IPC runtime.  The memory for SharedRegion zero must be valid
39  *  before Ipc_start() can be called.  Ipc_start() must be called before any
40  *  other IPC APIs are used.
41  *
42  *  The Ipc header should be included in an application as follows:
43  *  @code
44  *  #include <ti/ipc/Ipc.h>
45  *  @endcode
46  *
47  *  ============================================================================
48  */
50 #ifndef ti_ipc_Ipc__include
51 #define ti_ipc_Ipc__include
53 #if defined (__cplusplus)
54 extern "C" {
55 #endif
57 /* =============================================================================
58  *  All success and failure codes for the module
59  * =============================================================================
60  */
62 /*!
63  *  @def    Ipc_S_BUSY
64  *  @brief  The resource is still in use
65  */
66 #define Ipc_S_BUSY              2
68 /*!
69  *  @def    Ipc_S_ALREADYSETUP
70  *  @brief  The module has been already setup
71  */
72 #define Ipc_S_ALREADYSETUP      1
74 /*!
75  *  @def    Ipc_S_SUCCESS
76  *  @brief  Operation is successful.
77  */
78 #define Ipc_S_SUCCESS           0
80 /*!
81  *  @def    Ipc_E_FAIL
82  *  @brief  Generic failure.
83  */
84 #define Ipc_E_FAIL             -1
86 /*!
87  *  @def    Ipc_E_INVALIDARG
88  *  @brief  Argument passed to function is invalid.
89  */
90 #define Ipc_E_INVALIDARG       -2
92 /*!
93  *  @def    Ipc_E_MEMORY
94  *  @brief  Operation resulted in memory failure.
95  */
96 #define Ipc_E_MEMORY           -3
98 /*!
99  *  @def    Ipc_E_ALREADYEXISTS
100  *  @brief  The specified entity already exists.
101  */
102 #define Ipc_E_ALREADYEXISTS    -4
104 /*!
105  *  @def    Ipc_E_NOTFOUND
106  *  @brief  Unable to find the specified entity.
107  */
108 #define Ipc_E_NOTFOUND         -5
110 /*!
111  *  @def    Ipc_E_TIMEOUT
112  *  @brief  Operation timed out.
113  */
114 #define Ipc_E_TIMEOUT          -6
116 /*!
117  *  @def    Ipc_E_INVALIDSTATE
118  *  @brief  Module is not initialized or in an invalid state.
119  */
120 #define Ipc_E_INVALIDSTATE     -7
122 /*!
123  *  @def    Ipc_E_OSFAILURE
124  *  @brief  A failure occurred in an OS-specific call
125  */
126 #define Ipc_E_OSFAILURE        -8
128 /*!
129  *  @def    Ipc_E_RESOURCE
130  *  @brief  Specified resource is not available
131  */
132 #define Ipc_E_RESOURCE         -9
134 /*!
135  *  @def    Ipc_E_RESTART
136  *  @brief  Operation was interrupted. Please restart the operation
137  */
138 #define Ipc_E_RESTART          -10
140 /*!
141  *  @def    Ipc_E_NOTREADY
142  *  @brief  Operation was not ready.
143  */
144 #define Ipc_E_NOTREADY         -11
147 /* =============================================================================
148  *  Ipc Module-wide Functions
149  * =============================================================================
150  */
152 /*!
153  *  @brief      Attach to remote processor
154  *
155  *  This function uses shared memory to synchronize self with the remote
156  *  processor.  Both processors must call this function to attach to each
157  *  other.  Ipc_start() must be called before calling Ipc_attach().
158  *  A processor must attach to the owner of SharedRegion zero before
159  *  it can successfully attach to another processor.  Attempting to
160  *  attach to another processor first returns #Ipc_E_FAIL.
161  *
162  *  This function opens the default GateMP and SharedRegion zero heap.
163  *  The Notify, NameServerRemoteNotify, and MessageQ transport
164  *  instances are created for communicating with the specified remote
165  *  processor in SharedRegion zero heap.  The user's Ipc attach function
166  *  is called.
167  *
168  *  For BIOS, this function should be called within a 'while' loop
169  *  within a Task.  A Task_sleep() or Task_yield() should be called
170  *  within the loop to allow other threads in the system to execute.
171  *  This function needs to be called in a loop because the remote
172  *  processor may not be in a ready state.
173  *
174  *  Note:  For BIOS, if the config parameter Ipc.procSync is set to
175  *  Ipc.ProcSync_ALL, there is no need to call this function as it is
176  *  internally called by Ipc_start().
177  *
178  *  @code
179  *  while (Ipc_attach(remoteProcId) < 0) {
180  *      Task_sleep(1);
181  *  }
182  *  @endcode
183  *
184  *  @param      remoteProcId  remote processor's MultiProc id
185  *
186  *  @return     Status
187  *              - #Ipc_S_SUCCESS: attach was successful
188  *              - #Ipc_S_ALREADYSETUP: already attached
189  *              - #Ipc_E_MEMORY: operation failed due to a memory error
190  *              - #Ipc_E_FAIL: General failure
191  *              - #Ipc_E_NOTREADY: remote processor not ready
192  *
193  *  @sa         Ipc_detach Ipc_isAttached
194  */
195 Int Ipc_attach(UInt16 remoteProcId);
197 /*!
198  *  @brief      Detach from the remote processor
199  *
200  *  A processor must detach from all other processors before it can
201  *  successfully detach from the owner of SharedRegion zero.  Attempting to
202  *  detach from the owner of SharedRegion zero first returns #Ipc_E_FAIL.
203  *
204  *  If a processor successfully attached to a remote processor 'N' times,
205  *  it must call Ipc_detach 'N' times to be completely detached.
206  *  Ipc_detach returns #Ipc_S_BUSY for the first 'N - 1' times its called.
207  *  Ipc_detach returns #Ipc_S_SUCCESS, if successful, on the 'N' time its
208  *  called.  If called on a remote processor that is detached, #Ipc_S_SUCCESS
209  *  is returned.
210  *
211  *  This function should be called within a loop to make sure the processor
212  *  successfully detached from the remote processor.
213  *  If called from the processor with the bigger procId, this function closes
214  *  the instances created for communicating with the specified remote processor.
215  *  If called from the processor with the smaller procId, this function returns
216  *  Ipc_E_NOTREADY while the processor with the bigger procId has not finished
217  *  detaching.  Once the processor with the bigger procId is finished detaching,
218  *  this function deletes the instances created for communicating with the
219  *  specified remote processor.
220  *
221  *  For BIOS, this function should be called within a 'while' loop in a Task
222  *  because the slave may have to wait for the master to detach.  Furthermore,
223  *  a Task_sleep() or Task_yield() should be called within the same 'while'
224  *  loop to allow other threads in the system to execute.
225  *
226  *  @code
227  *  while (TRUE) {
228  *      status = Ipc_detach(remoteProcId);
229  *      if (status == Ipc_E_NOTREADY) {
230  *          Task_sleep(1);
231  *      }
232  *      else if (status < 0) {
233  *          System_printf("Ipc_detach failed \n");
234  *          break;
235  *      }
236  *      else {
237  *          break;
238  *      }
239  *  }
240  *  @endcode
241  *
242  *  @param      remoteProcId  remote processor's MultiProc id
243  *
244  *  @return     Status
245  *              - #Ipc_S_SUCCESS: operation was successful
246  *              - #Ipc_S_BUSY: attach count != 0
247  *              - #Ipc_E_FAIL: operation failed
248  *              - #Ipc_E_NOTREADY: processor not ready to detach
249  *
250  *  @sa         Ipc_attach Ipc_isAttached
251  */
252 Int Ipc_detach(UInt16 remoteProcId);
254 /*!
255  *  @brief      Query whether attached to a remote processor
256  *
257  *  Returns TRUE if attached to a remote processor and FALSE otherwise.  If
258  *  remoteProcId == MultiProc_self(), FALSE is always returned.
259  *
260  *  @param      remoteProcId  remote processor's MultiProc id
261  *
262  *  @return     TRUE if attached, FALSE if not attached
263  *
264  *  @sa         Ipc_attach Ipc_detach
265  */
266 Bool Ipc_isAttached(UInt16 remoteProcId);
268 /*!
269  *  @brief      Reads the config entry from the config area.
270  *
271  *  For more information about this API, refer to the documentation for
272  *  #Ipc_writeConfig
273  *
274  *  @param      remoteProcId  remote processor's MultiProc id
275  *  @param      tag           tag to identify a config entry
276  *  @param      cfg           address where the entry will be copied
277  *  @param      size          size of config entry
278  *
279  *  @return     Status
280  *              - #Ipc_S_SUCCESS: operation was successful
281  *              - #Ipc_E_FAIL: operation failed
282  *
283  *  @sa         Ipc_writeConfig
284  */
285 Int Ipc_readConfig(UInt16 remoteProcId, UInt32 tag, Ptr cfg, SizeT size);
287 /*!
288  *  @brief      Reserves memory, creates default GateMP and HeapMemMP
289  *
290  *  This function needs to be called before Ipc_attach().  It should
291  *  only be called once, unless the return value is #Ipc_E_NOTREADY.
292  *  This indicates that either the SharedRegion zero is not valid or
293  *  has not been setup yet so Ipc_start may be called again. Once
294  *  sucessfully started, subsequent calls returns #Ipc_S_ALREADYSETUP.
295  *
296  *  Ipc reserves some shared memory in SharedRegion zero for synchronization.
297  *  GateMP reserves some shared memory for managing the gates and for the
298  *  default GateMP.  The same amount of memory must be reserved by each
299  *  processor, but only the owner of SharedRegion zero clears the reserved
300  *  memory and creates the default GateMP. The default heap for each
301  *  SharedRegion is created by the owner of each SharedRegion.
302  *
303  *  Note:  For BIOS, if the config parameter Ipc.procSync is set to
304  *  Ipc.ProcSync_ALL, this function calls Ipc_attach() internally.
305  *
306  *  @return     Status
307  *              - #Ipc_S_SUCCESS: operation was successful
308  *              - #Ipc_S_ALREADYSETUP: already successfully called
309  *              - #Ipc_E_NOTREADY: shared memory is not ready
310  *              - #Ipc_E_FAIL: operation failed
311  */
312 Int Ipc_start(Void);
314 /*!
315  *  @brief      Resets the Ipc state
316  *
317  *  This function should be called only once and only after detaching
318  *  from all processors.  Once called, Ipc is placed back to
319  *  the same state as it was before Ipc_start() was called.
320  *
321  *  @return     Status
322  *              - #Ipc_S_SUCCESS: operation was successful
323  */
324 Int Ipc_stop(Void);
326 /*!
327  *  @brief      Writes the config entry to the config area.
328  *
329  *  The #Ipc_writeConfig and #Ipc_readConfig APIs are used to pass
330  *  configuration information from one core to another.  This 'information'
331  *  is passed via a pointer to shared memory with a given size and is
332  *  identified via a unique tag.  A typical use case of this API would be
333  *  passing configuration information from a Slave core to the Host at
334  *  startup-time.  For example, if MessageQ is used, this information
335  *  might include the queue name, message heap sizes, etc.
336  *
337  *  For #Ipc_writeConfig, if 'NULL' is passed in for the cfg parameter,
338  *  it attempts to free the shared memory that is allocated by a previous
339  *  #Ipc_writeConfig call. The remoteProcId, tag, and size must match
340  *  the previous #Ipc_writeConfig call.
341  *
342  *  The #Ipc_writeConfig API writes into SharedRegion 0 (SR0) and uses
343  *  the tag to uniquely identify the structure (cfg) and size written
344  *  into SR0 which both sides must agree on.
345  *
346  *  @param      remoteProcId  remote processor's MultiProc id
347  *  @param      tag           tag to identify a config entry
348  *  @param      cfg           address where the entry will be copied
349  *  @param      size          size of config entry
350  *
351  *  @return     Status
352  *              - #Ipc_S_SUCCESS: if operation was successful
353  *              - #Ipc_E_FAIL: if operation failed
354  *
355  *  @sa         Ipc_readConfig
356  */
357 Int Ipc_writeConfig(UInt16 remoteProcId, UInt32 tag, Ptr cfg, SizeT size);
359 #if defined (__cplusplus)
361 #endif /* defined (__cplusplus) */
363 #endif /* ti_ipc_Ipc__include */