Linux: GateMP: Check for Proper NameServer Value Length
[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 /*
128  *  ======== GateMP_attach ========
129  *  Internal function.
130  */
131 Int GateMP_attach(UInt16 procId)
133     Int status;
134     LAD_ClientHandle clHandle;
135     struct LAD_CommandObj cmd;
136     union LAD_ResponseObj rsp;
138     clHandle = LAD_findHandle();
140     if (clHandle == LAD_MAXNUMCLIENTS) {
141         PRINTVERBOSE0("GateMP_attach: not connected to LAD\n");
142         return (GateMP_E_RESOURCE);
143     }
145     cmd.cmd = LAD_GATEMP_ATTACH;
146     cmd.clientId = clHandle;
147     cmd.args.attach.procId = procId;
149     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
150         PRINTVERBOSE1("GateMP_attach: sending LAD command failed, "
151                 "status=%d\n", status);
152         return (GateMP_E_FAIL);
153     }
155     if ((status = LAD_getResponse(clHandle, &rsp)) != LAD_SUCCESS) {
156         PRINTVERBOSE1("GateMP_attach: no LAD response, status=%d\n",
157                 status);
158         return (GateMP_E_FAIL);
159     }
161     status = rsp.status;
162     PRINTVERBOSE1("GateMP_attach: LAD response, status=%d\n", status)
164     return (status);
167 /*
168  *  ======== GateMP_detach ========
169  *  Internal function.
170  */
171 Int GateMP_detach(UInt16 procId)
173     Int status;
174     LAD_ClientHandle clHandle;
175     struct LAD_CommandObj cmd;
176     union LAD_ResponseObj rsp;
178     clHandle = LAD_findHandle();
180     if (clHandle == LAD_MAXNUMCLIENTS) {
181         PRINTVERBOSE0("GateMP_detach: not connected to LAD\n");
182         return (GateMP_E_RESOURCE);
183     }
185     cmd.cmd = LAD_GATEMP_DETACH;
186     cmd.clientId = clHandle;
187     cmd.args.detach.procId = procId;
189     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
190         PRINTVERBOSE1("GateMP_detach: sending LAD command failed, "
191                 "status=%d\n", status);
192         return (GateMP_E_FAIL);
193     }
195     if ((status = LAD_getResponse(clHandle, &rsp)) != LAD_SUCCESS) {
196         PRINTVERBOSE1("GateMP_detach: no LAD response, status=%d\n",
197                 status);
198         return (GateMP_E_FAIL);
199     }
201     status = rsp.status;
202     PRINTVERBOSE1("GateMP_detach: LAD response, status=%d\n", status)
204     return (status);
207 Int GateMP_start(Void)
209     Int status;
210     LAD_ClientHandle handle;
211     struct LAD_CommandObj cmd;
212     union LAD_ResponseObj rsp;
214     handle = LAD_findHandle();
215     if (handle == LAD_MAXNUMCLIENTS) {
216         PRINTVERBOSE1(
217           "GateMP_start: can't find connection to daemon for pid %d\n",
218            getpid())
220         return -1;
221     }
223     cmd.cmd = LAD_GATEMP_START;
224     cmd.clientId = handle;
226     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
227         PRINTVERBOSE1(
228           "GateMP_start: sending LAD command failed, status=%d\n", status)
229         return -1;
230     }
232     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
233         PRINTVERBOSE1("GateMP_start: no LAD response, status=%d\n", status)
234         return -1;
235     }
237     status = rsp.gateMPStart.status;
239     PRINTVERBOSE2(
240       "GateMP_start: got LAD response for client %d, status=%d\n",
241       handle, status)
243     /*
244      * Initialize module state. Note that Nameserver handles are compatible
245      * across processes.
246      */
247     GateMP_module->nameServer = rsp.gateMPStart.nameServerHandle;
250     /* allocate memory for remote system gate handles */
251     if (status == GateMP_S_SUCCESS) {
252         GateMP_module->numRemoteSystem =
253             GateMP_getNumResources(GateMP_RemoteProtect_SYSTEM);
254         if (GateMP_module->numRemoteSystem > 0) {
255             GateMP_module->remoteSystemGates = calloc(1,
256                 GateMP_module->numRemoteSystem *
257                 sizeof(IGateProvider_Handle));
259             if (GateMP_module->remoteSystemGates == NULL) {
260                 status = GateMP_E_MEMORY;
261                 PRINTVERBOSE0("GateMP_start: memory allocation failed")
262             }
263         }
264         else {
265             GateMP_module->remoteSystemGates = NULL;
266         }
267     }
269     if (status == GateMP_S_SUCCESS) {
270         /* Open default gate */
271         status = GateMP_open("_GateMP_TI_dGate", &GateMP_module->defaultGate);
272         if (status < 0) {
273             PRINTVERBOSE1("GateMP_start: could not open default gate, \
274                 status=%d\n", status)
275         }
276     }
278     /* in failure case, release acquired resources in reverse order */
279     if (status < 0) {
280         GateMP_stop();
281     }
283     GateMP_module->isStarted = TRUE;
285     return status;
288 Int GateMP_stop(Void)
290     Int status = GateMP_S_SUCCESS;
292     PRINTVERBOSE0("GateMP_stop: entered\n")
294     /* close the default gate */
295     if (GateMP_module->defaultGate) {
296         GateMP_close(&GateMP_module->defaultGate);
297         GateMP_module->defaultGate = NULL;
298     }
300     /* free system gate array */
301     if (GateMP_module->remoteSystemGates != NULL) {
302         free(GateMP_module->remoteSystemGates);
303         GateMP_module->remoteSystemGates = NULL;
304     }
306     GateMP_module->isStarted = FALSE;
308     return status;
311 Void GateMP_Params_init(GateMP_Params *params)
313     if (params != NULL) {
314         memcpy(params, &GateMP_defInstParams, sizeof(GateMP_Params));
315     }
316     else {
317         PRINTVERBOSE0("GateMP_Params_init: Params argument cannot be NULL")
318     }
320     return;
323 GateMP_Handle GateMP_create(const GateMP_Params *params)
325     _GateMP_Params      _params;
326     GateMP_Handle       handle = NULL;
328     if (GateMP_module->isStarted == FALSE) {
329         PRINTVERBOSE0("GateMP_create: GateMP module has not been started!")
330     }
331     else {
332         memset(&_params, 0, sizeof(_GateMP_Params));
333         memcpy(&_params, params, sizeof(GateMP_Params));
335         handle = _GateMP_create(&_params);
336     }
338     return(handle);
341 static GateMP_Handle _GateMP_create(const _GateMP_Params *params)
343     GateMP_Handle       handle = NULL;
344     GateMP_Object *     obj = NULL;
345     Int                 status;
347     /* allocate the instance object */
348     obj = (GateMP_Object *)calloc(1, sizeof(GateMP_Object));
350     if (obj != NULL) {
351         status = GateMP_Instance_init(obj, params);
352         if (status < 0) {
353             free(obj);
354         }
355         else {
356             handle = (GateMP_Handle)obj;
357         }
358     }
359     else {
360         PRINTVERBOSE0("GateMP_create: Memory allocation failed")
361     }
363     return(handle);
366 Int GateMP_open(String name, GateMP_Handle *handle)
368     Int             status = GateMP_S_SUCCESS;
369     UInt32          len;
370     UInt32          nsValue[4];
371     GateMP_Object * obj = NULL;
372     UInt32          arg;
373     UInt32          mask;
374     UInt32          creatorProcId;
375     _GateMP_Params  params;
377     /* assert that a valid pointer has been supplied */
378     if (handle == NULL) {
379         PRINTVERBOSE0("GateMP_open: handle cannot be null")
380         status = GateMP_E_INVALIDARG;
381     }
383     if (status == GateMP_S_SUCCESS) {
384         len = sizeof(nsValue);
386         status = NameServer_get(GateMP_module->nameServer, name, &nsValue,
387             &len, NULL);
389         if (status < 0) {
390             *handle = NULL;
391             status = GateMP_E_NOTFOUND;
392         }
393         else if (len != sizeof(nsValue)) {
394             *handle = NULL;
395             status = GateMP_E_NOTFOUND;
396             PRINTVERBOSE0("GateMP configuration not valid for hostSupport. "
397                 "Try adding hostSupport to your config if it is needed.\n");
398         }
399         else {
400             arg = nsValue[2];
401             mask = nsValue[3];
402             creatorProcId = nsValue[1] >> 16;
403         }
404     }
406     if (status == GateMP_S_SUCCESS) {
407         /*
408          * The least significant bit of nsValue[1] == 0 means its a
409          * local (private) GateMP, otherwise its a remote (shared) GateMP.
410          */
411         if ((nsValue[1] & 0x1) == 0) {
412             if ((nsValue[1] >> 16) != MultiProc_self()) {
413                 /* error: trying to open another processor's private gate */
414                 *handle = NULL;
415                 PRINTVERBOSE0("GateMP_open: cannot open private gate from \
416                     another processor")
417                 status = GateMP_E_FAIL;
418             }
419             else if (nsValue[0] != getpid()) {
420                 /* error: trying to open another process's private gate */
421                 *handle = NULL;
422                 PRINTVERBOSE0("GateMP_open: cannot open private gate from \
423                     another process")
424                 status = GateMP_E_FAIL;
425             }
426         }
427     }
429     if (status == GateMP_S_SUCCESS) {
430         /* local gate */
431         if (GETREMOTE(mask) == GateMP_RemoteProtect_NONE) {
432             if (creatorProcId != MultiProc_self()) {
433                 status = GateMP_E_FAIL;
434             }
435             else {
436                 *handle = (GateMP_Handle)arg;
437                 obj = (GateMP_Object *)(*handle);
438                 pthread_mutex_lock(&GateMP_module->mutex);
439                 obj->numOpens++;
440                 pthread_mutex_unlock(&GateMP_module->mutex);
441             }
442         }
443         else {
444             /* remote case */
445             switch (GETREMOTE(mask)) {
446                 case GateMP_RemoteProtect_SYSTEM:
447                 case GateMP_RemoteProtect_CUSTOM1:
448                 case GateMP_RemoteProtect_CUSTOM2:
449                     obj = GateMP_module->remoteSystemGates[arg];
450                     break;
452                 default:
453                     status = GateMP_E_FAIL;
454                     PRINTVERBOSE0("GateMP_open: unsupported remote protection \
455                         type")
456                     break;
457             }
459             /*  If the object is NULL, then it must have been created
460              *  on a remote processor or in another process on the
461              *  local processor. Need to create a local object. This is
462              *  accomplished by setting the openFlag to TRUE.
463              */
464             if (status == GateMP_S_SUCCESS) {
465                 if (obj == NULL) {
466                     /* create a GateMP object with the openFlag set to true */
467                     params.name = NULL;
468                     params.openFlag = TRUE;
469                     params.sharedAddr = NULL;
470                     params.resourceId = arg;
471                     params.localProtect = GETLOCAL(mask);
472                     params.remoteProtect = GETREMOTE(mask);
474                     obj = (GateMP_Object *)_GateMP_create(&params);
476                     if (obj == NULL) {
477                         status = GateMP_E_FAIL;
478                     }
479                 }
480                 else {
481                     pthread_mutex_lock(&GateMP_module->mutex);
482                     obj->numOpens++;
483                     pthread_mutex_unlock(&GateMP_module->mutex);
484                 }
485             }
487             /* Return the "opened" GateMP instance  */
488             *handle = (GateMP_Handle)obj;
489         }
490     }
492     return status;
495 GateMP_Handle GateMP_getDefaultRemote()
497     return(GateMP_module->defaultGate);
500 GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
502     GateMP_Object *obj;
504     obj = (GateMP_Object *)handle;
505     return(obj->localProtect);
508 GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
510     GateMP_Object *obj;
512     obj = (GateMP_Object *)handle;
513     return (obj->remoteProtect);
516 static Int GateMP_getNumResources(GateMP_RemoteProtect type)
518     Int status;
519     LAD_ClientHandle handle;
520     struct LAD_CommandObj cmd;
521     union LAD_ResponseObj rsp;
523     handle = LAD_findHandle();
524     if (handle == LAD_MAXNUMCLIENTS) {
525         PRINTVERBOSE1(
526           "GateMP_getNumResources: can't find connection to daemon for pid %d\n",
527            getpid())
529         return -1;
530     }
532     cmd.cmd = LAD_GATEMP_GETNUMRESOURCES;
533     cmd.clientId = handle;
534     cmd.args.gateMPGetNumResources.type = type;
537     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
538         PRINTVERBOSE1(
539           "GateMP_getNumResources: sending LAD command failed, status=%d\n", status)
540         return -1;
541     }
543     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
544         PRINTVERBOSE1("GateMP_getNumResources: no LAD response, status=%d\n", status)
545         return -1;
546     }
548     status = rsp.gateMPGetNumResources.status;
550     PRINTVERBOSE2(
551       "GateMP_getNumResources: got LAD response for client %d, status=%d\n",
552       handle, status)
555     return (rsp.gateMPGetNumResources.value);
558 static Int GateMP_getFreeResource(GateMP_RemoteProtect type)
560     Int status;
561     LAD_ClientHandle handle;
562     struct LAD_CommandObj cmd;
563     union LAD_ResponseObj rsp;
565     handle = LAD_findHandle();
566     if (handle == LAD_MAXNUMCLIENTS) {
567         PRINTVERBOSE1(
568           "GateMP_getFreeResource: can't find connection to daemon for pid %d\n",
569            getpid())
571         return -1;
572     }
574     cmd.cmd = LAD_GATEMP_GETFREERESOURCE;
575     cmd.clientId = handle;
576     cmd.args.gateMPGetFreeResource.type = type;
578     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
579         PRINTVERBOSE1(
580           "GateMP_getFreeResource: sending LAD command failed, status=%d\n", status)
581         return -1;
582     }
584     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
585         PRINTVERBOSE1("GateMP_getFreeResource: no LAD response, status=%d\n", status)
586         return -1;
587     }
589     status = rsp.gateMPGetFreeResource.status;
591     PRINTVERBOSE2(
592       "GateMP_getNumResources: got LAD response for client %d, status=%d\n",
593       handle, status)
595     return (rsp.gateMPGetFreeResource.id);
598 static Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type)
600     Int status;
601     LAD_ClientHandle handle;
602     struct LAD_CommandObj cmd;
603     union LAD_ResponseObj rsp;
605     handle = LAD_findHandle();
606     if (handle == LAD_MAXNUMCLIENTS) {
607         PRINTVERBOSE1(
608           "GateMP_releaseResource: can't find connection to daemon for pid %d\n",
609            getpid())
611         return -1;
612     }
614     cmd.cmd = LAD_GATEMP_RELEASERESOURCE;
615     cmd.clientId = handle;
616     cmd.args.gateMPReleaseResource.type = type;
617     cmd.args.gateMPReleaseResource.id   = id;
619     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
620         PRINTVERBOSE1(
621           "GateMP_releaseResource: sending LAD command failed, status=%d\n", status)
622         return -1;
623     }
625     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
626         PRINTVERBOSE1("GateMP_releaseResource: no LAD response, status=%d\n", status)
627         return -1;
628     }
630     status = rsp.gateMPReleaseResource.status;
632     PRINTVERBOSE2(
633       "GateMP_releaseResource: got LAD response for client %d, status=%d\n",
634       handle, status)
636     return (status);
639 Bool GateMP_isSetup(Void)
641     Int status;
642     LAD_ClientHandle handle;
643     struct LAD_CommandObj cmd;
644     union LAD_ResponseObj rsp;
646     handle = LAD_findHandle();
647     if (handle == LAD_MAXNUMCLIENTS) {
648         PRINTVERBOSE1(
649           "GateMP_isSetup: can't find connection to daemon for pid %d\n",
650            getpid())
652         return -1;
653     }
655     cmd.cmd = LAD_GATEMP_ISSETUP;
656     cmd.clientId = handle;
657     cmd.args.gateMPIsSetup.result = FALSE;
659     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
660         PRINTVERBOSE1(
661           "GateMP_isSetup: sending LAD command failed, status=%d\n", status)
662         return -1 ;
663     }
665     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
666         PRINTVERBOSE1("GateMP_isSetup: no LAD response, status=%d\n", status)
667         return -1;
668     }
670     status = rsp.gateMPIsSetup.status;
672     PRINTVERBOSE2(
673       "GateMP_isSetup: got LAD response for client %d, status=%d\n",
674       handle, status)
676     assert(status == GateMP_S_SUCCESS);
678     return (rsp.gateMPIsSetup.result);
681 Int GateMP_close(GateMP_Handle *handle)
683     GateMP_Object * obj;
684     Int             status = GateMP_S_SUCCESS;
686     obj = (GateMP_Object *)(*handle);
688     pthread_mutex_lock(&GateMP_module->mutex);
690     /*  Cannot call with the numOpens equal to zero.  This is either
691      *  a created handle or been closed already.
692      */
693     if (obj->numOpens == 0) {
694         status = GateMP_E_INVALIDSTATE;
695     }
697     if (status == GateMP_S_SUCCESS) {
698         obj->numOpens--;
700         /*  If the count is zero and the gate is opened, then this
701          *  object was created in the open (i.e. the create happened
702          *  on a remote processor or another process).
703          */
704         if ((obj->numOpens == 0) && (obj->objType == Ipc_ObjType_OPENDYNAMIC)) {
705             GateMP_delete(handle);
706         }
707         else {
708             *handle = NULL;
709         }
710     }
712     pthread_mutex_unlock(&GateMP_module->mutex);
714     return(status);
717 Int GateMP_delete(GateMP_Handle *handlePtr)
719     Int               status = GateMP_S_SUCCESS;
721     if ((handlePtr == NULL) || (*handlePtr == NULL)) {
722         status =  GateMP_E_INVALIDARG;
723     }
724     else {
725         GateMP_Instance_finalize((GateMP_Object *)(*handlePtr), 0);
726         free(*handlePtr);
727         *handlePtr = NULL;
728     }
730     return status;
733 static Int GateMP_Instance_init(GateMP_Object *obj,
734     const _GateMP_Params *params)
736     GateMP_RemoteSystemProxy_Params     systemParams;
737     UInt32                              nsValue[4];
739     obj->resourceId = (UInt)-1;
741     /* TODO: create/open the local gate instance */
742     obj->localGate = NULL;
744     /* open GateMP instance */
745     if (params->openFlag == TRUE) {
746         /* all open work done here except for remote gateHandle */
747         obj->localProtect  = params->localProtect;
748         obj->remoteProtect = params->remoteProtect;
749         obj->nsKey         = 0;
750         obj->numOpens      = 1;
752         obj->objType       = Ipc_ObjType_OPENDYNAMIC;
753     }
755     /* create GateMP instance */
756     else {
757         obj->localProtect  = params->localProtect;
758         obj->remoteProtect = params->remoteProtect;
759         obj->nsKey         = 0;
760         obj->numOpens      = 0;
762         if (obj->remoteProtect == GateMP_RemoteProtect_NONE) {
763             /* TODO: create a local gate */
764             obj->gateHandle = obj->localGate;
766             /* create a local gate allocating from the local heap */
767             obj->objType = Ipc_ObjType_LOCAL;
768             obj->arg = (Bits32)obj;
769             obj->mask = SETMASK(obj->remoteProtect, obj->localProtect);
770             obj->creatorProcId = MultiProc_self();
772             if (params->name != NULL) {
773                 /*  nsv[0]       : creator process id
774                  *  nsv[1](31:16): creator procId
775                  *  nsv[1](15:0) : 0 = local gate, 1 = remote gate
776                  *  nsv[2]       : local gate object
777                  *  nsv[3]       : protection mask
778                  */
779                 nsValue[0] = getpid();
780                 nsValue[1] = MultiProc_self() << 16;
781                 nsValue[2] = obj->arg;
782                 nsValue[3] = obj->mask;
783                 obj->nsKey = NameServer_add(GateMP_module->nameServer,
784                         params->name, &nsValue, sizeof(nsValue));
785                 if (obj->nsKey == NULL) {
786                     PRINTVERBOSE0("GateMP_Instance_init: NameServer_add failed")
787                     return (GateMP_E_FAIL);
788                 }
789             }
791             /* nothing else to do for local gates */
792             return(0);
793         }
795         obj->objType = Ipc_ObjType_CREATEDYNAMIC;
796     }
798     /* proxy work for open and create done here */
799     switch (obj->remoteProtect) {
800         /* TODO: implement other types of remote protection */
801         case GateMP_RemoteProtect_SYSTEM:
802         case GateMP_RemoteProtect_CUSTOM1:
803         case GateMP_RemoteProtect_CUSTOM2:
804             if (obj->objType == Ipc_ObjType_OPENDYNAMIC) {
805                 /* resourceId set by open call */
806                 obj->resourceId = params->resourceId;
807             }
808             else {
809                 /* created instance */
810                 obj->resourceId = GateMP_getFreeResource(obj->remoteProtect);
811                 if (obj->resourceId == -1) {
812                     return (GateMP_E_RESOURCE);
813                 }
814             }
816             /* create the proxy object */
817             GateMP_RemoteSystemProxy_Params_init(&systemParams);
818             systemParams.resourceId = obj->resourceId;
819             systemParams.openFlag = (obj->objType == Ipc_ObjType_OPENDYNAMIC);
820             //systemParams.sharedAddr = obj->proxyAttrs;
822             /*
823              * TODO: Currently passing in localProtect instead of localGate,
824              * since existing GateHWSpinlock.h defines it this way
825              */
826             obj->gateHandle = (IGateProvider_Handle)
827                 GateMP_RemoteSystemProxy_create(obj->localProtect,
828                     &systemParams);
830             if (obj->gateHandle == NULL) {
831                 PRINTVERBOSE0("GateMP_Instance_init: failed to create proxy\n");
832                 return(GateMP_E_FAIL);
833             }
835             /* store the object handle in the gate array */
836             GateMP_module->remoteSystemGates[obj->resourceId] = obj;
837             break;
839         default:
840             break;
841     }
843     /* add name/attrs to NameServer table */
844     if (obj->objType != Ipc_ObjType_OPENDYNAMIC) {
845         obj->arg = obj->resourceId;
846         obj->mask = SETMASK(obj->remoteProtect, obj->localProtect);
848         if (params->name != NULL) {
849             /*  nsv[0]       : creator pid
850              *  nsv[1](31:16): creator procId
851              *  nsv[1](15:0) : 0 = local gate, 1 = remote gate
852              *  nsv[2]       : resource id
853              *  nsv[3]       : protection mask
854              */
855             nsValue[0] = getpid();
856             nsValue[1] = MultiProc_self() << 16 | 1;
857             nsValue[2] = obj->resourceId;
858             nsValue[3] = obj->mask;
859             obj->nsKey = NameServer_add(GateMP_module->nameServer,
860                     params->name, &nsValue, sizeof(nsValue));
862             if (obj->nsKey == NULL) {
863                 PRINTVERBOSE0("GateMP_Instance_init: NameServer_add failed")
864                 return (GateMP_E_FAIL);
865             }
866         }
867     }
869     return (GateMP_S_SUCCESS);
872 static Void GateMP_Instance_finalize(GateMP_Object *obj, Int status)
874     GateMP_Object ** remoteGates = NULL;
876     /* remove from NameServer */
877     if (obj->nsKey != 0) {
878         NameServer_removeEntry(GateMP_module->nameServer, obj->nsKey);
879         obj->nsKey = 0;
880     }
882     /* delete the remote gate */
883     switch (obj->remoteProtect) {
885         case GateMP_RemoteProtect_SYSTEM:
886         case GateMP_RemoteProtect_CUSTOM1:
887         case GateMP_RemoteProtect_CUSTOM2:
888             if (obj->gateHandle != NULL) {
889                 GateMP_RemoteSystemProxy_delete(
890                         (GateMP_RemoteSystemProxy_Handle *)&obj->gateHandle);
891             }
892             remoteGates = GateMP_module->remoteSystemGates;
893             break;
895         case GateMP_RemoteProtect_NONE:
896             /*  nothing else to finalize */
897             return;
899         default:
900             /* Nothing to do */
901             break;
902     }
904     /* TODO: close/delete local gate */
906     /* clear the handle array entry in local memory */
907     if (obj->resourceId != (UInt)-1) {
908         remoteGates[obj->resourceId] = NULL;
909     }
911     if ((obj->objType != Ipc_ObjType_OPENDYNAMIC)
912         && (obj->resourceId != (UInt)-1)) {
913         GateMP_releaseResource(obj->resourceId, obj->remoteProtect);
914     }
918 IArg GateMP_enter(GateMP_Handle handle)
920     GateMP_Object * obj;
921     IArg            key;
923     obj = (GateMP_Object *)handle;
924     key = IGateProvider_enter(obj->gateHandle);
926     return(key);
929 Void GateMP_leave(GateMP_Handle handle, IArg key)
931     GateMP_Object *obj;
933     obj = (GateMP_Object *)handle;
934     IGateProvider_leave(obj->gateHandle, key);