/* This function maps kernel space memory to user space memory. */
static int bridge_mmap(struct file *filp, struct vm_area_struct *vma)
{
#if GT_TRACE
	u32 offset = vma->vm_pgoff << PAGE_SHIFT;
#endif
	u32 status;

	DBC_Assert(vma->vm_start < vma->vm_end);

	/* TODO: Check for valid size. */
	/* It looks right now like this can map all of kernel memory if requested */

	vma->vm_flags |= VM_RESERVED | VM_IO;
	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

	GT_6trace(driverTrace, GT_3CLASS,
		 "vm filp %p offset %lx start %lx end %lx"
		 " page_prot %lx flags %lx\n", filp, offset, vma->vm_start,
		 vma->vm_end, vma->vm_page_prot, vma->vm_flags);

	status = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
				vma->vm_end - vma->vm_start, vma->vm_page_prot);
	if (status != 0)
		status = -EAGAIN;

	return status;
}
示例#2
0
/*!
 * ======== VirtQueue_getAvailBuf ========
 */
Int16 VirtQueue_getAvailBuf(VirtQueue_Handle vq, Void **buf)
{
    UInt16 head;

    GT_6trace(curTrace, GT_2CLASS, "getAvailBuf vq: 0x%x %d %d %d 0x%x 0x%x",
        (IArg)vq, vq->last_avail_idx, vq->vring.avail->idx, vq->vring.num,
        (IArg)&vq->vring.avail, (IArg)vq->vring.avail);

    /* There's nothing available? */
    if (vq->last_avail_idx == vq->vring.avail->idx) {
        /* We need to know about added buffers */
        vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;

        return (-1);
    }

    /* No need to know be kicked about added buffers anymore */
    vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;

    /*
     * Grab the next descriptor number they're advertising, and increment
     * the index we've seen.
     */
    head = vq->vring.avail->ring[vq->last_avail_idx++ % vq->vring.num];

    *buf = mapPAtoVA(vq, vq->vring.desc[head].addr);

    return (head);
}
示例#3
0
/*
 *  ======== modifyDefaultLinkCfgObjectBasedOnUserCfgData ========
 */
