示例#1
0
/*  ======== DMM_CreateTables ========
 *  Purpose:
 *      Create table to hold the information of physical address
 *      the buffer pages that is passed by the user, and the table
 *      to hold the information of the virtual memory that is reserved
 *      for DSP.
 */
DSP_STATUS DMM_CreateTables(struct DMM_OBJECT *hDmmMgr, u32 addr, u32 size)
{
	struct DMM_OBJECT *pDmmObj = (struct DMM_OBJECT *)hDmmMgr;
	DSP_STATUS status = DSP_SOK;

	GT_3trace(DMM_debugMask, GT_ENTER,
		 "Entered DMM_CreateTables () hDmmMgr %x, addr"
		 " %x, size %x\n", hDmmMgr, addr, size);
	status = DMM_DeleteTables(pDmmObj);
	if (DSP_SUCCEEDED(status)) {
		SYNC_EnterCS(pDmmObj->hDmmLock);
		dynMemMapBeg = addr;
		TableSize = (size/PG_SIZE_4K) + 1;
		/*  Create the free list */
		pVirtualMappingTable = (struct MapPage *) MEM_Calloc
		(TableSize*sizeof(struct MapPage), MEM_NONPAGED);
		if (pVirtualMappingTable == NULL)
			status = DSP_EMEMORY;
		else {
			/* This table will be used
			* to store the virtual to physical
			* address translations
			*/
			pPhysicalAddrTable = (u32 *)MEM_Calloc
				(TableSize*sizeof(u32), MEM_NONPAGED);
			GT_1trace(DMM_debugMask, GT_4CLASS,
			"DMM_CreateTables: Allocate"
			"memory for pPhysicalAddrTable=%d entries\n",
			TableSize);
			if (pPhysicalAddrTable == NULL) {
				status = DSP_EMEMORY;
				GT_0trace(DMM_debugMask, GT_7CLASS,
				    "DMM_CreateTables: Memory allocation for "
				    "pPhysicalAddrTable failed\n");
			} else {
			/* On successful allocation,
			* all entries are zero ('free') */
			iFreeRegion = 0;
			iFreeSize = TableSize*PG_SIZE_4K;
			pVirtualMappingTable[0].RegionSize = TableSize;
			}
		}
		SYNC_LeaveCS(pDmmObj->hDmmLock);
	} else
		GT_0trace(DMM_debugMask, GT_7CLASS,
			 "DMM_CreateTables: DMM_DeleteTables"
			 "Failure\n");

	GT_1trace(DMM_debugMask, GT_4CLASS, "Leaving DMM_CreateTables status"
							"0x%x\n", status);
	return status;
}
示例#2
0
/*
 *  ======== CreateChirpList ========
 *  Purpose:
 *      Initialize a queue of channel I/O Request/Completion packets.
 *  Parameters:
 *      uChirps:    Number of Chirps to allocate.
 *  Returns:
 *      Pointer to queue of IRPs, or NULL.
 *  Requires:
 *  Ensures:
 */
static struct LST_LIST *CreateChirpList(u32 uChirps)
{
	struct LST_LIST *pChirpList;
	struct CHNL_IRP *pChirp;
	u32 i;

	pChirpList = MEM_Calloc(sizeof(struct LST_LIST), MEM_NONPAGED);

	if (pChirpList) {
		INIT_LIST_HEAD(&pChirpList->head);
		/* Make N chirps and place on queue. */
		for (i = 0; (i < uChirps) && ((pChirp = MakeNewChirp()) !=
		    NULL); i++) {
			LST_PutTail(pChirpList, (struct list_head *)pChirp);
		}

		/* If we couldn't allocate all chirps, free those allocated: */
		if (i != uChirps) {
			FreeChirpList(pChirpList);
			pChirpList = NULL;
		}
	}

	return pChirpList;
}
示例#3
0
文件: ntfy.c 项目: ka6sox/nook_kernel
/*
 *  ======== NTFY_Create ========
 *  Purpose:
 *      Create an empty list of notifications.
 */
DSP_STATUS NTFY_Create(struct NTFY_OBJECT **phNtfy)
{
	struct NTFY_OBJECT *pNtfy;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(phNtfy != NULL);

	*phNtfy = NULL;
	MEM_AllocObject(pNtfy, struct NTFY_OBJECT, NTFY_SIGNATURE);

	if (pNtfy) {

		status = SYNC_InitializeDPCCS(&pNtfy->hSync);
		if (DSP_SUCCEEDED(status)) {
			pNtfy->notifyList = MEM_Calloc(sizeof(struct LST_LIST),
							MEM_NONPAGED);
			if (pNtfy->notifyList == NULL) {
				(void) SYNC_DeleteCS(pNtfy->hSync);
				MEM_FreeObject(pNtfy);
				status = DSP_EMEMORY;
			} else {
				INIT_LIST_HEAD(&pNtfy->notifyList->head);
				*phNtfy = pNtfy;
			}
		}
	} else {
		status = DSP_EMEMORY;
	}

	DBC_Ensure((DSP_FAILED(status) && *phNtfy == NULL) ||
		  (DSP_SUCCEEDED(status) && MEM_IsValidHandle((*phNtfy),
		  NTFY_SIGNATURE)));

	return status;
}
示例#4
0
/*
 *  ======== WMD_CHNL_Create ========
 *      Create a channel manager object, responsible for opening new channels
 *      and closing old ones for a given board.
 */
DSP_STATUS WMD_CHNL_Create(OUT struct CHNL_MGR **phChnlMgr,
			  struct DEV_OBJECT *hDevObject,
			  IN CONST struct CHNL_MGRATTRS *pMgrAttrs)
{
	DSP_STATUS status = DSP_SOK;
	struct CHNL_MGR *pChnlMgr = NULL;
	s32 cChannels;

	/* Check DBC requirements:  */
	DBC_Require(phChnlMgr != NULL);
	DBC_Require(pMgrAttrs != NULL);
	DBC_Require(pMgrAttrs->cChannels > 0);
	DBC_Require(pMgrAttrs->cChannels <= CHNL_MAXCHANNELS);
	DBC_Require(pMgrAttrs->uWordSize != 0);

	/* Allocate channel manager object: */
	MEM_AllocObject(pChnlMgr, struct CHNL_MGR, CHNL_MGRSIGNATURE);
	if (pChnlMgr) {
		/* The cChannels attr must equal the # of supported
		 * chnls for each transport(# chnls for PCPY = DDMA =
		 * ZCPY): i.e. pMgrAttrs->cChannels = CHNL_MAXCHANNELS =
		 * DDMA_MAXDDMACHNLS = DDMA_MAXZCPYCHNLS.  */
		DBC_Assert(pMgrAttrs->cChannels == CHNL_MAXCHANNELS);
		cChannels = CHNL_MAXCHANNELS + CHNL_MAXCHANNELS * CHNL_PCPY;
		/* Create array of channels: */
		pChnlMgr->apChannel = MEM_Calloc(
				sizeof(struct CHNL_OBJECT *) *
				cChannels, MEM_NONPAGED);
		if (pChnlMgr->apChannel) {
			/* Initialize CHNL_MGR object: */
			/* Shared memory driver. */
			pChnlMgr->dwType = CHNL_TYPESM;
			pChnlMgr->uWordSize = pMgrAttrs->uWordSize;
			/* total # chnls supported */
			pChnlMgr->cChannels = cChannels;
			pChnlMgr->cOpenChannels = 0;
			pChnlMgr->dwOutputMask = 0;
			pChnlMgr->dwLastOutput = 0;
			pChnlMgr->hDevObject = hDevObject;
			if (DSP_SUCCEEDED(status))
				status = SYNC_InitializeDPCCS(
							&pChnlMgr->hCSObj);
		} else {
			status = DSP_EMEMORY;
		}
	} else {
		status = DSP_EMEMORY;
	}

	if (DSP_FAILED(status)) {
		WMD_CHNL_Destroy(pChnlMgr);
		*phChnlMgr = NULL;
	} else {
		/* Return channel manager object to caller... */
		*phChnlMgr = pChnlMgr;
	}
	return status;
}
示例#5
0
/*
 *  ======== GS_alloc ========
 *  purpose:
 *      Allocates memory of the specified size.
 */
