Beispiel #1
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);
}
/*
 *  ======== syslink_frameq_create ========
 */
int syslink_frameq_create(
    resmgr_context_t *  ctp,
    io_devctl_t *       msg,
    syslink_ocb_t *     ocb)
{
    FrameQDrv_CmdArgs *         cargs;
    Ptr                         params = NULL;
    FrameQ_ShMem_Params *       shMemParams;
    Ptr                         mgrshMem;
    Ptr                         gateShMem;
    String                      name = NULL;
    UInt16                      index;
    SharedRegion_SRPtr          srptr;
    Ptr                         gateAttrs;
    Int                         status;

    status = 0;
    cargs = (FrameQDrv_CmdArgs *)(_DEVCTL_DATA(msg->i));
    params = (Ptr)(cargs+1);

    if (cargs->args.create.nameLen > 0) {
        name = ((FrameQ_Params*)params)->commonCreateParams.name =
            (String)((FrameQ_ShMem_Params*)params+1);
    }

    if (cargs->args.create.interfaceType == FrameQ_INTERFACE_SHAREDMEM) {
        shMemParams = (FrameQ_ShMem_Params*)params;
        shMemParams->sharedAddr =
            SharedRegion_getPtr((SharedRegion_SRPtr)shMemParams->sharedAddr);

        if ((SharedRegion_SRPtr)shMemParams->frameQBufMgrSharedAddr ==
            SharedRegion_INVALIDSRPTR) {
            shMemParams->frameQBufMgrSharedAddr = NULL;
        }
        else {
            shMemParams->frameQBufMgrSharedAddr =
                SharedRegion_getPtr((SharedRegion_SRPtr)
                    shMemParams->frameQBufMgrSharedAddr);
        }
        /* Copy FrameQ BufMgr Name */
        if (cargs->args.create.nameLen > 0) {
            if (cargs->args.create.fQBMnameLen > 0) {
                shMemParams->frameQBufMgrName =
                    (String)(name + cargs->args.create.nameLen);
            }
        }
        else if (cargs->args.create.fQBMnameLen > 0) {
            shMemParams->frameQBufMgrName =
                (String)((FrameQ_ShMem_Params*)params+1);
        }

        /* open the gate instance to get a handle */
        srptr = (SharedRegion_SRPtr)shMemParams->gate;
        if (srptr != SharedRegion_INVALIDSRPTR) {
            gateAttrs = SharedRegion_getPtr(srptr);
            status = GateMP_openByAddr(gateAttrs, &shMemParams->gate);
        }
        else {
            shMemParams->gate = NULL;
        }
    }

    /* Call FrameQ_create  with the updated params */
    if (status >= 0) {
        cargs->args.create.handle = FrameQ_create(params);
    }
    else {
        cargs->args.create.handle = NULL;
    }

    if (cargs->args.create.handle != NULL) {
        /* Get the required info to be able to create ClientNotify
         * Mgr instane at user space
         */
        mgrshMem = _FrameQ_getCliNotifyMgrShAddr(cargs->args.create.handle);
        index = SharedRegion_getId(mgrshMem);
        cargs->args.create.cliNotifyMgrSharedMem =
            SharedRegion_getSRPtr(mgrshMem, index);
        gateShMem=_FrameQ_getCliNotifyMgrGateShAddr(cargs->args.create.handle);
        index = SharedRegion_getId(gateShMem);
        cargs->args.create.cliGateSharedMem =
            SharedRegion_getSRPtr(gateShMem, index);
    }

    /* clear the return message, setup return values */
    memset(&msg->o, 0, sizeof(msg->o));
    msg->o.nbytes = sizeof(FrameQDrv_CmdArgs);

    return(_RESMGR_PTR(ctp, &msg->o, sizeof(msg->o) + msg->o.nbytes));
}
static Void IpcFramesInLink_copyFrameInfo(IpcFramesInLink_Obj * pObj,
                                          VIDFrame_Buf *src,
                                          FVID2_Frame  *dst,
                                          volatile SharedRegion_SRPtr srPtr[VIDFRAME_MAX_FIELDS][VIDFRAME_MAX_PLANES])
{
    Int i;
    UInt32 numPlanes;
    Uint32 fieldIdx;
    System_FrameInfo *frmInfo;

    //UTILS_assert(pObj->inQueInfo.numQue == 1);
    UTILS_COMPILETIME_ASSERT(VIDFRAME_MAX_FIELDS == FVID2_MAX_FIELDS);
    UTILS_COMPILETIME_ASSERT(VIDFRAME_MAX_PLANES == FVID2_MAX_PLANES);
    numPlanes =
      IpcFrameInLink_mapDataFormat2NumPlanes((FVID2_DataFormat)
        pObj->inQueInfo.queInfo[0].chInfo[src->channelNum].dataFormat);
    for (i = 0; i < numPlanes; i++)
    {
        if (src->fid == FVID2_FID_BOTTOM)
        {
            fieldIdx = 1;
        }
        else
        {
            fieldIdx = 0;
        }
        /* Force field idx to 0 irrespective of top/bot field since
         * other links expect in this format
         */
        fieldIdx = 0;

        if (SYSTEM_MT_TILEDMEM ==
            pObj->inQueInfo.queInfo[0].chInfo[src->channelNum].memType)
        {
            dst->addr[fieldIdx][i] = (Ptr)src->phyAddr[fieldIdx][i];
        }
        else
        {
            if (srPtr[fieldIdx][i] != IPC_LINK_INVALID_SRPTR)
            {
                dst->addr[fieldIdx][i] = SharedRegion_getPtr(srPtr[fieldIdx][i]);
            }
            else
            {
                /*!WARNING. Assume phyiscalAddr == VirtualAddr on RTOS side.
                 * This will break once we have mmu on RTOS side
                 * TODO: Invoke syslink API on RTOS side to map virt2phy
                 */
                dst->addr[fieldIdx][i] = src->phyAddr[fieldIdx][i];
            }
        }
    }
    dst->channelNum = src->channelNum;
    UTILS_assert(dst->channelNum < pObj->info.queInfo[0].numCh);
    dst->fid        = src->fid;
    dst->timeStamp  = src->timeStamp;
    dst->blankData    = NULL;
    dst->drvData      = NULL;
    dst->perFrameCfg  = NULL;
    dst->subFrameInfo = NULL;
    frmInfo           = dst->appData;
    UTILS_assert(frmInfo != NULL);
    frmInfo->pOrgListMPElem  = src;

    frmInfo->rtChInfo.height  = src->frameHeight;
    frmInfo->rtChInfo.width  = src->frameWidth;
    frmInfo->rtChInfo.pitch[0]  = src->framePitch[0];
    frmInfo->rtChInfo.pitch[1]  = src->framePitch[1];
    /* HACK HACK HACK !!! modify rtChInfoUpdate = TRUE once the 
       next link support dynamic resolution change */
    frmInfo->rtChInfoUpdate = TRUE;//FALSE;

}
Beispiel #4
0
/*
 *  ======== ti_sdo_ipc_ListMP_Instance_init ========
 */