static Void modifyDefaultLinkCfgObjectBasedOnUserCfgData( String serverName )
{
    LINKCFG_MemEntry *  linkcfgMemTable;
    LINKCFG_MemEntry *  e;
    static LINKCFG_MemEntry * linkcfgMemTables[] = { NULL /* to be set */ };
    Global_ArmDspLinkConfig * armDspLinkConfig = NULL;
    Global_ArmDspLinkConfigMemTableEntry *mte;
    DSP_BootMode    staticCfgDspCtl;
    DSP_BootMode    newCfgDspCtl;
    Int    serverNameIndex;
    UInt32 cmemPhysBase;
    size_t cmemSize;
    Int    status;

    /* MODIFY MEMORY CONFIGURATION */
    CMEM_BlockAttrs   blockAttrs;
    Int    numMemTableEntries, i = 0;
    Int    numMemEntries = 0;
    Int    memEntryIdx;
    Int    numCmemBlocks = 0;
    Bool   addCmemBlocks = FALSE;

    /* first locate our server in the list of server names */
    for (serverNameIndex = 0;;serverNameIndex++) {
        if (!strcmp(ti_sdo_ce_ipc_armDspLinkConfigServerNames[serverNameIndex],
            serverName)) {
                break;
        }
        if (ti_sdo_ce_ipc_armDspLinkConfigServerNames[serverNameIndex] ==
            NULL ) {
            GT_1trace(curTrace, GT_7CLASS, "Processor_create_d> "
                "ERROR: Cannot find DspLink configuration data for the server "
                "named '%s' -- verify that the name was specified correctly in "
                "the application configuration file.\n", serverName);
            return;
        }
    }

    GT_2trace(curTrace, GT_2CLASS, "Processor_create_d> "
        "Using DspLink config data for entry #%d [server '%s']\n",
        serverNameIndex, serverName );

    armDspLinkConfig = ti_sdo_ce_ipc_armDspLinkConfigs[ serverNameIndex ];

    ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->memTables = linkcfgMemTables;
    ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->memTables[0] = NULL;

    /*
     *  Count the number of CMEM blocks, so we can add entries for these,
     *  if needed.
     */
    status = CMEM_getNumBlocks(&numCmemBlocks);
    if (status != 0) {
        /* TODO: Is this always an error? */
        GT_0trace(curTrace, GT_6CLASS, "Processor_create_d> "
                "CMEM_getNumBlocks() failed!");
        numCmemBlocks = 0;
    }
    else {
        GT_1trace(curTrace, GT_2CLASS, "Processor_create_d> Number of CMEM "
                "blocks: %d\n", numCmemBlocks);
    }

    for (;armDspLinkConfig->memTable[i].segmentName != NULL; i++);

    /*
     *  Add a few extra entries in case we need to map CMEM blocks. The
     *  app's config will have at most one CMEM entry with base and length
     *  set to 0. We'll use CMEM_getBlockAttrs to get the base and length
     *  of all CMEM blocks. (Note: We will allocate at least one more entry
     *  then is actually needed, but this is easier than checking the
     *  memTable for "CMEM", and subtracting '1' from the nuber to allocate
     *  if "CMEM" is found.)
     */
    numMemEntries = i;
    numMemTableEntries = numMemEntries + numCmemBlocks;

    /* anything allocated here must be deallocated in procDelete */
    linkcfgMemTable = (LINKCFG_MemEntry *) Memory_alloc(
            sizeof(LINKCFG_MemEntry) * numMemTableEntries, NULL);

    if (linkcfgMemTable == NULL) {
        GT_0trace(curTrace, GT_7CLASS, "Processor_create_d> "
            "ERROR: Memory_alloc failed\n");
        return;
    }

    /* point link config memTables only entry to our list of memTable entries */
    ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->memTables[0] = linkcfgMemTable;

    for (i = 0, memEntryIdx = 0; i < numMemEntries; i++) {
        e   = &linkcfgMemTable[memEntryIdx];
        mte = &armDspLinkConfig->memTable[i];
        GT_4trace(curTrace, GT_2CLASS, "Processor_create_d> Adding memTable "
                "entry for %s, physAddr = 0x%x, dspAddr = 0x%x, size = 0x%x\n",
                mte->segmentName, mte->gppAddress, mte->startAddress,
                mte->sizeInBytes);

        if (!strcmp("CMEM", mte->segmentName)) {
            /* Skip CMEM entry, we'll add CMEM blocks later */
            addCmemBlocks = TRUE;
            continue;
        }

        e->entry        = memEntryIdx; //i;
        strncpy( e->name, mte->segmentName, DSP_MAX_STRLEN );
        e->physAddr     = mte->gppAddress; // gpp physical address
        e->dspVirtAddr  = mte->startAddress; // dsp view (physical or virtual)
        e->gppVirtAddr  = (UInt32)-1;
        e->size         = mte->sizeInBytes;
        e->shared       = mte->shared;
        e->syncd        = mte->syncd;

        memEntryIdx++;

        GT_6trace(curTrace, GT_2CLASS, "Processor_create_d> "
            "Adding DSP segment #%d to Link configuration: "
            "name='%s', startAddress=0x%x, sizeInBytes=0x%x, shared=%d, "
            "syncd=%d\n",
            i, e->name, e->physAddr, e->size, e->shared, e->syncd);
    }

    /* Now add the CMEM blocks if needed */
    if (addCmemBlocks) {
        for (i = 0; i < numCmemBlocks; i++) {
            e = &linkcfgMemTable[memEntryIdx];
            status = CMEM_getBlockAttrs(i, &blockAttrs);
            if (status != 0) {
                GT_1trace(curTrace, GT_7CLASS, "Processor_create_d> "
                        "ERROR: failed to get CMEM attrs of block %d\n", i);
                break;
            }
            sprintf(e->name, "CMEM_BLOCK%d", i);
            e->physAddr = blockAttrs.phys_base;
            e->dspVirtAddr = blockAttrs.phys_base;
            e->size = blockAttrs.size;
            memEntryIdx++;
        }
    }

    /* set number of memTable entries */
    ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->dspObject[0].memEntries =
        memEntryIdx; //numMemTableEntries;

    /* RESET vector is always #3 in the list (that's how Global.xdt arranges it;
     * read its start address and size and adjust some other params in the
     * dsplink config object. (Note: third in the list is index [2].
     */
    ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->dspObject[0].resumeAddr =
        armDspLinkConfig->memTable[2].startAddress + 0x20;
    ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->dspObject[0].resetVector =
        armDspLinkConfig->memTable[2].startAddress;
    ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->dspObject[0].resetCodeSize =
        armDspLinkConfig->memTable[2].sizeInBytes;

    /* SET DOPOWERCONTROL PER CE CONFIGURATION */
    staticCfgDspCtl =
        ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->dspObject[0].doDspCtrl;

    if (armDspLinkConfig->doDspCtrl == BootNoPwr) {
        newCfgDspCtl = DSP_BootMode_Boot_NoPwr;
    }
    else if (armDspLinkConfig->doDspCtrl == BootPwr) {
        newCfgDspCtl = DSP_BootMode_Boot_Pwr;
    }
    else if (armDspLinkConfig->doDspCtrl == NoLoadNoPwr) {
        newCfgDspCtl = DSP_BootMode_NoLoad_NoPwr;
    }
    else if (armDspLinkConfig->doDspCtrl == NoLoadPwr) {
        newCfgDspCtl = DSP_BootMode_NoLoad_Pwr;
    }
    else { /* NoBoot */
        newCfgDspCtl = DSP_BootMode_NoBoot;
    }

    ti_sdo_ce_ipc_Processor_linkcfg.dspConfigs[0]->dspObject[0].doDspCtrl =
        newCfgDspCtl;
    GT_2trace(curTrace, GT_2CLASS, "Processor_create_d> "
            "DODSPCTRL was=%d; now=%d\n", staticCfgDspCtl, newCfgDspCtl);
}
示例#4
0
/*
 *  ======== SPHENC_control ========
 *  This method must be the same for both local and remote invocation;
 *  each call site in the client might be calling different implementations
 *  (one that marshalls & sends and one that simply calls).  This API
 *  abstracts *all* speech encoders (both high and low complexity
 *  encoders are envoked using this method).
 */