void *GS_alloc(u32 size)
{
	void *p;

	p = MEM_Calloc(size, MEM_PAGED);
	if (p == NULL)
		return NULL;
	cumsize += size;
	return p;
}
示例#6
0
/*
 *  ======== freeBlock ========
 *  TO DO: freeBlock() allocates memory, which could result in failure.
 *  Could allocate an RMM_Header in RMM_alloc(), to be kept in a pool.
 *  freeBlock() could use an RMM_Header from the pool, freeing as blocks
 *  are coalesced.
 */
static bool freeBlock(struct RMM_TargetObj *target, u32 segid, u32 addr,
		     u32 size)
{
	struct RMM_Header *head;
	struct RMM_Header *thead;
	struct RMM_Header *rhead;
	bool retVal = true;

	/* Create a memory header to hold the newly free'd block. */
	rhead = MEM_Calloc(sizeof(struct RMM_Header), MEM_PAGED);
	if (rhead == NULL) {
		retVal = false;
	} else {
		/* search down the free list to find the right place for addr */
		head = target->freeList[segid];

		if (addr >= head->addr) {
			while (head->next != NULL && addr > head->next->addr)
				head = head->next;

			thead = head->next;

			head->next = rhead;
			rhead->next = thead;
			rhead->addr = addr;
			rhead->size = size;
		} else {
			*rhead = *head;
			head->next = rhead;
			head->addr = addr;
			head->size = size;
			thead = rhead->next;
		}

		/* join with upper block, if possible */
		if (thead != NULL && (rhead->addr + rhead->size) ==
		   thead->addr) {
			head->next = rhead->next;
			thead->size = size + thead->size;
			thead->addr = addr;
			MEM_Free(rhead);
			rhead = thead;
		}

		/* join with the lower block, if possible */
		if ((head->addr + head->size) == rhead->addr) {
			head->next = rhead->next;
			head->size = head->size + rhead->size;
			MEM_Free(rhead);
		}
	}

	return retVal;
}
示例#7
0
/*
 *  ======== regsupInit ========
 *  Purpose:
 *      Initialize the Registry Support module's private state.
 */
bool regsupInit(void)
{
	if (pRegKey != NULL)
		return true;

	/*  Need to allocate and setup our registry.  */
	pRegKey = MEM_Calloc(sizeof(struct RegKeyStruct), MEM_NONPAGED);
	if (pRegKey == NULL)
		return false;

	return true;
}
示例#8
0
/*
 *  ======== MakeNewChirp ========
 *      Allocate the memory for a new channel IRP.
 */
static struct CHNL_IRP *MakeNewChirp(void)
{
	struct CHNL_IRP *pChirp;

	pChirp = (struct CHNL_IRP *)MEM_Calloc(
		 sizeof(struct CHNL_IRP), MEM_NONPAGED);
	if (pChirp != NULL) {
		/* LST_InitElem only resets the list's member values. */
		LST_InitElem(&pChirp->link);
	}

	return pChirp;
}
示例#9
0
/*
 *  ======== AddNewMsg ========
 *      Must be called in message manager critical section.
 */
static DSP_STATUS AddNewMsg(struct LST_LIST *msgList)
{
	struct MSG_FRAME *pMsg;
	DSP_STATUS status = DSP_SOK;

	pMsg = (struct MSG_FRAME *)MEM_Calloc(sizeof(struct MSG_FRAME),
		MEM_PAGED);
	if (pMsg != NULL) {
		LST_InitElem((struct LST_ELEM *) pMsg);
		LST_PutTail(msgList, (struct LST_ELEM *) pMsg);
	} else {
		status = DSP_EMEMORY;
	}

	return status;
}
示例#10
0
/*
 *  ======== LST_Create ========
 *  Purpose:
 *      Allocates and initializes a circular list.
 */
struct LST_LIST *LST_Create(void)
{
	struct LST_LIST *pList;

	GT_0trace(LST_debugMask, GT_ENTER, "LST_Create: entered\n");

	pList = (struct LST_LIST *) MEM_Calloc(sizeof(struct LST_LIST),
		MEM_NONPAGED);
	if (pList != NULL) {
		pList->head.next = &pList->head;
		pList->head.prev = &pList->head;
		pList->head.self = NULL;
	}

	return pList;
}
示例#11
0
文件: list.c 项目: zp8001/STUDY_4.0.3
/** ============================================================================
 *  @func   LIST_Create
 *
 *  @desc   Allocates and initializes a circular list.
 *
 *  @modif  None
 *  ============================================================================
 */
EXPORT_API
DSP_STATUS
LIST_Create (OUT List ** list)
{
    DSP_STATUS  status  = DSP_SOK ;
    List *      myList = NULL    ;

    TRC_1ENTER ("LIST_Create", list) ;

    DBC_Require (list != NULL) ;

    if (list == NULL) {
        status = DSP_EINVALIDARG ;
        SET_FAILURE_REASON ;
    }
    else {
        status = MEM_Calloc ((Void **) &myList,
                             sizeof(List),
                             MEM_DEFAULT) ;

        if (DSP_FAILED (status)) {
            status = DSP_EMEMORY ;
            SET_FAILURE_REASON ;
        }
        else {
            DBC_Assert (myList != NULL) ;

            myList->head.next = &(myList->head) ;
            myList->head.prev = &(myList->head) ;

            *list = myList ;
        }
    }

    DBC_Ensure (   (DSP_SUCCEEDED (status) && (*list != NULL))
                || (DSP_FAILED (status))) ;

    TRC_1LEAVE ("LIST_Create", status) ;

    return status ;
}
示例#12
0
/*
 *  ======== COD_Open ========
 *      Open library for reading sections.
 */
DSP_STATUS COD_Open(struct COD_MANAGER *hMgr, IN char *pszCoffPath,
		    COD_FLAGS flags, struct COD_LIBRARYOBJ **pLib)
{
	DSP_STATUS status = DSP_SOK;
	struct COD_LIBRARYOBJ *lib = NULL;

	DBC_Require(cRefs > 0);
	DBC_Require(IsValid(hMgr));
	DBC_Require(pszCoffPath != NULL);
	DBC_Require(flags == COD_NOLOAD || flags == COD_SYMB);
	DBC_Require(pLib != NULL);

	GT_4trace(COD_debugMask, GT_ENTER, "Entered COD_Open, hMgr: 0x%x\n\t "
		  "pszCoffPath:  0x%x\tflags: 0x%x\tlib: 0x%x\n", hMgr,
		  pszCoffPath, flags, pLib);

	*pLib = NULL;

	lib = MEM_Calloc(sizeof(struct COD_LIBRARYOBJ), MEM_NONPAGED);
	if (lib == NULL) {
		GT_0trace(COD_debugMask, GT_7CLASS,
			 "COD_Open: Out Of Memory\n");
		status = DSP_EMEMORY;
	}

	if (DSP_SUCCEEDED(status)) {
		lib->hCodMgr = hMgr;
		status = hMgr->fxns.openFxn(hMgr->target, pszCoffPath, flags,
					   &lib->dbllLib);
		if (DSP_FAILED(status)) {
			GT_1trace(COD_debugMask, GT_7CLASS,
				 "COD_Open failed: 0x%x\n", status);
		} else {
			*pLib = lib;
		}
	}

	return status;
}
示例#13
0
/*
 * ======== PROCWRAP_GetTrace ========
 */