Int ti_sdo_ipc_ListMP_Instance_init(ti_sdo_ipc_ListMP_Object *obj,
        const ti_sdo_ipc_ListMP_Params *params,
        Error_Block *eb)
{
    SharedRegion_SRPtr sharedShmBase;
    Ptr localAddr;
    Int status;
    ListMP_Params sparams;
    IHeap_Handle regionHeap;

    if (params->openFlag == TRUE) {
        /* Open by sharedAddr */
        obj->objType = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC;
        obj->attrs = (ti_sdo_ipc_ListMP_Attrs *)params->sharedAddr;
        obj->regionId = SharedRegion_getId(&(obj->attrs->head));
        obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
        obj->cacheLineSize = SharedRegion_getCacheLineSize(obj->regionId);
    
        /* get the local address of the SRPtr */
        localAddr = SharedRegion_getPtr(obj->attrs->gateMPAddr);
        
        status = GateMP_openByAddr(localAddr, (GateMP_Handle *)&(obj->gate));
        if (status != GateMP_S_SUCCESS) {
            Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0);
            return (1);
        }
        
        return (0);
    }

    /* init the gate */
    if (params->gate != NULL) {
        obj->gate = params->gate;
    }
    else {
        obj->gate = (ti_sdo_ipc_GateMP_Handle)GateMP_getDefaultRemote();
    }
    
    if (params->sharedAddr == NULL) {
        /* Creating using a shared region ID */                
        obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION;
        obj->regionId = params->regionId;
        obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
        obj->cacheLineSize = SharedRegion_getCacheLineSize(obj->regionId);
                
        /* Need to allocate from the heap */
        ListMP_Params_init(&sparams);
        sparams.regionId = params->regionId;
        obj->allocSize = ListMP_sharedMemReq(&sparams);
            
        regionHeap = SharedRegion_getHeap(obj->regionId);
        Assert_isTrue(regionHeap != NULL, ti_sdo_ipc_SharedRegion_A_noHeap);

        /* The region heap will take care of the alignment */
        obj->attrs = Memory_alloc(regionHeap, obj->allocSize, 0, eb);

        if (obj->attrs == NULL) {
            return (2);
        }
    }
    else {
        /* Creating using sharedAddr */
        obj->regionId = SharedRegion_getId(params->sharedAddr);
            
        /* Assert that the buffer is in a valid shared region */
        Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID, 
                      ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);
                        
        /* set object's cacheEnabled, objType, and attrs  */
        obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
        obj->cacheLineSize = SharedRegion_getCacheLineSize(obj->regionId);
        obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
        obj->attrs = (ti_sdo_ipc_ListMP_Attrs *)params->sharedAddr;

        /* Assert that sharedAddr is cache aligned */
        Assert_isTrue((obj->cacheLineSize == 0) ||
                      ((UInt32)params->sharedAddr % obj->cacheLineSize == 0),
                      ti_sdo_ipc_Ipc_A_addrNotCacheAligned);
    }

    /* init the head (to be empty) */
    ListMP_elemClear(&(obj->attrs->head));
       
    /* store the GateMP sharedAddr in the Attrs */
    obj->attrs->gateMPAddr = ti_sdo_ipc_GateMP_getSharedAddr(obj->gate);

    /* last thing, set the status */
    obj->attrs->status = ti_sdo_ipc_ListMP_CREATED;
        
    if (obj->cacheEnabled) {
        Cache_wbInv(obj->attrs, sizeof(ti_sdo_ipc_ListMP_Attrs), 
                Cache_Type_ALL, TRUE);
    }
        
    /* add to NameServer if name not NULL */
    if (params->name != NULL) {
        sharedShmBase = SharedRegion_getSRPtr(obj->attrs, obj->regionId);
        obj->nsKey = NameServer_addUInt32(
            (NameServer_Handle)ListMP_module->nameServer, params->name,
            (UInt32)sharedShmBase);
        
        if (obj->nsKey == NULL) {
            Error_raise(eb, ti_sdo_ipc_Ipc_E_nameFailed, params->name, 0);
            return (3);
        }
    }

    return (0);
}
Beispiel #5
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);
}
Beispiel #6
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);
}
Beispiel #7
0
/*
 *  ======== SemaphoreMP_Instance_init ========
 */