XDAS_Int32 SPHENC_control(SPHENC_Handle handle, ISPHENC_Cmd id,
        ISPHENC_DynamicParams *dynParams, ISPHENC_Status *status)
{
    XDAS_Int32 retVal = SPHENC_EFAIL;

    SPHENC_DynamicParams refDynParams;
    XDAS_Int32 refStatusSize;

    /*
     * Note, we assign "VISA_isChecked()" results to a local variable
     * rather than repeatedly query it throughout this fxn because
     * someday we may allow dynamically changing the global
     * 'VISA_isChecked()' value on the fly.  If we allow that, we need
     * to ensure the value stays consistent in the context of this
     * call.
     */
    Bool checked = VISA_isChecked();

    if (checked) {
        /* Ensure dynParams and status are non-NULL, per the XDM spec */

        if ((!(XdmUtils_validateExtendedStruct(dynParams, sizeof(*dynParams),
                "dynParams"))) || (!(XdmUtils_validateExtendedStruct(status,
                sizeof(*status), "status")))) {
            /* for safety, return here before dereferencing and crashing */
            return (retVal);
        }
    }

    GT_6trace(CURTRACE, GT_ENTER, "SPHENC_control> "
        "Enter (handle=0x%x, id=%d, dynParams=0x%x (size=0x%x), "
        "status=0x%x (size=0x%x)\n",
        handle, id, dynParams, dynParams->size, status, status->size);

    if (handle) {
        ISPHENC_Fxns *fxns =
            (ISPHENC_Fxns *)VISA_getAlgFxns((VISA_Handle)handle);
        ISPHENC_Handle alg = VISA_getAlgHandle((VISA_Handle)handle);

        if ((fxns != NULL) && (alg != NULL)) {
            Log_printf(ti_sdo_ce_dvtLog, "%s", (Arg)"SPHENC:control",
                (Arg)handle, (Arg)0);

            if (checked) {

                /*
                 * Make a reference copy of dynParams, status->size, and
                 * status->data.bufSize so we can check that the codec
                 * didn't modify these read-only fields during control().
                 */
                refDynParams = *dynParams;
                refStatusSize = status->size;
            }

            VISA_enter((VISA_Handle)handle);
            retVal = fxns->control(alg, id, dynParams, status);
            VISA_exit((VISA_Handle)handle);

            if (checked) {
                /* ensure the codec didn't modify the read-only dynParams */
                if (memcmp(&refDynParams, dynParams, sizeof(*dynParams)) != 0) {
                    GT_1trace(CURTRACE, GT_7CLASS,
                        "ERROR> codec (0x%x) modified read-only dynParams "
                        "struct!\n", handle);
                }

                /* ensure the codec didn't change status->size */
                if (status->size != refStatusSize) {
                    GT_1trace(CURTRACE, GT_7CLASS,
                        "ERROR> codec (0x%x) modified read-only status->size "
                        "field!\n", handle);
                }
            }
        }
    }

    GT_2trace(CURTRACE, GT_ENTER, "SPHENC_control> "
        "Exit (handle=0x%x, retVal=0x%x)\n", handle, retVal);

    return (retVal);
}
/*
 *  ======== doTransfer ========
 */
