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 =
107 {
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 =
119 {
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)
132 {
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);
165 }
167 /*
168 * ======== GateMP_detach ========
169 * Internal function.
170 */
171 Int GateMP_detach(UInt16 procId)
172 {
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);
205 }
207 Int GateMP_start(Void)
208 {
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;
286 }
288 Int GateMP_stop(Void)
289 {
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;
309 }
311 Void GateMP_Params_init(GateMP_Params *params)
312 {
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;
321 }
323 GateMP_Handle GateMP_create(const GateMP_Params *params)
324 {
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);
339 }
341 static GateMP_Handle _GateMP_create(const _GateMP_Params *params)
342 {
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);
364 }
366 Int GateMP_open(String name, GateMP_Handle *handle)
367 {
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(¶ms);
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;
493 }
495 GateMP_Handle GateMP_getDefaultRemote()
496 {
497 return(GateMP_module->defaultGate);
498 }
500 GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
501 {
502 GateMP_Object *obj;
504 obj = (GateMP_Object *)handle;
505 return(obj->localProtect);
506 }
508 GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
509 {
510 GateMP_Object *obj;
512 obj = (GateMP_Object *)handle;
513 return (obj->remoteProtect);
514 }
516 static Int GateMP_getNumResources(GateMP_RemoteProtect type)
517 {
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);
556 }
558 static Int GateMP_getFreeResource(GateMP_RemoteProtect type)
559 {
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);
596 }
598 static Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type)
599 {
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);
637 }
639 Bool GateMP_isSetup(Void)
640 {
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);
679 }
681 Int GateMP_close(GateMP_Handle *handle)
682 {
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);
715 }
717 Int GateMP_delete(GateMP_Handle *handlePtr)
718 {
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;
731 }
733 static Int GateMP_Instance_init(GateMP_Object *obj,
734 const _GateMP_Params *params)
735 {
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);
870 }
872 static Void GateMP_Instance_finalize(GateMP_Object *obj, Int status)
873 {
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 }
916 }
918 IArg GateMP_enter(GateMP_Handle handle)
919 {
920 GateMP_Object * obj;
921 IArg key;
923 obj = (GateMP_Object *)handle;
924 key = IGateProvider_enter(obj->gateHandle);
926 return(key);
927 }
929 Void GateMP_leave(GateMP_Handle handle, IArg key)
930 {
931 GateMP_Object *obj;
933 obj = (GateMP_Object *)handle;
934 IGateProvider_leave(obj->gateHandle, key);
935 }