]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
* Patch by Peter Ryser, 20 Feb 2004:
authorwdenk <wdenk>
Mon, 23 Feb 2004 23:54:43 +0000 (23:54 +0000)
committerwdenk <wdenk>
Mon, 23 Feb 2004 23:54:43 +0000 (23:54 +0000)
  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

57 files changed:
CHANGELOG
MAKEALL
Makefile
README
board/emk/top860/top860.c
board/omap1610inn/omap1610innovator.c
board/omap1610inn/platform.S
board/xilinx/common/xbasic_types.c [new file with mode: 0644]
board/xilinx/common/xbasic_types.h [new file with mode: 0644]
board/xilinx/common/xbuf_descriptor.h [new file with mode: 0644]
board/xilinx/common/xdma_channel.c [new file with mode: 0644]
board/xilinx/common/xdma_channel.h [new file with mode: 0644]
board/xilinx/common/xdma_channel_i.h [new file with mode: 0644]
board/xilinx/common/xdma_channel_sg.c [new file with mode: 0644]
board/xilinx/common/xio.h [new file with mode: 0644]
board/xilinx/common/xipif_v1_23_b.h [new file with mode: 0644]
board/xilinx/common/xpacket_fifo_v1_00_b.c [new file with mode: 0644]
board/xilinx/common/xpacket_fifo_v1_00_b.h [new file with mode: 0644]
board/xilinx/common/xstatus.h [new file with mode: 0644]
board/xilinx/common/xversion.c [new file with mode: 0644]
board/xilinx/common/xversion.h [new file with mode: 0644]
board/xilinx/ml300/Makefile [new file with mode: 0644]
board/xilinx/ml300/config.mk [new file with mode: 0644]
board/xilinx/ml300/init.S [new file with mode: 0644]
board/xilinx/ml300/ml300.c [new file with mode: 0644]
board/xilinx/ml300/serial.c [new file with mode: 0644]
board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes [new file with mode: 0644]
board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.mld [new file with mode: 0644]
board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.tcl [new file with mode: 0644]
board/xilinx/ml300/u-boot.lds [new file with mode: 0644]
board/xilinx/ml300/u-boot.lds.debug [new file with mode: 0644]
board/xilinx/ml300/xparameters.h [new file with mode: 0644]
board/xilinx/xilinx_enet/emac_adapter.c [new file with mode: 0644]
board/xilinx/xilinx_enet/xemac.c [new file with mode: 0644]
board/xilinx/xilinx_enet/xemac.h [new file with mode: 0644]
board/xilinx/xilinx_enet/xemac_g.c [new file with mode: 0644]
board/xilinx/xilinx_enet/xemac_i.h [new file with mode: 0644]
board/xilinx/xilinx_enet/xemac_intr.c [new file with mode: 0644]
board/xilinx/xilinx_enet/xemac_intr_dma.c [new file with mode: 0644]
board/xilinx/xilinx_enet/xemac_l.h [new file with mode: 0644]
board/xilinx/xilinx_enet/xemac_options.c [new file with mode: 0644]
board/xilinx/xilinx_enet/xemac_polled.c [new file with mode: 0644]
common/cmd_bdinfo.c
cpu/arm925t/interrupts.c
cpu/arm926ejs/interrupts.c
cpu/nios/interrupts.c
cpu/nios/serial.c
cpu/ppc4xx/speed.c
doc/README.ml300 [new file with mode: 0644]
drivers/cfi_flash.c
include/configs/ml300.h [new file with mode: 0644]
include/configs/omap1610h2.h
include/watchdog.h
lib_nios/board.c
lib_nios/time.c
lib_ppc/board.c
nios_config.mk

index c7b673dab93a4b98b9138e8d5ef0d5d69a960eda..d87b0a48141d664b37d8013b562437c400057cfc 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,18 @@
 Changes for U-Boot 1.0.2:
 ======================================================================
 
+* 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
+
 * Patches by Reinhard Meyer, 14 Feb 2004:
   - update board/emk tree; use common flash driver
   - Corrected tested bits in machine check exception in cpu/mpc5xxx/traps.c
diff --git a/MAKEALL b/MAKEALL
index bcf890428c84ef5558c42b4ae87cdfc00b03ffc6..2fa71b6ab67b141dee331674cc3937013430c204 100644 (file)
--- a/MAKEALL
+++ b/MAKEALL
@@ -61,10 +61,10 @@ LIST_4xx="  \
        CPCI440         CPCIISER4       CRAYL1          csb272          \
        DASA_SIM        DP405           DU405           EBONY           \
        ERIC            EXBITGEN        HUB405          MIP405          \
-       MIP405T         ML2             OCRTC           ORSG            \
-       PCI405          PIP405          PLU405          PMC405          \
-       PPChameleonEVB  VOH405          W7OLMC          W7OLMG          \
-       WALNUT405       XPEDITE1K                                       \
+       MIP405T         ML2             ml300           OCRTC           \
+       ORSG            PCI405          PIP405          PLU405          \
+       PMC405          PPChameleonEVB  VOH405          W7OLMC          \
+       W7OLMG          WALNUT405       XPEDITE1K                       \
 "
 
 #########################################################################
index 9eebf9ceb911667b87a46706ac8770b51fd59da7..044b5caba3686884eadb57b65d4c6c6fe42bd086 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -593,6 +593,9 @@ MIP405T_config:unconfig
 ML2_config:unconfig
        @./mkconfig $(@:_config=) ppc ppc4xx ml2
 
+ml300_config:unconfig
+       @./mkconfig $(@:_config=) ppc ppc4xx ml300 xilinx
+
 OCRTC_config           \
 ORSG_config:   unconfig
        @./mkconfig $(@:_config=) ppc ppc4xx ocrtc esd
diff --git a/README b/README
index 3631f01c8d80469fec1e3c40fce021b6df072473..b5a287cbf73ff4eea0fdefaa032c300ec7eda46c 100644 (file)
--- a/README
+++ b/README
@@ -1153,60 +1153,6 @@ The following options need to be configured:
                SPI configuration items (port pins to use, etc). For
                an example, see include/configs/sacsng.h.
 
-- FPGA Support: CONFIG_FPGA_COUNT
-
-               Specify the number of FPGA devices to support.
-
-               CONFIG_FPGA
-
-               Used to specify the types of FPGA devices. For
-               example,
-               #define CONFIG_FPGA  CFG_XILINX_VIRTEX2
-
-               CFG_FPGA_PROG_FEEDBACK
-
-               Enable printing of hash marks during FPGA
-               configuration.
-
-               CFG_FPGA_CHECK_BUSY
-
-               Enable checks on FPGA configuration interface busy
-               status by the configuration function. This option
-               will require a board or device specific function to
-               be written.
-
-               CONFIG_FPGA_DELAY
-
-               If defined, a function that provides delays in the
-               FPGA configuration driver.
-
-               CFG_FPGA_CHECK_CTRLC
-
-               Allow Control-C to interrupt FPGA configuration
-
-               CFG_FPGA_CHECK_ERROR
-
-               Check for configuration errors during FPGA bitfile
-               loading. For example, abort during Virtex II
-               configuration if the INIT_B line goes low (which
-               indicated a CRC error).
-
-               CFG_FPGA_WAIT_INIT
-
-               Maximum time to wait for the INIT_B line to deassert
-               after PROB_B has been deasserted during a Virtex II
-               FPGA configuration sequence. The default time is 500 mS.
-
-               CFG_FPGA_WAIT_BUSY
-
-               Maximum time to wait for BUSY to deassert during
-               Virtex II FPGA configuration. The default is 5 mS.
-
-               CFG_FPGA_WAIT_CONFIG
-
-               Time to wait after FPGA configuration. The default is
-               200 mS.
-
 - FPGA Support: CONFIG_FPGA_COUNT
 
                Specify the number of FPGA devices to support.
index 931c0d1b675f841b38f4e28631788294906d77d9..84afaaa2b2a0011144a328ac070e75d385ff422a 100644 (file)
@@ -145,4 +145,3 @@ int misc_init_r (void)
 
        return (0);
 }
-
index 0f67a0c5904d4ad6febf11d2866498c69dc6da46..521eee34c39f2213e3c87dc234a974ef747ff546 100644 (file)
@@ -11,7 +11,7 @@
  * Kshitij Gupta <Kshitij@ti.com>
  *
  * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004
- * 
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -112,9 +112,9 @@ void ether__init (void)
 #ifdef CONFIG_H2_OMAP1610
        #define LAN_RESET_REGISTER 0x0400001c
 
-       /* The debug board on which the lan chip resides may not be powered 
-        * ON at the same time as the OMAP chip. So wait in a loop until the 
-        * lan reset register (on the debug board) is available (powered on) 
+       /* The debug board on which the lan chip resides may not be powered
+        * ON at the same time as the OMAP chip. So wait in a loop until the
+        * lan reset register (on the debug board) is available (powered on)
         * and reset the lan chip.
         */
 
@@ -123,7 +123,7 @@ void ether__init (void)
                *((volatile unsigned short *) LAN_RESET_REGISTER) = 0x0001;
                udelay (3);
        } while (*((volatile unsigned short *) LAN_RESET_REGISTER) != 0x0001);
