⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xemacps_bdring.c

📁 自学ZedBoard:使用IP通过ARM PS访问FPGA(源代码)
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: xemacps_bdring.c,v 1.1.2.1 2011/01/20 03:39:02 sadanan Exp $ *//******************************************************************************** (c) Copyright 2010 Xilinx, Inc. All rights reserved.** This file contains confidential and proprietary information of Xilinx, Inc.* and is protected under U.S. and international copyright and other* intellectual property laws.** DISCLAIMER* This disclaimer is not a license and does not grant any rights to the* materials distributed herewith. Except as otherwise provided in a valid* license issued to you by Xilinx, and to the maximum extent permitted by* applicable law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND WITH ALL* FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, EXPRESS,* IMPLIED, OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF* MERCHANTABILITY, NON-INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE;* and (2) Xilinx shall not be liable (whether in contract or tort, including* negligence, or under any other theory of liability) for any loss or damage* of any kind or nature related to, arising under or in connection with these* materials, including for any direct, or any indirect, special, incidental,* or consequential loss or damage (including loss of data, profits, goodwill,* or any type of loss or damage suffered as a result of any action brought by* a third party) even if such damage or loss was reasonably foreseeable or* Xilinx had been advised of the possibility of the same.** CRITICAL APPLICATIONS* Xilinx products are not designed or intended to be fail-safe, or for use in* any application requiring fail-safe performance, such as life-support or* safety devices or systems, Class III medical devices, nuclear facilities,* applications related to the deployment of airbags, or any other applications* that could lead to death, personal injury, or severe property or* environmental damage (individually and collectively, "Critical* Applications"). Customer assumes the sole risk and liability of any use of* Xilinx products in Critical Applications, subject only to applicable laws* and regulations governing limitations on product liability.** THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS PART OF THIS FILE* AT ALL TIMES.*******************************************************************************//*****************************************************************************//**** @file xemacps_bdring.c** This file implements buffer descriptor ring related functions.** <pre>* MODIFICATION HISTORY:** Ver   Who  Date     Changes* ----- ---- -------- -------------------------------------------------------* 1.00a wsy  01/10/10 First release* 1.00a asa  11/21/11 The function XEmacPs_BdRingFromHwTx is modified.*		      Earlier it used to search in "BdLimit" number of BDs to*		      know which BDs are processed. Now one more check is*		      added. It looks for BDs till the current BD pointer*		      reaches HwTail. By doing this processing time is saved.* 1.00a asa  01/24/12 The function XEmacPs_BdRingFromHwTx in file*		      xemacps_bdring.c is modified. Now start of packet is*		      searched for returning the number of BDs processed.* </pre>******************************************************************************//***************************** Include Files *********************************/#include "xstatus.h"#include "xil_cache.h"#include "xemacps_hw.h"#include "xemacps_bd.h"#include "xemacps_bdring.h"/************************** Constant Definitions *****************************//**************************** Type Definitions *******************************//***************** Macros (Inline Functions) Definitions *********************//**************************************************************************** * Define methods to flush and invalidate cache for BDs should they be * located in cached memory. These macros may NOPs if the underlying * XENV_BD_CACHE macros are not implemented or they do nothing. * * @note Assume cache line size is in word length. Please update accordingly *       for different system. ****************************************************************************/#define XENV_BD_CACHE_FLUSH#define XENV_BD_CACHE_INVALIDATE#ifdef XENV_BD_CACHE_FLUSH#  define XEMACPS_CACHE_FLUSH(BdPtr)               \      Xil_DCacheFlushRange((unsigned)BdPtr, XEMACPS_BD_NUM_WORDS * 4)#else#  define XEMACPS_CACHE_FLUSH(BdPtr)#endif#ifdef XENV_BD_CACHE_INVALIDATE#  define XEMACPS_CACHE_INVALIDATE(BdPtr)          \      Xil_DCacheInvalidateRange((unsigned)BdPtr, XEMACPS_BD_NUM_WORDS * 4)#else#  define XEMACPS_CACHE_INVALIDATE(BdPtr)#endif/**************************************************************************** * Compute the virtual address of a descriptor from its physical address * * @param BdPtr is the physical address of the BD * * @returns Virtual address of BdPtr * * @note Assume BdPtr is always a valid BD in the ring ****************************************************************************/#define XEMACPS_PHYS_TO_VIRT(BdPtr) \    ((u32)BdPtr + (RingPtr->BaseBdAddr - RingPtr->PhysBaseAddr))/**************************************************************************** * Compute the physical address of a descriptor from its virtual address * * @param BdPtr is the physical address of the BD * * @returns Physical address of BdPtr * * @note Assume BdPtr is always a valid BD in the ring ****************************************************************************/#define XEMACPS_VIRT_TO_PHYS(BdPtr) \    ((u32)BdPtr - (RingPtr->BaseBdAddr - RingPtr->PhysBaseAddr))/**************************************************************************** * Move the BdPtr argument ahead an arbitrary number of BDs wrapping around * to the beginning of the ring if needed. * * We know if a wrapaound should occur if the new BdPtr is greater than * the high address in the ring OR if the new BdPtr crosses over the * 0xFFFFFFFF to 0 boundary. The latter test is a valid one since we do not * allow a BD space to span this boundary. * * @param RingPtr is the ring BdPtr appears in * @param BdPtr on input is the starting BD position and on output is the *        final BD position * @param NumBd is the number of BD spaces to increment * ****************************************************************************/#define XEMACPS_RING_SEEKAHEAD(RingPtr, BdPtr, NumBd)                  \    {                                                                   \        u32 Addr = (u32)BdPtr;                                  \                                                                        \        Addr += ((RingPtr)->Separation * NumBd);                        \        if ((Addr > (RingPtr)->HighBdAddr) || ((u32)BdPtr > Addr))  \        {                                                               \            Addr -= (RingPtr)->Length;                                  \        }                                                               \                                                                        \        BdPtr = (XEmacPs_Bd*)Addr;                                     \    }/**************************************************************************** * Move the BdPtr argument backwards an arbitrary number of BDs wrapping * around to the end of the ring if needed. * * We know if a wrapaound should occur if the new BdPtr is less than * the base address in the ring OR if the new BdPtr crosses over the * 0xFFFFFFFF to 0 boundary. The latter test is a valid one since we do not * allow a BD space to span this boundary. * * @param RingPtr is the ring BdPtr appears in * @param BdPtr on input is the starting BD position and on output is the *        final BD position * @param NumBd is the number of BD spaces to increment * ****************************************************************************/#define XEMACPS_RING_SEEKBACK(RingPtr, BdPtr, NumBd)                   \    {                                                                   \        u32 Addr = (u32)BdPtr;                                  \                                                                        \        Addr -= ((RingPtr)->Separation * NumBd);                        \        if ((Addr < (RingPtr)->BaseBdAddr) || ((u32)BdPtr < Addr))  \        {                                                               \            Addr += (RingPtr)->Length;                                  \        }                                                               \                                                                        \        BdPtr = (XEmacPs_Bd*)Addr;                                     \    }/************************** Function Prototypes ******************************//************************** Variable Definitions *****************************//*****************************************************************************//** * Using a memory segment allocated by the caller, create and setup the BD list * for the given DMA channel. * * @param RingPtr is the instance to be worked on. * @param PhysAddr is the physical base address of user memory region. * @param VirtAddr is the virtual base address of the user memory region. If *        address translation is not being utilized, then VirtAddr should be *        equivalent to PhysAddr. * @param Alignment governs the byte alignment of individual BDs. This function *        will enforce a minimum alignment of 4 bytes with no maximum as long *        as it is specified as a power of 2. * @param BdCount is the number of BDs to setup in the user memory region. It *        is assumed the region is large enough to contain the BDs. * * @return * * - XST_SUCCESS if initialization was successful * - XST_NO_FEATURE if the provided instance is a non DMA type *   channel. * - XST_INVALID_PARAM under any of the following conditions: *   1) PhysAddr and/or VirtAddr are not aligned to the given Alignment *      parameter; *   2) Alignment parameter does not meet minimum requirements or is not a *      power of 2 value; *   3) BdCount is 0. * - XST_DMA_SG_LIST_ERROR if the memory segment containing the list spans *   over address 0x00000000 in virtual address space. * * @note * Make sure to pass in the right alignment value. *****************************************************************************/int XEmacPs_BdRingCreate(XEmacPs_BdRing * RingPtr, u32 PhysAddr,			  u32 VirtAddr, u32 Alignment, unsigned BdCount){	unsigned i;	u32 BdVirtAddr;	u32 BdPhyAddr;	/* In case there is a failure prior to creating list, make sure the	 * following attributes are 0 to prevent calls to other functions	 * from doing anything.	 */	RingPtr->AllCnt = 0;	RingPtr->FreeCnt = 0;	RingPtr->HwCnt = 0;	RingPtr->PreCnt = 0;	RingPtr->PostCnt = 0;	/* Make sure Alignment parameter meets minimum requirements */	if (Alignment < XEMACPS_DMABD_MINIMUM_ALIGNMENT) {		return (XST_INVALID_PARAM);	}	/* Make sure Alignment is a power of 2 */	if ((Alignment - 1) & Alignment) {		return (XST_INVALID_PARAM);	}	/* Make sure PhysAddr and VirtAddr are on same Alignment */	if ((PhysAddr % Alignment) || (VirtAddr % Alignment)) {		return (XST_INVALID_PARAM);	}	/* Is BdCount reasonable? */	if (BdCount == 0) {		return (XST_INVALID_PARAM);	}	/* Figure out how many bytes will be between the start of adjacent BDs */	RingPtr->Separation =		(sizeof(XEmacPs_Bd) + (Alignment - 1)) & ~(Alignment - 1);	/* Must make sure the ring doesn't span address 0x00000000. If it does,	 * then the next/prev BD traversal macros will fail.	 */	if (VirtAddr > (VirtAddr + (RingPtr->Separation * BdCount) - 1)) {		return (XST_DMA_SG_LIST_ERROR);	}	/* Initial ring setup:	 *  - Clear the entire space	 *  - Setup each BD's BDA field with the physical address of the next BD	 */	memset((void *) VirtAddr, 0, (RingPtr->Separation * BdCount));	BdVirtAddr = VirtAddr;	BdPhyAddr = PhysAddr + RingPtr->Separation;	for (i = 1; i < BdCount; i++) {		XEMACPS_CACHE_FLUSH(BdVirtAddr);		BdVirtAddr += RingPtr->Separation;		BdPhyAddr += RingPtr->Separation;	}	/* Setup and initialize pointers and counters */	RingPtr->RunState = XST_DMA_SG_IS_STOPPED;	RingPtr->BaseBdAddr = VirtAddr;	RingPtr->PhysBaseAddr = PhysAddr;	RingPtr->HighBdAddr = BdVirtAddr;	RingPtr->Length =		RingPtr->HighBdAddr - RingPtr->BaseBdAddr + RingPtr->Separation;	RingPtr->AllCnt = BdCount;	RingPtr->FreeCnt = BdCount;	RingPtr->FreeHead = (XEmacPs_Bd *) VirtAddr;	RingPtr->PreHead = (XEmacPs_Bd *) VirtAddr;	RingPtr->HwHead = (XEmacPs_Bd *) VirtAddr;	RingPtr->HwTail = (XEmacPs_Bd *) VirtAddr;	RingPtr->PostHead = (XEmacPs_Bd *) VirtAddr;	RingPtr->BdaRestart = (XEmacPs_Bd *) PhysAddr;	return (XST_SUCCESS);}/*****************************************************************************//** * Clone the given BD into every BD in the list. * every field of the source BD is replicated in every BD of the list. * * This function can be called only when all BDs are in the free group such as * they are immediately after initialization with XEmacPs_BdRingCreate(). * This prevents modification of BDs while they are in use by hardware or the * user. * * @param RingPtr is the pointer of BD ring instance to be worked on. * @param SrcBdPtr is the source BD template to be cloned into the list. This *        BD will be modified. * @param Direction is either XEMACPS_SEND or XEMACPS_RECV that indicates *        which direction. * * @return *   - XST_SUCCESS if the list was modified. *   - XST_DMA_SG_NO_LIST if a list has not been created. *   - XST_DMA_SG_LIST_ERROR if some of the BDs in this channel are under *     hardware or user control. *   - XST_DEVICE_IS_STARTED if the DMA channel has not been stopped. * *****************************************************************************/int XEmacPs_BdRingClone(XEmacPs_BdRing * RingPtr, XEmacPs_Bd * SrcBdPtr,			 u8 Direction){	unsigned i;	u32 CurBd;	/* Can't do this function if there isn't a ring */	if (RingPtr->AllCnt == 0) {		return (XST_DMA_SG_NO_LIST);	}	/* Can't do this function with the channel running */	if (RingPtr->RunState == XST_DMA_SG_IS_STARTED) {		return (XST_DEVICE_IS_STARTED);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -