Example #1
0
/*
 *  ======== 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);
}
Example #2
0
/*
 *  ======== 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);
}
Example #3
0
/*
 *  ======== GateAAMonitor_Instance_init ========
 */
Int GateAAMonitor_Instance_init(GateAAMonitor_Object *obj,
                                IGateProvider_Handle localGate,
                                const GateAAMonitor_Params *params,
                                Error_Block *eb)
{
    /* Assert that params->sharedAddr is valid */
    Assert_isTrue(
        (UInt32)params->sharedAddr >= GateAAMonitor_SL2_RANGE_BASE &&
        (UInt32)params->sharedAddr <  GateAAMonitor_SL2_RANGE_MAX,
        GateAAMonitor_A_invSharedAddr);

    obj->localGate  = localGate;
    obj->sharedAddr = (Ptr)_Ipc_roundup(params->sharedAddr,
            GateAAMonitor_CACHELINE_SIZE);
    obj->nested = 0;

    if (!params->openFlag) {
        /*
         *  The processor that inits the AAM initializes the value
         *  to zero (e.g. no one is using it). The other processors
         *  must invalidate the memory in case it is in cache.
         */
        *(obj->sharedAddr) = 0;
        Cache_wbInv((Ptr)obj->sharedAddr, GateAAMonitor_CACHELINE_SIZE,
                    Cache_Type_ALL, TRUE);
    }
    else {
        /* Opening. */
        Cache_inv((Ptr)obj->sharedAddr, GateAAMonitor_CACHELINE_SIZE,
                  Cache_Type_ALL, TRUE);
    }

    return (0);
}
void CacheInvalShrinkData(const uint8_T *Img, const uint8_T *ImgSmall, const uint32_t yStart, const uint32_t yEnd, const uint32_t yEvenOdd, const uint32_t xWidth, const uint32_t xWidthSmall)
{
	if (0 != MultiProc_self())	//skip on main core
	{
		#if 0

		//Invalidate input image data
		uint8_T* in_buf_start;
		uint32_T in_buf_size;
		CalcInputBufferPos(Img, yStart, yEnd, yEvenOdd, xWidth, in_buf_start, in_buf_size);
		Cache_inv((xdc_Ptr*) in_buf_start, in_buf_size, Cache_Type_ALL, CACHE_BLOCKING);		//Blocking because we will process the data immediately

		#endif

		//Invalidate parts of the output cache, because the main core zeroed memory after boot (or after the last calculation was finished when the DSP was idle)
		//In CacheWriteBackShrinkData() we push all image data, the data we wrote to and also the end of the lines which we didn't touch here. Because we didn't
		//touch the end of the lines (and left it black) we have to cacheinval it here to be sure its blackness is known to this core).
		/* Should be unnecessary since I introduced CacheInvalShrinkData()
		uint8_T* out_buf_start;
		uint32_T out_buf_size;
		CalcOutputBufferPos(ImgSmall, yStart, yEnd, xWidthSmall, out_buf_start, out_buf_size);
		Cache_inv((xdc_Ptr*) out_buf_start, out_buf_size, Cache_Type_ALL, CACHE_BLOCKING);		//Blocking because we will process the data immediately
		*/
	}
}
Example #5
0
/* Function to write back invalidate the Cache module */
Void Cache_wbInv(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait) {
    GT_4trace (curTrace, GT_ENTER, "Cache_wbInv", blockPtr, byteCnt, type, wait);
#if 0

/*
 * It appears that this #if 0'ed code doesn't actually perform the
 * invalidate part of the wbInv, and it appears that Cache_wb() and Cache_inv()
 * work properly, so for now we implement wbInv as a combination of the two
 * individual functions.
*/

#ifdef USE_CACHE_VOID_ARG
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)
                dmac_map_area(blockPtr, (size_t)byteCnt, DMA_BIDIRECTIONAL);
                outer_flush_range(__pa((UInt32)blockPtr),
                                  __pa((UInt32)(blockPtr+byteCnt)) );
#else
                dmac_flush_range(blockPtr, (blockPtr+byteCnt) );
#endif
#else
                dmac_flush_range( (UInt32)blockPtr, (UInt32)(blockPtr + byteCnt) );
#endif

