host_linux: Add example for use case with host running linux
[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)
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");
189 /* Function to setup the SharedRegion module. */
190 Int
191 SharedRegion_setup (SharedRegion_Config * cfg)
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;
290 /* Function to destroy the SharedRegion module. */
291 Int
292 SharedRegion_destroy (Void)
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;
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)
348     return(SharedRegion_module->isStarted) ;
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)
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(&params);
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(&params)
392                                          - params.sharedBufSize);
393                     heapHandle = HeapMemMP_create(&params);
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;
411 /* Function to stop the SharedRegion module.  */
412 Int
413 SharedRegion_stop (Void)
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;
466 /* Opens a heap, for non-owner processors, for each SharedRegion. */
467 Int
468 SharedRegion_attach (UInt16 remoteProcId)
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;
516 /* Closes a heap, for non-owner processors, for each SharedRegion. */
517 Int
518 SharedRegion_detach (UInt16 remoteProcId)
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;
559 /* Returns the address pointer associated with the shared region pointer. */
560 Ptr
561 SharedRegion_getPtr (SharedRegion_SRPtr srPtr)
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;
591 /* Returns the address pointer associated with the shared region pointer. */
592 SharedRegion_SRPtr
593 SharedRegion_getSRPtr (Ptr addr, UInt16 id)
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;
652 /* Whether address translation is enabled */
653 Bool
654 SharedRegion_translateEnabled (Void)
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);
665 /* Gets the number of regions */
666 UInt16
667 SharedRegion_getNumRegions (Void)
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);
677 /* Sets the table information entry in the table. */
678 Int
679 SharedRegion_setEntry (UInt16                id,
680                        SharedRegion_Entry  * entry)
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 (&params);
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(&params) - params.sharedBufSize
739                          */
740                         params.sharedBufSize -= (  HeapMemMP_sharedMemReq (&params)
741                                                  - params.sharedBufSize);
743                         heapHandle = HeapMemMP_create (&params);
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);
783 /* Clears the region in the table. */
784 Int
785 SharedRegion_clearEntry (UInt16 id)
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;
879 /* Clears the reserve memory for each region in the table. */
880 Void
881 SharedRegion_clearReservedMemory (Void)
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");
914 /* Initializes the entry fields */
915 Void
916 SharedRegion_entryInit (SharedRegion_Entry * entry)
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");
935 /* Returns Heap Handle of associated id */
936 Ptr
937 SharedRegion_getHeap (UInt16 id)
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
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)
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);
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)
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);
1071 /* Gets the entry information for the specified region id */
1072 Int
1073 SharedRegion_getEntry (UInt16               id,
1074                        SharedRegion_Entry * entry)
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;
1095 /* Get cache line size */
1096 SizeT
1097 SharedRegion_getCacheLineSize (UInt16 id)
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;
1136 /* Is cache enabled */
1137 Bool
1138 SharedRegion_isCacheEnabled (UInt16 id)
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);
1176 /* Returns invalid SRPtr value. */
1177 SharedRegion_SRPtr SharedRegion_invalidSRPtr (Void)
1179     return (SharedRegion_INVALIDSRPTR);
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)
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);
1225 /* Reserves the specified amount of memory from the specified region id. */
1226 Void
1227 SharedRegion_unreserveMemory (UInt16 id, SizeT size)
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 ;
1260 /* Return the number of offsetBits bits */
1261 static UInt32 SharedRegion_getNumOffsetBits (Void)
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);
1293 /* Checks to make sure overlap does not exists. */
1294 static Int SharedRegion_checkOverlap(Ptr base, SizeT len)
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);
1358 /* Return the region info */
1359 Void
1360 SharedRegion_getRegionInfo (UInt16                i,
1361                             SharedRegion_Region * region)
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");
1379 /* Sets the table information entry in the table (doesn't create heap). */
1380 Int
1381 _SharedRegion_setEntry (UInt16                id,
1382                         SharedRegion_Entry  * entry)
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);
1420 /* Gets region ID when given a physical address */
1421 UInt16 _SharedRegion_getIdPhys(Ptr physAddr)
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);
1472 /*
1473  *  ======== SharedRegion_getEntryPtr ========
1474  */
1475 SharedRegion_Entry *SharedRegion_getEntryPtr(UInt16 id)
1477     SharedRegion_Region *region;
1479     region = &(SharedRegion_module->regions[id]);
1480     return ((SharedRegion_Entry *)(&region->entry));