SharedRegion: Update to use linker symbols instead of platform map
[ipc/ipcdev.git] / packages / ti / sdo / ipc / SharedRegion.c
1 /*
2  * Copyright (c) 2012-2018 Texas Instruments Incorporated - http://www.ti.com
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*
33  *  ======== SharedRegion.c ========
34  *  Implementation of functions specified in SharedRegion.xdc.
35  */
37 #include <xdc/std.h>
38 #include <string.h>
39 #include <xdc/runtime/Assert.h>
40 #include <xdc/runtime/Error.h>
41 #include <xdc/runtime/IHeap.h>
42 #include <xdc/runtime/Memory.h>
44 #include <ti/sysbios/hal/Cache.h>
45 #include <ti/sysbios/hal/Hwi.h>
47 #include <ti/sdo/ipc/_Ipc.h>
48 #include <ti/sdo/utils/_MultiProc.h>
49 #include <ti/sdo/ipc/_SharedRegion.h>
50 #include <ti/sdo/ipc/heaps/_HeapMemMP.h>
52 #include "package/internal/SharedRegion.xdc.h"
54 #ifdef __ti__
55     #pragma FUNC_EXT_CALLED(SharedRegion_clearEntry);
56     #pragma FUNC_EXT_CALLED(SharedRegion_getCacheLineSize);
57     #pragma FUNC_EXT_CALLED(SharedRegion_getEntry);
58     #pragma FUNC_EXT_CALLED(SharedRegion_getEntryPtr);
59     #pragma FUNC_EXT_CALLED(SharedRegion_getHeap);
60     #pragma FUNC_EXT_CALLED(SharedRegion_getId);
61     #pragma FUNC_EXT_CALLED(SharedRegion_getIdByName);
62     #pragma FUNC_EXT_CALLED(SharedRegion_getNumRegions);
63     #pragma FUNC_EXT_CALLED(SharedRegion_getPtr);
64     #pragma FUNC_EXT_CALLED(SharedRegion_getSRPtr);
65     #pragma FUNC_EXT_CALLED(SharedRegion_isCacheEnabled);
66     #pragma FUNC_EXT_CALLED(SharedRegion_setEntry);
67     #pragma FUNC_EXT_CALLED(SharedRegion_translateEnabled);
68     #pragma FUNC_EXT_CALLED(SharedRegion_invalidSRPtr);
69 #endif
71 /*
72  *************************************************************************
73  *                       Common Header Functions
74  *************************************************************************
75  */
77 /*
78  *  ======== SharedRegion_clearEntry ========
79  *  Clears the region in the table.
80  */
81 Int SharedRegion_clearEntry(UInt16 id)
82 {
83     ti_sdo_ipc_SharedRegion_Region *region;
84     HeapMemMP_Handle    heapMemHandle;
85     UInt16 myId, ownerProcId;
86     Int status = HeapMemMP_S_SUCCESS;
87     UInt key;
89     /* Need to make sure id is smaller than numEntries */
90     Assert_isTrue((id < ti_sdo_ipc_SharedRegion_numEntries), ti_sdo_ipc_SharedRegion_A_idTooLarge);
92     /* Need to make sure not trying to clear Region 0 */
93     Assert_isTrue(id != 0, ti_sdo_ipc_SharedRegion_A_region0Clear);
95     myId = MultiProc_self();
97     /* get the region */
98     region = &(SharedRegion_module->regions[id]);
100     /* store these fields to local variables */
101     ownerProcId = region->entry.ownerProcId;
102     heapMemHandle  = (HeapMemMP_Handle)region->heap;
104     /* needs to be thread safe */
105     key = Hwi_disable();
107     /* clear region to their defaults */
108     region->entry.isValid       = FALSE;
109     region->entry.base          = NULL;
110     region->entry.len           = NULL;
111     region->entry.ownerProcId   = 0;
112     region->entry.cacheEnable   = TRUE;
113     region->entry.cacheLineSize = ti_sdo_ipc_SharedRegion_cacheLineSize;
114     region->entry.createHeap    = TRUE;
115     region->entry.name          = NULL;
116     region->reservedSize        = 0;
117     region->heap                = NULL;
119     /* leave the gate */
120     Hwi_restore(key);
122     /* delete or close previous created heap outside the gate */
123     if (heapMemHandle != NULL) {
124         if (ownerProcId == myId) {
125             status = HeapMemMP_delete(&heapMemHandle);
126         }
127         else if (ownerProcId != MultiProc_INVALIDID) {
128             status = HeapMemMP_close(&heapMemHandle);
129         }
130     }
132     if (status == HeapMemMP_S_SUCCESS) {
133         status = SharedRegion_S_SUCCESS;
134     }
135     else {
136         status = SharedRegion_E_FAIL;
137     }
139     return (status);
142 /*
143  *  ======== SharedRegion_getCacheLineSize ========
144  */
145 SizeT SharedRegion_getCacheLineSize(UInt16 id)
147     SizeT cacheLineSize = 0;
149     /*
150      *  if translate == TRUE or translate == FALSE
151      *  and 'id' is not INVALIDREGIONID, then Assert id is valid.
152      *  Return the heap associated with the region id.
153      *
154      *  If those conditions are not met, the id is from
155      *  an addres in local memory so return NULL.
156      */
157     if ((ti_sdo_ipc_SharedRegion_translate) ||
158         ((ti_sdo_ipc_SharedRegion_translate == FALSE) &&
159         (id != SharedRegion_INVALIDREGIONID))) {
160         /* Need to make sure id is smaller than numEntries */
161         Assert_isTrue((id < ti_sdo_ipc_SharedRegion_numEntries),
162             ti_sdo_ipc_SharedRegion_A_idTooLarge);
164         cacheLineSize = SharedRegion_module->regions[id].entry.cacheLineSize;
165     }
167     return (cacheLineSize);
170 /*
171  *  ======== SharedRegion_getEntry ========
172  */
173 Int SharedRegion_getEntry(UInt16 id, SharedRegion_Entry *entry)
175     ti_sdo_ipc_SharedRegion_Region *region;
177     /* Make sure entry is not NULL */
178     Assert_isTrue((entry != NULL), ti_sdo_ipc_Ipc_A_nullArgument);
180     /* Need to make sure id is smaller than numEntries */
181     Assert_isTrue((id < ti_sdo_ipc_SharedRegion_numEntries), ti_sdo_ipc_SharedRegion_A_idTooLarge);
183     region = &(SharedRegion_module->regions[id]);
185     entry->base          = region->entry.base;
186     entry->len           = (SizeT)(region->entry.len);
187     entry->ownerProcId   = region->entry.ownerProcId;
188     entry->isValid       = region->entry.isValid;
189     entry->cacheEnable   = region->entry.cacheEnable;
190     entry->cacheLineSize = region->entry.cacheLineSize;
191     entry->createHeap    = region->entry.createHeap;
192     entry->name          = region->entry.name;
194     return (SharedRegion_S_SUCCESS);
197 /*
198  *  ======== SharedRegion_getEntryPtr ========
199  */
200 SharedRegion_Entry *SharedRegion_getEntryPtr(UInt16 id)
202     ti_sdo_ipc_SharedRegion_Region *region;
204     region = &(SharedRegion_module->regions[id]);
205     return ((SharedRegion_Entry *)(&region->entry));
208 /*
209  *  ======== SharedRegion_getId ========
210  *  Returns the id of shared region that the pointer resides in.
211  *  Returns SharedRegion_INVALIDREGIONID if no region is found.
212  */
213 UInt16 SharedRegion_getId(Ptr addr)
215     ti_sdo_ipc_SharedRegion_Region *region;
216     UInt i;
217     UInt key;
218     UInt16 regionId = SharedRegion_INVALIDREGIONID;
220     /* Try to find the entry that contains the address */
221     for (i = 0; i < ti_sdo_ipc_SharedRegion_numEntries; i++) {
222         region = &(SharedRegion_module->regions[i]);
224         /* needs to be thread safe */
225         key = Hwi_disable();
227         if ((region->entry.isValid) && (addr >= region->entry.base) &&
228             (addr < (Ptr)((uintptr_t)region->entry.base + (SizeT)region->entry.len))) {
229             regionId = i;
231             /* leave the gate */
232             Hwi_restore(key);
233             break;
234         }
236         /* leave the gate */
237         Hwi_restore(key);
238     }
240     return (regionId);
243 /*
244  *  ======== SharedRegion_getIdByName ========
245  *  Returns the id of shared region that matches name.
246  *  Returns SharedRegion_INVALIDREGIONID if no region is found.
247  */
248 UInt16 SharedRegion_getIdByName(String name)
250     ti_sdo_ipc_SharedRegion_Region *region;
251     UInt16 i;
252     UInt key;
253     UInt16 regionId = SharedRegion_INVALIDREGIONID;
255     /* loop through entries to find matching name */
256     for (i = 0; i < ti_sdo_ipc_SharedRegion_numEntries; i++) {
257         region = &(SharedRegion_module->regions[i]);
259         /* needs to be thread safe */
260         key = Hwi_disable();
262         if (region->entry.isValid) {
263             if (strcmp(region->entry.name, name) == 0) {
264                 regionId = i;
266                 /* leave the gate */
267                 Hwi_restore(key);
268                 break;
269             }
270         }
272         /* leave the gate */
273             Hwi_restore(key);
274     }
276     return (regionId);
279 /*
280  *  ======== SharedRegion_getNumRegions ========
281  */
282 UInt16 SharedRegion_getNumRegions(Void)
284     return (ti_sdo_ipc_SharedRegion_numEntries);
287 /*
288  *  ======== SharedRegion_getPtr ========
289  *  This function takes a shared region pointer and returns a pointer.
290  */
291 Ptr SharedRegion_getPtr(SharedRegion_SRPtr srPtr)
293     ti_sdo_ipc_SharedRegion_Region *region;
294     Ptr returnPtr;
295     UInt16 regionId;
297     if (ti_sdo_ipc_SharedRegion_translate == FALSE) {
298         returnPtr = (Ptr)(uintptr_t)(srPtr);
299     }
300     else if (srPtr == ti_sdo_ipc_SharedRegion_INVALIDSRPTR) {
301         returnPtr = NULL;
302     }
303     else {
304         /* find regionId from srPtr */
305         regionId = (UInt32)srPtr >> ti_sdo_ipc_SharedRegion_numOffsetBits;
307         /* make sure regionId of SRPtr less than numEntries */
308         Assert_isTrue(regionId < ti_sdo_ipc_SharedRegion_numEntries,
309             ti_sdo_ipc_SharedRegion_A_idTooLarge);
311         region = &(SharedRegion_module->regions[regionId]);
313         /* Make sure the region is valid */
314         Assert_isTrue(region->entry.isValid == TRUE,
315                 ti_sdo_ipc_SharedRegion_A_regionInvalid);
317         returnPtr = (Ptr)(uintptr_t)((srPtr & ti_sdo_ipc_SharedRegion_offsetMask) +
318                           (uintptr_t)region->entry.base);
319     }
321     return (returnPtr);
324 /*
325  *  ======== SharedRegion_getSRPtr ========
326  *  This function takes a pointer and an id and returns a shared region
327  *  pointer.
328  */
329 SharedRegion_SRPtr SharedRegion_getSRPtr(Ptr addr, UInt16 id)
331     ti_sdo_ipc_SharedRegion_Region *region;
332     SharedRegion_SRPtr retPtr;
334     /* if translate == false, set SRPtr to addr */
335     if (ti_sdo_ipc_SharedRegion_translate == FALSE) {
336         retPtr = (SharedRegion_SRPtr)(uintptr_t)addr;
337     }
338     else if (addr == NULL) {
339         retPtr = ti_sdo_ipc_SharedRegion_INVALIDSRPTR;
340     }
341     else {
342         /* Need to make sure id is smaller than numEntries */
343         Assert_isTrue(id < ti_sdo_ipc_SharedRegion_numEntries,
344             ti_sdo_ipc_SharedRegion_A_idTooLarge);
346         region = &(SharedRegion_module->regions[id]);
348         /*
349          *  Note: The very last byte on the very last id cannot be mapped
350          *        because ti_sdo_ipc_SharedRegion_INVALIDSRPTR which is ~0 denotes an
351          *        error. Since pointers should be word aligned, we don't
352          *        expect this to be a problem.
353          *
354          *        ie: numEntries = 4,
355          *            id = 3, base = 0x00000000, len = 0x40000000
356          *            ==> address 0x3fffffff would be invalid because the
357          *                SRPtr for this address is 0xffffffff
358          */
359         if (((uintptr_t)addr >= (uintptr_t)region->entry.base) &&
360             ((uintptr_t)addr < ((uintptr_t)region->entry.base + (SizeT)region->entry.len))) {
361             retPtr = (SharedRegion_SRPtr)((id << ti_sdo_ipc_SharedRegion_numOffsetBits)
362                      | ((UInt32)addr - (UInt32)region->entry.base));
363         }
364         else {
365             Assert_isTrue(FALSE, ti_sdo_ipc_SharedRegion_A_addrOutOfRange);
366             retPtr = ti_sdo_ipc_SharedRegion_INVALIDSRPTR;
367         }
368     }
370     return (retPtr);
373 /*
374  *  ======== SharedRegion_isCacheEnabled ========
375  */
376 Bool SharedRegion_isCacheEnabled(UInt16 id)
378     Bool cacheEnable = FALSE;
380     /*
381      *  if translate == TRUE or translate == FALSE
382      *  and 'id' is not INVALIDREGIONID, then Assert id is valid.
383      *  Return the heap associated with the region id.
384      *
385      *  If those conditions are not met, the id is from
386      *  an address in local memory so return NULL.
387      */
388     if ((ti_sdo_ipc_SharedRegion_translate) ||
389         ((ti_sdo_ipc_SharedRegion_translate == FALSE) &&
390         (id != SharedRegion_INVALIDREGIONID))) {
391         /* Need to make sure id is smaller than numEntries */
392         Assert_isTrue((id < ti_sdo_ipc_SharedRegion_numEntries),
393             ti_sdo_ipc_SharedRegion_A_idTooLarge);
395         cacheEnable = SharedRegion_module->regions[id].entry.cacheEnable;
396     }
398     return (cacheEnable);
401 /*
402  *  ======== SharedRegion_setEntry ========
403  *  Sets the region specified in the table.
404  */
405 Int SharedRegion_setEntry(UInt16 id, SharedRegion_Entry *entry)
407     ti_sdo_ipc_SharedRegion_Region *region;
408     HeapMemMP_Params    params;
409     HeapMemMP_Handle    heapHandle;
410     HeapMemMP_Handle    *heapHandlePtr;
411     UInt                key;
412     Ptr                 sharedAddr;
413     Int status = SharedRegion_S_SUCCESS;
414     Error_Block eb;
416     /* Need to make sure id is smaller than numEntries */
417     Assert_isTrue((id < ti_sdo_ipc_SharedRegion_numEntries),
418         ti_sdo_ipc_SharedRegion_A_idTooLarge);
420     /* Make sure entry is not NULL */
421     Assert_isTrue((entry != NULL), ti_sdo_ipc_Ipc_A_nullArgument);
423     Error_init(&eb);
425     region = &(SharedRegion_module->regions[id]);
427     /* make sure region does not overlap existing ones */
428     status = SharedRegion_checkOverlap(entry->base, (SizeT)entry->len);
430     if (status == SharedRegion_S_SUCCESS) {
431         /* region entry should be invalid at this point */
432         if (region->entry.isValid) {
433             /* Assert that a region already exists */
434             Assert_isTrue(FALSE, ti_sdo_ipc_SharedRegion_A_alreadyExists);
435             status = SharedRegion_E_ALREADYEXISTS;
436             return (status);
437         }
439         /* Assert if cacheEnabled and cacheLineSize equal 0 */
440         if ((entry->cacheEnable) && (entry->cacheLineSize == 0)) {
441             /* if cache enabled, cache line size must != 0 */
442             Assert_isTrue(FALSE, ti_sdo_ipc_SharedRegion_A_cacheLineSizeIsZero);
443         }
445         /* needs to be thread safe */
446         key = Hwi_disable();
448         /* set specified region id to entry values */
449         region->entry.base          = entry->base;
450         region->entry.len           = (Ptr)entry->len;
451         region->entry.ownerProcId   = entry->ownerProcId;
452         region->entry.cacheEnable   = entry->cacheEnable;
453         region->entry.cacheLineSize = entry->cacheLineSize;
454         region->entry.createHeap    = entry->createHeap;
455         region->entry.name          = entry->name;
456         region->entry.isValid       = entry->isValid;
458         /* leave gate */
459         Hwi_restore(key);
461         if (!region->entry.isValid) {
462             /* Region isn't valid yet */
463             return (status);
464         }
466         if (entry->ownerProcId == MultiProc_self()) {
467             if ((entry->createHeap) && (region->heap == NULL)) {
468                 /* get current Ptr (reserve memory with size of 0) */
469                 sharedAddr = ti_sdo_ipc_SharedRegion_reserveMemory(id, 0);
471                 HeapMemMP_Params_init(&params);
472                 params.sharedAddr = sharedAddr;
473                 params.sharedBufSize = (SizeT)(region->entry.len) -
474                                        region->reservedSize;
476                 /*
477                  *  Calculate size of HeapMemMP_Attrs and adjust sharedBufSize
478                  *  Size of HeapMemMP_Attrs = HeapMemMP_sharedMemReq(&params) -
479                  *                            params.sharedBufSize
480                  */
481                 params.sharedBufSize -= (HeapMemMP_sharedMemReq(&params)
482                                          - params.sharedBufSize);
484                 heapHandle = HeapMemMP_create(&params);
485                 if (heapHandle == NULL) {
486                     region->entry.isValid = FALSE;
487                     return (SharedRegion_E_MEMORY);
488                 }
490                 region->heap = (IHeap_Handle)heapHandle;
491             }
492         }
493         else {
494             if ((entry->createHeap) && (region->heap == NULL)) {
495                 /* sharedAddr should match creator's for each region */
496                 sharedAddr = (Ptr)((UInt32)entry->base +
497                     region->reservedSize);
499                 /* set the pointer to a heap handle */
500                 heapHandlePtr = (HeapMemMP_Handle *)&(region->heap);
502                 /* open the heap by address */
503                 if (HeapMemMP_openByAddr(sharedAddr, heapHandlePtr) !=
504                     HeapMemMP_S_SUCCESS) {
505                     status = SharedRegion_E_FAIL;
506                     region->entry.isValid = FALSE;
507                 }
508             }
509         }
510     }
512     return (status);
515 /*
516  *  ======== SharedRegion_checkOverlap ========
517  *  Checks to make sure overlap does not exists.
518  */
519 Int SharedRegion_checkOverlap(Ptr base, SizeT len)
521     ti_sdo_ipc_SharedRegion_Region *region;
522     UInt i;
523     UInt key;
525     /* needs to be thread safe */
526     key = Hwi_disable();
528     /* check to make sure new region does not overlap existing ones */
529     for (i = 0; i < ti_sdo_ipc_SharedRegion_numEntries; i++) {
530         region = &(SharedRegion_module->regions[i]);
531         if (region->entry.isValid) {
532             if (base >= region->entry.base) {
533                 if (base < (Ptr)((UInt32)region->entry.base +
534                     (SizeT)region->entry.len)) {
535                     Hwi_restore(key);
536                     Assert_isTrue(FALSE, ti_sdo_ipc_SharedRegion_A_overlap);
537                     return (SharedRegion_E_FAIL);
538                 }
539             }
540             else {
541                 if ((Ptr)((UInt32)base + len) > region->entry.base) {
542                     Hwi_restore(key);
543                     Assert_isTrue(FALSE, ti_sdo_ipc_SharedRegion_A_overlap);
544                     return (SharedRegion_E_FAIL);
545                 }
546             }
547         }
548     }
550     Hwi_restore(key);
552     return (SharedRegion_S_SUCCESS);
556 /*
557  *  ======== SharedRegion_entryInit ========
558  */
559 Void SharedRegion_entryInit(SharedRegion_Entry *entry)
561     /* Make sure entry is not NULL */
562     Assert_isTrue((entry != NULL), ti_sdo_ipc_Ipc_A_nullArgument);
564     /* init the entry to default values */
565     entry->base          = NULL;
566     entry->len           = 0;
567     entry->ownerProcId   = 0;
568     entry->cacheEnable   = TRUE;
569     entry->cacheLineSize = ti_sdo_ipc_SharedRegion_cacheLineSize;
570     entry->createHeap    = TRUE;
571     entry->name          = NULL;
572     entry->isValid       = FALSE;
575 /*
576  *  ======== SharedRegion_getHeap ========
577  */
578 Ptr SharedRegion_getHeap(UInt16 id)
580     IHeap_Handle heap = NULL;
582     /*
583      *  if translate == TRUE or translate == FALSE
584      *  and 'id' is not INVALIDREGIONID, then Assert id is valid.
585      *  Return the heap associated with the region id.
586      *
587      *  If those conditions are not met, the id is from
588      *  an addres in local memory so return NULL.
589      */
590     if ((ti_sdo_ipc_SharedRegion_translate) ||
591         ((ti_sdo_ipc_SharedRegion_translate == FALSE) &&
592         (id != SharedRegion_INVALIDREGIONID))) {
594         /* assert id is valid */
595         Assert_isTrue(id < ti_sdo_ipc_SharedRegion_numEntries,
596             ti_sdo_ipc_SharedRegion_A_idTooLarge);
598         heap = SharedRegion_module->regions[id].heap;
599     }
601     return (heap);
604 /*
605  *  ======== SharedRegion_translateEnabled ========
606  */
607 Bool SharedRegion_translateEnabled(Void)
609     return (ti_sdo_ipc_SharedRegion_translate);
612 /*
613  *  ======== SharedRegion_invalidSRPtr ========
614  */
615 SharedRegion_SRPtr SharedRegion_invalidSRPtr(Void)
617     return (ti_sdo_ipc_SharedRegion_INVALIDSRPTR);
620 /*
621  *************************************************************************
622  *                      Module functions
623  *************************************************************************
624  */
626 /*
627  *  ======== ti_sdo_ipc_SharedRegion_attach ========
628  */
629 Int ti_sdo_ipc_SharedRegion_attach(UInt16 remoteProcId)
631     Int i;
632     Ptr sharedAddr;
633     ti_sdo_ipc_SharedRegion_Region *region;
634     HeapMemMP_Handle    *heapHandlePtr;
635     Int status = SharedRegion_S_SUCCESS;
637     /*
638      *  Loop through the regions and open the heap if not owner
639      */
640     for (i = 0; i < ti_sdo_ipc_SharedRegion_numEntries; i++) {
641         region = &(SharedRegion_module->regions[i]);
642         if ((region->entry.isValid) &&
643             (region->entry.ownerProcId != MultiProc_self()) &&
644             (region->entry.ownerProcId != MultiProc_INVALIDID) &&
645             (region->entry.createHeap) &&
646             (region->heap == NULL)) {
647             /* sharedAddr should match creator's for each region */
648             sharedAddr = (Ptr)((UInt32)region->entry.base +
649                 region->reservedSize);
651             /* get the heap handle from SharedRegion Module state */
652             heapHandlePtr = (HeapMemMP_Handle *)&(region->heap);
654             /* heap should already be created so open by address */
655             status = HeapMemMP_openByAddr(sharedAddr, heapHandlePtr);
656         }
657     }
659     return(status);
662 /*
663  *  ======== ti_sdo_ipc_SharedRegion_detach ========
664  */
665 Int ti_sdo_ipc_SharedRegion_detach(UInt16 remoteProcId)
667     Int i;
668     ti_sdo_ipc_SharedRegion_Region *region;
669     HeapMemMP_Handle    *heapHandlePtr;
670     Int status = SharedRegion_S_SUCCESS;
672     /*
673      *  Loop through the regions and close the heap only when
674      *  detaching from owner of heap.
675      */
676     for (i = 0; i < ti_sdo_ipc_SharedRegion_numEntries; i++) {
677         region = &(SharedRegion_module->regions[i]);
678         if ((region->entry.isValid) &&
679             (region->entry.ownerProcId == remoteProcId) &&
680             (region->heap != NULL)) {
681             /* get the heap handle from SharedRegion Module state */
682             heapHandlePtr = (HeapMemMP_Handle *)&(region->heap);
684             /* heap should already be created so open by address */
685             status = HeapMemMP_close(heapHandlePtr);
686         }
687     }
689     return(status);
692 /*
693  *  ======== ti_sdo_ipc_SharedRegion_clearReservedMemory ========
694  *  Clears the reserve memory for each region in the table.
695  */
696 Void ti_sdo_ipc_SharedRegion_clearReservedMemory()
698     Int i;
699     ti_sdo_ipc_SharedRegion_Region *region;
701     /*
702      *  Loop through shared regions. If an owner of a region is specified,
703      *  the owner zeros out the reserved memory in each region.
704      */
705     for (i = 0; i < ti_sdo_ipc_SharedRegion_numEntries; i++) {
706         region = &(SharedRegion_module->regions[i]);
707         if ((region->entry.isValid) &&
708             (region->entry.ownerProcId == MultiProc_self())) {
709             /* clear reserved memory */
710             memset(region->entry.base, 0, region->reservedSize);
712             /* writeback invalidate the cache if enabled in region */
713             if (region->entry.cacheEnable) {
714                 Cache_wbInv(region->entry.base, region->reservedSize,
715                          Cache_Type_ALL, TRUE);
716             }
717         }
718     }
721 /*
722  *  ======== ti_sdo_ipc_SharedRegion_reserveMemory ========
723  */
724 Ptr ti_sdo_ipc_SharedRegion_reserveMemory(UInt16 id, SizeT size)
726     ti_sdo_ipc_SharedRegion_Region *region;
727     UInt32 minAlign;
728     SizeT curSize, newSize;
729     Ptr   retPtr;
731     /* Need to make sure id is smaller than numEntries */
732     Assert_isTrue((id < ti_sdo_ipc_SharedRegion_numEntries),
733         ti_sdo_ipc_SharedRegion_A_idTooLarge);
735     /* assert that region at specified id is valid */
736     Assert_isTrue(SharedRegion_module->regions[id].entry.isValid == TRUE,
737                   ti_sdo_ipc_SharedRegion_A_regionInvalid);
739     minAlign = Memory_getMaxDefaultTypeAlign();
740     if (SharedRegion_getCacheLineSize(id) > minAlign) {
741         minAlign = SharedRegion_getCacheLineSize(id);
742     }
744     region = &(SharedRegion_module->regions[id]);
746     /* Set the current size to the reservedSize */
747     curSize = region->reservedSize;
749     /* No need to round here since curSize is already aligned */
750     retPtr = (Ptr)((UInt32)region->entry.base + curSize);
752     /*  Round the new size to the min alignment since */
753     newSize = _Ipc_roundup(size, minAlign);
755     /* Need to make sure (curSize + newSize) is smaller than region len */
756     Assert_isTrue(((SizeT)(region->entry.len) >= (curSize + newSize)),
757                    ti_sdo_ipc_SharedRegion_A_reserveTooMuch);
759     /* Add the new size to current size */
760     region->reservedSize = curSize + newSize;
762     return (retPtr);
765 /*
766  *  ======== ti_sdo_ipc_SharedRegion_resetInternalFields ========
767  */
768 Void ti_sdo_ipc_SharedRegion_resetInternalFields(UInt16 id)
770     ti_sdo_ipc_SharedRegion_Region *region;
772     /* Need to make sure id is smaller than numEntries */
773     Assert_isTrue((id < ti_sdo_ipc_SharedRegion_numEntries),
774         ti_sdo_ipc_SharedRegion_A_idTooLarge);
776     region = &(SharedRegion_module->regions[id]);
778     region->reservedSize = 0;
781 /*
782  *  ======== ti_sdo_ipc_SharedRegion_start ========
783  */
784 Int ti_sdo_ipc_SharedRegion_start(Void)
786     Int i;
787     ti_sdo_ipc_SharedRegion_Region *region;
788     HeapMemMP_Params    params;
789     HeapMemMP_Handle    heapHandle;
790     Ptr                 sharedAddr;
791     Int status = SharedRegion_S_SUCCESS;
793     /* assert that region 0 is valid */
794     Assert_isTrue((ti_sdo_ipc_SharedRegion_numEntries > 0) &&
795         (SharedRegion_module->regions[0].entry.isValid),
796         ti_sdo_ipc_SharedRegion_A_region0Invalid);
798     /*
799      *  Loop through shared regions. If an owner of a region is specified
800      *  and createHeap has been specified for the SharedRegion, then
801      *  the owner creates a HeapMemMP and the other processors open it.
802      */
803     for (i = 0; i < ti_sdo_ipc_SharedRegion_numEntries; i++) {
804         region = &(SharedRegion_module->regions[i]);
805         if ((region->entry.isValid) &&
806             (region->entry.ownerProcId == MultiProc_self()) &&
807             (region->entry.createHeap) &&
808             (region->heap == NULL)) {
809             /* get the next free address in each region */
810             sharedAddr = (Ptr)((UInt32)region->entry.base +
811                 region->reservedSize);
813             /*  Create the HeapMemMP in the region. */
814             HeapMemMP_Params_init(&params);
815             params.sharedAddr = sharedAddr;
816             params.sharedBufSize = (SizeT)(region->entry.len) - region->reservedSize;
818             /* Adjust to account for the size of HeapMemMP_Attrs */
819             params.sharedBufSize -= (HeapMemMP_sharedMemReq(&params)
820                                     - params.sharedBufSize);
821             heapHandle = HeapMemMP_create(&params);
823             if (heapHandle == NULL) {
824                 status = SharedRegion_E_FAIL;
825             }
826             else {
827                 /* put heap handle into SharedRegion Module state */
828                 region->heap = (IHeap_Handle)heapHandle;
829             }
830         }
831     }
833     return (status);
836 /*
837  *  ======== ti_sdo_ipc_SharedRegion_stop ========
838  */
839 Int ti_sdo_ipc_SharedRegion_stop(Void)
841     Int i;
842     ti_sdo_ipc_SharedRegion_Region *region;
843     HeapMemMP_Handle    *heapHandlePtr;
844     Int status = SharedRegion_S_SUCCESS;
846     /*
847      *  Loop through shared regions. If owner then delete the heap,
848      *  otherwise the heap should have been closed in detach().
849      */
850     for (i = 0; i < ti_sdo_ipc_SharedRegion_numEntries; i++) {
851         region = &(SharedRegion_module->regions[i]);
852         if ((region->entry.isValid) &&
853             (region->entry.ownerProcId == MultiProc_self()) &&
854             (region->heap != NULL)) {
855             /* get the heap handle from SharedRegion Module state */
856             heapHandlePtr = (HeapMemMP_Handle *)&(region->heap);
858             /* delete the HeapMemMP */
859             status = HeapMemMP_delete(heapHandlePtr);
860         }
861     }
863     return (status);