#else

    Cache_wb(blockPtr, byteCnt, type, wait);
    Cache_inv(blockPtr, byteCnt, type, wait);

#endif

    GT_0trace (curTrace, GT_LEAVE, "Cache_wbInv");
}
Example #6
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);
}
Example #7
0
/*
 *  ======== 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);
}
Example #8
0
/**
 * Cache invalidate image data if necessary
 */
void CacheInvalImageData(process_message_t* p_msg)
{
	if(0 != p_msg->info.NewImageDataArrived)
	{
		if (0 != MultiProc_self()) {
			#ifdef _TRACE_MC_
				logout("[core_%u] CACHE INVALIDATE IMAGE DATA ON SLAVE CORE (T %u bytes, R %u bytes)\n", p_msg->core_id, p_msg->info.Tsize, p_msg->info.Rsize);
			#endif
			Cache_inv((xdc_Ptr*) p_msg->info.Tvec, p_msg->info.Tsize , Cache_Type_ALL, CACHE_BLOCKING);
			Cache_inv((xdc_Ptr*) p_msg->info.Rvec, p_msg->info.Rsize , Cache_Type_ALL, CACHE_BLOCKING);
		} else {
			#ifdef _TRACE_MC_
				logout("[core_%u] CACHE INVALIDATE SKIPPED ON MAIN CORE (T %u bytes, R %u bytes)\n", p_msg->core_id, p_msg->info.Tsize, p_msg->info.Rsize);
			#endif
		}
	}
}
Example #9
0
/*
 *  ======== 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);
}
Example #10
0
/*
 *  ======== Memory_cacheInv ========
 */
Void Memory_cacheInv(Ptr addr, Int sizeInBytes)
{
    Log_print2(Diags_ENTRY, "[+E] Memory_cacheInv> "
            "Enter(addr=0x%x, sizeInBytes=%d)", (IArg)addr, (IArg)sizeInBytes);

    Cache_inv(addr, sizeInBytes, Cache_Type_ALL, TRUE);

    Log_print0(Diags_EXIT, "[+X] Memory_cacheInv> return");
}
Example #11
0
/*
 *  ======== 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(&params);
    
    /* 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(&params, &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);
}
Example #12
0
/*
 *  ======== 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(&params);

    /* 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, &params, eb);
        if (*handlePtr == NULL) {
            status = MessageQ_E_FAIL;
        }
        else {
            status = MessageQ_S_SUCCESS;
        }
    }

    return (status);
}
Example #13
0
/**
 * Cache invalidate the total image memory (happens after the main core zeroizes all memory (at boot time and after/between the calculations)
 */
void CacheInvalTotalMemory(process_message_t* p_msg)
{
	if (0 != MultiProc_self()) {
		#ifdef _TRACE_MC_
			logout("[core_%u] CACHE INVALIDATE ZEROIZRD DATA ON SLAVE CORE (T %u bytes, R %u bytes)\n", p_msg->core_id, p_msg->info.Tsize, p_msg->info.Rsize);
		#endif
		Cache_inv((xdc_Ptr*) p_msg->info.Tvec, p_msg->info.Tsize , Cache_Type_ALL, CACHE_BLOCKING);
	} else {
		#ifdef _TRACE_MC_
			//The following shouldn't happen ...
			logout("[core_%u] CACHE INVALIDATE ZEROIZRD DATA SKIPPED ON MAIN CORE (T %u bytes, R %u bytes)\n", p_msg->core_id, p_msg->info.Tsize, p_msg->info.Rsize);
		#endif
	}

}
Example #14
0
/**
 * Public, called from shrinkImageDSP (on the main core) after entering shrinkImage_on_core()
 */
void CacheInvalReadyShrinkedData(const uint8_T *ImgSmall, const uint32_t yStart, const uint32_t yEnd, const uint32_t xWidthSmall)
{
#ifdef _NO_IPC_TEST_
	if (0 == MultiProc_self())	//skip on main core
		return;
#else
	//ASSERT(0 == MultiProc_self());
#endif


	#if 0
	//Invalidate the output cache, we need the data the other cores wrote to.
	uint8_T* out_buf_start;
	uint32_T out_buf_size;
	CalcOutputBufferPos(ImgSmall, yStart, yEnd, xWidthSmall, out_buf_start, out_buf_size);
	Cache_inv((xdc_Ptr*) out_buf_start, out_buf_size, Cache_Type_ALL, CACHE_BLOCKING);		//Blocking because we will process the data immediately
	#endif
}
Example #15
0
static RPC_OMX_ERRORTYPE RPC_SKEL_ShareRegion(UInt32 size, UInt32 *data)
{
    buffer_one  *buffer_args;
	
	Frame_dsp *pFrame = NULL;

    buffer_args = (buffer_one *)((UInt32)data + sizeof(map_info_type) + sizeof(int));

	pFrame = (Frame_dsp*)buffer_args->addr;
	
	Cache_inv(pFrame, buffer_args->size, Cache_Type_ALL, TRUE);

	BRIEF_match(pFrame->kpoint_left, pFrame->n_kpoint_left, pFrame->kpoint_right, pFrame->n_kpoint_right, 
		pFrame->range, pFrame->best_choice, IMG_WIDTH, IMG_HEIGHT);

	Cache_wbInv(pFrame, buffer_args->size, Cache_Type_ALL, TRUE);

    return(0);
}
Example #16
0
/*
 *  ======== 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(&params);

    /* 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, &params, &eb);
        if (*handlePtr == NULL) {
            status = -1; //SemaphoreMP_E_FAIL;
        }
        else {
            status = 0; //SemaphoreMP_S_SUCCESS;
        }
    }

    return (status);
}
Example #17
0
/*
 *  ======== ListMP_empty ========
 */
Bool ListMP_empty(ListMP_Handle handle)
{
    ti_sdo_ipc_ListMP_Object *obj = (ti_sdo_ipc_ListMP_Object *)handle;
    Bool flag = FALSE;
    IArg key;
    SharedRegion_SRPtr sharedHead;
    
    /* prevent another thread or processor from modifying the ListMP */
    key = GateMP_enter((GateMP_Handle)obj->gate);


    if (ti_sdo_ipc_SharedRegion_translate == FALSE) {
        /* get the SRPtr for the head */
        sharedHead = (SharedRegion_SRPtr)&(obj->attrs->head);
    }
    else {
        /* get the SRPtr for the head */
        sharedHead = SharedRegion_getSRPtr(&(obj->attrs->head), obj->regionId);
    }

    /* if 'next' is ourself, then the ListMP must be empty */
    if (obj->attrs->head.next == sharedHead) {
        flag = TRUE;
    }

    if (obj->cacheEnabled) {
        /* invalidate the head to make sure we are not getting stale data */
        Cache_inv(&(obj->attrs->head), sizeof(ListMP_Elem), Cache_Type_ALL,
                  TRUE);
    }

    /* leave the gate */
    GateMP_leave((GateMP_Handle)obj->gate, key);

    return (flag);
}
Example #18
0
/*
 *  ======== 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);
}
Example #19
0
/*
 *  ======== 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);
}
Example #20
0
/*
 *  ======== Ipc_start ========
 */
Int Ipc_start()
{
    Int i;
    UInt16 baseId = MultiProc_getBaseIdOfCluster();
    SharedRegion_Entry entry;
    Ptr ipcSharedAddr;
    Ptr gateMPSharedAddr;
    GateMP_Params gateMPParams;
    Int status;

    /* Check whether Ipc_start has been called.  If so, succeed. */
    if (Ipc_module->ipcSharedAddr != NULL) {
        return (Ipc_S_ALREADYSETUP);
    }

    if (ti_sdo_ipc_Ipc_generateSlaveDataForHost) {
        /* get Ipc_sr0MemorySetup out of the cache */
        Cache_inv(&Ipc_sr0MemorySetup,
              sizeof(Ipc_sr0MemorySetup),
              Cache_Type_ALL,
              TRUE);

        /* check Ipc_sr0MemorySetup variable */
        if (Ipc_sr0MemorySetup == 0x0) {
            return (Ipc_E_NOTREADY);
        }
    }

    /* get region 0 information */
    SharedRegion_getEntry(0, &entry);

    /* if entry is not valid then return */
    if (entry.isValid == FALSE) {
        return (Ipc_E_NOTREADY);
    }

    /*
     *  Need to reserve memory in region 0 for processor synchronization.
     *  This must done before SharedRegion_start().
     */
    ipcSharedAddr = ti_sdo_ipc_SharedRegion_reserveMemory(
            0, Ipc_getRegion0ReservedSize());

    /* must reserve memory for GateMP before SharedRegion_start() */
    gateMPSharedAddr = ti_sdo_ipc_SharedRegion_reserveMemory(0,
            ti_sdo_ipc_GateMP_getRegion0ReservedSize());

    /* Init params for default gate (must match those in GateMP_start()) */
    GateMP_Params_init(&gateMPParams);
    gateMPParams.localProtect  = GateMP_LocalProtect_TASKLET;

    if (ti_sdo_utils_MultiProc_numProcessors > 1) {
        gateMPParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
    }
    else {
        gateMPParams.remoteProtect = GateMP_RemoteProtect_NONE;
    }

    /* reserve memory for default gate before SharedRegion_start() */
    ti_sdo_ipc_SharedRegion_reserveMemory(0, GateMP_sharedMemReq(&gateMPParams));

    /* clear the reserved memory */
    ti_sdo_ipc_SharedRegion_clearReservedMemory();

    /* Set shared addresses */
    Ipc_module->ipcSharedAddr = ipcSharedAddr;
    Ipc_module->gateMPSharedAddr = gateMPSharedAddr;

    /* create default GateMP, must be called before SharedRegion start */
    status = ti_sdo_ipc_GateMP_start(Ipc_module->gateMPSharedAddr);
    if (status < 0) {
        return (status);
    }

    /* create HeapMemMP in each SharedRegion */
    status = ti_sdo_ipc_SharedRegion_start();
    if (status < 0) {
        return (status);
    }

    /* Call attach for all procs if procSync is ALL */
    if (ti_sdo_ipc_Ipc_procSync == ti_sdo_ipc_Ipc_ProcSync_ALL) {
        /* Must attach to owner first to get default GateMP and HeapMemMP */
        if (MultiProc_self() != entry.ownerProcId) {
            do {
                status = Ipc_attach(entry.ownerProcId);
            } while (status == Ipc_E_NOTREADY);

            if (status < 0) {
                /* Ipc_attach failed. Get out of Ipc_start */
                return (status);
            }
        }

        /* Loop to attach to all other processors in cluster */
        for (i = 0; i < ti_sdo_utils_MultiProc_numProcsInCluster; i++, baseId++) {
            if ((baseId == MultiProc_self()) || (baseId == entry.ownerProcId)) {
                continue;
            }

            /* Skip the processor if there are no interrupt lines to it */
            if (Notify_numIntLines(baseId) == 0) {
                continue;
            }

            /* call Ipc_attach for every remote processor */
            do {
                status = Ipc_attach(baseId);
            } while (status == Ipc_E_NOTREADY);

            if (status < 0) {
                /* Ipc_attach failed. Get out of Ipc_start */
                return (status);
            }
        }
    }

    return (status);
}
Example #21
0
/*
 *  ======== SemaphoreMP_pend ========
 */
