1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34 35
36
37 import xdc.runtime.Error;
38 import xdc.runtime.Assert;
39 import xdc.rov.ViewInfo;
40 import ti.sdo.utils.MultiProc;
41
42 /*!
43 * ======== Ipc ========
44 * IPC Master Manager
45 *
46 * @p(html)
47 * This module has a common header that can be found in the {@link ti.ipc}
48 * package. Application code should include the common header file (not the
49 * RTSC-generated one):
50 *
51 * <PRE>#include <ti/ipc/Ipc.h></PRE>
52 *
53 * The RTSC module must be used in the application's RTSC configuration file
54 * (.cfg):
55 *
56 * <PRE>Ipc = xdc.useModule('ti.sdo.ipc.Ipc');</PRE>
57 *
58 * Documentation for all runtime APIs, instance configuration parameters,
59 * error codes macros and type definitions available to the application
60 * integrator can be found in the
61 * <A HREF="../../../../doxygen/html/files.html">Doxygen documenation</A>
62 * for the IPC product. However, the documentation presented on this page
63 * should be referred to for information specific to the RTSC module, such as
64 * module configuration, Errors, and Asserts.
65 * @p
66 *
67 * The most common static configuration that is required of the Ipc module
68 * is the {@link #procSync} configuration that affects the behavior of the
69 * Ipc_start and Ipc_attach runtime APIs.
70 *
71 * Additionally, certain subsystems of IPC (such as Notify and MessageQ) can
72 * be disabled to save resources on a per-connection basis by configuring Ipc
73 * using {@link #setEntryMeta}.
74 *
75 */
76
77 @Template ("./Ipc.xdt")
78 module Ipc
79 {
80 /*!
81 * ======== ModuleView ========
82 * @_nodoc
83 */
84 metaonly struct ModuleView {
85 UInt16 remoteProcId;
86 Bool attached;
87 Bool setupNotify;
88 Bool setupMessageQ;
89 };
90
91 /*!
92 * ======== rovViewInfo ========
93 * @_nodoc
94 */
95 @Facet
96 metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
97 xdc.rov.ViewInfo.create({
98 viewMap: [
99 ['Module',
100 {
101 type: xdc.rov.ViewInfo.MODULE_DATA,
102 viewInitFxn: 'viewInitModule',
103 structName: 'ModuleView'
104 }
105 ],
106 ]
107 });
108
109 /*!
110 * Various configuration options for {@link #procSync}
111 *
112 * The values in this enum affect the behavior of the Ipc_start and
113 * Ipc_attach runtime APIs.
114 *
115 * ProcSync_ALL: Calling Ipc_start will also internally Ipc_attach to
116 * each remote processor. The application should never call Ipc_attach.
117 * This type of startup and synchronization should be used if all IPC
118 * processors on a device start up at the same time and connections should
119 * be established between every possible pair of processors.
120 *
121 * ProcSync_PAIR (default): Calling Ipc_start will perform system-wide IPC
122 * initialization required on all processor, but connections to remote
123 * processors will not be established (i.e. Ipc_attach will never be
124 * called). This configuration should be chosen if synchronization is
125 * required and some/all these conditions are true:
126 * @p(blist)
127 * - It is necessary to control when synchronization with each remote
128 * processor occurs
129 * - Useful work can be done while trying to synchronize with a remote
130 * processor by yielding a thread after each attempt to Ipc_attach
131 * to the processor.
132 * - Connections to all remote processors are unnecessary and connections
133 * should selectively be made to save memory
134 * @p
135 * NOTE: A connection should be made to the owner of region 0 (usually the
136 * processor with id = 0) before any connection to any other remote
137 * processor can be made. For example, if there are three processors
138 * configured with MultiProc, #1 should attach to #0 before it can attach
139 * to #2.
140 *
141 * ProcSync_NONE: This should be selected with caution. Ipc_start will
142 * work exactly as it does with ProcSync_PAIR. However, Ipc_attach will
143 * not synchronize with the remote processor. Callers of Ipc_attach are
144 * bound by the same restrictions imposed by using ProcSync_PAIR.
145 * Additionally, an Ipc_attach to a remote processor whose id is less than
146 * our own has to occur *after* the corresponding remote processor has
147 * called attach to the original processor. For example, processor #2
148 * can call
149 * @p(code)
150 * Ipc_attach(1);
151 * @p
152 * only after processor #1 has called:
153 * @p(code)
154 * Ipc_attach(2);
155 * @p
156 *
157 */
158 enum ProcSync {
159 ProcSync_NONE, /*! ProcSync_PAIR with no synchronization */
160 ProcSync_PAIR, /*! Ipc_start does not Ipc_attach */
161 ProcSync_ALL /*! Ipc_start attach to all remote procs */
162 };
163
164 /*!
165 * Struct used for configuration via {@link #setEntryMeta}
166 *
167 * This structure defines the fields that are to be configured
168 * between the executing processor and a remote processor.
169 */
170 struct Entry {
171 UInt16 remoteProcId; /*! Remote processor id */
172 Bool setupNotify; /*! Whether to setup Notify */
173 Bool setupMessageQ; /*! Whether to setup MessageQ */
174 };
175
176 177 178 179 180
181
182 /*!
183 * ======== A_addrNotInSharedRegion ========
184 * Assert raised when an address lies outside all known shared regions
185 */
186 config Assert.Id A_addrNotInSharedRegion = {
187 msg: "A_addrNotInSharedRegion: Address not in any shared region"
188 };
189
190 /*!
191 * ======== A_addrNotCacheAligned ========
192 * Error raised when an address is not cache-aligned
193 */
194 config Assert.Id A_addrNotCacheAligned = {
195 msg: "A_addrNotCacheAligned: Address is not cache aligned"
196 };
197
198 /*!
199 * ======== A_nullArgument ========
200 * Assert raised when a required argument is null
201 */
202 config Assert.Id A_nullArgument = {
203 msg: "A_nullArgument: Required argument is null"
204 };
205
206 /*!
207 * ======== A_nullPointer ========
208 * Assert raised when a pointer is null
209 */
210 config Assert.Id A_nullPointer = {
211 msg: "A_nullPointer: Pointer is null"
212 };
213
214 /*!
215 * ======== A_invArgument ========
216 * Assert raised when an argument is invalid
217 */
218 config Assert.Id A_invArgument = {
219 msg: "A_invArgument: Invalid argument supplied"
220 };
221
222 /*!
223 * ======== A_invParam ========
224 * Assert raised when a parameter is invalid
225 */
226 config Assert.Id A_invParam = {
227 msg: "A_invParam: Invalid configuration parameter supplied"
228 };
229
230 /*!
231 * ======== E_versionMismatch ========
232 * Error raised when a version mismatch occurs
233 *
234 * Error raised in an open call because there is
235 * a version mismatch between the opener and the creator
236 */
237 config Error.Id E_versionMismatch = {
238 msg: "E_versionMismatch: IPC Module version mismatch: creator: %d, opener: %d"
239 };
240
241 /*!
242 * ======== A_internal ========
243 * Assert raised when an internal error is encountered
244 */
245 config Assert.Id A_internal = {
246 msg: "A_internal: An internal error has occurred"
247 };
248
249 250 251 252 253
254
255 /*!
256 * ======== sr0MemorySetup ========
257 * Shared memory is present or not for shared region 0 entry.
258 */
259 metaonly config Bool sr0MemorySetup;
260
261 /*! @_nodoc
262 * ======== hostProcId ========
263 * Host processor identifier.
264 *
265 * Used to specify the host processor's id. This parameter is only used
266 * in a Syslink system.
267 */
268 metaonly config UInt16 hostProcId = MultiProc.INVALIDID;
269
270 /*!
271 * ======== procSync ========
272 * Affects how Ipc_start and Ipc_attach behave
273 *
274 * Refer to the documentation for the {@link #ProcSync} enum for
275 * information about the various ProcSync options.
276 */
277 config ProcSync procSync = Ipc.ProcSync_PAIR;
278
279 /*! @_nodoc
280 * ======== generateSlaveDataForHost ========
281 * generates the slave's data into a section for the host.
282 */
283 config Bool generateSlaveDataForHost;
284
285 /*!
286 * ======== userFxn ========
287 * Attach and Detach hooks.
288 */
289 config UserFxn userFxn;
290
291 292 293 294 295
296
297 /*!
298 * ======== getEntry ========
299 * Gets the properties for attaching to a remote processor.
300 *
301 * This function must be called before Ipc_attach(). The
302 * parameter entry->remoteProcId field must be set prior to calling
303 * the function.
304 *
305 * @param(entry) Properties between a pair of processors.
306 */
307 Void getEntry(Entry *entry);
308
309 /*!
310 * ======== setEntryMeta ========
311 * Statically sets the properties for attaching to a remote processor.
312 *
313 * This function allows the user to configure whether Notify and/or
314 * MessageQ is setup during Ipc_attach(). If 'setupNotify' is set
315 * to 'false', neither the Notify or NameServerRemoteNotify instances
316 * are created. If 'setupMessageQ' is set to 'false', the MessageQ
317 * transport instances are not created. By default, both flags are
318 * set to 'true'.
319 *
320 * Note: For any pair of processors, the flags must be the same
321 *
322 * @param(entry) Properties between a pair of processors.
323 */
324 metaonly Void setEntryMeta(Entry entry);
325
326 /*!
327 * ======== setEntry ========
328 * Sets the properties for attaching to a remote processor.
329 *
330 * This function must be called before Ipc_attach(). It allows
331 * the user to configure whether Notify and/or MessageQ is setup
332 * during Ipc_attach(). If 'setupNotify' is set to 'FALSE',
333 * neither the Notify or NameServerRemoteNotify instances are
334 * created. If 'setupMessageQ' is set to 'FALSE', the MessageQ
335 * transport instances are not created. By default, both flags are
336 * set to 'TRUE'.
337 *
338 * Note: For any pair of processors, the flags must be the same
339 *
340 * @param(entry) Properties between a pair of processors.
341 */
342 Void setEntry(Entry *entry);
343
344 /*! @_nodoc
345 * This is needed to prevent the Ipc module from being optimized away
346 * during the whole_program[_debug] partial link.
347 */
348 Void dummy();
349
350
351 internal:
352
353
354 const UInt32 PROCSYNCSTART = 1;
355
356
357 const UInt32 PROCSYNCFINISH = 2;
358
359
360 const UInt32 PROCSYNCDETACH = 3;
361
362
363 enum ObjType {
364 ObjType_CREATESTATIC = 0x1,
365 ObjType_CREATESTATIC_REGION = 0x2,
366 ObjType_CREATEDYNAMIC = 0x4,
367 ObjType_CREATEDYNAMIC_REGION = 0x8,
368 ObjType_OPENDYNAMIC = 0x10,
369 ObjType_LOCAL = 0x20
370 };
371
372 373 374 375
376 struct ConfigEntry {
377 Bits32 remoteProcId;
378 Bits32 localProcId;
379 Bits32 tag;
380 Bits32 size;
381 Bits32 next;
382 };
383
384 /*!
385 * head of the config list
386 */
387 struct ConfigHead {
388 volatile Bits32 first;
389 };
390
391 struct ProcEntry {
392 Ptr localConfigList;
393 Ptr remoteConfigList;
394 Ptr userObj;
395 Bool attached;
396 Entry entry;
397 };
398
399
400 struct Reserved {
401 volatile Bits32 startedKey;
402 SharedRegion.SRPtr notifySRPtr;
403 SharedRegion.SRPtr nsrnSRPtr;
404 SharedRegion.SRPtr transportSRPtr;
405 SharedRegion.SRPtr configListHead;
406 };
407
408 /*! struct for attach/detach plugs. */
409 struct UserFxn {
410 Int (*attach)(Ptr *, UInt16);
411 Int (*detach)(Ptr *, UInt16);
412 };
413
414
415 metaonly config Entry entry[];
416
417 /*!
418 * ======== getMasterAddr() ========
419 */
420 Ptr getMasterAddr(UInt16 remoteProcId, Ptr sharedAddr);
421
422 /*!
423 * ======== getRegion0ReservedSize ========
424 * Returns the amount of memory to be reserved for Ipc in SharedRegion 0.
425 *
426 * This is used for synchronizing processors.
427 */
428 SizeT getRegion0ReservedSize();
429
430 /*!
431 * ======== getSlaveAddr() ========
432 */
433 Ptr getSlaveAddr(UInt16 remoteProcId, Ptr sharedAddr);
434
435 /*!
436 * ======== procSyncStart ========
437 * Starts the process of synchronizing processors.
438 *
439 * Shared memory in region 0 will be used. The processor which owns
440 * SharedRegion 0 writes its reserve memory address in region 0
441 * to let the other processors know it has started. It then spins
442 * until the other processors start. The other processors write their
443 * reserve memory address in region 0 to let the owner processor
444 * know they've started. The other processors then spin until the
445 * owner processor writes to let them know its finished the process
446 * of synchronization before continuing.
447 */
448 Int procSyncStart(UInt16 remoteProcId, Ptr sharedAddr);
449
450 /*!
451 * ======== procSyncFinish ========
452 * Finishes the process of synchronizing processors.
453 *
454 * Each processor writes its reserve memory address in SharedRegion 0
455 * to let the other processors know its finished the process of
456 * synchronization.
457 */
458 Int procSyncFinish(UInt16 remoteProcId, Ptr sharedAddr);
459
460 /*!
461 * ======== reservedSizePerProc ========
462 * The amount of memory required to be reserved per processor.
463 */
464 SizeT reservedSizePerProc();
465
466 /*! Used for populated the 'objType' field in ROV views*/
467 metaonly String getObjTypeStr$view(ObjType type);
468
469
470 struct Module_State {
471 Ptr ipcSharedAddr;
472 Ptr gateMPSharedAddr;
473 ProcEntry procEntry[];
474 };
475 }
476 477 478
479