/* * ======== ListMP_putTail ======== */ Int ListMP_putTail(ListMP_Handle handle, ListMP_Elem *elem) { ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle; UInt key; UInt16 id; ListMP_Elem *localPrevElem; SharedRegion_SRPtr sharedElem; SharedRegion_SRPtr sharedHead; Bool localPrevElemIsCached; /* prevent another thread or processor from modifying the ListMP */ key = GateMP_enter((GateMP_Handle)obj->gate); id = SharedRegion_getId(elem); if (ti_sdo_ipc_SharedRegion_translate == FALSE) { sharedElem = (SharedRegion_SRPtr)elem; sharedHead = (SharedRegion_SRPtr)&(obj->attrs->head); localPrevElem = (ListMP_Elem *)obj->attrs->head.prev; } else { sharedElem = SharedRegion_getSRPtr(elem, id); sharedHead = SharedRegion_getSRPtr(&(obj->attrs->head), obj->regionId); localPrevElem = SharedRegion_getPtr(obj->attrs->head.prev); } /* Assert that pointer is not NULL */ Assert_isTrue(localPrevElem != NULL, ti_sdo_ipc_Ipc_A_nullPointer); localPrevElemIsCached = SharedRegion_isCacheEnabled( SharedRegion_getId(localPrevElem)); if (localPrevElemIsCached) { Cache_inv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } /* add the new elem into the list */ elem->next = sharedHead; elem->prev = obj->attrs->head.prev; localPrevElem->next = sharedElem; obj->attrs->head.prev = sharedElem; if (localPrevElemIsCached) { /* Write-back because localPrevElem->next changed */ Cache_wbInv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } if (obj->cacheEnabled) { /* Write-back because obj->attrs->head.prev changed */ Cache_wbInv(&(obj->attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } if (SharedRegion_isCacheEnabled(id)) { /* Write-back because elem->next & elem->prev changed */ Cache_wbInv(elem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } GateMP_leave((GateMP_Handle)obj->gate, key); return (ListMP_S_SUCCESS); }
/* * ======== ListMP_prev ======== */ Ptr ListMP_prev(ListMP_Handle handle, ListMP_Elem *elem) { ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle; ListMP_Elem *retElem; /* returned elem */ Bool elemIsCached; /* elem == NULL -> start at the head */ if (elem == NULL) { elemIsCached = obj->cacheEnabled; elem = (ListMP_Elem *)&(obj->attrs->head); } else { elemIsCached = SharedRegion_isCacheEnabled(SharedRegion_getId(elem)); } if (elemIsCached) { Cache_inv(elem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } retElem = SharedRegion_getPtr(elem->prev); if (retElem == (ListMP_Elem *)(&(obj->attrs->head))) { retElem = NULL; } if (elemIsCached) { /* Invalidate because elem pulled into cache && elem != head. */ Cache_inv(elem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } return (retElem); }
/* * ======== GatePetersonN_Instance_init ======== */ Int GatePetersonN_Instance_init(GatePetersonN_Object *obj, IGateProvider_Handle localGate, const GatePetersonN_Params *params, Error_Block *eb) { SizeT offset; SizeT minAlign = Memory_getMaxDefaultTypeAlign(); SizeT i; if (SharedRegion_getCacheLineSize(params->regionId) > minAlign) { minAlign = SharedRegion_getCacheLineSize(params->regionId); } Assert_isTrue(params->sharedAddr != NULL, ti_sdo_ipc_Ipc_A_invParam); Assert_isTrue(GatePetersonN_numInstances != 0, ti_sdo_ipc_Ipc_A_invParam); obj->localGate = localGate; obj->cacheEnabled = SharedRegion_isCacheEnabled(params->regionId); obj->cacheLineSize = SharedRegion_getCacheLineSize(params->regionId); obj->nested = 0; /* This is not cluster aware: * obj->numProcessors = MultiProc_getNumProcessors(); * obj->selfId = MultiProc_self(); */ /* Cluster aware initialization */ obj->numProcessors = MultiProc_getNumProcsInCluster(); /* set selfId to 0-based offset within cluster. */ obj->selfId = MultiProc_self() - MultiProc_getBaseIdOfCluster(); /* Assign shared memory addresses for the protocol state variables */ offset = 0; for (i=0; i < obj->numProcessors; i++) { obj->enteredStage[i] = (Int32 *)((UArg)(params->sharedAddr) + offset); offset += minAlign; } for (i=0; i < obj->numProcessors - 1; i++) { obj->lastProcEnteringStage[i] = (Int32 *)((UArg)(params->sharedAddr) + offset); offset += minAlign; } if (!params->openFlag) { /* Creating. */ obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC; GatePetersonN_postInit(obj); } else { /* Opening. */ obj->objType = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC; } return (0); }
/* * ======== ti_sdo_ipc_Ipc_procSyncFinish ======== * Each processor writes its reserve memory address in SharedRegion 0 * to let the other processors know its finished the process of * synchronization. */ Int ti_sdo_ipc_Ipc_procSyncFinish(UInt16 remoteProcId, Ptr sharedAddr) { volatile ti_sdo_ipc_Ipc_Reserved *self, *remote; SizeT reservedSize = ti_sdo_ipc_Ipc_reservedSizePerProc(); Bool cacheEnabled = SharedRegion_isCacheEnabled(0); UInt oldPri; /* don't do any synchronization if procSync is NONE */ if (ti_sdo_ipc_Ipc_procSync == ti_sdo_ipc_Ipc_ProcSync_NONE) { return (Ipc_S_SUCCESS); } /* determine self and remote pointers */ if (MultiProc_self() < remoteProcId) { self = Ipc_getSlaveAddr(remoteProcId, sharedAddr); remote = ti_sdo_ipc_Ipc_getMasterAddr(remoteProcId, sharedAddr); } else { self = ti_sdo_ipc_Ipc_getMasterAddr(remoteProcId, sharedAddr); remote = Ipc_getSlaveAddr(remoteProcId, sharedAddr); } /* set my processor's reserved key to finish */ self->startedKey = ti_sdo_ipc_Ipc_PROCSYNCFINISH; /* write back my processor's reserve key */ if (cacheEnabled) { Cache_wbInv((Ptr)self, reservedSize, Cache_Type_ALL, TRUE); } /* if slave processor, wait for remote to finish sync */ if (MultiProc_self() < remoteProcId) { if (BIOS_getThreadType() == BIOS_ThreadType_Task) { oldPri = Task_getPri(Task_self()); } /* wait for remote processor to finish */ while (remote->startedKey != ti_sdo_ipc_Ipc_PROCSYNCFINISH && remote->startedKey != ti_sdo_ipc_Ipc_PROCSYNCDETACH) { /* Set self priority to 1 [lowest] and yield cpu */ if (BIOS_getThreadType() == BIOS_ThreadType_Task) { Task_setPri(Task_self(), 1); Task_yield(); } /* Check the remote's sync flag */ if (cacheEnabled) { Cache_inv((Ptr)remote, reservedSize, Cache_Type_ALL, TRUE); } } /* Restore self priority */ if (BIOS_getThreadType() == BIOS_ThreadType_Task) { Task_setPri(Task_self(), oldPri); } } return (Ipc_S_SUCCESS); }
/* * ======== ListMP_remove ======== */ Int ListMP_remove(ListMP_Handle handle, ListMP_Elem *elem) { ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle; UInt key; ListMP_Elem *localPrevElem; ListMP_Elem *localNextElem; Bool localPrevElemIsCached, localNextElemIsCached; /* Prevent another thread or processor from modifying the ListMP */ key = GateMP_enter((GateMP_Handle)obj->gate); if (ti_sdo_ipc_SharedRegion_translate == FALSE) { localPrevElem = (ListMP_Elem *)(elem->prev); localNextElem = (ListMP_Elem *)(elem->next); } else { localPrevElem = SharedRegion_getPtr(elem->prev); localNextElem = SharedRegion_getPtr(elem->next); } localPrevElemIsCached = SharedRegion_isCacheEnabled( SharedRegion_getId(localPrevElem)); localNextElemIsCached = SharedRegion_isCacheEnabled( SharedRegion_getId(localNextElem)); if (localPrevElemIsCached) { Cache_inv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } if (localNextElemIsCached) { Cache_inv(localNextElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } localPrevElem->next = elem->next; localNextElem->prev = elem->prev; if (localPrevElemIsCached) { Cache_wbInv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } if (localNextElemIsCached) { Cache_wbInv(localNextElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } GateMP_leave((GateMP_Handle)obj->gate, key); return (ListMP_S_SUCCESS); }
/* * ======== ListMP_openByAddr ======== */ Int ListMP_openByAddr(Ptr sharedAddr, ListMP_Handle *handlePtr) { ti_sdo_ipc_ListMP_Params params; ti_sdo_ipc_ListMP_Attrs *attrs; Error_Block eb; Int status; UInt16 id; Error_init(&eb); ti_sdo_ipc_ListMP_Params_init(¶ms); /* Tell Instance_init() that we're opening */ params.openFlag = TRUE; attrs = (ti_sdo_ipc_ListMP_Attrs *)sharedAddr; params.sharedAddr = sharedAddr; id = SharedRegion_getId(sharedAddr); if (SharedRegion_isCacheEnabled(id)) { Cache_inv(attrs, sizeof(ti_sdo_ipc_ListMP_Attrs), Cache_Type_ALL, TRUE); } if (attrs->status != ti_sdo_ipc_ListMP_CREATED) { *handlePtr = NULL; status = ListMP_E_NOTFOUND; } else { /* Create the object */ *handlePtr = (ListMP_Handle)ti_sdo_ipc_ListMP_create(¶ms, &eb); if (*handlePtr == NULL) { status = ListMP_E_FAIL; } else { status = ListMP_S_SUCCESS; } } if (SharedRegion_isCacheEnabled(id)) { Cache_inv(attrs, sizeof(ti_sdo_ipc_ListMP_Attrs), Cache_Type_ALL, TRUE); } return (status); }
/* * ======== Ipc_readConfig ======== */ Int Ipc_readConfig(UInt16 remoteProcId, UInt32 tag, Ptr cfg, SizeT size) { Int status = Ipc_E_FAIL; UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId); volatile ti_sdo_ipc_Ipc_ConfigEntry *entry; Bool cacheEnabled = SharedRegion_isCacheEnabled(0); /* Assert that the remoteProc in our cluster and isn't our own */ Assert_isTrue(clusterId < ti_sdo_utils_MultiProc_numProcsInCluster, ti_sdo_utils_MultiProc_A_invalidMultiProcId); if (cacheEnabled) { Cache_inv(Ipc_module->procEntry[clusterId].remoteConfigList, SharedRegion_getCacheLineSize(0), Cache_Type_ALL, TRUE); } entry = (ti_sdo_ipc_Ipc_ConfigEntry *) *Ipc_module->procEntry[clusterId].remoteConfigList; while ((SharedRegion_SRPtr)entry != ti_sdo_ipc_SharedRegion_INVALIDSRPTR) { entry = (ti_sdo_ipc_Ipc_ConfigEntry *) SharedRegion_getPtr((SharedRegion_SRPtr)entry); /* Traverse the list to find the tag */ if (cacheEnabled) { Cache_inv((Ptr)entry, size + sizeof(ti_sdo_ipc_Ipc_ConfigEntry), Cache_Type_ALL, TRUE); } if ((entry->remoteProcId == MultiProc_self()) && (entry->localProcId == remoteProcId) && (entry->tag == tag)) { if (size == entry->size) { memcpy(cfg, (Ptr)((UInt32)entry + sizeof(ti_sdo_ipc_Ipc_ConfigEntry)), entry->size); return (Ipc_S_SUCCESS); } else { return (Ipc_E_FAIL); } } entry = (ti_sdo_ipc_Ipc_ConfigEntry *)entry->next; } return (status); }
/* * ======== TransportShm_openByAddr ======== */ Int TransportShm_openByAddr(Ptr sharedAddr, TransportShm_Handle *handlePtr, Error_Block *eb) { TransportShm_Params params; TransportShm_Attrs *attrs; Int status; UInt16 id; if (sharedAddr == NULL) { return (MessageQ_E_FAIL); } TransportShm_Params_init(¶ms); /* Tell Instance_init() that we're opening */ params.openFlag = TRUE; attrs = (TransportShm_Attrs *)sharedAddr; id = SharedRegion_getId(sharedAddr); /* Assert that the region is valid */ Assert_isTrue(id != SharedRegion_INVALIDREGIONID, ti_sdo_ipc_Ipc_A_addrNotInSharedRegion); /* invalidate the attrs before using it */ if (SharedRegion_isCacheEnabled(id)) { Cache_inv(attrs, sizeof(TransportShm_Attrs), Cache_Type_ALL, TRUE); } /* set params field */ params.sharedAddr = sharedAddr; params.priority = attrs->priority; if (attrs->flag != TransportShm_UP) { /* make sure transport is up */ *handlePtr = NULL; status = MessageQ_E_NOTFOUND; } else { /* Create the object */ *handlePtr = TransportShm_create(attrs->creatorProcId, ¶ms, eb); if (*handlePtr == NULL) { status = MessageQ_E_FAIL; } else { status = MessageQ_S_SUCCESS; } } return (status); }
/* * ======== ti_sdo_ipc_ListMP_elemClear ======== */ Void ti_sdo_ipc_ListMP_elemClear(ti_sdo_ipc_ListMP_Elem *elem) { SharedRegion_SRPtr sharedElem; UInt16 id; id = SharedRegion_getId(elem); sharedElem = SharedRegion_getSRPtr(elem, id); elem->next = elem->prev = sharedElem; if (SharedRegion_isCacheEnabled(id)) { Cache_wbInv(elem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } }
/* * ======== TransportShm_put ======== * Assuming MessageQ_put is making sure that the arguments are ok */ Bool TransportShm_put(TransportShm_Object *obj, Ptr msg) { Int32 status; Bool retval = TRUE; IArg key; UInt16 id = SharedRegion_getId(msg); /* This transport only deals with messages allocated from SR's */ Assert_isTrue(id != SharedRegion_INVALIDREGIONID, ti_sdo_ipc_SharedRegion_A_regionInvalid); /* writeback invalidate the message */ if (SharedRegion_isCacheEnabled(id)) { Cache_wbInv(msg, ((MessageQ_Msg)(msg))->msgSize, Cache_Type_ALL, TRUE); } /* make sure ListMP_put and sendEvent are done before remote executes */ key = GateMP_enter((GateMP_Handle)obj->gate); /* Put the message on the remoteList */ ListMP_putTail((ListMP_Handle)obj->remoteList, (ListMP_Elem *)msg); /* Notify the remote processor */ status = Notify_sendEvent(obj->remoteProcId, 0, TransportShm_notifyEventId, 0, FALSE); /* check the status of the sendEvent */ if (status < 0) { /* remove the message from the List and return 'FALSE' */ ListMP_remove((ListMP_Handle)obj->remoteList, (ListMP_Elem *)msg); retval = FALSE; } /* leave the gate */ GateMP_leave((GateMP_Handle)obj->gate, key); return (retval); }
/* * ======== SemaphoreMP_openByAddr ======== */ Int SemaphoreMP_openByAddr(Ptr sharedAddr, SemaphoreMP_Handle *handlePtr) { SemaphoreMP_Params params; SemaphoreMP_Attrs *attrs; Int status; Error_Block eb; Error_init(&eb); SemaphoreMP_Params_init(¶ms); /* Tell Instance_init() that we're opening */ params.openFlag = TRUE; params.sharedAddr = sharedAddr; attrs = (SemaphoreMP_Attrs *)sharedAddr; if (SharedRegion_isCacheEnabled(SharedRegion_getId(sharedAddr))) { Cache_inv(attrs, sizeof(SemaphoreMP_Attrs), Cache_Type_ALL, TRUE); } if (attrs->status != SemaphoreMP_CREATED) { *handlePtr = NULL; status = -1; //SemaphoreMP_E_NOTFOUND; } else { *handlePtr = SemaphoreMP_create(0, ¶ms, &eb); if (*handlePtr == NULL) { status = -1; //SemaphoreMP_E_FAIL; } else { status = 0; //SemaphoreMP_S_SUCCESS; } } return (status); }
static Int32 IpcFramesInLink_getFrameBuf(IpcFramesInLink_Obj * pObj, SystemIpcFrames_ListElem * pListElem, FVID2_Frame ** pFrameBufPtr) { FVID2_Frame *freeFrameBuf; Int status; UTILS_assert(pListElem != NULL); /* No cache ops done since pListElem is allocated from non-cached memory */ UTILS_assert(SharedRegion_isCacheEnabled(SharedRegion_getId(pListElem)) == FALSE); status = Utils_queGet(&pObj->freeFrameQue, (Ptr *)&freeFrameBuf,1,BIOS_NO_WAIT); UTILS_assert(status == FVID2_SOK); IpcFramesInLink_copyFrameInfo(pObj, &pListElem->frameBuf, freeFrameBuf, pListElem->srBufPtr); *pFrameBufPtr = freeFrameBuf; return IPC_FRAMES_IN_LINK_S_SUCCESS; }
/* * ======== Ipc_detach ======== */ Int Ipc_detach(UInt16 remoteProcId) { Int i; UInt16 baseId = MultiProc_getBaseIdOfCluster(); UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId); Ptr notifySharedAddr; Ptr nsrnSharedAddr; Ptr msgqSharedAddr; volatile ti_sdo_ipc_Ipc_Reserved *slave, *master; SharedRegion_Entry entry; ti_sdo_ipc_Ipc_ProcEntry *ipc; SizeT reservedSize = ti_sdo_ipc_Ipc_reservedSizePerProc(); Bool cacheEnabled = SharedRegion_isCacheEnabled(0); Int status = Ipc_S_SUCCESS; UInt hwiKey; /* Assert remoteProcId is in our cluster and isn't our own */ Assert_isTrue(clusterId < ti_sdo_utils_MultiProc_numProcsInCluster, ti_sdo_utils_MultiProc_A_invalidMultiProcId); Assert_isTrue(remoteProcId != MultiProc_self(), ti_sdo_ipc_Ipc_A_invArgument); /* for checking and incrementing attached below */ hwiKey = Hwi_disable(); if (Ipc_module->procEntry[clusterId].attached > 1) { /* only detach if attach count reaches 1 */ Ipc_module->procEntry[clusterId].attached--; Hwi_restore(hwiKey); return (Ipc_S_BUSY); } else if (Ipc_module->procEntry[clusterId].attached == 0) { /* already detached, restore interrupts and return success */ Hwi_restore(hwiKey); return (Ipc_S_SUCCESS); } /* restore interrupts */ Hwi_restore(hwiKey); /* get region 0 information */ SharedRegion_getEntry(0, &entry); /* * Make sure we detach from all other procs in cluster before * detaching from owner of SR 0. */ if (remoteProcId == entry.ownerProcId) { for (i = 0; i < ti_sdo_utils_MultiProc_numProcsInCluster; i++, baseId++) { if ((baseId != MultiProc_self()) && (baseId != entry.ownerProcId) && (Ipc_module->procEntry[i].attached)) { return (Ipc_E_FAIL); } } } /* get the paramters associated with remoteProcId */ ipc = &(Ipc_module->procEntry[clusterId]); /* determine the slave's slot */ slave = Ipc_getSlaveAddr(remoteProcId, Ipc_module->ipcSharedAddr); /* determine the master's slot */ master = ti_sdo_ipc_Ipc_getMasterAddr(remoteProcId, Ipc_module->ipcSharedAddr); if (cacheEnabled) { Cache_inv((Ptr)slave, reservedSize, Cache_Type_ALL, TRUE); Cache_inv((Ptr)master, reservedSize, Cache_Type_ALL, TRUE); } if (MultiProc_self() < remoteProcId) { /* check to make sure master is not trying to attach */ if (master->startedKey == ti_sdo_ipc_Ipc_PROCSYNCSTART) { return (Ipc_E_NOTREADY); } } else { /* check to make sure slave is not trying to attach */ if (slave->startedKey == ti_sdo_ipc_Ipc_PROCSYNCSTART) { return (Ipc_E_NOTREADY); } } /* The slave processor waits for master to finish its detach sequence */ if (MultiProc_self() < remoteProcId) { if (master->startedKey != ti_sdo_ipc_Ipc_PROCSYNCDETACH) { return (Ipc_E_NOTREADY); } } /* Call user detach fxns */ for (i = 0; i < ti_sdo_ipc_Ipc_numUserFxns; i++) { if (ti_sdo_ipc_Ipc_userFxns[i].userFxn.detach) { status = ti_sdo_ipc_Ipc_userFxns[i].userFxn.detach( ti_sdo_ipc_Ipc_userFxns[i].arg, remoteProcId); if (status < 0) { return (status); } } } if ((ipc->entry.setupMessageQ) && (ti_sdo_ipc_MessageQ_SetupTransportProxy_isRegistered(remoteProcId))) { /* call MessageQ_detach for remote processor */ status = ti_sdo_ipc_MessageQ_SetupTransportProxy_detach(remoteProcId); if (status < 0) { return (Ipc_E_FAIL); } if (slave->transportSRPtr) { /* free the memory if slave processor */ if (MultiProc_self() < remoteProcId) { /* get the pointer to MessageQ transport instance */ msgqSharedAddr = SharedRegion_getPtr(slave->transportSRPtr); /* free the memory back to SharedRegion 0 heap */ Memory_free(SharedRegion_getHeap(0), msgqSharedAddr, ti_sdo_ipc_MessageQ_SetupTransportProxy_sharedMemReq( msgqSharedAddr)); /* set pointer for MessageQ transport instance back to NULL */ slave->transportSRPtr = NULL; } } } if ((ipc->entry.setupNotify) && (ti_sdo_utils_NameServer_isRegistered(remoteProcId))) { /* call NameServer_SetupProxy_detach for remote processor */ status = ti_sdo_utils_NameServer_SetupProxy_detach(remoteProcId); if (status < 0) { return (Ipc_E_FAIL); } if (slave->nsrnSRPtr) { /* free the memory if slave processor */ if (MultiProc_self() < remoteProcId) { /* get the pointer to NSRN instance */ nsrnSharedAddr = SharedRegion_getPtr(slave->nsrnSRPtr); /* free the memory back to SharedRegion 0 heap */ Memory_free(SharedRegion_getHeap(0), nsrnSharedAddr, ti_sdo_utils_NameServer_SetupProxy_sharedMemReq( nsrnSharedAddr)); /* set pointer for NSRN instance back to NULL */ slave->nsrnSRPtr = NULL; } } } if ((ipc->entry.setupNotify) && (Notify_intLineRegistered(remoteProcId, 0))) { /* call Notify_detach for remote processor */ status = ti_sdo_ipc_Notify_detach(remoteProcId); if (status < 0) { return (Ipc_E_FAIL); } if (slave->notifySRPtr) { /* free the memory if slave processor */ if (MultiProc_self() < remoteProcId) { /* get the pointer to Notify instance */ notifySharedAddr = SharedRegion_getPtr(slave->notifySRPtr); /* free the memory back to SharedRegion 0 heap */ Memory_free(SharedRegion_getHeap(0), notifySharedAddr, Notify_sharedMemReq(remoteProcId, notifySharedAddr)); /* set pointer for Notify instance back to NULL */ slave->notifySRPtr = NULL; } } } /* close any HeapMemMP which may have been opened */ status = ti_sdo_ipc_SharedRegion_detach(remoteProcId); if (status < 0) { return (status); } /* close any GateMP which may have been opened */ status = ti_sdo_ipc_GateMP_detach(remoteProcId); if (status < 0) { return (status); } if (MultiProc_self() < remoteProcId) { slave->configListHead = ti_sdo_ipc_SharedRegion_INVALIDSRPTR; slave->startedKey = ti_sdo_ipc_Ipc_PROCSYNCDETACH; if (cacheEnabled) { Cache_wbInv((Ptr)slave, reservedSize, Cache_Type_ALL, TRUE); } } else { master->configListHead = ti_sdo_ipc_SharedRegion_INVALIDSRPTR; master->startedKey = ti_sdo_ipc_Ipc_PROCSYNCDETACH; if (cacheEnabled) { Cache_wbInv((Ptr)master, reservedSize, Cache_Type_ALL, TRUE); } } /* attached must be decremented atomically */ hwiKey = Hwi_disable(); /* now detached from remote processor */ Ipc_module->procEntry[clusterId].attached--; /* restore interrupts */ Hwi_restore(hwiKey); return (status); }
/* * ======== ti_sdo_ipc_Ipc_procSyncStart ======== * The owner of SharedRegion 0 writes to its reserve memory address * in region 0 to let the other processors know it has started. * It then spins until the other processors start. * The other processors write their reserve memory address in * region 0 to let the owner processor know they've started. * The other processors then spin until the owner processor writes * to let them know that its finished the process of synchronization * before continuing. */ Int ti_sdo_ipc_Ipc_procSyncStart(UInt16 remoteProcId, Ptr sharedAddr) { volatile ti_sdo_ipc_Ipc_Reserved *self, *remote; ti_sdo_ipc_Ipc_ProcEntry *ipc; UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId); SizeT reservedSize = ti_sdo_ipc_Ipc_reservedSizePerProc(); Bool cacheEnabled = SharedRegion_isCacheEnabled(0); /* don't do any synchronization if procSync is NONE */ if (ti_sdo_ipc_Ipc_procSync == ti_sdo_ipc_Ipc_ProcSync_NONE) { return (Ipc_S_SUCCESS); } /* determine self and remote pointers */ if (MultiProc_self() < remoteProcId) { self = Ipc_getSlaveAddr(remoteProcId, sharedAddr); remote = ti_sdo_ipc_Ipc_getMasterAddr(remoteProcId, sharedAddr); } else { self = ti_sdo_ipc_Ipc_getMasterAddr(remoteProcId, sharedAddr); remote = Ipc_getSlaveAddr(remoteProcId, sharedAddr); } /* construct the config list */ ipc = &(Ipc_module->procEntry[clusterId]); ipc->localConfigList = (Ptr)&self->configListHead; ipc->remoteConfigList = (Ptr)&remote->configListHead; *ipc->localConfigList = ti_sdo_ipc_SharedRegion_INVALIDSRPTR; if (cacheEnabled) { Cache_wbInv(ipc->localConfigList, reservedSize, Cache_Type_ALL, TRUE); } if (MultiProc_self() < remoteProcId) { /* set my processor's reserved key to start */ self->startedKey = ti_sdo_ipc_Ipc_PROCSYNCSTART; /* write back my processor's reserve key */ if (cacheEnabled) { Cache_wbInv((Ptr)self, reservedSize, Cache_Type_ALL, TRUE); } /* wait for remote processor to start */ if (cacheEnabled) { Cache_inv((Ptr)remote, reservedSize, Cache_Type_ALL, TRUE); } if (remote->startedKey != ti_sdo_ipc_Ipc_PROCSYNCSTART) { return (Ipc_E_NOTREADY); } } else { /* wait for remote processor to start */ if (cacheEnabled) { Cache_inv((Ptr)remote, reservedSize, Cache_Type_ALL, TRUE); } if ((self->startedKey != ti_sdo_ipc_Ipc_PROCSYNCSTART) && (remote->startedKey != ti_sdo_ipc_Ipc_PROCSYNCSTART)) { return (Ipc_E_NOTREADY); } /* set my processor's reserved key to start */ self->startedKey = ti_sdo_ipc_Ipc_PROCSYNCSTART; /* write my processor's reserve key back */ if (cacheEnabled) { Cache_wbInv((Ptr)self, reservedSize, Cache_Type_ALL, TRUE); /* wait for remote processor to finish */ Cache_inv((Ptr)remote, reservedSize, Cache_Type_ALL, TRUE); } if (remote->startedKey != ti_sdo_ipc_Ipc_PROCSYNCFINISH) { return (Ipc_E_NOTREADY); } } return (Ipc_S_SUCCESS); }
/* * ======== SemaphoreMP_Instance_init ======== */ Int SemaphoreMP_Instance_init(SemaphoreMP_Object *obj, Int count, const SemaphoreMP_Params *params, Error_Block *eb) { Ptr localAddr; Int status; IHeap_Handle regionHeap; ListMP_Params listMPParams; SharedRegion_SRPtr sharedShmBase; if (params->openFlag) { /* Open by sharedAddr */ obj->objType = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC; obj->attrs = (SemaphoreMP_Attrs *)params->sharedAddr; obj->regionId = SharedRegion_getId(obj->attrs); obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId); obj->mode = (SemaphoreMP_Mode)obj->attrs->mode; regionHeap = SharedRegion_getHeap(obj->regionId); Assert_isTrue(regionHeap != NULL, ti_sdo_ipc_SharedRegion_A_noHeap); /* get the local address of the SRPtr */ localAddr = SharedRegion_getPtr(obj->attrs->gateMPAddr); status = GateMP_openByAddr(localAddr, (GateMP_Handle *)&(obj->gate)); if (status < 0) { return (1); } /* Open the ListMP */ localAddr = (Ptr)_Ipc_roundup( (UInt32)obj->attrs + sizeof(SemaphoreMP_Attrs), SharedRegion_getCacheLineSize(obj->regionId)); status = ListMP_openByAddr(localAddr, (ListMP_Handle *)&(obj->pendQ)); if (status < 0) { /* obj->freeList set to NULL */ return (4); } return (0); } /* init the gate */ if (params->gate != NULL) { obj->gate = params->gate; } else { obj->gate = (ti_sdo_ipc_GateMP_Handle)GateMP_getDefaultRemote(); } obj->mode = params->mode; if (params->sharedAddr == NULL) { /* Creating using a shared region ID */ obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION; obj->regionId = params->regionId; obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId); /* Need to allocate from the heap */ obj->allocSize = SemaphoreMP_sharedMemReq(params); regionHeap = SharedRegion_getHeap(obj->regionId); Assert_isTrue(regionHeap != NULL, ti_sdo_ipc_SharedRegion_A_noHeap); /* The region heap will take care of the alignment */ obj->attrs = Memory_alloc(regionHeap, obj->allocSize, 0, eb); if (obj->attrs == NULL) { return (2); } } else { /* Creating using sharedAddr */ obj->regionId = SharedRegion_getId(params->sharedAddr); /* Assert that the buffer is in a valid shared region */ Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID, ti_sdo_ipc_Ipc_A_addrNotInSharedRegion); /* Assert that sharedAddr is cache aligned */ Assert_isTrue(((UInt32)params->sharedAddr % SharedRegion_getCacheLineSize(obj->regionId) == 0), ti_sdo_ipc_Ipc_A_addrNotCacheAligned); /* set object's cacheEnabled, objType, and attrs */ obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId); obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC; obj->attrs = (SemaphoreMP_Attrs *)params->sharedAddr; } /* Store the GateMP sharedAddr in the SemaphoreMP Attrs */ obj->attrs->gateMPAddr = ti_sdo_ipc_GateMP_getSharedAddr(obj->gate); obj->attrs->mode = (Bits16)obj->mode; obj->attrs->count = count; /* Create the freeList */ ListMP_Params_init(&listMPParams); listMPParams.sharedAddr = (Ptr)_Ipc_roundup((UInt32)obj->attrs + sizeof(SemaphoreMP_Attrs), SharedRegion_getCacheLineSize(obj->regionId)); listMPParams.gate = (GateMP_Handle)obj->gate; obj->pendQ = (ti_sdo_ipc_ListMP_Handle)ListMP_create(&listMPParams); if (obj->pendQ == NULL) { return (3); } /* Last thing, set the status */ obj->attrs->status = SemaphoreMP_CREATED; if (obj->cacheEnabled) { Cache_wbInv(obj->attrs, sizeof(SemaphoreMP_Attrs), Cache_Type_ALL, TRUE); } /* Add entry to NameServer */ if (params->name != NULL) { /* We will store a shared pointer in the NameServer */ sharedShmBase = SharedRegion_getSRPtr(obj->attrs, obj->regionId); obj->nsKey = NameServer_addUInt32((NameServer_Handle) SemaphoreMP_module->nameServer, params->name, (UInt32)sharedShmBase); if (obj->nsKey == NULL) { /* NameServer_addUInt32 failed */ return (4); } } return (0); }
/* * ======== ti_sdo_ipc_ListMP_Instance_init ======== */ Int ti_sdo_ipc_ListMP_Instance_init(ti_sdo_ipc_ListMP_Object *obj, const ti_sdo_ipc_ListMP_Params *params, Error_Block *eb) { SharedRegion_SRPtr sharedShmBase; Ptr localAddr; Int status; ListMP_Params sparams; IHeap_Handle regionHeap; if (params->openFlag == TRUE) { /* Open by sharedAddr */ obj->objType = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC; obj->attrs = (ti_sdo_ipc_ListMP_Attrs *)params->sharedAddr; obj->regionId = SharedRegion_getId(&(obj->attrs->head)); obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId); obj->cacheLineSize = SharedRegion_getCacheLineSize(obj->regionId); /* get the local address of the SRPtr */ localAddr = SharedRegion_getPtr(obj->attrs->gateMPAddr); status = GateMP_openByAddr(localAddr, (GateMP_Handle *)&(obj->gate)); if (status != GateMP_S_SUCCESS) { Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0); return (1); } return (0); } /* init the gate */ if (params->gate != NULL) { obj->gate = params->gate; } else { obj->gate = (ti_sdo_ipc_GateMP_Handle)GateMP_getDefaultRemote(); } if (params->sharedAddr == NULL) { /* Creating using a shared region ID */ obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION; obj->regionId = params->regionId; obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId); obj->cacheLineSize = SharedRegion_getCacheLineSize(obj->regionId); /* Need to allocate from the heap */ ListMP_Params_init(&sparams); sparams.regionId = params->regionId; obj->allocSize = ListMP_sharedMemReq(&sparams); regionHeap = SharedRegion_getHeap(obj->regionId); Assert_isTrue(regionHeap != NULL, ti_sdo_ipc_SharedRegion_A_noHeap); /* The region heap will take care of the alignment */ obj->attrs = Memory_alloc(regionHeap, obj->allocSize, 0, eb); if (obj->attrs == NULL) { return (2); } } else { /* Creating using sharedAddr */ obj->regionId = SharedRegion_getId(params->sharedAddr); /* Assert that the buffer is in a valid shared region */ Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID, ti_sdo_ipc_Ipc_A_addrNotInSharedRegion); /* set object's cacheEnabled, objType, and attrs */ obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId); obj->cacheLineSize = SharedRegion_getCacheLineSize(obj->regionId); obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC; obj->attrs = (ti_sdo_ipc_ListMP_Attrs *)params->sharedAddr; /* Assert that sharedAddr is cache aligned */ Assert_isTrue((obj->cacheLineSize == 0) || ((UInt32)params->sharedAddr % obj->cacheLineSize == 0), ti_sdo_ipc_Ipc_A_addrNotCacheAligned); } /* init the head (to be empty) */ ListMP_elemClear(&(obj->attrs->head)); /* store the GateMP sharedAddr in the Attrs */ obj->attrs->gateMPAddr = ti_sdo_ipc_GateMP_getSharedAddr(obj->gate); /* last thing, set the status */ obj->attrs->status = ti_sdo_ipc_ListMP_CREATED; if (obj->cacheEnabled) { Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_ListMP_Attrs), Cache_Type_ALL, TRUE); } /* add to NameServer if name not NULL */ if (params->name != NULL) { sharedShmBase = SharedRegion_getSRPtr(obj->attrs, obj->regionId); obj->nsKey = NameServer_addUInt32( (NameServer_Handle)ListMP_module->nameServer, params->name, (UInt32)sharedShmBase); if (obj->nsKey == NULL) { Error_raise(eb, ti_sdo_ipc_Ipc_E_nameFailed, params->name, 0); return (3); } } return (0); }
/* * ======== NotifyDriverShm_Instance_init ======== */ Int NotifyDriverShm_Instance_init(NotifyDriverShm_Object *obj, const NotifyDriverShm_Params *params, Error_Block *eb) { UInt16 regionId; SizeT regionCacheSize, minAlign, procCtrlSize; /* * Check whether remote proc ID has been set and isn't the same as the * local proc ID */ Assert_isTrue ((params->remoteProcId != MultiProc_INVALIDID) && (params->remoteProcId != MultiProc_self()), ti_sdo_ipc_Ipc_A_invParam); /* * Determine obj->cacheEnabled using params->cacheEnabled and SharedRegion * cache flag setting, if applicable. */ obj->cacheEnabled = params->cacheEnabled; minAlign = params->cacheLineSize; if (minAlign == 0) { /* Fix alignment of zero */ minAlign = sizeof(Ptr); } regionId = SharedRegion_getId(params->sharedAddr); if (regionId != SharedRegion_INVALIDREGIONID) { /* * Override the user cacheEnabled setting if the region * cacheEnabled is FALSE. */ if (!SharedRegion_isCacheEnabled(regionId)) { obj->cacheEnabled = FALSE; } regionCacheSize = SharedRegion_getCacheLineSize(regionId); /* * Override the user cache line size setting if the region * cache line size is smaller. */ if (regionCacheSize < minAlign) { minAlign = regionCacheSize; } } /* Check if shared memory base addr is aligned to cache line boundary.*/ Assert_isTrue ((UInt32)params->sharedAddr % minAlign == 0, ti_sdo_ipc_Ipc_A_addrNotCacheAligned); obj->remoteProcId = params->remoteProcId; /* * Store all interrupt information so it may be used (if neccessary) by * the IInterrupt delegates */ obj->intInfo.remoteIntId = params->remoteIntId; obj->intInfo.localIntId = params->localIntId; obj->intInfo.intVectorId = params->intVectorId; obj->nesting = 0; if (params->remoteProcId > MultiProc_self()) { obj->selfId = 0; obj->otherId = 1; } else { obj->selfId = 1; obj->otherId = 0; } /* Initialize pointers to shared memory regions */ procCtrlSize = _Ipc_roundup(sizeof(NotifyDriverShm_ProcCtrl), minAlign); /* * Save the eventEntrySize in obj since we will need it at runtime to * index the event charts */ obj->eventEntrySize = _Ipc_roundup(sizeof(NotifyDriverShm_EventEntry), minAlign); obj->selfProcCtrl = (NotifyDriverShm_ProcCtrl *) ((UInt32)params->sharedAddr + (obj->selfId * procCtrlSize)); obj->otherProcCtrl = (NotifyDriverShm_ProcCtrl *) ((UInt32)params->sharedAddr + (obj->otherId * procCtrlSize)); obj->selfEventChart = (NotifyDriverShm_EventEntry *) ((UInt32)params->sharedAddr + (2 * procCtrlSize) + (obj->eventEntrySize * ti_sdo_ipc_Notify_numEvents * obj->selfId)); obj->otherEventChart = (NotifyDriverShm_EventEntry *) ((UInt32)params->sharedAddr + (2 * procCtrlSize) + (obj->eventEntrySize * ti_sdo_ipc_Notify_numEvents * obj->otherId)); /* Allocate memory for regChart and init to (UInt32)-1 (unregistered) */ obj->regChart = Memory_valloc( NotifyDriverShm_Object_heap(), (sizeof(UInt32) * ti_sdo_ipc_Notify_numEvents), NULL, ~0, eb); if (obj->regChart == NULL) { return (1); } /* Enable all events initially.*/ obj->selfProcCtrl->eventEnableMask = 0xFFFFFFFF; /* Write back our own ProcCtrl */ if (obj->cacheEnabled) { Cache_wbInv(obj->selfProcCtrl, sizeof(NotifyDriverShm_ProcCtrl), Cache_Type_ALL, TRUE); } /* Register the incoming interrupt */ NotifyDriverShm_InterruptProxy_intRegister(obj->remoteProcId, &(obj->intInfo), (Fxn)NotifyDriverShm_isr, (UArg)obj); return (0); }
/*! * @brief Function to perform device specific setup for Notify module. * This function creates the Notify drivers. * * @param[in] sharedAddr Shared address base. * * @sa NotifySetupOmapl1xx_detach */ Int NotifySetupOmapl1xx_attach (UInt16 procId, Ptr sharedAddr) { Int32 status = Notify_S_SUCCESS ; NotifyDriverShm_Params notifyShmParams; GT_1trace (curTrace, GT_ENTER, "NotifySetupOmapl1xx_attach", sharedAddr); GT_assert (curTrace, (sharedAddr != NULL)); #if !defined(SYSLINK_BUILD_OPTIMIZE) if (sharedAddr == NULL) { /*! @retval Notify_E_INVALIDARG Invalid NULL sharedAddr argument provided. */ status = Notify_E_INVALIDARG; GT_setFailureReason (curTrace, GT_4CLASS, "NotifySetupOmapl1xx_attach", status, "Invalid NULL sharedAddr provided."); } else { #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */ /* * Setup the notify driver to the DSP (Line 0) */ NotifyDriverShm_Params_init (¬ifyShmParams); notifyShmParams.cacheEnabled = SharedRegion_isCacheEnabled( SharedRegion_getId((Ptr)sharedAddr)); notifyShmParams.localIntId = NotifySetup_armRecvIntId0; notifyShmParams.remoteIntId = NotifySetup_dspRecvIntId0; notifyShmParams.remoteProcId = procId; notifyShmParams.lineId = 0u; notifyShmParams.sharedAddr = sharedAddr; NotifySetup_dspDriverHandle0 = NotifyDriverShm_create(¬ifyShmParams); #if !defined(SYSLINK_BUILD_OPTIMIZE) if (NotifySetup_dspDriverHandle0 == NULL) { /*! @retval Notify_E_FAIL NotifyDriverShm_create failed for line 0 */ status = Notify_E_FAIL; GT_setFailureReason (curTrace, GT_4CLASS, "NotifySetupOmapl1xx_attach", status, "NotifyDriverShm_create failed for line 0"); } else { #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */ NotifySetup_notifyHandle0 = Notify_create ( NotifySetup_dspDriverHandle0, procId, 0u, NULL); #if !defined(SYSLINK_BUILD_OPTIMIZE) if (NotifySetup_notifyHandle0 == NULL) { /*! @retval Notify_E_FAIL Notify_create failed for line 0 */ status = Notify_E_FAIL; GT_setFailureReason (curTrace, GT_4CLASS, "NotifySetupOmapl1xx_attach", status, "Notify_create failed for line 0"); } } if (status >= 0) { #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */ if (NotifySetup_useSecondLine) { /* * Setup the notify driver to the DSP (Line 1) */ NotifyDriverShm_Params_init (¬ifyShmParams); notifyShmParams.localIntId = NotifySetup_armRecvIntId1; notifyShmParams.remoteIntId = NotifySetup_dspRecvIntId1; notifyShmParams.remoteProcId = procId; notifyShmParams.lineId = 1u; notifyShmParams.sharedAddr = sharedAddr;/* To allow sharedegion * Calculations */ notifyShmParams.sharedAddr = (Ptr)((UInt32) sharedAddr + NotifyDriverShm_sharedMemReq (¬ifyShmParams)); NotifySetup_dspDriverHandle1 = NotifyDriverShm_create ( ¬ifyShmParams); #if !defined(SYSLINK_BUILD_OPTIMIZE) if (NotifySetup_dspDriverHandle1 == NULL) { /*! @retval Notify_E_FAIL NotifyDriverShm_create failed for line 1*/ status = Notify_E_FAIL; GT_setFailureReason (curTrace, GT_4CLASS, "NotifySetupOmapl1xx_attach", status, "NotifyDriverShm_create failed for line 1"); } else { #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */ NotifySetup_notifyHandle1 = Notify_create ( NotifySetup_dspDriverHandle1, procId, 1u, NULL); #if !defined(SYSLINK_BUILD_OPTIMIZE) if (NotifySetup_notifyHandle0 == NULL) { /*! @retval Notify_E_FAIL Notify_create failed for line 1*/ status = Notify_E_FAIL; GT_setFailureReason (curTrace, GT_4CLASS, "NotifySetupOmapl1xx_attach", status, "Notify_create failed for line 1"); } } #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */ } #if !defined(SYSLINK_BUILD_OPTIMIZE) } } #endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */ GT_1trace (curTrace, GT_LEAVE, "NotifySetupOmapl1xx_attach", status); /*! @retval Notify_S_SUCCESS Operation successful */ return (status); }
/* * ======== Ipc_writeConfig ======== */ Int Ipc_writeConfig(UInt16 remoteProcId, UInt32 tag, Ptr cfg, SizeT size) { Int status = Ipc_S_SUCCESS; UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId); SharedRegion_SRPtr curSRPtr, *prevSRPtr; ti_sdo_ipc_Ipc_ConfigEntry *entry; Error_Block eb; Bool cacheEnabled = SharedRegion_isCacheEnabled(0); /* Assert that the remoteProc in our cluster */ Assert_isTrue(clusterId < ti_sdo_utils_MultiProc_numProcsInCluster, ti_sdo_utils_MultiProc_A_invalidMultiProcId); Error_init(&eb); if (cfg == NULL) { status = Ipc_E_FAIL; /* get head of local config list and set prevSRPtr to it */ prevSRPtr = (Ipc_module->procEntry[clusterId].localConfigList); /* * When cfg is NULL, the last memory allocated from a previous * Ipc_writeConfig call with the same remoteProcId, tag, and size * is freed. */ curSRPtr = *prevSRPtr; /* loop through list of config entries until matching entry is found */ while (curSRPtr != ti_sdo_ipc_SharedRegion_INVALIDSRPTR) { /* convert Ptr associated with curSRPtr */ entry = (ti_sdo_ipc_Ipc_ConfigEntry *) (SharedRegion_getPtr(curSRPtr)); /* make sure entry matches remoteProcId, tag, and size */ if ((entry->remoteProcId == remoteProcId) && (entry->tag == tag) && (entry->size == size)) { /* Update the 'prev' next ptr */ *prevSRPtr = (SharedRegion_SRPtr)entry->next; /* writeback the 'prev' ptr */ if (cacheEnabled) { Cache_wb(prevSRPtr, sizeof(ti_sdo_ipc_Ipc_ConfigEntry), Cache_Type_ALL, FALSE); } /* free entry's memory back to shared heap */ Memory_free(SharedRegion_getHeap(0), entry, size + sizeof(ti_sdo_ipc_Ipc_ConfigEntry)); /* set the status to success */ status = Ipc_S_SUCCESS; break; } /* set the 'prev' to the 'cur' SRPtr */ prevSRPtr = (SharedRegion_SRPtr *)(&entry->next); /* point to next config entry */ curSRPtr = (SharedRegion_SRPtr)entry->next; } /* return that status */ return (status); } /* Allocate memory from the shared heap (System Heap) */ entry = Memory_alloc(SharedRegion_getHeap(0), size + sizeof(ti_sdo_ipc_Ipc_ConfigEntry), SharedRegion_getCacheLineSize(0), &eb); if (entry == NULL) { return (Ipc_E_FAIL); } /* set the entry */ entry->remoteProcId = remoteProcId; entry->localProcId = MultiProc_self(); entry->tag = tag; entry->size = size; memcpy((Ptr)((UInt32)entry + sizeof(ti_sdo_ipc_Ipc_ConfigEntry)), cfg, size); /* point the entry's next to the first entry in the list */ entry->next = *Ipc_module->procEntry[clusterId].localConfigList; /* first write-back the entry if cache is enabled */ if (cacheEnabled) { Cache_wb(entry, size + sizeof(ti_sdo_ipc_Ipc_ConfigEntry), Cache_Type_ALL, FALSE); } /* set the entry as the new first in the list */ *Ipc_module->procEntry[clusterId].localConfigList = SharedRegion_getSRPtr(entry, 0); /* write-back the config list */ if (cacheEnabled) { Cache_wb(Ipc_module->procEntry[clusterId].localConfigList, SharedRegion_getCacheLineSize(0), Cache_Type_ALL, FALSE); } return (status); }
/* * ======== ListMP_insert ======== */ Int ListMP_insert(ListMP_Handle handle, ListMP_Elem *newElem, ListMP_Elem *curElem) { ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle; UInt key; Int id; ListMP_Elem *localPrevElem; SharedRegion_SRPtr sharedNewElem; SharedRegion_SRPtr sharedCurElem; Bool curElemIsCached, localPrevElemIsCached; /* prevent another thread or processor from modifying the ListMP */ key = GateMP_enter((GateMP_Handle)obj->gate); if (ti_sdo_ipc_SharedRegion_translate == FALSE) { sharedNewElem = (SharedRegion_SRPtr)newElem; sharedCurElem = (SharedRegion_SRPtr)curElem; localPrevElem = (ListMP_Elem *)(curElem->prev); } else { /* get SRPtr for newElem */ id = SharedRegion_getId(newElem); sharedNewElem = SharedRegion_getSRPtr(newElem, id); /* get SRPtr for curElem */ id = SharedRegion_getId(curElem); sharedCurElem = SharedRegion_getSRPtr(curElem, id); } curElemIsCached = SharedRegion_isCacheEnabled(SharedRegion_getId(curElem)); if (curElemIsCached) { Cache_inv(curElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } /* get Ptr for curElem->prev */ localPrevElem = SharedRegion_getPtr(curElem->prev); localPrevElemIsCached = SharedRegion_isCacheEnabled( SharedRegion_getId(localPrevElem)); if (localPrevElemIsCached) { Cache_inv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } newElem->next = sharedCurElem; newElem->prev = curElem->prev; localPrevElem->next = sharedNewElem; curElem->prev = sharedNewElem; if (localPrevElemIsCached) { Cache_wbInv(localPrevElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } /* * The next two Cache_wbInv needs to be done because curElem * and newElem are passed in and maybe already in the cache */ if (curElemIsCached) { /* writeback invalidate current elem structure */ Cache_wbInv(curElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } if (SharedRegion_isCacheEnabled(SharedRegion_getId(newElem))) { /* writeback invalidate new elem structure */ Cache_wbInv(newElem, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } GateMP_leave((GateMP_Handle)obj->gate, key); return (ListMP_S_SUCCESS); }
/* * ======== ListMP_getTail ======== */ Ptr ListMP_getTail(ListMP_Handle handle) { ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle; ListMP_Elem *elem; ListMP_Elem *localHeadPrev; ListMP_Elem *localPrev; Bool localPrevIsCached; UInt key; /* prevent another thread or processor from modifying the ListMP */ key = GateMP_enter((GateMP_Handle)obj->gate); if (ti_sdo_ipc_SharedRegion_translate == FALSE) { localHeadPrev = (ListMP_Elem *)obj->attrs->head.prev; } else { localHeadPrev = SharedRegion_getPtr(obj->attrs->head.prev); } /* Assert that pointer is not NULL */ Assert_isTrue(localHeadPrev != NULL, ti_sdo_ipc_Ipc_A_nullPointer); /* See if the ListMP was empty */ if (localHeadPrev == (ListMP_Elem *)(&(obj->attrs->head))) { /* Empty, return NULL */ elem = NULL; } else { if (SharedRegion_isCacheEnabled(SharedRegion_getId(localHeadPrev))) { /* invalidate elem */ Cache_inv(localHeadPrev, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } if (ti_sdo_ipc_SharedRegion_translate == FALSE) { localPrev = (ListMP_Elem *)localHeadPrev->prev; } else { localPrev = SharedRegion_getPtr(localHeadPrev->prev); } /* Assert that pointer is not NULL */ Assert_isTrue(localPrev != NULL, ti_sdo_ipc_Ipc_A_nullPointer); /* Elem to return */ elem = localHeadPrev; localPrevIsCached = SharedRegion_isCacheEnabled( SharedRegion_getId(localPrev)); if (localPrevIsCached) { Cache_inv(localPrev, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } /* Fix the head of the list prev pointer */ obj->attrs->head.prev = elem->prev; /* Fix the next pointer of the new last elem on the list */ localPrev->next = localHeadPrev->next; if (localPrevIsCached) { Cache_wbInv(localPrev, sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } } if (obj->cacheEnabled) { Cache_wbInv(&(obj->attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL, TRUE); } GateMP_leave((GateMP_Handle)obj->gate, key); return (elem); }
/* * ======== Ipc_attach ======== */ Int Ipc_attach(UInt16 remoteProcId) { Int i; Ptr sharedAddr; SizeT memReq; volatile ti_sdo_ipc_Ipc_Reserved *slave; ti_sdo_ipc_Ipc_ProcEntry *ipc; Error_Block eb; SharedRegion_Entry entry; SizeT reservedSize = ti_sdo_ipc_Ipc_reservedSizePerProc(); Bool cacheEnabled = SharedRegion_isCacheEnabled(0); UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(remoteProcId); Int status; UInt hwiKey; /* Assert remoteProcId is in our cluster and isn't our own */ Assert_isTrue(clusterId < ti_sdo_utils_MultiProc_numProcsInCluster, ti_sdo_utils_MultiProc_A_invalidMultiProcId); Assert_isTrue(remoteProcId != MultiProc_self(), ti_sdo_ipc_Ipc_A_invArgument); /* Check whether Ipc_start has been called. If not, fail. */ if (Ipc_module->ipcSharedAddr == NULL) { return (Ipc_E_FAIL); } /* for checking and incrementing attached below */ hwiKey = Hwi_disable(); /* Make sure its not already attached */ if (Ipc_module->procEntry[clusterId].attached) { Ipc_module->procEntry[clusterId].attached++; /* restore interrupts and return */ Hwi_restore(hwiKey); return (Ipc_S_ALREADYSETUP); } /* restore interrupts */ Hwi_restore(hwiKey); /* get region 0 information */ SharedRegion_getEntry(0, &entry); /* Make sure we've attached to owner of SR0 if we're not owner */ if ((MultiProc_self() != entry.ownerProcId) && (remoteProcId != entry.ownerProcId) && !(Ipc_module->procEntry[ti_sdo_utils_MultiProc_getClusterId( entry.ownerProcId)].attached)) { return (Ipc_E_FAIL); } /* Init error block */ Error_init(&eb); /* determine the slave's slot */ slave = Ipc_getSlaveAddr(remoteProcId, Ipc_module->ipcSharedAddr); if (cacheEnabled) { Cache_inv((Ptr)slave, reservedSize, Cache_Type_ALL, TRUE); } /* Synchronize the processors. */ status = Ipc_procSyncStart(remoteProcId, Ipc_module->ipcSharedAddr); if (status < 0) { return (status); } /* must be called before SharedRegion_attach */ status = ti_sdo_ipc_GateMP_attach(remoteProcId, Ipc_module->gateMPSharedAddr); if (status < 0) { return (status); } /* retrieves the SharedRegion Heap handles */ status = ti_sdo_ipc_SharedRegion_attach(remoteProcId); if (status < 0) { return (status); } /* get the attach parameters associated with remoteProcId */ ipc = &(Ipc_module->procEntry[clusterId]); /* attach Notify if not yet attached and specified to set internal setup */ if (!(Notify_intLineRegistered(remoteProcId, 0)) && (ipc->entry.setupNotify)) { /* call Notify_attach */ memReq = Notify_sharedMemReq(remoteProcId, Ipc_module->ipcSharedAddr); if (memReq != 0) { if (MultiProc_self() < remoteProcId) { /* * calloc required here due to race condition. Its possible * that the slave, who creates the instance, tries a sendEvent * before the master has created its instance because the * state of memory was enabled from a previous run. */ sharedAddr = Memory_calloc(SharedRegion_getHeap(0), memReq, SharedRegion_getCacheLineSize(0), &eb); /* make sure alloc did not fail */ if (sharedAddr == NULL) { return (Ipc_E_MEMORY); } /* if cache enabled, wbInv the calloc above */ if (cacheEnabled) { Cache_wbInv(sharedAddr, memReq, Cache_Type_ALL, TRUE); } /* set the notify SRPtr */ slave->notifySRPtr = SharedRegion_getSRPtr(sharedAddr, 0); } else { /* get the notify SRPtr */ sharedAddr = SharedRegion_getPtr(slave->notifySRPtr); } } else { sharedAddr = NULL; slave->notifySRPtr = 0; } /* call attach to remote processor */ status = Notify_attach(remoteProcId, sharedAddr); if (status < 0) { if (MultiProc_self() < remoteProcId && sharedAddr != NULL) { /* free the memory back to SharedRegion 0 heap */ Memory_free(SharedRegion_getHeap(0), sharedAddr, memReq); } return (Ipc_E_FAIL); } } /* Must come after GateMP_start because depends on default GateMP */ if (!(ti_sdo_utils_NameServer_isRegistered(remoteProcId)) && (ipc->entry.setupNotify)) { memReq = ti_sdo_utils_NameServer_SetupProxy_sharedMemReq( Ipc_module->ipcSharedAddr); if (memReq != 0) { if (MultiProc_self() < remoteProcId) { sharedAddr = Memory_alloc(SharedRegion_getHeap(0), memReq, SharedRegion_getCacheLineSize(0), &eb); /* make sure alloc did not fail */ if (sharedAddr == NULL) { return (Ipc_E_MEMORY); } /* set the NSRN SRPtr */ slave->nsrnSRPtr = SharedRegion_getSRPtr(sharedAddr, 0); } else { /* get the NSRN SRPtr */ sharedAddr = SharedRegion_getPtr(slave->nsrnSRPtr); } } else { sharedAddr = NULL; slave->nsrnSRPtr = 0; } /* call attach to remote processor */ status = ti_sdo_utils_NameServer_SetupProxy_attach(remoteProcId, sharedAddr); if (status < 0) { if (MultiProc_self() < remoteProcId && sharedAddr != NULL) { /* free the memory back to SharedRegion 0 heap */ Memory_free(SharedRegion_getHeap(0), sharedAddr, memReq); } return (Ipc_E_FAIL); } } /* Must come after GateMP_start because depends on default GateMP */ if (!(ti_sdo_ipc_MessageQ_SetupTransportProxy_isRegistered(remoteProcId)) && (ipc->entry.setupMessageQ)) { memReq = ti_sdo_ipc_MessageQ_SetupTransportProxy_sharedMemReq( Ipc_module->ipcSharedAddr); if (memReq != 0) { if (MultiProc_self() < remoteProcId) { sharedAddr = Memory_alloc(SharedRegion_getHeap(0), memReq, SharedRegion_getCacheLineSize(0), &eb); /* make sure alloc did not fail */ if (sharedAddr == NULL) { return (Ipc_E_MEMORY); } /* set the transport SRPtr */ slave->transportSRPtr = SharedRegion_getSRPtr(sharedAddr, 0); } else { /* get the transport SRPtr */ sharedAddr = SharedRegion_getPtr(slave->transportSRPtr); } } else { sharedAddr = NULL; slave->transportSRPtr = 0; } /* call attach to remote processor */ status = ti_sdo_ipc_MessageQ_SetupTransportProxy_attach(remoteProcId, sharedAddr); if (status < 0) { if (MultiProc_self() < remoteProcId && sharedAddr != NULL) { /* free the memory back to SharedRegion 0 heap */ Memory_free(SharedRegion_getHeap(0), sharedAddr, memReq); } return (Ipc_E_FAIL); } } /* writeback invalidate slave's shared memory if cache enabled */ if (cacheEnabled) { if (MultiProc_self() < remoteProcId) { Cache_wbInv((Ptr)slave, reservedSize, Cache_Type_ALL, TRUE); } } /* Call user attach fxns */ for (i = 0; i < ti_sdo_ipc_Ipc_numUserFxns; i++) { if (ti_sdo_ipc_Ipc_userFxns[i].userFxn.attach) { status = ti_sdo_ipc_Ipc_userFxns[i].userFxn.attach( ti_sdo_ipc_Ipc_userFxns[i].arg, remoteProcId); if (status < 0) { return (status); } } } /* Finish the processor synchronization */ status = ti_sdo_ipc_Ipc_procSyncFinish(remoteProcId, Ipc_module->ipcSharedAddr); if (status < 0) { return (status); } /* for atomically incrementing attached */ hwiKey = Hwi_disable(); /* now attached to remote processor */ Ipc_module->procEntry[clusterId].attached++; /* restore interrupts */ Hwi_restore(hwiKey); return (status); }
/* * ======== TransportShm_Instance_init ======== */ Int TransportShm_Instance_init(TransportShm_Object *obj, UInt16 procId, const TransportShm_Params *params, Error_Block *eb) { Int localIndex; Int remoteIndex; Int status; Bool flag; UInt32 minAlign; ListMP_Params listMPParams[2]; Swi_Handle swiHandle; Swi_Params swiParams; Ptr localAddr; swiHandle = TransportShm_Instance_State_swiObj(obj); /* * Determine who gets the '0' slot in shared memory and who gets * the '1' slot. The '0' slot is given to the lower MultiProc id. */ if (MultiProc_self() < procId) { localIndex = 0; remoteIndex = 1; } else { localIndex = 1; remoteIndex = 0; } if (params->openFlag) { /* Open by sharedAddr */ obj->objType = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC; obj->self = (TransportShm_Attrs *)params->sharedAddr; obj->regionId = SharedRegion_getId(params->sharedAddr); obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId); localAddr = SharedRegion_getPtr(obj->self->gateMPAddr); status = GateMP_openByAddr(localAddr, (GateMP_Handle *)&obj->gate); if (status < 0) { Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0); return(1); } } else { /* init the gate for ListMP create below */ if (params->gate != NULL) { obj->gate = params->gate; } else { obj->gate = (ti_sdo_ipc_GateMP_Handle)GateMP_getDefaultRemote(); } /* Creating using sharedAddr */ obj->regionId = SharedRegion_getId(params->sharedAddr); /* Assert that the buffer is in a valid shared region */ Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID, ti_sdo_ipc_Ipc_A_addrNotInSharedRegion); /* Assert that sharedAddr is cache aligned */ Assert_isTrue(((UInt32)params->sharedAddr % SharedRegion_getCacheLineSize(obj->regionId) == 0), ti_sdo_ipc_Ipc_A_addrNotCacheAligned); /* set object's cacheEnabled, type, self */ obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId); obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC; obj->self = (TransportShm_Attrs *)params->sharedAddr; } /* determine the minimum alignment to align to */ minAlign = Memory_getMaxDefaultTypeAlign(); if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) { minAlign = SharedRegion_getCacheLineSize(obj->regionId); } /* * Carve up the shared memory. * If cache is enabled, these need to be on separate cache lines. * This is done with minAlign and _Ipc_roundup function. */ obj->other = (TransportShm_Attrs *)((UInt32)(obj->self) + (_Ipc_roundup(sizeof(TransportShm_Attrs), minAlign))); ListMP_Params_init(&(listMPParams[0])); listMPParams[0].gate = (GateMP_Handle)obj->gate; listMPParams[0].sharedAddr = (UInt32 *)((UInt32)(obj->other) + (_Ipc_roundup(sizeof(TransportShm_Attrs), minAlign))); ListMP_Params_init(&listMPParams[1]); listMPParams[1].gate = (GateMP_Handle)obj->gate; listMPParams[1].sharedAddr = (UInt32 *)((UInt32)(listMPParams[0].sharedAddr) + ListMP_sharedMemReq(&listMPParams[0])); obj->priority = params->priority; obj->remoteProcId = procId; Swi_Params_init(&swiParams); swiParams.arg0 = (UArg)obj; Swi_construct(Swi_struct(swiHandle), (Swi_FuncPtr)TransportShm_swiFxn, &swiParams, eb); if (params->openFlag == FALSE) { obj->localList = (ti_sdo_ipc_ListMP_Handle) ListMP_create(&(listMPParams[localIndex])); if (obj->localList == NULL) { Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0); return (2); } obj->remoteList = (ti_sdo_ipc_ListMP_Handle) ListMP_create(&(listMPParams[remoteIndex])); if (obj->localList == NULL) { Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0); return (2); } } else { /* Open the local ListMP instance */ status = ListMP_openByAddr(listMPParams[localIndex].sharedAddr, (ListMP_Handle *)&(obj->localList)); if (status < 0) { Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0); return (2); } /* Open the remote ListMP instance */ status = ListMP_openByAddr(listMPParams[remoteIndex].sharedAddr, (ListMP_Handle *)&(obj->remoteList)); if (status < 0) { Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0); return (2); } } /* register the event with Notify */ status = Notify_registerEventSingle( procId, /* remoteProcId */ 0, /* lineId */ TransportShm_notifyEventId, (Notify_FnNotifyCbck)TransportShm_notifyFxn, (UArg)swiHandle); if (status < 0) { Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0); return (3); } /* Register the transport with MessageQ */ flag = ti_sdo_ipc_MessageQ_registerTransport( TransportShm_Handle_upCast(obj), procId, params->priority); if (flag == FALSE) { Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0); return (4); } if (params->openFlag == FALSE) { obj->self->creatorProcId = MultiProc_self(); obj->self->notifyEventId = TransportShm_notifyEventId; obj->self->priority = obj->priority; /* Store the GateMP sharedAddr in the Attrs */ obj->self->gateMPAddr = ti_sdo_ipc_GateMP_getSharedAddr(obj->gate); obj->self->flag = TransportShm_UP; if (obj->cacheEnabled) { Cache_wbInv(obj->self, sizeof(TransportShm_Attrs), Cache_Type_ALL, TRUE); } } else { obj->other->flag = TransportShm_UP; if (obj->cacheEnabled) { Cache_wbInv(&(obj->other->flag), minAlign, Cache_Type_ALL, TRUE); } } obj->status = TransportShm_UP; return (0); }