Bool SemaphoreMP_pend(SemaphoreMP_Object *obj)
{
    UInt tskKey;
    SemaphoreMP_PendElem *elem;
    IArg gateMPKey;

    /* Check for correct calling context */
    Assert_isTrue((BIOS_getThreadType() == BIOS_ThreadType_Task),
                    SemaphoreMP_A_badContext);

    elem = ThreadLocal_getspecific(SemaphoreMP_pendElemKey);
    if (elem == NULL) {
        /* 
         * Choose region zero (instead of the region that contains the 
         * SemaphoreMP) since region zero is always accessible by all cores
         */
        elem = Memory_alloc(SharedRegion_getHeap(0), 
                sizeof(SemaphoreMP_PendElem), 0, NULL);
        ThreadLocal_setspecific(SemaphoreMP_pendElemKey, elem);
    }
    
    /* Enter the gate */
    gateMPKey = GateMP_enter((GateMP_Handle)obj->gate);

    if (obj->cacheEnabled) {
        Cache_inv(obj->attrs, sizeof(SemaphoreMP_Attrs), Cache_Type_ALL, TRUE);
    }
    
    /* check semaphore count */
    if (obj->attrs->count == 0) {
        /* lock task scheduler */
        tskKey = Task_disable();

        /* get task handle and block tsk */
        elem->task = (Bits32)Task_self();
        elem->procId = MultiProc_self();
        
        Task_block((Task_Handle)elem->task);
        
        if (obj->cacheEnabled) {
            Cache_wbInv(elem, sizeof(SemaphoreMP_PendElem), Cache_Type_ALL, TRUE);
        }

        /* add it to pendQ */
        ListMP_putTail((ListMP_Handle)obj->pendQ, (ListMP_Elem *)elem);

        /* Leave the gate */
        GateMP_leave((GateMP_Handle)obj->gate, gateMPKey);

        Task_restore(tskKey);/* the calling task will switch out here */

        return (TRUE);
    }
    else {
        obj->attrs->count--;
        if (obj->cacheEnabled) {
            Cache_wbInv(obj->attrs, sizeof(SemaphoreMP_Attrs), Cache_Type_ALL, 
                    TRUE);
        }

        /* Leave the gate */
        GateMP_leave((GateMP_Handle)obj->gate, gateMPKey);

        return (TRUE);
    }
}
Example #22
0
/*
 *  ======== 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);
}
Example #23
0
/*
 *  ======== 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);
}
Example #24
0
/*
 *  ======== GatePetersonN_enter ========
 */
IArg GatePetersonN_enter(GatePetersonN_Object *obj)
{
    IArg key;
    SizeT   numProcessors;
    SizeT   myProcId;
    Int32   curStage;
    SizeT   proc;

    /* Enter local gate */
    key = IGateProvider_enter(obj->localGate);

    /* If the gate object has already been entered, return the key */
    obj->nested++;
    if (obj->nested > 1) {
        return (key);
    }
    numProcessors = obj->numProcessors;
    myProcId      = obj->selfId;

    for (curStage=0; curStage < (numProcessors - 1); curStage++) {

        *(obj->enteredStage[myProcId]) = curStage;
        *(obj->lastProcEnteringStage[curStage]) = myProcId;

	if (obj->cacheEnabled) {

            Cache_wbInv((Ptr)obj->enteredStage[myProcId], obj->cacheLineSize,
                    Cache_Type_ALL, FALSE);
            Cache_wbInv((Ptr)obj->lastProcEnteringStage[curStage],
                    obj->cacheLineSize, Cache_Type_ALL, TRUE);
        }

        for (proc=0; proc < numProcessors; proc++) {

            if (proc != myProcId) {

	        if (obj->cacheEnabled) {

                    Cache_inv((Ptr)obj->enteredStage[proc],
                            obj->cacheLineSize, Cache_Type_ALL, FALSE);
                    Cache_inv((Ptr)obj->lastProcEnteringStage[curStage],
                            obj->cacheLineSize, Cache_Type_ALL, TRUE);
		}

                while ((*(obj->enteredStage[proc]) >= curStage) &&
                       (*(obj->lastProcEnteringStage[curStage]) == myProcId)) {

                    /* wait till 'proc' leaves or another 'proc' enters stage */
	            if (obj->cacheEnabled) {

                        Cache_inv((Ptr)obj->enteredStage[proc],
                                obj->cacheLineSize, Cache_Type_ALL, FALSE);
                        Cache_inv((Ptr)obj->lastProcEnteringStage[curStage],
                                obj->cacheLineSize, Cache_Type_ALL, TRUE);
                    }
                }
            }
        }

    } /* stages */

    return (key);
}
Example #25
0
/*
 *  ======== NotifyDriverShm_sendEvent ========
 */
