U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
July 2008
- 208 participants
- 579 discussions

29 Nov '08
3
2
Resubmit the driver for the ASIX AX88180 gigabit ethernet chip.
Signed-off-by: Louis Su louis(a)asix.com.tw
---
drivers/net/Makefile | 1 +
drivers/net/ax88180.c | 842
+++++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/ax88180.h | 415 ++++++++++++++++++++++++
3 files changed, 1258 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/ax88180.c
create mode 100644 drivers/net/ax88180.h
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 84be288..3a574e0 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libnet.a
COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o
+COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o
COBJS-$(CONFIG_BFIN_MAC) += bfin_mac.o
COBJS-$(CONFIG_DRIVER_CS8900) += cs8900.o
diff --git a/drivers/net/ax88180.c b/drivers/net/ax88180.c
new file mode 100644
index 0000000..5579ef0
--- /dev/null
+++ b/drivers/net/ax88180.c
@@ -0,0 +1,842 @@
+/* ax88180: ASIX AX88180 Non-PCI Gigabit Ethernet u-boot driver */
+/*
+ This program is free software; you can distribute it and/or modify
+ it under the terms of the GNU General Public License (Version 2) as
+ published by the Free Software Foundation.
+ This program is distributed in the hope 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.
+*/
+
+/*
+ ========================================================================
+ ASIX AX88180 Non-PCI 16/32-bit Gigabit Ethernet Linux Driver
+
+ The AX88180 Ethernet controller is a high performance and highly
+ integrated local CPU bus Ethernet controller with embedded 40K bytes
+ SRAM and supports both 16-bit and 32-bit SRAM-Like interfaces for any
+ embedded systems.
+ The AX88180 is a single chip 10/100/1000Mbps Gigabit Ethernet
+ controller that supports both MII and RGMII interfaces and is
+ compliant to IEEE 802.3, IEEE 802.3u and IEEE 802.3z standards.
+
+ Please visit ASIX's web site (http://www.asix.com.tw) for more
+ details.
+
+ Module Name : ax88180.c
+ Date : 2008-07-01
+ History
+ 09/06/2006 : New release for AX88180 US2 chip.
+ 07/01/2008 : Fix up the coding style and using functions
+ instead of most macros
+ ========================================================================
+*/
+#include <common.h>
+#include <command.h>
+#include <net.h>
+
+#include "ax88180.h"
+
+#ifdef CONFIG_DRIVER_AX88180
+
+/*
+===========================================================================
+<<<<<< Local SubProgram Declaration >>>>>>
+===========================================================================
+*/
+static void ax88180_rx_handler (void);
+static int ax88180_PHY_initial (void);
+static void ax88180_meida_config (void);
+static unsigned long get_CicadaPHY_meida_mode (void);
+static unsigned long get_MarvellPHY_meida_mode (void);
+static unsigned short ax88180_mdio_read (unsigned long phyaddr,
+ unsigned long regaddr);
+static void ax88180_mdio_write (unsigned long phyaddr,
+ unsigned long regaddr,
+ unsigned short regdata);
+
+/*
+===========================================================================
+<<<<<< Declare Macro/Structure Definition >>>>>>
+===========================================================================
+*/
+typedef enum _AX88180_LINK_STATE {
+ INS_LINK_DOWN,
+ INS_LINK_UP,
+ INS_LINK_UNKNOWN
+} AX88180_LINK_STATE;
+
+typedef struct _AX88180_PRIVATE {
+ unsigned long PhyAddr;
+ unsigned long PhyID0;
+ unsigned long FirstTxDesc;
+ unsigned long NextTxDesc;
+ unsigned long rxbuf_overflow_count;
+ AX88180_LINK_STATE LinkState;
+} AX88180_PRIVATE;
+
+AX88180_PRIVATE axlocal;
+
+#if (DEBUG_FLAGS & DEBUG_MSG)
+static inline void ax88180_disp_all_reg (void)
+{
+ unsigned long tmpval;
+ int i;
+ PRINTK (DEBUG_MSG, "ax88180: AX88180 MAC Registers:\n");
+ for (i = 0xFC00; i <= 0xFCFF; i += 4) {
+ READ_MACREG (i, tmpval);
+ PRINTK (DEBUG_MSG, "0x%04x=0x%08lx ", i, tmpval);
+ if ((i & 0xF) == 0xC)
+ PRINTK (DEBUG_MSG, "\n");
+ }
+ PRINTK (DEBUG_MSG, "\n");
+}
+
+static inline void ax88180_disp_phy_reg (void)
+{
+ unsigned long tmpval;
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, BMCR);
+ PRINTK (DEBUG_MSG, "BMCR=0x%04x ", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, BMSR);
+ PRINTK (DEBUG_MSG, "BMSR=0x%04x ", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, PHYIDR0);
+ PRINTK (DEBUG_MSG, "PHYIDR0=0x%04x ", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, PHYIDR1);
+ PRINTK (DEBUG_MSG, "PHYIDR1=0x%04x ", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, ANAR);
+ PRINTK (DEBUG_MSG, "ANAR=0x%04x ", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, ANLPAR);
+ PRINTK (DEBUG_MSG, "ANLPAR=0x%04x \n", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, ANER);
+ PRINTK (DEBUG_MSG, "ANER=0x%04x ", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, AUX_1000_CTRL);
+ PRINTK (DEBUG_MSG, "1G_CTRL=0x%04x ", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, AUX_1000_STATUS);
+ PRINTK (DEBUG_MSG, "1G_STATUS=0x%04x \n", (unsigned int)tmpval);
+ if (axlocal.PhyID0 == MARVELL_88E1111_PHYIDR0) {
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, M88_SSR);
+ PRINTK (DEBUG_MSG, "M88_SSR=0x%04x ", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, M88_IER);
+ PRINTK (DEBUG_MSG, "M88_IER=0x%04x ", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, M88_ISR);
+ PRINTK (DEBUG_MSG, "M88_ISR=0x%04x ", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, M88_EXT_SCR);
+ PRINTK (DEBUG_MSG, "M88_EXT_SCR=0x%04x ",
+ (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, M88_EXT_SSR);
+ PRINTK (DEBUG_MSG, "M88_EXT_SSR=0x%04x \n",
+ (unsigned int)tmpval);
+ } else if (axlocal.PhyID0 == CICADA_CIS8201_PHYIDR0) {
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, CIS_IMR);
+ PRINTK (DEBUG_MSG, "CIS_IMR=0x%04x ", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr, CIS_ISR);
+ PRINTK (DEBUG_MSG, "CIS_ISR=0x%04x ", (unsigned int)tmpval);
+ tmpval = ax88180_mdio_read (axlocal.PhyAddr,
+ CIS_AUX_CTRL_STATUS);
+ PRINTK (DEBUG_MSG, "CIS_AUX=0x%04x \n",
+ (unsigned int)tmpval);
+ }
+ READ_MACREG (RXCFG, tmpval);
+ PRINTK (DEBUG_MSG, "RXCFG=0x%08lx ", tmpval);
+ READ_MACREG (MACCFG0, tmpval);
+ PRINTK (DEBUG_MSG, "MACCFG0=0x%08lx ", tmpval);
+ READ_MACREG (MACCFG1, tmpval);
+ PRINTK (DEBUG_MSG, "MACCFG1=0x%08lx ", tmpval);
+ READ_MACREG (MACCFG2, tmpval);
+ PRINTK (DEBUG_MSG, "MACCFG2=0x%08lx \n\n", tmpval);
+}
+#else
+static inline void ax88180_disp_all_reg (void) {}
+static inline void ax88180_disp_phy_reg (void) {}
+#endif
+
+/*
+===========================================================================
+<<<<<< Local SubProgram Bodies >>>>>>
+===========================================================================
+*/
+static int
+ax88180_mdio_check_complete (void)
+{
+ int us_cnt = 10000;
+ unsigned long tmpval;
+
+ /* MDIO read/write should not take more than 10 ms */
+ while (--us_cnt) {
+ READ_MACREG (MDIOCTRL, tmpval);
+ if (((tmpval & READ_PHY) == 0) && ((tmpval & WRITE_PHY) == 0))
+ break;
+ }
+
+ return us_cnt;
+}
+
+static unsigned short
+ax88180_mdio_read (unsigned long phyaddr, unsigned long regaddr)
+{
+ unsigned long tmpval = 0;
+
+ WRITE_MACREG (MDIOCTRL, READ_PHY | (regaddr << 8) | phyaddr);
+
+ if (ax88180_mdio_check_complete ())
+ READ_MACREG (MDIODP, tmpval);
+ else
+ printf("Failed to read PHY register!\n");
+ return (unsigned short)(tmpval & 0xFFFF);
+}
+
+static void
+ax88180_mdio_write (unsigned long phyaddr, unsigned long regaddr,
+ unsigned short regdata)
+{
+ WRITE_MACREG (MDIODP, regdata);
+ WRITE_MACREG (MDIOCTRL, WRITE_PHY | (regaddr << 8) | phyaddr);
+
+ if(!ax88180_mdio_check_complete ())
+ printf("Failed to write PHY register!\n");
+}
+
+static int ax88180_phy_reset (void)
+{
+ unsigned short delay_cnt = 500;
+
+ ax88180_mdio_write (axlocal.PhyAddr, BMCR, PHY_RESET | AUTONEG_EN);
+
+ /* Wait for the reset to complete, or time out (500 ms) */
+ while (ax88180_mdio_read (axlocal.PhyAddr, BMCR) & PHY_RESET) {
+ udelay (1000);
+ if (--delay_cnt == 0) {
+ printf("Failed to reset PHY!\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void ax88180_mac_reset (void)
+{
+ unsigned long tmpval;
+
+ WRITE_MACREG (MISC, MISC_RESET_MAC);
+ READ_MACREG (MISC, tmpval);
+ WRITE_MACREG (MISC, MISC_NORMAL);
+ WRITE_MACREG (RXINDICATOR, DEFAULT_RXINDICATOR);
+ WRITE_MACREG (TXCMD, DEFAULT_TXCMD);
+ WRITE_MACREG (TXBS, DEFAULT_TXBS);
+ WRITE_MACREG (TXDES0, DEFAULT_TXDES0);
+ WRITE_MACREG (TXDES1, DEFAULT_TXDES1);
+ WRITE_MACREG (TXDES2, DEFAULT_TXDES2);
+ WRITE_MACREG (TXDES3, DEFAULT_TXDES3);
+ WRITE_MACREG (TXCFG, DEFAULT_TXCFG);
+ WRITE_MACREG (MACCFG2, DEFAULT_MACCFG2);
+ WRITE_MACREG (MACCFG3, DEFAULT_MACCFG3);
+ WRITE_MACREG (TXLEN, DEFAULT_TXLEN);
+ WRITE_MACREG (RXBTHD0, DEFAULT_RXBTHD0);
+ WRITE_MACREG (RXBTHD1, DEFAULT_RXBTHD1);
+ WRITE_MACREG (RXFULTHD, DEFAULT_RXFULTHD);
+ WRITE_MACREG (DOGTHD0, DEFAULT_DOGTHD0);
+ WRITE_MACREG (DOGTHD1, DEFAULT_DOGTHD1);
+}
+
+static int ax88180_poll_tx_complete (void)
+{
+ unsigned long tmp_data, txbs_txdp;
+ int TimeOutCnt = 10000;
+
+ txbs_txdp = 1 << axlocal.NextTxDesc;
+
+ while (TimeOutCnt--) {
+
+ READ_MACREG (TXBS, tmp_data);
+ if ((tmp_data & txbs_txdp) == 0)
+ break;
+
+ udelay (100);
+ }
+
+ if (TimeOutCnt)
+ return 0;
+ else
+ return -TimeOutCnt;
+}
+
+static void ax88180_rx_handler (void)
+{
+ unsigned char *rxdata;
+ unsigned long tmp_data;
+ unsigned long rx_packet_len;
+ unsigned int data_size;
+ unsigned int dword_count, byte_count;
+ unsigned long rxcurt_ptr, rxbound_ptr, next_ptr;
+ int i;
+ int j;
+
+ READ_MACREG (RXCURT, rxcurt_ptr);
+ READ_MACREG (RXBOUND, rxbound_ptr);
+ next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK;
+
+ PRINTK (RX_MSG, "ax88180: RX original RXBOUND=0x%08lx,"
+ " RXCURT=0x%08lx\n", rxbound_ptr, rxcurt_ptr);
+
+ while (next_ptr != rxcurt_ptr) {
+ WRITE_MACREG (RXINDICATOR, RX_START_READ);
+ READ_RXBUF (rx_packet_len);
+ if ((rx_packet_len == 0) || (rx_packet_len > MAX_RX_SIZE)) {
+ WRITE_MACREG (RXINDICATOR, RX_STOP_READ);
+ ax88180_mac_reset ();
+ printf ("ax88180: Invalid Rx packet length!"
+ " (len=0x%08lx)\n", rx_packet_len);
+
+ printf ("ax88180: RX RXBOUND=0x%08lx,"
+ "RXCURT=0x%08lx\n", rxbound_ptr, rxcurt_ptr);
+ return;
+ }
+ data_size = (unsigned int)rx_packet_len;
+ rxbound_ptr += (((data_size + 0xF) & 0xFFF0) >> 4) + 1;
+ rxbound_ptr &= RX_PAGE_NUM_MASK;
+
+ rxdata = (unsigned char *)NetRxPackets[0];
+
+#if defined (CONFIG_DRIVER_AX88180_16BIT)
+ dword_count = data_size >> 1;
+ byte_count = data_size & 0x1;
+#else
+ dword_count = data_size >> 2;
+ byte_count = data_size & 0x3;
+#endif
+ for (i = 0; i < dword_count; i++) {
+ READ_RXBUF (tmp_data);
+#if defined (CONFIG_DRIVER_AX88180_16BIT)
+ *((unsigned short *)rxdata + i) = tmp_data;
+#else
+ *((unsigned long *)rxdata + i) = tmp_data;
+#endif
+ }
+ if (byte_count != 0) {
+ READ_RXBUF (tmp_data);
+ for (j = 0; j < byte_count; j++) {
+ *(rxdata + (dword_count * 4) + j) =
+ (unsigned char)(tmp_data >> (j * 8));
+ }
+ }
+
+ WRITE_MACREG (RXINDICATOR, RX_STOP_READ);
+
+ /* Pass the packet up to the protocol layers. */
+ NetReceive (NetRxPackets[0], data_size);
+
+ WRITE_MACREG (RXBOUND, rxbound_ptr);
+
+ READ_MACREG (RXCURT, rxcurt_ptr);
+ READ_MACREG (RXBOUND, rxbound_ptr);
+ next_ptr = (rxbound_ptr + 1) & RX_PAGE_NUM_MASK;
+
+ PRINTK (RX_MSG, "ax88180: RX updated RXBOUND=0x%08lx,"
+ "RXCURT=0x%08lx\n", rxbound_ptr, rxcurt_ptr);
+ }
+
+ if (axlocal.rxbuf_overflow_count > 0)
+ axlocal.rxbuf_overflow_count--;
+
+ return;
+}
+
+static int ax88180_PHY_initial (void)
+{
+ unsigned long tmp_regval;
+ int i;
+ int ret;
+
+ /* Check avaliable PHY chipset */
+ axlocal.PhyAddr = MARVELL_88E1111_PHYADDR;
+ axlocal.PhyID0 = ax88180_mdio_read (axlocal.PhyAddr, PHYIDR0);
+
+ if (axlocal.PhyID0 == MARVELL_88E1111_PHYIDR0) {
+ PRINTK (DEBUG_MSG, "ax88180: Found Marvell 88E1111 PHY."
+ " (PHY Addr=0x%lx)\n", axlocal.PhyAddr);
+ tmp_regval = ax88180_mdio_read (axlocal.PhyAddr, M88_EXT_SSR);
+ if ((tmp_regval & HWCFG_MODE_MASK) == RGMII_COPPER_MODE) {
+ ax88180_mdio_write (axlocal.PhyAddr, M88_EXT_SCR,
+ DEFAULT_EXT_SCR);
+ if ((ret = ax88180_phy_reset ()) < 0)
+ return ret;
+ ax88180_mdio_write (axlocal.PhyAddr, M88_IER,
+ LINK_CHANGE_INT);
+ }
+ } else {
+ axlocal.PhyAddr = CICADA_CIS8201_PHYADDR;
+ axlocal.PhyID0 = ax88180_mdio_read (axlocal.PhyAddr, PHYIDR0);
+ if (axlocal.PhyID0 == CICADA_CIS8201_PHYIDR0) {
+ PRINTK (DEBUG_MSG, "ax88180: Found CICADA CIS8201 PHY"
+ " chipset. (PHY Addr=0x%lx)\n",
+ axlocal.PhyAddr);
+ ax88180_mdio_write (axlocal.PhyAddr, CIS_IMR,
+ (CIS_INT_ENABLE | LINK_CHANGE_INT));
+
+ /*
+ Set CIS_SMI_PRIORITY bit before force the media mode
+ */
+ tmp_regval = ax88180_mdio_read (axlocal.PhyAddr,
+ CIS_AUX_CTRL_STATUS);
+ tmp_regval &= ~CIS_SMI_PRIORITY;
+ ax88180_mdio_write (axlocal.PhyAddr,
+ CIS_AUX_CTRL_STATUS, tmp_regval);
+ } else {
+ printf ("ax88180: Unknown PHY chipset!!\n");
+ return -1;
+ }
+ }
+
+ /* Waiting for auto-negotiation complete. */
+ /* This may take up to 5 seconds */
+ PRINTK (DEBUG_MSG,
+ "ax88180: Waiting for auto-negotiation completion......\n");
+ for (i = 0; i < 5000; i++) {
+ tmp_regval = ax88180_mdio_read (axlocal.PhyAddr, BMSR);
+ if (tmp_regval & AUTONEG_COMPLETE) {
+ break;
+ }
+ udelay (1000);
+ }
+
+ return 0;
+}
+
+static void ax88180_meida_config (void)
+{
+ unsigned long bmcr_val, bmsr_val;
+ unsigned long rxcfg_val, maccfg0_val, maccfg1_val;
+ unsigned long RealMediaMode;
+ int i;
+
+ /* Waiting 200 msecs for PHY link stable */
+ for (i = 0; i < 200; i++) {
+ bmsr_val = ax88180_mdio_read (axlocal.PhyAddr, BMSR);
+ if (bmsr_val & LINKOK) {
+ break;
+ }
+ udelay (1000);
+ }
+
+ bmsr_val = ax88180_mdio_read (axlocal.PhyAddr, BMSR);
+ PRINTK (DEBUG_MSG, "ax88180: BMSR=0x%04x\n", (unsigned int)bmsr_val);
+
+ if (bmsr_val & LINKOK) {
+ bmcr_val = ax88180_mdio_read (axlocal.PhyAddr, BMCR);
+ if (bmcr_val & AUTONEG_EN) {
+ /* Waiting for Auto-negotiation completion */
+ /* This may take up to 5 seconds */
+ PRINTK (DEBUG_MSG, "ax88180: Auto-negotiation is "
+ "enabled. Waiting for NWay completion..\n");
+ for (i = 0; i < 5000; i++) {
+ bmsr_val = ax88180_mdio_read (axlocal.PhyAddr,
+ BMSR);
+ if (bmsr_val & AUTONEG_COMPLETE) {
+ break;
+ }
+ udelay (1000);
+ }
+ } else
+ PRINTK (DEBUG_MSG,
+ "ax88180: Auto-negotiation is disabled.\n");
+
+ PRINTK (DEBUG_MSG, "ax88180: BMCR=0x%04x, BMSR=0x%04x\n",
+ (unsigned int)bmcr_val, (unsigned int)bmsr_val);
+
+ /* Get real media mode here */
+ if (axlocal.PhyID0 == MARVELL_88E1111_PHYIDR0) {
+ RealMediaMode = get_MarvellPHY_meida_mode ();
+ } else if (axlocal.PhyID0 == CICADA_CIS8201_PHYIDR0) {
+ RealMediaMode = get_CicadaPHY_meida_mode ();
+ } else {
+ RealMediaMode = MEDIA_1000FULL;
+ }
+
+ switch (RealMediaMode) {
+ default:
+ case MEDIA_1000FULL:
+ PRINTK (DEBUG_MSG,
+ "ax88180: 1000Mbps Full-duplex mode.\n");
+ rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
+ maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0;
+ maccfg1_val = GIGA_MODE_EN | RXFLOW_EN |
+ FULLDUPLEX | DEFAULT_MACCFG1;
+ break;
+
+ case MEDIA_1000HALF:
+ PRINTK (DEBUG_MSG,
+ "ax88180: 1000Mbps Half-duplex mode.\n");
+ rxcfg_val = DEFAULT_RXCFG;
+ maccfg0_val = DEFAULT_MACCFG0;
+ maccfg1_val = GIGA_MODE_EN | DEFAULT_MACCFG1;
+ break;
+
+ case MEDIA_100FULL:
+ PRINTK (DEBUG_MSG,
+ "ax88180: 100Mbps Full-duplex mode.\n");
+ rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
+ maccfg0_val = SPEED100 | TXFLOW_ENABLE
+ | DEFAULT_MACCFG0;
+ maccfg1_val = RXFLOW_EN | FULLDUPLEX
+ | DEFAULT_MACCFG1;
+ break;
+
+ case MEDIA_100HALF:
+ PRINTK (DEBUG_MSG,
+ "ax88180: 100Mbps Half-duplex mode.\n");
+ rxcfg_val = DEFAULT_RXCFG;
+ maccfg0_val = SPEED100 | DEFAULT_MACCFG0;
+ maccfg1_val = DEFAULT_MACCFG1;
+ break;
+
+ case MEDIA_10FULL:
+ PRINTK (DEBUG_MSG,
+ "ax88180: 10Mbps Full-duplex mode.\n");
+ rxcfg_val = RXFLOW_ENABLE | DEFAULT_RXCFG;
+ maccfg0_val = TXFLOW_ENABLE | DEFAULT_MACCFG0;
+ maccfg1_val = RXFLOW_EN | FULLDUPLEX
+ | DEFAULT_MACCFG1;
+ break;
+
+ case MEDIA_10HALF:
+ PRINTK (DEBUG_MSG,
+ "ax88180: 10Mbps Half-duplex mode.\n");
+ rxcfg_val = DEFAULT_RXCFG;
+ maccfg0_val = DEFAULT_MACCFG0;
+ maccfg1_val = DEFAULT_MACCFG1;
+ break;
+ }
+
+ axlocal.LinkState = INS_LINK_UP;
+ } else {
+ rxcfg_val = DEFAULT_RXCFG;
+ maccfg0_val = DEFAULT_MACCFG0;
+ maccfg1_val = DEFAULT_MACCFG1;
+
+ axlocal.LinkState = INS_LINK_DOWN;
+ }
+
+ WRITE_MACREG (RXCFG, rxcfg_val);
+ WRITE_MACREG (MACCFG0, maccfg0_val);
+ WRITE_MACREG (MACCFG1, maccfg1_val);
+
+ return;
+}
+
+static unsigned long
+get_MarvellPHY_meida_mode (void)
+{
+ unsigned long m88_ssr;
+ unsigned long MediaMode;
+
+ m88_ssr = ax88180_mdio_read (axlocal.PhyAddr, M88_SSR);
+ switch (m88_ssr & SSR_MEDIA_MASK) {
+ default:
+ case SSR_1000FULL:
+ MediaMode = MEDIA_1000FULL;
+ break;
+ case SSR_1000HALF:
+ MediaMode = MEDIA_1000HALF;
+ break;
+ case SSR_100FULL:
+ MediaMode = MEDIA_100FULL;
+ break;
+ case SSR_100HALF:
+ MediaMode = MEDIA_100HALF;
+ break;
+ case SSR_10FULL:
+ MediaMode = MEDIA_10FULL;
+ break;
+ case SSR_10HALF:
+ MediaMode = MEDIA_10HALF;
+ break;
+ }
+
+ return MediaMode;
+}
+
+static unsigned long
+get_CicadaPHY_meida_mode (void)
+{
+ unsigned long tmp_regval;
+ unsigned long MediaMode;
+
+ tmp_regval = ax88180_mdio_read (axlocal.PhyAddr,
+ CIS_AUX_CTRL_STATUS);
+ switch (tmp_regval & CIS_MEDIA_MASK) {
+ default:
+ case CIS_1000FULL:
+ MediaMode = MEDIA_1000FULL;
+ break;
+ case CIS_1000HALF:
+ MediaMode = MEDIA_1000HALF;
+ break;
+ case CIS_100FULL:
+ MediaMode = MEDIA_100FULL;
+ break;
+ case CIS_100HALF:
+ MediaMode = MEDIA_100HALF;
+ break;
+ case CIS_10FULL:
+ MediaMode = MEDIA_10FULL;
+ break;
+ case CIS_10HALF:
+ MediaMode = MEDIA_10HALF;
+ break;
+ }
+
+ return MediaMode;
+}
+
+/*
+===========================================================================
+<<<<<< Exported SubProgram Bodies >>>>>>
+===========================================================================
+*/
+void eth_halt (void)
+{
+ /* Disable AX88180 TX/RX functions */
+ WRITE_MACREG (CMD, WAKEMOD);
+}
+
+int eth_init (bd_t *bd)
+{
+ unsigned long tmp_regval;
+ unsigned long macid0_val, macid1_val, macid2_val;
+ int ret, i;
+
+#if defined (CONFIG_DRIVER_AX88180_16BIT)
+ *((volatile unsigned short *)(AX88180_BASE + 6)) = (START_BASE >> 8);
+ *((volatile unsigned short *)AX88180_BASE ) = 1;
+#endif
+ memset (&axlocal, 0, sizeof (AX88180_PRIVATE));
+
+ ax88180_mac_reset ();
+
+ /* Disable AX88180 interrupt */
+ WRITE_MACREG (IMR, CLEAR_IMR);
+
+ /* Disable AX88180 TX/RX functions */
+ WRITE_MACREG (CMD, WAKEMOD);
+
+ axlocal.LinkState = INS_LINK_UNKNOWN;
+
+ /* Initial PHY registers */
+ if ((ret = ax88180_PHY_initial ()) < 0)
+ return ret;
+ ax88180_meida_config ();
+
+ /* Reload MAC address from EEPROM */
+ WRITE_MACREG (PROMCTRL, RELOAD_EEPROM);
+
+ /* Waiting for reload eeprom completion */
+ for (i = 0; i < 500; i++) {
+ READ_MACREG (PROMCTRL, tmp_regval);
+ if ((tmp_regval & RELOAD_EEPROM) == 0)
+ break;
+ udelay (1000);
+ }
+
+ /* Get MAC addresses */
+ READ_MACREG (MACID0, macid0_val);
+ READ_MACREG (MACID1, macid1_val);
+ READ_MACREG (MACID2, macid2_val);
+
+ bd->bi_enetaddr[0] = (unsigned char)macid0_val;
+ bd->bi_enetaddr[1] = (unsigned char)(macid0_val >> 8);
+ bd->bi_enetaddr[2] = (unsigned char)macid1_val;
+ bd->bi_enetaddr[3] = (unsigned char)(macid1_val >> 8);
+ bd->bi_enetaddr[4] = (unsigned char)macid2_val;
+ bd->bi_enetaddr[5] = (unsigned char)(macid2_val >> 8);
+
+ if (((macid0_val | macid1_val | macid2_val) == 0) ||
+ (bd->bi_enetaddr[0] & 0x01)) {
+ /* try to get MAC address from environment */
+ u8 i;
+ char *s, *e;
+ unsigned short tmp16;
+
+ s = getenv ("ethaddr");
+ for (i = 0; i < 6; ++i) {
+ bd->bi_enetaddr[i] = s ?
+ simple_strtoul (s, &e, 16) : 0;
+ if (s)
+ s = (*e) ? e + 1 : e;
+ }
+
+ tmp16 = bd->bi_enetaddr[1];
+ macid0_val = (tmp16 << 8) | bd->bi_enetaddr[0];
+ tmp16 = bd->bi_enetaddr[3];
+ macid1_val = (tmp16 << 8) | bd->bi_enetaddr[2];
+ tmp16 = bd->bi_enetaddr[5];
+ macid2_val = (tmp16 << 8) | bd->bi_enetaddr[4];
+
+ WRITE_MACREG (MACID0, macid0_val);
+ WRITE_MACREG (MACID1, macid1_val);
+ WRITE_MACREG (MACID2, macid2_val);
+ }
+
+ WRITE_MACREG (RXFILTER, DEFAULT_RXFILTER);
+
+ /* Initial variables here */
+ axlocal.FirstTxDesc = TXDP0;
+ axlocal.NextTxDesc = TXDP0;
+ axlocal.rxbuf_overflow_count = 0;
+
+ ax88180_disp_all_reg ();
+
+ /* Check if there is any invalid interrupt status. If yes, clear it. */
+ READ_MACREG (ISR, tmp_regval);
+ PRINTK (DEBUG_MSG, "ax88180: The interrupt status = 0x%08lx\n",
+ tmp_regval);
+ if (tmp_regval)
+ WRITE_MACREG (ISR, tmp_regval);
+
+ /* Start AX88180 TX/RX functions */
+ WRITE_MACREG (CMD, RXEN | TXEN | WAKEMOD);
+
+ return 0;
+}
+
+/* Get a data block via Ethernet */
+int eth_rx (void)
+{
+ unsigned long ISR_Status;
+ unsigned long rxcurt_ptr, rxbound_ptr;
+ unsigned long tmp_regval;
+
+ /* Read and check interrupt status here...... */
+ READ_MACREG (ISR, ISR_Status);
+
+ while (ISR_Status) {
+ /* Clear the interrupt status */
+ WRITE_MACREG (ISR, ISR_Status);
+
+ PRINTK (INT_MSG,
+ "\nax88180: The interrupt status = 0x%08lx\n",
+ ISR_Status);
+
+ if (ISR_Status & ISR_PHY) {
+ /* Read ISR register once to clear PHY interrupt bit */
+ tmp_regval = ax88180_mdio_read (axlocal.PhyAddr,
+ M88_ISR);
+ ax88180_meida_config ();
+ ax88180_disp_phy_reg ();
+ }
+
+ if (ISR_Status & ISR_RXBUFFOVR) {
+ axlocal.rxbuf_overflow_count++;
+ READ_MACREG (RXCURT, rxcurt_ptr);
+ READ_MACREG (RXBOUND, rxbound_ptr);
+ PRINTK (INT_MSG, "ax88180: RX Buffer overflow! "
+ "count=%d, RXBOUND=0x%08lx, RXCURT=0x%08lx\n",
+ (int)axlocal.rxbuf_overflow_count, rxbound_ptr,
+ rxcurt_ptr);
+
+ if (axlocal.rxbuf_overflow_count > 10) {
+ ax88180_mac_reset ();
+ axlocal.FirstTxDesc = TXDP0;
+ axlocal.NextTxDesc = TXDP0;
+ axlocal.rxbuf_overflow_count = 0;
+ }
+ }
+
+ if (ISR_Status & ISR_RX) {
+ ax88180_rx_handler ();
+ }
+
+ /* Read and check interrupt status here...... */
+ READ_MACREG (ISR, ISR_Status);
+ }
+
+ return 0;
+}
+
+/* Send a data block via Ethernet. */
+int eth_send (volatile void *packet, int length)
+{
+ volatile unsigned char *txdata;
+ unsigned long TXDES_addr;
+ unsigned long txcmd_txdp, txbs_txdp;
+ unsigned long tmp_data;
+ int i;
+
+ if (axlocal.LinkState != INS_LINK_UP) {
+ return 0;
+ }
+
+ txdata = (volatile unsigned char *)packet;
+
+ axlocal.FirstTxDesc = axlocal.NextTxDesc;
+ txbs_txdp = 1 << axlocal.FirstTxDesc;
+
+ READ_MACREG (TXBS, tmp_data);
+ READ_MACREG (TXBS, tmp_data);
+ PRINTK (TX_MSG, "ax88180: Checking available TXDP (TXBS=0x%08lx)\n",
+ tmp_data);
+
+ /* check the available transmit descriptor */
+ if (tmp_data & txbs_txdp) {
+ /* we should never get here. */
+ /* we are running out of resource */
+ return 0;
+ }
+
+ PRINTK (TX_MSG, "ax88180: TXDP%d is available, i=%d\n",
+ (int)axlocal.FirstTxDesc, i);
+
+ txcmd_txdp = axlocal.FirstTxDesc << 13;
+ TXDES_addr = TXDES0 + (axlocal.FirstTxDesc << 2);
+
+ WRITE_MACREG (TXCMD, txcmd_txdp | length | TX_START_WRITE);
+
+#if defined (CONFIG_DRIVER_AX88180_16BIT)
+ for (i = 0; i < length; i += 2) {
+ tmp_data =
+ (unsigned short)*(txdata + i) +
+ (unsigned short)(*(txdata + i + 1) << 8);
+ WRITE_TXBUF (tmp_data);
+ }
+#else
+ for (i = 0; i < length; i += 4) {
+ tmp_data =
+ (unsigned long)*(txdata + i) +
+ (unsigned long)(*(txdata + i + 1) << 8) +
+ (unsigned long)(*(txdata + i + 2) << 16) +
+ (unsigned long)(*(txdata + i + 3) << 24);
+ WRITE_TXBUF (tmp_data);
+ }
+#endif
+
+ WRITE_MACREG (TXCMD, txcmd_txdp | length);
+ WRITE_MACREG (TXBS, txbs_txdp);
+ WRITE_MACREG (TXDES_addr, TXDPx_ENABLE | length);
+
+ axlocal.NextTxDesc = (axlocal.NextTxDesc + 1) & TXDP_MASK;
+
+ /*
+ Check the available transmit descriptor, if we had exhausted all
+ transmit descriptor ,then we have to wait for at least one free
+ descriptor
+ */
+ txbs_txdp = 1 << axlocal.NextTxDesc;
+ READ_MACREG (TXBS, tmp_data);
+ if (tmp_data & txbs_txdp) {
+ if (ax88180_poll_tx_complete () < 0) {
+ ax88180_mac_reset ();
+ axlocal.FirstTxDesc = TXDP0;
+ axlocal.NextTxDesc = TXDP0;
+ printf ("ax88180: Transmit time out occurred!\n");
+ }
+ }
+
+ return 0;
+}
+#endif /* CONFIG_DRIVER_AX88180 */
+
diff --git a/drivers/net/ax88180.h b/drivers/net/ax88180.h
new file mode 100644
index 0000000..ae4b1b3
--- /dev/null
+++ b/drivers/net/ax88180.h
@@ -0,0 +1,415 @@
+/* ax88180.h: ASIX AX88180 Non-PCI Gigabit Ethernet u-boot driver */
+/*
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 <asm/types.h>
+#include <config.h>
+
+#ifdef CONFIG_DRIVER_AX88180
+
+#define ENABLE_JUMBO 1
+#define DISABLE_JUMBO 0
+
+#define ENABLE_BURST 1
+#define DISABLE_BURST 0
+
+#define NORMAL_RX_MODE 0
+#define RX_LOOPBACK_MODE 1
+#define RX_INIFINIT_LOOP_MODE 2
+#define TX_INIFINIT_LOOP_MODE 3
+
+#define DEFAULT_ETH_MTU 1500
+
+/* Jumbo packet size 4086 bytes included 4 bytes CRC*/
+#define MAX_JUMBO_MTU 4072
+
+/* Max Tx Jumbo size 4086 bytes included 4 bytes CRC */
+#define MAX_TX_JUMBO_SIZE 4086
+
+/* Max Rx Jumbo size is 15K Bytes */
+#define MAX_RX_SIZE 0x3C00
+
+#define MARVELL_88E1111_PHYADDR 0x18
+#define MARVELL_88E1111_PHYIDR0 0x0141
+
+#define CICADA_CIS8201_PHYADDR 0x01
+#define CICADA_CIS8201_PHYIDR0 0x000F
+
+#define MEDIA_AUTO 0
+#define MEDIA_1000FULL 1
+#define MEDIA_1000HALF 2
+#define MEDIA_100FULL 3
+#define MEDIA_100HALF 4
+#define MEDIA_10FULL 5
+#define MEDIA_10HALF 6
+
+#define AUTO_MEDIA 0
+#define FORCE_MEDIA 1
+
+#define TXDP_MASK 3
+#define TXDP0 0
+#define TXDP1 1
+#define TXDP2 2
+#define TXDP3 3
+
+#define CMD_MAP_SIZE 0x100
+
+#if defined (CONFIG_DRIVER_AX88180_16BIT)
+ #define AX88180_MEMORY_SIZE 0x00004000
+ #define START_BASE 0x1000
+
+ #define RX_BUF_SIZE 0x1000
+ #define TX_BUF_SIZE 0x0F00
+
+ #define TX_BASE START_BASE
+ #define CMD_BASE (TX_BASE + TX_BUF_SIZE)
+ #define RX_BASE (CMD_BASE + CMD_MAP_SIZE)
+#else
+ #define AX88180_MEMORY_SIZE 0x00010000
+
+ #define RX_BUF_SIZE 0x8000
+ #define TX_BUF_SIZE 0x7C00
+
+ #define RX_BASE 0x0000
+ #define TX_BASE (RX_BASE + RX_BUF_SIZE)
+ #define CMD_BASE (TX_BASE + TX_BUF_SIZE)
+#endif
+
+/* AX88180 Memory Mapping Definition */
+#define RXBUFFER_START RX_BASE
+ #define RX_PACKET_LEN_OFFSET 0
+ #define RX_PAGE_NUM_MASK 0x7FF //RX pages 0~7FFh
+#define TXBUFFER_START TX_BASE
+
+/* AX88180 MAC Register Definition */
+#define CMD (CMD_BASE + 0x0000)
+ #define WAKEMOD 0x00000001
+ #define TXEN 0x00000100
+ #define RXEN 0x00000200
+ #define DEFAULT_CMD WAKEMOD
+#define IMR (CMD_BASE + 0x0004)
+ #define IMR_RXBUFFOVR 0x00000001
+ #define IMR_WATCHDOG 0x00000002
+ #define IMR_TX 0x00000008
+ #define IMR_RX 0x00000010
+ #define IMR_PHY 0x00000020
+ #define CLEAR_IMR 0x00000000
+ #define DEFAULT_IMR (IMR_PHY | IMR_RX | IMR_TX |\
+ IMR_RXBUFFOVR | IMR_WATCHDOG)
+#define ISR (CMD_BASE + 0x0008)
+ #define ISR_RXBUFFOVR 0x00000001
+ #define ISR_WATCHDOG 0x00000002
+ #define ISR_TX 0x00000008
+ #define ISR_RX 0x00000010
+ #define ISR_PHY 0x00000020
+#define TXCFG (CMD_BASE + 0x0010)
+ #define AUTOPAD_CRC 0x00000050
+ #define DEFAULT_TXCFG AUTOPAD_CRC
+#define TXCMD (CMD_BASE + 0x0014)
+ #define TXCMD_TXDP_MASK 0x00006000
+ #define TXCMD_TXDP0 0x00000000
+ #define TXCMD_TXDP1 0x00002000
+ #define TXCMD_TXDP2 0x00004000
+ #define TXCMD_TXDP3 0x00006000
+ #define TX_START_WRITE 0x00008000
+ #define TX_STOP_WRITE 0x00000000
+ #define DEFAULT_TXCMD 0x00000000
+#define TXBS (CMD_BASE + 0x0018)
+ #define TXDP0_USED 0x00000001
+ #define TXDP1_USED 0x00000002
+ #define TXDP2_USED 0x00000004
+ #define TXDP3_USED 0x00000008
+ #define DEFAULT_TXBS 0x00000000
+#define TXDES0 (CMD_BASE + 0x0020)
+ #define TXDPx_ENABLE 0x00008000
+ #define TXDPx_LEN_MASK 0x00001FFF
+ #define DEFAULT_TXDES0 0x00000000
+#define TXDES1 (CMD_BASE + 0x0024)
+ #define TXDPx_ENABLE 0x00008000
+ #define TXDPx_LEN_MASK 0x00001FFF
+ #define DEFAULT_TXDES1 0x00000000
+#define TXDES2 (CMD_BASE + 0x0028)
+ #define TXDPx_ENABLE 0x00008000
+ #define TXDPx_LEN_MASK 0x00001FFF
+ #define DEFAULT_TXDES2 0x00000000
+#define TXDES3 (CMD_BASE + 0x002C)
+ #define TXDPx_ENABLE 0x00008000
+ #define TXDPx_LEN_MASK 0x00001FFF
+ #define DEFAULT_TXDES3 0x00000000
+#define RXCFG (CMD_BASE + 0x0030)
+ #define RXBUFF_PROTECT 0x00000001
+ #define RXTCPCRC_CHECK 0x00000010
+ #define RXFLOW_ENABLE 0x00000100
+ #define DEFAULT_RXCFG RXBUFF_PROTECT
+#define RXCURT (CMD_BASE + 0x0034)
+ #define DEFAULT_RXCURT 0x00000000
+#define RXBOUND (CMD_BASE + 0x0038)
+ #define DEFAULT_RXBOUND 0x7FF //RX pages 0~7FFh
+#define MACCFG0 (CMD_BASE + 0x0040)
+ #define MACCFG0_BIT3_0 0x00000007
+ #define IPGT_VAL 0x00000150
+ #define TXFLOW_ENABLE 0x00001000
+ #define SPEED100 0x00008000
+ #define DEFAULT_MACCFG0 (IPGT_VAL | MACCFG0_BIT3_0)
+#define MACCFG1 (CMD_BASE + 0x0044)
+ #define RGMII_EN 0x00000002
+ #define RXFLOW_EN 0x00000020
+ #define FULLDUPLEX 0x00000040
+ #define MAX_JUMBO_LEN_MASK 0x00000780
+ #define RXJUMBO_EN 0x00000800
+ #define GIGA_MODE_EN 0x00001000
+ #define RXCRC_CHECK 0x00002000
+ #define RXPAUSE_DA_CHECK 0x00004000
+
+ #define JUMBO_LEN_4K 0x00000200
+ #define JUMBO_LEN_15K 0x00000780
+ #define DEFAULT_MACCFG1 (RXCRC_CHECK | RXPAUSE_DA_CHECK |\
+ RGMII_EN)
+ #define CICADA_DEFAULT_MACCFG1 (RXCRC_CHECK | RXPAUSE_DA_CHECK)
+#define MACCFG2 (CMD_BASE + 0x0048)
+ #define MACCFG2_BIT15_8 0x00000100
+ #define JAM_LIMIT_MASK 0x000000FC
+ #define DEFAULT_JAM_LIMIT 0x00000064
+ #define DEFAULT_MACCFG2 MACCFG2_BIT15_8
+#define MACCFG3 (CMD_BASE + 0x004C)
+ #define IPGR2_VAL 0x0000000E
+ #define IPGR1_VAL 0x00000600
+ #define NOABORT 0x00008000
+ #define DEFAULT_MACCFG3 (IPGR1_VAL | IPGR2_VAL)
+#define TXPAUT (CMD_BASE + 0x0054)
+ #define DEFAULT_TXPAUT 0x001FE000
+#define RXBTHD0 (CMD_BASE + 0x0058)
+ #define DEFAULT_RXBTHD0 0x00000300
+#define RXBTHD1 (CMD_BASE + 0x005C)
+ #define DEFAULT_RXBTHD1 0x00000600
+#define RXFULTHD (CMD_BASE + 0x0060)
+ #define DEFAULT_RXFULTHD 0x00000100
+#define MISC (CMD_BASE + 0x0068)
+ /* Normal operation mode */
+ #define MISC_NORMAL 0x00000003
+ /* Clear bit 0 to reset MAC */
+ #define MISC_RESET_MAC 0x00000002
+ /* Clear bit 1 to reset PHY */
+ #define MISC_RESET_PHY 0x00000001
+ /* Clear bit 0 and 1 to reset MAC and PHY */
+ #define MISC_RESET_MAC_PHY 0x00000000
+ #define DEFAULT_MISC MISC_NORMAL
+#define MACID0 (CMD_BASE + 0x0070)
+#define MACID1 (CMD_BASE + 0x0074)
+#define MACID2 (CMD_BASE + 0x0078)
+#define TXLEN (CMD_BASE + 0x007C)
+ #define DEFAULT_TXLEN 0x000005FC
+#define RXFILTER (CMD_BASE + 0x0080)
+ #define RX_RXANY 0x00000001
+ #define RX_MULTICAST 0x00000002
+ #define RX_UNICAST 0x00000004
+ #define RX_BROADCAST 0x00000008
+ #define RX_MULTI_HASH 0x00000010
+ #define DISABLE_RXFILTER 0x00000000
+ #define DEFAULT_RXFILTER (RX_BROADCAST + RX_UNICAST)
+#define MDIOCTRL (CMD_BASE + 0x0084)
+ #define PHY_ADDR_MASK 0x0000001F
+ #define REG_ADDR_MASK 0x00001F00
+ #define READ_PHY 0x00004000
+ #define WRITE_PHY 0x00008000
+#define MDIODP (CMD_BASE + 0x0088)
+#define GPIOCTRL (CMD_BASE + 0x008C)
+#define RXINDICATOR (CMD_BASE + 0x0090)
+ #define RX_START_READ 0x00000001
+ #define RX_STOP_READ 0x00000000
+ #define DEFAULT_RXINDICATOR RX_STOP_READ
+#define TXST (CMD_BASE + 0x0094)
+#define MDCCLKPAT (CMD_BASE + 0x00A0)
+#define RXIPCRCCNT (CMD_BASE + 0x00A4)
+#define RXCRCCNT (CMD_BASE + 0x00A8)
+#define TXFAILCNT (CMD_BASE + 0x00AC)
+#define PROMDP (CMD_BASE + 0x00B0)
+#define PROMCTRL (CMD_BASE + 0x00B4)
+ #define RELOAD_EEPROM 0x00000200
+#define MAXRXLEN (CMD_BASE + 0x00B8)
+#define HASHTAB0 (CMD_BASE + 0x00C0)
+#define HASHTAB1 (CMD_BASE + 0x00C4)
+#define HASHTAB2 (CMD_BASE + 0x00C8)
+#define HASHTAB3 (CMD_BASE + 0x00CC)
+#define DOGTHD0 (CMD_BASE + 0x00E0)
+ #define DEFAULT_DOGTHD0 0x0000FFFF
+#define DOGTHD1 (CMD_BASE + 0x00E4)
+ #define START_WATCHDOG_TIMER 0x00008000
+ #define DEFAULT_DOGTHD1 0x00000FFF
+#define SOFTRST (CMD_BASE + 0x00EC)
+ #define SOFTRST_NORMAL 0x00000003
+ #define SOFTRST_RESET_MAC 0x00000002
+
+/* External PHY Register Definition */
+#define BMCR 0x0000
+ #define LINE_SPEED_MSB 0x0040
+ #define DUPLEX_MODE 0x0100
+ #define RESTART_AUTONEG 0x0200
+ #define POWER_DOWN 0x0800
+ #define AUTONEG_EN 0x1000
+ #define LINE_SPEED_LSB 0x2000
+ #define PHY_RESET 0x8000
+
+ #define MEDIAMODE_MASK (LINE_SPEED_MSB | LINE_SPEED_LSB |\
+ DUPLEX_MODE)
+ #define BMCR_SPEED_1000 LINE_SPEED_MSB
+ #define BMCR_SPEED_100 LINE_SPEED_LSB
+ #define BMCR_SPEED_10 0x0000
+
+ #define BMCR_1000FULL (BMCR_SPEED_1000 | DUPLEX_MODE)
+ #define BMCR_100FULL (BMCR_SPEED_100 | DUPLEX_MODE)
+ #define BMCR_100HALF BMCR_SPEED_100
+ #define BMCR_10FULL DUPLEX_MODE
+ #define BMCR_10HALF 0x0000
+#define BMSR 0x0001
+ #define LINKOK 0x0004
+ #define AUTONEG_ENABLE_STS 0x0008
+ #define AUTONEG_COMPLETE 0x0020
+#define PHYIDR0 0x0002
+#define PHYIDR1 0x0003
+#define ANAR 0x0004
+ #define ANAR_PAUSE 0x0400
+ #define ANAR_100FULL 0x0100
+ #define ANAR_100HALF 0x0080
+ #define ANAR_10FULL 0x0040
+ #define ANAR_10HALF 0x0020
+ #define ANAR_8023BIT 0x0001
+#define ANLPAR 0x0005
+#define ANER 0x0006
+#define AUX_1000_CTRL 0x0009
+ #define ENABLE_1000HALF 0x0100
+ #define ENABLE_1000FULL 0x0200
+ #define DEFAULT_AUX_1000_CTRL (ENABLE_1000HALF | ENABLE_1000FULL)
+#define AUX_1000_STATUS 0x000A
+ #define LP_1000HALF 0x0400
+ #define LP_1000FULL 0x0800
+
+/* Marvell 88E1111 Gigabit PHY Register Definition */
+#define M88_SSR 0x0011
+ #define SSR_SPEED_MASK 0xC000
+ #define SSR_SPEED_1000 0x8000
+ #define SSR_SPEED_100 0x4000
+ #define SSR_SPEED_10 0x0000
+ #define SSR_DUPLEX 0x2000
+ #define SSR_MEDIA_RESOLVED_OK 0x0800
+
+ #define SSR_MEDIA_MASK (SSR_SPEED_MASK | SSR_DUPLEX)
+ #define SSR_1000FULL (SSR_SPEED_1000 | SSR_DUPLEX)
+ #define SSR_1000HALF SSR_SPEED_1000
+ #define SSR_100FULL (SSR_SPEED_100 | SSR_DUPLEX)
+ #define SSR_100HALF SSR_SPEED_100
+ #define SSR_10FULL (SSR_SPEED_10 | SSR_DUPLEX)
+ #define SSR_10HALF SSR_SPEED_10
+#define M88_IER 0x0012
+ #define LINK_CHANGE_INT 0x0400
+#define M88_ISR 0x0013
+ #define LINK_CHANGE_STATUS 0x0400
+#define M88_EXT_SCR 0x0014
+ #define RGMII_RXCLK_DELAY 0x0080
+ #define RGMII_TXCLK_DELAY 0x0002
+ #define DEFAULT_EXT_SCR (RGMII_TXCLK_DELAY | RGMII_RXCLK_DELAY)
+#define M88_EXT_SSR 0x001B
+ #define HWCFG_MODE_MASK 0x000F
+ #define RGMII_COPPER_MODE 0x000B
+
+/* CICADA CIS8201 Gigabit PHY Register Definition */
+#define CIS_IMR 0x0019
+ #define CIS_INT_ENABLE 0x8000
+ #define CIS_LINK_CHANGE_INT 0x2000
+#define CIS_ISR 0x001A
+ #define CIS_INT_PENDING 0x8000
+ #define CIS_LINK_CHANGE_STATUS 0x2000
+#define CIS_AUX_CTRL_STATUS 0x001C
+ #define CIS_AUTONEG_COMPLETE 0x8000
+ #define CIS_SPEED_MASK 0x0018
+ #define CIS_SPEED_1000 0x0010
+ #define CIS_SPEED_100 0x0008
+ #define CIS_SPEED_10 0x0000
+ #define CIS_DUPLEX 0x0020
+
+ #define CIS_MEDIA_MASK (CIS_SPEED_MASK | CIS_DUPLEX)
+ #define CIS_1000FULL (CIS_SPEED_1000 | CIS_DUPLEX)
+ #define CIS_1000HALF CIS_SPEED_1000
+ #define CIS_100FULL (CIS_SPEED_100 | CIS_DUPLEX)
+ #define CIS_100HALF CIS_SPEED_100
+ #define CIS_10FULL (CIS_SPEED_10 | CIS_DUPLEX)
+ #define CIS_10HALF CIS_SPEED_10
+ #define CIS_SMI_PRIORITY 0x0004
+
+/* Debug Message Display Level Definition */
+#define TX_MSG 0x0001
+#define RX_MSG 0x0002
+#define INT_MSG 0x0004
+#define DEBUG_MSG 0x0008
+#define NO_MSG 0x0000
+#define DEBUG_FLAGS (NO_MSG)
+
+#define PRINTK(flag, args...) if (flag & DEBUG_FLAGS) printf (args)
+
+/*
+ Access RXBUFFER_START/TXBUFFER_START to read RX buffer/write TX buffer
+*/
+#if defined (CONFIG_DRIVER_AX88180_16BIT)
+#define READ_RXBUF(data) \
+ do { \
+ data = *(volatile unsigned short *) \
+ (AX88180_BASE + RXBUFFER_START); \
+ } while (0)
+
+#define WRITE_TXBUF(data) \
+ do { \
+ *(volatile unsigned short *)(AX88180_BASE + TXBUFFER_START) \
+ = data; \
+ } while (0)
+
+#define READ_MACREG(regaddr, regdata) \
+ do { \
+ regdata = *(volatile unsigned short *) \
+ (AX88180_BASE + regaddr); \
+ } while (0)
+
+#define WRITE_MACREG(regaddr, regdata) \
+ do { \
+ *(volatile unsigned short*)(AX88180_BASE + regaddr) \
+ = regdata; \
+ } while (0)
+#else
+#define READ_RXBUF(data) \
+ do { \
+ data = *(volatile unsigned long *) \
+ (AX88180_BASE + RXBUFFER_START); \
+ } while (0)
+
+#define WRITE_TXBUF(data) \
+ do { \
+ *(volatile unsigned long *)(AX88180_BASE + TXBUFFER_START) \
+ = data; \
+ } while (0)
+
+#define READ_MACREG(regaddr, regdata) \
+ do { \
+ regdata = *(volatile unsigned long*)(AX88180_BASE + regaddr); \
+ } while (0)
+
+#define WRITE_MACREG(regaddr, regdata) \
+ do { \
+ *(volatile unsigned long*)(AX88180_BASE + regaddr) \
+ = regdata; \
+ } while (0)
+#endif /* end of CONFIG_DRIVER_AX88180_16BIT */
+
+#endif /*end of CONFIG_DRIVER_AX88180 */
--
1.5.4.5
6
12
* Cleaned up asm-arm/sizes.h.
* Removed sloppy copies of the above file in several arch subdirectories.
Signed-off-by: Adrian Filipi <adrian.filipi(a)eurotech.com>
---
include/asm-arm/arch-arm925t/sizes.h | 50
----------------------------
include/asm-arm/arch-arm926ejs/sizes.h | 51
-----------------------------
include/asm-arm/arch-omap/sizes.h | 52
------------------------------
include/asm-arm/arch-omap24xx/omap2420.h | 2 +-
include/asm-arm/arch-omap24xx/sizes.h | 49
----------------------------
include/asm-arm/sizes.h | 51
++++++++++++++---------------
include/configs/h2_p2_dbg_board.h | 2 +-
include/configs/omap1510.h | 2 +-
include/configs/omap730.h | 2 +-
9 files changed, 28 insertions(+), 233 deletions(-)
delete mode 100644 include/asm-arm/arch-arm925t/sizes.h
delete mode 100644 include/asm-arm/arch-arm926ejs/sizes.h
delete mode 100644 include/asm-arm/arch-omap/sizes.h
delete mode 100644 include/asm-arm/arch-omap24xx/sizes.h
diff --git a/include/asm-arm/arch-arm925t/sizes.h
b/include/asm-arm/arch-arm925t/sizes.h
deleted file mode 100644
index 7319bd9..0000000
--- a/include/asm-arm/arch-arm925t/sizes.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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
- */
-/* DO NOT EDIT!! - this file automatically generated
- * from .s file by awk -f s2h.awk
- */
-/* Size defintions
- * Copyright (C) ARM Limited 1998. All rights reserved.
- */
-
-#ifndef __sizes_h
-#define __sizes_h 1
-
-/* handy sizes */
-#define SZ_1K 0x00000400
-#define SZ_4K 0x00001000
-#define SZ_8K 0x00002000
-#define SZ_16K 0x00004000
-#define SZ_64K 0x00010000
-#define SZ_128K 0x00020000
-#define SZ_256K 0x00040000
-#define SZ_512K 0x00080000
-
-#define SZ_1M 0x00100000
-#define SZ_2M 0x00200000
-#define SZ_4M 0x00400000
-#define SZ_8M 0x00800000
-#define SZ_16M 0x01000000
-#define SZ_32M 0x02000000
-#define SZ_64M 0x04000000
-#define SZ_128M 0x08000000
-#define SZ_256M 0x10000000
-#define SZ_512M 0x20000000
-
-#define SZ_1G 0x40000000
-#define SZ_2G 0x80000000
-
-#endif /* __sizes_h */
diff --git a/include/asm-arm/arch-arm926ejs/sizes.h
b/include/asm-arm/arch-arm926ejs/sizes.h
deleted file mode 100644
index ef0b99b..0000000
--- a/include/asm-arm/arch-arm926ejs/sizes.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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, MA0 2111-1307
- * USA
- */
-/* DO NOT EDIT!! - this file automatically generated
- * from .s file by awk -f s2h.awk
- */
-/* Size defintions
- * Copyright (C) ARM Limited 1998. All rights reserved.
- */
-
-#ifndef __sizes_h
-#define __sizes_h 1
-
-/* handy sizes */
-#define SZ_1K 0x00000400
-#define SZ_4K 0x00001000
-#define SZ_8K 0x00002000
-#define SZ_16K 0x00004000
-#define SZ_64K 0x00010000
-#define SZ_128K 0x00020000
-#define SZ_256K 0x00040000
-#define SZ_512K 0x00080000
-
-#define SZ_1M 0x00100000
-#define SZ_2M 0x00200000
-#define SZ_4M 0x00400000
-#define SZ_8M 0x00800000
-#define SZ_16M 0x01000000
-#define SZ_32M 0x02000000
-#define SZ_64M 0x04000000
-#define SZ_128M 0x08000000
-#define SZ_256M 0x10000000
-#define SZ_512M 0x20000000
-
-#define SZ_1G 0x40000000
-#define SZ_2G 0x80000000
-
-#endif /* __sizes_h */
diff --git a/include/asm-arm/arch-omap/sizes.h
b/include/asm-arm/arch-omap/sizes.h
deleted file mode 100644
index f8d92ca..0000000
--- a/include/asm-arm/arch-omap/sizes.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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
- */
-/* DO NOT EDIT!! - this file automatically generated
- * from .s file by awk -f s2h.awk
- */
-/* Size defintions
- * Copyright (C) ARM Limited 1998. All rights reserved.
- */
-
-#ifndef __sizes_h
-#define __sizes_h 1
-
-/* handy sizes */
-#define SZ_1K 0x00000400
-#define SZ_4K 0x00001000
-#define SZ_8K 0x00002000
-#define SZ_16K 0x00004000
-#define SZ_64K 0x00010000
-#define SZ_128K 0x00020000
-#define SZ_256K 0x00040000
-#define SZ_512K 0x00080000
-
-#define SZ_1M 0x00100000
-#define SZ_2M 0x00200000
-#define SZ_4M 0x00400000
-#define SZ_8M 0x00800000
-#define SZ_16M 0x01000000
-#define SZ_32M 0x02000000
-#define SZ_64M 0x04000000
-#define SZ_128M 0x08000000
-#define SZ_256M 0x10000000
-#define SZ_512M 0x20000000
-
-#define SZ_1G 0x40000000
-#define SZ_2G 0x80000000
-
-#endif
-
-/* END */
diff --git a/include/asm-arm/arch-omap24xx/omap2420.h
b/include/asm-arm/arch-omap24xx/omap2420.h
index 0c11bec..6032419 100644
--- a/include/asm-arm/arch-omap24xx/omap2420.h
+++ b/include/asm-arm/arch-omap24xx/omap2420.h
@@ -25,7 +25,7 @@
#ifndef _OMAP2420_SYS_H_
#define _OMAP2420_SYS_H_
-#include <asm/arch/sizes.h>
+#include <asm/sizes.h>
/*
* 2420 specific Section
diff --git a/include/asm-arm/arch-omap24xx/sizes.h
b/include/asm-arm/arch-omap24xx/sizes.h
deleted file mode 100644
index aaba18f..0000000
--- a/include/asm-arm/arch-omap24xx/sizes.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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
- */
-/* Size defintions
- * Copyright (C) ARM Limited 1998. All rights reserved.
- */
-
-#ifndef __sizes_h
-#define __sizes_h 1
-
-/* handy sizes */
-#define SZ_1K 0x00000400
-#define SZ_4K 0x00001000
-#define SZ_8K 0x00002000
-#define SZ_16K 0x00004000
-#define SZ_32K 0x00008000
-#define SZ_64K 0x00010000
-#define SZ_128K 0x00020000
-#define SZ_256K 0x00040000
-#define SZ_512K 0x00080000
-
-#define SZ_1M 0x00100000
-#define SZ_2M 0x00200000
-#define SZ_4M 0x00400000
-#define SZ_8M 0x00800000
-#define SZ_16M 0x01000000
-#define SZ_31M 0x01F00000
-#define SZ_32M 0x02000000
-#define SZ_64M 0x04000000
-#define SZ_128M 0x08000000
-#define SZ_256M 0x10000000
-#define SZ_512M 0x20000000
-
-#define SZ_1G 0x40000000
-#define SZ_2G 0x80000000
-
-#endif /* __sizes_h */
diff --git a/include/asm-arm/sizes.h b/include/asm-arm/sizes.h
index f8d92ca..1ffb327 100644
--- a/include/asm-arm/sizes.h
+++ b/include/asm-arm/sizes.h
@@ -13,40 +13,37 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
*/
-/* DO NOT EDIT!! - this file automatically generated
- * from .s file by awk -f s2h.awk
- */
/* Size defintions
* Copyright (C) ARM Limited 1998. All rights reserved.
*/
#ifndef __sizes_h
-#define __sizes_h 1
+#define __sizes_h 1
/* handy sizes */
-#define SZ_1K 0x00000400
-#define SZ_4K 0x00001000
-#define SZ_8K 0x00002000
-#define SZ_16K 0x00004000
-#define SZ_64K 0x00010000
-#define SZ_128K 0x00020000
-#define SZ_256K 0x00040000
-#define SZ_512K 0x00080000
-
-#define SZ_1M 0x00100000
-#define SZ_2M 0x00200000
-#define SZ_4M 0x00400000
-#define SZ_8M 0x00800000
-#define SZ_16M 0x01000000
-#define SZ_32M 0x02000000
-#define SZ_64M 0x04000000
-#define SZ_128M 0x08000000
-#define SZ_256M 0x10000000
-#define SZ_512M 0x20000000
+#define SZ_1K 0x00000400
+#define SZ_4K 0x00001000
+#define SZ_8K 0x00002000
+#define SZ_16K 0x00004000
+#define SZ_32K 0x00008000
+#define SZ_64K 0x00010000
+#define SZ_128K 0x00020000
+#define SZ_256K 0x00040000
+#define SZ_512K 0x00080000
-#define SZ_1G 0x40000000
-#define SZ_2G 0x80000000
+#define SZ_1M 0x00100000
+#define SZ_2M 0x00200000
+#define SZ_4M 0x00400000
+#define SZ_8M 0x00800000
+#define SZ_16M 0x01000000
+#define SZ_31M 0x01F00000
+#define SZ_32M 0x02000000
+#define SZ_64M 0x04000000
+#define SZ_128M 0x08000000
+#define SZ_256M 0x10000000
+#define SZ_512M 0x20000000
-#endif
+#define SZ_1G 0x40000000
+#define SZ_2G 0x80000000
-/* END */
+#endif /* __sizes_h */
diff --git a/include/configs/h2_p2_dbg_board.h
b/include/configs/h2_p2_dbg_board.h
index e0d823f..a4dea7d 100644
--- a/include/configs/h2_p2_dbg_board.h
+++ b/include/configs/h2_p2_dbg_board.h
@@ -31,7 +31,7 @@
#ifndef __INCLUDED_H2_P2_DBH_BOARD_H
#define __INCLUDED_H2_P2_DBH_BOARD_H
-#include <asm/arch/sizes.h>
+#include <asm/sizes.h>
/*
* The Debug board is designed to function with the P2 Sample, H2
diff --git a/include/configs/omap1510.h b/include/configs/omap1510.h
index 6787b19..9979453 100644
--- a/include/configs/omap1510.h
+++ b/include/configs/omap1510.h
@@ -28,7 +28,7 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <asm/arch/sizes.h>
+#include <asm/sizes.h>
/*
There are 2 sets of general I/O -->
diff --git a/include/configs/omap730.h b/include/configs/omap730.h
index 03abcb3..2d11d50 100644
--- a/include/configs/omap730.h
+++ b/include/configs/omap730.h
@@ -31,7 +31,7 @@
#ifndef __INCLUDED_OMAP730_H
#define __INCLUDED_OMAP730_H
-#include <asm/arch/sizes.h>
+#include <asm/sizes.h>
/***************************************************************************
* OMAP730 Configuration Registers
--
1.5.6
2
3
Hello u-boot-users,
I am currently in the process of developing a new driver in U-Boot. It
is a software "virtual ethernet over PCI" driver. The driver itself is
largely irrelevant for this problem.
During the development, I noticed that adding and removing certain
pieces of debugging code (which did not change any program state) caused
the board to hang on boot, like so:
================================================================================
U-Boot 1.3.4-rc1-00001-gb89881c-dirty (Jul 16 2008 - 14:54:56) MPC83XX
Reset Status: External/Internal Soft, External/Internal Hard
CPU: e300c1, MPC8349EA, Rev: 3.0 at 528 MHz, CSB: 264 MHz
Board: Freescale MPC8349EMDS
I2C:
As opposed to a normal boot:
================================================================================
U-Boot 1.3.4-rc1-00001-g8ff17d3-dirty (Jul 16 2008 - 12:00:01) MPC83XX
Reset Status: External/Internal Soft, External/Internal Hard
CPU: e300c1, MPC8349EA, Rev: 3.0 at 528 MHz, CSB: 264 MHz
Board: Freescale MPC8349EMDS
I2C: ready
SPI: ready
DRAM: 256 MB (DDR2, 64-bit, ECC on, 264 MHz)
FLASH: 32 MB
In: serial
Out: serial
Err: serial
Net: TSEC0, TSEC1
Type "run flash_nfs" to mount root filesystem over NFS
I have tried to narrow the problem down as much as possible, by removing
as much of my code as possible. I succeeded in reproducing the problem
using code that seemingly "does nothing wrong". The inlined patch is
against U-Boot v1.3.4-rc1
During my testing, it seemed that elf section alignment in the image
mattered. I took a broken, non-booting image and saved the section
offsets. They are reproduced below, generated with:
$ powerpc-linux-strip u-boot
$ powerpc-linux-readelf -e u-boot
Here is the output of the readelf command for my bad image:
================================================================================
ELF Header:
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, big endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: PowerPC
Version: 0x1
Entry point address: 0xfe000100
Start of program headers: 52 (bytes into file)
Start of section headers: 225328 (bytes into file)
Flags: 0x8000, relocatable-lib
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 2
Size of section headers: 40 (bytes)
Number of section headers: 12
Section header string table index: 11
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS fe000000 000078 032c50 00 AX 0 0 4
[ 2] .reloc PROGBITS fe033000 033078 0014c0 00 WA 0 0 1
[ 3] .data PROGBITS fe0344c0 034538 000bdc 00 WA 0 0 4
[ 4] .data.rel.ro.loca PROGBITS fe03509c 035114 000078 00 WA 0 0 4
[ 5] .data.rel PROGBITS fe035114 03518c 000710 00 WA 0 0 4
[ 6] data PROGBITS fe035824 03589c 000004 00 WA 0 0 4
[ 7] .data.rel.local PROGBITS fe035828 0358a0 000be4 00 WA 0 0 4
[ 8] .u_boot_cmd PROGBITS fe03640c 036484 000570 00 WA 0 0 4
[ 9] .bss NOBITS fe037000 000000 0068e0 00 WA 0 0 8
[10] .comment PROGBITS 00000000 0369f4 0005d6 00 0 0 1
[11] .shstrtab STRTAB 00000000 036fca 000065 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000078 0xfe000000 0xfe000000 0x3697c 0x3697c RWE 0x8
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
Section to Segment mapping:
Segment Sections...
00 .text .reloc .data .data.rel.ro.local .data.rel data .data.rel.local .u_boot_cmd
01
The part I found important was the size of each section. The .bss,
.comment, and .shstrtab don't seem to matter (but I may be wrong!)
I wrote some code that went into the appropriate sections to get the
sizes I needed. This is why there are lots of "a" in the patch (to boost
the .data section) and the extern variables (to boost the .reloc
section) and the extern variables with values (to boost the data section).
I also did my best to trim down the code that was added in
board/freescale/mpc8349emds/mpc8394emds.c checkboard(). In my original
code, all of the code is there. I left it there in the patch, but
#if 0'd out all of the parts that made no difference.
Removing the BCSR read does seem to fix the problem (while concurrently
adjusting the padding bits until the sections are the correct size). I
see nothing wrong with the BCSR read, and it may just be another
unrelated symptom.
Here is the readelf output on my non-working U-Boot binary (produced
from v1.3.4-rc1 + the attached patch), produced using the exact same
procedure as above:
================================================================================
ELF Header:
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, big endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: PowerPC
Version: 0x1
Entry point address: 0xfe000100
Start of program headers: 52 (bytes into file)
Start of section headers: 225232 (bytes into file)
Flags: 0x8000, relocatable-lib
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 2
Size of section headers: 40 (bytes)
Number of section headers: 12
Section header string table index: 11
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS fe000000 000078 032c50 00 AX 0 0 4
[ 2] .reloc PROGBITS fe033000 033078 0014c0 00 WA 0 0 1
[ 3] .data PROGBITS fe0344c0 034538 000bdc 00 WA 0 0 4
[ 4] .data.rel.ro.loca PROGBITS fe03509c 035114 000078 00 WA 0 0 4
[ 5] .data.rel PROGBITS fe035114 03518c 000710 00 WA 0 0 4
[ 6] data PROGBITS fe035824 03589c 000004 00 WA 0 0 4
[ 7] .data.rel.local PROGBITS fe035828 0358a0 000be4 00 WA 0 0 4
[ 8] .u_boot_cmd PROGBITS fe03640c 036484 000558 00 WA 0 0 4
[ 9] .bss NOBITS fe037000 000000 0068f0 00 WA 0 0 8
[10] .comment PROGBITS 00000000 0369dc 00058e 00 0 0 1
[11] .shstrtab STRTAB 00000000 036f6a 000065 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000078 0xfe000000 0xfe000000 0x36964 0x36964 RWE 0x8
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
Section to Segment mapping:
Segment Sections...
00 .text .reloc .data .data.rel.ro.local .data.rel data .data.rel.local .u_boot_cmd
01
I built U-Boot using ELDK-4.2, using the following:
$ make mrproper
$ make MPC8349EMDS_config
My board is a Freescale MPC8349EMDS evaluation board.
If you need any more information, I am happy to provide it.
I appreciate any help in tracking down this problem,
Ira Snyder
Here is the patch (I apologize for the 100 character "a" lines, but they
made counting the correct number much easier)
================================================================================
>From c537102983b207ad0855309aeb214a5a08cb0a4e Mon Sep 17 00:00:00 2001
From: Ira W. Snyder <iws(a)ovro.caltech.edu>
Date: Wed, 16 Jul 2008 11:58:16 -0700
Subject: [PATCH] Simplified brokenness
This patch breaks the MPC8349EMDS board boot, using as simple of
code as I could manage to find.
Signed-off-by: Ira W. Snyder <iws(a)ovro.caltech.edu>
---
board/freescale/mpc8349emds/mpc8349emds.c | 21 ++
cpu/mpc83xx/cpu.c | 2 +
drivers/net/Makefile | 1 +
drivers/net/pcinet.c | 428 +++++++++++++++++++++++++++++
drivers/net/pcinet2.c | 133 +++++++++
5 files changed, 585 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/pcinet.c
create mode 100644 drivers/net/pcinet2.c
diff --git a/board/freescale/mpc8349emds/mpc8349emds.c b/board/freescale/mpc8349emds/mpc8349emds.c
index 9a312c3..5c110c9 100644
--- a/board/freescale/mpc8349emds/mpc8349emds.c
+++ b/board/freescale/mpc8349emds/mpc8349emds.c
@@ -165,7 +165,28 @@ int fixed_sdram(void)
int checkboard (void)
{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ volatile u8 *bcsr = (u8 *)CFG_BCSR;
+ int host;
+ int in_pci_slot;
+
+#if 0
+ /* host or agent mode */
+ host = (immr->reset.rcwh & HRCWH_PCI_HOST) ? 1 : 0;
+#endif
+
+#if 1
+ /* in a pci slot or standalone */
+ in_pci_slot = (bcsr[10] & 0x80) ? 1 : 0;
+#endif
+
puts("Board: Freescale MPC8349EMDS\n");
+
+#if 0
+ printf("Mode: %s, %s\n",
+ host ? "Host" : "Agent",
+ in_pci_slot ? "in PCI slot" : "standalone");
+#endif
return 0;
}
diff --git a/cpu/mpc83xx/cpu.c b/cpu/mpc83xx/cpu.c
index 52e4476..5c68e2a 100644
--- a/cpu/mpc83xx/cpu.c
+++ b/cpu/mpc83xx/cpu.c
@@ -365,6 +365,7 @@ int dma_xfer(void *dest, u32 count, void *src)
*/
extern int tsec_initialize(bd_t * bis, int index, char *devname);
+extern int pcinet_initialize(bd_t *bis, int index, char *devname);
int cpu_eth_init(bd_t *bis)
{
@@ -374,6 +375,7 @@ int cpu_eth_init(bd_t *bis)
#if defined(CONFIG_TSEC2)
tsec_initialize(bis, 1, CONFIG_TSEC2_NAME);
#endif
+ pcinet_initialize(bis, 0, "pcinet");
return 0;
}
#endif
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index bcf31cb..3ce13c2 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -51,6 +51,7 @@ COBJS-$(CONFIG_NETCONSOLE) += netconsole.o
COBJS-$(CONFIG_DRIVER_NS7520_ETHERNET) += ns7520_eth.o
COBJS-$(CONFIG_NS8382X) += ns8382x.o
COBJS-$(CONFIG_DRIVER_NS9750_ETHERNET) += ns9750_eth.o
+COBJS-y += pcinet.o pcinet2.o
COBJS-$(CONFIG_PCNET) += pcnet.o
COBJS-$(CONFIG_PLB2800_ETHER) += plb2800_eth.o
COBJS-$(CONFIG_DRIVER_RTL8019) += rtl8019.o
diff --git a/drivers/net/pcinet.c b/drivers/net/pcinet.c
new file mode 100644
index 0000000..abfab48
--- /dev/null
+++ b/drivers/net/pcinet.c
@@ -0,0 +1,428 @@
+/*
+ * PCINet Virtual Ethernet over PCI driver
+ *
+ * This software may be used and distributed according to the
+ * terms of the GNU General Public License, Version 2, incorporated
+ * herein by reference.
+ *
+ * Copyright (c) 2008, Ira W. Snyder <iws(a)ovro.caltech.edu>
+ */
+
+#include <config.h>
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <command.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/atomic.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+const char longstring[] =
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+;
+
+extern volatile int pcinet_i1 = 1234;
+extern volatile int pcinet_i2;
+extern volatile int pcinet_i3;
+extern volatile int pcinet_i4;
+extern volatile int pcinet_i5;
+extern volatile int pcinet_i6;
+extern volatile int pcinet_i7;
+extern volatile int pcinet_i8;
+extern volatile int pcinet_i9;
+extern volatile int pcinet_i10;
+extern volatile int pcinet_i11;
+extern volatile int pcinet_i12;
+extern volatile int pcinet_i13;
+extern volatile int pcinet_i14;
+extern volatile int pcinet_i15;
+extern volatile int pcinet_i16;
+extern volatile int pcinet_i17;
+extern volatile int pcinet_i18;
+extern volatile int pcinet_i19;
+extern volatile int pcinet_i20;
+extern volatile int pcinet_i21;
+extern volatile int pcinet_i22;
+extern volatile int pcinet_i23;
+extern volatile int pcinet_i24;
+extern volatile int pcinet_i25;
+extern volatile int pcinet_i26;
+extern volatile int pcinet_i27;
+extern volatile int pcinet_i28;
+extern volatile int pcinet_i29;
+extern volatile int pcinet_i30;
+extern volatile int pcinet_i31;
+extern volatile int pcinet_i32;
+extern volatile int pcinet_i33;
+extern volatile int pcinet_i34;
+extern volatile int pcinet_i35;
+extern volatile int pcinet_i36;
+extern volatile int pcinet_i37;
+extern volatile int pcinet_i38;
+extern volatile int pcinet_i39;
+extern volatile int pcinet_i40;
+extern volatile int pcinet_i41;
+extern volatile int pcinet_i42;
+extern volatile int pcinet_i43;
+extern volatile int pcinet_i44;
+extern volatile int pcinet_i45;
+extern volatile int pcinet_i46;
+extern volatile int pcinet_i47;
+extern volatile int pcinet_i48;
+extern volatile int pcinet_i49;
+extern volatile int pcinet_i50;
+extern volatile int pcinet_i51;
+extern volatile int pcinet_i52;
+extern volatile int pcinet_i53;
+extern volatile int pcinet_i54;
+extern volatile int pcinet_i55;
+extern volatile int pcinet_i56;
+extern volatile int pcinet_i57;
+extern volatile int pcinet_i58;
+extern volatile int pcinet_i59;
+extern volatile int pcinet_i60;
+extern volatile int pcinet_i61;
+extern volatile int pcinet_i62;
+extern volatile int pcinet_i63;
+extern volatile int pcinet_i64;
+extern volatile int pcinet_i65;
+extern volatile int pcinet_i66;
+extern volatile int pcinet_i67;
+extern volatile int pcinet_i68;
+extern volatile int pcinet_i69;
+extern volatile int pcinet_i70;
+extern volatile int pcinet_i71;
+extern volatile int pcinet_i72;
+extern volatile int pcinet_i73;
+extern volatile int pcinet_i74;
+extern volatile int pcinet_i75;
+extern volatile int pcinet_i76;
+extern volatile int pcinet_i77;
+extern volatile int pcinet_i78;
+extern volatile int pcinet_i79;
+extern volatile int pcinet_i80;
+extern volatile int pcinet_i81;
+extern volatile int pcinet_i82;
+extern volatile int pcinet_i83;
+extern volatile int pcinet_i84;
+extern volatile int pcinet_i85;
+extern volatile int pcinet_i86;
+extern volatile int pcinet_i87;
+extern volatile int pcinet_i88;
+extern volatile int pcinet_i89;
+extern volatile int pcinet_i90;
+extern volatile int pcinet_i91;
+extern volatile int pcinet_i92;
+extern volatile int pcinet_i93;
+extern volatile int pcinet_i94;
+extern volatile int pcinet_i95;
+extern volatile int pcinet_i96;
+extern volatile int pcinet_i97;
+extern volatile int pcinet_i98;
+extern volatile int pcinet_i99;
+extern volatile int pcinet_i100;
+extern volatile int pcinet_i101;
+extern volatile int pcinet_i102;
+extern volatile int pcinet_i103;
+extern volatile int pcinet_i104;
+extern volatile int pcinet_i105;
+extern volatile int pcinet_i106;
+extern volatile int pcinet_i107;
+extern volatile int pcinet_i108;
+extern volatile int pcinet_i109;
+extern volatile int pcinet_i110;
+extern volatile int pcinet_i111;
+extern volatile int pcinet_i112;
+extern volatile int pcinet_i113;
+extern volatile int pcinet_i114;
+extern volatile int pcinet_i115;
+extern volatile int pcinet_i116;
+extern volatile int pcinet_i117;
+extern volatile int pcinet_i118;
+
+/* Called from net/eth.c to start the ethernet controller */
+int pcinet_initialize (bd_t *bis, int index, char *devname)
+{
+ volatile void *p = malloc(8192);
+ volatile void *p2 = memalign(4096, 4096);
+ volatile int i = pcinet_i1;
+ i = pcinet_i2;
+ i = pcinet_i3;
+ i = pcinet_i4;
+ i = pcinet_i5;
+ i = pcinet_i6;
+ i = pcinet_i7;
+ i = pcinet_i8;
+ i = pcinet_i9;
+ i = pcinet_i10;
+ i = pcinet_i11;
+ i = pcinet_i12;
+ i = pcinet_i13;
+ i = pcinet_i14;
+ i = pcinet_i15;
+ i = pcinet_i16;
+ i = pcinet_i17;
+ i = pcinet_i18;
+ i = pcinet_i19;
+ i = pcinet_i20;
+ i = pcinet_i21;
+ i = pcinet_i22;
+ i = pcinet_i23;
+ i = pcinet_i24;
+ i = pcinet_i25;
+ i = pcinet_i26;
+ i = pcinet_i27;
+ i = pcinet_i28;
+ i = pcinet_i29;
+ i = pcinet_i30;
+ i = pcinet_i31;
+ i = pcinet_i32;
+ i = pcinet_i33;
+ i = pcinet_i34;
+ i = pcinet_i35;
+ i = pcinet_i36;
+ i = pcinet_i37;
+ i = pcinet_i38;
+ i = pcinet_i39;
+ i = pcinet_i40;
+ i = pcinet_i41;
+ i = pcinet_i42;
+ i = pcinet_i43;
+ i = pcinet_i44;
+ i = pcinet_i45;
+ i = pcinet_i46;
+ i = pcinet_i47;
+ i = pcinet_i48;
+ i = pcinet_i49;
+ i = pcinet_i50;
+ i = pcinet_i51;
+ i = pcinet_i52;
+ i = pcinet_i53;
+ i = pcinet_i54;
+ i = pcinet_i55;
+ i = pcinet_i56;
+ i = pcinet_i57;
+ i = pcinet_i58;
+ i = pcinet_i59;
+ i = pcinet_i60;
+ i = pcinet_i61;
+ i = pcinet_i62;
+ i = pcinet_i63;
+ i = pcinet_i64;
+ i = pcinet_i65;
+ i = pcinet_i66;
+ i = pcinet_i67;
+ i = pcinet_i68;
+ i = pcinet_i69;
+ i = pcinet_i70;
+ i = pcinet_i71;
+ i = pcinet_i72;
+ i = pcinet_i73;
+ i = pcinet_i74;
+ i = pcinet_i75;
+ i = pcinet_i76;
+ i = pcinet_i77;
+ i = pcinet_i78;
+ i = pcinet_i79;
+ i = pcinet_i80;
+ i = pcinet_i81;
+ i = pcinet_i82;
+ i = pcinet_i83;
+ i = pcinet_i84;
+ i = pcinet_i85;
+ i = pcinet_i86;
+ i = pcinet_i87;
+ i = pcinet_i88;
+ i = pcinet_i89;
+ i = pcinet_i90;
+ i = pcinet_i91;
+ i = pcinet_i92;
+ i = pcinet_i93;
+ i = pcinet_i94;
+ i = pcinet_i95;
+ i = pcinet_i96;
+ i = pcinet_i97;
+ i = pcinet_i98;
+ i = pcinet_i99;
+ i = pcinet_i100;
+ i = pcinet_i101;
+ i = pcinet_i102;
+ i = pcinet_i103;
+ i = pcinet_i104;
+ i = pcinet_i105;
+ i = pcinet_i106;
+ i = pcinet_i107;
+ i = pcinet_i108;
+ i = pcinet_i109;
+ i = pcinet_i110;
+ i = pcinet_i111;
+ i = pcinet_i112;
+ i = pcinet_i113;
+ i = pcinet_i114;
+ i = pcinet_i115;
+ i = pcinet_i116;
+ i = pcinet_i117;
+ i = pcinet_i118;
+
+ printf("PCINET INIT: Alloc @ 0x%p\n", p);
+
+ for (i=0; i<10000000; ++i)
+ if (i % 100000 == 0)
+ printf("i=%d\n", i);
+
+ return 0;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet tw=92: */
diff --git a/drivers/net/pcinet2.c b/drivers/net/pcinet2.c
new file mode 100644
index 0000000..cfdfd33
--- /dev/null
+++ b/drivers/net/pcinet2.c
@@ -0,0 +1,133 @@
+/*
+ * ONE-LINE DESCRIPTION
+ *
+ * Copyright (c) 2008 Ira W. Snyder <iws(a)ovro.caltech.edu>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/* if you add a non-zero initializer here, the space moves from the
+ * .bss to the .data section */
+volatile int pcinet_i1;
+volatile int pcinet_i2;
+volatile int pcinet_i3;
+volatile int pcinet_i4;
+volatile int pcinet_i5;
+volatile int pcinet_i6;
+volatile int pcinet_i7;
+volatile int pcinet_i8;
+volatile int pcinet_i9;
+volatile int pcinet_i10;
+volatile int pcinet_i11;
+volatile int pcinet_i12;
+volatile int pcinet_i13;
+volatile int pcinet_i14;
+volatile int pcinet_i15;
+volatile int pcinet_i16;
+volatile int pcinet_i17;
+volatile int pcinet_i18;
+volatile int pcinet_i19;
+volatile int pcinet_i20;
+volatile int pcinet_i21;
+volatile int pcinet_i22;
+volatile int pcinet_i23;
+volatile int pcinet_i24;
+volatile int pcinet_i25;
+volatile int pcinet_i26;
+volatile int pcinet_i27;
+volatile int pcinet_i28;
+volatile int pcinet_i29;
+volatile int pcinet_i30;
+volatile int pcinet_i31;
+volatile int pcinet_i32;
+volatile int pcinet_i33;
+volatile int pcinet_i34;
+volatile int pcinet_i35;
+volatile int pcinet_i36;
+volatile int pcinet_i37;
+volatile int pcinet_i38;
+volatile int pcinet_i39;
+volatile int pcinet_i40;
+volatile int pcinet_i41;
+volatile int pcinet_i42;
+volatile int pcinet_i43;
+volatile int pcinet_i44;
+volatile int pcinet_i45;
+volatile int pcinet_i46;
+volatile int pcinet_i47;
+volatile int pcinet_i48;
+volatile int pcinet_i49;
+volatile int pcinet_i50;
+volatile int pcinet_i51;
+volatile int pcinet_i52;
+volatile int pcinet_i53;
+volatile int pcinet_i54;
+volatile int pcinet_i55;
+volatile int pcinet_i56;
+volatile int pcinet_i57;
+volatile int pcinet_i58;
+volatile int pcinet_i59;
+volatile int pcinet_i60;
+volatile int pcinet_i61;
+volatile int pcinet_i62;
+volatile int pcinet_i63;
+volatile int pcinet_i64;
+volatile int pcinet_i65;
+volatile int pcinet_i66;
+volatile int pcinet_i67;
+volatile int pcinet_i68;
+volatile int pcinet_i69;
+volatile int pcinet_i70;
+volatile int pcinet_i71;
+volatile int pcinet_i72;
+volatile int pcinet_i73;
+volatile int pcinet_i74;
+volatile int pcinet_i75;
+volatile int pcinet_i76;
+volatile int pcinet_i77;
+volatile int pcinet_i78;
+volatile int pcinet_i79;
+volatile int pcinet_i80;
+volatile int pcinet_i81;
+volatile int pcinet_i82;
+volatile int pcinet_i83;
+volatile int pcinet_i84;
+volatile int pcinet_i85;
+volatile int pcinet_i86;
+volatile int pcinet_i87;
+volatile int pcinet_i88;
+volatile int pcinet_i89;
+volatile int pcinet_i90;
+volatile int pcinet_i91;
+volatile int pcinet_i92;
+volatile int pcinet_i93;
+volatile int pcinet_i94;
+volatile int pcinet_i95;
+volatile int pcinet_i96;
+volatile int pcinet_i97;
+volatile int pcinet_i98;
+volatile int pcinet_i99;
+volatile int pcinet_i100;
+volatile int pcinet_i101;
+volatile int pcinet_i102;
+volatile int pcinet_i103;
+volatile int pcinet_i104;
+volatile int pcinet_i105;
+volatile int pcinet_i106;
+volatile int pcinet_i107;
+volatile int pcinet_i108;
+volatile int pcinet_i109;
+volatile int pcinet_i110;
+volatile int pcinet_i111;
+volatile int pcinet_i112;
+volatile int pcinet_i113;
+volatile int pcinet_i114;
+volatile int pcinet_i115;
+volatile int pcinet_i116;
+volatile int pcinet_i117;
+volatile int pcinet_i118;
+
+
+/* vim: set ts=8 sts=8 sw=8 noet tw=92: */
--
1.5.4.3
8
30
Wolfgang,
I wonder if you would consider (and accept a patch) changing the
u-boot architecture as described below.
As we all are well aware u-boot is a great software package which
speeds up bringing up new hardware immensely, its popularity is
obviously growing very fast. One thing which (IMO anyway) slows down
its acceptance is the way it handles relocating of itself into an
arbitrary DRAM area. (Arbitrary meaning that it depends on many
factors and the exact address can't be assigned ahead of time).
While this relocation is seamless for u-boot in its released form, it
becomes a pain each time a module needs to be added (not necessarily
for following release to the Open Source community, for instance used
for inhouse installations which include tens of thousand units for
some companies). If these added modules were not written in position
independent manner (namely, using structures with multiple stage
indirect pointers interleaved with data), the effort to make these
modules work in u-boot is very exhausting.
Here is the suggested alternative. I will talk about recent PPC
platforms, but it could be done very similar for most of the other
platforms I believe.
In general the PPC u-boot image consists of three parts: the bulk of
code and data, the startup page (the top 4k mapped out of reset), and
the reset vector (the top four bytes in the address space). The bulk
is usually aligned at a certain address matching the bootprom size,
and there is a gap between the bulk and the startup page.
Now, let's say we link and purge the bulk section twice, once locating
it at offset 0 and once at the normal u-boot TEXT_BASE, building two
binary images (not including the top 4k in both cases).
Then we compare the two images and identify all locations which are
different. All these locations are 4 byte aligned, and all differ by
the same amount - equal TEXT_BASE. Now we can build a table of offsets
which need to be changed when the program is moved into a different
location, include this table in the resulting image between the bulk
and the startup page, and use this table when relocating code.
Basically, this implements a poor man's loader, and it will be
sufficient in case the image we are dealing with is a flat binary
(which is of course the case with u-boot). This will allow to add any
code to u-boot without much worries about being able to relocate it
properly. We would do away with storing certain structures in certain
sections, dealing with GOT, etc.
I made some experiments, and this seems feasible, this could be done
as a local customization, but I would much prefer to release it to the
u-boot community and make it part of mainline - will you consider such
a patch?
Thank you for reading this far, please let me know what you think,
Vadim
12
67

[U-Boot-Users] [PATCH RFC] ARM: Davinci: NAND fix for large page ECC and linux compatibility
by Bernard Blackham 08 Sep '08
by Bernard Blackham 08 Sep '08
08 Sep '08
U-boot's HW ECC support for large page NAND on Davinci is completely
broken. Some kernels, such as the 2.6.10 one supported by
MontaVista for Davinci, rely upon this broken behaviour as they
share the same code for ECCs. In the existing scheme, error
detection *might* work on large page, but error correction
definitely does not. Small page ECC correction works, but the
format is not compatible with the mainline git kernel.
This patch adds ECC code that matches what is currently in the
Davinci git repository (since NAND support was added in 2.6.24).
This makes the ECC and OOB layout written by u-boot compatible with
Linux for both small page and large page devices and fixes ECC
correction for large page devices.
The code depends on a #define CFG_LINUX_COMPATIBLE_ECC, which is
undefined by default, making the default state backwards compatible.
I have verified this by compiling without the #define and producing
a binary byte-for-byte identical to one without this patch.
[NOTE: I have not yet been able to get my hands on a board with
small-page NAND to test, but large page does work. If anybody is
interested in testing it, please do and let me know if it works for
you (i.e. uboot with this patch and davinci git kernel can
read/write the same NAND).]
Signed-off-by: Bernard Blackham <bernard(a)largestprime.net>
---
cpu/arm926ejs/davinci/nand.c | 79 ++++++++++++++++++++++++++++++++++++++--
include/configs/davinci_dvevm.h | 12 ++++++
2 files changed, 89 insertions(+), 2 deletions(-)
Index: u-boot-1.3.3/cpu/arm926ejs/davinci/nand.c
===================================================================
--- u-boot-1.3.3.orig/cpu/arm926ejs/davinci/nand.c 2008-05-19 18:47:11.000000000 +0800
+++ u-boot-1.3.3/cpu/arm926ejs/davinci/nand.c 2008-06-27 13:04:03.000000000 +0800
@@ -87,6 +87,10 @@ static void nand_davinci_select_chip(str
}
#ifdef CFG_NAND_HW_ECC
+
+#ifndef CFG_LINUX_COMPATIBLE_ECC
+/* Linux-compatible ECC uses MTD defaults. */
+/* These layouts are not compatible with Linux or RBL/UBL. */
#ifdef CFG_NAND_LARGEPAGE
static struct nand_oobinfo davinci_nand_oobinfo = {
.useecc = MTD_NANDECC_AUTOPLACE,
@@ -104,6 +108,7 @@ static struct nand_oobinfo davinci_nand_
#else
#error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!"
#endif
+#endif
static void nand_davinci_enable_hwecc(struct mtd_info *mtd, int mode)
{
@@ -141,12 +146,29 @@ static u_int32_t nand_davinci_readecc(st
static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
{
+#ifdef CFG_LINUX_COMPATIBLE_ECC
+ unsigned int ecc_val = nand_davinci_readecc(mtd, 1);
+ /* squeeze 0 middle bits out so that it fits in 3 bytes */
+ unsigned int tmp = (ecc_val&0x0fff)|((ecc_val&0x0fff0000)>>4);
+ /* invert so that erased block ecc is correct */
+ tmp = ~tmp;
+ ecc_code[0] = (u_char)(tmp);
+ ecc_code[1] = (u_char)(tmp >> 8);
+ ecc_code[2] = (u_char)(tmp >> 16);
+#else
u_int32_t tmp;
int region, n;
struct nand_chip *this = mtd->priv;
n = (this->eccmode == NAND_ECC_HW12_2048) ? 4 : 1;
+ /*
+ * This is not how you should read ECCs on large page Davinci devices.
+ * The region parameter gets you ECCs for flash chips on different chip
+ * selects, not the 4x512 byte pages in a 2048 byte page.
+ *
+ * Preserved for backwards compatibility though.
+ */
region = 1;
while (n--) {
tmp = nand_davinci_readecc(mtd, region);
@@ -155,9 +177,51 @@ static int nand_davinci_calculate_ecc(st
*ecc_code++ = ((tmp >> 8) & 0x0f) | ((tmp >> 20) & 0xf0);
region++;
}
+#endif
+
return(0);
}
+#ifdef CFG_LINUX_COMPATIBLE_ECC
+static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat,
+ u_char *read_ecc, u_char *calc_ecc)
+{
+ struct nand_chip *chip = mtd->priv;
+ u_int32_t ecc_nand = read_ecc[0] | (read_ecc[1] << 8) |
+ (read_ecc[2] << 16);
+ u_int32_t ecc_calc = calc_ecc[0] | (calc_ecc[1] << 8) |
+ (calc_ecc[2] << 16);
+ u_int32_t diff = ecc_calc ^ ecc_nand;
+
+ if (diff) {
+ if ((((diff>>12)^diff) & 0xfff) == 0xfff) {
+ /* Correctable error */
+ if ((diff>>(12+3)) < chip->eccsize) {
+ uint8_t find_bit = 1 << ((diff>>12)&7);
+ uint32_t find_byte = diff>>(12+3);
+ dat[find_byte] ^= find_bit;
+ DEBUG (MTD_DEBUG_LEVEL0, "Correcting single bit ECC error at offset: %d, bit: %d\n", find_byte, find_bit);
+ return 1;
+ } else {
+ return -1;
+ }
+ } else if (!(diff & (diff-1))) {
+ /* Single bit ECC error in the ECC itself,
+ nothing to fix */
+ DEBUG (MTD_DEBUG_LEVEL0, "Single bit ECC error in ECC.\n");
+ return 1;
+ } else {
+ /* Uncorrectable error */
+ DEBUG (MTD_DEBUG_LEVEL0, "ECC UNCORRECTED_ERROR 1\n");
+ return -1;
+ }
+
+ }
+ return 0;
+}
+
+#else
+
static void nand_davinci_gen_true_ecc(u_int8_t *ecc_buf)
{
u_int32_t tmp = ecc_buf[0] | (ecc_buf[1] << 16) | ((ecc_buf[2] & 0xf0) << 20) | ((ecc_buf[2] & 0x0f) << 8);
@@ -291,7 +355,9 @@ static int nand_davinci_correct_data(str
}
return(0);
}
-#endif
+#endif /* CFG_LINUX_COMPATIBLE_ECC */
+
+#endif /* CFG_NAND_HW_ECC */
static int nand_davinci_dev_ready(struct mtd_info *mtd)
{
@@ -356,7 +422,13 @@ int board_nand_init(struct nand_chip *na
#ifdef CFG_NAND_USE_FLASH_BBT
nand->options = NAND_USE_FLASH_BBT;
#endif
+
#ifdef CFG_NAND_HW_ECC
+
+#ifdef CFG_LINUX_COMPATIBLE_ECC
+ nand->eccmode = NAND_ECC_HW3_512;
+#else
+
#ifdef CFG_NAND_LARGEPAGE
nand->eccmode = NAND_ECC_HW12_2048;
#elif defined(CFG_NAND_SMALLPAGE)
@@ -365,12 +437,15 @@ int board_nand_init(struct nand_chip *na
#error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!"
#endif
nand->autooob = &davinci_nand_oobinfo;
+
+#endif /* CFG_LINUX_COMPATIBLE_ECC */
+
nand->calculate_ecc = nand_davinci_calculate_ecc;
nand->correct_data = nand_davinci_correct_data;
nand->enable_hwecc = nand_davinci_enable_hwecc;
#else
nand->eccmode = NAND_ECC_SOFT;
-#endif
+#endif /* CFG_NAND_HW_ECC */
/* Set address of hardware control function */
nand->hwcontrol = nand_davinci_hwcontrol;
Index: u-boot-1.3.3/include/configs/davinci_dvevm.h
===================================================================
--- u-boot-1.3.3.orig/include/configs/davinci_dvevm.h 2008-05-19 18:47:11.000000000 +0800
+++ u-boot-1.3.3/include/configs/davinci_dvevm.h 2008-06-27 13:04:07.000000000 +0800
@@ -46,6 +46,18 @@
#define CONFIG_NOR_UART_BOOT
*/
+/*
+ * Previous versions of u-boot (1.3.3 and prior) and Montavista Linux kernels
+ * generated bogus ECCs on large-page NAND. Both large and small page NAND ECCs
+ * were incompatible with the Linux davinci git tree (since NAND was integrated
+ * in 2.6.24).
+ * Don't turn this on if you want backwards compatibility.
+ * Do turn this on if you want u-boot to be able to read and write NAND
+ * that can be written or read by the Linux davinci git kernel.
+ *
+#define CFG_LINUX_COMPATIBLE_ECC
+ */
+
/*=======*/
/* Board */
/*=======*/
5
5

[U-Boot-Users] [PATCH] (resubmit) ppc4xx: ML507: Environment in flash and MTD Support
by Ricardo Ribalda Delgado 06 Sep '08
by Ricardo Ribalda Delgado 06 Sep '08
06 Sep '08
-Relocate the location of u-boot in the flash
-Save the environment in one sector of the flash memory
-MTD Support
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda(a)uam.es>
---
-Previus commit included files from other commit
Makefile | 2 +-
board/xilinx/ml507/xparameters.h | 2 +-
include/configs/ml507.h | 15 +++++++++++----
3 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/Makefile b/Makefile
index 8f4fdd0..ea572cf 100644
--- a/Makefile
+++ b/Makefile
@@ -1352,7 +1352,7 @@ ml300_config: unconfig
ml507_flash_config: unconfig
@mkdir -p $(obj)include $(obj)board/xilinx/ml507
@cp $(obj)board/xilinx/ml507/u-boot-rom.lds $(obj)board/xilinx/ml507/u-boot.lds
- @echo "TEXT_BASE = 0xFE3E0000" > $(obj)board/xilinx/ml507/config.tmp
+ @echo "TEXT_BASE = 0xFE360000" > $(obj)board/xilinx/ml507/config.tmp
@$(MKCONFIG) $(@:_flash_config=) ppc ppc4xx ml507 xilinx
ml507_config: unconfig
diff --git a/board/xilinx/ml507/xparameters.h b/board/xilinx/ml507/xparameters.h
index 6a8e183..77d2ddf 100644
--- a/board/xilinx/ml507/xparameters.h
+++ b/board/xilinx/ml507/xparameters.h
@@ -24,7 +24,7 @@
#define XPAR_DDR2_SDRAM_MEM_BASEADDR 0x00000000
#define XPAR_IIC_EEPROM_BASEADDR 0x81600000
#define XPAR_INTC_0_BASEADDR 0x81800000
-#define XPAR_LLTEMAC_0_BASEADDR 0x81c00000
+#define XPAR_LLTEMAC_0_BASEADDR 0x81C00000
#define XPAR_UARTLITE_0_BASEADDR 0x84000000
#define XPAR_FLASH_MEM0_BASEADDR 0xFE000000
#define XPAR_PLB_CLOCK_FREQ_HZ 100000000
diff --git a/include/configs/ml507.h b/include/configs/ml507.h
index a79bc1e..c653a51 100644
--- a/include/configs/ml507.h
+++ b/include/configs/ml507.h
@@ -33,7 +33,7 @@
#define CFG_SDRAM_SIZE_MB 256
#define CFG_MONITOR_BASE TEXT_BASE
#define CFG_MONITOR_LEN ( 192 * 1024 )
-#define CFG_MALLOC_LEN ( 128 * 1024 )
+#define CFG_MALLOC_LEN ( CFG_ENV_SIZE + 128 * 1024 )
/*Uart*/
#define CONFIG_XILINX_UARTLITE
@@ -49,6 +49,8 @@
#define CONFIG_CMD_ELF
#define CONFIG_CMD_IRQ
#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_JFFS2
+#define CONFIG_JFFS2_CMDLINE
#undef CONFIG_CMD_I2C
#undef CONFIG_CMD_DTT
#undef CONFIG_CMD_NET
@@ -58,9 +60,11 @@
#undef CONFIG_CMD_IMLS
/*Env*/
-#define CFG_ENV_IS_NOWHERE
-#define CFG_ENV_SIZE 0x200
-#define CFG_ENV_OFFSET 0x100
+#define CFG_ENV_IS_IN_FLASH
+#define CFG_ENV_SIZE 0x20000
+#define CFG_ENV_SECT_SIZE 0x20000
+#define CFG_ENV_OFFSET 0x340000
+#define CFG_ENV_ADDR (XPAR_FLASH_MEM0_BASEADDR+CFG_ENV_OFFSET)
/*Misc*/
#define CONFIG_BOOTDELAY 5 /* autoboot after 5 seconds */
@@ -111,5 +115,8 @@
#define CFG_MAX_FLASH_BANKS 1
#define CFG_MAX_FLASH_SECT 259
#define CFG_FLASH_PROTECTION
+#define MTDIDS_DEFAULT "nor0=ml507-flash"
+#define MTDPARTS_DEFAULT "mtdparts=ml507-flash:-(user)"
+
#endif /* __CONFIG_H */
--
1.5.6.3
2
5

06 Sep '08
JFFS2 command support on OneNAND.
- Fix typo.
- Fix nand_bbt_descr redefinition when NAND and OneNAND are enabled.
TODO: Use NAND command interface (e.g.: part_validate_*nand()).
Signed-off-by: Kyungmin Park <kyungmin.park(a)samsung.com>
Signed-off-by: Fathi Boudra <fabo(a)debian.org>
---
diff --git a/common/cmd_jffs2.c b/common/cmd_jffs2.c
index b4698be..43e33dd 100644
--- a/common/cmd_jffs2.c
+++ b/common/cmd_jffs2.c
@@ -51,7 +51,7 @@
* mtdids=<idmap>[,<idmap>,...]
*
* <idmap> := <dev-id>=<mtd-id>
- * <dev-id> := 'nand'|'nor'<dev-num>
+ * <dev-id> := 'nand'|'nor'|'onenand'<dev-num>
* <dev-num> := mtd device number, 0...
* <mtd-id> := unique device tag used by linux kernel to find mtd device (mtd->name)
*
@@ -103,6 +103,13 @@
#include <nand.h>
#endif /* !CFG_NAND_LEGACY */
#endif
+
+#if defined(CONFIG_CMD_ONENAND)
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+#include <onenand_uboot.h>
+#endif
+
/* enable/disable debugging messages */
#define DEBUG_JFFS
#undef DEBUG_JFFS
@@ -401,6 +408,42 @@ static int part_validate_nand(struct mtdids *id, struct part_info *part)
}
/**
+ * Performs sanity check for supplied OneNAND flash partition.
+ * Table of existing OneNAND flash devices is searched and partition device
+ * is located. Alignment with the granularity of nand erasesize is verified.
+ *
+ * @param id of the parent device
+ * @param part partition to validate
+ * @return 0 if partition is valid, 1 otherwise
+ */
+static int part_validate_onenand(struct mtdids *id, struct part_info *part)
+{
+#if defined(CONFIG_CMD_ONENAND)
+ /* info for OneNAND chips */
+ struct mtd_info *mtd;
+
+ mtd = &onenand_mtd;
+
+ if ((unsigned long)(part->offset) % mtd->erasesize) {
+ printf("%s%d: partition (%s) start offset"
+ "alignment incorrect\n",
+ MTD_DEV_TYPE(id->type), id->num, part->name);
+ return 1;
+ }
+
+ if (part->size % mtd->erasesize) {
+ printf("%s%d: partition (%s) size alignment incorrect\n",
+ MTD_DEV_TYPE(id->type), id->num, part->name);
+ return 1;
+ }
+
+ return 0;
+#else
+ return 1;
+#endif
+}
+
+/**
* Performs sanity check for supplied partition. Offset and size are verified
* to be within valid range. Partition type is checked and either
* parts_validate_nor() or parts_validate_nand() is called with the argument
@@ -436,6 +479,8 @@ static int part_validate(struct mtdids *id, struct part_info *part)
return part_validate_nand(id, part);
else if (id->type == MTD_DEV_TYPE_NOR)
return part_validate_nor(id, part);
+ else if (id->type == MTD_DEV_TYPE_ONENAND)
+ return part_validate_onenand(id, part);
else
DEBUGF("part_validate: invalid dev type\n");
@@ -755,7 +800,15 @@ static int device_validate(u8 type, u8 num, u32 *size)
#else
printf("support for NAND devices not present\n");
#endif
- }
+ } else if (type == MTD_DEV_TYPE_ONENAND) {
+#if defined(CONFIG_CMD_ONENAND)
+ *size = onenand_mtd.size;
+ return 0;
+#else
+ printf("support for OneNAND devices not present\n");
+#endif
+ } else
+ printf("Unknown device type %d\n", type);
return 1;
}
@@ -1065,8 +1118,8 @@ static struct mtdids* id_find_by_mtd_id(const char *mtd_id, unsigned int mtd_id_
#endif /* #ifdef CONFIG_JFFS2_CMDLINE */
/**
- * Parse device id string <dev-id> := 'nand'|'nor'<dev-num>, return device
- * type and number.
+ * Parse device id string <dev-id> := 'nand'|'nor'|'onenand'<dev-num>,
+ * return device type and number.
*
* @param id string describing device id
* @param ret_id output pointer to next char after parse completes (output)
@@ -1085,6 +1138,9 @@ int id_parse(const char *id, const char **ret_id, u8 *dev_type, u8 *dev_num)
} else if (strncmp(p, "nor", 3) == 0) {
*dev_type = MTD_DEV_TYPE_NOR;
p += 3;
+ } else if (strncmp(p, "onenand", 7) == 0) {
+ *dev_type = MTD_DEV_TYPE_ONENAND;
+ p += 7;
} else {
printf("incorrect device type in %s\n", id);
return 1;
@@ -1489,7 +1545,7 @@ static int parse_mtdids(const char *const ids)
while(p && (*p != '\0')) {
ret = 1;
- /* parse 'nor'|'nand'<dev-num> */
+ /* parse 'nor'|'nand'|'onenand'<dev-num> */
if (id_parse(p, &p, &type, &num) != 0)
break;
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index 87344ab..04d4088 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -21,6 +21,7 @@
#include <linux/mtd/compat.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
+#include <linux/mtd/bbm.h>
#include <malloc.h>
#include <asm/errno.h>
diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c
index 8a06777..7dc29c4 100644
--- a/fs/jffs2/jffs2_1pass.c
+++ b/fs/jffs2/jffs2_1pass.c
@@ -271,6 +271,107 @@ static void put_fl_mem_nand(void *buf)
}
#endif
+#if defined(CONFIG_CMD_ONENAND)
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+#include <onenand_uboot.h>
+
+#define ONENAND_PAGE_SIZE 2048
+#define ONENAND_PAGE_SHIFT 11
+#define ONENAND_PAGE_MASK (~(ONENAND_PAGE_SIZE-1))
+
+#ifndef ONENAND_CACHE_PAGES
+#define ONENAND_CACHE_PAGES 4
+#endif
+#define ONENAND_CACHE_SIZE (ONENAND_CACHE_PAGES*ONENAND_PAGE_SIZE)
+
+static u8* onenand_cache;
+static u32 onenand_cache_off = (u32)-1;
+
+static int read_onenand_cached(u32 off, u32 size, u_char *buf)
+{
+ u32 bytes_read = 0;
+ size_t retlen;
+ int cpy_bytes;
+
+ while (bytes_read < size) {
+ if ((off + bytes_read < onenand_cache_off) ||
+ (off + bytes_read >= onenand_cache_off + ONENAND_CACHE_SIZE)) {
+ onenand_cache_off = (off + bytes_read) & ONENAND_PAGE_MASK;
+ if (!onenand_cache) {
+ /* This memory never gets freed but 'cause
+ it's a bootloader, nobody cares */
+ onenand_cache = malloc(ONENAND_CACHE_SIZE);
+ if (!onenand_cache) {
+ printf("read_onenand_cached: can't alloc cache size %d bytes\n",
+ ONENAND_CACHE_SIZE);
+ return -1;
+ }
+ }
+
+ retlen = ONENAND_CACHE_SIZE;
+ if (onenand_read(&onenand_mtd, onenand_cache_off, retlen,
+ &retlen, onenand_cache) != 0 ||
+ retlen != ONENAND_CACHE_SIZE) {
+ printf("read_onenand_cached: error reading nand off %#x size %d bytes\n",
+ onenand_cache_off, ONENAND_CACHE_SIZE);
+ return -1;
+ }
+ }
+ cpy_bytes = onenand_cache_off + ONENAND_CACHE_SIZE - (off + bytes_read);
+ if (cpy_bytes > size - bytes_read)
+ cpy_bytes = size - bytes_read;
+ memcpy(buf + bytes_read,
+ onenand_cache + off + bytes_read - onenand_cache_off,
+ cpy_bytes);
+ bytes_read += cpy_bytes;
+ }
+ return bytes_read;
+}
+
+static void *get_fl_mem_onenand(u32 off, u32 size, void *ext_buf)
+{
+ u_char *buf = ext_buf ? (u_char *)ext_buf : (u_char *)malloc(size);
+
+ if (NULL == buf) {
+ printf("get_fl_mem_onenand: can't alloc %d bytes\n", size);
+ return NULL;
+ }
+ if (read_onenand_cached(off, size, buf) < 0) {
+ if (!ext_buf)
+ free(buf);
+ return NULL;
+ }
+
+ return buf;
+}
+
+static void *get_node_mem_onenand(u32 off)
+{
+ struct jffs2_unknown_node node;
+ void *ret = NULL;
+
+ if (NULL == get_fl_mem_onenand(off, sizeof(node), &node))
+ return NULL;
+
+ ret = get_fl_mem_onenand(off, node.magic ==
+ JFFS2_MAGIC_BITMASK ? node.totlen : sizeof(node),
+ NULL);
+ if (!ret) {
+ printf("off = %#x magic %#x type %#x node.totlen = %d\n",
+ off, node.magic, node.nodetype, node.totlen);
+ }
+ return ret;
+}
+
+
+static void put_fl_mem_onenand(void *buf)
+{
+ free(buf);
+}
+#endif
+
#if defined(CONFIG_CMD_FLASH)
/*
@@ -316,6 +417,11 @@ static inline void *get_fl_mem(u32 off, u32 size, void *ext_buf)
return get_fl_mem_nand(off, size, ext_buf);
#endif
+#if defined(CONFIG_CMD_ONENAND)
+ if (id->type == MTD_DEV_TYPE_ONENAND)
+ return get_fl_mem_onenand(off, size, ext_buf);
+#endif
+
printf("get_fl_mem: unknown device type, using raw offset!\n");
return (void*)off;
}
@@ -335,19 +441,31 @@ static inline void *get_node_mem(u32 off)
return get_node_mem_nand(off);
#endif
+#if defined(CONFIG_CMD_ONENAND)
+ if (id->type == MTD_DEV_TYPE_ONENAND)
+ return get_node_mem_onenand(off);
+#endif
+
printf("get_node_mem: unknown device type, using raw offset!\n");
return (void*)off;
}
static inline void put_fl_mem(void *buf)
{
-#if defined(CONFIG_JFFS2_NAND) && \
- defined(CONFIG_CMD_NAND)
+#if (defined(CONFIG_JFFS2_NAND) && defined(CONFIG_CMD_NAND)) || \
+ defined(CONFIG_CMD_ONENAND)
struct mtdids *id = current_part->dev->id;
+#endif
+#if defined(CONFIG_JFFS2_NAND) && defined(CONFIG_CMD_NAND)
if (id->type == MTD_DEV_TYPE_NAND)
return put_fl_mem_nand(buf);
#endif
+
+#if defined(CONFIG_CMD_ONENAND)
+ if (id->type == MTD_DEV_TYPE_ONENAND)
+ return put_fl_mem_onenand(buf);
+#endif
}
/* Compression names */
diff --git a/include/jffs2/load_kernel.h b/include/jffs2/load_kernel.h
index 882a80e..37871de 100644
--- a/include/jffs2/load_kernel.h
+++ b/include/jffs2/load_kernel.h
@@ -28,9 +28,14 @@
#include <linux/list.h>
/* mtd device types */
-#define MTD_DEV_TYPE_NOR 0x0001
-#define MTD_DEV_TYPE_NAND 0x0002
-#define MTD_DEV_TYPE(type) ((type == MTD_DEV_TYPE_NAND) ? "nand" : "nor")
+enum {
+ MTD_DEV_TYPE_NOR,
+ MTD_DEV_TYPE_NAND,
+ MTD_DEV_TYPE_ONENAND,
+};
+
+#define MTD_DEV_TYPE(type) ((type == MTD_DEV_TYPE_NAND) ? "nand" : \
+ (type == MTD_DEV_TYPE_ONENAND) ? "onenand" : "nor")
struct mtd_device {
struct list_head link;
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 4b0c2df..019d2b1 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -14,10 +14,10 @@
#include <linux/mtd/onenand_regs.h>
-/* Note: The header order is impoertant */
+/* Note: The header order is important */
#include <onenand_uboot.h>
-#include <linux/mtd/bbm.h>
+#include <linux/mtd/compat.h>
#define MAX_BUFFERRAM 2
#define MAX_ONENAND_PAGESIZE (2048 + 64)
diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h
index 4449f98..24ace2a 100644
--- a/include/onenand_uboot.h
+++ b/include/onenand_uboot.h
@@ -27,6 +27,8 @@ typedef int wait_queue_head_t;
struct mtd_info;
struct erase_info;
+extern struct mtd_info onenand_mtd;
+
/* Functions */
extern void onenand_init(void);
extern int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
3
4

03 Sep '08
Add high speed support to USB code. Extracted from Juniper Networks patch.
I know that the mergewindow is closed but wanted to get feedback on these
patches if possible.
Signed-off-by: Tor Krill <tor(a)excito.com>
---
common/cmd_usb.c | 3 ++-
common/usb.c | 30 +++++++++++++++++++++++++-----
include/usb.h | 16 +++++++++-------
include/usb_defs.h | 10 ++++++++++
4 files changed, 46 insertions(+), 13 deletions(-)
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 9be86b8..03282f6 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -276,7 +276,8 @@ void usb_show_tree_graph(struct usb_device *dev,char *pre)
pre[index++]= has_child ? '|' : ' ';
pre[index]=0;
printf(" %s (%s, %dmA)\n",usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass),
- dev->slow ? "1.5MBit/s" : "12MBit/s",dev->config.MaxPower * 2);
+ (dev->speed == USB_SPEED_LOW) ? "1.5MBit/s" : (dev->speed == USB_SPEED_FULL)
+ ? "12MBit/s" : "480MBit/s", dev->config.MaxPower * 2);
if (strlen(dev->mf) ||
strlen(dev->prod) ||
strlen(dev->serial))
diff --git a/common/usb.c b/common/usb.c
index a0107dc..44f35bc 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -793,6 +793,11 @@ int usb_new_device(struct usb_device *dev)
case 16: dev->maxpacketsize = 1; break;
case 32: dev->maxpacketsize = 2; break;
case 64: dev->maxpacketsize = 3; break;
+ case 512: dev->maxpacketsize = 6; break;
+ default:
+ printf("XXX bMaxPacketSize0 unsupported (%u)\n",
+ dev->descriptor.bMaxPacketSize0);
+ break;
}
dev->devnum = addr;
@@ -981,8 +986,10 @@ static int hub_port_reset(struct usb_device *dev, int port,
}
portstatus = le16_to_cpu(portsts.wPortStatus);
portchange = le16_to_cpu(portsts.wPortChange);
- USB_HUB_PRINTF("portstatus %x, change %x, %s\n", portstatus ,portchange,
- portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
+ USB_HUB_PRINTF("portstatus %x, change %x, %s Speed\n", portstatus ,portchange,
+ portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low" :
+ portstatus&(1<<USB_PORT_FEAT_HIGHSPEED) ? "High" :
+ "Full");
USB_HUB_PRINTF("STAT_C_CONNECTION = %d STAT_CONNECTION = %d USB_PORT_STAT_ENABLE %d\n",
(portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0,
(portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0,
@@ -1026,8 +1033,10 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
portstatus = le16_to_cpu(portsts.wPortStatus);
portchange = le16_to_cpu(portsts.wPortChange);
- USB_HUB_PRINTF("portstatus %x, change %x, %s\n", portstatus, portchange,
- portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
+ USB_HUB_PRINTF("portstatus %x, change %x, %s Speed\n", portstatus, portchange,
+ portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low" :
+ portstatus&(1<<USB_PORT_FEAT_HIGHSPEED) ? "High" :
+ "Full");
/* Clear the connection change status */
usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_CONNECTION);
@@ -1052,10 +1061,21 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
/* Allocate a new device struct for it */
usb=usb_alloc_new_device();
- usb->slow = (portstatus & USB_PORT_STAT_LOW_SPEED) ? 1 : 0;
+ switch (portstatus & USB_PORT_STAT_SPEED) {
+ case 0:
+ usb->speed = USB_SPEED_FULL;
+ break;
+ case USB_PORT_STAT_LOW_SPEED:
+ usb->speed = USB_SPEED_LOW;
+ break;
+ case USB_PORT_STAT_HIGH_SPEED:
+ usb->speed = USB_SPEED_HIGH;
+ break;
+ }
dev->children[port] = usb;
usb->parent=dev;
+ usb->portnr = port + 1;
/* Run it through the hoops (find a driver, etc) */
if (usb_new_device(usb)) {
/* Woops, disable the port */
diff --git a/include/usb.h b/include/usb.h
index 5a6ffdd..410f9cf 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -132,7 +132,7 @@ struct usb_config_descriptor {
struct usb_device {
int devnum; /* Device number on USB bus */
- int slow; /* Slow device? */
+ int speed; /* full/low/high */
char mf[32]; /* manufacturer */
char prod[32]; /* product */
char serial[32]; /* serial number */
@@ -161,6 +161,7 @@ struct usb_device {
unsigned long status;
int act_len; /* transfered bytes */
int maxchild; /* Number of ports if hub */
+ int portnr;
struct usb_device *parent;
struct usb_device *children[USB_MAXCHILDREN];
};
@@ -171,7 +172,7 @@ struct usb_device {
#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || \
defined(CONFIG_USB_OHCI_NEW) || defined (CONFIG_USB_SL811HS) || \
- defined(CONFIG_USB_ISP116X_HCD)
+ defined(CONFIG_USB_ISP116X_HCD) || defined (CONFIG_USB_EHCI)
int usb_lowlevel_init(void);
int usb_lowlevel_stop(void);
@@ -264,7 +265,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
* - endpoint number (4 bits)
* - current Data0/1 state (1 bit)
* - direction (1 bit)
- * - speed (1 bit)
+ * - speed (2 bits)
* - max packet size (2 bits: 8, 16, 32 or 64)
* - pipe type (2 bits: control, interrupt, bulk, isochronous)
*
@@ -280,7 +281,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
* - device: bits 8-14
* - endpoint: bits 15-18
* - Data0/1: bit 19
- * - speed: bit 26 (0 = Full, 1 = Low Speed)
+ * - speed: bits 26-27 (0 = Full, 1 = Low, 2 = High)
* - pipe type: bits 30-31 (00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk)
*
* Why? Because it's arbitrary, and whatever encoding we select is really
@@ -290,8 +291,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
*/
/* Create various pipes... */
#define create_pipe(dev,endpoint) \
- (((dev)->devnum << 8) | (endpoint << 15) | ((dev)->slow << 26) | (dev)->maxpacketsize)
-#define default_pipe(dev) ((dev)->slow <<26)
+ (((dev)->devnum << 8) | (endpoint << 15) | ((dev)->speed << 26) | (dev)->maxpacketsize)
+#define default_pipe(dev) ((dev)->speed << 26)
#define usb_sndctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | create_pipe(dev,endpoint))
#define usb_rcvctrlpipe(dev,endpoint) ((PIPE_CONTROL << 30) | create_pipe(dev,endpoint) | USB_DIR_IN)
@@ -323,7 +324,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
#define usb_pipe_endpdev(pipe) (((pipe) >> 8) & 0x7ff)
#define usb_pipeendpoint(pipe) (((pipe) >> 15) & 0xf)
#define usb_pipedata(pipe) (((pipe) >> 19) & 1)
-#define usb_pipeslow(pipe) (((pipe) >> 26) & 1)
+#define usb_pipespeed(pipe) (((pipe) >> 26) & 3)
+#define usb_pipeslow(pipe) (usb_pipespeed(pipe) == USB_SPEED_LOW)
#define usb_pipetype(pipe) (((pipe) >> 30) & 3)
#define usb_pipeisoc(pipe) (usb_pipetype((pipe)) == PIPE_ISOCHRONOUS)
#define usb_pipeint(pipe) (usb_pipetype((pipe)) == PIPE_INTERRUPT)
diff --git a/include/usb_defs.h b/include/usb_defs.h
index 353019f..8032e57 100644
--- a/include/usb_defs.h
+++ b/include/usb_defs.h
@@ -80,6 +80,12 @@
#define USB_DIR_OUT 0
#define USB_DIR_IN 0x80
+/* USB device speeds */
+#define USB_SPEED_FULL 0x0 /* 12Mbps */
+#define USB_SPEED_LOW 0x1 /* 1.5Mbps */
+#define USB_SPEED_HIGH 0x2 /* 480Mbps */
+#define USB_SPEED_RESERVED 0x3
+
/* Descriptor types */
#define USB_DT_DEVICE 0x01
#define USB_DT_CONFIG 0x02
@@ -202,6 +208,7 @@
#define USB_PORT_FEAT_RESET 4
#define USB_PORT_FEAT_POWER 8
#define USB_PORT_FEAT_LOWSPEED 9
+#define USB_PORT_FEAT_HIGHSPEED 10
#define USB_PORT_FEAT_C_CONNECTION 16
#define USB_PORT_FEAT_C_ENABLE 17
#define USB_PORT_FEAT_C_SUSPEND 18
@@ -216,6 +223,9 @@
#define USB_PORT_STAT_RESET 0x0010
#define USB_PORT_STAT_POWER 0x0100
#define USB_PORT_STAT_LOW_SPEED 0x0200
+#define USB_PORT_STAT_HIGH_SPEED 0x0400 /* support for EHCI */
+#define USB_PORT_STAT_SPEED \
+ (USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED)
/* wPortChange bits */
#define USB_PORT_STAT_C_CONNECTION 0x0001
--
1.5.6
3
8

01 Sep '08
I meanwhile realized that the entire makefile system doesn't really cope
with the fact. So what I'm left with is something along the lines of
the attached patch, where the cpu/arm920t/start.S #includes a
cpu/arm920t/s3c24x0/start.S file.
It's not really nice, but otherwise I assure you anyone touching the
arm920t start.S file again will find itself in #ifdef/endif hell, once
all my s3c24xx related patches would be merged...
Index: u-boot/cpu/arm920t/s3c24x0/start.S
===================================================================
--- /dev/null
+++ u-boot/cpu/arm920t/s3c24x0/start.S
@@ -0,0 +1,155 @@
+/*
+ * armboot - Startup Code for S3C24xx CPU-cores
+ *
+ *
+ */
+
+
+/* the actual start code */
+
+start_code:
+ /*
+ * set the cpu to SVC32 mode
+ */
+ mrs r0,cpsr
+ bic r0,r0,#0x1f
+ orr r0,r0,#0xd3
+ msr cpsr,r0
+
+ bl coloured_LED_init
+ bl red_LED_on
+
+ /* turn off the watchdog */
+
+# if defined(CONFIG_S3C2400)
+# define pWTCON 0x15300000
+# define INTMSK 0x14400008 /* Interupt-Controller base addresses */
+# define CLKDIVN 0x14800014 /* clock divisor register */
+#else
+# define pWTCON 0x53000000
+# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
+# define INTSUBMSK 0x4A00001C
+# define CLKDIVN 0x4C000014 /* clock divisor register */
+# endif
+
+ ldr r0, =pWTCON
+ mov r1, #0x0
+ str r1, [r0]
+
+ /*
+ * mask all IRQs by setting all bits in the INTMR - default
+ */
+ mov r1, #0xffffffff
+ ldr r0, =INTMSK
+ str r1, [r0]
+# if defined(CONFIG_S3C2410)
+ ldr r1, =0x3ff
+ ldr r0, =INTSUBMSK
+ str r1, [r0]
+# endif
+
+ /* FCLK:HCLK:PCLK = 1:2:4 */
+ /* default FCLK is 120 MHz ! */
+ ldr r0, =CLKDIVN
+ mov r1, #3
+ str r1, [r0]
+
+ /*
+ * we do sys-critical inits only at reboot,
+ * not when booting from ram!
+ */
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ bl cpu_init_crit
+#endif
+
+
+#ifndef CONFIG_SKIP_RELOCATE_UBOOT
+relocate: /* relocate U-Boot to RAM */
+ adr r0, _start /* r0 <- current position of code */
+ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
+ cmp r0, r1 /* don't reloc during debug */
+ beq stack_setup
+
+ ldr r2, _armboot_start
+ ldr r3, _bss_start
+ sub r2, r3, r2 /* r2 <- size of armboot */
+ add r2, r0, r2 /* r2 <- source end address */
+
+copy_loop:
+ ldmia r0!, {r3-r10} /* copy from source address [r0] */
+ stmia r1!, {r3-r10} /* copy to target address [r1] */
+ cmp r0, r2 /* until source end addreee [r2] */
+ ble copy_loop
+#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
+
+ /* Set up the stack */
+stack_setup:
+ ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
+ sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
+ sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
+#ifdef CONFIG_USE_IRQ
+ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
+#endif
+ sub sp, r0, #12 /* leave 3 words for abort-stack */
+
+clear_bss:
+ ldr r0, _bss_start /* find start of bss segment */
+ ldr r1, _bss_end /* stop here */
+ mov r2, #0x00000000 /* clear */
+
+clbss_l:str r2, [r0] /* clear loop... */
+ add r0, r0, #4
+ cmp r0, r1
+ ble clbss_l
+
+ ldr pc, _start_armboot
+
+_start_armboot: .word start_armboot
+
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+cpu_init_crit:
+ /*
+ * flush v4 I/D caches
+ */
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
+ mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
+
+ /*
+ * disable MMU stuff and caches
+ */
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
+ bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
+ orr r0, r0, #0x00000002 @ set bit 2 (A) Align
+ orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
+ mcr p15, 0, r0, c1, c0, 0
+
+ /*
+ * before relocating, we have to setup RAM timing
+ * because memory timing is board-dependend, you will
+ * find a lowlevel_init.S in your board directory.
+ */
+ mov ip, lr
+
+ bl lowlevel_init
+
+ mov lr, ip
+ mov pc, lr
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
+
+
+
Index: u-boot/cpu/arm920t/start.S
===================================================================
--- u-boot.orig/cpu/arm920t/start.S
+++ u-boot/cpu/arm920t/start.S
@@ -103,6 +103,10 @@
#endif
+#if defined(CONFIG_S3C24xx)
+#include "s3c24x0/start.S"
+#else
+
/*
* the actual start code
*/
@@ -133,43 +137,6 @@
bne copyex
#endif
-#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
- /* turn off the watchdog */
-
-# if defined(CONFIG_S3C2400)
-# define pWTCON 0x15300000
-# define INTMSK 0x14400008 /* Interupt-Controller base addresses */
-# define CLKDIVN 0x14800014 /* clock divisor register */
-#else
-# define pWTCON 0x53000000
-# define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
-# define INTSUBMSK 0x4A00001C
-# define CLKDIVN 0x4C000014 /* clock divisor register */
-# endif
-
- ldr r0, =pWTCON
- mov r1, #0x0
- str r1, [r0]
-
- /*
- * mask all IRQs by setting all bits in the INTMR - default
- */
- mov r1, #0xffffffff
- ldr r0, =INTMSK
- str r1, [r0]
-# if defined(CONFIG_S3C2410)
- ldr r1, =0x3ff
- ldr r0, =INTSUBMSK
- str r1, [r0]
-# endif
-
- /* FCLK:HCLK:PCLK = 1:2:4 */
- /* default FCLK is 120 MHz ! */
- ldr r0, =CLKDIVN
- mov r1, #3
- str r1, [r0]
-#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */
-
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
@@ -270,6 +237,8 @@
mov pc, lr
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
+#endif /* S3C24xx */
+
/*
*************************************************************************
*
Index: u-boot/include/configs/VCMA9.h
===================================================================
--- u-boot.orig/include/configs/VCMA9.h
+++ u-boot/include/configs/VCMA9.h
@@ -35,6 +35,7 @@
*/
#define CONFIG_ARM920T 1 /* This is an ARM920T Core */
#define CONFIG_S3C2410 1 /* in a SAMSUNG S3C2410 SoC */
+#define CONFIG_S3C24xx 1 /* in a SAMSUNG S3C24xx family */
#define CONFIG_VCMA9 1 /* on a MPL VCMA9 Board */
#define LITTLEENDIAN 1 /* used by usb_ohci.c */
Index: u-boot/include/configs/sbc2410x.h
===================================================================
--- u-boot.orig/include/configs/sbc2410x.h
+++ u-boot/include/configs/sbc2410x.h
@@ -45,6 +45,7 @@
*/
#define CONFIG_ARM920T 1 /* This is an ARM920T Core */
#define CONFIG_S3C2410 1 /* in a SAMSUNG S3C2410 SoC */
+#define CONFIG_S3C24xx 1 /* in a SAMSUNG S3C24xx family */
#define CONFIG_SBC2410X 1 /* on a friendly-arm SBC-2410X Board */
/* input clock of PLL */
Index: u-boot/include/configs/smdk2400.h
===================================================================
--- u-boot.orig/include/configs/smdk2400.h
+++ u-boot/include/configs/smdk2400.h
@@ -36,6 +36,7 @@
*/
#define CONFIG_ARM920T 1 /* This is an ARM920T core */
#define CONFIG_S3C2400 1 /* in a SAMSUNG S3C2400 SoC */
+#define CONFIG_S3C24xx 1 /* in a SAMSUNG S3C24xx family */
#define CONFIG_SMDK2400 1 /* on an SAMSUNG SMDK2400 Board */
/* input clock of PLL */
Index: u-boot/include/configs/smdk2410.h
===================================================================
--- u-boot.orig/include/configs/smdk2410.h
+++ u-boot/include/configs/smdk2410.h
@@ -35,6 +35,7 @@
*/
#define CONFIG_ARM920T 1 /* This is an ARM920T Core */
#define CONFIG_S3C2410 1 /* in a SAMSUNG S3C2410 SoC */
+#define CONFIG_S3C24xx 1 /* in a SAMSUNG S3C24xx family */
#define CONFIG_SMDK2410 1 /* on a SAMSUNG SMDK2410 Board */
/* input clock of PLL */
--
- Harald Welte <laforge(a)gnumonks.org> http://laforge.gnumonks.org/
============================================================================
"Privacy in residential applications is a desirable marketing option."
(ETSI EN 300 175-7 Ch. A6)
3
6