Int SemaphoreMP_Instance_init(SemaphoreMP_Object *obj, Int count,
        const SemaphoreMP_Params *params, Error_Block *eb)
{
    Ptr localAddr;
    Int status;
    IHeap_Handle regionHeap;
    ListMP_Params listMPParams;
    SharedRegion_SRPtr sharedShmBase;
    
    if (params->openFlag) {
        /* Open by sharedAddr */
        obj->objType = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC;
        obj->attrs = (SemaphoreMP_Attrs *)params->sharedAddr;
        obj->regionId = SharedRegion_getId(obj->attrs);
        obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
    
        obj->mode = (SemaphoreMP_Mode)obj->attrs->mode;
    
        regionHeap = SharedRegion_getHeap(obj->regionId);
        Assert_isTrue(regionHeap != NULL, ti_sdo_ipc_SharedRegion_A_noHeap);
    
        /* get the local address of the SRPtr */
        localAddr = SharedRegion_getPtr(obj->attrs->gateMPAddr);
        status = GateMP_openByAddr(localAddr, (GateMP_Handle *)&(obj->gate));
        if (status < 0) {
            return (1);
        }
        
        /* Open the ListMP */
        localAddr = (Ptr)_Ipc_roundup(
            (UInt32)obj->attrs + sizeof(SemaphoreMP_Attrs), 
            SharedRegion_getCacheLineSize(obj->regionId));
        status = ListMP_openByAddr(localAddr, (ListMP_Handle *)&(obj->pendQ));
        if (status < 0) {
            /* obj->freeList set to NULL */
            return (4);
        }

        return (0);
    }

    /* init the gate */
    if (params->gate != NULL) {
        obj->gate = params->gate;
    }
    else {
        obj->gate = (ti_sdo_ipc_GateMP_Handle)GateMP_getDefaultRemote();
    }
    obj->mode = params->mode;
    
    if (params->sharedAddr == NULL) {
        /* Creating using a shared region ID */                
        obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC_REGION;
        obj->regionId = params->regionId;
        obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
                
        /* Need to allocate from the heap */
        obj->allocSize = SemaphoreMP_sharedMemReq(params);
            
        regionHeap = SharedRegion_getHeap(obj->regionId);
        Assert_isTrue(regionHeap != NULL, ti_sdo_ipc_SharedRegion_A_noHeap);

        /* The region heap will take care of the alignment */
        obj->attrs = Memory_alloc(regionHeap, obj->allocSize, 0, eb);
        if (obj->attrs == NULL) {
            return (2);
        }
    }
    else {
        /* Creating using sharedAddr */
        obj->regionId = SharedRegion_getId(params->sharedAddr);
                    
        /* Assert that the buffer is in a valid shared region */
        Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID, 
                      ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);
        
        /* Assert that sharedAddr is cache aligned */
        Assert_isTrue(((UInt32)params->sharedAddr % 
                      SharedRegion_getCacheLineSize(obj->regionId) == 0),
                      ti_sdo_ipc_Ipc_A_addrNotCacheAligned);
                
        /* set object's cacheEnabled, objType, and attrs  */
        obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
        obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
        obj->attrs = (SemaphoreMP_Attrs *)params->sharedAddr;
    }
    
    /* Store the GateMP sharedAddr in the SemaphoreMP Attrs */
    obj->attrs->gateMPAddr = ti_sdo_ipc_GateMP_getSharedAddr(obj->gate);
    obj->attrs->mode = (Bits16)obj->mode;
    obj->attrs->count = count;
    
    /* Create the freeList */
    ListMP_Params_init(&listMPParams);
    listMPParams.sharedAddr = (Ptr)_Ipc_roundup((UInt32)obj->attrs +
            sizeof(SemaphoreMP_Attrs), 
            SharedRegion_getCacheLineSize(obj->regionId));
    listMPParams.gate = (GateMP_Handle)obj->gate;
    obj->pendQ = (ti_sdo_ipc_ListMP_Handle)ListMP_create(&listMPParams);
    if (obj->pendQ == NULL) {
        return (3);
    }
    
    /* Last thing, set the status */
    obj->attrs->status = SemaphoreMP_CREATED;
    if (obj->cacheEnabled) {
        Cache_wbInv(obj->attrs, sizeof(SemaphoreMP_Attrs), Cache_Type_ALL, 
                TRUE);
    }
    
    /* Add entry to NameServer */
    if (params->name != NULL) {
        /* We will store a shared pointer in the NameServer */
        sharedShmBase = SharedRegion_getSRPtr(obj->attrs,
                                              obj->regionId);
        obj->nsKey = NameServer_addUInt32((NameServer_Handle)
                SemaphoreMP_module->nameServer, params->name,
                (UInt32)sharedShmBase);
        if (obj->nsKey == NULL) {
            /* NameServer_addUInt32 failed */
            return (4); 
        }
    }
    
    return (0);
}
Beispiel #8
0
/*
 *  ======== TransportShm_Instance_init ========
 */