Int NotifyDriverShm_sendEvent(NotifyDriverShm_Object *obj,
                              UInt32                 eventId,
                              UInt32                 payload,
                              Bool                   waitClear)
{
    NotifyDriverShm_EventEntry *eventEntry;
    UInt32 i;
    UInt sysKey;
    
    eventEntry = EVENTENTRY(obj->otherEventChart, obj->eventEntrySize, eventId);

    /* Check whether driver on other processor is initialized */
    if (obj->cacheEnabled) {
        Cache_inv(obj->otherProcCtrl, sizeof(NotifyDriverShm_ProcCtrl),
                  Cache_Type_ALL, TRUE);
    }

    if (obj->otherProcCtrl->recvInitStatus != NotifyDriverShm_INIT_STAMP) {
        /*
         * This may be used for polling till the other driver is ready, so
         * do not assert or error
         */
        return (Notify_E_NOTINITIALIZED);
    }

    /* Check to see if the remote event is enabled */
    if (!TEST_BIT(obj->otherProcCtrl->eventEnableMask, eventId)) {
        return (Notify_E_EVTDISABLED);
    }

    /* Check to see if the remote event is registered */
    if (!TEST_BIT(obj->otherProcCtrl->eventRegMask, eventId)) {
        return (Notify_E_EVTNOTREGISTERED);
    }

    
    if (waitClear) {
        i = 0;

        if (obj->cacheEnabled) {
            Cache_inv(eventEntry, sizeof(NotifyDriverShm_EventEntry),
                Cache_Type_ALL, TRUE);
        }

        /* 
         *  The system gate is needed to ensure that checking eventEntry->flag 
         *  is atomic with the eventEntry modifications (flag/payload).
         */
        sysKey = Hwi_disable();

        /* Wait for completion of previous event from other side. */
        while ((eventEntry->flag != NotifyDriverShm_DOWN)) {
            /* 
             * Leave critical section protection. Create a window
             * of opportunity for other interrupts to be handled.
             */
            Hwi_restore(sysKey);
            i++;
            if ((i != (UInt32)-1) &&  
                (i == ti_sdo_ipc_Notify_sendEventPollCount)) {
                return (Notify_E_TIMEOUT);
            }
            
            if (obj->cacheEnabled) {
                Cache_inv(eventEntry, sizeof(NotifyDriverShm_EventEntry),
                    Cache_Type_ALL, TRUE);
            }
            
            /* Re-enter the system gate */
            sysKey = Hwi_disable();
        }
    }
    else {
        /* 
         *  The system gate is needed to ensure that checking eventEntry->flag 
         *  is atomic with the eventEntry modifications (flag/payload).
         */
        sysKey = Hwi_disable();
    }
    
    /* Set the event bit field and payload.*/
    eventEntry->payload = payload;
    eventEntry->flag    = NotifyDriverShm_UP;
    if (obj->cacheEnabled) {
        Cache_wbInv(eventEntry, sizeof(NotifyDriverShm_EventEntry),
            Cache_Type_ALL, TRUE);
    }

    /* Send an interrupt to the Remote Processor */
    NotifyDriverShm_InterruptProxy_intSend(obj->remoteProcId, &(obj->intInfo),
                                           eventId);
                                           
    /* must not restore interrupts before sending the interrupt */
    Hwi_restore(sysKey);   
    
    return (Notify_S_SUCCESS);
}
Example #26
0
/*
 *  ======== NotifyDriverShm_disableEvent ========
 */
