From 028ab6b598b628326116acd88e0f35aa9f526d12 Mon Sep 17 00:00:00 2001 From: wdenk Date: Mon, 23 Feb 2004 23:54:43 +0000 Subject: * Patch by Peter Ryser, 20 Feb 2004: Add support for the Xilinx ML300 platform * Patch by Stephan Linz, 17 Feb 2004: Fix watchdog support for NIOS * Patch by Josh Fryman, 16 Feb 2004: Fix byte-swapping for cfi_flash.c for different bus widths * Patch by Jon Diekema, 14 Jeb 2004: Remove duplicate "FPGA Support" notes from the README file --- board/xilinx/common/xpacket_fifo_v1_00_b.c | 448 +++++++++++++++++++++++++++++ 1 file changed, 448 insertions(+) create mode 100644 board/xilinx/common/xpacket_fifo_v1_00_b.c (limited to 'board/xilinx/common/xpacket_fifo_v1_00_b.c') 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 0000000000..ae2d6d43c5 --- /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. +* +*
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b rpm 03/26/02  First release
+* 
+* +*****************************************************************************/ + +/***************************** 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. +*

+* 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; +} -- cgit v1.2.1