Int TransportShm_Instance_init(TransportShm_Object *obj,
        UInt16 procId, const TransportShm_Params *params,
        Error_Block *eb)
{
    Int            localIndex;
    Int            remoteIndex;
    Int            status;
    Bool           flag;
    UInt32         minAlign;
    ListMP_Params  listMPParams[2];
    Swi_Handle     swiHandle;
    Swi_Params     swiParams;
    Ptr            localAddr;

    swiHandle = TransportShm_Instance_State_swiObj(obj);

    /*
     *  Determine who gets the '0' slot in shared memory and who gets
     *  the '1' slot. The '0' slot is given to the lower MultiProc id.
     */
    if (MultiProc_self() < procId) {
        localIndex  = 0;
        remoteIndex = 1;
    }
    else {
        localIndex  = 1;
        remoteIndex = 0;
    }

    if (params->openFlag) {
        /* Open by sharedAddr */
        obj->objType = ti_sdo_ipc_Ipc_ObjType_OPENDYNAMIC;
        obj->self = (TransportShm_Attrs *)params->sharedAddr;
        obj->regionId = SharedRegion_getId(params->sharedAddr);
        obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);

        localAddr = SharedRegion_getPtr(obj->self->gateMPAddr);
        status = GateMP_openByAddr(localAddr, (GateMP_Handle *)&obj->gate);
        if (status < 0) {
            Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0);
            return(1);
        }
    }
    else {
        /* init the gate for ListMP create below */
        if (params->gate != NULL) {
            obj->gate = params->gate;
        }
        else {
            obj->gate = (ti_sdo_ipc_GateMP_Handle)GateMP_getDefaultRemote();
        }

        /* Creating using sharedAddr */
        obj->regionId = SharedRegion_getId(params->sharedAddr);

        /* Assert that the buffer is in a valid shared region */
        Assert_isTrue(obj->regionId != SharedRegion_INVALIDREGIONID,
                ti_sdo_ipc_Ipc_A_addrNotInSharedRegion);

        /* Assert that sharedAddr is cache aligned */
        Assert_isTrue(((UInt32)params->sharedAddr %
                SharedRegion_getCacheLineSize(obj->regionId) == 0),
                ti_sdo_ipc_Ipc_A_addrNotCacheAligned);

        /* set object's cacheEnabled, type, self */
        obj->cacheEnabled = SharedRegion_isCacheEnabled(obj->regionId);
        obj->objType = ti_sdo_ipc_Ipc_ObjType_CREATEDYNAMIC;
        obj->self = (TransportShm_Attrs *)params->sharedAddr;
    }

    /* determine the minimum alignment to align to */
    minAlign = Memory_getMaxDefaultTypeAlign();
    if (SharedRegion_getCacheLineSize(obj->regionId) > minAlign) {
        minAlign = SharedRegion_getCacheLineSize(obj->regionId);
    }

    /*
     *  Carve up the shared memory.
     *  If cache is enabled, these need to be on separate cache lines.
     *  This is done with minAlign and _Ipc_roundup function.
     */
    obj->other = (TransportShm_Attrs *)((UInt32)(obj->self) +
        (_Ipc_roundup(sizeof(TransportShm_Attrs), minAlign)));

    ListMP_Params_init(&(listMPParams[0]));
    listMPParams[0].gate = (GateMP_Handle)obj->gate;
    listMPParams[0].sharedAddr = (UInt32 *)((UInt32)(obj->other) +
        (_Ipc_roundup(sizeof(TransportShm_Attrs), minAlign)));

    ListMP_Params_init(&listMPParams[1]);
    listMPParams[1].gate = (GateMP_Handle)obj->gate;
    listMPParams[1].sharedAddr = (UInt32 *)((UInt32)(listMPParams[0].sharedAddr)
        + ListMP_sharedMemReq(&listMPParams[0]));

    obj->priority      = params->priority;
    obj->remoteProcId  = procId;

    Swi_Params_init(&swiParams);
    swiParams.arg0 = (UArg)obj;
    Swi_construct(Swi_struct(swiHandle),
                 (Swi_FuncPtr)TransportShm_swiFxn,
                 &swiParams, eb);

    if (params->openFlag == FALSE) {
        obj->localList = (ti_sdo_ipc_ListMP_Handle)
                ListMP_create(&(listMPParams[localIndex]));
        if (obj->localList == NULL) {
            Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0);
            return (2);
        }

        obj->remoteList = (ti_sdo_ipc_ListMP_Handle)
                ListMP_create(&(listMPParams[remoteIndex]));
        if (obj->localList == NULL) {
            Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0);
            return (2);
        }
    }
    else {
        /* Open the local ListMP instance */
        status = ListMP_openByAddr(listMPParams[localIndex].sharedAddr,
                                   (ListMP_Handle *)&(obj->localList));

        if (status < 0) {
            Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0);
            return (2);
        }

        /* Open the remote ListMP instance */
        status = ListMP_openByAddr(listMPParams[remoteIndex].sharedAddr,
                                   (ListMP_Handle *)&(obj->remoteList));

        if (status < 0) {
            Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0);
            return (2);
        }
    }

    /* register the event with Notify */
    status = Notify_registerEventSingle(
                 procId,    /* remoteProcId */
                 0,         /* lineId */
                 TransportShm_notifyEventId,
                 (Notify_FnNotifyCbck)TransportShm_notifyFxn,
                 (UArg)swiHandle);
    if (status < 0) {
        Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0);
        return (3);
    }

    /* Register the transport with MessageQ */
    flag = ti_sdo_ipc_MessageQ_registerTransport(
            TransportShm_Handle_upCast(obj), procId, params->priority);
    if (flag == FALSE) {
        Error_raise(eb, ti_sdo_ipc_Ipc_E_internal, 0, 0);
        return (4);
    }

    if (params->openFlag == FALSE) {
        obj->self->creatorProcId = MultiProc_self();
        obj->self->notifyEventId = TransportShm_notifyEventId;
        obj->self->priority = obj->priority;

        /* Store the GateMP sharedAddr in the Attrs */
        obj->self->gateMPAddr = ti_sdo_ipc_GateMP_getSharedAddr(obj->gate);
        obj->self->flag = TransportShm_UP;

        if (obj->cacheEnabled) {
            Cache_wbInv(obj->self, sizeof(TransportShm_Attrs),
                     Cache_Type_ALL, TRUE);
        }
    }
    else {
        obj->other->flag = TransportShm_UP;
        if (obj->cacheEnabled) {
            Cache_wbInv(&(obj->other->flag), minAlign, Cache_Type_ALL, TRUE);
        }
    }

    obj->status = TransportShm_UP;

    return (0);
}