Void NotifyDriverShm_disableEvent(NotifyDriverShm_Object *obj, UInt32 eventId)
{
    UInt sysKey;
    NotifyDriverShm_EventEntry *eventEntry;
    
    Assert_isTrue(eventId < ti_sdo_ipc_Notify_numEvents, 
            ti_sdo_ipc_Ipc_A_invArgument);

    /* 
     *  Atomically unset the corresponding bit in the processor's 
     *  eventEnableMask 
     */
    sysKey = Hwi_disable();
    CLEAR_BIT(obj->selfProcCtrl->eventEnableMask, eventId);
    Hwi_restore(sysKey);
    if (obj->cacheEnabled) {
        Cache_wbInv(obj->selfProcCtrl, sizeof(NotifyDriverShm_ProcCtrl), 
            Cache_Type_ALL, TRUE);
    }

    eventEntry = EVENTENTRY(obj->selfEventChart, obj->eventEntrySize, 
            eventId);
    if (obj->cacheEnabled) {
        Cache_inv(eventEntry,
                  sizeof(NotifyDriverShm_EventEntry),
                  Cache_Type_ALL, TRUE);
    }
    
    /* 
     *  Disable incoming Notify interrupts.  This is done to ensure that the
     *  eventEntry->flag is read atomically with any write back to shared
     *  memory
     */
    NotifyDriverShm_disable(obj);

    /* 
     *  Is the local NotifyDriverShm_disableEvent happening between the 
     *  following two NotifyDriverShm_sendEvent operations on the remote 
     *  processor?
     *  1. Writing NotifyDriverShm_UP to shared memory
     *  2. Sending the interrupt across
     *  If so, we should handle this event so the other core isn't left spinning
     *  until the event is re-enabled and the next NotifyDriverShm_isr executes
     *  This race condition is very rare but we need to account for it:
     */
    if (eventEntry->flag == NotifyDriverShm_UP) {
        /* 
         *  Acknowledge the event. No need to store the payload. The other side 
         *  will not send this event again even though flag is down, because the
         *  event is now disabled. So the payload within the eventChart will not
         *  get overwritten. 
         */
        eventEntry->flag = NotifyDriverShm_DOWN;
        
        /* Write back acknowledgement */
        if (obj->cacheEnabled) {
            Cache_wbInv(eventEntry, sizeof(NotifyDriverShm_EventEntry),
                Cache_Type_ALL, TRUE);
        }
        
        /* 
         *  Execute the callback function. This will execute in a Task
         *  or Swi context (not Hwi!)
         */
        ti_sdo_ipc_Notify_exec(obj->notifyHandle, eventId, eventEntry->payload);
    }

    /* Re-enable incoming Notify interrupts */
    NotifyDriverShm_enable(obj);
}
Example #27
0
/*
 *  ======== NotifyDriverShm_isr ========
 */
Void NotifyDriverShm_isr(UArg arg)
{
    UInt                            i;
    NotifyDriverShm_EventEntry      *eventEntry;
    NotifyDriverShm_Object          *obj;
    UInt32                          eventId;
    UInt32                          payload;

    obj = (NotifyDriverShm_Object *)arg;

    /* Make sure the NotifyDriverShm_Object is not NULL */
    Assert_isTrue(obj != NULL, ti_sdo_ipc_Ipc_A_internal);
    
    /* Clear the remote interrupt */
    NotifyDriverShm_InterruptProxy_intClear(obj->remoteProcId, 
                                            &(obj->intInfo));
    
    /*
     * Iterate till no asserted event is found for one complete loop
     * through all registered events.
     */
    i = 0;
    do {
        eventId = obj->regChart[i];

        /* Check if the entry is a valid registered event. */
        if (eventId != (UInt32)-1) {
            /*
             *  Check whether the event is disabled. If so, avoid the 
             *  unnecessary Cache invalidate. NOTE: selfProcCtrl does not have
             *  to be cache-invalidated because:
             *  1) Whenever self is written to by the local processor its memory
             *     is also invalidated
             *  2) 'selfProcCtrl' is never written to by the remote processor
             */
            if (!TEST_BIT(obj->selfProcCtrl->eventEnableMask, 
                (UInt32)eventId)) {
                i++;
                continue; 
            }
            
            eventEntry = EVENTENTRY(obj->selfEventChart, obj->eventEntrySize, 
                eventId);
            
            if (obj->cacheEnabled) {
                Cache_inv(eventEntry,
                          sizeof(NotifyDriverShm_EventEntry),
                          Cache_Type_ALL, TRUE);
            }

            /* Check if the event is set */
            if (eventEntry->flag == NotifyDriverShm_UP) {
                /* 
                 *  Save the payload since it may be overwritten before 
                 *  Notify_exec is called 
                 */
                payload = eventEntry->payload;
                
                /* Acknowledge the event. */
                eventEntry->flag = NotifyDriverShm_DOWN;
                
                /* Write back acknowledgement */
                if (obj->cacheEnabled) {
                    Cache_wbInv(eventEntry, sizeof(NotifyDriverShm_EventEntry),
                        Cache_Type_ALL, TRUE);
                }

                /* Execute the callback function */
                ti_sdo_ipc_Notify_exec(obj->notifyHandle, eventId, payload);

                /* reinitialize the event check counter. */
                i = 0;
            }
            else {
                /* check for next event. */
                i++;
            }
        }
    }
    while ((eventId != (UInt32)-1) && (i < ti_sdo_ipc_Notify_numEvents));
}
Example #28
0
/*
 *  ======== 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);
}