All of lore.kernel.org
 help / color / mirror / Atom feed
From: Graeme Russ <graeme.russ@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [RFC][PATCH 2a/3] New i386 board (includes code relocation)
Date: Mon, 29 Sep 2008 23:26:44 +1000	[thread overview]
Message-ID: <48E0D794.1020308@gmail.com> (raw)

Split to meet mailing list size limit

Initial addition of eNET files - builds clean but will not run until
additional i386 code changes are made

Signed-off-by: Graeme Russ <graeme.russ@gmail.com>

--

diff --git a/MAKEALL b/MAKEALL
index 9ccb9ac..6f65870 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -645,6 +645,7 @@ LIST_I486="		\
 	sc520_cdp	\
 	sc520_spunk	\
 	sc520_spunk_rel	\
+	sc520_eNET	\
 "
 
 LIST_x86="		\
diff --git a/Makefile b/Makefile
index 7c13ce8..cdfca1c 100644
--- a/Makefile
+++ b/Makefile
@@ -2843,6 +2843,12 @@ sc520_spunk_config	:	unconfig
 sc520_spunk_rel_config	:	unconfig
 	@$(MKCONFIG) $(@:_config=) i386 i386 sc520_spunk
 
+#########################################################################
+## Serck eNET
+#########################################################################
+eNET_config	:	unconfig
+	@$(MKCONFIG) $(@:_config=) i386 i386 eNET
+
 #========================================================================
 # MIPS
 #========================================================================
