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