static Void doTransfer(IDMA3_Handle handle)
{
    unsigned char *src, *dst;
    unsigned char *srcFrameStart, *dstFrameStart;
    ACPY3_PaRamRegs *paRamCache;
    Int numTransfers = handle->numPaRams;
    Int transferNo;
    unsigned short ccnt;
    unsigned short bcnt;
    unsigned short acnt;
    short srcElementIndex;
    short dstElementIndex;
    short srcFrameIndex;
    short dstFrameIndex;

    GT_1trace(CURTRACE, GT_ENTER, "doTransfer> Enter "
            "(handle=0x%x) \n", handle);

    for (transferNo = 0; transferNo < numTransfers; transferNo++) {
        /*
         * Use each transfer's cached paRam settings. The
         */
        paRamCache = (ACPY3_PaRamRegs *)ACPY3_getPaRamCache(handle,
                transferNo);

        src  = paRamCache->src;
        dst  = paRamCache->dst;
        acnt = paRamCache->acnt;
        bcnt = paRamCache->bcnt;

        /*
         *  QDMA can only transfer a single frame, so ccnt must always be 1.
         */
        ccnt = 1;

        srcElementIndex = paRamCache->srcElementIndex;
        dstElementIndex = paRamCache->dstElementIndex;
        srcFrameIndex = paRamCache->srcFrameIndex;
        dstFrameIndex = paRamCache->dstFrameIndex;

        GT_6trace(CURTRACE, GT_2CLASS, "doTransfer> Transfer %d,"
                " acnt  0x%x, bcnt 0x%x, src 0x%x, dst 0x%x, srcIndex 0x%x, "
                "dstIndex 0x%x\n", acnt, bcnt, src, dst, srcElementIndex, 
                dstElementIndex);

        while (ccnt-- > 0) {
            /* Keep track of the start of the frame */
            srcFrameStart = src;
            dstFrameStart = dst;

            /* Copy a frame */
            while (bcnt-- > 0) {

                /* Copy an element */
                while (acnt-- > 0) {
                    *dst++ = *src++;
                }

                /*
                 * Reset ACNT counter.
                 * Advance src/dst ptrs to beginning of next line/1D-vector
                 */
                acnt = paRamCache->acnt;
                src = (src - acnt) + srcElementIndex ;
                dst = (dst - acnt) + dstElementIndex;
            }

            /* adjust src and dst to the beginning of a frame + frameIndex*/
            bcnt = paRamCache->bcnt;
            src = srcFrameStart + srcFrameIndex;
            dst = dstFrameStart + dstFrameIndex;
        }
    } /* for each transfer */

    GT_0trace(CURTRACE, GT_ENTER, "doTransfer> Exit\n");
}
示例#6
0
/*
 *  ======== RMM_alloc ========
 */
