Bind message queue to new remote processor
[ipc/ipcdev.git] / linux / src / api / gates / GateMP.c
1 /*
2  * Copyright (c) 2013-2014, 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  */
35 #include <ti/ipc/Std.h>
37 #include <stdlib.h>
38 #include <string.h>
40 #include <pthread.h>
41 #include <assert.h>
43 #include <ti/ipc/GateMP.h>
44 #include <ti/ipc/NameServer.h>
45 #include <ti/ipc/MultiProc.h>
47 #include <GateMP_config.h>
49 #include <_GateMP.h>
51 /* Socket Protocol Family */
52 #include <net/rpmsg.h>
54 /* Socket utils: */
55 #include <SocketFxns.h>
57 #include <ladclient.h>
58 #include <_lad.h>
61 /* structure for GateMP module state */
62 typedef struct {
63     GateMP_Params       defaultInstParams;
64     /* Default instance creation parameters */
65     GateMP_Handle       defaultGate;
66     /* Handle to default gate */
67     NameServer_Handle   nameServer;
68     /* NameServer for GateMP instances */
69     Bool                isStarted;
70     /* Has GateMP been started */
71     pthread_mutex_t     mutex;
72     /* Mutex for use on local process to serialize access to gate obj */
73     GateMP_Object **    remoteSystemGates;
74     /* Remote system gates */
75     Int                 numRemoteSystem;
76     /* Number of remote system gates */
77 } GateMP_ModuleObject;
79 /* traces in this file are controlled via _GateMP_verbose */
80 Bool _GateMP_verbose = FALSE;
81 #define verbose _GateMP_verbose
83 /* Internal structure defining parameters for GateMP_Instance_init */
84 typedef struct {
85     String name;                        /* Name of instance */
86     UInt16 regionId;                    /* not used on host*/
87     Ptr sharedAddr;                     /* not used on host*/
88     GateMP_LocalProtect localProtect;   /* Local protection level  */
89     GateMP_RemoteProtect remoteProtect; /* Remote protection level */
90     UInt32 resourceId;                  /* resource id */
91     Bool openFlag;                      /* Is this open or create? */
92 } _GateMP_Params;
94 static Int GateMP_getNumResources(GateMP_RemoteProtect type);
95 static Int GateMP_getFreeResource(GateMP_RemoteProtect type);
96 static Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type);
97 static GateMP_Handle _GateMP_create (const _GateMP_Params * params);
98 static Int GateMP_Instance_init(GateMP_Object *obj,
99     const _GateMP_Params *params);
100 static Void GateMP_Instance_finalize(GateMP_Object *obj, Int status);
102 /* -----------------------------------------------------------------------------
103  * Globals
104  * -----------------------------------------------------------------------------
105  */
106 static GateMP_ModuleObject GateMP_state =
108     .remoteSystemGates  = NULL,
109     .defaultGate        = NULL,
110     .nameServer         = NULL,
111     .mutex              = PTHREAD_MUTEX_INITIALIZER,
112 //    .gateMutex          = NULL,
113 //    .gateProcess        = NULL
114 };
116 static GateMP_ModuleObject *GateMP_module = &GateMP_state;
118 static GateMP_Params GateMP_defInstParams =
120     .name           = NULL,
121     .regionId       = 0,
122     .sharedAddr     = NULL,
123     .localProtect   = GateMP_LocalProtect_PROCESS,
124     .remoteProtect  = GateMP_RemoteProtect_SYSTEM
125 };
127 Int GateMP_start(Void)
129     Int status;
130     LAD_ClientHandle handle;
131     struct LAD_CommandObj cmd;
132     union LAD_ResponseObj rsp;
134     handle = LAD_findHandle();
135     if (handle == LAD_MAXNUMCLIENTS) {
136         PRINTVERBOSE1(
137           "GateMP_start: can't find connection to daemon for pid %d\n",
138            getpid())
140         return -1;
141     }
143     cmd.cmd = LAD_GATEMP_START;
144     cmd.clientId = handle;
146     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
147         PRINTVERBOSE1(
148           "GateMP_start: sending LAD command failed, status=%d\n", status)
149         return -1;
150     }
152     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
153         PRINTVERBOSE1("GateMP_start: no LAD response, status=%d\n", status)
154         return -1;
155     }
157     status = rsp.gateMPStart.status;
159     PRINTVERBOSE2(
160       "GateMP_start: got LAD response for client %d, status=%d\n",
161       handle, status)
163     /*
164      * Initialize module state. Note that Nameserver handles are compatible
165      * across processes.
166      */
167     GateMP_module->nameServer = rsp.gateMPStart.nameServerHandle;
170     /* allocate memory for remote system gate handles */
171     if (status == GateMP_S_SUCCESS) {
172         GateMP_module->numRemoteSystem =
173             GateMP_getNumResources(GateMP_RemoteProtect_SYSTEM);
174         if (GateMP_module->numRemoteSystem > 0) {
175             GateMP_module->remoteSystemGates = calloc(1,
176                 GateMP_module->numRemoteSystem *
177                 sizeof(IGateProvider_Handle));
179             if (GateMP_module->remoteSystemGates == NULL) {
180                 status = GateMP_E_MEMORY;
181                 PRINTVERBOSE0("GateMP_start: memory allocation failed")
182             }
183         }
184         else {
185             GateMP_module->remoteSystemGates = NULL;
186         }
187     }
189     if (status == GateMP_S_SUCCESS) {
190         /* Open default gate */
191         status = GateMP_open("_GateMP_TI_dGate", &GateMP_module->defaultGate);
192         if (status < 0) {
193             PRINTVERBOSE1("GateMP_start: could not open default gate, \
194                 status=%d\n", status)
195         }
196     }
198     /* in failure case, release acquired resources in reverse order */
199     if (status < 0) {
200         GateMP_stop();
201     }
203     GateMP_module->isStarted = TRUE;
205     return status;
208 Int GateMP_stop(Void)
210     Int status = GateMP_S_SUCCESS;
212     PRINTVERBOSE0("GateMP_stop: entered\n")
214     /* close the default gate */
215     if (GateMP_module->defaultGate) {
216         GateMP_close(&GateMP_module->defaultGate);
217         GateMP_module->defaultGate = NULL;
218     }
220     /* free system gate array */
221     if (GateMP_module->remoteSystemGates != NULL) {
222         free(GateMP_module->remoteSystemGates);
223         GateMP_module->remoteSystemGates = NULL;
224     }
226     GateMP_module->isStarted = FALSE;
228     return status;
231 Void GateMP_Params_init(GateMP_Params *params)
233     if (params != NULL) {
234         memcpy(params, &GateMP_defInstParams, sizeof(GateMP_Params));
235     }
236     else {
237         PRINTVERBOSE0("GateMP_Params_init: Params argument cannot be NULL")
238     }
240     return;
243 GateMP_Handle GateMP_create(const GateMP_Params *params)
245     _GateMP_Params      _params;
246     GateMP_Handle       handle = NULL;
248     if (GateMP_module->isStarted == FALSE) {
249         PRINTVERBOSE0("GateMP_create: GateMP module has not been started!")
250     }
251     else {
252         memset(&_params, 0, sizeof(_GateMP_Params));
253         memcpy(&_params, params, sizeof(GateMP_Params));
255         handle = _GateMP_create(&_params);
256     }
258     return(handle);
261 static GateMP_Handle _GateMP_create(const _GateMP_Params *params)
263     GateMP_Handle       handle = NULL;
264     GateMP_Object *     obj = NULL;
265     Int                 status;
267     /* allocate the instance object */
268     obj = (GateMP_Object *)calloc(1, sizeof(GateMP_Object));
270     if (obj != NULL) {
271         status = GateMP_Instance_init(obj, params);
272         if (status < 0) {
273             free(obj);
274         }
275         else {
276             handle = (GateMP_Handle)obj;
277         }
278     }
279     else {
280         PRINTVERBOSE0("GateMP_create: Memory allocation failed")
281     }
283     return(handle);
286 Int GateMP_open(String name, GateMP_Handle *handle)
288     Int             status = GateMP_S_SUCCESS;
289     UInt32          len;
290     UInt32          nsValue[4];
291     GateMP_Object * obj = NULL;
292     UInt32          arg;
293     UInt32          mask;
294     UInt32          creatorProcId;
295     _GateMP_Params  params;
297     /* assert that a valid pointer has been supplied */
298     if (handle == NULL) {
299         PRINTVERBOSE0("GateMP_open: handle cannot be null")
300         status = GateMP_E_INVALIDARG;
301     }
303     if (status == GateMP_S_SUCCESS) {
304         len = sizeof(nsValue);
306         status = NameServer_get(GateMP_module->nameServer, name, &nsValue,
307             &len, NULL);
309         if (status < 0) {
310             *handle = NULL;
311             status = GateMP_E_NOTFOUND;
312         }
313         else {
314             arg = nsValue[2];
315             mask = nsValue[3];
316             creatorProcId = nsValue[1] >> 16;
317         }
318     }
320     if (status == GateMP_S_SUCCESS) {
321         /*
322          * The least significant bit of nsValue[1] == 0 means its a
323          * local (private) GateMP, otherwise its a remote (shared) GateMP.
324          */
325         if ((nsValue[1] & 0x1) == 0) {
326             if ((nsValue[1] >> 16) != MultiProc_self()) {
327                 /* error: trying to open another processor's private gate */
328                 *handle = NULL;
329                 PRINTVERBOSE0("GateMP_open: cannot open private gate from \
330                     another processor")
331                 status = GateMP_E_FAIL;
332             }
333             else if (nsValue[0] != getpid()) {
334                 /* error: trying to open another process's private gate */
335                 *handle = NULL;
336                 PRINTVERBOSE0("GateMP_open: cannot open private gate from \
337                     another process")
338                 status = GateMP_E_FAIL;
339             }
340         }
341     }
343     if (status == GateMP_S_SUCCESS) {
344         /* local gate */
345         if (GETREMOTE(mask) == GateMP_RemoteProtect_NONE) {
346             if (creatorProcId != MultiProc_self()) {
347                 status = GateMP_E_FAIL;
348             }
349             else {
350                 *handle = (GateMP_Handle)arg;
351                 obj = (GateMP_Object *)(*handle);
352                 pthread_mutex_lock(&GateMP_module->mutex);
353                 obj->numOpens++;
354                 pthread_mutex_unlock(&GateMP_module->mutex);
355             }
356         }
357         else {
358             /* remote case */
359             switch (GETREMOTE(mask)) {
360                 case GateMP_RemoteProtect_SYSTEM:
361                 case GateMP_RemoteProtect_CUSTOM1:
362                 case GateMP_RemoteProtect_CUSTOM2:
363                     obj = GateMP_module->remoteSystemGates[arg];
364                     break;
366                 default:
367                     status = GateMP_E_FAIL;
368                     PRINTVERBOSE0("GateMP_open: unsupported remote protection \
369                         type")
370                     break;
371             }
373             /*  If the object is NULL, then it must have been created
374              *  on a remote processor or in another process on the
375              *  local processor. Need to create a local object. This is
376              *  accomplished by setting the openFlag to TRUE.
377              */
378             if (status == GateMP_S_SUCCESS) {
379                 if (obj == NULL) {
380                     /* create a GateMP object with the openFlag set to true */
381                     params.name = NULL;
382                     params.openFlag = TRUE;
383                     params.sharedAddr = NULL;
384                     params.resourceId = arg;
385                     params.localProtect = GETLOCAL(mask);
386                     params.remoteProtect = GETREMOTE(mask);
388                     obj = (GateMP_Object *)_GateMP_create(&params);
390                     if (obj == NULL) {
391                         status = GateMP_E_FAIL;
392                     }
393                 }
394                 else {
395                     pthread_mutex_lock(&GateMP_module->mutex);
396                     obj->numOpens++;
397                     pthread_mutex_unlock(&GateMP_module->mutex);
398                 }
399             }
401             /* Return the "opened" GateMP instance  */
402             *handle = (GateMP_Handle)obj;
403         }
404     }
406     return status;
409 GateMP_Handle GateMP_getDefaultRemote()
411     return(GateMP_module->defaultGate);
414 GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
416     GateMP_Object *obj;
418     obj = (GateMP_Object *)handle;
419     return(obj->localProtect);
422 GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
424     GateMP_Object *obj;
426     obj = (GateMP_Object *)handle;
427     return (obj->remoteProtect);
430 static Int GateMP_getNumResources(GateMP_RemoteProtect type)
432     Int status;
433     LAD_ClientHandle handle;
434     struct LAD_CommandObj cmd;
435     union LAD_ResponseObj rsp;
437     handle = LAD_findHandle();
438     if (handle == LAD_MAXNUMCLIENTS) {
439         PRINTVERBOSE1(
440           "GateMP_getNumResources: can't find connection to daemon for pid %d\n",
441            getpid())
443         return -1;
444     }
446     cmd.cmd = LAD_GATEMP_GETNUMRESOURCES;
447     cmd.clientId = handle;
448     cmd.args.gateMPGetNumResources.type = type;
451     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
452         PRINTVERBOSE1(
453           "GateMP_getNumResources: sending LAD command failed, status=%d\n", status)
454         return -1;
455     }
457     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
458         PRINTVERBOSE1("GateMP_getNumResources: no LAD response, status=%d\n", status)
459         return -1;
460     }
462     status = rsp.gateMPGetNumResources.status;
464     PRINTVERBOSE2(
465       "GateMP_getNumResources: got LAD response for client %d, status=%d\n",
466       handle, status)
469     return (rsp.gateMPGetNumResources.value);
472 static Int GateMP_getFreeResource(GateMP_RemoteProtect type)
474     Int status;
475     LAD_ClientHandle handle;
476     struct LAD_CommandObj cmd;
477     union LAD_ResponseObj rsp;
479     handle = LAD_findHandle();
480     if (handle == LAD_MAXNUMCLIENTS) {
481         PRINTVERBOSE1(
482           "GateMP_getFreeResource: can't find connection to daemon for pid %d\n",
483            getpid())
485         return -1;
486     }
488     cmd.cmd = LAD_GATEMP_GETFREERESOURCE;
489     cmd.clientId = handle;
490     cmd.args.gateMPGetFreeResource.type = type;
492     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
493         PRINTVERBOSE1(
494           "GateMP_getFreeResource: sending LAD command failed, status=%d\n", status)
495         return -1;
496     }
498     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
499         PRINTVERBOSE1("GateMP_getFreeResource: no LAD response, status=%d\n", status)
500         return -1;
501     }
503     status = rsp.gateMPGetFreeResource.status;
505     PRINTVERBOSE2(
506       "GateMP_getNumResources: got LAD response for client %d, status=%d\n",
507       handle, status)
509     return (rsp.gateMPGetFreeResource.id);
512 static Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type)
514     Int status;
515     LAD_ClientHandle handle;
516     struct LAD_CommandObj cmd;
517     union LAD_ResponseObj rsp;
519     handle = LAD_findHandle();
520     if (handle == LAD_MAXNUMCLIENTS) {
521         PRINTVERBOSE1(
522           "GateMP_releaseResource: can't find connection to daemon for pid %d\n",
523            getpid())
525         return -1;
526     }
528     cmd.cmd = LAD_GATEMP_RELEASERESOURCE;
529     cmd.clientId = handle;
530     cmd.args.gateMPReleaseResource.type = type;
531     cmd.args.gateMPReleaseResource.id   = id;
533     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
534         PRINTVERBOSE1(
535           "GateMP_releaseResource: sending LAD command failed, status=%d\n", status)
536         return -1;
537     }
539     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
540         PRINTVERBOSE1("GateMP_releaseResource: no LAD response, status=%d\n", status)
541         return -1;
542     }
544     status = rsp.gateMPReleaseResource.status;
546     PRINTVERBOSE2(
547       "GateMP_releaseResource: got LAD response for client %d, status=%d\n",
548       handle, status)
550     return (status);
553 Bool GateMP_isSetup(Void)
555     Int status;
556     LAD_ClientHandle handle;
557     struct LAD_CommandObj cmd;
558     union LAD_ResponseObj rsp;
560     handle = LAD_findHandle();
561     if (handle == LAD_MAXNUMCLIENTS) {
562         PRINTVERBOSE1(
563           "GateMP_isSetup: can't find connection to daemon for pid %d\n",
564            getpid())
566         return -1;
567     }
569     cmd.cmd = LAD_GATEMP_ISSETUP;
570     cmd.clientId = handle;
571     cmd.args.gateMPIsSetup.result = FALSE;
573     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
574         PRINTVERBOSE1(
575           "GateMP_isSetup: sending LAD command failed, status=%d\n", status)
576         return -1 ;
577     }
579     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
580         PRINTVERBOSE1("GateMP_isSetup: no LAD response, status=%d\n", status)
581         return -1;
582     }
584     status = rsp.gateMPIsSetup.status;
586     PRINTVERBOSE2(
587       "GateMP_isSetup: got LAD response for client %d, status=%d\n",
588       handle, status)
590     assert(status == GateMP_S_SUCCESS);
592     return (rsp.gateMPIsSetup.result);
595 Int GateMP_close(GateMP_Handle *handle)
597     GateMP_Object * obj;
598     Int             status = GateMP_S_SUCCESS;
600     obj = (GateMP_Object *)(*handle);
602     pthread_mutex_lock(&GateMP_module->mutex);
604     /*  Cannot call with the numOpens equal to zero.  This is either
605      *  a created handle or been closed already.
606      */
607     if (obj->numOpens == 0) {
608         status = GateMP_E_INVALIDSTATE;
609     }
611     if (status == GateMP_S_SUCCESS) {
612         obj->numOpens--;
614         /*  If the count is zero and the gate is opened, then this
615          *  object was created in the open (i.e. the create happened
616          *  on a remote processor or another process).
617          */
618         if ((obj->numOpens == 0) && (obj->objType == Ipc_ObjType_OPENDYNAMIC)) {
619             GateMP_delete(handle);
620         }
621         else {
622             *handle = NULL;
623         }
624     }
626     pthread_mutex_unlock(&GateMP_module->mutex);
628     return(status);
631 Int GateMP_delete(GateMP_Handle *handlePtr)
633     Int               status = GateMP_S_SUCCESS;
635     if ((handlePtr == NULL) || (*handlePtr == NULL)) {
636         status =  GateMP_E_INVALIDARG;
637     }
638     else {
639         GateMP_Instance_finalize((GateMP_Object *)(*handlePtr), 0);
640         free(*handlePtr);
641         *handlePtr = NULL;
642     }
644     return status;
647 static Int GateMP_Instance_init(GateMP_Object *obj,
648     const _GateMP_Params *params)
650     GateMP_RemoteSystemProxy_Params     systemParams;
651     UInt32                              nsValue[4];
653     obj->resourceId = (UInt)-1;
655     /* TODO: create/open the local gate instance */
656     obj->localGate = NULL;
658     /* open GateMP instance */
659     if (params->openFlag == TRUE) {
660         /* all open work done here except for remote gateHandle */
661         obj->localProtect  = params->localProtect;
662         obj->remoteProtect = params->remoteProtect;
663         obj->nsKey         = 0;
664         obj->numOpens      = 1;
666         obj->objType       = Ipc_ObjType_OPENDYNAMIC;
667     }
669     /* create GateMP instance */
670     else {
671         obj->localProtect  = params->localProtect;
672         obj->remoteProtect = params->remoteProtect;
673         obj->nsKey         = 0;
674         obj->numOpens      = 0;
676         if (obj->remoteProtect == GateMP_RemoteProtect_NONE) {
677             /* TODO: create a local gate */
678             obj->gateHandle = obj->localGate;
680             /* create a local gate allocating from the local heap */
681             obj->objType = Ipc_ObjType_LOCAL;
682             obj->arg = (Bits32)obj;
683             obj->mask = SETMASK(obj->remoteProtect, obj->localProtect);
684             obj->creatorProcId = MultiProc_self();
686             if (params->name != NULL) {
687                 /*  nsv[0]       : creator process id
688                  *  nsv[1](31:16): creator procId
689                  *  nsv[1](15:0) : 0 = local gate, 1 = remote gate
690                  *  nsv[2]       : local gate object
691                  *  nsv[3]       : protection mask
692                  */
693                 nsValue[0] = getpid();
694                 nsValue[1] = MultiProc_self() << 16;
695                 nsValue[2] = obj->arg;
696                 nsValue[3] = obj->mask;
697                 obj->nsKey = NameServer_add(GateMP_module->nameServer,
698                         params->name, &nsValue, sizeof(nsValue));
699                 if (obj->nsKey == NULL) {
700                     PRINTVERBOSE0("GateMP_Instance_init: NameServer_add failed")
701                     return (GateMP_E_FAIL);
702                 }
703             }
705             /* nothing else to do for local gates */
706             return(0);
707         }
709         obj->objType = Ipc_ObjType_CREATEDYNAMIC;
710     }
712     /* proxy work for open and create done here */
713     switch (obj->remoteProtect) {
714         /* TODO: implement other types of remote protection */
715         case GateMP_RemoteProtect_SYSTEM:
716         case GateMP_RemoteProtect_CUSTOM1:
717         case GateMP_RemoteProtect_CUSTOM2:
718             if (obj->objType == Ipc_ObjType_OPENDYNAMIC) {
719                 /* resourceId set by open call */
720                 obj->resourceId = params->resourceId;
721             }
722             else {
723                 /* created instance */
724                 obj->resourceId = GateMP_getFreeResource(obj->remoteProtect);
725                 if (obj->resourceId == -1) {
726                     return (GateMP_E_RESOURCE);
727                 }
728             }
730             /* create the proxy object */
731             GateMP_RemoteSystemProxy_Params_init(&systemParams);
732             systemParams.resourceId = obj->resourceId;
733             systemParams.openFlag = (obj->objType == Ipc_ObjType_OPENDYNAMIC);
734             //systemParams.sharedAddr = obj->proxyAttrs;
736             /*
737              * TODO: Currently passing in localProtect instead of localGate,
738              * since existing GateHWSpinlock.h defines it this way
739              */
740             obj->gateHandle = (IGateProvider_Handle)
741                 GateMP_RemoteSystemProxy_create(obj->localProtect,
742                     &systemParams);
744             if (obj->gateHandle == NULL) {
745                 PRINTVERBOSE0("GateMP_Instance_init: failed to create proxy\n");
746                 return(GateMP_E_FAIL);
747             }
749             /* store the object handle in the gate array */
750             GateMP_module->remoteSystemGates[obj->resourceId] = obj;
751             break;
753         default:
754             break;
755     }
757     /* add name/attrs to NameServer table */
758     if (obj->objType != Ipc_ObjType_OPENDYNAMIC) {
759         obj->arg = obj->resourceId;
760         obj->mask = SETMASK(obj->remoteProtect, obj->localProtect);
762         if (params->name != NULL) {
763             /*  nsv[0]       : creator pid
764              *  nsv[1](31:16): creator procId
765              *  nsv[1](15:0) : 0 = local gate, 1 = remote gate
766              *  nsv[2]       : resource id
767              *  nsv[3]       : protection mask
768              */
769             nsValue[0] = getpid();
770             nsValue[1] = MultiProc_self() << 16 | 1;
771             nsValue[2] = obj->resourceId;
772             nsValue[3] = obj->mask;
773             obj->nsKey = NameServer_add(GateMP_module->nameServer,
774                     params->name, &nsValue, sizeof(nsValue));
776             if (obj->nsKey == NULL) {
777                 PRINTVERBOSE0("GateMP_Instance_init: NameServer_add failed")
778                 return (GateMP_E_FAIL);
779             }
780         }
781     }
783     return (GateMP_S_SUCCESS);
786 static Void GateMP_Instance_finalize(GateMP_Object *obj, Int status)
788     GateMP_Object ** remoteGates = NULL;
790     /* remove from NameServer */
791     if (obj->nsKey != 0) {
792         NameServer_removeEntry(GateMP_module->nameServer, obj->nsKey);
793         obj->nsKey = 0;
794     }
796     /* delete the remote gate */
797     switch (obj->remoteProtect) {
799         case GateMP_RemoteProtect_SYSTEM:
800         case GateMP_RemoteProtect_CUSTOM1:
801         case GateMP_RemoteProtect_CUSTOM2:
802             if (obj->gateHandle != NULL) {
803                 GateMP_RemoteSystemProxy_delete(
804                         (GateMP_RemoteSystemProxy_Handle *)&obj->gateHandle);
805             }
806             remoteGates = GateMP_module->remoteSystemGates;
807             break;
809         case GateMP_RemoteProtect_NONE:
810             /*  nothing else to finalize */
811             return;
813         default:
814             /* Nothing to do */
815             break;
816     }
818     /* TODO: close/delete local gate */
820     /* clear the handle array entry in local memory */
821     if (obj->resourceId != (UInt)-1) {
822         remoteGates[obj->resourceId] = NULL;
823     }
825     if ((obj->objType != Ipc_ObjType_OPENDYNAMIC)
826         && (obj->resourceId != (UInt)-1)) {
827         GateMP_releaseResource(obj->resourceId, obj->remoteProtect);
828     }
832 IArg GateMP_enter(GateMP_Handle handle)
834     GateMP_Object * obj;
835     IArg            key;
837     obj = (GateMP_Object *)handle;
838     key = IGateProvider_enter(obj->gateHandle);
840     return(key);
843 Void GateMP_leave(GateMP_Handle handle, IArg key)
845     GateMP_Object *obj;
847     obj = (GateMP_Object *)handle;
848     IGateProvider_leave(obj->gateHandle, key);