]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - packages/ti/sdo/ipc/GateMP.c
GateMP: Add cache operation to make sure the SR0 contents are synced up
[ipc/ipcdev.git] / packages / ti / sdo / ipc / GateMP.c
1 /*
2  * Copyright (c) 2012-2015 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         status = GateMP_openByAddr(sharedAddr, handlePtr);
293     }
294     else {
295         /*  need to track number of opens atomically */
296         key = Hwi_disable();
297         resourceId = nsValue[2];
298         mask = nsValue[3];
300         /* Remote case */
301         switch (GETREMOTE(mask)) {
302             case GateMP_RemoteProtect_SYSTEM:
303                 obj = GateMP_module->remoteSystemGates[resourceId];
304                 break;
306             case GateMP_RemoteProtect_CUSTOM1:
307                 obj = GateMP_module->remoteCustom1Gates[resourceId];
308                 break;
310             case GateMP_RemoteProtect_CUSTOM2:
311                 obj = GateMP_module->remoteCustom2Gates[resourceId];
312                 break;
314             default:
315                 obj = NULL;
316                 status = GateMP_E_FAIL;
317                 break;
318         }
320         if (status == GateMP_S_SUCCESS) {
321             /*
322              *  If the object is NULL, then it must have been created on a
323              *  remote processor. Need to create a local object. This is
324              *  accomplished by setting the openFlag to TRUE.
325              */
326             if (obj == NULL) {
327                 /* Create a GateMP object with the openFlag set to true */
328                 ti_sdo_ipc_GateMP_Params_init(&params);
329                 params.openFlag = TRUE;
330                 params.sharedAddr = NULL;
331                 params.resourceId = resourceId;
332                 params.localProtect = GETLOCAL(mask);
333                 params.remoteProtect = GETREMOTE(mask);
335                 obj = ti_sdo_ipc_GateMP_create(&params, &eb);
336                 if (obj == NULL) {
337                     status = GateMP_E_FAIL;
338                 }
339             }
340             else {
341                 obj->numOpens++;
342             }
343         }
345         /* Return the GateMP instance  */
346         *handlePtr = (GateMP_Handle)obj;
348         /* restore hwi mask */
349         Hwi_restore(key);
350     }
352     return (status);
355 /*
356  *  ======== GateMP_openByAddr ========
357  */
358 Int GateMP_openByAddr(Ptr sharedAddr, GateMP_Handle *handlePtr)
360     Int status = GateMP_S_SUCCESS;
361     UInt key;
362     ti_sdo_ipc_GateMP_Object *obj;
363     ti_sdo_ipc_GateMP_Params params;
364     ti_sdo_ipc_GateMP_Attrs *attrs;
365     UInt16 regionId;
366     Error_Block eb;
368     Error_init(&eb);
370     attrs = (ti_sdo_ipc_GateMP_Attrs *)sharedAddr;
372     /* get the region id and invalidate attrs is needed */
373     regionId = SharedRegion_getId(sharedAddr);
374     if (regionId != SharedRegion_INVALIDREGIONID) {
375         if (SharedRegion_isCacheEnabled(regionId)) {
376             Cache_inv(attrs, sizeof(ti_sdo_ipc_GateMP_Attrs), Cache_Type_ALL,
377                     TRUE);
378         }
379     }
381     if (attrs->status != ti_sdo_ipc_GateMP_CREATED) {
382         *handlePtr = NULL;
383         status = GateMP_E_NOTFOUND;
384     }
385     else {
386         /* Local gate */
387         if (GETREMOTE(attrs->mask) == GateMP_RemoteProtect_NONE) {
388             if (attrs->creatorProcId != MultiProc_self()) {
389                 Error_raise(&eb, ti_sdo_ipc_GateMP_E_localGate, 0, 0);
390                 return (GateMP_E_FAIL);
391             }
393             /* need to atomically increment number of opens */
394             key = Hwi_disable();
396             obj = (ti_sdo_ipc_GateMP_Object *)attrs->arg;
397             *handlePtr = (GateMP_Handle)obj;
398             obj->numOpens++;
400             /* restore hwi mask */
401             Hwi_restore(key);
403             return (GateMP_S_SUCCESS);
404         }
406         /*  need to track number of opens atomically */
407         key = Hwi_disable();
409         /* Remote case */
410         switch (GETREMOTE(attrs->mask)) {
411             case GateMP_RemoteProtect_SYSTEM:
412                 obj = GateMP_module->remoteSystemGates[attrs->arg];
413                 break;
415             case GateMP_RemoteProtect_CUSTOM1:
416                 obj = GateMP_module->remoteCustom1Gates[attrs->arg];
417                 break;
419             case GateMP_RemoteProtect_CUSTOM2:
420                 obj = GateMP_module->remoteCustom2Gates[attrs->arg];
421                 break;
423             default:
424                 obj = NULL;
425                 status = GateMP_E_FAIL;
426                 break;
427         }
429         if (status == GateMP_S_SUCCESS) {
430             /*
431              *  If the object is NULL, then it must have been created on a
432              *  remote processor. Need to create a local object. This is
433              *  accomplished by setting the openFlag to TRUE.
434              */
435             if (obj == NULL) {
436                 /* Create a GateMP object with the openFlag set to true */
437                 ti_sdo_ipc_GateMP_Params_init(&params);
438                 params.openFlag = TRUE;
439                 params.sharedAddr = sharedAddr;
440                 params.resourceId = attrs->arg;
441                 params.localProtect = GETLOCAL(attrs->mask);
442                 params.remoteProtect = GETREMOTE(attrs->mask);
444                 obj = ti_sdo_ipc_GateMP_create(&params, &eb);
445                 if (obj == NULL) {
446                     status = GateMP_E_FAIL;
447                 }
448             }
449             else {
450                 obj->numOpens++;
451             }
452         }
454         /* Return the GateMP instance  */
455         *handlePtr = (GateMP_Handle)obj;
457         /* restore hwi mask */
458         Hwi_restore(key);
459     }
461     return (status);
464 /*
465  *  ======== GateMP_sharedMemReq ========
466  */
467 SizeT GateMP_sharedMemReq(const GateMP_Params *params)
469     SizeT memReq, minAlign;
470     UInt16 regionId;
471     ti_sdo_ipc_GateMP_RemoteSystemProxy_Params systemParams;
472     ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params custom1Params;
473     ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params custom2Params;
475     if (params->sharedAddr) {
476         regionId = SharedRegion_getId(params->sharedAddr);
477     }
478     else {
479         regionId = params->regionId;
480     }
482     Assert_isTrue(regionId != SharedRegion_INVALIDREGIONID,
483             ti_sdo_ipc_Ipc_A_internal);
485     minAlign = Memory_getMaxDefaultTypeAlign();
486     if (SharedRegion_getCacheLineSize(regionId) > minAlign) {
487         minAlign = SharedRegion_getCacheLineSize(regionId);
488     }
490     memReq = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
492     /* add the amount of shared memory required by proxy */
493     if (params->remoteProtect == GateMP_RemoteProtect_SYSTEM) {
494         ti_sdo_ipc_GateMP_RemoteSystemProxy_Params_init(&systemParams);
495         systemParams.regionId = regionId;
496         memReq += ti_sdo_ipc_GateMP_RemoteSystemProxy_sharedMemReq(
497                 (IGateMPSupport_Params *)&systemParams);
498     }
499     else if (params->remoteProtect == GateMP_RemoteProtect_CUSTOM1) {
500         ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params_init(&custom1Params);
501         custom1Params.regionId = regionId;
502         memReq += ti_sdo_ipc_GateMP_RemoteCustom1Proxy_sharedMemReq(
503                 (IGateMPSupport_Params *)&custom1Params);
504     }
505     else if (params->remoteProtect == GateMP_RemoteProtect_CUSTOM2) {
506         ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params_init(&custom2Params);
507         custom2Params.regionId = regionId;
508         memReq += ti_sdo_ipc_GateMP_RemoteCustom2Proxy_sharedMemReq(
509                 (IGateMPSupport_Params *)&custom2Params);
510     }
512     return (memReq);
515 /*
516  *************************************************************************
517  *                       Module functions
518  *************************************************************************
519  */
521 /*
522  *  ======== ti_sdo_ipc_GateMP_createLocal ========
523  */
524 IGateProvider_Handle ti_sdo_ipc_GateMP_createLocal(
525     ti_sdo_ipc_GateMP_LocalProtect localProtect)
527     IGateProvider_Handle gateHandle;
529     /* Create the local gate. */
530     switch (localProtect) {
531         case GateMP_LocalProtect_NONE:
532             /* Plug with the GateNull singleton */
533             gateHandle = GateMP_module->gateNull;
534             break;
536         case GateMP_LocalProtect_INTERRUPT:
537             /* Plug with the GateAll singleton */
538             gateHandle = GateMP_module->gateAll;
539             break;
541         case GateMP_LocalProtect_TASKLET:
542             /* Plug with the GateSwi singleton */
543             gateHandle = GateMP_module->gateSwi;
544             break;
546         case GateMP_LocalProtect_THREAD:
547         case GateMP_LocalProtect_PROCESS:
548             /* Plug with the GateMutexPri singleton */
549             gateHandle = GateMP_module->gateMutexPri;
550             break;
552         default:
553             /* Invalid local protection level encountered */
554             Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
555             break;
556     }
558     return (gateHandle);
561 /*
562  *  ======== GateMP_getDefaultRemote ========
563  */
564 GateMP_Handle GateMP_getDefaultRemote()
566     return ((GateMP_Handle)GateMP_module->defaultGate);
569 /*
570  *  ======== GateMP_getLocalProtect ========
571  */
572 GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
574     ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)handle;
576     Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
578     return ((GateMP_LocalProtect)obj->localProtect);
581 /*
582  *  ======== GateMP_getRemoteProtect ========
583  */
584 GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
586     ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)handle;
588     Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
590     return ((GateMP_RemoteProtect)obj->remoteProtect);
593 /*
594  *  ======== ti_sdo_ipc_GateMP_getRegion0ReservedSize ========
595  */
596 SizeT ti_sdo_ipc_GateMP_getRegion0ReservedSize(Void)
598     SizeT reserved, minAlign;
600     minAlign = Memory_getMaxDefaultTypeAlign();
602     if (SharedRegion_getCacheLineSize(0) > minAlign) {
603         minAlign = SharedRegion_getCacheLineSize(0);
604     }
606     reserved = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
608     reserved += _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
610     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
611         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
612             reserved += _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
613     }
615     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
616         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
617             reserved += _Ipc_roundup(GateMP_module->numRemoteCustom2, minAlign);
618     }
620     return (reserved);
623 /*
624  *  ======== ti_sdo_ipc_GateMP_setRegion0Reserved ========
625  */
626 Void ti_sdo_ipc_GateMP_setRegion0Reserved(Ptr sharedAddr)
628     ti_sdo_ipc_GateMP_Reserved *reserve;
629     SizeT minAlign, offset;
630     UInt i;
631     Bits32 *delegateReservedMask;
632     UInt32 nsValue[6];
633     Int ret;
635     minAlign = Memory_getMaxDefaultTypeAlign();
636     if (SharedRegion_getCacheLineSize(0) > minAlign) {
637         minAlign = SharedRegion_getCacheLineSize(0);
638     }
640     /* setup ti_sdo_ipc_GateMP_Reserved fields */
641     reserve = (ti_sdo_ipc_GateMP_Reserved *)sharedAddr;
642     reserve->version = ti_sdo_ipc_GateMP_VERSION;
644     if (SharedRegion_isCacheEnabled(0)) {
645         Cache_wbInv(sharedAddr, sizeof(ti_sdo_ipc_GateMP_Reserved),
646             Cache_Type_ALL, TRUE);
647     }
649     /*
650      *  initialize the in-use array in shared memory for the system gates.
651      */
652     offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
653     GateMP_module->remoteSystemInUse =
654         (Ptr)((UInt32)sharedAddr + offset);
656     if (GateMP_module->numRemoteSystem != 0) {
657         memset(GateMP_module->remoteSystemInUse, 0,
658             GateMP_module->numRemoteSystem * sizeof(UInt8));
659         delegateReservedMask =
660                 ti_sdo_ipc_GateMP_RemoteSystemProxy_getReservedMask();
661         if (delegateReservedMask != NULL) {
662             for (i = 0; i < GateMP_module->numRemoteSystem; i++) {
663                 if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
664                     GateMP_module->remoteSystemInUse[i] = RESERVED;
665                 }
666             }
667         }
669         if (SharedRegion_isCacheEnabled(0)) {
670             Cache_wbInv(GateMP_module->remoteSystemInUse,
671                 GateMP_module->numRemoteSystem * sizeof(UInt8),
672                 Cache_Type_ALL,
673                 TRUE);
674         }
675     }
677     /*
678      *  initialize the in-use array in shared memory for the custom1 gates.
679      *  Need to check if this proxy is the same as system
680      */
681     offset = _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
682     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
683         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
684         if (GateMP_module->numRemoteCustom1 != 0) {
685             GateMP_module->remoteCustom1InUse =
686                 GateMP_module->remoteSystemInUse + offset;
688             memset(GateMP_module->remoteCustom1InUse, 0,
689                 GateMP_module->numRemoteCustom1 * sizeof(UInt8));
690             delegateReservedMask =
691                     ti_sdo_ipc_GateMP_RemoteCustom1Proxy_getReservedMask();
692             if (delegateReservedMask != NULL) {
693                 for (i = 0; i < GateMP_module->numRemoteCustom1; i++) {
694                     if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
695                         GateMP_module->remoteCustom1InUse[i] = RESERVED;
696                     }
697                 }
698             }
699             if (SharedRegion_isCacheEnabled(0)) {
700                 Cache_wbInv(GateMP_module->remoteCustom1InUse,
701                      GateMP_module->numRemoteCustom1 * sizeof(UInt8),
702                      Cache_Type_ALL,
703                      TRUE);
704             }
705         }
706     }
707     else {
708         GateMP_module->remoteCustom1InUse = GateMP_module->remoteSystemInUse;
709         GateMP_module->remoteCustom1Gates = GateMP_module->remoteSystemGates;
710     }
712     /*
713      *  initialize the in-use array in shared memory for the custom2 gates.
714      *  Need to check if this proxy is the same as system or custom1
715      */
716     offset = _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
717     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
718         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
719         if (GateMP_module->numRemoteCustom2 != 0) {
720                 GateMP_module->remoteCustom2InUse =
721                     GateMP_module->remoteCustom1InUse + offset;
723             memset(GateMP_module->remoteCustom2InUse, 0,
724                 GateMP_module->numRemoteCustom2 * sizeof(UInt8));
725             delegateReservedMask =
726                     ti_sdo_ipc_GateMP_RemoteCustom2Proxy_getReservedMask();
727             if (delegateReservedMask != NULL) {
728                 for (i = 0; i < GateMP_module->numRemoteCustom2; i++) {
729                     if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
730                         GateMP_module->remoteCustom2InUse[i] = RESERVED;
731                     }
732                 }
733             }
735             if (SharedRegion_isCacheEnabled(0)) {
736                 Cache_wbInv(GateMP_module->remoteCustom2InUse,
737                      GateMP_module->numRemoteCustom2 * sizeof(UInt8),
738                      Cache_Type_ALL,
739                      TRUE);
740             }
741         }
742     }
743     else if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
744              ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
745         GateMP_module->remoteCustom2InUse =
746             GateMP_module->remoteCustom1InUse;
747         GateMP_module->remoteCustom2Gates =
748             GateMP_module->remoteCustom1Gates;
749     }
750     else {
751         GateMP_module->remoteCustom2InUse = GateMP_module->remoteSystemInUse;
752         GateMP_module->remoteCustom2Gates = GateMP_module->remoteSystemGates;
753     }
755     if (GateMP_module->hostSupport == TRUE) {
756         /* Add special entry to store inuse arrays' location and size */
757         ret = _GateMP_virtToPhys(
758             (UInt32)GateMP_module->remoteSystemInUse, &nsValue[0]);
759         Assert_isTrue(ret == GateMP_S_SUCCESS, (Assert_Id)NULL);
760         (void)ret;   /* silence unused var warning when asserts disabled */
761         if (GateMP_module->numRemoteCustom1 != 0) {
762             ret = _GateMP_virtToPhys(
763                 (UInt32)GateMP_module->remoteCustom1InUse, &nsValue[1]);
764             Assert_isTrue(ret == GateMP_S_SUCCESS, (Assert_Id)NULL);
765         }
766         else {
767             nsValue[1] = 0;
768         }
769         if (GateMP_module->numRemoteCustom2 != 0) {
770             ret = _GateMP_virtToPhys(
771                 (UInt32)GateMP_module->remoteCustom2InUse, &nsValue[2]);
772             Assert_isTrue(ret == GateMP_S_SUCCESS, (Assert_Id)NULL);
773         }
774         else {
775             nsValue[2] = 0;
776         }
777         nsValue[3] = GateMP_module->numRemoteSystem;
778         nsValue[4] = GateMP_module->numRemoteCustom1;
779         nsValue[5] = GateMP_module->numRemoteCustom2;
780         GateMP_module->nsKey = NameServer_add((NameServer_Handle)
781             GateMP_module->nameServer, "_GateMP_TI_info", &nsValue,
782             sizeof(nsValue));
783     }
786 /*
787  *  ======== ti_sdo_ipc_GateMP_openRegion0Reserved ========
788  */
789 Void ti_sdo_ipc_GateMP_openRegion0Reserved(Ptr sharedAddr)
791     ti_sdo_ipc_GateMP_Reserved *reserve;
792     SizeT minAlign, offset;
794     minAlign = Memory_getMaxDefaultTypeAlign();
795     if (SharedRegion_getCacheLineSize(0) > minAlign) {
796         minAlign = SharedRegion_getCacheLineSize(0);
797     }
800     /* setup ti_sdo_ipc_GateMP_Reserved fields */
801     reserve = (ti_sdo_ipc_GateMP_Reserved *)sharedAddr;
803     if (reserve->version != ti_sdo_ipc_GateMP_VERSION) {
804         /* Version mismatch: return an error */
805         Error_raise(NULL, ti_sdo_ipc_Ipc_E_versionMismatch, reserve->version,
806                     ti_sdo_ipc_GateMP_VERSION);
807         return;
808     }
810     offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
811     GateMP_module->remoteSystemInUse =
812         (Ptr)((UInt32)sharedAddr + offset);
814     /*
815      *  initialize the in-use array in shared memory for the custom1 gates.
816      *  Need to check if this proxy is the same as system
817      */
818     offset = _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
819     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
820         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
821         if (GateMP_module->numRemoteCustom1 != 0) {
822             GateMP_module->remoteCustom1InUse =
823                 GateMP_module->remoteSystemInUse + offset;
824         }
825     }
826     else {
827         GateMP_module->remoteCustom1InUse = GateMP_module->remoteSystemInUse;
828         GateMP_module->remoteCustom1Gates = GateMP_module->remoteSystemGates;
829     }
831     offset = _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
832     if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
833         ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
834         if (GateMP_module->numRemoteCustom2 != 0) {
835             GateMP_module->remoteCustom2InUse =
836                 GateMP_module->remoteCustom1InUse + offset;
837         }
838     }
839     else if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
840              ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
841         GateMP_module->remoteCustom2InUse =
842             GateMP_module->remoteCustom1InUse;
843         GateMP_module->remoteCustom2Gates =
844             GateMP_module->remoteCustom1Gates;
845     }
846     else {
847         GateMP_module->remoteCustom2InUse = GateMP_module->remoteSystemInUse;
848         GateMP_module->remoteCustom2Gates = GateMP_module->remoteSystemGates;
849     }
852 /*
853  *  ======== ti_sdo_ipc_GateMP_attach ========
854  */
855 Int ti_sdo_ipc_GateMP_attach(UInt16 remoteProcId, Ptr sharedAddr)
857     Ptr gateMPsharedAddr;
858     SharedRegion_Entry entry;
859     ti_sdo_ipc_GateMP_Handle defaultGate;
860     Int status = GateMP_S_SUCCESS;
862     /* If default gate is not NULL return since its already set */
863     if (GateMP_getDefaultRemote() != NULL) {
864         return(GateMP_S_ALREADYSETUP);
865     }
867     /* get region 0 information */
868     SharedRegion_getEntry(0, &entry);
870     gateMPsharedAddr = (Ptr)((UInt32)sharedAddr +
871                        ti_sdo_ipc_GateMP_getRegion0ReservedSize());
873     if ((entry.ownerProcId != MultiProc_self()) &&
874         (entry.ownerProcId != MultiProc_INVALIDID)) {
876         /* Make sure to invalidate cache before using shared memory content */
877         if (entry.cacheEnable) {
878             Cache_inv(sharedAddr, ti_sdo_ipc_GateMP_getRegion0ReservedSize(),
879                       Cache_Type_ALL, TRUE);
880         }
882         /* if not the owner of the SharedRegion */
883         ti_sdo_ipc_GateMP_openRegion0Reserved(sharedAddr);
885         /* open the gate by address */
886         status = GateMP_openByAddr(gateMPsharedAddr,
887                 (GateMP_Handle *)&defaultGate);
889         /* openByAddr should always succeed */
890         Assert_isTrue(status >= 0, ti_sdo_ipc_Ipc_A_internal);
892         /* set the default GateMP for opener */
893         ti_sdo_ipc_GateMP_setDefaultRemote(defaultGate);
894     }
896     return (status);
899 /*
900  *  ======== ti_sdo_ipc_GateMP_detach ========
901  */
902 Int ti_sdo_ipc_GateMP_detach(UInt16 remoteProcId)
904     SharedRegion_Entry entry;
905     GateMP_Handle gate;
906     Int status = GateMP_S_SUCCESS;
908     /* get region 0 information */
909     SharedRegion_getEntry(0, &entry);
911     if ((entry.isValid) &&
912         (entry.ownerProcId == remoteProcId)) {
913         /* get the default gate */
914         gate = GateMP_getDefaultRemote();
916         if (gate != NULL) {
917             /* close the gate */
918             status = GateMP_close(&gate);
920             /* set the default remote gate to NULL */
921             ti_sdo_ipc_GateMP_setDefaultRemote(NULL);
922         }
923     }
925     return (status);
928 /*
929  *  ======== ti_sdo_ipc_GateMP_start ========
930  */
931 Int ti_sdo_ipc_GateMP_start(Ptr sharedAddr)
933     SharedRegion_Entry       entry;
934     ti_sdo_ipc_GateMP_Params gateMPParams;
935     ti_sdo_ipc_GateMP_Handle defaultGate;
936     Int status = GateMP_S_SUCCESS;
937     Error_Block eb;
939     /* get region 0 information */
940     SharedRegion_getEntry(0, &entry);
942     /* if entry owner proc is not specified return */
943     if (entry.ownerProcId == MultiProc_INVALIDID) {
944         return (status);
945     }
947     if (entry.ownerProcId == MultiProc_self()) {
948         /* if owner of the SharedRegion */
949         ti_sdo_ipc_GateMP_setRegion0Reserved(sharedAddr);
951         /* create default GateMP */
952         ti_sdo_ipc_GateMP_Params_init(&gateMPParams);
953         gateMPParams.sharedAddr = (Ptr)((UInt32)sharedAddr +
954                 ti_sdo_ipc_GateMP_getRegion0ReservedSize());
955         gateMPParams.localProtect  = ti_sdo_ipc_GateMP_LocalProtect_TASKLET;
956         gateMPParams.name = "_GateMP_TI_dGate";
958         if (ti_sdo_utils_MultiProc_numProcessors > 1) {
959             gateMPParams.remoteProtect = ti_sdo_ipc_GateMP_RemoteProtect_SYSTEM;
960         }
961         else {
962             gateMPParams.remoteProtect = ti_sdo_ipc_GateMP_RemoteProtect_NONE;
963         }
965         Error_init(&eb);
966         defaultGate = ti_sdo_ipc_GateMP_create(&gateMPParams, &eb);
967         if (defaultGate != NULL) {
968             /* set the default GateMP for creator */
969             ti_sdo_ipc_GateMP_setDefaultRemote(defaultGate);
970         }
971         else {
972             status = GateMP_E_FAIL;
973         }
974     }
976     return (status);
979 /*
980  *  ======== ti_sdo_ipc_GateMP_stop ========
981  */
982 Int ti_sdo_ipc_GateMP_stop()
984     SharedRegion_Entry entry;
985     GateMP_Handle gate;
986     Int status = GateMP_S_SUCCESS;
988     /* get region 0 information */
989     SharedRegion_getEntry(0, &entry);
991     if ((entry.isValid) &&
992         (entry.createHeap) &&
993         (entry.ownerProcId == MultiProc_self())) {
994         /* get the default GateMP */
995         gate = GateMP_getDefaultRemote();
997         if (gate != NULL) {
998             /* set the default GateMP to NULL */
999             ti_sdo_ipc_GateMP_setDefaultRemote(NULL);
1001             /* delete the default GateMP */
1002             status = GateMP_delete(&gate);
1003         }
1005         /* Remove global info entry from NameServer */
1006         if ((GateMP_module->hostSupport == TRUE) &&
1007             (GateMP_module->nsKey != 0)) {
1008             NameServer_removeEntry((NameServer_Handle)GateMP_module->nameServer,
1009                 GateMP_module->nsKey);
1010         }
1011     }
1013     return (status);
1016 /*
1017  *************************************************************************
1018  *                       Instance functions
1019  *************************************************************************
1020  */
1022 /*
1023  *  ======== ti_sdo_ipc_GateMP_Instance_init ========
1024  */
1025 Int ti_sdo_ipc_GateMP_Instance_init(ti_sdo_ipc_GateMP_Object *obj,
1026         const ti_sdo_ipc_GateMP_Params *params,
1027         Error_Block *eb)
1029     UInt key;
1030     IGateMPSupport_Handle remoteHandle;
1031     IGateProvider_Handle localHandle;
1032     ti_sdo_ipc_GateMP_RemoteSystemProxy_Params systemParams;
1033     ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params custom1Params;
1034     ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params custom2Params;
1035     SizeT minAlign, offset;
1036     SharedRegion_SRPtr sharedShmBase;
1037     GateMP_Params sparams;
1038     UInt32 nsValue[4];
1039     UInt32 sizeNsValue;
1040     IHeap_Handle regionHeap;
1042     /* Initialize resourceId to an invalid value */
1043     obj->resourceId = (UInt)-1;
1045     localHandle = ti_sdo_ipc_GateMP_createLocal(params->localProtect);
1047     /* Open GateMP instance */
1048     if (params->openFlag == TRUE) {
1049         /* all open work done here except for remote gateHandle */
1050         obj->localProtect   = params->localProtect;
1051         obj->remoteProtect  = params->remoteProtect;
1052         obj->nsKey          = 0;
1053         obj->numOpens       = 0; /* Will be set to 1 after init() complete */
1054         obj->attrs          = (ti_sdo_ipc_GateMP_Attrs *)params->sharedAddr;
1055         if (obj->attrs != NULL) {
1056             obj->regionId       = SharedRegion_getId((Ptr)obj->attrs);
1057             obj->cacheEnabled   = SharedRegion_isCacheEnabled(obj->regionId);
1058             /* Assert that the buffer is in a valid shared region */
1059             Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID,
1060                       ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);
1061         }
1063         obj->allocSize      = 0;
1064         obj->objType        = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC;
1066         minAlign = Memory_getMaxDefaultTypeAlign();
1068         if ((obj->attrs != NULL) &&
1069             (SharedRegion_getCacheLineSize(obj->regionId) > minAlign)) {
1070             minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1071         }
1073         offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1075         /* TODO: host side created gates cannot have proxy memory */
1076         if (obj->attrs != NULL) {
1077             obj->proxyAttrs = (Ptr)((UInt32)obj->attrs + offset);
1078         }
1079         else {
1080             obj->proxyAttrs = NULL;
1081         }
1082     }
1083     /* Create GateMP instance */
1084     else {
1085         obj->localProtect  = params->localProtect;
1086         obj->remoteProtect = params->remoteProtect;
1087         obj->nsKey         = 0;
1088         obj->numOpens      = 0;
1090         if (obj->remoteProtect == GateMP_RemoteProtect_NONE) {
1091             obj->gateHandle = ti_sdo_ipc_GateMP_createLocal(obj->localProtect);
1092             if (params->sharedAddr != NULL) {
1093                 /* Create a local gate using shared memory */
1094                 obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
1095                 obj->attrs = params->sharedAddr;
1096                 obj->regionId = SharedRegion_getId((Ptr)obj->attrs);
1097                 obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
1098             }
1099             else {
1100                 /* Create a local gate allocating from the local heap */
1101                 obj->objType = ti_sdo_ipc_Ipc_ObjType_LOCAL;
1102                 obj->regionId = ti_sdo_ipc_SharedRegion_INVALIDREGIONID;
1103                 obj->cacheEnabled  = FALSE; /* local */
1104                 obj->attrs = Memory_alloc(NULL,
1105                         sizeof(ti_sdo_ipc_GateMP_Attrs), 0, eb);
1106                 if (obj->attrs == NULL) {
1107                     return (2);
1108                 }
1110             }
1112             obj->attrs->arg = (Bits32)obj;
1113             obj->attrs->mask = SETMASK(obj->remoteProtect, obj->localProtect);
1114             obj->attrs->creatorProcId = MultiProc_self();
1115             obj->attrs->status = ti_sdo_ipc_GateMP_CREATED;
1116             if (obj->cacheEnabled) {
1117                 /*
1118                  *  Need to write back memory if cache is enabled because cache
1119                  *  will be invalidated during openByAddr
1120                  */
1121                 Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1122                         Cache_Type_ALL, TRUE);
1123             }
1125             if (params->name) {
1126                 nsValue[0] = (UInt32)obj->attrs;
1127                 /*
1128                  *  Top 16 bits = procId of creator
1129                  *  Bottom 16 bits = '0' if local, '1' otherwise
1130                  */
1131                 nsValue[1] = ((UInt32)MultiProc_self()) << 16;
1133                 if (GateMP_module->hostSupport == TRUE) {
1134                     nsValue[2] = obj->attrs->arg;
1135                     nsValue[3] = obj->attrs->mask;
1136                     sizeNsValue = sizeof(nsValue);
1137                 }
1138                 else {
1139                     sizeNsValue = 2 * sizeof(UInt32);
1140                 }
1142                 obj->nsKey = NameServer_add((NameServer_Handle)
1143                         GateMP_module->nameServer, params->name, &nsValue,
1144                         sizeNsValue);
1146                 if (obj->nsKey == NULL) {
1147                     Error_raise(eb, ti_sdo_ipc_Ipc_E_nameFailed, params->name,
1148                         0);
1149                     return (3);
1150                 }
1151             }
1153             /* Nothing else to do for local gates */
1154             return (0);
1155         }
1157         if (params->sharedAddr == NULL) {
1158             /* Need to allocate from heap */
1159             obj->objType        = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION;
1160             obj->regionId       = params->regionId;
1161             GateMP_getSharedParams(&sparams, params);
1162             obj->allocSize      = GateMP_sharedMemReq(&sparams);
1163             obj->cacheEnabled   = SharedRegion_isCacheEnabled(obj->regionId);
1165             /* The region heap will do the alignment */
1166             regionHeap = SharedRegion_getHeap(obj->regionId);
1167             Assert_isTrue(regionHeap != NULL, ti_sdo_ipc_SharedRegion_A_noHeap);
1168             obj->attrs = Memory_alloc(regionHeap, obj->allocSize, 0, eb);
1169             if (obj->attrs == NULL) {
1170                 return (3);
1171             }
1173             minAlign = Memory_getMaxDefaultTypeAlign();
1175             if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) {
1176                 minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1177             }
1179             offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1181             obj->proxyAttrs = (Ptr)((UInt32)obj->attrs + offset);
1182         }
1183         else {
1184             /* creating using sharedAddr */
1185             obj->regionId = SharedRegion_getId(params->sharedAddr);
1186             /* Assert that the buffer is in a valid shared region */
1187             Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID,
1188                           ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);
1190             obj->attrs = (ti_sdo_ipc_GateMP_Attrs *)params->sharedAddr;
1191             obj->cacheEnabled  = SharedRegion_isCacheEnabled(obj->regionId);
1192             obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
1194             minAlign = Memory_getMaxDefaultTypeAlign();
1196             if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) {
1197                 minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1198             }
1200             /* Assert that sharedAddr has correct alignment */
1201             Assert_isTrue(minAlign == 0 ||
1202                           ((UInt32)params->sharedAddr % minAlign) == 0,
1203                           ti_sdo_ipc_Ipc_A_addrNotCacheAligned);
1205             offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1207             obj->proxyAttrs = (Ptr)((UInt32)obj->attrs + offset);
1208         }
1209     }
1211     /* Proxy work for open and create done here */
1212     switch (obj->remoteProtect) {
1213         case GateMP_RemoteProtect_SYSTEM:
1214             if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1215                 /* Created Instance */
1216                 obj->resourceId = GateMP_getFreeResource(
1217                     GateMP_module->remoteSystemInUse,
1218                              GateMP_module->numRemoteSystem, eb);
1219                 if (Error_check(eb) == TRUE) {
1220                     return (4);
1221                 }
1222             }
1223             else {
1224                 /* resourceId set by open call */
1225                 obj->resourceId = params->resourceId;
1226             }
1228             /* Create the proxy object */
1229             ti_sdo_ipc_GateMP_RemoteSystemProxy_Params_init(&systemParams);
1230             systemParams.resourceId = obj->resourceId;
1231             systemParams.openFlag =
1232                     (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1233             systemParams.sharedAddr = obj->proxyAttrs;
1234             systemParams.regionId = obj->regionId;
1235             remoteHandle = ti_sdo_ipc_GateMP_RemoteSystemProxy_create(
1236                     localHandle, &systemParams, eb);
1238             if (remoteHandle == NULL) {
1239                 return (5);
1240             }
1242             /* Fill in the local array because it is cooked */
1243             key = Hwi_disable();
1244             GateMP_module->remoteSystemGates[obj->resourceId] = obj;
1245             Hwi_restore(key);
1246             break;
1248         case GateMP_RemoteProtect_CUSTOM1:
1249             if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1250                 obj->resourceId = GateMP_getFreeResource(
1251                              GateMP_module->remoteCustom1InUse,
1252                              GateMP_module->numRemoteCustom1, eb);
1253                 if (Error_check(eb) == TRUE) {
1254                     return (4);
1255                 }
1256             }
1257             else {
1258                 /* resourceId set by open call */
1259                 obj->resourceId = params->resourceId;
1260             }
1262             /* Create the proxy object */
1263             ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params_init(&custom1Params);
1264             custom1Params.resourceId = obj->resourceId;
1265             custom1Params.openFlag =
1266                     (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1267             custom1Params.sharedAddr = obj->proxyAttrs;
1268             custom1Params.regionId = obj->regionId;
1269             remoteHandle = ti_sdo_ipc_GateMP_RemoteCustom1Proxy_create(
1270                     localHandle, &custom1Params, eb);
1271             if (remoteHandle == NULL) {
1272                 return (5);
1273             }
1275             /* Fill in the local array because it is cooked */
1276             key = Hwi_disable();
1277             GateMP_module->remoteCustom1Gates[obj->resourceId] = obj;
1278             Hwi_restore(key);
1279             break;
1281         case GateMP_RemoteProtect_CUSTOM2:
1282             if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1283                 obj->resourceId = GateMP_getFreeResource(
1284                              GateMP_module->remoteCustom2InUse,
1285                              GateMP_module->numRemoteCustom2, eb);
1286                 if (Error_check(eb) == TRUE) {
1287                     return (4);
1288                 }
1289             }
1290             else {
1291                 /* resourceId set by open call */
1292                 obj->resourceId = params->resourceId;
1293             }
1295             /* Create the proxy object */
1296             ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params_init(&custom2Params);
1297             custom2Params.resourceId = obj->resourceId;
1298             custom2Params.openFlag =
1299                     (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1300             custom2Params.sharedAddr = obj->proxyAttrs;
1301             custom2Params.regionId = obj->regionId;
1302             remoteHandle = ti_sdo_ipc_GateMP_RemoteCustom2Proxy_create(
1303                     localHandle, &custom2Params, eb);
1304             if (remoteHandle == NULL) {
1305                 return (5);
1306             }
1308             /* Fill in the local array because it is cooked */
1309             key = Hwi_disable();
1310             GateMP_module->remoteCustom2Gates[obj->resourceId] = obj;
1311             Hwi_restore(key);
1312             break;
1314         default:
1315             /* Should never be here */
1316             Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
1317             return (5);  /* keep Coverity happy */
1318     }
1320     obj->gateHandle = IGateMPSupport_Handle_upCast(remoteHandle);
1322     /* Place Name/Attrs into NameServer table */
1323     if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1324         /* Fill in the attrs */
1325         obj->attrs->arg = obj->resourceId;
1326         obj->attrs->mask = SETMASK(obj->remoteProtect, obj->localProtect);
1327         obj->attrs->creatorProcId = MultiProc_self();
1328         obj->attrs->status = ti_sdo_ipc_GateMP_CREATED;
1330         if (obj->cacheEnabled) {
1331             Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1332                     Cache_Type_ALL, TRUE);
1333         }
1335         if (params->name != NULL) {
1336             sharedShmBase = SharedRegion_getSRPtr(obj->attrs, obj->regionId);
1337             nsValue[0] = (UInt32)sharedShmBase;
1338             /*
1339              *  Top 16 bits = procId of creator
1340              *  Bottom 16 bits = '0' if local, '1' otherwise
1341              */
1342             nsValue[1] = ((UInt32)MultiProc_self() << 16) | 1;
1344             if (GateMP_module->hostSupport == TRUE) {
1345                 /* Making a copy of these for host processor */
1346                 nsValue[2] = obj->attrs->arg;
1347                 nsValue[3] = obj->attrs->mask;
1348                 sizeNsValue = sizeof(nsValue);
1349             }
1350             else {
1351                 sizeNsValue = 2 * sizeof(UInt32);
1352             }
1354             obj->nsKey = NameServer_add((NameServer_Handle)
1355                     GateMP_module->nameServer, params->name, &nsValue,
1356                     sizeNsValue);
1358             if (obj->nsKey == NULL) {
1359                 Error_raise(eb, ti_sdo_ipc_Ipc_E_nameFailed, params->name, 0);
1360                 return (6);
1361             }
1362         }
1364         Log_write2(ti_sdo_ipc_GateMP_LM_create,
1365                 (UArg)obj->remoteProtect, (UArg)obj->resourceId);
1366     }
1367     else {
1368         obj->numOpens = 1;
1370         Log_write2(ti_sdo_ipc_GateMP_LM_open,
1371             (UArg)obj->remoteProtect, (UArg)obj->resourceId);
1372     }
1374     return (0);
1377 /*
1378  *  ======== ti_sdo_ipc_GateMP_Instance_finalize ========
1379  */
1380 Void ti_sdo_ipc_GateMP_Instance_finalize(
1381         ti_sdo_ipc_GateMP_Object *obj, Int status)
1383     UInt systemKey;
1384     ti_sdo_ipc_GateMP_RemoteSystemProxy_Handle systemHandle;
1385     ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Handle custom1Handle;
1386     ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Handle custom2Handle;
1388     ti_sdo_ipc_GateMP_Handle *remoteHandles;
1389     UInt8 *inUseArray;
1390     UInt size;
1392     /* Cannot call when numOpen is non-zero. */
1393     Assert_isTrue(obj->numOpens == 0, ti_sdo_ipc_GateMP_A_invalidDelete);
1395     /* Removed from NameServer */
1396     if (obj->nsKey != 0) {
1397         NameServer_removeEntry((NameServer_Handle)GateMP_module->nameServer,
1398                 obj->nsKey);
1399     }
1401     /* Set the status to 0 */
1402     if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1403         obj->attrs->status = 0;
1404         if (obj->cacheEnabled) {
1405             Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1406                     Cache_Type_ALL, TRUE);
1407         }
1408     }
1410     /*
1411      *  If ObjType_LOCAL, memory was allocated from the local system heap.
1412      *  obj->attrs might be NULL if the Memory_alloc failed in Instance_init
1413      */
1414     if (obj->objType == ti_sdo_ipc_Ipc_ObjType_LOCAL && obj->attrs != NULL) {
1415         Memory_free(NULL, obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs));
1416     }
1418     switch (obj->remoteProtect) {
1419         case GateMP_RemoteProtect_SYSTEM:
1420             if (obj->gateHandle) {
1421                 systemHandle =
1422                 ti_sdo_ipc_GateMP_RemoteSystemProxy_Handle_downCast2(
1423                         obj->gateHandle);
1424                 ti_sdo_ipc_GateMP_RemoteSystemProxy_delete(&systemHandle);
1425             }
1427             inUseArray = GateMP_module->remoteSystemInUse;
1428             remoteHandles = GateMP_module->remoteSystemGates;
1429             size = GateMP_module->numRemoteSystem * sizeof(UInt8);
1430             break;
1432         case GateMP_RemoteProtect_CUSTOM1:
1433             if (obj->gateHandle) {
1434                 custom1Handle =
1435                         ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Handle_downCast2(
1436                             obj->gateHandle);
1437                 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_delete(&custom1Handle);
1438             }
1440             inUseArray = GateMP_module->remoteCustom1InUse;
1441             remoteHandles = GateMP_module->remoteCustom1Gates;
1442             size = GateMP_module->numRemoteCustom1 * sizeof(UInt8);
1443             break;
1445         case GateMP_RemoteProtect_CUSTOM2:
1446             if (obj->gateHandle) {
1447                 custom2Handle =
1448                         ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Handle_downCast2(
1449                             obj->gateHandle);
1450                 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_delete(&custom2Handle);
1451             }
1453             inUseArray = GateMP_module->remoteCustom2InUse;
1454             remoteHandles = GateMP_module->remoteCustom2Gates;
1455             size = GateMP_module->numRemoteCustom2 * sizeof(UInt8);
1456             break;
1457         case GateMP_RemoteProtect_NONE:
1458             /*
1459              *  Nothing else to finalize. Any alloc'ed memory has already been
1460              *  freed
1461              */
1462             Log_write2(ti_sdo_ipc_GateMP_LM_delete, (UArg)obj->remoteProtect,
1463                 (UArg)obj->resourceId);
1464             return;
1465         default:
1466             /* Should never be here */
1467             Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
1468             break;
1469     }
1471     /* Clear the handle array entry in local memory */
1472     if (obj->resourceId != (UInt)-1) {
1473         remoteHandles[obj->resourceId] = NULL;
1474     }
1476     if ((obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) &&
1477         (obj->resourceId != (UInt)-1)) {
1478         /* Clear the resource used flag in shared memory */
1479         if (GateMP_module->defaultGate != NULL) {
1480             systemKey = GateMP_enter((GateMP_Handle)GateMP_module->defaultGate);
1481         }
1482         else {
1483             /* this should only be done when deleting the very last GateMP */
1484             systemKey = Hwi_disable();
1485         }
1487 #ifdef xdc_target__isaCompatible_v7A
1488         /* ARM speculative execution might have pulled array into cache */
1489         if (obj->cacheEnabled) {
1490             Cache_inv(inUseArray, size, Cache_Type_ALL, TRUE);
1491         }
1492 #endif
1493         /* update the GateMP resource tracker */
1494         inUseArray[obj->resourceId] = UNUSED;
1495         if (obj->cacheEnabled) {
1496             Cache_wbInv(inUseArray, size, Cache_Type_ALL, TRUE);
1497         }
1499         if (GateMP_module->defaultGate != NULL) {
1500             GateMP_leave((GateMP_Handle)GateMP_module->defaultGate, systemKey);
1501         }
1502         else {
1503             Hwi_restore(systemKey);
1504         }
1505     }
1507     if (obj->objType == ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION) {
1508         /* Free memory allocated from the region heap */
1509         if (obj->attrs) {
1510             Memory_free(SharedRegion_getHeap(obj->regionId), obj->attrs,
1511                 obj->allocSize);
1512         }
1513     }
1515     Log_write2(ti_sdo_ipc_GateMP_LM_delete, (UArg)obj->remoteProtect,
1516             (UArg)obj->resourceId);
1519 /*
1520  *  ======== ti_sdo_ipc_GateMP_getSharedAddr ========
1521  */
1522 SharedRegion_SRPtr ti_sdo_ipc_GateMP_getSharedAddr(
1523         ti_sdo_ipc_GateMP_Object *obj)
1525     SharedRegion_SRPtr srPtr;
1527     srPtr = SharedRegion_getSRPtr(obj->attrs, obj->regionId);
1529     return (srPtr);
1532 /*
1533  *  ======== ti_sdo_ipc_GateMP_setDefaultRemote ========
1534  */
1535 Void ti_sdo_ipc_GateMP_setDefaultRemote(ti_sdo_ipc_GateMP_Object *obj)
1537     GateMP_module->defaultGate = obj;
1540 /*
1541  *************************************************************************
1542  *                       Internal functions
1543  *************************************************************************
1544  */
1546 /*
1547  *  ======== ti_sdo_ipc_GateMP_getFreeResource ========
1548  */
1549 UInt ti_sdo_ipc_GateMP_getFreeResource(UInt8 *inUse, Int num, Error_Block *eb)
1551     UInt key;
1552     Bool flag = FALSE;
1553     UInt resourceId;
1554     GateMP_Handle defaultGate;
1556     /* Need to look at shared memory. Enter default gate */
1557     defaultGate = GateMP_getDefaultRemote();
1559     if (defaultGate){
1560         key = GateMP_enter(defaultGate);
1561     }
1563     /* Invalidate cache before looking at the in-use flags */
1564     if (SharedRegion_isCacheEnabled(0)) {
1565         Cache_inv(inUse, num * sizeof(UInt8), Cache_Type_ALL, TRUE);
1566     }
1568     /*
1569      *  Find a free resource id. Note: zero is reserved on the
1570      *  system proxy for the default gate.
1571      */
1572     for (resourceId = 0; resourceId < num; resourceId++) {
1573         /*
1574          *  If not in-use, set the inUse to TRUE to prevent other
1575          *  creates from getting this one.
1576          */
1577         if (inUse[resourceId] == UNUSED) {
1578            flag = TRUE;
1580            /* Denote in shared memory that the resource is used */
1581            inUse[resourceId] = USED;
1582            break;
1583        }
1584     }
1586     /* Write-back if a in-use flag was changed */
1587     if (flag == TRUE && SharedRegion_isCacheEnabled(0)) {
1588         Cache_wbInv(inUse, num * sizeof(UInt8), Cache_Type_ALL, TRUE);
1589     }
1591     /* Done with the critical section */
1592     if (defaultGate) {
1593         GateMP_leave(defaultGate, key);
1594     }
1596     if (flag == FALSE) {
1597         resourceId = (UInt)-1;
1598         Error_raise(eb, ti_sdo_ipc_GateMP_E_gateUnavailable, 0, 0);
1599     }
1601     return (resourceId);