DSP_STATUS RMM_alloc(struct RMM_TargetObj *target, u32 segid, u32 size,
		    u32 align, u32 *dspAddr, bool reserve)
{
	struct RMM_OvlySect *sect;
	struct RMM_OvlySect *prevSect = NULL;
	struct RMM_OvlySect *newSect;
	u32 addr;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(MEM_IsValidHandle(target, RMM_TARGSIGNATURE));
	DBC_Require(dspAddr != NULL);
	DBC_Require(size > 0);
	DBC_Require(reserve || (target->numSegs > 0));
	DBC_Require(cRefs > 0);

	GT_6trace(RMM_debugMask, GT_ENTER,
		 "RMM_alloc(0x%lx, 0x%lx, 0x%lx, 0x%lx, "
		 "0x%lx, 0x%lx)\n", target, segid, size, align, dspAddr,
		 reserve);
	if (!reserve) {
		if (!allocBlock(target, segid, size, align, dspAddr)) {
			status = DSP_EMEMORY;
		} else {
			/* Increment the number of allocated blocks in this
			 * segment */
			target->segTab[segid].number++;
		}
		goto func_end;
	}
	/* An overlay section - See if block is already in use. If not,
	 * insert into the list in ascending address size.  */
	addr = *dspAddr;
	sect = (struct RMM_OvlySect *)LST_First(target->ovlyList);
	/*  Find place to insert new list element. List is sorted from
	 *  smallest to largest address. */
	while (sect != NULL) {
		if (addr <= sect->addr) {
			/* Check for overlap with sect */
			if ((addr + size > sect->addr) || (prevSect &&
			   (prevSect->addr + prevSect->size > addr))) {
				status = DSP_EOVERLAYMEMORY;
			}
			break;
		}
		prevSect = sect;
		sect = (struct RMM_OvlySect *)LST_Next(target->ovlyList,
			(struct LST_ELEM *)sect);
	}
	if (DSP_SUCCEEDED(status)) {
		/* No overlap - allocate list element for new section. */
		newSect = MEM_Calloc(sizeof(struct RMM_OvlySect), MEM_PAGED);
		if (newSect == NULL) {
			status = DSP_EMEMORY;
		} else {
			LST_InitElem((struct LST_ELEM *)newSect);
			newSect->addr = addr;
			newSect->size = size;
			newSect->page = segid;
			if (sect == NULL) {
				/* Put new section at the end of the list */
				LST_PutTail(target->ovlyList,
					   (struct LST_ELEM *)newSect);
			} else {
				/* Put new section just before sect */
				LST_InsertBefore(target->ovlyList,
						(struct LST_ELEM *)newSect,
						(struct LST_ELEM *)sect);
			}
		}
	}
func_end:
	return status;
}
/*
 *  ======== _freeResource ========
 *  Actually free resources from the EDMA3 Low Level Resource Manager Handle
 */
