diff options
Diffstat (limited to 'board/xilinx/common/xpacket_fifo_v1_00_b.c')
| -rw-r--r-- | board/xilinx/common/xpacket_fifo_v1_00_b.c | 448 | 
1 files changed, 448 insertions, 0 deletions
| diff --git a/board/xilinx/common/xpacket_fifo_v1_00_b.c b/board/xilinx/common/xpacket_fifo_v1_00_b.c new file mode 100644 index 000000000..ae2d6d43c --- /dev/null +++ b/board/xilinx/common/xpacket_fifo_v1_00_b.c @@ -0,0 +1,448 @@ +/****************************************************************************** +* +*     Author: Xilinx, Inc. +* +* +*     This program is free software; you can redistribute it and/or modify it +*     under the terms of the GNU General Public License as published by the +*     Free Software Foundation; either version 2 of the License, or (at your +*     option) any later version. +* +* +*     XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A +*     COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS +*     ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, +*     XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE +*     FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING +*     ANY THIRD PARTY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. +*     XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO +*     THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY +*     WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM +*     CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND +*     FITNESS FOR A PARTICULAR PURPOSE. +* +* +*     Xilinx hardware products are not intended for use in life support +*     appliances, devices, or systems. Use in such applications is +*     expressly prohibited. +* +* +*     (c) Copyright 2002-2004 Xilinx Inc. +*     All rights reserved. +* +* +*     You should have received a copy of the GNU General Public License along +*     with this program; if not, write to the Free Software Foundation, Inc., +*     675 Mass Ave, Cambridge, MA 02139, USA. +* +******************************************************************************/ +/*****************************************************************************/ +/* +* +* @file xpacket_fifo_v1_00_b.c +* +* Contains functions for the XPacketFifoV100b component. See xpacket_fifo_v1_00_b.h +* for more information about the component. +* +* <pre> +* MODIFICATION HISTORY: +* +* Ver   Who  Date     Changes +* ----- ---- -------- ----------------------------------------------- +* 1.00b rpm 03/26/02  First release +* </pre> +* +*****************************************************************************/ + +/***************************** Include Files *********************************/ + +#include "xbasic_types.h" +#include "xio.h" +#include "xstatus.h" +#include "xpacket_fifo_v1_00_b.h" + +/************************** Constant Definitions *****************************/ + +/* width of a FIFO word */ + +#define XPF_FIFO_WIDTH_BYTE_COUNT       4UL + +/**************************** Type Definitions *******************************/ + +/***************** Macros (Inline Functions) Definitions *********************/ + +/************************* Variable Definitions ******************************/ + +/************************** Function Prototypes ******************************/ + +/*****************************************************************************/ +/* +* +* This function initializes a packet FIFO.  Initialization resets the +* FIFO such that it's empty and ready to use. +* +* @param InstancePtr contains a pointer to the FIFO to operate on. +* @param RegBaseAddress contains the base address of the registers for +*        the packet FIFO. +* @param DataBaseAddress contains the base address of the data for +*        the packet FIFO. +* +* @return +* +* Always returns XST_SUCCESS. +* +* @note +* +* None. +* +******************************************************************************/ +XStatus +XPacketFifoV100b_Initialize(XPacketFifoV100b * InstancePtr, +			    u32 RegBaseAddress, u32 DataBaseAddress) +{ +	/* assert to verify input argument are valid */ + +	XASSERT_NONVOID(InstancePtr != NULL); + +	/* initialize the component variables to the specified state */ + +	InstancePtr->RegBaseAddress = RegBaseAddress; +	InstancePtr->DataBaseAddress = DataBaseAddress; +	InstancePtr->IsReady = XCOMPONENT_IS_READY; + +	/* reset the FIFO such that it's empty and ready to use and indicate the +	 * initialization was successful, note that the is ready variable must be +	 * set prior to calling the reset function to prevent an assert +	 */ +	XPF_V100B_RESET(InstancePtr); + +	return XST_SUCCESS; +} + +/*****************************************************************************/ +/* +* +* This function performs a self-test on the specified packet FIFO.  The self +* test resets the FIFO and reads a register to determine if it is the correct +* reset value.  This test is destructive in that any data in the FIFO will +* be lost. +* +* @param InstancePtr is a pointer to the packet FIFO to be operated on. +* +* @param FifoType specifies the type of FIFO, read or write, for the self test. +*        The FIFO type is specified by the values XPF_READ_FIFO_TYPE or +*        XPF_WRITE_FIFO_TYPE. +* +* @return +* +* XST_SUCCESS is returned if the selftest is successful, or +* XST_PFIFO_BAD_REG_VALUE indicating that the value readback from the +* occupancy/vacancy count register after a reset does not match the +* specified reset value. +* +* @note +* +* None. +* +******************************************************************************/ +XStatus +XPacketFifoV100b_SelfTest(XPacketFifoV100b * InstancePtr, u32 FifoType) +{ +	u32 Register; + +	/* assert to verify valid input arguments */ + +	XASSERT_NONVOID(InstancePtr != NULL); +	XASSERT_NONVOID((FifoType == XPF_READ_FIFO_TYPE) || +			(FifoType == XPF_WRITE_FIFO_TYPE)); +	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); + +	/* reset the fifo and then check to make sure the occupancy/vacancy +	 * register contents are correct for a reset condition +	 */ +	XPF_V100B_RESET(InstancePtr); + +	Register = XIo_In32(InstancePtr->RegBaseAddress + +			    XPF_COUNT_STATUS_REG_OFFSET); + +	/* check the value of the register to ensure that it's correct for the +	 * specified FIFO type since both FIFO types reset to empty, but a bit +	 * in the register changes definition based upon FIFO type +	 */ + +	if (FifoType == XPF_READ_FIFO_TYPE) { +		/* check the regiser value for a read FIFO which should be empty */ + +		if (Register != XPF_EMPTY_FULL_MASK) { +			return XST_PFIFO_BAD_REG_VALUE; +		} +	} else { +		/* check the register value for a write FIFO which should not be full +		 * on reset +		 */ +		if ((Register & XPF_EMPTY_FULL_MASK) != 0) { +			return XST_PFIFO_BAD_REG_VALUE; +		} +	} + +	/* the test was successful */ + +	return XST_SUCCESS; +} + +/*****************************************************************************/ +/* +* +* Read data from a FIFO and puts it into a specified buffer. The packet FIFO is +* currently 32 bits wide such that an input buffer which is a series of bytes +* is filled from the FIFO a word at a time. If the requested byte count is not +* a multiple of 32 bit words, it is necessary for this function to format the +* remaining 32 bit word from the FIFO into a series of bytes in the buffer. +* There may be up to 3 extra bytes which must be extracted from the last word +* of the FIFO and put into the buffer. +* +* @param InstancePtr contains a pointer to the FIFO to operate on. +* @param BufferPtr points to the memory buffer to write the data into. This +*        buffer must be 32 bit aligned or an alignment exception could be +*        generated. Since this buffer is a byte buffer, the data is assumed to +*        be endian independent. +* @param ByteCount contains the number of bytes to read from the FIFO. This +*        number of bytes must be present in the FIFO or an error will be +*        returned. +* +* @return +* +* XST_SUCCESS indicates the operation was successful.  If the number of +* bytes specified by the byte count is not present in the FIFO +* XST_PFIFO_LACK_OF_DATA is returned. +* +* If the function was successful, the specified buffer is modified to contain +* the bytes which were removed from the FIFO. +* +* @note +* +* Note that the exact number of bytes which are present in the FIFO is +* not known by this function.  It can only check for a number of 32 bit +* words such that if the byte count specified is incorrect, but is still +* possible based on the number of words in the FIFO, up to 3 garbage bytes +* may be present at the end of the buffer. +* <br><br> +* This function assumes that if the device consuming data from the FIFO is +* a byte device, the order of the bytes to be consumed is from the most +* significant byte to the least significant byte of a 32 bit word removed +* from the FIFO. +* +******************************************************************************/ +XStatus +XPacketFifoV100b_Read(XPacketFifoV100b * InstancePtr, +		      u8 * BufferPtr, u32 ByteCount) +{ +	u32 FifoCount; +	u32 WordCount; +	u32 ExtraByteCount; +	u32 *WordBuffer = (u32 *) BufferPtr; + +	/* assert to verify valid input arguments including 32 bit alignment of +	 * the buffer pointer +	 */ +	XASSERT_NONVOID(InstancePtr != NULL); +	XASSERT_NONVOID(BufferPtr != NULL); +	XASSERT_NONVOID(((u32) BufferPtr & +			 (XPF_FIFO_WIDTH_BYTE_COUNT - 1)) == 0); +	XASSERT_NONVOID(ByteCount != 0); +	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); + +	/* get the count of how many 32 bit words are in the FIFO, if there aren't +	 * enought words to satisfy the request, return an error +	 */ + +	FifoCount = XIo_In32(InstancePtr->RegBaseAddress + +			     XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK; + +	if ((FifoCount * XPF_FIFO_WIDTH_BYTE_COUNT) < ByteCount) { +		return XST_PFIFO_LACK_OF_DATA; +	} + +	/* calculate the number of words to read from the FIFO before the word +	 * containing the extra bytes, and calculate the number of extra bytes +	 * the extra bytes are defined as those at the end of the buffer when +	 * the buffer does not end on a 32 bit boundary +	 */ +	WordCount = ByteCount / XPF_FIFO_WIDTH_BYTE_COUNT; +	ExtraByteCount = ByteCount % XPF_FIFO_WIDTH_BYTE_COUNT; + +	/* Read the 32 bit words from the FIFO for all the buffer except the +	 * last word which contains the extra bytes, the following code assumes +	 * that the buffer is 32 bit aligned, otherwise an alignment exception could +	 * be generated +	 */ +	for (FifoCount = 0; FifoCount < WordCount; FifoCount++) { +		WordBuffer[FifoCount] = XIo_In32(InstancePtr->DataBaseAddress); +	} + +	/* if there are extra bytes to handle, read the last word from the FIFO +	 * and insert the extra bytes into the buffer +	 */ +	if (ExtraByteCount > 0) { +		u32 LastWord; +		u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount); + +		/* get the last word from the FIFO for the extra bytes */ + +		LastWord = XIo_In32(InstancePtr->DataBaseAddress); + +		/* one extra byte in the last word, put the byte into the next location +		 * of the buffer, bytes in a word of the FIFO are ordered from most +		 * significant byte to least +		 */ +		if (ExtraByteCount == 1) { +			ExtraBytesBuffer[0] = (u8) (LastWord >> 24); +		} + +		/* two extra bytes in the last word, put each byte into the next two +		 * locations of the buffer +		 */ +		else if (ExtraByteCount == 2) { +			ExtraBytesBuffer[0] = (u8) (LastWord >> 24); +			ExtraBytesBuffer[1] = (u8) (LastWord >> 16); +		} +		/* three extra bytes in the last word, put each byte into the next three +		 * locations of the buffer +		 */ +		else if (ExtraByteCount == 3) { +			ExtraBytesBuffer[0] = (u8) (LastWord >> 24); +			ExtraBytesBuffer[1] = (u8) (LastWord >> 16); +			ExtraBytesBuffer[2] = (u8) (LastWord >> 8); +		} +	} +	return XST_SUCCESS; +} + +/*****************************************************************************/ +/* +* +* Write data into a packet FIFO. The packet FIFO is currently 32 bits wide +* such that an input buffer which is a series of bytes must be written into the +* FIFO a word at a time. If the buffer is not a multiple of 32 bit words, it is +* necessary for this function to format the remaining bytes into a single 32 +* bit word to be inserted into the FIFO. This is necessary to avoid any +* accesses past the end of the buffer. +* +* @param InstancePtr contains a pointer to the FIFO to operate on. +* @param BufferPtr points to the memory buffer that data is to be read from +*        and written into the FIFO. Since this buffer is a byte buffer, the data +*        is assumed to be endian independent. This buffer must be 32 bit aligned +*        or an alignment exception could be generated. +* @param ByteCount contains the number of bytes to read from the buffer and to +*        write to the FIFO. +* +* @return +* +* XST_SUCCESS is returned if the operation succeeded.  If there is not enough +* room in the FIFO to hold the specified bytes, XST_PFIFO_NO_ROOM is +* returned. +* +* @note +* +* This function assumes that if the device inserting data into the FIFO is +* a byte device, the order of the bytes in each 32 bit word is from the most +* significant byte to the least significant byte. +* +******************************************************************************/ +XStatus +XPacketFifoV100b_Write(XPacketFifoV100b * InstancePtr, +		       u8 * BufferPtr, u32 ByteCount) +{ +	u32 FifoCount; +	u32 WordCount; +	u32 ExtraByteCount; +	u32 *WordBuffer = (u32 *) BufferPtr; + +	/* assert to verify valid input arguments including 32 bit alignment of +	 * the buffer pointer +	 */ +	XASSERT_NONVOID(InstancePtr != NULL); +	XASSERT_NONVOID(BufferPtr != NULL); +	XASSERT_NONVOID(((u32) BufferPtr & +			 (XPF_FIFO_WIDTH_BYTE_COUNT - 1)) == 0); +	XASSERT_NONVOID(ByteCount != 0); +	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); + +	/* get the count of how many words may be inserted into the FIFO */ + +	FifoCount = XIo_In32(InstancePtr->RegBaseAddress + +			     XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK; + +	/* Calculate the number of 32 bit words required to insert the specified +	 * number of bytes in the FIFO and determine the number of extra bytes +	 * if the buffer length is not a multiple of 32 bit words +	 */ + +	WordCount = ByteCount / XPF_FIFO_WIDTH_BYTE_COUNT; +	ExtraByteCount = ByteCount % XPF_FIFO_WIDTH_BYTE_COUNT; + +	/* take into account the extra bytes in the total word count */ + +	if (ExtraByteCount > 0) { +		WordCount++; +	} + +	/* if there's not enough room in the FIFO to hold the specified +	 * number of bytes, then indicate an error, +	 */ +	if (FifoCount < WordCount) { +		return XST_PFIFO_NO_ROOM; +	} + +	/* readjust the word count to not take into account the extra bytes */ + +	if (ExtraByteCount > 0) { +		WordCount--; +	} + +	/* Write all the bytes of the buffer which can be written as 32 bit +	 * words into the FIFO, waiting to handle the extra bytes seperately +	 */ +	for (FifoCount = 0; FifoCount < WordCount; FifoCount++) { +		XIo_Out32(InstancePtr->DataBaseAddress, WordBuffer[FifoCount]); +	} + +	/* if there are extra bytes to handle, extract them from the buffer +	 * and create a 32 bit word and write it to the FIFO +	 */ +	if (ExtraByteCount > 0) { +		u32 LastWord = 0; +		u8 *ExtraBytesBuffer = (u8 *) (WordBuffer + WordCount); + +		/* one extra byte in the buffer, put the byte into the last word +		 * to be inserted into the FIFO, perform this processing inline rather +		 * than in a loop to help performance +		 */ +		if (ExtraByteCount == 1) { +			LastWord = ExtraBytesBuffer[0] << 24; +		} + +		/* two extra bytes in the buffer, put each byte into the last word +		 * to be inserted into the FIFO +		 */ +		else if (ExtraByteCount == 2) { +			LastWord = ExtraBytesBuffer[0] << 24 | +			    ExtraBytesBuffer[1] << 16; +		} + +		/* three extra bytes in the buffer, put each byte into the last word +		 * to be inserted into the FIFO +		 */ +		else if (ExtraByteCount == 3) { +			LastWord = ExtraBytesBuffer[0] << 24 | +			    ExtraBytesBuffer[1] << 16 | +			    ExtraBytesBuffer[2] << 8; +		} + +		/* write the last 32 bit word to the FIFO and return with no errors */ + +		XIo_Out32(InstancePtr->DataBaseAddress, LastWord); +	} + +	return XST_SUCCESS; +} |