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

📄 xdmaps.c

📁 自学ZedBoard:使用IP通过ARM PS访问FPGA(源代码)
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************* (c) Copyright 2009-2012 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 xdmaps.c** This file contains the implementation of the interface functions for XDmaPs* driver. Refer to the header file xdmaps.h for more detailed information.** <pre>* MODIFICATION HISTORY:** Ver   Who  	Date     Changes* ----- ------ -------- ----------------------------------------------* 1.00	hbm    08/19/2010 First Release* 1.00  nm     05/25/2011 Updated for minor doxygen corrections* 1.02a sg     05/16/2012 Made changes for doxygen and moved some function*			  header from the xdmaps.h file to xdmaps.c file*			  Other cleanup for coding guidelines and CR 657109*			  and CR 657898* </pre>******************************************************************************//***************************** Include Files ********************************/#include <string.h>#include "xstatus.h"#include "xdmaps.h"#include "xil_io.h"#include "xil_cache.h"#include "xil_printf.h"// #define XDMAPS_DEBUG#undef PDBG#ifdef XDMAPS_DEBUG#	define PDBG(fmt, args...) xil_printf(fmt, ## args)#else#	define PDBG(fmt, args...)#endif/************************** Constant Definitions ****************************//* The following constant defines the amount of error that is allowed for * a specified baud rate. This error is the difference between the actual * baud rate that will be generated using the specified clock and the * desired baud rate. *//**************************** Type Definitions ******************************//***************** Macros (Inline Functions) Definitions ********************//************************** Function Prototypes *****************************/static int XDmaPs_Exec_DMAKILL(u32 BaseAddr,				unsigned int Channel,				unsigned int Thread);static void XDmaPs_BufPool_Free(XDmaPs_ProgBuf *Pool, void *Buf);static int XDmaPs_Exec_DMAGO(u32 BaseAddr, unsigned int Channel, u32 DmaProg);static void XDmaPs_DoneISR_n(XDmaPs *InstPtr, unsigned Channel);static void *XDmaPs_BufPool_Allocate(XDmaPs_ProgBuf *Pool);static int XDmaPs_BuildDmaProg(unsigned Channel, XDmaPs_Cmd *Cmd,				unsigned CacheLength);static void XDmaPs_Print_DmaProgBuf(char *Buf, int Length);/************************** Variable Definitions ****************************//****************************************************************************//**** Initializes a specific XDmaPs instance such that it is ready to be used.* The data format of the device is setup for 8 data bits, 1 stop bit, and no* parity by default. The baud rate is set to a default value specified by* Config->DefaultBaudRate if set, otherwise it is set to 19.2K baud. The* receive FIFO threshold is set for 8 bytes. The default operating mode of the* driver is polled mode.** @param	InstPtr is a pointer to the XDmaPs instance.* @param	Config is a reference to a structure containing information*		about a specific XDmaPs driver.* @param	EffectiveAddr is the device base address in the virtual memory*		address space. The caller is responsible for keeping the*		address mapping from EffectiveAddr to the device physical base*		address unchanged once this function is invoked. Unexpected*		errors may occur if the address mapping changes after this*		function is called. If address translation is not used, pass in*		the physical address instead.** @return**		- XST_SUCCESS on initialization completion** @note		None.******************************************************************************/int XDmaPs_CfgInitialize(XDmaPs *InstPtr,			  XDmaPs_Config *Config,			  u32 EffectiveAddr){	int Status = XST_SUCCESS;	unsigned int CacheLength = 0;	u32 CfgReg;	unsigned Channel;	XDmaPs_ChannelData *ChanData;	/*	 * Assert validates the input arguments	 */	Xil_AssertNonvoid(InstPtr != NULL);	Xil_AssertNonvoid(Config != NULL);	/*	 * Setup the driver instance using passed in parameters	 */	InstPtr->Config.DeviceId = Config->DeviceId;	InstPtr->Config.BaseAddress = EffectiveAddr;	CfgReg = XDmaPs_ReadReg(EffectiveAddr, XDMAPS_CR1_OFFSET);	CacheLength = CfgReg & XDMAPS_CR1_I_CACHE_LEN_MASK;	if (CacheLength < 2 || CacheLength > 5)		CacheLength = 0;	else		CacheLength = 1 << CacheLength;	InstPtr->CacheLength = CacheLength;	memset(InstPtr->Chans, 0,	       sizeof(XDmaPs_ChannelData[XDMAPS_CHANNELS_PER_DEV]));	for (Channel = 0; Channel < XDMAPS_CHANNELS_PER_DEV; Channel++) {		ChanData = InstPtr->Chans + Channel;		ChanData->ChanId = Channel;		ChanData->DevId = Config->DeviceId;	}	InstPtr->IsReady = 1;	return Status;}/****************************************************************************//**** Reset the DMA Manager.** @param	InstPtr is the DMA instance.** @return	0 on success, -1 on time out** @note		None.******************************************************************************/int XDmaPs_ResetManager(XDmaPs *InstPtr){	int Status;	Status = XDmaPs_Exec_DMAKILL(InstPtr->Config.BaseAddress,				      0, 0);	return Status;}/****************************************************************************//**** Reset the specified DMA Channel.** @param	InstPtr is the DMA instance.* @param	Channel is the channel to be reset.** @return	0 on success, -1 on time out** @note		None.******************************************************************************/int XDmaPs_ResetChannel(XDmaPs *InstPtr, unsigned int Channel){	int Status;	Status = XDmaPs_Exec_DMAKILL(InstPtr->Config.BaseAddress,				      Channel, 1);	return Status;}/*****************************************************************************//**** Driver fault interrupt service routine* This is the one that connects the GIC** @param	InstPtr is the DMA instance.** @return	None.** @note		None.*******************************************************************************/void XDmaPs_FaultISR(XDmaPs *InstPtr){	void *DmaProgBuf;	u32 Fsm; /* Fault status DMA manager register value */	u32 Fsc; /* Fault status DMA channel register value */	u32 FaultType; /* Fault type DMA manager register value */	u32 BaseAddr = InstPtr->Config.BaseAddress;	u32 Pc; /* DMA Pc or channel Pc */	XDmaPs_ChannelData *ChanData;	unsigned Chan;	unsigned DevId;	XDmaPs_Cmd *DmaCmd;	PDBG("inside Fault ISR dev %d\r\n", InstPtr->Config.DeviceId);	Fsm = XDmaPs_ReadReg(BaseAddr, XDMAPS_FSM_OFFSET) & 0x01;	Fsc = XDmaPs_ReadReg(BaseAddr, XDMAPS_FSC_OFFSET) & 0xFF;	DevId = InstPtr->Config.DeviceId;	if (Fsm) {		/*		 * if DMA manager is fault		 */		FaultType = XDmaPs_ReadReg(BaseAddr, XDMAPS_FTM_OFFSET);		Pc = XDmaPs_ReadReg(BaseAddr, XDMAPS_DPC_OFFSET);		xil_printf("PL330 device %d fault with type: %x at Pc %x\n",			   DevId,			   FaultType, Pc);		/* kill the DMA manager thread */		/* Should we disable interrupt?*/		XDmaPs_Exec_DMAKILL(BaseAddr, 0, 0);	}	/*	 * check which channel faults and kill the channel thread	 */	for (Chan = 0;	     Chan < XDMAPS_CHANNELS_PER_DEV;	     Chan++) {		if (Fsc & (0x01 << Chan)) {			PDBG("xdmaps_fault_isr: channel %d device %d\n",			     Chan, DevId);			FaultType =				XDmaPs_ReadReg(BaseAddr,						XDmaPs_FTCn_OFFSET(Chan));			Pc = XDmaPs_ReadReg(BaseAddr,					     XDmaPs_CPCn_OFFSET(Chan));			PDBG("xdmaps_fault_isr: fault type %#x Pc %#x\n",			     FaultType, Pc);			/* kill the channel thread */			PDBG("xdmaps_fault_isr: "			     "killing channel %d for device %d\n",			     Chan,			     InstPtr->Config.DeviceId);			/* Should we disable interrupt? */			XDmaPs_Exec_DMAKILL(BaseAddr, Chan, 1);			/*			 * get the fault type and fault Pc and invoke the			 * fault callback.			 */			ChanData = InstPtr->Chans + Chan;			DmaCmd = ChanData->DmaCmdToHw;			/* Should we check DmaCmd is not null */			DmaCmd->DmaStatus = -1;			DmaCmd->ChanFaultType = FaultType;			DmaCmd->ChanFaultPCAddr = Pc;			ChanData->DmaCmdFromHw = DmaCmd;			ChanData->DmaCmdToHw = NULL;			if (!ChanData->HoldDmaProg) {				DmaProgBuf = (void *)DmaCmd->GeneratedDmaProg;				if (DmaProgBuf)					XDmaPs_BufPool_Free(ChanData->ProgBufPool,							     DmaProgBuf);				DmaCmd->GeneratedDmaProg = NULL;			}			if (InstPtr->FaultHandler)				InstPtr->FaultHandler(Chan,						      DmaCmd,						      InstPtr->FaultRef);		}	}}/*****************************************************************************//**** Set the done handler for a channel.** @param	InstPtr is the DMA instance.* @param	Channel is the channel number.* @param	DoneHandler is the done interrupt handler.* @param	CallbackRef is the callback reference data.** @return	None.** @note		None.*******************************************************************************/int XDmaPs_SetDoneHandler(XDmaPs *InstPtr,			   unsigned Channel,			   XDmaPsDoneHandler DoneHandler,			   void *CallbackRef){	XDmaPs_ChannelData *ChanData;	Xil_AssertNonvoid(InstPtr != NULL);	if (Channel >= XDMAPS_CHANNELS_PER_DEV)		return XST_FAILURE;	ChanData = InstPtr->Chans + Channel;	ChanData->DoneHandler = DoneHandler;	ChanData->DoneRef = CallbackRef;	return 0;}/*****************************************************************************//**** Set the fault handler for a channel.** @param	InstPtr is the DMA instance.* @param	FaultHandler is the fault interrupt handler.* @param	CallbackRef is the callback reference data.** @return	None.** @note		None.*******************************************************************************/int XDmaPs_SetFaultHandler(XDmaPs *InstPtr,			    XDmaPsFaultHandler FaultHandler,			    void *CallbackRef){	Xil_AssertNonvoid(InstPtr != NULL);	InstPtr->FaultHandler = FaultHandler;	InstPtr->FaultRef = CallbackRef;	return XST_SUCCESS;}/****************************************************************************//*** Construction function for DMAEND instruction. This function fills the program* buffer with the constructed instruction.** @param	DmaProg the DMA program buffer, it's the starting address for*		the instruction being constructed** @return 	The number of bytes for this instruction which is 1.** @note		None.******************************************************************************/inline int XDmaPs_Instr_DMAEND(char *DmaProg){	/*	 * DMAEND encoding:	 * 7 6 5 4 3 2 1 0	 * 0 0 0 0 0 0 0 0	 */	*DmaProg = 0x0;	return 1;}inline void XDmaPs_Memcpy4(char *Dst, char *Src){	*Dst = *Src;	*(Dst + 1) = *(Src + 1);	*(Dst + 2) = *(Src + 2);	*(Dst + 3) = *(Src + 3);}/****************************************************************************//**** Construction function for DMAGO instruction. This function fills the program* buffer with the constructed instruction.** @param	DmaProg is the DMA program buffer, it's the starting address*		for the instruction being constructed* @param	Cn is the Channel number, 0 - 7* @param	Imm is 32-bit immediate number written to the Channel Program*		Counter.* @param	Ns is Non-secure flag. If Ns is 1, the DMA channel operates in*		the Non-secure state. If Ns is 0, the execution depends on the*		security state of the DMA manager:*		DMA manager is in the Secure state, DMA channel operates in the*		Secure state.*		DMA manager is in the Non-secure state, DMAC aborts.** @return	The number of bytes for this instruction which is 6.** @note		None******************************************************************************/inline int XDmaPs_Instr_DMAGO(char *DmaProg, unsigned int Cn,			       u32 Imm, unsigned int Ns){	PDBG("entering XDmaPs_Instr_DMAGO(%x, %d, %x, %d)\r\n",	     (unsigned int)DmaProg, Cn, Imm, Ns);	/*	 * DMAGO encoding:	 * 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00	 *  0  0  0  0  0 |cn[2:0]| 1  0  1  0  0  0 ns  0	 *	 * 47 ... 16	 *  imm[32:0]	 */	*DmaProg = 0xA0 | ((Ns << 1) & 0x02);	*(DmaProg + 1) = (u8)(Cn & 0x07);	// *((u32 *)(DmaProg + 2)) = Imm;	XDmaPs_Memcpy4(DmaProg + 2, (char *)&Imm);	/* success */	return 6;}/****************************************************************************//**** Construction function for DMALD instruction. This function fills the program* buffer with the constructed instruction.** @param	DmaProg the DMA program buffer, it's the starting address for the*		instruction being constructed** @return 	The number of bytes for this instruction which is 1.** @note		None.******************************************************************************/inline int XDmaPs_Instr_DMALD(char *DmaProg){	/*	 * DMALD encoding	 * 7 6 5 4 3 2 1  0	 * 0 0 0 0 0 1 bs x	 *	 * Note: this driver doesn't support conditional load or store,	 * so the bs bit is 0 and x bit is 0.	 */	*DmaProg = 0x04;	return 1;}/****************************************************************************//**** Construction function for DMALP instruction. This function fills the program* buffer with the constructed instruction.** @param	DmaProg is the DMA program buffer, it's the starting address*		for the instruction being constructed

⌨️ 快捷键说明

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