static inline IRES_Status _freeResource(IALG_Handle algHandle, 
       Int scratchGroupId, short edma3Chan, short qdmaChan, 
       short numPaRams, short * paRamIndex, short numTccs, short * tccIndex,
       Bool contigRequest) 
{

    EDMA3_ResDesc resObj;
    IRES_Status status = IRES_OK;
    EDMA3_Result result = EDMA3_SOK;
    EDMA3_Handle rmHandle;
    int i;
    short toFreeTccs = 0;
    short toFreeParams = 0;
    Bool contig = FALSE;

/* TODO: Don't need to do anything for scratchGroupId != -1 */

    GT_6trace(CURTRACE, GT_ENTER, "_freeResource> Enter "
            "(algHandle=0x%x, scratchGroupId=%d, edma3Chan=%d, qdmaChan=%d, "
            "numPaRams=%d, numTccs=0x%x\n)",
            algHandle, scratchGroupId, edma3Chan, qdmaChan, numPaRams, numTccs);
    /*
     * Obtain Resource Manager handle corresponding to this algorithm in this 
     * scratch Group 
     */
    rmHandle = EDMA3_getResourceManager(algHandle, scratchGroupId);
/*
  1. Couple request into Logical EDMA channel request 
  2. Couple request into Logical QDMA channel request
  3. Couple request  for multiple (or the rest of the paRams) into contigPaRams
     request
  4. Request rest of the QDMA channels required -> will waste resources
  5. Request rest of the TCCs required  -> will waste resources
*/
    if ((numPaRams > 0) && (numTccs > 0)) {

        /* 1. */
        if (IRES_EDMA3CHAN_CHAN_NONE != edma3Chan) {

            /* If free request is for EDMA N, 
               then PaRam and TCC should be of the same number */
/* TODO: Assuming ordering of resources, maybe should search instead */         
            if ((edma3Chan == tccIndex[toFreeTccs]) && 
                    (edma3Chan == paRamIndex[toFreeParams])) {
    
                resObj.type = EDMA3_RES_DMA_CHANNEL; 
                resObj.resId = edma3Chan;
                tccIndex[toFreeTccs] = edma3Chan;  /* Requesting tcc == edma */ 
    
                if (EDMA3_SOK != EDMA3_freeLogicalChannel(rmHandle, 
                        &resObj)) {
                    //TODO: Blind release of logical channel, double check
                    //, (unsigned int *)&paRamArray[toFreeParams], 
                    // (unsigned int *)&tccIndex[toFreeTccs]))

                    status =  IRES_EFAIL;
                    goto freeResourceFail;
                }
                toFreeParams++;
                toFreeTccs++;
                numPaRams--;
                numTccs--;
                edma3Chan = IRES_EDMA3CHAN_CHAN_NONE;
            }
        }
        /* 2. */
        else if (IRES_EDMA3CHAN_CHAN_NONE != qdmaChan) {
            
            /* If request is for QDMA N  or QDMA Any, P should be ANY */
            /* TO check: Basically coupling QDMA channel with first PaRam and  
                         Tcc */
            
                    
    
                resObj.type = EDMA3_RES_QDMA_CHANNEL; 
                resObj.resId = qdmaChan; 

                if (EDMA3_SOK != EDMA3_freeLogicalChannel(rmHandle, 
                        &resObj)) {
                    //TODO: Blind release of logical channel, double check
                    //, (unsigned int *)&paRamArray[toFreeParams], 
                    // (unsigned int *)&tccIndex[toFreeTccs])) 

                    status =  IRES_EFAIL;
                    goto freeResourceFail;
                }
                toFreeParams++;
                toFreeTccs++;
                numPaRams--;
                numTccs--;
                qdmaChan = IRES_EDMA3CHAN_CHAN_NONE;
        }
    }

    /* 3. */

    /* Alloc contiguous or Not P */
    if (numPaRams > 0) {

        resObj.type = EDMA3_RES_PARAM_SET;


        /*
         * Check if params are contiguous 
         */
        contig = _checkContig(&paRamIndex[toFreeParams], numPaRams);
        
        /*
         * Check if they were requested contiguously
         */
        contig &= contigRequest;
        
        if (!contig) {
    
            /*
             * Free the PaRams individually
             */
            for (i = 0; i < numPaRams; i++) {
        
                resObj.resId = paRamIndex[toFreeParams];
                if (EDMA3_SOK != EDMA3_freeResource( rmHandle,&resObj)) {
        
                    status =  IRES_EFAIL;
                    goto freeResourceFail;
                }
                else {
        
                    toFreeParams++;
                }
            }
    
        }
        else {
            resObj.resId = paRamIndex[toFreeParams];
            if (EDMA3_SOK != EDMA3_freeContiguousResource(rmHandle,
                    &resObj, numPaRams)) {
        
                status =  IRES_EFAIL;
                goto freeResourceFail;
            }
            else {
                    toFreeParams += numPaRams;
            }
            numPaRams = 0;
        }
    }

    /* 4 */
    if (IRES_EDMA3CHAN_CHAN_NONE != edma3Chan) {

        resObj.type = EDMA3_RES_DMA_CHANNEL;
        resObj.resId = edma3Chan; 

        GT_1trace(CURTRACE, GT_2CLASS, 
                "IRESMAN_EDMA3CHAN_getHandles> Freeing individual EDMA "
                "channel %d, might cause other resources to be freed!\n", 
                resObj.resId);

        if (EDMA3_SOK != EDMA3_freeResource( rmHandle,&resObj)) {

            status =  IRES_EFAIL;
            goto freeResourceFail;
        }
        edma3Chan = IRES_EDMA3CHAN_CHAN_NONE;
    }

    if (IRES_EDMA3CHAN_CHAN_NONE != qdmaChan) {

        resObj.type = EDMA3_RES_QDMA_CHANNEL;
        resObj.resId = qdmaChan; 

        GT_1trace(CURTRACE, GT_2CLASS, 
                "IRESMAN_EDMA3CHAN_getHandles> Freeing individual Qdma "
                "channel %d, might cause other resources to be freed !\n", 
                resObj.resId);

        if (EDMA3_SOK != EDMA3_freeResource(rmHandle, &resObj)) {

            status =  IRES_EFAIL;
            goto freeResourceFail;
        }

        qdmaChan = IRES_EDMA3CHAN_CHAN_NONE;
    }

    if (numTccs > 0) {

        resObj.type = EDMA3_RES_TCC;

        GT_1trace(CURTRACE, GT_2CLASS, 
                "IRESMAN_EDMA3CHAN_getHandles> Freeing %d individual Tcc(s),"
                "might cause other resources to be freed!\n", numTccs);

        for(i = 0 ; i < numTccs; i++) {

            resObj.resId = tccIndex[toFreeTccs];

            if (EDMA3_SOK != EDMA3_freeResource( rmHandle, &resObj)) {

                status =  IRES_EFAIL;
                goto freeResourceFail;
            }

            GT_1trace(CURTRACE, GT_4CLASS,
                    "IRESMAN_EDMA3CHAN_getHandles> Freed TCC %d\n", 
                    tccIndex[toFreeTccs]); 

            toFreeTccs++;
        }

        numTccs = 0;
    }

freeResourceFail:
    result = EDMA3_releaseResourceManager(algHandle, scratchGroupId);

    if (result != EDMA3_SOK) {
        status = IRES_EFAIL; 
    }

    GT_1trace(CURTRACE, GT_ENTER, "_freeResource> Exit "
            "(status=%d)\n",status);

    return (status);
}
示例#8
0
/*
 *  ======== COD_LoadBase ========
 *  Purpose:
 *      Load the initial program image, optionally with command-line arguments,
 *      on the DSP system managed by the supplied handle. The program to be
 *      loaded must be the first element of the args array and must be a fully
 *      qualified pathname.
 *  Details:
 *      if nArgc doesn't match the number of arguments in the aArgs array, the
 *      aArgs array is searched for a NULL terminating entry, and argc is
 *      recalculated to reflect this.  In this way, we can support NULL
 *      terminating aArgs arrays, if nArgc is very large.
 */
