]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - linux/src/api/gates/GateMP.c
Fix Linux GateMP bug by introducing new GateMP_attach(procId) API
[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 {
394             arg = nsValue[2];
395             mask = nsValue[3];
396             creatorProcId = nsValue[1] >> 16;
397         }
398     }
400     if (status == GateMP_S_SUCCESS) {
401         /*
402          * The least significant bit of nsValue[1] == 0 means its a
403          * local (private) GateMP, otherwise its a remote (shared) GateMP.
404          */
405         if ((nsValue[1] & 0x1) == 0) {
406             if ((nsValue[1] >> 16) != MultiProc_self()) {
407                 /* error: trying to open another processor's private gate */
408                 *handle = NULL;
409                 PRINTVERBOSE0("GateMP_open: cannot open private gate from \
410                     another processor")
411                 status = GateMP_E_FAIL;
412             }
413             else if (nsValue[0] != getpid()) {
414                 /* error: trying to open another process's private gate */
415                 *handle = NULL;
416                 PRINTVERBOSE0("GateMP_open: cannot open private gate from \
417                     another process")
418                 status = GateMP_E_FAIL;
419             }
420         }
421     }
423     if (status == GateMP_S_SUCCESS) {
424         /* local gate */
425         if (GETREMOTE(mask) == GateMP_RemoteProtect_NONE) {
426             if (creatorProcId != MultiProc_self()) {
427                 status = GateMP_E_FAIL;
428             }
429             else {
430                 *handle = (GateMP_Handle)arg;
431                 obj = (GateMP_Object *)(*handle);
432                 pthread_mutex_lock(&GateMP_module->mutex);
433                 obj->numOpens++;
434                 pthread_mutex_unlock(&GateMP_module->mutex);
435             }
436         }
437         else {
438             /* remote case */
439             switch (GETREMOTE(mask)) {
440                 case GateMP_RemoteProtect_SYSTEM:
441                 case GateMP_RemoteProtect_CUSTOM1:
442                 case GateMP_RemoteProtect_CUSTOM2:
443                     obj = GateMP_module->remoteSystemGates[arg];
444                     break;
446                 default:
447                     status = GateMP_E_FAIL;
448                     PRINTVERBOSE0("GateMP_open: unsupported remote protection \
449                         type")
450                     break;
451             }
453             /*  If the object is NULL, then it must have been created
454              *  on a remote processor or in another process on the
455              *  local processor. Need to create a local object. This is
456              *  accomplished by setting the openFlag to TRUE.
457              */
458             if (status == GateMP_S_SUCCESS) {
459                 if (obj == NULL) {
460                     /* create a GateMP object with the openFlag set to true */
461                     params.name = NULL;
462                     params.openFlag = TRUE;
463                     params.sharedAddr = NULL;
464                     params.resourceId = arg;
465                     params.localProtect = GETLOCAL(mask);
466                     params.remoteProtect = GETREMOTE(mask);
468                     obj = (GateMP_Object *)_GateMP_create(&params);
470                     if (obj == NULL) {
471                         status = GateMP_E_FAIL;
472                     }
473                 }
474                 else {
475                     pthread_mutex_lock(&GateMP_module->mutex);
476                     obj->numOpens++;
477                     pthread_mutex_unlock(&GateMP_module->mutex);
478                 }
479             }
481             /* Return the "opened" GateMP instance  */
482             *handle = (GateMP_Handle)obj;
483         }
484     }
486     return status;
489 GateMP_Handle GateMP_getDefaultRemote()
491     return(GateMP_module->defaultGate);
494 GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
496     GateMP_Object *obj;
498     obj = (GateMP_Object *)handle;
499     return(obj->localProtect);
502 GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
504     GateMP_Object *obj;
506     obj = (GateMP_Object *)handle;
507     return (obj->remoteProtect);
510 static Int GateMP_getNumResources(GateMP_RemoteProtect type)
512     Int status;
513     LAD_ClientHandle handle;
514     struct LAD_CommandObj cmd;
515     union LAD_ResponseObj rsp;
517     handle = LAD_findHandle();
518     if (handle == LAD_MAXNUMCLIENTS) {
519         PRINTVERBOSE1(
520           "GateMP_getNumResources: can't find connection to daemon for pid %d\n",
521            getpid())
523         return -1;
524     }
526     cmd.cmd = LAD_GATEMP_GETNUMRESOURCES;
527     cmd.clientId = handle;
528     cmd.args.gateMPGetNumResources.type = type;
531     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
532         PRINTVERBOSE1(
533           "GateMP_getNumResources: sending LAD command failed, status=%d\n", status)
534         return -1;
535     }
537     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
538         PRINTVERBOSE1("GateMP_getNumResources: no LAD response, status=%d\n", status)
539         return -1;
540     }
542     status = rsp.gateMPGetNumResources.status;
544     PRINTVERBOSE2(
545       "GateMP_getNumResources: got LAD response for client %d, status=%d\n",
546       handle, status)
549     return (rsp.gateMPGetNumResources.value);
552 static Int GateMP_getFreeResource(GateMP_RemoteProtect type)
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_getFreeResource: can't find connection to daemon for pid %d\n",
563            getpid())
565         return -1;
566     }
568     cmd.cmd = LAD_GATEMP_GETFREERESOURCE;
569     cmd.clientId = handle;
570     cmd.args.gateMPGetFreeResource.type = type;
572     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
573         PRINTVERBOSE1(
574           "GateMP_getFreeResource: sending LAD command failed, status=%d\n", status)
575         return -1;
576     }
578     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
579         PRINTVERBOSE1("GateMP_getFreeResource: no LAD response, status=%d\n", status)
580         return -1;
581     }
583     status = rsp.gateMPGetFreeResource.status;
585     PRINTVERBOSE2(
586       "GateMP_getNumResources: got LAD response for client %d, status=%d\n",
587       handle, status)
589     return (rsp.gateMPGetFreeResource.id);
592 static Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type)
594     Int status;
595     LAD_ClientHandle handle;
596     struct LAD_CommandObj cmd;
597     union LAD_ResponseObj rsp;
599     handle = LAD_findHandle();
600     if (handle == LAD_MAXNUMCLIENTS) {
601         PRINTVERBOSE1(
602           "GateMP_releaseResource: can't find connection to daemon for pid %d\n",
603            getpid())
605         return -1;
606     }
608     cmd.cmd = LAD_GATEMP_RELEASERESOURCE;
609     cmd.clientId = handle;
610     cmd.args.gateMPReleaseResource.type = type;
611     cmd.args.gateMPReleaseResource.id   = id;
613     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
614         PRINTVERBOSE1(
615           "GateMP_releaseResource: sending LAD command failed, status=%d\n", status)
616         return -1;
617     }
619     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
620         PRINTVERBOSE1("GateMP_releaseResource: no LAD response, status=%d\n", status)
621         return -1;
622     }
624     status = rsp.gateMPReleaseResource.status;
626     PRINTVERBOSE2(
627       "GateMP_releaseResource: got LAD response for client %d, status=%d\n",
628       handle, status)
630     return (status);
633 Bool GateMP_isSetup(Void)
635     Int status;
636     LAD_ClientHandle handle;
637     struct LAD_CommandObj cmd;
638     union LAD_ResponseObj rsp;
640     handle = LAD_findHandle();
641     if (handle == LAD_MAXNUMCLIENTS) {
642         PRINTVERBOSE1(
643           "GateMP_isSetup: can't find connection to daemon for pid %d\n",
644            getpid())
646         return -1;
647     }
649     cmd.cmd = LAD_GATEMP_ISSETUP;
650     cmd.clientId = handle;
651     cmd.args.gateMPIsSetup.result = FALSE;
653     if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
654         PRINTVERBOSE1(
655           "GateMP_isSetup: sending LAD command failed, status=%d\n", status)
656         return -1 ;
657     }
659     if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
660         PRINTVERBOSE1("GateMP_isSetup: no LAD response, status=%d\n", status)
661         return -1;
662     }
664     status = rsp.gateMPIsSetup.status;
666     PRINTVERBOSE2(
667       "GateMP_isSetup: got LAD response for client %d, status=%d\n",
668       handle, status)
670     assert(status == GateMP_S_SUCCESS);
672     return (rsp.gateMPIsSetup.result);
675 Int GateMP_close(GateMP_Handle *handle)
677     GateMP_Object * obj;
678     Int             status = GateMP_S_SUCCESS;
680     obj = (GateMP_Object *)(*handle);
682     pthread_mutex_lock(&GateMP_module->mutex);
684     /*  Cannot call with the numOpens equal to zero.  This is either
685      *  a created handle or been closed already.
686      */
687     if (obj->numOpens == 0) {
688         status = GateMP_E_INVALIDSTATE;
689     }
691     if (status == GateMP_S_SUCCESS) {
692         obj->numOpens--;
694         /*  If the count is zero and the gate is opened, then this
695          *  object was created in the open (i.e. the create happened
696          *  on a remote processor or another process).
697          */
698         if ((obj->numOpens == 0) && (obj->objType == Ipc_ObjType_OPENDYNAMIC)) {
699             GateMP_delete(handle);
700         }
701         else {
702             *handle = NULL;
703         }
704     }
706     pthread_mutex_unlock(&GateMP_module->mutex);
708     return(status);
711 Int GateMP_delete(GateMP_Handle *handlePtr)
713     Int               status = GateMP_S_SUCCESS;
715     if ((handlePtr == NULL) || (*handlePtr == NULL)) {
716         status =  GateMP_E_INVALIDARG;
717     }
718     else {
719         GateMP_Instance_finalize((GateMP_Object *)(*handlePtr), 0);
720         free(*handlePtr);
721         *handlePtr = NULL;
722     }
724     return status;
727 static Int GateMP_Instance_init(GateMP_Object *obj,
728     const _GateMP_Params *params)
730     GateMP_RemoteSystemProxy_Params     systemParams;
731     UInt32                              nsValue[4];
733     obj->resourceId = (UInt)-1;
735     /* TODO: create/open the local gate instance */
736     obj->localGate = NULL;
738     /* open GateMP instance */
739     if (params->openFlag == TRUE) {
740         /* all open work done here except for remote gateHandle */
741         obj->localProtect  = params->localProtect;
742         obj->remoteProtect = params->remoteProtect;
743         obj->nsKey         = 0;
744         obj->numOpens      = 1;
746         obj->objType       = Ipc_ObjType_OPENDYNAMIC;
747     }
749     /* create GateMP instance */
750     else {
751         obj->localProtect  = params->localProtect;
752         obj->remoteProtect = params->remoteProtect;
753         obj->nsKey         = 0;
754         obj->numOpens      = 0;
756         if (obj->remoteProtect == GateMP_RemoteProtect_NONE) {
757             /* TODO: create a local gate */
758             obj->gateHandle = obj->localGate;
760             /* create a local gate allocating from the local heap */
761             obj->objType = Ipc_ObjType_LOCAL;
762             obj->arg = (Bits32)obj;
763             obj->mask = SETMASK(obj->remoteProtect, obj->localProtect);
764             obj->creatorProcId = MultiProc_self();
766             if (params->name != NULL) {
767                 /*  nsv[0]       : creator process id
768                  *  nsv[1](31:16): creator procId
769                  *  nsv[1](15:0) : 0 = local gate, 1 = remote gate
770                  *  nsv[2]       : local gate object
771                  *  nsv[3]       : protection mask
772                  */
773                 nsValue[0] = getpid();
774                 nsValue[1] = MultiProc_self() << 16;
775                 nsValue[2] = obj->arg;
776                 nsValue[3] = obj->mask;
777                 obj->nsKey = NameServer_add(GateMP_module->nameServer,
778                         params->name, &nsValue, sizeof(nsValue));
779                 if (obj->nsKey == NULL) {
780                     PRINTVERBOSE0("GateMP_Instance_init: NameServer_add failed")
781                     return (GateMP_E_FAIL);
782                 }
783             }
785             /* nothing else to do for local gates */
786             return(0);
787         }
789         obj->objType = Ipc_ObjType_CREATEDYNAMIC;
790     }
792     /* proxy work for open and create done here */
793     switch (obj->remoteProtect) {
794         /* TODO: implement other types of remote protection */
795         case GateMP_RemoteProtect_SYSTEM:
796         case GateMP_RemoteProtect_CUSTOM1:
797         case GateMP_RemoteProtect_CUSTOM2:
798             if (obj->objType == Ipc_ObjType_OPENDYNAMIC) {
799                 /* resourceId set by open call */
800                 obj->resourceId = params->resourceId;
801             }
802             else {
803                 /* created instance */
804                 obj->resourceId = GateMP_getFreeResource(obj->remoteProtect);
805                 if (obj->resourceId == -1) {
806                     return (GateMP_E_RESOURCE);
807                 }
808             }
810             /* create the proxy object */
811             GateMP_RemoteSystemProxy_Params_init(&systemParams);
812             systemParams.resourceId = obj->resourceId;
813             systemParams.openFlag = (obj->objType == Ipc_ObjType_OPENDYNAMIC);
814             //systemParams.sharedAddr = obj->proxyAttrs;
816             /*
817              * TODO: Currently passing in localProtect instead of localGate,
818              * since existing GateHWSpinlock.h defines it this way
819              */
820             obj->gateHandle = (IGateProvider_Handle)
821                 GateMP_RemoteSystemProxy_create(obj->localProtect,
822                     &systemParams);
824             if (obj->gateHandle == NULL) {
825                 PRINTVERBOSE0("GateMP_Instance_init: failed to create proxy\n");
826                 return(GateMP_E_FAIL);
827             }
829             /* store the object handle in the gate array */
830             GateMP_module->remoteSystemGates[obj->resourceId] = obj;
831             break;
833         default:
834             break;
835     }
837     /* add name/attrs to NameServer table */
838     if (obj->objType != Ipc_ObjType_OPENDYNAMIC) {
839         obj->arg = obj->resourceId;
840         obj->mask = SETMASK(obj->remoteProtect, obj->localProtect);
842         if (params->name != NULL) {
843             /*  nsv[0]       : creator pid
844              *  nsv[1](31:16): creator procId
845              *  nsv[1](15:0) : 0 = local gate, 1 = remote gate
846              *  nsv[2]       : resource id
847              *  nsv[3]       : protection mask
848              */
849             nsValue[0] = getpid();
850             nsValue[1] = MultiProc_self() << 16 | 1;
851             nsValue[2] = obj->resourceId;
852             nsValue[3] = obj->mask;
853             obj->nsKey = NameServer_add(GateMP_module->nameServer,
854                     params->name, &nsValue, sizeof(nsValue));
856             if (obj->nsKey == NULL) {
857                 PRINTVERBOSE0("GateMP_Instance_init: NameServer_add failed")
858                 return (GateMP_E_FAIL);
859             }
860         }
861     }
863     return (GateMP_S_SUCCESS);
866 static Void GateMP_Instance_finalize(GateMP_Object *obj, Int status)
868     GateMP_Object ** remoteGates = NULL;
870     /* remove from NameServer */
871     if (obj->nsKey != 0) {
872         NameServer_removeEntry(GateMP_module->nameServer, obj->nsKey);
873         obj->nsKey = 0;
874     }
876     /* delete the remote gate */
877     switch (obj->remoteProtect) {
879         case GateMP_RemoteProtect_SYSTEM:
880         case GateMP_RemoteProtect_CUSTOM1:
881         case GateMP_RemoteProtect_CUSTOM2:
882             if (obj->gateHandle != NULL) {
883                 GateMP_RemoteSystemProxy_delete(
884                         (GateMP_RemoteSystemProxy_Handle *)&obj->gateHandle);
885             }
886             remoteGates = GateMP_module->remoteSystemGates;
887             break;
889         case GateMP_RemoteProtect_NONE:
890             /*  nothing else to finalize */
891             return;
893         default:
894             /* Nothing to do */
895             break;
896     }
898     /* TODO: close/delete local gate */
900     /* clear the handle array entry in local memory */
901     if (obj->resourceId != (UInt)-1) {
902         remoteGates[obj->resourceId] = NULL;
903     }
905     if ((obj->objType != Ipc_ObjType_OPENDYNAMIC)
906         && (obj->resourceId != (UInt)-1)) {
907         GateMP_releaseResource(obj->resourceId, obj->remoteProtect);
908     }
912 IArg GateMP_enter(GateMP_Handle handle)
914     GateMP_Object * obj;
915     IArg            key;
917     obj = (GateMP_Object *)handle;
918     key = IGateProvider_enter(obj->gateHandle);
920     return(key);
923 Void GateMP_leave(GateMP_Handle handle, IArg key)
925     GateMP_Object *obj;
927     obj = (GateMP_Object *)handle;
928     IGateProvider_leave(obj->gateHandle, key);