diff --git a/board/eNET/Makefile b/board/eNET/Makefile
new file mode 100644
index 0000000..a124b33
--- /dev/null
+++ b/board/eNET/Makefile
@@ -0,0 +1,57 @@
+#
+# (C) Copyright 2008
+# Graeme Russ, graeme.russ at gmail.com.
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2002
+# Daniel Engstr?m, Omicron Ceti AB, daniel at omicron.se.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= eNET.o flash.o fpga.o
+SOBJS	:= eNET_start16.o eNET_start.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/eNET/config.mk b/board/eNET/config.mk
new file mode 100644
index 0000000..6797f8a
--- /dev/null
+++ b/board/eNET/config.mk
@@ -0,0 +1,25 @@
+#
+# (C) Copyright 2002
+# Daniel Engstr?m, Omicron Ceti AB, daniel at omicron.se.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+
+TEXT_BASE = 0x38040000
diff --git a/board/eNET/eNET.c b/board/eNET/eNET.c
new file mode 100644
index 0000000..1b4af58
--- /dev/null
+++ b/board/eNET/eNET.c
@@ -0,0 +1,640 @@
+/*
+ *
+ * (C) Copyright 2002
+ * Daniel Engstr?m, Omicron Ceti AB <daniel@omicron.se>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/ic/sc520.h>
+#include <spi.h>
+
+#ifdef CONFIG_HW_WATCHDOG
+#include <watchdog.h>
+#endif
+
+#include "hardware.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#undef SC520_CDP_DEBUG
+
+#ifdef	SC520_CDP_DEBUG
+#define	PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define PRINTF(fmt,args...)
+#endif
+
+
+extern int do_autoscript (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_bdinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_iminfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+/* extern int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); */
+extern int do_coninfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_itest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_load_serial (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_mem_md (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_mem_mm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_mem_nm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_mem_mw (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_mem_cp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_mem_base (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_mem_loop (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_mem_mtest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_sleep (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_printenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_setenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_run (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_imgextract (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_version (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_echo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+extern int do_help (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+
+
+void hw_watchdog_reset(void)
+{
+	u16 wd_state;
+
+	wd_state = readw(CFG_WATCHDIG_PIO_DATA);
+
+	if (wd_state & CFG_WATCHDOG_PIO_BIT) {
+		/* Watchdog output high - lower it*/
+		writew(CFG_WATCHDOG_PIO_BIT, CFG_WATCHDIG_PIO_CLR);
+	}
+	else {
+		/* Watchdog output low - raise it*/
+		writew(CFG_WATCHDOG_PIO_BIT, CFG_WATCHDIG_PIO_SET);
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+void init_sc520_enet (void)
+{
+
+	/* Set the UARTxCTL register at it's slower,
+	 * baud clock giving us a 1.8432 MHz reference
+	 */
+	write_mmcr_byte(SC520_UART1CTL, 7);
+
+
+	/* enable PCI bus arbitrer */
+/*	mov		ebx, SYSARBCTL			; SC520 control bits for the CPU bus arbiter and the PCI bus arbiter.	*/
+/*	mov		byte ptr [ebx], 06h	;										*/
+	write_mmcr_byte(SC520_SYSARBCTL,0x06);  /* enable concurrent mode */
+
+
+	/*	??	mov		ebx, SYSARBMENB			; SC520 System Arbiter Master Enable				*/
+/*	??	mov		word ptr [ebx], 0003h	;									*/
+	write_mmcr_word(SC520_SYSARBMENB, 0x0003); /* enable external grants */
+
+
+	if (CFG_SC520_HIGH_SPEED) {
+		write_mmcr_byte(SC520_CPUCTL, 0x2);	/* set it to 133 MHz and write back */
+		gd->cpu_clk = 133000000;
+/*		printf("## CPU Speed set to 133MHz\n"); */
+	} else {
+		write_mmcr_byte(SC520_CPUCTL, 1);	/* set CPU to 100 MHz and write back cache */
+/*		printf("## CPU Speed set to 100MHz\n"); */
+		gd->cpu_clk = 100000000;
+	}
+
+
+	/* wait at least one millisecond */
+	asm("movl	$0x2000,%%ecx\n"
+	    "wait_loop:	pushl %%ecx\n"
+	    "popl	%%ecx\n"
+	    "loop wait_loop\n": : : "ecx");
+
+	/* turn on the SDRAM write buffer */
+	write_mmcr_byte(SC520_DBCTL, 0x11);
+
+	/* turn on the cache and disable write through */
+	asm("movl	%%cr0, %%eax\n"
+	    "andl	$0x9fffffff, %%eax\n"
+	    "movl	%%eax, %%cr0\n"  : : : "eax");
+}
+
+/*
+ * Theory:
+ * We first set up all IRQs to be non-pci, edge triggered,
+ * when we later enumerate the pci bus and pci_sc520_fixup_irq() gets
+ * called we reallocate irqs to the pci bus with sc520_pci_set_irq()
+ * as needed. Whe choose the irqs to gram from a configurable list
+ * inside pci_sc520_fixup_irq() (If this list contains stupid irq's
+ * such as 0 thngas will not work)
+ */
+
+static void irq_init(void)
+{
+#if 0
+	/* disable global interrupt mode */
+	write_mmcr_byte(SC520_PICICR, 0x40);
+
+	/* set all irqs to edge */
+	write_mmcr_byte(SC520_MPICMODE, 0x00);
+	write_mmcr_byte(SC520_SL1PICMODE, 0x00);
+	write_mmcr_byte(SC520_SL2PICMODE, 0x00);
+
+	/* active low polarity on PIC interrupt pins,
+	 *  active high polarity on all other irq pins */
+/*	write_mmcr_word(SC520_INTPINPOL, 0x0000);	*/
+
+	/* set irq number mapping */
+	write_mmcr_byte(SC520_GPTMR1MAP, SC520_IRQ_DISABLED);   /* disable GP timer 1 INT */
+	write_mmcr_byte(SC520_GPTMR2MAP, SC520_IRQ_DISABLED);   /* disable GP timer 2 INT */
+	write_mmcr_byte(SC520_PIT0MAP, SC520_IRQ0);             /* Set PIT timer 0 INT to IRQ0 */
+	write_mmcr_byte(SC520_PIT1MAP, SC520_IRQ_DISABLED);     /* disable PIT timer 1 INT */
+	write_mmcr_byte(SC520_PIT2MAP, SC520_IRQ_DISABLED);     /* disable PIT timer 2 INT */
+	write_mmcr_byte(SC520_PCIINTCMAP, SC520_IRQ_DISABLED);  /* disable PCI INT C */
+	write_mmcr_byte(SC520_PCIINTDMAP, SC520_IRQ_DISABLED);  /* disable PCI INT D */
+	write_mmcr_byte(SC520_DMABCINTMAP, SC520_IRQ_DISABLED); /* disable DMA INT */
+	write_mmcr_byte(SC520_SSIMAP, SC520_IRQ_DISABLED);      /* disable Synchronius serial INT */
+	write_mmcr_byte(SC520_WDTMAP, SC520_IRQ_DISABLED);      /* disable Watchdog INT */
+	write_mmcr_byte(SC520_RTCMAP, SC520_IRQ8);              /* Set RTC int to 8 */
+	write_mmcr_byte(SC520_WPVMAP, SC520_IRQ_DISABLED);      /* disable write protect INT */
+	write_mmcr_byte(SC520_ICEMAP, SC520_IRQ1);              /* Set ICE Debug Serielport INT to IRQ1 */
+	write_mmcr_byte(SC520_FERRMAP,SC520_IRQ13);		/* Set FP error INT to IRQ13 */
+#endif
+
+/*	mov		ebx, UART1MAP		; UART1MAP interrupt map			*/
+/*	mov		byte ptr [ebx], 02h	; connect to Master PIC IR1			*/
+/* 	mov		ebx, GPTMR0MAP		; GP Timer 0 Interrupt Mapping			*/
+/*	mov		byte ptr [ebx], 01h	; connect to Master PIC IR0			*/
+/*	mov		ebx, PCIINTAMAP		; PCI Interrupt A Mapping Register (INTA_INT)	*/
+/*	mov		byte ptr [ebx], 03h	; connect to Slave 1 PIC IR0			*/
+/*	mov		ebx, PCIINTBMAP		; PCI Interrupt B Mapping Register (INTB_INT)	*/
+/*	mov		byte ptr [ebx], 04h	; connect to Slave 1 PIC IR1			*/
+/*	mov		ebx, GP0IMAP		; GPIRQ0 interrupt map (UART_A_INT)		*/
+/*	mov		byte ptr [ebx], 07h	; connect to Slave 1 PIC IR4			*/
+/*	mov		ebx, GP1IMAP		; GPIRQ1 interrupt map (UART_B_INT)		*/
+/*	mov		byte ptr [ebx], 08h	; connect to Slave 1 PIC IR5			*/
+/*	mov		ebx, GP2IMAP		; GPIRQ2 interrupt map (UART_C_INT)		*/
+/*	mov		byte ptr [ebx], 09h	; connect to Slave 1 PIC IR6			*/
+/*	mov		ebx, GP3IMAP		; GPIRQ3 interrupt map (UART_D_INT)		*/
+/*	mov		byte ptr [ebx], 0ah	; connect to Slave 1 PIC IR7			*/
+/*	mov		ebx, GP4IMAP		; GPIRQ4 interrupt map (DPRAM1_INT)		*/
+/*	mov		byte ptr [ebx], 0bh	; connect to Master PIC IR3			*/
+/*	mov		ebx, GP6IMAP		; GPIRQ6 interrupt map (IRIG_INT)		*/
+/*	mov		byte ptr [ebx], 0ch	; connect to Master PIC IR4			*/
+/*	mov		ebx, GP7IMAP		; GPIRQ7 interrupt map (EXP1_INT)		*/
+/*	mov		byte ptr [ebx], 0eh	; connect to Slave 2 PIC IR1			*/
+/*	mov		ebx, GP8IMAP		; GPIRQ8 interrupt map (EXP2_INT)		*/
+/*	mov		byte ptr [ebx], 0fh	; connect to Slave 2 PIC IR2			*/
+/*	mov		ebx, GP9IMAP		; GPIRQ9 interrupt map (EXP3_INT)		*/
+/*	mov		byte ptr [ebx], 010h	; connect to Slave 2 PIC IR3			*/
+/*	mov		ebx, GP10IMAP		; GPIRQ10 interrupt map (EXP4_INT or I2C_INT)	*/
+/*	mov		byte ptr [ebx], 011h	; connect to Slave 2 PIC IR4			*/
+/*	mov		ebx, BOOTCSCTL		; BOOTCS Control Register			*/
+/*	mov		word ptr [ebx], 0033h	; 3 wait states					*/
+/*	mov		ebx, ROMCS1CTL		; ROMCS1 Control Register			*/
+/*	mov		word ptr [ebx], 0615h							*/
+/*	mov		ebx, ROMCS2CTL		; ROMCS2 Control Register			*/
+/*	mov		word ptr [ebx], 0615h							*/
+/*	mov		ebx, ADDDECCTL		; SC520 Address Decode Control Register		*/
+/*	mov		byte ptr [ebx], 02h	; Enable RTC & UART1, Disable UART2		*/
+
+	write_mmcr_word(SC520_INTPINPOL, 0x0410);
+	write_mmcr_byte(SC520_UART1MAP, 0x02);
+	write_mmcr_byte(SC520_GPTMR0MAP, 0x01);
+	write_mmcr_byte(SC520_PCIINTAMAP, 0x03);
+	write_mmcr_byte(SC520_PCIINTBMAP, 0x04);
+	write_mmcr_byte(SC520_GP0IMAP, 0x07);
+	write_mmcr_byte(SC520_GP1IMAP, 0x08);
+	write_mmcr_byte(SC520_GP2IMAP, 0x09);
+	write_mmcr_byte(SC520_GP3IMAP, 0x0a);
+	write_mmcr_byte(SC520_GP4IMAP, 0x0b);
+	write_mmcr_byte(SC520_GP6IMAP, 0x0c);
+	write_mmcr_byte(SC520_GP7IMAP, 0x0e);
+	write_mmcr_byte(SC520_GP8IMAP, 0x0f);
+	write_mmcr_byte(SC520_GP9IMAP, 0x10);
+	write_mmcr_byte(SC520_GP10IMAP, 0x11);
+	write_mmcr_word(SC520_BOOTCSCTL, 0x0033);
+	write_mmcr_word(SC520_ROMCS1CTL, 0x0615);
+	write_mmcr_word(SC520_ROMCS2CTL, 0x0615);
+	write_mmcr_byte(SC520_ADDDECCTL, 0x02);
+
+/*	write_mmcr_byte(SC520_GP5IMAP, SC520_IRQ5);		*/	/* Set GPIRQ5 (ISA IRQ5) to IRQ5 */
+/*	write_mmcr_byte(SC520_GP0IMAP, SC520_IRQ11);		*/	/* Set GPIRQ0 (ISA IRQ11) to IRQ10 */
+/*	write_mmcr_byte(SC520_UART2MAP, SC520_IRQ_DISABLED);	*/	/* disable internal UART2 INT */
+/*	write_mmcr_word(SC520_PCIHOSTMAP, 0x11f);		*/	/* Map PCI hostbridge INT to NMI */
+/*	write_mmcr_word(SC520_ECCMAP, 0x100);			*/	/* Map SDRAM ECC failure INT to NMI */
+
+}
+
+#if 0
+/* PCI stuff */
+static void pci_sc520_cdp_fixup_irq(struct pci_controller *hose, pci_dev_t dev)
+{
+	/* a configurable lists of irqs to steal
+	 * when we need one (a board with more pci interrupt pins
+	 * would use a larger table */
+	static int irq_list[] = {
+		CFG_FIRST_PCI_IRQ,
+		CFG_SECOND_PCI_IRQ,
+		CFG_THIRD_PCI_IRQ,
+		CFG_FORTH_PCI_IRQ
+	};
+	static int next_irq_index=0;
+
+	unsigned char tmp_pin;
+	int pin;
+
+	pci_hose_read_config_byte(hose, dev, PCI_INTERRUPT_PIN, &tmp_pin);
+	pin = (int)tmp_pin;
+
+	pin-=1; /* pci config space use 1-based numbering */
+	if (-1 == pin) {
+		return; /* device use no irq */
+	}
+
+
+	/* map device number +  pin to a pin on the sc520 */
+	switch (PCI_DEV(dev)) {
+	case 20:
+		pin+=SC520_PCI_INTA;
+		break;
+
+	case 19:
+		pin+=SC520_PCI_INTB;
+		break;
+
+	case 18:
+		pin+=SC520_PCI_INTC;
+		break;
+
+	case 17:
+		pin+=SC520_PCI_INTD;
+		break;
+
+	default:
+		return;
+	}
+
+	pin&=3; /* wrap around */
+
+	if (sc520_pci_ints[pin] == -1) {
+		/* re-route one interrupt for us */
+		if (next_irq_index > 3) {
+			return;
+		}
+		if (pci_sc520_set_irq(pin, irq_list[next_irq_index])) {
+			return;
+		}
+		next_irq_index++;
+	}
+
+
+	if (-1 != sc520_pci_ints[pin]) {
+		pci_hose_write_config_byte(hose, dev, PCI_INTERRUPT_LINE,
+					   sc520_pci_ints[pin]);
+	}
+	PRINTF("fixup_irq: device %d pin %c irq %d\n",
+	       PCI_DEV(dev), 'A' + pin, sc520_pci_ints[pin]);
+}
+
+static struct pci_controller sc520_cdp_hose = {
+	fixup_irq: pci_sc520_cdp_fixup_irq,
+};
+
+void pci_init_board(void)
+{
+	pci_sc520_init(&sc520_cdp_hose);
+}
+#endif
+
+#if 0
+/* set up the ISA bus timing and system address mappings */
+static void bus_init(void)
+{
+
+	/* set up the GP IO pins */
+	write_mmcr_word(SC520_PIOPFS31_16, 0xf7ff);	/* set the GPIO pin function 31-16 reg */
+	write_mmcr_word(SC520_PIOPFS15_0, 0xffff);	/* set the GPIO pin function 15-0 reg */
+	write_mmcr_byte(SC520_CSPFS, 0xf8);		/* set the CS pin function  reg */
+	write_mmcr_byte(SC520_CLKSEL, 0x70);
+
+
+	write_mmcr_byte(SC520_GPCSRT, 1);   /* set the GP CS offset */
+	write_mmcr_byte(SC520_GPCSPW, 3);   /* set the GP CS pulse width */
+	write_mmcr_byte(SC520_GPCSOFF, 1);  /* set the GP CS offset */
+	write_mmcr_byte(SC520_GPRDW, 3);    /* set the RD pulse width */
+	write_mmcr_byte(SC520_GPRDOFF, 1);  /* set the GP RD offset */
+	write_mmcr_byte(SC520_GPWRW, 3);    /* set the GP WR pulse width */
+	write_mmcr_byte(SC520_GPWROFF, 1);  /* set the GP WR offset */
+
+	write_mmcr_word(SC520_BOOTCSCTL, 0x1823);		/* set up timing of BOOTCS */
+	write_mmcr_word(SC520_ROMCS1CTL, 0x1823);		/* set up timing of ROMCS1 */
+	write_mmcr_word(SC520_ROMCS2CTL, 0x1823);		/* set up timing of ROMCS2 */
+
+	/* adjust the memory map:
+	 * by default the first 256MB (0x00000000 - 0x0fffffff) is mapped to SDRAM
+	 * and 256MB to 1G-128k  (0x1000000 - 0x37ffffff) is mapped to PCI mmio
+	 * we need to map 1G-128k - 1G (0x38000000 - 0x3fffffff) to CS1 */
+
+	/* SRAM = GPCS3 128k @ d0000-effff*/
+	write_mmcr_long(SC520_PAR2,  0x4e00400d);
+
+	/* IDE0 = GPCS6 1f0-1f7 */
+	write_mmcr_long(SC520_PAR3,  0x380801f0);
+
+	/* IDE1 = GPCS7 3f6 */
+	write_mmcr_long(SC520_PAR4,  0x3c0003f6);
+	/* bootcs */
+	write_mmcr_long(SC520_PAR12, 0x8bffe800);
+	/* romcs2 */
+	write_mmcr_long(SC520_PAR13, 0xcbfff000);
+	/* romcs1 */
+	write_mmcr_long(SC520_PAR14, 0xabfff800);
+	/* 680 LEDS */
+	write_mmcr_long(SC520_PAR15, 0x30000640);
+
+	write_mmcr_byte(SC520_ADDDECCTL, 0);
+
+	asm ("wbinvd\n"); /* Flush cache, req. after setting the unchached attribute ona PAR */
+}
+#endif
+
+#if 0
+/*
+ * This function should map a chunk of size bytes
+ * of the system address space to the ISA bus
+ *
+ * The function will return the memory address
+ * as seen by the host (which may very will be the
+ * same as the bus address)
+ */
+u32 isa_map_rom(u32 bus_addr, int size)
+{
+	u32 par;
+
+	PRINTF("isa_map_rom asked to map %d bytes at %x\n",
+	       size, bus_addr);
+
+	par = size;
+	if (par < 0x80000) {
+		par = 0x80000;
+	}
+	par >>= 12;
+	par--;
+	par&=0x7f;
+	par <<= 18;
+	par |= (bus_addr>>12);
+	par |= 0x50000000;
+
+	PRINTF ("setting PAR11 to %x\n", par);
+
+	/* Map rom 0x10000 with PAR1 */
+	write_mmcr_long(SC520_PAR11,  par);
+
+	return bus_addr;
+}
+
+/*
+ * this function removed any mapping created
+ * with pci_get_rom_window()
+ */
+void isa_unmap_rom(u32 addr)
+{
+	PRINTF("isa_unmap_rom asked to unmap %x", addr);
+	if ((addr>>12) == (read_mmcr_long(SC520_PAR11)&0x3ffff)) {
+		write_mmcr_long(SC520_PAR11, 0);
+		PRINTF(" done\n");
+		return;
+	}
+	PRINTF(" not ours\n");
+}
+#endif
+
+#ifdef CONFIG_PCI
+#define PCI_ROM_TEMP_SPACE 0x10000
+/*
+ * This function should map a chunk of size bytes
+ * of the system address space to the PCI bus,
+ * suitable to map PCI ROMS (bus address < 16M)
+ * the function will return the host memory address
+ * which should be converted into a bus address
+ * before used to configure the PCI rom address
+ * decoder
+ */
+u32 pci_get_rom_window(struct pci_controller *hose, int size)
+{
+	u32 par;
+
+	par = size;
+	if (par < 0x80000) {
+		par = 0x80000;
+	}
+	par >>= 16;
+	par--;
+	par&=0x7ff;
+	par <<= 14;
+	par |= (PCI_ROM_TEMP_SPACE>>16);
+	par |= 0x72000000;
+
+	PRINTF ("setting PAR1 to %x\n", par);
+
+	/* Map rom 0x10000 with PAR1 */
+	write_mmcr_long(SC520_PAR1,  par);
+
+	return PCI_ROM_TEMP_SPACE;
+}
+
+/*
+ * this function removed any mapping created
+ * with pci_get_rom_window()
+ */
+void pci_remove_rom_window(struct pci_controller *hose, u32 addr)
+{
+	PRINTF("pci_remove_rom_window: %x", addr);
+	if (addr == PCI_ROM_TEMP_SPACE) {
+		write_mmcr_long(SC520_PAR1, 0);
+		PRINTF(" done\n");
+		return;
+	}
+	PRINTF(" not ours\n");
+
+}
+
+/*
+ * This function is called in order to provide acces to the
+ * legacy video I/O ports on the PCI bus.
+ * After this function accesses to I/O ports 0x3b0-0x3bb and
+ * 0x3c0-0x3df shuld result in transactions on the PCI bus.
+ *
+ */
+int pci_enable_legacy_video_ports(struct pci_controller *hose)
+{
+	/* Map video memory to 0xa0000*/
+	write_mmcr_long(SC520_PAR0,  0x7200400a);
+
+	/* forward all I/O accesses to PCI */
+	write_mmcr_byte(SC520_ADDDECCTL,
+			read_mmcr_byte(SC520_ADDDECCTL) | IO_HOLE_DEST_PCI);
+
+
+	/* so we map away all io ports to pci (only way to access pci io
+	 * below 0x400. But then we have to map back the portions that we dont
+	 * use so that the generate cycles on the GPIO bus where the sio and
+	 * ISA slots are connected, this requre the use of several PAR registers
+	 */
+
+	/* bring 0x100 - 0x1ef back to ISA using PAR5 */
+	write_mmcr_long(SC520_PAR5, 0x30ef0100);
+
+	/* IDE use 1f0-1f7 */
+
+	/* bring 0x1f8 - 0x2f7 back to ISA using PAR6 */
+	write_mmcr_long(SC520_PAR6, 0x30ff01f8);
+
+	/* com2 use 2f8-2ff */
+
+	/* bring 0x300 - 0x3af back to ISA using PAR7 */
+	write_mmcr_long(SC520_PAR7, 0x30af0300);
+
+	/* vga use 3b0-3bb */
+
+	/* bring 0x3bc - 0x3bf back to ISA using PAR8 */
+	write_mmcr_long(SC520_PAR8, 0x300303bc);
+
+	/* vga use 3c0-3df */
+
+	/* bring 0x3e0 - 0x3f5 back to ISA using PAR9 */
+	write_mmcr_long(SC520_PAR9, 0x301503e0);
+
+	/* ide use 3f6 */
+
+	/* bring 0x3f7  back to ISA using PAR10 */
+	write_mmcr_long(SC520_PAR10, 0x300003f7);
+
+	/* com1 use 3f8-3ff */
+
+	return 0;
+}
+#endif
+
+/*
+ * Miscelaneous platform dependent initializations
+ */
+
+int board_init(void)
+{
+/*	init_sc520();	*/
+
+	init_sc520_enet();
+
+	/*	bus_init(); */
+
+	irq_init();
+
+	/* max drive current on SDRAM */
+/*	write_mmcr_word(SC520_DSCTL, 0x0100);	*/
+
+	/* enter debug mode after next reset (only if jumper is also set) */
+/*	write_mmcr_byte(SC520_RESCFG, 0x00);	*/
+
+	/* Crystal is 33.000MHz */
+	gd->bus_clk = 33000000;
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	init_sc520_dram();
+	return 0;
+}
+
+void show_boot_progress(int val)
+{
+	uchar led_mask;
+
+	led_mask = 0x00;
+
+	if (val < 0)
+		led_mask |= LED_ERR_BITMASK;
+
+	led_mask |= (uchar)(val & 0x001f);
+	outb(led_mask, LED_LATCH_ADDRESS);
+}
+
+
+int last_stage_init(void)
+{
+	int minor;
+	int major;
+
+	major = minor = 0;
+
+	printf("Serck Controls eNET\n");
+	printf("last_stage_init()@%08lx\n", (ulong)last_stage_init);
+
+	printf("autoscript => do_autoscript()        @ 0x%08lx\n", (ulong)do_autoscript);
+	printf("bdinfo     => do_bdinfo()            @ 0x%08lx\n", (ulong)do_bdinfo);
+	printf("go         => do_go()                @ 0x%08lx\n", (ulong)do_go);
+	printf("reset      => do_reset()             @ 0x%08lx\n", (ulong)do_reset);
+	printf("bootm      => do_bootm()             @ 0x%08lx\n", (ulong)do_bootm);
+	printf("boot       => do_bootd()             @ 0x%08lx\n", (ulong)do_bootd);
+	printf("bootd      => do_bootd()             @ 0x%08lx\n", (ulong)do_bootd);
+	printf("iminfo     => do_iminfo()            @ 0x%08lx\n", (ulong)do_iminfo);
+/*	printf("imls       => do_imls()              @ 0x%08lx\n", (ulong)do_imls); */
+	printf("imls       => do_imls()              @ <undefined>\n");
+	printf("coninfo    => do_coninfo()           @ 0x%08lx\n", (ulong)do_coninfo);
+	printf("itest      => do_itest()             @ 0x%08lx\n", (ulong)do_itest);
+	printf("loads      => do_load_serial()       @ 0x%08lx\n", (ulong)do_load_serial);
+	printf("loadb      => do_load_serial_bin()   @ 0x%08lx\n", (ulong)do_load_serial_bin);
+	printf("loady      => do_load_serial_bin()   @ 0x%08lx\n", (ulong)do_load_serial_bin);
+	printf("md         => do_mem_md()            @ 0x%08lx\n", (ulong)do_mem_md);
+	printf("mm         => do_mem_mm()            @ 0x%08lx\n", (ulong)do_mem_mm);
+	printf("nm         => do_mem_nm()            @ 0x%08lx\n", (ulong)do_mem_nm);
+	printf("mw         => do_mem_mw()            @ 0x%08lx\n", (ulong)do_mem_mw);
+	printf("cp         => do_mem_cp()            @ 0x%08lx\n", (ulong)do_mem_cp);
+	printf("cmp        => do_mem_cmp()           @ 0x%08lx\n", (ulong)do_mem_cmp);
+	printf("crc32      => do_mem_crc()           @ 0x%08lx\n", (ulong)do_mem_crc);
+	printf("base       => do_mem_base()          @ 0x%08lx\n", (ulong)do_mem_base);
+	printf("loop       => do_mem_loop()          @ 0x%08lx\n", (ulong)do_mem_loop);
+	printf("mtest      => do_mem_mtest()         @ 0x%08lx\n", (ulong)do_mem_mtest);
+	printf("sleep      => do_sleep()             @ 0x%08lx\n", (ulong)do_sleep);
+	printf("printenv   => do_printenv()          @ 0x%08lx\n", (ulong)do_printenv);
+	printf("setenv     => do_setenv()            @ 0x%08lx\n", (ulong)do_setenv);
+	printf("saveenv    => do_saveenv()           @ 0x%08lx\n", (ulong)do_saveenv);
+	printf("run        => do_run()               @ 0x%08lx\n", (ulong)do_run);
+	printf("imxtract   => do_imgextract()        @ 0x%08lx\n", (ulong)do_imgextract);
+	printf("version    => do_version()           @ 0x%08lx\n", (ulong)do_version);
+	printf("echo       => do_echo()              @ 0x%08lx\n", (ulong)do_echo);
+	printf("help       => do_help()              @ 0x%08lx\n", (ulong)do_help);
+	printf("?          => do_help()              @ 0x%08lx\n", (ulong)do_help);
+
+
+	return 0;
+}
+
+
diff --git a/board/eNET/eNET_start.S b/board/eNET/eNET_start.S
new file mode 100644
index 0000000..124660c
--- /dev/null
+++ b/board/eNET/eNET_start.S
@@ -0,0 +1,224 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engstr?m, Omicron Ceti AB <daniel@omicron.se>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <asm/ic/sc520_defs.h>
+
+#include "hardware_defs.h"
+
+sc520_cdp_registers:
+/*
+ * This is the MMCR configuration array - only change the values here if
+ * you are absolutely sure you know what you are doing
+ */
+/* size		offset		value */
+.word 0x0001 ; .word 0x0040 ; .long 0x00000000	/* SDRAM buffer control */
+.word 0x0001 ; .word 0x0c08 ; .long 0x00000001	/* GP Chip Select Recovery Time */
+.word 0x0001 ; .word 0x0c09 ; .long 0x00000007	/* GP Chip Select Pulse Width */
+.word 0x0001 ; .word 0x0c0a ; .long 0x00000000	/* GP Chip Select Offset */
+.word 0x0001 ; .word 0x0c0b ; .long 0x00000005	/* GP Read pulse width */
+.word 0x0001 ; .word 0x0c0c ; .long 0x00000001	/* GP Read offset */
+.word 0x0001 ; .word 0x0c0d ; .long 0x00000005	/* GP Write pulse width */
+.word 0x0001 ; .word 0x0c0e ; .long 0x00000001	/* GP Write offset */
+.word 0x0002 ; .word 0x0c30 ; .long 0x00000630	/* PIO15_PIO0 Data */
+.word 0x0002 ; .word 0x0c32 ; .long 0x00002000	/* PIO31_PIO16 Data */
+.word 0x0002 ; .word 0x0c2c ; .long 0x00002000	/* GPIO directionreg */
+.word 0x0002 ; .word 0x0c2a ; .long 0x000087b5	/* GPIO directionreg */
+.word 0x0002 ; .word 0x0c22 ; .long 0x00000dfe	/* GPIO pin function 31-16 reg */
+.word 0x0002 ; .word 0x0c20 ; .long 0x0000200a	/* GPIO pin function 15-0 reg */
+.word 0x0001 ; .word 0x0c24 ; .long 0x000000F8	/* Chip Select Pin Function Select */
+.word 0x0004 ; .word 0x0090 ; .long 0x200713f8	/* PAR2 - Uart A (GPCS0, 0x013f8, 8 Bytes) */
+.word 0x0004 ; .word 0x0094 ; .long 0x2c0712f8	/* PAR3 - Uart B (GPCS3, 0x012f8, 8 Bytes) */
+.word 0x0004 ; .word 0x0098 ; .long 0x300711f8	/* PAR4 - Uart C (GPCS4, 0x011f8, 8 Bytes) */
+.word 0x0004 ; .word 0x009c ; .long 0x340710f8	/* PAR5 - Uart D (GPCS5, 0x010f8, 8 Bytes) */
+.word 0x0004 ; .word 0x00a0 ; .long 0xe3ffc000	/* PAR6 - SDRAM (0x00000000, 128MB) */
+.word 0x0004 ; .word 0x00a4 ; .long 0xaa3fd000	/* PAR7 - StrataFlash (ROMCS1, 0x10000000, 16MB) */
+.word 0x0004 ; .word 0x00a8 ; .long 0xca3fd100	/* PAR8 - StrataFlash (ROMCS2, 0x11000000, 16MB) */
+.word 0x0004 ; .word 0x00ac ; .long 0x4203d900	/* PAR9 - SRAM (GPCS0, 0x19000000, 1MB) */
+.word 0x0004 ; .word 0x00b0 ; .long 0x4e03d910	/* PAR10 -SRAM (GPCS3, 0x19100000, 1MB) */
+.word 0x0004 ; .word 0x00b4 ; .long 0x50018100	/* PAR11 -DP-RAM (GPCS4, 0x18100000, 4kB) */
+.word 0x0004 ; .word 0x00b8 ; .long 0x54020000	/* PAR12 -CFLASH1 (0x200000000, 4kB) */
+.word 0x0004 ; .word 0x00bc ; .long 0x5c020001	/* PAR13 -CFLASH2 (0x200010000, 4kB) */
+.word 0x0004 ; .word 0x00c0 ; .long 0x8bfff800	/* PAR14 - BOOTCS at  0x18000000 */
+.word 0x0004 ; .word 0x00c4 ; .long 0x38201000	/* PAR15 - LEDs etc (GPCS6, 0x1000, 20 Bytes */
+.word 0x0002 ; .word 0x0cb0 ; .long 0x00003333	/* Activate watchdog status register step 1 */
+.word 0x0002 ; .word 0x0cb0 ; .long 0x0000cccc	/* Activate watchdog status register step 2 */
+.word 0x0002 ; .word 0x0cb0 ; .long 0x00000000	/* Disable Watchdog */
+.word 0x0000 ; .word 0x0000 ; .long 0x00000000	/* EOT */
+
+/* board early intialization */
+.globl early_board_init
+early_board_init:
+	movl    $sc520_cdp_registers,%esi
+init_loop:
+	movl    $0xfffef000,%edi     /* MMCR base to edi */
+	movw	(%esi), %bx          /* load sizer to bx */
+	cmpw	$0, %bx              /* if sie is 0 we're done */
+	je	done
+	xorl	%edx,%edx
+	movw	2(%esi), %dx        /* load MMCR offset to dx */
+	addl	%edx, %edi          /* add offset to base in edi */
+	movl	4(%esi), %eax       /* load value in eax */
+	cmpw	$1, %bx
+	je	byte                 /* byte op? */
+	cmpw	$2, %bx
+	je	word                 /* word op? */
+	movl	%eax, (%edi)         /* must be long, then */
+	jmp	next
+byte:   movb    %al,(%edi)
+	jmp	next
+word:	movw	%ax,(%edi)
+next:	addl	$8, %esi             /* advance esi */
+	jmp	init_loop
+done:
+	/* The LEDs are now available */
+	movw	$LED_LATCH_ADDRESS, %dx
+	movb	$0x0f, %al
+	outb	%al, %dx
+
+	/* Initialize 8259 master */
+#	mov     al, 78h     ; Use int vectors 78h to 7fh.
+#	mov     dx, MPICICW2
+#	out     dx, al
+#	jmp     $+2
+#	mov     al, 24h     ; IR2 and IR5 has a slave PIC.
+#	out     dx, al			; MPICICW3
+#	jmp     $+2
+#	mov     al, 01h     ; Master, 8086 mode.
+#	out     dx, al			; MPICICW4
+#	jmp     $+2
+#	mov     al, 0ffh    ; Mask interrupt of master PIC.
+#	out     dx, al      ; MPICINTMSK
+#	jmp     $+2
+	movb	$0x11, %al
+	movw	$MPICICW1, %dx
+	outb     %al, %dx
+	jmp     .+2
+	movb	$0x78, %al
+	movw	$MPICICW2, %dx
+	outb     %al, %dx
+	jmp     .+2
+	movb	$0x24, %al
+	out     %al, %dx
+	jmp     .+2
+	movb	$0x01, %al
+	outb     %al, %dx
+	jmp     .+2
+	movb	$0xff, %al
+	outb     %al, %dx
+	jmp     .+2
+
+	/* Initialize 8259 slave1 */
+#	mov     al, 11h        ; Edge, slave 1, ICW4.
+#	mov     dx, S1PICICW1
+#	out     dx, al
+#	jmp     $+2
+#	mov     al, 70h        ; Use int vectors 70h to 77h.
+#	mov     dx, S1PICICW2
+#	out     dx, al
+#	jmp     $+2
+#	mov     al, 02h        ; Slave ID = 2.
+#	out     dx, al			   ; S1PICICW3
+#	jmp     $+2
+#	mov     al, 01h        ; Enable device.
+#	out     dx, al			   ; S1PICICW4
+#	jmp     $+2
+#	mov     al, 0ffh       ; Mask interrupt of slave PIC.
+#	out     dx, al			   ; S1PICINTMSK
+#	jmp     $+2
+	movb	$0x11, %al
+	movw	$S1PICICW1, %dx
+	outb     %al, %dx
+	jmp     .+2
+	movb	$0x70, %al
+	movw	$S1PICICW2, %dx
+	outb     %al, %dx
+	jmp     .+2
+	movb	$0x02, %al
+	outb     %al, %dx
+	jmp     .+2
+	movb	$0x01, %al
+	outb     %al, %dx
+	jmp     .+2
+	movb	$0xff, %al
+	outb     %al, %dx
+	jmp     .+2
+
+	/* Initialize 8259 slave 2 */
+#	mov     al, 11h        ; Edge, slave 2, ICW4.
+#	mov     dx, S2PICICW1
+#	out     dx, al
+#	jmp     $+2
+#	mov     al, 68h        ; Use int vectors 68h to 6fh.
+#	mov     dx, S2PICICW2
+#	out     dx, al
+#	jmp     $+2
+#	mov     al, 05h        ; Slave ID = 5.
+#	out     dx, al			   ; S2PICICW3
+#	jmp     $+2
+#	mov     al, 01h        ; Enable Device.
+#	out     dx, al			   ; S2PICICW4
+#	jmp     $+2
+#	mov     al, 0ffh       ; Mask interrupt of slave 2 PIC.
+#	out     dx, al			   ; S2PICINTMSK
+#	jmp     $+2
+	movb	$0x11, %al
+	movw	$S2PICICW1, %dx
+	outb     %al, %dx
+	jmp     .+2
+	movb	$0x68, %al
+	movw	$S2PICICW2, %dx
+	outb     %al, %dx
+	jmp     .+2
+	movb	$0x05, %al
+	outb     %al, %dx
+	jmp     .+2
+	movb	$0x01, %al
+	outb     %al, %dx
+	jmp     .+2
+	movb	$0xff, %al
+	outb     %al, %dx
+	jmp     .+2
+
+
+	jmp	*%ebp		     /* return to caller */
+
+.globl show_boot_progress_asm
+show_boot_progress_asm:
+
+	movb	%al, %dl	/* Create Working Copy */
+	andb	$0x80, %dl	/* Mask in only Error bit */
+	shrb	$0x02, %dl	/* Shift Error bit to Error LED */
+	andb	$0x0f, %al	/* Mask out 'Error' bit */
+	orb	%dl, %al	/* Mask in ERR LED */
+	movw	$LED_LATCH_ADDRESS, %dx
+	outb	%al, %dx
+
+	jmp	*%ebp		/* return to caller */
+
+
+.globl cpu_halt_asm
+cpu_halt_asm:
+	movb	$0x0f, %al
+	movw	$LED_LATCH_ADDRESS, %dx
+	outb	%al, %dx
+	hlt
+	jmp cpu_halt_asm
diff --git a/board/eNET/eNET_start16.S b/board/eNET/eNET_start16.S
new file mode 100644
index 0000000..e0d2ebb
--- /dev/null
+++ b/board/eNET/eNET_start16.S
@@ -0,0 +1,91 @@
+/*
+ * (C) Copyright 2002
+ * Daniel Engstr?m, Omicron Ceti AB <daniel@omicron.se>.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * 16bit initialization code.
+ * This code have to map the area of the boot flash
+ * that is used by U-boot to its final destination.
+ */
+
+#include "hardware.h"
+
+.text
+.section .start16, "ax"
+.code16
+.globl board_init16
+board_init16:
+	/* Alias MMCR to 0xdf000 */
+	movw	$0xfffc, %dx
+	movl	$0x800df0cb, %eax
+	outl	%eax, %dx
+
+	/* Set ds to point to MMCR alias */
+	movw	$0xdf00, %ax
+	movw	%ax, %ds
+
+	/* Map the entire flash at 0x38000000
+	 * (with BOOTCS and PAR14, use 0xabfff800 for ROMCS1) */
+	movl    $0xc0, %edi
+	movl	$0x8bfff800, %eax
+	movl	%eax, (%di)
+
+	/* Disable SDRAM write buffer */
+	movw    $0x40,%di
+	xorw    %ax,%ax
+	movb    %al, (%di)
+
+#; turn off the cache
+#	mov	eax, cr0
+#	or	eax,060000000h
+#	mov	cr0, eax
+#	wbinvd		; flush the cache
+
+
+	/* Disabe MMCR alias */
+	movw	$0xfffc, %dx
+	movl	$0x000000cb, %eax
+	outl	%eax, %dx
+
+	/* the return address is stored in bp */
+	jmp	*%bp
+
+.section .bios, "ax"
+.code16
+.globl realmode_reset
+realmode_reset:
+	/* Alias MMCR to 0xdf000 */
+	movw	$0xfffc, %dx
+	movl	$0x800df0cb, %eax
+	outl	%eax, %dx
+
+	/* Set ds to point to MMCR alias */
+	movw	$0xdf00, %ax
+	movw	%ax, %ds
+
+	/* issue software reset thorugh MMCR */
+	movl    $0xd72, %edi
+	movb	$0x01, %al
+	movb	%al, (%di)
+
+1:	hlt
+	jmp	1
diff --git a/board/eNET/flash.c b/board/eNET/flash.c
new file mode 100644
index 0000000..168477b
--- /dev/null
+++ b/board/eNET/flash.c
@@ -0,0 +1,641 @@
+/*
+ * (C) Copyright 2002, 2003
+ * Daniel Engstr?m, Omicron Ceti AB, daniel at omicron.se
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <asm/ic/sc520.h>
+
+#define PROBE_BUFFER_SIZE 1024
+static unsigned char buffer[PROBE_BUFFER_SIZE];
+
+#define SC520_MAX_FLASH_BANKS  3
+#define SC520_FLASH_BANK0_BASE 0x38000000  /* BOOTCS */
+#define SC520_FLASH_BANK1_BASE 0x10ffffff  /* ROMCS0 */
+#define SC520_FLASH_BANK2_BASE 0x11ffffff  /* ROMCS1 */
+#define SC520_FLASH_BANKSIZE   0x1000000
+
+#define AMD29LV016B_SIZE        0x80000
+#define AMD29LV016B_SECTORS     32
+
+flash_info_t    flash_info[SC520_MAX_FLASH_BANKS];
+
+#define READY 1
+#define ERR   2
+#define TMO   4
+
+/*-----------------------------------------------------------------------
+ */
+
+
+static u32 _probe_flash(u32 addr, u32 bw, int il)
+{
+	u32 result=0;
+
+	/* First do an unlock cycle for the benefit of
+	 * devices that need it */
+
+	switch (bw) {
+
+	case 1:
+		*(volatile u8*)(addr+0x5555) = 0xaa;
+		*(volatile u8*)(addr+0x2aaa) = 0x55;
+		*(volatile u8*)(addr+0x5555) = 0x90;
+
+		/* Read vendor */
+		result = *(volatile u8*)addr;
+		result <<= 16;
+
+		/* Read device */
+		result |= *(volatile u8*)(addr+2);
+
+		/* Return device to data mode */
+		*(volatile u8*)addr = 0xff;
+		*(volatile u8*)(addr+0x5555), 0xf0;
+		break;
+
+	case 2:
+		*(volatile u16*)(addr+0xaaaa) = 0xaaaa;
+		*(volatile u16*)(addr+0x5554) = 0x5555;
+
+		/* Issue identification command */
+		if (il == 2) {
+			*(volatile u16*)(addr+0xaaaa) = 0x9090;
+
+			/* Read vendor */
+			result = *(volatile u8*)addr;
+			result <<= 16;
+
+			/* Read device */
+			result |= *(volatile u8*)(addr+2);
+
+			/* Return device to data mode */
+			*(volatile u16*)addr =  0xffff;
+			*(volatile u16*)(addr+0xaaaa), 0xf0f0;
+
+		} else {
+			*(volatile u8*)(addr+0xaaaa) = 0x90;
+			/* Read vendor */
+			result = *(volatile u16*)addr;
+			result <<= 16;
+
+			/* Read device */
+			result |= *(volatile u16*)(addr+2);
+
+			/* Return device to data mode */
+			*(volatile u8*)addr = 0xff;
+			*(volatile u8*)(addr+0xaaaa), 0xf0;
+		}
+
+		break;
+
+	 case 4:
+		*(volatile u32*)(addr+0x5554) = 0xaaaaaaaa;
+		*(volatile u32*)(addr+0xaaa8) = 0x55555555;
+
+		switch (il) {
+		case 1:
+			/* Issue identification command */
+			*(volatile u8*)(addr+0x5554) = 0x90;
+
+			/* Read vendor */
+			result = *(volatile u16*)addr;
+			result <<= 16;
+
+			/* Read device */
+			result |= *(volatile u16*)(addr+4);
+
+			/* Return device to data mode */
+			*(volatile u8*)addr =  0xff;
+			*(volatile u8*)(addr+0x5554), 0xf0;
+			break;
+
+		case 2:
+			/* Issue identification command */
+			*(volatile u32*)(addr + 0x5554) = 0x00900090;
+
+			/* Read vendor */
+			result = *(volatile u16*)addr;
+			result <<= 16;
+
+			/* Read device */
+			result |= *(volatile u16*)(addr+4);
+
+			/* Return device to data mode */
+			*(volatile u32*)addr =  0x00ff00ff;
+			*(volatile u32*)(addr+0x5554), 0x00f000f0;
+			break;
+
+		case 4:
+			/* Issue identification command */
+			*(volatile u32*)(addr+0x5554) = 0x90909090;
+
+			/* Read vendor */
+			result = *(volatile u8*)addr;
+			result <<= 16;
+
+			/* Read device */
+			result |= *(volatile u8*)(addr+4);
+
+			/* Return device to data mode */
+			*(volatile u32*)addr =  0xffffffff;
+			*(volatile u32*)(addr+0x5554), 0xf0f0f0f0;
+			break;
+		}
+		break;
+	}
+
+
+	return result;
+}
+
+extern int _probe_flash_end;
+asm ("_probe_flash_end:\n"
+     ".long 0\n");
+
+static int identify_flash(unsigned address, int width)
+{
+	int is;
+	int device;
+	int vendor;
+	int size;
+	unsigned res;
+
+	u32 (*_probe_flash_ptr)(u32 a, u32 bw, int il);
+
+	size = (unsigned)&_probe_flash_end - (unsigned)_probe_flash;
+
+	if (size > PROBE_BUFFER_SIZE) {
+		printf("_probe_flash() routine too large (%d) %p - %p\n",
+		       size, &_probe_flash_end, _probe_flash);
+		return 0;
+	}
+
+	memcpy(buffer, _probe_flash, size);
+	_probe_flash_ptr = (void*)buffer;
+
+	is = disable_interrupts();
+	res = _probe_flash_ptr(address, width, 1);
+	if (is) {
+		enable_interrupts();
+	}
+
+
+	vendor = res >> 16;
+	device = res & 0xffff;
+
+
+	return res;
+}
+
+ulong flash_init(void)
+{
+	int i, j;
+	ulong size = 0;
+
+	printf("flash_init ()");
+
+	printf("Test %d Test %08x\n", 2, 1024);
+
+	for (i = 0; i < SC520_MAX_FLASH_BANKS; i++) {
+		unsigned id;
+		ulong flashbase = 0;
+		int sectsize = 0;
+
+		memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
+		switch (i) {
+		case 0:
+			flashbase = SC520_FLASH_BANK0_BASE;
+			break;
+		case 1:
+			flashbase = SC520_FLASH_BANK1_BASE;
+			break;
+		case 2:
+			flashbase = SC520_FLASH_BANK2_BASE;
+			break;
+		default:
+			panic("configured too many flash banks!\n");
+		}
+
+		id = identify_flash(flashbase, 4);
+		switch (id & 0x00ff00ff) {
+		case 0x000100c8:
+			/* 29LV016B/29LV017B */
+			flash_info[i].flash_id =
+				(AMD_MANUFACT & FLASH_VENDMASK) |
+				(AMD_ID_LV016B & FLASH_TYPEMASK);
+
+			flash_info[i].size = AMD29LV016B_SIZE*4;
+			flash_info[i].sector_count = AMD29LV016B_SECTORS;
+			sectsize = (AMD29LV016B_SIZE*4)/AMD29LV016B_SECTORS;
+			printf("Bank %d: 4 x AMD 29LV017B\n", i);
+			break;
+
+
+		default:
+			printf("Bank %d have unknown flash %08x\n", i, id);
+			flash_info[i].flash_id = FLASH_UNKNOWN;
+			continue;
+		}
+
+		for (j = 0; j < flash_info[i].sector_count; j++) {
+			flash_info[i].start[j] = flashbase + j * sectsize;
+		}
+		size += flash_info[i].size;
+
+		flash_protect(FLAG_PROTECT_CLEAR,
+			      flash_info[i].start[0],
+			       flash_info[i].start[0] + flash_info[i].size - 1,
+			      &flash_info[i]);
+	}
+
+	/*
+	 * Protect monitor and environment sectors
+	 */
+	flash_protect(FLAG_PROTECT_SET,
+		      i386boot_start,
+		      i386boot_end,
+		      &flash_info[0]);
+#ifdef CFG_ENV_ADDR
+	flash_protect(FLAG_PROTECT_SET,
+		      CFG_ENV_ADDR,
+		      CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+		      &flash_info[0]);
+#endif
+	return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info(flash_info_t *info)
+{
+	int i;
+
+	switch (info->flash_id & FLASH_VENDMASK) {
+
+	case (AMD_MANUFACT & FLASH_VENDMASK):
+		printf("AMD:   ");
+		switch (info->flash_id & FLASH_TYPEMASK) {
+		case (AMD_ID_LV016B & FLASH_TYPEMASK):
+			printf("4x AMD29LV017B (4x16Mbit)\n");
+			break;
+		default:
+			printf("Unknown Chip Type\n");
+			goto done;
+			break;
+		}
+
+		break;
+	default:
+		printf("Unknown Vendor ");
+		break;
+	}
+
+
+	printf("  Size: %ld MB in %d Sectors\n",
+	       info->size >> 20, info->sector_count);
+
+	printf("  Sector Start Addresses:");
+	for (i = 0; i < info->sector_count; i++) {
+		if ((i % 5) == 0) {
+			printf ("\n   ");
+		}
+		printf (" %08lX%s", info->start[i],
+			info->protect[i] ? " (RO)" : "     ");
+	}
+	printf ("\n");
+
+done:	;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+/* this needs to be inlined, the SWTMRMMILLI register is reset by each read */
+#define __udelay(delay) \
+{	\
+	unsigned micro; \
+	unsigned milli=0; \
+	\
+	micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \
+	 \
+	for (;;) { \
+		\
+		milli += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); \
+		micro = *(volatile u16*)(0xfffef000+SC520_SWTMRMICRO); \
+		\
+		if ((delay) <= (micro + (milli * 1000))) { \
+			break; \
+		} \
+	} \
+} while (0)
+
+static u32 _amd_erase_flash(u32 addr, u32 sector)
+{
+	unsigned elapsed;
+
+	/* Issue erase */
+	*(volatile u32*)(addr + 0x5554) = 0xAAAAAAAA;
+	*(volatile u32*)(addr + 0xaaa8) = 0x55555555;
+	*(volatile u32*)(addr + 0x5554) = 0x80808080;
+	/* And one unlock */
+	*(volatile u32*)(addr + 0x5554) = 0xAAAAAAAA;
+	*(volatile u32*)(addr + 0xaaa8) = 0x55555555;
+	/* Sector erase command comes last */
+	*(volatile u32*)(addr + sector) = 0x30303030;
+
+	elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */
+	elapsed = 0;
+	__udelay(50);
+	while (((*(volatile u32*)(addr + sector)) & 0x80808080) != 0x80808080) {
+
+		elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
+		if (elapsed > ((CFG_FLASH_ERASE_TOUT/CFG_HZ) * 1000)) {
+			*(volatile u32*)(addr) = 0xf0f0f0f0;
+			return 1;
+		}
+	}
+
+	*(volatile u32*)(addr) = 0xf0f0f0f0;
+
+	return 0;
+}
+
+extern int _amd_erase_flash_end;
+asm ("_amd_erase_flash_end:\n"
+     ".long 0\n");
+
+int flash_erase(flash_info_t *info, int s_first, int s_last)
+{
+	u32 (*_erase_flash_ptr)(u32 a, u32 so);
+	int prot;
+	int sect;
+	unsigned size;
+
+	if ((s_first < 0) || (s_first > s_last)) {
+		if (info->flash_id == FLASH_UNKNOWN) {
+			printf("- missing\n");
+		} else {
+			printf("- no sectors to erase\n");
+		}
+		return 1;
+	}
+
+	if ((info->flash_id & FLASH_VENDMASK) == (AMD_MANUFACT & FLASH_VENDMASK)) {
+		size = (unsigned)&_amd_erase_flash_end - (unsigned)_amd_erase_flash;
+
+		if (size > PROBE_BUFFER_SIZE) {
+			printf("_amd_erase_flash() routine too large (%d) %p - %p\n",
+			       size, &_amd_erase_flash_end, _amd_erase_flash);
+			return 0;
+		}
+
+		memcpy(buffer, _amd_erase_flash, size);
+		_erase_flash_ptr = (void*)buffer;
+
+	}  else {
+		printf ("Can't erase unknown flash type - aborted\n");
+		return 1;
+	}
+
+	prot = 0;
+	for (sect=s_first; sect<=s_last; ++sect) {
+		if (info->protect[sect]) {
+			prot++;
+		}
+	}
+
+	if (prot) {
+		printf ("- Warning: %d protected sectors will not be erased!\n", prot);
+	} else {
+		printf ("\n");
+	}
+
+
+	/* Start erase on unprotected sectors */
+	for (sect = s_first; sect<=s_last; sect++) {
+
+		if (info->protect[sect] == 0) { /* not protected */
+			int res;
+			int flag;
+
+			/* Disable interrupts which might cause a timeout here */
+			flag = disable_interrupts();
+
+			res = _erase_flash_ptr(info->start[0], info->start[sect]-info->start[0]);
+
+			/* re-enable interrupts if necessary */
+			if (flag) {
+				enable_interrupts();
+			}
+
+
+			if (res) {
+				printf("Erase timed out, sector %d\n", sect);
+				return res;
+			}
+
+			putc('.');
+		}
+	}
+
+
+	return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int _amd_write_word(unsigned start, unsigned dest, unsigned data)
+{
+	volatile u32 *addr2 = (u32*)start;
+	volatile u32 *dest2 = (u32*)dest;
+	volatile u32 *data2 = (u32*)&data;
+	unsigned elapsed;
+
+	/* Check if Flash is (sufficiently) erased */
+	if ((*((volatile u32*)dest) & (u32)data) != (u32)data) {
+		return 2;
+	}
+
+	addr2[0x5554] = 0xAAAAAAAA;
+	addr2[0xaaa8] = 0x55555555;
+	addr2[0x5554] = 0xA0A0A0A0;
+
+	dest2[0] = data;
+
+	elapsed = *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI); /* dummy read */
+	elapsed = 0;
+
+	/* data polling for D7 */
+	while ((dest2[0] & 0x80808080) != (data2[0] & 0x80808080)) {
+		elapsed += *(volatile u16*)(0xfffef000+SC520_SWTMRMILLI);
+		if (elapsed > ((CFG_FLASH_WRITE_TOUT/CFG_HZ) * 1000)) {
+			addr2[0] = 0xf0f0f0f0;
+			return 1;
+		}
+	}
+
+
+	addr2[0] = 0xf0f0f0f0;
+
+	return 0;
+}
+
+extern int _amd_write_word_end;
+asm ("_amd_write_word_end:\n"
+     ".long 0\n");
+
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ * 3 - Unsupported flash type
+ */
+
+int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+	ulong cp, wp, data;
+	int i, l, rc;
+	int flag;
+	u32 (*_write_word_ptr)(unsigned start, unsigned dest, unsigned data);
+	unsigned size;
+
+	if ((info->flash_id & FLASH_VENDMASK) == (AMD_MANUFACT & FLASH_VENDMASK)) {
+		size = (unsigned)&_amd_write_word_end - (unsigned)_amd_write_word;
+
+		if (size > PROBE_BUFFER_SIZE) {
+			printf("_amd_write_word() routine too large (%d) %p - %p\n",
+			       size, &_amd_write_word_end, _amd_write_word);
+			return 0;
+		}
+
+		memcpy(buffer, _amd_write_word, size);
+		_write_word_ptr = (void*)buffer;
+
+	} else {
+		printf ("Can't program unknown flash type - aborted\n");
+		return 3;
+	}
+
+
+	wp = (addr & ~3);	/* get lower word aligned address */
+
+
+	/*
+	 * handle unaligned start bytes
+	 */
+	if ((l = addr - wp) != 0) {
+		data = 0;
+		for (i=0, cp=wp; i<l; ++i, ++cp) {
+			data |= (*(uchar *)cp) << (8*i);
+		}
+		for (; i<4 && cnt>0; ++i) {
+			data |= *src++ << (8*i);
+			--cnt;
+			++cp;
+		}
+		for (; cnt==0 && i<4; ++i, ++cp) {
+			data |= (*(uchar *)cp)  << (8*i);
+		}
+
+		/* Disable interrupts which might cause a timeout here */
+		flag = disable_interrupts();
+
+		rc = _write_word_ptr(info->start[0], wp, data);
+
+		/* re-enable interrupts if necessary */
+		if (flag) {
+			enable_interrupts();
+		}
+		if (rc != 0) {
+			return rc;
+		}
+		wp += 4;
+	}
+
+	/*
+	 * handle word aligned part
+	 */
+	while (cnt >= 4) {
+		data = 0;
+
+		for (i=0; i<4; ++i) {
+			data |= *src++ << (8*i);
+		}
+
+		/* Disable interrupts which might cause a timeout here */
+		flag = disable_interrupts();
+
+		rc = _write_word_ptr(info->start[0], wp, data);
+
+		/* re-enable interrupts if necessary */
+		if (flag) {
+			enable_interrupts();
+		}
+		if (rc != 0) {
+			return rc;
+		}
+		wp  += 4;
+		cnt -= 4;
+	}
+
+	if (cnt == 0) {
+		return 0;
+	}
+
+	/*
+	 * handle unaligned tail bytes
+	 */
+	data = 0;
+	for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+		data |= *src++ << (8*i);
+		--cnt;
+	}
+
+	for (; i<4; ++i, ++cp) {
+		data |= (*(uchar *)cp) << (8*i);
+	}
+
+	/* Disable interrupts which might cause a timeout here */
+	flag = disable_interrupts();
+
+	rc = _write_word_ptr(info->start[0], wp, data);
+
+	/* re-enable interrupts if necessary */
+	if (flag) {
+		enable_interrupts();
+	}
+
+	return rc;
+
+}

             reply	other threads:[~2008-09-29 13:26 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-29 13:26 Graeme Russ [this message]
2008-10-27 23:37 ` [U-Boot] [RFC][PATCH 2a/3] New i386 board (includes code relocation) Wolfgang Denk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48E0D794.1020308@gmail.com \
    --to=graeme.russ@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.