-       
+
        do {
                *((volatile unsigned short *) LAN_RESET_REGISTER) = 0x0000;
                udelay (3);
index 17756953ead27e263f69e523918dcbac7e950aed..4d6224cccfa14654364fc75a0d5e0616359105aa 100644 (file)
@@ -6,7 +6,7 @@
  * Kshitij Gupta <Kshitij@ti.com>
  *
  * Modified for OMAP 1610 H2 board by Nishant Kamat, Jan 2004
- * 
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -251,7 +251,7 @@ common_tc:
        ldr     r0,     REG_TC_EMIFS_CS3_CONFIG
        str     r1,     [r0] /* Chip Select 3 */
 
-#ifdef CONFIG_H2_OMAP1610      
+#ifdef CONFIG_H2_OMAP1610
        /* inserting additional 2 clock cycle hold time for LAN */
        ldr     r0,     REG_TC_EMIFS_CS1_ADVANCED
        ldr     r1,     VAL_TC_EMIFS_CS1_ADVANCED
diff --git a/board/xilinx/common/xbasic_types.c b/board/xilinx/common/xbasic_types.c
new file mode 100644 (file)
index 0000000..c3a171a
--- /dev/null
@@ -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 (file)
index 0000000..ef0b7c2
--- /dev/null
@@ -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 (file)
index 0000000..fdd51d5
--- /dev/null
@@ -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 (file)
index 0000000..25f1e26
--- /dev/null
@@ -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 (file)
index 0000000..06976c3
--- /dev/null
@@ -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 (file)
index 0000000..e9f343b
--- /dev/null
@@ -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 (file)
index 0000000..a8e9462
--- /dev/null
@@ -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 (file)
index 0000000..5bb09c8
--- /dev/null
@@ -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 (file)
index 0000000..b1520e9
--- /dev/null
@@ -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 (file)
index 0000000..ae2d6d4
--- /dev/null
@@ -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 (file)
index 0000000..1cda0e8
--- /dev/null
@@ -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 (file)
index 0000000..ffda4d7
--- /dev/null
@@ -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 (file)
index 0000000..c8a6915
--- /dev/null
@@ -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 (file)
index 0000000..17f9da7
--- /dev/null
@@ -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 */
diff --git a/board/xilinx/ml300/Makefile b/board/xilinx/ml300/Makefile
new file mode 100644 (file)
index 0000000..d9007c0
--- /dev/null
@@ -0,0 +1,57 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# 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., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+CFLAGS   += -I../ml300 -I../common -I../xilinx_enet
+
+LIB    = lib$(BOARD).a
+
+OBJS   = $(BOARD).o serial.o \
+         ../xilinx_enet/emac_adapter.o ../xilinx_enet/xemac.o \
+         ../xilinx_enet/xemac_options.o ../xilinx_enet/xemac_polled.o \
+         ../xilinx_enet/xemac_intr.o ../xilinx_enet/xemac_g.o \
+         ../xilinx_enet/xemac_intr_dma.o \
+         ../common/xbasic_types.o ../common/xdma_channel.o \
+         ../common/xdma_channel_sg.o ../common/xpacket_fifo_v1_00_b.o \
+         ../common/xversion.o
+
+SOBJS  = init.o
+
+$(LIB):        $(OBJS) $(SOBJS)
+       $(AR) crv $@ $^
+
+clean:
+       rm -f $(SOBJS) $(OBJS)
+
+distclean:     clean
+       rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:       Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+               $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/xilinx/ml300/config.mk b/board/xilinx/ml300/config.mk
new file mode 100644 (file)
index 0000000..57ddb2f
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# (C) Copyright 2000
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# 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., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+#
+# esd ADCIOP boards
+#
+
+#TEXT_BASE = 0xFFFE0000
+TEXT_BASE = 0x04000000
diff --git a/board/xilinx/ml300/init.S b/board/xilinx/ml300/init.S
new file mode 100644 (file)
index 0000000..f753df8
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * init.S: Stubs for U-Boot initialization
+ *
+ *     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.
+ *
+ *
+ */
+
+       .globl ext_bus_cntlr_init
+ext_bus_cntlr_init:
+       blr
+
+       .globl sdram_init
+sdram_init:
+       blr
diff --git a/board/xilinx/ml300/ml300.c b/board/xilinx/ml300/ml300.c
new file mode 100644 (file)
index 0000000..dbe8a8a
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * ml300.c: U-Boot platform support for Xilinx ML300 board
+ *
+ *     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.
+ *
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+#include "xparameters.h"
+
+int
+board_pre_init(void)
+{
+       return 0;
+}
+
+int
+checkboard(void)
+{
+       unsigned char *s = getenv("serial#");
+       unsigned char *e;
+
+       if (!s || strncmp(s, "ML300", 9)) {
+               printf("### No HW ID - assuming ML300");
+       } else {
+               for (e = s; *e; ++e) {
+                       if (*e == ' ')
+                               break;
+               }
+
+               for (; s < e; ++s) {
+                       putc(*s);
+               }
+       }
+
+       putc('\n');
+
+       return (0);
+}
+
+long int
+initdram(int board_type)
+{
+       return 128 * 1024 * 1024;
+}
+
+int
+testdram(void)
+{
+       printf("test: xxx MB - ok\n");
+
+       return (0);
+}
+
+/* implement functions originally in cpu/ppc4xx/speed.c */
+void
+get_sys_info(sys_info_t * sysInfo)
+{
+       sysInfo->freqProcessor = XPAR_CORE_CLOCK_FREQ_HZ;
+
+       /* only correct if the PLB and OPB run at the same frequency */
+       sysInfo->freqPLB = XPAR_UARTNS550_0_CLOCK_FREQ_HZ;
+       sysInfo->freqPCI = XPAR_UARTNS550_0_CLOCK_FREQ_HZ / 3;
+}
+
+ulong
+get_PCI_freq(void)
+{
+       ulong val;
+       PPC405_SYS_INFO sys_info;
+
+       get_sys_info(&sys_info);
+       val = sys_info.freqPCI;
+       return val;
+}
diff --git a/board/xilinx/ml300/serial.c b/board/xilinx/ml300/serial.c
new file mode 100644 (file)
index 0000000..19bcc6f
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ *     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.
+ *
+ */
+
+#include <asm/u-boot.h>
+#include <asm/processor.h>
+#include <common.h>
+#include <command.h>
+#include <configs/ml300.h>
+#include "xparameters.h"
+
+#define USE_CHAN1 \
+       ((defined XPAR_UARTNS550_0_BASEADDR) && (defined CFG_INIT_CHAN1))
+#define USE_CHAN2 \
+       ((defined XPAR_UARTNS550_1_BASEADDR) && (defined CFG_INIT_CHAN2))
+
+#if USE_CHAN1
+#include <ns16550.h>
+#endif
+
+#if USE_CHAN1
+const NS16550_t COM_PORTS[] = { (NS16550_t) (XPAR_UARTNS550_0_BASEADDR + 3)
+#if USE_CHAN2
+           , (NS16550_t) (XPAR_UARTNS550_1_BASEADDR + 3)
+#endif
+};
+#endif
+
+int
+serial_init(void)
+{
+#if USE_CHAN1
+       DECLARE_GLOBAL_DATA_PTR;
+       int clock_divisor;
+
+       clock_divisor = XPAR_UARTNS550_0_CLOCK_FREQ_HZ / 16 / gd->baudrate;
+       (void) NS16550_init(COM_PORTS[0], clock_divisor);
+#if USE_CHAN2
+       clock_divisor = XPAR_UARTNS550_1_CLOCK_FREQ_HZ / 16 / gd->baudrate;
+       (void) NS16550_init(COM_PORTS[1], clock_divisor);
+#endif
+#endif
+       return 0;
+
+}
+
+void
+serial_putc(const char c)
+{
+       if (c == '\n')
+               NS16550_putc(COM_PORTS[CFG_DUART_CHAN], '\r');
+
+       NS16550_putc(COM_PORTS[CFG_DUART_CHAN], c);
+}
+
+int
+serial_getc(void)
+{
+       return NS16550_getc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+int
+serial_tstc(void)
+{
+       return NS16550_tstc(COM_PORTS[CFG_DUART_CHAN]);
+}
+
+void
+serial_setbrg(void)
+{
+#if USE_CHAN1
+       DECLARE_GLOBAL_DATA_PTR;
+       int clock_divisor;
+
+       clock_divisor = XPAR_UARTNS550_0_CLOCK_FREQ_HZ / 16 / gd->baudrate;
+       NS16550_reinit(COM_PORTS[0], clock_divisor);
+#if USE_CHAN2
+       clock_divisor = XPAR_UARTNS550_1_CLOCK_FREQ_HZ / 16 / gd->baudrate;
+       NS16550_reinit(COM_PORTS[1], clock_divisor);
+#endif
+#endif
+}
+
+void
+serial_puts(const char *s)
+{
+       while (*s) {
+               serial_putc(*s++);
+       }
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+void
+kgdb_serial_init(void)
+{
+}
+
+void
+putDebugChar(int c)
+{
+       serial_putc(c);
+}
+
+void
+putDebugStr(const char *str)
+{
+       serial_puts(str);
+}
+
+int
+getDebugChar(void)
+{
+       return serial_getc();
+}
+
+void
+kgdb_interruptible(int yes)
+{
+       return;
+}
+#endif                         /* CFG_CMD_KGDB */
diff --git a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes b/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/Ltypes
new file mode 100644 (file)
index 0000000..319b925
--- /dev/null
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+if[$
+# -ne 1 ]
+   then echo "usage: Ltypes filename" > &2 exit 2 fi FILE = "$1"
+#TMPFILE='mktemp "${FILE}.XXXXXX"' || exit 1
+   TMPFILE = $ {
+   FILE}
+
+   . ` date "+%s" ` touch $TMPFILE || exit 1
+# Change all the Xilinx types to Linux types and put the result into a temp file
+   sed
+   - e 's/\bXTRUE\b/TRUE/g'
+   - e 's/\bXFALSE\b/FALSE/g'
+   - e 's/\bXNULL\b/NULL/g'
+   - e 's/<asm/delay.h>/<asm\/delay.h>/g'
+   - e 's/\bXENV_USLEEP\b/udelay/g'
+   - e 's/\bXuint8\b/u8/g'
+   - e 's/\bXuint16\b/u16/g'
+   - e 's/\bXuint32\b/u32/g'
+   - e 's/\bXint8\b/s8/g'
+   - e 's/\bXint16\b/s16/g'
+   - e 's/\bXint32\b/s32/g' - e 's/\bXboolean\b/u32/g' "${FILE}" > "${TMPFILE}"
+# Overlay the original file with the temp file
+   mv "${TMPFILE}" "${FILE}"
+# Are we doing xbasic_types.h?
+   if["${FILE##*/}" = xbasic_types.h]
+   then
+# Remember as you're reading this that we've already gone through the prior
+# sed script.  We need to do some other things to xbasic_types.h:
+#   1) Add ifndefs around TRUE and FALSE defines
+#   2) Remove definition of NULL as NULL
+#   3) Replace most of the primitive types section with a #include
+   sed - e '/u32 true/,/#define false/Ic\
+#ifndef TRUE\
+#define TRUE 1\
+#endif\
+#ifndef FALSE\
+#define FALSE 0\
+#endif' - e '/#define[[:space:]][[:space:]]*NULL[[:space:]][[:space:]]*NULL/d' - e '/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*char[[:space:]][[:space:]]*u8/,/typedef[[:space:]][[:space:]]*unsigned[[:space:]][[:space:]]*long[[:space:]][[:space:]]*u32.*boolean/c\
+#include <linux/types.h>' "${FILE}" > "${TMPFILE}" mv "${TMPFILE}" "${FILE}" fi
diff --git a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.mld b/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.mld
new file mode 100644 (file)
index 0000000..e1aa7fd
--- /dev/null
@@ -0,0 +1,48 @@
+# (c) Copyright 2004 Xilinx Inc.
+#     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.
+
+OPTION psf_version = 2.1;
+
+BEGIN LIBRARY uboot OPTION DRC = uboot_drc;
+
+BEGIN ARRAY connected_periphs PROPERTY desc = "Peripherals connected to U-Boot";
+PROPERTY size = 0;
+PARAM name = periph_name, desc = "Name of Peripheral connected", type = string;
+END ARRAY
+    PARAMETER name = TARGET_DIR, desc =
+    "Target Directory for U-Boot BSP", type = string;
+
+END LIBRARY
diff --git a/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.tcl b/board/xilinx/ml300/sw_services/uboot_v1_00_a/data/uboot_v2_1_0.tcl
new file mode 100644 (file)
index 0000000..8d939b4
--- /dev/null
@@ -0,0 +1,298 @@
+#
+#      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.
+#
+# Globals
+lappend drvlist
+set ltypes "../../../sw_services/uboot_v1_00_a/data/Ltypes"
+
+proc uboot_drc {lib_handle} {
+    puts "U-Boot DRC..."
+}
+
+proc generate {libname} {
+    
+    global drvlist
+    
+    # Get list of peripherals connected to uboot
+    set conn_periphs [xget_handle $libname "ARRAY" "connected_periphs"]
+    #lappend drvlist
+    if {[string compare -nocase $conn_periphs ""] != 0} {
+       set conn_periphs_elems [xget_handle $conn_periphs "ELEMENTS" "*"]
+       # For each periph
+       foreach periph_elem $conn_periphs_elems {
+           set periph [xget_value $periph_elem "PARAMETER" "periph_name"]
+           # 1. Get driver
+           set drv [xget_swhandle $periph]
+           set posn [lsearch -exact $drvlist $drv]
+           if {$posn == -1} {
+               lappend drvlist $drv
+           }
+       }
+       
+       set file_handle [xopen_include_file "xparameters.h"]
+       puts $file_handle "\n/******************************************************************/\n"
+       puts $file_handle "/* U-Boot Redefines */"
+       puts $file_handle "\n/******************************************************************/\n"
+       close $file_handle
+       
+       foreach drv $drvlist {
+           set drvname [xget_value $drv "NAME"]
+           
+           #Redefines xparameters.h
+           if {[string compare -nocase $drvname "uartns550"] == 0} {
+               xredefine_uartns550 $drv "xparameters.h"
+           }  elseif {[string compare -nocase $drvname "emac"] == 0} {
+               xredefine_emac $drv "xparameters.h"
+           }
+       }
+    }
+    
+    # define core_clock
+    xredefine_params $libname "xparameters.h" "CORE_CLOCK_FREQ_HZ"
+}
+
+proc xget_corefreq {} {
+    set processor [xget_processor] 
+    set name [xget_value $processor "NAME"]
+    puts "procname : $name"
+    set processor_driver [xget_swhandle [xget_value $processor "NAME"]]
+    puts "procdrv : $processor_driver"
+    if {[string compare -nocase $processor_driver ""] != 0} {
+       set arg "CORE_CLOCK_FREQ_HZ"
+       #set retval [xget_value $processor_driver "PARAMETER" $arg]
+       set retval [xget_dname [xget_value $processor_driver "NAME"] $arg]
+       return $retval
+    }
+}
+
+# procedure that adds # defines to xparameters.h as XPAR_argument
+proc xredefine_params {handle file_name args} {
+    
+    puts "xredfine ..."
+    # Open include file
+    set file_handle [xopen_include_file $file_name]
+    puts "args : $args"
+
+    foreach arg $args {
+       if {[string compare -nocase $arg "CORE_CLOCK_FREQ_HZ"] == 0} {
+           set value [xget_corefreq]
+           puts "corefreq : $value"
+       } else {
+           set value [xget_value $handle "PARAMETER" $arg]
+           puts "value : $value"
+       }
+       
+       if {$value != ""} {
+           set value [xformat_addr_string $value $arg]
+           set name [string toupper $arg]
+           set name [format "XPAR_%s" $name]
+           puts $file_handle "#define $name $value"
+       }
+    }
+
+    puts $file_handle "\n/******************************************************************/\n"
+    close $file_handle
+}
+
+# uart redefines...
+proc xredefine_uartns550 {drvhandle file_name} {
+    
+    xredefine_include_file $drvhandle $file_name "uartns550" "C_BASEADDR" "C_HIGHADDR" "CLOCK_HZ" "DEVICE_ID"
+    
+}
+
+proc xredefine_emac {drvhandle file_name} {
+    
+    xredefine_include_file $drvhandle $file_name "emac" "C_BASEADDR" "C_HIGHADDR" "C_DMA_PRESENT" "C_MII_EXIST" "C_ERR_COUNT_EXIST" "DEVICE_ID"
+    
+}
+
+#######################
+
+proc xredefine_include_file {drv_handle file_name drv_string args} {
+    
+    # Open include file
+    set file_handle [xopen_include_file $file_name]
+    
+    # Get all peripherals connected to this driver
+    set periphs [xget_periphs $drv_handle] 
+    
+    set pname [format "XPAR_%s_" [string toupper $drv_string]]
+    
+    # Print all parameters for all peripherals
+    set device_id 0
+    set sub_periphs 1
+    foreach periph $periphs {
+       puts "$periph : $drv_string : $sub_periphs"
+
+       for {set i 0} {$i < $sub_periphs} {incr i} {
+           foreach arg $args {
+               set name "${pname}${device_id}_"
+           
+               if {[string compare -nocase "CLOCK_HZ" $arg] == 0} {
+                   set xdrv_string [format "%s%s" "X" $drv_string]
+                   set value [xget_dname $xdrv_string $arg]
+                   set name "${name}CLOCK_FREQ_HZ"
+               } else {
+                   if {[string match C_* $arg]} {
+                       set name [format "%s%s" $name [string range $arg 2 end]]
+                   } else {
+                       set name "${name}${arg}"
+                   }
+                   set value [xget_name $periph $arg]
+               }
+
+               if {[string compare -nocase "uartns550" $drv_string] == 0} {
+                   if {[string compare -nocase "C_BASEADDR" $arg] == 0} {
+                       set value [format "(%s%s%s)" $value "+" "0x1000"]
+                   }
+               }
+
+               puts $file_handle "#define $name $value"
+               if {[string compare -nocase "DEVICE_ID" $arg] == 0} {
+                   incr device_id
+               }
+           }
+       }
+    }          
+    puts $file_handle "\n/******************************************************************/\n"
+    close $file_handle
+}
+
+##################################################
+# procedure post_generate
+# This generates the drivers directory for uboot
+# and runs the ltypes script
+##################################################
+
+proc post_generate {lib_handle} {
+    
+    global drvlist
+    
+    # Create U-Boot tree structure
+    set pwd [pwd]
+    set common_dir "uboot/board/xilinx/common"
+    set xilinx_enet_dir "uboot/board/xilinx/xilinx_enet"
+    set ml300_dir  "uboot/board/xilinx/ml300"
+    
+    exec bash -c "mkdir -p $common_dir $xilinx_enet_dir $ml300_dir"
+    
+    # Copy files for xilinx_ocp
+    xcopy_commonfiles
+
+    foreach drv $drvlist {
+       set drvname [xget_value $drv "NAME"]
+       set ver [xget_value $drv "PARAMETER" "DRIVER_VER"]
+       set ver [string map {. _} $ver]
+       set dirname [format "%s_v%s" $drvname $ver]
+       
+       if {[string compare -nocase $drvname "emac"] == 0} {
+           xcopy_emac $drv $dirname
+       }
+    }
+    
+    # Call Ltypes Script here
+    set uboot "uboot"
+    xltype_file $uboot
+
+    # Move xparameters.h around
+    exec bash -c "cp ../../include/xparameters.h $ml300_dir"
+
+    # copy the whole U-Boot BSP to its final destination
+    set value [xget_value $lib_handle "PARAMETER" TARGET_DIR]
+    puts "TARGET_DIR : $value"
+
+    if {$value != ""} {
+        if {[file isdirectory $value] == 0} {
+            exec bash -c "mkdir -p $value"
+        }
+        exec bash -c "cp -Rp uboot/* $value"
+    }
+}
+
+proc xcopy_commonfiles {} {
+
+    global drvlist
+
+    set common_dir "uboot/board/xilinx/common"
+    
+    foreach drv $drvlist {
+       set depends [xget_value $drv "OPTION" "DEPENDS"]
+       foreach dep $depends {
+           puts "dep : $dep"
+           if {[file isdirectory "../$dep"] == 1} {
+               exec bash -c "cp -f ../$dep/src/*.c $common_dir"
+               exec bash -c "cp -f ../$dep/src/*.h $common_dir"
+           }
+       }
+    }
+    
+}
+
+proc xcopy_emac {drv_handle dirname} {
+    set emac "board/xilinx/xilinx_enet"
+    xcopy_dir $dirname $emac
+}
+
+proc xcopy_dir {srcdir dstdir} {
+    
+    set dstdirname [format "%s%s" "uboot/" $dstdir]
+    if {[file isdirectory "../$srcdir"] == 1} {
+       # Copy files from src to dst
+       exec bash -c "mkdir -p $dstdirname"
+       exec bash -c "cp -f ../$srcdir/src/*.c $dstdirname"
+       exec bash -c "cp -f ../$srcdir/src/*.h $dstdirname"
+    } else {
+       puts "$srcdir does not exist ..."
+    }
+}
+
+
+proc xltype_file {filename} {
+
+    global ltypes
+
+    puts $filename
+
+    if {[file isdirectory $filename]} {
+       foreach entry [glob -nocomplain [file join $filename *]] {
+           xltype_file $entry
+       }
+    } else {
+       exec bash -c "$ltypes $filename"
+    }
+    
+}
diff --git a/board/xilinx/ml300/u-boot.lds b/board/xilinx/ml300/u-boot.lds
new file mode 100644 (file)
index 0000000..e7b7e10
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+ENTRY(_start)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .rel.text      : { *(.rel.text)              }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)              }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  }
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within */
+    /* the sector layout of our flash chips!   XXX FIXME XXX   */
+/*
+    cpu/ppc4xx/start.o (.text)
+    board/xilinx/ml300/init.o  (.text)
+    cpu/ppc4xx/kgdb.o  (.text)
+    cpu/ppc4xx/traps.o (.text)
+    cpu/ppc4xx/interrupts.o    (.text)
+    cpu/ppc4xx/serial.o        (.text)
+    cpu/ppc4xx/cpu_init.o      (.text)
+    cpu/ppc4xx/speed.o (.text)
+    cpu/ppc4xx/405gp_enet.o    (.text)
+    common/dlmalloc.o  (.text)
+    lib_generic/crc32.o                (.text)
+    lib_ppc/extable.o  (.text)
+    lib_generic/zlib.o         (.text)
+*/
+/*    . = env_offset;*/
+/*    common/environment.o(.text)*/
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+    *(.rodata.str1.4)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/board/xilinx/ml300/u-boot.lds.debug b/board/xilinx/ml300/u-boot.lds.debug
new file mode 100644 (file)
index 0000000..d483424
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .rel.text      : { *(.rel.text)              }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)              }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  }
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within */
+    /* the sector layout of our flash chips!   XXX FIXME XXX   */
+
+    mpc8xx/start.o     (.text)
+    common/dlmalloc.o  (.text)
+    lib_generic/vsprintf.o     (.text)
+    lib_generic/crc32.o                (.text)
+    lib_ppc/extable.o  (.text)
+
+    common/environment.o(.text)
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __u_boot_cmd_start = .;
+  .u_boot_cmd : { *(.u_boot_cmd) }
+  __u_boot_cmd_end = .;
+
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(4096);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(4096);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
diff --git a/board/xilinx/ml300/xparameters.h b/board/xilinx/ml300/xparameters.h
new file mode 100644 (file)
index 0000000..c636256
--- /dev/null
@@ -0,0 +1,216 @@
+/*******************************************************************
+*
+* CAUTION: This file is automatically generated by libgen.
+* Version: Xilinx EDK 6.1.2 EDK_G.14
+* DO NOT EDIT.
+*
+*     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.
+*
+* Description: Driver parameters
+*
+*******************************************************************/
+
+#define XPAR_XPCI_NUM_INSTANCES 1
+#define XPAR_XPCI_CLOCK_HZ 33333333
+#define XPAR_OPB_PCI_REF_0_DEVICE_ID 0
+#define XPAR_OPB_PCI_REF_0_BASEADDR 0x20000000
+#define XPAR_OPB_PCI_REF_0_HIGHADDR 0x3FFFFFFF
+#define XPAR_OPB_PCI_REF_0_CONFIG_ADDR 0x3C000000
+#define XPAR_OPB_PCI_REF_0_CONFIG_DATA 0x3C000004
+#define XPAR_OPB_PCI_REF_0_LCONFIG_ADDR 0x3E000000
+#define XPAR_OPB_PCI_REF_0_MEM_BASEADDR 0x20000000
+#define XPAR_OPB_PCI_REF_0_MEM_HIGHADDR 0x37FFFFFF
+#define XPAR_OPB_PCI_REF_0_IO_BASEADDR 0x38000000
+#define XPAR_OPB_PCI_REF_0_IO_HIGHADDR 0x3BFFFFFF
+
+/******************************************************************/
+
+#define XPAR_XEMAC_NUM_INSTANCES 1
+#define XPAR_OPB_ETHERNET_0_BASEADDR 0x60000000
+#define XPAR_OPB_ETHERNET_0_HIGHADDR 0x60003FFF
+#define XPAR_OPB_ETHERNET_0_DEVICE_ID 0
+#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST 1
+#define XPAR_OPB_ETHERNET_0_DMA_PRESENT 1
+#define XPAR_OPB_ETHERNET_0_MII_EXIST 1
+
+/******************************************************************/
+
+#define XPAR_MY_OPB_GPIO_0_DEVICE_ID_0 0
+#define XPAR_MY_OPB_GPIO_0_BASEADDR_0 0x90000000
+#define XPAR_MY_OPB_GPIO_0_HIGHADDR_0 (0x90000000+0x7)
+#define XPAR_MY_OPB_GPIO_0_DEVICE_ID_1 1
+#define XPAR_MY_OPB_GPIO_0_BASEADDR_1 (0x90000000+0x8)
+#define XPAR_MY_OPB_GPIO_0_HIGHADDR_1 (0x90000000+0x1F)
+#define XPAR_XGPIO_NUM_INSTANCES 2
+
+/******************************************************************/
+
+#define XPAR_XIIC_NUM_INSTANCES 1
+#define XPAR_OPB_IIC_0_BASEADDR 0xA8000000
+#define XPAR_OPB_IIC_0_HIGHADDR 0xA80001FF
+#define XPAR_OPB_IIC_0_DEVICE_ID 0
+#define XPAR_OPB_IIC_0_TEN_BIT_ADR 0
+
+/******************************************************************/
+
+#define XPAR_XUARTNS550_NUM_INSTANCES 2
+#define XPAR_XUARTNS550_CLOCK_HZ 100000000
+#define XPAR_OPB_UART16550_0_BASEADDR 0xA0000000
+#define XPAR_OPB_UART16550_0_HIGHADDR 0xA0001FFF
+#define XPAR_OPB_UART16550_0_DEVICE_ID 0
+#define XPAR_OPB_UART16550_1_BASEADDR 0xA0010000
+#define XPAR_OPB_UART16550_1_HIGHADDR 0xA0011FFF
+#define XPAR_OPB_UART16550_1_DEVICE_ID 1
+
+/******************************************************************/
+
+#define XPAR_XSPI_NUM_INSTANCES 1
+#define XPAR_OPB_SPI_0_BASEADDR 0xA4000000
+#define XPAR_OPB_SPI_0_HIGHADDR 0xA400007F
+#define XPAR_OPB_SPI_0_DEVICE_ID 0
+#define XPAR_OPB_SPI_0_FIFO_EXIST 1
+#define XPAR_OPB_SPI_0_SPI_SLAVE_ONLY 0
+#define XPAR_OPB_SPI_0_NUM_SS_BITS 1
+
+/******************************************************************/
+
+#define XPAR_XPS2_NUM_INSTANCES 2
+#define XPAR_OPB_PS2_DUAL_REF_0_DEVICE_ID_0 0
+#define XPAR_OPB_PS2_DUAL_REF_0_BASEADDR_0 0xA9000000
+#define XPAR_OPB_PS2_DUAL_REF_0_HIGHADDR_0 (0xA9000000+0x3F)
+#define XPAR_OPB_PS2_DUAL_REF_0_DEVICE_ID_1 1
+#define XPAR_OPB_PS2_DUAL_REF_0_BASEADDR_1 (0xA9000000+0x1000)
+#define XPAR_OPB_PS2_DUAL_REF_0_HIGHADDR_1 (0xA9000000+0x103F)
+
+/******************************************************************/
+
+#define XPAR_XTOUCHSCREEN_NUM_INSTANCES 1
+#define XPAR_OPB_TSD_REF_0_BASEADDR 0xAA000000
+#define XPAR_OPB_TSD_REF_0_HIGHADDR 0xAA000007
+#define XPAR_OPB_TSD_REF_0_DEVICE_ID 0
+
+/******************************************************************/
+
+#define XPAR_OPB_AC97_CONTROLLER_REF_0_BASEADDR 0xA6000000
+#define XPAR_OPB_AC97_CONTROLLER_REF_0_HIGHADDR 0xA60000FF
+#define XPAR_OPB_PAR_PORT_REF_0_BASEADDR 0x90010000
+#define XPAR_OPB_PAR_PORT_REF_0_HIGHADDR 0x900100FF
+#define XPAR_PLB_DDR_0_BASEADDR 0x00000000
+#define XPAR_PLB_DDR_0_HIGHADDR 0x0FFFFFFF
+
+/******************************************************************/
+
+#define XPAR_XINTC_HAS_IPR 1
+#define XPAR_INTC_MAX_NUM_INTR_INPUTS 18
+#define XPAR_XINTC_USE_DCR 0
+#define XPAR_XINTC_NUM_INSTANCES 1
+#define XPAR_DCR_INTC_0_BASEADDR 0xD0000FC0
+#define XPAR_DCR_INTC_0_HIGHADDR 0xD0000FDF
+#define XPAR_DCR_INTC_0_DEVICE_ID 0
+#define XPAR_DCR_INTC_0_KIND_OF_INTR 0x00038000
+
+/******************************************************************/
+
+#define XPAR_DCR_INTC_0_MISC_LOGIC_0_PHY_MII_INT_INTR 0
+#define XPAR_DCR_INTC_0_OPB_ETHERNET_0_IP2INTC_IRPT_INTR 1
+#define XPAR_DCR_INTC_0_MISC_LOGIC_0_IIC_TEMP_CRIT_INTR 2
+#define XPAR_DCR_INTC_0_MISC_LOGIC_0_IIC_IRQ_INTR 3
+#define XPAR_DCR_INTC_0_OPB_IIC_0_IP2INTC_IRPT_INTR 4
+#define XPAR_DCR_INTC_0_OPB_SYSACE_0_SYSACE_IRQ_INTR 5
+#define XPAR_DCR_INTC_0_OPB_UART16550_0_IP2INTC_IRPT_INTR 6
+#define XPAR_DCR_INTC_0_OPB_UART16550_1_IP2INTC_IRPT_INTR 7
+#define XPAR_DCR_INTC_0_OPB_PS2_DUAL_REF_0_SYS_INTR1_INTR 8
+#define XPAR_DCR_INTC_0_OPB_PS2_DUAL_REF_0_SYS_INTR2_INTR 9
+#define XPAR_DCR_INTC_0_OPB_SPI_0_IP2INTC_IRPT_INTR 10
+#define XPAR_DCR_INTC_0_OPB_TSD_REF_0_INTR_INTR 11
+#define XPAR_DCR_INTC_0_OPB_AC97_CONTROLLER_REF_0_PLAYBACK_INTERRUPT_INTR 12
+#define XPAR_DCR_INTC_0_OPB_AC97_CONTROLLER_REF_0_RECORD_INTERRUPT_INTR 13
+#define XPAR_DCR_INTC_0_OPB_PCI_REF_0_INTR_OUT_INTR 14
+#define XPAR_DCR_INTC_0_PLB2OPB_BRIDGE_0_BUS_ERROR_DET_INTR 15
+#define XPAR_DCR_INTC_0_PLB_V34_0_BUS_ERROR_DET_INTR 16
+#define XPAR_DCR_INTC_0_OPB2PLB_BRIDGE_0_BUS_ERROR_DET_INTR 17
+
+/******************************************************************/
+
+#define XPAR_XTFT_NUM_INSTANCES 1
+#define XPAR_PLB_TFT_CNTLR_REF_0_DCR_BASEADDR 0xD0000200
+#define XPAR_PLB_TFT_CNTLR_REF_0_DCR_HIGHADDR 0xD0000207
+#define XPAR_PLB_TFT_CNTLR_REF_0_DEVICE_ID 0
+
+/******************************************************************/
+
+#define XPAR_XSYSACE_MEM_WIDTH 8
+#define XPAR_XSYSACE_NUM_INSTANCES 1
+#define XPAR_OPB_SYSACE_0_BASEADDR 0xCF000000
+#define XPAR_OPB_SYSACE_0_HIGHADDR 0xCF0001FF
+#define XPAR_OPB_SYSACE_0_DEVICE_ID 0
+#define XPAR_OPB_SYSACE_0_MEM_WIDTH 8
+
+/******************************************************************/
+
+#define STDIN_BASEADDRESS 0xA0000000
+#define STDOUT_BASEADDRESS 0xA0000000
+#define XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ 300000000
+
+/******************************************************************/
+
+/* U-Boot Redefines */
+
+/******************************************************************/
+
+#define XPAR_UARTNS550_0_BASEADDR (XPAR_OPB_UART16550_0_BASEADDR+0x1000)
+#define XPAR_UARTNS550_0_HIGHADDR XPAR_OPB_UART16550_0_HIGHADDR
+#define XPAR_UARTNS550_0_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
+#define XPAR_UARTNS550_0_DEVICE_ID XPAR_OPB_UART16550_0_DEVICE_ID
+#define XPAR_UARTNS550_1_BASEADDR (XPAR_OPB_UART16550_1_BASEADDR+0x1000)
+#define XPAR_UARTNS550_1_HIGHADDR XPAR_OPB_UART16550_1_HIGHADDR
+#define XPAR_UARTNS550_1_CLOCK_FREQ_HZ XPAR_XUARTNS550_CLOCK_HZ
+#define XPAR_UARTNS550_1_DEVICE_ID XPAR_OPB_UART16550_1_DEVICE_ID
+
+/******************************************************************/
+
+#define XPAR_EMAC_0_BASEADDR XPAR_OPB_ETHERNET_0_BASEADDR
+#define XPAR_EMAC_0_HIGHADDR XPAR_OPB_ETHERNET_0_HIGHADDR
+#define XPAR_EMAC_0_DMA_PRESENT XPAR_OPB_ETHERNET_0_DMA_PRESENT
+#define XPAR_EMAC_0_MII_EXIST XPAR_OPB_ETHERNET_0_MII_EXIST
+#define XPAR_EMAC_0_ERR_COUNT_EXIST XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST
+#define XPAR_EMAC_0_DEVICE_ID XPAR_OPB_ETHERNET_0_DEVICE_ID
+
+/******************************************************************/
+
+#define XPAR_CORE_CLOCK_FREQ_HZ XPAR_CPU_PPC405_CORE_CLOCK_FREQ_HZ
+
+/******************************************************************/
diff --git a/board/xilinx/xilinx_enet/emac_adapter.c b/board/xilinx/xilinx_enet/emac_adapter.c
new file mode 100644 (file)
index 0000000..a3c37ba
--- /dev/null
@@ -0,0 +1,153 @@
+/******************************************************************************
+*
+*     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.
+*
+******************************************************************************/
+
+#include <common.h>
+#include <net.h>
+#include <configs/ml300.h>
+#include "xparameters.h"
+#include "xemac.h"
+
+#if defined(XPAR_EMAC_0_DEVICE_ID)
+/*
+ * ENET_MAX_MTU and ENET_MAX_MTU_ALIGNED are set from
+ * PKTSIZE and PKTSIZE_ALIGN (include/net.h)
+ */
+
+#define ENET_MAX_MTU           PKTSIZE
+#define ENET_MAX_MTU_ALIGNED   PKTSIZE_ALIGN
+#define ENET_ADDR_LENGTH       6
+
+static XEmac Emac;
+static char etherrxbuff[PKTSIZE_ALIGN];        /* Receive buffer */
+
+/* hardcoded MAC address for the Xilinx EMAC Core */
+static u8 EMACAddr[ENET_ADDR_LENGTH] = { 0x00, 0x0a, 0x35, 0x00, 0x22, 0x01 };
+
+static int initialized = 0;
+
+void
+eth_halt(void)
+{
+       if (initialized)
+               (void) XEmac_Stop(&Emac);
+}
+
+int
+eth_init(bd_t * bis)
+{
+       u32 Options;
+       XStatus Result;
+
+#ifdef DEBUG
+       printf("EMAC Initialization Started\n\r");
+#endif
+
+       Result = XEmac_Initialize(&Emac, XPAR_EMAC_0_DEVICE_ID);
+       if (Result != XST_SUCCESS) {
+               return 0;
+       }
+
+       /* make sure the Emac is stopped before it is started */
+       (void) XEmac_Stop(&Emac);
+
+       memcpy(bis->bi_enetaddr, EMACAddr, 6);
+       Result = XEmac_SetMacAddress(&Emac, EMACAddr);
+       if (Result != XST_SUCCESS) {
+               return 0;
+       }
+
+       Options =
+           (XEM_POLLED_OPTION | XEM_UNICAST_OPTION | XEM_BROADCAST_OPTION |
+            XEM_FDUPLEX_OPTION | XEM_INSERT_FCS_OPTION |
+            XEM_INSERT_PAD_OPTION);
+       Result = XEmac_SetOptions(&Emac, Options);
+       if (Result != XST_SUCCESS) {
+               return 0;
+       }
+
+       Result = XEmac_Start(&Emac);
+       if (Result != XST_SUCCESS) {
+               return 0;
+       }
+#ifdef DEBUG
+       printf("EMAC Initialization complete\n\r");
+#endif
+
+       initialized = 1;
+
+       return (0);
+}
+
+/*-----------------------------------------------------------------------------+
++-----------------------------------------------------------------------------*/
+int
+eth_send(volatile void *ptr, int len)
+{
+       XStatus Result;
+
+       if (len > ENET_MAX_MTU)
+               len = ENET_MAX_MTU;
+
+       Result = XEmac_PollSend(&Emac, (u8 *) ptr, len);
+       if (Result == XST_SUCCESS) {
+               return (1);
+       } else {
+               printf("Error while sending frame\n\r");
+               return (0);
+       }
+
+}
+
+int
+eth_rx(void)
+{
+       u32 RecvFrameLength;
+       XStatus Result;
+
+       RecvFrameLength = PKTSIZE;
+       Result = XEmac_PollRecv(&Emac, (u8 *) etherrxbuff, &RecvFrameLength);
+       if (Result == XST_SUCCESS) {
+               NetReceive(etherrxbuff, RecvFrameLength);
+               return (1);
+       } else {
+               return (0);
+       }
+}
+
+#endif
diff --git a/board/xilinx/xilinx_enet/xemac.c b/board/xilinx/xilinx_enet/xemac.c
new file mode 100644 (file)
index 0000000..48b4ede
--- /dev/null
@@ -0,0 +1,844 @@
+/******************************************************************************
+*
+*     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 xemac.c
+*
+* The XEmac driver. Functions in this file are the minimum required functions
+* for this driver. See xemac.h for a detailed description of the driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00b rpm  07/23/02 Removed the PHY reset from Initialize()
+* 1.00b rmm  09/23/02 Removed commented code in Initialize(). Recycled as
+*                     XEmac_mPhyReset macro in xemac_l.h.
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* 1.00c rpm  12/12/02 Changed location of IsStarted assignment in XEmac_Start
+*                     to be sure the flag is set before the device and
+*                     interrupts are enabled.
+* 1.00c rpm  02/03/03 SelfTest was not clearing polled mode. Take driver out
+*                     of polled mode in XEmac_Reset() to fix this problem.
+* 1.00c rmm  05/13/03 Fixed diab compiler warnings relating to asserts.
+* </pre>
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xemac_i.h"
+#include "xio.h"
+#include "xipif_v1_23_b.h"     /* Uses v1.23b of the IPIF */
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static XStatus ConfigureDma(XEmac * InstancePtr);
+static XStatus ConfigureFifo(XEmac * InstancePtr);
+static void StubFifoHandler(void *CallBackRef);
+static void StubErrorHandler(void *CallBackRef, XStatus ErrorCode);
+static void StubSgHandler(void *CallBackRef, XBufDescriptor * BdPtr,
+                         u32 NumBds);
+
+/************************** Variable Definitions *****************************/
+
+/*****************************************************************************/
+/**
+*
+* Initialize a specific XEmac instance/driver.  The initialization entails:
+* - Initialize fields of the XEmac structure
+* - Clear the Ethernet statistics for this device
+* - Initialize the IPIF component with its register base address
+* - Configure the FIFO components with their register base addresses.
+* - If the device is configured with DMA, configure the DMA channel components
+*   with their register base addresses. At some later time, memory pools for
+*   the scatter-gather descriptor lists may be passed to the driver.
+* - Reset the Ethernet MAC
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param DeviceId is the unique id of the device controlled by this XEmac
+*        instance.  Passing in a device id associates the generic XEmac
+*        instance to a specific device, as chosen by the caller or application
+*        developer.
+*
+* @return
+*
+* - XST_SUCCESS if initialization was successful
+* - XST_DEVICE_IS_STARTED if the device has already been started
+* - XST_DEVICE_NOT_FOUND if device configuration information was not found for
+*   a device with the supplied device ID.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XEmac_Initialize(XEmac * InstancePtr, u16 DeviceId)
+{
+       XStatus Result;
+       XEmac_Config *ConfigPtr;        /* configuration information */
+
+       XASSERT_NONVOID(InstancePtr != NULL);
+
+       /*
+        * If the device is started, disallow the initialize and return a status
+        * indicating it is started.  This allows the user to stop the device
+        * and reinitialize, but prevents a user from inadvertently initializing
+        */
+       if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+               return XST_DEVICE_IS_STARTED;
+       }
+
+       /*
+        * Lookup the device configuration in the temporary CROM table. Use this
+        * configuration info down below when initializing this component.
+        */
+       ConfigPtr = XEmac_LookupConfig(DeviceId);
+       if (ConfigPtr == NULL) {
+               return XST_DEVICE_NOT_FOUND;
+       }
+
+       /*
+        * Set some default values
+        */
+       InstancePtr->IsReady = 0;
+       InstancePtr->IsStarted = 0;
+       InstancePtr->IpIfDmaConfig = ConfigPtr->IpIfDmaConfig;
+       InstancePtr->HasMii = ConfigPtr->HasMii;
+       InstancePtr->HasMulticastHash = FALSE;
+
+       /* Always default polled to false, let user configure this mode */
+       InstancePtr->IsPolled = FALSE;
+       InstancePtr->FifoRecvHandler = StubFifoHandler;
+       InstancePtr->FifoSendHandler = StubFifoHandler;
+       InstancePtr->ErrorHandler = StubErrorHandler;
+       InstancePtr->SgRecvHandler = StubSgHandler;
+       InstancePtr->SgSendHandler = StubSgHandler;
+
+       /*
+        * Clear the statistics for this driver
+        */
+       XEmac_mClearStruct((u8 *) & InstancePtr->Stats, sizeof (XEmac_Stats));
+
+       /*
+        * Initialize the device register base addresses
+        */
+       InstancePtr->BaseAddress = ConfigPtr->BaseAddress;
+
+       /*
+        * Configure the send and receive FIFOs in the MAC
+        */
+       Result = ConfigureFifo(InstancePtr);
+       if (Result != XST_SUCCESS) {
+               return Result;
+       }
+
+       /*
+        * If the device is configured for DMA, configure the send and receive DMA
+        * channels in the MAC.
+        */
+       if (XEmac_mIsDma(InstancePtr)) {
+               Result = ConfigureDma(InstancePtr);
+               if (Result != XST_SUCCESS) {
+                       return Result;
+               }
+       }
+
+       /*
+        * Indicate the component is now ready to use. Note that this is done before
+        * we reset the device and the PHY below, which may seem a bit odd. The
+        * choice was made to move it here rather than remove the asserts in various
+        * functions (e.g., Reset() and all functions that it calls).  Applications
+        * that use multiple threads, one to initialize the XEmac driver and one
+        * waiting on the IsReady condition could have a problem with this sequence.
+        */
+       InstancePtr->IsReady = XCOMPONENT_IS_READY;
+
+       /*
+        * Reset the MAC to get it into its initial state. It is expected that
+        * device configuration by the user will take place after this
+        * initialization is done, but before the device is started.
+        */
+       XEmac_Reset(InstancePtr);
+
+       return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Start the Ethernet controller as follows:
+*   - If not in polled mode
+*       - Set the internal interrupt enable registers appropriately
+*       - Enable interrupts within the device itself. Note that connection of
+*         the driver's interrupt handler to the interrupt source (typically
+*         done using the interrupt controller component) is done by the higher
+*         layer software.
+*       - If the device is configured with scatter-gather DMA, start the DMA
+*         channels if the descriptor lists are not empty
+*   - Enable the transmitter
+*   - Enable the receiver
+*
+* The PHY is enabled after driver initialization. We assume the upper layer
+* software has configured it and the EMAC appropriately before this function
+* is called.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* - XST_SUCCESS if the device was started successfully
+* - XST_NO_CALLBACK if a callback function has not yet been registered using
+*   the SetxxxHandler function. This is required if in interrupt mode.
+* - XST_DEVICE_IS_STARTED if the device is already started
+* - XST_DMA_SG_NO_LIST if configured for scatter-gather DMA and a descriptor
+*   list has not yet been created for the send or receive channel.
+*
+* @note
+*
+* The driver tries to match the hardware configuration. So if the hardware
+* is configured with scatter-gather DMA, the driver expects to start the
+* scatter-gather channels and expects that the user has set up the buffer
+* descriptor lists already. If the user expects to use the driver in a mode
+* different than how the hardware is configured, the user should modify the
+* configuration table to reflect the mode to be used. Modifying the config
+* table is a workaround for now until we get some experience with how users
+* are intending to use the hardware in its different configurations. For
+* example, if the hardware is built with scatter-gather DMA but the user is
+* intending to use only simple DMA, the user either needs to modify the config
+* table as a workaround or rebuild the hardware with only simple DMA.
+*
+* This function makes use of internal resources that are shared between the
+* Start, Stop, and SetOptions functions. So if one task might be setting device
+* options while another is trying to start the device, the user is required to
+* provide protection of this shared data (typically using a semaphore).
+*
+******************************************************************************/
+XStatus
+XEmac_Start(XEmac * InstancePtr)
+{
+       u32 ControlReg;
+       XStatus Result;
+
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       /*
+        * If it is already started, return a status indicating so
+        */
+       if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+               return XST_DEVICE_IS_STARTED;
+       }
+
+       /*
+        * If not polled, enable interrupts
+        */
+       if (!InstancePtr->IsPolled) {
+               /*
+                * Verify that the callbacks have been registered, then enable
+                * interrupts
+                */
+               if (XEmac_mIsSgDma(InstancePtr)) {
+                       if ((InstancePtr->SgRecvHandler == StubSgHandler) ||
+                           (InstancePtr->SgSendHandler == StubSgHandler)) {
+                               return XST_NO_CALLBACK;
+                       }
+
+                       /* Enable IPIF interrupts */
+                       XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
+                                             XEM_IPIF_DMA_DFT_MASK |
+                                             XIIF_V123B_ERROR_MASK);
+                       XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress,
+                                             XEM_EIR_DFT_SG_MASK);
+
+                       /* Enable scatter-gather DMA interrupts */
+                       XDmaChannel_SetIntrEnable(&InstancePtr->RecvChannel,
+                                                 XEM_DMA_SG_INTR_MASK);
+                       XDmaChannel_SetIntrEnable(&InstancePtr->SendChannel,
+                                                 XEM_DMA_SG_INTR_MASK);
+               } else {
+                       if ((InstancePtr->FifoRecvHandler == StubFifoHandler) ||
+                           (InstancePtr->FifoSendHandler == StubFifoHandler)) {
+                               return XST_NO_CALLBACK;
+                       }
+
+                       /* Enable IPIF interrupts (used by simple DMA also) */
+                       XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
+                                             XEM_IPIF_FIFO_DFT_MASK |
+                                             XIIF_V123B_ERROR_MASK);
+                       XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress,
+                                             XEM_EIR_DFT_FIFO_MASK);
+               }
+
+               /* Enable the global IPIF interrupt output */
+               XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+       }
+
+       /*
+        * Indicate that the device is started before we enable the transmitter
+        * or receiver. This needs to be done before because as soon as the
+        * receiver is enabled we may get an interrupt, and there are functions
+        * in the interrupt handling path that rely on the IsStarted flag.
+        */
+       InstancePtr->IsStarted = XCOMPONENT_IS_STARTED;
+
+       /*
+        * Enable the transmitter, and receiver (do a read/modify/write to preserve
+        * current settings). There is no critical section here since this register
+        * is not modified during interrupt context.
+        */
+       ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
+       ControlReg &= ~(XEM_ECR_XMIT_RESET_MASK | XEM_ECR_RECV_RESET_MASK);
+       ControlReg |= (XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK);
+
+       XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);
+
+       /*
+        * If configured with scatter-gather DMA and not polled, restart the
+        * DMA channels in case there are buffers ready to be sent or received into.
+        * The DMA SgStart function uses data that can be modified during interrupt
+        * context, so a critical section is required here.
+        */
+       if ((XEmac_mIsSgDma(InstancePtr)) && (!InstancePtr->IsPolled)) {
+               XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
+
+               /*
+                * The only error we care about is if the list has not yet been
+                * created, or on receive, if no buffer descriptors have been
+                * added yet (the list is empty). Other errors are benign at this point.
+                */
+               Result = XDmaChannel_SgStart(&InstancePtr->RecvChannel);
+               if ((Result == XST_DMA_SG_NO_LIST)
+                   || (Result == XST_DMA_SG_LIST_EMPTY)) {
+                       XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+                       return Result;
+               }
+
+               Result = XDmaChannel_SgStart(&InstancePtr->SendChannel);
+               if (Result == XST_DMA_SG_NO_LIST) {
+                       XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+                       return Result;
+               }
+
+               XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+       }
+
+       return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Stop the Ethernet MAC as follows:
+*   - If the device is configured with scatter-gather DMA, stop the DMA
+*     channels (wait for acknowledgment of stop)
+*   - Disable the transmitter and receiver
+*   - Disable interrupts if not in polled mode (the higher layer software is
+*     responsible for disabling interrupts at the interrupt controller)
+*
+* The PHY is left enabled after a Stop is called.
+*
+* If the device is configured for scatter-gather DMA, the DMA engine stops at
+* the next buffer descriptor in its list. The remaining descriptors in the list
+* are not removed, so anything in the list will be transmitted or received when
+* the device is restarted. The side effect of doing this is that the last
+* buffer descriptor processed by the DMA engine before stopping may not be the
+* last descriptor in the Ethernet frame. So when the device is restarted, a
+* partial frame (i.e., a bad frame) may be transmitted/received. This is only a
+* concern if a frame can span multiple buffer descriptors, which is dependent
+* on the size of the network buffers.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* - XST_SUCCESS if the device was stopped successfully
+* - XST_DEVICE_IS_STOPPED if the device is already stopped
+*
+* @note
+*
+* This function makes use of internal resources that are shared between the
+* Start, Stop, and SetOptions functions. So if one task might be setting device
+* options while another is trying to start the device, the user is required to
+* provide protection of this shared data (typically using a semaphore).
+*
+******************************************************************************/
+XStatus
+XEmac_Stop(XEmac * InstancePtr)
+{
+       u32 ControlReg;
+
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       /*
+        * If the device is already stopped, do nothing but return a status
+        * indicating so
+        */
+       if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
+               return XST_DEVICE_IS_STOPPED;
+       }
+
+       /*
+        * If configured for scatter-gather DMA, stop the DMA channels. Ignore
+        * the XST_DMA_SG_IS_STOPPED return code. There is a critical section
+        * here between SgStart and SgStop, and SgStart can be called in interrupt
+        * context, so disable interrupts while calling SgStop.
+        */
+       if (XEmac_mIsSgDma(InstancePtr)) {
+               XBufDescriptor *BdTemp; /* temporary descriptor pointer */
+
+               XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
+
+               (void) XDmaChannel_SgStop(&InstancePtr->SendChannel, &BdTemp);
+               (void) XDmaChannel_SgStop(&InstancePtr->RecvChannel, &BdTemp);
+
+               XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+       }
+
+       /*
+        * Disable the transmitter and receiver. There is no critical section
+        * here since this register is not modified during interrupt context.
+        */
+       ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
+       ControlReg &= ~(XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK);
+       XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);
+
+       /*
+        * If not in polled mode, disable interrupts for IPIF (includes MAC and
+        * DMAs)
+        */
+       if (!InstancePtr->IsPolled) {
+               XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
+       }
+
+       InstancePtr->IsStarted = 0;
+
+       return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Reset the Ethernet MAC. This is a graceful reset in that the device is stopped
+* first. Resets the DMA channels, the FIFOs, the transmitter, and the receiver.
+* The PHY is not reset. Any frames in the scatter-gather descriptor lists will
+* remain in the lists. The side effect of doing this is that after a reset and
+* following a restart of the device, frames that were in the list before the
+* reset may be transmitted or received. Reset must only be called after the
+* driver has been initialized.
+*
+* The driver is also taken out of polled mode if polled mode was set. The user
+* is responsbile for re-configuring the driver into polled mode after the
+* reset if desired.
+*
+* The configuration after this reset is as follows:
+*   - Half duplex
+*   - Disabled transmitter and receiver
+*   - Enabled PHY (the PHY is not reset)
+*   - MAC transmitter does pad insertion, FCS insertion, and source address
+*     overwrite.
+*   - MAC receiver does not strip padding or FCS
+*   - Interframe Gap as recommended by IEEE Std. 802.3 (96 bit times)
+*   - Unicast addressing enabled
+*   - Broadcast addressing enabled
+*   - Multicast addressing disabled (addresses are preserved)
+*   - Promiscuous addressing disabled
+*   - Default packet threshold and packet wait bound register values for
+*     scatter-gather DMA operation
+*   - MAC address of all zeros
+*   - Non-polled mode
+*
+* The upper layer software is responsible for re-configuring (if necessary)
+* and restarting the MAC after the reset. Note that the PHY is not reset. PHY
+* control is left to the upper layer software. Note also that driver statistics
+* are not cleared on reset. It is up to the upper layer software to clear the
+* statistics if needed.
+*
+* When a reset is required due to an internal error, the driver notifies the
+* upper layer software of this need through the ErrorHandler callback and
+* specific status codes.  The upper layer software is responsible for calling
+* this Reset function and then re-configuring the device.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+* @internal
+*
+* The reset is accomplished by setting the IPIF reset register.  This takes
+* care of resetting all hardware blocks, including the MAC.
+*
+******************************************************************************/
+void
+XEmac_Reset(XEmac * InstancePtr)
+{
+       XASSERT_VOID(InstancePtr != NULL);
+       XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       /*
+        * Stop the device first
+        */
+       (void) XEmac_Stop(InstancePtr);
+
+       /*
+        * Take the driver out of polled mode
+        */
+       InstancePtr->IsPolled = FALSE;
+
+       /*
+        * Reset the entire IPIF at once.  If we choose someday to reset each
+        * hardware block separately, the reset should occur in the direction of
+        * data flow. For example, for the send direction the reset order is DMA
+        * first, then FIFO, then the MAC transmitter.
+        */
+       XIIF_V123B_RESET(InstancePtr->BaseAddress);
+
+       if (XEmac_mIsSgDma(InstancePtr)) {
+               /*
+                * After reset, configure the scatter-gather DMA packet threshold and
+                * packet wait bound registers to default values. Ignore the return
+                * values of these functions since they only return error if the device
+                * is not stopped.
+                */
+               (void) XEmac_SetPktThreshold(InstancePtr, XEM_SEND,
+                                            XEM_SGDMA_DFT_THRESHOLD);
+               (void) XEmac_SetPktThreshold(InstancePtr, XEM_RECV,
+                                            XEM_SGDMA_DFT_THRESHOLD);
+               (void) XEmac_SetPktWaitBound(InstancePtr, XEM_SEND,
+                                            XEM_SGDMA_DFT_WAITBOUND);
+               (void) XEmac_SetPktWaitBound(InstancePtr, XEM_RECV,
+                                            XEM_SGDMA_DFT_WAITBOUND);
+       }
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the MAC address for this driver/device.  The address is a 48-bit value.
+* The device must be stopped before calling this function.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param AddressPtr is a pointer to a 6-byte MAC address.
+*
+* @return
+*
+* - XST_SUCCESS if the MAC address was set successfully
+* - XST_DEVICE_IS_STARTED if the device has not yet been stopped
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XEmac_SetMacAddress(XEmac * InstancePtr, u8 * AddressPtr)
+{
+       u32 MacAddr = 0;
+
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(AddressPtr != NULL);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       /*
+        * The device must be stopped before setting the MAC address
+        */
+       if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+               return XST_DEVICE_IS_STARTED;
+       }
+
+       /*
+        * Set the device station address high and low registers
+        */
+       MacAddr = (AddressPtr[0] << 8) | AddressPtr[1];
+       XIo_Out32(InstancePtr->BaseAddress + XEM_SAH_OFFSET, MacAddr);
+
+       MacAddr = (AddressPtr[2] << 24) | (AddressPtr[3] << 16) |
+           (AddressPtr[4] << 8) | AddressPtr[5];
+
+       XIo_Out32(InstancePtr->BaseAddress + XEM_SAL_OFFSET, MacAddr);
+
+       return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Get the MAC address for this driver/device.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param BufferPtr is an output parameter, and is a pointer to a buffer into
+*        which the current MAC address will be copied. The buffer must be at
+*        least 6 bytes.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_GetMacAddress(XEmac * InstancePtr, u8 * BufferPtr)
+{
+       u32 MacAddrHi;
+       u32 MacAddrLo;
+
+       XASSERT_VOID(InstancePtr != NULL);
+       XASSERT_VOID(BufferPtr != NULL);
+       XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       MacAddrHi = XIo_In32(InstancePtr->BaseAddress + XEM_SAH_OFFSET);
+       MacAddrLo = XIo_In32(InstancePtr->BaseAddress + XEM_SAL_OFFSET);
+
+       BufferPtr[0] = (u8) (MacAddrHi >> 8);
+       BufferPtr[1] = (u8) MacAddrHi;
+       BufferPtr[2] = (u8) (MacAddrLo >> 24);
+       BufferPtr[3] = (u8) (MacAddrLo >> 16);
+       BufferPtr[4] = (u8) (MacAddrLo >> 8);
+       BufferPtr[5] = (u8) MacAddrLo;
+}
+
+/******************************************************************************/
+/**
+*
+* Configure DMA capabilities.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* - XST_SUCCESS  if successful initialization of DMA
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static XStatus
+ConfigureDma(XEmac * InstancePtr)
+{
+       XStatus Result;
+
+       /*
+        * Initialize the DMA channels with their base addresses. We assume
+        * scatter-gather DMA is the only possible configuration. Descriptor space
+        * will need to be set later by the upper layer.
+        */
+       Result = XDmaChannel_Initialize(&InstancePtr->RecvChannel,
+                                       InstancePtr->BaseAddress +
+                                       XEM_DMA_RECV_OFFSET);
+       if (Result != XST_SUCCESS) {
+               return Result;
+       }
+
+       Result = XDmaChannel_Initialize(&InstancePtr->SendChannel,
+                                       InstancePtr->BaseAddress +
+                                       XEM_DMA_SEND_OFFSET);
+
+       return Result;
+}
+
+/******************************************************************************/
+/**
+*
+* Configure the send and receive FIFO components with their base addresses
+* and interrupt masks.  Currently the base addresses are defined constants.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* XST_SUCCESS if successful initialization of the packet FIFOs
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static XStatus
+ConfigureFifo(XEmac * InstancePtr)
+{
+       XStatus Result;
+
+       /*
+        * Return status from the packet FIFOs initialization is ignored since
+        * they always return success.
+        */
+       Result = XPacketFifoV100b_Initialize(&InstancePtr->RecvFifo,
+                                            InstancePtr->BaseAddress +
+                                            XEM_PFIFO_RXREG_OFFSET,
+                                            InstancePtr->BaseAddress +
+                                            XEM_PFIFO_RXDATA_OFFSET);
+       if (Result != XST_SUCCESS) {
+               return Result;
+       }
+
+       Result = XPacketFifoV100b_Initialize(&InstancePtr->SendFifo,
+                                            InstancePtr->BaseAddress +
+                                            XEM_PFIFO_TXREG_OFFSET,
+                                            InstancePtr->BaseAddress +
+                                            XEM_PFIFO_TXDATA_OFFSET);
+       return Result;
+}
+
+/******************************************************************************/
+/**
+*
+* This is a stub for the scatter-gather send and recv callbacks. The stub
+* is here in case the upper layers forget to set the handlers.
+*
+* @param CallBackRef is a pointer to the upper layer callback reference
+* @param BdPtr is a pointer to the first buffer descriptor in a list
+* @param NumBds is the number of descriptors in the list.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+StubSgHandler(void *CallBackRef, XBufDescriptor * BdPtr, u32 NumBds)
+{
+       XASSERT_VOID_ALWAYS();
+}
+
+/******************************************************************************/
+/**
+*
+* This is a stub for the non-DMA send and recv callbacks.  The stub is here in
+* case the upper layers forget to set the handlers.
+*
+* @param CallBackRef is a pointer to the upper layer callback reference
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+StubFifoHandler(void *CallBackRef)
+{
+       XASSERT_VOID_ALWAYS();
+}
+
+/******************************************************************************/
+/**
+*
+* This is a stub for the asynchronous error callback.  The stub is here in
+* case the upper layers forget to set the handler.
+*
+* @param CallBackRef is a pointer to the upper layer callback reference
+* @param ErrorCode is the Xilinx error code, indicating the cause of the error
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+StubErrorHandler(void *CallBackRef, XStatus ErrorCode)
+{
+       XASSERT_VOID_ALWAYS();
+}
+
+/*****************************************************************************/
+/**
+*
+* Lookup the device configuration based on the unique device ID.  The table
+* EmacConfigTable contains the configuration info for each device in the system.
+*
+* @param DeviceId is the unique device ID of the device being looked up.
+*
+* @return
+*
+* A pointer to the configuration table entry corresponding to the given
+* device ID, or NULL if no match is found.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XEmac_Config *
+XEmac_LookupConfig(u16 DeviceId)
+{
+       XEmac_Config *CfgPtr = NULL;
+       int i;
+
+       for (i = 0; i < XPAR_XEMAC_NUM_INSTANCES; i++) {
+               if (XEmac_ConfigTable[i].DeviceId == DeviceId) {
+                       CfgPtr = &XEmac_ConfigTable[i];
+                       break;
+               }
+       }
+
+       return CfgPtr;
+}
diff --git a/board/xilinx/xilinx_enet/xemac.h b/board/xilinx/xilinx_enet/xemac.h
new file mode 100644 (file)
index 0000000..ed704bf
--- /dev/null
@@ -0,0 +1,673 @@
+/******************************************************************************
+*
+*     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 xemac.h
+*
+* The Xilinx Ethernet driver component.         This component supports the Xilinx
+* Ethernet 10/100 MAC (EMAC).
+*
+* The Xilinx Ethernet 10/100 MAC supports the following features:
+*   - Simple and scatter-gather DMA operations, as well as simple memory
+*     mapped direct I/O interface (FIFOs).
+*   - Media Independent Interface (MII) for connection to external
+*     10/100 Mbps PHY transceivers.
+*   - MII management control reads and writes with MII PHYs
+*   - Independent internal transmit and receive FIFOs
+*   - CSMA/CD compliant operations for half-duplex modes
+*   - Programmable PHY reset signal
+*   - Unicast, broadcast, and promiscuous address filtering (no multicast yet)
+*   - Internal loopback
+*   - Automatic source address insertion or overwrite (programmable)
+*   - Automatic FCS insertion and stripping (programmable)
+*   - Automatic pad insertion and stripping (programmable)
+*   - Pause frame (flow control) detection in full-duplex mode
+*   - Programmable interframe gap
+*   - VLAN frame support.
+*   - Pause frame support
+*
+* The device driver supports all the features listed above.
+*
+* <b>Driver Description</b>
+*
+* The device driver enables higher layer software (e.g., an application) to
+* communicate to the EMAC. The driver handles transmission and reception of
+* Ethernet frames, as well as configuration of the controller. It does not
+* handle protocol stack functionality such as Link Layer Control (LLC) or the
+* Address Resolution Protocol (ARP). The protocol stack that makes use of the
+* driver handles this functionality. This implies that the driver is simply a
+* pass-through mechanism between a protocol stack and the EMAC. A single device
+* driver can support multiple EMACs.
+*
+* The driver is designed for a zero-copy buffer scheme. That is, the driver will
+* not copy buffers. This avoids potential throughput bottlenecks within the
+* driver.
+*
+* Since the driver is a simple pass-through mechanism between a protocol stack
+* and the EMAC, no assembly or disassembly of Ethernet frames is done at the
+* driver-level. This assumes that the protocol stack passes a correctly
+* formatted Ethernet frame to the driver for transmission, and that the driver
+* does not validate the contents of an incoming frame
+*
+* <b>PHY Communication</b>
+*
+* The driver provides rudimentary read and write functions to allow the higher
+* layer software to access the PHY. The EMAC provides MII registers for the
+* driver to access. This management interface can be parameterized away in the
+* FPGA implementation process. If this is the case, the PHY read and write
+* functions of the driver return XST_NO_FEATURE.
+*
+* External loopback is usually supported at the PHY. It is up to the user to
+* turn external loopback on or off at the PHY. The driver simply provides pass-
+* through functions for configuring the PHY. The driver does not read, write,
+* or reset the PHY on its own. All control of the PHY must be done by the user.
+*
+* <b>Asynchronous Callbacks</b>
+*
+* The driver services interrupts and passes Ethernet frames to the higher layer
+* software through asynchronous callback functions. When using the driver
+* directly (i.e., not with the RTOS protocol stack), the higher layer
+* software must register its callback functions during initialization. The
+* driver requires callback functions for received frames, for confirmation of
+* transmitted frames, and for asynchronous errors.
+*
+* <b>Interrupts</b>
+*
+* The driver has no dependencies on the interrupt controller. The driver
+* provides two interrupt handlers.  XEmac_IntrHandlerDma() handles interrupts
+* when the EMAC is configured with scatter-gather DMA. XEmac_IntrHandlerFifo()
+* handles interrupts when the EMAC is configured for direct FIFO I/O or simple
+* DMA. Either of these routines can be connected to the system interrupt
+* controller by the user.
+*
+* <b>Interrupt Frequency</b>
+*
+* When the EMAC is configured with scatter-gather DMA, the frequency of
+* interrupts can be controlled with the interrupt coalescing features of the
+* scatter-gather DMA engine. The frequency of interrupts can be adjusted using
+* the driver API functions for setting the packet count threshold and the packet
+* wait bound values.
+*
+* The scatter-gather DMA engine only interrupts when the packet count threshold
+* is reached, instead of interrupting for each packet. A packet is a generic
+* term used by the scatter-gather DMA engine, and is equivalent to an Ethernet
+* frame in our case.
+*
+* The packet wait bound is a timer value used during interrupt coalescing to
+* trigger an interrupt when not enough packets have been received to reach the
+* packet count threshold.
+*
+* These values can be tuned by the user to meet their needs. If there appear to
+* be interrupt latency problems or delays in packet arrival that are longer than
+* might be expected, the user should verify that the packet count threshold is
+* set low enough to receive interrupts before the wait bound timer goes off.
+*
+* <b>Device Reset</b>
+*
+* Some errors that can occur in the device require a device reset. These errors
+* are listed in the XEmac_SetErrorHandler() function header. The user's error
+* handler is responsible for resetting the device and re-configuring it based on
+* its needs (the driver does not save the current configuration). When
+* integrating into an RTOS, these reset and re-configure obligations are
+* taken care of by the Xilinx adapter software if it exists for that RTOS.
+*
+* <b>Device Configuration</b>
+*
+* The device can be configured in various ways during the FPGA implementation
+* process.  Configuration parameters are stored in the xemac_g.c files.
+* A table is defined where each entry contains configuration information
+* for an EMAC device.  This information includes such things as the base address
+* of the memory-mapped device, the base addresses of IPIF, DMA, and FIFO modules
+* within the device, and whether the device has DMA, counter registers,
+* multicast support, MII support, and flow control.
+*
+* The driver tries to use the features built into the device. So if, for
+* example, the hardware is configured with scatter-gather DMA, the driver
+* expects to start the scatter-gather channels and expects that the user has set
+* up the buffer descriptor lists already. If the user expects to use the driver
+* in a mode different than how the hardware is configured, the user should
+* modify the configuration table to reflect the mode to be used. Modifying the
+* configuration table is a workaround for now until we get some experience with
+* how users are intending to use the hardware in its different configurations.
+* For example, if the hardware is built with scatter-gather DMA but the user is
+* intending to use only simple DMA, the user either needs to modify the config
+* table as a workaround or rebuild the hardware with only simple DMA. The
+* recommendation at this point is to build the hardware with the features you
+* intend to use. If you're inclined to modify the table, do so before the call
+* to XEmac_Initialize().  Here is a snippet of code that changes a device to
+* simple DMA (the hardware needs to have DMA for this to work of course):
+* <pre>
+*       XEmac_Config *ConfigPtr;
+*
+*       ConfigPtr = XEmac_LookupConfig(DeviceId);
+*       ConfigPtr->IpIfDmaConfig = XEM_CFG_SIMPLE_DMA;
+* </pre>
+*
+* <b>Simple DMA</b>
+*
+* Simple DMA is supported through the FIFO functions, FifoSend and FifoRecv, of
+* the driver (i.e., there is no separate interface for it). The driver makes use
+* of the DMA engine for a simple DMA transfer if the device is configured with
+* DMA, otherwise it uses the FIFOs directly. While the simple DMA interface is
+* therefore transparent to the user, the caching of network buffers is not.
+* If the device is configured with DMA and the FIFO interface is used, the user
+* must ensure that the network buffers are not cached or are cache coherent,
+* since DMA will be used to transfer to and from the Emac device. If the device
+* is configured with DMA and the user really wants to use the FIFOs directly,
+* the user should rebuild the hardware without DMA. If unable to do this, there
+* is a workaround (described above in Device Configuration) to modify the
+* configuration table of the driver to fake the driver into thinking the device
+* has no DMA. A code snippet follows:
+* <pre>
+*       XEmac_Config *ConfigPtr;
+*
+*       ConfigPtr = XEmac_LookupConfig(DeviceId);
+*       ConfigPtr->IpIfDmaConfig = XEM_CFG_NO_DMA;
+* </pre>
+*
+* <b>Asserts</b>
+*
+* Asserts are used within all Xilinx drivers to enforce constraints on argument
+* values. Asserts can be turned off on a system-wide basis by defining, at
+* compile time, the NDEBUG identifier. By default, asserts are turned on and it
+* is recommended that users leave asserts on during development.
+*
+* <b>Building the driver</b>
+*
+* The XEmac driver is composed of several source files. Why so many?  This
+* allows the user to build and link only those parts of the driver that are
+* necessary. Since the EMAC hardware can be configured in various ways (e.g.,
+* with or without DMA), the driver too can be built with varying features.
+* For the most part, this means that besides always linking in xemac.c, you
+* link in only the driver functionality you want. Some of the choices you have
+* are polled vs. interrupt, interrupt with FIFOs only vs. interrupt with DMA,
+* self-test diagnostics, and driver statistics. Note that currently the DMA code
+* must be linked in, even if you don't have DMA in the device.
+*
+* @note
+*
+* Xilinx drivers are typically composed of two components, one is the driver
+* and the other is the adapter.         The driver is independent of OS and processor
+* and is intended to be highly portable.  The adapter is OS-specific and
+* facilitates communication between the driver and an OS.
+* <br><br>
+* This driver is intended to be RTOS and processor independent.         It works
+* with physical addresses only.         Any needs for dynamic memory management,
+* threads or thread mutual exclusion, virtual memory, or cache control must
+* be satisfied by the layer above this driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver  Who  Date     Changes
+* ----- ---- -------- -------------------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00b rpm  10/08/02 Replaced HasSgDma boolean with IpifDmaConfig enumerated
+*                    configuration parameter
+* 1.00c rpm  12/05/02 New version includes support for simple DMA and the delay
+*                    argument to SgSend
+* 1.00c rpm  02/03/03 The XST_DMA_SG_COUNT_EXCEEDED return code was removed
+*                    from SetPktThreshold in the internal DMA driver. Also
+*                    avoided compiler warnings by initializing Result in the
+*                    DMA interrupt service routines.
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XEMAC_H                        /* prevent circular inclusions */
+#define XEMAC_H                        /* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xstatus.h"
+#include "xparameters.h"
+#include "xpacket_fifo_v1_00_b.h"      /* Uses v1.00b of Packet Fifo */
+#include "xdma_channel.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * Device information
+ */
+#define XEM_DEVICE_NAME            "xemac"
+#define XEM_DEVICE_DESC            "Xilinx Ethernet 10/100 MAC"
+
+/** @name Configuration options
+ *
+ * Device configuration options (see the XEmac_SetOptions() and
+ * XEmac_GetOptions() for information on how to use these options)
+ * @{
+ */
+/**
+ * <pre>
+ *   XEM_BROADCAST_OPTION       Broadcast addressing on or off (default is on)
+ *   XEM_UNICAST_OPTION                 Unicast addressing on or off (default is on)
+ *   XEM_PROMISC_OPTION                 Promiscuous addressing on or off (default is off)
+ *   XEM_FDUPLEX_OPTION                 Full duplex on or off (default is off)
+ *   XEM_POLLED_OPTION          Polled mode on or off (default is off)
+ *   XEM_LOOPBACK_OPTION        Internal loopback on or off (default is off)
+ *   XEM_FLOW_CONTROL_OPTION    Interpret pause frames in full duplex mode
+ *                              (default is off)
+ *   XEM_INSERT_PAD_OPTION      Pad short frames on transmit (default is on)
+ *   XEM_INSERT_FCS_OPTION      Insert FCS (CRC) on transmit (default is on)
+ *   XEM_INSERT_ADDR_OPTION     Insert source address on transmit (default is on)
+ *   XEM_OVWRT_ADDR_OPTION      Overwrite source address on transmit. This is
+ *                              only used if source address insertion is on.
+ *                              (default is on)
+ *   XEM_STRIP_PAD_FCS_OPTION   Strip FCS and padding from received frames
+ *                              (default is off)
+  * </pre>
+ */
+#define XEM_UNICAST_OPTION       0x00000001UL
+#define XEM_BROADCAST_OPTION     0x00000002UL
+#define XEM_PROMISC_OPTION       0x00000004UL
+#define XEM_FDUPLEX_OPTION       0x00000008UL
+#define XEM_POLLED_OPTION        0x00000010UL
+#define XEM_LOOPBACK_OPTION      0x00000020UL
+#define XEM_FLOW_CONTROL_OPTION          0x00000080UL
+#define XEM_INSERT_PAD_OPTION    0x00000100UL
+#define XEM_INSERT_FCS_OPTION    0x00000200UL
+#define XEM_INSERT_ADDR_OPTION   0x00000400UL
+#define XEM_OVWRT_ADDR_OPTION    0x00000800UL
+#define XEM_STRIP_PAD_FCS_OPTION  0x00002000UL
+/*@}*/
+/*
+ * Not supported yet:
+ *   XEM_MULTICAST_OPTION       Multicast addressing on or off (default is off)
+ */
+/* NOT SUPPORTED YET... */
+#define XEM_MULTICAST_OPTION     0x00000040UL
+
+/*
+ * Some default values for interrupt coalescing within the scatter-gather
+ * DMA engine.
+ */
+#define XEM_SGDMA_DFT_THRESHOLD            1   /* Default pkt threshold */
+#define XEM_SGDMA_MAX_THRESHOLD            255 /* Maximum pkt theshold */
+#define XEM_SGDMA_DFT_WAITBOUND            5   /* Default pkt wait bound (msec) */
+#define XEM_SGDMA_MAX_WAITBOUND            1023        /* Maximum pkt wait bound (msec) */
+
+/*
+ * Direction identifiers. These are used for setting values like packet
+ * thresholds and wait bound for specific channels
+ */
+#define XEM_SEND    1
+#define XEM_RECV    2
+
+/*
+ * Arguments to SgSend function to indicate whether to hold off starting
+ * the scatter-gather engine.
+ */
+#define XEM_SGDMA_NODELAY     0 /* start SG DMA immediately */
+#define XEM_SGDMA_DELAY              1 /* do not start SG DMA */
+
+/*
+ * Constants to determine the configuration of the hardware device. They are
+ * used to allow the driver to verify it can operate with the hardware.
+ */
+#define XEM_CFG_NO_IPIF                    0   /* Not supported by the driver */
+#define XEM_CFG_NO_DMA             1   /* No DMA */
+#define XEM_CFG_SIMPLE_DMA         2   /* Simple DMA */
+#define XEM_CFG_DMA_SG             3   /* DMA scatter gather */
+
+/*
+ * The next few constants help upper layers determine the size of memory
+ * pools used for Ethernet buffers and descriptor lists.
+ */
+#define XEM_MAC_ADDR_SIZE   6  /* six-byte MAC address */
+#define XEM_MTU                    1500        /* max size of Ethernet frame */
+#define XEM_HDR_SIZE       14  /* size of Ethernet header */
+#define XEM_HDR_VLAN_SIZE   18 /* size of Ethernet header with VLAN */
+#define XEM_TRL_SIZE       4   /* size of Ethernet trailer (FCS) */
+#define XEM_MAX_FRAME_SIZE  (XEM_MTU + XEM_HDR_SIZE + XEM_TRL_SIZE)
+#define XEM_MAX_VLAN_FRAME_SIZE         (XEM_MTU + XEM_HDR_VLAN_SIZE + XEM_TRL_SIZE)
+
+/*
+ * Define a default number of send and receive buffers
+ */
+#define XEM_MIN_RECV_BUFS   32 /* minimum # of recv buffers */
+#define XEM_DFT_RECV_BUFS   64 /* default # of recv buffers */
+
+#define XEM_MIN_SEND_BUFS   16 /* minimum # of send buffers */
+#define XEM_DFT_SEND_BUFS   32 /* default # of send buffers */
+
+#define XEM_MIN_BUFFERS            (XEM_MIN_RECV_BUFS + XEM_MIN_SEND_BUFS)
+#define XEM_DFT_BUFFERS            (XEM_DFT_RECV_BUFS + XEM_DFT_SEND_BUFS)
+
+/*
+ * Define the number of send and receive buffer descriptors, used for
+ * scatter-gather DMA
+ */
+#define XEM_MIN_RECV_DESC   16 /* minimum # of recv descriptors */
+#define XEM_DFT_RECV_DESC   32 /* default # of recv descriptors */
+
+#define XEM_MIN_SEND_DESC   8  /* minimum # of send descriptors */
+#define XEM_DFT_SEND_DESC   16 /* default # of send descriptors */
+
+/**************************** Type Definitions *******************************/
+
+/**
+ * Ethernet statistics (see XEmac_GetStats() and XEmac_ClearStats())
+ */
+typedef struct {
+       u32 XmitFrames;          /**< Number of frames transmitted */
+       u32 XmitBytes;           /**< Number of bytes transmitted */
+       u32 XmitLateCollisionErrors;
+                                /**< Number of transmission failures
+                                         due to late collisions */
+       u32 XmitExcessDeferral;  /**< Number of transmission failures
+                                         due o excess collision deferrals */
+       u32 XmitOverrunErrors;   /**< Number of transmit overrun errors */
+       u32 XmitUnderrunErrors;  /**< Number of transmit underrun errors */
+       u32 RecvFrames;          /**< Number of frames received */
+       u32 RecvBytes;           /**< Number of bytes received */
+       u32 RecvFcsErrors;       /**< Number of frames discarded due
+                                         to FCS errors */
+       u32 RecvAlignmentErrors; /**< Number of frames received with
+                                         alignment errors */
+       u32 RecvOverrunErrors;   /**< Number of frames discarded due
+                                         to overrun errors */
+       u32 RecvUnderrunErrors;  /**< Number of recv underrun errors */
+       u32 RecvMissedFrameErrors;
+                                /**< Number of frames missed by MAC */
+       u32 RecvCollisionErrors; /**< Number of frames discarded due
+                                         to collisions */
+       u32 RecvLengthFieldErrors;
+                                /**< Number of frames discarded with
+                                         invalid length field */
+       u32 RecvShortErrors;     /**< Number of short frames discarded */
+       u32 RecvLongErrors;      /**< Number of long frames discarded */
+       u32 DmaErrors;           /**< Number of DMA errors since init */
+       u32 FifoErrors;          /**< Number of FIFO errors since init */
+       u32 RecvInterrupts;      /**< Number of receive interrupts */
+       u32 XmitInterrupts;      /**< Number of transmit interrupts */
+       u32 EmacInterrupts;      /**< Number of MAC (device) interrupts */
+       u32 TotalIntrs;          /**< Total interrupts */
+} XEmac_Stats;
+
+/**
+ * This typedef contains configuration information for a device.
+ */
+typedef struct {
+       u16 DeviceId;       /**< Unique ID  of device */
+       u32 BaseAddress;    /**< Register base address */
+       u32 HasCounters;   /**< Does device have counters? */
+       u8 IpIfDmaConfig;   /**< IPIF/DMA hardware configuration */
+       u32 HasMii;        /**< Does device support MII? */
+
+} XEmac_Config;
+
+/** @name Typedefs for callbacks
+ * Callback functions.
+ * @{
+ */
+/**
+ * Callback when data is sent or received with scatter-gather DMA.
+ *
+ * @param CallBackRef is a callback reference passed in by the upper layer
+ *       when setting the callback functions, and passed back to the upper
+ *       layer when the callback is invoked.
+ * @param BdPtr is a pointer to the first buffer descriptor in a list of
+ *       buffer descriptors.
+ * @param NumBds is the number of buffer descriptors in the list pointed
+ *       to by BdPtr.
+ */
+typedef void (*XEmac_SgHandler) (void *CallBackRef, XBufDescriptor * BdPtr,
+                                u32 NumBds);
+
+/**
+ * Callback when data is sent or received with direct FIFO communication or
+ * simple DMA. The user typically defines two callacks, one for send and one
+ * for receive.
+ *
+ * @param CallBackRef is a callback reference passed in by the upper layer
+ *       when setting the callback functions, and passed back to the upper
+ *       layer when the callback is invoked.
+ */
+typedef void (*XEmac_FifoHandler) (void *CallBackRef);
+
+/**
+ * Callback when an asynchronous error occurs.
+ *
+ * @param CallBackRef is a callback reference passed in by the upper layer
+ *       when setting the callback functions, and passed back to the upper
+ *       layer when the callback is invoked.
+ * @param ErrorCode is a Xilinx error code defined in xstatus.h.  Also see
+ *       XEmac_SetErrorHandler() for a description of possible errors.
+ */
+typedef void (*XEmac_ErrorHandler) (void *CallBackRef, XStatus ErrorCode);
+/*@}*/
+
+/**
+ * The XEmac driver instance data. The user is required to allocate a
+ * variable of this type for every EMAC device in the system. A pointer
+ * to a variable of this type is then passed to the driver API functions.
+ */
+typedef struct {
+       u32 BaseAddress;        /* Base address (of IPIF) */
+       u32 IsStarted;          /* Device is currently started */
+       u32 IsReady;            /* Device is initialized and ready */
+       u32 IsPolled;           /* Device is in polled mode */
+       u8 IpIfDmaConfig;       /* IPIF/DMA hardware configuration */
+       u32 HasMii;             /* Does device support MII? */
+       u32 HasMulticastHash;   /* Does device support multicast hash table? */
+
+       XEmac_Stats Stats;
+       XPacketFifoV100b RecvFifo;      /* FIFO used to receive frames */
+       XPacketFifoV100b SendFifo;      /* FIFO used to send frames */
+
+       /*
+        * Callbacks
+        */
+       XEmac_FifoHandler FifoRecvHandler;      /* for non-DMA/simple DMA interrupts */
+       void *FifoRecvRef;
+       XEmac_FifoHandler FifoSendHandler;      /* for non-DMA/simple DMA interrupts */
+       void *FifoSendRef;
+       XEmac_ErrorHandler ErrorHandler;        /* for asynchronous errors */
+       void *ErrorRef;
+
+       XDmaChannel RecvChannel;        /* DMA receive channel driver */
+       XDmaChannel SendChannel;        /* DMA send channel driver */
+
+       XEmac_SgHandler SgRecvHandler;  /* callback for scatter-gather DMA */
+       void *SgRecvRef;
+       XEmac_SgHandler SgSendHandler;  /* callback for scatter-gather DMA */
+       void *SgSendRef;
+} XEmac;
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device is currently configured for
+* scatter-gather DMA.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured for scatter-gather DMA, or FALSE
+* if it is not.
+*
+* @note
+*
+* Signature: u32 XEmac_mIsSgDma(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mIsSgDma(InstancePtr) \
+           ((InstancePtr)->IpIfDmaConfig == XEM_CFG_DMA_SG)
+
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device is currently configured for simple DMA.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured for simple DMA, or FALSE otherwise
+*
+* @note
+*
+* Signature: u32 XEmac_mIsSimpleDma(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mIsSimpleDma(InstancePtr) \
+           ((InstancePtr)->IpIfDmaConfig == XEM_CFG_SIMPLE_DMA)
+
+/*****************************************************************************/
+/**
+*
+* This macro determines if the device is currently configured with DMA (either
+* simple DMA or scatter-gather DMA)
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Boolean TRUE if the device is configured with DMA, or FALSE otherwise
+*
+* @note
+*
+* Signature: u32 XEmac_mIsDma(XEmac *InstancePtr)
+*
+******************************************************************************/
+#define XEmac_mIsDma(InstancePtr) \
+           (XEmac_mIsSimpleDma(InstancePtr) || XEmac_mIsSgDma(InstancePtr))
+
+/************************** Function Prototypes ******************************/
+
+/*
+ * Initialization functions in xemac.c
+ */
+XStatus XEmac_Initialize(XEmac * InstancePtr, u16 DeviceId);
+XStatus XEmac_Start(XEmac * InstancePtr);
+XStatus XEmac_Stop(XEmac * InstancePtr);
+void XEmac_Reset(XEmac * InstancePtr);
+XEmac_Config *XEmac_LookupConfig(u16 DeviceId);
+
+/*
+ * Diagnostic functions in xemac_selftest.c
+ */
+XStatus XEmac_SelfTest(XEmac * InstancePtr);
+
+/*
+ * Polled functions in xemac_polled.c
+ */
+XStatus XEmac_PollSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount);
+XStatus XEmac_PollRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr);
+
+/*
+ * Interrupts with scatter-gather DMA functions in xemac_intr_dma.c
+ */
+XStatus XEmac_SgSend(XEmac * InstancePtr, XBufDescriptor * BdPtr, int Delay);
+XStatus XEmac_SgRecv(XEmac * InstancePtr, XBufDescriptor * BdPtr);
+XStatus XEmac_SetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 Threshold);
+XStatus XEmac_GetPktThreshold(XEmac * InstancePtr, u32 Direction,
+                             u8 * ThreshPtr);
+XStatus XEmac_SetPktWaitBound(XEmac * InstancePtr, u32 Direction,
+                             u32 TimerValue);
+XStatus XEmac_GetPktWaitBound(XEmac * InstancePtr, u32 Direction,
+                             u32 * WaitPtr);
+XStatus XEmac_SetSgRecvSpace(XEmac * InstancePtr, u32 * MemoryPtr,
+                            u32 ByteCount);
+XStatus XEmac_SetSgSendSpace(XEmac * InstancePtr, u32 * MemoryPtr,
+                            u32 ByteCount);
+void XEmac_SetSgRecvHandler(XEmac * InstancePtr, void *CallBackRef,
+                           XEmac_SgHandler FuncPtr);
+void XEmac_SetSgSendHandler(XEmac * InstancePtr, void *CallBackRef,
+                           XEmac_SgHandler FuncPtr);
+
+void XEmac_IntrHandlerDma(void *InstancePtr);  /* interrupt handler */
+
+/*
+ * Interrupts with direct FIFO functions in xemac_intr_fifo.c. Also used
+ * for simple DMA.
+ */
+XStatus XEmac_FifoSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount);
+XStatus XEmac_FifoRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr);
+void XEmac_SetFifoRecvHandler(XEmac * InstancePtr, void *CallBackRef,
+                             XEmac_FifoHandler FuncPtr);
+void XEmac_SetFifoSendHandler(XEmac * InstancePtr, void *CallBackRef,
+                             XEmac_FifoHandler FuncPtr);
+
+void XEmac_IntrHandlerFifo(void *InstancePtr); /* interrupt handler */
+
+/*
+ * General interrupt-related functions in xemac_intr.c
+ */
+void XEmac_SetErrorHandler(XEmac * InstancePtr, void *CallBackRef,
+                          XEmac_ErrorHandler FuncPtr);
+
+/*
+ * MAC configuration in xemac_options.c
+ */
+XStatus XEmac_SetOptions(XEmac * InstancePtr, u32 OptionFlag);
+u32 XEmac_GetOptions(XEmac * InstancePtr);
+XStatus XEmac_SetMacAddress(XEmac * InstancePtr, u8 * AddressPtr);
+void XEmac_GetMacAddress(XEmac * InstancePtr, u8 * BufferPtr);
+XStatus XEmac_SetInterframeGap(XEmac * InstancePtr, u8 Part1, u8 Part2);
+void XEmac_GetInterframeGap(XEmac * InstancePtr, u8 * Part1Ptr, u8 * Part2Ptr);
+
+/*
+ * Multicast functions in xemac_multicast.c (not supported by EMAC yet)
+ */
+XStatus XEmac_MulticastAdd(XEmac * InstancePtr, u8 * AddressPtr);
+XStatus XEmac_MulticastClear(XEmac * InstancePtr);
+
+/*
+ * PHY configuration in xemac_phy.c
+ */
+XStatus XEmac_PhyRead(XEmac * InstancePtr, u32 PhyAddress,
+                     u32 RegisterNum, u16 * PhyDataPtr);
+XStatus XEmac_PhyWrite(XEmac * InstancePtr, u32 PhyAddress,
+                      u32 RegisterNum, u16 PhyData);
+
+/*
+ * Statistics in xemac_stats.c
+ */
+void XEmac_GetStats(XEmac * InstancePtr, XEmac_Stats * StatsPtr);
+void XEmac_ClearStats(XEmac * InstancePtr);
+
+#endif                         /* end of protection macro */
diff --git a/board/xilinx/xilinx_enet/xemac_g.c b/board/xilinx/xilinx_enet/xemac_g.c
new file mode 100644 (file)
index 0000000..9340f91
--- /dev/null
@@ -0,0 +1,60 @@
+/*******************************************************************
+*
+* CAUTION: This file is automatically generated by libgen.
+* Version: Xilinx EDK 6.1.2 EDK_G.14
+* DO NOT EDIT.
+*
+*     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.
+*
+* Description: Driver configuration
+*
+*******************************************************************/
+
+#include "xparameters.h"
+#include "xemac.h"
+
+/*
+* The configuration table for devices
+*/
+
+XEmac_Config XEmac_ConfigTable[] = {
+       {
+        XPAR_OPB_ETHERNET_0_DEVICE_ID,
+        XPAR_OPB_ETHERNET_0_BASEADDR,
+        XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST,
+        XPAR_OPB_ETHERNET_0_DMA_PRESENT,
+        XPAR_OPB_ETHERNET_0_MII_EXIST}
+};
diff --git a/board/xilinx/xilinx_enet/xemac_i.h b/board/xilinx/xilinx_enet/xemac_i.h
new file mode 100644 (file)
index 0000000..9c160f3
--- /dev/null
@@ -0,0 +1,207 @@
+/******************************************************************************
+*
+*     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 xemac_i.h
+*
+* This header file contains internal identifiers, which are those shared
+* between XEmac components.  The identifiers in this file are not intended for
+* use external to the driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver  Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00b rpm  04/29/02 Moved register definitions to xemac_l.h
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XEMAC_I_H              /* prevent circular inclusions */
+#define XEMAC_I_H              /* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xemac.h"
+#include "xemac_l.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * Default buffer descriptor control word masks. The default send BD control
+ * is set for incrementing the source address by one for each byte transferred,
+ * and specify that the destination address (FIFO) is local to the device. The
+ * default receive BD control is set for incrementing the destination address
+ * by one for each byte transferred, and specify that the source address is
+ * local to the device.
+ */
+#define XEM_DFT_SEND_BD_MASK   (XDC_DMACR_SOURCE_INCR_MASK | \
+                                XDC_DMACR_DEST_LOCAL_MASK)
+#define XEM_DFT_RECV_BD_MASK   (XDC_DMACR_DEST_INCR_MASK |  \
+                                XDC_DMACR_SOURCE_LOCAL_MASK)
+
+/*
+ * Masks for the IPIF Device Interrupt enable and status registers.
+ */
+#define XEM_IPIF_EMAC_MASK     0x00000004UL    /* MAC interrupt */
+#define XEM_IPIF_SEND_DMA_MASK 0x00000008UL    /* Send DMA interrupt */
+#define XEM_IPIF_RECV_DMA_MASK 0x00000010UL    /* Receive DMA interrupt */
+#define XEM_IPIF_RECV_FIFO_MASK 0x00000020UL   /* Receive FIFO interrupt */
+#define XEM_IPIF_SEND_FIFO_MASK 0x00000040UL   /* Send FIFO interrupt */
+
+/*
+ * Default IPIF Device Interrupt mask when configured for DMA
+ */
+#define XEM_IPIF_DMA_DFT_MASK  (XEM_IPIF_SEND_DMA_MASK |   \
+                                XEM_IPIF_RECV_DMA_MASK |   \
+                                XEM_IPIF_EMAC_MASK |       \
+                                XEM_IPIF_SEND_FIFO_MASK |  \
+                                XEM_IPIF_RECV_FIFO_MASK)
+
+/*
+ * Default IPIF Device Interrupt mask when configured without DMA
+ */
+#define XEM_IPIF_FIFO_DFT_MASK (XEM_IPIF_EMAC_MASK |       \
+                                XEM_IPIF_SEND_FIFO_MASK |  \
+                                XEM_IPIF_RECV_FIFO_MASK)
+
+#define XEM_IPIF_DMA_DEV_INTR_COUNT   7 /* Number of interrupt sources */
+#define XEM_IPIF_FIFO_DEV_INTR_COUNT  5 /* Number of interrupt sources */
+#define XEM_IPIF_DEVICE_INTR_COUNT  7  /* Number of interrupt sources */
+#define XEM_IPIF_IP_INTR_COUNT     22  /* Number of MAC interrupts */
+
+/* a mask for all transmit interrupts, used in polled mode */
+#define XEM_EIR_XMIT_ALL_MASK  (XEM_EIR_XMIT_DONE_MASK |           \
+                                XEM_EIR_XMIT_ERROR_MASK |          \
+                                XEM_EIR_XMIT_SFIFO_EMPTY_MASK |    \
+                                XEM_EIR_XMIT_LFIFO_FULL_MASK)
+
+/* a mask for all receive interrupts, used in polled mode */
+#define XEM_EIR_RECV_ALL_MASK  (XEM_EIR_RECV_DONE_MASK |           \
+                                XEM_EIR_RECV_ERROR_MASK |          \
+                                XEM_EIR_RECV_LFIFO_EMPTY_MASK |    \
+                                XEM_EIR_RECV_LFIFO_OVER_MASK |     \
+                                XEM_EIR_RECV_LFIFO_UNDER_MASK |    \
+                                XEM_EIR_RECV_DFIFO_OVER_MASK |     \
+                                XEM_EIR_RECV_MISSED_FRAME_MASK |   \
+                                XEM_EIR_RECV_COLLISION_MASK |      \
+                                XEM_EIR_RECV_FCS_ERROR_MASK |      \
+                                XEM_EIR_RECV_LEN_ERROR_MASK |      \
+                                XEM_EIR_RECV_SHORT_ERROR_MASK |    \
+                                XEM_EIR_RECV_LONG_ERROR_MASK |     \
+                                XEM_EIR_RECV_ALIGN_ERROR_MASK)
+
+/* a default interrupt mask for scatter-gather DMA operation */
+#define XEM_EIR_DFT_SG_MASK    (XEM_EIR_RECV_ERROR_MASK |          \
+                               XEM_EIR_RECV_LFIFO_OVER_MASK |      \
+                               XEM_EIR_RECV_LFIFO_UNDER_MASK |     \
+                               XEM_EIR_XMIT_SFIFO_OVER_MASK |      \
+                               XEM_EIR_XMIT_SFIFO_UNDER_MASK |     \
+                               XEM_EIR_XMIT_LFIFO_OVER_MASK |      \
+                               XEM_EIR_XMIT_LFIFO_UNDER_MASK |     \
+                               XEM_EIR_RECV_DFIFO_OVER_MASK |      \
+                               XEM_EIR_RECV_MISSED_FRAME_MASK |    \
+                               XEM_EIR_RECV_COLLISION_MASK |       \
+                               XEM_EIR_RECV_FCS_ERROR_MASK |       \
+                               XEM_EIR_RECV_LEN_ERROR_MASK |       \
+                               XEM_EIR_RECV_SHORT_ERROR_MASK |     \
+                               XEM_EIR_RECV_LONG_ERROR_MASK |      \
+                               XEM_EIR_RECV_ALIGN_ERROR_MASK)
+
+/* a default interrupt mask for non-DMA operation (direct FIFOs) */
+#define XEM_EIR_DFT_FIFO_MASK  (XEM_EIR_XMIT_DONE_MASK |           \
+                               XEM_EIR_RECV_DONE_MASK |            \
+                               XEM_EIR_DFT_SG_MASK)
+
+/*
+ * Mask for the DMA interrupt enable and status registers when configured
+ * for scatter-gather DMA.
+ */
+#define XEM_DMA_SG_INTR_MASK   (XDC_IXR_DMA_ERROR_MASK  |      \
+                                XDC_IXR_PKT_THRESHOLD_MASK |   \
+                                XDC_IXR_PKT_WAIT_BOUND_MASK |  \
+                                XDC_IXR_SG_END_MASK)
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/*
+*
+* Clears a structure of given size, in bytes, by setting each byte to 0.
+*
+* @param StructPtr is a pointer to the structure to be cleared.
+* @param NumBytes is the number of bytes in the structure.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* Signature: void XEmac_mClearStruct(u8 *StructPtr, unsigned int NumBytes)
+*
+******************************************************************************/
+#define XEmac_mClearStruct(StructPtr, NumBytes)            \
+{                                                  \
+    int i;                                         \
+    u8 *BytePtr = (u8 *)(StructPtr);       \
+    for (i=0; i < (unsigned int)(NumBytes); i++)    \
+    {                                              \
+       *BytePtr++ = 0;                             \
+    }                                              \
+}
+
+/************************** Variable Definitions *****************************/
+
+extern XEmac_Config XEmac_ConfigTable[];
+
+/************************** Function Prototypes ******************************/
+
+void XEmac_CheckEmacError(XEmac * InstancePtr, u32 IntrStatus);
+void XEmac_CheckFifoRecvError(XEmac * InstancePtr);
+void XEmac_CheckFifoSendError(XEmac * InstancePtr);
+
+#endif                         /* end of protection macro */
diff --git a/board/xilinx/xilinx_enet/xemac_intr.c b/board/xilinx/xilinx_enet/xemac_intr.c
new file mode 100644 (file)
index 0000000..b9a2621
--- /dev/null
@@ -0,0 +1,402 @@
+/******************************************************************************
+*
+*     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 xemac_intr.c
+*
+* This file contains general interrupt-related functions of the XEmac driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* 1.00c rpm  03/31/03 Added comment to indicate that no Receive Length FIFO
+*                     overrun interrupts occur in v1.00l and later of the EMAC
+*                     device. This avoids the need to reset the device on
+*                     receive overruns.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xemac_i.h"
+#include "xio.h"
+#include "xipif_v1_23_b.h"     /* Uses v1.23b of the IPIF */
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Set the callback function for handling asynchronous errors.  The upper layer
+* software should call this function during initialization.
+*
+* The error callback is invoked by the driver within interrupt context, so it
+* needs to do its job quickly. If there are potentially slow operations within
+* the callback, these should be done at task-level.
+*
+* The Xilinx errors that must be handled by the callback are:
+* - XST_DMA_ERROR indicates an unrecoverable DMA error occurred. This is
+*   typically a bus error or bus timeout. The handler must reset and
+*   re-configure the device.
+* - XST_FIFO_ERROR indicates an unrecoverable FIFO error occurred. This is a
+*   deadlock condition in the packet FIFO. The handler must reset and
+*   re-configure the device.
+* - XST_RESET_ERROR indicates an unrecoverable MAC error occurred, usually an
+*   overrun or underrun. The handler must reset and re-configure the device.
+* - XST_DMA_SG_NO_LIST indicates an attempt was made to access a scatter-gather
+*   DMA list that has not yet been created.
+* - XST_DMA_SG_LIST_EMPTY indicates the driver tried to get a descriptor from
+*   the receive descriptor list, but the list was empty.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param CallBackRef is a reference pointer to be passed back to the adapter in
+*        the callback. This helps the adapter correlate the callback to a
+*        particular driver.
+* @param FuncPtr is the pointer to the callback function.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_SetErrorHandler(XEmac * InstancePtr, void *CallBackRef,
+                     XEmac_ErrorHandler FuncPtr)
+{
+       XASSERT_VOID(InstancePtr != NULL);
+       XASSERT_VOID(FuncPtr != NULL);
+       XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       InstancePtr->ErrorHandler = FuncPtr;
+       InstancePtr->ErrorRef = CallBackRef;
+}
+
+/****************************************************************************/
+/*
+*
+* Check the interrupt status bits of the Ethernet MAC for errors. Errors
+* currently handled are:
+* - Receive length FIFO overrun. Indicates data was lost due to the receive
+*   length FIFO becoming full during the reception of a packet. Only a device
+*   reset clears this condition.
+* - Receive length FIFO underrun. An attempt to read an empty FIFO. Only a
+*   device reset clears this condition.
+* - Transmit status FIFO overrun. Indicates data was lost due to the transmit
+*   status FIFO becoming full following the transmission of a packet. Only a
+*   device reset clears this condition.
+* - Transmit status FIFO underrun. An attempt to read an empty FIFO. Only a
+*   device reset clears this condition.
+* - Transmit length FIFO overrun. Indicates data was lost due to the transmit
+*   length FIFO becoming full following the transmission of a packet. Only a
+*   device reset clears this condition.
+* - Transmit length FIFO underrun. An attempt to read an empty FIFO. Only a
+*   device reset clears this condition.
+* - Receive data FIFO overrun. Indicates data was lost due to the receive data
+*   FIFO becoming full during the reception of a packet.
+* - Receive data errors:
+*   - Receive missed frame error. Valid data was lost by the MAC.
+*   - Receive collision error. Data was lost by the MAC due to a collision.
+*   - Receive FCS error.  Data was dicarded by the MAC due to FCS error.
+*   - Receive length field error. Data was dicarded by the MAC due to an invalid
+*     length field in the packet.
+*   - Receive short error. Data was dicarded by the MAC because a packet was
+*     shorter than allowed.
+*   - Receive long error. Data was dicarded by the MAC because a packet was
+*     longer than allowed.
+*   - Receive alignment error. Data was truncated by the MAC because its length
+*     was not byte-aligned.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param IntrStatus is the contents of the interrupt status register to be checked
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* This function is intended for internal use only.
+*
+******************************************************************************/
+void
+XEmac_CheckEmacError(XEmac * InstancePtr, u32 IntrStatus)
+{
+       u32 ResetError = FALSE;
+
+       /*
+        * First check for receive fifo overrun/underrun errors. Most require a
+        * reset by the user to clear, but the data FIFO overrun error does not.
+        */
+       if (IntrStatus & XEM_EIR_RECV_DFIFO_OVER_MASK) {
+               InstancePtr->Stats.RecvOverrunErrors++;
+               InstancePtr->Stats.FifoErrors++;
+       }
+
+       if (IntrStatus & XEM_EIR_RECV_LFIFO_OVER_MASK) {
+               /*
+                * Receive Length FIFO overrun interrupts no longer occur in v1.00l
+                * and later of the EMAC device. Frames are just dropped by the EMAC
+                * if the length FIFO is full. The user would notice the Receive Missed
+                * Frame count incrementing without any other errors being reported.
+                * This code is left here for backward compatibility with v1.00k and
+                * older EMAC devices.
+                */
+               InstancePtr->Stats.RecvOverrunErrors++;
+               InstancePtr->Stats.FifoErrors++;
+               ResetError = TRUE;      /* requires a reset */
+       }
+
+       if (IntrStatus & XEM_EIR_RECV_LFIFO_UNDER_MASK) {
+               InstancePtr->Stats.RecvUnderrunErrors++;
+               InstancePtr->Stats.FifoErrors++;
+               ResetError = TRUE;      /* requires a reset */
+       }
+
+       /*
+        * Now check for general receive errors. Get the latest count where
+        * available, otherwise just bump the statistic so we know the interrupt
+        * occurred.
+        */
+       if (IntrStatus & XEM_EIR_RECV_ERROR_MASK) {
+               if (IntrStatus & XEM_EIR_RECV_MISSED_FRAME_MASK) {
+                       /*
+                        * Caused by length FIFO or data FIFO overruns on receive side
+                        */
+                       InstancePtr->Stats.RecvMissedFrameErrors =
+                           XIo_In32(InstancePtr->BaseAddress +
+                                    XEM_RMFC_OFFSET);
+               }
+
+               if (IntrStatus & XEM_EIR_RECV_COLLISION_MASK) {
+                       InstancePtr->Stats.RecvCollisionErrors =
+                           XIo_In32(InstancePtr->BaseAddress + XEM_RCC_OFFSET);
+               }
+
+               if (IntrStatus & XEM_EIR_RECV_FCS_ERROR_MASK) {
+                       InstancePtr->Stats.RecvFcsErrors =
+                           XIo_In32(InstancePtr->BaseAddress +
+                                    XEM_RFCSEC_OFFSET);
+               }
+
+               if (IntrStatus & XEM_EIR_RECV_LEN_ERROR_MASK) {
+                       InstancePtr->Stats.RecvLengthFieldErrors++;
+               }
+
+               if (IntrStatus & XEM_EIR_RECV_SHORT_ERROR_MASK) {
+                       InstancePtr->Stats.RecvShortErrors++;
+               }
+
+               if (IntrStatus & XEM_EIR_RECV_LONG_ERROR_MASK) {
+                       InstancePtr->Stats.RecvLongErrors++;
+               }
+
+               if (IntrStatus & XEM_EIR_RECV_ALIGN_ERROR_MASK) {
+                       InstancePtr->Stats.RecvAlignmentErrors =
+                           XIo_In32(InstancePtr->BaseAddress +
+                                    XEM_RAEC_OFFSET);
+               }
+
+               /*
+                * Bump recv interrupts stats only if not scatter-gather DMA (this
+                * stat gets bumped elsewhere in that case)
+                */
+               if (!XEmac_mIsSgDma(InstancePtr)) {
+                       InstancePtr->Stats.RecvInterrupts++;    /* TODO: double bump? */
+               }
+
+       }
+
+       /*
+        * Check for transmit errors. These apply to both DMA and non-DMA modes
+        * of operation. The entire device should be reset after overruns or
+        * underruns.
+        */
+       if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
+                         XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
+               InstancePtr->Stats.XmitOverrunErrors++;
+               InstancePtr->Stats.FifoErrors++;
+               ResetError = TRUE;
+       }
+
+       if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
+                         XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
+               InstancePtr->Stats.XmitUnderrunErrors++;
+               InstancePtr->Stats.FifoErrors++;
+               ResetError = TRUE;
+       }
+
+       if (ResetError) {
+               /*
+                * If a reset error occurred, disable the EMAC interrupts since the
+                * reset-causing interrupt(s) is latched in the EMAC - meaning it will
+                * keep occurring until the device is reset. In order to give the higher
+                * layer software time to reset the device, we have to disable the
+                * overrun/underrun interrupts until that happens. We trust that the
+                * higher layer resets the device. We are able to get away with disabling
+                * all EMAC interrupts since the only interrupts it generates are for
+                * error conditions, and we don't care about any more errors right now.
+                */
+               XIIF_V123B_WRITE_IIER(InstancePtr->BaseAddress, 0);
+
+               /*
+                * Invoke the error handler callback, which should result in a reset
+                * of the device by the upper layer software.
+                */
+               InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
+                                         XST_RESET_ERROR);
+       }
+}
+
+/*****************************************************************************/
+/*
+*
+* Check the receive packet FIFO for errors. FIFO error interrupts are:
+* - Deadlock.  See the XPacketFifo component for a description of deadlock on a
+*   FIFO.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Although the function returns void, it can return an asynchronous error to the
+* application through the error handler.  It can return XST_FIFO_ERROR if a FIFO
+* error occurred.
+*
+* @note
+*
+* This function is intended for internal use only.
+*
+******************************************************************************/
+void
+XEmac_CheckFifoRecvError(XEmac * InstancePtr)
+{
+       /*
+        * Although the deadlock is currently the only interrupt from a packet
+        * FIFO, make sure it is deadlocked before taking action. There is no
+        * need to clear this interrupt since it requires a reset of the device.
+        */
+       if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->RecvFifo)) {
+               u32 IntrEnable;
+
+               InstancePtr->Stats.FifoErrors++;
+
+               /*
+                * Invoke the error callback function, which should result in a reset
+                * of the device by the upper layer software. We first need to disable
+                * the FIFO interrupt, since otherwise the upper layer thread that
+                * handles the reset may never run because this interrupt condition
+                * doesn't go away until a reset occurs (there is no way to ack it).
+                */
+               IntrEnable = XIIF_V123B_READ_DIER(InstancePtr->BaseAddress);
+               XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
+                                     IntrEnable & ~XEM_IPIF_RECV_FIFO_MASK);
+
+               InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
+                                         XST_FIFO_ERROR);
+       }
+}
+
+/*****************************************************************************/
+/*
+*
+* Check the send packet FIFO for errors. FIFO error interrupts are:
+* - Deadlock. See the XPacketFifo component for a description of deadlock on a
+*   FIFO.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Although the function returns void, it can return an asynchronous error to the
+* application through the error handler.  It can return XST_FIFO_ERROR if a FIFO
+* error occurred.
+*
+* @note
+*
+* This function is intended for internal use only.
+*
+******************************************************************************/
+void
+XEmac_CheckFifoSendError(XEmac * InstancePtr)
+{
+       /*
+        * Although the deadlock is currently the only interrupt from a packet
+        * FIFO, make sure it is deadlocked before taking action. There is no
+        * need to clear this interrupt since it requires a reset of the device.
+        */
+       if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->SendFifo)) {
+               u32 IntrEnable;
+
+               InstancePtr->Stats.FifoErrors++;
+
+               /*
+                * Invoke the error callback function, which should result in a reset
+                * of the device by the upper layer software. We first need to disable
+                * the FIFO interrupt, since otherwise the upper layer thread that
+                * handles the reset may never run because this interrupt condition
+                * doesn't go away until a reset occurs (there is no way to ack it).
+                */
+               IntrEnable = XIIF_V123B_READ_DIER(InstancePtr->BaseAddress);
+               XIIF_V123B_WRITE_DIER(InstancePtr->BaseAddress,
+                                     IntrEnable & ~XEM_IPIF_SEND_FIFO_MASK);
+
+               InstancePtr->ErrorHandler(InstancePtr->ErrorRef,
+                                         XST_FIFO_ERROR);
+       }
+}
diff --git a/board/xilinx/xilinx_enet/xemac_intr_dma.c b/board/xilinx/xilinx_enet/xemac_intr_dma.c
new file mode 100644 (file)
index 0000000..567abb4
--- /dev/null
@@ -0,0 +1,1344 @@
+/******************************************************************************
+*
+*     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 xemac_intr_dma.c
+*
+* Contains functions used in interrupt mode when configured with scatter-gather
+* DMA.
+*
+* The interrupt handler, XEmac_IntrHandlerDma(), must be connected by the user
+* to the interrupt controller.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- ---------------------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00c rpm  12/05/02 New version includes support for simple DMA and the delay
+*                     argument to SgSend
+* 1.00c rpm  02/03/03 The XST_DMA_SG_COUNT_EXCEEDED return code was removed
+*                     from SetPktThreshold in the internal DMA driver. Also
+*                     avoided compiler warnings by initializing Result in the
+*                     interrupt service routines.
+* 1.00c rpm  03/26/03 Fixed a problem in the interrupt service routines where
+*                     the interrupt status was toggled clear after a call to
+*                     ErrorHandler, but if ErrorHandler reset the device the
+*                     toggle actually asserted the interrupt because the
+*                     reset had cleared it.
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xemac_i.h"
+#include "xio.h"
+#include "xbuf_descriptor.h"
+#include "xdma_channel.h"
+#include "xipif_v1_23_b.h"     /* Uses v1.23b of the IPIF */
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/************************** Function Prototypes ******************************/
+
+static void HandleDmaRecvIntr(XEmac * InstancePtr);
+static void HandleDmaSendIntr(XEmac * InstancePtr);
+static void HandleEmacDmaIntr(XEmac * InstancePtr);
+
+/*****************************************************************************/
+/**
+*
+* Send an Ethernet frame using scatter-gather DMA. The caller attaches the
+* frame to one or more buffer descriptors, then calls this function once for
+* each descriptor. The caller is responsible for allocating and setting up the
+* descriptor. An entire Ethernet frame may or may not be contained within one
+* descriptor.  This function simply inserts the descriptor into the scatter-
+* gather engine's transmit list. The caller is responsible for providing mutual
+* exclusion to guarantee that a frame is contiguous in the transmit list. The
+* buffer attached to the descriptor must be word-aligned.
+*
+* The driver updates the descriptor with the device control register before
+* being inserted into the transmit list.  If this is the last descriptor in
+* the frame, the inserts are committed, which means the descriptors for this
+* frame are now available for transmission.
+*
+* It is assumed that the upper layer software supplies a correctly formatted
+* Ethernet frame, including the destination and source addresses, the
+* type/length field, and the data field.  It is also assumed that upper layer
+* software does not append FCS at the end of the frame.
+*
+* The buffer attached to the descriptor must be word-aligned on the front end.
+*
+* This call is non-blocking.  Notification of error or successful transmission
+* is done asynchronously through the send or error callback function.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param BdPtr is the address of a descriptor to be inserted into the transmit
+*        ring.
+* @param Delay indicates whether to start the scatter-gather DMA channel
+*        immediately, or whether to wait. This allows the user to build up a
+*        list of more than one descriptor before starting the transmission of
+*        the packets, which allows the application to keep up with DMA and have
+*        a constant stream of frames being transmitted. Use XEM_SGDMA_NODELAY or
+*        XEM_SGDMA_DELAY, defined in xemac.h, as the value of this argument. If
+*        the user chooses to delay and build a list, the user must call this
+*        function with the XEM_SGDMA_NODELAY option or call XEmac_Start() to
+*        kick off the tranmissions.
+*
+* @return
+*
+* - XST_SUCCESS if the buffer was successfull sent
+* - XST_DEVICE_IS_STOPPED if the Ethernet MAC has not been started yet
+* - XST_NOT_SGDMA if the device is not in scatter-gather DMA mode
+* - XST_DMA_SG_LIST_FULL if the descriptor list for the DMA channel is full
+* - XST_DMA_SG_BD_LOCKED if the DMA channel cannot insert the descriptor into
+*   the list because a locked descriptor exists at the insert point
+* - XST_DMA_SG_NOTHING_TO_COMMIT if even after inserting a descriptor into the
+*   list, the DMA channel believes there are no new descriptors to commit. If
+*   this is ever encountered, there is likely a thread mutual exclusion problem
+*   on transmit.
+*
+* @note
+*
+* This function is not thread-safe. The user must provide mutually exclusive
+* access to this function if there are to be multiple threads that can call it.
+*
+* @internal
+*
+* A status that should never be returned from this function, although
+* the code is set up to handle it, is XST_DMA_SG_NO_LIST. Starting the device
+* requires a list to be created, and this function requires the device to be
+* started.
+*
+******************************************************************************/
+XStatus
+XEmac_SgSend(XEmac * InstancePtr, XBufDescriptor * BdPtr, int Delay)
+{
+       XStatus Result;
+       u32 BdControl;
+
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(BdPtr != NULL);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       /*
+        * Be sure the device is configured for scatter-gather DMA, then be sure
+        * it is started.
+        */
+       if (!XEmac_mIsSgDma(InstancePtr)) {
+               return XST_NOT_SGDMA;
+       }
+
+       /*
+        * Set some descriptor control word defaults (source address increment
+        * and local destination address) and the destination address
+        * (the FIFO).  These are the same for every transmit descriptor.
+        */
+       BdControl = XBufDescriptor_GetControl(BdPtr);
+       XBufDescriptor_SetControl(BdPtr, BdControl | XEM_DFT_SEND_BD_MASK);
+
+       XBufDescriptor_SetDestAddress(BdPtr,
+                                     InstancePtr->BaseAddress +
+                                     XEM_PFIFO_TXDATA_OFFSET);
+
+       /*
+        * Put the descriptor in the send list. The DMA component accesses data
+        * here that can also be modified in interrupt context, so a critical
+        * section is required.
+        */
+       XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
+
+       Result = XDmaChannel_PutDescriptor(&InstancePtr->SendChannel, BdPtr);
+       if (Result != XST_SUCCESS) {
+               XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+               return Result;
+       }
+
+       /*
+        * If this is the last buffer in the frame, commit the inserts and start
+        * the DMA engine if necessary
+        */
+       if (XBufDescriptor_IsLastControl(BdPtr)) {
+               Result = XDmaChannel_CommitPuts(&InstancePtr->SendChannel);
+               if (Result != XST_SUCCESS) {
+                       XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+                       return Result;
+               }
+
+               if (Delay == XEM_SGDMA_NODELAY) {
+                       /*
+                        * Start the DMA channel. Ignore the return status since we know the
+                        * list exists and has at least one entry and we don't care if the
+                        * channel is already started.  The DMA component accesses data here
+                        * that can be modified at interrupt or task levels, so a critical
+                        * section is required.
+                        */
+                       (void) XDmaChannel_SgStart(&InstancePtr->SendChannel);
+               }
+       }
+
+       XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+
+       return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Add a descriptor, with an attached empty buffer, into the receive descriptor
+* list. The buffer attached to the descriptor must be word-aligned. This is
+* used by the upper layer software during initialization when first setting up
+* the receive descriptors, and also during reception of frames to replace
+* filled buffers with empty buffers. This function can be called when the
+* device is started or stopped. Note that it does start the scatter-gather DMA
+* engine.  Although this is not necessary during initialization, it is not a
+* problem during initialization because the MAC receiver is not yet started.
+*
+* The buffer attached to the descriptor must be word-aligned on both the front
+* end and the back end.
+*
+* Notification of received frames are done asynchronously through the receive
+* callback function.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param BdPtr is a pointer to the buffer descriptor that will be added to the
+*        descriptor list.
+*
+* @return
+*
+* - XST_SUCCESS if a descriptor was successfully returned to the driver
+* - XST_NOT_SGDMA if the device is not in scatter-gather DMA mode
+* - XST_DMA_SG_LIST_FULL if the receive descriptor list is full
+* - XST_DMA_SG_BD_LOCKED if the DMA channel cannot insert the descriptor into
+*   the list because a locked descriptor exists at the insert point.
+* - XST_DMA_SG_NOTHING_TO_COMMIT if even after inserting a descriptor into the
+*   list, the DMA channel believes there are no new descriptors to commit.
+*
+* @internal
+*
+* A status that should never be returned from this function, although
+* the code is set up to handle it, is XST_DMA_SG_NO_LIST. Starting the device
+* requires a list to be created, and this function requires the device to be
+* started.
+*
+******************************************************************************/
+XStatus
+XEmac_SgRecv(XEmac * InstancePtr, XBufDescriptor * BdPtr)
+{
+       XStatus Result;
+       u32 BdControl;
+
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(BdPtr != NULL);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       /*
+        * Be sure the device is configured for scatter-gather DMA
+        */
+       if (!XEmac_mIsSgDma(InstancePtr)) {
+               return XST_NOT_SGDMA;
+       }
+
+       /*
+        * Set some descriptor control word defaults (destination address increment
+        * and local source address) and the source address (the FIFO). These are
+        * the same for every receive descriptor.
+        */
+       BdControl = XBufDescriptor_GetControl(BdPtr);
+       XBufDescriptor_SetControl(BdPtr, BdControl | XEM_DFT_RECV_BD_MASK);
+       XBufDescriptor_SetSrcAddress(BdPtr,
+                                    InstancePtr->BaseAddress +
+                                    XEM_PFIFO_RXDATA_OFFSET);
+
+       /*
+        * Put the descriptor into the channel's descriptor list and commit.
+        * Although this function is likely called within interrupt context, there
+        * is the possibility that the upper layer software queues it to a task.
+        * In this case, a critical section is needed here to protect shared data
+        * in the DMA component.
+        */
+       XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress);
+
+       Result = XDmaChannel_PutDescriptor(&InstancePtr->RecvChannel, BdPtr);
+       if (Result != XST_SUCCESS) {
+               XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+               return Result;
+       }
+
+       Result = XDmaChannel_CommitPuts(&InstancePtr->RecvChannel);
+       if (Result != XST_SUCCESS) {
+               XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+               return Result;
+       }
+
+       /*
+        * Start the DMA channel. Ignore the return status since we know the list
+        * exists and has at least one entry and we don't care if the channel is
+        * already started. The DMA component accesses data here that can be
+        * modified at interrupt or task levels, so a critical section is required.
+        */
+       (void) XDmaChannel_SgStart(&InstancePtr->RecvChannel);
+
+       XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress);
+
+       return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* The interrupt handler for the Ethernet driver when configured with scatter-
+* gather DMA.
+*
+* Get the interrupt status from the IpIf to determine the source of the
+* interrupt.  The source can be: MAC, Recv Packet FIFO, Send Packet FIFO, Recv
+* DMA channel, or Send DMA channel. The packet FIFOs only interrupt during
+* "deadlock" conditions.
+*
+* @param InstancePtr is a pointer to the XEmac instance that just interrupted.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_IntrHandlerDma(void *InstancePtr)
+{
+       u32 IntrStatus;
+       XEmac *EmacPtr = (XEmac *) InstancePtr;
+
+       EmacPtr->Stats.TotalIntrs++;
+
+       /*
+        * Get the interrupt status from the IPIF. There is no clearing of
+        * interrupts in the IPIF. Interrupts must be cleared at the source.
+        */
+       IntrStatus = XIIF_V123B_READ_DIPR(EmacPtr->BaseAddress);
+
+       /*
+        * See which type of interrupt is being requested, and service it
+        */
+       if (IntrStatus & XEM_IPIF_RECV_DMA_MASK) {      /* Receive DMA interrupt */
+               EmacPtr->Stats.RecvInterrupts++;
+               HandleDmaRecvIntr(EmacPtr);
+       }
+
+       if (IntrStatus & XEM_IPIF_SEND_DMA_MASK) {      /* Send DMA interrupt */
+               EmacPtr->Stats.XmitInterrupts++;
+               HandleDmaSendIntr(EmacPtr);
+       }
+
+       if (IntrStatus & XEM_IPIF_EMAC_MASK) {  /* MAC interrupt */
+               EmacPtr->Stats.EmacInterrupts++;
+               HandleEmacDmaIntr(EmacPtr);
+       }
+
+       if (IntrStatus & XEM_IPIF_RECV_FIFO_MASK) {     /* Receive FIFO interrupt */
+               EmacPtr->Stats.RecvInterrupts++;
+               XEmac_CheckFifoRecvError(EmacPtr);
+       }
+
+       if (IntrStatus & XEM_IPIF_SEND_FIFO_MASK) {     /* Send FIFO interrupt */
+               EmacPtr->Stats.XmitInterrupts++;
+               XEmac_CheckFifoSendError(EmacPtr);
+       }
+
+       if (IntrStatus & XIIF_V123B_ERROR_MASK) {
+               /*
+                * An error occurred internal to the IPIF. This is more of a debug and
+                * integration issue rather than a production error. Don't do anything
+                * other than clear it, which provides a spot for software to trap
+                * on the interrupt and begin debugging.
+                */
+               XIIF_V123B_WRITE_DISR(EmacPtr->BaseAddress,
+                                     XIIF_V123B_ERROR_MASK);
+       }
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the packet count threshold for this device. The device must be stopped
+* before setting the threshold. The packet count threshold is used for interrupt
+* coalescing, which reduces the frequency of interrupts from the device to the
+* processor. In this case, the scatter-gather DMA engine only interrupts when
+* the packet count threshold is reached, instead of interrupting for each packet.
+* A packet is a generic term used by the scatter-gather DMA engine, and is
+* equivalent to an Ethernet frame in our case.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param Direction indicates the channel, send or receive, from which the
+*        threshold register is read.
+* @param Threshold is the value of the packet threshold count used during
+*        interrupt coalescing. A value of 0 disables the use of packet threshold
+*        by the hardware.
+*
+* @return
+*
+* - XST_SUCCESS if the threshold was successfully set
+* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
+* - XST_DEVICE_IS_STARTED if the device has not been stopped
+* - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on
+*   asserts would also catch this error.
+*
+* @note
+*
+* 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
+XEmac_SetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 Threshold)
+{
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       /*
+        * Be sure device is configured for scatter-gather DMA and has been stopped
+        */
+       if (!XEmac_mIsSgDma(InstancePtr)) {
+               return XST_NOT_SGDMA;
+       }
+
+       if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+               return XST_DEVICE_IS_STARTED;
+       }
+
+       /*
+        * Based on the direction, set the packet threshold in the
+        * corresponding DMA channel component.  Default to the receive
+        * channel threshold register (if an invalid Direction is passed).
+        */
+       switch (Direction) {
+       case XEM_SEND:
+               return XDmaChannel_SetPktThreshold(&InstancePtr->SendChannel,
+                                                  Threshold);
+
+       case XEM_RECV:
+               return XDmaChannel_SetPktThreshold(&InstancePtr->RecvChannel,
+                                                  Threshold);
+
+       default:
+               return XST_INVALID_PARAM;
+       }
+}
+
+/*****************************************************************************/
+/**
+*
+* Get the value of the packet count threshold for this driver/device. The packet
+* count threshold is used for interrupt coalescing, which reduces the frequency
+* of interrupts from the device to the processor. In this case, the
+* scatter-gather DMA engine only interrupts when the packet count threshold is
+* reached, instead of interrupting for each packet. A packet is a generic term
+* used by the scatter-gather DMA engine, and is equivalent to an Ethernet frame
+* in our case.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param Direction indicates the channel, send or receive, from which the
+*        threshold register is read.
+* @param ThreshPtr is a pointer to the byte into which the current value of the
+*        packet threshold register will be copied. An output parameter. A value
+*        of 0 indicates the use of packet threshold by the hardware is disabled.
+*
+* @return
+*
+* - XST_SUCCESS if the packet threshold was retrieved successfully
+* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
+* - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on
+*   asserts would also catch this error.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XEmac_GetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 * ThreshPtr)
+{
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
+       XASSERT_NONVOID(ThreshPtr != NULL);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       if (!XEmac_mIsSgDma(InstancePtr)) {
+               return XST_NOT_SGDMA;
+       }
+
+       /*
+        * Based on the direction, return the packet threshold set in the
+        * corresponding DMA channel component.  Default to the value in
+        * the receive channel threshold register (if an invalid Direction
+        * is passed).
+        */
+       switch (Direction) {
+       case XEM_SEND:
+               *ThreshPtr =
+                   XDmaChannel_GetPktThreshold(&InstancePtr->SendChannel);
+               break;
+
+       case XEM_RECV:
+               *ThreshPtr =
+                   XDmaChannel_GetPktThreshold(&InstancePtr->RecvChannel);
+               break;
+
+       default:
+               return XST_INVALID_PARAM;
+       }
+
+       return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the packet wait bound timer for this driver/device. The device must be
+* stopped before setting the timer value. The packet wait bound is used during
+* interrupt coalescing to trigger an interrupt when not enough packets have been
+* received to reach the packet count threshold. A packet is a generic term used
+* by the scatter-gather DMA engine, and is equivalent to an Ethernet frame in
+* our case. The timer is in milliseconds.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param Direction indicates the channel, send or receive, from which the
+*        threshold register is read.
+* @param TimerValue is the value of the packet wait bound used during interrupt
+*        coalescing. It is in milliseconds in the range 0  - 1023. A value of 0
+*        disables the packet wait bound timer.
+*
+* @return
+*
+* - XST_SUCCESS if the packet wait bound was set successfully
+* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
+* - XST_DEVICE_IS_STARTED if the device has not been stopped
+* - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on
+*   asserts would also catch this error.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XEmac_SetPktWaitBound(XEmac * InstancePtr, u32 Direction, u32 TimerValue)
+{
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
+       XASSERT_NONVOID(TimerValue <= XEM_SGDMA_MAX_WAITBOUND);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       /*
+        * Be sure device is configured for scatter-gather DMA and has been stopped
+        */
+       if (!XEmac_mIsSgDma(InstancePtr)) {
+               return XST_NOT_SGDMA;
+       }
+
+       if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+               return XST_DEVICE_IS_STARTED;
+       }
+
+       /*
+        * Based on the direction, set the packet wait bound in the
+        * corresponding DMA channel component.  Default to the receive
+        * channel wait bound register (if an invalid Direction is passed).
+        */
+       switch (Direction) {
+       case XEM_SEND:
+               XDmaChannel_SetPktWaitBound(&InstancePtr->SendChannel,
+                                           TimerValue);
+               break;
+
+       case XEM_RECV:
+               XDmaChannel_SetPktWaitBound(&InstancePtr->RecvChannel,
+                                           TimerValue);
+               break;
+
+       default:
+               return XST_INVALID_PARAM;
+       }
+
+       return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Get the packet wait bound timer for this driver/device. The packet wait bound
+* is used during interrupt coalescing to trigger an interrupt when not enough
+* packets have been received to reach the packet count threshold. A packet is a
+* generic term used by the scatter-gather DMA engine, and is equivalent to an
+* Ethernet frame in our case. The timer is in milliseconds.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param Direction indicates the channel, send or receive, from which the
+*        threshold register is read.
+* @param WaitPtr is a pointer to the byte into which the current value of the
+*        packet wait bound register will be copied. An output parameter. Units
+*        are in milliseconds in the range 0  - 1023. A value of 0 indicates the
+*        packet wait bound timer is disabled.
+*
+* @return
+*
+* - XST_SUCCESS if the packet wait bound was retrieved successfully
+* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
+* - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on
+*   asserts would also catch this error.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XEmac_GetPktWaitBound(XEmac * InstancePtr, u32 Direction, u32 * WaitPtr)
+{
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV);
+       XASSERT_NONVOID(WaitPtr != NULL);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       if (!XEmac_mIsSgDma(InstancePtr)) {
+               return XST_NOT_SGDMA;
+       }
+
+       /*
+        * Based on the direction, return the packet wait bound set in the
+        * corresponding DMA channel component.  Default to the value in
+        * the receive channel wait bound register (if an invalid Direction
+        * is passed).
+        */
+       switch (Direction) {
+       case XEM_SEND:
+               *WaitPtr =
+                   XDmaChannel_GetPktWaitBound(&InstancePtr->SendChannel);
+               break;
+
+       case XEM_RECV:
+               *WaitPtr =
+                   XDmaChannel_GetPktWaitBound(&InstancePtr->RecvChannel);
+               break;
+
+       default:
+               return XST_INVALID_PARAM;
+       }
+
+       return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Give the driver the memory space to be used for the scatter-gather DMA
+* receive descriptor list. This function should only be called once, during
+* initialization of the Ethernet driver. The memory space must be big enough
+* to hold some number of descriptors, depending on the needs of the system.
+* The xemac.h file defines minimum and default numbers of descriptors
+* which can be used to allocate this memory space.
+*
+* The memory space must be word-aligned. An assert will occur if asserts are
+* turned on and the memory is not word-aligned.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param MemoryPtr is a pointer to the word-aligned memory.
+* @param ByteCount is the length, in bytes, of the memory space.
+*
+* @return
+*
+* - XST_SUCCESS if the space was initialized successfully
+* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
+* - XST_DMA_SG_LIST_EXISTS if this list space has already been created
+*
+* @note
+*
+* If the device is configured for scatter-gather DMA, this function must be
+* called AFTER the XEmac_Initialize() function because the DMA channel
+* components must be initialized before the memory space is set.
+*
+******************************************************************************/
+XStatus
+XEmac_SetSgRecvSpace(XEmac * InstancePtr, u32 * MemoryPtr, u32 ByteCount)
+{
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(MemoryPtr != NULL);
+       XASSERT_NONVOID(ByteCount != 0);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       if (!XEmac_mIsSgDma(InstancePtr)) {
+               return XST_NOT_SGDMA;
+       }
+
+       return XDmaChannel_CreateSgList(&InstancePtr->RecvChannel, MemoryPtr,
+                                       ByteCount);
+}
+
+/*****************************************************************************/
+/**
+*
+* Give the driver the memory space to be used for the scatter-gather DMA
+* transmit descriptor list. This function should only be called once, during
+* initialization of the Ethernet driver. The memory space must be big enough
+* to hold some number of descriptors, depending on the needs of the system.
+* The xemac.h file defines minimum and default numbers of descriptors
+* which can be used to allocate this memory space.
+*
+* The memory space must be word-aligned. An assert will occur if asserts are
+* turned on and the memory is not word-aligned.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param MemoryPtr is a pointer to the word-aligned memory.
+* @param ByteCount is the length, in bytes, of the memory space.
+*
+* @return
+*
+* - XST_SUCCESS if the space was initialized successfully
+* - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA
+* - XST_DMA_SG_LIST_EXISTS if this list space has already been created
+*
+* @note
+*
+* If the device is configured for scatter-gather DMA, this function must be
+* called AFTER the XEmac_Initialize() function because the DMA channel
+* components must be initialized before the memory space is set.
+*
+******************************************************************************/
+XStatus
+XEmac_SetSgSendSpace(XEmac * InstancePtr, u32 * MemoryPtr, u32 ByteCount)
+{
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(MemoryPtr != NULL);
+       XASSERT_NONVOID(ByteCount != 0);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       if (!XEmac_mIsSgDma(InstancePtr)) {
+               return XST_NOT_SGDMA;
+       }
+
+       return XDmaChannel_CreateSgList(&InstancePtr->SendChannel, MemoryPtr,
+                                       ByteCount);
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the callback function for handling received frames in scatter-gather DMA
+* mode.  The upper layer software should call this function during
+* initialization.  The callback is called once per frame received. The head of
+* a descriptor list is passed in along with the number of descriptors in the
+* list. Before leaving the callback, the upper layer software should attach a
+* new buffer to each descriptor in the list.
+*
+* The callback is invoked by the driver within interrupt context, so it needs
+* to do its job quickly. Sending the received frame up the protocol stack
+* should be done at task-level. If there are other potentially slow operations
+* within the callback, these too should be done at task-level.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param CallBackRef is a reference pointer to be passed back to the adapter in
+*        the callback. This helps the adapter correlate the callback to a
+*        particular driver.
+* @param FuncPtr is the pointer to the callback function.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_SetSgRecvHandler(XEmac * InstancePtr, void *CallBackRef,
+                      XEmac_SgHandler FuncPtr)
+{
+       /*
+        * Asserted IsDmaSg here instead of run-time check because there is really
+        * no ill-effects of setting these when not configured for scatter-gather.
+        */
+       XASSERT_VOID(InstancePtr != NULL);
+       XASSERT_VOID(FuncPtr != NULL);
+       XASSERT_VOID(XEmac_mIsSgDma(InstancePtr));
+       XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       InstancePtr->SgRecvHandler = FuncPtr;
+       InstancePtr->SgRecvRef = CallBackRef;
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the callback function for handling confirmation of transmitted frames in
+* scatter-gather DMA mode.  The upper layer software should call this function
+* during initialization.  The callback is called once per frame sent. The head
+* of a descriptor list is passed in along with the number of descriptors in
+* the list. The callback is responsible for freeing buffers attached to these
+* descriptors.
+*
+* The callback is invoked by the driver within interrupt context, so it needs
+* to do its job quickly. If there are potentially slow operations within the
+* callback, these should be done at task-level.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param CallBackRef is a reference pointer to be passed back to the adapter in
+*        the callback. This helps the adapter correlate the callback to a
+*        particular driver.
+* @param FuncPtr is the pointer to the callback function.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+void
+XEmac_SetSgSendHandler(XEmac * InstancePtr, void *CallBackRef,
+                      XEmac_SgHandler FuncPtr)
+{
+       /*
+        * Asserted IsDmaSg here instead of run-time check because there is really
+        * no ill-effects of setting these when not configured for scatter-gather.
+        */
+       XASSERT_VOID(InstancePtr != NULL);
+       XASSERT_VOID(FuncPtr != NULL);
+       XASSERT_VOID(XEmac_mIsSgDma(InstancePtr));
+       XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       InstancePtr->SgSendHandler = FuncPtr;
+       InstancePtr->SgSendRef = CallBackRef;
+}
+
+/*****************************************************************************/
+/*
+*
+* Handle an interrupt from the DMA receive channel. DMA interrupts are:
+*
+* - DMA error. DMA encountered a bus error or timeout. This is a fatal error
+*   that requires reset of the channel.  The driver calls the error handler
+*   of the upper layer software with an error code indicating the device should
+*   be reset.
+* - Packet count threshold reached.  For scatter-gather operations, indicates
+*   the threshold for the number of packets not serviced by software has been
+*   reached. The driver behaves as follows:
+*       - Get the value of the packet counter, which tells us how many packets
+*         are ready to be serviced
+*       - For each packet
+*           - For each descriptor, remove it from the scatter-gather list
+*           - Check for the last descriptor in the frame, and if set
+*               - Bump frame statistics
+*               - Call the scatter-gather receive callback function
+*               - Decrement the packet counter by one
+*       Note that there are no receive errors reported in the status word of
+*       the buffer descriptor.  If receive errors occur, the MAC drops the
+*       packet, and we only find out about the errors through various error
+*       count registers.
+* - Packet wait bound reached.  For scatter-gather, indicates the time to wait
+*   for the next packet has expired.  The driver follows the same logic as when
+*   the packet count threshold interrupt is received.
+* - Scatter-gather end acknowledge.  Hardware has reached the end of the
+*   descriptor list.  The driver follows the same logic as when the packet count
+*   threshold interrupt is received. In addition, the driver restarts the DMA
+*   scatter-gather channel in case there are newly inserted descriptors.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Although the function returns void, there are asynchronous errors that can
+* be generated (by calling the ErrorHandler) from this function.  These are:
+* - XST_DMA_SG_LIST_EMPTY indicates we tried to get a buffer descriptor from the
+*   DMA channel, but there was not one ready for software.
+* - XST_DMA_ERROR indicates a DMA bus error or timeout occurred. This is a fatal
+*   error that requires reset.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+HandleDmaRecvIntr(XEmac * InstancePtr)
+{
+       u32 IntrStatus;
+
+       /*
+        * Read the interrupt status
+        */
+       IntrStatus = XDmaChannel_GetIntrStatus(&InstancePtr->RecvChannel);
+
+       /*
+        * For packet threshold or wait bound interrupts, process desciptors. Also
+        * process descriptors on a SG end acknowledgement, which means the end of
+        * the descriptor list has been reached by the hardware. For receive, this
+        * is potentially trouble since it means the descriptor list is full,
+        * unless software can process enough packets quickly enough so the
+        * hardware has room to put new packets.
+        */
+       if (IntrStatus & (XDC_IXR_PKT_THRESHOLD_MASK |
+                         XDC_IXR_PKT_WAIT_BOUND_MASK | XDC_IXR_SG_END_MASK)) {
+               XStatus Result = XST_SUCCESS;
+               u32 NumFrames;
+               u32 NumProcessed;
+               u32 NumBuffers;
+               u32 NumBytes;
+               u32 IsLast;
+               XBufDescriptor *FirstBdPtr;
+               XBufDescriptor *BdPtr;
+
+               /*
+                * Get the number of unserviced packets
+                */
+               NumFrames = XDmaChannel_GetPktCount(&InstancePtr->RecvChannel);
+
+               for (NumProcessed = 0; NumProcessed < NumFrames; NumProcessed++) {
+                       IsLast = FALSE;
+                       FirstBdPtr = NULL;
+                       NumBuffers = 0;
+                       NumBytes = 0;
+
+                       /*
+                        * For each packet, get the descriptor from the list. On the
+                        * last one in the frame, make the callback to the upper layer.
+                        */
+                       while (!IsLast) {
+                               Result =
+                                   XDmaChannel_GetDescriptor(&InstancePtr->
+                                                             RecvChannel,
+                                                             &BdPtr);
+                               if (Result != XST_SUCCESS) {
+                                       /*
+                                        * An error getting a buffer descriptor from the list.
+                                        * This should not happen, but if it does, report it to
+                                        * the error callback and break out of the loops to service
+                                        * other interrupts.
+                                        */
+                                       InstancePtr->ErrorHandler(InstancePtr->
+                                                                 ErrorRef,
+                                                                 Result);
+                                       break;
+                               }
+
+                               /*
+                                * Keep a pointer to the first descriptor in the list, as it
+                                * will be passed to the upper layers in a bit. By the fact
+                                * that we received this packet means no errors occurred, so
+                                * no need to check the device status word for errors.
+                                */
+                               if (FirstBdPtr == NULL) {
+                                       FirstBdPtr = BdPtr;
+                               }
+
+                               NumBytes += XBufDescriptor_GetLength(BdPtr);
+
+                               /*
+                                * Check to see if this is the last descriptor in the frame,
+                                * and if so, set the IsLast flag to get out of the loop.
+                                */
+                               if (XBufDescriptor_IsLastStatus(BdPtr)) {
+                                       IsLast = TRUE;
+                               }
+
+                               /*
+                                * Bump the number of buffers in this packet
+                                */
+                               NumBuffers++;
+
+                       }       /* end while loop */
+
+                       /*
+                        * Check for error that occurred inside the while loop, and break
+                        * out of the for loop if there was one so other interrupts can
+                        * be serviced.
+                        */
+                       if (Result != XST_SUCCESS) {
+                               break;
+                       }
+
+                       InstancePtr->Stats.RecvFrames++;
+                       InstancePtr->Stats.RecvBytes += NumBytes;
+
+                       /*
+                        * Make the callback to the upper layers, passing it the first
+                        * descriptor in the packet and the number of descriptors in the
+                        * packet.
+                        */
+                       InstancePtr->SgRecvHandler(InstancePtr->SgRecvRef,
+                                                  FirstBdPtr, NumBuffers);
+
+                       /*
+                        * Decrement the packet count register to reflect the fact we
+                        * just processed a packet
+                        */
+                       XDmaChannel_DecrementPktCount(&InstancePtr->
+                                                     RecvChannel);
+
+               }               /* end for loop */
+
+               /*
+                * If the interrupt was an end-ack, check the descriptor list again to
+                * see if it is empty. If not, go ahead and restart the scatter-gather
+                * channel. This is to fix a possible race condition where, on receive,
+                * the driver attempted to start a scatter-gather channel that was
+                * already started, which resulted in no action from the XDmaChannel
+                * component. But, just after the XDmaChannel component saw that the
+                * hardware was already started, the hardware stopped because it
+                * reached the end of the list.  In that case, this interrupt is
+                * generated and we can restart the hardware here.
+                */
+               if (IntrStatus & XDC_IXR_SG_END_MASK) {
+                       /*
+                        * Ignore the return status since we know the list exists and we
+                        * don't care if the list is empty or the channel is already started.
+                        */
+                       (void) XDmaChannel_SgStart(&InstancePtr->RecvChannel);
+               }
+       }
+
+       /*
+        * All interrupts are handled (except the error below) so acknowledge
+        * (clear) the interrupts by writing the value read above back to the status
+        * register. The packet count interrupt must be acknowledged after the
+        * decrement, otherwise it will come right back. We clear the interrupts
+        * before we handle the error interrupt because the ErrorHandler should
+        * result in a reset, which clears the interrupt status register. So we
+        * don't want to toggle the interrupt back on by writing the interrupt
+        * status register with an old value after a reset.
+        */
+       XDmaChannel_SetIntrStatus(&InstancePtr->RecvChannel, IntrStatus);
+
+       /*
+        * Check for DMA errors and call the error callback function if an error
+        * occurred (DMA bus or timeout error), which should result in a reset of
+        * the device by the upper layer software.
+        */
+       if (IntrStatus & XDC_IXR_DMA_ERROR_MASK) {
+               InstancePtr->Stats.DmaErrors++;
+               InstancePtr->ErrorHandler(InstancePtr->ErrorRef, XST_DMA_ERROR);
+       }
+}
+
+/*****************************************************************************/
+/*
+*
+* Handle an interrupt from the DMA send channel. DMA interrupts are:
+*
+* - DMA error. DMA encountered a bus error or timeout. This is a fatal error
+*   that requires reset of the channel.  The driver calls the error handler
+*   of the upper layer software with an error code indicating the device should
+*   be reset.
+* - Packet count threshold reached.  For scatter-gather operations, indicates
+*   the threshold for the number of packets not serviced by software has been
+*   reached. The driver behaves as follows:
+*       - Get the value of the packet counter, which tells us how many packets
+*         are ready to be serviced
+*       - For each packet
+*           - For each descriptor, remove it from the scatter-gather list
+*           - Check for the last descriptor in the frame, and if set
+*               - Bump frame statistics
+*               - Call the scatter-gather receive callback function
+*               - Decrement the packet counter by one
+*       Note that there are no receive errors reported in the status word of
+*       the buffer descriptor.  If receive errors occur, the MAC drops the
+*       packet, and we only find out about the errors through various error
+*       count registers.
+* - Packet wait bound reached.  For scatter-gather, indicates the time to wait
+*   for the next packet has expired.  The driver follows the same logic as when
+*   the packet count threshold interrupt is received.
+* - Scatter-gather end acknowledge.  Hardware has reached the end of the
+*   descriptor list.  The driver follows the same logic as when the packet count
+*   threshold interrupt is received. In addition, the driver restarts the DMA
+*   scatter-gather channel in case there are newly inserted descriptors.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* Although the function returns void, there are asynchronous errors
+* that can be generated from this function.  These are:
+* - XST_DMA_SG_LIST_EMPTY indicates we tried to get a buffer descriptor from
+*   the DMA channel, but there was not one ready for software.
+* - XST_DMA_ERROR indicates a DMA bus error or timeout occurred. This is a
+*   fatal error that requires reset.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+HandleDmaSendIntr(XEmac * InstancePtr)
+{
+       u32 IntrStatus;
+
+       /*
+        * Read the interrupt status
+        */
+       IntrStatus = XDmaChannel_GetIntrStatus(&InstancePtr->SendChannel);
+
+       /*
+        * For packet threshold or wait bound interrupt, process descriptors. Also
+        * process descriptors on a SG end acknowledgement, which means the end of
+        * the descriptor list has been reached by the hardware. For transmit,
+        * this is a normal condition during times of light traffic.  In fact, the
+        * wait bound interrupt may be masked for transmit since the end-ack would
+        * always occur before the wait bound expires.
+        */
+       if (IntrStatus & (XDC_IXR_PKT_THRESHOLD_MASK |
+                         XDC_IXR_PKT_WAIT_BOUND_MASK | XDC_IXR_SG_END_MASK)) {
+               XStatus Result = XST_SUCCESS;
+               u32 NumFrames;
+               u32 NumProcessed;
+               u32 NumBuffers;
+               u32 NumBytes;
+               u32 IsLast;
+               XBufDescriptor *FirstBdPtr;
+               XBufDescriptor *BdPtr;
+
+               /*
+                * Get the number of unserviced packets
+                */
+               NumFrames = XDmaChannel_GetPktCount(&InstancePtr->SendChannel);
+
+               for (NumProcessed = 0; NumProcessed < NumFrames; NumProcessed++) {
+                       IsLast = FALSE;
+                       FirstBdPtr = NULL;
+                       NumBuffers = 0;
+                       NumBytes = 0;
+
+                       /*
+                        * For each frame, traverse the descriptor list and look for
+                        * errors. On the last one in the frame, make the callback.
+                        */
+                       while (!IsLast) {
+                               Result =
+                                   XDmaChannel_GetDescriptor(&InstancePtr->
+                                                             SendChannel,
+                                                             &BdPtr);
+                               if (Result != XST_SUCCESS) {
+                                       /*
+                                        * An error getting a buffer descriptor from the list.
+                                        * This should not happen, but if it does, report it to
+                                        * the error callback and break out of the loops to service
+                                        * other interrupts
+                                        */
+                                       InstancePtr->ErrorHandler(InstancePtr->
+                                                                 ErrorRef,
+                                                                 Result);
+                                       break;
+                               }
+
+                               /*
+                                * Keep a pointer to the first descriptor in the list and
+                                * check the device status for errors. The device status is
+                                * only available in the first descriptor of a packet.
+                                */
+                               if (FirstBdPtr == NULL) {
+                                       u32 XmitStatus;
+
+                                       FirstBdPtr = BdPtr;
+
+                                       XmitStatus =
+                                           XBufDescriptor_GetDeviceStatus
+                                           (BdPtr);
+                                       if (XmitStatus &
+                                           XEM_TSR_EXCESS_DEFERRAL_MASK) {
+                                               InstancePtr->Stats.
+                                                   XmitExcessDeferral++;
+                                       }
+
+                                       if (XmitStatus &
+                                           XEM_TSR_LATE_COLLISION_MASK) {
+                                               InstancePtr->Stats.
+                                                   XmitLateCollisionErrors++;
+                                       }
+                               }
+
+                               NumBytes += XBufDescriptor_GetLength(BdPtr);
+
+                               /*
+                                * Check to see if this is the last descriptor in the frame,
+                                * and if so, set the IsLast flag to get out of the loop. The
+                                * transmit channel must check the last bit in the control
+                                * word, not the status word (the DMA engine does not update
+                                * the last bit in the status word for the transmit direction).
+                                */
+                               if (XBufDescriptor_IsLastControl(BdPtr)) {
+                                       IsLast = TRUE;
+                               }
+
+                               /*
+                                * Bump the number of buffers in this packet
+                                */
+                               NumBuffers++;
+
+                       }       /* end while loop */
+
+                       /*
+                        * Check for error that occurred inside the while loop, and break
+                        * out of the for loop if there was one so other interrupts can
+                        * be serviced.
+                        */
+                       if (Result != XST_SUCCESS) {
+                               break;
+                       }
+
+                       InstancePtr->Stats.XmitFrames++;
+                       InstancePtr->Stats.XmitBytes += NumBytes;
+
+                       /*
+                        * Make the callback to the upper layers, passing it the first
+                        * descriptor in the packet and the number of descriptors in the
+                        * packet.
+                        */
+                       InstancePtr->SgSendHandler(InstancePtr->SgSendRef,
+                                                  FirstBdPtr, NumBuffers);
+
+                       /*
+                        * Decrement the packet count register to reflect the fact we
+                        * just processed a packet
+                        */
+                       XDmaChannel_DecrementPktCount(&InstancePtr->
+                                                     SendChannel);
+
+               }               /* end for loop */
+
+               /*
+                * If the interrupt was an end-ack, check the descriptor list again to
+                * see if it is empty. If not, go ahead and restart the scatter-gather
+                * channel. This is to fix a possible race condition where, on transmit,
+                * the driver attempted to start a scatter-gather channel that was
+                * already started, which resulted in no action from the XDmaChannel
+                * component. But, just after the XDmaChannel component saw that the
+                * hardware was already started, the hardware stopped because it
+                * reached the end of the list.  In that case, this interrupt is
+                * generated and we can restart the hardware here.
+                */
+               if (IntrStatus & XDC_IXR_SG_END_MASK) {
+                       /*
+                        * Ignore the return status since we know the list exists and we
+                        * don't care if the list is empty or the channel is already started.
+                        */
+                       (void) XDmaChannel_SgStart(&InstancePtr->SendChannel);
+               }
+       }
+
+       /*
+        * All interrupts are handled (except the error below) so acknowledge
+        * (clear) the interrupts by writing the value read above back to the status
+        * register. The packet count interrupt must be acknowledged after the
+        * decrement, otherwise it will come right back. We clear the interrupts
+        * before we handle the error interrupt because the ErrorHandler should
+        * result in a reset, which clears the interrupt status register. So we
+        * don't want to toggle the interrupt back on by writing the interrupt
+        * status register with an old value after a reset.
+        */
+       XDmaChannel_SetIntrStatus(&InstancePtr->SendChannel, IntrStatus);
+
+       /*
+        * Check for DMA errors and call the error callback function if an error
+        * occurred (DMA bus or timeout error), which should result in a reset of
+        * the device by the upper layer software.
+        */
+       if (IntrStatus & XDC_IXR_DMA_ERROR_MASK) {
+               InstancePtr->Stats.DmaErrors++;
+               InstancePtr->ErrorHandler(InstancePtr->ErrorRef, XST_DMA_ERROR);
+       }
+}
+
+/*****************************************************************************/
+/*
+*
+* Handle an interrupt from the Ethernet MAC when configured with scatter-gather
+* DMA. The only interrupts handled in this case are errors.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* None.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+static void
+HandleEmacDmaIntr(XEmac * InstancePtr)
+{
+       u32 IntrStatus;
+
+       /*
+        * When configured with DMA, the EMAC generates interrupts only when errors
+        * occur. We clear the interrupts immediately so that any latched status
+        * interrupt bits will reflect the true status of the device, and so any
+        * pulsed interrupts (non-status) generated during the Isr will not be lost.
+        */
+       IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
+       XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress, IntrStatus);
+
+       /*
+        * Check the MAC for errors
+        */
+       XEmac_CheckEmacError(InstancePtr, IntrStatus);
+}
diff --git a/board/xilinx/xilinx_enet/xemac_l.h b/board/xilinx/xilinx_enet/xemac_l.h
new file mode 100644 (file)
index 0000000..a463937
--- /dev/null
@@ -0,0 +1,462 @@
+/******************************************************************************
+*
+*     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 xemac_l.h
+*
+* This header file contains identifiers and low-level driver functions (or
+* macros) that can be used to access the device.  High-level driver functions
+* are defined in xemac.h.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver  Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00b rpm  04/26/02 First release
+* 1.00b rmm  09/23/02 Added XEmac_mPhyReset macro
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* </pre>
+*
+******************************************************************************/
+
+#ifndef XEMAC_L_H              /* prevent circular inclusions */
+#define XEMAC_L_H              /* by using protection macros */
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+/* Offset of the MAC registers from the IPIF base address */
+#define XEM_REG_OFFSET    0x1100UL
+
+/*
+ * Register offsets for the Ethernet MAC. Each register is 32 bits.
+ */
+#define XEM_EMIR_OFFSET          (XEM_REG_OFFSET + 0x0)        /* EMAC Module ID */
+#define XEM_ECR_OFFSET   (XEM_REG_OFFSET + 0x4)        /* MAC Control */
+#define XEM_IFGP_OFFSET          (XEM_REG_OFFSET + 0x8)        /* Interframe Gap */
+#define XEM_SAH_OFFSET   (XEM_REG_OFFSET + 0xC)        /* Station addr, high */
+#define XEM_SAL_OFFSET   (XEM_REG_OFFSET + 0x10)       /* Station addr, low */
+#define XEM_MGTCR_OFFSET  (XEM_REG_OFFSET + 0x14)      /* MII mgmt control */
+#define XEM_MGTDR_OFFSET  (XEM_REG_OFFSET + 0x18)      /* MII mgmt data */
+#define XEM_RPLR_OFFSET          (XEM_REG_OFFSET + 0x1C)       /* Rx packet length */
+#define XEM_TPLR_OFFSET          (XEM_REG_OFFSET + 0x20)       /* Tx packet length */
+#define XEM_TSR_OFFSET   (XEM_REG_OFFSET + 0x24)       /* Tx status */
+#define XEM_RMFC_OFFSET          (XEM_REG_OFFSET + 0x28)       /* Rx missed frames */
+#define XEM_RCC_OFFSET   (XEM_REG_OFFSET + 0x2C)       /* Rx collisions */
+#define XEM_RFCSEC_OFFSET (XEM_REG_OFFSET + 0x30)      /* Rx FCS errors */
+#define XEM_RAEC_OFFSET          (XEM_REG_OFFSET + 0x34)       /* Rx alignment errors */
+#define XEM_TEDC_OFFSET          (XEM_REG_OFFSET + 0x38)       /* Transmit excess
+                                                        * deferral cnt */
+
+/*
+ * Register offsets for the IPIF components
+ */
+#define XEM_ISR_OFFSET          0x20UL /* Interrupt status */
+
+#define XEM_DMA_OFFSET          0x2300UL
+#define XEM_DMA_SEND_OFFSET     (XEM_DMA_OFFSET + 0x0) /* DMA send channel */
+#define XEM_DMA_RECV_OFFSET     (XEM_DMA_OFFSET + 0x40)        /* DMA recv channel */
+
+#define XEM_PFIFO_OFFSET        0x2000UL
+#define XEM_PFIFO_TXREG_OFFSET  (XEM_PFIFO_OFFSET + 0x0)       /* Tx registers */
+#define XEM_PFIFO_RXREG_OFFSET  (XEM_PFIFO_OFFSET + 0x10)      /* Rx registers */
+#define XEM_PFIFO_TXDATA_OFFSET         (XEM_PFIFO_OFFSET + 0x100)     /* Tx keyhole */
+#define XEM_PFIFO_RXDATA_OFFSET         (XEM_PFIFO_OFFSET + 0x200)     /* Rx keyhole */
+
+/*
+ * EMAC Module Identification Register (EMIR)
+ */
+#define XEM_EMIR_VERSION_MASK   0xFFFF0000UL   /* Device version */
+#define XEM_EMIR_TYPE_MASK      0x0000FF00UL   /* Device type */
+
+/*
+ * EMAC Control Register (ECR)
+ */
+#define XEM_ECR_FULL_DUPLEX_MASK        0x80000000UL   /* Full duplex mode */
+#define XEM_ECR_XMIT_RESET_MASK                 0x40000000UL   /* Reset transmitter */
+#define XEM_ECR_XMIT_ENABLE_MASK        0x20000000UL   /* Enable transmitter */
+#define XEM_ECR_RECV_RESET_MASK                 0x10000000UL   /* Reset receiver */
+#define XEM_ECR_RECV_ENABLE_MASK        0x08000000UL   /* Enable receiver */
+#define XEM_ECR_PHY_ENABLE_MASK                 0x04000000UL   /* Enable PHY */
+#define XEM_ECR_XMIT_PAD_ENABLE_MASK    0x02000000UL   /* Enable xmit pad insert */
+#define XEM_ECR_XMIT_FCS_ENABLE_MASK    0x01000000UL   /* Enable xmit FCS insert */
+#define XEM_ECR_XMIT_ADDR_INSERT_MASK   0x00800000UL   /* Enable xmit source addr
+                                                        * insertion */
+#define XEM_ECR_XMIT_ERROR_INSERT_MASK  0x00400000UL   /* Insert xmit error */
+#define XEM_ECR_XMIT_ADDR_OVWRT_MASK    0x00200000UL   /* Enable xmit source addr
+                                                        * overwrite */
+#define XEM_ECR_LOOPBACK_MASK           0x00100000UL   /* Enable internal
+                                                        * loopback */
+#define XEM_ECR_RECV_STRIP_ENABLE_MASK  0x00080000UL   /* Enable recv pad/fcs strip */
+#define XEM_ECR_UNICAST_ENABLE_MASK     0x00020000UL   /* Enable unicast addr */
+#define XEM_ECR_MULTI_ENABLE_MASK       0x00010000UL   /* Enable multicast addr */
+#define XEM_ECR_BROAD_ENABLE_MASK       0x00008000UL   /* Enable broadcast addr */
+#define XEM_ECR_PROMISC_ENABLE_MASK     0x00004000UL   /* Enable promiscuous mode */
+#define XEM_ECR_RECV_ALL_MASK           0x00002000UL   /* Receive all frames */
+#define XEM_ECR_RESERVED2_MASK          0x00001000UL   /* Reserved */
+#define XEM_ECR_MULTI_HASH_ENABLE_MASK  0x00000800UL   /* Enable multicast hash */
+#define XEM_ECR_PAUSE_FRAME_MASK        0x00000400UL   /* Interpret pause frames */
+#define XEM_ECR_CLEAR_HASH_MASK                 0x00000200UL   /* Clear hash table */
+#define XEM_ECR_ADD_HASH_ADDR_MASK      0x00000100UL   /* Add hash table address */
+
+/*
+ * Interframe Gap Register (IFGR)
+ */
+#define XEM_IFGP_PART1_MASK        0xF8000000UL        /* Interframe Gap Part1 */
+#define XEM_IFGP_PART1_SHIFT       27
+#define XEM_IFGP_PART2_MASK        0x07C00000UL        /* Interframe Gap Part2 */
+#define XEM_IFGP_PART2_SHIFT       22
+
+/*
+ * Station Address High Register (SAH)
+ */
+#define XEM_SAH_ADDR_MASK          0x0000FFFFUL        /* Station address high bytes */
+
+/*
+ * Station Address Low Register (SAL)
+ */
+#define XEM_SAL_ADDR_MASK          0xFFFFFFFFUL        /* Station address low bytes */
+
+/*
+ * MII Management Control Register (MGTCR)
+ */
+#define XEM_MGTCR_START_MASK       0x80000000UL        /* Start/Busy */
+#define XEM_MGTCR_RW_NOT_MASK      0x40000000UL        /* Read/Write Not (direction) */
+#define XEM_MGTCR_PHY_ADDR_MASK            0x3E000000UL        /* PHY address */
+#define XEM_MGTCR_PHY_ADDR_SHIFT    25 /* PHY address shift */
+#define XEM_MGTCR_REG_ADDR_MASK            0x01F00000UL        /* Register address */
+#define XEM_MGTCR_REG_ADDR_SHIFT    20 /* Register addr shift */
+#define XEM_MGTCR_MII_ENABLE_MASK   0x00080000UL       /* Enable MII from EMAC */
+#define XEM_MGTCR_RD_ERROR_MASK            0x00040000UL        /* MII mgmt read error */
+
+/*
+ * MII Management Data Register (MGTDR)
+ */
+#define XEM_MGTDR_DATA_MASK        0x0000FFFFUL        /* MII data */
+
+/*
+ * Receive Packet Length Register (RPLR)
+ */
+#define XEM_RPLR_LENGTH_MASK       0x0000FFFFUL        /* Receive packet length */
+
+/*
+ * Transmit Packet Length Register (TPLR)
+ */
+#define XEM_TPLR_LENGTH_MASK       0x0000FFFFUL        /* Transmit packet length */
+
+/*
+ * Transmit Status Register (TSR)
+ */
+#define XEM_TSR_EXCESS_DEFERRAL_MASK 0x80000000UL      /* Transmit excess deferral */
+#define XEM_TSR_FIFO_UNDERRUN_MASK   0x40000000UL      /* Packet FIFO underrun */
+#define XEM_TSR_ATTEMPTS_MASK       0x3E000000UL       /* Transmission attempts */
+#define XEM_TSR_LATE_COLLISION_MASK  0x01000000UL      /* Transmit late collision */
+
+/*
+ * Receive Missed Frame Count (RMFC)
+ */
+#define XEM_RMFC_DATA_MASK         0x0000FFFFUL
+
+/*
+ * Receive Collision Count (RCC)
+ */
+#define XEM_RCC_DATA_MASK          0x0000FFFFUL
+
+/*
+ * Receive FCS Error Count (RFCSEC)
+ */
+#define XEM_RFCSEC_DATA_MASK       0x0000FFFFUL
+
+/*
+ * Receive Alignment Error Count (RALN)
+ */
+#define XEM_RAEC_DATA_MASK         0x0000FFFFUL
+
+/*
+ * Transmit Excess Deferral Count (TEDC)
+ */
+#define XEM_TEDC_DATA_MASK         0x0000FFFFUL
+
+/*
+ * EMAC Interrupt Registers (Status and Enable) masks. These registers are
+ * part of the IPIF IP Interrupt registers
+ */
+#define XEM_EIR_XMIT_DONE_MASK        0x00000001UL     /* Xmit complete */
+#define XEM_EIR_RECV_DONE_MASK        0x00000002UL     /* Recv complete */
+#define XEM_EIR_XMIT_ERROR_MASK               0x00000004UL     /* Xmit error */
+#define XEM_EIR_RECV_ERROR_MASK               0x00000008UL     /* Recv error */
+#define XEM_EIR_XMIT_SFIFO_EMPTY_MASK  0x00000010UL    /* Xmit status fifo empty */
+#define XEM_EIR_RECV_LFIFO_EMPTY_MASK  0x00000020UL    /* Recv length fifo empty */
+#define XEM_EIR_XMIT_LFIFO_FULL_MASK   0x00000040UL    /* Xmit length fifo full */
+#define XEM_EIR_RECV_LFIFO_OVER_MASK   0x00000080UL    /* Recv length fifo
+                                                        * overrun */
+#define XEM_EIR_RECV_LFIFO_UNDER_MASK  0x00000100UL    /* Recv length fifo
+                                                        * underrun */
+#define XEM_EIR_XMIT_SFIFO_OVER_MASK   0x00000200UL    /* Xmit status fifo
+                                                        * overrun */
+#define XEM_EIR_XMIT_SFIFO_UNDER_MASK  0x00000400UL    /* Transmit status fifo
+                                                        * underrun */
+#define XEM_EIR_XMIT_LFIFO_OVER_MASK   0x00000800UL    /* Transmit length fifo
+                                                        * overrun */
+#define XEM_EIR_XMIT_LFIFO_UNDER_MASK  0x00001000UL    /* Transmit length fifo
+                                                        * underrun */
+#define XEM_EIR_XMIT_PAUSE_MASK               0x00002000UL     /* Transmit pause pkt
+                                                        * received */
+#define XEM_EIR_RECV_DFIFO_OVER_MASK   0x00004000UL    /* Receive data fifo
+                                                        * overrun */
+#define XEM_EIR_RECV_MISSED_FRAME_MASK 0x00008000UL    /* Receive missed frame
+                                                        * error */
+#define XEM_EIR_RECV_COLLISION_MASK    0x00010000UL    /* Receive collision
+                                                        * error */
+#define XEM_EIR_RECV_FCS_ERROR_MASK    0x00020000UL    /* Receive FCS error */
+#define XEM_EIR_RECV_LEN_ERROR_MASK    0x00040000UL    /* Receive length field
+                                                        * error */
+#define XEM_EIR_RECV_SHORT_ERROR_MASK  0x00080000UL    /* Receive short frame
+                                                        * error */
+#define XEM_EIR_RECV_LONG_ERROR_MASK   0x00100000UL    /* Receive long frame
+                                                        * error */
+#define XEM_EIR_RECV_ALIGN_ERROR_MASK  0x00200000UL    /* Receive alignment
+                                                        * error */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************
+*
+* Low-level driver macros and functions. The list below provides signatures
+* to help the user use the macros.
+*
+* u32 XEmac_mReadReg(u32 BaseAddress, int RegOffset)
+* void XEmac_mWriteReg(u32 BaseAddress, int RegOffset, u32 Mask)
+*
+* void XEmac_mSetControlReg(u32 BaseAddress, u32 Mask)
+* void XEmac_mSetMacAddress(u32 BaseAddress, u8 *AddressPtr)
+*
+* void XEmac_mEnable(u32 BaseAddress)
+* void XEmac_mDisable(u32 BaseAddress)
+*
+* u32 XEmac_mIsTxDone(u32 BaseAddress)
+* u32 XEmac_mIsRxEmpty(u32 BaseAddress)
+*
+* void XEmac_SendFrame(u32 BaseAddress, u8 *FramePtr, int Size)
+* int XEmac_RecvFrame(u32 BaseAddress, u8 *FramePtr)
+*
+*****************************************************************************/
+
+/****************************************************************************/
+/**
+*
+* Read the given register.
+*
+* @param    BaseAddress is the base address of the device
+* @param    RegOffset is the register offset to be read
+*
+* @return   The 32-bit value of the register
+*
+* @note            None.
+*
+*****************************************************************************/
+#define XEmac_mReadReg(BaseAddress, RegOffset) \
+                   XIo_In32((BaseAddress) + (RegOffset))
+
+/****************************************************************************/
+/**
+*
+* Write the given register.
+*
+* @param    BaseAddress is the base address of the device
+* @param    RegOffset is the register offset to be written
+* @param    Data is the 32-bit value to write to the register
+*
+* @return   None.
+*
+* @note            None.
+*
+*****************************************************************************/
+#define XEmac_mWriteReg(BaseAddress, RegOffset, Data) \
+                   XIo_Out32((BaseAddress) + (RegOffset), (Data))
+
+/****************************************************************************/
+/**
+*
+* Set the contents of the control register. Use the XEM_ECR_* constants
+* defined above to create the bit-mask to be written to the register.
+*
+* @param    BaseAddress is the base address of the device
+* @param    Mask is the 16-bit value to write to the control register
+*
+* @return   None.
+*
+* @note            None.
+*
+*****************************************************************************/
+#define XEmac_mSetControlReg(BaseAddress, Mask) \
+                   XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, (Mask))
+
+/****************************************************************************/
+/**
+*
+* Set the station address of the EMAC device.
+*
+* @param    BaseAddress is the base address of the device
+* @param    AddressPtr is a pointer to a 6-byte MAC address
+*
+* @return   None.
+*
+* @note            None.
+*
+*****************************************************************************/
+#define XEmac_mSetMacAddress(BaseAddress, AddressPtr)              \
+{                                                                  \
+    u32 MacAddr;                                               \
+                                                                   \
+    MacAddr = ((AddressPtr)[0] << 8) | (AddressPtr)[1];                    \
+    XIo_Out32((BaseAddress) + XEM_SAH_OFFSET, MacAddr);                    \
+                                                                   \
+    MacAddr = ((AddressPtr)[2] << 24) | ((AddressPtr)[3] << 16) |   \
+             ((AddressPtr)[4] << 8) | (AddressPtr)[5];             \
+                                                                   \
+    XIo_Out32((BaseAddress) + XEM_SAL_OFFSET, MacAddr);                    \
+}
+
+/****************************************************************************/
+/**
+*
+* Enable the transmitter and receiver. Preserve the contents of the control
+* register.
+*
+* @param    BaseAddress is the base address of the device
+*
+* @return   None.
+*
+* @note            None.
+*
+*****************************************************************************/
+#define XEmac_mEnable(BaseAddress) \
+{ \
+    u32 Control; \
+    Control = XIo_In32((BaseAddress) + XEM_ECR_OFFSET); \
+    Control &= ~(XEM_ECR_XMIT_RESET_MASK | XEM_ECR_RECV_RESET_MASK); \
+    Control |= (XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK); \
+    XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
+}
+
+/****************************************************************************/
+/**
+*
+* Disable the transmitter and receiver. Preserve the contents of the control
+* register.
+*
+* @param    BaseAddress is the base address of the device
+*
+* @return   None.
+*
+* @note            None.
+*
+*****************************************************************************/
+#define XEmac_mDisable(BaseAddress) \
+               XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, \
+                   XIo_In32((BaseAddress) + XEM_ECR_OFFSET) & \
+                   ~(XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK))
+
+/****************************************************************************/
+/**
+*
+* Check to see if the transmission is complete.
+*
+* @param    BaseAddress is the base address of the device
+*
+* @return   TRUE if it is done, or FALSE if it is not.
+*
+* @note            None.
+*
+*****************************************************************************/
+#define XEmac_mIsTxDone(BaseAddress) \
+            (XIo_In32((BaseAddress) + XEM_ISR_OFFSET) & XEM_EIR_XMIT_DONE_MASK)
+
+/****************************************************************************/
+/**
+*
+* Check to see if the receive FIFO is empty.
+*
+* @param    BaseAddress is the base address of the device
+*
+* @return   TRUE if it is empty, or FALSE if it is not.
+*
+* @note            None.
+*
+*****************************************************************************/
+#define XEmac_mIsRxEmpty(BaseAddress) \
+         (!(XIo_In32((BaseAddress) + XEM_ISR_OFFSET) & XEM_EIR_RECV_DONE_MASK))
+
+/****************************************************************************/
+/**
+*
+* Reset MII compliant PHY
+*
+* @param    BaseAddress is the base address of the device
+*
+* @return   None.
+*
+* @note            None.
+*
+*****************************************************************************/
+#define XEmac_mPhyReset(BaseAddress) \
+{ \
+    u32 Control;                                   \
+    Control = XIo_In32((BaseAddress) + XEM_ECR_OFFSET); \
+    Control &= ~XEM_ECR_PHY_ENABLE_MASK;               \
+    XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
+    Control |= XEM_ECR_PHY_ENABLE_MASK;                        \
+    XIo_Out32((BaseAddress) + XEM_ECR_OFFSET, Control); \
+}
+
+/************************** Function Prototypes ******************************/
+
+void XEmac_SendFrame(u32 BaseAddress, u8 * FramePtr, int Size);
+int XEmac_RecvFrame(u32 BaseAddress, u8 * FramePtr);
+
+#endif                         /* end of protection macro */
diff --git a/board/xilinx/xilinx_enet/xemac_options.c b/board/xilinx/xilinx_enet/xemac_options.c
new file mode 100644 (file)
index 0000000..1f225f8
--- /dev/null
@@ -0,0 +1,318 @@
+/******************************************************************************
+*
+*     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 xemac_options.c
+*
+* Functions in this file handle configuration of the XEmac driver.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xemac_i.h"
+#include "xio.h"
+
+/************************** Constant Definitions *****************************/
+
+#define XEM_MAX_IFG         32 /* Maximum Interframe gap value */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+/************************** Variable Definitions *****************************/
+
+/*
+ * A table of options and masks. This table maps the user-visible options with
+ * the control register masks. It is used in Set/GetOptions as an alternative
+ * to a series of if/else pairs. Note that the polled options does not have a
+ * corresponding entry in the control register, so it does not exist in the
+ * table.
+ */
+typedef struct {
+       u32 Option;
+       u32 Mask;
+} OptionMap;
+
+static OptionMap OptionsTable[] = {
+       {XEM_UNICAST_OPTION, XEM_ECR_UNICAST_ENABLE_MASK},
+       {XEM_BROADCAST_OPTION, XEM_ECR_BROAD_ENABLE_MASK},
+       {XEM_PROMISC_OPTION, XEM_ECR_PROMISC_ENABLE_MASK},
+       {XEM_FDUPLEX_OPTION, XEM_ECR_FULL_DUPLEX_MASK},
+       {XEM_LOOPBACK_OPTION, XEM_ECR_LOOPBACK_MASK},
+       {XEM_MULTICAST_OPTION, XEM_ECR_MULTI_ENABLE_MASK},
+       {XEM_FLOW_CONTROL_OPTION, XEM_ECR_PAUSE_FRAME_MASK},
+       {XEM_INSERT_PAD_OPTION, XEM_ECR_XMIT_PAD_ENABLE_MASK},
+       {XEM_INSERT_FCS_OPTION, XEM_ECR_XMIT_FCS_ENABLE_MASK},
+       {XEM_INSERT_ADDR_OPTION, XEM_ECR_XMIT_ADDR_INSERT_MASK},
+       {XEM_OVWRT_ADDR_OPTION, XEM_ECR_XMIT_ADDR_OVWRT_MASK},
+       {XEM_STRIP_PAD_FCS_OPTION, XEM_ECR_RECV_STRIP_ENABLE_MASK}
+};
+
+#define XEM_NUM_OPTIONS     (sizeof(OptionsTable) / sizeof(OptionMap))
+
+/*****************************************************************************/
+/**
+*
+* Set Ethernet driver/device options.  The device must be stopped before
+* calling this function.  The options are contained within a bit-mask with each
+* bit representing an option (i.e., you can OR the options together). A one (1)
+* in the bit-mask turns an option on, and a zero (0) turns the option off.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param OptionsFlag is a bit-mask representing the Ethernet options to turn on
+*        or off. See xemac.h for a description of the available options.
+*
+* @return
+*
+* - XST_SUCCESS if the options were set successfully
+* - XST_DEVICE_IS_STARTED if the device has not yet been stopped
+*
+* @note
+*
+* This function is not thread-safe and makes use of internal resources that are
+* shared between the Start, Stop, and SetOptions functions, so if one task
+* might be setting device options while another is trying to start the device,
+* protection of this shared data (typically using a semaphore) is required.
+*
+******************************************************************************/
+XStatus
+XEmac_SetOptions(XEmac * InstancePtr, u32 OptionsFlag)
+{
+       u32 ControlReg;
+       int Index;
+
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+               return XST_DEVICE_IS_STARTED;
+       }
+
+       ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
+
+       /*
+        * Loop through the options table, turning the option on or off
+        * depending on whether the bit is set in the incoming options flag.
+        */
+       for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) {
+               if (OptionsFlag & OptionsTable[Index].Option) {
+                       ControlReg |= OptionsTable[Index].Mask; /* turn it on */
+               } else {
+                       ControlReg &= ~OptionsTable[Index].Mask;        /* turn it off */
+               }
+       }
+
+       /*
+        * TODO: need to validate addr-overwrite only if addr-insert?
+        */
+
+       /*
+        * Now write the control register. Leave it to the upper layers
+        * to restart the device.
+        */
+       XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg);
+
+       /*
+        * Check the polled option
+        */
+       if (OptionsFlag & XEM_POLLED_OPTION) {
+               InstancePtr->IsPolled = TRUE;
+       } else {
+               InstancePtr->IsPolled = FALSE;
+       }
+
+       return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Get Ethernet driver/device options. The 32-bit value returned is a bit-mask
+* representing the options.  A one (1) in the bit-mask means the option is on,
+* and a zero (0) means the option is off.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+*
+* @return
+*
+* The 32-bit value of the Ethernet options. The value is a bit-mask
+* representing all options that are currently enabled. See xemac.h for a
+* description of the available options.
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+u32
+XEmac_GetOptions(XEmac * InstancePtr)
+{
+       u32 OptionsFlag = 0;
+       u32 ControlReg;
+       int Index;
+
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       /*
+        * Get the control register to determine which options are currently set.
+        */
+       ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);
+
+       /*
+        * Loop through the options table to determine which options are set
+        */
+       for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) {
+               if (ControlReg & OptionsTable[Index].Mask) {
+                       OptionsFlag |= OptionsTable[Index].Option;
+               }
+       }
+
+       if (InstancePtr->IsPolled) {
+               OptionsFlag |= XEM_POLLED_OPTION;
+       }
+
+       return OptionsFlag;
+}
+
+/*****************************************************************************/
+/**
+*
+* Set the Interframe Gap (IFG), which is the time the MAC delays between
+* transmitting frames.  There are two parts required.  The total interframe gap
+* is the total of the two parts.  The values provided for the Part1 and Part2
+* parameters are multiplied by 4 to obtain the bit-time interval. The first
+* part should be the first 2/3 of the total interframe gap. The MAC will reset
+* the interframe gap timer if carrier sense becomes true during the period
+* defined by interframe gap Part1. Part1 may be shorter than 2/3 the total and
+* can be as small as zero. The second part should be the last 1/3 of the total
+* interframe gap, but can be as large as the total interframe gap. The MAC
+* will not reset the interframe gap timer if carrier sense becomes true during
+* the period defined by interframe gap Part2.
+*
+* The device must be stopped before setting the interframe gap.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param Part1 is the interframe gap part 1 (which will be multiplied by 4 to
+*        get the bit-time interval).
+* @param Part2 is the interframe gap part 2 (which will be multiplied by 4 to
+*        get the bit-time interval).
+*
+* @return
+*
+* - XST_SUCCESS if the interframe gap was set successfully
+* - XST_DEVICE_IS_STARTED if the device has not been stopped
+*
+* @note
+*
+* None.
+*
+******************************************************************************/
+XStatus
+XEmac_SetInterframeGap(XEmac * InstancePtr, u8 Part1, u8 Part2)
+{
+       u32 Ifg;
+
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(Part1 < XEM_MAX_IFG);
+       XASSERT_NONVOID(Part2 < XEM_MAX_IFG);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       /*
+        * Be sure device has been stopped
+        */
+       if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) {
+               return XST_DEVICE_IS_STARTED;
+       }
+
+       Ifg = Part1 << XEM_IFGP_PART1_SHIFT;
+       Ifg |= (Part2 << XEM_IFGP_PART2_SHIFT);
+       XIo_Out32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET, Ifg);
+
+       return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Get the interframe gap, parts 1 and 2. See the description of interframe gap
+* above in XEmac_SetInterframeGap().
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param Part1Ptr is a pointer to an 8-bit buffer into which the interframe gap
+*        part 1 value will be copied.
+* @param Part2Ptr is a pointer to an 8-bit buffer into which the interframe gap
+*        part 2 value will be copied.
+*
+* @return
+*
+* None. The values of the interframe gap parts are copied into the
+* output parameters.
+*
+******************************************************************************/
+void
+XEmac_GetInterframeGap(XEmac * InstancePtr, u8 * Part1Ptr, u8 * Part2Ptr)
+{
+       u32 Ifg;
+
+       XASSERT_VOID(InstancePtr != NULL);
+       XASSERT_VOID(Part1Ptr != NULL);
+       XASSERT_VOID(Part2Ptr != NULL);
+       XASSERT_VOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       Ifg = XIo_In32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET);
+       *Part1Ptr = (Ifg & XEM_IFGP_PART1_MASK) >> XEM_IFGP_PART1_SHIFT;
+       *Part2Ptr = (Ifg & XEM_IFGP_PART2_MASK) >> XEM_IFGP_PART2_SHIFT;
+}
diff --git a/board/xilinx/xilinx_enet/xemac_polled.c b/board/xilinx/xilinx_enet/xemac_polled.c
new file mode 100644 (file)
index 0000000..23768bc
--- /dev/null
@@ -0,0 +1,482 @@
+/******************************************************************************
+*
+*     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 xemac_polled.c
+*
+* Contains functions used when the driver is in polled mode. Use the
+* XEmac_SetOptions() function to put the driver into polled mode.
+*
+* <pre>
+* MODIFICATION HISTORY:
+*
+* Ver   Who  Date     Changes
+* ----- ---- -------- -----------------------------------------------
+* 1.00a rpm  07/31/01 First release
+* 1.00b rpm  02/20/02 Repartitioned files and functions
+* 1.00c rpm  12/05/02 New version includes support for simple DMA
+* </pre>
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xbasic_types.h"
+#include "xemac_i.h"
+#include "xio.h"
+#include "xipif_v1_23_b.h"     /* Uses v1.23b of the IPIF */
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Variable Definitions *****************************/
+
+/************************** Function Prototypes ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Send an Ethernet frame in polled mode.  The device/driver must be in polled
+* mode before calling this function. The driver writes the frame directly to
+* the MAC's packet FIFO, then enters a loop checking the device status for
+* completion or error. Statistics are updated if an error occurs. The buffer
+* to be sent must be word-aligned.
+*
+* It is assumed that the upper layer software supplies a correctly formatted
+* Ethernet frame, including the destination and source addresses, the
+* type/length field, and the data field.  It is also assumed that upper layer
+* software does not append FCS at the end of the frame.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param BufPtr is a pointer to a word-aligned buffer containing the Ethernet
+*        frame to be sent.
+* @param ByteCount is the size of the Ethernet frame.
+*
+* @return
+*
+* - XST_SUCCESS if the frame was sent successfully
+* - XST_DEVICE_IS_STOPPED if the device has not yet been started
+* - XST_NOT_POLLED if the device is not in polled mode
+* - XST_FIFO_NO_ROOM if there is no room in the EMAC's length FIFO for this frame
+* - XST_FIFO_ERROR if the FIFO was overrun or underrun. This error is critical
+*   and requires the caller to reset the device.
+* - XST_EMAC_COLLISION if the send failed due to excess deferral or late
+*   collision
+*
+* @note
+*
+* There is the possibility that this function will not return if the hardware
+* is broken (i.e., it never sets the status bit indicating that transmission is
+* done). If this is of concern to the user, the user should provide protection
+* from this problem - perhaps by using a different timer thread to monitor the
+* PollSend thread. On a 10Mbps MAC, it takes about 1.21 msecs to transmit a
+* maximum size Ethernet frame (1518 bytes). On a 100Mbps MAC, it takes about
+* 121 usecs to transmit a maximum size Ethernet frame.
+*
+* @internal
+*
+* The EMAC uses FIFOs behind its length and status registers. For this reason,
+* it is important to keep the length, status, and data FIFOs in sync when
+* reading or writing to them.
+*
+******************************************************************************/
+XStatus
+XEmac_PollSend(XEmac * InstancePtr, u8 * BufPtr, u32 ByteCount)
+{
+       u32 IntrStatus;
+       u32 XmitStatus;
+       XStatus Result;
+
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(BufPtr != NULL);
+       XASSERT_NONVOID(ByteCount > XEM_HDR_SIZE);      /* send at least 1 byte */
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       /*
+        * Be sure the device is configured for polled mode and it is started
+        */
+       if (!InstancePtr->IsPolled) {
+               return XST_NOT_POLLED;
+       }
+
+       if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
+               return XST_DEVICE_IS_STOPPED;
+       }
+
+       /*
+        * Check for overruns and underruns for the transmit status and length
+        * FIFOs and make sure the send packet FIFO is not deadlocked. Any of these
+        * conditions is bad enough that we do not want to continue. The upper layer
+        * software should reset the device to resolve the error.
+        */
+       IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
+
+       /*
+        * Overrun errors
+        */
+       if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
+                         XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
+               InstancePtr->Stats.XmitOverrunErrors++;
+               InstancePtr->Stats.FifoErrors++;
+               return XST_FIFO_ERROR;
+       }
+
+       /*
+        * Underrun errors
+        */
+       if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
+                         XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
+               InstancePtr->Stats.XmitUnderrunErrors++;
+               InstancePtr->Stats.FifoErrors++;
+               return XST_FIFO_ERROR;
+       }
+
+       if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->SendFifo)) {
+               InstancePtr->Stats.FifoErrors++;
+               return XST_FIFO_ERROR;
+       }
+
+       /*
+        * Before writing to the data FIFO, make sure the length FIFO is not
+        * full.  The data FIFO might not be full yet even though the length FIFO
+        * is. This avoids an overrun condition on the length FIFO and keeps the
+        * FIFOs in sync.
+        */
+       if (IntrStatus & XEM_EIR_XMIT_LFIFO_FULL_MASK) {
+               /*
+                * Clear the latched LFIFO_FULL bit so next time around the most
+                * current status is represented
+                */
+               XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
+                                     XEM_EIR_XMIT_LFIFO_FULL_MASK);
+               return XST_FIFO_NO_ROOM;
+       }
+
+       /*
+        * This is a non-blocking write. The packet FIFO returns an error if there
+        * is not enough room in the FIFO for this frame.
+        */
+       Result =
+           XPacketFifoV100b_Write(&InstancePtr->SendFifo, BufPtr, ByteCount);
+       if (Result != XST_SUCCESS) {
+               return Result;
+       }
+
+       /*
+        * Loop on the MAC's status to wait for any pause to complete.
+        */
+       IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
+
+       while ((IntrStatus & XEM_EIR_XMIT_PAUSE_MASK) != 0) {
+               IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
+               /*
+                  * Clear the pause status from the transmit status register
+                */
+               XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
+                                     IntrStatus & XEM_EIR_XMIT_PAUSE_MASK);
+       }
+
+       /*
+        * Set the MAC's transmit packet length register to tell it to transmit
+        */
+       XIo_Out32(InstancePtr->BaseAddress + XEM_TPLR_OFFSET, ByteCount);
+
+       /*
+        * Loop on the MAC's status to wait for the transmit to complete. The
+        * transmit status is in the FIFO when the XMIT_DONE bit is set.
+        */
+       do {
+               IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
+       }
+       while ((IntrStatus & XEM_EIR_XMIT_DONE_MASK) == 0);
+
+       XmitStatus = XIo_In32(InstancePtr->BaseAddress + XEM_TSR_OFFSET);
+
+       InstancePtr->Stats.XmitFrames++;
+       InstancePtr->Stats.XmitBytes += ByteCount;
+
+       /*
+        * Check for various errors, bump statistics, and return an error status.
+        */
+
+       /*
+        * Overrun errors
+        */
+       if (IntrStatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
+                         XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
+               InstancePtr->Stats.XmitOverrunErrors++;
+               InstancePtr->Stats.FifoErrors++;
+               return XST_FIFO_ERROR;
+       }
+
+       /*
+        * Underrun errors
+        */
+       if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
+                         XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
+               InstancePtr->Stats.XmitUnderrunErrors++;
+               InstancePtr->Stats.FifoErrors++;
+               return XST_FIFO_ERROR;
+       }
+
+       /*
+        * Clear the interrupt status register of transmit statuses
+        */
+       XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
+                             IntrStatus & XEM_EIR_XMIT_ALL_MASK);
+
+       /*
+        * Collision errors are stored in the transmit status register
+        * instead of the interrupt status register
+        */
+       if (XmitStatus & XEM_TSR_EXCESS_DEFERRAL_MASK) {
+               InstancePtr->Stats.XmitExcessDeferral++;
+               return XST_EMAC_COLLISION_ERROR;
+       }
+
+       if (XmitStatus & XEM_TSR_LATE_COLLISION_MASK) {
+               InstancePtr->Stats.XmitLateCollisionErrors++;
+               return XST_EMAC_COLLISION_ERROR;
+       }
+
+       return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* Receive an Ethernet frame in polled mode. The device/driver must be in polled
+* mode before calling this function. The driver receives the frame directly
+* from the MAC's packet FIFO. This is a non-blocking receive, in that if there
+* is no frame ready to be received at the device, the function returns with an
+* error. The MAC's error status is not checked, so statistics are not updated
+* for polled receive. The buffer into which the frame will be received must be
+* word-aligned.
+*
+* @param InstancePtr is a pointer to the XEmac instance to be worked on.
+* @param BufPtr is a pointer to a word-aligned buffer into which the received
+*        Ethernet frame will be copied.
+* @param ByteCountPtr is both an input and an output parameter. It is a pointer
+*        to a 32-bit word that contains the size of the buffer on entry into the
+*        function and the size the received frame on return from the function.
+*
+* @return
+*
+* - XST_SUCCESS if the frame was sent successfully
+* - XST_DEVICE_IS_STOPPED if the device has not yet been started
+* - XST_NOT_POLLED if the device is not in polled mode
+* - XST_NO_DATA if there is no frame to be received from the FIFO
+* - XST_BUFFER_TOO_SMALL if the buffer to receive the frame is too small for
+*   the frame waiting in the FIFO.
+*
+* @note
+*
+* Input buffer must be big enough to hold the largest Ethernet frame. Buffer
+* must also be 32-bit aligned.
+*
+* @internal
+*
+* The EMAC uses FIFOs behind its length and status registers. For this reason,
+* it is important to keep the length, status, and data FIFOs in sync when
+* reading or writing to them.
+*
+******************************************************************************/
+XStatus
+XEmac_PollRecv(XEmac * InstancePtr, u8 * BufPtr, u32 * ByteCountPtr)
+{
+       XStatus Result;
+       u32 PktLength;
+       u32 IntrStatus;
+
+       XASSERT_NONVOID(InstancePtr != NULL);
+       XASSERT_NONVOID(BufPtr != NULL);
+       XASSERT_NONVOID(ByteCountPtr != NULL);
+       XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
+
+       /*
+        * Be sure the device is configured for polled mode and it is started
+        */
+       if (!InstancePtr->IsPolled) {
+               return XST_NOT_POLLED;
+       }
+
+       if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) {
+               return XST_DEVICE_IS_STOPPED;
+       }
+
+       /*
+        * Make sure the buffer is big enough to hold the maximum frame size.
+        * We need to do this because as soon as we read the MAC's packet length
+        * register, which is actually a FIFO, we remove that length from the
+        * FIFO.  We do not want to read the length FIFO without also reading the
+        * data FIFO since this would get the FIFOs out of sync.  So we have to
+        * make this restriction.
+        */
+       if (*ByteCountPtr < XEM_MAX_FRAME_SIZE) {
+               return XST_BUFFER_TOO_SMALL;
+       }
+
+       /*
+        * First check for packet FIFO deadlock and return an error if it has
+        * occurred. A reset by the caller is necessary to correct this problem.
+        */
+       if (XPF_V100B_IS_DEADLOCKED(&InstancePtr->RecvFifo)) {
+               InstancePtr->Stats.FifoErrors++;
+               return XST_FIFO_ERROR;
+       }
+
+       /*
+        * Get the interrupt status to know what happened (whether an error occurred
+        * and/or whether frames have been received successfully). When clearing the
+        * intr status register, clear only statuses that pertain to receive.
+        */
+       IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);
+       XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,
+                             IntrStatus & XEM_EIR_RECV_ALL_MASK);
+
+       /*
+        * Check receive errors and bump statistics so the caller will have a clue
+        * as to why data may not have been received. We continue on if an error
+        * occurred since there still may be frames that were received successfully.
+        */
+       if (IntrStatus & (XEM_EIR_RECV_LFIFO_OVER_MASK |
+                         XEM_EIR_RECV_DFIFO_OVER_MASK)) {
+               InstancePtr->Stats.RecvOverrunErrors++;
+               InstancePtr->Stats.FifoErrors++;
+       }
+
+       if (IntrStatus & XEM_EIR_RECV_LFIFO_UNDER_MASK) {
+               InstancePtr->Stats.RecvUnderrunErrors++;
+               InstancePtr->Stats.FifoErrors++;
+       }
+
+       /*
+        * General receive errors
+        */
+       if (IntrStatus & XEM_EIR_RECV_ERROR_MASK) {
+               if (IntrStatus & XEM_EIR_RECV_MISSED_FRAME_MASK) {
+                       InstancePtr->Stats.RecvMissedFrameErrors =
+                           XIo_In32(InstancePtr->BaseAddress +
+                                    XEM_RMFC_OFFSET);
+               }
+
+               if (IntrStatus & XEM_EIR_RECV_COLLISION_MASK) {
+                       InstancePtr->Stats.RecvCollisionErrors =
+                           XIo_In32(InstancePtr->BaseAddress + XEM_RCC_OFFSET);
+               }
+
+               if (IntrStatus & XEM_EIR_RECV_FCS_ERROR_MASK) {
+                       InstancePtr->Stats.RecvFcsErrors =
+                           XIo_In32(InstancePtr->BaseAddress +
+                                    XEM_RFCSEC_OFFSET);
+               }
+
+               if (IntrStatus & XEM_EIR_RECV_LEN_ERROR_MASK) {
+                       InstancePtr->Stats.RecvLengthFieldErrors++;
+               }
+
+               if (IntrStatus & XEM_EIR_RECV_SHORT_ERROR_MASK) {
+                       InstancePtr->Stats.RecvShortErrors++;
+               }
+
+               if (IntrStatus & XEM_EIR_RECV_LONG_ERROR_MASK) {
+                       InstancePtr->Stats.RecvLongErrors++;
+               }
+
+               if (IntrStatus & XEM_EIR_RECV_ALIGN_ERROR_MASK) {
+                       InstancePtr->Stats.RecvAlignmentErrors =
+                           XIo_In32(InstancePtr->BaseAddress +
+                                    XEM_RAEC_OFFSET);
+               }
+       }
+
+       /*
+        * Before reading from the length FIFO, make sure the length FIFO is not
+        * empty. We could cause an underrun error if we try to read from an
+        * empty FIFO.
+        */
+       if ((IntrStatus & XEM_EIR_RECV_DONE_MASK) == 0) {
+               return XST_NO_DATA;
+       }
+
+       /*
+        * Determine, from the MAC, the length of the next packet available
+        * in the data FIFO (there should be a non-zero length here)
+        */
+       PktLength = XIo_In32(InstancePtr->BaseAddress + XEM_RPLR_OFFSET);
+       if (PktLength == 0) {
+               return XST_NO_DATA;
+       }
+
+       /*
+        * Write the RECV_DONE bit in the status register to clear it. This bit
+        * indicates the RPLR is non-empty, and we know it's set at this point.
+        * We clear it so that subsequent entry into this routine will reflect the
+        * current status. This is done because the non-empty bit is latched in the
+        * IPIF, which means it may indicate a non-empty condition even though
+        * there is something in the FIFO.
+        */
+       XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress, XEM_EIR_RECV_DONE_MASK);
+
+       /*
+        * We assume that the MAC never has a length bigger than the largest
+        * Ethernet frame, so no need to make another check here.
+        */
+
+       /*
+        * This is a non-blocking read. The FIFO returns an error if there is
+        * not at least the requested amount of data in the FIFO.
+        */
+       Result =
+           XPacketFifoV100b_Read(&InstancePtr->RecvFifo, BufPtr, PktLength);
+       if (Result != XST_SUCCESS) {
+               return Result;
+       }
+
+       InstancePtr->Stats.RecvFrames++;
+       InstancePtr->Stats.RecvBytes += PktLength;
+
+       *ByteCountPtr = PktLength;
+
+       return XST_SUCCESS;
+}
index 6549be61ff1e7163d3b8b96613d8c06060dc5581..cd192b05b19a80d9c4b54ce3032cb37607c3aef0 100644 (file)
@@ -59,13 +59,13 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        print_num ("immr_base",     bd->bi_immr_base    );
 #endif
        print_num ("bootflags",     bd->bi_bootflags    );
