1 /*
2 * Copyright (c) 2012-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 */
36 #include <xdc/std.h>
37 #include <string.h>
38 #include <xdc/runtime/Error.h>
39 #include <xdc/runtime/Assert.h>
40 #include <xdc/runtime/System.h>
41 #include <xdc/runtime/IGateProvider.h>
42 #include <xdc/runtime/IHeap.h>
43 #include <xdc/runtime/Memory.h>
44 #include <xdc/runtime/Log.h>
46 #include <ti/sdo/ipc/interfaces/IGateMPSupport.h>
48 #include <ti/sysbios/gates/GateMutexPri.h>
49 #include <ti/sysbios/gates/GateSwi.h>
50 #include <ti/sysbios/gates/GateAll.h>
51 #include <ti/sysbios/hal/Cache.h>
52 #include <ti/sysbios/hal/Hwi.h>
54 #include <ti/sdo/ipc/_Ipc.h>
55 #include <ti/sdo/utils/_MultiProc.h>
56 #include <ti/sdo/ipc/_GateMP.h>
57 #include <ti/sdo/utils/_NameServer.h>
58 #include <ti/sdo/ipc/_SharedRegion.h>
60 #include "package/internal/GateMP.xdc.h"
62 /* Helper macros */
63 #define GETREMOTE(mask) ((ti_sdo_ipc_GateMP_RemoteProtect)((mask) >> 8))
64 #define GETLOCAL(mask) ((ti_sdo_ipc_GateMP_LocalProtect)((mask) & 0xFF))
65 #define SETMASK(remoteProtect, localProtect) \
66 ((Bits32)((remoteProtect) << 8 | (localProtect)))
68 /* Values used to populate the resource 'inUse' arrays */
69 #define UNUSED ((UInt8)0)
70 #define USED ((UInt8)1)
71 #define RESERVED ((UInt8)-1)
73 #ifdef __ti__
74 #pragma FUNC_EXT_CALLED(GateMP_Params_init);
75 #pragma FUNC_EXT_CALLED(GateMP_create);
76 #pragma FUNC_EXT_CALLED(GateMP_close);
77 #pragma FUNC_EXT_CALLED(GateMP_delete);
78 #pragma FUNC_EXT_CALLED(GateMP_enter);
79 #pragma FUNC_EXT_CALLED(GateMP_getDefaultRemote);
80 #pragma FUNC_EXT_CALLED(GateMP_getLocalProtect);
81 #pragma FUNC_EXT_CALLED(GateMP_getRemoteProtect);
82 #pragma FUNC_EXT_CALLED(GateMP_leave);
83 #pragma FUNC_EXT_CALLED(GateMP_open);
84 #pragma FUNC_EXT_CALLED(GateMP_openByAddr);
85 #pragma FUNC_EXT_CALLED(GateMP_sharedMemReq);
86 #endif
88 /*
89 * ======== GateMP_getSharedParams ========
90 */
91 static Void GateMP_getSharedParams(GateMP_Params *sparams,
92 const ti_sdo_ipc_GateMP_Params *params)
93 {
94 sparams->name = params->name;
95 sparams->regionId = params->regionId;
96 sparams->sharedAddr = params->sharedAddr;
97 sparams->localProtect = (GateMP_LocalProtect)
98 params->localProtect;
99 sparams->remoteProtect = (GateMP_RemoteProtect)
100 params->remoteProtect;
101 }
103 /*
104 * ======== GateMP_getRTSCParams ========
105 */
106 static Void GateMP_getRTSCParams(ti_sdo_ipc_GateMP_Params *params,
107 const GateMP_Params *sparams)
108 {
110 ti_sdo_ipc_GateMP_Params_init(params);
112 params->name = sparams->name;
113 params->regionId = sparams->regionId;
114 params->sharedAddr = sparams->sharedAddr;
115 params->localProtect = (ti_sdo_ipc_GateMP_LocalProtect)
116 sparams->localProtect;
117 params->remoteProtect = (ti_sdo_ipc_GateMP_RemoteProtect)
118 sparams->remoteProtect;
119 }
121 /*
122 *************************************************************************
123 * Common Header Functions
124 *************************************************************************
125 */
127 /*
128 * ======== GateMP_Params_init ========
129 */
130 Void GateMP_Params_init(GateMP_Params *sparams)
131 {
132 ti_sdo_ipc_GateMP_Params params;
134 ti_sdo_ipc_GateMP_Params_init(¶ms);
135 GateMP_getSharedParams(sparams, ¶ms);
136 }
138 /*
139 * ======== GateMP_create ========
140 */
141 GateMP_Handle GateMP_create(const GateMP_Params *sparams)
142 {
143 ti_sdo_ipc_GateMP_Params params;
144 ti_sdo_ipc_GateMP_Object *obj;
145 Error_Block eb;
147 GateMP_getRTSCParams(¶ms, (Ptr)sparams);
149 Error_init(&eb);
151 /* call the module create */
152 obj = ti_sdo_ipc_GateMP_create(¶ms, &eb);
154 return ((GateMP_Handle)obj);
155 }
157 /*
158 * ======== GateMP_close ========
159 */
160 Int GateMP_close(GateMP_Handle *handlePtr)
161 {
162 ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)*handlePtr;
163 UInt key;
164 Int count;
166 /*
167 * Cannot call with the numOpens equal to zero. This is either
168 * a created handle or been closed already.
169 */
170 Assert_isTrue((obj->numOpens != 0), ti_sdo_ipc_GateMP_A_invalidClose);
172 key = Hwi_disable();
173 count = --obj->numOpens;
174 Hwi_restore(key);
176 /*
177 * if the count is zero and the gate is opened, then this
178 * object was created in the open (i.e. the create happened
179 * on a remote processor.
180 */
181 if ((count == 0) && (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC)) {
182 GateMP_delete(handlePtr);
183 }
185 *handlePtr = NULL;
187 return (GateMP_S_SUCCESS);
188 }
190 /*
191 * ======== GateMP_delete ========
192 */
193 Int GateMP_delete(GateMP_Handle *handlePtr)
194 {
195 ti_sdo_ipc_GateMP_delete((ti_sdo_ipc_GateMP_Handle *)handlePtr);
197 return (GateMP_S_SUCCESS);
198 }
200 /*
201 * ======== GateMP_enter ========
202 */
203 IArg GateMP_enter(GateMP_Handle handle)
204 {
205 IArg key;
206 ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)handle;
208 Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
210 key = IGateProvider_enter(obj->gateHandle);
212 Log_write3(ti_sdo_ipc_GateMP_LM_enter,(UArg)obj->remoteProtect,
213 (UArg)obj->resourceId, key);
215 return (key);
216 }
218 /*
219 * ======== GateMP_leave ========
220 */
221 Void GateMP_leave(GateMP_Handle handle, IArg key)
222 {
223 ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)handle;
225 Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
227 IGateProvider_leave(obj->gateHandle, key);
229 Log_write3(ti_sdo_ipc_GateMP_LM_leave, (UArg)obj->remoteProtect,
230 (UArg)obj->resourceId, key);
231 }
233 /*
234 * ======== GateMP_open ========
235 */
236 Int GateMP_open(String name, GateMP_Handle *handlePtr)
237 {
238 SharedRegion_SRPtr sharedShmBase;
239 Int status;
240 ti_sdo_ipc_GateMP_Object *obj;
241 ti_sdo_ipc_GateMP_Params params;
242 Error_Block eb;
243 UInt key;
244 UInt32 len;
245 UInt32 mask;
246 UInt32 resourceId;
247 Ptr sharedAddr;
248 UInt32 nsValue[4];
250 Error_init(&eb);
252 /* Assert that a pointer has been supplied */
253 Assert_isTrue(handlePtr != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
255 len = sizeof(nsValue);
257 /*
258 * Get the Attrs out of the NameServer instance.
259 * Search all processors.
260 */
261 status = NameServer_get((NameServer_Handle)GateMP_module->nameServer, name,
262 &nsValue, &len, ti_sdo_utils_MultiProc_procIdList);
264 if (status < 0) {
265 *handlePtr = NULL;
266 return (GateMP_E_NOTFOUND);
267 }
269 /*
270 * The least significant bit of nsValue[1] == 0 means its a
271 * local GateMP, otherwise its a remote GateMP.
272 */
273 if (((nsValue[1] & 0x1) == 0) &&
274 ((nsValue[1] >> 16) != MultiProc_self())) {
275 /* Trying to open a local GateMP remotely */
276 *handlePtr = NULL;
277 return (GateMP_E_FAIL);
278 }
280 if ((nsValue[1] & 0x1) == 0) {
281 /*
282 * Opening a local GateMP locally. The GateMP is created
283 * from a local heap so don't do SharedRegion Ptr conversion.
284 */
285 sharedAddr = (Ptr)nsValue[0];
286 status = GateMP_openByAddr(sharedAddr, handlePtr);
287 }
288 else if (GateMP_module->hostSupport == FALSE) {
289 /* Opening a remote GateMP. Need to do SharedRegion Ptr conversion. */
290 sharedShmBase = (SharedRegion_SRPtr)nsValue[0];
291 sharedAddr = SharedRegion_getPtr(sharedShmBase);
292 status = GateMP_openByAddr(sharedAddr, handlePtr);
293 }
294 else {
295 /* need to track number of opens atomically */
296 key = Hwi_disable();
297 resourceId = nsValue[2];
298 mask = nsValue[3];
300 /* Remote case */
301 switch (GETREMOTE(mask)) {
302 case GateMP_RemoteProtect_SYSTEM:
303 obj = GateMP_module->remoteSystemGates[resourceId];
304 break;
306 case GateMP_RemoteProtect_CUSTOM1:
307 obj = GateMP_module->remoteCustom1Gates[resourceId];
308 break;
310 case GateMP_RemoteProtect_CUSTOM2:
311 obj = GateMP_module->remoteCustom2Gates[resourceId];
312 break;
314 default:
315 obj = NULL;
316 status = GateMP_E_FAIL;
317 break;
318 }
320 if (status == GateMP_S_SUCCESS) {
321 /*
322 * If the object is NULL, then it must have been created on a
323 * remote processor. Need to create a local object. This is
324 * accomplished by setting the openFlag to TRUE.
325 */
326 if (obj == NULL) {
327 /* Create a GateMP object with the openFlag set to true */
328 ti_sdo_ipc_GateMP_Params_init(¶ms);
329 params.openFlag = TRUE;
330 params.sharedAddr = NULL;
331 params.resourceId = resourceId;
332 params.localProtect = GETLOCAL(mask);
333 params.remoteProtect = GETREMOTE(mask);
335 obj = ti_sdo_ipc_GateMP_create(¶ms, &eb);
336 if (obj == NULL) {
337 status = GateMP_E_FAIL;
338 }
339 }
340 else {
341 obj->numOpens++;
342 }
343 }
345 /* Return the GateMP instance */
346 *handlePtr = (GateMP_Handle)obj;
348 /* restore hwi mask */
349 Hwi_restore(key);
350 }
352 return (status);
353 }
355 /*
356 * ======== GateMP_openByAddr ========
357 */
358 Int GateMP_openByAddr(Ptr sharedAddr, GateMP_Handle *handlePtr)
359 {
360 Int status = GateMP_S_SUCCESS;
361 UInt key;
362 ti_sdo_ipc_GateMP_Object *obj;
363 ti_sdo_ipc_GateMP_Params params;
364 ti_sdo_ipc_GateMP_Attrs *attrs;
365 UInt16 regionId;
366 Error_Block eb;
368 Error_init(&eb);
370 attrs = (ti_sdo_ipc_GateMP_Attrs *)sharedAddr;
372 /* get the region id and invalidate attrs is needed */
373 regionId = SharedRegion_getId(sharedAddr);
374 if (regionId != SharedRegion_INVALIDREGIONID) {
375 if (SharedRegion_isCacheEnabled(regionId)) {
376 Cache_inv(attrs, sizeof(ti_sdo_ipc_GateMP_Attrs), Cache_Type_ALL,
377 TRUE);
378 }
379 }
381 if (attrs->status != ti_sdo_ipc_GateMP_CREATED) {
382 *handlePtr = NULL;
383 status = GateMP_E_NOTFOUND;
384 }
385 else {
386 /* Local gate */
387 if (GETREMOTE(attrs->mask) == GateMP_RemoteProtect_NONE) {
388 if (attrs->creatorProcId != MultiProc_self()) {
389 Error_raise(&eb, ti_sdo_ipc_GateMP_E_localGate, 0, 0);
390 return (GateMP_E_FAIL);
391 }
393 /* need to atomically increment number of opens */
394 key = Hwi_disable();
396 obj = (ti_sdo_ipc_GateMP_Object *)attrs->arg;
397 *handlePtr = (GateMP_Handle)obj;
398 obj->numOpens++;
400 /* restore hwi mask */
401 Hwi_restore(key);
403 return (GateMP_S_SUCCESS);
404 }
406 /* need to track number of opens atomically */
407 key = Hwi_disable();
409 /* Remote case */
410 switch (GETREMOTE(attrs->mask)) {
411 case GateMP_RemoteProtect_SYSTEM:
412 obj = GateMP_module->remoteSystemGates[attrs->arg];
413 break;
415 case GateMP_RemoteProtect_CUSTOM1:
416 obj = GateMP_module->remoteCustom1Gates[attrs->arg];
417 break;
419 case GateMP_RemoteProtect_CUSTOM2:
420 obj = GateMP_module->remoteCustom2Gates[attrs->arg];
421 break;
423 default:
424 obj = NULL;
425 status = GateMP_E_FAIL;
426 break;
427 }
429 if (status == GateMP_S_SUCCESS) {
430 /*
431 * If the object is NULL, then it must have been created on a
432 * remote processor. Need to create a local object. This is
433 * accomplished by setting the openFlag to TRUE.
434 */
435 if (obj == NULL) {
436 /* Create a GateMP object with the openFlag set to true */
437 ti_sdo_ipc_GateMP_Params_init(¶ms);
438 params.openFlag = TRUE;
439 params.sharedAddr = sharedAddr;
440 params.resourceId = attrs->arg;
441 params.localProtect = GETLOCAL(attrs->mask);
442 params.remoteProtect = GETREMOTE(attrs->mask);
444 obj = ti_sdo_ipc_GateMP_create(¶ms, &eb);
445 if (obj == NULL) {
446 status = GateMP_E_FAIL;
447 }
448 }
449 else {
450 obj->numOpens++;
451 }
452 }
454 /* Return the GateMP instance */
455 *handlePtr = (GateMP_Handle)obj;
457 /* restore hwi mask */
458 Hwi_restore(key);
459 }
461 return (status);
462 }
464 /*
465 * ======== GateMP_sharedMemReq ========
466 */
467 SizeT GateMP_sharedMemReq(const GateMP_Params *params)
468 {
469 SizeT memReq, minAlign;
470 UInt16 regionId;
471 ti_sdo_ipc_GateMP_RemoteSystemProxy_Params systemParams;
472 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params custom1Params;
473 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params custom2Params;
475 if (params->sharedAddr) {
476 regionId = SharedRegion_getId(params->sharedAddr);
477 }
478 else {
479 regionId = params->regionId;
480 }
482 Assert_isTrue(regionId != SharedRegion_INVALIDREGIONID,
483 ti_sdo_ipc_Ipc_A_internal);
485 minAlign = Memory_getMaxDefaultTypeAlign();
486 if (SharedRegion_getCacheLineSize(regionId) > minAlign) {
487 minAlign = SharedRegion_getCacheLineSize(regionId);
488 }
490 memReq = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
492 /* add the amount of shared memory required by proxy */
493 if (params->remoteProtect == GateMP_RemoteProtect_SYSTEM) {
494 ti_sdo_ipc_GateMP_RemoteSystemProxy_Params_init(&systemParams);
495 systemParams.regionId = regionId;
496 memReq += ti_sdo_ipc_GateMP_RemoteSystemProxy_sharedMemReq(
497 (IGateMPSupport_Params *)&systemParams);
498 }
499 else if (params->remoteProtect == GateMP_RemoteProtect_CUSTOM1) {
500 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params_init(&custom1Params);
501 custom1Params.regionId = regionId;
502 memReq += ti_sdo_ipc_GateMP_RemoteCustom1Proxy_sharedMemReq(
503 (IGateMPSupport_Params *)&custom1Params);
504 }
505 else if (params->remoteProtect == GateMP_RemoteProtect_CUSTOM2) {
506 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params_init(&custom2Params);
507 custom2Params.regionId = regionId;
508 memReq += ti_sdo_ipc_GateMP_RemoteCustom2Proxy_sharedMemReq(
509 (IGateMPSupport_Params *)&custom2Params);
510 }
512 return (memReq);
513 }
515 /*
516 *************************************************************************
517 * Module functions
518 *************************************************************************
519 */
521 /*
522 * ======== ti_sdo_ipc_GateMP_createLocal ========
523 */
524 IGateProvider_Handle ti_sdo_ipc_GateMP_createLocal(
525 ti_sdo_ipc_GateMP_LocalProtect localProtect)
526 {
527 IGateProvider_Handle gateHandle;
529 /* Create the local gate. */
530 switch (localProtect) {
531 case GateMP_LocalProtect_NONE:
532 /* Plug with the GateNull singleton */
533 gateHandle = GateMP_module->gateNull;
534 break;
536 case GateMP_LocalProtect_INTERRUPT:
537 /* Plug with the GateAll singleton */
538 gateHandle = GateMP_module->gateAll;
539 break;
541 case GateMP_LocalProtect_TASKLET:
542 /* Plug with the GateSwi singleton */
543 gateHandle = GateMP_module->gateSwi;
544 break;
546 case GateMP_LocalProtect_THREAD:
547 case GateMP_LocalProtect_PROCESS:
548 /* Plug with the GateMutexPri singleton */
549 gateHandle = GateMP_module->gateMutexPri;
550 break;
552 default:
553 /* Invalid local protection level encountered */
554 Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
555 break;
556 }
558 return (gateHandle);
559 }
561 /*
562 * ======== GateMP_getDefaultRemote ========
563 */
564 GateMP_Handle GateMP_getDefaultRemote()
565 {
566 return ((GateMP_Handle)GateMP_module->defaultGate);
567 }
569 /*
570 * ======== GateMP_getLocalProtect ========
571 */
572 GateMP_LocalProtect GateMP_getLocalProtect(GateMP_Handle handle)
573 {
574 ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)handle;
576 Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
578 return ((GateMP_LocalProtect)obj->localProtect);
579 }
581 /*
582 * ======== GateMP_getRemoteProtect ========
583 */
584 GateMP_RemoteProtect GateMP_getRemoteProtect(GateMP_Handle handle)
585 {
586 ti_sdo_ipc_GateMP_Object *obj = (ti_sdo_ipc_GateMP_Object *)handle;
588 Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_nullArgument);
590 return ((GateMP_RemoteProtect)obj->remoteProtect);
591 }
593 /*
594 * ======== ti_sdo_ipc_GateMP_getRegion0ReservedSize ========
595 */
596 SizeT ti_sdo_ipc_GateMP_getRegion0ReservedSize(Void)
597 {
598 SizeT reserved, minAlign;
600 minAlign = Memory_getMaxDefaultTypeAlign();
602 if (SharedRegion_getCacheLineSize(0) > minAlign) {
603 minAlign = SharedRegion_getCacheLineSize(0);
604 }
606 reserved = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
608 reserved += _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
610 if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
611 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
612 reserved += _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
613 }
615 if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
616 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
617 reserved += _Ipc_roundup(GateMP_module->numRemoteCustom2, minAlign);
618 }
620 return (reserved);
621 }
623 /*
624 * ======== ti_sdo_ipc_GateMP_setRegion0Reserved ========
625 */
626 Void ti_sdo_ipc_GateMP_setRegion0Reserved(Ptr sharedAddr)
627 {
628 ti_sdo_ipc_GateMP_Reserved *reserve;
629 SizeT minAlign, offset;
630 UInt i;
631 Bits32 *delegateReservedMask;
632 UInt32 nsValue[6];
634 minAlign = Memory_getMaxDefaultTypeAlign();
635 if (SharedRegion_getCacheLineSize(0) > minAlign) {
636 minAlign = SharedRegion_getCacheLineSize(0);
637 }
639 /* setup ti_sdo_ipc_GateMP_Reserved fields */
640 reserve = (ti_sdo_ipc_GateMP_Reserved *)sharedAddr;
641 reserve->version = ti_sdo_ipc_GateMP_VERSION;
643 if (SharedRegion_isCacheEnabled(0)) {
644 Cache_wbInv(sharedAddr, sizeof(ti_sdo_ipc_GateMP_Reserved),
645 Cache_Type_ALL, TRUE);
646 }
648 /*
649 * initialize the in-use array in shared memory for the system gates.
650 */
651 offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
652 GateMP_module->remoteSystemInUse =
653 (Ptr)((UInt32)sharedAddr + offset);
655 memset(GateMP_module->remoteSystemInUse, 0,
656 GateMP_module->numRemoteSystem * sizeof(UInt8));
657 delegateReservedMask =
658 ti_sdo_ipc_GateMP_RemoteSystemProxy_getReservedMask();
659 if (delegateReservedMask != NULL) {
660 for (i = 0; i < GateMP_module->numRemoteSystem; i++) {
661 if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
662 GateMP_module->remoteSystemInUse[i] = RESERVED;
663 }
664 }
665 }
667 if (SharedRegion_isCacheEnabled(0)) {
668 Cache_wbInv(GateMP_module->remoteSystemInUse,
669 GateMP_module->numRemoteSystem * sizeof(UInt8),
670 Cache_Type_ALL,
671 TRUE);
672 }
674 /*
675 * initialize the in-use array in shared memory for the custom1 gates.
676 * Need to check if this proxy is the same as system
677 */
678 offset = _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
679 if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
680 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
681 if (GateMP_module->numRemoteCustom1 != 0) {
682 GateMP_module->remoteCustom1InUse =
683 GateMP_module->remoteSystemInUse + offset;
684 }
686 memset(GateMP_module->remoteCustom1InUse, 0,
687 GateMP_module->numRemoteCustom1 * sizeof(UInt8));
688 delegateReservedMask =
689 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_getReservedMask();
690 if (delegateReservedMask != NULL) {
691 for (i = 0; i < GateMP_module->numRemoteCustom1; i++) {
692 if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
693 GateMP_module->remoteCustom1InUse[i] = RESERVED;
694 }
695 }
696 }
697 if (SharedRegion_isCacheEnabled(0)) {
698 Cache_wbInv(GateMP_module->remoteCustom1InUse,
699 GateMP_module->numRemoteCustom1 * sizeof(UInt8),
700 Cache_Type_ALL,
701 TRUE);
702 }
703 }
704 else {
705 GateMP_module->remoteCustom1InUse = GateMP_module->remoteSystemInUse;
706 GateMP_module->remoteCustom1Gates = GateMP_module->remoteSystemGates;
707 }
709 /*
710 * initialize the in-use array in shared memory for the custom2 gates.
711 * Need to check if this proxy is the same as system or custom1
712 */
713 offset = _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
714 if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
715 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
716 if (GateMP_module->numRemoteCustom2 != 0) {
717 GateMP_module->remoteCustom2InUse =
718 GateMP_module->remoteCustom1InUse + offset;
719 }
721 memset(GateMP_module->remoteCustom2InUse, 0,
722 GateMP_module->numRemoteCustom2 * sizeof(UInt8));
723 delegateReservedMask =
724 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_getReservedMask();
725 if (delegateReservedMask != NULL) {
726 for (i = 0; i < GateMP_module->numRemoteCustom2; i++) {
727 if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
728 GateMP_module->remoteCustom2InUse[i] = RESERVED;
729 }
730 }
731 }
733 if (SharedRegion_isCacheEnabled(0)) {
734 Cache_wbInv(GateMP_module->remoteCustom2InUse,
735 GateMP_module->numRemoteCustom2 * sizeof(UInt8),
736 Cache_Type_ALL,
737 TRUE);
738 }
739 }
740 else if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
741 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
742 GateMP_module->remoteCustom2InUse =
743 GateMP_module->remoteCustom1InUse;
744 GateMP_module->remoteCustom2Gates =
745 GateMP_module->remoteCustom1Gates;
746 }
747 else {
748 GateMP_module->remoteCustom2InUse = GateMP_module->remoteSystemInUse;
749 GateMP_module->remoteCustom2Gates = GateMP_module->remoteSystemGates;
750 }
752 if (GateMP_module->hostSupport == TRUE) {
753 /* Add special entry to store inuse arrays' location and size */
754 nsValue[0] = (UInt32)GateMP_module->remoteSystemInUse;
755 nsValue[1] = (UInt32)GateMP_module->remoteCustom1InUse;
756 nsValue[2] = (UInt32)GateMP_module->remoteCustom2InUse;
757 nsValue[3] = GateMP_module->numRemoteSystem;
758 nsValue[4] = GateMP_module->numRemoteCustom1;
759 nsValue[5] = GateMP_module->numRemoteCustom2;
760 GateMP_module->nsKey = NameServer_add((NameServer_Handle)
761 GateMP_module->nameServer, "_GateMP_TI_info", &nsValue,
762 sizeof(nsValue));
763 }
764 }
766 /*
767 * ======== ti_sdo_ipc_GateMP_openRegion0Reserved ========
768 */
769 Void ti_sdo_ipc_GateMP_openRegion0Reserved(Ptr sharedAddr)
770 {
771 ti_sdo_ipc_GateMP_Reserved *reserve;
772 SizeT minAlign, offset;
774 minAlign = Memory_getMaxDefaultTypeAlign();
775 if (SharedRegion_getCacheLineSize(0) > minAlign) {
776 minAlign = SharedRegion_getCacheLineSize(0);
777 }
780 /* setup ti_sdo_ipc_GateMP_Reserved fields */
781 reserve = (ti_sdo_ipc_GateMP_Reserved *)sharedAddr;
783 if (reserve->version != ti_sdo_ipc_GateMP_VERSION) {
784 /* Version mismatch: return an error */
785 Error_raise(NULL, ti_sdo_ipc_Ipc_E_versionMismatch, reserve->version,
786 ti_sdo_ipc_GateMP_VERSION);
787 return;
788 }
790 offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
791 GateMP_module->remoteSystemInUse =
792 (Ptr)((UInt32)sharedAddr + offset);
794 /*
795 * initialize the in-use array in shared memory for the custom1 gates.
796 * Need to check if this proxy is the same as system
797 */
798 offset = _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
799 if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
800 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
801 if (GateMP_module->numRemoteCustom1 != 0) {
802 GateMP_module->remoteCustom1InUse =
803 GateMP_module->remoteSystemInUse + offset;
804 }
805 }
806 else {
807 GateMP_module->remoteCustom1InUse = GateMP_module->remoteSystemInUse;
808 GateMP_module->remoteCustom1Gates = GateMP_module->remoteSystemGates;
809 }
811 offset = _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
812 if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
813 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
814 if (GateMP_module->numRemoteCustom2 != 0) {
815 GateMP_module->remoteCustom2InUse =
816 GateMP_module->remoteCustom1InUse + offset;
817 }
818 }
819 else if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
820 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
821 GateMP_module->remoteCustom2InUse =
822 GateMP_module->remoteCustom1InUse;
823 GateMP_module->remoteCustom2Gates =
824 GateMP_module->remoteCustom1Gates;
825 }
826 else {
827 GateMP_module->remoteCustom2InUse = GateMP_module->remoteSystemInUse;
828 GateMP_module->remoteCustom2Gates = GateMP_module->remoteSystemGates;
829 }
830 }
832 /*
833 * ======== ti_sdo_ipc_GateMP_attach ========
834 */
835 Int ti_sdo_ipc_GateMP_attach(UInt16 remoteProcId, Ptr sharedAddr)
836 {
837 Ptr gateMPsharedAddr;
838 SharedRegion_Entry entry;
839 ti_sdo_ipc_GateMP_Handle defaultGate;
840 Int status = GateMP_S_SUCCESS;
842 /* If default gate is not NULL return since its already set */
843 if (GateMP_getDefaultRemote() != NULL) {
844 return(GateMP_S_ALREADYSETUP);
845 }
847 /* get region 0 information */
848 SharedRegion_getEntry(0, &entry);
850 gateMPsharedAddr = (Ptr)((UInt32)sharedAddr +
851 ti_sdo_ipc_GateMP_getRegion0ReservedSize());
853 if ((entry.ownerProcId != MultiProc_self()) &&
854 (entry.ownerProcId != MultiProc_INVALIDID)) {
855 /* if not the owner of the SharedRegion */
856 ti_sdo_ipc_GateMP_openRegion0Reserved(sharedAddr);
858 /* open the gate by address */
859 status = GateMP_openByAddr(gateMPsharedAddr,
860 (GateMP_Handle *)&defaultGate);
862 /* openByAddr should always succeed */
863 Assert_isTrue(status >= 0, ti_sdo_ipc_Ipc_A_internal);
865 /* set the default GateMP for opener */
866 ti_sdo_ipc_GateMP_setDefaultRemote(defaultGate);
867 }
869 return (status);
870 }
872 /*
873 * ======== ti_sdo_ipc_GateMP_detach ========
874 */
875 Int ti_sdo_ipc_GateMP_detach(UInt16 remoteProcId)
876 {
877 SharedRegion_Entry entry;
878 GateMP_Handle gate;
879 Int status = GateMP_S_SUCCESS;
881 /* get region 0 information */
882 SharedRegion_getEntry(0, &entry);
884 if ((entry.isValid) &&
885 (entry.ownerProcId == remoteProcId)) {
886 /* get the default gate */
887 gate = GateMP_getDefaultRemote();
889 if (gate != NULL) {
890 /* close the gate */
891 status = GateMP_close(&gate);
893 /* set the default remote gate to NULL */
894 ti_sdo_ipc_GateMP_setDefaultRemote(NULL);
895 }
896 }
898 return (status);
899 }
901 /*
902 * ======== ti_sdo_ipc_GateMP_start ========
903 */
904 Int ti_sdo_ipc_GateMP_start(Ptr sharedAddr)
905 {
906 SharedRegion_Entry entry;
907 ti_sdo_ipc_GateMP_Params gateMPParams;
908 ti_sdo_ipc_GateMP_Handle defaultGate;
909 Int status = GateMP_S_SUCCESS;
910 Error_Block eb;
912 /* get region 0 information */
913 SharedRegion_getEntry(0, &entry);
915 /* if entry owner proc is not specified return */
916 if (entry.ownerProcId == MultiProc_INVALIDID) {
917 return (status);
918 }
920 if (entry.ownerProcId == MultiProc_self()) {
921 /* if owner of the SharedRegion */
922 ti_sdo_ipc_GateMP_setRegion0Reserved(sharedAddr);
924 /* create default GateMP */
925 ti_sdo_ipc_GateMP_Params_init(&gateMPParams);
926 gateMPParams.sharedAddr = (Ptr)((UInt32)sharedAddr +
927 ti_sdo_ipc_GateMP_getRegion0ReservedSize());
928 gateMPParams.localProtect = ti_sdo_ipc_GateMP_LocalProtect_TASKLET;
929 gateMPParams.name = "_GateMP_TI_dGate";
931 if (ti_sdo_utils_MultiProc_numProcessors > 1) {
932 gateMPParams.remoteProtect = ti_sdo_ipc_GateMP_RemoteProtect_SYSTEM;
933 }
934 else {
935 gateMPParams.remoteProtect = ti_sdo_ipc_GateMP_RemoteProtect_NONE;
936 }
938 Error_init(&eb);
939 defaultGate = ti_sdo_ipc_GateMP_create(&gateMPParams, &eb);
940 if (defaultGate != NULL) {
941 /* set the default GateMP for creator */
942 ti_sdo_ipc_GateMP_setDefaultRemote(defaultGate);
943 }
944 else {
945 status = GateMP_E_FAIL;
946 }
947 }
949 return (status);
950 }
952 /*
953 * ======== ti_sdo_ipc_GateMP_stop ========
954 */
955 Int ti_sdo_ipc_GateMP_stop()
956 {
957 SharedRegion_Entry entry;
958 GateMP_Handle gate;
959 Int status = GateMP_S_SUCCESS;
961 /* get region 0 information */
962 SharedRegion_getEntry(0, &entry);
964 if ((entry.isValid) &&
965 (entry.createHeap) &&
966 (entry.ownerProcId == MultiProc_self())) {
967 /* get the default GateMP */
968 gate = GateMP_getDefaultRemote();
970 if (gate != NULL) {
971 /* set the default GateMP to NULL */
972 ti_sdo_ipc_GateMP_setDefaultRemote(NULL);
974 /* delete the default GateMP */
975 status = GateMP_delete(&gate);
976 }
978 /* Remove global info entry from NameServer */
979 if ((GateMP_module->hostSupport == TRUE) &&
980 (GateMP_module->nsKey != 0)) {
981 NameServer_removeEntry((NameServer_Handle)GateMP_module->nameServer,
982 GateMP_module->nsKey);
983 }
984 }
986 return (status);
987 }
989 /*
990 *************************************************************************
991 * Instance functions
992 *************************************************************************
993 */
995 /*
996 * ======== ti_sdo_ipc_GateMP_Instance_init ========
997 */
998 Int ti_sdo_ipc_GateMP_Instance_init(ti_sdo_ipc_GateMP_Object *obj,
999 const ti_sdo_ipc_GateMP_Params *params,
1000 Error_Block *eb)
1001 {
1002 UInt key;
1003 IGateMPSupport_Handle remoteHandle;
1004 IGateProvider_Handle localHandle;
1005 ti_sdo_ipc_GateMP_RemoteSystemProxy_Params systemParams;
1006 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params custom1Params;
1007 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params custom2Params;
1008 SizeT minAlign, offset;
1009 SharedRegion_SRPtr sharedShmBase;
1010 GateMP_Params sparams;
1011 UInt32 nsValue[4];
1012 UInt32 sizeNsValue;
1013 IHeap_Handle regionHeap;
1015 /* Initialize resourceId to an invalid value */
1016 obj->resourceId = (UInt)-1;
1018 localHandle = ti_sdo_ipc_GateMP_createLocal(params->localProtect);
1020 /* Open GateMP instance */
1021 if (params->openFlag == TRUE) {
1022 /* all open work done here except for remote gateHandle */
1023 obj->localProtect = params->localProtect;
1024 obj->remoteProtect = params->remoteProtect;
1025 obj->nsKey = 0;
1026 obj->numOpens = 0; /* Will be set to 1 after init() complete */
1027 obj->attrs = (ti_sdo_ipc_GateMP_Attrs *)params->sharedAddr;
1028 if (obj->attrs != NULL) {
1029 obj->regionId = SharedRegion_getId((Ptr)obj->attrs);
1030 obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
1031 /* Assert that the buffer is in a valid shared region */
1032 Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID,
1033 ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);
1034 }
1036 obj->allocSize = 0;
1037 obj->objType = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC;
1039 minAlign = Memory_getMaxDefaultTypeAlign();
1041 if ((obj->attrs != NULL) &&
1042 (SharedRegion_getCacheLineSize(obj->regionId) > minAlign)) {
1043 minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1044 }
1046 offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1048 /* TODO: host side created gates cannot have proxy memory */
1049 if (obj->attrs != NULL) {
1050 obj->proxyAttrs = (Ptr)((UInt32)obj->attrs + offset);
1051 }
1052 else {
1053 obj->proxyAttrs = NULL;
1054 }
1055 }
1056 /* Create GateMP instance */
1057 else {
1058 obj->localProtect = params->localProtect;
1059 obj->remoteProtect = params->remoteProtect;
1060 obj->nsKey = 0;
1061 obj->numOpens = 0;
1063 if (obj->remoteProtect == GateMP_RemoteProtect_NONE) {
1064 obj->gateHandle = ti_sdo_ipc_GateMP_createLocal(obj->localProtect);
1065 if (params->sharedAddr != NULL) {
1066 /* Create a local gate using shared memory */
1067 obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
1068 obj->attrs = params->sharedAddr;
1069 obj->regionId = SharedRegion_getId((Ptr)obj->attrs);
1070 obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
1071 }
1072 else {
1073 /* Create a local gate allocating from the local heap */
1074 obj->objType = ti_sdo_ipc_Ipc_ObjType_LOCAL;
1075 obj->regionId = ti_sdo_ipc_SharedRegion_INVALIDREGIONID;
1076 obj->cacheEnabled = FALSE; /* local */
1077 obj->attrs = Memory_alloc(NULL,
1078 sizeof(ti_sdo_ipc_GateMP_Attrs), 0, eb);
1079 if (obj->attrs == NULL) {
1080 return (2);
1081 }
1083 }
1085 obj->attrs->arg = (Bits32)obj;
1086 obj->attrs->mask = SETMASK(obj->remoteProtect, obj->localProtect);
1087 obj->attrs->creatorProcId = MultiProc_self();
1088 obj->attrs->status = ti_sdo_ipc_GateMP_CREATED;
1089 if (obj->cacheEnabled) {
1090 /*
1091 * Need to write back memory if cache is enabled because cache
1092 * will be invalidated during openByAddr
1093 */
1094 Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1095 Cache_Type_ALL, TRUE);
1096 }
1098 if (params->name) {
1099 nsValue[0] = (UInt32)obj->attrs;
1100 /*
1101 * Top 16 bits = procId of creator
1102 * Bottom 16 bits = '0' if local, '1' otherwise
1103 */
1104 nsValue[1] = ((UInt32)MultiProc_self()) << 16;
1106 if (GateMP_module->hostSupport == TRUE) {
1107 nsValue[2] = obj->attrs->arg;
1108 nsValue[3] = obj->attrs->mask;
1109 sizeNsValue = sizeof(nsValue);
1110 }
1111 else {
1112 sizeNsValue = 2 * sizeof(UInt32);
1113 }
1115 obj->nsKey = NameServer_add((NameServer_Handle)
1116 GateMP_module->nameServer, params->name, &nsValue,
1117 sizeNsValue);
1119 if (obj->nsKey == NULL) {
1120 Error_raise(eb, ti_sdo_ipc_Ipc_E_nameFailed, params->name,
1121 0);
1122 return (3);
1123 }
1124 }
1126 /* Nothing else to do for local gates */
1127 return (0);
1128 }
1130 if (params->sharedAddr == NULL) {
1131 /* Need to allocate from heap */
1132 obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION;
1133 obj->regionId = params->regionId;
1134 GateMP_getSharedParams(&sparams, params);
1135 obj->allocSize = GateMP_sharedMemReq(&sparams);
1136 obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
1138 /* The region heap will do the alignment */
1139 regionHeap = SharedRegion_getHeap(obj->regionId);
1140 Assert_isTrue(regionHeap != NULL, ti_sdo_ipc_SharedRegion_A_noHeap);
1141 obj->attrs = Memory_alloc(regionHeap, obj->allocSize, 0, eb);
1142 if (obj->attrs == NULL) {
1143 return (3);
1144 }
1146 minAlign = Memory_getMaxDefaultTypeAlign();
1148 if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) {
1149 minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1150 }
1152 offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1154 obj->proxyAttrs = (Ptr)((UInt32)obj->attrs + offset);
1155 }
1156 else {
1157 /* creating using sharedAddr */
1158 obj->regionId = SharedRegion_getId(params->sharedAddr);
1159 /* Assert that the buffer is in a valid shared region */
1160 Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID,
1161 ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);
1163 obj->attrs = (ti_sdo_ipc_GateMP_Attrs *)params->sharedAddr;
1164 obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
1165 obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
1167 minAlign = Memory_getMaxDefaultTypeAlign();
1169 if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) {
1170 minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1171 }
1173 /* Assert that sharedAddr has correct alignment */
1174 Assert_isTrue(minAlign == 0 ||
1175 ((UInt32)params->sharedAddr % minAlign) == 0,
1176 ti_sdo_ipc_Ipc_A_addrNotCacheAligned);
1178 offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1180 obj->proxyAttrs = (Ptr)((UInt32)obj->attrs + offset);
1181 }
1182 }
1184 /* Proxy work for open and create done here */
1185 switch (obj->remoteProtect) {
1186 case GateMP_RemoteProtect_SYSTEM:
1187 if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1188 /* Created Instance */
1189 obj->resourceId = GateMP_getFreeResource(
1190 GateMP_module->remoteSystemInUse,
1191 GateMP_module->numRemoteSystem, eb);
1192 if (Error_check(eb) == TRUE) {
1193 return (4);
1194 }
1195 }
1196 else {
1197 /* resourceId set by open call */
1198 obj->resourceId = params->resourceId;
1199 }
1201 /* Create the proxy object */
1202 ti_sdo_ipc_GateMP_RemoteSystemProxy_Params_init(&systemParams);
1203 systemParams.resourceId = obj->resourceId;
1204 systemParams.openFlag =
1205 (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1206 systemParams.sharedAddr = obj->proxyAttrs;
1207 systemParams.regionId = obj->regionId;
1208 remoteHandle = ti_sdo_ipc_GateMP_RemoteSystemProxy_create(
1209 localHandle, &systemParams, eb);
1211 if (remoteHandle == NULL) {
1212 return (5);
1213 }
1215 /* Fill in the local array because it is cooked */
1216 key = Hwi_disable();
1217 GateMP_module->remoteSystemGates[obj->resourceId] = obj;
1218 Hwi_restore(key);
1219 break;
1221 case GateMP_RemoteProtect_CUSTOM1:
1222 if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1223 obj->resourceId = GateMP_getFreeResource(
1224 GateMP_module->remoteCustom1InUse,
1225 GateMP_module->numRemoteCustom1, eb);
1226 if (Error_check(eb) == TRUE) {
1227 return (4);
1228 }
1229 }
1230 else {
1231 /* resourceId set by open call */
1232 obj->resourceId = params->resourceId;
1233 }
1235 /* Create the proxy object */
1236 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params_init(&custom1Params);
1237 custom1Params.resourceId = obj->resourceId;
1238 custom1Params.openFlag =
1239 (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1240 custom1Params.sharedAddr = obj->proxyAttrs;
1241 custom1Params.regionId = obj->regionId;
1242 remoteHandle = ti_sdo_ipc_GateMP_RemoteCustom1Proxy_create(
1243 localHandle, &custom1Params, eb);
1244 if (remoteHandle == NULL) {
1245 return (5);
1246 }
1248 /* Fill in the local array because it is cooked */
1249 key = Hwi_disable();
1250 GateMP_module->remoteCustom1Gates[obj->resourceId] = obj;
1251 Hwi_restore(key);
1252 break;
1254 case GateMP_RemoteProtect_CUSTOM2:
1255 if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1256 obj->resourceId = GateMP_getFreeResource(
1257 GateMP_module->remoteCustom2InUse,
1258 GateMP_module->numRemoteCustom2, eb);
1259 if (Error_check(eb) == TRUE) {
1260 return (4);
1261 }
1262 }
1263 else {
1264 /* resourceId set by open call */
1265 obj->resourceId = params->resourceId;
1266 }
1268 /* Create the proxy object */
1269 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params_init(&custom2Params);
1270 custom2Params.resourceId = obj->resourceId;
1271 custom2Params.openFlag =
1272 (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1273 custom2Params.sharedAddr = obj->proxyAttrs;
1274 custom2Params.regionId = obj->regionId;
1275 remoteHandle = ti_sdo_ipc_GateMP_RemoteCustom2Proxy_create(
1276 localHandle, &custom2Params, eb);
1277 if (remoteHandle == NULL) {
1278 return (5);
1279 }
1281 /* Fill in the local array because it is cooked */
1282 key = Hwi_disable();
1283 GateMP_module->remoteCustom2Gates[obj->resourceId] = obj;
1284 Hwi_restore(key);
1285 break;
1287 default:
1288 /* Should never be here */
1289 Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
1290 return (5); /* keep Coverity happy */
1291 }
1293 obj->gateHandle = IGateMPSupport_Handle_upCast(remoteHandle);
1295 /* Place Name/Attrs into NameServer table */
1296 if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1297 /* Fill in the attrs */
1298 obj->attrs->arg = obj->resourceId;
1299 obj->attrs->mask = SETMASK(obj->remoteProtect, obj->localProtect);
1300 obj->attrs->creatorProcId = MultiProc_self();
1301 obj->attrs->status = ti_sdo_ipc_GateMP_CREATED;
1303 if (obj->cacheEnabled) {
1304 Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1305 Cache_Type_ALL, TRUE);
1306 }
1308 if (params->name != NULL) {
1309 sharedShmBase = SharedRegion_getSRPtr(obj->attrs, obj->regionId);
1310 nsValue[0] = (UInt32)sharedShmBase;
1311 /*
1312 * Top 16 bits = procId of creator
1313 * Bottom 16 bits = '0' if local, '1' otherwise
1314 */
1315 nsValue[1] = ((UInt32)MultiProc_self() << 16) | 1;
1317 if (GateMP_module->hostSupport == TRUE) {
1318 /* Making a copy of these for host processor */
1319 nsValue[2] = obj->attrs->arg;
1320 nsValue[3] = obj->attrs->mask;
1321 sizeNsValue = sizeof(nsValue);
1322 }
1323 else {
1324 sizeNsValue = 2 * sizeof(UInt32);
1325 }
1327 obj->nsKey = NameServer_add((NameServer_Handle)
1328 GateMP_module->nameServer, params->name, &nsValue,
1329 sizeNsValue);
1331 if (obj->nsKey == NULL) {
1332 Error_raise(eb, ti_sdo_ipc_Ipc_E_nameFailed, params->name, 0);
1333 return (6);
1334 }
1335 }
1337 Log_write2(ti_sdo_ipc_GateMP_LM_create,
1338 (UArg)obj->remoteProtect, (UArg)obj->resourceId);
1339 }
1340 else {
1341 obj->numOpens = 1;
1343 Log_write2(ti_sdo_ipc_GateMP_LM_open,
1344 (UArg)obj->remoteProtect, (UArg)obj->resourceId);
1345 }
1347 return (0);
1348 }
1350 /*
1351 * ======== ti_sdo_ipc_GateMP_Instance_finalize ========
1352 */
1353 Void ti_sdo_ipc_GateMP_Instance_finalize(
1354 ti_sdo_ipc_GateMP_Object *obj, Int status)
1355 {
1356 UInt systemKey;
1357 ti_sdo_ipc_GateMP_RemoteSystemProxy_Handle systemHandle;
1358 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Handle custom1Handle;
1359 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Handle custom2Handle;
1361 ti_sdo_ipc_GateMP_Handle *remoteHandles;
1362 UInt8 *inUseArray;
1363 UInt numResources;
1365 /* Cannot call when numOpen is non-zero. */
1366 Assert_isTrue(obj->numOpens == 0, ti_sdo_ipc_GateMP_A_invalidDelete);
1368 /* Removed from NameServer */
1369 if (obj->nsKey != 0) {
1370 NameServer_removeEntry((NameServer_Handle)GateMP_module->nameServer,
1371 obj->nsKey);
1372 }
1374 /* Set the status to 0 */
1375 if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1376 obj->attrs->status = 0;
1377 if (obj->cacheEnabled) {
1378 Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1379 Cache_Type_ALL, TRUE);
1380 }
1381 }
1383 /*
1384 * If ObjType_LOCAL, memory was allocated from the local system heap.
1385 * obj->attrs might be NULL if the Memory_alloc failed in Instance_init
1386 */
1387 if (obj->objType == ti_sdo_ipc_Ipc_ObjType_LOCAL && obj->attrs != NULL) {
1388 Memory_free(NULL, obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs));
1389 }
1391 switch (obj->remoteProtect) {
1392 case GateMP_RemoteProtect_SYSTEM:
1393 if (obj->gateHandle) {
1394 systemHandle =
1395 ti_sdo_ipc_GateMP_RemoteSystemProxy_Handle_downCast2(
1396 obj->gateHandle);
1397 ti_sdo_ipc_GateMP_RemoteSystemProxy_delete(&systemHandle);
1398 }
1400 inUseArray = GateMP_module->remoteSystemInUse;
1401 remoteHandles = GateMP_module->remoteSystemGates;
1402 numResources = GateMP_module->numRemoteSystem;
1403 break;
1405 case GateMP_RemoteProtect_CUSTOM1:
1406 if (obj->gateHandle) {
1407 custom1Handle =
1408 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Handle_downCast2(
1409 obj->gateHandle);
1410 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_delete(&custom1Handle);
1411 }
1413 inUseArray = GateMP_module->remoteCustom1InUse;
1414 remoteHandles = GateMP_module->remoteCustom1Gates;
1415 numResources = GateMP_module->numRemoteCustom1;
1416 break;
1418 case GateMP_RemoteProtect_CUSTOM2:
1419 if (obj->gateHandle) {
1420 custom2Handle =
1421 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Handle_downCast2(
1422 obj->gateHandle);
1423 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_delete(&custom2Handle);
1424 }
1426 inUseArray = GateMP_module->remoteCustom2InUse;
1427 remoteHandles = GateMP_module->remoteCustom2Gates;
1428 numResources = GateMP_module->numRemoteCustom2;
1429 break;
1430 case GateMP_RemoteProtect_NONE:
1431 /*
1432 * Nothing else to finalize. Any alloc'ed memory has already been
1433 * freed
1434 */
1435 Log_write2(ti_sdo_ipc_GateMP_LM_delete, (UArg)obj->remoteProtect,
1436 (UArg)obj->resourceId);
1437 return;
1438 default:
1439 /* Should never be here */
1440 Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
1441 break;
1442 }
1444 /* Clear the handle array entry in local memory */
1445 if (obj->resourceId != (UInt)-1) {
1446 remoteHandles[obj->resourceId] = NULL;
1447 }
1449 if ((obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) &&
1450 (obj->resourceId != (UInt)-1)) {
1451 /* Clear the resource used flag in shared memory */
1452 if (GateMP_module->defaultGate != NULL) {
1453 systemKey = GateMP_enter((GateMP_Handle)GateMP_module->defaultGate);
1454 }
1455 else {
1456 /* this should only be done when deleting the very last GateMP */
1457 systemKey = Hwi_disable();
1458 }
1460 /* update the GateMP resource tracker */
1461 inUseArray[obj->resourceId] = UNUSED;
1462 if (obj->cacheEnabled) {
1463 Cache_wbInv(inUseArray,
1464 numResources * sizeof(UInt8),
1465 Cache_Type_ALL,
1466 TRUE);
1467 }
1469 if (GateMP_module->defaultGate != NULL) {
1470 GateMP_leave((GateMP_Handle)GateMP_module->defaultGate, systemKey);
1471 }
1472 else {
1473 Hwi_restore(systemKey);
1474 }
1475 }
1477 if (obj->objType == ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION) {
1478 /* Free memory allocated from the region heap */
1479 if (obj->attrs) {
1480 Memory_free(SharedRegion_getHeap(obj->regionId), obj->attrs,
1481 obj->allocSize);
1482 }
1483 }
1485 Log_write2(ti_sdo_ipc_GateMP_LM_delete, (UArg)obj->remoteProtect,
1486 (UArg)obj->resourceId);
1487 }
1489 /*
1490 * ======== ti_sdo_ipc_GateMP_getSharedAddr ========
1491 */
1492 SharedRegion_SRPtr ti_sdo_ipc_GateMP_getSharedAddr(
1493 ti_sdo_ipc_GateMP_Object *obj)
1494 {
1495 SharedRegion_SRPtr srPtr;
1497 srPtr = SharedRegion_getSRPtr(obj->attrs, obj->regionId);
1499 return (srPtr);
1500 }
1502 /*
1503 * ======== ti_sdo_ipc_GateMP_setDefaultRemote ========
1504 */
1505 Void ti_sdo_ipc_GateMP_setDefaultRemote(ti_sdo_ipc_GateMP_Object *obj)
1506 {
1507 GateMP_module->defaultGate = obj;
1508 }
1510 /*
1511 *************************************************************************
1512 * Internal functions
1513 *************************************************************************
1514 */
1516 /*
1517 * ======== ti_sdo_ipc_GateMP_getFreeResource ========
1518 */
1519 UInt ti_sdo_ipc_GateMP_getFreeResource(UInt8 *inUse, Int num, Error_Block *eb)
1520 {
1521 UInt key;
1522 Bool flag = FALSE;
1523 UInt resourceId;
1524 GateMP_Handle defaultGate;
1526 /* Need to look at shared memory. Enter default gate */
1527 defaultGate = GateMP_getDefaultRemote();
1529 if (defaultGate){
1530 key = GateMP_enter(defaultGate);
1531 }
1533 /* Invalidate cache before looking at the in-use flags */
1534 if (SharedRegion_isCacheEnabled(0)) {
1535 Cache_inv(inUse, num * sizeof(UInt8), Cache_Type_ALL, TRUE);
1536 }
1538 /*
1539 * Find a free resource id. Note: zero is reserved on the
1540 * system proxy for the default gate.
1541 */
1542 for (resourceId = 0; resourceId < num; resourceId++) {
1543 /*
1544 * If not in-use, set the inUse to TRUE to prevent other
1545 * creates from getting this one.
1546 */
1547 if (inUse[resourceId] == UNUSED) {
1548 flag = TRUE;
1550 /* Denote in shared memory that the resource is used */
1551 inUse[resourceId] = USED;
1552 break;
1553 }
1554 }
1556 /* Write-back if a in-use flag was changed */
1557 if (flag == TRUE && SharedRegion_isCacheEnabled(0)) {
1558 Cache_wbInv(inUse, num * sizeof(UInt8), Cache_Type_ALL, TRUE);
1559 }
1561 /* Done with the critical section */
1562 if (defaultGate) {
1563 GateMP_leave(defaultGate, key);
1564 }
1566 if (flag == FALSE) {
1567 resourceId = (UInt)-1;
1568 Error_raise(eb, ti_sdo_ipc_GateMP_E_gateUnavailable, 0, 0);
1569 }
1571 return (resourceId);
1572 }