]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - packages/ti/sdo/ipc/GateMP.c
Initial commit
[ipc/ipcdev.git] / packages / ti / sdo / ipc / GateMP.c
1 /*
2  * Copyright (c) 2012-2013, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
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     UInt32 len;
241     Ptr sharedAddr;
242     UInt32 nsValue[2];
244     /* Assert that a pointer has been supplied */
245     Assert_isTrue(handlePtr != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
247     len = sizeof(nsValue);
249     /*
250      *  Get the Attrs out of the NameServer instance.
251      *  Search all processors.
252      */
253     status = NameServer_get((NameServer_Handle)GateMP_module->nameServer, name,
254             &nsValue, &len, ti_sdo_utils_MultiProc_procIdList);
256     if (status < 0) {
257         *handlePtr = NULL;
258         return (GateMP_E_NOTFOUND);
259     }
261     /*
262      * The least significant bit of nsValue[1] == 0 means its a
263      * local GateMP, otherwise its a remote GateMP.
264      */
265     if (((nsValue[1] & 0x1) == 0) &&
266         ((nsValue[1] >> 16) != MultiProc_self())) {
267         /* Trying to open a local GateMP remotely */
268         *handlePtr = NULL;
269         return (GateMP_E_FAIL);
270     }
272     if ((nsValue[1] & 0x1) == 0) {
273         /*
274          * Opening a local GateMP locally. The GateMP is created
275          * from a local heap so don't do SharedRegion Ptr conversion.
276          */
277         sharedAddr = (Ptr)nsValue[0];
278     }
279     else {
280         /* Opening a remote GateMP. Need to do SharedRegion Ptr conversion. */
281         sharedShmBase = (SharedRegion_SRPtr)nsValue[0];
282         sharedAddr = SharedRegion_getPtr(sharedShmBase);
283     }
285     status = GateMP_openByAddr(sharedAddr, handlePtr);
287     return (status);
290 /*
291  *  ======== GateMP_openByAddr ========
292  */
293 Int GateMP_openByAddr(Ptr sharedAddr, GateMP_Handle *handlePtr)
295     Int status = GateMP_S_SUCCESS;
296     UInt key;
297     ti_sdo_ipc_GateMP_Object *obj;
298     ti_sdo_ipc_GateMP_Params params;
299     ti_sdo_ipc_GateMP_Attrs *attrs;
300     UInt16 regionId;
301     Error_Block eb;
303     Error_init(&eb);
305     attrs = (ti_sdo_ipc_GateMP_Attrs *)sharedAddr;
307     /* get the region id and invalidate attrs is needed */
308     regionId = SharedRegion_getId(sharedAddr);
309     if (regionId != SharedRegion_INVALIDREGIONID) {
310         if (SharedRegion_isCacheEnabled(regionId)) {
311             Cache_inv(attrs, sizeof(ti_sdo_ipc_GateMP_Attrs), Cache_Type_ALL,
312                     TRUE);
313         }
314     }
316     if (attrs->status != ti_sdo_ipc_GateMP_CREATED) {
317         *handlePtr = NULL;
318         status = GateMP_E_NOTFOUND;
319     }
320     else {
321         /* Local gate */
322         if (GETREMOTE(attrs->mask) == GateMP_RemoteProtect_NONE) {
323             if (attrs->creatorProcId != MultiProc_self()) {
324                 Error_raise(&eb, ti_sdo_ipc_GateMP_E_localGate, 0, 0);
325                 return (GateMP_E_FAIL);
326             }
328             /* need to atomically increment number of opens */
329             key = Hwi_disable();
331             obj = (ti_sdo_ipc_GateMP_Object *)attrs->arg;
332             *handlePtr = (GateMP_Handle)obj;
333             obj->numOpens++;
335             /* restore hwi mask */
336             Hwi_restore(key);
338             return (GateMP_S_SUCCESS);
339         }
341         /*  need to track number of opens atomically */
342         key = Hwi_disable();
344         /* Remote case */
345         switch (GETREMOTE(attrs->mask)) {
346             case GateMP_RemoteProtect_SYSTEM:
347                 obj = GateMP_module->remoteSystemGates[attrs->arg];
348                 break;
350             case GateMP_RemoteProtect_CUSTOM1:
351                 obj = GateMP_module->remoteCustom1Gates[attrs->arg];
352                 break;
354             case GateMP_RemoteProtect_CUSTOM2:
355                 obj = GateMP_module->remoteCustom2Gates[attrs->arg];
356                 break;
358             default:
359                 obj = NULL;
360                 status = GateMP_E_FAIL;
361                 break;
362         }
364         if (status == GateMP_S_SUCCESS) {
365             /*
366              *  If the object is NULL, then it must have been created on a
367              *  remote processor. Need to create a local object. This is
368              *  accomplished by setting the openFlag to TRUE.
369              */
370             if (obj == NULL) {
371                 /* Create a GateMP object with the openFlag set to true */
372                 ti_sdo_ipc_GateMP_Params_init(&params);
373                 params.openFlag = TRUE;
374                 params.sharedAddr = sharedAddr;
375                 params.resourceId = attrs->arg;
376                 params.localProtect = GETLOCAL(attrs->mask);
377                 params.remoteProtect = GETREMOTE(attrs->mask);
379                 obj = ti_sdo_ipc_GateMP_create(&params, &eb);
380                 if (obj == NULL) {
381                     status = GateMP_E_FAIL;
382                 }
383             }
384             else {
385                 obj->numOpens++;
386             }
387         }
389         /* Return the GateMP instance  */
390         *handlePtr = (GateMP_Handle)obj;
392         /* restore hwi mask */
393         Hwi_restore(key);
394     }
396     return (status);
399 /*
400  *  ======== GateMP_sharedMemReq ========
401  */
402 SizeT GateMP_sharedMemReq(const GateMP_Params *params)
404     SizeT memReq, minAlign;
405     UInt16 regionId;
406     ti_sdo_ipc_GateMP_RemoteSystemProxy_Params systemParams;
407     ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params custom1Params;
408     ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params custom2Params;
410     if (params->sharedAddr) {
411         regionId = SharedRegion_getId(params->sharedAddr);
412     }
413     else {
414         regionId = params->regionId;
415     }
417     Assert_isTrue(regionId != SharedRegion_INVALIDREGIONID,
418             ti_sdo_ipc_Ipc_A_internal);
420     minAlign = Memory_getMaxDefaultTypeAlign();
421     if (SharedRegion_getCacheLineSize(regionId) > minAlign) {
422         minAlign = SharedRegion_getCacheLineSize(regionId);
423     }
425     memReq = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
427     /* add the amount of shared memory required by proxy */
428     if (params->remoteProtect == GateMP_RemoteProtect_SYSTEM) {
429         ti_sdo_ipc_GateMP_RemoteSystemProxy_Params_init(&systemParams);
430         systemParams.regionId = regionId;
431         memReq += ti_sdo_ipc_GateMP_RemoteSystemProxy_sharedMemReq(
432                 (IGateMPSupport_Params *)&systemParams);
433     }
434     else if (params->remoteProtect == GateMP_RemoteProtect_CUSTOM1) {
435         ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params_init(&custom1Params);
436         custom1Params.regionId = regionId;
437         memReq += ti_sdo_ipc_GateMP_RemoteCustom1Proxy_sharedMemReq(
438                 (IGateMPSupport_Params *)&custom1Params);
439     }
440     else if (params->remoteProtect == GateMP_RemoteProtect_CUSTOM2) {
441         ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params_init(&custom2Params);
442         custom2Params.regionId = regionId;
443         memReq += ti_sdo_ipc_GateMP_RemoteCustom2Proxy_sharedMemReq(
444                 (IGateMPSupport_Params *)&custom2Params);
445     }
447     return (memReq);
450 /*
451  *************************************************************************
452  *                       Module functions
453  *************************************************************************
454  */
456 /*
457  *  ======== ti_sdo_ipc_GateMP_createLocal ========
458  */
459 IGateProvider_Handle ti_sdo_ipc_GateMP_createLocal(
460     ti_sdo_ipc_GateMP_LocalProtect localProtect)
462     IGateProvider_Handle gateHandle;
464     /* Create the local gate. */
465     switch (localProtect) {
466         case GateMP_LocalProtect_NONE:
467             /* Plug with the GateNull singleton */
468             gateHandle = GateMP_module->gateNull;
469             break;
471         case GateMP_LocalProtect_INTERRUPT:
472             /* Plug with the GateAll singleton */
473             gateHandle = GateMP_module->gateAll;
474             break;
476         case GateMP_LocalProtect_TASKLET:
477             /* Plug with the GateSwi singleton */
478             gateHandle = GateMP_module->gateSwi;
479             break;
481         case GateMP_LocalProtect_THREAD:
482         case GateMP_LocalProtect_PROCESS:
483             /* Plug with the GateMutexPri singleton */
484             gateHandle = GateMP_module->gateMutexPri;
485             break;
487         default:
488             /* Invalid local protection level encountered */
489             Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
490             break;
491     }
493     return (gateHandle);
496 /*
497  *  ======== GateMP_getDefaultRemote ========
498  */
499 GateMP_Handle GateMP_getDefaultRemote()
501     return ((GateMP_Handle)GateMP_module->defaultGate);
504 /*
505  *  ======== GateMP_getLocalProtect ========
506  */
507 GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
509     ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)handle;
511     Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
513     return ((GateMP_LocalProtect)obj->localProtect);
516 /*
517  *  ======== GateMP_getRemoteProtect ========
518  */
519 GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
521     ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)handle;
523     Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
525     return ((GateMP_RemoteProtect)obj->remoteProtect);
528 /*
529  *  ======== ti_sdo_ipc_GateMP_getRegion0ReservedSize ========
530  */
531 SizeT ti_sdo_ipc_GateMP_getRegion0ReservedSize(Void)
533     SizeT reserved, minAlign;
535     minAlign = Memory_getMaxDefaultTypeAlign();
537     if (SharedRegion_getCacheLineSize(0) > minAlign) {
538         minAlign = SharedRegion_getCacheLineSize(0);
539     }
541     reserved = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
543     reserved += _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
545     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
546         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
547             reserved += _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
548     }
550     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
551         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
552             reserved += _Ipc_roundup(GateMP_module->numRemoteCustom2, minAlign);
553     }
555     return (reserved);
558 /*
559  *  ======== ti_sdo_ipc_GateMP_setRegion0Reserved ========
560  */
561 Void ti_sdo_ipc_GateMP_setRegion0Reserved(Ptr sharedAddr)
563     ti_sdo_ipc_GateMP_Reserved *reserve;
564     SizeT minAlign, offset;
565     UInt i;
566     Bits32 *delegateReservedMask;
568     minAlign = Memory_getMaxDefaultTypeAlign();
569     if (SharedRegion_getCacheLineSize(0) > minAlign) {
570         minAlign = SharedRegion_getCacheLineSize(0);
571     }
573     /* setup ti_sdo_ipc_GateMP_Reserved fields */
574     reserve = (ti_sdo_ipc_GateMP_Reserved *)sharedAddr;
575     reserve->version = ti_sdo_ipc_GateMP_VERSION;
577     if (SharedRegion_isCacheEnabled(0)) {
578         Cache_wbInv(sharedAddr, sizeof(ti_sdo_ipc_GateMP_Reserved),
579             Cache_Type_ALL, TRUE);
580     }
582     /*
583      *  initialize the in-use array in shared memory for the system gates.
584      */
585     offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
586     GateMP_module->remoteSystemInUse =
587         (Ptr)((UInt32)sharedAddr + offset);
589     memset(GateMP_module->remoteSystemInUse, 0,
590         GateMP_module->numRemoteSystem * sizeof(UInt8));
591     delegateReservedMask =
592             ti_sdo_ipc_GateMP_RemoteSystemProxy_getReservedMask();
593     if (delegateReservedMask != NULL) {
594         for (i = 0; i < GateMP_module->numRemoteSystem; i++) {
595             if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
596                 GateMP_module->remoteSystemInUse[i] = RESERVED;
597             }
598         }
599     }
601     if (SharedRegion_isCacheEnabled(0)) {
602         Cache_wbInv(GateMP_module->remoteSystemInUse,
603             GateMP_module->numRemoteSystem * sizeof(UInt8),
604             Cache_Type_ALL,
605             TRUE);
606     }
608     /*
609      *  initialize the in-use array in shared memory for the custom1 gates.
610      *  Need to check if this proxy is the same as system
611      */
612     offset = _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
613     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
614         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
615         if (GateMP_module->numRemoteCustom1 != 0) {
616             GateMP_module->remoteCustom1InUse =
617                 GateMP_module->remoteSystemInUse + offset;
618         }
620         memset(GateMP_module->remoteCustom1InUse, 0,
621             GateMP_module->numRemoteCustom1 * sizeof(UInt8));
622         delegateReservedMask =
623                 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_getReservedMask();
624         if (delegateReservedMask != NULL) {
625             for (i = 0; i < GateMP_module->numRemoteCustom1; i++) {
626                 if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
627                     GateMP_module->remoteCustom1InUse[i] = RESERVED;
628                 }
629             }
630         }
631         if (SharedRegion_isCacheEnabled(0)) {
632             Cache_wbInv(GateMP_module->remoteCustom1InUse,
633                  GateMP_module->numRemoteCustom1 * sizeof(UInt8),
634                  Cache_Type_ALL,
635                  TRUE);
636         }
637     }
638     else {
639         GateMP_module->remoteCustom1InUse = GateMP_module->remoteSystemInUse;
640         GateMP_module->remoteCustom1Gates = GateMP_module->remoteSystemGates;
641     }
643     /*
644      *  initialize the in-use array in shared memory for the custom2 gates.
645      *  Need to check if this proxy is the same as system or custom1
646      */
647     offset = _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
648     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
649         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
650         if (GateMP_module->numRemoteCustom2 != 0) {
651                 GateMP_module->remoteCustom2InUse =
652                     GateMP_module->remoteCustom1InUse + offset;
653         }
655         memset(GateMP_module->remoteCustom2InUse, 0,
656             GateMP_module->numRemoteCustom2 * sizeof(UInt8));
657         delegateReservedMask =
658                 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_getReservedMask();
659         if (delegateReservedMask != NULL) {
660             for (i = 0; i < GateMP_module->numRemoteCustom2; i++) {
661                 if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
662                     GateMP_module->remoteCustom2InUse[i] = RESERVED;
663                 }
664             }
665         }
667         if (SharedRegion_isCacheEnabled(0)) {
668             Cache_wbInv(GateMP_module->remoteCustom2InUse,
669                  GateMP_module->numRemoteCustom2 * sizeof(UInt8),
670                  Cache_Type_ALL,
671                  TRUE);
672         }
673     }
674     else if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
675              ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
676         GateMP_module->remoteCustom2InUse =
677             GateMP_module->remoteCustom1InUse;
678         GateMP_module->remoteCustom2Gates =
679             GateMP_module->remoteCustom1Gates;
680     }
681     else {
682         GateMP_module->remoteCustom2InUse = GateMP_module->remoteSystemInUse;
683         GateMP_module->remoteCustom2Gates = GateMP_module->remoteSystemGates;
684     }
687 /*
688  *  ======== ti_sdo_ipc_GateMP_openRegion0Reserved ========
689  */
690 Void ti_sdo_ipc_GateMP_openRegion0Reserved(Ptr sharedAddr)
692     ti_sdo_ipc_GateMP_Reserved *reserve;
693     SizeT minAlign, offset;
695     minAlign = Memory_getMaxDefaultTypeAlign();
696     if (SharedRegion_getCacheLineSize(0) > minAlign) {
697         minAlign = SharedRegion_getCacheLineSize(0);
698     }
701     /* setup ti_sdo_ipc_GateMP_Reserved fields */
702     reserve = (ti_sdo_ipc_GateMP_Reserved *)sharedAddr;
704     if (reserve->version != ti_sdo_ipc_GateMP_VERSION) {
705         /* Version mismatch: return an error */
706         Error_raise(NULL, ti_sdo_ipc_Ipc_E_versionMismatch, reserve->version,
707                     ti_sdo_ipc_GateMP_VERSION);
708         return;
709     }
711     offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
712     GateMP_module->remoteSystemInUse =
713         (Ptr)((UInt32)sharedAddr + offset);
715     /*
716      *  initialize the in-use array in shared memory for the custom1 gates.
717      *  Need to check if this proxy is the same as system
718      */
719     offset = _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
720     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
721         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
722         if (GateMP_module->numRemoteCustom1 != 0) {
723             GateMP_module->remoteCustom1InUse =
724                 GateMP_module->remoteSystemInUse + offset;
725         }
726     }
727     else {
728         GateMP_module->remoteCustom1InUse = GateMP_module->remoteSystemInUse;
729         GateMP_module->remoteCustom1Gates = GateMP_module->remoteSystemGates;
730     }
732     offset = _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
733     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
734         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
735         if (GateMP_module->numRemoteCustom2 != 0) {
736             GateMP_module->remoteCustom2InUse =
737                 GateMP_module->remoteCustom1InUse + offset;
738         }
739     }
740     else if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
741              ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
742         GateMP_module->remoteCustom2InUse =
743             GateMP_module->remoteCustom1InUse;
744         GateMP_module->remoteCustom2Gates =
745             GateMP_module->remoteCustom1Gates;
746     }
747     else {
748         GateMP_module->remoteCustom2InUse = GateMP_module->remoteSystemInUse;
749         GateMP_module->remoteCustom2Gates = GateMP_module->remoteSystemGates;
750     }
753 /*
754  *  ======== ti_sdo_ipc_GateMP_attach ========
755  */
756 Int ti_sdo_ipc_GateMP_attach(UInt16 remoteProcId, Ptr sharedAddr)
758     Ptr gateMPsharedAddr;
759     SharedRegion_Entry entry;
760     ti_sdo_ipc_GateMP_Handle defaultGate;
761     Int status = GateMP_S_SUCCESS;
763     /* If default gate is not NULL return since its already set */
764     if (GateMP_getDefaultRemote() != NULL) {
765         return(GateMP_S_ALREADYSETUP);
766     }
768     /* get region 0 information */
769     SharedRegion_getEntry(0, &entry);
771     gateMPsharedAddr = (Ptr)((UInt32)sharedAddr +
772                        ti_sdo_ipc_GateMP_getRegion0ReservedSize());
774     if ((entry.ownerProcId != MultiProc_self()) &&
775         (entry.ownerProcId != MultiProc_INVALIDID)) {
776         /* if not the owner of the SharedRegion */
777         ti_sdo_ipc_GateMP_openRegion0Reserved(sharedAddr);
779         /* open the gate by address */
780         status = GateMP_openByAddr(gateMPsharedAddr,
781                 (GateMP_Handle *)&defaultGate);
783         /* openByAddr should always succeed */
784         Assert_isTrue(status >= 0, ti_sdo_ipc_Ipc_A_internal);
786         /* set the default GateMP for opener */
787         ti_sdo_ipc_GateMP_setDefaultRemote(defaultGate);
788     }
790     return (status);
793 /*
794  *  ======== ti_sdo_ipc_GateMP_detach ========
795  */
796 Int ti_sdo_ipc_GateMP_detach(UInt16 remoteProcId)
798     SharedRegion_Entry entry;
799     GateMP_Handle gate;
800     Int status = GateMP_S_SUCCESS;
802     /* get region 0 information */
803     SharedRegion_getEntry(0, &entry);
805     if ((entry.isValid) &&
806         (entry.ownerProcId == remoteProcId)) {
807         /* get the default gate */
808         gate = GateMP_getDefaultRemote();
810         if (gate != NULL) {
811             /* close the gate */
812             status = GateMP_close(&gate);
814             /* set the default remote gate to NULL */
815             ti_sdo_ipc_GateMP_setDefaultRemote(NULL);
816         }
817     }
819     return (status);
822 /*
823  *  ======== ti_sdo_ipc_GateMP_start ========
824  */
825 Int ti_sdo_ipc_GateMP_start(Ptr sharedAddr)
827     SharedRegion_Entry       entry;
828     ti_sdo_ipc_GateMP_Params gateMPParams;
829     ti_sdo_ipc_GateMP_Handle defaultGate;
830     Int status = GateMP_S_SUCCESS;
831     Error_Block eb;
833     /* get region 0 information */
834     SharedRegion_getEntry(0, &entry);
836     /* if entry owner proc is not specified return */
837     if (entry.ownerProcId == MultiProc_INVALIDID) {
838         return (status);
839     }
841     if (entry.ownerProcId == MultiProc_self()) {
842         /* if owner of the SharedRegion */
843         ti_sdo_ipc_GateMP_setRegion0Reserved(sharedAddr);
845         /* create default GateMP */
846         ti_sdo_ipc_GateMP_Params_init(&gateMPParams);
847         gateMPParams.sharedAddr = (Ptr)((UInt32)sharedAddr +
848                 ti_sdo_ipc_GateMP_getRegion0ReservedSize());
849         gateMPParams.localProtect  = ti_sdo_ipc_GateMP_LocalProtect_TASKLET;
851         if (ti_sdo_utils_MultiProc_numProcessors > 1) {
852             gateMPParams.remoteProtect = ti_sdo_ipc_GateMP_RemoteProtect_SYSTEM;
853         }
854         else {
855             gateMPParams.remoteProtect = ti_sdo_ipc_GateMP_RemoteProtect_NONE;
856         }
858         Error_init(&eb);
859         defaultGate = ti_sdo_ipc_GateMP_create(&gateMPParams, &eb);
860         if (defaultGate != NULL) {
861             /* set the default GateMP for creator */
862             ti_sdo_ipc_GateMP_setDefaultRemote(defaultGate);
863         }
864         else {
865             status = GateMP_E_FAIL;
866         }
867     }
869     return (status);
872 /*
873  *  ======== ti_sdo_ipc_GateMP_stop ========
874  */
875 Int ti_sdo_ipc_GateMP_stop()
877     SharedRegion_Entry entry;
878     GateMP_Handle gate;
879     Int status = GateMP_S_SUCCESS;
881     /* get region 0 information */
882     SharedRegion_getEntry(0, &entry);
884     if ((entry.isValid) &&
885         (entry.createHeap) &&
886         (entry.ownerProcId == MultiProc_self())) {
887         /* get the default GateMP */
888         gate = GateMP_getDefaultRemote();
890         if (gate != NULL) {
891             /* set the default GateMP to NULL */
892             ti_sdo_ipc_GateMP_setDefaultRemote(NULL);
894             /* delete the default GateMP */
895             status = GateMP_delete(&gate);
896         }
897     }
899     return (status);
902 /*
903  *************************************************************************
904  *                       Instance functions
905  *************************************************************************
906  */
908 /*
909  *  ======== ti_sdo_ipc_GateMP_Instance_init ========
910  */
911 Int ti_sdo_ipc_GateMP_Instance_init(ti_sdo_ipc_GateMP_Object *obj,
912         const ti_sdo_ipc_GateMP_Params *params,
913         Error_Block *eb)
915     UInt key;
916     IGateMPSupport_Handle remoteHandle;
917     IGateProvider_Handle localHandle;
918     ti_sdo_ipc_GateMP_RemoteSystemProxy_Params systemParams;
919     ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params custom1Params;
920     ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params custom2Params;
921     SizeT minAlign, offset;
922     SharedRegion_SRPtr sharedShmBase;
923     GateMP_Params sparams;
924     UInt32 nsValue[2];
925     IHeap_Handle regionHeap;
927     /* Initialize resourceId to an invalid value */
928     obj->resourceId = (UInt)-1;
930     localHandle = ti_sdo_ipc_GateMP_createLocal(params->localProtect);
932     /* Open GateMP instance */
933     if (params->openFlag == TRUE) {
934         /* all open work done here except for remote gateHandle */
935         obj->localProtect   = params->localProtect;
936         obj->remoteProtect  = params->remoteProtect;
937         obj->nsKey          = 0;
938         obj->numOpens       = 0; /* Will be set to 1 after init() complete */
939         obj->attrs          = (ti_sdo_ipc_GateMP_Attrs *)params->sharedAddr;
940         obj->regionId       = SharedRegion_getId((Ptr)obj->attrs);
941         obj->cacheEnabled   = SharedRegion_isCacheEnabled(obj->regionId);
943         /* Assert that the buffer is in a valid shared region */
944         Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID,
945                       ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);
947         obj->allocSize      = 0;
948         obj->objType        = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC;
950         minAlign = Memory_getMaxDefaultTypeAlign();
952         if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) {
953             minAlign = SharedRegion_getCacheLineSize(obj->regionId);
954         }
956         offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
958         obj->proxyAttrs = (Ptr)((UInt32)obj->attrs + offset);
959     }
960     /* Create GateMP instance */
961     else {
962         obj->localProtect  = params->localProtect;
963         obj->remoteProtect = params->remoteProtect;
964         obj->nsKey         = 0;
965         obj->numOpens      = 0;
967         if (obj->remoteProtect == GateMP_RemoteProtect_NONE) {
968             obj->gateHandle = ti_sdo_ipc_GateMP_createLocal(obj->localProtect);
969             if (params->sharedAddr != NULL) {
970                 /* Create a local gate using shared memory */
971                 obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
972                 obj->attrs = params->sharedAddr;
973                 obj->regionId = SharedRegion_getId((Ptr)obj->attrs);
974                 obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
975             }
976             else {
977                 /* Create a local gate allocating from the local heap */
978                 obj->objType = ti_sdo_ipc_Ipc_ObjType_LOCAL;
979                 obj->regionId = ti_sdo_ipc_SharedRegion_INVALIDREGIONID;
980                 obj->cacheEnabled  = FALSE; /* local */
981                 obj->attrs = Memory_alloc(NULL,
982                         sizeof(ti_sdo_ipc_GateMP_Attrs), 0, eb);
983                 if (obj->attrs == NULL) {
984                     return (2);
985                 }
987             }
989             obj->attrs->arg = (Bits32)obj;
990             obj->attrs->mask = SETMASK(obj->remoteProtect, obj->localProtect);
991             obj->attrs->creatorProcId = MultiProc_self();
992             obj->attrs->status = ti_sdo_ipc_GateMP_CREATED;
993             if (obj->cacheEnabled) {
994                 /*
995                  *  Need to write back memory if cache is enabled because cache
996                  *  will be invalidated during openByAddr
997                  */
998                 Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
999                         Cache_Type_ALL, TRUE);
1000             }
1002             if (params->name) {
1003                 nsValue[0] = (UInt32)obj->attrs;
1004                 /*
1005                  *  Top 16 bits = procId of creator
1006                  *  Bottom 16 bits = '0' if local, '1' otherwise
1007                  */
1008                 nsValue[1] = ((UInt32)MultiProc_self()) << 16;
1009                 obj->nsKey = NameServer_add((NameServer_Handle)
1010                         GateMP_module->nameServer, params->name, &nsValue,
1011                         2 * sizeof(UInt32));
1013                 if (obj->nsKey == NULL) {
1014                     Error_raise(eb, ti_sdo_ipc_Ipc_E_nameFailed, params->name,
1015                         0);
1016                     return (3);
1017                 }
1018             }
1020             /* Nothing else to do for local gates */
1021             return (0);
1022         }
1024         if (params->sharedAddr == NULL) {
1025             /* Need to allocate from heap */
1026             obj->objType        = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION;
1027             obj->regionId       = params->regionId;
1028             GateMP_getSharedParams(&sparams, params);
1029             obj->allocSize      = GateMP_sharedMemReq(&sparams);
1030             obj->cacheEnabled   = SharedRegion_isCacheEnabled(obj->regionId);
1032             /* The region heap will do the alignment */
1033             regionHeap = SharedRegion_getHeap(obj->regionId);
1034             Assert_isTrue(regionHeap != NULL, ti_sdo_ipc_SharedRegion_A_noHeap);
1035             obj->attrs = Memory_alloc(regionHeap, obj->allocSize, 0, eb);
1036             if (obj->attrs == NULL) {
1037                 return (3);
1038             }
1040             minAlign = Memory_getMaxDefaultTypeAlign();
1042             if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) {
1043                 minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1044             }
1046             offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1048             obj->proxyAttrs = (Ptr)((UInt32)obj->attrs + offset);
1049         }
1050         else {
1051             /* creating using sharedAddr */
1052             obj->regionId = SharedRegion_getId(params->sharedAddr);
1053             /* Assert that the buffer is in a valid shared region */
1054             Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID,
1055                           ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);
1057             obj->attrs = (ti_sdo_ipc_GateMP_Attrs *)params->sharedAddr;
1058             obj->cacheEnabled  = SharedRegion_isCacheEnabled(obj->regionId);
1059             obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
1061             minAlign = Memory_getMaxDefaultTypeAlign();
1063             if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) {
1064                 minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1065             }
1067             /* Assert that sharedAddr has correct alignment */
1068             Assert_isTrue(minAlign == 0 ||
1069                           ((UInt32)params->sharedAddr % minAlign) == 0,
1070                           ti_sdo_ipc_Ipc_A_addrNotCacheAligned);
1072             offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1074             obj->proxyAttrs = (Ptr)((UInt32)obj->attrs + offset);
1075         }
1076     }
1078     /* Proxy work for open and create done here */
1079     switch (obj->remoteProtect) {
1080         case GateMP_RemoteProtect_SYSTEM:
1081             if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1082                 /* Created Instance */
1083                 obj->resourceId = GateMP_getFreeResource(
1084                     GateMP_module->remoteSystemInUse,
1085                              GateMP_module->numRemoteSystem, eb);
1086                 if (Error_check(eb) == TRUE) {
1087                     return (4);
1088                 }
1089             }
1090             else {
1091                 /* resourceId set by open call */
1092                 obj->resourceId = params->resourceId;
1093             }
1095             /* Create the proxy object */
1096             ti_sdo_ipc_GateMP_RemoteSystemProxy_Params_init(&systemParams);
1097             systemParams.resourceId = obj->resourceId;
1098             systemParams.openFlag =
1099                     (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1100             systemParams.sharedAddr = obj->proxyAttrs;
1101             systemParams.regionId = obj->regionId;
1102             remoteHandle = ti_sdo_ipc_GateMP_RemoteSystemProxy_create(
1103                     localHandle, &systemParams, eb);
1105             if (remoteHandle == NULL) {
1106                 return (5);
1107             }
1109             /* Finish filling in the object */
1110             obj->gateHandle = IGateMPSupport_Handle_upCast(remoteHandle);
1112             /* Fill in the local array because it is cooked */
1113             key = Hwi_disable();
1114             GateMP_module->remoteSystemGates[obj->resourceId] = obj;
1115             Hwi_restore(key);
1116             break;
1118         case GateMP_RemoteProtect_CUSTOM1:
1119             if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1120                 obj->resourceId = GateMP_getFreeResource(
1121                              GateMP_module->remoteCustom1InUse,
1122                              GateMP_module->numRemoteCustom1, eb);
1123                 if (Error_check(eb) == TRUE) {
1124                     return (4);
1125                 }
1126             }
1127             else {
1128                 /* resourceId set by open call */
1129                 obj->resourceId = params->resourceId;
1130             }
1132             /* Create the proxy object */
1133             ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params_init(&custom1Params);
1134             custom1Params.resourceId = obj->resourceId;
1135             custom1Params.openFlag =
1136                     (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1137             custom1Params.sharedAddr = obj->proxyAttrs;
1138             custom1Params.regionId = obj->regionId;
1139             remoteHandle = ti_sdo_ipc_GateMP_RemoteCustom1Proxy_create(
1140                     localHandle, &custom1Params, eb);
1141             if (remoteHandle == NULL) {
1142                 return (5);
1143             }
1145             /* Fill in the local array because it is cooked */
1146             key = Hwi_disable();
1147             GateMP_module->remoteCustom1Gates[obj->resourceId] = obj;
1148             Hwi_restore(key);
1149             break;
1151         case GateMP_RemoteProtect_CUSTOM2:
1152             if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1153                 obj->resourceId = GateMP_getFreeResource(
1154                              GateMP_module->remoteCustom2InUse,
1155                              GateMP_module->numRemoteCustom2, eb);
1156                 if (Error_check(eb) == TRUE) {
1157                     return (4);
1158                 }
1159             }
1160             else {
1161                 /* resourceId set by open call */
1162                 obj->resourceId = params->resourceId;
1163             }
1165             /* Create the proxy object */
1166             ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params_init(&custom2Params);
1167             custom2Params.resourceId = obj->resourceId;
1168             custom2Params.openFlag =
1169                     (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1170             custom2Params.sharedAddr = obj->proxyAttrs;
1171             custom2Params.regionId = obj->regionId;
1172             remoteHandle = ti_sdo_ipc_GateMP_RemoteCustom2Proxy_create(
1173                     localHandle, &custom2Params, eb);
1174             if (remoteHandle == NULL) {
1175                 return (5);
1176             }
1178             /* Fill in the local array because it is cooked */
1179             key = Hwi_disable();
1180             GateMP_module->remoteCustom2Gates[obj->resourceId] = obj;
1181             Hwi_restore(key);
1182             break;
1184         default:
1185             /* Should never be here */
1186             Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
1187             return (5);  /* keep Coverity happy */
1188     }
1190     obj->gateHandle = IGateMPSupport_Handle_upCast(remoteHandle);
1192     /* Place Name/Attrs into NameServer table */
1193     if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1194         /* Fill in the attrs */
1195         obj->attrs->arg = obj->resourceId;
1196         obj->attrs->mask = SETMASK(obj->remoteProtect, obj->localProtect);
1197         obj->attrs->creatorProcId = MultiProc_self();
1198         obj->attrs->status = ti_sdo_ipc_GateMP_CREATED;
1200         if (obj->cacheEnabled) {
1201             Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1202                     Cache_Type_ALL, TRUE);
1203         }
1205         if (params->name != NULL) {
1206             sharedShmBase = SharedRegion_getSRPtr(obj->attrs, obj->regionId);
1207             nsValue[0] = (UInt32)sharedShmBase;
1208             /*
1209              *  Top 16 bits = procId of creator
1210              *  Bottom 16 bits = '0' if local, '1' otherwise
1211              */
1212             nsValue[1] = ((UInt32)MultiProc_self() << 16) | 1;
1213             obj->nsKey = NameServer_add(
1214                     (NameServer_Handle)GateMP_module->nameServer, params->name,
1215                     &nsValue, 2 * sizeof(UInt32));
1217             if (obj->nsKey == NULL) {
1218                 Error_raise(eb, ti_sdo_ipc_Ipc_E_nameFailed, params->name, 0);
1219                 return (6);
1220             }
1221         }
1223         Log_write2(ti_sdo_ipc_GateMP_LM_create,
1224                 (UArg)obj->remoteProtect, (UArg)obj->resourceId);
1225     }
1226     else {
1227         obj->numOpens = 1;
1229         Log_write2(ti_sdo_ipc_GateMP_LM_open,
1230             (UArg)obj->remoteProtect, (UArg)obj->resourceId);
1231     }
1233     return (0);
1236 /*
1237  *  ======== ti_sdo_ipc_GateMP_Instance_finalize ========
1238  */
1239 Void ti_sdo_ipc_GateMP_Instance_finalize(
1240         ti_sdo_ipc_GateMP_Object *obj, Int status)
1242     UInt systemKey;
1243     ti_sdo_ipc_GateMP_RemoteSystemProxy_Handle systemHandle;
1244     ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Handle custom1Handle;
1245     ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Handle custom2Handle;
1247     ti_sdo_ipc_GateMP_Handle *remoteHandles;
1248     UInt8 *inUseArray;
1249     UInt numResources;
1251     /* Cannot call when numOpen is non-zero. */
1252     Assert_isTrue(obj->numOpens == 0, ti_sdo_ipc_GateMP_A_invalidDelete);
1254     /* Removed from NameServer */
1255     if (obj->nsKey != 0) {
1256         NameServer_removeEntry((NameServer_Handle)GateMP_module->nameServer,
1257                 obj->nsKey);
1258     }
1260     /* Set the status to 0 */
1261     if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1262         obj->attrs->status = 0;
1263         if (obj->cacheEnabled) {
1264             Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1265                     Cache_Type_ALL, TRUE);
1266         }
1267     }
1269     /*
1270      *  If ObjType_LOCAL, memory was allocated from the local system heap.
1271      *  obj->attrs might be NULL if the Memory_alloc failed in Instance_init
1272      */
1273     if (obj->objType == ti_sdo_ipc_Ipc_ObjType_LOCAL && obj->attrs != NULL) {
1274         Memory_free(NULL, obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs));
1275     }
1277     switch (obj->remoteProtect) {
1278         case GateMP_RemoteProtect_SYSTEM:
1279             if (obj->gateHandle) {
1280                 systemHandle =
1281                 ti_sdo_ipc_GateMP_RemoteSystemProxy_Handle_downCast2(
1282                         obj->gateHandle);
1283                 ti_sdo_ipc_GateMP_RemoteSystemProxy_delete(&systemHandle);
1284             }
1286             inUseArray = GateMP_module->remoteSystemInUse;
1287             remoteHandles = GateMP_module->remoteSystemGates;
1288             numResources = GateMP_module->numRemoteSystem;
1289             break;
1291         case GateMP_RemoteProtect_CUSTOM1:
1292             if (obj->gateHandle) {
1293                 custom1Handle =
1294                         ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Handle_downCast2(
1295                             obj->gateHandle);
1296                 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_delete(&custom1Handle);
1297             }
1299             inUseArray = GateMP_module->remoteCustom1InUse;
1300             remoteHandles = GateMP_module->remoteCustom1Gates;
1301             numResources = GateMP_module->numRemoteCustom1;
1302             break;
1304         case GateMP_RemoteProtect_CUSTOM2:
1305             if (obj->gateHandle) {
1306                 custom2Handle =
1307                         ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Handle_downCast2(
1308                             obj->gateHandle);
1309                 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_delete(&custom2Handle);
1310             }
1312             inUseArray = GateMP_module->remoteCustom2InUse;
1313             remoteHandles = GateMP_module->remoteCustom2Gates;
1314             numResources = GateMP_module->numRemoteCustom2;
1315             break;
1316         case GateMP_RemoteProtect_NONE:
1317             /*
1318              *  Nothing else to finalize. Any alloc'ed memory has already been
1319              *  freed
1320              */
1321             Log_write2(ti_sdo_ipc_GateMP_LM_delete, (UArg)obj->remoteProtect,
1322                 (UArg)obj->resourceId);
1323             return;
1324         default:
1325             /* Should never be here */
1326             Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
1327             break;
1328     }
1330     /* Clear the handle array entry in local memory */
1331     if (obj->resourceId != (UInt)-1) {
1332         remoteHandles[obj->resourceId] = NULL;
1333     }
1335     if ((obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) &&
1336         (obj->resourceId != (UInt)-1)) {
1337         /* Clear the resource used flag in shared memory */
1338         if (GateMP_module->defaultGate != NULL) {
1339             systemKey = GateMP_enter((GateMP_Handle)GateMP_module->defaultGate);
1340         }
1341         else {
1342             /* this should only be done when deleting the very last GateMP */
1343             systemKey = Hwi_disable();
1344         }
1346         /* update the GateMP resource tracker */
1347         inUseArray[obj->resourceId] = UNUSED;
1348         if (obj->cacheEnabled) {
1349             Cache_wbInv(inUseArray,
1350                         numResources * sizeof(UInt8),
1351                         Cache_Type_ALL,
1352                         TRUE);
1353         }
1355         if (GateMP_module->defaultGate != NULL) {
1356             GateMP_leave((GateMP_Handle)GateMP_module->defaultGate, systemKey);
1357         }
1358         else {
1359             Hwi_restore(systemKey);
1360         }
1361     }
1363     if (obj->objType == ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION) {
1364         /* Free memory allocated from the region heap */
1365         if (obj->attrs) {
1366             Memory_free(SharedRegion_getHeap(obj->regionId), obj->attrs,
1367                 obj->allocSize);
1368         }
1369     }
1371     Log_write2(ti_sdo_ipc_GateMP_LM_delete, (UArg)obj->remoteProtect,
1372             (UArg)obj->resourceId);
1375 /*
1376  *  ======== ti_sdo_ipc_GateMP_getSharedAddr ========
1377  */
1378 SharedRegion_SRPtr ti_sdo_ipc_GateMP_getSharedAddr(
1379         ti_sdo_ipc_GateMP_Object *obj)
1381     SharedRegion_SRPtr srPtr;
1383     srPtr = SharedRegion_getSRPtr(obj->attrs, obj->regionId);
1385     return (srPtr);
1388 /*
1389  *  ======== ti_sdo_ipc_GateMP_setDefaultRemote ========
1390  */
1391 Void ti_sdo_ipc_GateMP_setDefaultRemote(ti_sdo_ipc_GateMP_Object *obj)
1393     GateMP_module->defaultGate = obj;
1396 /*
1397  *************************************************************************
1398  *                       Internal functions
1399  *************************************************************************
1400  */
1402 /*
1403  *  ======== ti_sdo_ipc_GateMP_getFreeResource ========
1404  */
1405 UInt ti_sdo_ipc_GateMP_getFreeResource(UInt8 *inUse, Int num, Error_Block *eb)
1407     UInt key;
1408     Bool flag = FALSE;
1409     UInt resourceId;
1410     GateMP_Handle defaultGate;
1412     /* Need to look at shared memory. Enter default gate */
1413     defaultGate = GateMP_getDefaultRemote();
1415     if (defaultGate){
1416         key = GateMP_enter(defaultGate);
1417     }
1419     /* Invalidate cache before looking at the in-use flags */
1420     if (SharedRegion_isCacheEnabled(0)) {
1421         Cache_inv(inUse, num * sizeof(UInt8), Cache_Type_ALL, TRUE);
1422     }
1424     /*
1425      *  Find a free resource id. Note: zero is reserved on the
1426      *  system proxy for the default gate.
1427      */
1428     for (resourceId = 0; resourceId < num; resourceId++) {
1429         /*
1430          *  If not in-use, set the inUse to TRUE to prevent other
1431          *  creates from getting this one.
1432          */
1433         if (inUse[resourceId] == UNUSED) {
1434            flag = TRUE;
1436            /* Denote in shared memory that the resource is used */
1437            inUse[resourceId] = USED;
1438            break;
1439        }
1440     }
1442     /* Write-back if a in-use flag was changed */
1443     if (flag == TRUE && SharedRegion_isCacheEnabled(0)) {
1444         Cache_wbInv(inUse, num * sizeof(UInt8), Cache_Type_ALL, TRUE);
1445     }
1447     /* Done with the critical section */
1448     if (defaultGate) {
1449         GateMP_leave(defaultGate, key);
1450     }
1452     if (flag == FALSE) {
1453         resourceId = (UInt)-1;
1454         Error_raise(eb, ti_sdo_ipc_GateMP_E_gateUnavailable, 0, 0);
1455     }
1457     return (resourceId);