-#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP)
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300)
        print_str ("procfreq",      strmhz(buf, bd->bi_procfreq));
        print_str ("plb_busfreq",           strmhz(buf, bd->bi_plb_busfreq));
-#if defined(CONFIG_405GP) || defined(CONFIG_405EP)
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || defined(CONFIG_XILINX_ML300)
        print_str ("pci_busfreq",           strmhz(buf, bd->bi_pci_busfreq));
 #endif
-#else  /* ! CONFIG_405GP, CONFIG_405CR, CONFIG_405EP */
+#else  /* ! CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300 */
 #if defined(CONFIG_8260) || defined(CONFIG_MPC8560)
        print_str ("vco",           strmhz(buf, bd->bi_vco));
        print_str ("sccfreq",       strmhz(buf, bd->bi_sccfreq));
@@ -76,7 +76,7 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        print_str ("cpmfreq",       strmhz(buf, bd->bi_cpmfreq));
 #endif
        print_str ("busfreq",       strmhz(buf, bd->bi_busfreq));
-#endif /* CONFIG_405GP, CONFIG_405CR, CONFIG_405EP */
+#endif /* CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_ML300 */
        printf ("ethaddr     =");
        for (i=0; i<6; ++i) {
                printf ("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]);
index 7897184fc2f3bb3126f60df915b7d2586bcc69bf..00e8c18e1d83c254d64a0598053a4a90ea0a8fe5 100644 (file)
@@ -237,7 +237,7 @@ void udelay (unsigned long usec)
        }
 
        tmp = get_timer (0);            /* get current timestamp */
-       if( (tmo + tmp) < tmp )         /* if setting this fordward will roll time stamp */
+       if( (tmo + tmp + 1) < tmp )     /* if setting this fordward will roll time stamp */
                reset_timer_masked ();  /* reset "advancing" timestamp to 0, set lastdec value */
        else
                tmo += tmp;             /* else, set advancing stamp wake up time */
index 4d6efebebe64ec02f859fcf2e0f1a75c84b58327..616793380f9cf3786103e24631176e73c904f4eb 100644 (file)
@@ -229,7 +229,7 @@ void udelay (unsigned long usec)
        }
 
        tmp = get_timer (0);            /* get current timestamp */