u32 PROCWRAP_GetTrace(union Trapped_Args *args, void *pr_ctxt)
{
	DSP_STATUS status;
	u8 *pBuf;

	GT_0trace(WCD_debugMask, GT_ENTER, "PROCWRAP_GetTrace: entered\n");

	DBC_Require(args->ARGS_PROC_GETTRACE.uMaxSize <= MAX_TRACEBUFLEN);

	pBuf = MEM_Calloc(args->ARGS_PROC_GETTRACE.uMaxSize, MEM_NONPAGED);
	if (pBuf != NULL) {
		status = PROC_GetTrace(args->ARGS_PROC_GETTRACE.hProcessor,
				      pBuf, args->ARGS_PROC_GETTRACE.uMaxSize);
	} else {
		status = DSP_EMEMORY;
	}
	cp_to_usr(args->ARGS_PROC_GETTRACE.pBuf, pBuf, status,
		 args->ARGS_PROC_GETTRACE.uMaxSize);
	if (pBuf)
		MEM_Free(pBuf);

	return status;
}
/* This function is called when an application opens a handle to the
 * bridge driver. */
static int bridge_open(struct inode *ip, struct file *filp)
{
	int status = 0;
	struct PROCESS_CONTEXT *pr_ctxt = NULL;

#ifdef CONFIG_BRIDGE_RECOVERY
	if (recover)
		wait_for_completion(&bridge_open_comp);
#endif

	/*
	 * Allocate a new process context and insert it into global
	 * process context list.
	 */
	pr_ctxt = MEM_Calloc(sizeof(struct PROCESS_CONTEXT), MEM_PAGED);
	if (pr_ctxt) {
		pr_ctxt->resState = PROC_RES_ALLOCATED;
		spin_lock_init(&pr_ctxt->dmm_map_lock);
		INIT_LIST_HEAD(&pr_ctxt->dmm_map_list);
		spin_lock_init(&pr_ctxt->dmm_rsv_lock);
		INIT_LIST_HEAD(&pr_ctxt->dmm_rsv_list);
		mutex_init(&pr_ctxt->node_mutex);
		mutex_init(&pr_ctxt->strm_mutex);
	} else {
		status = -ENOMEM;
	}

	filp->private_data = pr_ctxt;

#ifdef CONFIG_BRIDGE_RECOVERY
	if (!status)
		atomic_inc(&bridge_cref);
#endif

	return status;
}
示例#15
0
/*
 *  ======== COD_Create ========
 *  Purpose:
 *      Create an object to manage code on a DSP system.
 *      This object can be used to load an initial program image with
 *      arguments that can later be expanded with
 *      dynamically loaded object files.
 *
 */
DSP_STATUS COD_Create(OUT struct COD_MANAGER **phMgr, char *pstrDummyFile,
		     IN OPTIONAL CONST struct COD_ATTRS *attrs)
{
	struct COD_MANAGER *hMgrNew;
	struct DBLL_Attrs zlAttrs;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(cRefs > 0);
	DBC_Require(phMgr != NULL);

	GT_3trace(COD_debugMask, GT_ENTER,
		  "Entered COD_Create, Args: \t\nphMgr: "
		  "0x%x\t\npstrDummyFile: 0x%x\t\nattr: 0x%x\n",
		  phMgr, pstrDummyFile, attrs);
	/* assume failure */
	*phMgr = NULL;

	/* we don't support non-default attrs yet */
	if (attrs != NULL)
		return DSP_ENOTIMPL;

	hMgrNew = MEM_Calloc(sizeof(struct COD_MANAGER), MEM_NONPAGED);
	if (hMgrNew == NULL) {
		GT_0trace(COD_debugMask, GT_7CLASS,
			  "COD_Create: Out Of Memory\n");
		return DSP_EMEMORY;
	}

	hMgrNew->ulMagic = MAGIC;

	/* Set up loader functions */
	hMgrNew->fxns = dbllFxns;

	/* initialize the ZL module */
	hMgrNew->fxns.initFxn();

	zlAttrs.alloc = (DBLL_AllocFxn)NoOp;
	zlAttrs.free = (DBLL_FreeFxn)NoOp;
	zlAttrs.fread = (DBLL_ReadFxn)COD_fRead;
	zlAttrs.fseek = (DBLL_SeekFxn)COD_fSeek;
	zlAttrs.ftell = (DBLL_TellFxn)COD_fTell;
	zlAttrs.fclose = (DBLL_FCloseFxn)COD_fClose;
	zlAttrs.fopen = (DBLL_FOpenFxn)COD_fOpen;
	zlAttrs.symLookup = NULL;
	zlAttrs.baseImage = true;
	zlAttrs.logWrite = NULL;
	zlAttrs.logWriteHandle = NULL;
	zlAttrs.write = NULL;
	zlAttrs.rmmHandle = NULL;
	zlAttrs.wHandle = NULL;
	zlAttrs.symHandle = NULL;
	zlAttrs.symArg = NULL;

	hMgrNew->attrs = zlAttrs;

	status = hMgrNew->fxns.createFxn(&hMgrNew->target, &zlAttrs);

	if (DSP_FAILED(status)) {
		COD_Delete(hMgrNew);
		GT_1trace(COD_debugMask, GT_7CLASS,
			  "COD_Create:ZL Create Failed: 0x%x\n", status);
		return COD_E_ZLCREATEFAILED;
	}

	/* return the new manager */
	*phMgr = hMgrNew;
	GT_1trace(COD_debugMask, GT_1CLASS,
		  "COD_Create: Success CodMgr: 0x%x\n",	*phMgr);
	return DSP_SOK;
}
示例#16
0
/** ============================================================================
 *  @func   LDRV_getLinkGppCfg
 *
 *  @desc   Gets the pointer to kernel configuration structure after creating
 *          it (if required). Copies only GPP structures.
 *
 *  @modif  None
 *  ============================================================================
 */
