ipc: Remove compiler warnings
[ipc/ipcdev.git] / packages / ti / sdo / ipc / GateMP.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  *  ======== GateMP.c ========
34  */
36 #include <xdc/std.h>
37 #include <string.h>
38 #include <xdc/runtime/Error.h>
39 #include <xdc/runtime/Assert.h>
40 #include <xdc/runtime/System.h>
41 #include <xdc/runtime/IGateProvider.h>
42 #include <xdc/runtime/IHeap.h>
43 #include <xdc/runtime/Memory.h>
44 #include <xdc/runtime/Log.h>
46 #include <ti/sdo/ipc/interfaces/IGateMPSupport.h>
48 #include <ti/sysbios/gates/GateMutexPri.h>
49 #include <ti/sysbios/gates/GateSwi.h>
50 #include <ti/sysbios/gates/GateAll.h>
51 #include <ti/sysbios/hal/Cache.h>
52 #include <ti/sysbios/hal/Hwi.h>
54 #include <ti/sdo/ipc/_Ipc.h>
55 #include <ti/sdo/utils/_MultiProc.h>
56 #include <ti/sdo/ipc/_GateMP.h>
57 #include <ti/sdo/utils/_NameServer.h>
58 #include <ti/sdo/ipc/_SharedRegion.h>
60 #include "package/internal/GateMP.xdc.h"
62 /* Helper macros */
63 #define GETREMOTE(mask) ((ti_sdo_ipc_GateMP_RemoteProtect)((mask) >> 8))
64 #define GETLOCAL(mask)  ((ti_sdo_ipc_GateMP_LocalProtect)((mask) & 0xFF))
65 #define SETMASK(remoteProtect, localProtect) \
66                         ((Bits32)((remoteProtect) << 8 | (localProtect)))
68 /* Values used to populate the resource 'inUse' arrays */
69 #define UNUSED          ((UInt8)0)
70 #define USED            ((UInt8)1)
71 #define RESERVED        ((UInt8)-1)
73 #ifdef __ti__
74     #pragma FUNC_EXT_CALLED(GateMP_Params_init);
75     #pragma FUNC_EXT_CALLED(GateMP_create);
76     #pragma FUNC_EXT_CALLED(GateMP_close);
77     #pragma FUNC_EXT_CALLED(GateMP_delete);
78     #pragma FUNC_EXT_CALLED(GateMP_enter);
79     #pragma FUNC_EXT_CALLED(GateMP_getDefaultRemote);
80     #pragma FUNC_EXT_CALLED(GateMP_getLocalProtect);
81     #pragma FUNC_EXT_CALLED(GateMP_getRemoteProtect);
82     #pragma FUNC_EXT_CALLED(GateMP_leave);
83     #pragma FUNC_EXT_CALLED(GateMP_open);
84     #pragma FUNC_EXT_CALLED(GateMP_openByAddr);
85     #pragma FUNC_EXT_CALLED(GateMP_sharedMemReq);
86 #endif
88 /*
89  *  ======== GateMP_getSharedParams ========
90  */
91 static Void GateMP_getSharedParams(GateMP_Params *sparams,
92         const ti_sdo_ipc_GateMP_Params *params)
93 {
94     sparams->name             = params->name;
95     sparams->regionId         = params->regionId;
96     sparams->sharedAddr       = params->sharedAddr;
97     sparams->localProtect     = (GateMP_LocalProtect)
98         params->localProtect;
99     sparams->remoteProtect    = (GateMP_RemoteProtect)
100         params->remoteProtect;
103 /*
104  *  ======== GateMP_getRTSCParams ========
105  */
106 static Void GateMP_getRTSCParams(ti_sdo_ipc_GateMP_Params *params,
107         const GateMP_Params *sparams)
110     ti_sdo_ipc_GateMP_Params_init(params);
112     params->name             = sparams->name;
113     params->regionId         = sparams->regionId;
114     params->sharedAddr       = sparams->sharedAddr;
115     params->localProtect     = (ti_sdo_ipc_GateMP_LocalProtect)
116         sparams->localProtect;
117     params->remoteProtect    = (ti_sdo_ipc_GateMP_RemoteProtect)
118         sparams->remoteProtect;
121 /*
122  *************************************************************************
123  *                       Common Header Functions
124  *************************************************************************
125  */
127 /*
128  *  ======== GateMP_Params_init ========
129  */
130 Void GateMP_Params_init(GateMP_Params *sparams)
132     ti_sdo_ipc_GateMP_Params params;
134     ti_sdo_ipc_GateMP_Params_init(&params);
135     GateMP_getSharedParams(sparams, &params);
138 /*
139  *  ======== GateMP_create ========
140  */
141 GateMP_Handle GateMP_create(const GateMP_Params *sparams)
143     ti_sdo_ipc_GateMP_Params params;
144     ti_sdo_ipc_GateMP_Object *obj;
145     Error_Block eb;
147     GateMP_getRTSCParams(&params, (Ptr)sparams);
149     Error_init(&eb);
151     /* call the module create */
152     obj = ti_sdo_ipc_GateMP_create(&params, &eb);
154     return ((GateMP_Handle)obj);
157 /*
158  *  ======== GateMP_close ========
159  */
160 Int GateMP_close(GateMP_Handle *handlePtr)
162     ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)*handlePtr;
163     UInt key;
164     Int count;
166     /*
167      *  Cannot call with the numOpens equal to zero.  This is either
168      *  a created handle or been closed already.
169      */
170     Assert_isTrue((obj->numOpens != 0), ti_sdo_ipc_GateMP_A_invalidClose);
172     key = Hwi_disable();
173     count = --obj->numOpens;
174     Hwi_restore(key);
176     /*
177      *  if the count is zero and the gate is opened, then this
178      *  object was created in the open (i.e. the create happened
179      *  on a remote processor.
180      */
181     if ((count == 0) && (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC)) {
182         GateMP_delete(handlePtr);
183     }
185     *handlePtr = NULL;
187     return (GateMP_S_SUCCESS);
190 /*
191  *  ======== GateMP_delete ========
192  */
193 Int GateMP_delete(GateMP_Handle *handlePtr)
195     ti_sdo_ipc_GateMP_delete((ti_sdo_ipc_GateMP_Handle *)handlePtr);
197     return (GateMP_S_SUCCESS);
200 /*
201  *  ======== GateMP_enter ========
202  */
203 IArg GateMP_enter(GateMP_Handle handle)
205     IArg key;
206     ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)handle;
208     Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
210     key = IGateProvider_enter(obj->gateHandle);
212     Log_write3(ti_sdo_ipc_GateMP_LM_enter,(UArg)obj->remoteProtect,
213             (UArg)obj->resourceId, key);
215     return (key);
218 /*
219  *  ======== GateMP_leave ========
220  */
221 Void GateMP_leave(GateMP_Handle handle, IArg key)
223     ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)handle;
225     Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
227     IGateProvider_leave(obj->gateHandle, key);
229     Log_write3(ti_sdo_ipc_GateMP_LM_leave, (UArg)obj->remoteProtect,
230         (UArg)obj->resourceId, key);
233 /*
234  *  ======== GateMP_open ========
235  */
236 Int GateMP_open(String name, GateMP_Handle *handlePtr)
238     SharedRegion_SRPtr sharedShmBase;
239     Int status;
240     ti_sdo_ipc_GateMP_Object *obj;
241     ti_sdo_ipc_GateMP_Params params;
242     Error_Block eb;
243     UInt key;
244     UInt32 len;
245     UInt32 mask;
246     UInt32 resourceId;
247     Ptr sharedAddr;
248     UInt32 nsValue[4];
250     Error_init(&eb);
252     /* Assert that a pointer has been supplied */
253     Assert_isTrue(handlePtr != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
255     len = sizeof(nsValue);
257     /*
258      *  Get the Attrs out of the NameServer instance.
259      *  Search all processors.
260      */
261     status = NameServer_get((NameServer_Handle)GateMP_module->nameServer, name,
262             &nsValue, &len, MultiProc_getClusterProcList());
264     if (status < 0) {
265         *handlePtr = NULL;
266         return (GateMP_E_NOTFOUND);
267     }
269     /*
270      * The least significant bit of nsValue[1] == 0 means its a
271      * local GateMP, otherwise its a remote GateMP.
272      */
273     if (((nsValue[1] & 0x1) == 0) &&
274         ((nsValue[1] >> 16) != MultiProc_self())) {
275         /* Trying to open a local GateMP remotely */
276         *handlePtr = NULL;
277         return (GateMP_E_FAIL);
278     }
280     if ((nsValue[1] & 0x1) == 0) {
281         /*
282          * Opening a local GateMP locally. The GateMP is created
283          * from a local heap so don't do SharedRegion Ptr conversion.
284          */
285         sharedAddr = (Ptr)nsValue[0];
286         status = GateMP_openByAddr(sharedAddr, handlePtr);
287     }
288     else if (GateMP_module->hostSupport == FALSE) {
289         /* Opening a remote GateMP. Need to do SharedRegion Ptr conversion. */
290         sharedShmBase = (SharedRegion_SRPtr)nsValue[0];
291         sharedAddr = SharedRegion_getPtr(sharedShmBase);
292         if ( sharedAddr == NULL ) {
293             *handlePtr = NULL;
294             return (GateMP_E_FAIL);
295         }
296         status = GateMP_openByAddr(sharedAddr, handlePtr);
297     }
298     else {
299         /*  need to track number of opens atomically */
300         key = Hwi_disable();
301         resourceId = nsValue[2];
302         mask = nsValue[3];
304         /* Remote case */
305         switch (GETREMOTE(mask)) {
306             case GateMP_RemoteProtect_SYSTEM:
307                 obj = GateMP_module->remoteSystemGates[resourceId];
308                 break;
310             case GateMP_RemoteProtect_CUSTOM1:
311                 obj = GateMP_module->remoteCustom1Gates[resourceId];
312                 break;
314             case GateMP_RemoteProtect_CUSTOM2:
315                 obj = GateMP_module->remoteCustom2Gates[resourceId];
316                 break;
318             default:
319                 obj = NULL;
320                 status = GateMP_E_FAIL;
321                 break;
322         }
324         if (status == GateMP_S_SUCCESS) {
325             /*
326              *  If the object is NULL, then it must have been created on a
327              *  remote processor. Need to create a local object. This is
328              *  accomplished by setting the openFlag to TRUE.
329              */
330             if (obj == NULL) {
331                 /* Create a GateMP object with the openFlag set to true */
332                 ti_sdo_ipc_GateMP_Params_init(&params);
333                 params.openFlag = TRUE;
334                 params.sharedAddr = NULL;
335                 params.resourceId = resourceId;
336                 params.localProtect = GETLOCAL(mask);
337                 params.remoteProtect = GETREMOTE(mask);
339                 obj = ti_sdo_ipc_GateMP_create(&params, &eb);
340                 if (obj == NULL) {
341                     status = GateMP_E_FAIL;
342                 }
343             }
344             else {
345                 obj->numOpens++;
346             }
347         }
349         /* Return the GateMP instance  */
350         *handlePtr = (GateMP_Handle)obj;
352         /* restore hwi mask */
353         Hwi_restore(key);
354     }
356     return (status);
359 /*
360  *  ======== GateMP_openByAddr ========
361  */
362 Int GateMP_openByAddr(Ptr sharedAddr, GateMP_Handle *handlePtr)
364     Int status = GateMP_S_SUCCESS;
365     UInt key;
366     ti_sdo_ipc_GateMP_Object *obj;
367     ti_sdo_ipc_GateMP_Params params;
368     ti_sdo_ipc_GateMP_Attrs *attrs;
369     UInt16 regionId;
370     Error_Block eb;
372     Error_init(&eb);
374     attrs = (ti_sdo_ipc_GateMP_Attrs *)sharedAddr;
376     /* get the region id and invalidate attrs is needed */
377     regionId = SharedRegion_getId(sharedAddr);
378     if (regionId != SharedRegion_INVALIDREGIONID) {
379         if (SharedRegion_isCacheEnabled(regionId)) {
380             Cache_inv(attrs, sizeof(ti_sdo_ipc_GateMP_Attrs), Cache_Type_ALL,
381                     TRUE);
382         }
383     }
385     if (attrs->status != ti_sdo_ipc_GateMP_CREATED) {
386         *handlePtr = NULL;
387         status = GateMP_E_NOTFOUND;
388     }
389     else {
390         /* Local gate */
391         if (GETREMOTE(attrs->mask) == GateMP_RemoteProtect_NONE) {
392             if (attrs->creatorProcId != MultiProc_self()) {
393                 Error_raise(&eb, ti_sdo_ipc_GateMP_E_localGate, 0, 0);
394                 return (GateMP_E_FAIL);
395             }
397             /* need to atomically increment number of opens */
398             key = Hwi_disable();
400             obj = (ti_sdo_ipc_GateMP_Object *)attrs->arg;
401             *handlePtr = (GateMP_Handle)obj;
402             obj->numOpens++;
404             /* restore hwi mask */
405             Hwi_restore(key);
407             return (GateMP_S_SUCCESS);
408         }
410         /*  need to track number of opens atomically */
411         key = Hwi_disable();
413         /* Remote case */
414         switch (GETREMOTE(attrs->mask)) {
415             case GateMP_RemoteProtect_SYSTEM:
416                 obj = GateMP_module->remoteSystemGates[attrs->arg];
417                 break;
419             case GateMP_RemoteProtect_CUSTOM1:
420                 obj = GateMP_module->remoteCustom1Gates[attrs->arg];
421                 break;
423             case GateMP_RemoteProtect_CUSTOM2:
424                 obj = GateMP_module->remoteCustom2Gates[attrs->arg];
425                 break;
427             default:
428                 obj = NULL;
429                 status = GateMP_E_FAIL;
430                 break;
431         }
433         if (status == GateMP_S_SUCCESS) {
434             /*
435              *  If the object is NULL, then it must have been created on a
436              *  remote processor. Need to create a local object. This is
437              *  accomplished by setting the openFlag to TRUE.
438              */
439             if (obj == NULL) {
440                 /* Create a GateMP object with the openFlag set to true */
441                 ti_sdo_ipc_GateMP_Params_init(&params);
442                 params.openFlag = TRUE;
443                 params.sharedAddr = sharedAddr;
444                 params.resourceId = attrs->arg;
445                 params.localProtect = GETLOCAL(attrs->mask);
446                 params.remoteProtect = GETREMOTE(attrs->mask);
448                 obj = ti_sdo_ipc_GateMP_create(&params, &eb);
449                 if (obj == NULL) {
450                     status = GateMP_E_FAIL;
451                 }
452             }
453             else {
454                 obj->numOpens++;
455             }
456         }
458         /* Return the GateMP instance  */
459         *handlePtr = (GateMP_Handle)obj;
461         /* restore hwi mask */
462         Hwi_restore(key);
463     }
465     return (status);
468 /*
469  *  ======== GateMP_sharedMemReq ========
470  */
471 SizeT GateMP_sharedMemReq(const GateMP_Params *params)
473     SizeT memReq, minAlign;
474     UInt16 regionId;
475     ti_sdo_ipc_GateMP_RemoteSystemProxy_Params systemParams;
476     ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params custom1Params;
477     ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params custom2Params;
479     if (params->sharedAddr) {
480         regionId = SharedRegion_getId(params->sharedAddr);
481     }
482     else {
483         regionId = params->regionId;
484     }
486     Assert_isTrue(regionId != SharedRegion_INVALIDREGIONID,
487             ti_sdo_ipc_Ipc_A_internal);
489     minAlign = Memory_getMaxDefaultTypeAlign();
490     if (SharedRegion_getCacheLineSize(regionId) > minAlign) {
491         minAlign = SharedRegion_getCacheLineSize(regionId);
492     }
494     memReq = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
496     /* add the amount of shared memory required by proxy */
497     if (params->remoteProtect == GateMP_RemoteProtect_SYSTEM) {
498         ti_sdo_ipc_GateMP_RemoteSystemProxy_Params_init(&systemParams);
499         systemParams.regionId = regionId;
500         memReq += ti_sdo_ipc_GateMP_RemoteSystemProxy_sharedMemReq(
501                 (IGateMPSupport_Params *)&systemParams);
502     }
503     else if (params->remoteProtect == GateMP_RemoteProtect_CUSTOM1) {
504         ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params_init(&custom1Params);
505         custom1Params.regionId = regionId;
506         memReq += ti_sdo_ipc_GateMP_RemoteCustom1Proxy_sharedMemReq(
507                 (IGateMPSupport_Params *)&custom1Params);
508     }
509     else if (params->remoteProtect == GateMP_RemoteProtect_CUSTOM2) {
510         ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params_init(&custom2Params);
511         custom2Params.regionId = regionId;
512         memReq += ti_sdo_ipc_GateMP_RemoteCustom2Proxy_sharedMemReq(
513                 (IGateMPSupport_Params *)&custom2Params);
514     }
516     return (memReq);
519 /*
520  *************************************************************************
521  *                       Module functions
522  *************************************************************************
523  */
525 /*
526  *  ======== ti_sdo_ipc_GateMP_createLocal ========
527  */
528 IGateProvider_Handle ti_sdo_ipc_GateMP_createLocal(
529     ti_sdo_ipc_GateMP_LocalProtect localProtect)
531     IGateProvider_Handle gateHandle;
533     /* Create the local gate. */
534     switch (localProtect) {
535         case GateMP_LocalProtect_NONE:
536             /* Plug with the GateNull singleton */
537             gateHandle = GateMP_module->gateNull;
538             break;
540         case GateMP_LocalProtect_INTERRUPT:
541             /* Plug with the GateAll singleton */
542             gateHandle = GateMP_module->gateAll;
543             break;
545         case GateMP_LocalProtect_TASKLET:
546             /* Plug with the GateSwi singleton */
547             gateHandle = GateMP_module->gateSwi;
548             break;
550         case GateMP_LocalProtect_THREAD:
551         case GateMP_LocalProtect_PROCESS:
552             /* Plug with the GateMutexPri singleton */
553             gateHandle = GateMP_module->gateMutexPri;
554             break;
556         default:
557             /* Invalid local protection level encountered */
558             Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
559             break;
560     }
562     return (gateHandle);
565 /*
566  *  ======== GateMP_getDefaultRemote ========
567  */
568 GateMP_Handle GateMP_getDefaultRemote()
570     return ((GateMP_Handle)GateMP_module->defaultGate);
573 /*
574  *  ======== GateMP_getLocalProtect ========
575  */
576 GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
578     ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)handle;
580     Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
582     return ((GateMP_LocalProtect)obj->localProtect);
585 /*
586  *  ======== GateMP_getRemoteProtect ========
587  */
588 GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
590     ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)handle;
592     Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
594     return ((GateMP_RemoteProtect)obj->remoteProtect);
597 /*
598  *  ======== ti_sdo_ipc_GateMP_getRegion0ReservedSize ========
599  */
600 SizeT ti_sdo_ipc_GateMP_getRegion0ReservedSize(Void)
602     SizeT reserved, minAlign;
604     minAlign = Memory_getMaxDefaultTypeAlign();
606     if (SharedRegion_getCacheLineSize(0) > minAlign) {
607         minAlign = SharedRegion_getCacheLineSize(0);
608     }
610     reserved = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
612     reserved += _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
614     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
615         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
616             reserved += _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
617     }
619     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
620         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
621             reserved += _Ipc_roundup(GateMP_module->numRemoteCustom2, minAlign);
622     }
624     return (reserved);
627 /*
628  *  ======== ti_sdo_ipc_GateMP_setRegion0Reserved ========
629  */
630 Void ti_sdo_ipc_GateMP_setRegion0Reserved(Ptr sharedAddr)
632     ti_sdo_ipc_GateMP_Reserved *reserve;
633     SizeT minAlign, offset;
634     UInt i;
635     Bits32 *delegateReservedMask;
636     UInt32 nsValue[6];
637     Int ret;
639     minAlign = Memory_getMaxDefaultTypeAlign();
640     if (SharedRegion_getCacheLineSize(0) > minAlign) {
641         minAlign = SharedRegion_getCacheLineSize(0);
642     }
644     /* setup ti_sdo_ipc_GateMP_Reserved fields */
645     reserve = (ti_sdo_ipc_GateMP_Reserved *)sharedAddr;
646     reserve->version = ti_sdo_ipc_GateMP_VERSION;
648     if (SharedRegion_isCacheEnabled(0)) {
649         Cache_wbInv(sharedAddr, sizeof(ti_sdo_ipc_GateMP_Reserved),
650             Cache_Type_ALL, TRUE);
651     }
653     /*
654      *  initialize the in-use array in shared memory for the system gates.
655      */
656     offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
657     GateMP_module->remoteSystemInUse =
658         (Ptr)((uintptr_t)sharedAddr + offset);
660     if (GateMP_module->numRemoteSystem != 0) {
661         memset(GateMP_module->remoteSystemInUse, 0,
662             GateMP_module->numRemoteSystem * sizeof(UInt8));
663         delegateReservedMask =
664                 ti_sdo_ipc_GateMP_RemoteSystemProxy_getReservedMask();
665         if (delegateReservedMask != NULL) {
666             for (i = 0; i < GateMP_module->numRemoteSystem; i++) {
667                 if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
668                     GateMP_module->remoteSystemInUse[i] = RESERVED;
669                 }
670             }
671         }
673         if (SharedRegion_isCacheEnabled(0)) {
674             Cache_wbInv(GateMP_module->remoteSystemInUse,
675                 GateMP_module->numRemoteSystem * sizeof(UInt8),
676                 Cache_Type_ALL,
677                 TRUE);
678         }
679     }
681     /*
682      *  initialize the in-use array in shared memory for the custom1 gates.
683      *  Need to check if this proxy is the same as system
684      */
685     offset = _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
686     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
687         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
688         if (GateMP_module->numRemoteCustom1 != 0) {
689             GateMP_module->remoteCustom1InUse =
690                 GateMP_module->remoteSystemInUse + offset;
692             memset(GateMP_module->remoteCustom1InUse, 0,
693                 GateMP_module->numRemoteCustom1 * sizeof(UInt8));
694             delegateReservedMask =
695                     ti_sdo_ipc_GateMP_RemoteCustom1Proxy_getReservedMask();
696             if (delegateReservedMask != NULL) {
697                 for (i = 0; i < GateMP_module->numRemoteCustom1; i++) {
698                     if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
699                         GateMP_module->remoteCustom1InUse[i] = RESERVED;
700                     }
701                 }
702             }
703             if (SharedRegion_isCacheEnabled(0)) {
704                 Cache_wbInv(GateMP_module->remoteCustom1InUse,
705                      GateMP_module->numRemoteCustom1 * sizeof(UInt8),
706                      Cache_Type_ALL,
707                      TRUE);
708             }
709         }
710     }
711     else {
712         GateMP_module->remoteCustom1InUse = GateMP_module->remoteSystemInUse;
713         GateMP_module->remoteCustom1Gates = GateMP_module->remoteSystemGates;
714     }
716     /*
717      *  initialize the in-use array in shared memory for the custom2 gates.
718      *  Need to check if this proxy is the same as system or custom1
719      */
720     offset = _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
721     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
722         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
723         if (GateMP_module->numRemoteCustom2 != 0) {
724                 GateMP_module->remoteCustom2InUse =
725                     GateMP_module->remoteCustom1InUse + offset;
727             memset(GateMP_module->remoteCustom2InUse, 0,
728                 GateMP_module->numRemoteCustom2 * sizeof(UInt8));
729             delegateReservedMask =
730                     ti_sdo_ipc_GateMP_RemoteCustom2Proxy_getReservedMask();
731             if (delegateReservedMask != NULL) {
732                 for (i = 0; i < GateMP_module->numRemoteCustom2; i++) {
733                     if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
734                         GateMP_module->remoteCustom2InUse[i] = RESERVED;
735                     }
736                 }
737             }
739             if (SharedRegion_isCacheEnabled(0)) {
740                 Cache_wbInv(GateMP_module->remoteCustom2InUse,
741                      GateMP_module->numRemoteCustom2 * sizeof(UInt8),
742                      Cache_Type_ALL,
743                      TRUE);
744             }
745         }
746     }
747     else if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
748              ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
749         GateMP_module->remoteCustom2InUse =
750             GateMP_module->remoteCustom1InUse;
751         GateMP_module->remoteCustom2Gates =
752             GateMP_module->remoteCustom1Gates;
753     }
754     else {
755         GateMP_module->remoteCustom2InUse = GateMP_module->remoteSystemInUse;
756         GateMP_module->remoteCustom2Gates = GateMP_module->remoteSystemGates;
757     }
759     if (GateMP_module->hostSupport == TRUE) {
760         /* Add special entry to store inuse arrays' location and size */
761         ret = _GateMP_virtToPhys(
762             (uintptr_t)GateMP_module->remoteSystemInUse, &nsValue[0]);
763         Assert_isTrue(ret == GateMP_S_SUCCESS, (Assert_Id)0);
764         (void)ret;   /* silence unused var warning when asserts disabled */
765         if (GateMP_module->numRemoteCustom1 != 0) {
766             ret = _GateMP_virtToPhys(
767                 (uintptr_t)GateMP_module->remoteCustom1InUse, &nsValue[1]);
768             Assert_isTrue(ret == GateMP_S_SUCCESS, (Assert_Id)0);
769         }
770         else {
771             nsValue[1] = 0;
772         }
773         if (GateMP_module->numRemoteCustom2 != 0) {
774             ret = _GateMP_virtToPhys(
775                 (uintptr_t)GateMP_module->remoteCustom2InUse, &nsValue[2]);
776             Assert_isTrue(ret == GateMP_S_SUCCESS, (Assert_Id)0);
777         }
778         else {
779             nsValue[2] = 0;
780         }
781         nsValue[3] = GateMP_module->numRemoteSystem;
782         nsValue[4] = GateMP_module->numRemoteCustom1;
783         nsValue[5] = GateMP_module->numRemoteCustom2;
784         GateMP_module->nsKey = NameServer_add((NameServer_Handle)
785             GateMP_module->nameServer, "_GateMP_TI_info", &nsValue,
786             sizeof(nsValue));
787     }
790 /*
791  *  ======== ti_sdo_ipc_GateMP_openRegion0Reserved ========
792  */
793 Void ti_sdo_ipc_GateMP_openRegion0Reserved(Ptr sharedAddr)
795     ti_sdo_ipc_GateMP_Reserved *reserve;
796     SizeT minAlign, offset;
798     minAlign = Memory_getMaxDefaultTypeAlign();
799     if (SharedRegion_getCacheLineSize(0) > minAlign) {
800         minAlign = SharedRegion_getCacheLineSize(0);
801     }
804     /* setup ti_sdo_ipc_GateMP_Reserved fields */
805     reserve = (ti_sdo_ipc_GateMP_Reserved *)sharedAddr;
807     if (reserve->version != ti_sdo_ipc_GateMP_VERSION) {
808         /* Version mismatch: return an error */
809         Error_raise(NULL, ti_sdo_ipc_Ipc_E_versionMismatch, reserve->version,
810                     ti_sdo_ipc_GateMP_VERSION);
811         return;
812     }
814     offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
815     GateMP_module->remoteSystemInUse =
816         (Ptr)((uintptr_t)sharedAddr + offset);
818     /*
819      *  initialize the in-use array in shared memory for the custom1 gates.
820      *  Need to check if this proxy is the same as system
821      */
822     offset = _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
823     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
824         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
825         if (GateMP_module->numRemoteCustom1 != 0) {
826             GateMP_module->remoteCustom1InUse =
827                 GateMP_module->remoteSystemInUse + offset;
828         }
829     }
830     else {
831         GateMP_module->remoteCustom1InUse = GateMP_module->remoteSystemInUse;
832         GateMP_module->remoteCustom1Gates = GateMP_module->remoteSystemGates;
833     }
835     offset = _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
836     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
837         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
838         if (GateMP_module->numRemoteCustom2 != 0) {
839             GateMP_module->remoteCustom2InUse =
840                 GateMP_module->remoteCustom1InUse + offset;
841         }
842     }
843     else if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
844              ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
845         GateMP_module->remoteCustom2InUse =
846             GateMP_module->remoteCustom1InUse;
847         GateMP_module->remoteCustom2Gates =
848             GateMP_module->remoteCustom1Gates;
849     }
850     else {
851         GateMP_module->remoteCustom2InUse = GateMP_module->remoteSystemInUse;
852         GateMP_module->remoteCustom2Gates = GateMP_module->remoteSystemGates;
853     }
856 /*
857  *  ======== ti_sdo_ipc_GateMP_attach ========
858  */
859 Int ti_sdo_ipc_GateMP_attach(UInt16 remoteProcId, Ptr sharedAddr)
861     Ptr gateMPsharedAddr;
862     SharedRegion_Entry entry;
863     ti_sdo_ipc_GateMP_Handle defaultGate;
864     Int status = GateMP_S_SUCCESS;
866     /* If default gate is not NULL return since its already set */
867     if (GateMP_getDefaultRemote() != NULL) {
868         return(GateMP_S_ALREADYSETUP);
869     }
871     /* get region 0 information */
872     SharedRegion_getEntry(0, &entry);
874     gateMPsharedAddr = (Ptr)((uintptr_t)sharedAddr +
875                        ti_sdo_ipc_GateMP_getRegion0ReservedSize());
877     if ((entry.ownerProcId != MultiProc_self()) &&
878         (entry.ownerProcId != MultiProc_INVALIDID)) {
880         /* Make sure to invalidate cache before using shared memory content */
881         if (entry.cacheEnable) {
882             Cache_inv(sharedAddr, ti_sdo_ipc_GateMP_getRegion0ReservedSize(),
883                       Cache_Type_ALL, TRUE);
884         }
886         /* if not the owner of the SharedRegion */
887         ti_sdo_ipc_GateMP_openRegion0Reserved(sharedAddr);
889         /* open the gate by address */
890         status = GateMP_openByAddr(gateMPsharedAddr,
891                 (GateMP_Handle *)&defaultGate);
893         /* openByAddr should always succeed */
894         Assert_isTrue(status >= 0, ti_sdo_ipc_Ipc_A_internal);
896         /* set the default GateMP for opener */
897         ti_sdo_ipc_GateMP_setDefaultRemote(defaultGate);
898     }
900     return (status);
903 /*
904  *  ======== ti_sdo_ipc_GateMP_detach ========
905  */
906 Int ti_sdo_ipc_GateMP_detach(UInt16 remoteProcId)
908     SharedRegion_Entry entry;
909     GateMP_Handle gate;
910     Int status = GateMP_S_SUCCESS;
912     /* get region 0 information */
913     SharedRegion_getEntry(0, &entry);
915     if ((entry.isValid) &&
916         (entry.ownerProcId == remoteProcId)) {
917         /* get the default gate */
918         gate = GateMP_getDefaultRemote();
920         if (gate != NULL) {
921             /* close the gate */
922             status = GateMP_close(&gate);
924             /* set the default remote gate to NULL */
925             ti_sdo_ipc_GateMP_setDefaultRemote(NULL);
926         }
927     }
929     return (status);
932 /*
933  *  ======== ti_sdo_ipc_GateMP_start ========
934  */
935 Int ti_sdo_ipc_GateMP_start(Ptr sharedAddr)
937     SharedRegion_Entry       entry;
938     ti_sdo_ipc_GateMP_Params gateMPParams;
939     ti_sdo_ipc_GateMP_Handle defaultGate;
940     Int status = GateMP_S_SUCCESS;
941     Error_Block eb;
943     /* get region 0 information */
944     SharedRegion_getEntry(0, &entry);
946     /* if entry owner proc is not specified return */
947     if (entry.ownerProcId == MultiProc_INVALIDID) {
948         return (status);
949     }
951     if (entry.ownerProcId == MultiProc_self()) {
952         /* if owner of the SharedRegion */
953         ti_sdo_ipc_GateMP_setRegion0Reserved(sharedAddr);
955         /* create default GateMP */
956         ti_sdo_ipc_GateMP_Params_init(&gateMPParams);
957         gateMPParams.sharedAddr = (Ptr)((uintptr_t)sharedAddr +
958                 ti_sdo_ipc_GateMP_getRegion0ReservedSize());
959         gateMPParams.localProtect  = ti_sdo_ipc_GateMP_LocalProtect_TASKLET;
960         gateMPParams.name = "_GateMP_TI_dGate";
962         if (ti_sdo_utils_MultiProc_numProcessors > 1) {
963             gateMPParams.remoteProtect = ti_sdo_ipc_GateMP_RemoteProtect_SYSTEM;
964         }
965         else {
966             gateMPParams.remoteProtect = ti_sdo_ipc_GateMP_RemoteProtect_NONE;
967         }
969         Error_init(&eb);
970         defaultGate = ti_sdo_ipc_GateMP_create(&gateMPParams, &eb);
971         if (defaultGate != NULL) {
972             /* set the default GateMP for creator */
973             ti_sdo_ipc_GateMP_setDefaultRemote(defaultGate);
974         }
975         else {
976             status = GateMP_E_FAIL;
977         }
978     }
980     return (status);
983 /*
984  *  ======== ti_sdo_ipc_GateMP_stop ========
985  */
986 Int ti_sdo_ipc_GateMP_stop()
988     SharedRegion_Entry entry;
989     GateMP_Handle gate;
990     Int status = GateMP_S_SUCCESS;
992     /* get region 0 information */
993     SharedRegion_getEntry(0, &entry);
995     if ((entry.isValid) &&
996         (entry.createHeap) &&
997         (entry.ownerProcId == MultiProc_self())) {
998         /* get the default GateMP */
999         gate = GateMP_getDefaultRemote();
1001         if (gate != NULL) {
1002             /* set the default GateMP to NULL */
1003             ti_sdo_ipc_GateMP_setDefaultRemote(NULL);
1005             /* delete the default GateMP */
1006             status = GateMP_delete(&gate);
1007         }
1009         /* Remove global info entry from NameServer */
1010         if ((GateMP_module->hostSupport == TRUE) &&
1011             (GateMP_module->nsKey != 0)) {
1012             NameServer_removeEntry((NameServer_Handle)GateMP_module->nameServer,
1013                 GateMP_module->nsKey);
1014         }
1015     }
1017     return (status);
1020 /*
1021  *************************************************************************
1022  *                       Instance functions
1023  *************************************************************************
1024  */
1026 /*
1027  *  ======== ti_sdo_ipc_GateMP_Instance_init ========
1028  */
1029 Int ti_sdo_ipc_GateMP_Instance_init(ti_sdo_ipc_GateMP_Object *obj,
1030         const ti_sdo_ipc_GateMP_Params *params,
1031         Error_Block *eb)
1033     UInt key;
1034     IGateMPSupport_Handle remoteHandle;
1035     IGateProvider_Handle localHandle;
1036     ti_sdo_ipc_GateMP_RemoteSystemProxy_Params systemParams;
1037     ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params custom1Params;
1038     ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params custom2Params;
1039     SizeT minAlign, offset;
1040     SharedRegion_SRPtr sharedShmBase;
1041     GateMP_Params sparams;
1042     UInt32 nsValue[4];
1043     UInt32 sizeNsValue;
1044     IHeap_Handle regionHeap;
1046     /* Initialize resourceId to an invalid value */
1047     obj->resourceId = (UInt)-1;
1049     localHandle = ti_sdo_ipc_GateMP_createLocal(params->localProtect);
1051     /* Open GateMP instance */
1052     if (params->openFlag == TRUE) {
1053         /* all open work done here except for remote gateHandle */
1054         obj->localProtect   = params->localProtect;
1055         obj->remoteProtect  = params->remoteProtect;
1056         obj->nsKey          = 0;
1057         obj->numOpens       = 0; /* Will be set to 1 after init() complete */
1058         obj->attrs          = (ti_sdo_ipc_GateMP_Attrs *)params->sharedAddr;
1059         if (obj->attrs != NULL) {
1060             obj->regionId       = SharedRegion_getId((Ptr)obj->attrs);
1061             obj->cacheEnabled   = SharedRegion_isCacheEnabled(obj->regionId);
1062             /* Assert that the buffer is in a valid shared region */
1063             Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID,
1064                       ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);
1065         }
1067         obj->allocSize      = 0;
1068         obj->objType        = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC;
1070         minAlign = Memory_getMaxDefaultTypeAlign();
1072         if ((obj->attrs != NULL) &&
1073             (SharedRegion_getCacheLineSize(obj->regionId) > minAlign)) {
1074             minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1075         }
1077         offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1079         /* TODO: host side created gates cannot have proxy memory */
1080         if (obj->attrs != NULL) {
1081             obj->proxyAttrs = (Ptr)((uintptr_t)obj->attrs + offset);
1082         }
1083         else {
1084             obj->proxyAttrs = NULL;
1085         }
1086     }
1087     /* Create GateMP instance */
1088     else {
1089         obj->localProtect  = params->localProtect;
1090         obj->remoteProtect = params->remoteProtect;
1091         obj->nsKey         = 0;
1092         obj->numOpens      = 0;
1094         if (obj->remoteProtect == GateMP_RemoteProtect_NONE) {
1095             obj->gateHandle = ti_sdo_ipc_GateMP_createLocal(obj->localProtect);
1096             if (params->sharedAddr != NULL) {
1097                 /* Create a local gate using shared memory */
1098                 obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
1099                 obj->attrs = params->sharedAddr;
1100                 obj->regionId = SharedRegion_getId((Ptr)obj->attrs);
1101                 obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
1102             }
1103             else {
1104                 /* Create a local gate allocating from the local heap */
1105                 obj->objType = ti_sdo_ipc_Ipc_ObjType_LOCAL;
1106                 obj->regionId = ti_sdo_ipc_SharedRegion_INVALIDREGIONID;
1107                 obj->cacheEnabled  = FALSE; /* local */
1108                 obj->attrs = Memory_alloc(NULL,
1109                         sizeof(ti_sdo_ipc_GateMP_Attrs), 0, eb);
1110                 if (obj->attrs == NULL) {
1111                     return (2);
1112                 }
1114             }
1116             obj->attrs->arg = (Bits32)obj;
1117             obj->attrs->mask = SETMASK(obj->remoteProtect, obj->localProtect);
1118             obj->attrs->creatorProcId = MultiProc_self();
1119             obj->attrs->status = ti_sdo_ipc_GateMP_CREATED;
1120             if (obj->cacheEnabled) {
1121                 /*
1122                  *  Need to write back memory if cache is enabled because cache
1123                  *  will be invalidated during openByAddr
1124                  */
1125                 Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1126                         Cache_Type_ALL, TRUE);
1127             }
1129             if (params->name) {
1130                 nsValue[0] = (uintptr_t)obj->attrs;
1131                 /*
1132                  *  Top 16 bits = procId of creator
1133                  *  Bottom 16 bits = '0' if local, '1' otherwise
1134                  */
1135                 nsValue[1] = ((uintptr_t)MultiProc_self()) << 16;
1137                 if (GateMP_module->hostSupport == TRUE) {
1138                     nsValue[2] = obj->attrs->arg;
1139                     nsValue[3] = obj->attrs->mask;
1140                     sizeNsValue = sizeof(nsValue);
1141                 }
1142                 else {
1143                     sizeNsValue = 2 * sizeof(UInt32);
1144                 }
1146                 obj->nsKey = NameServer_add((NameServer_Handle)
1147                         GateMP_module->nameServer, params->name, &nsValue,
1148                         sizeNsValue);
1150                 if (obj->nsKey == NULL) {
1151                     Error_raise(eb, ti_sdo_ipc_Ipc_E_nameFailed, params->name,
1152                         0);
1153                     return (3);
1154                 }
1155             }
1157             /* Nothing else to do for local gates */
1158             return (0);
1159         }
1161         if (params->sharedAddr == NULL) {
1162             /* Need to allocate from heap */
1163             obj->objType        = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION;
1164             obj->regionId       = params->regionId;
1165             GateMP_getSharedParams(&sparams, params);
1166             obj->allocSize      = GateMP_sharedMemReq(&sparams);
1167             obj->cacheEnabled   = SharedRegion_isCacheEnabled(obj->regionId);
1169             /* The region heap will do the alignment */
1170             regionHeap = SharedRegion_getHeap(obj->regionId);
1171             Assert_isTrue(regionHeap != NULL, ti_sdo_ipc_SharedRegion_A_noHeap);
1172             obj->attrs = Memory_alloc(regionHeap, obj->allocSize, 0, eb);
1173             if (obj->attrs == NULL) {
1174                 return (3);
1175             }
1177             minAlign = Memory_getMaxDefaultTypeAlign();
1179             if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) {
1180                 minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1181             }
1183             offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1185             obj->proxyAttrs = (Ptr)((uintptr_t)obj->attrs + offset);
1186         }
1187         else {
1188             /* creating using sharedAddr */
1189             obj->regionId = SharedRegion_getId(params->sharedAddr);
1190             /* Assert that the buffer is in a valid shared region */
1191             Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID,
1192                           ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);
1194             obj->attrs = (ti_sdo_ipc_GateMP_Attrs *)params->sharedAddr;
1195             obj->cacheEnabled  = SharedRegion_isCacheEnabled(obj->regionId);
1196             obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
1198             minAlign = Memory_getMaxDefaultTypeAlign();
1200             if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) {
1201                 minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1202             }
1204             /* Assert that sharedAddr has correct alignment */
1205             Assert_isTrue(minAlign == 0 ||
1206                           ((uintptr_t)params->sharedAddr % minAlign) == 0,
1207                           ti_sdo_ipc_Ipc_A_addrNotCacheAligned);
1209             offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1211             obj->proxyAttrs = (Ptr)((uintptr_t)obj->attrs + offset);
1212         }
1213     }
1215     /* Proxy work for open and create done here */
1216     switch (obj->remoteProtect) {
1217         case GateMP_RemoteProtect_SYSTEM:
1218             if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1219                 /* Created Instance */
1220                 obj->resourceId = GateMP_getFreeResource(
1221                     GateMP_module->remoteSystemInUse,
1222                              GateMP_module->numRemoteSystem, eb);
1223                 if (Error_check(eb) == TRUE) {
1224                     return (4);
1225                 }
1226             }
1227             else {
1228                 /* resourceId set by open call */
1229                 obj->resourceId = params->resourceId;
1230             }
1232             /* Create the proxy object */
1233             ti_sdo_ipc_GateMP_RemoteSystemProxy_Params_init(&systemParams);
1234             systemParams.resourceId = obj->resourceId;
1235             systemParams.openFlag =
1236                     (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1237             systemParams.sharedAddr = obj->proxyAttrs;
1238             systemParams.regionId = obj->regionId;
1239             remoteHandle = ti_sdo_ipc_GateMP_RemoteSystemProxy_create(
1240                     localHandle, &systemParams, eb);
1242             if (remoteHandle == NULL) {
1243                 return (5);
1244             }
1246             /* Fill in the local array because it is cooked */
1247             key = Hwi_disable();
1248             GateMP_module->remoteSystemGates[obj->resourceId] = obj;
1249             Hwi_restore(key);
1250             break;
1252         case GateMP_RemoteProtect_CUSTOM1:
1253             if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1254                 obj->resourceId = GateMP_getFreeResource(
1255                              GateMP_module->remoteCustom1InUse,
1256                              GateMP_module->numRemoteCustom1, eb);
1257                 if (Error_check(eb) == TRUE) {
1258                     return (4);
1259                 }
1260             }
1261             else {
1262                 /* resourceId set by open call */
1263                 obj->resourceId = params->resourceId;
1264             }
1266             /* Create the proxy object */
1267             ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params_init(&custom1Params);
1268             custom1Params.resourceId = obj->resourceId;
1269             custom1Params.openFlag =
1270                     (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1271             custom1Params.sharedAddr = obj->proxyAttrs;
1272             custom1Params.regionId = obj->regionId;
1273             remoteHandle = ti_sdo_ipc_GateMP_RemoteCustom1Proxy_create(
1274                     localHandle, &custom1Params, eb);
1275             if (remoteHandle == NULL) {
1276                 return (5);
1277             }
1279             /* Fill in the local array because it is cooked */
1280             key = Hwi_disable();
1281             GateMP_module->remoteCustom1Gates[obj->resourceId] = obj;
1282             Hwi_restore(key);
1283             break;
1285         case GateMP_RemoteProtect_CUSTOM2:
1286             if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1287                 obj->resourceId = GateMP_getFreeResource(
1288                              GateMP_module->remoteCustom2InUse,
1289                              GateMP_module->numRemoteCustom2, eb);
1290                 if (Error_check(eb) == TRUE) {
1291                     return (4);
1292                 }
1293             }
1294             else {
1295                 /* resourceId set by open call */
1296                 obj->resourceId = params->resourceId;
1297             }
1299             /* Create the proxy object */
1300             ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params_init(&custom2Params);
1301             custom2Params.resourceId = obj->resourceId;
1302             custom2Params.openFlag =
1303                     (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1304             custom2Params.sharedAddr = obj->proxyAttrs;
1305             custom2Params.regionId = obj->regionId;
1306             remoteHandle = ti_sdo_ipc_GateMP_RemoteCustom2Proxy_create(
1307                     localHandle, &custom2Params, eb);
1308             if (remoteHandle == NULL) {
1309                 return (5);
1310             }
1312             /* Fill in the local array because it is cooked */
1313             key = Hwi_disable();
1314             GateMP_module->remoteCustom2Gates[obj->resourceId] = obj;
1315             Hwi_restore(key);
1316             break;
1318         default:
1319             /* Should never be here */
1320             Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
1321             return (5);  /* keep Coverity happy */
1322     }
1324     obj->gateHandle = IGateMPSupport_Handle_upCast(remoteHandle);
1326     /* Place Name/Attrs into NameServer table */
1327     if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1328         /* Fill in the attrs */
1329         obj->attrs->arg = obj->resourceId;
1330         obj->attrs->mask = SETMASK(obj->remoteProtect, obj->localProtect);
1331         obj->attrs->creatorProcId = MultiProc_self();
1332         obj->attrs->status = ti_sdo_ipc_GateMP_CREATED;
1334         if (obj->cacheEnabled) {
1335             Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1336                     Cache_Type_ALL, TRUE);
1337         }
1339         if (params->name != NULL) {
1340             sharedShmBase = SharedRegion_getSRPtr(obj->attrs, obj->regionId);
1341             nsValue[0] = (UInt32)sharedShmBase;
1342             /*
1343              *  Top 16 bits = procId of creator
1344              *  Bottom 16 bits = '0' if local, '1' otherwise
1345              */
1346             nsValue[1] = ((UInt32)MultiProc_self() << 16) | 1;
1348             if (GateMP_module->hostSupport == TRUE) {
1349                 /* Making a copy of these for host processor */
1350                 nsValue[2] = obj->attrs->arg;
1351                 nsValue[3] = obj->attrs->mask;
1352                 sizeNsValue = sizeof(nsValue);
1353             }
1354             else {
1355                 sizeNsValue = 2 * sizeof(UInt32);
1356             }
1358             obj->nsKey = NameServer_add((NameServer_Handle)
1359                     GateMP_module->nameServer, params->name, &nsValue,
1360                     sizeNsValue);
1362             if (obj->nsKey == NULL) {
1363                 Error_raise(eb, ti_sdo_ipc_Ipc_E_nameFailed, params->name, 0);
1364                 return (6);
1365             }
1366         }
1368         Log_write2(ti_sdo_ipc_GateMP_LM_create,
1369                 (UArg)obj->remoteProtect, (UArg)obj->resourceId);
1370     }
1371     else {
1372         obj->numOpens = 1;
1374         Log_write2(ti_sdo_ipc_GateMP_LM_open,
1375             (UArg)obj->remoteProtect, (UArg)obj->resourceId);
1376     }
1378     return (0);
1381 /*
1382  *  ======== ti_sdo_ipc_GateMP_Instance_finalize ========
1383  */
1384 Void ti_sdo_ipc_GateMP_Instance_finalize(
1385         ti_sdo_ipc_GateMP_Object *obj, Int status)
1387     UInt systemKey;
1388     ti_sdo_ipc_GateMP_RemoteSystemProxy_Handle systemHandle;
1389     ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Handle custom1Handle;
1390     ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Handle custom2Handle;
1392     ti_sdo_ipc_GateMP_Handle *remoteHandles;
1393     UInt8 *inUseArray;
1394     UInt size;
1396     /* Cannot call when numOpen is non-zero. */
1397     Assert_isTrue(obj->numOpens == 0, ti_sdo_ipc_GateMP_A_invalidDelete);
1399     /* Removed from NameServer */
1400     if (obj->nsKey != 0) {
1401         NameServer_removeEntry((NameServer_Handle)GateMP_module->nameServer,
1402                 obj->nsKey);
1403     }
1405     /* Set the status to 0 */
1406     if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1407         obj->attrs->status = 0;
1408         if (obj->cacheEnabled) {
1409             Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1410                     Cache_Type_ALL, TRUE);
1411         }
1412     }
1414     /*
1415      *  If ObjType_LOCAL, memory was allocated from the local system heap.
1416      *  obj->attrs might be NULL if the Memory_alloc failed in Instance_init
1417      */
1418     if (obj->objType == ti_sdo_ipc_Ipc_ObjType_LOCAL && obj->attrs != NULL) {
1419         Memory_free(NULL, obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs));
1420     }
1422     switch (obj->remoteProtect) {
1423         case GateMP_RemoteProtect_SYSTEM:
1424             if (obj->gateHandle) {
1425                 systemHandle =
1426                 ti_sdo_ipc_GateMP_RemoteSystemProxy_Handle_downCast2(
1427                         obj->gateHandle);
1428                 ti_sdo_ipc_GateMP_RemoteSystemProxy_delete(&systemHandle);
1429             }
1431             inUseArray = GateMP_module->remoteSystemInUse;
1432             remoteHandles = GateMP_module->remoteSystemGates;
1433             size = GateMP_module->numRemoteSystem * sizeof(UInt8);
1434             break;
1436         case GateMP_RemoteProtect_CUSTOM1:
1437             if (obj->gateHandle) {
1438                 custom1Handle =
1439                         ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Handle_downCast2(
1440                             obj->gateHandle);
1441                 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_delete(&custom1Handle);
1442             }
1444             inUseArray = GateMP_module->remoteCustom1InUse;
1445             remoteHandles = GateMP_module->remoteCustom1Gates;
1446             size = GateMP_module->numRemoteCustom1 * sizeof(UInt8);
1447             break;
1449         case GateMP_RemoteProtect_CUSTOM2:
1450             if (obj->gateHandle) {
1451                 custom2Handle =
1452                         ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Handle_downCast2(
1453                             obj->gateHandle);
1454                 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_delete(&custom2Handle);
1455             }
1457             inUseArray = GateMP_module->remoteCustom2InUse;
1458             remoteHandles = GateMP_module->remoteCustom2Gates;
1459             size = GateMP_module->numRemoteCustom2 * sizeof(UInt8);
1460             break;
1461         case GateMP_RemoteProtect_NONE:
1462             /*
1463              *  Nothing else to finalize. Any alloc'ed memory has already been
1464              *  freed
1465              */
1466             Log_write2(ti_sdo_ipc_GateMP_LM_delete, (UArg)obj->remoteProtect,
1467                 (UArg)obj->resourceId);
1468             return;
1469         default:
1470             /* Should never be here */
1471             Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
1472             break;
1473     }
1475     /* Clear the handle array entry in local memory */
1476     if (obj->resourceId != (UInt)-1) {
1477         remoteHandles[obj->resourceId] = NULL;
1478     }
1480     if ((obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) &&
1481         (obj->resourceId != (UInt)-1)) {
1482         /* Clear the resource used flag in shared memory */
1483         if (GateMP_module->defaultGate != NULL) {
1484             systemKey = GateMP_enter((GateMP_Handle)GateMP_module->defaultGate);
1485         }
1486         else {
1487             /* this should only be done when deleting the very last GateMP */
1488             systemKey = Hwi_disable();
1489         }
1491 #ifdef xdc_target__isaCompatible_v7A
1492         /* ARM speculative execution might have pulled array into cache */
1493         if (obj->cacheEnabled) {
1494             Cache_inv(inUseArray, size, Cache_Type_ALL, TRUE);
1495         }
1496 #endif
1497         /* update the GateMP resource tracker */
1498         inUseArray[obj->resourceId] = UNUSED;
1499         if (obj->cacheEnabled) {
1500             Cache_wbInv(inUseArray, size, Cache_Type_ALL, TRUE);
1501         }
1503         if (GateMP_module->defaultGate != NULL) {
1504             GateMP_leave((GateMP_Handle)GateMP_module->defaultGate, systemKey);
1505         }
1506         else {
1507             Hwi_restore(systemKey);
1508         }
1509     }
1511     if (obj->objType == ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION) {
1512         /* Free memory allocated from the region heap */
1513         if (obj->attrs) {
1514             Memory_free(SharedRegion_getHeap(obj->regionId), obj->attrs,
1515                 obj->allocSize);
1516         }
1517     }
1519     Log_write2(ti_sdo_ipc_GateMP_LM_delete, (UArg)obj->remoteProtect,
1520             (UArg)obj->resourceId);
1523 /*
1524  *  ======== ti_sdo_ipc_GateMP_getSharedAddr ========
1525  */
1526 SharedRegion_SRPtr ti_sdo_ipc_GateMP_getSharedAddr(
1527         ti_sdo_ipc_GateMP_Object *obj)
1529     SharedRegion_SRPtr srPtr;
1531     srPtr = SharedRegion_getSRPtr(obj->attrs, obj->regionId);
1533     return (srPtr);
1536 /*
1537  *  ======== ti_sdo_ipc_GateMP_setDefaultRemote ========
1538  */
1539 Void ti_sdo_ipc_GateMP_setDefaultRemote(ti_sdo_ipc_GateMP_Object *obj)
1541     GateMP_module->defaultGate = obj;
1544 /*
1545  *************************************************************************
1546  *                       Internal functions
1547  *************************************************************************
1548  */
1550 /*
1551  *  ======== ti_sdo_ipc_GateMP_getFreeResource ========
1552  */
1553 UInt ti_sdo_ipc_GateMP_getFreeResource(UInt8 *inUse, Int num, Error_Block *eb)
1555     UInt key;
1556     Bool flag = FALSE;
1557     UInt resourceId;
1558     GateMP_Handle defaultGate;
1560     /* Need to look at shared memory. Enter default gate */
1561     defaultGate = GateMP_getDefaultRemote();
1563     if (defaultGate){
1564         key = GateMP_enter(defaultGate);
1565     }
1567     /* Invalidate cache before looking at the in-use flags */
1568     if (SharedRegion_isCacheEnabled(0)) {
1569         Cache_inv(inUse, num * sizeof(UInt8), Cache_Type_ALL, TRUE);
1570     }
1572     /*
1573      *  Find a free resource id. Note: zero is reserved on the
1574      *  system proxy for the default gate.
1575      */
1576     for (resourceId = 0; resourceId < num; resourceId++) {
1577         /*
1578          *  If not in-use, set the inUse to TRUE to prevent other
1579          *  creates from getting this one.
1580          */
1581         if (inUse[resourceId] == UNUSED) {
1582            flag = TRUE;
1584            /* Denote in shared memory that the resource is used */
1585            inUse[resourceId] = USED;
1586            break;
1587        }
1588     }
1590     /* Write-back if a in-use flag was changed */
1591     if (flag == TRUE && SharedRegion_isCacheEnabled(0)) {
1592         Cache_wbInv(inUse, num * sizeof(UInt8), Cache_Type_ALL, TRUE);
1593     }
1595     /* Done with the critical section */
1596     if (defaultGate) {
1597         GateMP_leave(defaultGate, key);
1598     }
1600     if (flag == FALSE) {
1601         resourceId = (UInt)-1;
1602         Error_raise(eb, ti_sdo_ipc_GateMP_E_gateUnavailable, 0, 0);
1603     }
1605     return (resourceId);