DSP_STATUS COD_LoadBase(struct COD_MANAGER *hMgr, u32 nArgc, char *aArgs[],
			COD_WRITEFXN pfnWrite, void *pArb, char *envp[])
{
	DBLL_Flags flags;
	struct DBLL_Attrs saveAttrs;
	struct DBLL_Attrs newAttrs;
	DSP_STATUS status;
	u32 i;

	DBC_Require(cRefs > 0);
	DBC_Require(IsValid(hMgr));
	DBC_Require(nArgc > 0);
	DBC_Require(aArgs != NULL);
	DBC_Require(aArgs[0] != NULL);
	DBC_Require(pfnWrite != NULL);
	DBC_Require(hMgr->baseLib != NULL);

	GT_6trace(COD_debugMask, GT_ENTER,
		 "Entered COD_LoadBase, hMgr:  0x%x\n \t"
		 "nArgc:  0x%x\n\taArgs:  0x%x\n\tpfnWrite:  0x%x\n\tpArb:"
		 " 0x%x\n \tenvp:  0x%x\n", hMgr, nArgc, aArgs, pfnWrite,
		 pArb, envp);
	/*
	 *  Make sure every argv[] stated in argc has a value, or change argc to
	 *  reflect true number in NULL terminated argv array.
	 */
	for (i = 0; i < nArgc; i++) {
		if (aArgs[i] == NULL) {
			nArgc = i;
			break;
		}
	}

	/* set the write function for this operation */
	hMgr->fxns.getAttrsFxn(hMgr->target, &saveAttrs);

	newAttrs = saveAttrs;
	newAttrs.write = (DBLL_WriteFxn)pfnWrite;
	newAttrs.wHandle = pArb;
	newAttrs.alloc = (DBLL_AllocFxn)NoOp;
	newAttrs.free = (DBLL_FreeFxn)NoOp;
	newAttrs.logWrite = NULL;
	newAttrs.logWriteHandle = NULL;

	/* Load the image */
	flags = DBLL_CODE | DBLL_DATA | DBLL_SYMB;
	status = hMgr->fxns.loadFxn(hMgr->baseLib, flags, &newAttrs,
		 &hMgr->ulEntry);
	if (DSP_FAILED(status)) {
		hMgr->fxns.closeFxn(hMgr->baseLib);
		GT_1trace(COD_debugMask, GT_7CLASS,
			  "COD_LoadBase: COD Load failed: "
			  "0x%x\n", status);
	}
	if (DSP_SUCCEEDED(status))
		hMgr->fLoaded = true;
	else
		hMgr->baseLib = NULL;

	return status;
}