e9d17c2b0adcd18de9a805cf57a4a3399ac5169d
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 Int GateMP_start(Void)
128 {
129 Int status;
130 LAD_ClientHandle handle;
131 struct LAD_CommandObj cmd;
132 union LAD_ResponseObj rsp;
134 handle = LAD_findHandle();
135 if (handle == LAD_MAXNUMCLIENTS) {
136 PRINTVERBOSE1(
137 "GateMP_start: can't find connection to daemon for pid %d\n",
138 getpid())
140 return -1;
141 }
143 cmd.cmd = LAD_GATEMP_START;
144 cmd.clientId = handle;
146 if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
147 PRINTVERBOSE1(
148 "GateMP_start: sending LAD command failed, status=%d\n", status)
149 return -1;
150 }
152 if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
153 PRINTVERBOSE1("GateMP_start: no LAD response, status=%d\n", status)
154 return -1;
155 }
157 status = rsp.gateMPStart.status;
159 PRINTVERBOSE2(
160 "GateMP_start: got LAD response for client %d, status=%d\n",
161 handle, status)
163 /*
164 * Initialize module state. Note that Nameserver handles are compatible
165 * across processes.
166 */
167 GateMP_module->nameServer = rsp.gateMPStart.nameServerHandle;
170 /* allocate memory for remote system gate handles */
171 if (status == GateMP_S_SUCCESS) {
172 GateMP_module->numRemoteSystem =
173 GateMP_getNumResources(GateMP_RemoteProtect_SYSTEM);
174 if (GateMP_module->numRemoteSystem > 0) {
175 GateMP_module->remoteSystemGates = calloc(1,
176 GateMP_module->numRemoteSystem *
177 sizeof(IGateProvider_Handle));
179 if (GateMP_module->remoteSystemGates == NULL) {
180 status = GateMP_E_MEMORY;
181 PRINTVERBOSE0("GateMP_start: memory allocation failed")
182 }
183 }
184 else {
185 GateMP_module->remoteSystemGates = NULL;
186 }
187 }
189 if (status == GateMP_S_SUCCESS) {
190 /* Open default gate */
191 status = GateMP_open("_GateMP_TI_dGate", &GateMP_module->defaultGate);
192 if (status < 0) {
193 PRINTVERBOSE1("GateMP_start: could not open default gate, \
194 status=%d\n", status)
195 }
196 }
198 /* in failure case, release acquired resources in reverse order */
199 if (status < 0) {
200 GateMP_stop();
201 }
203 GateMP_module->isStarted = TRUE;
205 return status;
206 }
208 Int GateMP_stop(Void)
209 {
210 Int status = GateMP_S_SUCCESS;
212 PRINTVERBOSE0("GateMP_stop: entered\n")
214 /* close the default gate */
215 if (GateMP_module->defaultGate) {
216 GateMP_close(&GateMP_module->defaultGate);
217 GateMP_module->defaultGate = NULL;
218 }
220 /* free system gate array */
221 if (GateMP_module->remoteSystemGates != NULL) {
222 free(GateMP_module->remoteSystemGates);
223 GateMP_module->remoteSystemGates = NULL;
224 }
226 GateMP_module->isStarted = FALSE;
228 return status;
229 }
231 Void GateMP_Params_init(GateMP_Params *params)
232 {
233 if (params != NULL) {
234 memcpy(params, &GateMP_defInstParams, sizeof(GateMP_Params));
235 }
236 else {
237 PRINTVERBOSE0("GateMP_Params_init: Params argument cannot be NULL")
238 }
240 return;
241 }
243 GateMP_Handle GateMP_create(const GateMP_Params *params)
244 {
245 _GateMP_Params _params;
246 GateMP_Handle handle = NULL;
248 if (GateMP_module->isStarted == FALSE) {
249 PRINTVERBOSE0("GateMP_create: GateMP module has not been started!")
250 }
251 else {
252 memset(&_params, 0, sizeof(_GateMP_Params));
253 memcpy(&_params, params, sizeof(GateMP_Params));
255 handle = _GateMP_create(&_params);
256 }
258 return(handle);
259 }
261 static GateMP_Handle _GateMP_create(const _GateMP_Params *params)
262 {
263 GateMP_Handle handle = NULL;
264 GateMP_Object * obj = NULL;
265 Int status;
267 /* allocate the instance object */
268 obj = (GateMP_Object *)calloc(1, sizeof(GateMP_Object));
270 if (obj != NULL) {
271 status = GateMP_Instance_init(obj, params);
272 if (status < 0) {
273 free(obj);
274 }
275 else {
276 handle = (GateMP_Handle)obj;
277 }
278 }
279 else {
280 PRINTVERBOSE0("GateMP_create: Memory allocation failed")
281 }
283 return(handle);
284 }
286 Int GateMP_open(String name, GateMP_Handle *handle)
287 {
288 Int status = GateMP_S_SUCCESS;
289 UInt32 len;
290 UInt32 nsValue[4];
291 GateMP_Object * obj = NULL;
292 UInt32 arg;
293 UInt32 mask;
294 UInt32 creatorProcId;
295 _GateMP_Params params;
297 /* assert that a valid pointer has been supplied */
298 if (handle == NULL) {
299 PRINTVERBOSE0("GateMP_open: handle cannot be null")
300 status = GateMP_E_INVALIDARG;
301 }
303 if (status == GateMP_S_SUCCESS) {
304 len = sizeof(nsValue);
306 status = NameServer_get(GateMP_module->nameServer, name, &nsValue,
307 &len, NULL);
309 if (status < 0) {
310 *handle = NULL;
311 status = GateMP_E_NOTFOUND;
312 }
313 else {
314 arg = nsValue[2];
315 mask = nsValue[3];
316 creatorProcId = nsValue[1] >> 16;
317 }
318 }
320 if (status == GateMP_S_SUCCESS) {
321 /*
322 * The least significant bit of nsValue[1] == 0 means its a
323 * local (private) GateMP, otherwise its a remote (shared) GateMP.
324 */
325 if ((nsValue[1] & 0x1) == 0) {
326 if ((nsValue[1] >> 16) != MultiProc_self()) {
327 /* error: trying to open another processor's private gate */
328 *handle = NULL;
329 PRINTVERBOSE0("GateMP_open: cannot open private gate from \
330 another processor")
331 status = GateMP_E_FAIL;
332 }
333 else if (nsValue[0] != getpid()) {
334 /* error: trying to open another process's private gate */
335 *handle = NULL;
336 PRINTVERBOSE0("GateMP_open: cannot open private gate from \
337 another process")
338 status = GateMP_E_FAIL;
339 }
340 }
341 }
343 if (status == GateMP_S_SUCCESS) {
344 /* local gate */
345 if (GETREMOTE(mask) == GateMP_RemoteProtect_NONE) {
346 if (creatorProcId != MultiProc_self()) {
347 status = GateMP_E_FAIL;
348 }
349 else {
350 *handle = (GateMP_Handle)arg;
351 obj = (GateMP_Object *)(*handle);
352 pthread_mutex_lock(&GateMP_module->mutex);
353 obj->numOpens++;
354 pthread_mutex_unlock(&GateMP_module->mutex);
355 }
356 }
357 else {
358 /* remote case */
359 switch (GETREMOTE(mask)) {
360 case GateMP_RemoteProtect_SYSTEM:
361 case GateMP_RemoteProtect_CUSTOM1:
362 case GateMP_RemoteProtect_CUSTOM2:
363 obj = GateMP_module->remoteSystemGates[arg];
364 break;
366 default:
367 status = GateMP_E_FAIL;
368 PRINTVERBOSE0("GateMP_open: unsupported remote protection \
369 type")
370 break;
371 }
373 /* If the object is NULL, then it must have been created
374 * on a remote processor or in another process on the
375 * local processor. Need to create a local object. This is
376 * accomplished by setting the openFlag to TRUE.
377 */
378 if (status == GateMP_S_SUCCESS) {
379 if (obj == NULL) {
380 /* create a GateMP object with the openFlag set to true */
381 params.name = NULL;
382 params.openFlag = TRUE;
383 params.sharedAddr = NULL;
384 params.resourceId = arg;
385 params.localProtect = GETLOCAL(mask);
386 params.remoteProtect = GETREMOTE(mask);
388 obj = (GateMP_Object *)_GateMP_create(¶ms);
390 if (obj == NULL) {
391 status = GateMP_E_FAIL;
392 }
393 }
394 else {
395 pthread_mutex_lock(&GateMP_module->mutex);
396 obj->numOpens++;
397 pthread_mutex_unlock(&GateMP_module->mutex);
398 }
399 }
401 /* Return the "opened" GateMP instance */
402 *handle = (GateMP_Handle)obj;
403 }
404 }
406 return status;
407 }
409 GateMP_Handle GateMP_getDefaultRemote()
410 {
411 return(GateMP_module->defaultGate);
412 }
414 GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
415 {
416 GateMP_Object *obj;
418 obj = (GateMP_Object *)handle;
419 return(obj->localProtect);
420 }
422 GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
423 {
424 GateMP_Object *obj;
426 obj = (GateMP_Object *)handle;
427 return (obj->remoteProtect);
428 }
430 static Int GateMP_getNumResources(GateMP_RemoteProtect type)
431 {
432 Int status;
433 LAD_ClientHandle handle;
434 struct LAD_CommandObj cmd;
435 union LAD_ResponseObj rsp;
437 handle = LAD_findHandle();
438 if (handle == LAD_MAXNUMCLIENTS) {
439 PRINTVERBOSE1(
440 "GateMP_getNumResources: can't find connection to daemon for pid %d\n",
441 getpid())
443 return -1;
444 }
446 cmd.cmd = LAD_GATEMP_GETNUMRESOURCES;
447 cmd.clientId = handle;
448 cmd.args.gateMPGetNumResources.type = type;
451 if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
452 PRINTVERBOSE1(
453 "GateMP_getNumResources: sending LAD command failed, status=%d\n", status)
454 return -1;
455 }
457 if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
458 PRINTVERBOSE1("GateMP_getNumResources: no LAD response, status=%d\n", status)
459 return -1;
460 }
462 status = rsp.gateMPGetNumResources.status;
464 PRINTVERBOSE2(
465 "GateMP_getNumResources: got LAD response for client %d, status=%d\n",
466 handle, status)
469 return (rsp.gateMPGetNumResources.value);
470 }
472 static Int GateMP_getFreeResource(GateMP_RemoteProtect type)
473 {
474 Int status;
475 LAD_ClientHandle handle;
476 struct LAD_CommandObj cmd;
477 union LAD_ResponseObj rsp;
479 handle = LAD_findHandle();
480 if (handle == LAD_MAXNUMCLIENTS) {
481 PRINTVERBOSE1(
482 "GateMP_getFreeResource: can't find connection to daemon for pid %d\n",
483 getpid())
485 return -1;
486 }
488 cmd.cmd = LAD_GATEMP_GETFREERESOURCE;
489 cmd.clientId = handle;
490 cmd.args.gateMPGetFreeResource.type = type;
492 if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
493 PRINTVERBOSE1(
494 "GateMP_getFreeResource: sending LAD command failed, status=%d\n", status)
495 return -1;
496 }
498 if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
499 PRINTVERBOSE1("GateMP_getFreeResource: no LAD response, status=%d\n", status)
500 return -1;
501 }
503 status = rsp.gateMPGetFreeResource.status;
505 PRINTVERBOSE2(
506 "GateMP_getNumResources: got LAD response for client %d, status=%d\n",
507 handle, status)
509 return (rsp.gateMPGetFreeResource.id);
510 }
512 static Int GateMP_releaseResource(UInt id, GateMP_RemoteProtect type)
513 {
514 Int status;
515 LAD_ClientHandle handle;
516 struct LAD_CommandObj cmd;
517 union LAD_ResponseObj rsp;
519 handle = LAD_findHandle();
520 if (handle == LAD_MAXNUMCLIENTS) {
521 PRINTVERBOSE1(
522 "GateMP_releaseResource: can't find connection to daemon for pid %d\n",
523 getpid())
525 return -1;
526 }
528 cmd.cmd = LAD_GATEMP_RELEASERESOURCE;
529 cmd.clientId = handle;
530 cmd.args.gateMPReleaseResource.type = type;
531 cmd.args.gateMPReleaseResource.id = id;
533 if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
534 PRINTVERBOSE1(
535 "GateMP_releaseResource: sending LAD command failed, status=%d\n", status)
536 return -1;
537 }
539 if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
540 PRINTVERBOSE1("GateMP_releaseResource: no LAD response, status=%d\n", status)
541 return -1;
542 }
544 status = rsp.gateMPReleaseResource.status;
546 PRINTVERBOSE2(
547 "GateMP_releaseResource: got LAD response for client %d, status=%d\n",
548 handle, status)
550 return (status);
551 }
553 Bool GateMP_isSetup(Void)
554 {
555 Int status;
556 LAD_ClientHandle handle;
557 struct LAD_CommandObj cmd;
558 union LAD_ResponseObj rsp;
560 handle = LAD_findHandle();
561 if (handle == LAD_MAXNUMCLIENTS) {
562 PRINTVERBOSE1(
563 "GateMP_isSetup: can't find connection to daemon for pid %d\n",
564 getpid())
566 return -1;
567 }
569 cmd.cmd = LAD_GATEMP_ISSETUP;
570 cmd.clientId = handle;
571 cmd.args.gateMPIsSetup.result = FALSE;
573 if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
574 PRINTVERBOSE1(
575 "GateMP_isSetup: sending LAD command failed, status=%d\n", status)
576 return -1 ;
577 }
579 if ((status = LAD_getResponse(handle, &rsp)) != LAD_SUCCESS) {
580 PRINTVERBOSE1("GateMP_isSetup: no LAD response, status=%d\n", status)
581 return -1;
582 }
584 status = rsp.gateMPIsSetup.status;
586 PRINTVERBOSE2(
587 "GateMP_isSetup: got LAD response for client %d, status=%d\n",
588 handle, status)
590 assert(status == GateMP_S_SUCCESS);
592 return (rsp.gateMPIsSetup.result);
593 }
595 Int GateMP_close(GateMP_Handle *handle)
596 {
597 GateMP_Object * obj;
598 Int status = GateMP_S_SUCCESS;
600 obj = (GateMP_Object *)(*handle);
602 pthread_mutex_lock(&GateMP_module->mutex);
604 /* Cannot call with the numOpens equal to zero. This is either
605 * a created handle or been closed already.
606 */
607 if (obj->numOpens == 0) {
608 status = GateMP_E_INVALIDSTATE;
609 }
611 if (status == GateMP_S_SUCCESS) {
612 obj->numOpens--;
614 /* If the count is zero and the gate is opened, then this
615 * object was created in the open (i.e. the create happened
616 * on a remote processor or another process).
617 */
618 if ((obj->numOpens == 0) && (obj->objType == Ipc_ObjType_OPENDYNAMIC)) {
619 GateMP_delete(handle);
620 }
621 else {
622 *handle = NULL;
623 }
624 }
626 pthread_mutex_unlock(&GateMP_module->mutex);
628 return(status);
629 }
631 Int GateMP_delete(GateMP_Handle *handlePtr)
632 {
633 Int status = GateMP_S_SUCCESS;
635 if ((handlePtr == NULL) || (*handlePtr == NULL)) {
636 status = GateMP_E_INVALIDARG;
637 }
638 else {
639 GateMP_Instance_finalize((GateMP_Object *)(*handlePtr), 0);
640 free(*handlePtr);
641 *handlePtr = NULL;
642 }
644 return status;
645 }
647 static Int GateMP_Instance_init(GateMP_Object *obj,
648 const _GateMP_Params *params)
649 {
650 GateMP_RemoteSystemProxy_Params systemParams;
651 UInt32 nsValue[4];
653 obj->resourceId = (UInt)-1;
655 /* TODO: create/open the local gate instance */
656 obj->localGate = NULL;
658 /* open GateMP instance */
659 if (params->openFlag == TRUE) {
660 /* all open work done here except for remote gateHandle */
661 obj->localProtect = params->localProtect;
662 obj->remoteProtect = params->remoteProtect;
663 obj->nsKey = 0;
664 obj->numOpens = 1;
666 obj->objType = Ipc_ObjType_OPENDYNAMIC;
667 }
669 /* create GateMP instance */
670 else {
671 obj->localProtect = params->localProtect;
672 obj->remoteProtect = params->remoteProtect;
673 obj->nsKey = 0;
674 obj->numOpens = 0;
676 if (obj->remoteProtect == GateMP_RemoteProtect_NONE) {
677 /* TODO: create a local gate */
678 obj->gateHandle = obj->localGate;
680 /* create a local gate allocating from the local heap */
681 obj->objType = Ipc_ObjType_LOCAL;
682 obj->arg = (Bits32)obj;
683 obj->mask = SETMASK(obj->remoteProtect, obj->localProtect);
684 obj->creatorProcId = MultiProc_self();
686 if (params->name != NULL) {
687 /* nsv[0] : creator process id
688 * nsv[1](31:16): creator procId
689 * nsv[1](15:0) : 0 = local gate, 1 = remote gate
690 * nsv[2] : local gate object
691 * nsv[3] : protection mask
692 */
693 nsValue[0] = getpid();
694 nsValue[1] = MultiProc_self() << 16;
695 nsValue[2] = obj->arg;
696 nsValue[3] = obj->mask;
697 obj->nsKey = NameServer_add(GateMP_module->nameServer,
698 params->name, &nsValue, sizeof(nsValue));
699 if (obj->nsKey == NULL) {
700 PRINTVERBOSE0("GateMP_Instance_init: NameServer_add failed")
701 return (GateMP_E_FAIL);
702 }
703 }
705 /* nothing else to do for local gates */
706 return(0);
707 }
709 obj->objType = Ipc_ObjType_CREATEDYNAMIC;
710 }
712 /* proxy work for open and create done here */
713 switch (obj->remoteProtect) {
714 /* TODO: implement other types of remote protection */
715 case GateMP_RemoteProtect_SYSTEM:
716 case GateMP_RemoteProtect_CUSTOM1:
717 case GateMP_RemoteProtect_CUSTOM2:
718 if (obj->objType == Ipc_ObjType_OPENDYNAMIC) {
719 /* resourceId set by open call */
720 obj->resourceId = params->resourceId;
721 }
722 else {
723 /* created instance */
724 obj->resourceId = GateMP_getFreeResource(obj->remoteProtect);
725 if (obj->resourceId == -1) {
726 return (GateMP_E_RESOURCE);
727 }
728 }
730 /* create the proxy object */
731 GateMP_RemoteSystemProxy_Params_init(&systemParams);
732 systemParams.resourceId = obj->resourceId;
733 systemParams.openFlag = (obj->objType == Ipc_ObjType_OPENDYNAMIC);
734 //systemParams.sharedAddr = obj->proxyAttrs;
736 /*
737 * TODO: Currently passing in localProtect instead of localGate,
738 * since existing GateHWSpinlock.h defines it this way
739 */
740 obj->gateHandle = (IGateProvider_Handle)
741 GateMP_RemoteSystemProxy_create(obj->localProtect,
742 &systemParams);
744 if (obj->gateHandle == NULL) {
745 PRINTVERBOSE0("GateMP_Instance_init: failed to create proxy\n");
746 return(GateMP_E_FAIL);
747 }
749 /* store the object handle in the gate array */
750 GateMP_module->remoteSystemGates[obj->resourceId] = obj;
751 break;
753 default:
754 break;
755 }
757 /* add name/attrs to NameServer table */
758 if (obj->objType != Ipc_ObjType_OPENDYNAMIC) {
759 obj->arg = obj->resourceId;
760 obj->mask = SETMASK(obj->remoteProtect, obj->localProtect);
762 if (params->name != NULL) {
763 /* nsv[0] : creator pid
764 * nsv[1](31:16): creator procId
765 * nsv[1](15:0) : 0 = local gate, 1 = remote gate
766 * nsv[2] : resource id
767 * nsv[3] : protection mask
768 */
769 nsValue[0] = getpid();
770 nsValue[1] = MultiProc_self() << 16 | 1;
771 nsValue[2] = obj->resourceId;
772 nsValue[3] = obj->mask;
773 obj->nsKey = NameServer_add(GateMP_module->nameServer,
774 params->name, &nsValue, sizeof(nsValue));
776 if (obj->nsKey == NULL) {
777 PRINTVERBOSE0("GateMP_Instance_init: NameServer_add failed")
778 return (GateMP_E_FAIL);
779 }
780 }
781 }
783 return (GateMP_S_SUCCESS);
784 }
786 static Void GateMP_Instance_finalize(GateMP_Object *obj, Int status)
787 {
788 GateMP_Object ** remoteGates = NULL;
790 /* remove from NameServer */
791 if (obj->nsKey != 0) {
792 NameServer_removeEntry(GateMP_module->nameServer, obj->nsKey);
793 obj->nsKey = 0;
794 }
796 /* delete the remote gate */
797 switch (obj->remoteProtect) {
799 case GateMP_RemoteProtect_SYSTEM:
800 case GateMP_RemoteProtect_CUSTOM1:
801 case GateMP_RemoteProtect_CUSTOM2:
802 if (obj->gateHandle != NULL) {
803 GateMP_RemoteSystemProxy_delete(
804 (GateMP_RemoteSystemProxy_Handle *)&obj->gateHandle);
805 }
806 remoteGates = GateMP_module->remoteSystemGates;
807 break;
809 case GateMP_RemoteProtect_NONE:
810 /* nothing else to finalize */
811 return;
813 default:
814 /* Nothing to do */
815 break;
816 }
818 /* TODO: close/delete local gate */
820 /* clear the handle array entry in local memory */
821 if (obj->resourceId != (UInt)-1) {
822 remoteGates[obj->resourceId] = NULL;
823 }
825 if ((obj->objType != Ipc_ObjType_OPENDYNAMIC)
826 && (obj->resourceId != (UInt)-1)) {
827 GateMP_releaseResource(obj->resourceId, obj->remoteProtect);
828 }
830 }
832 IArg GateMP_enter(GateMP_Handle handle)
833 {
834 GateMP_Object * obj;
835 IArg key;
837 obj = (GateMP_Object *)handle;
838 key = IGateProvider_enter(obj->gateHandle);
840 return(key);
841 }
843 Void GateMP_leave(GateMP_Handle handle, IArg key)
844 {
845 GateMP_Object *obj;
847 obj = (GateMP_Object *)handle;
848 IGateProvider_leave(obj->gateHandle, key);
849 }