-       if( (tmo + tmp) < tmp )         /* if setting this fordward will roll time stamp */
+       if( (tmo + tmp + 1) < tmp )     /* if setting this fordward will roll time stamp */
                reset_timer_masked ();  /* reset "advancing" timestamp to 0, set lastdec value */
        else
                tmo += tmp;             /* else, set advancing stamp wake up time */
index 450946bbc3b69bcbf1f6852e8fe2d29b66e928fa..443680582d538b93cf6f0f6f776fdf866cd862d3 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/ptrace.h>
 #include <common.h>
 #include <command.h>
+#include <watchdog.h>
 #ifdef CONFIG_STATUS_LED
 #include <status_led.h>
 #endif
@@ -54,6 +55,7 @@ void reset_timer (void)
 
 ulong get_timer (ulong base)
 {
+       WATCHDOG_RESET ();
        return (timestamp - base);
 }
 
index 61b26ab14958b83fc139a5c5fa722eeb68b124d4..34257a2fe9040ae38c952a5a90354b4fc5a3be7e 100644 (file)
@@ -23,6 +23,7 @@
 
 
 #include <common.h>
+#include <watchdog.h>
 #include <nios-io.h>
 
 
@@ -62,7 +63,7 @@ void serial_putc( char c )
        if (c == '\n')
                serial_putc('\r');
        while( (uart->status & NIOS_UART_TRDY) == 0 )
-               ;
+               WATCHDOG_RESET ();
        uart->txdata = (unsigned char)c;
 }
 
@@ -81,6 +82,6 @@ int serial_tstc( void )
 int serial_getc( void )
 {
        while( serial_tstc() == 0 )
-               ;
+               WATCHDOG_RESET ();
        return( uart->rxdata & 0x00ff );
 }
index dfd2a04d51cf66bffef01093daa4b2029e120d57..e776050bccc7eab8ea01fd26d2bab778a607152a 100644 (file)
@@ -299,6 +299,10 @@ ulong get_OPB_freq (void)
        return sys_info.freqOPB;
 }
 
+#elif defined(CONFIG_XILINX_ML300)
+extern void get_sys_info (sys_info_t * sysInfo);
+extern ulong get_PCI_freq (void);
+
 #elif defined(CONFIG_405)
 
 void get_sys_info (sys_info_t * sysInfo) {
diff --git a/doc/README.ml300 b/doc/README.ml300
new file mode 100644 (file)
index 0000000..c9ef6e6
--- /dev/null
@@ -0,0 +1,128 @@
+Xilinx ML300 platform
+=====================
+
+0. Introduction
+---------------
+
+The Xilinx ML300 board is based on the Virtex-II Pro FPGA with
+integrated IBM PowerPC 405 core. The board is normally booted from
+System ACE CF. U-Boot is then run out of main memory.
+
+An FPGA is a configurable and thus very flexible device. To
+accommodate for this flexibility this port of U-Boot includes the
+required means to regenerate the drivers and configuration files if
+you decide to change the hardware design. The required steps are
+described below.
+
+
+1. Requirements
+---------------
+
+To compile and run U-Boot on the Xilinx ML300 platform you need the
+following items.
+
+- A Xilinx ML300 platform (see http://www.xilinx.com/ml300)
+- EDK and ISE development tools (shipping with ML300)
+- Parallel4 cable (shipping with ML300)
+- The EDK reference design for ML300. You can get this as design #6 from
+  http://www.xilinx.com/ise/embedded/edk_examples.htm
+- A BOOTP/TFTP server
+
+
+2. Quick Start
+--------------
+
+To compile and run U-Boot on ML300 follow the steps below. Make sure
+to consult the documentation for U-Boot, EDK, and the EDK reference
+design for ML300 if you have any questions.
+
+1. Implement the EDK reference design for ML300. You can use any of
+   the project files, for example from a xygwin shell:
+   $ xps -nw system_linux.xmp
+   XPS% run init_bram
+2. Configure and compile U-Boot. Change into the root directory of
+   U-Boot and run:
+   $ export CROSS_COMPILE=powerpc-eabi-
+   $ make ml300_config
+   $ make
+3. Set up the ML300, connect the Parallel4 and the serial cable. Start
+   a terminal on your host computer and set the communication
+   parameters to 9600,8N1,no handshake.
+4. Set up the BOOTP/TFTP server on your host machine. U-Boot is
+   preconfigured to use a fixed HW MAC address of 00:0A:35:00:22:01.
+5. Download the bitstream to the ML300.
+6. Use XMD to download and run U-Boot on the ML300:
+   $ xmd
+   XMD% ppcconnect
+   XMD% dow u-boot
+   XMD% run
+
+You can now make an ACE file out of bitstream and U-Boot:
+   $ xmd genace.tcl -jprog -board ml300 -hw  \
+     implementation/download.bit -elf u-boot -ace top.ace
+
+Put the ACE file onto the MicroDrive, for example into xilinx/myace,
+and reboot ML300.
+
+
+3. Generating a Custom BSP for U-Boot
+-------------------------------------
+
+If you decide to change the EDK reference design for ML300 or if you
+build a new design from scratch either with the Base System Builder in
+XPS or all by hand you most likely will change the base addresses for
+the Uart and the Ethernet peripheral. If you do so you will have two
+options:
+
+1. Edit boards/xilinx/ml300/xparameters.h to reflect the changes you
+   made to your hardware.
+2. Use the MLD technology provided by Xilinx Platform Studio to make
+   the changes automatically. To do so go to the root directory of the
+   EDK reference design for ML300. Copy the Linux project file and the
+   Linux software configuration file:
+   $ cp system_linux.xmp system_uboot.xmp
+   $ cp system_linux.mss system_uboot.mss
+
+   Edit system_uboot.xmp and and have it point to system_uboot.mss for
+   the software configuration.
+
+   Then, copy the sw_services directory in
+   boards/xilinx/ml300/sw_services to the root directory of the EDK
+   reference design for ML300.
+   $ cp -R <uboot dir>/boards/xilinx/ml300/sw_services <edk dir>
+
+   Modify system_uboot.mss. Look for the Linux library definition
+   and change it to generate a BSP for U-Boot. An example, might look
+   like this:
+
+   BEGIN LIBRARY
+    PARAMETER LIBRARY_NAME = uboot
+    PARAMETER LIBRARY_VER = 1.00.a
+    PARAMETER CONNECTED_PERIPHS = (opb_uart16550_0,opb_ethernet_0)
+    PARAMETER TARGET_DIR = <uboot dir>
+   END
+
+   Now, you are ready to generate the Xilinx ML300 BSP for U-Boot:
+   $ xps -nw system_uboot.xmp
+   XPS% run libs
+
+   If all goes well the new configuration has been copied into the
+   right places within the U-Boot source tree. Recompile U-Boot and
+   run it on the ML300.
+
+
+4. ToDo
+-------
+
+- Add support for all other peripherals on ML300.
+- Read the MAC address out of the IIC EEPROM.
+- Store the bootargs in the IIC EEPROM.
+
+
+5. References
+-------------
+
+ML300:                 http://www.xilinx.com/ml300
+EDK:                   http://www.xilinx.com/edk
+ISE:                   http://www.xilinx.com/ise
+Reference Design:      http://www.xilinx.com/ise/embedded/edk_examples.htm
index 95179aeb65a96979c5f3065862823fe45ee7b501..d31b38f1b479487507380605fa8470c03e034ccb 100644 (file)
@@ -46,7 +46,9 @@
 
 #include <common.h>
 #include <asm/processor.h>
+#include <linux/byteorder/swab.h>
 #ifdef CFG_FLASH_CFI_DRIVER
+
 /*
  * This file implements a Common Flash Interface (CFI) driver for U-Boot.
  * The width of the port and the width of the chips are determined at initialization.
@@ -164,31 +166,24 @@ typedef unsigned long flash_sect_t;
 
 static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c);
 static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf);
-static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
-                            uint offset, uchar cmd);
+static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
 static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect);
-static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset,
-                         uchar cmd);
-static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset,
-                       uchar cmd);
-static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset,
-                        uchar cmd);
+static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
+static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd);
 static int flash_detect_cfi (flash_info_t * info);
 static ulong flash_get_size (ulong base, int banknum);
-static int flash_write_cfiword (flash_info_t * info, ulong dest,
-                               cfiword_t cword);
+static int flash_write_cfiword (flash_info_t * info, ulong dest, cfiword_t cword);
 static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
                                    ulong tout, char *prompt);
 #ifdef CFG_FLASH_USE_BUFFER_WRITE
-static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
-                                 int len);
+static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, int len);
 #endif
 
 /*-----------------------------------------------------------------------
  * create an address based on the offset and the port width
  */
-inline uchar *flash_make_addr (flash_info_t * info, flash_sect_t sect,
-                              uint offset)
+inline uchar *flash_make_addr (flash_info_t * info, flash_sect_t sect, uint offset)
 {
        return ((uchar *) (info->start[sect] + (offset * info->portwidth)));
 }
@@ -230,7 +225,6 @@ static void flash_printqry (flash_info_t * info, flash_sect_t sect)
                debug ("\n");
        }
 }
