[processor-sdk/big-data-ipc-examples.git] / host_linux / simple_buffer_example / host / SharedRegion / src / SharedRegion.c
1 /*
2 * Copyright (c) 2008-2017, Texas Instruments Incorporated
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * * Neither the name of Texas Instruments Incorporated nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
32 /**
33 * @file SharedRegion.c
34 *
35 * @brief Shared Region Manager
36 */
38 /* Standard headers */
39 #include <assert.h>
40 #include <string.h>
41 #include <stdlib.h>
43 /* IPC headers */
44 #include <ti/ipc/Std.h>
45 #include "Std.h"
46 #include <ti/ipc/MultiProc.h>
47 #include <IGateProvider.h>
48 #include <GateMutex.h>
50 #include "Trace.h"
51 #include "Cache.h"
52 #include "Memory.h"
54 #include "_SharedRegion.h"
56 //#define ENABLE_LOCAL_LOCK
58 #define ROUNDUP(size, align) \
59 (UInt32)(((UInt32)(size) + ((UInt32)(align) - 1)) & ~((UInt32)(align) - 1))
61 /* =============================================================================
62 * Macros
63 * =============================================================================
64 */
65 /* Macro to make a correct module magic number with refCount */
66 #define SharedRegion_MAKE_MAGICSTAMP(x) ((SharedRegion_MODULEID << 16u) | (x))
68 /* =============================================================================
69 * Structure & Enums
70 * =============================================================================
71 */
73 /*!
74 * @brief Module state object.
75 */
76 typedef struct SharedRegion_ModuleObject_tag {
77 UInt32 refCount;
78 /*!< Reference count */
79 #ifdef ENABLE_LOCAL_LOCK
80 IGateProvider_Handle localLock;
81 /*!< Handle to a gate instance */
82 #endif
83 SharedRegion_Region * regions;
84 /*!< Pointer to the regions */
85 SharedRegion_Config cfg;
86 /*!< Current config values */
87 SharedRegion_Config defCfg;
88 /*!< Default config values */
89 UInt32 numOffsetBits;
90 /*!< number of bits for the offset for a SRPtr. This value is calculated */
91 UInt32 offsetMask;
92 /*!< offset bitmask using for generating a SRPtr */
93 bool isStarted;
94 /*!< indicates whether shared region start API is called */
95 UInt32 *regionRefCount;
96 /* To keep track of how many start/stop region API is called for a region*/
97 } SharedRegion_ModuleObject;
99 /* =============================================================================
100 * Global
101 * =============================================================================
102 */
103 /*!
104 * @brief Shared region state object variable with default settings
105 */
106 static
107 SharedRegion_ModuleObject SharedRegion_state = {
108 .numOffsetBits = 0,
109 .regions = NULL,
110 #ifdef ENABLE_LOCAL_LOCK
111 .localLock = NULL,
112 #endif
113 .regionRefCount = NULL,
114 .offsetMask = 0,
115 .defCfg.numEntries = 4u,
116 .defCfg.translate = TRUE,
117 .defCfg.cacheLineSize = 128u
118 };
120 /*!
121 * @var SharedRegion_module
122 *
123 * @brief Pointer to the SharedRegion module state.
124 */
125 static
126 SharedRegion_ModuleObject * SharedRegion_module = &SharedRegion_state;
128 /*!
129 * @brief SharedRegion_CREATED flag in shared memory
130 */
131 const UInt32 SharedRegion_CREATED = 0x08111963;
133 /*!
134 * @brief SharedRegion_VERSION attribute in shared memory
135 */
136 const UInt32 SharedRegion_VERSION = 1;
138 /* =============================================================================
139 * Forward declarations of internal functions
140 * =============================================================================
141 */
142 /*!
143 * @brief Checks to make sure overlap does not exists.
144 * Return error if overlap found.
145 *
146 * @param base Base of Shared Region
147 * @param len Length of Shared Region
148 *
149 * @sa None
150 */
151 static Int SharedRegion_checkOverlap (Ptr base, UInt32 len);
153 /*
154 * @brief Return the number of offsetBits bits
155 *
156 * @param None
157 *
158 * @sa None
159 */
160 static UInt32 SharedRegion_getNumOffsetBits (Void);
162 /* =============================================================================
163 * APIs
164 * =============================================================================
165 */
166 /* Function to get the configuration */
167 Void
168 SharedRegion_getConfig (SharedRegion_Config * config)
169 {
170 GT_1trace (curTrace, GT_ENTER, "SharedRegion_getConfig", config);
172 GT_assert (curTrace, (config != NULL));
174 if ((SharedRegion_module->refCount & SharedRegion_MAKE_MAGICSTAMP(0)) <
175 SharedRegion_MAKE_MAGICSTAMP(1)) {
176 memcpy ((Ptr) config,
177 (Ptr) &SharedRegion_module->defCfg,
178 sizeof (SharedRegion_Config));
179 }
180 else {
181 memcpy ((Ptr) config,
182 (Ptr) &SharedRegion_module->cfg,
183 sizeof (SharedRegion_Config));
184 }
186 GT_0trace (curTrace, GT_LEAVE, "SharedRegion_getConfig");
187 }
189 /* Function to setup the SharedRegion module. */
190 Int
191 SharedRegion_setup (SharedRegion_Config * cfg)
192 {
193 Int status = SharedRegion_S_SUCCESS;
194 UInt32 eb;
195 SharedRegion_Config tmpCfg;
196 UInt32 i;
198 GT_1trace (curTrace, GT_ENTER, "SharedRegion_setup", cfg);
199 eb=0;
201 if (cfg == NULL) {
202 SharedRegion_getConfig (&tmpCfg);
203 cfg = &tmpCfg;
204 }
206 if (cfg == NULL) {
207 SharedRegion_getConfig (&tmpCfg);
208 cfg = &tmpCfg;
209 }
211 /* This sets the refCount variable is not initialized, upper 16 bits is
212 * written with module Id to ensure correctness of refCount variable.
213 */
214 if((SharedRegion_module->refCount & SharedRegion_MAKE_MAGICSTAMP(0))
215 != SharedRegion_MAKE_MAGICSTAMP(0)) {
216 SharedRegion_module->refCount = SharedRegion_MAKE_MAGICSTAMP(0);
217 }
218 if (++SharedRegion_module->refCount
219 != SharedRegion_MAKE_MAGICSTAMP(1u)) {
220 status = SharedRegion_S_ALREADYSETUP;
221 GT_0trace (curTrace,
222 GT_2CLASS,
223 "SharedRegion Module already initialized!");
224 }
225 else {
226 /* copy the user provided values into the state object */
227 memcpy ((Ptr) &SharedRegion_module->cfg,
228 (Ptr) cfg,
229 sizeof (SharedRegion_Config));
231 /* In a single processor system, we should never translate.
232 * but on HlOS side where there are user space virtual space
233 * we should set translate = TRUE.
234 */
236 SharedRegion_module->cfg.translate = TRUE;
238 /* Allocate memory for the regions */
239 SharedRegion_module->regions = (SharedRegion_Region *)
240 malloc(sizeof(SharedRegion_Region)
241 *SharedRegion_module->cfg.numEntries);
243 SharedRegion_module->regionRefCount = malloc (sizeof (UInt32)
244 * SharedRegion_module->cfg.numEntries);
245 GT_assert(curTrace,(SharedRegion_module->regionRefCount != NULL));
247 for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
248 SharedRegion_module->regions[i].entry.base = NULL;
249 SharedRegion_module->regions[i].entry.len = 0;
250 SharedRegion_module->regions[i].entry.ownerProcId = 0;
251 SharedRegion_module->regions[i].entry.isValid = FALSE;
252 SharedRegion_module->regions[i].entry.cacheEnable = FALSE;
253 SharedRegion_module->regions[i].entry.cacheLineSize =
254 SharedRegion_module->cfg.cacheLineSize;
255 SharedRegion_module->regions[i].entry.createHeap = FALSE;
256 SharedRegion_module->regions[i].reservedSize = 0;
257 #ifdef ENABLE_HEAPMP
258 SharedRegion_module->regions[i].heap = NULL;
259 #endif
260 SharedRegion_module->regions[i].entry.name = NULL;
261 }
263 /* set the defaults for region 0 */
264 #ifdef ENABLE_HEAPMP
265 SharedRegion_module->regions[0].entry.createHeap = TRUE;
266 #endif
267 SharedRegion_module->regions[0].entry.ownerProcId = MultiProc_self();
269 SharedRegion_module->numOffsetBits = SharedRegion_getNumOffsetBits ();
270 SharedRegion_module->offsetMask =
271 (1 << SharedRegion_module->numOffsetBits) - 1;
272 SharedRegion_module->isStarted = FALSE;
273 #ifdef ENABLE_LOCAL_LOCK
274 /* Create a lock for protecting list object */
275 SharedRegion_module->localLock = (IGateProvider_Handle)
276 GateMutex_create ((GateMutex_Params*)NULL, &eb);
277 #endif
278 }
280 if (status < 0) {
281 SharedRegion_destroy ();
282 }
284 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_setup", status);
286 /*! @retval SharedRegion_SUCCESS operation was successful */
287 return status;
288 }
290 /* Function to destroy the SharedRegion module. */
291 Int
292 SharedRegion_destroy (Void)
293 {
294 Int status = SharedRegion_S_SUCCESS;
295 #ifdef ENABLE_LOCAL_LOCK
296 IArg key;
297 #endif
298 GT_0trace (curTrace, GT_ENTER, "SharedRegion_destroy");
300 if ( --SharedRegion_module->refCount
301 == SharedRegion_MAKE_MAGICSTAMP(0)) {
302 #ifdef ENABLE_LOCAL_LOCK
303 /* Enter the gate */
304 key = IGateProvider_enter (SharedRegion_module->localLock);
305 #endif
306 if (SharedRegion_module->regionRefCount != NULL) {
307 free (SharedRegion_module->regionRefCount);
308 SharedRegion_module->regionRefCount = NULL;
309 }
311 if (SharedRegion_module->regions != NULL) {
312 free (SharedRegion_module->regions);
313 SharedRegion_module->regions = NULL;
314 }
316 memset (&SharedRegion_module->cfg,
317 0,
318 sizeof (SharedRegion_Config));
320 SharedRegion_module->numOffsetBits = 0;
321 SharedRegion_module->offsetMask = 0;
322 #ifdef ENABLE_LOCAL_LOCK
323 /* Leave the gate */
324 IGateProvider_leave (SharedRegion_module->localLock, key);
325 /* Delete the local lock */
326 if (SharedRegion_module->localLock != NULL) {
327 status = GateMutex_delete ((GateMutex_Handle *)
328 &SharedRegion_module->localLock);
329 GT_assert (curTrace, (status >= 0));
330 if (status < 0) {
331 status = SharedRegion_E_FAIL;
332 }
333 }
334 #endif
335 }
337 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_destroy", status);
339 return status;
340 }
342 /* API to know whether shared region is started or not.Returns true if shared
343 * region is already started othere wise returns false.
344 */
345 Int
346 _SharedRegion_isStarted(Void)
347 {
348 return(SharedRegion_module->isStarted) ;
349 }
351 /* Creates a heap by owner of region for each SharedRegion.
352 * Function is called by Ipc_start(). Requires that SharedRegion 0
353 * be valid before calling start().
354 */
355 Int
356 SharedRegion_start (Void)
357 {
358 Int status = SharedRegion_S_SUCCESS;
359 SharedRegion_Region * region = NULL;
360 #ifdef ENABLE_HEAPMP
361 Ptr sharedAddr = NULL;
362 HeapMemMP_Handle heapHandle = NULL;
363 HeapMemMP_Params params;
364 #endif
365 Int i;
367 GT_0trace (curTrace, GT_ENTER, "SharedRegion_start");
369 /*
370 * Loop through shared regions. If an owner of a region is specified
371 * and createHeap has been specified for the SharedRegion, then
372 * the owner creates a HeapMemMP and the other processors open it.
373 */
374 for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
375 region = &(SharedRegion_module->regions[i]);
376 if (region->entry.isValid) {
377 #ifdef ENABLE_HEAPMP
378 if ((region->entry.ownerProcId == MultiProc_self())
379 && (region->entry.createHeap)
380 && (region->heap == NULL)) {
381 /* get the next free address in each region */
382 sharedAddr = (Ptr)((UInt32)region->entry.base
383 + region->reservedSize);
385 /* Create the HeapMemMP in the region. */
386 HeapMemMP_Params_init(¶ms);
387 params.sharedAddr = sharedAddr;
388 params.sharedBufSize = region->entry.len - region->reservedSize;
390 /* Adjust to account for the size of HeapMemMP_Attrs */
391 params.sharedBufSize -= (HeapMemMP_sharedMemReq(¶ms)
392 - params.sharedBufSize);
393 heapHandle = HeapMemMP_create(¶ms);
395 /* put heap handle into SharedRegion Module state */
396 region->heap = heapHandle;
397 }
398 #endif
399 SharedRegion_module->regionRefCount[i] += 1;
400 }
401 }
403 /* Set flag indiacting shared region has been started */
404 SharedRegion_module->isStarted = TRUE;
406 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_start", status);
408 return status;
409 }
411 /* Function to stop the SharedRegion module. */
412 Int
413 SharedRegion_stop (Void)
414 {
415 Int status = SharedRegion_S_SUCCESS;
416 #ifdef ENABLE_HEAPMP
417 Int tmpStatus = SharedRegion_S_SUCCESS;
418 #endif
419 SharedRegion_Region * region = NULL;
420 Int i;
422 GT_0trace (curTrace, GT_ENTER, "SharedRegion_stop");
424 /*
425 * Loop through shared regions. If an owner of a region is specified
426 * and createHeap has been specified for the SharedRegion, then
427 * the other processors close it and the owner deletes the HeapMemMP.
428 */
429 for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
430 region = &(SharedRegion_module->regions[i]);
431 if (region->entry.isValid) {
432 #ifdef ENABLE_HEAPMP
433 if ((region->entry.ownerProcId == MultiProc_self ())
434 && (region->entry.createHeap)
435 && (region->heap != NULL)) {
436 /* Delete heap */
437 tmpStatus = HeapMemMP_delete ((HeapMemMP_Handle *)
438 &(region->heap));
439 if ((tmpStatus < 0) && (status >= 0)) {
440 status = SharedRegion_E_FAIL;
441 }
442 }
443 #endif
444 memset (region, 0, sizeof (SharedRegion_Region));
445 SharedRegion_entryInit (&(region->entry));
447 SharedRegion_module->regionRefCount[i] -= 1;
448 }
449 }
451 /* set the defaults for region 0 */
452 memset (&(SharedRegion_module->regions[0]),
453 0,
454 sizeof (SharedRegion_Region));
455 SharedRegion_entryInit (&(SharedRegion_module->regions[0].entry));
456 SharedRegion_module->regions[0].entry.createHeap = TRUE;
457 SharedRegion_module->regions[0].entry.ownerProcId = MultiProc_self();
458 /* Set flag indicating shared region has been started */
459 SharedRegion_module->isStarted = FALSE;
461 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_stop", status);
463 return status;
464 }
466 /* Opens a heap, for non-owner processors, for each SharedRegion. */
467 Int
468 SharedRegion_attach (UInt16 remoteProcId)
469 {
470 Int status = SharedRegion_S_SUCCESS;
471 SharedRegion_Region * region = NULL;
472 #ifdef ENABLE_HEAPMP
473 Ptr sharedAddr = NULL;
474 #endif
475 Int i;
477 GT_1trace (curTrace, GT_ENTER, "SharedRegion_attach", remoteProcId);
479 GT_assert (curTrace, (remoteProcId < MultiProc_MAXPROCESSORS));
481 /*
482 * Loop through the regions and open the heap if not owner
483 */
484 for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
485 region = &(SharedRegion_module->regions [i]);
486 if (region->entry.isValid) {
487 #ifdef ENABLE_HEAPMP
488 if ((region->entry.ownerProcId != MultiProc_self ()) &&
489 (region->entry.ownerProcId != MultiProc_INVALIDID) &&
490 (region->entry.createHeap) &&
491 (region->heap == NULL)) {
492 /* SharedAddr should match creator's for each region */
493 sharedAddr = (Ptr) ((UInt32) region->entry.base +
494 region->reservedSize);
496 /* Heap should already be created so open by address */
497 status = HeapMemMP_openByAddr (sharedAddr,
498 (HeapMemMP_Handle *) &(region->heap));
499 if (status < 0) {
500 status = SharedRegion_E_FAIL;
502 /* Break the loop on failure. */
503 break;
504 }
505 }
506 #endif
507 SharedRegion_module->regionRefCount[i] ++;
508 }
509 }
511 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_attach", status);
513 return status;
514 }
516 /* Closes a heap, for non-owner processors, for each SharedRegion. */
517 Int
518 SharedRegion_detach (UInt16 remoteProcId)
519 {
520 Int status = SharedRegion_S_SUCCESS;
521 #ifdef ENABLE_HEAPMP
522 Int tmpStatus = SharedRegion_S_SUCCESS;
523 #endif
524 SharedRegion_Region * region = NULL;
525 UInt16 i;
527 GT_1trace (curTrace, GT_ENTER, "SharedRegion_detach", remoteProcId);
529 GT_assert (curTrace, (remoteProcId < MultiProc_MAXPROCESSORS));
531 /*
532 * Loop through the regions and open the heap if not owner
533 */
534 for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
535 region = &(SharedRegion_module->regions [i]);
536 if (region->entry.isValid) {
537 #ifdef ENABLE_HEAPMP
538 if ((region->entry.ownerProcId != MultiProc_self ()) &&
539 (region->entry.ownerProcId != MultiProc_INVALIDID) &&
540 (region->entry.createHeap) && (region->heap != NULL)) {
541 /* Close the heap */
542 tmpStatus = HeapMemMP_close ((HeapMemMP_Handle *)
543 &(region->heap));
544 if ((tmpStatus < 0) && (status >= 0)) {
545 status = SharedRegion_E_FAIL;
547 }
548 }
549 #endif
550 SharedRegion_module->regionRefCount[i]--;
551 }
552 }
554 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_detach", status);
556 return status;
557 }
559 /* Returns the address pointer associated with the shared region pointer. */
560 Ptr
561 SharedRegion_getPtr (SharedRegion_SRPtr srPtr)
562 {
563 SharedRegion_Region * region = NULL;
564 Ptr returnPtr = NULL;
565 UInt16 regionId;
567 GT_1trace (curTrace, GT_ENTER, "SharedRegion_getPtr", srPtr);
569 /* srPtr can be invalid. */
571 if (srPtr != SharedRegion_INVALIDSRPTR) {
572 if (SharedRegion_module->cfg.translate == FALSE) {
573 returnPtr = (Ptr) srPtr;
574 }
575 else {
576 regionId = (UInt32) (srPtr >> SharedRegion_module->numOffsetBits);
578 region = &(SharedRegion_module->regions [regionId]);
580 returnPtr = (Ptr)( (srPtr & SharedRegion_module->offsetMask)
581 + (UInt32) region->entry.base);
583 }
584 }
586 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getPtr", returnPtr);
588 return returnPtr;
589 }
591 /* Returns the address pointer associated with the shared region pointer. */
592 SharedRegion_SRPtr
593 SharedRegion_getSRPtr (Ptr addr, UInt16 id)
594 {
595 SharedRegion_Region * region = NULL;
596 SharedRegion_SRPtr retPtr = SharedRegion_INVALIDSRPTR;
598 GT_2trace (curTrace, GT_ENTER, "SharedRegion_getSRPtr", addr, id);
600 /* addr can be NULL. */
602 /* Return invalid for NULL addr */
603 if (addr != NULL) {
604 GT_assert (curTrace, (id != SharedRegion_INVALIDREGIONID));
605 GT_assert (curTrace,
606 ( (id != SharedRegion_INVALIDREGIONID)
607 && (id < SharedRegion_module->cfg.numEntries)));
609 /* if no shared region configured, set SRPtr to addr */
610 if (SharedRegion_module->cfg.translate == FALSE) {
611 retPtr = (SharedRegion_SRPtr) addr;
612 }
613 else {
614 region = &(SharedRegion_module->regions[id]);
616 /*
617 * Note: The very last byte on the very last id cannot be
618 * mapped because SharedRegion_INVALIDSRPTR which is ~0
619 * denotes an error. Since pointers should be word
620 * aligned, we don't expect this to be a problem.
621 *
622 * ie: numEntries = 4,
623 * id = 3, base = 0x00000000, len = 0x40000000
624 * ==> address 0x3fffffff would be invalid because
625 * the SRPtr for this address is 0xffffffff
626 */
627 if ( ((UInt32) addr >= (UInt32) region->entry.base)
628 && ( (UInt32) addr
629 < ((UInt32) region->entry.base + region->entry.len))) {
630 retPtr = (SharedRegion_SRPtr)
631 ( (id << SharedRegion_module->numOffsetBits)
632 | ((UInt32) addr - (UInt32) region->entry.base));
633 }
634 else {
635 retPtr = SharedRegion_INVALIDSRPTR;
636 GT_setFailureReason (curTrace,
637 GT_4CLASS,
638 "SharedRegion_getSRPtr",
639 SharedRegion_E_INVALIDARG,
640 "Provided addr is not in correct range"
641 " for the specified id!");
642 }
643 }
645 }
647 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getSRPtr", retPtr);
649 return retPtr;
650 }
652 /* Whether address translation is enabled */
653 Bool
654 SharedRegion_translateEnabled (Void)
655 {
656 GT_0trace (curTrace, GT_ENTER, "SharedRegion_translateEnabled");
657 GT_1trace (curTrace,
658 GT_LEAVE,
659 "SharedRegion_translateEnabled",
660 SharedRegion_module->cfg.translate);
662 return (SharedRegion_module->cfg.translate);
663 }
665 /* Gets the number of regions */
666 UInt16
667 SharedRegion_getNumRegions (Void)
668 {
669 GT_0trace (curTrace, GT_ENTER, "SharedRegion_getNumRegions");
670 GT_1trace (curTrace,
671 GT_LEAVE,
672 "SharedRegion_getNumRegions",
673 SharedRegion_module->cfg.numEntries);
674 return (SharedRegion_module->cfg.numEntries);
675 }
677 /* Sets the table information entry in the table. */
678 Int
679 SharedRegion_setEntry (UInt16 id,
680 SharedRegion_Entry * entry)
681 {
682 Int status = SharedRegion_S_SUCCESS;
683 SharedRegion_Region * region = NULL;
684 #ifdef ENABLE_HEAPMP
685 Ptr sharedAddr = NULL;
686 #endif
687 #ifdef ENABLE_HEAPMP
688 HeapMemMP_Handle heapHandle = NULL;
689 HeapMemMP_Handle * heapHandlePtr = NULL;
690 HeapMemMP_Params params;
691 #endif
692 #ifdef ENABLE_LOCAL_LOCK
693 IArg key;
694 #endif
696 GT_2trace (curTrace, GT_ENTER, "SharedRegion_setEntry", id, entry);
698 GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
699 GT_assert (curTrace, (entry != NULL));
701 region = &(SharedRegion_module->regions [id]);
703 /* Make sure region does not overlap existing ones */
704 status = SharedRegion_checkOverlap (region->entry.base,
705 region->entry.len);
707 if (region->entry.isValid) {
708 /* region already exist */
709 SharedRegion_module->regionRefCount[id] += 1;
710 }
711 else {
712 #ifdef ENABLE_LOCAL_LOCK
713 /* needs to be thread safe */
714 key = IGateProvider_enter (SharedRegion_module->localLock);
715 #endif
716 /* set specified region id to entry values */
717 memcpy ((Ptr) &(region->entry),
718 (Ptr) entry,
719 sizeof (SharedRegion_Entry));
720 #ifdef ENABLE_LOCAL_LOCK
721 /* leave gate */
722 IGateProvider_leave (SharedRegion_module->localLock, key);
723 #endif
725 #ifdef ENABLE_HEAPMP
726 if (entry->ownerProcId == MultiProc_self ()) {
727 if ((entry->createHeap) && (region->heap == NULL)) {
728 /* get current Ptr (reserve memory with size of 0) */
729 sharedAddr = SharedRegion_reserveMemory (id, 0);
730 HeapMemMP_Params_init (¶ms);
731 params.sharedAddr = sharedAddr;
732 params.sharedBufSize = region->entry.len
733 - region->reservedSize;
735 /*
736 * Calculate size of HeapMemMP_Attrs and adjust
737 * sharedBufSize. Size of HeapMemMP_Attrs =
738 * HeapMemMP_sharedMemReq(¶ms) - params.sharedBufSize
739 */
740 params.sharedBufSize -= ( HeapMemMP_sharedMemReq (¶ms)
741 - params.sharedBufSize);
743 heapHandle = HeapMemMP_create (¶ms);
744 if (heapHandle == NULL) {
745 region->entry.isValid = FALSE;
746 status = SharedRegion_E_MEMORY;
748 }
749 else {
750 region->heap = heapHandle;
751 }
752 }
753 }
754 else {
755 if ((entry->createHeap) && (region->heap == NULL)) {
756 /* sharedAddr should match creator's for each region */
757 sharedAddr = (Ptr)( (UInt32) region->entry.base
758 + region->reservedSize);
760 /* set the pointer to a heap handle */
761 heapHandlePtr = (HeapMemMP_Handle *) &(region->heap);
763 /* open the heap by address */
764 status = HeapMemMP_openByAddr (sharedAddr, heapHandlePtr);
765 if (status < 0) {
766 region->entry.isValid = FALSE;
767 status = SharedRegion_E_FAIL;
769 }
770 }
771 }
772 #endif
773 if (region->entry.isValid) {
774 SharedRegion_module->regionRefCount[id] ++;
775 }
776 }
778 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_setEntry", status);
780 return (status);
781 }
783 /* Clears the region in the table. */
784 Int
785 SharedRegion_clearEntry (UInt16 id)
786 {
787 Int status = SharedRegion_S_SUCCESS;
788 SharedRegion_Region * region = NULL;
789 #ifdef ENABLE_HEAPMP
790 HeapMemMP_Handle heapmemPtr = NULL;
791 UInt16 myId;
792 UInt16 ownerProcId;
793 #endif
794 #ifdef ENABLE_LOCAL_LOCK
795 IArg key;
796 #endif
798 GT_1trace (curTrace, GT_ENTER, "SharedRegion_clearEntry", id);
800 GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
801 /* Need to make sure not trying to clear Region 0 */
803 #ifdef ENABLE_HEAPMP
804 myId = MultiProc_self ();
805 #endif
807 #ifdef ENABLE_LOCAL_LOCK
808 /* Needs to be thread safe */
809 key = IGateProvider_enter (SharedRegion_module->localLock);
810 #endif
812 region = &(SharedRegion_module->regions [id]);
814 #ifdef ENABLE_HEAPMP
815 /* Store these fields to local variables */
816 ownerProcId = region->entry.ownerProcId;
817 heapmemPtr = region->heap;
818 #endif
819 if (region->entry.isValid) {
820 SharedRegion_module->regionRefCount[id] -= 1;
821 }
823 if (SharedRegion_module->regionRefCount[id] == 0) {
824 /* Assert if region is 0.
825 * Region 0 should always be cleared through SharedRegion_stop API
826 */
827 GT_assert (curTrace, (id != 0));
828 /* Clear region to their defaults */
829 region->entry.isValid = FALSE;
830 region->entry.base = NULL;
831 region->entry.len = 0u;
832 region->entry.ownerProcId = 0u;
833 region->entry.cacheEnable = FALSE;
834 region->entry.cacheLineSize = SharedRegion_module->cfg.cacheLineSize;
835 region->entry.createHeap = TRUE;
836 region->entry.name = NULL;
837 region->reservedSize = 0u;
838 #ifdef ENABLE_HEAPMP
839 region->heap = NULL;
840 #endif
842 #ifdef ENABLE_LOCAL_LOCK
843 IGateProvider_leave (SharedRegion_module->localLock, key);
844 #endif
846 #ifdef ENABLE_HEAPMP
847 /* Delete or close previous created heap outside the gate */
848 if (heapmemPtr != NULL) {
849 if (ownerProcId == myId) {
850 status = HeapMemMP_delete ((HeapMemMP_Handle *) &heapmemPtr);
851 if (status < 0) {
852 status = SharedRegion_E_FAIL;
854 }
855 }
856 else if (ownerProcId != MultiProc_INVALIDID) {
857 status = HeapMemMP_close ((HeapMemMP_Handle *) &heapmemPtr);
858 if (status < 0) {
859 status = SharedRegion_E_FAIL;
861 }
862 }
863 }
864 #endif
865 #ifdef ENABLE_LOCAL_LOCK
866 /* Needs to be thread safe */
867 key = IGateProvider_enter (SharedRegion_module->localLock);
868 #endif
869 }
870 #ifdef ENABLE_LOCAL_LOCK
871 IGateProvider_leave (SharedRegion_module->localLock, key);
872 #endif
874 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_clearEntry", status);
876 return status;
877 }
879 /* Clears the reserve memory for each region in the table. */
880 Void
881 SharedRegion_clearReservedMemory (Void)
882 {
883 SharedRegion_Region * region = NULL;
884 Int i;
886 GT_0trace (curTrace, GT_ENTER, "SharedRegion_clearReservedMemory");
888 /*
889 * Loop through shared regions. If an owner of a region is specified,
890 * the owner zeros out the reserved memory in each region.
891 */
892 for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
893 region = &(SharedRegion_module->regions [i]);
894 if ( (region->entry.isValid)
895 && (region->entry.ownerProcId == MultiProc_self ())) {
896 /* Clear reserved memory, if any */
897 if (region->reservedSize != 0) {
898 memset (region->entry.base, 0, region->reservedSize);
900 /* Writeback invalidate the cache if enabled in region */
901 if (region->entry.cacheEnable) {
902 Cache_wbInv (region->entry.base,
903 region->reservedSize,
904 Cache_Type_ALL,
905 TRUE);
906 }
907 }
908 }
909 }
911 GT_0trace (curTrace, GT_LEAVE, "SharedRegion_clearReservedMemory");
912 }
914 /* Initializes the entry fields */
915 Void
916 SharedRegion_entryInit (SharedRegion_Entry * entry)
917 {
918 GT_1trace (curTrace, GT_ENTER, "SharedRegion_entryInit", entry);
920 GT_assert (curTrace, (entry != NULL));
922 /* init the entry to default values */
923 entry->base = NULL;
924 entry->len = 0u;
925 entry->ownerProcId = 0u;
926 entry->cacheEnable = TRUE;
927 entry->cacheLineSize = SharedRegion_module->cfg.cacheLineSize;
928 entry->createHeap = TRUE;
929 entry->name = NULL;
930 entry->isValid = FALSE;
932 GT_0trace (curTrace, GT_LEAVE, "SharedRegion_entryInit");
933 }
935 /* Returns Heap Handle of associated id */
936 Ptr
937 SharedRegion_getHeap (UInt16 id)
938 {
939 #ifdef ENABLE_HEAPMP
940 HeapMemMP_Handle heap = NULL;
941 #endif
943 GT_1trace (curTrace, GT_ENTER, "SharedRegion_getHeap", id);
945 GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
947 /*
948 * If translate == TRUE or translate == FALSE
949 * and 'id' is not INVALIDREGIONID, then assert id is valid.
950 * Return the heap associated with the region id.
951 *
952 * If those conditions are not met, the id is from
953 * an addres in local memory so return NULL.
954 */
955 if ( (SharedRegion_module->cfg.translate)
956 || ( (SharedRegion_module->cfg.translate == FALSE)
957 && (id != SharedRegion_INVALIDREGIONID))) {
958 if (id >= SharedRegion_module->cfg.numEntries) {
959 /* Need to make sure id is smaller than numEntries */
960 GT_setFailureReason (curTrace,
961 GT_4CLASS,
962 "SharedRegion_getHeap",
963 SharedRegion_E_INVALIDARG,
964 "id cannot be larger than numEntries!");
965 }
966 else {
967 #ifdef ENABLE_HEAPMP
968 heap = SharedRegion_module->regions [id].heap;
969 #endif
970 }
971 }
973 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getHeap", heap);
975 #ifdef ENABLE_HEAPMP
976 return (Ptr) heap;
977 #else
978 return NULL;
979 #endif
980 }
982 /* Returns the id of shared region in which the pointer resides.
983 * Returns 0 if SharedRegion_module->cfg.translate set to TRUE.
984 * It returns SharedRegion_INVALIDREGIONID if no entry is found.
985 */
986 UInt16
987 SharedRegion_getId (Ptr addr)
988 {
989 SharedRegion_Region * region = NULL;
990 UInt16 regionId = SharedRegion_INVALIDREGIONID;
991 #ifdef ENABLE_LOCAL_LOCK
992 IArg key;
993 #endif
994 UInt16 i;
996 GT_1trace (curTrace, GT_ENTER, "SharedRegion_getId", addr);
998 /* addr can be NULL. */
1000 /* Return invalid for NULL addr */
1001 if (addr != NULL) {
1002 #ifdef ENABLE_LOCAL_LOCK
1003 key = IGateProvider_enter (SharedRegion_module->localLock);
1004 #endif
1006 for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
1007 region = &(SharedRegion_module->regions [i]);
1008 if ( (region->entry.isValid)
1009 && (addr >= region->entry.base)
1010 && ( addr
1011 < (Ptr)((UInt32) region->entry.base + region->entry.len))) {
1012 regionId = i;
1013 break;
1014 }
1015 }
1017 #ifdef ENABLE_LOCAL_LOCK
1018 IGateProvider_leave (SharedRegion_module->localLock, key);
1019 #endif
1020 }
1022 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getId", regionId);
1024 return (regionId);
1025 }
1027 /* Returns the id of shared region that matches name.
1028 * Returns SharedRegion_INVALIDREGIONID if no region is found.
1029 */
1030 UInt16
1031 SharedRegion_getIdByName (String name)
1032 {
1033 SharedRegion_Region * region = NULL;
1034 UInt16 regionId = SharedRegion_INVALIDREGIONID;
1035 UInt16 i;
1036 #ifdef ENABLE_LOCAL_LOCK
1037 IArg key;
1038 #endif
1040 GT_1trace (curTrace, GT_ENTER, "SharedRegion_getIdByName", name);
1042 GT_assert (curTrace, (name != NULL));
1044 #ifdef ENABLE_LOCAL_LOCK
1045 /* Needs to be thread safe */
1046 key = IGateProvider_enter (SharedRegion_module->localLock);
1047 #endif
1049 /* loop through entries to find matching name */
1050 for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
1051 region = &(SharedRegion_module->regions [i]);
1053 if (region->entry.isValid) {
1054 if (strcmp (region->entry.name, name) == 0) {
1055 regionId = i;
1056 break;
1057 }
1058 }
1059 }
1061 #ifdef ENABLE_LOCAL_LOCK
1062 /* leave the gate */
1063 IGateProvider_leave (SharedRegion_module->localLock, key);
1064 #endif
1066 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getIdByName", regionId);
1068 return (regionId);
1069 }
1071 /* Gets the entry information for the specified region id */
1072 Int
1073 SharedRegion_getEntry (UInt16 id,
1074 SharedRegion_Entry * entry)
1075 {
1076 Int status = SharedRegion_S_SUCCESS;
1077 SharedRegion_Region * region = NULL;
1079 GT_2trace (curTrace, GT_ENTER, "SharedRegion_getEntry", id, entry);
1081 GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
1082 GT_assert (curTrace, (entry != NULL));
1084 region = &(SharedRegion_module->regions [id]);
1086 memcpy ((Ptr) entry,
1087 (Ptr) &(region->entry),
1088 sizeof (SharedRegion_Entry));
1090 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getEntry", status);
1092 return status;
1093 }
1095 /* Get cache line size */
1096 SizeT
1097 SharedRegion_getCacheLineSize (UInt16 id)
1098 {
1099 SizeT cacheLineSize = 0u;
1101 GT_1trace (curTrace, GT_ENTER, "SharedRegion_getCacheLineSize", id);
1103 GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
1105 /*
1106 * If translate == TRUE or translate == FALSE
1107 * and 'id' is not INVALIDREGIONID, then assert id is valid.
1108 * Return the heap associated with the region id.
1109 *
1110 * If those conditions are not met, the id is from
1111 * an addres in local memory so return NULL.
1112 */
1113 if ( (SharedRegion_module->cfg.translate)
1114 || ( (SharedRegion_module->cfg.translate == FALSE)
1115 && (id != SharedRegion_INVALIDREGIONID))) {
1116 if (id >= SharedRegion_module->cfg.numEntries) {
1117 /* Need to make sure id is smaller than numEntries */
1118 GT_setFailureReason (curTrace,
1119 GT_4CLASS,
1120 "SharedRegion_getCacheLineSize",
1121 SharedRegion_E_INVALIDARG,
1122 "id cannot be larger than numEntries!");
1123 }
1124 else {
1125 cacheLineSize =
1126 SharedRegion_module->regions [id].entry.cacheLineSize;
1127 }
1128 }
1130 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getCacheLineSize",
1131 cacheLineSize);
1133 return cacheLineSize;
1134 }
1136 /* Is cache enabled */
1137 Bool
1138 SharedRegion_isCacheEnabled (UInt16 id)
1139 {
1140 Bool cacheEnable = FALSE;
1142 GT_1trace (curTrace, GT_ENTER, "SharedRegion_isCacheEnabled", id);
1144 GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
1146 /*
1147 * If translate == TRUE or translate == FALSE
1148 * and 'id' is not INVALIDREGIONID, then assert id is valid.
1149 * Return the heap associated with the region id.
1150 *
1151 * If those conditions are not met, the id is from
1152 * an addres in local memory so return NULL.
1153 */
1154 if ( (SharedRegion_module->cfg.translate)
1155 || ( (SharedRegion_module->cfg.translate == FALSE)
1156 && (id != SharedRegion_INVALIDREGIONID))) {
1157 if (id >= SharedRegion_module->cfg.numEntries) {
1158 /* Need to make sure id is smaller than numEntries */
1159 GT_setFailureReason (curTrace,
1160 GT_4CLASS,
1161 "SharedRegion_isCacheEnabled",
1162 SharedRegion_E_INVALIDARG,
1163 "id cannot be larger than numEntries!");
1164 }
1165 else {
1166 cacheEnable =
1167 SharedRegion_module->regions[id].entry.cacheEnable;
1168 }
1169 }
1171 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_isCacheEnabled", cacheEnable);
1173 return (cacheEnable);
1174 }
1176 /* Returns invalid SRPtr value. */
1177 SharedRegion_SRPtr SharedRegion_invalidSRPtr (Void)
1178 {
1179 return (SharedRegion_INVALIDSRPTR);
1180 }
1182 /* =============================================================================
1183 * Internal Functions
1184 * =============================================================================
1185 */
1186 /* Reserves the specified amount of memory from the specified region id. */
1187 Ptr
1188 SharedRegion_reserveMemory (UInt16 id, SizeT size)
1189 {
1190 Ptr retPtr = NULL;
1191 SharedRegion_Region * region = NULL;
1192 UInt32 minAlign;
1193 SizeT newSize;
1194 SizeT curSize;
1196 GT_2trace (curTrace, GT_ENTER, "SharedRegion_reserveMemory", id, size);
1198 GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
1200 minAlign = Memory_getMaxDefaultTypeAlign ();
1202 if (SharedRegion_getCacheLineSize (id) > minAlign) {
1203 minAlign = SharedRegion_getCacheLineSize (id);
1204 }
1206 region = &(SharedRegion_module->regions [id]);
1208 /* Set the current size to the reservedSize */
1209 curSize = region->reservedSize;
1211 /* No need to round here since curSize is already aligned */
1212 retPtr = (Ptr)((UInt32) region->entry.base + curSize);
1214 /* Round the new size to the min alignment since */
1215 newSize = ROUNDUP (size, minAlign);
1217 /* Add the new size to current size */
1218 region->reservedSize = curSize + newSize;
1220 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_reserveMemory", retPtr);
1222 return (retPtr);
1223 }
1225 /* Reserves the specified amount of memory from the specified region id. */
1226 Void
1227 SharedRegion_unreserveMemory (UInt16 id, SizeT size)
1228 {
1229 SharedRegion_Region * region = NULL;
1230 UInt32 minAlign;
1231 SizeT newSize;
1232 SizeT curSize;
1234 GT_2trace (curTrace, GT_ENTER, "SharedRegion_unreserveMemory", id, size);
1236 GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
1238 minAlign = Memory_getMaxDefaultTypeAlign ();
1240 if (SharedRegion_getCacheLineSize (id) > minAlign) {
1241 minAlign = SharedRegion_getCacheLineSize (id);
1242 }
1244 region = &(SharedRegion_module->regions [id]);
1246 /* Set the current size to the unreservedSize */
1247 curSize = region->reservedSize;
1249 /* Round the new size to the min alignment since */
1250 newSize = ROUNDUP (size, minAlign);
1252 /* Add the new size to current size */
1253 region->reservedSize = curSize - newSize;
1255 GT_0trace (curTrace, GT_LEAVE, "SharedRegion_unreserveMemory");
1257 return ;
1258 }
1260 /* Return the number of offsetBits bits */
1261 static UInt32 SharedRegion_getNumOffsetBits (Void)
1262 {
1263 UInt32 numEntries = SharedRegion_module->cfg.numEntries;
1264 UInt32 indexBits = 0;
1265 UInt32 numOffsetBits = 0;
1267 GT_0trace (curTrace, GT_ENTER, "SharedRegion_getNumOffsetBits");
1269 if (numEntries == 0) {
1270 indexBits = 0;
1271 }
1272 else if (numEntries == 1) {
1273 indexBits = 1;
1274 }
1275 else {
1276 numEntries = numEntries - 1;
1278 /* determine the number of bits for the index */
1279 while (numEntries) {
1280 indexBits++;
1281 numEntries = numEntries >> 1;
1282 }
1283 }
1285 numOffsetBits = 32 - indexBits;
1287 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getNumOffsetBits",
1288 numOffsetBits);
1290 return (numOffsetBits);
1291 }
1293 /* Checks to make sure overlap does not exists. */
1294 static Int SharedRegion_checkOverlap(Ptr base, SizeT len)
1295 {
1296 Int status = SharedRegion_S_SUCCESS;
1297 SharedRegion_Region * region = NULL;
1298 #ifdef ENABLE_LOCAL_LOCK
1299 IArg key = 0;
1300 #endif
1301 UInt32 i;
1303 GT_2trace (curTrace, GT_ENTER, "SharedRegion_checkOverlap", base, len);
1305 #ifdef ENABLE_LOCAL_LOCK
1306 key = IGateProvider_enter (SharedRegion_module->localLock);
1307 #endif
1308 /* check whether new region overlaps existing ones */
1309 for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
1310 region = &(SharedRegion_module->regions [i]);
1311 if (region->entry.isValid) {
1312 if ((base == region->entry.base)&&(len == region->entry.len)) {
1313 /* OK.Return sucess as user is going to create the same
1314 * shared region from different process
1315 */
1316 break;
1317 }
1318 else if (base >= region->entry.base) {
1319 if ( base
1320 < (Ptr)( (UInt32) region->entry.base
1321 + region->entry.len)) {
1322 status = SharedRegion_E_FAIL;
1323 GT_setFailureReason (curTrace,
1324 GT_4CLASS,
1325 "SharedRegion_checkOverlap",
1326 status,
1327 "Specified region falls within another"
1328 " region!");
1329 /* Break on failure. */
1330 break;
1331 }
1332 }
1333 else {
1334 if ((Ptr) ((UInt32) base + len) > region->entry.base) {
1335 status = SharedRegion_E_FAIL;
1336 GT_setFailureReason (curTrace,
1337 GT_4CLASS,
1338 "SharedRegion_checkOverlap",
1339 status,
1340 "Specified region spans across"
1341 " multiple regions!");
1342 /* Break on failure. */
1343 break;
1344 }
1345 }
1346 }
1347 }
1349 #ifdef ENABLE_LOCAL_LOCK
1350 IGateProvider_leave (SharedRegion_module->localLock, key);
1351 #endif
1353 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_checkOverlap", status);
1355 return (status);
1356 }
1358 /* Return the region info */
1359 Void
1360 SharedRegion_getRegionInfo (UInt16 i,
1361 SharedRegion_Region * region)
1362 {
1363 SharedRegion_Region * regions = NULL;
1365 GT_2trace (curTrace, GT_ENTER, "SharedRegion_getRegionInfo", i, region);
1367 GT_assert (curTrace, (i < SharedRegion_module->cfg.numEntries));
1368 GT_assert (curTrace, (region != NULL));
1370 regions = &(SharedRegion_module->regions[i]);
1372 memcpy ((Ptr) region,
1373 (Ptr) regions,
1374 sizeof (SharedRegion_Region));
1376 GT_0trace (curTrace, GT_LEAVE, "SharedRegion_getRegionInfo");
1377 }
1379 /* Sets the table information entry in the table (doesn't create heap). */
1380 Int
1381 _SharedRegion_setEntry (UInt16 id,
1382 SharedRegion_Entry * entry)
1383 {
1384 Int status = SharedRegion_S_SUCCESS;
1385 SharedRegion_Region * region = NULL;
1386 #ifdef ENABLE_LOCAL_LOCK
1387 IArg key;
1388 #endif
1390 GT_2trace (curTrace, GT_ENTER, "_SharedRegion_setEntry", id, entry);
1392 GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
1393 GT_assert (curTrace, (entry != NULL));
1395 region = &(SharedRegion_module->regions [id]);
1397 /* Make sure region does not overlap existing ones */
1398 status = SharedRegion_checkOverlap (region->entry.base,
1399 region->entry.len);
1400 #ifdef ENABLE_LOCAL_LOCK
1401 /* needs to be thread safe */
1402 key = IGateProvider_enter (SharedRegion_module->localLock);
1403 #endif
1405 /* set specified region id to entry values */
1406 memcpy ((Ptr) &(region->entry),
1407 (Ptr) entry,
1408 sizeof (SharedRegion_Entry));
1410 #ifdef ENABLE_LOCAL_LOCK
1411 /* leave gate */
1412 IGateProvider_leave (SharedRegion_module->localLock, key);
1413 #endif
1415 GT_1trace (curTrace, GT_LEAVE, "_SharedRegion_setEntry", status);
1417 return (status);
1418 }
1420 /* Gets region ID when given a physical address */
1421 UInt16 _SharedRegion_getIdPhys(Ptr physAddr)
1422 {
1423 SharedRegion_Region * region = NULL;
1424 UInt16 regionId = SharedRegion_INVALIDREGIONID;
1425 #ifdef ENABLE_LOCAL_LOCK
1426 IArg key;
1427 #endif
1428 UInt16 i;
1429 Ptr base;
1431 GT_1trace (curTrace, GT_ENTER, "SharedRegion_getIdPhys", physAddr);
1433 /* physAddr can be NULL. */
1435 /* Return invalid for NULL physAddr */
1436 if (physAddr != NULL) {
1437 #ifdef ENABLE_LOCAL_LOCK
1438 key = IGateProvider_enter (SharedRegion_module->localLock);
1439 #endif
1440 for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
1441 region = &SharedRegion_module->regions[i];
1442 if (region->entry.isValid) {
1443 #ifdef ENABLE_HEAPMP
1444 if (region->entry.createHeap) {
1445 base = MemoryOS_translate(region->entry.base,
1446 Memory_XltFlags_Virt2Phys);
1447 }
1448 else
1449 #endif
1450 {
1451 base = region->entry.base;
1452 }
1453 if ((physAddr >= base) &&
1454 (physAddr < (Ptr)((UInt32)base + region->entry.len))) {
1456 regionId = i;
1457 break;
1458 }
1459 }
1460 }
1462 #ifdef ENABLE_LOCAL_LOCK
1463 IGateProvider_leave (SharedRegion_module->localLock, key);
1464 #endif
1465 }
1467 GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getIdPhys", regionId);
1469 return (regionId);
1470 }
1472 /*
1473 * ======== SharedRegion_getEntryPtr ========
1474 */
1475 SharedRegion_Entry *SharedRegion_getEntryPtr(UInt16 id)
1476 {
1477 SharedRegion_Region *region;
1479 region = &(SharedRegion_module->regions[id]);
1480 return ((SharedRegion_Entry *)(®ion->entry));
1481 }