summaryrefslogtreecommitdiff
path: root/board/xilinx/common/xpacket_fifo_v1_00_b.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/xilinx/common/xpacket_fifo_v1_00_b.c')
-rw-r--r--board/xilinx/common/xpacket_fifo_v1_00_b.c448
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;
+}