-
 #endif
 
 
@@ -286,7 +280,6 @@ ushort flash_read_ushort (flash_info_t * info, flash_sect_t sect, uint offset)
  */
 ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
 {
-
        uchar *addr;
        ulong retval;
 
@@ -304,8 +297,7 @@ ulong flash_read_long (flash_info_t * info, flash_sect_t sect, uint offset)
 #endif
 #if defined(__LITTLE_ENDIAN)
        retval = (addr[0] << 16) | (addr[(info->portwidth)] << 24) |
-               (addr[(2 * info->portwidth)]) | (addr[(3 * info->portwidth)]
-                                                << 8);
+               (addr[(2 * info->portwidth)]) | (addr[(3 * info->portwidth)] << 8);
 #else
        retval = (addr[(2 * info->portwidth) - 1] << 24) |
                (addr[(info->portwidth) - 1] << 16) |
@@ -327,7 +319,8 @@ unsigned long flash_init (void)
                flash_info[i].flash_id = FLASH_UNKNOWN;
                size += flash_info[i].size = flash_get_size (bank_base[i], i);
                if (flash_info[i].flash_id == FLASH_UNKNOWN) {
-                       printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n", i, flash_info[i].size, flash_info[i].size << 20);
+                       printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
+                               i, flash_info[i].size, flash_info[i].size << 20);
                }
        }
 
