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 =
106 {
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 =
118 {
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)
127 {
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;
205 }
207 Int GateMP_stop(Void)
208 {
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;
228 }
230 Void GateMP_Params_init(GateMP_Params *params)
231 {
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;
240 }
242 GateMP_Handle GateMP_create(const GateMP_Params *params)
243 {
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);
258 }
260 static GateMP_Handle _GateMP_create(const _GateMP_Params *params)
261 {
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);
283 }
285 Int GateMP_open(String name, GateMP_Handle *handle)
286 {
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(¶ms);
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;
406 }
408 GateMP_Handle GateMP_getDefaultRemote()
409 {
410 return(GateMP_module->defaultGate);
411 }
413 GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
414 {
415 GateMP_Object *obj;
417 obj = (GateMP_Object *)handle;
418 return(obj->localProtect);
419 }
421 GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
422 {
423 GateMP_Object *obj;
425 obj = (GateMP_Object *)handle;
426 return (obj->remoteProtect);
427 }
429 static Int GateMP_getNumResources(GateMP_RemoteProtect type)
430 {
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);
469 }
471 static Int GateMP_getFreeResource(GateMP_RemoteProtect type)
472 {
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);
509 }
511 static Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type)
512 {
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);
550 }
552 Bool GateMP_isSetup(Void)
553 {
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);
592 }
594 Int GateMP_close(GateMP_Handle *handle)
595 {
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);
628 }
630 Int GateMP_delete(GateMP_Handle *handlePtr)
631 {
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;
644 }
646 static Int GateMP_Instance_init(GateMP_Object *obj,
647 const _GateMP_Params *params)
648 {
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);
783 }
785 static Void GateMP_Instance_finalize(GateMP_Object *obj, Int status)
786 {
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 }
829 }
831 IArg GateMP_enter(GateMP_Handle handle)
832 {
833 GateMP_Object * obj;
834 IArg key;
836 obj = (GateMP_Object *)handle;
837 key = IGateProvider_enter(obj->gateHandle);
839 return(key);
840 }
842 Void GateMP_leave(GateMP_Handle handle, IArg key)
843 {
844 GateMP_Object *obj;
846 obj = (GateMP_Object *)handle;
847 IGateProvider_leave(obj->gateHandle, key);
848 }