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)
360 }
361 #endif /* defined (__cplusplus) */
363 #endif /* ti_ipc_Ipc__include */