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 {
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(¶ms);
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;
487 }
489 GateMP_Handle GateMP_getDefaultRemote()
490 {
491 return(GateMP_module->defaultGate);
492 }
494 GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
495 {
496 GateMP_Object *obj;
498 obj = (GateMP_Object *)handle;
499 return(obj->localProtect);
500 }
502 GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
503 {
504 GateMP_Object *obj;
506 obj = (GateMP_Object *)handle;
507 return (obj->remoteProtect);
508 }
510 static Int GateMP_getNumResources(GateMP_RemoteProtect type)
511 {
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);
550 }
552 static Int GateMP_getFreeResource(GateMP_RemoteProtect type)
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_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);
590 }
592 static Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type)
593 {
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);
631 }
633 Bool GateMP_isSetup(Void)
634 {
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);
673 }
675 Int GateMP_close(GateMP_Handle *handle)
676 {
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);
709 }
711 Int GateMP_delete(GateMP_Handle *handlePtr)
712 {
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;
725 }
727 static Int GateMP_Instance_init(GateMP_Object *obj,
728 const _GateMP_Params *params)
729 {
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);
864 }
866 static Void GateMP_Instance_finalize(GateMP_Object *obj, Int status)
867 {
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 }
910 }
912 IArg GateMP_enter(GateMP_Handle handle)
913 {
914 GateMP_Object * obj;
915 IArg key;
917 obj = (GateMP_Object *)handle;
918 key = IGateProvider_enter(obj->gateHandle);
920 return(key);
921 }
923 Void GateMP_leave(GateMP_Handle handle, IArg key)
924 {
925 GateMP_Object *obj;
927 obj = (GateMP_Object *)handle;
928 IGateProvider_leave(obj->gateHandle, key);
929 }