@@ -377,21 +370,16 @@ int flash_erase (flash_info_t * info, int s_first, int s_last)
                        switch (info->vendor) {
                        case CFI_CMDSET_INTEL_STANDARD:
                        case CFI_CMDSET_INTEL_EXTENDED:
-                               flash_write_cmd (info, sect, 0,
-                                                FLASH_CMD_CLEAR_STATUS);
-                               flash_write_cmd (info, sect, 0,
-                                                FLASH_CMD_BLOCK_ERASE);
-                               flash_write_cmd (info, sect, 0,
-                                                FLASH_CMD_ERASE_CONFIRM);
+                               flash_write_cmd (info, sect, 0, FLASH_CMD_CLEAR_STATUS);
+                               flash_write_cmd (info, sect, 0, FLASH_CMD_BLOCK_ERASE);
+                               flash_write_cmd (info, sect, 0, FLASH_CMD_ERASE_CONFIRM);
                                break;
                        case CFI_CMDSET_AMD_STANDARD:
                        case CFI_CMDSET_AMD_EXTENDED:
                                flash_unlock_seq (info, sect);
-                               flash_write_cmd (info, sect, 0x555,
-                                                AMD_CMD_ERASE_START);
+                               flash_write_cmd (info, sect, 0x555, AMD_CMD_ERASE_START);
                                flash_unlock_seq (info, sect);
-                               flash_write_cmd (info, sect, 0,
-                                                AMD_CMD_ERASE_SECTOR);
+                               flash_write_cmd (info, sect, 0, AMD_CMD_ERASE_SECTOR);
                                break;
                        default:
                                debug ("Unkown flash vendor %d\n",
@@ -425,7 +413,11 @@ void flash_print_info (flash_info_t * info)
                (info->portwidth << 3), (info->chipwidth << 3));
        printf ("  Size: %ld MB in %d Sectors\n",
                info->size >> 20, info->sector_count);
-       printf (" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n", info->erase_blk_tout, info->write_tout, info->buffer_write_tout, info->buffer_size);
+       printf (" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n",
+               info->erase_blk_tout,
+               info->write_tout,
+               info->buffer_write_tout,
+               info->buffer_size);
 
        printf ("  Sector Start Addresses:");
        for (i = 0; i < info->sector_count; ++i) {
@@ -605,7 +597,6 @@ int flash_real_protect (flash_info_t * info, long sector, int prot)
                        }
                }
        }
