Int32 System_ipcNotifyInit() { UInt32 procId, i; Int32 status; memset(gSystem_ipcObj.notifyCb, 0, sizeof(gSystem_ipcObj.notifyCb)); i = 0; while (gSystem_ipcEnableProcId[i] != SYSTEM_PROC_MAX) { procId = gSystem_ipcEnableProcId[i]; if ((procId != System_getSelfProcId()) && (procId != SYSTEM_PROC_INVALID)) { Vps_printf (" %d: SYSTEM: Notify register to [%s] line %d, event %d ... \n", Utils_getCurTimeInMsec(), MultiProc_getName(procId), SYSTEM_IPC_NOTIFY_LINE_ID, SYSTEM_IPC_NOTIFY_EVENT_ID); if (Notify_intLineRegistered(procId, SYSTEM_IPC_NOTIFY_LINE_ID) == FALSE) { UTILS_assert(0); } if (Notify_eventAvailable (procId, SYSTEM_IPC_NOTIFY_LINE_ID, SYSTEM_IPC_NOTIFY_EVENT_ID) == FALSE) { UTILS_assert(0); } status = Notify_registerEvent(procId, SYSTEM_IPC_NOTIFY_LINE_ID, SYSTEM_IPC_NOTIFY_EVENT_ID, System_ipcNotifyHandler, NULL); UTILS_assert(status == Notify_S_SUCCESS); } i++; } return status; }
/* * ======== 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); }
/* * ======== 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); }