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