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