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