NORMAL_API
DSP_STATUS
LDRV_getLinkGppCfg (IN  LINKCFG_Object *  linkCfg,
                    OUT LINKCFG_Object ** knlLinkCfg)
{
    DSP_STATUS       status = DSP_SOK ;
    LINKCFG_Object * knlCfg = NULL ;
    Void *           tmpUsrPtr ;
    Uint32           size ;
    Uint32           procId ;
    Uint32           i      ;

    TRC_2ENTER ("LDRV_getLinkCfg", linkCfg, knlLinkCfg) ;

    DBC_Require (linkCfg    != NULL) ;
    DBC_Require (knlLinkCfg != NULL) ;

    /*  ------------------------------------------------------------------------
     *  Allocate memory for the global LINKCFG object and initialize it.
     *  ------------------------------------------------------------------------
     */
    status = MEM_Calloc ((Void **) knlLinkCfg,
                         sizeof (LINKCFG_Object),
                         MEM_DEFAULT) ;
    if (DSP_SUCCEEDED (status)) {
        knlCfg = *knlLinkCfg ;

        /* Copy the contents of the object from user-space. Return value
         * indicates number of bytes that were not copied.
         */
        status = USER_copyFromUser ((Void *) knlCfg,
                                    (Void *) linkCfg,
                                    sizeof (LINKCFG_Object)) ;
        if (DSP_FAILED (status)) {
            SET_FAILURE_REASON ;
        }
    }
    else {
        SET_FAILURE_REASON ;
    }

    /*  ------------------------------------------------------------------------
     *  Allocate memory required for the GPP object and initialize it.
     *  ------------------------------------------------------------------------
     */
    if (DSP_SUCCEEDED (status)) {
        tmpUsrPtr = (Void *) knlCfg->gppObject ;
        size      = sizeof (LINKCFG_Gpp) ;
        /* Allocate memory for the GPP object. */
        status = MEM_Alloc ((Void **) &(knlCfg->gppObject),
                            size,
                            MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the object from user-space. */
            status = USER_copyFromUser ((Void *) (knlCfg->gppObject),
                                        tmpUsrPtr,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }

    /*  ------------------------------------------------------------------------
     *  Get the DSP Config if available, this ensures that multi-process works,
     *  If values provided at setup are from a process, proc_attach done by some
     *  other process then copy_to_user must pass.
     *  ------------------------------------------------------------------------
     */
    for (procId  = 0 ;
         (procId < MAX_DSPS) && (DSP_SUCCEEDED (status)) ;
         ) {
        status = LDRV_getLinkDspCfg (procId,
                                     knlCfg->dspConfigs [procId],
                                     *knlLinkCfg) ;
        if (DSP_SUCCEEDED(status))
        procId++ ;
    }

    if (DSP_FAILED (status)) {
        /* Free the copied DSP values */
        for (i = 0 ; i < procId ; i++) {
            LDRV_freeLinkDspCfg (i, *knlLinkCfg) ;
        }

        /* Free the GPP value */
        LDRV_freeLinkGppCfg (knlCfg) ;
    }

    TRC_1LEAVE ("LDRV_getLinkGppCfg", status) ;

    return status ;
}
示例#17
0
/** ============================================================================
 *  @func   LDRV_getLinkDspCfg
 *
 *  @desc   Gets the pointer to kernel configuration structure after creating
 *          it (if required). Copies only DSP structures.
 *
 *  @modif  None
 *  ============================================================================
 */
NORMAL_API
DSP_STATUS
LDRV_getLinkDspCfg (IN  ProcessorId         procId,
                    IN  LINKCFG_DspConfig * dspCfg,
                    OUT LINKCFG_Object *    knlLinkCfg)
{
    DSP_STATUS          status        = DSP_SOK ;
    LINKCFG_DspConfig * knlDspCfg     = NULL ;
    LINKCFG_Dsp *       dspObject     = NULL ;
#if !(defined (ONLY_PROC_COMPONENT))
    LINKCFG_LinkDrv *   linkDrvObject = NULL ;
#endif /* if !(defined (ONLY_PROC_COMPONENT)) */
    Void *              tmpUsrPtr ;
    Void *              tmpKnlPtr ;
    Uint32              size ;
    Uint32              tableId ;

    TRC_3ENTER ("LDRV_getLinkDspCfg",procId, dspCfg, knlLinkCfg) ;

    DBC_Require (knlLinkCfg != NULL) ;
    DBC_Require (IS_VALID_PROCID (procId)) ;

    if (DSP_SUCCEEDED (status)) {
        size = sizeof (LINKCFG_DspConfig) ;
        /* Allocate memory for the DSP object. */
        status = MEM_Alloc ((Void **) &(tmpKnlPtr),
                            size,
                            MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the objects from user-space. */
            status = USER_copyFromUser ((Void *) tmpKnlPtr,
                                        (void *) dspCfg,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
            else {
                knlLinkCfg->dspConfigs [procId] = tmpKnlPtr ;
                knlDspCfg = tmpKnlPtr ;
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }

    /*  ------------------------------------------------------------------------
     *  Allocate memory required for the DSP and initialize it.
     *  ------------------------------------------------------------------------
     */
    if (DSP_SUCCEEDED (status)) {
        tmpUsrPtr = knlDspCfg->dspObject ;
        size      = sizeof (LINKCFG_Dsp) ;
        /* Allocate memory for the DSP object. */
        status = MEM_Alloc ((Void **) &(knlDspCfg->dspObject),
                            size,
                            MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the objects from user-space. */
            status = USER_copyFromUser ((Void *) knlDspCfg->dspObject,
                                        (void *) tmpUsrPtr,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
            else {
                dspObject = knlDspCfg->dspObject ;
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }

    /*  ------------------------------------------------------------------------
     *  Allocate memory required for the Link driver object array and initialize
     *  it.
     *  ------------------------------------------------------------------------
     */
#if !(defined (ONLY_PROC_COMPONENT))
    if (DSP_SUCCEEDED (status)) {
        tmpUsrPtr = (Void *) knlDspCfg->linkDrvObjects ;
        size      = sizeof (LINKCFG_LinkDrv) *  knlDspCfg->numDrvs ;
        /* Allocate memory for the Link Driver object array. */
        status = MEM_Alloc ((Void **) &(knlDspCfg->linkDrvObjects),
                            size,
                            MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the objects from user-space. */
            status = USER_copyFromUser ((Void *) (knlDspCfg->linkDrvObjects),
                                        tmpUsrPtr,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
            else {
                linkDrvObject =
                             &knlDspCfg->linkDrvObjects [dspObject->linkDrvId] ;
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }
#endif /* if !(defined (ONLY_PROC_COMPONENT)) */

    /*  ------------------------------------------------------------------------
     *  Allocate memory required for the array of memory tables and initialize
     *  it.
     *  ------------------------------------------------------------------------
     */
    if (DSP_SUCCEEDED (status)) {
        tmpUsrPtr = (Void *) knlDspCfg->memTables ;
        size = sizeof (LINKCFG_MemEntry *) * knlDspCfg->numMemTables ;
        /* Allocate memory for the array of pointers to memory tables. */
        status = MEM_Calloc ((Void **) &(knlDspCfg->memTables),
                             size,
                             MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the array of pointers from user-space. */
            status = USER_copyFromUser ((Void *) (knlDspCfg->memTables),
                                        tmpUsrPtr,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
            else {
                tableId   = knlDspCfg->dspObject->memTableId ;
                tmpUsrPtr = (Void *) knlDspCfg->memTables [tableId] ;
                size =  sizeof (LINKCFG_MemEntry)
                      * knlDspCfg->dspObject->memEntries ;

                /* Allocate memory for the memory table. */
                status = MEM_Alloc ((Void **)
                                    &(knlDspCfg->memTables [tableId]),
                                    size,
                                    MEM_DEFAULT) ;
                if (DSP_SUCCEEDED (status)) {
                    /* Copy the contents of the objects from user-space. */
                    status = USER_copyFromUser (
                                      (Void *) (knlDspCfg->memTables [tableId]),
                                                tmpUsrPtr,
                                                size) ;
                    if (DSP_FAILED (status)) {
                        SET_FAILURE_REASON ;
                    }
                }
                else {
                    SET_FAILURE_REASON ;
                }
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }

#if !(defined (ONLY_PROC_COMPONENT))
    /*  ------------------------------------------------------------------------
     *  Allocate memory required for the array of IPS tables and initialize it.
     *  ------------------------------------------------------------------------
     */
    if (DSP_SUCCEEDED (status)) {
        tmpUsrPtr = (Void *) knlDspCfg->ipsTables ;
        size      = sizeof (LINKCFG_Ips *) * knlDspCfg->numIpsTables ;
        /* Allocate memory for the array of pointers to IPS tables. */
        status = MEM_Calloc ((Void **) &(knlDspCfg->ipsTables),
                             size,
                             MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the array of pointers from user-space. */
            status = USER_copyFromUser ((Void *) (knlDspCfg->ipsTables),
                                        tmpUsrPtr,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
            else {
                tableId   = linkDrvObject->ipsTableId;
                tmpUsrPtr = (Void *) knlDspCfg->ipsTables [tableId] ;
                size =   sizeof (LINKCFG_Ips) * linkDrvObject->numIpsEntries ;

                /* Allocate memory for the IPS table. */
                status = MEM_Alloc ((Void **)
                                    &(knlDspCfg->ipsTables [tableId]),
                                    size,
                                    MEM_DEFAULT) ;
                if (DSP_SUCCEEDED (status)) {
                    /* Copy the contents of the objects from user-space. */
                    status = USER_copyFromUser ((Void *)
                                      (knlDspCfg->ipsTables [tableId]),
                                      tmpUsrPtr,
                                      size) ;
                    if (DSP_FAILED (status)) {
                        SET_FAILURE_REASON ;
                    }
                }
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }

#if defined (POOL_COMPONENT)
    /*  ------------------------------------------------------------------------
     *  Allocate memory required for the array of Pool tables and initialize it.
     *  ------------------------------------------------------------------------
     */
    if (DSP_SUCCEEDED (status)) {
        tmpUsrPtr = (Void *) knlDspCfg->poolTables ;
        size      = sizeof (LINKCFG_Pool *) * knlDspCfg->numPoolTables ;
        /* Allocate memory for the array of pointers to Pool tables. */
        status = MEM_Calloc ((Void **) &(knlDspCfg->poolTables),
                             size,
                             MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the array of pointers from user-space. */
            status = USER_copyFromUser ((Void *) (knlDspCfg->poolTables),
                                        tmpUsrPtr,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
            else {
                tableId = linkDrvObject->poolTableId ;
                tmpUsrPtr = (Void *) knlDspCfg->poolTables [tableId] ;
                size = sizeof (LINKCFG_Pool) * linkDrvObject->numPools ;

                /* Allocate memory for the Pool table. */
                status = MEM_Alloc ((Void **)
                                   &(knlDspCfg->poolTables [tableId]),
                                   size,
                                   MEM_DEFAULT) ;
                if (DSP_SUCCEEDED (status)) {
                    /* Copy the contents of the objects from user-space. */
                    status = USER_copyFromUser (
                                     (Void *) (knlDspCfg->poolTables [tableId]),
                                     tmpUsrPtr,
                                     size) ;
                    if (DSP_FAILED (status)) {
                        SET_FAILURE_REASON ;
                    }
                }
                else {
                    SET_FAILURE_REASON ;
                }
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }
#endif /* if defined (POOL_COMPONENT) */

#if defined (CHNL_COMPONENT)
    /*  ------------------------------------------------------------------------
     *  Allocate memory required for the array of Data driver tables and
     *  initialize it.
     *  ------------------------------------------------------------------------
     */
    if (DSP_SUCCEEDED (status)) {
        tmpUsrPtr = (Void *) knlDspCfg->dataTables ;
        size = sizeof (LINKCFG_DataDrv *) * knlDspCfg->numDataTables ;
        /* Allocate memory for the array of pointers to Data driver tables. */
        status = MEM_Calloc ((Void **) &(knlDspCfg->dataTables),
                             size,
                             MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the array of pointers from user-space. */
            status = USER_copyFromUser ((Void *) (knlDspCfg->dataTables),
                                        tmpUsrPtr,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
            else {
                tableId = linkDrvObject->dataTableId ;
                tmpUsrPtr = (Void *) knlDspCfg->dataTables [tableId] ;
                size =  sizeof (LINKCFG_DataDrv)
                      * linkDrvObject->numDataDrivers ;

                /* Allocate memory for the Data driver table. */
                status = MEM_Alloc ((Void **)
                                   &(knlDspCfg->dataTables [tableId]),
                                   size,
                                   MEM_DEFAULT) ;
                if (DSP_SUCCEEDED (status)) {
                    /* Copy the contents of the objects from user-space. */
                    status = USER_copyFromUser (
                                     (Void *) (knlDspCfg->dataTables [tableId]),
                                     tmpUsrPtr,
                                     size) ;
                    if (DSP_FAILED (status)) {
                        SET_FAILURE_REASON ;
                    }
                }
                else {
                    SET_FAILURE_REASON ;
                }
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }
#endif /* if defined (CHNL_COMPONENT) */

#if defined (MSGQ_COMPONENT)
    /*  ------------------------------------------------------------------------
     *  Allocate memory required for the MQT object array and initialize it.
     *  ------------------------------------------------------------------------
     */
    if (DSP_SUCCEEDED (status)) {
        tmpUsrPtr = (Void *) knlDspCfg->mqtObjects ;
        size      = sizeof (LINKCFG_Mqt) * knlDspCfg->numMqts ;
        /* Allocate memory for the MQT object array. */
        status = MEM_Alloc ((Void **) &(knlDspCfg->mqtObjects),
                            size,
                            MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the objects from user-space. */
            status = USER_copyFromUser ((Void *) (knlDspCfg->mqtObjects),
                                        tmpUsrPtr,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }
#endif /* if defined (MSGQ_COMPONENT) */

#if defined (RINGIO_COMPONENT)
    /*  ------------------------------------------------------------------------
     *  Allocate memory required for the RingIO object array and initialize it.
     *  ------------------------------------------------------------------------
     */
    if (DSP_SUCCEEDED (status)) {
        tmpUsrPtr = (Void *) knlDspCfg->ringIoObjects ;
        size      = sizeof (LINKCFG_RingIo) * knlDspCfg->numRingIo ;
        /* Allocate memory for the RingIO object array. */
        status = MEM_Alloc ((Void **) &(knlDspCfg->ringIoObjects),
                            size,
                            MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the objects from user-space. */
            status = USER_copyFromUser ((Void *)(knlDspCfg->ringIoObjects),
                                        tmpUsrPtr,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }
#endif /* if defined (RINGIO_COMPONENT) */

#if defined (MPLIST_COMPONENT)
    /*  ------------------------------------------------------------------------
     *  Allocate memory required for the MPLIST object array and initialize it.
     *  ------------------------------------------------------------------------
     */
    if (DSP_SUCCEEDED (status)) {
        tmpUsrPtr = (Void *) knlDspCfg->mplistObjects ;
        size      = sizeof (LINKCFG_MpList) * knlDspCfg->numMpList ;
        /* Allocate memory for the MPLIST object array. */
        status = MEM_Alloc ((Void **) &(knlDspCfg->mplistObjects),
                            size,
                            MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the objects from user-space. */
            status = USER_copyFromUser ((Void *)(knlDspCfg->mplistObjects),
                                        tmpUsrPtr,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }
#endif /* if defined (MPLIST_COMPONENT) */

#if defined (MPCS_COMPONENT)
    /*  ------------------------------------------------------------------------
     *  Allocate memory required for the MPCS object array and initialize it.
     *  ------------------------------------------------------------------------
     */
    if (DSP_SUCCEEDED (status)) {
        tmpUsrPtr = (Void *) knlDspCfg->mpcsObjects ;
        size      = sizeof (LINKCFG_Mpcs) * knlDspCfg->numMpcs ;
        /* Allocate memory for the MPCS object array. */
        status = MEM_Alloc ((Void **) &(knlDspCfg->mpcsObjects),
                            size,
                            MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the objects from user-space. */
            status = USER_copyFromUser ((Void *) (knlDspCfg->mpcsObjects),
                                        tmpUsrPtr,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }
#endif /* if defined (MPCS_COMPONENT) */

#if defined (LOG_COMPONENT)
    /*  ------------------------------------------------------------------------
     *  Allocate memory required for the LOG object and initialize it.
     *  ------------------------------------------------------------------------
     */
    if (DSP_SUCCEEDED (status)) {
        tmpUsrPtr = (Void *) knlDspCfg->logObject ;
        size      = sizeof (LINKCFG_Log) ;
        /* Allocate memory for the GPP object. */
        status = MEM_Alloc ((Void **) &(knlDspCfg->logObject),
                            size,
                            MEM_DEFAULT) ;
        if (DSP_SUCCEEDED (status)) {
            /* Copy the contents of the object from user-space. */
            status = USER_copyFromUser ((Void *) (knlDspCfg->logObject),
                                        tmpUsrPtr,
                                        size) ;
            if (DSP_FAILED (status)) {
                SET_FAILURE_REASON ;
            }
        }
        else {
            SET_FAILURE_REASON ;
        }
    }
#endif /* if defined (LOG_COMPONENT) */
#endif /* if !(defined (ONLY_PROC_COMPONENT)) */

    if (DSP_FAILED (status)) {
        LDRV_freeLinkDspCfg (procId, knlLinkCfg) ;
    }

    TRC_1LEAVE ("LDRV_getLinkDspCfg", status) ;

    return status ;
}
示例#18
0
/*
 *  ======== DBLL_open ========
 */
DSP_STATUS DBLL_open(struct DBLL_TarObj *target, char *file, DBLL_Flags flags,
		    struct DBLL_LibraryObj **pLib)
{
	struct DBLL_TarObj *zlTarget = (struct DBLL_TarObj *)target;
	struct DBLL_LibraryObj *zlLib = NULL;
	s32 err;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(cRefs > 0);
	DBC_Require(MEM_IsValidHandle(zlTarget, DBLL_TARGSIGNATURE));
	DBC_Require(zlTarget->attrs.fopen != NULL);
	DBC_Require(file != NULL);
	DBC_Require(pLib != NULL);

	GT_3trace(DBLL_debugMask, GT_ENTER,
		 "DBLL_open: target: 0x%x file: %s pLib:"
		 " 0x%x\n", target, file, pLib);
	zlLib = zlTarget->head;
	while (zlLib != NULL) {
               if (strcmp(zlLib->fileName, file) == 0) {
			/* Library is already opened */
			zlLib->openRef++;
			break;
		}
		zlLib = zlLib->next;
	}
	if (zlLib == NULL) {
		/* Allocate DBL library object */
		MEM_AllocObject(zlLib, struct DBLL_LibraryObj,
				DBLL_LIBSIGNATURE);
		if (zlLib == NULL) {
			GT_0trace(DBLL_debugMask, GT_6CLASS,
				 "DBLL_open: Memory allocation failed\n");
			status = DSP_EMEMORY;
		} else {
			zlLib->ulPos = 0;
			/* Increment ref count to allow close on failure
			 * later on */
			zlLib->openRef++;
			zlLib->pTarget = zlTarget;
			/* Keep a copy of the file name */
                       zlLib->fileName = MEM_Calloc(strlen(file) + 1,
							MEM_PAGED);
			if (zlLib->fileName == NULL) {
				GT_0trace(DBLL_debugMask, GT_6CLASS,
					 "DBLL_open: Memory "
					 "allocation failed\n");
				status = DSP_EMEMORY;
			} else {
                               strncpy(zlLib->fileName, file,
                                          strlen(file) + 1);
			}
			zlLib->symTab = NULL;
		}
	}
	/*
	 *  Set up objects needed by the dynamic loader
	 */
	if (DSP_FAILED(status))
		goto func_cont;

	/* Stream */
	zlLib->stream.dlStream.read_buffer = readBuffer;
	zlLib->stream.dlStream.set_file_posn = setFilePosn;
	zlLib->stream.lib = zlLib;
	/* Symbol */
	zlLib->symbol.dlSymbol.Add_To_Symbol_Table = addToSymbolTable;
	zlLib->symbol.dlSymbol.Find_Matching_Symbol = findSymbol;
	zlLib->symbol.dlSymbol.Purge_Symbol_Table = purgeSymbolTable;
	zlLib->symbol.dlSymbol.Allocate = allocate;
	zlLib->symbol.dlSymbol.Deallocate = deallocate;
	zlLib->symbol.dlSymbol.Error_Report = errorReport;
	zlLib->symbol.lib = zlLib;
	/* Allocate */
	zlLib->allocate.dlAlloc.Allocate = rmmAlloc;
	zlLib->allocate.dlAlloc.Deallocate = rmmDealloc;
	zlLib->allocate.lib = zlLib;
	/* Init */
	zlLib->init.dlInit.connect = connect;
	zlLib->init.dlInit.readmem = readMem;
	zlLib->init.dlInit.writemem = writeMem;
	zlLib->init.dlInit.fillmem = fillMem;
	zlLib->init.dlInit.execute = execute;
	zlLib->init.dlInit.release = release;
	zlLib->init.lib = zlLib;
	if (DSP_SUCCEEDED(status) && zlLib->fp == NULL)
		status = dofOpen(zlLib);

	zlLib->ulPos = (*(zlLib->pTarget->attrs.ftell)) (zlLib->fp);
	(*(zlLib->pTarget->attrs.fseek))(zlLib->fp, (long) 0, SEEK_SET);
	/* Create a hash table for symbols if flag is set */
	if (zlLib->symTab != NULL || !(flags & DBLL_SYMB))
		goto func_cont;

	zlLib->symTab = GH_create(MAXBUCKETS, sizeof(struct Symbol), nameHash,
				 nameMatch, symDelete);
	if (zlLib->symTab == NULL) {
		status = DSP_EMEMORY;
	} else {
		/* Do a fake load to get symbols - set write function to NoOp */
		zlLib->init.dlInit.writemem = NoOp;
		err = Dynamic_Open_Module(&zlLib->stream.dlStream,
					&zlLib->symbol.dlSymbol,
					&zlLib->allocate.dlAlloc,
					&zlLib->init.dlInit, 0,
					&zlLib->mHandle);
		if (err != 0) {
			GT_1trace(DBLL_debugMask, GT_6CLASS, "DBLL_open: "
				 "Dynamic_Load_Module failed: 0x%lx\n", err);
			status = DSP_EDYNLOAD;
		} else {
			/* Now that we have the symbol table, we can unload */
			err = Dynamic_Unload_Module(zlLib->mHandle,
						   &zlLib->symbol.dlSymbol,
						   &zlLib->allocate.dlAlloc,
						   &zlLib->init.dlInit);
			if (err != 0) {
				GT_1trace(DBLL_debugMask, GT_6CLASS,
					"DBLL_open: "
					"Dynamic_Unload_Module failed: 0x%lx\n",
					err);
				status = DSP_EDYNLOAD;
			}
			zlLib->mHandle = NULL;
		}
	}
func_cont:
	if (DSP_SUCCEEDED(status)) {
		if (zlLib->openRef == 1) {
			/* First time opened - insert in list */
			if (zlTarget->head)
				(zlTarget->head)->prev = zlLib;

			zlLib->prev = NULL;
			zlLib->next = zlTarget->head;
			zlTarget->head = zlLib;
		}
		*pLib = (struct DBLL_LibraryObj *)zlLib;
	} else {
		*pLib = NULL;
		if (zlLib != NULL)
			DBLL_close((struct DBLL_LibraryObj *)zlLib);

	}
	DBC_Ensure((DSP_SUCCEEDED(status) && (zlLib->openRef > 0) &&
		  MEM_IsValidHandle(((struct DBLL_LibraryObj *)(*pLib)),
		  DBLL_LIBSIGNATURE)) || (DSP_FAILED(status) && *pLib == NULL));
	return status;
}
示例#19
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;
}
示例#20
0
/*
 *  ======== RMM_create ========
 */
DSP_STATUS RMM_create(struct RMM_TargetObj **pTarget,
		     struct RMM_Segment segTab[], u32 numSegs)
{
	struct RMM_Header *hptr;
	struct RMM_Segment *sptr, *tmp;
	struct RMM_TargetObj *target;
	s32 i;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(pTarget != NULL);
	DBC_Require(numSegs == 0 || segTab != NULL);

	GT_3trace(RMM_debugMask, GT_ENTER,
		 "RMM_create(0x%lx, 0x%lx, 0x%lx)\n",
		 pTarget, segTab, numSegs);

	/* Allocate DBL target object */
	MEM_AllocObject(target, struct RMM_TargetObj, RMM_TARGSIGNATURE);

	if (target == NULL) {
		GT_0trace(RMM_debugMask, GT_6CLASS,
			 "RMM_create: Memory allocation failed\n");
		status = DSP_EMEMORY;
	}
	if (DSP_FAILED(status))
		goto func_cont;

	target->numSegs = numSegs;
	if (!(numSegs > 0))
		goto func_cont;

	/* Allocate the memory for freelist from host's memory */
	target->freeList = MEM_Calloc(numSegs * sizeof(struct RMM_Header *),
				     MEM_PAGED);
	if (target->freeList == NULL) {
		GT_0trace(RMM_debugMask, GT_6CLASS,
			 "RMM_create: Memory allocation failed\n");
		status = DSP_EMEMORY;
	} else {
		/* Allocate headers for each element on the free list */
		for (i = 0; i < (s32) numSegs; i++) {
			target->freeList[i] =
					MEM_Calloc(sizeof(struct RMM_Header),
					MEM_PAGED);
			if (target->freeList[i] == NULL) {
				GT_0trace(RMM_debugMask, GT_6CLASS,
					 "RMM_create: Memory "
					 "allocation failed\n");
				status = DSP_EMEMORY;
				break;
			}
		}
		/* Allocate memory for initial segment table */
		target->segTab = MEM_Calloc(numSegs *
				 sizeof(struct RMM_Segment), MEM_PAGED);
		if (target->segTab == NULL) {
			GT_0trace(RMM_debugMask, GT_6CLASS,
				 "RMM_create: Memory allocation failed\n");
			status = DSP_EMEMORY;
		} else {
			/* Initialize segment table and free list */
			sptr = target->segTab;
			for (i = 0, tmp = segTab; numSegs > 0; numSegs--, i++) {
				*sptr = *tmp;
				hptr = target->freeList[i];
				hptr->addr = tmp->base;
				hptr->size = tmp->length;
				hptr->next = NULL;
				tmp++;
				sptr++;
			}
		}
	}
func_cont:
	/* Initialize overlay memory list */
	if (DSP_SUCCEEDED(status)) {
		target->ovlyList = LST_Create();
		if (target->ovlyList == NULL) {
			GT_0trace(RMM_debugMask, GT_6CLASS,
				 "RMM_create: Memory allocation failed\n");
			status = DSP_EMEMORY;
		}
	}

	if (DSP_SUCCEEDED(status)) {
		*pTarget = target;
	} else {
		*pTarget = NULL;
		if (target)
			RMM_delete(target);

	}

	DBC_Ensure((DSP_SUCCEEDED(status) && MEM_IsValidHandle((*pTarget),
		  RMM_TARGSIGNATURE)) || (DSP_FAILED(status) && *pTarget ==
		  NULL));

	return status;
}
示例#21
0
/*
 *  ======== WMD_DEH_Notify ========
 *      DEH error notification function. Informs user about the error.
 */
void WMD_DEH_Notify(struct DEH_MGR *hDehMgr, u32 ulEventMask,
			 u32 dwErrInfo)
{
	struct DEH_MGR *pDehMgr = (struct DEH_MGR *)hDehMgr;
	struct WMD_DEV_CONTEXT *pDevContext;
	u32 memPhysical = 0;
	u32 HW_MMU_MAX_TLB_COUNT = 31;
	extern u32 faultAddr;
	u32 cnt = 0;

	if (MEM_IsValidHandle(pDehMgr, SIGNATURE)) {
		printk(KERN_INFO "WMD_DEH_Notify: ********** DEVICE EXCEPTION "
			"**********\n");
		pDevContext = (struct WMD_DEV_CONTEXT *)pDehMgr->hWmdContext;

		switch (ulEventMask) {
		case DSP_SYSERROR:
			/* reset errInfo structure before use */
			pDehMgr->errInfo.dwErrMask = DSP_SYSERROR;
			pDehMgr->errInfo.dwVal1 = 0L;
			pDehMgr->errInfo.dwVal2 = 0L;
			pDehMgr->errInfo.dwVal3 = 0L;
			pDehMgr->errInfo.dwVal1 = dwErrInfo;
			printk(KERN_ERR "WMD_DEH_Notify: DSP_SYSERROR, errInfo "
				"= 0x%x\n", dwErrInfo);

			dump_dl_modules(pDevContext);
			dump_dsp_stack(pDevContext);

			break;
		case DSP_MMUFAULT:
			/* MMU fault routine should have set err info
			 * structure */
			pDehMgr->errInfo.dwErrMask = DSP_MMUFAULT;
			printk(KERN_INFO "WMD_DEH_Notify: DSP_MMUFAULT,"
				"errInfo = 0x%x\n", dwErrInfo);
			printk(KERN_INFO "WMD_DEH_Notify: DSP_MMUFAULT, High "
				"Address = 0x%x\n",
				(unsigned int)pDehMgr->errInfo.dwVal1);
			printk(KERN_INFO "WMD_DEH_Notify: DSP_MMUFAULT, Low "
				"Address = 0x%x\n",
				(unsigned int)pDehMgr->errInfo.dwVal2);
			printk(KERN_INFO "WMD_DEH_Notify: DSP_MMUFAULT, fault "
				"address = 0x%x\n", (unsigned int)faultAddr);

			PrintDspTraceBuffer(pDevContext);
			dump_dl_modules(pDevContext);

			dummyVaAddr = (u32)MEM_Calloc(sizeof(char) * 0x1000,
					MEM_PAGED);
			memPhysical  = VirtToPhys(PG_ALIGN_LOW((u32)dummyVaAddr,
								PG_SIZE_4K));
			pDevContext = (struct WMD_DEV_CONTEXT *)
						pDehMgr->hWmdContext;
			/* Reset the dynamic mmu index to fixed count if it
			 * exceeds 31. So that the dynmmuindex is always
			 * between the range of standard/fixed entries
			 * and 31.  */
			if (pDevContext->numTLBEntries >
			   HW_MMU_MAX_TLB_COUNT) {
				pDevContext->numTLBEntries = pDevContext->
					fixedTLBEntries;
			}

			HW_MMU_TLBAdd(pDevContext->dwDSPMmuBase,
				memPhysical, faultAddr, HW_PAGE_SIZE_4KB, 1,
				&mapAttrs, HW_SET, HW_SET);
			/*
			 * Send a GP Timer interrupt to DSP
			 * The DSP expects a GP timer interrupt after an
			 * MMU-Fault Request GPTimer
			 */
			if (timer) {
				omap_dm_timer_enable(timer);
				/* Enable overflow interrupt */
				omap_dm_timer_set_int_enable(timer,
						GPTIMER_IRQ_OVERFLOW);
				/*
				 * Set counter value to overflow counter after
				 * one tick and start timer
				 */
				omap_dm_timer_set_load_start(timer, 0,
							0xfffffffe);

				/* Wait 80us for timer to overflow */
				udelay(80);

				/* Check interrupt status and */
				/* wait for interrupt */
				cnt = 0;
				while (!(omap_dm_timer_read_status(timer) &
					GPTIMER_IRQ_OVERFLOW)) {
					if (cnt++ >=
						GPTIMER_IRQ_WAIT_MAX_CNT) {
						pr_err("%s: GPTimer interrupt"
							" failed\n", __func__);
						break;
					}
				}
			}

			/* Clear MMU interrupt */
			HW_MMU_EventAck(pDevContext->dwDSPMmuBase,
					 HW_MMU_TRANSLATION_FAULT);

			dump_dsp_stack(hDehMgr->hWmdContext);
			if (timer)
				omap_dm_timer_disable(timer);
			break;
#ifdef CONFIG_BRIDGE_NTFY_PWRERR
		case DSP_PWRERROR:
			/* reset errInfo structure before use */
			pDehMgr->errInfo.dwErrMask = DSP_PWRERROR;
			pDehMgr->errInfo.dwVal1 = 0L;
			pDehMgr->errInfo.dwVal2 = 0L;
			pDehMgr->errInfo.dwVal3 = 0L;
			pDehMgr->errInfo.dwVal1 = dwErrInfo;
			printk(KERN_ERR "WMD_DEH_Notify: DSP_PWRERROR, errInfo "
					"= 0x%x\n", dwErrInfo);
			break;
#endif /* CONFIG_BRIDGE_NTFY_PWRERR */
#ifdef CONFIG_BRIDGE_WDT3
		case DSP_WDTOVERFLOW:
			pDehMgr->errInfo.dwErrMask = DSP_WDTOVERFLOW;
			pDehMgr->errInfo.dwVal1 = 0L;
			pDehMgr->errInfo.dwVal2 = 0L;
			pDehMgr->errInfo.dwVal3 = 0L;
			pr_err("WMD_DEH_Notify: DSP_WDTOVERFLOW \n ");
			break;
#endif
		default:
			DBG_Trace(DBG_LEVEL6,
				 "WMD_DEH_Notify: Unknown Error, errInfo = "
				 "0x%x\n", dwErrInfo);
			break;
		}

		/* Filter subsequent notifications when an error occurs */
		if (pDevContext->dwBrdState != BRD_ERROR) {
			NTFY_Notify(pDehMgr->hNtfy, ulEventMask);
#ifdef CONFIG_BRIDGE_RECOVERY
			bridge_recover_schedule();
#endif
		}

		/* Set the Board state as ERROR */
		pDevContext->dwBrdState = BRD_ERROR;
		/* Disable all the clocks that were enabled by DSP */
		(void)DSP_PeripheralClocks_Disable(pDevContext, NULL);
#ifdef CONFIG_BRIDGE_WDT3
		/*
		 * Avoid the subsequent WDT if it happens once,
		 * also If MMU fault occurs
		 */
		dsp_wdt_enable(false);
#endif

	}
}
示例#22
0
文件: ntfy.c 项目: ka6sox/nook_kernel
/*
 *  ======== NTFY_Register ========
 *  Purpose:
 *      Add a notification element to the list. If the notification is already
 *      registered, and uEventMask != 0, the notification will get posted for
 *      events specified in the new event mask. If the notification is already
 *      registered and uEventMask == 0, the notification will be unregistered.
 */
DSP_STATUS NTFY_Register(struct NTFY_OBJECT *hNtfy,
			 struct DSP_NOTIFICATION *hNotification,
			 u32 uEventMask, u32 uNotifyType)
{
	struct NOTIFICATION *pNotify;
	struct SYNC_ATTRS syncAttrs;
	DSP_STATUS status = DSP_SOK;

	DBC_Require(MEM_IsValidHandle(hNtfy, NTFY_SIGNATURE));

	if (hNotification == NULL)
		status = DSP_EHANDLE;

	/* Return DSP_ENOTIMPL if uNotifyType is not supported */
	if (DSP_SUCCEEDED(status)) {
		if (!IsValidNotifyMask(uNotifyType))
			status = DSP_ENOTIMPL;

	}

	if (DSP_FAILED(status))
		return status;

	(void)SYNC_EnterCS(hNtfy->hSync);

	pNotify = (struct NOTIFICATION *)LST_First(hNtfy->notifyList);
	while (pNotify != NULL) {
		/* If there is more than one notification type, each
		 * type may require its own handler code.  */

		if (hNotification->handle == pNotify->hSync) {
			/* found */
			break;
		}
		pNotify = (struct NOTIFICATION *)LST_Next(hNtfy->notifyList,
			  (struct list_head *)pNotify);
	}
	if (pNotify == NULL) {
		/* Not registered */
		if (uEventMask == 0) {
			status = DSP_EVALUE;
		} else {
			/* Allocate NOTIFICATION object, add to list */
			pNotify = MEM_Calloc(sizeof(struct NOTIFICATION),
					     MEM_PAGED);
			if (pNotify == NULL)
				status = DSP_EMEMORY;

		}
		if (DSP_SUCCEEDED(status)) {
			LST_InitElem((struct list_head *)pNotify);
			 /* If there is more than one notification type, each
			 * type may require its own handler code. */
			status = SYNC_OpenEvent(&pNotify->hSync, &syncAttrs);
			hNotification->handle = pNotify->hSync;

			if (DSP_SUCCEEDED(status)) {
				pNotify->uEventMask = uEventMask;
				pNotify->uNotifyType = uNotifyType;
				LST_PutTail(hNtfy->notifyList,
					   (struct list_head *)pNotify);
			} else {
				DeleteNotify(pNotify);
			}
		}
	} else {
		/* Found in list */
		if (uEventMask == 0) {
			/* Remove from list and free */
			LST_RemoveElem(hNtfy->notifyList,
				      (struct list_head *)pNotify);
			DeleteNotify(pNotify);
		} else {
			/* Update notification mask (type shouldn't change) */
			pNotify->uEventMask = uEventMask;
		}
	}
	(void)SYNC_LeaveCS(hNtfy->hSync);
	return status;
}