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 38 39 40 41 42 43 44 45
46
47 package ti.sdo.ipc;
48
49 import xdc.runtime.Error;
50 import xdc.runtime.IHeap;
51 import xdc.rov.ViewInfo;
52
53 /*!
54 * ======== SharedRegion ========
55 * Shared memory manager and address translator.
56 *
57 * @p(html)
58 * This module has a common header that can be found in the {@link ti.ipc}
59 * package. Application code should include the common header file (not the
60 * RTSC-generated one):
61 *
62 * <PRE>#include <ti/ipc/SharedRegion.h></PRE>
63 *
64 * The RTSC module must be used in the application's RTSC configuration file
65 * (.cfg) if runtime APIs will be used in the application:
66 *
67 * <PRE>SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');</PRE>
68 *
69 * Documentation for all runtime APIs, instance configuration parameters,
70 * error codes macros and type definitions available to the application
71 * integrator can be found in the
72 * <A HREF="../../../../doxygen/html/files.html">Doxygen documenation</A>
73 * for the IPC product. However, the documentation presented on this page
74 * should be referred to for information specific to the RTSC module, such as
75 * module configuration, Errors, and Asserts.
76 * @p
77 *
78 * The SharedRegion module is designed to be used in a multi-processor
79 * environment in which memory regions are shared and accessed
80 * across different processors. The module itself does not use any shared
81 * memory, because all module state is stored locally. SharedRegion
82 * APIs use the system gate for thread protection.
83 *
84 * This module creates and stores a local shared memory region table. The
85 * table contains the processor's view for every shared region in the system.
86 * The table must not contain any overlapping regions. Each processor's
87 * view of a particular shared memory region is determined by the region id.
88 * In cases where a processor cannot access a certain shared memory region,
89 * that shared memory region should be left invalid for that processor.
90 * Note: The {@link #numEntries} must be the same on all processors.
91 *
92 * Each shared region contains the following:
93 * @p(blist)
94 * -base: The base address
95 * -len: The length
96 * -name: The name of the region
97 * -isValid: Whether the region is valid
98 * -ownerProcId: The id of the processor which owns the region
99 * -cacheEnable: Whether the region is cacheable
100 * -cacheLineSize: The cache line size
101 * -createHeap: Whether a heap is created for the region.
102 * @p
103 *
104 * A region is added statically using the {@link #setEntryMeta} API.
105 * The length of a region must be the same across all processors.
106 * The owner of the region can be specified. If specified, the owner
107 * manages the shared region. It creates a HeapMemMP instance which spans
108 * the full size of the region. The other processors open the same HeapMemMP
109 * instance.
110 *
111 * Note: Prior to calling Ipc_start(), If a SharedRegion's 'isValid'
112 * is true and 'createHeap' is true then the owner of the SharedRegion
113 * must be the same as the owner of SharedRegion 0.
114 *
115 * An example of a SharedRegion configuration is as follows:
116 *
117 * @p(code)
118 *
119 * var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
120 * SharedRegion.setEntryMeta(0,
121 * { base: 0x80000000,
122 * len: 0x20000,
123 * ownerProcId: 0,
124 * isValid: true,
125 * cacheLineSize: 64,
126 * name: "DDR2",
127 * });
128 *
129 * @p
130 *
131 * The shared region table along with a shared region pointer (SRPtr)
132 * is used to do address translation at runtime. The shared region
133 * pointer is a 32-bit portable pointer composed of an id and offset.
134 * The most significant bits of a SRPtr are used for the id.
135 * The id corresponds to the index of the entry in the table.
136 * The offset is the offset from the base of the shared memory region.
137 * The number of entries in the table determines the number of bits to
138 * use for the id. Increasing the number of entries increases the
139 * range of ids but decreases the range of the offset.
140 *
141 * Note: Region 0 must be visible by all processors. Region 0 is used for
142 * synchonizing the processors, creating the default GateMP, and
143 * creating Notify and MessageQ transport instances. The HeapMemMP
144 * created in Region 0 is the length of the region minus memory
145 * reserved for creating these internal instances.
146 *
147 * Refer to the doxygen documentation for run-time API documenation.
148 *
149 */
150
151 module SharedRegion
152 {
153 /*!
154 * ======== RegionView ========
155 * @_nodoc
156 */
157 metaonly struct RegionView {
158 UInt16 id;
159 String base;
160 String end;
161 String len;
162 UInt16 ownerProcId;
163 Bool cacheEnable;
164 Bool isValid;
165 UInt16 cacheLineSize;
166 SizeT reservedSize;
167 Ptr heap;
168 String name;
169 };
170
171 /*!
172 * ======== rovViewInfo ========
173 * @_nodoc
174 */
175 @Facet
176 metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
177 xdc.rov.ViewInfo.create({
178 viewMap: [
179 ['Regions',
180 {
181 type: xdc.rov.ViewInfo.MODULE_DATA,
182 viewInitFxn: 'viewInitRegions',
183 structName: 'RegionView'
184 }
185 ]
186 ]
187 });
188
189 /*!
190 * Definition of shared region pointer type
191 */
192 typedef Bits32 SRPtr;
193
194 /*!
195 * Assert raised when the id is larger than numEntries.
196 */
197 config xdc.runtime.Assert.Id A_idTooLarge =
198 {msg: "A_idTooLarge: id cannot be larger than numEntries"};
199
200 /*!
201 * Assert raised when an address is out of the range of the region id.
202 */
203 config xdc.runtime.Assert.Id A_addrOutOfRange =
204 {msg: "A_addrOutOfRange: Address is out of region id's range"};
205
206 /*!
207 * Assert raised when attempting to clear region 0
208 */
209 config xdc.runtime.Assert.Id A_region0Clear =
210 {msg: "A_region0Clear: Region 0 cannot be cleared"};
211
212 /*!
213 * Assert raised when region zero is invalid
214 */
215 config xdc.runtime.Assert.Id A_region0Invalid =
216 {msg: "A_region0Invalid: Region zero is invalid"};
217
218 /*!
219 * Assert raised when region is invalid
220 */
221 config xdc.runtime.Assert.Id A_regionInvalid =
222 {msg: "A_regionInvalid: Region is invalid"};
223
224 /*!
225 * Assert raised when the trying to reserve too much memory.
226 */
227 config xdc.runtime.Assert.Id A_reserveTooMuch =
228 {msg: "A_reserveTooMuch: Trying to reserve too much memory"};
229
230 /*!
231 * Assert raised when cache enabled but cache line size = 0.
232 */
233 config xdc.runtime.Assert.Id A_cacheLineSizeIsZero =
234 {msg: "A_cacheLineSizeIsZero: cache line size cannot be zero"};
235
236 /*!
237 * Assert raised when a new entry overlaps an existing one.
238 */
239 config xdc.runtime.Assert.Id A_overlap =
240 {msg: "A_overlap: Shared region overlaps"};
241
242 /*!
243 * Assert raised when a valid table entry already exists.
244 */
245 config xdc.runtime.Assert.Id A_alreadyExists =
246 {msg: "A_alreadyExists: Trying to overwrite an existing valid entry"};
247
248 /*!
249 * Assert raised when trying to use a heap for a region that has no heap
250 */
251 config xdc.runtime.Assert.Id A_noHeap =
252 {msg: "A_noHeap: Region has no heap"};
253
254 /*!
255 * ======== Entry ========
256 * Structure for specifying a region.
257 *
258 * Each region entry should not overlap with any other entry. The
259 * length of a region should be the same across all processors.
260 *
261 * During static configuration, the 'isValid' field can be set to 'false'
262 * to signify a partially completed entry. This should only be done
263 * if the base address of the entry is not known during static
264 * configuration. The entry can be completed and the
265 * 'isValid' field can be set to true at runtime.
266 *
267 * @field(base) The base address.
268 * @field(len) The length.
269 * @field(ownerProcId) MultiProc id of processor that manages region.
270 * @field(isValid) Whether the region is valid or not.
271 * @field(cacheEnable) Whether the region is cacheable.
272 * @field(cacheLineSize) The cache line size for the region.
273 * @field(createHeap) Whether a heap is created for the region.
274 * @field(name) The name associated with the region.
275 */
276 struct Entry {
277 Ptr base;
278 SizeT len;
279 UInt16 ownerProcId;
280 Bool isValid;
281 Bool cacheEnable;
282 SizeT cacheLineSize;
283 Bool createHeap;
284 String name;
285 };
286
287 /*! Specifies the invalid id */
288 const UInt16 INVALIDREGIONID = 0xFFFF;
289
290 /*! Specifies the default owner proc id */
291 const UInt16 DEFAULTOWNERID = ~0;
292
293 /*!
294 * Worst-case cache line size
295 *
296 * This is the default system cache line size for all modules.
297 * When a module puts structures in shared memory, this value is
298 * used to make sure items are aligned on a cache line boundary.
299 * If no cacheLineSize is specified for a region, it will use this
300 * value.
301 */
302 config SizeT cacheLineSize = 128;
303
304 /*!
305 * The number of shared region table entries.
306 *
307 * This value is used for calculating the number of bits for the offset.
308 * Note: This value must be the same across all processors in the system.
309 * Increasing this parameter will increase the footprint and
310 * the time for translating a pointer to a SRPtr.
311 */
312 config UInt16 numEntries = 4;
313
314 /*!
315 * Determines whether address translation is required.
316 *
317 * This configuration parameter should be set to 'false' if and only if all
318 * shared memory regions have the same base address for all processors.
319 * If 'false', it results in a fast {@link #getPtr} and {@link #getSRPtr},
320 * because a SRPtr is equivalent to a Ptr and no translation is done.
321 */
322 config Bool translate = true;
323
324 /*! @_nodoc
325 * Value that corresponds to NULL in SRPtr address space.
326 */
327 config SRPtr INVALIDSRPTR = 0xFFFFFFFF;
328
329 /*! @_nodoc
330 * ======== attach ========
331 * Opens a heap, for non-owner processors, for each SharedRegion.
332 *
333 * Function is called in Ipc_attach().
334 */
335 Int attach(UInt16 remoteProcId);
336
337 /*! @_nodoc
338 * ======== clearReservedMemory ========
339 * Clears the reserve memory for each region in the table.
340 */
341 Void clearReservedMemory();
342
343 /*!
344 * ======== getCacheLineSizeMeta ========
345 * Meta version of Ipc_getCacheLineSize
346 */
347 metaonly SizeT getCacheLineSizeMeta(UInt16 id);
348
349 /*! @_nodoc
350 * ======== getIdMeta ========
351 * Returns the region id for a given local address
352 *
353 * @param(addr) Address to retrieve the shared region pointer.
354 *
355 * @b(returns) region id
356 */
357 metaonly UInt16 getIdMeta(Ptr addr);
358
359 /*! @_nodoc
360 * ======== getPtrMeta ========
361 * Meta version of {@link #getPtr}
362 */
363 metaonly Ptr getPtrMeta(SRPtr srptr);
364
365 /*! @_nodoc
366 * ======== getPtrMeta$view ========
367 * ROV-time version of getPtrMeta
368 *
369 * @param(srptr) Shared region pointer.
370 *
371 * @b(returns) Pointer associated with shared region pointer.
372 */
373 metaonly Ptr getPtrMeta$view(SRPtr srptr);
374
375 /*! @_nodoc
376 * ======== getSRPtrMeta ========
377 * Meta version of {@link #getSRPtr}
378 */
379 metaonly SRPtr getSRPtrMeta(Ptr addr);
380
381 /*! @_nodoc
382 * ======== getSRPtrMeta$view ========
383 * ROV-time version of getSRPtrMeta
384 *
385 * @param(addr) Address to retrieve the shared region pointer.
386 *
387 * @b(returns) Shared region pointer.
388 */
389 metaonly SRPtr getSRPtrMeta$view(Ptr addr);
390
391 /*! @_nodoc
392 * ======== isCacheEnabledMeta ========
393 * Meta version of {@link #isCacheEnabled}
394 */
395 metaonly Bool isCacheEnabledMeta(UInt16 id);
396
397 /*! @_nodoc
398 * ======== reserveMemory ========
399 * Reserves the specified amount of memory from the specified region id.
400 *
401 * Must be called before Ipc_start(). The amount of memory reserved
402 * must be the same on all cores.
403 * The return pointer is the starting address that was reserved.
404 *
405 * @param(id) Region id.
406 * @param(size) Amount of memory to reserve.
407 *
408 * @b(returns) Starting address of memory reserved.
409 */
410 Ptr reserveMemory(UInt16 id, SizeT size);
411
412 /*! @_nodoc
413 * ======== resetInternalFields ========
414 * Reset the internal fields of a region.
415 *
416 * This function is called in Ipc_stop() to reset the reservedSize
417 * and heap handle. It should not be called by the user.
418 *
419 * @param(id) Region id.
420 */
421 Void resetInternalFields(UInt16 id);
422
423 /*!
424 * ======== setEntryMeta ========
425 * Sets the entry at the specified region id in the shared region table.
426 *
427 * The required parameters are base and len. All the other fields will
428 * get their default if not specified.
429 *
430 * @param(id) Region id.
431 * @param(entry) Entry fields about the region.
432 */
433 metaonly Void setEntryMeta(UInt16 id, Entry entry);
434
435 /*! @_nodoc
436 * ======== start ========
437 * Creates a heap by owner of region for each SharedRegion.
438 *
439 * Function is called by Ipc_start(). Requires that SharedRegion 0
440 * be valid before calling start().
441 */
442 Int start();
443
444
445 internal:
446
447 const UInt32 CREATED = 0x08111963;
448
449
450 struct Region {
451 Entry entry;
452 SizeT reservedSize;
453 IHeap.Handle heap;
454 };
455
456
457 metaonly config Entry entry[];
458
459
460 metaonly config UInt entryCount;
461
462
463 config UInt32 numOffsetBits;
464
465
466 config UInt32 offsetMask;
467
468 469 470 471 472 473 474 475 476
477 Int checkOverlap(Ptr base, SizeT len);
478
479 480 481 482 483
484 struct Module_State {
485 Region regions[];
486 };
487 }
488