Linux: Added GateMP support for DRA7XX devices
[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;
80 static Bool verbose = FALSE;
82 /* Internal structure defining parameters for GateMP_Instance_init */
83 typedef struct {
84     String name;                        /* Name of instance */
85     UInt16 regionId;                    /* not used on host*/
86     Ptr sharedAddr;                     /* not used on host*/
87     GateMP_LocalProtect localProtect;   /* Local protection level  */
88     GateMP_RemoteProtect remoteProtect; /* Remote protection level */
89     UInt32 resourceId;                  /* resource id */
90     Bool openFlag;                      /* Is this open or create? */
91 } _GateMP_Params;
93 static Int GateMP_getNumResources(GateMP_RemoteProtect type);
94 static Int GateMP_getFreeResource(GateMP_RemoteProtect type);
95 static Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type);
96 static GateMP_Handle _GateMP_create (const _GateMP_Params * params);
97 static Int GateMP_Instance_init(GateMP_Object *obj,
98     const _GateMP_Params *params);
99 static Void GateMP_Instance_finalize(GateMP_Object *obj, Int status);
101 /* -----------------------------------------------------------------------------
102  * Globals
103  * -----------------------------------------------------------------------------
104  */
105 static GateMP_ModuleObject GateMP_state =
107     .remoteSystemGates  = NULL,
108     .defaultGate        = NULL,
109     .nameServer         = NULL,
110     .mutex              = PTHREAD_MUTEX_INITIALIZER,
111 //    .gateMutex          = NULL,
112 //    .gateProcess        = NULL
113 };
115 static GateMP_ModuleObject *GateMP_module = &GateMP_state;
117 static GateMP_Params GateMP_defInstParams =
119     .name           = NULL,
120     .regionId       = 0,
121     .sharedAddr     = NULL,
122     .localProtect   = GateMP_LocalProtect_PROCESS,
123     .remoteProtect  = GateMP_RemoteProtect_SYSTEM
124 };
126 Int GateMP_start(Void)
128     Int status;
129     LAD_ClientHandle handle;
130     struct LAD_CommandObj cmd;
131     union LAD_ResponseObj rsp;
133     handle = LAD_findHandle();
134     if (handle == LAD_MAXNUMCLIENTS) {
135         PRINTVERBOSE1(
136           "GateMP_start: can't find connection to daemon for pid %d\n",
137            getpid())
139         return -1;
140     }
142     cmd.cmd = LAD_GATEMP_START;
143     cmd.clientId = handle;
145     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
146         PRINTVERBOSE1(
147           "GateMP_start: sending LAD command failed, status=%d\n", status)
148         return -1;
149     }
151     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
152         PRINTVERBOSE1("GateMP_start: no LAD response, status=%d\n", status)
153         return -1;
154     }
156     status = rsp.gateMPStart.status;
158     PRINTVERBOSE2(
159       "GateMP_start: got LAD response for client %d, status=%d\n",
160       handle, status)
162     /*
163      * Initialize module state. Note that Nameserver handles are compatible
164      * across processes.
165      */
166     GateMP_module->nameServer = rsp.gateMPStart.nameServerHandle;
169     /* allocate memory for remote system gate handles */
170     if (status == GateMP_S_SUCCESS) {
171         GateMP_module->numRemoteSystem =
172             GateMP_getNumResources(GateMP_RemoteProtect_SYSTEM);
173         if (GateMP_module->numRemoteSystem > 0) {
174             GateMP_module->remoteSystemGates = calloc(1,
175                 GateMP_module->numRemoteSystem *
176                 sizeof(IGateProvider_Handle));
178             if (GateMP_module->remoteSystemGates == NULL) {
179                 status = GateMP_E_MEMORY;
180                 PRINTVERBOSE0("GateMP_start: memory allocation failed")
181             }
182         }
183         else {
184             GateMP_module->remoteSystemGates = NULL;
185         }
186     }
188     if (status == GateMP_S_SUCCESS) {
189         /* Open default gate */
190         status = GateMP_open("_GateMP_TI_dGate", &GateMP_module->defaultGate);
191         if (status < 0) {
192             PRINTVERBOSE1("GateMP_start: could not open default gate, \
193                 status=%d\n", status)
194         }
195     }
197     /* in failure case, release acquired resources in reverse order */
198     if (status < 0) {
199         GateMP_stop();
200     }
202     GateMP_module->isStarted = TRUE;
204     return status;
207 Int GateMP_stop(Void)
209     Int status = GateMP_S_SUCCESS;
211     PRINTVERBOSE0("GateMP_stop: entered\n")
213     /* close the default gate */
214     if (GateMP_module->defaultGate) {
215         GateMP_close(&GateMP_module->defaultGate);
216         GateMP_module->defaultGate = NULL;
217     }
219     /* free system gate array */
220     if (GateMP_module->remoteSystemGates != NULL) {
221         free(GateMP_module->remoteSystemGates);
222         GateMP_module->remoteSystemGates = NULL;
223     }
225     GateMP_module->isStarted = FALSE;
227     return status;
230 Void GateMP_Params_init(GateMP_Params *params)
232     if (params != NULL) {
233         memcpy(params, &GateMP_defInstParams, sizeof(GateMP_Params));
234     }
235     else {
236         PRINTVERBOSE0("GateMP_Params_init: Params argument cannot be NULL")
237     }
239     return;
242 GateMP_Handle GateMP_create(const GateMP_Params *params)
244     _GateMP_Params      _params;
245     GateMP_Handle       handle = NULL;
247     if (GateMP_module->isStarted == FALSE) {
248         PRINTVERBOSE0("GateMP_create: GateMP module has not been started!")
249     }
250     else {
251         memset(&_params, 0, sizeof(_GateMP_Params));
252         memcpy(&_params, params, sizeof(GateMP_Params));
254         handle = _GateMP_create(&_params);
255     }
257     return(handle);
260 static GateMP_Handle _GateMP_create(const _GateMP_Params *params)
262     GateMP_Handle       handle = NULL;
263     GateMP_Object *     obj = NULL;
264     Int                 status;
266     /* allocate the instance object */
267     obj = (GateMP_Object *)calloc(1, sizeof(GateMP_Object));
269     if (obj != NULL) {
270         status = GateMP_Instance_init(obj, params);
271         if (status < 0) {
272             free(obj);
273         }
274         else {
275             handle = (GateMP_Handle)obj;
276         }
277     }
278     else {
279         PRINTVERBOSE0("GateMP_create: Memory allocation failed")
280     }
282     return(handle);
285 Int GateMP_open(String name, GateMP_Handle *handle)
287     Int             status = GateMP_S_SUCCESS;
288     UInt32          len;
289     UInt32          nsValue[4];
290     GateMP_Object * obj = NULL;
291     UInt32          arg;
292     UInt32          mask;
293     UInt32          creatorProcId;
294     _GateMP_Params  params;
296     /* assert that a valid pointer has been supplied */
297     if (handle == NULL) {
298         PRINTVERBOSE0("GateMP_open: handle cannot be null")
299         status = GateMP_E_INVALIDARG;
300     }
302     if (status == GateMP_S_SUCCESS) {
303         len = sizeof(nsValue);
305         status = NameServer_get(GateMP_module->nameServer, name, &nsValue,
306             &len, NULL);
308         if (status < 0) {
309             *handle = NULL;
310             status = GateMP_E_NOTFOUND;
311         }
312         else {
313             arg = nsValue[2];
314             mask = nsValue[3];
315             creatorProcId = nsValue[1] >> 16;
316         }
317     }
319     if (status == GateMP_S_SUCCESS) {
320         /*
321          * The least significant bit of nsValue[1] == 0 means its a
322          * local (private) GateMP, otherwise its a remote (shared) GateMP.
323          */
324         if ((nsValue[1] & 0x1) == 0) {
325             if ((nsValue[1] >> 16) != MultiProc_self()) {
326                 /* error: trying to open another processor's private gate */
327                 *handle = NULL;
328                 PRINTVERBOSE0("GateMP_open: cannot open private gate from \
329                     another processor")
330                 status = GateMP_E_FAIL;
331             }
332             else if (nsValue[0] != getpid()) {
333                 /* error: trying to open another process's private gate */
334                 *handle = NULL;
335                 PRINTVERBOSE0("GateMP_open: cannot open private gate from \
336                     another process")
337                 status = GateMP_E_FAIL;
338             }
339         }
340     }
342     if (status == GateMP_S_SUCCESS) {
343         /* local gate */
344         if (GETREMOTE(mask) == GateMP_RemoteProtect_NONE) {
345             if (creatorProcId != MultiProc_self()) {
346                 status = GateMP_E_FAIL;
347             }
348             else {
349                 *handle = (GateMP_Handle)arg;
350                 obj = (GateMP_Object *)(*handle);
351                 pthread_mutex_lock(&GateMP_module->mutex);
352                 obj->numOpens++;
353                 pthread_mutex_unlock(&GateMP_module->mutex);
354             }
355         }
356         else {
357             /* remote case */
358             switch (GETREMOTE(mask)) {
359                 case GateMP_RemoteProtect_SYSTEM:
360                 case GateMP_RemoteProtect_CUSTOM1:
361                 case GateMP_RemoteProtect_CUSTOM2:
362                     obj = GateMP_module->remoteSystemGates[arg];
363                     break;
365                 default:
366                     status = GateMP_E_FAIL;
367                     PRINTVERBOSE0("GateMP_open: unsupported remote protection \
368                         type")
369                     break;
370             }
372             /*  If the object is NULL, then it must have been created
373              *  on a remote processor or in another process on the
374              *  local processor. Need to create a local object. This is
375              *  accomplished by setting the openFlag to TRUE.
376              */
377             if (status == GateMP_S_SUCCESS) {
378                 if (obj == NULL) {
379                     /* create a GateMP object with the openFlag set to true */
380                     params.name = NULL;
381                     params.openFlag = TRUE;
382                     params.sharedAddr = NULL;
383                     params.resourceId = arg;
384                     params.localProtect = GETLOCAL(mask);
385                     params.remoteProtect = GETREMOTE(mask);
387                     obj = (GateMP_Object *)_GateMP_create(&params);
389                     if (obj == NULL) {
390                         status = GateMP_E_FAIL;
391                     }
392                 }
393                 else {
394                     pthread_mutex_lock(&GateMP_module->mutex);
395                     obj->numOpens++;
396                     pthread_mutex_unlock(&GateMP_module->mutex);
397                 }
398             }
400             /* Return the "opened" GateMP instance  */
401             *handle = (GateMP_Handle)obj;
402         }
403     }
405     return status;
408 GateMP_Handle GateMP_getDefaultRemote()
410     return(GateMP_module->defaultGate);
413 GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
415     GateMP_Object *obj;
417     obj = (GateMP_Object *)handle;
418     return(obj->localProtect);
421 GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
423     GateMP_Object *obj;
425     obj = (GateMP_Object *)handle;
426     return (obj->remoteProtect);
429 static Int GateMP_getNumResources(GateMP_RemoteProtect type)
431     Int status;
432     LAD_ClientHandle handle;
433     struct LAD_CommandObj cmd;
434     union LAD_ResponseObj rsp;
436     handle = LAD_findHandle();
437     if (handle == LAD_MAXNUMCLIENTS) {
438         PRINTVERBOSE1(
439           "GateMP_getNumResources: can't find connection to daemon for pid %d\n",
440            getpid())
442         return -1;
443     }
445     cmd.cmd = LAD_GATEMP_GETNUMRESOURCES;
446     cmd.clientId = handle;
447     cmd.args.gateMPGetNumResources.type = type;
450     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
451         PRINTVERBOSE1(
452           "GateMP_getNumResources: sending LAD command failed, status=%d\n", status)
453         return -1;
454     }
456     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
457         PRINTVERBOSE1("GateMP_getNumResources: no LAD response, status=%d\n", status)
458         return -1;
459     }
461     status = rsp.gateMPGetNumResources.status;
463     PRINTVERBOSE2(
464       "GateMP_getNumResources: got LAD response for client %d, status=%d\n",
465       handle, status)
468     return (rsp.gateMPGetNumResources.value);
471 static Int GateMP_getFreeResource(GateMP_RemoteProtect type)
473     Int status;
474     LAD_ClientHandle handle;
475     struct LAD_CommandObj cmd;
476     union LAD_ResponseObj rsp;
478     handle = LAD_findHandle();
479     if (handle == LAD_MAXNUMCLIENTS) {
480         PRINTVERBOSE1(
481           "GateMP_getFreeResource: can't find connection to daemon for pid %d\n",
482            getpid())
484         return -1;
485     }
487     cmd.cmd = LAD_GATEMP_GETFREERESOURCE;
488     cmd.clientId = handle;
489     cmd.args.gateMPGetFreeResource.type = type;
491     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
492         PRINTVERBOSE1(
493           "GateMP_getFreeResource: sending LAD command failed, status=%d\n", status)
494         return -1;
495     }
497     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
498         PRINTVERBOSE1("GateMP_getFreeResource: no LAD response, status=%d\n", status)
499         return -1;
500     }
502     status = rsp.gateMPGetFreeResource.status;
504     PRINTVERBOSE2(
505       "GateMP_getNumResources: got LAD response for client %d, status=%d\n",
506       handle, status)
508     return (rsp.gateMPGetFreeResource.id);
511 static Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type)
513     Int status;
514     LAD_ClientHandle handle;
515     struct LAD_CommandObj cmd;
516     union LAD_ResponseObj rsp;
518     handle = LAD_findHandle();
519     if (handle == LAD_MAXNUMCLIENTS) {
520         PRINTVERBOSE1(
521           "GateMP_releaseResource: can't find connection to daemon for pid %d\n",
522            getpid())
524         return -1;
525     }
527     cmd.cmd = LAD_GATEMP_RELEASERESOURCE;
528     cmd.clientId = handle;
529     cmd.args.gateMPReleaseResource.type = type;
530     cmd.args.gateMPReleaseResource.id   = id;
532     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
533         PRINTVERBOSE1(
534           "GateMP_releaseResource: sending LAD command failed, status=%d\n", status)
535         return -1;
536     }
538     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
539         PRINTVERBOSE1("GateMP_releaseResource: no LAD response, status=%d\n", status)
540         return -1;
541     }
543     status = rsp.gateMPReleaseResource.status;
545     PRINTVERBOSE2(
546       "GateMP_releaseResource: got LAD response for client %d, status=%d\n",
547       handle, status)
549     return (status);
552 Bool GateMP_isSetup(Void)
554     Int status;
555     LAD_ClientHandle handle;
556     struct LAD_CommandObj cmd;
557     union LAD_ResponseObj rsp;
559     handle = LAD_findHandle();
560     if (handle == LAD_MAXNUMCLIENTS) {
561         PRINTVERBOSE1(
562           "GateMP_isSetup: can't find connection to daemon for pid %d\n",
563            getpid())
565         return -1;
566     }
568     cmd.cmd = LAD_GATEMP_ISSETUP;
569     cmd.clientId = handle;
570     cmd.args.gateMPIsSetup.result = FALSE;
572     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
573         PRINTVERBOSE1(
574           "GateMP_isSetup: sending LAD command failed, status=%d\n", status)
575         return -1 ;
576     }
578     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
579         PRINTVERBOSE1("GateMP_isSetup: no LAD response, status=%d\n", status)
580         return -1;
581     }
583     status = rsp.gateMPIsSetup.status;
585     PRINTVERBOSE2(
586       "GateMP_isSetup: got LAD response for client %d, status=%d\n",
587       handle, status)
589     assert(status == GateMP_S_SUCCESS);
591     return (rsp.gateMPIsSetup.result);
594 Int GateMP_close(GateMP_Handle *handle)
596     GateMP_Object * obj;
597     Int             status = GateMP_S_SUCCESS;
599     obj = (GateMP_Object *)(*handle);
601     pthread_mutex_lock(&GateMP_module->mutex);
603     /*  Cannot call with the numOpens equal to zero.  This is either
604      *  a created handle or been closed already.
605      */
606     if (obj->numOpens == 0) {
607         status = GateMP_E_INVALIDSTATE;
608     }
610     if (status == GateMP_S_SUCCESS) {
611         obj->numOpens--;
613         /*  If the count is zero and the gate is opened, then this
614          *  object was created in the open (i.e. the create happened
615          *  on a remote processor or another process).
616          */
617         if ((obj->numOpens == 0) && (obj->objType == Ipc_ObjType_OPENDYNAMIC)) {
618             GateMP_delete(handle);
619         }
620         else {
621             *handle = NULL;
622         }
623     }
625     pthread_mutex_unlock(&GateMP_module->mutex);
627     return(status);
630 Int GateMP_delete(GateMP_Handle *handlePtr)
632     Int               status = GateMP_S_SUCCESS;
634     if ((handlePtr == NULL) || (*handlePtr == NULL)) {
635         status =  GateMP_E_INVALIDARG;
636     }
637     else {
638         GateMP_Instance_finalize((GateMP_Object *)(*handlePtr), 0);
639         free(*handlePtr);
640         *handlePtr = NULL;
641     }
643     return status;
646 static Int GateMP_Instance_init(GateMP_Object *obj,
647     const _GateMP_Params *params)
649     GateMP_RemoteSystemProxy_Params     systemParams;
650     UInt32                              nsValue[4];
652     obj->resourceId = (UInt)-1;
654     /* TODO: create/open the local gate instance */
655     obj->localGate = NULL;
657     /* open GateMP instance */
658     if (params->openFlag == TRUE) {
659         /* all open work done here except for remote gateHandle */
660         obj->localProtect  = params->localProtect;
661         obj->remoteProtect = params->remoteProtect;
662         obj->nsKey         = 0;
663         obj->numOpens      = 1;
665         obj->objType       = Ipc_ObjType_OPENDYNAMIC;
666     }
668     /* create GateMP instance */
669     else {
670         obj->localProtect  = params->localProtect;
671         obj->remoteProtect = params->remoteProtect;
672         obj->nsKey         = 0;
673         obj->numOpens      = 0;
675         if (obj->remoteProtect == GateMP_RemoteProtect_NONE) {
676             /* TODO: create a local gate */
677             obj->gateHandle = obj->localGate;
679             /* create a local gate allocating from the local heap */
680             obj->objType = Ipc_ObjType_LOCAL;
681             obj->arg = (Bits32)obj;
682             obj->mask = SETMASK(obj->remoteProtect, obj->localProtect);
683             obj->creatorProcId = MultiProc_self();
685             if (params->name != NULL) {
686                 /*  nsv[0]       : creator process id
687                  *  nsv[1](31:16): creator procId
688                  *  nsv[1](15:0) : 0 = local gate, 1 = remote gate
689                  *  nsv[2]       : local gate object
690                  *  nsv[3]       : protection mask
691                  */
692                 nsValue[0] = getpid();
693                 nsValue[1] = MultiProc_self() << 16;
694                 nsValue[2] = obj->arg;
695                 nsValue[3] = obj->mask;
696                 obj->nsKey = NameServer_add(GateMP_module->nameServer,
697                         params->name, &nsValue, sizeof(nsValue));
698                 if (obj->nsKey == NULL) {
699                     PRINTVERBOSE0("GateMP_Instance_init: NameServer_add failed")
700                     return (GateMP_E_FAIL);
701                 }
702             }
704             /* nothing else to do for local gates */
705             return(0);
706         }
708         obj->objType = Ipc_ObjType_CREATEDYNAMIC;
709     }
711     /* proxy work for open and create done here */
712     switch (obj->remoteProtect) {
713         /* TODO: implement other types of remote protection */
714         case GateMP_RemoteProtect_SYSTEM:
715         case GateMP_RemoteProtect_CUSTOM1:
716         case GateMP_RemoteProtect_CUSTOM2:
717             if (obj->objType == Ipc_ObjType_OPENDYNAMIC) {
718                 /* resourceId set by open call */
719                 obj->resourceId = params->resourceId;
720             }
721             else {
722                 /* created instance */
723                 obj->resourceId = GateMP_getFreeResource(obj->remoteProtect);
724                 if (obj->resourceId == -1) {
725                     return (GateMP_E_RESOURCE);
726                 }
727             }
729             /* create the proxy object */
730             GateMP_RemoteSystemProxy_Params_init(&systemParams);
731             systemParams.resourceId = obj->resourceId;
732             systemParams.openFlag = (obj->objType == Ipc_ObjType_OPENDYNAMIC);
733             //systemParams.sharedAddr = obj->proxyAttrs;
735             /*
736              * TODO: Currently passing in localProtect instead of localGate,
737              * since existing GateHWSpinlock.h defines it this way
738              */
739             obj->gateHandle = (IGateProvider_Handle)
740                 GateMP_RemoteSystemProxy_create(obj->localProtect,
741                     &systemParams);
743             if (obj->gateHandle == NULL) {
744                 PRINTVERBOSE0("GateMP_Instance_init: failed to create proxy\n");
745                 return(GateMP_E_FAIL);
746             }
748             /* store the object handle in the gate array */
749             GateMP_module->remoteSystemGates[obj->resourceId] = obj;
750             break;
752         default:
753             break;
754     }
756     /* add name/attrs to NameServer table */
757     if (obj->objType != Ipc_ObjType_OPENDYNAMIC) {
758         obj->arg = obj->resourceId;
759         obj->mask = SETMASK(obj->remoteProtect, obj->localProtect);
761         if (params->name != NULL) {
762             /*  nsv[0]       : creator pid
763              *  nsv[1](31:16): creator procId
764              *  nsv[1](15:0) : 0 = local gate, 1 = remote gate
765              *  nsv[2]       : resource id
766              *  nsv[3]       : protection mask
767              */
768             nsValue[0] = getpid();
769             nsValue[1] = MultiProc_self() << 16 | 1;
770             nsValue[2] = obj->resourceId;
771             nsValue[3] = obj->mask;
772             obj->nsKey = NameServer_add(GateMP_module->nameServer,
773                     params->name, &nsValue, sizeof(nsValue));
775             if (obj->nsKey == NULL) {
776                 PRINTVERBOSE0("GateMP_Instance_init: NameServer_add failed")
777                 return (GateMP_E_FAIL);
778             }
779         }
780     }
782     return (GateMP_S_SUCCESS);
785 static Void GateMP_Instance_finalize(GateMP_Object *obj, Int status)
787     GateMP_Object ** remoteGates = NULL;
789     /* remove from NameServer */
790     if (obj->nsKey != 0) {
791         NameServer_removeEntry(GateMP_module->nameServer, obj->nsKey);
792         obj->nsKey = 0;
793     }
795     /* delete the remote gate */
796     switch (obj->remoteProtect) {
798         case GateMP_RemoteProtect_SYSTEM:
799         case GateMP_RemoteProtect_CUSTOM1:
800         case GateMP_RemoteProtect_CUSTOM2:
801             if (obj->gateHandle != NULL) {
802                 GateMP_RemoteSystemProxy_delete(
803                         (GateMP_RemoteSystemProxy_Handle *)&obj->gateHandle);
804             }
805             remoteGates = GateMP_module->remoteSystemGates;
806             break;
808         case GateMP_RemoteProtect_NONE:
809             /*  nothing else to finalize */
810             return;
812         default:
813             /* Nothing to do */
814             break;
815     }
817     /* TODO: close/delete local gate */
819     /* clear the handle array entry in local memory */
820     if (obj->resourceId != (UInt)-1) {
821         remoteGates[obj->resourceId] = NULL;
822     }
824     if ((obj->objType != Ipc_ObjType_OPENDYNAMIC)
825         && (obj->resourceId != (UInt)-1)) {
826         GateMP_releaseResource(obj->resourceId, obj->remoteProtect);
827     }
831 IArg GateMP_enter(GateMP_Handle handle)
833     GateMP_Object * obj;
834     IArg            key;
836     obj = (GateMP_Object *)handle;
837     key = IGateProvider_enter(obj->gateHandle);
839     return(key);
842 Void GateMP_leave(GateMP_Handle handle, IArg key)
844     GateMP_Object *obj;
846     obj = (GateMP_Object *)handle;
847     IGateProvider_leave(obj->gateHandle, key);