-
        return retcode;
 }
 
@@ -706,16 +697,12 @@ static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
                        retcode = ERR_INVAL;
                        printf ("Flash %s error at address %lx\n", prompt,
                                info->start[sector]);
-                       if (flash_isset
-                           (info, sector, 0,
-                            FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)) {
+                       if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)) {
                                printf ("Command Sequence Error.\n");
-                       } else if (flash_isset
-                                  (info, sector, 0, FLASH_STATUS_ECLBS)) {
+                       } else if (flash_isset (info, sector, 0, FLASH_STATUS_ECLBS)) {
                                printf ("Block Erase Error.\n");
                                retcode = ERR_NOT_ERASED;
-                       } else if (flash_isset
-                                  (info, sector, 0, FLASH_STATUS_PSLBS)) {
+                       } else if (flash_isset (info, sector, 0, FLASH_STATUS_PSLBS)) {
                                printf ("Locking Error\n");
                        }
                        if (flash_isset (info, sector, 0, FLASH_STATUS_DPS)) {
@@ -762,16 +749,28 @@ static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf)
        int i;
 
 #if defined(__LITTLE_ENDIAN)
-       ushort stmp;
+       ushort stmpw;
+       uint   stmpi;
 #endif
        uchar *cp = (uchar *) cmdbuf;
 
        for (i = 0; i < info->portwidth; i++)
                *cp++ = ((i + 1) % info->chipwidth) ? '\0' : cmd;
 #if defined(__LITTLE_ENDIAN)
-       if (info->portwidth == 2) {
-               stmp = *(ushort *) cmdbuf;
-               *(ushort *) cmdbuf = swab16 (stmp);
+       switch (info->portwidth) {
+       case FLASH_CFI_8BIT:
+               break;
+       case FLASH_CFI_16BIT:
+               stmpw = *(ushort *) cmdbuf;
+               *(ushort *) cmdbuf = __swab16 (stmpw);
+               break;
+       case FLASH_CFI_32BIT:
+               stmpi = *(uint *) cmdbuf;
+               *(uint *) cmdbuf = __swab32 (stmpi);
+               break;
+       default:
+               printf("WARNING: flash_make_cmd: unsuppported LittleEndian mode\n");
+               break;
        }
 #endif
 }
@@ -779,8 +778,7 @@ static void flash_make_cmd (flash_info_t * info, uchar cmd, void *cmdbuf)
 /*
  * Write a proper sized command to the correct address
  */
-static void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
-                            uint offset, uchar cmd)
+static void flash_write_cmd (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
 {
 
        volatile cfiptr_t addr;
@@ -831,8 +829,7 @@ static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
 
 /*-----------------------------------------------------------------------
  */
-static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset,
-                         uchar cmd)
+static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
 {
        cfiptr_t cptr;
        cfiword_t cword;
@@ -877,8 +874,7 @@ static int flash_isequal (flash_info_t * info, flash_sect_t sect, uint offset,
 
 /*-----------------------------------------------------------------------
  */
-static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset,
-                       uchar cmd)
+static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
 {
        cfiptr_t cptr;
        cfiword_t cword;
@@ -908,8 +904,7 @@ static int flash_isset (flash_info_t * info, flash_sect_t sect, uint offset,
 
 /*-----------------------------------------------------------------------
  */
-static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset,
-                        uchar cmd)
+static int flash_toggle (flash_info_t * info, flash_sect_t sect, uint offset, uchar cmd)
 {
        cfiptr_t cptr;
        cfiword_t cword;
@@ -953,27 +948,18 @@ static int flash_detect_cfi (flash_info_t * info)
                     info->chipwidth <= info->portwidth;
                     info->chipwidth <<= 1) {
                        flash_write_cmd (info, 0, 0, FLASH_CMD_RESET);
-                       flash_write_cmd (info, 0, FLASH_OFFSET_CFI,
-                                        FLASH_CMD_CFI);
-                       if (flash_isequal
-                           (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
-                           && flash_isequal (info, 0,
-                                             FLASH_OFFSET_CFI_RESP + 1, 'R')
-                           && flash_isequal (info, 0,
-                                             FLASH_OFFSET_CFI_RESP + 2,
-                                             'Y')) {
-                               info->interface =
-                                       flash_read_ushort (info, 0,
-                                                          FLASH_OFFSET_INTERFACE);
+                       flash_write_cmd (info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
+                       if (flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP, 'Q')
+                           && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R')
+                           && flash_isequal (info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y')) {
+                               info->interface = flash_read_ushort (info, 0, FLASH_OFFSET_INTERFACE);
                                debug ("device interface is %d\n",
                                       info->interface);
                                debug ("found port %d chip %d ",
                                       info->portwidth, info->chipwidth);
                                debug ("port %d bits chip %d bits\n",
-                                      info->
-                                      portwidth << CFI_FLASH_SHIFT_WIDTH,
-                                      info->
-                                      chipwidth << CFI_FLASH_SHIFT_WIDTH);
+                                      info->portwidth << CFI_FLASH_SHIFT_WIDTH,
+                                      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
                                return 1;
                        }
                }
@@ -1001,9 +987,7 @@ static ulong flash_get_size (ulong base, int banknum)
        info->start[0] = base;
 
        if (flash_detect_cfi (info)) {
-               info->vendor =
-                       flash_read_ushort (info, 0,
-                                          FLASH_OFFSET_PRIMARY_VENDOR);
+               info->vendor = flash_read_ushort (info, 0, FLASH_OFFSET_PRIMARY_VENDOR);
 #ifdef DEBUG
                flash_printqry (info, 0);
 #endif
@@ -1026,9 +1010,7 @@ static ulong flash_get_size (ulong base, int banknum)
                    && (info->chipwidth == FLASH_CFI_BY8)) {
                        size_ratio >>= 1;
                }
-               num_erase_regions =
-                       flash_read_uchar (info,
-                                         FLASH_OFFSET_NUM_ERASE_REGIONS);
+               num_erase_regions = flash_read_uchar (info, FLASH_OFFSET_NUM_ERASE_REGIONS);
                debug ("size_ratio %d port %d bits chip %d bits\n",
                       size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
                       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
@@ -1037,7 +1019,8 @@ static ulong flash_get_size (ulong base, int banknum)
                sector = base;
                for (i = 0; i < num_erase_regions; i++) {
                        if (i > NUM_ERASE_REGIONS) {
-                               printf ("%d erase regions found, only %d used\n", num_erase_regions, NUM_ERASE_REGIONS);
+                               printf ("%d erase regions found, only %d used\n",
+                                       num_erase_regions, NUM_ERASE_REGIONS);
                                break;
                        }
                        tmp = flash_read_long (info, 0,
@@ -1047,7 +1030,8 @@ static ulong flash_get_size (ulong base, int banknum)
                                (tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
                        tmp >>= 16;
                        erase_region_count = (tmp & 0xffff) + 1;
-                       printf ("erase_region_count = %d erase_region_size = %d\n", erase_region_count, erase_region_size);
+                       printf ("erase_region_count = %d erase_region_size = %d\n",
+                               erase_region_count, erase_region_size);
                        for (j = 0; j < erase_region_count; j++) {
                                info->start[sect_cnt] = sector;
                                sector += (erase_region_size * size_ratio);
@@ -1061,29 +1045,14 @@ static ulong flash_get_size (ulong base, int banknum)
 
                info->sector_count = sect_cnt;
                /* multiply the size by the number of chips */
-               info->size =
-                       (1 << flash_read_uchar (info, FLASH_OFFSET_SIZE)) *
-                       size_ratio;
-               info->buffer_size =
-                       (1 <<
-                        flash_read_ushort (info, 0,
-                                           FLASH_OFFSET_BUFFER_SIZE));
+               info->size = (1 << flash_read_uchar (info, FLASH_OFFSET_SIZE)) * size_ratio;
+               info->buffer_size = (1 << flash_read_ushort (info, 0, FLASH_OFFSET_BUFFER_SIZE));
                tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_ETOUT);
-               info->erase_blk_tout =
-                       (tmp *
-                        (1 <<
-                         flash_read_uchar (info, FLASH_OFFSET_EMAX_TOUT)));
+               info->erase_blk_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_EMAX_TOUT)));
                tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_WBTOUT);
-               info->buffer_write_tout =
-                       (tmp *
-                        (1 <<
-                         flash_read_uchar (info, FLASH_OFFSET_WBMAX_TOUT)));
+               info->buffer_write_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_WBMAX_TOUT)));
                tmp = 1 << flash_read_uchar (info, FLASH_OFFSET_WTOUT);
-               info->write_tout =
-                       (tmp *
-                        (1 <<
-                         flash_read_uchar (info,
-                                           FLASH_OFFSET_WMAX_TOUT))) / 1000;
+               info->write_tout = (tmp * (1 << flash_read_uchar (info, FLASH_OFFSET_WMAX_TOUT))) / 1000;
                info->flash_id = FLASH_MAN_CFI;
        }
 
diff --git a/include/configs/ml300.h b/include/configs/ml300.h
new file mode 100644 (file)
index 0000000..d93925e
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * ML300.h: ML300 specific config options
+ *
+ * http://www.xilinx.com/ml300
+ *
+ * Derived from : ML2.h
+ *
+ *     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 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 products are not intended for use in life support appliances,
+ *     devices, or systems. Use in such applications is expressly prohibited.
+ *
+ *
+ *     (c) Copyright 2002 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.
+  *
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* #define DEBUG */
+/* #define ET_DEBUG 1 */
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_405             1       /* This is a PPC405 CPU         */
+#define CONFIG_4xx             1       /* ...member of PPC4xx family   */
+#define CONFIG_XILINX_ML300    1       /* ...on a Xilinx ML300 board   */
+
+#define CFG_ENV_IS_NOWHERE     1       /* environment is in RAM */
+#define CFG_NO_FLASH           1       /* no flash */
+#define CFG_ENV_SIZE           0x2000
+#define CONFIG_BAUDRATE                9600
+#define CONFIG_BOOTDELAY       3       /* autoboot after 3 seconds     */
+
+#define CONFIG_BOOTCOMMAND     "bootp" /* autoboot command     */
+
+#define CONFIG_BOOTARGS                "console=ttyS0,9600 ip=off " \
+                               "root=/dev/xsysace/disc0/part3 rw"
+
+#define CONFIG_LOADS_ECHO      1       /* echo on for serial download  */
+#define CFG_LOADS_BAUD_CHANGE  1       /* allow baudrate change        */
+
+#define REMOVE_COMMANDS               (CFG_CMD_FLASH | CFG_CMD_LOADS | CFG_CMD_FAT | \
+                               CFG_CMD_IMLS )
+#define CONFIG_COMMANDS               ((CONFIG_CMD_DFL | CFG_CMD_NET) \
+                               & ~REMOVE_COMMANDS)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/* #define CONFIG_SYS_CLK_FREQ XPAR_CORE_CLOCK_FREQ_HZ */
+/* 300000000 */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP           /* undef to save memory         */
+#define CFG_PROMPT     "=> "   /* Monitor Command Prompt       */
+
+#define CFG_CBSIZE     256     /* Console I/O Buffer Size      */
+
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)  /* Print Buffer Size */
+#define CFG_MAXARGS    16      /* max number of command args   */
+#define CFG_BARGSIZE   CFG_CBSIZE      /* Boot Argument Buffer Size    */
+
+#define CFG_MEMTEST_START      0x0400000       /* memtest works on     */
+#define CFG_MEMTEST_END                0x0C00000       /* 4 ... 12 MB in DRAM  */
+
+#define CFG_DUART_CHAN         0
+#define CFG_NS16550_REG_SIZE -4
+#define CFG_NS16550 1
+#define CFG_INIT_CHAN1  1
+
+/* The following table includes the supported baudrates */
+#define CFG_BAUDRATE_TABLE  \
+    {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
+
+#define CFG_LOAD_ADDR          0x400000        /* default load address */
+#define CFG_EXTBDINFO          1       /* To use extended board_into (bd_t) */
+
+#define CFG_HZ         1000    /* decrementer freq: 1 ms ticks */
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define CFG_SDRAM_BASE         0x00000000
+#define CFG_MONITOR_BASE       0x04000000
+#define CFG_MONITOR_LEN                (192 * 1024)    /* Reserve 196 kB for Monitor   */
+#define CFG_MALLOC_LEN         (128 * 1024)    /* Reserve 128 kB for malloc()  */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CFG_BOOTMAPSZ          (8 << 20)       /* Initial Memory map for Linux */
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_DCACHE_SIZE                16384   /* For IBM 405 CPUs     */
+#define CFG_CACHELINE_SIZE     32      /* ...                  */
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+
+#define CFG_INIT_RAM_ADDR      0x800000  /* inside of SDRAM */
+#define CFG_INIT_RAM_END       0x2000    /* End of used area in RAM */
+#define CFG_GBL_DATA_SIZE      128       /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET    (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define CFG_INIT_SP_OFFSET     CFG_GBL_DATA_OFFSET
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD  0x01    /* Normal Power-On: Boot from FLASH     */
+#define BOOTFLAG_WARM  0x02    /* Software reboot                      */
+
+#endif                         /* __CONFIG_H */
index 2eb65e20811f752871ba0398b0e635b686d93853..7d232ca3c3c3a61ca9aee281a2be7da371c26f10 100644 (file)
@@ -73,7 +73,7 @@
 #define CFG_NS16550_REG_SIZE   (-4)
 #define CFG_NS16550_CLK        (48000000)              /* can be 12M/32Khz or 48Mhz */
 #define CFG_NS16550_COM1       0xfffb0000      /* uart1, bluetooth uart */
-                                               
+
 /*
  * select serial console configuration
  */
index 7180259d05445db5e08a77493194b7c4778226d0..ac6ba8c09147365b666a2684e5bbba851946367e 100644 (file)
 #  error "Configuration error: CONFIG_HW_WATCHDOG and CONFIG_WATCHDOG can't be used together."
 #endif
 
+#if defined(__ASSEMBLY__) && defined(__NIOS__)
+#  error "Configuration error: WATCHDOG_RESET inside assembler not supported for Nios platforms."
+#endif
+
 /*
  * Hardware watchdog
  */
index fb477e94e0cfc537837127fffba43fa524053d1f..d6c02d8a4ced882676116e7f88b0e801152b95eb 100644 (file)
@@ -139,13 +139,16 @@ void board_init (void)
        bd->bi_baudrate = CONFIG_BAUDRATE;
 
        for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+               WATCHDOG_RESET ();
                if ((*init_fnc_ptr) () != 0) {
                        hang ();
                }
        }
 
+       WATCHDOG_RESET ();
        bd->bi_flashsize = flash_init();
 
+       WATCHDOG_RESET ();
        mem_malloc_init();
        malloc_bin_reloc();
        env_relocate();
@@ -157,12 +160,14 @@ void board_init (void)
                if (s) s = (*e) ? e + 1 : e;
        }
 
+       WATCHDOG_RESET ();
        devices_init();
        jumptable_init();
        console_init_r();
        /*
         */
 
+       WATCHDOG_RESET ();
        interrupt_init ();
 
 #ifdef CONFIG_STATUS_LED
index 765b9c1989a74e0cc5f2743aaaa8c8abb911b6b1..25a233ea785a13d09e2e8d5a82b179d39572f8aa 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <common.h>
+#include <watchdog.h>
 
 
 extern void dly_clks( unsigned long ticks );
@@ -33,5 +34,6 @@ void udelay(unsigned long usec)
         * cpu clocks.
         */
        unsigned long cnt = (CONFIG_SYS_CLK_FREQ/1000000) * usec;
+       WATCHDOG_RESET ();      /* trigger watchdog if needed */
        dly_clks (cnt);
 }
index 04a1b8bfa5409d4e36463cbce92179b382e18981..a6305339aeabf913aed0b9562d44293aca8ad0fe 100644 (file)
@@ -515,6 +515,8 @@ void board_init_f (ulong bootflag)
 #endif
        bd->bi_iic_fast[0] = 0;
        bd->bi_iic_fast[1] = 0;
+#elif defined(CONFIG_XILINX_ML300)
+       bd->bi_pci_busfreq = get_PCI_freq ();
 #endif
 #endif
 
index 2e610eb7d560614b852a33d7db448da151ed70f7..728f8bf6a7fffab49369d8259212e7f9cc228072 100644 (file)
@@ -22,4 +22,4 @@
 # MA 02111-1307 USA
 #
 
-PLATFORM_CPPFLAGS += -m32 -DCONFIG_NIOS -ffixed-g7
+PLATFORM_CPPFLAGS += -m32 -DCONFIG_NIOS -D__NIOS__ -ffixed-g7