/* * ======== Notify_disable ======== */ UInt Notify_disable(UInt16 procId, UInt16 lineId) { UInt key; UInt modKey; UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId); ti_sdo_ipc_Notify_Object *obj; Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors && lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered); /* Nesting value and enable state have to be in sync */ modKey = Gate_enterModule(); obj->nesting++; if (obj->nesting == 1) { /* Disable receiving all events */ if (procId != MultiProc_self()) { INotifyDriver_disable(obj->driverHandle); } } key = obj->nesting; Gate_leaveModule(modKey); return (key); }
/* * ======== HeapMem_getStats ======== */ Void HeapMem_getStats(HeapMem_Object *obj, Memory_Stats *stats) { IArg key; HeapMem_Header *curHeader; stats->totalSize = obj->head.size; stats->totalFreeSize = 0; /* determined later */ stats->largestFreeSize = 0; /* determined later */ key = Gate_enterModule(); curHeader = obj->head.next; while (curHeader != NULL) { stats->totalFreeSize += curHeader->size; if (stats->largestFreeSize < curHeader->size) { stats->largestFreeSize = curHeader->size; } curHeader = curHeader->next; } Gate_leaveModule(key); return; }
/* * ======== Notify_restore ======== */ Void Notify_restore(UInt16 procId, UInt16 lineId, UInt key) { UInt modKey; UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId); ti_sdo_ipc_Notify_Object *obj; Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors && lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered); Assert_isTrue(key == obj->nesting, ti_sdo_ipc_Notify_A_outOfOrderNesting); /* Nesting value and enable state have to be in sync */ modKey = Gate_enterModule(); obj->nesting--; if (obj->nesting == 0) { /* Enable receiving events */ if (procId != MultiProc_self()) { INotifyDriver_enable(obj->driverHandle); } } Gate_leaveModule(modKey); }
/** * @name DomxTunnelMgr_unRegisterHandle * @brief UnResgiter a component handle * @param hComponentHandle : Handle to component to be unregistered * @return none */ Void DomxTunnelMgr_unRegisterHandle (OmxTypes_OMX_HANDLETYPE hComponentHandle) { OMX_CONFIG_DOMXPROXYCOMPINFO sDomxProxyInfo; OMX_ERRORTYPE eError; Int nCompIdx; IArg key; DOMX_UTL_TRACE_FUNCTION_ENTRY_LEVEL1 (); nCompIdx = domxtmgr_get_component_registry_index (hComponentHandle); if (-1 == nCompIdx) { eError = OMX_GetConfig (hComponentHandle, (OMX_INDEXTYPE) OMX_TI_IndexConfigGetDomxCompInfo, &sDomxProxyInfo); if (OMX_ErrorNone == eError) { nCompIdx = domxtmgr_get_component_registry_index (sDomxProxyInfo.hCompRealHandle); DOMX_UTL_TRACE_FUNCTION_ASSERT ((-1 != nCompIdx), "Component handle not found"); } else { DOMX_UTL_TRACE_FUNCTION_ASSERT ((OMX_ErrorNone == eError), "OMX_GetConfig returned error"); } } domxtmgr_delete_proxylite_connections (hComponentHandle); key = Gate_enterModule (); domxtmgr_unregister_component (nCompIdx); Gate_leaveModule (key); DOMX_UTL_TRACE_FUNCTION_EXIT_LEVEL1 (eError); return; }
/* * ======== Notify_unregisterEventSingle ======== */ Int Notify_unregisterEventSingle(UInt16 procId, UInt16 lineId, UInt32 eventId) { UInt32 strippedEventId = (eventId & 0xFFFF); UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId); Int status; ti_sdo_ipc_Notify_Object *obj; UInt modKey; Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors && lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument); Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents, ti_sdo_ipc_Notify_A_invArgument); Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent); modKey = Gate_enterModule(); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered); if (obj->callbacks[strippedEventId].fnNotifyCbck) { if (procId != MultiProc_self()) { /* * First, Tell the remote notify driver that the event is now * unregistered */ INotifyDriver_unregisterEvent(obj->driverHandle, strippedEventId); } /* * No need to protect these modifications with the system gate because * we shouldn't get preempted by Notify_exec after INotifyDriver_ * unregisterEvent. */ obj->callbacks[strippedEventId].fnNotifyCbck = NULL; obj->callbacks[strippedEventId].cbckArg = NULL; status = Notify_S_SUCCESS; } else { /* No callback is registered. Fail. */ status = Notify_E_FAIL; } Gate_leaveModule(modKey); return (status); }
/* * ======== Notify_registerEventSingle ======== */ Int Notify_registerEventSingle(UInt16 procId, UInt16 lineId, UInt32 eventId, Notify_FnNotifyCbck fnNotifyCbck, UArg cbckArg) { UInt32 strippedEventId = (eventId & 0xFFFF); UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId); UInt modKey; Int status; ti_sdo_ipc_Notify_Object *obj; Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors && lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument); Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents, ti_sdo_ipc_Notify_A_invArgument); Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent); modKey = Gate_enterModule(); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered); if (obj->callbacks[strippedEventId].fnNotifyCbck) { /* A callback is already registered. Fail. */ status = Notify_E_ALREADYEXISTS; } else { /* * No callback is registered. Register it. There is no need to protect * these modifications because the event isn't registered yet. */ obj->callbacks[strippedEventId].fnNotifyCbck = (Fxn)fnNotifyCbck; obj->callbacks[strippedEventId].cbckArg = cbckArg; if (procId != MultiProc_self()) { /* Tell the remote notify driver that the event is now registered */ INotifyDriver_registerEvent(obj->driverHandle, strippedEventId); } status = Notify_S_SUCCESS; } Gate_leaveModule(modKey); return (status); }
/** * @name domxtmgr_module_init * @brief DomxTunnelManager Module level init function * @param component_name : OMX Component name * @param info : Info entry to be populated * @param eb : Used to raise error * @return none */ static Void domxtmgr_module_init () { IArg key; Log_print1 (Diags_ENTRY, "Entering %s (void)", (xdc_IArg) __FUNCTION__); key = Gate_enterModule (); DOMX_UTL_TRACE_FUNCTION_ASSERT ((DomxTunnelMgr_module->connectionInfoTbl.length == DomxTunnelMgr_maxNumComponents), "Table length != maxNumComponents"); DomxTunnelMgr_module->numActiveComponents = 0; DomxTunnelMgr_module->initDone = TRUE; Gate_leaveModule (key); Log_print1 (Diags_EXIT, "Leaving %s retVal: void", (xdc_IArg) __FUNCTION__); }
/** * @name DomxTunnelMgr_registerSkelInfo * @brief Register a components skeleton info * @param hComponentHandle : Handle to component to register * @param szCompName : Component name * @param pRpcSkelHandle : Pointer to RPC skel handle * @param cComponentRcmSvrName : Name of component rcm server name * @return none */ Void DomxTunnelMgr_registerSkelInfo (OmxTypes_OMX_HANDLETYPE hComponentHandle, Char *szCompName, OmxTypes_OMX_PTR pRpcSkelHandle, Char *cComponentRcmSvrName) { DomxCore_componentCoreInfoEntry *entry; Error_Block ebObj; Error_Block *eb = &ebObj; Int nCompIdx = DOMX_INT_TUNNELMGR_INVALID; IArg key; DOMX_UTL_TRACE_FUNCTION_ENTRY_LEVEL1 (); Error_init (eb); if (FALSE == DomxTunnelMgr_module->initDone) { domxtmgr_module_init (); } key = Gate_enterModule (); domxtmgr_map_component_name2info (szCompName, &entry, eb); if (NULL != entry) { DOMX_UTL_TRACE_FUNCTION_ASSERT ((entry->coreId == DomxCore_localCoreId), "Entry coreID != localCoreID"); nCompIdx = domxtmgr_get_component_registry_index (hComponentHandle); DOMX_UTL_TRACE_FUNCTION_ASSERT ((nCompIdx != DOMX_INT_TUNNELMGR_INVALID), "Invalid Comp index"); domxtmgr_register_skelinfo (nCompIdx, pRpcSkelHandle, cComponentRcmSvrName); } Gate_leaveModule (key); /* TODO: Component should return error code */ DOMX_UTL_TRACE_FUNCTION_ASSERT ((FALSE == Error_check (eb)), "DomxTunnelMgr_registerSkelInfo failed"); DOMX_UTL_TRACE_FUNCTION_EXIT_LEVEL1 (OMX_ErrorNone); }
/** ******************************************************************************** * @func MEMCFG_ModuleDeInit * @brief This function performs de-initialization of shared regions and set the * Module instance appropriately. * * @param[in ] None : None * * @returns MEMCFG_MODSTAT_INITIALIZED * MEMCFG_MODSTAT_NOTINITIALIZED ******************************************************************************** */ uint32_t MEMCFG_ModuleDeInit (void) { IArg key; int32_t memcfg_retval; key = Gate_enterModule (); if (MEMCFG_MODSTAT_INITIALIZED == MEMCFG_module->uInitState) { memcfg_retval = memcfg_module_deinit_shared_region (); if (MEMCFG_S_SUCCESS == memcfg_retval) { MEMCFG_module->uInitState = MEMCFG_MODSTAT_NOTINITIALIZED; } } /* End of IF: if (MEMCFG_MODSTAT_NOTINITIALIZED == uInitState) */ Gate_leaveModule (key); return (MEMCFG_module->uInitState); } /* MEMCFG_ModuleInit */
/* * ======== Notify_registerEvent ======== */ Int Notify_registerEvent(UInt16 procId, UInt16 lineId, UInt32 eventId, Notify_FnNotifyCbck fnNotifyCbck, UArg cbckArg) { UInt32 strippedEventId = (eventId & 0xFFFF); UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId); Int status; ti_sdo_ipc_Notify_Object *obj; UInt modKey; List_Handle eventList; ti_sdo_ipc_Notify_EventListener *listener; Bool listWasEmpty; Error_Block eb; Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors && lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument); Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents, ti_sdo_ipc_Notify_A_invArgument); Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent); Error_init(&eb); modKey = Gate_enterModule(); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered); /* Allocate a new EventListener */ listener = Memory_alloc(ti_sdo_ipc_Notify_Object_heap(), sizeof(ti_sdo_ipc_Notify_EventListener), 0, &eb); if (listener == NULL) { /* Listener memory allocation failed. Leave module gate & return */ Gate_leaveModule(modKey); return (Notify_E_MEMORY); } listener->callback.fnNotifyCbck = (Fxn)fnNotifyCbck; listener->callback.cbckArg = cbckArg; eventList = List_Object_get(obj->eventList, strippedEventId); /* * Store whether the list was empty so we know whether to register the * callback */ listWasEmpty = List_empty(eventList); /* * Need to atomically add to the list using the system gate because * Notify_exec might preempt List_remove. List_put is atomic. */ List_put(eventList, (List_Elem *)listener); if (listWasEmpty) { /* * Registering this event for the first time. Need to register the * callback function. */ status = Notify_registerEventSingle(procId, lineId, eventId, Notify_execMany, (UArg)obj); /* Notify_registerEventSingle should always succeed */ Assert_isTrue(status == Notify_S_SUCCESS, ti_sdo_ipc_Notify_A_internal); } status = Notify_S_SUCCESS; Gate_leaveModule(modKey); return (status); }
/* * ======== HeapMem_enter ======== * Enter the HeapMem module's gate. */ IArg HeapMem_enter() { return (Gate_enterModule()); }
/* * ======== write8 ========= * * Odd serial numbers indicate a new record, even serial numbers indicate * an "extension" to the previous record. 0 is a sentinal for no record, * but only if it doesn't follow a -1 (0xffffffff). If a serial number * of 0 follows a serial number of 0xffffffff, it's an extension, otherwise * it's a "no record". */ Void LoggerBuf_write8(LoggerBuf_Object *obj, Log_Event evt, Types_ModuleId mid, IArg a1, IArg a2, IArg a3, IArg a4, IArg a5, IArg a6, IArg a7, IArg a8) { /* part1 */ IArg key; Int adv; Int32 ser; LoggerBuf_Entry *e; /* Do nothing if the instance is disabled. */ if (!obj->enabled) { return; } /* * If event level filtering is enabled, and the event isn't a high enough * level, drop the record and return. */ if (LoggerBuf_filterByLevel && LoggerBuf_filterOutEvent(Log_getMask(evt))) { return; } /* * If all of the following are true: * - A logger has been specified to route status events to * - This is a status event * - This logger is NOT the status logger * Pass the event to the status logger and return. * * Otherwise, continue to log the event. */ if ((LoggerBuf_statusLogger != NULL) && (Log_getMask(evt) & Diags_STATUS) && (LoggerBuf_statusLogger != xdc_runtime_LoggerBuf_Handle_to_xdc_runtime_ILogger(obj))) { ILogger_write8(LoggerBuf_statusLogger, evt, mid, a1, a2, a3, a4, a5, a6, a7, a8); return; } key = Gate_enterModule(); /* * Record new serial number even if the buffer is FULL. We do this * because the buffer might become un-FULL at some later time, and * a reader (decoder) of the buffer needs to know if events have * been missed. */ ser = obj->serial; obj->serial += 2; adv = obj->advance; if (adv == LoggerBuf_FULL) { goto leave; } e = obj->curEntry; if (e == obj->endEntry) { if (adv == LoggerBuf_WRAP) { obj->curEntry = obj->entryArr; } else { obj->advance = LoggerBuf_FULL; } } else { obj->curEntry = e + 1; } LoggerBuf_TimestampProxy_get64(&e->tstamp); e->serial = ser; e->evt = Types_makeEvent(Log_getEventId(evt), mid); e->arg1 = a1; e->arg2 = a2; e->arg3 = a3; e->arg4 = a4; /* part 2 */ /* * We intentionally don't check for a "new" FULL condition here * since we want to write only the "extension" record, so a decoder * can know that this is an incomplete record and therefore throw * it away. By not checking for FULL here, we end up just overwriting * the "starter" record (that was written above) of a two-entry record * with the "extension" record. */ e = obj->curEntry; if (e == obj->endEntry) { if (adv == LoggerBuf_WRAP) { obj->curEntry = obj->entryArr; } else { obj->advance = LoggerBuf_FULL; } } else { obj->curEntry = e + 1; } e->serial = ser + 1; e->evt = ~0; e->arg1 = a5; e->arg2 = a6; e->arg3 = a7; e->arg4 = a8; leave: Gate_leaveModule(key); }
/* * ======== processPipeCommand ======== */ static Void processPipeCommand(String command) { Int i, j, n; String mask; IArg key; DBG( "Processing pipe command '%s'\n", command ); /* first check if this command is an alias */ for (i = 0; TraceUtil_cmdAliases[i] != NULL; i++) { if (!strcmp( TraceUtil_cmdAliases[i][0], command )) { for (j = 1; TraceUtil_cmdAliases[i][j] != NULL; j++) { processPipeCommand( TraceUtil_cmdAliases[i][j] ); } return; /* we have finished processing the alias */ } } if (strstr( command, TRACECMD_ARMTRACEMASK ) == command) { mask = command + strlen( TRACECMD_ARMTRACEMASK ); INFO( "Setting Arm trace mask to '%s'\n", mask ); GT_set( mask ); } else if (strstr( command, TRACECMD_DSP0TRACEMASK ) == command) { mask = command + strlen( TRACECMD_DSP0TRACEMASK ); INFO( "Setting DSP0 trace mask to '%s'\n", mask ); key = Gate_enterModule(); Engine_setTrace(hEngine, mask); Gate_leaveModule(key); } else if (strstr( command, TRACECMD_REFRESHPERIOD ) == command) { n = atoi( command + strlen( TRACECMD_REFRESHPERIOD ) ); INFO( "Setting trace refresh period to %d ms.\n", n ); refresh = n * 1000; } else if (strstr( command, TRACECMD_RESETFILES ) == command) { INFO( "Resetting trace/log files.\n" ); if (localTraceFilePtr != NULL && localTraceFilePtr != stdout && localTraceFilePtr != stderr) { DBG( "Resetting Arm trace file.\n" ); /* rewind file (stdio operation) then truncate it (OS operation) */ rewind( localTraceFilePtr ); ftruncate( fileno( localTraceFilePtr ), 0L ); } if (dsp0TraceFilePtr != NULL && dsp0TraceFilePtr != stdout && dsp0TraceFilePtr != stderr) { DBG("Resetting DSP trace file.\n"); rewind(dsp0TraceFilePtr); ftruncate(fileno(dsp0TraceFilePtr), 0L); } if (dsp0BiosFilePtr != NULL) { DBG("Resetting DSP log file.\n"); rewind(dsp0BiosFilePtr); ftruncate(fileno(dsp0BiosFilePtr), 0L); } } else { WARN("Unknown trace pipe command '%s'\n", command); } }
/** * @name DomxTunnelMgr_registerHandle * @brief Resgiter a component handle * @param hComponentHandle : Handle to component to register * @param szCompName : Component name * @return none */ Void DomxTunnelMgr_registerHandle (OmxTypes_OMX_HANDLETYPE hComponentHandle, Char *szCompName) { IArg key; OMX_CONFIG_DOMXPROXYCOMPINFO sDomxProxyInfo; OMX_ERRORTYPE eError; DomxCore_componentCoreInfoEntry *entry; Error_Block ebObj; Error_Block *eb = &ebObj; DOMX_UTL_TRACE_FUNCTION_ENTRY_LEVEL1 (); Log_print3 (Diags_USER1, "Entered: %s (0x%x, 0x%x)", (xdc_IArg) __FUNCTION__, (xdc_IArg) hComponentHandle, (xdc_IArg) szCompName); Error_init (eb); if (FALSE == DomxTunnelMgr_module->initDone) { domxtmgr_module_init (); } key = Gate_enterModule (); domxtmgr_map_component_name2info (szCompName, &entry, eb); if (NULL != entry) { if (entry->coreId == DomxCore_localCoreId) { domxtmgr_register_connection (hComponentHandle, szCompName, DomxCore_localCoreId, NULL, NULL, hComponentHandle, DomxCore_localCoreId, eb); } else { eError = OMX_GetConfig (hComponentHandle, (OMX_INDEXTYPE) OMX_TI_IndexConfigGetDomxCompInfo, &sDomxProxyInfo); if (OMX_ErrorNone == eError) { domxtmgr_register_connection (sDomxProxyInfo.hCompRealHandle, szCompName, entry->coreId, (OmxTypes_OMX_PTR) sDomxProxyInfo. nRpcSkelPtr, (OmxTypes_OMX_S8 *) sDomxProxyInfo. cComponentRcmSvrName, hComponentHandle, DomxCore_localCoreId, eb); /* Also register connenction on remote core */ domxtmgr_register_connection (sDomxProxyInfo.hCompRealHandle, szCompName, entry->coreId, NULL, NULL, sDomxProxyInfo.hCompRealHandle, entry->coreId, eb); } else { DOMX_UTL_TRACE_FUNCTION_ASSERT ((OMX_ErrorNone == eError), "OMX_GetConfig returned error"); } } } Gate_leaveModule (key); /* TODO: Component should return error code */ DOMX_UTL_TRACE_FUNCTION_ASSERT ((FALSE == Error_check (eb)), "Error in DomxTunnelMgr_registerHandle"); DOMX_UTL_TRACE_FUNCTION_EXIT_LEVEL1 (OMX_ErrorNone); }
/* * ======== LoggerBuf_getNextEntry ======== * "atomically" read and clear the next entry in the log * * Returns: * 0 - no entry in the log * 1,2 - read one or two complete entries (write4, write8) * -1 - read one but there may be another * * Below are some notes on the implementation. * * Pointers: * - cureEntry points to the next entry to write * - endEntry points to the last entry (not past it) * - readEntry points to the entry that will be read on the next call to * getNextEntry. * * Edge cases: * - An extension record can be orphaned (the base can be missing) * - A base record cannot be missing its extension (the records are written in * order, so the base is always overwritten first) * - The serial number can wrap from 0xFFFFFFFF to 0x0. * - If a base record is at the end of the buffer, its extension may be at * the beginning. */ Int LoggerBuf_getNextEntry(LoggerBuf_Object *obj, Log_EventRec *evtRec) { LoggerBuf_Entry *ent; LoggerBuf_Entry *nextEnt; Int nEntries; Bits32 serA; IArg key; nEntries = 0; key = Gate_enterModule(); ent = obj->readEntry; serA = ent->serial; if ((serA & 1) != 0) { /* serial numbers are odd and start at 1 */ nEntries++; /* reduce two-spaced serial numbers to consecutive ints */ evtRec->serial = (serA + 1) / 2; evtRec->evt = ent->evt; evtRec->tstamp = ent->tstamp; evtRec->arg[0] = ent->arg1; evtRec->arg[1] = ent->arg2; evtRec->arg[2] = ent->arg3; evtRec->arg[3] = ent->arg4; memset(ent, 0, sizeof (LoggerBuf_Entry)); /* get pointer to next entry */ if (ent == obj->endEntry) { nextEnt = obj->entryArr; } else { nextEnt = ent + 1; } if (nextEnt->serial == (serA + 1)) { /* continuation record */ nEntries++; evtRec->arg[4] = nextEnt->arg1; evtRec->arg[5] = nextEnt->arg2; evtRec->arg[6] = nextEnt->arg3; evtRec->arg[7] = nextEnt->arg4; memset(nextEnt, 0, sizeof (LoggerBuf_Entry)); /* get pointer to next entry */ if (nextEnt == obj->endEntry) { nextEnt = obj->entryArr; } else { nextEnt += 1; } } else { evtRec->arg[4] = 0; evtRec->arg[5] = 0; evtRec->arg[6] = 0; evtRec->arg[7] = 0; } } else { /* * readEntry has an even sequence number, so it's either an * incomplete record, or it's empty. If it's incomplete, we * need to toss it by advancing readEntry, but if it's empty * we want to do nothing. We need to be able to distinguish * between an incomplete "extension" record that has a serial * number of 0 (since it's base record was 0xffffffff) and * an empty record, and we do this by checking the evt field, * which gets set to ~0 for extension records in write8. */ if ((ent->evt == 0) && (ent->serial == 0)) { /* empty record, don't advance read pointer */ nextEnt = obj->readEntry; } else if (ent->evt == ~0) { /* extension record */ /* return -1 to indicate there may be more to go */ nEntries = -1; if (ent == obj->endEntry) { nextEnt = obj->entryArr; } else { nextEnt = ent + 1; } } else { /* return -1 to indicate there may be more to go */ nEntries = -1; /* bogus extension record, clear & advance read pointer */ memset(ent, 0, sizeof (LoggerBuf_Entry)); if (ent == obj->endEntry) { nextEnt = obj->entryArr; } else { nextEnt = ent + 1; } } } obj->readEntry = nextEnt; Gate_leaveModule(key); return (nEntries); }
/** * @name DomxTunnelMgr_mapTunnelComponentPeerHandles * @brief Map component handle to peer handles to be used in tunnel request * @param hTunneledOutput : Handle to output port component * @param hTunneledInput : Handle to input port component * @param hTunneledOutputPeerMap : Handle to mapped output port component * @param hTunneledOutputPeerMap : Handle to mapped input port component * @return none */ Void DomxTunnelMgr_mapTunnelComponentPeerHandles (OmxTypes_OMX_HANDLETYPE hTunneledOutput, OmxTypes_OMX_HANDLETYPE hTunneledInput, OmxTypes_OMX_HANDLETYPE *hTunneledOutputPeerMap, OmxTypes_OMX_HANDLETYPE *hTunneledInputPeerMap) { OMX_CONFIG_DOMXPROXYCOMPINFO sDomxProxyInfohOut, sDomxProxyInfohIn; DomxTypes_coreType eOutCompCoreId, eInCompCoreId; Int32 nCompIdxhOut, nCompIdxhIn; Error_Block ebObj; Error_Block *eb = &ebObj; IArg key; Bool bDisconnecthOut = FALSE; Bool bDisconnecthIn = FALSE; DOMX_UTL_TRACE_FUNCTION_ENTRY_LEVEL1 (); Log_print5 (Diags_USER1, "Entered: %s (0x%x, 0x%x, 0x%x, 0x%x)", (xdc_IArg) __FUNCTION__, (xdc_IArg) hTunneledOutput, (xdc_IArg) hTunneledInput, (xdc_IArg) hTunneledOutputPeerMap, (xdc_IArg) hTunneledInputPeerMap); Error_init (eb); if (FALSE == DomxTunnelMgr_module->initDone) { domxtmgr_module_init (); } key = Gate_enterModule (); *hTunneledOutputPeerMap = NULL; *hTunneledInputPeerMap = NULL; sDomxProxyInfohOut.pRpcStubHandle = NULL; sDomxProxyInfohIn.pRpcStubHandle = NULL; if (NULL != hTunneledOutput) { domxtmgr_get_component_connection_info (hTunneledOutput, &sDomxProxyInfohOut, &nCompIdxhOut, &eOutCompCoreId, eb); } else { bDisconnecthOut = TRUE; } if (FALSE == Error_check (eb)) { if (NULL != hTunneledInput) { Log_print1 (Diags_USER1, "eOutCompCoreId: %d\n", eOutCompCoreId); domxtmgr_get_component_connection_info (hTunneledInput, &sDomxProxyInfohIn, &nCompIdxhIn, &eInCompCoreId, eb); } else { bDisconnecthIn = TRUE; } } if (FALSE == Error_check (eb)) { if (NULL != hTunneledOutput) { if (FALSE == bDisconnecthIn) { Log_print1 (Diags_USER1, "eInCompCoreId: %d\n", eInCompCoreId); domxtmgr_map_connection_handle (nCompIdxhOut, eInCompCoreId, sDomxProxyInfohIn.pRpcStubHandle, hTunneledInputPeerMap, eb); } else { /* Do nothing for now */ } } } if (FALSE == Error_check (eb)) { if (NULL != hTunneledInput) { if (FALSE == bDisconnecthOut) { domxtmgr_map_connection_handle (nCompIdxhIn, eOutCompCoreId, sDomxProxyInfohOut.pRpcStubHandle, hTunneledOutputPeerMap, eb); } else { /* Do nothing for now */ } } } Gate_leaveModule (key); /* TODO: Component should return error code */ DOMX_UTL_TRACE_FUNCTION_ASSERT ((FALSE == Error_check (eb)), " in mapTunnelComponentPeerHandles"); DOMX_UTL_TRACE_FUNCTION_EXIT_LEVEL1 (OMX_ErrorNone); }
/* * ======== HeapMem_alloc ======== * HeapMem is implemented such that all of the memory and blocks it works * with have an alignment that is a multiple of the header size and have a * size which is a multiple of the header size. Maintaining this requirement * throughout the implementation ensures that there are never any odd * alignments or odd block sizes to deal with. * * Specifically: * The buffer managed by HeapMem: * 1. Is aligned on a multiple of sizeof(HeapMem_Header) * 2. Has an adjusted size that is a multiple of sizeof(HeapMem_Header) * All blocks on the freelist: * 1. Are aligned on a multiple of sizeof(HeapMem_Header) * 2. Have a size that is a multiple of sizeof(HeapMem_Header) * All allocated blocks: * 1. Are aligned on a multiple of sizeof(HeapMem_Header) * 2. Have a size that is a multiple of sizeof(HeapMem_Header) * */ Ptr HeapMem_alloc(HeapMem_Object *obj, SizeT reqSize, SizeT reqAlign, Error_Block *eb) { IArg key; HeapMem_Header *prevHeader, *newHeader, *curHeader; Char *allocAddr; Memory_Size curSize, adjSize; SizeT remainSize; /* free memory after allocated memory */ SizeT adjAlign, offset; /* Assert that requested align is a power of 2 */ Assert_isTrue(((reqAlign & (reqAlign - 1)) == 0), HeapMem_A_align); adjSize = (Memory_Size)reqSize; /* Make size requested a multiple of Memory_Header */ if ((offset = (adjSize & (obj->minBlockAlign - 1))) != 0) { adjSize = adjSize + (obj->minBlockAlign - offset); } /* Assert that requested block size is non-zero */ Assert_isTrue((adjSize != 0), HeapMem_A_zeroBlock); /* * Make sure the alignment is at least as large as the sizeof * HeapMem_Header. * Note: adjAlign must be a power of 2 (by function constraint) and * Header size is also a power of 2, */ adjAlign = reqAlign; if (adjAlign & (obj->minBlockAlign - 1)) { /* adjAlign is less than Header size */ adjAlign = obj->minBlockAlign; } key = Gate_enterModule(); /* * The block will be allocated from curHeader. Maintain a pointer to * prevHeader so prevHeader->next can be updated after the alloc. */ prevHeader = &obj->head; curHeader = prevHeader->next; /* Loop over the free list. */ while (curHeader != NULL) { curSize = curHeader->size; /* * Determine the offset from the beginning to make sure * the alignment request is honored. */ offset = (Memory_Size)curHeader & (adjAlign - 1); if (offset) { offset = adjAlign - offset; } /* Internal Assert that offset is a multiple of minBlockAlign */ Assert_isTrue(((offset & (obj->minBlockAlign - 1)) == 0), NULL); /* big enough? */ if (curSize >= (adjSize + offset)) { /* Set the pointer that will be returned. Alloc from front */ allocAddr = (Char *)((Memory_Size)curHeader + offset); /* * Determine the remaining memory after the allocated block. * Note: this cannot be negative because of above comparison. */ remainSize = curSize - adjSize - offset; /* Internal Assert that remainSize is a multiple of header size */ Assert_isTrue(((remainSize & (obj->minBlockAlign - 1)) == 0), NULL); /* * If there is memory at the beginning (due to alignment * requirements), maintain it in the list. * * offset and remainSize must be multiples of * sizeof(HeapMem_Header). Therefore the address of the newHeader * below must be a multiple of the sizeof(HeapMem_Header), thus * maintaining the requirement. */ if (offset) { /* Adjust the curHeader size accordingly */ curHeader->size = offset; /* * If there is remaining memory, add into the free list. * Note: no need to coalesce and we have HeapMem locked so * it is safe. */ if (remainSize) { newHeader = (HeapMem_Header *) ((Memory_Size)allocAddr + adjSize); newHeader->next = curHeader->next; newHeader->size = remainSize; curHeader->next = newHeader; } } else { /* * If there is any remaining, link it in, * else point to the next free block. * Note: no need to coalesce and we have HeapMem locked so * it is safe. */ if (remainSize) { newHeader = (HeapMem_Header *) ((Memory_Size)allocAddr + adjSize); newHeader->next = curHeader->next; newHeader->size = remainSize; prevHeader->next = newHeader; } else { prevHeader->next = curHeader->next; } } Gate_leaveModule(key); /* Success, return the allocated memory */ return ((Ptr)allocAddr); } else { prevHeader = curHeader; curHeader = curHeader->next; } } Gate_leaveModule(key); Error_raise(eb, HeapMem_E_memory, (IArg)obj, (IArg)reqSize); return (NULL); }
/* * ======== Notify_unregisterEvent ======== */ Int Notify_unregisterEvent(UInt16 procId, UInt16 lineId, UInt32 eventId, Notify_FnNotifyCbck fnNotifyCbck, UArg cbckArg) { UInt32 strippedEventId = (eventId & 0xFFFF); UInt16 clusterId = ti_sdo_utils_MultiProc_getClusterId(procId); Int status; UInt sysKey, modKey; ti_sdo_ipc_Notify_Object *obj; List_Handle eventList; ti_sdo_ipc_Notify_EventListener *listener; UInt count = 0; Assert_isTrue(procId < ti_sdo_utils_MultiProc_numProcessors && lineId < ti_sdo_ipc_Notify_numLines, ti_sdo_ipc_Notify_A_invArgument); Assert_isTrue(strippedEventId < ti_sdo_ipc_Notify_numEvents, ti_sdo_ipc_Notify_A_invArgument); Assert_isTrue(ISRESERVED(eventId), ti_sdo_ipc_Notify_A_reservedEvent); modKey = Gate_enterModule(); obj = (ti_sdo_ipc_Notify_Object *) Notify_module->notifyHandles[clusterId][lineId]; Assert_isTrue(obj != NULL, ti_sdo_ipc_Notify_A_notRegistered); eventList = List_Object_get(obj->eventList, strippedEventId); if (List_empty(eventList)) { return (Notify_E_NOTFOUND); } /* Get the first listener on the list */ listener = (ti_sdo_ipc_Notify_EventListener *)List_next(eventList, NULL); while (listener != NULL) { count++; if (listener->callback.fnNotifyCbck == (Fxn)fnNotifyCbck && listener->callback.cbckArg == cbckArg ) { break; /* found a match! */ } listener = (ti_sdo_ipc_Notify_EventListener *) List_next(eventList, (List_Elem *)listener); } if (listener == NULL) { /* Event listener not found */ status = Notify_E_NOTFOUND; } else { if (count == 1 && List_next(eventList, (List_Elem *)listener) == NULL) { /* * If only one element counted so far and the List_next returns * NULL, the list will be empty after unregistering. Therefore, * unregister the callback function. */ status = Notify_unregisterEventSingle(procId, lineId, eventId); /* unregisterEvent should always suceed */ Assert_isTrue(status == Notify_S_SUCCESS, ti_sdo_ipc_Notify_A_internal); /* No need to protect the list removal: the event's unregistered */ List_remove(eventList, (List_Elem *)listener); } else { /* * Need to atomically remove from the list using the system gate * because Notify_exec might preempt List_remove (the event is * still registered) */ sysKey = Hwi_disable(); List_remove(eventList, (List_Elem *)listener); Hwi_restore(sysKey); } /* Free the memory alloc'ed for the event listener */ Memory_free(ti_sdo_ipc_Notify_Object_heap(), listener, sizeof(ti_sdo_ipc_Notify_EventListener)); status = Notify_S_SUCCESS; } Gate_leaveModule(modKey); return (status); }
/* * ======== HeapMem_free ======== */ Void HeapMem_free(HeapMem_Object *obj, Ptr addr, SizeT size) { IArg key; HeapMem_Header *curHeader, *newHeader, *nextHeader; SizeT offset; /* Make sure the addr is aligned properly */ Assert_isTrue((((UArg)addr & (obj->minBlockAlign - 1)) == 0), HeapMem_A_invalidFree); /* obj->head never changes, doesn't need Gate protection. */ curHeader = &obj->head; /* Restore size to actual allocated size */ if ((offset = size & (obj->minBlockAlign - 1)) != 0) { size += obj->minBlockAlign - offset; } key = Gate_enterModule(); newHeader = (HeapMem_Header *)addr; nextHeader = curHeader->next; /* * Make sure the entire buffer is in the range of the heap. * Note the obj->head.size never changes */ Assert_isTrue((((UArg)newHeader >= (UArg)(obj->buf)) && ((UArg)newHeader + size <= (UArg)(obj->buf) + obj->head.size)), HeapMem_A_invalidFree); /* Go down freelist and find right place for buf */ while (nextHeader != NULL && nextHeader < newHeader) { /* Make sure the addr is not in this free block */ Assert_isTrue(((UArg)newHeader >= (UArg)nextHeader + nextHeader->size), HeapMem_A_invalidFree); curHeader = nextHeader; nextHeader = nextHeader->next; } newHeader->next = nextHeader; newHeader->size = size; curHeader->next = newHeader; /* Join contiguous free blocks */ if (nextHeader != NULL) { /* * Verify the free size is not overlapping. Not all cases are * detectable, but it is worth a shot. Note: only do this * assert if nextHeader is non-NULL. */ Assert_isTrue((((UArg)newHeader + size) <= (UArg)nextHeader), HeapMem_A_invalidFree); /* Join with upper block */ if (((Memory_Size)newHeader + size) == (Memory_Size)nextHeader) { newHeader->next = nextHeader->next; newHeader->size += nextHeader->size; } } /* * Join with lower block. Make sure to check to see if not the * first block. */ if ((curHeader != &obj->head) && (((Memory_Size)curHeader + curHeader->size) == (Memory_Size)newHeader)) { curHeader->next = newHeader->next; curHeader->size += newHeader->size; } Gate_leaveModule(key); }
/* * ======== traceThrFxn ======== */ static void *traceThrFxn(void *arg) { String engineName = (String) arg; Server_Status status; FILE *f; IArg key; /* determine DSP line prefix: "[DSP] " if local and DSP trace end up at the same * file, otherwise "" */ char *dspPrefix = (dsp0TraceFilePtr == localTraceFilePtr) ? "[DSP] " : ""; DBG("Trace thread started\n"); hEngine = Engine_open(engineName, NULL, NULL); if (hEngine == NULL) { ERR("Failed to open codec engine \"%s\"\n", engineName); threadCreateFailed = TRUE; return ((void *) -1); } /* for multi-process situations, make sure can acquire server trace */ if (Global_useLinkArbiter) { /* get server handle */ hServer = Engine_getServer(hEngine); /* cleanup and abort if can't get server handle */ if (hServer == NULL) { Engine_close(hEngine); ERR("Failed to get server handle\n"); threadCreateFailed = TRUE; return ((void *) -1); } /* request server trace token */ status = Server_connectTrace(hServer, &traceToken); /* cleanup and abort if trace could not acquire trace token */ if (status != Server_EOK) { Engine_close(hEngine); ERR("Failed to connect for server trace\n"); threadCreateFailed = TRUE; return ((void *) -1); } } /* else: if single-process, don't need to explictly connect for trace */ Engine_setTrace(hEngine, dsp0mask); /* create the pipe thread now */ if (cmdPipeFile != NULL && cmdPipeFile[0] != '\0') { if (pthread_create(&pipeThread, NULL, pipeThrFxn, NULL)) { ERR("Failed to create pipe thread\n"); } else { /* run the thread just created so it can immediately execute * pending cmdPipe trace commands -- in case there are any */ while (pipeThreadCreated == FALSE) { sched_yield(); } } } /* TODO: remove? will LogClient_connect be inside CE? */ /* * Note, call LogClient_connect() before releasing the main thread to * avoid context switching away _during_ the connect() call - which could * result in a skewed timesynch log. */ if (dsp0BiosFilePtr != NULL) { // LogClient_connect(); } /* Release the spinning main thread to run */ traceThreadCreated = TRUE; while (!quit) { if (refresh > 0) { DBG("Writing DSP logs\n"); key = Gate_enterModule(); Engine_fwriteTrace(hEngine, dspPrefix, dsp0TraceFilePtr); if (dsp0BiosFilePtr != NULL) { // LogClient_fwriteLogs(dsp0BiosFilePtr); } Gate_leaveModule(key); DBG("Sleeping for %d us\n", refresh); usleep(refresh); } else { DBG("Sleeping for %d us\n", SLEEPWHENNOREFRESH); usleep( SLEEPWHENNOREFRESH ); } } if (refresh > 0) { DBG("Trace thread exiting, writing final DSP logs\n"); /* try to collect anything that remained one more time */ key = Gate_enterModule(); Engine_fwriteTrace(hEngine, dspPrefix, dsp0TraceFilePtr); if (dsp0BiosFilePtr != NULL) { // LogClient_fwriteLogs(dsp0BiosFilePtr); } Gate_leaveModule(key); } if (dsp0BiosFilePtr != NULL) { // LogClient_disconnect(); } /* for multi-process situations, release trace token back to RMS */ if (Global_useLinkArbiter) { Server_disconnectTrace(hServer, traceToken); } Engine_close(hEngine); DBG("Quitting trace thread\n"); /* and killing our offspring. */ if (pipeThread != NULL) { DBG("Telling pipe thread to quit\n"); f = fopen(cmdPipeFile, "w"); if (f != NULL) { fputs(TRACECMD_QUIT, f); fclose(f); DBG("Wrote quit command, waiting for the pipe thread to join\n"); if (pthread_join(pipeThread, NULL)) { ERR("Failed to join pipe thread\n"); } DBG("Pipe thread joined.\n"); } } return ((void *) 1); }
/* * ======== write4 ========= */ Void LoggerBuf_write4(LoggerBuf_Object *obj, Log_Event evt, Types_ModuleId mid, IArg a1, IArg a2, IArg a3, IArg a4) { IArg key; Int adv; Int32 ser; LoggerBuf_Entry *e; /* Do nothing if the instance is disabled. */ if (!obj->enabled) { return; } /* * If event level filtering is enabled, and the event isn't a high enough * level, drop the record and return. */ if (LoggerBuf_filterByLevel && LoggerBuf_filterOutEvent(Log_getMask(evt))) { return; } /* * If all of the following are true: * - A logger has been specified to route status events to * - This is a status event * - This logger is NOT the status logger * Pass the event to the status logger and return. * * Otherwise, continue to log the event. */ if ((LoggerBuf_statusLogger != NULL) && (Log_getMask(evt) & Diags_STATUS) && (LoggerBuf_statusLogger != xdc_runtime_LoggerBuf_Handle_to_xdc_runtime_ILogger(obj))) { ILogger_write4(LoggerBuf_statusLogger, evt, mid, a1, a2, a3, a4); return; } key = Gate_enterModule(); /* * Record new serial number even if the buffer is FULL. We do this * because a reader (decoder) of the buffer needs to know if events * have been missed, and the buffer might become un-FULL at some * later time. */ ser = obj->serial; obj->serial += 2; adv = obj->advance; if (adv == LoggerBuf_FULL) { goto leave; } e = obj->curEntry; if (e == obj->endEntry) { if (adv == LoggerBuf_WRAP) { obj->curEntry = obj->entryArr; } else { obj->advance = LoggerBuf_FULL; } } else { obj->curEntry = e + 1; } LoggerBuf_TimestampProxy_get64(&e->tstamp); e->serial = ser; e->evt = Types_makeEvent(Log_getEventId(evt), mid); e->arg1 = a1; e->arg2 = a2; e->arg3 = a3; e->arg4 = a4; leave: Gate_leaveModule(key); }