1 /* --COPYRIGHT--,BSD
2 * Copyright (c) $(CPYYEAR), 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 * --/COPYRIGHT--*/
32 /*
33 * ======== SharedRegion.xdc ========
34 *
35 *! Revision History
36 *! ================
37 *! 23-Mar-2010 skp cdoc updates
38 *! 02-Oct-2009 jv Added cacheEnable, cacheAlign flags, rename
39 *! Info to TableEntry, add support for single image.
40 *! 05-Jun-2009 jv Implement code review comments
41 *! 20-Mar-2009 jv change the types for meta function so they work.
42 *! 05-Feb-2009 jv Applied code review comments.
43 *! 29-Nov-2009 jv Copy from interface to here. Add Info functions.
44 *! 20-Nov-2008 jv Created from design review.
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 * An example of a SharedRegion configuration is as follows:
112 *
113 * @p(code) 114 *
115 * var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
116 * SharedRegion.setEntryMeta(0,
117 * { base: 0x80000000,
118 * len: 0x20000,
119 * ownerProcId: 0,
120 * isValid: true,
121 * cacheLineSize: 64,
122 * name: "DDR2",
123 * });
124 *
125 * @p 126 *
127 * The shared region table along with a shared region pointer (SRPtr)
128 * is used to do address translation at runtime. The shared region
129 * pointer is a 32-bit portable pointer composed of an id and offset.
130 * The most significant bits of a SRPtr are used for the id.
131 * The id corresponds to the index of the entry in the table.
132 * The offset is the offset from the base of the shared memory region.
133 * The number of entries in the table determines the number of bits to
134 * use for the id. Increasing the number of entries increases the
135 * range of ids but decreases the range of the offset.
136 *
137 * Note: Region 0 must be visible by all processors. Region 0 is used for
138 * synchonizing the processors, creating the default GateMP, and
139 * creating Notify and MessageQ transport instances. The HeapMemMP
140 * created in Region 0 is the length of the region minus memory
141 * reserved for creating these internal instances.
142 *
143 * Refer to the doxygen documentation for run-time API documenation.
144 *
145 */
146
147 module SharedRegion
148 {
149 /*!
150 * ======== RegionView ========
151 * @_nodoc 152 */
153 metaonlystruct RegionView {
154 String base;
155 String end;
156 String len;
157 UInt16 ownerProcId;
158 Bool cacheEnable;
159 Bool isValid;
160 UInt16 cacheLineSize;
161 SizeT reservedSize;
162 Ptr heap;
163 String name;
164 };
165
166 /*!
167 * ======== rovViewInfo ========
168 * @_nodoc 169 */
170 @Facet
171 metaonlyconfig xdc.rov.ViewInfo.Instance rovViewInfo =
172 xdc.rov.ViewInfo.create({
173 viewMap: [
174 ['Regions',
175 {
176 type: xdc.rov.ViewInfo.MODULE_DATA,
177 viewInitFxn: 'viewInitRegions',
178 structName: 'RegionView'
179 }
180 ]
181 ]
182 });
183
184 /*!
185 * Definition of shared region pointer type
186 */
187 typedef Bits32 SRPtr;
188
189 /*!
190 * Assert raised when the id is larger than numEntries.
191 */
192 config xdc.runtime.Assert.Id A_idTooLarge =
193 {msg: "A_idTooLarge: id cannot be larger than numEntries"};
194
195 /*!
196 * Assert raised when an address is out of the range of the region id.
197 */
198 config xdc.runtime.Assert.Id A_addrOutOfRange =
199 {msg: "A_addrOutOfRange: Address is out of region id's range"};
200
201 /*!
202 * Assert raised when attempting to clear region 0
203 */
204 config xdc.runtime.Assert.Id A_region0Clear =
205 {msg: "A_region0Clear: Region 0 cannot be cleared"};
206
207 /*!
208 * Assert raised when region zero is invalid
209 */
210 config xdc.runtime.Assert.Id A_region0Invalid =
211 {msg: "A_region0Invalid: Region zero is invalid"};
212
213 /*!
214 * Assert raised when region is invalid
215 */
216 config xdc.runtime.Assert.Id A_regionInvalid =
217 {msg: "A_regionInvalid: Region is invalid"};
218
219 /*!
220 * Assert raised when the trying to reserve too much memory.
221 */
222 config xdc.runtime.Assert.Id A_reserveTooMuch =
223 {msg: "A_reserveTooMuch: Trying to reserve too much memory"};
224
225 /*!
226 * Assert raised when cache enabled but cache line size = 0.
227 */
228 config xdc.runtime.Assert.Id A_cacheLineSizeIsZero =
229 {msg: "A_cacheLineSizeIsZero: cache line size cannot be zero"};
230
231 /*!
232 * Assert raised when a new entry overlaps an existing one.
233 */
234 config xdc.runtime.Assert.Id A_overlap =
235 {msg: "A_overlap: Shared region overlaps"};
236
237 /*!
238 * Assert raised when a valid table entry already exists.
239 */
240 config xdc.runtime.Assert.Id A_alreadyExists =
241 {msg: "A_alreadyExists: Trying to overwrite an existing valid entry"};
242
243 /*!
244 * Assert raised when trying to use a heap for a region that has no heap
245 */
246 config xdc.runtime.Assert.Id A_noHeap =
247 {msg: "A_noHeap: Region has no heap"};
248
249 /*!
250 * ======== Entry ========
251 * Structure for specifying a region.
252 *
253 * Each region entry should not overlap with any other entry. The
254 * length of a region should be the same across all processors.
255 *
256 * During static configuration, the 'isValid' field can be set to 'false'
257 * to signify a partially completed entry. This should only be done
258 * if the base address of the entry is not known during static
259 * configuration. The entry can be completed and the
260 * 'isValid' field can be set to true at runtime.
261 *
262 * @field(base) The base address.
263 * @field(len) The length.
264 * @field(ownerProcId) MultiProc id of processor that manages region.
265 * @field(isValid) Whether the region is valid or not.
266 * @field(cacheEnable) Whether the region is cacheable.
267 * @field(cacheLineSize) The cache line size for the region.
268 * @field(createHeap) Whether a heap is created for the region.
269 * @field(name) The name associated with the region.
270 */
271 struct Entry {
272 Ptr base;
273 SizeT len;
274 UInt16 ownerProcId;
275 Bool isValid;
276 Bool cacheEnable;
277 SizeT cacheLineSize;
278 Bool createHeap;
279 String name;
280 };
281
282 /*! Specifies the invalid id */
283 const UInt16 INVALIDREGIONID = 0xFFFF;
284
285 /*! Specifies the default owner proc id */
286 const UInt16 DEFAULTOWNERID = ~0;
287
288 /*!
289 * Worst-case cache line size
290 *
291 * This is the default system cache line size for all modules.
292 * When a module puts structures in shared memory, this value is
293 * used to make sure items are aligned on a cache line boundary.
294 * If no cacheLineSize is specified for a region, it will use this
295 * value.
296 */
297 config SizeT cacheLineSize = 128;
298
299 /*!
300 * The number of shared region table entries.
301 *
302 * This value is used for calculating the number of bits for the offset.
303 * Note: This value must be the same across all processors in the system.
304 * Increasing this parameter will increase the footprint and
305 * the time for translating a pointer to a SRPtr.
306 */
307 config UInt16 numEntries = 4;
308
309 /*!
310 * Determines whether address translation is required.
311 *
312 * This configuration parameter should be set to 'false' if and only if all
313 * shared memory regions have the same base address for all processors.
314 * If 'false', it results in a fast {@link #getPtr} and {@link #getSRPtr},
315 * because a SRPtr is equivalent to a Ptr and no translation is done.
316 */
317 config Bool translate = true;
318
319 /*! @_nodoc 320 * Value that corresponds to NULL in SRPtr address space.
321 */
322 config SRPtr INVALIDSRPTR = 0xFFFFFFFF;
323
324 /*! @_nodoc 325 * ======== attach ========
326 * Opens a heap, for non-owner processors, for each SharedRegion.
327 *
328 * Function is called in Ipc_attach().
329 */
330 Int attach(UInt16 remoteProcId);
331
332 /*! @_nodoc 333 * ======== clearReservedMemory ========
334 * Clears the reserve memory for each region in the table.
335 */
336 Void clearReservedMemory();
337
338 /*!
339 * ======== getCacheLineSizeMeta ========
340 * Meta version of Ipc_getCacheLineSize
341 */
342 metaonly SizeT getCacheLineSizeMeta(UInt16 id);
343
344 /*! @_nodoc 345 * ======== getIdMeta ========
346 * Returns the region id for a given local address
347 *
348 * @param(addr) Address to retrieve the shared region pointer.
349 *
350 * @b(returns) region id
351 */
352 metaonly UInt16 getIdMeta(Ptr addr);
353
354 /*! @_nodoc 355 * ======== getPtrMeta ========
356 * Meta version of {@link #getPtr}
357 */
358 metaonly Ptr getPtrMeta(SRPtr srptr);
359
360 /*! @_nodoc 361 * ======== getPtrMeta$view ========
362 * ROV-time version of getPtrMeta
363 *
364 * @param(srptr) Shared region pointer.
365 *
366 * @b(returns) Pointer associated with shared region pointer.
367 */
368 metaonly Ptr getPtrMeta$view(SRPtr srptr);
369
370 /*! @_nodoc 371 * ======== getSRPtrMeta ========
372 * Meta version of {@link #getSRPtr}
373 */
374 metaonly SRPtr getSRPtrMeta(Ptr addr);
375
376 /*! @_nodoc 377 * ======== getSRPtrMeta$view ========
378 * ROV-time version of getSRPtrMeta
379 *
380 * @param(addr) Address to retrieve the shared region pointer.
381 *
382 * @b(returns) Shared region pointer.
383 */
384 metaonly SRPtr getSRPtrMeta$view(Ptr addr);
385
386 /*! @_nodoc 387 * ======== isCacheEnabledMeta ========
388 * Meta version of {@link #isCacheEnabled}
389 */
390 metaonly Bool isCacheEnabledMeta(UInt16 id);
391
392 /*! @_nodoc 393 * ======== reserveMemory ========
394 * Reserves the specified amount of memory from the specified region id.
395 *
396 * Must be called before Ipc_start(). The amount of memory reserved
397 * must be the same on all cores.
398 * The return pointer is the starting address that was reserved.
399 *
400 * @param(id) Region id.
401 * @param(size) Amount of memory to reserve.
402 *
403 * @b(returns) Starting address of memory reserved.
404 */
405 Ptr reserveMemory(UInt16 id, SizeT size);
406
407 /*!
408 * ======== setEntryMeta ========
409 * Sets the entry at the specified region id in the shared region table.
410 *
411 * The required parameters are base and len. All the other fields will
412 * get their default if not specified.
413 *
414 * @param(id) Region id.
415 * @param(entry) Entry fields about the region.
416 */
417 metaonly Void setEntryMeta(UInt16 id, Entry entry);
418
419 /*! @_nodoc 420 * ======== start ========
421 * Creates a heap by owner of region for each SharedRegion.
422 *
423 * Function is called by Ipc_start(). Requires that SharedRegion 0
424 * be valid before calling start().
425 */
426 Int start();
427
428
429 internal:
430
431 const UInt32 CREATED = 0x08111963;
432
433 /* Information stored on a per region basis */
434 struct Region {
435 Entry entry;
436 SizeT reservedSize;
437 IHeap.Handle heap;
438 };
439
440 /* Temporary storage of shared regions */
441 metaonlyconfig Entry entry[];
442
443 /* internal to keep track of the number of entries added */
444 metaonlyconfig UInt entryCount;
445
446 /* number of bits for the offset for a SRPtr. This value is calculated */
447 config UInt32 numOffsetBits;
448
449 /* offset bitmask using for generating a SRPtr */
450 config UInt32 offsetMask;
451
452 /*
453 * ======== checkOverlap ========
454 * Determines if there is an overlap with an existing entry
455 *
456 * @param(base) Base address of the region
457 * @param(len) Size of the region
458 *
459 * @b(returns) Status if successful or not.
460 */
461 Int checkOverlap(Ptr base, SizeT len);
462
463 /*
464 * ======== Module State structure ========
465 * The regions array contains information for each shared region entry.
466 * The size of the table will be determined by the number of entries.
467 */
468 struct Module_State {
469 Region regions[];
470 };
471 }
472