1 /*
2 * Copyright (c) 2012-2013, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 /*
33 * ======== SharedRegion.xdc ========
34 *
35 */
37 package ti.sdo.ipc;
39 import xdc.runtime.Error;
40 import xdc.runtime.IHeap;
41 import xdc.rov.ViewInfo;
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 * Note: Prior to calling Ipc_start(), If a SharedRegion's 'isValid'
102 * is true and 'createHeap' is true then the owner of the SharedRegion
103 * must be the same as the owner of SharedRegion 0.
104 *
105 * An example of a SharedRegion configuration is as follows:
106 *
107 * @p(code)
108 *
109 * var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
110 * SharedRegion.setEntryMeta(0,
111 * { base: 0x80000000,
112 * len: 0x20000,
113 * ownerProcId: 0,
114 * isValid: true,
115 * cacheLineSize: 64,
116 * name: "DDR2",
117 * });
118 *
119 * @p
120 *
121 * The shared region table along with a shared region pointer (SRPtr)
122 * is used to do address translation at runtime. The shared region
123 * pointer is a 32-bit portable pointer composed of an id and offset.
124 * The most significant bits of a SRPtr are used for the id.
125 * The id corresponds to the index of the entry in the table.
126 * The offset is the offset from the base of the shared memory region.
127 * The number of entries in the table determines the number of bits to
128 * use for the id. Increasing the number of entries increases the
129 * range of ids but decreases the range of the offset.
130 *
131 * Note: Region 0 must be visible by all processors. Region 0 is used for
132 * synchonizing the processors, creating the default GateMP, and
133 * creating Notify and MessageQ transport instances. The HeapMemMP
134 * created in Region 0 is the length of the region minus memory
135 * reserved for creating these internal instances.
136 *
137 * Refer to the doxygen documentation for run-time API documenation.
138 *
139 */
141 module SharedRegion
142 {
143 /*!
144 * ======== RegionView ========
145 * @_nodoc
146 */
147 metaonly struct RegionView {
148 UInt16 id;
149 String base;
150 String end;
151 String len;
152 UInt16 ownerProcId;
153 Bool cacheEnable;
154 Bool isValid;
155 UInt16 cacheLineSize;
156 SizeT reservedSize;
157 Ptr heap;
158 String name;
159 };
161 /*!
162 * ======== rovViewInfo ========
163 * @_nodoc
164 */
165 @Facet
166 metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
167 xdc.rov.ViewInfo.create({
168 viewMap: [
169 ['Regions',
170 {
171 type: xdc.rov.ViewInfo.MODULE_DATA,
172 viewInitFxn: 'viewInitRegions',
173 structName: 'RegionView'
174 }
175 ]
176 ]
177 });
179 /*!
180 * Definition of shared region pointer type
181 */
182 typedef Bits32 SRPtr;
184 /*!
185 * Assert raised when the id is larger than numEntries.
186 */
187 config xdc.runtime.Assert.Id A_idTooLarge =
188 {msg: "A_idTooLarge: id cannot be larger than numEntries"};
190 /*!
191 * Assert raised when an address is out of the range of the region id.
192 */
193 config xdc.runtime.Assert.Id A_addrOutOfRange =
194 {msg: "A_addrOutOfRange: Address is out of region id's range"};
196 /*!
197 * Assert raised when attempting to clear region 0
198 */
199 config xdc.runtime.Assert.Id A_region0Clear =
200 {msg: "A_region0Clear: Region 0 cannot be cleared"};
202 /*!
203 * Assert raised when region zero is invalid
204 */
205 config xdc.runtime.Assert.Id A_region0Invalid =
206 {msg: "A_region0Invalid: Region zero is invalid"};
208 /*!
209 * Assert raised when region is invalid
210 */
211 config xdc.runtime.Assert.Id A_regionInvalid =
212 {msg: "A_regionInvalid: Region is invalid"};
214 /*!
215 * Assert raised when the trying to reserve too much memory.
216 */
217 config xdc.runtime.Assert.Id A_reserveTooMuch =
218 {msg: "A_reserveTooMuch: Trying to reserve too much memory"};
220 /*!
221 * Assert raised when cache enabled but cache line size = 0.
222 */
223 config xdc.runtime.Assert.Id A_cacheLineSizeIsZero =
224 {msg: "A_cacheLineSizeIsZero: cache line size cannot be zero"};
226 /*!
227 * Assert raised when a new entry overlaps an existing one.
228 */
229 config xdc.runtime.Assert.Id A_overlap =
230 {msg: "A_overlap: Shared region overlaps"};
232 /*!
233 * Assert raised when a valid table entry already exists.
234 */
235 config xdc.runtime.Assert.Id A_alreadyExists =
236 {msg: "A_alreadyExists: Trying to overwrite an existing valid entry"};
238 /*!
239 * Assert raised when trying to use a heap for a region that has no heap
240 */
241 config xdc.runtime.Assert.Id A_noHeap =
242 {msg: "A_noHeap: Region has no heap"};
244 /*!
245 * ======== Entry ========
246 * Structure for specifying a region.
247 *
248 * Each region entry should not overlap with any other entry. The
249 * length of a region should be the same across all processors.
250 *
251 * During static configuration, the 'isValid' field can be set to 'false'
252 * to signify a partially completed entry. This should only be done
253 * if the base address of the entry is not known during static
254 * configuration. The entry can be completed and the
255 * 'isValid' field can be set to true at runtime.
256 *
257 * @field(base) The base address.
258 * @field(len) The length.
259 * @field(ownerProcId) MultiProc id of processor that manages region.
260 * @field(isValid) Whether the region is valid or not.
261 * @field(cacheEnable) Whether the region is cacheable.
262 * @field(cacheLineSize) The cache line size for the region.
263 * @field(createHeap) Whether a heap is created for the region.
264 * @field(name) The name associated with the region.
265 */
266 struct Entry {
267 Ptr base;
268 SizeT len;
269 UInt16 ownerProcId;
270 Bool isValid;
271 Bool cacheEnable;
272 SizeT cacheLineSize;
273 Bool createHeap;
274 String name;
275 };
277 /*! Specifies the invalid id */
278 const UInt16 INVALIDREGIONID = 0xFFFF;
280 /*! Specifies the default owner proc id */
281 const UInt16 DEFAULTOWNERID = ~0;
283 /*!
284 * Worst-case cache line size
285 *
286 * This is the default system cache line size for all modules.
287 * When a module puts structures in shared memory, this value is
288 * used to make sure items are aligned on a cache line boundary.
289 * If no cacheLineSize is specified for a region, it will use this
290 * value.
291 */
292 config SizeT cacheLineSize = 128;
294 /*!
295 * The number of shared region table entries.
296 *
297 * This value is used for calculating the number of bits for the offset.
298 * Note: This value must be the same across all processors in the system.
299 * Increasing this parameter will increase the footprint and
300 * the time for translating a pointer to a SRPtr.
301 */
302 config UInt16 numEntries = 4;
304 /*!
305 * Determines whether address translation is required.
306 *
307 * This configuration parameter should be set to 'false' if and only if all
308 * shared memory regions have the same base address for all processors.
309 * If 'false', it results in a fast {@link #getPtr} and {@link #getSRPtr},
310 * because a SRPtr is equivalent to a Ptr and no translation is done.
311 */
312 config Bool translate = true;
314 /*! @_nodoc
315 * Value that corresponds to NULL in SRPtr address space.
316 */
317 config SRPtr INVALIDSRPTR = 0xFFFFFFFF;
319 /*! @_nodoc
320 * ======== attach ========
321 * Opens a heap, for non-owner processors, for each SharedRegion.
322 *
323 * Function is called in Ipc_attach().
324 */
325 Int attach(UInt16 remoteProcId);
327 /*! @_nodoc
328 * ======== clearReservedMemory ========
329 * Clears the reserve memory for each region in the table.
330 */
331 Void clearReservedMemory();
333 /*! @_nodoc
334 * ======== detach ========
335 * Close the heap, for non-owner processors when detaching from the owner.
336 *
337 * Function is called in Ipc_detach().
338 */
339 Int detach(UInt16 remoteProcId);
341 /*!
342 * ======== genSectionInCmd ========
343 * Enable/Disable generation of output section in linker cmd file
344 *
345 * This function can be called for each shared region to not generate
346 * an output section in the linker command file. By default all shared
347 * region entries generate an output section in the linker command file.
348 *
349 * @param(id) Region id.
350 * @param(gen) TRUE - generate, FALSE - don't generate
351 */
352 metaonly Void genSectionInCmd(UInt16 id, Bool gen);
354 /*!
355 * ======== getCacheLineSizeMeta ========
356 * Meta version of Ipc_getCacheLineSize
357 */
358 metaonly SizeT getCacheLineSizeMeta(UInt16 id);
360 /*! @_nodoc
361 * ======== getIdMeta ========
362 * Returns the region id for a given local address
363 *
364 * @param(addr) Address to retrieve the shared region pointer.
365 *
366 * @b(returns) region id
367 */
368 metaonly UInt16 getIdMeta(Ptr addr);
370 /*! @_nodoc
371 * ======== getPtrMeta ========
372 * Meta version of {@link #getPtr}
373 */
374 metaonly Ptr getPtrMeta(SRPtr srptr);
376 /*! @_nodoc
377 * ======== getPtrMeta$view ========
378 * ROV-time version of getPtrMeta
379 *
380 * @param(srptr) Shared region pointer.
381 *
382 * @b(returns) Pointer associated with shared region pointer.
383 */
384 metaonly Ptr getPtrMeta$view(SRPtr srptr);
386 /*! @_nodoc
387 * ======== getSRPtrMeta ========
388 * Meta version of {@link #getSRPtr}
389 */
390 metaonly SRPtr getSRPtrMeta(Ptr addr);
392 /*! @_nodoc
393 * ======== getSRPtrMeta$view ========
394 * ROV-time version of getSRPtrMeta
395 *
396 * @param(addr) Address to retrieve the shared region pointer.
397 *
398 * @b(returns) Shared region pointer.
399 */
400 metaonly SRPtr getSRPtrMeta$view(Ptr addr);
402 /*! @_nodoc
403 * ======== isCacheEnabledMeta ========
404 * Meta version of {@link #isCacheEnabled}
405 */
406 metaonly Bool isCacheEnabledMeta(UInt16 id);
408 /*! @_nodoc
409 * ======== reserveMemory ========
410 * Reserves the specified amount of memory from the specified region id.
411 *
412 * Must be called before Ipc_start(). The amount of memory reserved
413 * must be the same on all cores.
414 * The return pointer is the starting address that was reserved.
415 *
416 * @param(id) Region id.
417 * @param(size) Amount of memory to reserve.
418 *
419 * @b(returns) Starting address of memory reserved.
420 */
421 Ptr reserveMemory(UInt16 id, SizeT size);
423 /*! @_nodoc
424 * ======== resetInternalFields ========
425 * Reset the internal fields of a region.
426 *
427 * This function is called in Ipc_stop() to reset the reservedSize
428 * and heap handle. It should not be called by the user.
429 *
430 * @param(id) Region id.
431 */
432 Void resetInternalFields(UInt16 id);
434 /*!
435 * ======== setEntryMeta ========
436 * Sets the entry at the specified region id in the shared region table.
437 *
438 * The required parameters are base and len. All the other fields will
439 * get their default if not specified.
440 *
441 * @param(id) Region id.
442 * @param(entry) Entry fields about the region.
443 */
444 metaonly Void setEntryMeta(UInt16 id, Entry entry);
446 /*! @_nodoc
447 * ======== start ========
448 * Creates a heap by owner of region for each SharedRegion.
449 *
450 * Function is called by Ipc_start(). Requires that SharedRegion 0
451 * be valid before calling start().
452 */
453 Int start();
455 /*! @_nodoc
456 * ======== stop ========
457 * Undo what was done by start.
458 *
459 * This function is called by Ipc_stop(). It deletes any heap that
460 * was created in start for the owner of any SharedRegion. For
461 * non-owners, it doesn't do anything.
462 */
463 Int stop();
466 internal:
468 const UInt32 CREATED = 0x08111963;
470 /* Information stored on a per region basis */
471 struct Region {
472 Entry entry;
473 SizeT reservedSize;
474 IHeap.Handle heap;
475 };
477 /* temporary storage of shared regions */
478 metaonly config Entry entry[];
480 /* generate linker section for shared regions */
481 metaonly config Bool genSectionInLinkCmd[];
483 /* internal to keep track of the number of entries added */
484 metaonly config UInt entryCount;
486 /* number of bits for the offset for a SRPtr. This value is calculated */
487 config UInt32 numOffsetBits;
489 /* offset bitmask using for generating a SRPtr */
490 config UInt32 offsetMask;
492 /*
493 * ======== checkOverlap ========
494 * Determines if there is an overlap with an existing entry
495 *
496 * @param(base) Base address of the region
497 * @param(len) Size of the region
498 *
499 * @b(returns) Status if successful or not.
500 */
501 Int checkOverlap(Ptr base, SizeT len);
503 /*
504 * ======== Module State structure ========
505 * The regions array contains information for each shared region entry.
506 * The size of the table will be determined by the number of entries.
507 */
508 struct Module_State {
509 Region regions[];
510 };
511 }