1 /*
2 * Copyright (c) 2012-2015 Texas Instruments Incorporated - http://www.ti.com
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, MultiProc_getClusterProcList());
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];
633 Int ret;
635 minAlign = Memory_getMaxDefaultTypeAlign();
636 if (SharedRegion_getCacheLineSize(0) > minAlign) {
637 minAlign = SharedRegion_getCacheLineSize(0);
638 }
640 /* setup ti_sdo_ipc_GateMP_Reserved fields */
641 reserve = (ti_sdo_ipc_GateMP_Reserved *)sharedAddr;
642 reserve->version = ti_sdo_ipc_GateMP_VERSION;
644 if (SharedRegion_isCacheEnabled(0)) {
645 Cache_wbInv(sharedAddr, sizeof(ti_sdo_ipc_GateMP_Reserved),
646 Cache_Type_ALL, TRUE);
647 }
649 /*
650 * initialize the in-use array in shared memory for the system gates.
651 */
652 offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
653 GateMP_module->remoteSystemInUse =
654 (Ptr)((UInt32)sharedAddr + offset);
656 if (GateMP_module->numRemoteSystem != 0) {
657 memset(GateMP_module->remoteSystemInUse, 0,
658 GateMP_module->numRemoteSystem * sizeof(UInt8));
659 delegateReservedMask =
660 ti_sdo_ipc_GateMP_RemoteSystemProxy_getReservedMask();
661 if (delegateReservedMask != NULL) {
662 for (i = 0; i < GateMP_module->numRemoteSystem; i++) {
663 if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
664 GateMP_module->remoteSystemInUse[i] = RESERVED;
665 }
666 }
667 }
669 if (SharedRegion_isCacheEnabled(0)) {
670 Cache_wbInv(GateMP_module->remoteSystemInUse,
671 GateMP_module->numRemoteSystem * sizeof(UInt8),
672 Cache_Type_ALL,
673 TRUE);
674 }
675 }
677 /*
678 * initialize the in-use array in shared memory for the custom1 gates.
679 * Need to check if this proxy is the same as system
680 */
681 offset = _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
682 if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
683 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
684 if (GateMP_module->numRemoteCustom1 != 0) {
685 GateMP_module->remoteCustom1InUse =
686 GateMP_module->remoteSystemInUse + offset;
688 memset(GateMP_module->remoteCustom1InUse, 0,
689 GateMP_module->numRemoteCustom1 * sizeof(UInt8));
690 delegateReservedMask =
691 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_getReservedMask();
692 if (delegateReservedMask != NULL) {
693 for (i = 0; i < GateMP_module->numRemoteCustom1; i++) {
694 if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
695 GateMP_module->remoteCustom1InUse[i] = RESERVED;
696 }
697 }
698 }
699 if (SharedRegion_isCacheEnabled(0)) {
700 Cache_wbInv(GateMP_module->remoteCustom1InUse,
701 GateMP_module->numRemoteCustom1 * sizeof(UInt8),
702 Cache_Type_ALL,
703 TRUE);
704 }
705 }
706 }
707 else {
708 GateMP_module->remoteCustom1InUse = GateMP_module->remoteSystemInUse;
709 GateMP_module->remoteCustom1Gates = GateMP_module->remoteSystemGates;
710 }
712 /*
713 * initialize the in-use array in shared memory for the custom2 gates.
714 * Need to check if this proxy is the same as system or custom1
715 */
716 offset = _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
717 if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
718 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
719 if (GateMP_module->numRemoteCustom2 != 0) {
720 GateMP_module->remoteCustom2InUse =
721 GateMP_module->remoteCustom1InUse + offset;
723 memset(GateMP_module->remoteCustom2InUse, 0,
724 GateMP_module->numRemoteCustom2 * sizeof(UInt8));
725 delegateReservedMask =
726 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_getReservedMask();
727 if (delegateReservedMask != NULL) {
728 for (i = 0; i < GateMP_module->numRemoteCustom2; i++) {
729 if (delegateReservedMask[i >> 5] & (1 << (i % 32))) {
730 GateMP_module->remoteCustom2InUse[i] = RESERVED;
731 }
732 }
733 }
735 if (SharedRegion_isCacheEnabled(0)) {
736 Cache_wbInv(GateMP_module->remoteCustom2InUse,
737 GateMP_module->numRemoteCustom2 * sizeof(UInt8),
738 Cache_Type_ALL,
739 TRUE);
740 }
741 }
742 }
743 else if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
744 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
745 GateMP_module->remoteCustom2InUse =
746 GateMP_module->remoteCustom1InUse;
747 GateMP_module->remoteCustom2Gates =
748 GateMP_module->remoteCustom1Gates;
749 }
750 else {
751 GateMP_module->remoteCustom2InUse = GateMP_module->remoteSystemInUse;
752 GateMP_module->remoteCustom2Gates = GateMP_module->remoteSystemGates;
753 }
755 if (GateMP_module->hostSupport == TRUE) {
756 /* Add special entry to store inuse arrays' location and size */
757 ret = _GateMP_virtToPhys(
758 (UInt32)GateMP_module->remoteSystemInUse, &nsValue[0]);
759 Assert_isTrue(ret == GateMP_S_SUCCESS, (Assert_Id)NULL);
760 (void)ret; /* silence unused var warning when asserts disabled */
761 if (GateMP_module->numRemoteCustom1 != 0) {
762 ret = _GateMP_virtToPhys(
763 (UInt32)GateMP_module->remoteCustom1InUse, &nsValue[1]);
764 Assert_isTrue(ret == GateMP_S_SUCCESS, (Assert_Id)NULL);
765 }
766 else {
767 nsValue[1] = 0;
768 }
769 if (GateMP_module->numRemoteCustom2 != 0) {
770 ret = _GateMP_virtToPhys(
771 (UInt32)GateMP_module->remoteCustom2InUse, &nsValue[2]);
772 Assert_isTrue(ret == GateMP_S_SUCCESS, (Assert_Id)NULL);
773 }
774 else {
775 nsValue[2] = 0;
776 }
777 nsValue[3] = GateMP_module->numRemoteSystem;
778 nsValue[4] = GateMP_module->numRemoteCustom1;
779 nsValue[5] = GateMP_module->numRemoteCustom2;
780 GateMP_module->nsKey = NameServer_add((NameServer_Handle)
781 GateMP_module->nameServer, "_GateMP_TI_info", &nsValue,
782 sizeof(nsValue));
783 }
784 }
786 /*
787 * ======== ti_sdo_ipc_GateMP_openRegion0Reserved ========
788 */
789 Void ti_sdo_ipc_GateMP_openRegion0Reserved(Ptr sharedAddr)
790 {
791 ti_sdo_ipc_GateMP_Reserved *reserve;
792 SizeT minAlign, offset;
794 minAlign = Memory_getMaxDefaultTypeAlign();
795 if (SharedRegion_getCacheLineSize(0) > minAlign) {
796 minAlign = SharedRegion_getCacheLineSize(0);
797 }
800 /* setup ti_sdo_ipc_GateMP_Reserved fields */
801 reserve = (ti_sdo_ipc_GateMP_Reserved *)sharedAddr;
803 if (reserve->version != ti_sdo_ipc_GateMP_VERSION) {
804 /* Version mismatch: return an error */
805 Error_raise(NULL, ti_sdo_ipc_Ipc_E_versionMismatch, reserve->version,
806 ti_sdo_ipc_GateMP_VERSION);
807 return;
808 }
810 offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Reserved), minAlign);
811 GateMP_module->remoteSystemInUse =
812 (Ptr)((UInt32)sharedAddr + offset);
814 /*
815 * initialize the in-use array in shared memory for the custom1 gates.
816 * Need to check if this proxy is the same as system
817 */
818 offset = _Ipc_roundup(GateMP_module->numRemoteSystem, minAlign);
819 if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1] ==
820 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
821 if (GateMP_module->numRemoteCustom1 != 0) {
822 GateMP_module->remoteCustom1InUse =
823 GateMP_module->remoteSystemInUse + offset;
824 }
825 }
826 else {
827 GateMP_module->remoteCustom1InUse = GateMP_module->remoteSystemInUse;
828 GateMP_module->remoteCustom1Gates = GateMP_module->remoteSystemGates;
829 }
831 offset = _Ipc_roundup(GateMP_module->numRemoteCustom1, minAlign);
832 if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
833 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2) {
834 if (GateMP_module->numRemoteCustom2 != 0) {
835 GateMP_module->remoteCustom2InUse =
836 GateMP_module->remoteCustom1InUse + offset;
837 }
838 }
839 else if (GateMP_module->proxyMap[ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM2] ==
840 ti_sdo_ipc_GateMP_ProxyOrder_CUSTOM1) {
841 GateMP_module->remoteCustom2InUse =
842 GateMP_module->remoteCustom1InUse;
843 GateMP_module->remoteCustom2Gates =
844 GateMP_module->remoteCustom1Gates;
845 }
846 else {
847 GateMP_module->remoteCustom2InUse = GateMP_module->remoteSystemInUse;
848 GateMP_module->remoteCustom2Gates = GateMP_module->remoteSystemGates;
849 }
850 }
852 /*
853 * ======== ti_sdo_ipc_GateMP_attach ========
854 */
855 Int ti_sdo_ipc_GateMP_attach(UInt16 remoteProcId, Ptr sharedAddr)
856 {
857 Ptr gateMPsharedAddr;
858 SharedRegion_Entry entry;
859 ti_sdo_ipc_GateMP_Handle defaultGate;
860 Int status = GateMP_S_SUCCESS;
862 /* If default gate is not NULL return since its already set */
863 if (GateMP_getDefaultRemote() != NULL) {
864 return(GateMP_S_ALREADYSETUP);
865 }
867 /* get region 0 information */
868 SharedRegion_getEntry(0, &entry);
870 gateMPsharedAddr = (Ptr)((UInt32)sharedAddr +
871 ti_sdo_ipc_GateMP_getRegion0ReservedSize());
873 if ((entry.ownerProcId != MultiProc_self()) &&
874 (entry.ownerProcId != MultiProc_INVALIDID)) {
876 /* Make sure to invalidate cache before using shared memory content */
877 if (entry.cacheEnable) {
878 Cache_inv(sharedAddr, ti_sdo_ipc_GateMP_getRegion0ReservedSize(),
879 Cache_Type_ALL, TRUE);
880 }
882 /* if not the owner of the SharedRegion */
883 ti_sdo_ipc_GateMP_openRegion0Reserved(sharedAddr);
885 /* open the gate by address */
886 status = GateMP_openByAddr(gateMPsharedAddr,
887 (GateMP_Handle *)&defaultGate);
889 /* openByAddr should always succeed */
890 Assert_isTrue(status >= 0, ti_sdo_ipc_Ipc_A_internal);
892 /* set the default GateMP for opener */
893 ti_sdo_ipc_GateMP_setDefaultRemote(defaultGate);
894 }
896 return (status);
897 }
899 /*
900 * ======== ti_sdo_ipc_GateMP_detach ========
901 */
902 Int ti_sdo_ipc_GateMP_detach(UInt16 remoteProcId)
903 {
904 SharedRegion_Entry entry;
905 GateMP_Handle gate;
906 Int status = GateMP_S_SUCCESS;
908 /* get region 0 information */
909 SharedRegion_getEntry(0, &entry);
911 if ((entry.isValid) &&
912 (entry.ownerProcId == remoteProcId)) {
913 /* get the default gate */
914 gate = GateMP_getDefaultRemote();
916 if (gate != NULL) {
917 /* close the gate */
918 status = GateMP_close(&gate);
920 /* set the default remote gate to NULL */
921 ti_sdo_ipc_GateMP_setDefaultRemote(NULL);
922 }
923 }
925 return (status);
926 }
928 /*
929 * ======== ti_sdo_ipc_GateMP_start ========
930 */
931 Int ti_sdo_ipc_GateMP_start(Ptr sharedAddr)
932 {
933 SharedRegion_Entry entry;
934 ti_sdo_ipc_GateMP_Params gateMPParams;
935 ti_sdo_ipc_GateMP_Handle defaultGate;
936 Int status = GateMP_S_SUCCESS;
937 Error_Block eb;
939 /* get region 0 information */
940 SharedRegion_getEntry(0, &entry);
942 /* if entry owner proc is not specified return */
943 if (entry.ownerProcId == MultiProc_INVALIDID) {
944 return (status);
945 }
947 if (entry.ownerProcId == MultiProc_self()) {
948 /* if owner of the SharedRegion */
949 ti_sdo_ipc_GateMP_setRegion0Reserved(sharedAddr);
951 /* create default GateMP */
952 ti_sdo_ipc_GateMP_Params_init(&gateMPParams);
953 gateMPParams.sharedAddr = (Ptr)((UInt32)sharedAddr +
954 ti_sdo_ipc_GateMP_getRegion0ReservedSize());
955 gateMPParams.localProtect = ti_sdo_ipc_GateMP_LocalProtect_TASKLET;
956 gateMPParams.name = "_GateMP_TI_dGate";
958 if (ti_sdo_utils_MultiProc_numProcessors > 1) {
959 gateMPParams.remoteProtect = ti_sdo_ipc_GateMP_RemoteProtect_SYSTEM;
960 }
961 else {
962 gateMPParams.remoteProtect = ti_sdo_ipc_GateMP_RemoteProtect_NONE;
963 }
965 Error_init(&eb);
966 defaultGate = ti_sdo_ipc_GateMP_create(&gateMPParams, &eb);
967 if (defaultGate != NULL) {
968 /* set the default GateMP for creator */
969 ti_sdo_ipc_GateMP_setDefaultRemote(defaultGate);
970 }
971 else {
972 status = GateMP_E_FAIL;
973 }
974 }
976 return (status);
977 }
979 /*
980 * ======== ti_sdo_ipc_GateMP_stop ========
981 */
982 Int ti_sdo_ipc_GateMP_stop()
983 {
984 SharedRegion_Entry entry;
985 GateMP_Handle gate;
986 Int status = GateMP_S_SUCCESS;
988 /* get region 0 information */
989 SharedRegion_getEntry(0, &entry);
991 if ((entry.isValid) &&
992 (entry.createHeap) &&
993 (entry.ownerProcId == MultiProc_self())) {
994 /* get the default GateMP */
995 gate = GateMP_getDefaultRemote();
997 if (gate != NULL) {
998 /* set the default GateMP to NULL */
999 ti_sdo_ipc_GateMP_setDefaultRemote(NULL);
1001 /* delete the default GateMP */
1002 status = GateMP_delete(&gate);
1003 }
1005 /* Remove global info entry from NameServer */
1006 if ((GateMP_module->hostSupport == TRUE) &&
1007 (GateMP_module->nsKey != 0)) {
1008 NameServer_removeEntry((NameServer_Handle)GateMP_module->nameServer,
1009 GateMP_module->nsKey);
1010 }
1011 }
1013 return (status);
1014 }
1016 /*
1017 *************************************************************************
1018 * Instance functions
1019 *************************************************************************
1020 */
1022 /*
1023 * ======== ti_sdo_ipc_GateMP_Instance_init ========
1024 */
1025 Int ti_sdo_ipc_GateMP_Instance_init(ti_sdo_ipc_GateMP_Object *obj,
1026 const ti_sdo_ipc_GateMP_Params *params,
1027 Error_Block *eb)
1028 {
1029 UInt key;
1030 IGateMPSupport_Handle remoteHandle;
1031 IGateProvider_Handle localHandle;
1032 ti_sdo_ipc_GateMP_RemoteSystemProxy_Params systemParams;
1033 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params custom1Params;
1034 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params custom2Params;
1035 SizeT minAlign, offset;
1036 SharedRegion_SRPtr sharedShmBase;
1037 GateMP_Params sparams;
1038 UInt32 nsValue[4];
1039 UInt32 sizeNsValue;
1040 IHeap_Handle regionHeap;
1042 /* Initialize resourceId to an invalid value */
1043 obj->resourceId = (UInt)-1;
1045 localHandle = ti_sdo_ipc_GateMP_createLocal(params->localProtect);
1047 /* Open GateMP instance */
1048 if (params->openFlag == TRUE) {
1049 /* all open work done here except for remote gateHandle */
1050 obj->localProtect = params->localProtect;
1051 obj->remoteProtect = params->remoteProtect;
1052 obj->nsKey = 0;
1053 obj->numOpens = 0; /* Will be set to 1 after init() complete */
1054 obj->attrs = (ti_sdo_ipc_GateMP_Attrs *)params->sharedAddr;
1055 if (obj->attrs != NULL) {
1056 obj->regionId = SharedRegion_getId((Ptr)obj->attrs);
1057 obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
1058 /* Assert that the buffer is in a valid shared region */
1059 Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID,
1060 ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);
1061 }
1063 obj->allocSize = 0;
1064 obj->objType = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC;
1066 minAlign = Memory_getMaxDefaultTypeAlign();
1068 if ((obj->attrs != NULL) &&
1069 (SharedRegion_getCacheLineSize(obj->regionId) > minAlign)) {
1070 minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1071 }
1073 offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1075 /* TODO: host side created gates cannot have proxy memory */
1076 if (obj->attrs != NULL) {
1077 obj->proxyAttrs = (Ptr)((UInt32)obj->attrs + offset);
1078 }
1079 else {
1080 obj->proxyAttrs = NULL;
1081 }
1082 }
1083 /* Create GateMP instance */
1084 else {
1085 obj->localProtect = params->localProtect;
1086 obj->remoteProtect = params->remoteProtect;
1087 obj->nsKey = 0;
1088 obj->numOpens = 0;
1090 if (obj->remoteProtect == GateMP_RemoteProtect_NONE) {
1091 obj->gateHandle = ti_sdo_ipc_GateMP_createLocal(obj->localProtect);
1092 if (params->sharedAddr != NULL) {
1093 /* Create a local gate using shared memory */
1094 obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
1095 obj->attrs = params->sharedAddr;
1096 obj->regionId = SharedRegion_getId((Ptr)obj->attrs);
1097 obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
1098 }
1099 else {
1100 /* Create a local gate allocating from the local heap */
1101 obj->objType = ti_sdo_ipc_Ipc_ObjType_LOCAL;
1102 obj->regionId = ti_sdo_ipc_SharedRegion_INVALIDREGIONID;
1103 obj->cacheEnabled = FALSE; /* local */
1104 obj->attrs = Memory_alloc(NULL,
1105 sizeof(ti_sdo_ipc_GateMP_Attrs), 0, eb);
1106 if (obj->attrs == NULL) {
1107 return (2);
1108 }
1110 }
1112 obj->attrs->arg = (Bits32)obj;
1113 obj->attrs->mask = SETMASK(obj->remoteProtect, obj->localProtect);
1114 obj->attrs->creatorProcId = MultiProc_self();
1115 obj->attrs->status = ti_sdo_ipc_GateMP_CREATED;
1116 if (obj->cacheEnabled) {
1117 /*
1118 * Need to write back memory if cache is enabled because cache
1119 * will be invalidated during openByAddr
1120 */
1121 Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1122 Cache_Type_ALL, TRUE);
1123 }
1125 if (params->name) {
1126 nsValue[0] = (UInt32)obj->attrs;
1127 /*
1128 * Top 16 bits = procId of creator
1129 * Bottom 16 bits = '0' if local, '1' otherwise
1130 */
1131 nsValue[1] = ((UInt32)MultiProc_self()) << 16;
1133 if (GateMP_module->hostSupport == TRUE) {
1134 nsValue[2] = obj->attrs->arg;
1135 nsValue[3] = obj->attrs->mask;
1136 sizeNsValue = sizeof(nsValue);
1137 }
1138 else {
1139 sizeNsValue = 2 * sizeof(UInt32);
1140 }
1142 obj->nsKey = NameServer_add((NameServer_Handle)
1143 GateMP_module->nameServer, params->name, &nsValue,
1144 sizeNsValue);
1146 if (obj->nsKey == NULL) {
1147 Error_raise(eb, ti_sdo_ipc_Ipc_E_nameFailed, params->name,
1148 0);
1149 return (3);
1150 }
1151 }
1153 /* Nothing else to do for local gates */
1154 return (0);
1155 }
1157 if (params->sharedAddr == NULL) {
1158 /* Need to allocate from heap */
1159 obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION;
1160 obj->regionId = params->regionId;
1161 GateMP_getSharedParams(&sparams, params);
1162 obj->allocSize = GateMP_sharedMemReq(&sparams);
1163 obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
1165 /* The region heap will do the alignment */
1166 regionHeap = SharedRegion_getHeap(obj->regionId);
1167 Assert_isTrue(regionHeap != NULL, ti_sdo_ipc_SharedRegion_A_noHeap);
1168 obj->attrs = Memory_alloc(regionHeap, obj->allocSize, 0, eb);
1169 if (obj->attrs == NULL) {
1170 return (3);
1171 }
1173 minAlign = Memory_getMaxDefaultTypeAlign();
1175 if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) {
1176 minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1177 }
1179 offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1181 obj->proxyAttrs = (Ptr)((UInt32)obj->attrs + offset);
1182 }
1183 else {
1184 /* creating using sharedAddr */
1185 obj->regionId = SharedRegion_getId(params->sharedAddr);
1186 /* Assert that the buffer is in a valid shared region */
1187 Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID,
1188 ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);
1190 obj->attrs = (ti_sdo_ipc_GateMP_Attrs *)params->sharedAddr;
1191 obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
1192 obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
1194 minAlign = Memory_getMaxDefaultTypeAlign();
1196 if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) {
1197 minAlign = SharedRegion_getCacheLineSize(obj->regionId);
1198 }
1200 /* Assert that sharedAddr has correct alignment */
1201 Assert_isTrue(minAlign == 0 ||
1202 ((UInt32)params->sharedAddr % minAlign) == 0,
1203 ti_sdo_ipc_Ipc_A_addrNotCacheAligned);
1205 offset = _Ipc_roundup(sizeof(ti_sdo_ipc_GateMP_Attrs), minAlign);
1207 obj->proxyAttrs = (Ptr)((UInt32)obj->attrs + offset);
1208 }
1209 }
1211 /* Proxy work for open and create done here */
1212 switch (obj->remoteProtect) {
1213 case GateMP_RemoteProtect_SYSTEM:
1214 if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1215 /* Created Instance */
1216 obj->resourceId = GateMP_getFreeResource(
1217 GateMP_module->remoteSystemInUse,
1218 GateMP_module->numRemoteSystem, eb);
1219 if (Error_check(eb) == TRUE) {
1220 return (4);
1221 }
1222 }
1223 else {
1224 /* resourceId set by open call */
1225 obj->resourceId = params->resourceId;
1226 }
1228 /* Create the proxy object */
1229 ti_sdo_ipc_GateMP_RemoteSystemProxy_Params_init(&systemParams);
1230 systemParams.resourceId = obj->resourceId;
1231 systemParams.openFlag =
1232 (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1233 systemParams.sharedAddr = obj->proxyAttrs;
1234 systemParams.regionId = obj->regionId;
1235 remoteHandle = ti_sdo_ipc_GateMP_RemoteSystemProxy_create(
1236 localHandle, &systemParams, eb);
1238 if (remoteHandle == NULL) {
1239 return (5);
1240 }
1242 /* Fill in the local array because it is cooked */
1243 key = Hwi_disable();
1244 GateMP_module->remoteSystemGates[obj->resourceId] = obj;
1245 Hwi_restore(key);
1246 break;
1248 case GateMP_RemoteProtect_CUSTOM1:
1249 if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1250 obj->resourceId = GateMP_getFreeResource(
1251 GateMP_module->remoteCustom1InUse,
1252 GateMP_module->numRemoteCustom1, eb);
1253 if (Error_check(eb) == TRUE) {
1254 return (4);
1255 }
1256 }
1257 else {
1258 /* resourceId set by open call */
1259 obj->resourceId = params->resourceId;
1260 }
1262 /* Create the proxy object */
1263 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Params_init(&custom1Params);
1264 custom1Params.resourceId = obj->resourceId;
1265 custom1Params.openFlag =
1266 (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1267 custom1Params.sharedAddr = obj->proxyAttrs;
1268 custom1Params.regionId = obj->regionId;
1269 remoteHandle = ti_sdo_ipc_GateMP_RemoteCustom1Proxy_create(
1270 localHandle, &custom1Params, eb);
1271 if (remoteHandle == NULL) {
1272 return (5);
1273 }
1275 /* Fill in the local array because it is cooked */
1276 key = Hwi_disable();
1277 GateMP_module->remoteCustom1Gates[obj->resourceId] = obj;
1278 Hwi_restore(key);
1279 break;
1281 case GateMP_RemoteProtect_CUSTOM2:
1282 if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1283 obj->resourceId = GateMP_getFreeResource(
1284 GateMP_module->remoteCustom2InUse,
1285 GateMP_module->numRemoteCustom2, eb);
1286 if (Error_check(eb) == TRUE) {
1287 return (4);
1288 }
1289 }
1290 else {
1291 /* resourceId set by open call */
1292 obj->resourceId = params->resourceId;
1293 }
1295 /* Create the proxy object */
1296 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Params_init(&custom2Params);
1297 custom2Params.resourceId = obj->resourceId;
1298 custom2Params.openFlag =
1299 (obj->objType == ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC);
1300 custom2Params.sharedAddr = obj->proxyAttrs;
1301 custom2Params.regionId = obj->regionId;
1302 remoteHandle = ti_sdo_ipc_GateMP_RemoteCustom2Proxy_create(
1303 localHandle, &custom2Params, eb);
1304 if (remoteHandle == NULL) {
1305 return (5);
1306 }
1308 /* Fill in the local array because it is cooked */
1309 key = Hwi_disable();
1310 GateMP_module->remoteCustom2Gates[obj->resourceId] = obj;
1311 Hwi_restore(key);
1312 break;
1314 default:
1315 /* Should never be here */
1316 Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
1317 return (5); /* keep Coverity happy */
1318 }
1320 obj->gateHandle = IGateMPSupport_Handle_upCast(remoteHandle);
1322 /* Place Name/Attrs into NameServer table */
1323 if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1324 /* Fill in the attrs */
1325 obj->attrs->arg = obj->resourceId;
1326 obj->attrs->mask = SETMASK(obj->remoteProtect, obj->localProtect);
1327 obj->attrs->creatorProcId = MultiProc_self();
1328 obj->attrs->status = ti_sdo_ipc_GateMP_CREATED;
1330 if (obj->cacheEnabled) {
1331 Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1332 Cache_Type_ALL, TRUE);
1333 }
1335 if (params->name != NULL) {
1336 sharedShmBase = SharedRegion_getSRPtr(obj->attrs, obj->regionId);
1337 nsValue[0] = (UInt32)sharedShmBase;
1338 /*
1339 * Top 16 bits = procId of creator
1340 * Bottom 16 bits = '0' if local, '1' otherwise
1341 */
1342 nsValue[1] = ((UInt32)MultiProc_self() << 16) | 1;
1344 if (GateMP_module->hostSupport == TRUE) {
1345 /* Making a copy of these for host processor */
1346 nsValue[2] = obj->attrs->arg;
1347 nsValue[3] = obj->attrs->mask;
1348 sizeNsValue = sizeof(nsValue);
1349 }
1350 else {
1351 sizeNsValue = 2 * sizeof(UInt32);
1352 }
1354 obj->nsKey = NameServer_add((NameServer_Handle)
1355 GateMP_module->nameServer, params->name, &nsValue,
1356 sizeNsValue);
1358 if (obj->nsKey == NULL) {
1359 Error_raise(eb, ti_sdo_ipc_Ipc_E_nameFailed, params->name, 0);
1360 return (6);
1361 }
1362 }
1364 Log_write2(ti_sdo_ipc_GateMP_LM_create,
1365 (UArg)obj->remoteProtect, (UArg)obj->resourceId);
1366 }
1367 else {
1368 obj->numOpens = 1;
1370 Log_write2(ti_sdo_ipc_GateMP_LM_open,
1371 (UArg)obj->remoteProtect, (UArg)obj->resourceId);
1372 }
1374 return (0);
1375 }
1377 /*
1378 * ======== ti_sdo_ipc_GateMP_Instance_finalize ========
1379 */
1380 Void ti_sdo_ipc_GateMP_Instance_finalize(
1381 ti_sdo_ipc_GateMP_Object *obj, Int status)
1382 {
1383 UInt systemKey;
1384 ti_sdo_ipc_GateMP_RemoteSystemProxy_Handle systemHandle;
1385 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Handle custom1Handle;
1386 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Handle custom2Handle;
1388 ti_sdo_ipc_GateMP_Handle *remoteHandles;
1389 UInt8 *inUseArray;
1390 UInt size;
1392 /* Cannot call when numOpen is non-zero. */
1393 Assert_isTrue(obj->numOpens == 0, ti_sdo_ipc_GateMP_A_invalidDelete);
1395 /* Removed from NameServer */
1396 if (obj->nsKey != 0) {
1397 NameServer_removeEntry((NameServer_Handle)GateMP_module->nameServer,
1398 obj->nsKey);
1399 }
1401 /* Set the status to 0 */
1402 if (obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) {
1403 obj->attrs->status = 0;
1404 if (obj->cacheEnabled) {
1405 Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs),
1406 Cache_Type_ALL, TRUE);
1407 }
1408 }
1410 /*
1411 * If ObjType_LOCAL, memory was allocated from the local system heap.
1412 * obj->attrs might be NULL if the Memory_alloc failed in Instance_init
1413 */
1414 if (obj->objType == ti_sdo_ipc_Ipc_ObjType_LOCAL && obj->attrs != NULL) {
1415 Memory_free(NULL, obj->attrs, sizeof(ti_sdo_ipc_GateMP_Attrs));
1416 }
1418 switch (obj->remoteProtect) {
1419 case GateMP_RemoteProtect_SYSTEM:
1420 if (obj->gateHandle) {
1421 systemHandle =
1422 ti_sdo_ipc_GateMP_RemoteSystemProxy_Handle_downCast2(
1423 obj->gateHandle);
1424 ti_sdo_ipc_GateMP_RemoteSystemProxy_delete(&systemHandle);
1425 }
1427 inUseArray = GateMP_module->remoteSystemInUse;
1428 remoteHandles = GateMP_module->remoteSystemGates;
1429 size = GateMP_module->numRemoteSystem * sizeof(UInt8);
1430 break;
1432 case GateMP_RemoteProtect_CUSTOM1:
1433 if (obj->gateHandle) {
1434 custom1Handle =
1435 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_Handle_downCast2(
1436 obj->gateHandle);
1437 ti_sdo_ipc_GateMP_RemoteCustom1Proxy_delete(&custom1Handle);
1438 }
1440 inUseArray = GateMP_module->remoteCustom1InUse;
1441 remoteHandles = GateMP_module->remoteCustom1Gates;
1442 size = GateMP_module->numRemoteCustom1 * sizeof(UInt8);
1443 break;
1445 case GateMP_RemoteProtect_CUSTOM2:
1446 if (obj->gateHandle) {
1447 custom2Handle =
1448 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_Handle_downCast2(
1449 obj->gateHandle);
1450 ti_sdo_ipc_GateMP_RemoteCustom2Proxy_delete(&custom2Handle);
1451 }
1453 inUseArray = GateMP_module->remoteCustom2InUse;
1454 remoteHandles = GateMP_module->remoteCustom2Gates;
1455 size = GateMP_module->numRemoteCustom2 * sizeof(UInt8);
1456 break;
1457 case GateMP_RemoteProtect_NONE:
1458 /*
1459 * Nothing else to finalize. Any alloc'ed memory has already been
1460 * freed
1461 */
1462 Log_write2(ti_sdo_ipc_GateMP_LM_delete, (UArg)obj->remoteProtect,
1463 (UArg)obj->resourceId);
1464 return;
1465 default:
1466 /* Should never be here */
1467 Assert_isTrue(FALSE, ti_sdo_ipc_Ipc_A_internal);
1468 break;
1469 }
1471 /* Clear the handle array entry in local memory */
1472 if (obj->resourceId != (UInt)-1) {
1473 remoteHandles[obj->resourceId] = NULL;
1474 }
1476 if ((obj->objType != ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC) &&
1477 (obj->resourceId != (UInt)-1)) {
1478 /* Clear the resource used flag in shared memory */
1479 if (GateMP_module->defaultGate != NULL) {
1480 systemKey = GateMP_enter((GateMP_Handle)GateMP_module->defaultGate);
1481 }
1482 else {
1483 /* this should only be done when deleting the very last GateMP */
1484 systemKey = Hwi_disable();
1485 }
1487 #ifdef xdc_target__isaCompatible_v7A
1488 /* ARM speculative execution might have pulled array into cache */
1489 if (obj->cacheEnabled) {
1490 Cache_inv(inUseArray, size, Cache_Type_ALL, TRUE);
1491 }
1492 #endif
1493 /* update the GateMP resource tracker */
1494 inUseArray[obj->resourceId] = UNUSED;
1495 if (obj->cacheEnabled) {
1496 Cache_wbInv(inUseArray, size, Cache_Type_ALL, TRUE);
1497 }
1499 if (GateMP_module->defaultGate != NULL) {
1500 GateMP_leave((GateMP_Handle)GateMP_module->defaultGate, systemKey);
1501 }
1502 else {
1503 Hwi_restore(systemKey);
1504 }
1505 }
1507 if (obj->objType == ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION) {
1508 /* Free memory allocated from the region heap */
1509 if (obj->attrs) {
1510 Memory_free(SharedRegion_getHeap(obj->regionId), obj->attrs,
1511 obj->allocSize);
1512 }
1513 }
1515 Log_write2(ti_sdo_ipc_GateMP_LM_delete, (UArg)obj->remoteProtect,
1516 (UArg)obj->resourceId);
1517 }
1519 /*
1520 * ======== ti_sdo_ipc_GateMP_getSharedAddr ========
1521 */
1522 SharedRegion_SRPtr ti_sdo_ipc_GateMP_getSharedAddr(
1523 ti_sdo_ipc_GateMP_Object *obj)
1524 {
1525 SharedRegion_SRPtr srPtr;
1527 srPtr = SharedRegion_getSRPtr(obj->attrs, obj->regionId);
1529 return (srPtr);
1530 }
1532 /*
1533 * ======== ti_sdo_ipc_GateMP_setDefaultRemote ========
1534 */
1535 Void ti_sdo_ipc_GateMP_setDefaultRemote(ti_sdo_ipc_GateMP_Object *obj)
1536 {
1537 GateMP_module->defaultGate = obj;
1538 }
1540 /*
1541 *************************************************************************
1542 * Internal functions
1543 *************************************************************************
1544 */
1546 /*
1547 * ======== ti_sdo_ipc_GateMP_getFreeResource ========
1548 */
1549 UInt ti_sdo_ipc_GateMP_getFreeResource(UInt8 *inUse, Int num, Error_Block *eb)
1550 {
1551 UInt key;
1552 Bool flag = FALSE;
1553 UInt resourceId;
1554 GateMP_Handle defaultGate;
1556 /* Need to look at shared memory. Enter default gate */
1557 defaultGate = GateMP_getDefaultRemote();
1559 if (defaultGate){
1560 key = GateMP_enter(defaultGate);
1561 }
1563 /* Invalidate cache before looking at the in-use flags */
1564 if (SharedRegion_isCacheEnabled(0)) {
1565 Cache_inv(inUse, num * sizeof(UInt8), Cache_Type_ALL, TRUE);
1566 }
1568 /*
1569 * Find a free resource id. Note: zero is reserved on the
1570 * system proxy for the default gate.
1571 */
1572 for (resourceId = 0; resourceId < num; resourceId++) {
1573 /*
1574 * If not in-use, set the inUse to TRUE to prevent other
1575 * creates from getting this one.
1576 */
1577 if (inUse[resourceId] == UNUSED) {
1578 flag = TRUE;
1580 /* Denote in shared memory that the resource is used */
1581 inUse[resourceId] = USED;
1582 break;
1583 }
1584 }
1586 /* Write-back if a in-use flag was changed */
1587 if (flag == TRUE && SharedRegion_isCacheEnabled(0)) {
1588 Cache_wbInv(inUse, num * sizeof(UInt8), Cache_Type_ALL, TRUE);
1589 }
1591 /* Done with the critical section */
1592 if (defaultGate) {
1593 GateMP_leave(defaultGate, key);
1594 }
1596 if (flag == FALSE) {
1597 resourceId = (UInt)-1;
1598 Error_raise(eb, ti_sdo_ipc_GateMP_E_gateUnavailable, 0, 0);
1599 }
1601 return (resourceId);
1602 }