* 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
diff --git a/board/xilinx/common/xbasic_types.c b/board/xilinx/common/xbasic_types.c
new file mode 100644
index 0000000..c3a171a
--- /dev/null
+++ b/board/xilinx/common/xbasic_types.c
@@ -0,0 +1,165 @@
+/******************************************************************************
+*
+*     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 xbasic_types.c
+*
+* This file contains basic functions for Xilinx software IP.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a rpm  11/07/03 Added XNullHandler function as a stub interrupt handler
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/**
+ * This variable allows testing to be done easier with asserts. An assert
+ * sets this variable such that a driver can evaluate this variable
+ * to determine if an assert occurred.
+ */
+unsigned int XAssertStatus;
+
+/**
+ * This variable allows the assert functionality to be changed for testing
+ * such that it does not wait infinitely. Use the debugger to disable the
+ * waiting during testing of asserts.
+ */
+u32 XWaitInAssert = TRUE;
+
+/* The callback function to be invoked when an assert is taken */
+static XAssertCallback XAssertCallbackRoutine = (XAssertCallback) NULL;
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Implements assert. Currently, it calls a user-defined callback function
+* if one has been set.  Then, it potentially enters an infinite loop depending
+* on the value of the XWaitInAssert variable.
+*
+* @param    File is the name of the filename of the source
+* @param    Line is the linenumber within File
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XAssert(char *File, int Line)
+{
+	/* if the callback has been set then invoke it */
+	if (XAssertCallbackRoutine != NULL) {
+		(*XAssertCallbackRoutine) (File, Line);
+	}
+
+	/* if specified, wait indefinitely such that the assert will show up
+	 * in testing
+	 */
+	while (XWaitInAssert) {
+	}
+}
+
+/*****************************************************************************/
+/**
+*
+* Sets up a callback function to be invoked when an assert occurs. If there
+* was already a callback installed, then it is replaced.
+*
+* @param    Routine is the callback to be invoked when an assert is taken
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* This function has no effect if NDEBUG is set
+*
+******************************************************************************/
+void
+XAssertSetCallback(XAssertCallback Routine)
+{
+	XAssertCallbackRoutine = Routine;
+}
+
+/*****************************************************************************/
+/**
+*
+* Null handler function. This follows the XInterruptHandler signature for
+* interrupt handlers. It can be used to assign a null handler (a stub) to an
+* interrupt controller vector table.
+*
+* @param    NullParameter is an arbitrary void pointer and not used.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XNullHandler(void *NullParameter)
+{
+}
diff --git a/board/xilinx/common/xbasic_types.h b/board/xilinx/common/xbasic_types.h
new file mode 100644
index 0000000..ef0b7c2
--- /dev/null
+++ b/board/xilinx/common/xbasic_types.h
@@ -0,0 +1,283 @@
+/******************************************************************************
+*
+*     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 xbasic_types.h
+*
+* This file contains basic types for Xilinx software IP.  These types do not
+* follow the standard naming convention with respect to using the component
+* name in front of each name because they are considered to be primitives.
+*
+* @note
+*
+* This file contains items which are architecture dependent.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver	Who    Date   Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a rmm  12/14/01 First release
+*	rmm  05/09/03 Added "xassert always" macros to rid ourselves of diab
+*		      compiler warnings
+* 1.00a rpm  11/07/03 Added XNullHandler function as a stub interrupt handler
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XBASIC_TYPES_H		/* prevent circular inclusions */
+#define XBASIC_TYPES_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+/************************** Constant Definitions *****************************/
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+/** Null */
+
+#define XCOMPONENT_IS_READY	0x11111111	/* component has been initialized */
+#define XCOMPONENT_IS_STARTED	0x22222222	/* component has been started */
+
+/* the following constants and declarations are for unit test purposes and are
+ * designed to be used in test applications.
+ */
+#define XTEST_PASSED	0
+#define XTEST_FAILED	1
+
+#define XASSERT_NONE	 0
+#define XASSERT_OCCURRED 1
+
+extern unsigned int XAssertStatus;
+extern void XAssert(char *, int);
+
+/**************************** Type Definitions *******************************/
+
+/** @name Primitive types
+ * These primitive types are created for transportability.
+ * They are dependent upon the target architecture.
+ * @{
+ */
+#include <linux/types.h>
+
+typedef struct {
+	u32 Upper;
+	u32 Lower;
+} Xuint64;
+
+/*@}*/
+
+/**
+ * This data type defines an interrupt handler for a device.
+ * The argument points to the instance of the component
+ */
+typedef void (*XInterruptHandler) (void *InstancePtr);
+
+/**
+ * This data type defines a callback to be invoked when an
+ * assert occurs. The callback is invoked only when asserts are enabled
+ */
+typedef void (*XAssertCallback) (char *FilenamePtr, int LineNumber);
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+* Return the most significant half of the 64 bit data type.
+*
+* @param x is the 64 bit word.
+*
+* @return
+*
+* The upper 32 bits of the 64 bit word.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XUINT64_MSW(x) ((x).Upper)
+
+/*****************************************************************************/
+/**
+* Return the least significant half of the 64 bit data type.
+*
+* @param x is the 64 bit word.
+*
+* @return
+*
+* The lower 32 bits of the 64 bit word.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XUINT64_LSW(x) ((x).Lower)
+
+#ifndef NDEBUG
+
+/*****************************************************************************/
+/**
+* This assert macro is to be used for functions that do not return anything
+* (void). This in conjunction with the XWaitInAssert boolean can be used to
+* accomodate tests so that asserts which fail allow execution to continue.
+*
+* @param expression is the expression to evaluate. If it evaluates to false,
+*	 the assert occurs.
+*
+* @return
+*
+* Returns void unless the XWaitInAssert variable is true, in which case
+* no return is made and an infinite loop is entered.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XASSERT_VOID(expression)			\
+{							\
+	if (expression) {				\
+		XAssertStatus = XASSERT_NONE;		\
+	} else {					\
+		XAssert(__FILE__, __LINE__);		\
+		XAssertStatus = XASSERT_OCCURRED;	\
+		return;					\
+	}						\
+}
+
+/*****************************************************************************/
+/**
+* This assert macro is to be used for functions that do return a value. This in
+* conjunction with the XWaitInAssert boolean can be used to accomodate tests so
+* that asserts which fail allow execution to continue.
+*
+* @param expression is the expression to evaluate. If it evaluates to false,
+*	 the assert occurs.
+*
+* @return
+*
+* Returns 0 unless the XWaitInAssert variable is true, in which case
+* no return is made and an infinite loop is entered.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XASSERT_NONVOID(expression)		   \
+{						   \
+	if (expression) {			   \
+		XAssertStatus = XASSERT_NONE;	   \
+	} else {				   \
+		XAssert(__FILE__, __LINE__);	   \
+		XAssertStatus = XASSERT_OCCURRED;  \
+		return 0;			   \
+	}					   \
+}
+
+/*****************************************************************************/
+/**
+* Always assert. This assert macro is to be used for functions that do not
+* return anything (void). Use for instances where an assert should always
+* occur.
+*
+* @return
+*
+* Returns void unless the XWaitInAssert variable is true, in which case
+* no return is made and an infinite loop is entered.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XASSERT_VOID_ALWAYS()			   \
+{						   \
+	XAssert(__FILE__, __LINE__);		   \
+	XAssertStatus = XASSERT_OCCURRED;	   \
+	return;					   \
+}
+
+/*****************************************************************************/
+/**
+* Always assert. This assert macro is to be used for functions that do return
+* a value. Use for instances where an assert should always occur.
+*
+* @return
+*
+* Returns void unless the XWaitInAssert variable is true, in which case
+* no return is made and an infinite loop is entered.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+#define XASSERT_NONVOID_ALWAYS()		   \
+{						   \
+	XAssert(__FILE__, __LINE__);		   \
+	XAssertStatus = XASSERT_OCCURRED;	   \
+	return 0;				   \
+}
+
+#else
+
+#define XASSERT_VOID(expression)
+#define XASSERT_VOID_ALWAYS()
+#define XASSERT_NONVOID(expression)
+#define XASSERT_NONVOID_ALWAYS()
+#endif
+
+/************************** Function Prototypes ******************************/
+
+void XAssertSetCallback(XAssertCallback Routine);
+void XNullHandler(void *NullParameter);
+
+#endif	/* end of protection macro */
diff --git a/board/xilinx/common/xbuf_descriptor.h b/board/xilinx/common/xbuf_descriptor.h
new file mode 100644
index 0000000..fdd51d5
--- /dev/null
+++ b/board/xilinx/common/xbuf_descriptor.h
@@ -0,0 +1,252 @@
+/******************************************************************************
+*
+*     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.
+*
+* FILENAME:
+*
+* xbuf_descriptor.h
+*
+* DESCRIPTION:
+*
+* This file contains the interface for the XBufDescriptor component.
+* The XBufDescriptor component is a passive component that only maps over
+* a buffer descriptor data structure shared by the scatter gather DMA hardware
+* and software. The component's primary purpose is to provide encapsulation of
+* the buffer descriptor processing.  See the source file xbuf_descriptor.c for
+* details.
+*
+* NOTES:
+*
+* Most of the functions of this component are implemented as macros in order
+* to optimize the processing.  The names are not all uppercase such that they
+* can be switched between macros and functions easily.
+*
+******************************************************************************/
+
+#ifndef XBUF_DESCRIPTOR_H	/* prevent circular inclusions */
+#define XBUF_DESCRIPTOR_H	/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xdma_channel_i.h"
+
+/************************** Constant Definitions *****************************/
+
+/* The following constants allow access to all fields of a buffer descriptor
+ * and are necessary at this level of visibility to allow macros to access
+ * and modify the fields of a buffer descriptor.  It is not expected that the
+ * user of a buffer descriptor would need to use these constants.
+ */
+
+#define XBD_DEVICE_STATUS_OFFSET    0
+#define XBD_CONTROL_OFFSET	    1
+#define XBD_SOURCE_OFFSET	    2
+#define XBD_DESTINATION_OFFSET	    3
+#define XBD_LENGTH_OFFSET	    4
+#define XBD_STATUS_OFFSET	    5
+#define XBD_NEXT_PTR_OFFSET	    6
+#define XBD_ID_OFFSET		    7
+#define XBD_FLAGS_OFFSET	    8
+#define XBD_RQSTED_LENGTH_OFFSET    9
+
+#define XBD_SIZE_IN_WORDS	    10
+
+/*
+ * The following constants define the bits of the flags field of a buffer
+ * descriptor
+ */
+
+#define XBD_FLAGS_LOCKED_MASK	    1UL
+
+/**************************** Type Definitions *******************************/
+
+typedef u32 XBufDescriptor[XBD_SIZE_IN_WORDS];
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/* each of the following macros are named the same as functions rather than all
+ * upper case in order to allow either the macros or the functions to be
+ * used, see the source file xbuf_descriptor.c for documentation
+ */
+
+#define XBufDescriptor_Initialize(InstancePtr)			\
+{								\
+    (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) = 0);	    \
+    (*((u32 *)InstancePtr + XBD_SOURCE_OFFSET) = 0);	    \
+    (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET) = 0);   \
+    (*((u32 *)InstancePtr + XBD_LENGTH_OFFSET) = 0);	    \
+    (*((u32 *)InstancePtr + XBD_STATUS_OFFSET) = 0);	    \
+    (*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET) = 0); \
+    (*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET) = 0);	    \
+    (*((u32 *)InstancePtr + XBD_ID_OFFSET) = 0);	    \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) = 0);	    \
+    (*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) = 0); \
+}
+
+#define XBufDescriptor_GetControl(InstancePtr)	 \
+    (u32)(*((u32 *)InstancePtr + XBD_CONTROL_OFFSET))
+
+#define XBufDescriptor_SetControl(InstancePtr, Control)	 \
+    (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) = (u32)Control)
+
+#define XBufDescriptor_IsLastControl(InstancePtr) \
+    (u32)(*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) & \
+	       XDC_CONTROL_LAST_BD_MASK)
+
+#define XBufDescriptor_SetLast(InstancePtr) \
+    (*((u32 *)InstancePtr + XBD_CONTROL_OFFSET) |= XDC_CONTROL_LAST_BD_MASK)
+
+#define XBufDescriptor_GetSrcAddress(InstancePtr) \
+    ((u32 *)(*((u32 *)InstancePtr + XBD_SOURCE_OFFSET)))
+
+#define XBufDescriptor_SetSrcAddress(InstancePtr, Source) \
+    (*((u32 *)InstancePtr + XBD_SOURCE_OFFSET) = (u32)Source)
+
+#define XBufDescriptor_GetDestAddress(InstancePtr) \
+    ((u32 *)(*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET)))
+
+#define XBufDescriptor_SetDestAddress(InstancePtr, Destination) \
+    (*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET) = (u32)Destination)
+
+#define XBufDescriptor_GetLength(InstancePtr)				\
+    (u32)(*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) -	\
+	      *((u32 *)InstancePtr + XBD_LENGTH_OFFSET))
+
+#define XBufDescriptor_SetLength(InstancePtr, Length)			    \
+{									    \
+    (*((u32 *)InstancePtr + XBD_LENGTH_OFFSET) = (u32)(Length));    \
+    (*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET) = (u32)(Length));\
+}
+
+#define XBufDescriptor_GetStatus(InstancePtr)	 \
+    (u32)(*((u32 *)InstancePtr + XBD_STATUS_OFFSET))
+
+#define XBufDescriptor_SetStatus(InstancePtr, Status)	 \
+    (*((u32 *)InstancePtr + XBD_STATUS_OFFSET) = (u32)Status)
+
+#define XBufDescriptor_IsLastStatus(InstancePtr) \
+    (u32)(*((u32 *)InstancePtr + XBD_STATUS_OFFSET) & \
+	       XDC_STATUS_LAST_BD_MASK)
+
+#define XBufDescriptor_GetDeviceStatus(InstancePtr) \
+    ((u32)(*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET)))
+
+#define XBufDescriptor_SetDeviceStatus(InstancePtr, Status) \
+    (*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET) = (u32)Status)
+
+#define XBufDescriptor_GetNextPtr(InstancePtr) \
+    (XBufDescriptor *)(*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET))
+
+#define XBufDescriptor_SetNextPtr(InstancePtr, NextPtr) \
+    (*((u32 *)InstancePtr + XBD_NEXT_PTR_OFFSET) = (u32)NextPtr)
+
+#define XBufDescriptor_GetId(InstancePtr) \
+    (u32)(*((u32 *)InstancePtr + XBD_ID_OFFSET))
+
+#define XBufDescriptor_SetId(InstancePtr, Id) \
+    (*((u32 *)InstancePtr + XBD_ID_OFFSET) = (u32)Id)
+
+#define XBufDescriptor_GetFlags(InstancePtr) \
+    (u32)(*((u32 *)InstancePtr + XBD_FLAGS_OFFSET))
+
+#define XBufDescriptor_SetFlags(InstancePtr, Flags) \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) = (u32)Flags)
+
+#define XBufDescriptor_Lock(InstancePtr) \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) |= XBD_FLAGS_LOCKED_MASK)
+
+#define XBufDescriptor_Unlock(InstancePtr) \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) &= ~XBD_FLAGS_LOCKED_MASK)
+
+#define XBufDescriptor_IsLocked(InstancePtr) \
+    (*((u32 *)InstancePtr + XBD_FLAGS_OFFSET) & XBD_FLAGS_LOCKED_MASK)
+
+/************************** Function Prototypes ******************************/
+
+/* The following prototypes are provided to allow each of the functions to
+ * be implemented as a function rather than a macro, and to provide the
+ * syntax to allow users to understand how to call the macros, they are
+ * commented out to prevent linker errors
+ *
+
+u32 XBufDescriptor_Initialize(XBufDescriptor* InstancePtr);
+
+u32 XBufDescriptor_GetControl(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetControl(XBufDescriptor* InstancePtr, u32 Control);
+
+u32 XBufDescriptor_IsLastControl(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetLast(XBufDescriptor* InstancePtr);
+
+u32 XBufDescriptor_GetLength(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetLength(XBufDescriptor* InstancePtr, u32 Length);
+
+u32 XBufDescriptor_GetStatus(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetStatus(XBufDescriptor* InstancePtr, u32 Status);
+u32 XBufDescriptor_IsLastStatus(XBufDescriptor* InstancePtr);
+
+u32 XBufDescriptor_GetDeviceStatus(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetDeviceStatus(XBufDescriptor* InstancePtr,
+				    u32 Status);
+
+u32 XBufDescriptor_GetSrcAddress(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetSrcAddress(XBufDescriptor* InstancePtr,
+				  u32 SourceAddress);
+
+u32 XBufDescriptor_GetDestAddress(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetDestAddress(XBufDescriptor* InstancePtr,
+				   u32 DestinationAddress);
+
+XBufDescriptor* XBufDescriptor_GetNextPtr(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetNextPtr(XBufDescriptor* InstancePtr,
+			       XBufDescriptor* NextPtr);
+
+u32 XBufDescriptor_GetId(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetId(XBufDescriptor* InstancePtr, u32 Id);
+
+u32 XBufDescriptor_GetFlags(XBufDescriptor* InstancePtr);
+void XBufDescriptor_SetFlags(XBufDescriptor* InstancePtr, u32 Flags);
+
+void XBufDescriptor_Lock(XBufDescriptor* InstancePtr);
+void XBufDescriptor_Unlock(XBufDescriptor* InstancePtr);
+u32 XBufDescriptor_IsLocked(XBufDescriptor* InstancePtr);
+
+void XBufDescriptor_Copy(XBufDescriptor* InstancePtr,
+			 XBufDescriptor* DestinationPtr);
+
+*/
+
+#endif				/* end of protection macro */
diff --git a/board/xilinx/common/xdma_channel.c b/board/xilinx/common/xdma_channel.c
new file mode 100644
index 0000000..25f1e26
--- /dev/null
+++ b/board/xilinx/common/xdma_channel.c
@@ -0,0 +1,738 @@
+/******************************************************************************
+*
+*     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.
+*
+* FILENAME:
+*
+* xdma_channel.c
+*
+* DESCRIPTION:
+*
+* This file contains the DMA channel component. This component supports
+* a distributed DMA design in which each device can have it's own dedicated
+* DMA channel, as opposed to a centralized DMA design. This component
+* performs processing for DMA on all devices.
+*
+* See xdma_channel.h for more information about this component.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xdma_channel.h"
+#include "xbasic_types.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_Initialize
+*
+* DESCRIPTION:
+*
+* This function initializes a DMA channel.  This function must be called
+* prior to using a DMA channel.  Initialization of a channel includes setting
+* up the registers base address, and resetting the channel such that it's in a
+* known state.  Interrupts for the channel are disabled when the channel is
+* reset.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* BaseAddress contains the base address of the registers for the DMA channel.
+*
+* RETURN VALUE:
+*
+* XST_SUCCESS indicating initialization was successful.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress)
+{
+	/* assert to verify input arguments, don't assert base address */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	/* setup the base address of the registers for the DMA channel such
+	 * that register accesses can be done
+	 */
+	InstancePtr->RegBaseAddress = BaseAddress;
+
+	/* initialize the scatter gather list such that it indicates it has not
+	 * been created yet and the DMA channel is ready to use (initialized)
+	 */
+	InstancePtr->GetPtr = NULL;
+	InstancePtr->PutPtr = NULL;
+	InstancePtr->CommitPtr = NULL;
+	InstancePtr->LastPtr = NULL;
+
+	InstancePtr->TotalDescriptorCount = 0;
+	InstancePtr->ActiveDescriptorCount = 0;
+	InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+	/* initialize the version of the component
+	 */
+	XVersion_FromString(&InstancePtr->Version, "1.00a");
+
+	/* reset the DMA channel such that it's in a known state and ready
+	 * and indicate the initialization occured with no errors, note that
+	 * the is ready variable must be set before this call or reset will assert
+	 */
+	XDmaChannel_Reset(InstancePtr);
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_IsReady
+*
+* DESCRIPTION:
+*
+* This function determines if a DMA channel component has been successfully
+* initialized such that it's ready to use.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* TRUE if the DMA channel component is ready, FALSE otherwise.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_IsReady(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments used by the base component */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+
+	return InstancePtr->IsReady == XCOMPONENT_IS_READY;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetVersion
+*
+* DESCRIPTION:
+*
+* This function gets the software version for the specified DMA channel
+* component.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* A pointer to the software version of the specified DMA channel.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+XVersion *
+XDmaChannel_GetVersion(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return a pointer to the version of the DMA channel */
+
+	return &InstancePtr->Version;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SelfTest
+*
+* DESCRIPTION:
+*
+* This function performs a self test on the specified DMA channel.  This self
+* test is destructive as the DMA channel is reset and a register default is
+* verified.
+*
+* ARGUMENTS:
+*
+* InstancePtr is a pointer to the DMA channel to be operated on.
+*
+* RETURN VALUE:
+*
+* XST_SUCCESS is returned if the self test is successful, or one of the
+* following errors.
+*
+*	XST_DMA_RESET_REGISTER_ERROR 		Indicates the control register value
+*										after a reset was not correct
+*
+* NOTES:
+*
+* This test does not performs a DMA transfer to test the channel because the
+* DMA hardware will not currently allow a non-local memory transfer to non-local
+* memory (memory copy), but only allows a non-local memory to or from the device
+* memory (typically a FIFO).
+*
+******************************************************************************/
+
+#define XDC_CONTROL_REG_RESET_MASK  0x98000000UL	/* control reg reset value */
+
+XStatus
+XDmaChannel_SelfTest(XDmaChannel * InstancePtr)
+{
+	u32 ControlReg;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* reset the DMA channel such that it's in a known state before the test
+	 * it resets to no interrupts enabled, the desired state for the test
+	 */
+	XDmaChannel_Reset(InstancePtr);
+
+	/* this should be the first test to help prevent a lock up with the polling
+	 * loop that occurs later in the test, check the reset value of the DMA
+	 * control register to make sure it's correct, return with an error if not
+	 */
+	ControlReg = XDmaChannel_GetControl(InstancePtr);
+	if (ControlReg != XDC_CONTROL_REG_RESET_MASK) {
+		return XST_DMA_RESET_REGISTER_ERROR;
+	}
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_Reset
+*
+* DESCRIPTION:
+*
+* This function resets the DMA channel. This is a destructive operation such
+* that it should not be done while a channel is being used.  If the DMA channel
+* is transferring data into other blocks, such as a FIFO, it may be necessary
+* to reset other blocks.  This function does not modify the contents of a
+* scatter gather list for a DMA channel such that the user is responsible for
+* getting buffer descriptors from the list if necessary.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void
+XDmaChannel_Reset(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* reset the DMA channel such that it's in a known state, the reset
+	 * register is self clearing such that it only has to be set
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_RST_REG_OFFSET,
+		  XDC_RESET_MASK);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetControl
+*
+* DESCRIPTION:
+*
+* This function gets the control register contents of the DMA channel.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* The control register contents of the DMA channel. One or more of the
+* following values may be contained the register.  Each of the values are
+* unique bit masks.
+*
+*	XDC_DMACR_SOURCE_INCR_MASK	Increment the source address
+*	XDC_DMACR_DEST_INCR_MASK	Increment the destination address
+*	XDC_DMACR_SOURCE_LOCAL_MASK Local source address
+*	XDC_DMACR_DEST_LOCAL_MASK	Local destination address
+*	XDC_DMACR_SG_ENABLE_MASK	Scatter gather enable
+*	XDC_DMACR_GEN_BD_INTR_MASK	Individual buffer descriptor interrupt
+*	XDC_DMACR_LAST_BD_MASK		Last buffer descriptor in a packet
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_GetControl(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return the contents of the DMA control register */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SetControl
+*
+* DESCRIPTION:
+*
+* This function sets the control register of the specified DMA channel.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* Control contains the value to be written to the control register of the DMA
+* channel. One or more of the following values may be contained the register.
+* Each of the values are unique bit masks such that they may be ORed together
+* to enable multiple bits or inverted and ANDed to disable multiple bits.
+*
+*	XDC_DMACR_SOURCE_INCR_MASK	Increment the source address
+*	XDC_DMACR_DEST_INCR_MASK	Increment the destination address
+*	XDC_DMACR_SOURCE_LOCAL_MASK Local source address
+*	XDC_DMACR_DEST_LOCAL_MASK	Local destination address
+*	XDC_DMACR_SG_ENABLE_MASK	Scatter gather enable
+*	XDC_DMACR_GEN_BD_INTR_MASK	Individual buffer descriptor interrupt
+*	XDC_DMACR_LAST_BD_MASK		Last buffer descriptor in a packet
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void
+XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control)
+{
+	/* assert to verify input arguments except the control which can't be
+	 * asserted since all values are valid
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the DMA control register to the specified value */
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET, Control);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetStatus
+*
+* DESCRIPTION:
+*
+* This function gets the status register contents of the DMA channel.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* The status register contents of the DMA channel. One or more of the
+* following values may be contained the register. Each of the values are
+* unique bit masks.
+*
+*	XDC_DMASR_BUSY_MASK			The DMA channel is busy
+*	XDC_DMASR_BUS_ERROR_MASK	A bus error occurred
+*	XDC_DMASR_BUS_TIMEOUT_MASK	A bus timeout occurred
+*	XDC_DMASR_LAST_BD_MASK		The last buffer descriptor of a packet
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_GetStatus(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return the contents of the DMA status register */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SetIntrStatus
+*
+* DESCRIPTION:
+*
+* This function sets the interrupt status register of the specified DMA channel.
+* Setting any bit of the interrupt status register will clear the bit to
+* indicate the interrupt processing has been completed. The definitions of each
+* bit in the register match the definition of the bits in the interrupt enable
+* register.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* Status contains the value to be written to the status register of the DMA
+* channel.  One or more of the following values may be contained the register.
+* Each of the values are unique bit masks such that they may be ORed together
+* to enable multiple bits or inverted and ANDed to disable multiple bits.
+*
+*	XDC_IXR_DMA_DONE_MASK		The dma operation is done
+*	XDC_IXR_DMA_ERROR_MASK	    The dma operation had an error
+*	XDC_IXR_PKT_DONE_MASK	    A packet is complete
+*	XDC_IXR_PKT_THRESHOLD_MASK 	The packet count threshold reached
+*	XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
+*	XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
+*	XDC_IXR_BD_MASK				A buffer descriptor is done
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void
+XDmaChannel_SetIntrStatus(XDmaChannel * InstancePtr, u32 Status)
+{
+	/* assert to verify input arguments except the status which can't be
+	 * asserted since all values are valid
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the interrupt status register with the specified value such that
+	 * all bits which are set in the register are cleared effectively clearing
+	 * any active interrupts
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET, Status);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetIntrStatus
+*
+* DESCRIPTION:
+*
+* This function gets the interrupt status register of the specified DMA channel.
+* The interrupt status register indicates which interrupts are active
+* for the DMA channel.  If an interrupt is active, the status register must be
+* set (written) with the bit set for each interrupt which has been processed
+* in order to clear the interrupts.  The definitions of each bit in the register
+* match the definition of the bits in the interrupt enable register.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* The interrupt status register contents of the specified DMA channel.
+* One or more of the following values may be contained the register.
+* Each of the values are unique bit masks.
+*
+*	XDC_IXR_DMA_DONE_MASK		The dma operation is done
+*	XDC_IXR_DMA_ERROR_MASK	    The dma operation had an error
+*	XDC_IXR_PKT_DONE_MASK	    A packet is complete
+*	XDC_IXR_PKT_THRESHOLD_MASK 	The packet count threshold reached
+*	XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
+*	XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
+*	XDC_IXR_SG_END_MASK			Current descriptor was the end of the list
+*	XDC_IXR_BD_MASK				A buffer descriptor is done
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_GetIntrStatus(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return the contents of the interrupt status register */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SetIntrEnable
+*
+* DESCRIPTION:
+*
+* This function sets the interrupt enable register of the specified DMA
+* channel.  The interrupt enable register contains bits which enable
+* individual interrupts for the DMA channel.  The definitions of each bit
+* in the register match the definition of the bits in the interrupt status
+* register.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* Enable contains the interrupt enable register contents to be written
+* in the DMA channel. One or more of the following values may be contained
+* the register. Each of the values are unique bit masks such that they may be
+* ORed together to enable multiple bits or inverted and ANDed to disable
+* multiple bits.
+*
+*	XDC_IXR_DMA_DONE_MASK		The dma operation is done
+*	XDC_IXR_DMA_ERROR_MASK	    The dma operation had an error
+*	XDC_IXR_PKT_DONE_MASK	    A packet is complete
+*	XDC_IXR_PKT_THRESHOLD_MASK 	The packet count threshold reached
+*	XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
+*	XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
+*	XDC_IXR_SG_END_MASK			Current descriptor was the end of the list
+*	XDC_IXR_BD_MASK				A buffer descriptor is done
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void
+XDmaChannel_SetIntrEnable(XDmaChannel * InstancePtr, u32 Enable)
+{
+	/* assert to verify input arguments except the enable which can't be
+	 * asserted since all values are valid
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the interrupt enable register to the specified value */
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET, Enable);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetIntrEnable
+*
+* DESCRIPTION:
+*
+* This function gets the interrupt enable of the DMA channel.  The
+* interrupt enable contains flags which enable individual interrupts for the
+* DMA channel. The definitions of each bit in the register match the definition
+* of the bits in the interrupt status register.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* RETURN VALUE:
+*
+* The interrupt enable of the DMA channel.  One or more of the following values
+* may be contained the register. Each of the values are unique bit masks.
+*
+*	XDC_IXR_DMA_DONE_MASK		The dma operation is done
+*	XDC_IXR_DMA_ERROR_MASK	    The dma operation had an error
+*	XDC_IXR_PKT_DONE_MASK	    A packet is complete
+*	XDC_IXR_PKT_THRESHOLD_MASK 	The packet count threshold reached
+*	XDC_IXR_PKT_WAIT_BOUND_MASK The packet wait bound reached
+*	XDC_IXR_SG_DISABLE_ACK_MASK The scatter gather disable completed
+*	XDC_IXR_BD_MASK				A buffer descriptor is done
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_GetIntrEnable(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* return the contents of the interrupt enable register */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_IE_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_Transfer
+*
+* DESCRIPTION:
+*
+* This function starts the DMA channel transferring data from a memory source
+* to a memory destination. This function only starts the operation and returns
+* before the operation may be complete.  If the interrupt is enabled, an
+* interrupt will be generated when the operation is complete, otherwise it is
+* necessary to poll the channel status to determine when it's complete.  It is
+* the responsibility of the caller to determine when the operation is complete
+* by handling the generated interrupt or polling the status.  It is also the
+* responsibility of the caller to ensure that the DMA channel is not busy with
+* another transfer before calling this function.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.
+*
+* SourcePtr contains a pointer to the source memory where the data is to
+* be tranferred from and must be 32 bit aligned.
+*
+* DestinationPtr contains a pointer to the destination memory where the data
+* is to be transferred and must be 32 bit aligned.
+*
+* ByteCount contains the number of bytes to transfer during the DMA operation.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* The DMA h/w will not currently allow a non-local memory transfer to non-local
+* memory (memory copy), but only allows a non-local memory to or from the device
+* memory (typically a FIFO).
+*
+* It is the responsibility of the caller to ensure that the cache is
+* flushed and invalidated both before and after the DMA operation completes
+* if the memory pointed to is cached. The caller must also ensure that the
+* pointers contain a physical address rather than a virtual address
+* if address translation is being used.
+*
+******************************************************************************/
+void
+XDmaChannel_Transfer(XDmaChannel * InstancePtr,
+		     u32 * SourcePtr, u32 * DestinationPtr, u32 ByteCount)
+{
+	/* assert to verify input arguments and the alignment of any arguments
+	 * which have expected alignments
+	 */
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(SourcePtr != NULL);
+	XASSERT_VOID(((u32) SourcePtr & 3) == 0);
+	XASSERT_VOID(DestinationPtr != NULL);
+	XASSERT_VOID(((u32) DestinationPtr & 3) == 0);
+	XASSERT_VOID(ByteCount != 0);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* setup the source and destination address registers for the transfer */
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_SA_REG_OFFSET,
+		  (u32) SourcePtr);
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_DA_REG_OFFSET,
+		  (u32) DestinationPtr);
+
+	/* start the DMA transfer to copy from the source buffer to the
+	 * destination buffer by writing the length to the length register
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_LEN_REG_OFFSET, ByteCount);
+}
diff --git a/board/xilinx/common/xdma_channel.h b/board/xilinx/common/xdma_channel.h
new file mode 100644
index 0000000..06976c3
--- /dev/null
+++ b/board/xilinx/common/xdma_channel.h
@@ -0,0 +1,291 @@
+/******************************************************************************
+*
+*     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.
+*
+* FILENAME:
+*
+* xdma_channel.h
+*
+* DESCRIPTION:
+*
+* This file contains the DMA channel component implementation. This component
+* supports a distributed DMA design in which each device can have it's own
+* dedicated DMA channel, as opposed to a centralized DMA design.
+* A device which uses DMA typically contains two DMA channels, one for
+* sending data and the other for receiving data.
+*
+* This component is designed to be used as a basic building block for
+* designing a device driver. It provides registers accesses such that all
+* DMA processing can be maintained easier, but the device driver designer
+* must still understand all the details of the DMA channel.
+*
+* The DMA channel allows a CPU to minimize the CPU interaction required to move
+* data between a memory and a device.  The CPU requests the DMA channel to
+* perform a DMA operation and typically continues performing other processing
+* until the DMA operation completes.  DMA could be considered a primitive form
+* of multiprocessing such that caching and address translation can be an issue.
+*
+* Scatter Gather Operations
+*
+* The DMA channel may support scatter gather operations. A scatter gather
+* operation automates the DMA channel such that multiple buffers can be
+* sent or received with minimal software interaction with the hardware.  Buffer
+* descriptors, contained in the XBufDescriptor component, are used by the
+* scatter gather operations of the DMA channel to describe the buffers to be
+* processed.
+*
+* Scatter Gather List Operations
+*
+* A scatter gather list may be supported by each DMA channel.  The scatter
+* gather list allows buffer descriptors to be put into the list by a device
+* driver which requires scatter gather.  The hardware processes the buffer
+* descriptors which are contained in the list and modifies the buffer
+* descriptors to reflect the status of the DMA operations.  The device driver
+* is notified by interrupt that specific DMA events occur including scatter
+* gather events.  The device driver removes the completed buffer descriptors
+* from the scatter gather list to evaluate the status of each DMA operation.
+*
+* The scatter gather list is created and buffer descriptors are inserted into
+* the list.  Buffer descriptors are never removed from the list after it's
+* creation such that a put operation copies from a temporary buffer descriptor
+* to a buffer descriptor in the list.  Get operations don't copy from the list
+* to a temporary, but return a pointer to the buffer descriptor in the list.
+* A buffer descriptor in the list may be locked to prevent it from being
+* overwritten by a put operation.  This allows the device driver to get a
+* descriptor from a scatter gather list and prevent it from being overwritten
+* until the buffer associated with the buffer descriptor has been processed.
+*
+* Typical Scatter Gather Processing
+*
+* The following steps illustrate the typical processing to use the
+* scatter gather features of a DMA channel.
+*
+* 1. Create a scatter gather list for the DMA channel which puts empty buffer
+*    descriptors into the list.
+* 2. Create buffer descriptors which describe the buffers to be filled with
+* 	 receive data or the buffers which contain data to be sent.
+* 3. Put buffer descriptors into the DMA channel scatter list such that scatter
+*    gather operations are requested.
+* 4. Commit the buffer descriptors in the list such that they are ready to be
+*    used by the DMA channel hardware.
+* 5. Start the scatter gather operations of the DMA channel.
+* 6. Process any interrupts which occur as a result of the scatter gather
+*    operations or poll the DMA channel to determine the status.
+*
+* Interrupts
+*
+* Each DMA channel has the ability to generate an interrupt.  This component
+* does not perform processing for the interrupt as this processing is typically
+* tightly coupled with the device which is using the DMA channel.  It is the
+* responsibility of the caller of DMA functions to manage the interrupt
+* including connecting to the interrupt and enabling/disabling the interrupt.
+*
+* Critical Sections
+*
+* It is the responsibility of the device driver designer to use critical
+* sections as necessary when calling functions of the DMA channel.  This
+* component does not use critical sections and it does access registers using
+* read-modify-write operations.  Calls to DMA functions from a main thread
+* and from an interrupt context could produce unpredictable behavior such that
+* the caller must provide the appropriate critical sections.
+*
+* Address Translation
+*
+* All addresses of data structures which are passed to DMA functions must
+* be physical (real) addresses as opposed to logical (virtual) addresses.
+*
+* Caching
+*
+* The memory which is passed to the function which creates the scatter gather
+* list must not be cached such that buffer descriptors are non-cached.  This
+* is necessary because the buffer descriptors are kept in a ring buffer and
+* not directly accessible to the caller of DMA functions.
+*
+* The caller of DMA functions is responsible for ensuring that any data
+* buffers which are passed to the DMA channel are cache-line aligned if
+* necessary.
+*
+* The caller of DMA functions is responsible for ensuring that any data
+* buffers which are passed to the DMA channel have been flushed from the cache.
+*
+* The caller of DMA functions is responsible for ensuring that the cache is
+* invalidated prior to using any data buffers which are the result of a DMA
+* operation.
+*
+* Memory Alignment
+*
+* The addresses of data buffers which are passed to DMA functions must be
+* 32 bit word aligned since the DMA hardware performs 32 bit word transfers.
+*
+* Mutual Exclusion
+*
+* The functions of the DMA channel are not thread safe such that the caller
+* of all DMA functions is responsible for ensuring mutual exclusion for a
+* DMA channel.  Mutual exclusion across multiple DMA channels is not
+* necessary.
+*
+* NOTES:
+*
+* Many of the provided functions which are register accessors don't provide
+* a lot of error detection. The caller is expected to understand the impact
+* of a function call based upon the current state of the DMA channel.  This
+* is done to minimize the overhead in this component.
+*
+******************************************************************************/
+
+#ifndef XDMA_CHANNEL_H		/* prevent circular inclusions */
+#define XDMA_CHANNEL_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xdma_channel_i.h"	/* constants shared with buffer descriptor */
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xversion.h"
+#include "xbuf_descriptor.h"
+
+/************************** Constant Definitions *****************************/
+
+/* the following constants provide access to the bit fields of the DMA control
+ * register (DMACR)
+ */
+#define XDC_DMACR_SOURCE_INCR_MASK	0x80000000UL	/* increment source address */
+#define XDC_DMACR_DEST_INCR_MASK	0x40000000UL	/* increment dest address */
+#define XDC_DMACR_SOURCE_LOCAL_MASK 0x20000000UL	/* local source address */
+#define XDC_DMACR_DEST_LOCAL_MASK	0x10000000UL	/* local dest address */
+#define XDC_DMACR_SG_DISABLE_MASK	0x08000000UL	/* scatter gather disable */
+#define XDC_DMACR_GEN_BD_INTR_MASK	0x04000000UL	/* descriptor interrupt */
+#define XDC_DMACR_LAST_BD_MASK		XDC_CONTROL_LAST_BD_MASK	/* last buffer */
+															 /*     descriptor  */
+
+/* the following constants provide access to the bit fields of the DMA status
+ * register (DMASR)
+ */
+#define XDC_DMASR_BUSY_MASK			0x80000000UL	/* channel is busy */
+#define XDC_DMASR_BUS_ERROR_MASK	0x40000000UL	/* bus error occurred */
+#define XDC_DMASR_BUS_TIMEOUT_MASK	0x20000000UL	/* bus timeout occurred */
+#define XDC_DMASR_LAST_BD_MASK		XDC_STATUS_LAST_BD_MASK	/* last buffer */
+														    /* descriptor  */
+#define XDC_DMASR_SG_BUSY_MASK		0x08000000UL	/* scatter gather is busy */
+
+/* the following constants provide access to the bit fields of the interrupt
+ * status register (ISR) and the interrupt enable register (IER), bit masks
+ * match for both registers such that they are named IXR
+ */
+#define XDC_IXR_DMA_DONE_MASK		0x1UL	/* dma operation done */
+#define XDC_IXR_DMA_ERROR_MASK	    0x2UL	/* dma operation error */
+#define XDC_IXR_PKT_DONE_MASK	    0x4UL	/* packet done */
+#define XDC_IXR_PKT_THRESHOLD_MASK 	0x8UL	/* packet count threshold */
+#define XDC_IXR_PKT_WAIT_BOUND_MASK 0x10UL	/* packet wait bound reached */
+#define XDC_IXR_SG_DISABLE_ACK_MASK 0x20UL	/* scatter gather disable
+						   acknowledge occurred */
+#define XDC_IXR_SG_END_MASK			0x40UL	/* last buffer descriptor
+							   disabled scatter gather */
+#define XDC_IXR_BD_MASK				0x80UL	/* buffer descriptor done */
+
+/**************************** Type Definitions *******************************/
+
+/*
+ * the following structure contains data which is on a per instance basis
+ * for the XDmaChannel component
+ */
+typedef struct XDmaChannelTag {
+	XVersion Version;	/* version of the driver */
+	u32 RegBaseAddress;	/* base address of registers */
+	u32 IsReady;		/* device is initialized and ready */
+
+	XBufDescriptor *PutPtr;	/* keep track of where to put into list */
+	XBufDescriptor *GetPtr;	/* keep track of where to get from list */
+	XBufDescriptor *CommitPtr;	/* keep track of where to commit in list */
+	XBufDescriptor *LastPtr;	/* keep track of the last put in the list */
+	u32 TotalDescriptorCount;	/* total # of descriptors in the list */
+	u32 ActiveDescriptorCount;	/* # of descriptors pointing to buffers
+					   * in the buffer descriptor list */
+} XDmaChannel;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+XStatus XDmaChannel_Initialize(XDmaChannel * InstancePtr, u32 BaseAddress);
+u32 XDmaChannel_IsReady(XDmaChannel * InstancePtr);
+XVersion *XDmaChannel_GetVersion(XDmaChannel * InstancePtr);
+XStatus XDmaChannel_SelfTest(XDmaChannel * InstancePtr);
+void XDmaChannel_Reset(XDmaChannel * InstancePtr);
+
+/* Control functions */
+
+u32 XDmaChannel_GetControl(XDmaChannel * InstancePtr);
+void XDmaChannel_SetControl(XDmaChannel * InstancePtr, u32 Control);
+
+/* Status functions */
+
+u32 XDmaChannel_GetStatus(XDmaChannel * InstancePtr);
+void XDmaChannel_SetIntrStatus(XDmaChannel * InstancePtr, u32 Status);
+u32 XDmaChannel_GetIntrStatus(XDmaChannel * InstancePtr);
+void XDmaChannel_SetIntrEnable(XDmaChannel * InstancePtr, u32 Enable);
+u32 XDmaChannel_GetIntrEnable(XDmaChannel * InstancePtr);
+
+/* DMA without scatter gather functions */
+
+void XDmaChannel_Transfer(XDmaChannel * InstancePtr,
+			  u32 * SourcePtr, u32 * DestinationPtr, u32 ByteCount);
+
+/* Scatter gather functions */
+
+XStatus XDmaChannel_SgStart(XDmaChannel * InstancePtr);
+XStatus XDmaChannel_SgStop(XDmaChannel * InstancePtr,
+			   XBufDescriptor ** BufDescriptorPtr);
+XStatus XDmaChannel_CreateSgList(XDmaChannel * InstancePtr,
+				 u32 * MemoryPtr, u32 ByteCount);
+u32 XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr);
+
+XStatus XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr,
+				  XBufDescriptor * BufDescriptorPtr);
+XStatus XDmaChannel_CommitPuts(XDmaChannel * InstancePtr);
+XStatus XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr,
+				  XBufDescriptor ** BufDescriptorPtr);
+
+/* Packet functions for interrupt collescing */
+
+u32 XDmaChannel_GetPktCount(XDmaChannel * InstancePtr);
+void XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr);
+XStatus XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold);
+u8 XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr);
+void XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound);
+u32 XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr);
+
+#endif				/* end of protection macro */
diff --git a/board/xilinx/common/xdma_channel_i.h b/board/xilinx/common/xdma_channel_i.h
new file mode 100644
index 0000000..e9f343b
--- /dev/null
+++ b/board/xilinx/common/xdma_channel_i.h
@@ -0,0 +1,110 @@
+/******************************************************************************
+*
+*     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.
+*
+* FILENAME:
+*
+* xdma_channel_i.h
+*
+* DESCRIPTION:
+*
+* This file contains data which is shared internal data for the DMA channel
+* component. It is also shared with the buffer descriptor component which is
+* very tightly coupled with the DMA channel component.
+*
+* NOTES:
+*
+* The last buffer descriptor constants must be located here to prevent a
+* circular dependency between the DMA channel component and the buffer
+* descriptor component.
+*
+******************************************************************************/
+
+#ifndef XDMA_CHANNEL_I_H	/* prevent circular inclusions */
+#define XDMA_CHANNEL_I_H	/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xversion.h"
+
+/************************** Constant Definitions *****************************/
+
+#define XDC_DMA_CHANNEL_V1_00_A		"1.00a"
+
+/* the following constant provides access to the bit fields of the DMA control
+ * register (DMACR) which must be shared between the DMA channel component
+ * and the buffer descriptor component
+ */
+#define XDC_CONTROL_LAST_BD_MASK	0x02000000UL	/* last buffer descriptor */
+
+/* the following constant provides access to the bit fields of the DMA status
+ * register (DMASR) which must be shared between the DMA channel component
+ * and the buffer descriptor component
+ */
+#define XDC_STATUS_LAST_BD_MASK		0x10000000UL	/* last buffer descriptor */
+
+/* the following constants provide access to each of the registers of a DMA
+ * channel
+ */
+#define XDC_RST_REG_OFFSET	0	/* reset register */
+#define XDC_MI_REG_OFFSET	0	/* module information register */
+#define XDC_DMAC_REG_OFFSET	4	/* DMA control register */
+#define XDC_SA_REG_OFFSET	8	/* source address register */
+#define XDC_DA_REG_OFFSET	12	/* destination address register */
+#define XDC_LEN_REG_OFFSET	16	/* length register */
+#define XDC_DMAS_REG_OFFSET	20	/* DMA status register */
+#define XDC_BDA_REG_OFFSET	24	/* buffer descriptor address register */
+#define XDC_SWCR_REG_OFFSET 28	/* software control register */
+#define XDC_UPC_REG_OFFSET	32	/* unserviced packet count register */
+#define	XDC_PCT_REG_OFFSET	36	/* packet count threshold register */
+#define XDC_PWB_REG_OFFSET	40	/* packet wait bound register */
+#define XDC_IS_REG_OFFSET	44	/* interrupt status register */
+#define XDC_IE_REG_OFFSET	48	/* interrupt enable register */
+
+/* the following constant is written to the reset register to reset the
+ * DMA channel
+ */
+#define XDC_RESET_MASK				0x0000000AUL
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+#endif				/* end of protection macro */
diff --git a/board/xilinx/common/xdma_channel_sg.c b/board/xilinx/common/xdma_channel_sg.c
new file mode 100644
index 0000000..a8e9462
--- /dev/null
+++ b/board/xilinx/common/xdma_channel_sg.c
@@ -0,0 +1,1317 @@
+/* $Id: xdma_channel_sg.c,v 1.6 2003/02/03 19:50:33 moleres Exp $ */
+/******************************************************************************
+*
+*     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.
+*
+* FILENAME:
+*
+* xdma_channel_sg.c
+*
+* DESCRIPTION:
+*
+* This file contains the implementation of the XDmaChannel component which is
+* related to scatter gather operations.
+*
+* Scatter Gather Operations
+*
+* The DMA channel may support scatter gather operations. A scatter gather
+* operation automates the DMA channel such that multiple buffers can be
+* sent or received with minimal software interaction with the hardware.	 Buffer
+* descriptors, contained in the XBufDescriptor component, are used by the
+* scatter gather operations of the DMA channel to describe the buffers to be
+* processed.
+*
+* Scatter Gather List Operations
+*
+* A scatter gather list may be supported by each DMA channel.  The scatter
+* gather list allows buffer descriptors to be put into the list by a device
+* driver which requires scatter gather.	 The hardware processes the buffer
+* descriptors which are contained in the list and modifies the buffer
+* descriptors to reflect the status of the DMA operations.  The device driver
+* is notified by interrupt that specific DMA events occur including scatter
+* gather events.  The device driver removes the completed buffer descriptors
+* from the scatter gather list to evaluate the status of each DMA operation.
+*
+* The scatter gather list is created and buffer descriptors are inserted into
+* the list.  Buffer descriptors are never removed from the list after it's
+* creation such that a put operation copies from a temporary buffer descriptor
+* to a buffer descriptor in the list.  Get operations don't copy from the list
+* to a temporary, but return a pointer to the buffer descriptor in the list.
+* A buffer descriptor in the list may be locked to prevent it from being
+* overwritten by a put operation.  This allows the device driver to get a
+* descriptor from a scatter gather list and prevent it from being overwritten
+* until the buffer associated with the buffer descriptor has been processed.
+*
+* The get and put functions only operate on the list and are asynchronous from
+* the hardware which may be using the list of descriptors.  This is important
+* because there are no checks in the get and put functions to ensure that the
+* hardware has processed the descriptors.  This must be handled by the driver
+* using the DMA scatter gather channel through the use of the other functions.
+* When a scatter gather operation is started, the start function does ensure
+* that the descriptor to start has not already been processed by the hardware
+* and is not the first of a series of descriptors that have not been committed
+* yet.
+*
+* Descriptors are put into the list but not marked as ready to use by the
+* hardware until a commit operation is done.  This allows multiple descriptors
+* which may contain a single packet of information for a protocol to be
+* guaranteed not to cause any underflow conditions during transmission. The
+* hardware design only allows descriptors to cause it to stop after a descriptor
+* has been processed rather than before it is processed.  A series of
+* descriptors are put into the list followed by a commit operation, or each
+* descriptor may be commited.  A commit operation is performed by changing a
+* single descriptor, the first of the series of puts, to indicate that the
+* hardware may now use all descriptors after it.  The last descriptor in the
+* list is always set to cause the hardware to stop after it is processed.
+*
+* Typical Scatter Gather Processing
+*
+* The following steps illustrate the typical processing to use the
+* scatter gather features of a DMA channel.
+*
+* 1. Create a scatter gather list for the DMA channel which puts empty buffer
+*    descriptors into the list.
+* 2. Create buffer descriptors which describe the buffers to be filled with
+*    receive data or the buffers which contain data to be sent.
+* 3. Put buffer descriptors into the DMA channel scatter list such that scatter
+*    gather operations are requested.
+* 4. Commit the buffer descriptors in the list such that they are ready to be
+*    used by the DMA channel hardware.
+* 5. Start the scatter gather operations of the DMA channel.
+* 6. Process any interrupts which occur as a result of the scatter gather
+*    operations or poll the DMA channel to determine the status.  This may
+*    be accomplished by getting the packet count for the channel and then
+*    getting the appropriate number of descriptors from the list for that
+*    number of packets.
+*
+* Minimizing Interrupts
+*
+* The Scatter Gather operating mode is designed to reduce the amount of CPU
+* throughput necessary to manage the hardware for devices. A key to the CPU
+* throughput is the number and rate of interrupts that the CPU must service.
+* Devices with higher data rates can cause larger numbers of interrupts and
+* higher frequency interrupts. Ideally the number of interrupts can be reduced
+* by only generating an interrupt when a specific amount of data has been
+* received from the interface. This design suffers from a lack of interrupts
+* when the amount of data received is less than the specified amount of data
+* to generate an interrupt. In order to help minimize the number of interrupts
+* which the CPU must service, an algorithm referred to as "interrupt coalescing"
+* is utilized.
+*
+* Interrupt Coalescing
+*
+* The principle of interrupt coalescing is to wait before generating an
+* interrupt until a certain number of packets have been received or sent. An
+* interrupt is also generated if a smaller number of packets have been received
+* followed by a certain period of time with no packet reception. This is a
+* trade-off of latency for bandwidth and is accomplished using several
+* mechanisms of the hardware including a counter for packets received or
+* transmitted and a packet timer. These two hardware mechanisms work in
+* combination to allow a reduction in the number of interrupts processed by the
+* CPU for packet reception.
+*
+* Unserviced Packet Count
+*
+* The purpose of the packet counter is to count the number of packets received
+* or transmitted and provide an interrupt when a specific number of packets
+* have been processed by the hardware. An interrupt is generated whenever the
+* counter is greater than or equal to the Packet Count Threshold. This counter
+* contains an accurate count of the number of packets that the hardware has
+* processed, either received or transmitted, and the software has not serviced.
+*
+* The packet counter allows the number of interrupts to be reduced by waiting
+* to generate an interrupt until enough packets are received. For packet
+* reception, packet counts of less than the number to generate an interrupt
+* would not be serviced without the addition of a packet timer. This counter is
+* continuously updated by the hardware, not latched to the value at the time
+* the interrupt occurred.
+*
+* The packet counter can be used within the interrupt service routine for the
+* device to reduce the number of interrupts. The interrupt service routine
+* loops while performing processing for each packet which has been received or
+* transmitted and decrements the counter by a specified value. At the same time,
+* the hardware is possibly continuing to receive or transmit more packets such
+* that the software may choose, based upon the value in the packet counter, to
+* remain in the interrupt service routine rather than exiting and immediately
+* returning. This feature should be used with caution as reducing the number of
+* interrupts is beneficial, but unbounded interrupt processing is not desirable.
+*
+* Since the hardware may be incrementing the packet counter simultaneously
+* with the software decrementing the counter, there is a need for atomic
+* operations. The hardware ensures that the operation is atomic such that
+* simultaneous accesses are properly handled.
+*
+* Packet Wait Bound
+*
+* The purpose of the packet wait bound is to augment the unserviced packet
+* count. Whenever there is no pending interrupt for the channel and the
+* unserviced packet count is non-zero, a timer starts counting timeout at the
+* value contained the the packet wait bound register.  If the timeout is
+* reached, an interrupt is generated such that the software may service the
+* data which was buffered.
+*
+* NOTES:
+*
+* Special Test Conditions:
+*
+* The scatter gather list processing must be thoroughly tested if changes are
+* made.	 Testing should include putting and committing single descriptors and
+* putting multiple descriptors followed by a single commit.  There are some
+* conditions in the code which handle the exception conditions.
+*
+* The Put Pointer points to the next location in the descriptor list to copy
+* in a new descriptor. The Get Pointer points to the next location in the
+* list to get a descriptor from.  The Get Pointer only allows software to
+* have a traverse the list after the hardware has finished processing some
+* number of descriptors.  The Commit Pointer points to the descriptor in the
+* list which is to be committed.  It is also used to determine that no
+* descriptor is waiting to be commited (NULL).	The Last Pointer points to
+* the last descriptor that was put into the list.  It typically points
+* to the previous descriptor to the one pointed to by the Put Pointer.
+* Comparisons are done between these pointers to determine when the following
+* special conditions exist.
+
+* Single Put And Commit
+*
+* The buffer descriptor is ready to be used by the hardware so it is important
+* for the descriptor to not appear to be waiting to be committed.  The commit
+* pointer is reset when a commit is done indicating there are no descriptors
+* waiting to be committed.  In all cases but this one, the descriptor is
+* changed to cause the hardware to go to the next descriptor after processing
+* this one.  But in this case, this is the last descriptor in the list such
+* that it must not be changed.
+*
+* 3 Or More Puts And Commit
+*
+* A series of 3 or more puts followed by a single commit is different in that
+* only the 1st descriptor put into the list is changed when the commit is done.
+* This requires each put starting on the 3rd to change the previous descriptor
+* so that it allows the hardware to continue to the next descriptor in the list.
+*
+* The 1st Put Following A Commit
+*
+* The commit caused the commit pointer to be NULL indicating that there are no
+* descriptors waiting to be committed.	It is necessary for the next put to set
+* the commit pointer so that a commit must follow the put for the hardware to
+* use the descriptor.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver	Who  Date     Changes
+* ----- ---- -------- ------------------------------------------------------
+* 1.00a rpm  02/03/03 Removed the XST_DMA_SG_COUNT_EXCEEDED return code
+*		      from SetPktThreshold.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xdma_channel.h"
+#include "xbasic_types.h"
+#include "xio.h"
+#include "xbuf_descriptor.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+#define XDC_SWCR_SG_ENABLE_MASK 0x80000000UL	/* scatter gather enable */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/* the following macro copies selected fields of a buffer descriptor to another
+ * buffer descriptor, this was provided by the buffer descriptor component but
+ * was moved here since it is only used internally to this component and since
+ * it does not copy all fields
+ */
+#define CopyBufferDescriptor(InstancePtr, DestinationPtr)	   \
+{								   \
+    *((u32 *)DestinationPtr + XBD_CONTROL_OFFSET) =	       \
+	*((u32 *)InstancePtr + XBD_CONTROL_OFFSET);	       \
+    *((u32 *)DestinationPtr + XBD_SOURCE_OFFSET) =	       \
+	*((u32 *)InstancePtr + XBD_SOURCE_OFFSET);	       \
+    *((u32 *)DestinationPtr + XBD_DESTINATION_OFFSET) =	       \
+	*((u32 *)InstancePtr + XBD_DESTINATION_OFFSET);	       \
+    *((u32 *)DestinationPtr + XBD_LENGTH_OFFSET) =	       \
+	*((u32 *)InstancePtr + XBD_LENGTH_OFFSET);	       \
+    *((u32 *)DestinationPtr + XBD_STATUS_OFFSET) =	       \
+	*((u32 *)InstancePtr + XBD_STATUS_OFFSET);	       \
+    *((u32 *)DestinationPtr + XBD_DEVICE_STATUS_OFFSET) =      \
+	*((u32 *)InstancePtr + XBD_DEVICE_STATUS_OFFSET);      \
+    *((u32 *)DestinationPtr + XBD_ID_OFFSET) =		       \
+	*((u32 *)InstancePtr + XBD_ID_OFFSET);		       \
+    *((u32 *)DestinationPtr + XBD_FLAGS_OFFSET) =	       \
+	*((u32 *)InstancePtr + XBD_FLAGS_OFFSET);	       \
+    *((u32 *)DestinationPtr + XBD_RQSTED_LENGTH_OFFSET) =      \
+	*((u32 *)InstancePtr + XBD_RQSTED_LENGTH_OFFSET);      \
+}
+
+/************************** Variable Definitions *****************************/
+
+/************************** Function Prototypes ******************************/
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SgStart
+*
+* DESCRIPTION:
+*
+* This function starts a scatter gather operation for a scatter gather
+* DMA channel.	The first buffer descriptor in the buffer descriptor list
+* will be started with the scatter gather operation.  A scatter gather list
+* should have previously been created for the DMA channel and buffer
+* descriptors put into the scatter gather list such that there are scatter
+* operations ready to be performed.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* A status containing XST_SUCCESS if scatter gather was started successfully
+* for the DMA channel.
+*
+* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
+* been created.
+*
+* A value of XST_DMA_SG_LIST_EMPTY indicates scatter gather was not started
+* because the scatter gather list of the DMA channel does not contain any
+* buffer descriptors that are ready to be processed by the hardware.
+*
+* A value of XST_DMA_SG_IS_STARTED indicates scatter gather was not started
+* because the scatter gather was not stopped, but was already started.
+*
+* A value of XST_DMA_SG_BD_NOT_COMMITTED indicates the buffer descriptor of
+* scatter gather list which was to be started is not committed to the list.
+* This status is more likely if this function is being called from an ISR
+* and non-ISR processing is putting descriptors into the list.
+*
+* A value of XST_DMA_SG_NO_DATA indicates that the buffer descriptor of the
+* scatter gather list which was to be started had already been used by the
+* hardware for a DMA transfer that has been completed.
+*
+* NOTES:
+*
+* It is the responsibility of the caller to get all the buffer descriptors
+* after performing a stop operation and before performing a start operation.
+* If buffer descriptors are not retrieved between stop and start operations,
+* buffer descriptors may be processed by the hardware more than once.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_SgStart(XDmaChannel * InstancePtr)
+{
+	u32 Register;
+	XBufDescriptor *LastDescriptorPtr;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if a scatter gather list has not been created yet, return a status */
+
+	if (InstancePtr->TotalDescriptorCount == 0) {
+		return XST_DMA_SG_NO_LIST;
+	}
+
+	/* if the scatter gather list exists but is empty then return a status */
+
+	if (XDmaChannel_IsSgListEmpty(InstancePtr)) {
+		return XST_DMA_SG_LIST_EMPTY;
+	}
+
+	/* if scatter gather is busy for the DMA channel, return a status because
+	 * restarting it could lose data
+	 */
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAS_REG_OFFSET);
+	if (Register & XDC_DMASR_SG_BUSY_MASK) {
+		return XST_DMA_SG_IS_STARTED;
+	}
+
+	/* get the address of the last buffer descriptor which the DMA hardware
+	 * finished processing
+	 */
+	LastDescriptorPtr =
+	    (XBufDescriptor *) XIo_In32(InstancePtr->RegBaseAddress +
+					XDC_BDA_REG_OFFSET);
+
+	/* setup the first buffer descriptor that will be sent when the scatter
+	 * gather channel is enabled, this is only necessary one time since
+	 * the BDA register of the channel maintains the last buffer descriptor
+	 * processed
+	 */
+	if (LastDescriptorPtr == NULL) {
+		XIo_Out32(InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET,
+			  (u32) InstancePtr->GetPtr);
+	} else {
+		XBufDescriptor *NextDescriptorPtr;
+
+		/* get the next descriptor to be started, if the status indicates it
+		 * hasn't already been used by the h/w, then it's OK to start it,
+		 * s/w sets the status of each descriptor to busy and then h/w clears
+		 * the busy when it is complete
+		 */
+		NextDescriptorPtr =
+		    XBufDescriptor_GetNextPtr(LastDescriptorPtr);
+
+		if ((XBufDescriptor_GetStatus(NextDescriptorPtr) &
+		     XDC_DMASR_BUSY_MASK) == 0) {
+			return XST_DMA_SG_NO_DATA;
+		}
+		/* don't start the DMA SG channel if the descriptor to be processed
+		 * by h/w is to be committed by the s/w, this function can be called
+		 * such that it interrupts a thread that was putting into the list
+		 */
+		if (NextDescriptorPtr == InstancePtr->CommitPtr) {
+			return XST_DMA_SG_BD_NOT_COMMITTED;
+		}
+	}
+
+	/* start the scatter gather operation by clearing the stop bit in the
+	 * control register and setting the enable bit in the s/w control register,
+	 * both of these are necessary to cause it to start, right now the order of
+	 * these statements is important, the software control register should be
+	 * set 1st.  The other order can cause the CPU to have a loss of sync
+	 * because it cannot read/write the register while the DMA operation is
+	 * running
+	 */
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET);
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET,
+		  Register | XDC_SWCR_SG_ENABLE_MASK);
+
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET);
+
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_DMAC_REG_OFFSET,
+		  Register & ~XDC_DMACR_SG_DISABLE_MASK);
+
+	/* indicate the DMA channel scatter gather operation was started
+	 * successfully
+	 */
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SgStop
+*
+* DESCRIPTION:
+*
+* This function stops a scatter gather operation for a scatter gather
+* DMA channel. This function starts the process of stopping a scatter
+* gather operation that is in progress and waits for the stop to be completed.
+* Since it waits for the operation to stopped before returning, this function
+* could take an amount of time relative to the size of the DMA scatter gather
+* operation which is in progress.  The scatter gather list of the DMA channel
+* is not modified by this function such that starting the scatter gather
+* channel after stopping it will cause it to resume.  This operation is
+* considered to be a graceful stop in that the scatter gather operation
+* completes the current buffer descriptor before stopping.
+*
+* If the interrupt is enabled, an interrupt will be generated when the
+* operation is stopped and the caller is responsible for handling the
+* interrupt.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* BufDescriptorPtr is also a return value which contains a pointer to the
+* buffer descriptor which the scatter gather operation completed when it
+* was stopped.
+*
+* RETURN VALUE:
+*
+* A status containing XST_SUCCESS if scatter gather was stopped successfully
+* for the DMA channel.
+*
+* A value of XST_DMA_SG_IS_STOPPED indicates scatter gather was not stoppped
+* because the scatter gather is not started, but was already stopped.
+*
+* BufDescriptorPtr contains a pointer to the buffer descriptor which was
+* completed when the operation was stopped.
+*
+* NOTES:
+*
+* This function implements a loop which polls the hardware for an infinite
+* amount of time. If the hardware is not operating correctly, this function
+* may never return.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_SgStop(XDmaChannel * InstancePtr,
+		   XBufDescriptor ** BufDescriptorPtr)
+{
+	u32 Register;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufDescriptorPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* get the contents of the software control register, if scatter gather is not
+	 * enabled (started), then return a status because the disable acknowledge
+	 * would not be generated
+	 */
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET);
+
+	if ((Register & XDC_SWCR_SG_ENABLE_MASK) == 0) {
+		return XST_DMA_SG_IS_STOPPED;
+	}
+
+	/* Ensure the interrupt status for the scatter gather is cleared such
+	 * that this function will wait til the disable has occurred, writing
+	 * a 1 to only that bit in the register will clear only it
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET,
+		  XDC_IXR_SG_DISABLE_ACK_MASK);
+
+	/* disable scatter gather by writing to the software control register
+	 * without modifying any other bits of the register
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET,
+		  Register & ~XDC_SWCR_SG_ENABLE_MASK);
+
+	/* scatter gather does not disable immediately, but after the current
+	 * buffer descriptor is complete, so wait for the DMA channel to indicate
+	 * the disable is complete
+	 */
+	do {
+		Register =
+		    XIo_In32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET);
+	} while ((Register & XDC_IXR_SG_DISABLE_ACK_MASK) == 0);
+
+	/* Ensure the interrupt status for the scatter gather disable is cleared,
+	 * writing a 1 to only that bit in the register will clear only it
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET,
+		  XDC_IXR_SG_DISABLE_ACK_MASK);
+
+	/* set the specified buffer descriptor pointer to point to the buffer
+	 * descriptor that the scatter gather DMA channel was processing
+	 */
+	*BufDescriptorPtr =
+	    (XBufDescriptor *) XIo_In32(InstancePtr->RegBaseAddress +
+					XDC_BDA_REG_OFFSET);
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_CreateSgList
+*
+* DESCRIPTION:
+*
+* This function creates a scatter gather list in the DMA channel.  A scatter
+* gather list consists of a list of buffer descriptors that are available to
+* be used for scatter gather operations.  Buffer descriptors are put into the
+* list to request a scatter gather operation to be performed.
+*
+* A number of buffer descriptors are created from the specified memory and put
+* into a buffer descriptor list as empty buffer descriptors. This function must
+* be called before non-empty buffer descriptors may be put into the DMA channel
+* to request scatter gather operations.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* MemoryPtr contains a pointer to the memory which is to be used for buffer
+* descriptors and must not be cached.
+*
+* ByteCount contains the number of bytes for the specified memory to be used
+* for buffer descriptors.
+*
+* RETURN VALUE:
+*
+* A status contains XST_SUCCESS if the scatter gather list was successfully
+* created.
+*
+* A value of XST_DMA_SG_LIST_EXISTS indicates that the scatter gather list
+* was not created because the list has already been created.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_CreateSgList(XDmaChannel * InstancePtr,
+			 u32 * MemoryPtr, u32 ByteCount)
+{
+	XBufDescriptor *BufferDescriptorPtr = (XBufDescriptor *) MemoryPtr;
+	XBufDescriptor *PreviousDescriptorPtr = NULL;
+	XBufDescriptor *StartOfListPtr = BufferDescriptorPtr;
+	u32 UsedByteCount;
+
+	/* assert to verify valid input arguments, alignment for those
+	 * arguments that have alignment restrictions, and at least enough
+	 * memory for one buffer descriptor
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(MemoryPtr != NULL);
+	XASSERT_NONVOID(((u32) MemoryPtr & 3) == 0);
+	XASSERT_NONVOID(ByteCount != 0);
+	XASSERT_NONVOID(ByteCount >= sizeof (XBufDescriptor));
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if the scatter gather list has already been created, then return
+	 * with a status
+	 */
+	if (InstancePtr->TotalDescriptorCount != 0) {
+		return XST_DMA_SG_LIST_EXISTS;
+	}
+
+	/* loop thru the specified memory block and create as many buffer
+	 * descriptors as possible putting each into the list which is
+	 * implemented as a ring buffer, make sure not to use any memory which
+	 * is not large enough for a complete buffer descriptor
+	 */
+	UsedByteCount = 0;
+	while ((UsedByteCount + sizeof (XBufDescriptor)) <= ByteCount) {
+		/* setup a pointer to the next buffer descriptor in the memory and
+		 * update # of used bytes to know when all of memory is used
+		 */
+		BufferDescriptorPtr = (XBufDescriptor *) ((u32) MemoryPtr +
+							  UsedByteCount);
+
+		/* initialize the new buffer descriptor such that it doesn't contain
+		 * garbage which could be used by the DMA hardware
+		 */
+		XBufDescriptor_Initialize(BufferDescriptorPtr);
+
+		/* if this is not the first buffer descriptor to be created,
+		 * then link it to the last created buffer descriptor
+		 */
+		if (PreviousDescriptorPtr != NULL) {
+			XBufDescriptor_SetNextPtr(PreviousDescriptorPtr,
+						  BufferDescriptorPtr);
+		}
+
+		/* always keep a pointer to the last created buffer descriptor such
+		 * that they can be linked together in the ring buffer
+		 */
+		PreviousDescriptorPtr = BufferDescriptorPtr;
+
+		/* keep a count of the number of descriptors in the list to allow
+		 * error processing to be performed
+		 */
+		InstancePtr->TotalDescriptorCount++;
+
+		UsedByteCount += sizeof (XBufDescriptor);
+	}
+
+	/* connect the last buffer descriptor created and inserted in the list
+	 * to the first such that a ring buffer is created
+	 */
+	XBufDescriptor_SetNextPtr(BufferDescriptorPtr, StartOfListPtr);
+
+	/* initialize the ring buffer to indicate that there are no
+	 * buffer descriptors in the list which point to valid data buffers
+	 */
+	InstancePtr->PutPtr = BufferDescriptorPtr;
+	InstancePtr->GetPtr = BufferDescriptorPtr;
+	InstancePtr->CommitPtr = NULL;
+	InstancePtr->LastPtr = BufferDescriptorPtr;
+	InstancePtr->ActiveDescriptorCount = 0;
+
+	/* indicate the scatter gather list was successfully created */
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_IsSgListEmpty
+*
+* DESCRIPTION:
+*
+* This function determines if the scatter gather list of a DMA channel is
+* empty with regard to buffer descriptors which are pointing to buffers to be
+* used for scatter gather operations.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* A value of TRUE if the scatter gather list is empty, otherwise a value of
+* FALSE.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_IsSgListEmpty(XDmaChannel * InstancePtr)
+{
+	/* assert to verify valid input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if the number of descriptors which are being used in the list is zero
+	 * then the list is empty
+	 */
+	return (InstancePtr->ActiveDescriptorCount == 0);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_PutDescriptor
+*
+* DESCRIPTION:
+*
+* This function puts a buffer descriptor into the DMA channel scatter
+* gather list. A DMA channel maintains a list of buffer descriptors which are
+* to be processed.  This function puts the specified buffer descriptor
+* at the next location in the list.  Note that since the list is already intact,
+* the information in the parameter is copied into the list (rather than modify
+* list pointers on the fly).
+*
+* After buffer descriptors are put into the list, they must also be committed
+* by calling another function.	This allows multiple buffer descriptors which
+* span a single packet to be put into the list while preventing the hardware
+* from starting the first buffer descriptor of the packet.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* BufferDescriptorPtr is a pointer to the buffer descriptor to be put into
+* the next available location of the scatter gather list.
+*
+* RETURN VALUE:
+*
+* A status which indicates XST_SUCCESS if the buffer descriptor was
+* successfully put into the scatter gather list.
+*
+* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
+* been created.
+*
+* A value of XST_DMA_SG_LIST_FULL indicates the buffer descriptor was not
+* put into the list because the list was full.
+*
+* A value of XST_DMA_SG_BD_LOCKED indicates the buffer descriptor was not
+* put into the list because the buffer descriptor in the list which is to
+* be overwritten was locked.  A locked buffer descriptor indicates the higher
+* layered software is still using the buffer descriptor.
+*
+* NOTES:
+*
+* It is necessary to create a scatter gather list for a DMA channel before
+* putting buffer descriptors into it.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_PutDescriptor(XDmaChannel * InstancePtr,
+			  XBufDescriptor * BufferDescriptorPtr)
+{
+	u32 Control;
+
+	/* assert to verify valid input arguments and alignment for those
+	 * arguments that have alignment restrictions
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufferDescriptorPtr != NULL);
+	XASSERT_NONVOID(((u32) BufferDescriptorPtr & 3) == 0);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if a scatter gather list has not been created yet, return a status */
+
+	if (InstancePtr->TotalDescriptorCount == 0) {
+		return XST_DMA_SG_NO_LIST;
+	}
+
+	/* if the list is full because all descriptors are pointing to valid
+	 * buffers, then indicate an error, this code assumes no list or an
+	 * empty list is detected above
+	 */
+	if (InstancePtr->ActiveDescriptorCount ==
+	    InstancePtr->TotalDescriptorCount) {
+		return XST_DMA_SG_LIST_FULL;
+	}
+
+	/* if the buffer descriptor in the list which is to be overwritten is
+	 * locked, then don't overwrite it and return a status
+	 */
+	if (XBufDescriptor_IsLocked(InstancePtr->PutPtr)) {
+		return XST_DMA_SG_BD_LOCKED;
+	}
+
+	/* set the scatter gather stop bit in the control word of the descriptor
+	 * to cause the h/w to stop after it processes this descriptor since it
+	 * will be the last in the list
+	 */
+	Control = XBufDescriptor_GetControl(BufferDescriptorPtr);
+	XBufDescriptor_SetControl(BufferDescriptorPtr,
+				  Control | XDC_DMACR_SG_DISABLE_MASK);
+
+	/* set both statuses in the descriptor so we tell if they are updated with
+	 * the status of the transfer, the hardware should change the busy in the
+	 * DMA status to be false when it completes
+	 */
+	XBufDescriptor_SetStatus(BufferDescriptorPtr, XDC_DMASR_BUSY_MASK);
+	XBufDescriptor_SetDeviceStatus(BufferDescriptorPtr, 0);
+
+	/* copy the descriptor into the next position in the list so it's ready to
+	 * be used by the h/w, this assumes the descriptor in the list prior to this
+	 * one still has the stop bit in the control word set such that the h/w
+	 * use this one yet
+	 */
+	CopyBufferDescriptor(BufferDescriptorPtr, InstancePtr->PutPtr);
+
+	/* only the last in the list and the one to be committed have scatter gather
+	 * disabled in the control word, a commit requires only one descriptor
+	 * to be changed, when # of descriptors to commit > 2 all others except the
+	 * 1st and last have scatter gather enabled
+	 */
+	if ((InstancePtr->CommitPtr != InstancePtr->LastPtr) &&
+	    (InstancePtr->CommitPtr != NULL)) {
+		Control = XBufDescriptor_GetControl(InstancePtr->LastPtr);
+		XBufDescriptor_SetControl(InstancePtr->LastPtr,
+					  Control & ~XDC_DMACR_SG_DISABLE_MASK);
+	}
+
+	/* update the list data based upon putting a descriptor into the list,
+	 * these operations must be last
+	 */
+	InstancePtr->ActiveDescriptorCount++;
+
+	/* only update the commit pointer if it is not already active, this allows
+	 * it to be deactivated after every commit such that a single descriptor
+	 * which is committed does not appear to be waiting to be committed
+	 */
+	if (InstancePtr->CommitPtr == NULL) {
+		InstancePtr->CommitPtr = InstancePtr->LastPtr;
+	}
+
+	/* these updates MUST BE LAST after the commit pointer update in order for
+	 * the commit pointer to track the correct descriptor to be committed
+	 */
+	InstancePtr->LastPtr = InstancePtr->PutPtr;
+	InstancePtr->PutPtr = XBufDescriptor_GetNextPtr(InstancePtr->PutPtr);
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_CommitPuts
+*
+* DESCRIPTION:
+*
+* This function commits the buffer descriptors which have been put into the
+* scatter list for the DMA channel since the last commit operation was
+* performed.  This enables the calling functions to put several buffer
+* descriptors into the list (e.g.,a packet's worth) before allowing the scatter
+* gather operations to start.  This prevents the DMA channel hardware from
+* starting to use the buffer descriptors in the list before they are ready
+* to be used (multiple buffer descriptors for a single packet).
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* A status indicating XST_SUCCESS if the buffer descriptors of the list were
+* successfully committed.
+*
+* A value of XST_DMA_SG_NOTHING_TO_COMMIT indicates that the buffer descriptors
+* were not committed because there was nothing to commit in the list.  All the
+* buffer descriptors which are in the list are commited.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_CommitPuts(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if the buffer descriptor to be committed is already committed or
+	 * the list is empty (none have been put in), then indicate an error
+	 */
+	if ((InstancePtr->CommitPtr == NULL) ||
+	    XDmaChannel_IsSgListEmpty(InstancePtr)) {
+		return XST_DMA_SG_NOTHING_TO_COMMIT;
+	}
+
+	/* last descriptor in the list must have scatter gather disabled so the end
+	 * of the list is hit by h/w, if descriptor to commit is not last in list,
+	 * commit descriptors by enabling scatter gather in the descriptor
+	 */
+	if (InstancePtr->CommitPtr != InstancePtr->LastPtr) {
+		u32 Control;
+
+		Control = XBufDescriptor_GetControl(InstancePtr->CommitPtr);
+		XBufDescriptor_SetControl(InstancePtr->CommitPtr, Control &
+					  ~XDC_DMACR_SG_DISABLE_MASK);
+	}
+	/* Update the commit pointer to indicate that there is nothing to be
+	 * committed, this state is used by start processing to know that the
+	 * buffer descriptor to start is not waiting to be committed
+	 */
+	InstancePtr->CommitPtr = NULL;
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetDescriptor
+*
+* DESCRIPTION:
+*
+* This function gets a buffer descriptor from the scatter gather list of the
+* DMA channel. The buffer descriptor is retrieved from the scatter gather list
+* and the scatter gather list is updated to not include the retrieved buffer
+* descriptor.  This is typically done after a scatter gather operation
+* completes indicating that a data buffer has been successfully sent or data
+* has been received into the data buffer. The purpose of this function is to
+* allow the device using the scatter gather operation to get the results of the
+* operation.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* BufDescriptorPtr is a pointer to a pointer to the buffer descriptor which
+* was retrieved from the list.	The buffer descriptor is not really removed
+* from the list, but it is changed to a state such that the hardware will not
+* use it again until it is put into the scatter gather list of the DMA channel.
+*
+* RETURN VALUE:
+*
+* A status indicating XST_SUCCESS if a buffer descriptor was retrieved from
+* the scatter gather list of the DMA channel.
+*
+* A value of XST_DMA_SG_NO_LIST indicates the scatter gather list has not
+* been created.
+*
+* A value of XST_DMA_SG_LIST_EMPTY indicates no buffer descriptor was
+* retrieved from the list because there are no buffer descriptors to be
+* processed in the list.
+*
+* BufDescriptorPtr is updated to point to the buffer descriptor which was
+* retrieved from the list if the status indicates success.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_GetDescriptor(XDmaChannel * InstancePtr,
+			  XBufDescriptor ** BufDescriptorPtr)
+{
+	u32 Control;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(BufDescriptorPtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if a scatter gather list has not been created yet, return a status */
+
+	if (InstancePtr->TotalDescriptorCount == 0) {
+		return XST_DMA_SG_NO_LIST;
+	}
+
+	/* if the buffer descriptor list is empty, then indicate an error */
+
+	if (XDmaChannel_IsSgListEmpty(InstancePtr)) {
+		return XST_DMA_SG_LIST_EMPTY;
+	}
+
+	/* retrieve the next buffer descriptor which is ready to be processed from
+	 * the buffer descriptor list for the DMA channel, set the control word
+	 * such that hardware will stop after the descriptor has been processed
+	 */
+	Control = XBufDescriptor_GetControl(InstancePtr->GetPtr);
+	XBufDescriptor_SetControl(InstancePtr->GetPtr,
+				  Control | XDC_DMACR_SG_DISABLE_MASK);
+
+	/* set the input argument, which is also an output, to point to the
+	 * buffer descriptor which is to be retrieved from the list
+	 */
+	*BufDescriptorPtr = InstancePtr->GetPtr;
+
+	/* update the pointer of the DMA channel to reflect the buffer descriptor
+	 * was retrieved from the list by setting it to the next buffer descriptor
+	 * in the list and indicate one less descriptor in the list now
+	 */
+	InstancePtr->GetPtr = XBufDescriptor_GetNextPtr(InstancePtr->GetPtr);
+	InstancePtr->ActiveDescriptorCount--;
+
+	return XST_SUCCESS;
+}
+
+/*********************** Interrupt Collescing Functions **********************/
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetPktCount
+*
+* DESCRIPTION:
+*
+* This function returns the value of the unserviced packet count register of
+* the DMA channel.  This count represents the number of packets that have been
+* sent or received by the hardware, but not processed by software.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* The unserviced packet counter register contents for the DMA channel.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_GetPktCount(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* get the unserviced packet count from the register and return it */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_DecrementPktCount
+*
+* DESCRIPTION:
+*
+* This function decrements the value of the unserviced packet count register.
+* This informs the hardware that the software has processed a packet.  The
+* unserviced packet count register may only be decremented by one in the
+* hardware.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void
+XDmaChannel_DecrementPktCount(XDmaChannel * InstancePtr)
+{
+	u32 Register;
+
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* if the unserviced packet count register can be decremented (rather
+	 * than rolling over) decrement it by writing a 1 to the register,
+	 * this is the only valid write to the register as it serves as an
+	 * acknowledge that a packet was handled by the software
+	 */
+	Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET);
+	if (Register > 0) {
+		XIo_Out32(InstancePtr->RegBaseAddress + XDC_UPC_REG_OFFSET,
+			  1UL);
+	}
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SetPktThreshold
+*
+* DESCRIPTION:
+*
+* This function sets the value of the packet count threshold register of the
+* DMA channel.	It reflects the number of packets that must be sent or
+* received before generating an interrupt.  This value helps implement
+* a concept called "interrupt coalescing", which is used to reduce the number
+* of interrupts from devices with high data rates.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* Threshold is the value that is written to the threshold register of the
+* DMA channel.
+*
+* RETURN VALUE:
+*
+* A status containing XST_SUCCESS if the packet count threshold was
+* successfully set.
+*
+* NOTES:
+*
+* The packet threshold could be set to larger than the number of descriptors
+* allocated to the DMA channel. In this case, the wait bound will take over
+* and always indicate data arrival. There was a check in this function that
+* returned an error if the treshold was larger than the number of descriptors,
+* but that was removed because users would then have to set the threshold
+* only after they set descriptor space, which is an order dependency that
+* caused confustion.
+*
+******************************************************************************/
+XStatus
+XDmaChannel_SetPktThreshold(XDmaChannel * InstancePtr, u8 Threshold)
+{
+	/* assert to verify input arguments, don't assert the threshold since
+	 * it's range is unknown
+	 */
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the packet count threshold in the register such that an interrupt
+	 * may be generated, if enabled, when the packet count threshold is
+	 * reached or exceeded
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET,
+		  (u32) Threshold);
+
+	/* indicate the packet count threshold was successfully set */
+
+	return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetPktThreshold
+*
+* DESCRIPTION:
+*
+* This function gets the value of the packet count threshold register of the
+* DMA channel.	This value reflects the number of packets that must be sent or
+* received before generating an interrupt.  This value helps implement a concept
+* called "interrupt coalescing", which is used to reduce the number of
+* interrupts from devices with high data rates.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* The packet threshold register contents for the DMA channel and is a value in
+* the range 0 - 1023.  A value of 0 indicates the packet wait bound timer is
+* disabled.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u8
+XDmaChannel_GetPktThreshold(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* get the packet count threshold from the register and return it,
+	 * since only 8 bits are used, cast it to return only those bits */
+
+	return (u8) XIo_In32(InstancePtr->RegBaseAddress + XDC_PCT_REG_OFFSET);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_SetPktWaitBound
+*
+* DESCRIPTION:
+*
+* This function sets the value of the packet wait bound register of the
+* DMA channel.	This value reflects the timer value used to trigger an
+* interrupt when not enough packets have been received to reach the packet
+* count threshold.
+*
+* The timer is in millisecond units with +/- 33% accuracy.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* WaitBound is the value, in milliseconds, to be stored in the wait bound
+* register of the DMA channel and is a value in the range 0  - 1023.  A value
+* of 0 disables the packet wait bound timer.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+void
+XDmaChannel_SetPktWaitBound(XDmaChannel * InstancePtr, u32 WaitBound)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(WaitBound < 1024);
+	XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* set the packet wait bound in the register such that interrupt may be
+	 * generated, if enabled, when packets have not been handled for a specific
+	 * amount of time
+	 */
+	XIo_Out32(InstancePtr->RegBaseAddress + XDC_PWB_REG_OFFSET, WaitBound);
+}
+
+/******************************************************************************
+*
+* FUNCTION:
+*
+* XDmaChannel_GetPktWaitBound
+*
+* DESCRIPTION:
+*
+* This function gets the value of the packet wait bound register of the
+* DMA channel.	This value contains the timer value used to trigger an
+* interrupt when not enough packets have been received to reach the packet
+* count threshold.
+*
+* The timer is in millisecond units with +/- 33% accuracy.
+*
+* ARGUMENTS:
+*
+* InstancePtr contains a pointer to the DMA channel to operate on.  The DMA
+* channel should be configured to use scatter gather in order for this function
+* to be called.
+*
+* RETURN VALUE:
+*
+* The packet wait bound register contents for the DMA channel.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+u32
+XDmaChannel_GetPktWaitBound(XDmaChannel * InstancePtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+	/* get the packet wait bound from the register and return it */
+
+	return XIo_In32(InstancePtr->RegBaseAddress + XDC_PWB_REG_OFFSET);
+}
diff --git a/board/xilinx/common/xio.h b/board/xilinx/common/xio.h
new file mode 100644
index 0000000..5bb09c8
--- /dev/null
+++ b/board/xilinx/common/xio.h
@@ -0,0 +1,81 @@
+/*
+ * xio.h
+ *
+ * Defines XIo functions for Xilinx OCP in terms of Linux primitives
+ *
+ * Author: MontaVista Software, Inc.
+ *         source@mvista.com
+ *
+ * Copyright 2002 MontaVista Software 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.
+ *
+ *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  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.
+ */
+
+#ifndef XIO_H
+#define XIO_H
+
+#include "xbasic_types.h"
+#include <asm/io.h>
+
+typedef u32 XIo_Address;
+
+extern inline u8
+XIo_In8(XIo_Address InAddress)
+{
+	return (u8) in_8((volatile unsigned char *) InAddress);
+}
+extern inline u16
+XIo_In16(XIo_Address InAddress)
+{
+	return (u16) in_be16((volatile unsigned short *) InAddress);
+}
+extern inline u32
+XIo_In32(XIo_Address InAddress)
+{
+	return (u32) in_be32((volatile unsigned *) InAddress);
+}
+extern inline void
+XIo_Out8(XIo_Address OutAddress, u8 Value)
+{
+	out_8((volatile unsigned char *) OutAddress, Value);
+}
+extern inline void
+XIo_Out16(XIo_Address OutAddress, u16 Value)
+{
+	out_be16((volatile unsigned short *) OutAddress, Value);
+}
+extern inline void
+XIo_Out32(XIo_Address OutAddress, u32 Value)
+{
+	out_be32((volatile unsigned *) OutAddress, Value);
+}
+
+#define XIo_ToLittleEndian16(s,d) (*(u16*)(d) = cpu_to_le16((u16)(s)))
+#define XIo_ToLittleEndian32(s,d) (*(u32*)(d) = cpu_to_le32((u32)(s)))
+#define XIo_ToBigEndian16(s,d) (*(u16*)(d) = cpu_to_be16((u16)(s)))
+#define XIo_ToBigEndian32(s,d) (*(u32*)(d) = cpu_to_be32((u32)(s)))
+
+#define XIo_FromLittleEndian16(s,d) (*(u16*)(d) = le16_to_cpu((u16)(s)))
+#define XIo_FromLittleEndian32(s,d) (*(u32*)(d) = le32_to_cpu((u32)(s)))
+#define XIo_FromBigEndian16(s,d) (*(u16*)(d) = be16_to_cpu((u16)(s)))
+#define XIo_FromBigEndian32(s,d) (*(u32*)(d) = be32_to_cpu((u32)(s)))
+
+#endif				/* XIO_H */
diff --git a/board/xilinx/common/xipif_v1_23_b.h b/board/xilinx/common/xipif_v1_23_b.h
new file mode 100644
index 0000000..b1520e9
--- /dev/null
+++ b/board/xilinx/common/xipif_v1_23_b.h
@@ -0,0 +1,763 @@
+/******************************************************************************
+*
+*     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.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* FILENAME:
+*
+* xipif.h
+*
+* DESCRIPTION:
+*
+* The XIpIf component encapsulates the IPIF, which is the standard interface
+* that IP must adhere to when connecting to a bus.  The purpose of this
+* component is to encapsulate the IPIF processing such that maintainability
+* is increased.	 This component does not provide a lot of abstraction from
+* from the details of the IPIF as it is considered a building block for
+* device drivers.  A device driver designer must be familiar with the
+* details of the IPIF hardware to use this component.
+*
+* The IPIF hardware provides a building block for all hardware devices such
+* that each device does not need to reimplement these building blocks. The
+* IPIF contains other building blocks, such as FIFOs and DMA channels, which
+* are also common to many devices.  These blocks are implemented as separate
+* hardware blocks and instantiated within the IPIF.  The primary hardware of
+* the IPIF which is implemented by this software component is the interrupt
+* architecture.	 Since there are many blocks of a device which may generate
+* interrupts, all the interrupt processing is contained in the common part
+* of the device, the IPIF.  This interrupt processing is for the device level
+* only and does not include any processing for the interrupt controller.
+*
+* A device is a mechanism such as an Ethernet MAC.  The device is made
+* up of several parts which include an IPIF and the IP.	 The IPIF contains most
+* of the device infrastructure which is common to all devices, such as
+* interrupt processing, DMA channels, and FIFOs.  The infrastructure may also
+* be referred to as IPIF internal blocks since they are part of the IPIF and
+* are separate blocks that can be selected based upon the needs of the device.
+* The IP of the device is the logic that is unique to the device and interfaces
+* to the IPIF of the device.
+*
+* In general, there are two levels of registers within the IPIF.  The first
+* level, referred to as the device level, contains registers which are for the
+* entire device.  The second level, referred to as the IP level, contains
+* registers which are specific to the IP of the device.	 The two levels of
+* registers are designed to be hierarchical such that the device level is
+* is a more general register set above the more specific registers of the IP.
+* The IP level of registers provides functionality which is typically common
+* across all devices and allows IP designers to focus on the unique aspects
+* of the IP.
+*
+* Critical Sections
+*
+* It is the responsibility of the device driver designer to use critical
+* sections as necessary when calling functions of the IPIF.  This component
+* does not use critical sections and it does access registers using
+* read-modify-write operations.	 Calls to IPIF functions from a main thread
+* and from an interrupt context could produce unpredictable behavior such that
+* the caller must provide the appropriate critical sections.
+*
+* Mutual Exclusion
+*
+* The functions of the IPIF are not thread safe such that the caller of all
+* functions is responsible for ensuring mutual exclusion for an IPIF.  Mutual
+* exclusion across multiple IPIF components is not necessary.
+*
+* NOTES:
+*
+* None.
+*
+* MODIFICATION HISTORY:
+*
+* Ver	Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.23b jhl  02/27/01 Repartioned to minimize size
+*
+******************************************************************************/
+
+#ifndef XIPIF_H			/* prevent circular inclusions */
+#define XIPIF_H			/* by using protection macros */
+
+/***************************** Include Files *********************************/
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xversion.h"
+
+/************************** Constant Definitions *****************************/
+
+/* the following constants define the register offsets for the registers of the
+ * IPIF, there are some holes in the memory map for reserved addresses to allow
+ * other registers to be added and still match the memory map of the interrupt
+ * controller registers
+ */
+#define XIIF_V123B_DISR_OFFSET	   0UL	/* device interrupt status register */
+#define XIIF_V123B_DIPR_OFFSET	   4UL	/* device interrupt pending register */
+#define XIIF_V123B_DIER_OFFSET	   8UL	/* device interrupt enable register */
+#define XIIF_V123B_DIIR_OFFSET	   24UL /* device interrupt ID register */
+#define XIIF_V123B_DGIER_OFFSET	   28UL /* device global interrupt enable reg */
+#define XIIF_V123B_IISR_OFFSET	   32UL /* IP interrupt status register */
+#define XIIF_V123B_IIER_OFFSET	   40UL /* IP interrupt enable register */
+#define XIIF_V123B_RESETR_OFFSET   64UL /* reset register */
+
+#define XIIF_V123B_RESET_MASK		  0xAUL
+
+/* the following constant is used for the device global interrupt enable
+ * register, to enable all interrupts for the device, this is the only bit
+ * in the register
+ */
+#define XIIF_V123B_GINTR_ENABLE_MASK	  0x80000000UL
+
+/* the following constants contain the masks to identify each internal IPIF
+ * condition in the device registers of the IPIF, interrupts are assigned
+ * in the register from LSB to the MSB
+ */
+#define XIIF_V123B_ERROR_MASK		  1UL	/* LSB of the register */
+
+/* The following constants contain interrupt IDs which identify each internal
+ * IPIF condition, this value must correlate with the mask constant for the
+ * error
+ */
+#define XIIF_V123B_ERROR_INTERRUPT_ID	  0	/* interrupt bit #, (LSB = 0) */
+#define XIIF_V123B_NO_INTERRUPT_ID	  128	/* no interrupts are pending */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_RESET
+*
+* DESCRIPTION:
+*
+* Reset the IPIF component and hardware.  This is a destructive operation that
+* could cause the loss of data since resetting the IPIF of a device also
+* resets the device using the IPIF and any blocks, such as FIFOs or DMA
+* channels, within the IPIF.  All registers of the IPIF will contain their
+* reset value when this function returns.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+
+/* the following constant is used in the reset register to cause the IPIF to
+ * reset
+ */
+#define XIIF_V123B_RESET(RegBaseAddress) \
+    XIo_Out32(RegBaseAddress + XIIF_V123B_RESETR_OFFSET, XIIF_V123B_RESET_MASK)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_WRITE_DISR
+*
+* DESCRIPTION:
+*
+* This function sets the device interrupt status register to the value.
+* This register indicates the status of interrupt sources for a device
+* which contains the IPIF.  The status is independent of whether interrupts
+* are enabled and could be used for polling a device at a higher level rather
+* than a more detailed level.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device which contains the IPIF.  With the exception of some internal IPIF
+* conditions, the contents of this register are not latched but indicate
+* the live status of the interrupt sources within the device.  Writing any of
+* the non-latched bits of the register will have no effect on the register.
+*
+* For the latched bits of this register only, setting a bit which is zero
+* within this register causes an interrupt to generated.  The device global
+* interrupt enable register and the device interrupt enable register must be set
+* appropriately to allow an interrupt to be passed out of the device. The
+* interrupt is cleared by writing to this register with the bits to be
+* cleared set to a one and all others to zero.	This register implements a
+* toggle on write functionality meaning any bits which are set in the value
+* written cause the bits in the register to change to the opposite state.
+*
+* This function writes the specified value to the register such that
+* some bits may be set and others cleared.  It is the caller's responsibility
+* to get the value of the register prior to setting the value to prevent a
+* destructive behavior.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* Status contains the value to be written to the interrupt status register of
+* the device.  The only bits which can be written are the latched bits which
+* contain the internal IPIF conditions.	 The following values may be used to
+* set the status register or clear an interrupt condition.
+*
+*   XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_WRITE_DISR(RegBaseAddress, Status) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_DISR_OFFSET, (Status))
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_READ_DISR
+*
+* DESCRIPTION:
+*
+* This function gets the device interrupt status register contents.
+* This register indicates the status of interrupt sources for a device
+* which contains the IPIF.  The status is independent of whether interrupts
+* are enabled and could be used for polling a device at a higher level.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device which contains the IPIF.  With the exception of some internal IPIF
+* conditions, the contents of this register are not latched but indicate
+* the live status of the interrupt sources within the device.
+*
+* For only the latched bits of this register, the interrupt may be cleared by
+* writing to these bits in the status register.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* A status which contains the value read from the interrupt status register of
+* the device. The bit definitions are specific to the device with
+* the exception of the latched internal IPIF condition bits. The following
+* values may be used to detect internal IPIF conditions in the status.
+*
+*   XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_DISR(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_DISR_OFFSET)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_WRITE_DIER
+*
+* DESCRIPTION:
+*
+* This function sets the device interrupt enable register contents.
+* This register controls which interrupt sources of the device are allowed to
+* generate an interrupt.  The device global interrupt enable register must also
+* be set appropriately for an interrupt to be passed out of the device.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device which contains the IPIF.  Setting a bit in this register enables that
+* interrupt source to generate an interrupt.  Clearing a bit in this register
+* disables interrupt generation for that interrupt source.
+*
+* This function writes only the specified value to the register such that
+* some interrupts source may be enabled and others disabled.  It is the
+* caller's responsibility to get the value of the interrupt enable register
+* prior to setting the value to prevent an destructive behavior.
+*
+* An interrupt source may not be enabled to generate an interrupt, but can
+* still be polled in the interrupt status register.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* Enable contains the value to be written to the interrupt enable register
+* of the device.  The bit definitions are specific to the device with
+* the exception of the internal IPIF conditions. The following
+* values may be used to enable the internal IPIF conditions interrupts.
+*
+*   XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* Signature: u32 XIIF_V123B_WRITE_DIER(u32 RegBaseAddress,
+*					  u32 Enable)
+*
+******************************************************************************/
+#define XIIF_V123B_WRITE_DIER(RegBaseAddress, Enable) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_DIER_OFFSET, (Enable))
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_READ_DIER
+*
+* DESCRIPTION:
+*
+* This function gets the device interrupt enable register contents.
+* This register controls which interrupt sources of the device
+* are allowed to generate an interrupt.	 The device global interrupt enable
+* register and the device interrupt enable register must also be set
+* appropriately for an interrupt to be passed out of the device.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device which contains the IPIF.  Setting a bit in this register enables that
+* interrupt source to generate an interrupt if the global enable is set
+* appropriately.  Clearing a bit in this register disables interrupt generation
+* for that interrupt source regardless of the global interrupt enable.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* The value read from the interrupt enable register of the device.  The bit
+* definitions are specific to the device with the exception of the internal
+* IPIF conditions. The following values may be used to determine from the
+* value if the internal IPIF conditions interrupts are enabled.
+*
+*   XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_DIER(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_DIER_OFFSET)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_READ_DIPR
+*
+* DESCRIPTION:
+*
+* This function gets the device interrupt pending register contents.
+* This register indicates the pending interrupt sources, those that are waiting
+* to be serviced by the software, for a device which contains the IPIF.
+* An interrupt must be enabled in the interrupt enable register of the IPIF to
+* be pending.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* the device which contains the IPIF.  With the exception of some internal IPIF
+* conditions, the contents of this register are not latched since the condition
+* is latched in the IP interrupt status register, by an internal block of the
+* IPIF such as a FIFO or DMA channel, or by the IP of the device.  This register
+* is read only and is not latched, but it is necessary to acknowledge (clear)
+* the interrupt condition by performing the appropriate processing for the IP
+* or block within the IPIF.
+*
+* This register can be thought of as the contents of the interrupt status
+* register ANDed with the contents of the interrupt enable register.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* The value read from the interrupt pending register of the device.  The bit
+* definitions are specific to the device with the exception of the latched
+* internal IPIF condition bits. The following values may be used to detect
+* internal IPIF conditions in the value.
+*
+*   XIIF_V123B_ERROR_MASK     Indicates a device error in the IPIF
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_DIPR(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_DIPR_OFFSET)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_READ_DIIR
+*
+* DESCRIPTION:
+*
+* This function gets the device interrupt ID for the highest priority interrupt
+* which is pending from the interrupt ID register. This function provides
+* priority resolution such that faster interrupt processing is possible.
+* Without priority resolution, it is necessary for the software to read the
+* interrupt pending register and then check each interrupt source to determine
+* if an interrupt is pending.  Priority resolution becomes more important as the
+* number of interrupt sources becomes larger.
+*
+* Interrupt priorities are based upon the bit position of the interrupt in the
+* interrupt pending register with bit 0 being the highest priority. The
+* interrupt ID is the priority of the interrupt, 0 - 31, with 0 being the
+* highest priority. The interrupt ID register is live rather than latched such
+* that multiple calls to this function may not yield the same results.	A
+* special value, outside of the interrupt priority range of 0 - 31, is
+* contained in the register which indicates that no interrupt is pending.  This
+* may be useful for allowing software to continue processing interrupts in a
+* loop until there are no longer any interrupts pending.
+*
+* The interrupt ID is designed to allow a function pointer table to be used
+* in the software such that the interrupt ID is used as an index into that
+* table.  The function pointer table could contain an instance pointer, such
+* as to DMA channel, and a function pointer to the function which handles
+* that interrupt.  This design requires the interrupt processing of the device
+* driver to be partitioned into smaller more granular pieces based upon
+* hardware used by the device, such as DMA channels and FIFOs.
+*
+* It is not mandatory that this function be used by the device driver software.
+* It may choose to read the pending register and resolve the pending interrupt
+* priorities on it's own.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* An interrupt ID, 0 - 31, which identifies the highest priority interrupt
+* which is pending.  A value of XIIF_NO_INTERRUPT_ID indicates that there is
+* no interrupt pending. The following values may be used to identify the
+* interrupt ID for the internal IPIF interrupts.
+*
+*   XIIF_V123B_ERROR_INTERRUPT_ID     Indicates a device error in the IPIF
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_DIIR(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_DIIR_OFFSET)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_GLOBAL_INTR_DISABLE
+*
+* DESCRIPTION:
+*
+* This function disables all interrupts for the device by writing to the global
+* interrupt enable register.  This register provides the ability to disable
+* interrupts without any modifications to the interrupt enable register such
+* that it is minimal effort to restore the interrupts to the previous enabled
+* state.  The corresponding function, XIpIf_GlobalIntrEnable, is provided to
+* restore the interrupts to the previous enabled state.	 This function is
+* designed to be used in critical sections of device drivers such that it is
+* not necessary to disable other device interrupts.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_GINTR_DISABLE(RegBaseAddress) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_DGIER_OFFSET, 0)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_GINTR_ENABLE
+*
+* DESCRIPTION:
+*
+* This function writes to the global interrupt enable register to enable
+* interrupts from the device.  This register provides the ability to enable
+* interrupts without any modifications to the interrupt enable register such
+* that it is minimal effort to restore the interrupts to the previous enabled
+* state.  This function does not enable individual interrupts as the interrupt
+* enable register must be set appropriately.  This function is designed to be
+* used in critical sections of device drivers such that it is not necessary to
+* disable other device interrupts.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_GINTR_ENABLE(RegBaseAddress)		  \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_DGIER_OFFSET, \
+	       XIIF_V123B_GINTR_ENABLE_MASK)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_IS_GINTR_ENABLED
+*
+* DESCRIPTION:
+*
+* This function determines if interrupts are enabled at the global level by
+* reading the gloabl interrupt register. This register provides the ability to
+* disable interrupts without any modifications to the interrupt enable register
+* such that it is minimal effort to restore the interrupts to the previous
+* enabled state.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* TRUE if interrupts are enabled for the IPIF, FALSE otherwise.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_IS_GINTR_ENABLED(RegBaseAddress)		\
+    (XIo_In32((RegBaseAddress) + XIIF_V123B_DGIER_OFFSET) ==	\
+	      XIIF_V123B_GINTR_ENABLE_MASK)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_WRITE_IISR
+*
+* DESCRIPTION:
+*
+* This function sets the IP interrupt status register to the specified value.
+* This register indicates the status of interrupt sources for the IP of the
+* device.  The IP is defined as the part of the device that connects to the
+* IPIF.	 The status is independent of whether interrupts are enabled such that
+* the status register may also be polled when interrupts are not enabled.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* IP.  All bits of this register are latched. Setting a bit which is zero
+* within this register causes an interrupt to be generated.  The device global
+* interrupt enable register and the device interrupt enable register must be set
+* appropriately to allow an interrupt to be passed out of the device. The
+* interrupt is cleared by writing to this register with the bits to be
+* cleared set to a one and all others to zero.	This register implements a
+* toggle on write functionality meaning any bits which are set in the value
+* written cause the bits in the register to change to the opposite state.
+*
+* This function writes only the specified value to the register such that
+* some status bits may be set and others cleared.  It is the caller's
+* responsibility to get the value of the register prior to setting the value
+* to prevent an destructive behavior.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* Status contains the value to be written to the IP interrupt status
+* register.  The bit definitions are specific to the device IP.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_WRITE_IISR(RegBaseAddress, Status) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_IISR_OFFSET, (Status))
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_READ_IISR
+*
+* DESCRIPTION:
+*
+* This function gets the contents of the IP interrupt status register.
+* This register indicates the status of interrupt sources for the IP of the
+* device.  The IP is defined as the part of the device that connects to the
+* IPIF. The status is independent of whether interrupts are enabled such
+* that the status register may also be polled when interrupts are not enabled.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* device.  All bits of this register are latched.  Writing a 1 to a bit within
+* this register causes an interrupt to be generated if enabled in the interrupt
+* enable register and the global interrupt enable is set.  Since the status is
+* latched, each status bit must be acknowledged in order for the bit in the
+* status register to be updated.  Each bit can be acknowledged by writing a
+* 0 to the bit in the status register.
+
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* A status which contains the value read from the IP interrupt status register.
+* The bit definitions are specific to the device IP.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_READ_IISR(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_IISR_OFFSET)
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_WRITE_IIER
+*
+* DESCRIPTION:
+*
+* This function sets the IP interrupt enable register contents.	 This register
+* controls which interrupt sources of the IP are allowed to generate an
+* interrupt.  The global interrupt enable register and the device interrupt
+* enable register must also be set appropriately for an interrupt to be
+* passed out of the device containing the IPIF and the IP.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* IP.  Setting a bit in this register enables the interrupt source to generate
+* an interrupt.	 Clearing a bit in this register disables interrupt generation
+* for that interrupt source.
+*
+* This function writes only the specified value to the register such that
+* some interrupt sources may be enabled and others disabled.  It is the
+* caller's responsibility to get the value of the interrupt enable register
+* prior to setting the value to prevent an destructive behavior.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* Enable contains the value to be written to the IP interrupt enable register.
+* The bit definitions are specific to the device IP.
+*
+* RETURN VALUE:
+*
+* None.
+*
+* NOTES:
+*
+* None.
+*
+******************************************************************************/
+#define XIIF_V123B_WRITE_IIER(RegBaseAddress, Enable) \
+    XIo_Out32((RegBaseAddress) + XIIF_V123B_IIER_OFFSET, (Enable))
+
+/******************************************************************************
+*
+* MACRO:
+*
+* XIIF_V123B_READ_IIER
+*
+* DESCRIPTION:
+*
+*
+* This function gets the IP interrupt enable register contents.	 This register
+* controls which interrupt sources of the IP are allowed to generate an
+* interrupt.  The global interrupt enable register and the device interrupt
+* enable register must also be set appropriately for an interrupt to be
+* passed out of the device containing the IPIF and the IP.
+*
+* Each bit of the register correlates to a specific interrupt source within the
+* IP.  Setting a bit in this register enables the interrupt source to generate
+* an interrupt.	 Clearing a bit in this register disables interrupt generation
+* for that interrupt source.
+*
+* ARGUMENTS:
+*
+* RegBaseAddress contains the base address of the IPIF registers.
+*
+* RETURN VALUE:
+*
+* The contents read from the IP interrupt enable register.  The bit definitions
+* are specific to the device IP.
+*
+* NOTES:
+*
+* Signature: u32 XIIF_V123B_READ_IIER(u32 RegBaseAddress)
+*
+******************************************************************************/
+#define XIIF_V123B_READ_IIER(RegBaseAddress) \
+    XIo_In32((RegBaseAddress) + XIIF_V123B_IIER_OFFSET)
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Initialization Functions
+ */
+XStatus XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth);
+
+#endif				/* end of protection macro */
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 0000000..ae2d6d4
--- /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;
+}
diff --git a/board/xilinx/common/xpacket_fifo_v1_00_b.h b/board/xilinx/common/xpacket_fifo_v1_00_b.h
new file mode 100644
index 0000000..1cda0e8
--- /dev/null
+++ b/board/xilinx/common/xpacket_fifo_v1_00_b.h
@@ -0,0 +1,306 @@
+/******************************************************************************
+*
+*     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.h
+*
+* This component is a common component because it's primary purpose is to
+* prevent code duplication in drivers. A driver which must handle a packet
+* FIFO uses this component rather than directly manipulating a packet FIFO.
+*
+* A FIFO is a device which has dual port memory such that one user may be
+* inserting data into the FIFO while another is consuming data from the FIFO.
+* A packet FIFO is designed for use with packet protocols such as Ethernet and
+* ATM.  It is typically only used with devices when DMA and/or Scatter Gather
+* is used.  It differs from a nonpacket FIFO in that it does not provide any
+* interrupts for thresholds of the FIFO such that it is less useful without
+* DMA.
+*
+* @note
+*
+* This component has the capability to generate an interrupt when an error
+* condition occurs.  It is the user's responsibility to provide the interrupt
+* processing to handle the interrupt. This component provides the ability to
+* determine if that interrupt is active, a deadlock condition, and the ability
+* to reset the FIFO to clear the condition. In this condition, the device which
+* is using the FIFO should also be reset to prevent other problems. This error
+* condition could occur as a normal part of operation if the size of the FIFO
+* is not setup correctly.  See the hardware IP specification for more details.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b rpm 03/26/02  First release
+* </pre>
+*
+*****************************************************************************/
+#ifndef XPACKET_FIFO_H		/* prevent circular inclusions */
+#define XPACKET_FIFO_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * These constants specify the FIFO type and are mutually exclusive
+ */
+#define XPF_READ_FIFO_TYPE      0	/* a read FIFO */
+#define XPF_WRITE_FIFO_TYPE     1	/* a write FIFO */
+
+/*
+ * These constants define the offsets to each of the registers from the
+ * register base address, each of the constants are a number of bytes
+ */
+#define XPF_RESET_REG_OFFSET            0UL
+#define XPF_MODULE_INFO_REG_OFFSET      0UL
+#define XPF_COUNT_STATUS_REG_OFFSET     4UL
+
+/*
+ * This constant is used with the Reset Register
+ */
+#define XPF_RESET_FIFO_MASK             0x0000000A
+
+/*
+ * These constants are used with the Occupancy/Vacancy Count Register. This
+ * register also contains FIFO status
+ */
+#define XPF_COUNT_MASK                  0x0000FFFF
+#define XPF_DEADLOCK_MASK               0x20000000
+#define XPF_ALMOST_EMPTY_FULL_MASK      0x40000000
+#define XPF_EMPTY_FULL_MASK             0x80000000
+
+/**************************** Type Definitions *******************************/
+
+/*
+ * The XPacketFifo driver instance data. The driver is required to allocate a
+ * variable of this type for every packet FIFO in the device.
+ */
+typedef struct {
+	u32 RegBaseAddress;	/* Base address of registers */
+	u32 IsReady;		/* Device is initialized and ready */
+	u32 DataBaseAddress;	/* Base address of data for FIFOs */
+} XPacketFifoV100b;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/*
+*
+* Reset the specified packet FIFO.  Resetting a FIFO will cause any data
+* contained in the FIFO to be lost.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XPF_V100B_RESET(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_RESET(InstancePtr) \
+    XIo_Out32((InstancePtr)->RegBaseAddress + XPF_RESET_REG_OFFSET, XPF_RESET_FIFO_MASK);
+
+/*****************************************************************************/
+/*
+*
+* Get the occupancy count for a read packet FIFO and the vacancy count for a
+* write packet FIFO. These counts indicate the number of 32-bit words
+* contained (occupancy) in the FIFO or the number of 32-bit words available
+* to write (vacancy) in the FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* The occupancy or vacancy count for the specified packet FIFO.
+*
+* @note
+*
+* Signature: u32 XPF_V100B_GET_COUNT(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_GET_COUNT(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
+    XPF_COUNT_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is almost empty. Almost empty is
+* defined for a read FIFO when there is only one data word in the FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is almost empty, FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XPF_V100B_IS_ALMOST_EMPTY(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_IS_ALMOST_EMPTY(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
+    XPF_ALMOST_EMPTY_FULL_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is almost full. Almost full is
+* defined for a write FIFO when there is only one available data word in the
+* FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is almost full, FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XPF_V100B_IS_ALMOST_FULL(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_IS_ALMOST_FULL(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
+    XPF_ALMOST_EMPTY_FULL_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is empty. This applies only to a
+* read FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is empty, FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XPF_V100B_IS_EMPTY(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_IS_EMPTY(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
+    XPF_EMPTY_FULL_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is full. This applies only to a
+* write FIFO.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is full, FALSE otherwise.
+*
+* @note
+*
+* Signature: u32 XPF_V100B_IS_FULL(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_IS_FULL(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
+    XPF_EMPTY_FULL_MASK)
+
+/*****************************************************************************/
+/*
+*
+* Determine if the specified packet FIFO is deadlocked.  This condition occurs
+* when the FIFO is full and empty at the same time and is caused by a packet
+* being written to the FIFO which exceeds the total data capacity of the FIFO.
+* It occurs because of the mark/restore features of the packet FIFO which allow
+* retransmission of a packet. The software should reset the FIFO and any devices
+* using the FIFO when this condition occurs.
+*
+* @param InstancePtr contains a pointer to the FIFO to operate on.
+*
+* @return
+*
+* TRUE if the packet FIFO is deadlocked, FALSE otherwise.
+*
+* @note
+*
+* This component has the capability to generate an interrupt when an error
+* condition occurs.  It is the user's responsibility to provide the interrupt
+* processing to handle the interrupt. This function provides the ability to
+* determine if a deadlock condition, and the ability to reset the FIFO to
+* clear the condition.
+*
+* In this condition, the device which is using the FIFO should also be reset
+* to prevent other problems. This error condition could occur as a normal part
+* of operation if the size of the FIFO is not setup correctly.
+*
+* Signature: u32 XPF_V100B_IS_DEADLOCKED(XPacketFifoV100b *InstancePtr)
+*
+******************************************************************************/
+#define XPF_V100B_IS_DEADLOCKED(InstancePtr) \
+    (XIo_In32((InstancePtr)->RegBaseAddress + XPF_COUNT_STATUS_REG_OFFSET) & \
+    XPF_DEADLOCK_MASK)
+
+/************************** Function Prototypes ******************************/
+
+/* Standard functions */
+
+XStatus XPacketFifoV100b_Initialize(XPacketFifoV100b * InstancePtr,
+				    u32 RegBaseAddress, u32 DataBaseAddress);
+XStatus XPacketFifoV100b_SelfTest(XPacketFifoV100b * InstancePtr, u32 FifoType);
+
+/* Data functions */
+
+XStatus XPacketFifoV100b_Read(XPacketFifoV100b * InstancePtr,
+			      u8 * ReadBufferPtr, u32 ByteCount);
+XStatus XPacketFifoV100b_Write(XPacketFifoV100b * InstancePtr,
+			       u8 * WriteBufferPtr, u32 ByteCount);
+
+#endif				/* end of protection macro */
diff --git a/board/xilinx/common/xstatus.h b/board/xilinx/common/xstatus.h
new file mode 100644
index 0000000..ffda4d7
--- /dev/null
+++ b/board/xilinx/common/xstatus.h
@@ -0,0 +1,347 @@
+/******************************************************************************
+*
+*     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 xstatus.h
+*
+* This file contains Xilinx software status codes.  Status codes have their
+* own data type called XStatus.  These codes are used throughout the Xilinx
+* device drivers.
+*
+******************************************************************************/
+
+#ifndef XSTATUS_H		/* prevent circular inclusions */
+#define XSTATUS_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+
+/************************** Constant Definitions *****************************/
+
+/*********************** Common statuses 0 - 500 *****************************/
+
+#define XST_SUCCESS                     0L
+#define XST_FAILURE                     1L
+#define XST_DEVICE_NOT_FOUND            2L
+#define XST_DEVICE_BLOCK_NOT_FOUND      3L
+#define XST_INVALID_VERSION             4L
+#define XST_DEVICE_IS_STARTED           5L
+#define XST_DEVICE_IS_STOPPED           6L
+#define XST_FIFO_ERROR                  7L	/* an error occurred during an
+						   operation with a FIFO such as
+						   an underrun or overrun, this
+						   error requires the device to
+						   be reset */
+#define XST_RESET_ERROR                 8L	/* an error occurred which requires
+						   the device to be reset */
+#define XST_DMA_ERROR                   9L	/* a DMA error occurred, this error
+						   typically requires the device
+						   using the DMA to be reset */
+#define XST_NOT_POLLED                  10L	/* the device is not configured for
+						   polled mode operation */
+#define XST_FIFO_NO_ROOM                11L	/* a FIFO did not have room to put
+						   the specified data into */
+#define XST_BUFFER_TOO_SMALL            12L	/* the buffer is not large enough
+						   to hold the expected data */
+#define XST_NO_DATA                     13L	/* there was no data available */
+#define XST_REGISTER_ERROR              14L	/* a register did not contain the
+						   expected value */
+#define XST_INVALID_PARAM               15L	/* an invalid parameter was passed
+						   into the function */
+#define XST_NOT_SGDMA                   16L	/* the device is not configured for
+						   scatter-gather DMA operation */
+#define XST_LOOPBACK_ERROR              17L	/* a loopback test failed */
+#define XST_NO_CALLBACK                 18L	/* a callback has not yet been
+						 * registered */
+#define XST_NO_FEATURE                  19L	/* device is not configured with
+						 * the requested feature */
+#define XST_NOT_INTERRUPT               20L	/* device is not configured for
+						 * interrupt mode operation */
+#define XST_DEVICE_BUSY                 21L	/* device is busy */
+#define XST_ERROR_COUNT_MAX             22L	/* the error counters of a device
+						 * have maxed out */
+#define XST_IS_STARTED                  23L	/* used when part of device is
+						 * already started i.e.
+						 * sub channel */
+#define XST_IS_STOPPED                  24L	/* used when part of device is
+						 * already stopped i.e.
+						 * sub channel */
+
+/***************** Utility Component statuses 401 - 500  *********************/
+
+#define XST_MEMTEST_FAILED              401L	/* memory test failed */
+
+/***************** Common Components statuses 501 - 1000 *********************/
+
+/********************* Packet Fifo statuses 501 - 510 ************************/
+
+#define XST_PFIFO_LACK_OF_DATA          501L	/* not enough data in FIFO   */
+#define XST_PFIFO_NO_ROOM               502L	/* not enough room in FIFO   */
+#define XST_PFIFO_BAD_REG_VALUE         503L	/* self test, a register value
+						   was invalid after reset */
+
+/************************** DMA statuses 511 - 530 ***************************/
+
+#define XST_DMA_TRANSFER_ERROR          511L	/* self test, DMA transfer
+						   failed */
+#define XST_DMA_RESET_REGISTER_ERROR    512L	/* self test, a register value
+						   was invalid after reset */
+#define XST_DMA_SG_LIST_EMPTY           513L	/* scatter gather list contains
+						   no buffer descriptors ready
+						   to be processed */
+#define XST_DMA_SG_IS_STARTED           514L	/* scatter gather not stopped */
+#define XST_DMA_SG_IS_STOPPED           515L	/* scatter gather not running */
+#define XST_DMA_SG_LIST_FULL            517L	/* all the buffer desciptors of
+						   the scatter gather list are
+						   being used */
+#define XST_DMA_SG_BD_LOCKED            518L	/* the scatter gather buffer
+						   descriptor which is to be
+						   copied over in the scatter
+						   list is locked */
+#define XST_DMA_SG_NOTHING_TO_COMMIT    519L	/* no buffer descriptors have been
+						   put into the scatter gather
+						   list to be commited */
+#define XST_DMA_SG_COUNT_EXCEEDED       521L	/* the packet count threshold
+						   specified was larger than the
+						   total # of buffer descriptors
+						   in the scatter gather list */
+#define XST_DMA_SG_LIST_EXISTS          522L	/* the scatter gather list has
+						   already been created */
+#define XST_DMA_SG_NO_LIST              523L	/* no scatter gather list has
+						   been created */
+#define XST_DMA_SG_BD_NOT_COMMITTED     524L	/* the buffer descriptor which was
+						   being started was not committed
+						   to the list */
+#define XST_DMA_SG_NO_DATA              525L	/* the buffer descriptor to start
+						   has already been used by the
+						   hardware so it can't be reused
+						 */
+
+/************************** IPIF statuses 531 - 550 ***************************/
+
+#define XST_IPIF_REG_WIDTH_ERROR        531L	/* an invalid register width
+						   was passed into the function */
+#define XST_IPIF_RESET_REGISTER_ERROR   532L	/* the value of a register at
+						   reset was not valid */
+#define XST_IPIF_DEVICE_STATUS_ERROR    533L	/* a write to the device interrupt
+						   status register did not read
+						   back correctly */
+#define XST_IPIF_DEVICE_ACK_ERROR       534L	/* the device interrupt status
+						   register did not reset when
+						   acked */
+#define XST_IPIF_DEVICE_ENABLE_ERROR    535L	/* the device interrupt enable
+						   register was not updated when
+						   other registers changed */
+#define XST_IPIF_IP_STATUS_ERROR        536L	/* a write to the IP interrupt
+						   status register did not read
+						   back correctly */
+#define XST_IPIF_IP_ACK_ERROR           537L	/* the IP interrupt status register
+						   did not reset when acked */
+#define XST_IPIF_IP_ENABLE_ERROR        538L	/* IP interrupt enable register was
+						   not updated correctly when other
+						   registers changed */
+#define XST_IPIF_DEVICE_PENDING_ERROR   539L	/* The device interrupt pending
+						   register did not indicate the
+						   expected value */
+#define XST_IPIF_DEVICE_ID_ERROR        540L	/* The device interrupt ID register
+						   did not indicate the expected
+						   value */
+
+/****************** Device specific statuses 1001 - 4095 *********************/
+
+/********************* Ethernet statuses 1001 - 1050 *************************/
+
+#define XST_EMAC_MEMORY_SIZE_ERROR  1001L	/* Memory space is not big enough
+						 * to hold the minimum number of
+						 * buffers or descriptors */
+#define XST_EMAC_MEMORY_ALLOC_ERROR 1002L	/* Memory allocation failed */
+#define XST_EMAC_MII_READ_ERROR     1003L	/* MII read error */
+#define XST_EMAC_MII_BUSY           1004L	/* An MII operation is in progress */
+#define XST_EMAC_OUT_OF_BUFFERS     1005L	/* Adapter is out of buffers */
+#define XST_EMAC_PARSE_ERROR        1006L	/* Invalid adapter init string */
+#define XST_EMAC_COLLISION_ERROR    1007L	/* Excess deferral or late
+						 * collision on polled send */
+
+/*********************** UART statuses 1051 - 1075 ***************************/
+#define XST_UART
+
+#define XST_UART_INIT_ERROR         1051L
+#define XST_UART_START_ERROR        1052L
+#define XST_UART_CONFIG_ERROR       1053L
+#define XST_UART_TEST_FAIL          1054L
+#define XST_UART_BAUD_ERROR         1055L
+#define XST_UART_BAUD_RANGE         1056L
+
+/************************ IIC statuses 1076 - 1100 ***************************/
+
+#define XST_IIC_SELFTEST_FAILED         1076	/* self test failed            */
+#define XST_IIC_BUS_BUSY                1077	/* bus found busy              */
+#define XST_IIC_GENERAL_CALL_ADDRESS    1078	/* mastersend attempted with   */
+					     /* general call address        */
+#define XST_IIC_STAND_REG_RESET_ERROR   1079	/* A non parameterizable reg   */
+					     /* value after reset not valid */
+#define XST_IIC_TX_FIFO_REG_RESET_ERROR 1080	/* Tx fifo included in design  */
+					     /* value after reset not valid */
+#define XST_IIC_RX_FIFO_REG_RESET_ERROR 1081	/* Rx fifo included in design  */
+					     /* value after reset not valid */
+#define XST_IIC_TBA_REG_RESET_ERROR     1082	/* 10 bit addr incl in design  */
+					     /* value after reset not valid */
+#define XST_IIC_CR_READBACK_ERROR       1083	/* Read of the control register */
+					     /* didn't return value written */
+#define XST_IIC_DTR_READBACK_ERROR      1084	/* Read of the data Tx reg     */
+					     /* didn't return value written */
+#define XST_IIC_DRR_READBACK_ERROR      1085	/* Read of the data Receive reg */
+					     /* didn't return value written */
+#define XST_IIC_ADR_READBACK_ERROR      1086	/* Read of the data Tx reg     */
+					     /* didn't return value written */
+#define XST_IIC_TBA_READBACK_ERROR      1087	/* Read of the 10 bit addr reg */
+					     /* didn't return written value */
+#define XST_IIC_NOT_SLAVE               1088	/* The device isn't a slave    */
+
+/*********************** ATMC statuses 1101 - 1125 ***************************/
+
+#define XST_ATMC_ERROR_COUNT_MAX    1101L	/* the error counters in the ATM
+						   controller hit the max value
+						   which requires the statistics
+						   to be cleared */
+
+/*********************** Flash statuses 1126 - 1150 **************************/
+
+#define XST_FLASH_BUSY                1126L	/* Flash is erasing or programming */
+#define XST_FLASH_READY               1127L	/* Flash is ready for commands */
+#define XST_FLASH_ERROR               1128L	/* Flash had detected an internal
+						   error. Use XFlash_DeviceControl
+						   to retrieve device specific codes */
+#define XST_FLASH_ERASE_SUSPENDED     1129L	/* Flash is in suspended erase state */
+#define XST_FLASH_WRITE_SUSPENDED     1130L	/* Flash is in suspended write state */
+#define XST_FLASH_PART_NOT_SUPPORTED  1131L	/* Flash type not supported by
+						   driver */
+#define XST_FLASH_NOT_SUPPORTED       1132L	/* Operation not supported */
+#define XST_FLASH_TOO_MANY_REGIONS    1133L	/* Too many erase regions */
+#define XST_FLASH_TIMEOUT_ERROR       1134L	/* Programming or erase operation
+						   aborted due to a timeout */
+#define XST_FLASH_ADDRESS_ERROR       1135L	/* Accessed flash outside its
+						   addressible range */
+#define XST_FLASH_ALIGNMENT_ERROR     1136L	/* Write alignment error */
+#define XST_FLASH_BLOCKING_CALL_ERROR 1137L	/* Couldn't return immediately from
+						   write/erase function with
+						   XFL_NON_BLOCKING_WRITE/ERASE
+						   option cleared */
+#define XST_FLASH_CFI_QUERY_ERROR     1138L	/* Failed to query the device */
+
+/*********************** SPI statuses 1151 - 1175 ****************************/
+
+#define XST_SPI_MODE_FAULT          1151	/* master was selected as slave */
+#define XST_SPI_TRANSFER_DONE       1152	/* data transfer is complete */
+#define XST_SPI_TRANSMIT_UNDERRUN   1153	/* slave underruns transmit register */
+#define XST_SPI_RECEIVE_OVERRUN     1154	/* device overruns receive register */
+#define XST_SPI_NO_SLAVE            1155	/* no slave has been selected yet */
+#define XST_SPI_TOO_MANY_SLAVES     1156	/* more than one slave is being
+						 * selected */
+#define XST_SPI_NOT_MASTER          1157	/* operation is valid only as master */
+#define XST_SPI_SLAVE_ONLY          1158	/* device is configured as slave-only */
+#define XST_SPI_SLAVE_MODE_FAULT    1159	/* slave was selected while disabled */
+
+/********************** OPB Arbiter statuses 1176 - 1200 *********************/
+
+#define XST_OPBARB_INVALID_PRIORITY  1176	/* the priority registers have either
+						 * one master assigned to two or more
+						 * priorities, or one master not
+						 * assigned to any priority
+						 */
+#define XST_OPBARB_NOT_SUSPENDED     1177	/* an attempt was made to modify the
+						 * priority levels without first
+						 * suspending the use of priority
+						 * levels
+						 */
+#define XST_OPBARB_PARK_NOT_ENABLED  1178	/* bus parking by id was enabled but
+						 * bus parking was not enabled
+						 */
+#define XST_OPBARB_NOT_FIXED_PRIORITY 1179	/* the arbiter must be in fixed
+						 * priority mode to allow the
+						 * priorities to be changed
+						 */
+
+/************************ Intc statuses 1201 - 1225 **************************/
+
+#define XST_INTC_FAIL_SELFTEST      1201	/* self test failed */
+#define XST_INTC_CONNECT_ERROR      1202	/* interrupt already in use */
+
+/********************** TmrCtr statuses 1226 - 1250 **************************/
+
+#define XST_TMRCTR_TIMER_FAILED     1226	/* self test failed */
+
+/********************** WdtTb statuses 1251 - 1275 ***************************/
+
+#define XST_WDTTB_TIMER_FAILED      1251L
+
+/********************** PlbArb statuses 1276 - 1300 **************************/
+
+#define XST_PLBARB_FAIL_SELFTEST    1276L
+
+/********************** Plb2Opb statuses 1301 - 1325 *************************/
+
+#define XST_PLB2OPB_FAIL_SELFTEST   1301L
+
+/********************** Opb2Plb statuses 1326 - 1350 *************************/
+
+#define XST_OPB2PLB_FAIL_SELFTEST   1326L
+
+/********************** SysAce statuses 1351 - 1360 **************************/
+
+#define XST_SYSACE_NO_LOCK          1351L	/* No MPU lock has been granted */
+
+/********************** PCI Bridge statuses 1361 - 1375 **********************/
+
+#define XST_PCI_INVALID_ADDRESS     1361L
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * The status typedef.
+ */
+typedef u32 XStatus;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+#endif				/* end of protection macro */
diff --git a/board/xilinx/common/xversion.c b/board/xilinx/common/xversion.c
new file mode 100644
index 0000000..c8a6915
--- /dev/null
+++ b/board/xilinx/common/xversion.c
@@ -0,0 +1,350 @@
+/******************************************************************************
+*
+*     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.
+*
+******************************************************************************/
+/*****************************************************************************
+*
+* This file contains the implementation of the XVersion component. This
+* component represents a version ID.  It is encapsulated within a component
+* so that it's type and implementation can change without affecting users of
+* it.
+*
+* The version is formatted as X.YYZ where X = 0 - 9, Y = 00 - 99, Z = a - z
+* X is the major revision, YY is the minor revision, and Z is the
+* compatability revision.
+*
+* Packed versions are also utilized for the configuration ROM such that
+* memory is minimized. A packed version consumes only 16 bits and is
+* formatted as follows.
+*
+* <pre>
+* Revision                  Range       Bit Positions
+*
+* Major Revision            0 - 9       Bits 15 - 12
+* Minor Revision            0 - 99      Bits 11 - 5
+* Compatability Revision    a - z       Bits 4 - 0
+</pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xversion.h"
+
+/************************** Constant Definitions *****************************/
+
+/* the following constants define the masks and shift values to allow the
+ * revisions to be packed and unpacked, a packed version is packed into a 16
+ * bit value in the following format, XXXXYYYYYYYZZZZZ, where XXXX is the
+ * major revision, YYYYYYY is the minor revision, and ZZZZZ is the compatability
+ * revision
+ */
+#define XVE_MAJOR_SHIFT_VALUE       12
+#define XVE_MINOR_ONLY_MASK         0x0FE0
+#define XVE_MINOR_SHIFT_VALUE       5
+#define XVE_COMP_ONLY_MASK          0x001F
+
+/* the following constants define the specific characters of a version string
+ * for each character of the revision, a version string is in the following
+ * format, "X.YYZ" where X is the major revision (0 - 9), YY is the minor
+ * revision (00 - 99), and Z is the compatability revision (a - z)
+ */
+#define XVE_MAJOR_CHAR      0	/* major revision 0 - 9 */
+#define XVE_MINOR_TENS_CHAR 2	/* minor revision tens 0 - 9 */
+#define XVE_MINOR_ONES_CHAR 3	/* minor revision ones 0 - 9 */
+#define XVE_COMP_CHAR       4	/* compatability revision a - z */
+#define XVE_END_STRING_CHAR 5
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static u32 IsVersionStringValid(s8 * StringPtr);
+
+/*****************************************************************************
+*
+* Unpacks a packed version into the specified version. Versions are packed
+* into the configuration ROM to reduce the amount storage. A packed version
+* is a binary format as oppossed to a non-packed version which is implemented
+* as a string.
+*
+* @param    InstancePtr points to the version to unpack the packed version into.
+* @param    PackedVersion contains the packed version to unpack.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XVersion_UnPack(XVersion * InstancePtr, u16 PackedVersion)
+{
+	/* not implemented yet since CROM related */
+}
+
+/*****************************************************************************
+*
+* Packs a version into the specified packed version. Versions are packed into
+* the configuration ROM to reduce the amount storage.
+*
+* @param    InstancePtr points to the version to pack.
+* @param    PackedVersionPtr points to the packed version which will receive
+*           the new packed version.
+*
+* @return
+*
+* A status, XST_SUCCESS, indicating the packing was accomplished
+* successfully, or an error, XST_INVALID_VERSION, indicating the specified
+* input version was not valid such that the pack did not occur
+* <br><br>
+* The packed version pointed to by PackedVersionPtr is modified with the new
+* packed version if the status indicates success.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XVersion_Pack(XVersion * InstancePtr, u16 * PackedVersionPtr)
+{
+	/* not implemented yet since CROM related */
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************
+*
+* Determines if two versions are equal.
+*
+* @param    InstancePtr points to the first version to be compared.
+* @param    VersionPtr points to a second version to be compared.
+*
+* @return
+*
+* TRUE if the versions are equal, FALSE otherwise.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32
+XVersion_IsEqual(XVersion * InstancePtr, XVersion * VersionPtr)
+{
+	u8 *Version1 = (u8 *) InstancePtr;
+	u8 *Version2 = (u8 *) VersionPtr;
+	int Index;
+
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(VersionPtr != NULL);
+
+	/* check each byte of the versions to see if they are the same,
+	 * return at any point a byte differs between them
+	 */
+	for (Index = 0; Index < sizeof (XVersion); Index++) {
+		if (Version1[Index] != Version2[Index]) {
+			return FALSE;
+		}
+	}
+
+	/* No byte was found to be different between the versions, so indicate
+	 * the versions are equal
+	 */
+	return TRUE;
+}
+
+/*****************************************************************************
+*
+* Converts a version to a null terminated string.
+*
+* @param    InstancePtr points to the version to convert.
+* @param    StringPtr points to the string which will be the result of the
+*           conversion. This does not need to point to a null terminated
+*           string as an input, but must point to storage which is an adequate
+*           amount to hold the result string.
+*
+* @return
+*
+* The null terminated string is inserted at the location pointed to by
+* StringPtr if the status indicates success.
+*
+* @note
+*
+* It is necessary for the caller to have already allocated the storage to
+* contain the string.  The amount of memory necessary for the string is
+* specified in the version header file.
+*
+******************************************************************************/
+void
+XVersion_ToString(XVersion * InstancePtr, s8 * StringPtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(StringPtr != NULL);
+
+	/* since version is implemented as a string, just copy the specified
+	 * input into the specified output
+	 */
+	XVersion_Copy(InstancePtr, (XVersion *) StringPtr);
+}
+
+/*****************************************************************************
+*
+* Initializes a version from a null terminated string. Since the string may not
+* be a format which is compatible with the version, an error could occur.
+*
+* @param    InstancePtr points to the version which is to be initialized.
+* @param    StringPtr points to a null terminated string which will be
+*           converted to a version.  The format of the string must match the
+*           version string format which is X.YYX where X = 0 - 9, YY = 00 - 99,
+*           Z = a - z.
+*
+* @return
+*
+* A status, XST_SUCCESS, indicating the conversion was accomplished
+* successfully, or XST_INVALID_VERSION indicating the version string format
+* was not valid.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XVersion_FromString(XVersion * InstancePtr, s8 * StringPtr)
+{
+	/* assert to verify input arguments */
+
+	XASSERT_NONVOID(InstancePtr != NULL);
+	XASSERT_NONVOID(StringPtr != NULL);
+
+	/* if the version string specified is not valid, return an error */
+
+	if (!IsVersionStringValid(StringPtr)) {
+		return XST_INVALID_VERSION;
+	}
+
+	/* copy the specified string into the specified version and indicate the
+	 * conversion was successful
+	 */
+	XVersion_Copy((XVersion *) StringPtr, InstancePtr);
+
+	return XST_SUCCESS;
+}
+
+/*****************************************************************************
+*
+* Copies the contents of a version to another version.
+*
+* @param    InstancePtr points to the version which is the source of data for
+*           the copy operation.
+* @param    VersionPtr points to another version which is the destination of
+*           the copy operation.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XVersion_Copy(XVersion * InstancePtr, XVersion * VersionPtr)
+{
+	u8 *Source = (u8 *) InstancePtr;
+	u8 *Destination = (u8 *) VersionPtr;
+	int Index;
+
+	/* assert to verify input arguments */
+
+	XASSERT_VOID(InstancePtr != NULL);
+	XASSERT_VOID(VersionPtr != NULL);
+
+	/* copy each byte of the source version to the destination version */
+
+	for (Index = 0; Index < sizeof (XVersion); Index++) {
+		Destination[Index] = Source[Index];
+	}
+}
+
+/*****************************************************************************
+*
+* Determines if the specified version is valid.
+*
+* @param    StringPtr points to the string to be validated.
+*
+* @return
+*
+* TRUE if the version string is a valid format, FALSE otherwise.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static u32
+IsVersionStringValid(s8 * StringPtr)
+{
+	/* if the input string is not a valid format, "X.YYZ" where X = 0 - 9,
+	 * YY = 00 - 99, and Z = a - z, then indicate it's not valid
+	 */
+	if ((StringPtr[XVE_MAJOR_CHAR] < '0') ||
+	    (StringPtr[XVE_MAJOR_CHAR] > '9') ||
+	    (StringPtr[XVE_MINOR_TENS_CHAR] < '0') ||
+	    (StringPtr[XVE_MINOR_TENS_CHAR] > '9') ||
+	    (StringPtr[XVE_MINOR_ONES_CHAR] < '0') ||
+	    (StringPtr[XVE_MINOR_ONES_CHAR] > '9') ||
+	    (StringPtr[XVE_COMP_CHAR] < 'a') ||
+	    (StringPtr[XVE_COMP_CHAR] > 'z')) {
+		return FALSE;
+	}
+
+	return TRUE;
+}
diff --git a/board/xilinx/common/xversion.h b/board/xilinx/common/xversion.h
new file mode 100644
index 0000000..17f9da7
--- /dev/null
+++ b/board/xilinx/common/xversion.h
@@ -0,0 +1,97 @@
+/******************************************************************************
+*
+*     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.
+*
+******************************************************************************/
+/*****************************************************************************
+*
+* This file contains the interface for the XVersion component. This
+* component represents a version ID.  It is encapsulated within a component
+* so that it's type and implementation can change without affecting users of
+* it.
+*
+* The version is formatted as X.YYZ where X = 0 - 9, Y = 00 - 99, Z = a - z
+* X is the major revision, YY is the minor revision, and Z is the
+* compatability revision.
+*
+* Packed versions are also utilized for the configuration ROM such that
+* memory is minimized. A packed version consumes only 16 bits and is
+* formatted as follows.
+*
+* <pre>
+* Revision                  Range       Bit Positions
+*
+* Major Revision            0 - 9       Bits 15 - 12
+* Minor Revision            0 - 99      Bits 11 - 5
+* Compatability Revision    a - z       Bits 4 - 0
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XVERSION_H		/* prevent circular inclusions */
+#define XVERSION_H		/* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/* the following data type is used to hold a null terminated version string
+ * consisting of the following format, "X.YYX"
+ */
+typedef s8 XVersion[6];
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+void XVersion_UnPack(XVersion * InstancePtr, u16 PackedVersion);
+
+XStatus XVersion_Pack(XVersion * InstancePtr, u16 * PackedVersion);
+
+u32 XVersion_IsEqual(XVersion * InstancePtr, XVersion * VersionPtr);
+
+void XVersion_ToString(XVersion * InstancePtr, s8 * StringPtr);
+
+XStatus XVersion_FromString(XVersion * InstancePtr, s8 * StringPtr);
+
+void XVersion_Copy(XVersion * InstancePtr, XVersion * VersionPtr);
+
+#endif				/* end of protection macro */