Merge branch 'master' of /home/wd/git/u-boot/custodians
diff --git a/MAKEALL b/MAKEALL
index fbde734..233e266 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -645,8 +645,8 @@
 #########################################################################
 
 LIST_microblaze="	\
-	suzaku		\
 	ml401		\
+	suzaku		\
 	xupv2p		\
 "
 
@@ -719,6 +719,12 @@
 	${LIST_sh4}	\
 "
 
+#########################################################################
+## SPARC Systems
+#########################################################################
+
+LIST_sparc="gr_xc3s_1500	gr_cpci_ax2000	gr_ep2s60	grsim	grsim_leon2"
+
 #-----------------------------------------------------------------------
 
 #----- for now, just run PPC by default -----
@@ -747,6 +753,7 @@
 	case "$arg" in
 	arm|SA|ARM7|ARM9|ARM10|ARM11|ixp|pxa| \
 	avr32| \
+	sparc| \
 	blackfin| \
 	coldfire| \
 	microblaze| \
diff --git a/Makefile b/Makefile
index e5b4210..f4b5bcd 100644
--- a/Makefile
+++ b/Makefile
@@ -165,7 +165,10 @@
 endif
 ifeq ($(ARCH),sh)
 CROSS_COMPILE = sh4-linux-
-endif	# sh
+endif
+ifeq ($(ARCH),sparc)
+CROSS_COMPILE = sparc-elf-
+endif	# sparc
 endif	# HOSTARCH,ARCH
 endif	# CROSS_COMPILE
 
@@ -2880,6 +2883,38 @@
 	@echo "#define CONFIG_R2DPLUS 1" >> include/config.h
 	@./mkconfig -a $(@:_config=) sh sh4 r2dplus
 
+#========================================================================
+# SPARC
+#========================================================================
+#########################################################################
+## LEON3
+#########################################################################
+
+# Gaisler GR-XC3S-1500 board
+gr_xc3s_1500_config : unconfig
+	@$(MKCONFIG) $(@:_config=) sparc leon3 gr_xc3s_1500 gaisler
+
+# Gaisler GR-CPCI-AX2000 board, a General purpose FPGA-AX system
+gr_cpci_ax2000_config : unconfig
+	@$(MKCONFIG) $(@:_config=) sparc leon3 gr_cpci_ax2000 gaisler
+
+# Gaisler GRLIB template design (GPL SPARC/LEON3) for Altera NIOS
+# Development board Stratix II edition, FPGA Device EP2S60.
+gr_ep2s60_config: unconfig
+	@$(MKCONFIG) $(@:_config=) sparc leon3 gr_ep2s60 gaisler
+
+# Gaisler LEON3 GRSIM simulator
+grsim_config : unconfig
+	@$(MKCONFIG) $(@:_config=) sparc leon3 grsim gaisler
+
+#########################################################################
+## LEON2
+#########################################################################
+
+# Gaisler LEON2 GRSIM simulator
+grsim_leon2_config : unconfig
+	@$(MKCONFIG) $(@:_config=) sparc leon2 grsim_leon2 gaisler
+
 #########################################################################
 #########################################################################
 #########################################################################
diff --git a/README b/README
index 5d059e7..7c16345 100644
--- a/README
+++ b/README
@@ -153,6 +153,8 @@
   - at32ap	Files specific to Atmel AVR32 AP CPUs
   - i386	Files specific to i386 CPUs
   - ixp		Files specific to Intel XScale IXP CPUs
+  - leon2	Files specific to Gaisler LEON2 SPARC CPU
+  - leon3	Files specific to Gaisler LEON3 SPARC CPU
   - mcf52x2	Files specific to Freescale ColdFire MCF52x2 CPUs
   - mcf5227x	Files specific to Freescale ColdFire MCF5227x CPUs
   - mcf532x	Files specific to Freescale ColdFire MCF5329 CPUs
@@ -186,6 +188,7 @@
 - lib_mips	Files generic to MIPS	 architecture
 - lib_nios	Files generic to NIOS	 architecture
 - lib_ppc	Files generic to PowerPC architecture
+- lib_sparc	Files generic to SPARC	 architecture
 - libfdt	Library files to support flattened device trees
 - net		Networking code
 - post		Power On Self Test
@@ -2040,6 +2043,13 @@
 		This option also enables the building of the cfi_flash driver
 		in the drivers directory
 
+- CFG_FLASH_USE_BUFFER_WRITE
+		Use buffered writes to flash.
+
+- CONFIG_FLASH_SPANSION_S29WS_N
+		s29ws-n MirrorBit flash has non-standard addresses for buffered
+		write commands.
+
 - CFG_FLASH_QUIET_TEST
 		If this option is defined, the common CFI flash doesn't
 		print it's warning upon not recognized FLASH banks. This
diff --git a/board/freescale/mpc837xemds/mpc837xemds.c b/board/freescale/mpc837xemds/mpc837xemds.c
index f7cd5fe..40a505b 100644
--- a/board/freescale/mpc837xemds/mpc837xemds.c
+++ b/board/freescale/mpc837xemds/mpc837xemds.c
@@ -36,7 +36,7 @@
 	u32 spridr = in_be32(&immr->sysconf.spridr);
 
 	/* we check only part num, and don't look for CPU revisions */
-	switch (spridr) {
+	switch (PARTID_NO_E(spridr)) {
 	case SPR_8377:
 		fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA,
 				 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
diff --git a/board/freescale/mpc837xerdb/mpc837xerdb.c b/board/freescale/mpc837xerdb/mpc837xerdb.c
index e054f4e..f73fd5a 100644
--- a/board/freescale/mpc837xerdb/mpc837xerdb.c
+++ b/board/freescale/mpc837xerdb/mpc837xerdb.c
@@ -16,10 +16,10 @@
 #include <i2c.h>
 #include <asm/io.h>
 #include <asm/fsl_serdes.h>
+#include <fdt_support.h>
 #include <spd_sdram.h>
 #include <vsc7385.h>
 
-
 #if defined(CFG_DRAM_TEST)
 int
 testdram(void)
diff --git a/board/gaisler/gr_cpci_ax2000/Makefile b/board/gaisler/gr_cpci_ax2000/Makefile
new file mode 100644
index 0000000..d58f50d
--- /dev/null
+++ b/board/gaisler/gr_cpci_ax2000/Makefile
@@ -0,0 +1,52 @@
+
+#
+# (C) Copyright 2003-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= $(BOARD).o
+
+#flash.o
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/gaisler/gr_cpci_ax2000/config.mk b/board/gaisler/gr_cpci_ax2000/config.mk
new file mode 100644
index 0000000..6c4d56b
--- /dev/null
+++ b/board/gaisler/gr_cpci_ax2000/config.mk
@@ -0,0 +1,37 @@
+#
+# (C) Copyright 2008
+# Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+#
+# 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
+#
+
+#
+# GR-CPCI-AX2000 board
+#
+
+# U-BOOT IN FLASH
+TEXT_BASE = 0x00000000
+
+# U-BOOT IN RAM or SDRAM with -nosram flag set when starting GRMON
+#TEXT_BASE = 0x40000000
+
+# U-BOOT IN SDRAM
+#TEXT_BASE = 0x60000000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
diff --git a/board/gaisler/gr_cpci_ax2000/gr_cpci_ax2000.c b/board/gaisler/gr_cpci_ax2000/gr_cpci_ax2000.c
new file mode 100644
index 0000000..d99b455
--- /dev/null
+++ b/board/gaisler/gr_cpci_ax2000/gr_cpci_ax2000.c
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2008
+ * Daniel Hellstrom, daniel@gaisler.com.
+ *
+ * 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 <config.h>
+#include <asm/leon.h>
+
+long int initdram(int board_type)
+{
+	return 1;
+}
+
+int checkboard(void)
+{
+	puts("Board: GR-CPCI-AX2000\n");
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	return 0;
+}
diff --git a/board/gaisler/gr_cpci_ax2000/u-boot.lds b/board/gaisler/gr_cpci_ax2000/u-boot.lds
new file mode 100644
index 0000000..3958670
--- /dev/null
+++ b/board/gaisler/gr_cpci_ax2000/u-boot.lds
@@ -0,0 +1,160 @@
+/* Linker script for Gaisler Research AB's GR-CPCI-AX2000 board
+ * with template design.
+ *
+ * (C) Copyright 2008
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc")
+OUTPUT_ARCH(sparc)
+ENTRY(_start)
+SECTIONS
+{
+
+/* Read-only sections, merged into text segment: */
+	. = + SIZEOF_HEADERS;
+	.interp : { *(.interp) }
+	.hash          : { *(.hash)		}
+	.dynsym        : { *(.dynsym)		}
+	.dynstr        : { *(.dynstr)		}
+	.rel.text      : { *(.rel.text)		}
+	.rela.text     : { *(.rela.text)	}
+	.rel.data      : { *(.rel.data)		}
+	.rela.data     : { *(.rela.data)	}
+	.rel.rodata    : { *(.rel.rodata)	}
+	.rela.rodata   : { *(.rela.rodata)	}
+	.rel.got       : { *(.rel.got)		}
+	.rela.got      : { *(.rela.got)		}
+	.rel.ctors     : { *(.rel.ctors)	}
+	.rela.ctors    : { *(.rela.ctors)	}
+	.rel.dtors     : { *(.rel.dtors)	}
+	.rela.dtors    : { *(.rela.dtors)	}
+	.rel.bss       : { *(.rel.bss)		}
+	.rela.bss      : { *(.rela.bss)		}
+	.rel.plt       : { *(.rel.plt)		}
+	.rela.plt      : { *(.rela.plt)		}
+	.init          : { *(.init)		}
+	.plt : { *(.plt) }
+
+	.text : {
+		_load_addr = .;
+		_text = .;
+
+		*(.start)
+		cpu/leon3/start.o (.text)
+/* 8k is the same as the PROM offset from end of main memory, (CFG_PROM_SIZE) */
+		. = ALIGN(8192);
+/* PROM CODE, Will be relocated to the end of memory,
+ * no global data accesses please.
+ */
+		__prom_start = .;
+		*(.prom.pgt)
+		*(.prom.data)
+		*(.prom.text)
+		. = ALIGN(16);
+		__prom_end = .;
+		*(.text)
+		*(.fixup)
+		*(.gnu.warning)
+/*		*(.got1)*/
+		. = ALIGN(16);
+		*(.rodata)
+		*(.rodata1)
+		*(.rodata.*)
+		*(.eh_frame)
+	}
+	. = ALIGN(4);
+	_etext = .;
+
+	/* CMD Table */
+
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	. = ALIGN(4);
+	__u_boot_cmd_end = .;
+
+	.data	:
+	{
+		*(.data)
+		*(.data1)
+		*(.data.rel)
+		*(.data.rel.*)
+		*(.sdata)
+		*(.sdata2)
+		*(.dynamic)
+		CONSTRUCTORS
+	}
+	_edata	=	.;
+	PROVIDE (edata = .);
+
+	. = ALIGN(4);
+	__got_start = .;
+	.got : {
+		*(.got)
+/*		*(.data.rel)
+		*(.data.rel.local)*/
+		. = ALIGN(16);
+	}
+	__got_end = .;
+
+/*	.data.rel : { } */
+
+	. = ALIGN(4096);
+	__init_begin = .;
+	.text.init : { *(.text.init) }
+	.data.init : { *(.data.init) }
+	. = ALIGN(4096);
+	__init_end = .;
+
+	__bss_start = .;
+	.bss		:
+	{
+	 *(.sbss) *(.scommon)
+	 *(.dynbss)
+	 *(.bss)
+	 *(COMMON)
+	. = ALIGN(16); /* to speed clearing of bss up */
+	}
+	__bss_end = . ;
+	_end = . ;
+	PROVIDE (end = .);
+
+/* Relocated into main memory */
+
+	/* Start of main memory */
+	/*. = 0x40000000;*/
+
+	.stack (NOLOAD)	: { *(.stack) }
+
+	/* PROM CODE */
+
+	/* global data in RAM passed to kernel after booting */
+
+  .stab 0		: { *(.stab) }
+  .stabstr 0		: { *(.stabstr) }
+  .stab.excl 0		: { *(.stab.excl) }
+  .stab.exclstr 0	: { *(.stab.exclstr) }
+  .stab.index 0		: { *(.stab.index) }
+  .stab.indexstr 0	: { *(.stab.indexstr) }
+  .comment 0		: { *(.comment) }
+
+}
diff --git a/board/gaisler/gr_ep2s60/Makefile b/board/gaisler/gr_ep2s60/Makefile
new file mode 100644
index 0000000..d58f50d
--- /dev/null
+++ b/board/gaisler/gr_ep2s60/Makefile
@@ -0,0 +1,52 @@
+
+#
+# (C) Copyright 2003-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= $(BOARD).o
+
+#flash.o
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/gaisler/gr_ep2s60/config.mk b/board/gaisler/gr_ep2s60/config.mk
new file mode 100644
index 0000000..2ee0957
--- /dev/null
+++ b/board/gaisler/gr_ep2s60/config.mk
@@ -0,0 +1,35 @@
+#
+# (C) Copyright 2008
+# Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+#
+# 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
+#
+
+#
+# Altera NIOS delopment board Stratix II edition, FPGA device EP2S60,
+# with GRLIB Template design (GPL Open Source SPARC/LEON3)
+#
+
+# U-BOOT IN FLASH
+TEXT_BASE = 0x00000000
+
+# U-BOOT IN SDRAM
+#TEXT_BASE = 0x40000000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
diff --git a/board/gaisler/gr_ep2s60/gr_ep2s60.c b/board/gaisler/gr_ep2s60/gr_ep2s60.c
new file mode 100644
index 0000000..e8617f0
--- /dev/null
+++ b/board/gaisler/gr_ep2s60/gr_ep2s60.c
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2008
+ * Daniel Hellstrom, daniel@gaisler.com.
+ *
+ * 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 <config.h>
+#include <asm/leon.h>
+
+long int initdram(int board_type)
+{
+	return 1;
+}
+
+int checkboard(void)
+{
+	puts("Board: EP2S60 GRLIB\n");
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	return 0;
+}
diff --git a/board/gaisler/gr_ep2s60/u-boot.lds b/board/gaisler/gr_ep2s60/u-boot.lds
new file mode 100644
index 0000000..100350d
--- /dev/null
+++ b/board/gaisler/gr_ep2s60/u-boot.lds
@@ -0,0 +1,160 @@
+/* Linker script for Gaisler Research AB's Template design
+ * for Altera NIOS Development board Stratix II Edition, EP2S60 FPGA.
+ *
+ * (C) Copyright 2008
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc")
+OUTPUT_ARCH(sparc)
+ENTRY(_start)
+SECTIONS
+{
+
+/* Read-only sections, merged into text segment: */
+	. = + SIZEOF_HEADERS;
+	.interp : { *(.interp) }
+	.hash          : { *(.hash)		}
+	.dynsym        : { *(.dynsym)		}
+	.dynstr        : { *(.dynstr)		}
+	.rel.text      : { *(.rel.text)		}
+	.rela.text     : { *(.rela.text)	}
+	.rel.data      : { *(.rel.data)		}
+	.rela.data     : { *(.rela.data)	}
+	.rel.rodata    : { *(.rel.rodata)	}
+	.rela.rodata   : { *(.rela.rodata)	}
+	.rel.got       : { *(.rel.got)		}
+	.rela.got      : { *(.rela.got)		}
+	.rel.ctors     : { *(.rel.ctors)	}
+	.rela.ctors    : { *(.rela.ctors)	}
+	.rel.dtors     : { *(.rel.dtors)	}
+	.rela.dtors    : { *(.rela.dtors)	}
+	.rel.bss       : { *(.rel.bss)		}
+	.rela.bss      : { *(.rela.bss)		}
+	.rel.plt       : { *(.rel.plt)		}
+	.rela.plt      : { *(.rela.plt)		}
+	.init          : { *(.init)		}
+	.plt : { *(.plt) }
+
+	.text : {
+		_load_addr = .;
+		_text = .;
+
+		*(.start)
+		cpu/leon3/start.o (.text)
+/* 8k is the same as the PROM offset from end of main memory, (CFG_PROM_SIZE) */
+		. = ALIGN(8192);
+/* PROM CODE, Will be relocated to the end of memory,
+ * no global data accesses please.
+ */
+		__prom_start = .;
+		*(.prom.pgt)
+		*(.prom.data)
+		*(.prom.text)
+		. = ALIGN(16);
+		__prom_end = .;
+		*(.text)
+		*(.fixup)
+		*(.gnu.warning)
+/*		*(.got1)*/
+		. = ALIGN(16);
+		*(.rodata)
+		*(.rodata1)
+		*(.rodata.*)
+		*(.eh_frame)
+	}
+	. = ALIGN(4);
+	_etext = .;
+
+	/* CMD Table */
+
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	. = ALIGN(4);
+	__u_boot_cmd_end = .;
+
+	.data	:
+	{
+		*(.data)
+		*(.data1)
+		*(.data.rel)
+		*(.data.rel.*)
+		*(.sdata)
+		*(.sdata2)
+		*(.dynamic)
+		CONSTRUCTORS
+	}
+	_edata	=	.;
+	PROVIDE (edata = .);
+
+	. = ALIGN(4);
+	__got_start = .;
+	.got : {
+		*(.got)
+/*		*(.data.rel)
+		*(.data.rel.local)*/
+		. = ALIGN(16);
+	}
+	__got_end = .;
+
+/*	.data.rel : { } */
+
+	. = ALIGN(4096);
+	__init_begin = .;
+	.text.init : { *(.text.init) }
+	.data.init : { *(.data.init) }
+	. = ALIGN(4096);
+	__init_end = .;
+
+	__bss_start = .;
+	.bss		:
+	{
+	 *(.sbss) *(.scommon)
+	 *(.dynbss)
+	 *(.bss)
+	 *(COMMON)
+	. = ALIGN(16); /* to speed clearing of bss up */
+	}
+	__bss_end = . ;
+	_end = . ;
+	PROVIDE (end = .);
+
+/* Relocated into main memory */
+
+	/* Start of main memory */
+	/*. = 0x40000000;*/
+
+	.stack (NOLOAD)	: { *(.stack) }
+
+	/* PROM CODE */
+
+	/* global data in RAM passed to kernel after booting */
+
+  .stab 0		: { *(.stab) }
+  .stabstr 0		: { *(.stabstr) }
+  .stab.excl 0		: { *(.stab.excl) }
+  .stab.exclstr 0	: { *(.stab.exclstr) }
+  .stab.index 0		: { *(.stab.index) }
+  .stab.indexstr 0	: { *(.stab.indexstr) }
+  .comment 0		: { *(.comment) }
+
+}
diff --git a/board/gaisler/gr_xc3s_1500/Makefile b/board/gaisler/gr_xc3s_1500/Makefile
new file mode 100644
index 0000000..d58f50d
--- /dev/null
+++ b/board/gaisler/gr_xc3s_1500/Makefile
@@ -0,0 +1,52 @@
+
+#
+# (C) Copyright 2003-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= $(BOARD).o
+
+#flash.o
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/gaisler/gr_xc3s_1500/config.mk b/board/gaisler/gr_xc3s_1500/config.mk
new file mode 100644
index 0000000..35cbc1b
--- /dev/null
+++ b/board/gaisler/gr_xc3s_1500/config.mk
@@ -0,0 +1,34 @@
+#
+# (C) Copyright 2007
+# Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+#
+# 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
+#
+
+#
+# GR-XC3S-1500 board
+#
+
+# U-BOOT IN FLASH
+TEXT_BASE = 0x00000000
+
+# U-BOOT IN RAM
+#TEXT_BASE = 0x40000000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
diff --git a/board/gaisler/gr_xc3s_1500/gr_xc3s_1500.c b/board/gaisler/gr_xc3s_1500/gr_xc3s_1500.c
new file mode 100644
index 0000000..1ee7024
--- /dev/null
+++ b/board/gaisler/gr_xc3s_1500/gr_xc3s_1500.c
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2007
+ * Daniel Hellstrom, daniel@gaisler.com.
+ *
+ * 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 <config.h>
+#include <asm/leon.h>
+
+long int initdram(int board_type)
+{
+	return 1;
+}
+
+int checkboard(void)
+{
+	puts("Board: GR-XC3S-1500\n");
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	return 0;
+}
diff --git a/board/gaisler/gr_xc3s_1500/u-boot.lds b/board/gaisler/gr_xc3s_1500/u-boot.lds
new file mode 100644
index 0000000..3848c68
--- /dev/null
+++ b/board/gaisler/gr_xc3s_1500/u-boot.lds
@@ -0,0 +1,162 @@
+/* Linker script for Gaisler Research AB's GR-XC3S-1500 board
+ * with template design.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc")
+OUTPUT_ARCH(sparc)
+ENTRY(_start)
+SECTIONS
+{
+
+/* Read-only sections, merged into text segment: */
+	. = + SIZEOF_HEADERS;
+	.interp : { *(.interp) }
+	.hash          : { *(.hash)		}
+	.dynsym        : { *(.dynsym)		}
+	.dynstr        : { *(.dynstr)		}
+	.rel.text      : { *(.rel.text)		}
+	.rela.text     : { *(.rela.text)	}
+	.rel.data      : { *(.rel.data)		}
+	.rela.data     : { *(.rela.data)	}
+	.rel.rodata    : { *(.rel.rodata)	}
+	.rela.rodata   : { *(.rela.rodata)	}
+	.rel.got       : { *(.rel.got)		}
+	.rela.got      : { *(.rela.got)		}
+	.rel.ctors     : { *(.rel.ctors)	}
+	.rela.ctors    : { *(.rela.ctors)	}
+	.rel.dtors     : { *(.rel.dtors)	}
+	.rela.dtors    : { *(.rela.dtors)	}
+	.rel.bss       : { *(.rel.bss)		}
+	.rela.bss      : { *(.rela.bss)		}
+	.rel.plt       : { *(.rel.plt)		}
+	.rela.plt      : { *(.rela.plt)		}
+	.init          : { *(.init)		}
+	.plt : { *(.plt) }
+
+	.text : {
+		_load_addr = .;
+		_text = .;
+
+		*(.start)
+		cpu/leon3/start.o (.text)
+/* 8k is the same as the PROM offset from end of main memory, (CFG_PROM_SIZE) */
+		. = ALIGN(8192);
+/* PROM CODE, Will be relocated to the end of memory,
+ * no global data accesses please.
+ */
+		__prom_start = .;
+		*(.prom.pgt)
+		*(.prom.data)
+		*(.prom.text)
+		. = ALIGN(16);
+		__prom_end = .;
+		*(.text)
+		*(.fixup)
+		*(.gnu.warning)
+/*		*(.got1)*/
+		. = ALIGN(16);
+		*(.rodata)
+		*(.rodata1)
+		*(.rodata.*)
+		*(.eh_frame)
+	}
+	. = ALIGN(4);
+	_etext = .;
+
+	/* CMD Table */
+
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	. = ALIGN(4);
+	__u_boot_cmd_end = .;
+
+	.data	:
+	{
+		*(.data)
+		*(.data1)
+		*(.data.rel)
+		*(.data.rel.*)
+		*(.sdata)
+		*(.sdata2)
+		*(.dynamic)
+		CONSTRUCTORS
+	}
+	_edata	=	.;
+	PROVIDE (edata = .);
+
+	. = ALIGN(4);
+	__got_start = .;
+	.got : {
+		*(.got)
+/*		*(.data.rel)
+		*(.data.rel.local)*/
+		. = ALIGN(16);
+	}
+	__got_end = .;
+
+/*	.data.rel : { } */
+
+
+	. = ALIGN(4096);
+	__init_begin = .;
+	.text.init : { *(.text.init) }
+	.data.init : { *(.data.init) }
+	. = ALIGN(4096);
+	__init_end = .;
+
+	__bss_start = .;
+	.bss		:
+	{
+	 *(.sbss) *(.scommon)
+	 *(.dynbss)
+	 *(.bss)
+	 *(COMMON)
+	. = ALIGN(16); /* to speed clearing of bss up */
+	}
+	__bss_end = . ;
+	_end = . ;
+	PROVIDE (end = .);
+
+/* Relocated into main memory */
+
+	/* Start of main memory */
+	/*. = 0x40000000;*/
+
+	.stack (NOLOAD)	: { *(.stack) }
+
+	/* PROM CODE */
+
+	/* global data in RAM passed to kernel after booting */
+
+
+  .stab 0		: { *(.stab) }
+  .stabstr 0		: { *(.stabstr) }
+  .stab.excl 0		: { *(.stab.excl) }
+  .stab.exclstr 0	: { *(.stab.exclstr) }
+  .stab.index 0		: { *(.stab.index) }
+  .stab.indexstr 0	: { *(.stab.indexstr) }
+  .comment 0		: { *(.comment) }
+
+}
diff --git a/board/gaisler/grsim/Makefile b/board/gaisler/grsim/Makefile
new file mode 100644
index 0000000..6295109
--- /dev/null
+++ b/board/gaisler/grsim/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2003-2004
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= $(BOARD).o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/gaisler/grsim/config.mk b/board/gaisler/grsim/config.mk
new file mode 100644
index 0000000..81cd415
--- /dev/null
+++ b/board/gaisler/grsim/config.mk
@@ -0,0 +1,34 @@
+#
+# (C) Copyright 2007
+# Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+#
+# 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
+#
+
+#
+# GRSIM simulating a LEON3 GR-XC3S-1500 board
+#
+
+# U-BOOT IN FLASH
+TEXT_BASE = 0x00000000
+
+# U-BOOT IN RAM
+#TEXT_BASE = 0x40000000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
diff --git a/board/gaisler/grsim/grsim.c b/board/gaisler/grsim/grsim.c
new file mode 100644
index 0000000..70a2f23
--- /dev/null
+++ b/board/gaisler/grsim/grsim.c
@@ -0,0 +1,43 @@
+/* GRSIM/TSIM board
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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/leon.h>
+
+long int initdram(int board_type)
+{
+	return 1;
+}
+
+int checkboard(void)
+{
+	puts("Board: GRSIM/TSIM\n");
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	return 0;
+}
diff --git a/board/gaisler/grsim/u-boot.lds b/board/gaisler/grsim/u-boot.lds
new file mode 100644
index 0000000..1e8bb69
--- /dev/null
+++ b/board/gaisler/grsim/u-boot.lds
@@ -0,0 +1,161 @@
+/* Linker script for Gaisler Research AB's GRSIM LEON3 simulator.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc")
+OUTPUT_ARCH(sparc)
+ENTRY(_start)
+SECTIONS
+{
+
+/* Read-only sections, merged into text segment: */
+	. = + SIZEOF_HEADERS;
+	.interp : { *(.interp) }
+	.hash          : { *(.hash) }
+	.dynsym        : { *(.dynsym) }
+	.dynstr        : { *(.dynstr) }
+	.rel.text      : { *(.rel.text) }
+	.rela.text     : { *(.rela.text) }
+	.rel.data      : { *(.rel.data) }
+	.rela.data     : { *(.rela.data) }
+	.rel.rodata    : { *(.rel.rodata) }
+	.rela.rodata   : { *(.rela.rodata) }
+	.rel.got       : { *(.rel.got) }
+	.rela.got      : { *(.rela.got) }
+	.rel.ctors     : { *(.rel.ctors) }
+	.rela.ctors    : { *(.rela.ctors) }
+	.rel.dtors     : { *(.rel.dtors) }
+	.rela.dtors    : { *(.rela.dtors) }
+	.rel.bss       : { *(.rel.bss) }
+	.rela.bss      : { *(.rela.bss) }
+	.rel.plt       : { *(.rel.plt) }
+	.rela.plt      : { *(.rela.plt) }
+	.init          : { *(.init) }
+	.plt : { *(.plt) }
+
+	.text : {
+		_load_addr = .;
+		_text = .;
+
+		*(.start)
+		cpu/leon3/start.o (.text)
+/* 8k is the same as the PROM offset from end of main memory, (CFG_PROM_SIZE) */
+		. = ALIGN(8192);
+/* PROM CODE, Will be relocated to the end of memory,
+ * no global data accesses please.
+ */
+		__prom_start = .;
+		*(.prom.pgt)
+		*(.prom.data)
+		*(.prom.text)
+		. = ALIGN(16);
+		__prom_end = .;
+		*(.text)
+		*(.fixup)
+		*(.gnu.warning)
+/*		*(.got1)*/
+		. = ALIGN(16);
+		*(.rodata)
+		*(.rodata1)
+		*(.rodata.*)
+		*(.eh_frame)
+	}
+	. = ALIGN(4);
+	_etext = .;
+
+	/* CMD Table */
+
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	. = ALIGN(4);
+	__u_boot_cmd_end = .;
+
+	.data	:
+	{
+		*(.data)
+		*(.data1)
+		*(.data.rel)
+		*(.data.rel.*)
+		*(.sdata)
+		*(.sdata2)
+		*(.dynamic)
+		CONSTRUCTORS
+	}
+	_edata	=	.;
+	PROVIDE (edata = .);
+
+	. = ALIGN(4);
+	__got_start = .;
+	.got : {
+		*(.got)
+/*		*(.data.rel)
+		*(.data.rel.local)*/
+		. = ALIGN(16);
+	}
+	__got_end = .;
+
+/*	.data.rel : { } */
+
+
+	. = ALIGN(4096);
+	__init_begin = .;
+	.text.init : { *(.text.init) }
+	.data.init : { *(.data.init) }
+	. = ALIGN(4096);
+	__init_end = .;
+
+	__bss_start = .;
+	.bss	:
+	{
+	 *(.sbss) *(.scommon)
+	 *(.dynbss)
+	 *(.bss)
+	 *(COMMON)
+	. = ALIGN(16); /* to speed clearing of bss up */
+	}
+	__bss_end = . ;
+	_end = . ;
+	PROVIDE (end = .);
+
+/* Relocated into main memory */
+
+	/* Start of main memory */
+	/*. = 0x40000000;*/
+
+	.stack (NOLOAD)	: { *(.stack) }
+
+	/* PROM CODE */
+
+	/* global data in RAM passed to kernel after booting */
+
+
+	.stab 0		: { *(.stab) }
+	.stabstr 0		: { *(.stabstr) }
+	.stab.excl 0		: { *(.stab.excl) }
+	.stab.exclstr 0	: { *(.stab.exclstr) }
+	.stab.index 0		: { *(.stab.index) }
+	.stab.indexstr 0	: { *(.stab.indexstr) }
+	.comment 0		: { *(.comment) }
+
+}
diff --git a/board/gaisler/grsim_leon2/Makefile b/board/gaisler/grsim_leon2/Makefile
new file mode 100644
index 0000000..6295109
--- /dev/null
+++ b/board/gaisler/grsim_leon2/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2003-2004
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).a
+
+COBJS	:= $(BOARD).o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/gaisler/grsim_leon2/config.mk b/board/gaisler/grsim_leon2/config.mk
new file mode 100644
index 0000000..65eba1b
--- /dev/null
+++ b/board/gaisler/grsim_leon2/config.mk
@@ -0,0 +1,34 @@
+#
+# (C) Copyright 2007
+# Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+#
+# 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
+#
+
+#
+# GRSIM simulating a LEON2 board
+#
+
+# RUN U-BOOT FROM PROM
+TEXT_BASE = 0x00000000
+
+# RUN U-BOOT FROM RAM
+#TEXT_BASE = 0x40000000
+
+PLATFORM_CPPFLAGS += -DTEXT_BASE=$(TEXT_BASE) -I$(TOPDIR)/board
diff --git a/board/gaisler/grsim_leon2/grsim_leon2.c b/board/gaisler/grsim_leon2/grsim_leon2.c
new file mode 100644
index 0000000..55dfe82
--- /dev/null
+++ b/board/gaisler/grsim_leon2/grsim_leon2.c
@@ -0,0 +1,43 @@
+/* GRSIM/TSIM board
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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/leon.h>
+
+long int initdram(int board_type)
+{
+	return 1;
+}
+
+int checkboard(void)
+{
+	puts("Board: GRSIM/TSIM LEON2\n");
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	return 0;
+}
diff --git a/board/gaisler/grsim_leon2/u-boot.lds b/board/gaisler/grsim_leon2/u-boot.lds
new file mode 100644
index 0000000..2a22082
--- /dev/null
+++ b/board/gaisler/grsim_leon2/u-boot.lds
@@ -0,0 +1,159 @@
+/* Linker script for Gaisler Research AB's GRSIM LEON2 simulator.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc")
+OUTPUT_ARCH(sparc)
+ENTRY(_start)
+SECTIONS
+{
+
+/* Read-only sections, merged into text segment: */
+	. = + SIZEOF_HEADERS;
+	.interp : { *(.interp) }
+	.hash          : { *(.hash) }
+	.dynsym        : { *(.dynsym) }
+	.dynstr        : { *(.dynstr) }
+	.rel.text      : { *(.rel.text) }
+	.rela.text     : { *(.rela.text) }
+	.rel.data      : { *(.rel.data) }
+	.rela.data     : { *(.rela.data) }
+	.rel.rodata    : { *(.rel.rodata) }
+	.rela.rodata   : { *(.rela.rodata) }
+	.rel.got       : { *(.rel.got) }
+	.rela.got      : { *(.rela.got) }
+	.rel.ctors     : { *(.rel.ctors) }
+	.rela.ctors    : { *(.rela.ctors) }
+	.rel.dtors     : { *(.rel.dtors) }
+	.rela.dtors    : { *(.rela.dtors) }
+	.rel.bss       : { *(.rel.bss) }
+	.rela.bss      : { *(.rela.bss) }
+	.rel.plt       : { *(.rel.plt) }
+	.rela.plt      : { *(.rela.plt) }
+	.init          : { *(.init) }
+	.plt : { *(.plt) }
+
+	.text : {
+		_load_addr = .;
+		_text = .;
+
+		*(.start)
+		cpu/leon2/start.o (.text)
+/* 8k is the same as the PROM offset from end of main memory, (CFG_PROM_SIZE) */
+		. = ALIGN(8192);
+/* PROM CODE, Will be relocated to the end of memory,
+ * no global data accesses please.
+ */
+		__prom_start = .;
+		*(.prom.pgt)
+		*(.prom.data)
+		*(.prom.text)
+		. = ALIGN(16);
+		__prom_end = .;
+		*(.text)
+		*(.fixup)
+		*(.gnu.warning)
+/*		*(.got1)*/
+		. = ALIGN(16);
+		*(.rodata)
+		*(.rodata1)
+		*(.rodata.*)
+		*(.eh_frame)
+	}
+	. = ALIGN(4);
+	_etext = .;
+
+	/* CMD Table */
+
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	. = ALIGN(4);
+	__u_boot_cmd_end = .;
+
+	.data	:
+	{
+		*(.data)
+		*(.data1)
+		*(.data.rel)
+		*(.data.rel.*)
+		*(.sdata)
+		*(.sdata2)
+		*(.dynamic)
+		CONSTRUCTORS
+	}
+	_edata	=	.;
+	PROVIDE (edata = .);
+
+	. = ALIGN(4);
+	__got_start = .;
+	.got : {
+		*(.got)
+/*		*(.data.rel)
+		*(.data.rel.local)*/
+		. = ALIGN(16);
+	}
+	__got_end = .;
+
+/*	.data.rel : { } */
+
+	. = ALIGN(4096);
+	__init_begin = .;
+	.text.init : { *(.text.init) }
+	.data.init : { *(.data.init) }
+	. = ALIGN(4096);
+	__init_end = .;
+
+	__bss_start = .;
+	.bss	:
+	{
+	 *(.sbss) *(.scommon)
+	 *(.dynbss)
+	 *(.bss)
+	 *(COMMON)
+	. = ALIGN(16); /* to speed clearing of bss up */
+	}
+	__bss_end = . ;
+	_end = . ;
+	PROVIDE (end = .);
+
+/* Relocated into main memory */
+
+	/* Start of main memory */
+	/*. = 0x40000000;*/
+
+	.stack (NOLOAD)	: { *(.stack) }
+
+	/* PROM CODE */
+
+	/* global data in RAM passed to kernel after booting */
+
+	.stab 0		: { *(.stab) }
+	.stabstr 0		: { *(.stabstr) }
+	.stab.excl 0		: { *(.stab.excl) }
+	.stab.exclstr 0	: { *(.stab.exclstr) }
+	.stab.index 0		: { *(.stab.index) }
+	.stab.indexstr 0	: { *(.stab.indexstr) }
+	.comment 0		: { *(.comment) }
+
+}
diff --git a/board/xilinx/ml401/Makefile b/board/xilinx/ml401/Makefile
index 9ab5633..ee9b6d5 100644
--- a/board/xilinx/ml401/Makefile
+++ b/board/xilinx/ml401/Makefile
@@ -22,25 +22,10 @@
 #
 
 include $(TOPDIR)/config.mk
-ifneq ($(OBJTREE),$(SRCTREE))
-$(shell mkdir -p $(obj)../common)
-$(shell mkdir -p $(obj)../xilinx_enet)
-endif
-
-INCS		:= -I../common -I../xilinx_enet
-CFLAGS		+= $(INCS)
-HOST_CFLAGS	+= $(INCS)
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	= $(BOARD).o \
-	  ../xilinx_enet/emac_adapter.o  ../xilinx_enet/xemac.o \
-	  ../xilinx_enet/xemac_options.o ../xilinx_enet/xemac_polled.o \
-	  ../xilinx_enet/xemac_intr.o ../xilinx_enet/xemac_g.o \
-	  ../xilinx_enet/xemac_intr_dma.o ../common/xipif_v1_23_b.o \
-	  ../common/xbasic_types.o ../common/xdma_channel.o \
-	  ../common/xdma_channel_sg.o ../common/xpacket_fifo_v1_00_b.o \
-	  ../common/xversion.o \
+COBJS	= $(BOARD).o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
diff --git a/board/xilinx/ml401/xparameters.h b/board/xilinx/ml401/xparameters.h
index 1a116ea..d805061 100644
--- a/board/xilinx/ml401/xparameters.h
+++ b/board/xilinx/ml401/xparameters.h
@@ -41,8 +41,8 @@
 #define XILINX_TIMER_IRQ	0
 
 /* Uart pheriphery is RS232_Uart */
-#define XILINX_UART_BASEADDR	0x40600000
-#define XILINX_UART_BAUDRATE	115200
+#define XILINX_UARTLITE_BASEADDR	0x40600000
+#define XILINX_UARTLITE_BAUDRATE	115200
 
 /* IIC pheriphery is IIC_EEPROM */
 #define XILINX_IIC_0_BASEADDR	0x40800000
@@ -66,10 +66,4 @@
 #define XILINX_SYSACE_MEM_WIDTH	16
 
 /* Ethernet controller is Ethernet_MAC */
-#define XPAR_XEMAC_NUM_INSTANCES	1
-#define XPAR_OPB_ETHERNET_0_DEVICE_ID	0
-#define XPAR_OPB_ETHERNET_0_BASEADDR	0x40c00000
-#define XPAR_OPB_ETHERNET_0_HIGHADDR	0x40c0ffff
-#define XPAR_OPB_ETHERNET_0_DMA_PRESENT	1
-#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST	1
-#define XPAR_OPB_ETHERNET_0_MII_EXIST	1
+#define XILINX_EMACLITE_BASEADDR       0x40C00000
diff --git a/board/xilinx/xupv2p/Makefile b/board/xilinx/xupv2p/Makefile
index 9ab5633..ee9b6d5 100644
--- a/board/xilinx/xupv2p/Makefile
+++ b/board/xilinx/xupv2p/Makefile
@@ -22,25 +22,10 @@
 #
 
 include $(TOPDIR)/config.mk
-ifneq ($(OBJTREE),$(SRCTREE))
-$(shell mkdir -p $(obj)../common)
-$(shell mkdir -p $(obj)../xilinx_enet)
-endif
-
-INCS		:= -I../common -I../xilinx_enet
-CFLAGS		+= $(INCS)
-HOST_CFLAGS	+= $(INCS)
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	= $(BOARD).o \
-	  ../xilinx_enet/emac_adapter.o  ../xilinx_enet/xemac.o \
-	  ../xilinx_enet/xemac_options.o ../xilinx_enet/xemac_polled.o \
-	  ../xilinx_enet/xemac_intr.o ../xilinx_enet/xemac_g.o \
-	  ../xilinx_enet/xemac_intr_dma.o ../common/xipif_v1_23_b.o \
-	  ../common/xbasic_types.o ../common/xdma_channel.o \
-	  ../common/xdma_channel_sg.o ../common/xpacket_fifo_v1_00_b.o \
-	  ../common/xversion.o \
+COBJS	= $(BOARD).o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
diff --git a/board/xilinx/xupv2p/xparameters.h b/board/xilinx/xupv2p/xparameters.h
index a96c693..9e5ebda 100644
--- a/board/xilinx/xupv2p/xparameters.h
+++ b/board/xilinx/xupv2p/xparameters.h
@@ -37,8 +37,8 @@
 #define XILINX_TIMER_IRQ	1
 
 /* Uart pheriphery is RS232_Uart_1 */
-#define XILINX_UART_BASEADDR	0x40600000
-#define XILINX_UART_BAUDRATE	115200
+#define XILINX_UARTLITE_BASEADDR	0x40600000
+#define XILINX_UARTLITE_BAUDRATE	115200
 
 /* GPIO is LEDs_4Bit*/
 #define XILINX_GPIO_BASEADDR	0x40000000
@@ -55,10 +55,4 @@
 #define XILINX_SYSACE_MEM_WIDTH	16
 
 /* Ethernet controller is Ethernet_MAC */
-#define XPAR_XEMAC_NUM_INSTANCES	1
-#define XPAR_OPB_ETHERNET_0_DEVICE_ID	0
-#define XPAR_OPB_ETHERNET_0_BASEADDR	0x40c00000
-#define XPAR_OPB_ETHERNET_0_HIGHADDR	0x40c0ffff
-#define XPAR_OPB_ETHERNET_0_DMA_PRESENT	1
-#define XPAR_OPB_ETHERNET_0_ERR_COUNT_EXIST	1
-#define XPAR_OPB_ETHERNET_0_MII_EXIST	1
+#define XILINX_EMACLITE_BASEADDR       0x40C00000
diff --git a/common/Makefile b/common/Makefile
index 0d67337..c71b228 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -32,6 +32,7 @@
 COBJS-y += altera.o
 COBJS-y += bedbug.o
 COBJS-y += circbuf.o
+COBJS-$(CONFIG_CMD_AMBAPP) += cmd_ambapp.o
 COBJS-y += cmd_autoscript.o
 COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
 COBJS-$(CONFIG_CMD_BEDBUG) += cmd_bedbug.o
diff --git a/common/cmd_ambapp.c b/common/cmd_ambapp.c
new file mode 100644
index 0000000..738412b
--- /dev/null
+++ b/common/cmd_ambapp.c
@@ -0,0 +1,278 @@
+/*
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ */
+
+/*
+ * AMBA Plug&Play information list command
+ *
+ */
+#include <common.h>
+#include <command.h>
+#include <ambapp.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* We put these variables into .data section so that they are zero
+ * when entering the AMBA Plug & Play routines (in cpu/cpu/ambapp.c)
+ * the first time. BSS is not garantueed to be zero since BSS 
+ * hasn't been cleared the first times entering the CPU AMBA functions.
+ *
+ * The AMBA PnP routines call these functions if ambapp_???_print is set.
+ * 
+ */
+int ambapp_apb_print __attribute__ ((section(".data"))) = 0;
+int ambapp_ahb_print __attribute__ ((section(".data"))) = 0;
+
+typedef struct {
+	int device_id;
+	char *name;
+} ambapp_device_name;
+
+static ambapp_device_name gaisler_devices[] = {
+	{GAISLER_LEON3, "GAISLER_LEON3"},
+	{GAISLER_LEON3DSU, "GAISLER_LEON3DSU"},
+	{GAISLER_ETHAHB, "GAISLER_ETHAHB"},
+	{GAISLER_ETHMAC, "GAISLER_ETHMAC"},
+	{GAISLER_APBMST, "GAISLER_APBMST"},
+	{GAISLER_AHBUART, "GAISLER_AHBUART"},
+	{GAISLER_SRCTRL, "GAISLER_SRCTRL"},
+	{GAISLER_SDCTRL, "GAISLER_SDCTRL"},
+	{GAISLER_APBUART, "GAISLER_APBUART"},
+	{GAISLER_IRQMP, "GAISLER_IRQMP"},
+	{GAISLER_AHBRAM, "GAISLER_AHBRAM"},
+	{GAISLER_GPTIMER, "GAISLER_GPTIMER"},
+	{GAISLER_PCITRG, "GAISLER_PCITRG"},
+	{GAISLER_PCISBRG, "GAISLER_PCISBRG"},
+	{GAISLER_PCIFBRG, "GAISLER_PCIFBRG"},
+	{GAISLER_PCITRACE, "GAISLER_PCITRACE"},
+	{GAISLER_AHBTRACE, "GAISLER_AHBTRACE"},
+	{GAISLER_ETHDSU, "GAISLER_ETHDSU"},
+	{GAISLER_PIOPORT, "GAISLER_PIOPORT"},
+	{GAISLER_AHBJTAG, "GAISLER_AHBJTAG"},
+	{GAISLER_ATACTRL, "GAISLER_ATACTRL"},
+	{GAISLER_VGA, "GAISLER_VGA"},
+	{GAISLER_KBD, "GAISLER_KBD"},
+	{GAISLER_L2TIME, "GAISLER_L2TIME"},
+	{GAISLER_L2C, "GAISLER_L2C"},
+	{GAISLER_PLUGPLAY, "GAISLER_PLUGPLAY"},
+	{GAISLER_SPW, "GAISLER_SPW"},
+	{GAISLER_SPW2, "GAISLER_SPW2"},
+	{GAISLER_EHCI, "GAISLER_EHCI"},
+	{GAISLER_UHCI, "GAISLER_UHCI"},
+	{GAISLER_AHBSTAT, "GAISLER_AHBSTAT"},
+	{GAISLER_DDR2SPA, "GAISLER_DDR2SPA"},
+	{GAISLER_DDRSPA, "GAISLER_DDRSPA"},
+	{0, NULL}
+};
+
+static ambapp_device_name esa_devices[] = {
+	{ESA_LEON2, "ESA_LEON2"},
+	{ESA_MCTRL, "ESA_MCTRL"},
+	{0, NULL}
+};
+
+static ambapp_device_name opencores_devices[] = {
+	{OPENCORES_PCIBR, "OPENCORES_PCIBR"},
+	{OPENCORES_ETHMAC, "OPENCORES_ETHMAC"},
+	{0, NULL}
+};
+
+typedef struct {
+	unsigned int vendor_id;
+	char *name;
+	ambapp_device_name *devices;
+} ambapp_vendor_devnames;
+
+static ambapp_vendor_devnames vendors[] = {
+	{VENDOR_GAISLER, "VENDOR_GAISLER", gaisler_devices},
+	{VENDOR_ESA, "VENDOR_ESA", esa_devices},
+	{VENDOR_OPENCORES, "VENDOR_OPENCORES", opencores_devices},
+	{0, NULL, 0}
+};
+
+static char *ambapp_get_devname(ambapp_device_name * devs, int id)
+{
+	if (!devs)
+		return NULL;
+
+	while (devs->device_id > 0) {
+		if (devs->device_id == id)
+			return devs->name;
+		devs++;
+	}
+	return NULL;
+}
+
+char *ambapp_device_id2str(int vendor, int id)
+{
+	ambapp_vendor_devnames *ven = &vendors[0];
+
+	while (ven->vendor_id > 0) {
+		if (ven->vendor_id == vendor) {
+			return ambapp_get_devname(ven->devices, id);
+		}
+		ven++;
+	}
+	return NULL;
+}
+
+char *ambapp_vendor_id2str(int vendor)
+{
+	ambapp_vendor_devnames *ven = &vendors[0];
+
+	while (ven->vendor_id > 0) {
+		if (ven->vendor_id == vendor) {
+			return ven->name;
+		}
+		ven++;
+	}
+	return NULL;
+}
+
+static char *unknown = "unknown";
+
+/* Print one APB device */
+void ambapp_print_apb(apbctrl_pp_dev * apb, ambapp_ahbdev * apbmst, int index)
+{
+	char *dev_str, *ven_str;
+	int irq, ver, vendor, deviceid;
+	unsigned int address, apbmst_base, mask;
+
+	vendor = amba_vendor(apb->conf);
+	deviceid = amba_device(apb->conf);
+	irq = amba_irq(apb->conf);
+	ver = amba_ver(apb->conf);
+	apbmst_base = apbmst->address[0] & LEON3_IO_AREA;
+	address = (apbmst_base | (((apb->bar & 0xfff00000) >> 12))) &
+	    (((apb->bar & 0x0000fff0) << 4) | 0xfff00000);
+
+	mask = amba_membar_mask(apb->bar) << 8;
+	mask = ((~mask) & 0x000fffff) + 1;
+
+	ven_str = ambapp_vendor_id2str(vendor);
+	if (!ven_str) {
+		ven_str = unknown;
+		dev_str = unknown;
+	} else {
+		dev_str = ambapp_device_id2str(vendor, deviceid);
+		if (!dev_str)
+			dev_str = unknown;
+	}
+
+	printf("0x%02x:0x%02x:0x%02x: %s  %s\n"
+	       "   apb: 0x%08x - 0x%08x\n"
+	       "   irq: %-2d (ver: %-2d)\n",
+	       index, vendor, deviceid, ven_str, dev_str, address,
+	       address + mask, irq, ver);
+}
+
+void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index)
+{
+	char *dev_str, *ven_str;
+	int irq, ver, vendor, deviceid;
+	unsigned int addr, mask;
+	int j;
+
+	vendor = amba_vendor(ahb->conf);
+	deviceid = amba_device(ahb->conf);
+	irq = amba_irq(ahb->conf);
+	ver = amba_ver(ahb->conf);
+
+	ven_str = ambapp_vendor_id2str(vendor);
+	if (!ven_str) {
+		ven_str = unknown;
+		dev_str = unknown;
+	} else {
+		dev_str = ambapp_device_id2str(vendor, deviceid);
+		if (!dev_str)
+			dev_str = unknown;
+	}
+
+	printf("0x%02x:0x%02x:0x%02x: %s  %s\n",
+	       index, vendor, deviceid, ven_str, dev_str);
+
+	for (j = 0; j < 4; j++) {
+		addr = amba_membar_start(ahb->bars[j]);
+		if (amba_membar_type(ahb->bars[j]) == 0)
+			continue;
+		if (amba_membar_type(ahb->bars[j]) == AMBA_TYPE_AHBIO)
+			addr = AMBA_TYPE_AHBIO_ADDR(addr);
+		mask = amba_membar_mask(ahb->bars[j]) << 20;
+		printf("   mem: 0x%08x - 0x%08x\n", addr, addr + ((~mask) + 1));
+	}
+
+	printf("   irq: %-2d (ver: %d)\n", irq, ver);
+}
+
+int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+
+	/* Print AHB Masters */
+	puts("--------- AHB Masters ---------\n");
+	ambapp_apb_print = 0;
+	ambapp_ahb_print = 1;
+	ambapp_ahbmst_count(99, 99);	/* Get vendor&device 99 = nonexistent... */
+
+	/* Print AHB Slaves */
+	puts("--------- AHB Slaves  ---------\n");
+	ambapp_ahbslv_count(99, 99);	/* Get vendor&device 99 = nonexistent... */
+
+	/* Print APB Slaves */
+	puts("--------- APB Slaves  ---------\n");
+	ambapp_apb_print = 1;
+	ambapp_ahb_print = 0;
+	ambapp_apb_count(99, 99);	/* Get vendor&device 99 = nonexistent... */
+
+	/* Reset, no futher printing */
+	ambapp_apb_print = 0;
+	ambapp_ahb_print = 0;
+	puts("\n");
+	return 0;
+}
+
+int ambapp_init_reloc(void)
+{
+	ambapp_vendor_devnames *vend = vendors;
+	ambapp_device_name *dev;
+
+	while (vend->vendor_id && vend->name) {
+		vend->name = (char *)((unsigned int)vend->name + gd->reloc_off);
+		vend->devices =
+		    (ambapp_device_name *) ((unsigned int)vend->devices +
+					    gd->reloc_off);;
+		dev = vend->devices;
+		vend++;
+		if (!dev)
+			continue;
+		while (dev->device_id && dev->name) {
+			dev->name =
+			    (char *)((unsigned int)dev->name + gd->reloc_off);;
+			dev++;
+		}
+	}
+	return 0;
+}
+
+U_BOOT_CMD(ambapp, 1, 1, do_ambapp_print,
+	   "ambapp  - list AMBA Plug&Play information\n",
+	   "ambapp\n"
+	   "    - lists AMBA (AHB & APB) Plug&Play devices present on the system\n");
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c
index bbb0192..731c1d2 100644
--- a/common/cmd_bdinfo.c
+++ b/common/cmd_bdinfo.c
@@ -208,6 +208,45 @@
 	return 0;
 }
 
+#elif defined(CONFIG_SPARC)	/* SPARC */
+int do_bdinfo(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	bd_t *bd = gd->bd;
+#if defined(CONFIG_CMD_NET)
+	int i;
+#endif
+
+#ifdef DEBUG
+	print_num("bd address             ", (ulong) bd);
+#endif
+	print_num("memstart               ", bd->bi_memstart);
+	print_num("memsize                ", bd->bi_memsize);
+	print_num("flashstart             ", bd->bi_flashstart);
+	print_num("CFG_MONITOR_BASE       ", CFG_MONITOR_BASE);
+	print_num("CFG_ENV_ADDR           ", CFG_ENV_ADDR);
+	printf("CFG_RELOC_MONITOR_BASE = 0x%lx (%d)\n", CFG_RELOC_MONITOR_BASE,
+	       CFG_MONITOR_LEN);
+	printf("CFG_MALLOC_BASE        = 0x%lx (%d)\n", CFG_MALLOC_BASE,
+	       CFG_MALLOC_LEN);
+	printf("CFG_INIT_SP_OFFSET     = 0x%lx (%d)\n", CFG_INIT_SP_OFFSET,
+	       CFG_STACK_SIZE);
+	printf("CFG_PROM_OFFSET        = 0x%lx (%d)\n", CFG_PROM_OFFSET,
+	       CFG_PROM_SIZE);
+	printf("CFG_GBL_DATA_OFFSET    = 0x%lx (%d)\n", CFG_GBL_DATA_OFFSET,
+	       CFG_GBL_DATA_SIZE);
+
+#if defined(CONFIG_CMD_NET)
+	puts("ethaddr                =");
+	for (i = 0; i < 6; ++i) {
+		printf("%c%02X", i ? ':' : ' ', bd->bi_enetaddr[i]);
+	}
+	puts("\nIP addr                = ");
+	print_IPaddr(bd->bi_ip_addr);
+#endif
+	printf("\nbaudrate               = %6ld bps\n", bd->bi_baudrate);
+	return 0;
+}
+
 #elif defined(CONFIG_M68K) /* M68K */
 static void print_str(const char *, const char *);
 
diff --git a/common/image.c b/common/image.c
index f04826a..ce49bb2 100644
--- a/common/image.c
+++ b/common/image.c
@@ -1014,7 +1014,7 @@
 	return 0;
 }
 
-#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
+#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)
 /**
  * boot_ramdisk_high - relocate init ramdisk
  * @lmb: pointer to lmb handle, will be used for memory mgmt
diff --git a/cpu/leon2/Makefile b/cpu/leon2/Makefile
new file mode 100644
index 0000000..7cc4420
--- /dev/null
+++ b/cpu/leon2/Makefile
@@ -0,0 +1,54 @@
+#
+# (C) Copyright 2003-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(CPU).a
+
+START	= start.o
+SOBJS	=
+COBJS	= cpu_init.o serial.o cpu.o interrupts.o prom.o
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+$(START): $(START:.o=.S)
+	$(CC) -D__ASSEMBLY__ $(DBGFLAGS) $(OPTFLAGS) -D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) \
+	-I$(TOPDIR)/include -fno-builtin -ffreestanding -nostdinc -isystem $(gccincdir) -pipe \
+	$(PLATFORM_CPPFLAGS) -Wall -Wstrict-prototypes \
+	-I$(TOPDIR)/board -c -o $(START) $(START:.o=.S)
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/leon2/config.mk b/cpu/leon2/config.mk
new file mode 100644
index 0000000..30b224a
--- /dev/null
+++ b/cpu/leon2/config.mk
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+PLATFORM_RELFLAGS += -fPIC
+
+PLATFORM_CPPFLAGS += -DCONFIG_LEON
diff --git a/cpu/leon2/cpu.c b/cpu/leon2/cpu.c
new file mode 100644
index 0000000..1c1e24b
--- /dev/null
+++ b/cpu/leon2/cpu.c
@@ -0,0 +1,58 @@
+/* CPU specific code for the LEON2 CPU
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ *
+ * 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 <watchdog.h>
+#include <command.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern void _reset_reloc(void);
+
+int checkcpu(void)
+{
+	/* check LEON version here */
+	printf("CPU: LEON2\n");
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+void cpu_reset(void)
+{
+	/* Interrupts off */
+	disable_interrupts();
+
+	/* jump to restart in flash */
+	_reset_reloc();
+}
+
+int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	cpu_reset();
+
+	return 1;
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/cpu/leon2/cpu_init.c b/cpu/leon2/cpu_init.c
new file mode 100644
index 0000000..a24f778
--- /dev/null
+++ b/cpu/leon2/cpu_init.c
@@ -0,0 +1,142 @@
+/* Initializes CPU and basic hardware such as memory
+ * controllers, IRQ controller and system timer 0.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ *
+ * 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/asi.h>
+#include <asm/leon.h>
+
+#include <config.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* reset CPU (jump to 0, without reset) */
+void start(void);
+
+struct {
+	gd_t gd_area;
+	bd_t bd;
+} global_data;
+
+/*
+ * Breath some life into the CPU...
+ *
+ * Set up the memory map,
+ * initialize a bunch of registers.
+ *
+ * Run from FLASH/PROM:
+ *  - until memory controller is set up, only registers avaiable
+ *  - no global variables available for writing
+ *  - constants avaiable
+ */
+
+void cpu_init_f(void)
+{
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+
+	/* initialize the IRQMP */
+	leon2->Interrupt_Force = 0;
+	leon2->Interrupt_Pending = 0;
+	leon2->Interrupt_Clear = 0xfffe;	/* clear all old pending interrupts */
+	leon2->Interrupt_Mask = 0xfffe0000;	/* mask all IRQs */
+
+	/* cache */
+
+       /* I/O port setup */
+#ifdef LEON2_IO_PORT_DIR
+       leon2->PIO_Direction = LEON2_IO_PORT_DIR;
+#endif
+#ifdef LEON2_IO_PORT_DATA
+       leon2->PIO_Data = LEON2_IO_PORT_DATA;
+#endif
+#ifdef LEON2_IO_PORT_INT
+       leon2->PIO_Interrupt = LEON2_IO_PORT_INT;
+#else
+       leon2->PIO_Interrupt = 0;
+#endif
+}
+
+void cpu_init_f2(void)
+{
+
+}
+
+/*
+ * initialize higher level parts of CPU like time base and timers
+ */
+int cpu_init_r(void)
+{
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+
+	/* initialize prescaler common to all timers to 1MHz */
+	leon2->Scaler_Counter = leon2->Scaler_Reload =
+	    (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1;
+
+	return (0);
+}
+
+/* Uses Timer 0 to get accurate
+ * pauses. Max 2 raised to 32 ticks
+ *
+ */
+void cpu_wait_ticks(unsigned long ticks)
+{
+	unsigned long start = get_timer(0);
+	while (get_timer(start) < ticks) ;
+}
+
+/* initiate and setup timer0 interrupt to 1MHz
+ * Return irq number for timer int or a negative number for
+ * dealing with self
+ */
+int timer_interrupt_init_cpu(void)
+{
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+
+	/* 1ms ticks */
+	leon2->Timer_Counter_1 = 0;
+	leon2->Timer_Reload_1 = 999;	/* (((1000000 / 100) - 1)) */
+	leon2->Timer_Control_1 =
+	    (LEON2_TIMER_CTRL_EN | LEON2_TIMER_CTRL_RS | LEON2_TIMER_CTRL_LD);
+
+	return LEON2_TIMER1_IRQNO;
+}
+
+/*
+ * This function is intended for SHORT delays only.
+ */
+unsigned long cpu_usec2ticks(unsigned long usec)
+{
+	/* timer set to 1kHz ==> 1 clk tick = 1 msec */
+	if (usec < 1000)
+		return 1;
+	return (usec / 1000);
+}
+
+unsigned long cpu_ticks2usec(unsigned long ticks)
+{
+	/* 1tick = 1usec */
+	return ticks * 1000;
+}
diff --git a/cpu/leon2/interrupts.c b/cpu/leon2/interrupts.c
new file mode 100644
index 0000000..35b375c
--- /dev/null
+++ b/cpu/leon2/interrupts.c
@@ -0,0 +1,217 @@
+/*
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ *
+ * (C) Copyright 2006
+ * Detlev Zundel, DENX Software Engineering, dzu@denx.de
+ *
+ * (C) Copyright -2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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/stack.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <command.h>
+#include <asm/irq.h>
+
+#include <asm/leon.h>
+
+/* 15 normal irqs and a non maskable interrupt */
+#define NR_IRQS 15
+
+struct irq_action {
+	interrupt_handler_t *handler;
+	void *arg;
+	unsigned int count;
+};
+
+static struct irq_action irq_handlers[NR_IRQS] = { {0}, };
+static int spurious_irq_cnt = 0;
+static int spurious_irq = 0;
+
+static inline unsigned int leon2_get_irqmask(unsigned int irq)
+{
+	if ((irq < 0) || (irq >= NR_IRQS)) {
+		return 0;
+	} else {
+		return (1 << irq);
+	}
+}
+
+static void leon2_ic_disable(unsigned int irq)
+{
+	unsigned int mask, pil;
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+
+	pil = intLock();
+
+	/* get mask of interrupt */
+	mask = leon2_get_irqmask(irq);
+
+	/* set int level */
+	leon2->Interrupt_Mask =
+	    SPARC_NOCACHE_READ(&leon2->Interrupt_Mask) & (~mask);
+
+	intUnlock(pil);
+}
+
+static void leon2_ic_enable(unsigned int irq)
+{
+	unsigned int mask, pil;
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+
+	pil = intLock();
+
+	/* get mask of interrupt */
+	mask = leon2_get_irqmask(irq);
+
+	/* set int level */
+	leon2->Interrupt_Mask =
+	    SPARC_NOCACHE_READ(&leon2->Interrupt_Mask) | mask;
+
+	intUnlock(pil);
+}
+
+void handler_irq(int irq, struct pt_regs *regs)
+{
+	if (irq_handlers[irq].handler) {
+		if (((unsigned int)irq_handlers[irq].handler > CFG_RAM_END) ||
+		    ((unsigned int)irq_handlers[irq].handler < CFG_RAM_BASE)
+		    ) {
+			printf("handler_irq: bad handler: %x, irq number %d\n",
+			       (unsigned int)irq_handlers[irq].handler, irq);
+			return;
+		}
+		irq_handlers[irq].handler(irq_handlers[irq].arg);
+		irq_handlers[irq].count++;
+	} else {
+		spurious_irq_cnt++;
+		spurious_irq = irq;
+	}
+}
+
+void leon2_force_int(int irq)
+{
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+
+	if ((irq >= NR_IRQS) || (irq < 0))
+		return;
+	printf("Forcing interrupt %d\n", irq);
+
+	leon2->Interrupt_Force =
+	    SPARC_NOCACHE_READ(&leon2->Interrupt_Force) | (1 << irq);
+}
+
+/****************************************************************************/
+
+int interrupt_init_cpu(void)
+{
+	return (0);
+}
+
+/****************************************************************************/
+
+/* Handle Timer 0 IRQ */
+void timer_interrupt_cpu(void *arg)
+{
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+
+	leon2->Timer_Control_1 =
+	    (LEON2_TIMER_CTRL_EN | LEON2_TIMER_CTRL_RS | LEON2_TIMER_CTRL_LD);
+
+	/* nothing to do here */
+	return;
+}
+
+/****************************************************************************/
+
+/*
+ * Install and free a interrupt handler.
+ */
+
+void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg)
+{
+	if (irq < 0 || irq >= NR_IRQS) {
+		printf("irq_install_handler: bad irq number %d\n", irq);
+		return;
+	}
+
+	if (irq_handlers[irq].handler != NULL)
+		printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
+		       (ulong) handler, (ulong) irq_handlers[irq].handler);
+
+	if (((unsigned int)handler > CFG_RAM_END) ||
+	    ((unsigned int)handler < CFG_RAM_BASE)
+	    ) {
+		printf("irq_install_handler: bad handler: %x, irq number %d\n",
+		       (unsigned int)handler, irq);
+		return;
+	}
+	irq_handlers[irq].handler = handler;
+	irq_handlers[irq].arg = arg;
+
+	/* enable irq on LEON2 hardware */
+	leon2_ic_enable(irq);
+
+}
+
+void irq_free_handler(int irq)
+{
+	if (irq < 0 || irq >= NR_IRQS) {
+		printf("irq_free_handler: bad irq number %d\n", irq);
+		return;
+	}
+
+	/* disable irq on LEON2 hardware */
+	leon2_ic_disable(irq);
+
+	irq_handlers[irq].handler = NULL;
+	irq_handlers[irq].arg = NULL;
+}
+
+/****************************************************************************/
+
+#if defined(CONFIG_CMD_IRQ)
+void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
+{
+	int irq;
+	unsigned int pil = get_pil();
+	printf("PIL level: %u\n\r", pil);
+	printf("Spurious IRQ: %u, last unknown IRQ: %d\n",
+	       spurious_irq_cnt, spurious_irq);
+
+	puts("\nInterrupt-Information:\n" "Nr  Routine   Arg       Count\n");
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		if (irq_handlers[irq].handler != NULL) {
+			printf("%02d  %08lx  %08lx  %ld\n", irq,
+			       (unsigned int)irq_handlers[irq].handler,
+			       (unsigned int)irq_handlers[irq].arg,
+			       irq_handlers[irq].count);
+		}
+	}
+}
+#endif
diff --git a/cpu/leon2/prom.c b/cpu/leon2/prom.c
new file mode 100644
index 0000000..b031995
--- /dev/null
+++ b/cpu/leon2/prom.c
@@ -0,0 +1,1047 @@
+/* prom.c - emulates a sparc v0 PROM for the linux kernel.
+ *
+ * Copyright (C) 2003 Konrad Eisele <eiselekd@web.de>
+ * Copyright (C) 2004 Stefan Holst <mail@s-holst.de>
+ * Copyright (C) 2007 Daniel Hellstrom <daniel@gaisler.com>
+ *
+ * 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/prom.h>
+#include <asm/machines.h>
+#include <asm/srmmu.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/leon.h>
+
+#include <config.h>
+/*
+#define PRINT_ROM_VEC
+*/
+extern struct linux_romvec *kernel_arg_promvec;
+
+#define PROM_PGT __attribute__ ((__section__ (".prom.pgt")))
+#define PROM_TEXT __attribute__ ((__section__ (".prom.text")))
+#define PROM_DATA __attribute__ ((__section__ (".prom.data")))
+
+/* for __va */
+extern int __prom_start;
+#define PAGE_OFFSET 0xf0000000
+#define phys_base CFG_SDRAM_BASE
+#define PROM_OFFS 8192
+#define PROM_SIZE_MASK (PROM_OFFS-1)
+#define __va(x) ( \
+	(void *)( ((unsigned long)(x))-PROM_OFFS+ \
+	(CFG_PROM_OFFSET-phys_base)+PAGE_OFFSET-TEXT_BASE ) \
+	)
+#define __phy(x) ((void *)(((unsigned long)(x))-PROM_OFFS+CFG_PROM_OFFSET-TEXT_BASE))
+
+struct property {
+	char *name;
+	char *value;
+	int length;
+};
+
+struct node {
+	int level;
+	struct property *properties;
+};
+
+static void leon_reboot(char *bcommand);
+static void leon_halt(void);
+static int leon_nbputchar(int c);
+static int leon_nbgetchar(void);
+
+static int no_nextnode(int node);
+static int no_child(int node);
+static int no_proplen(int node, char *name);
+static int no_getprop(int node, char *name, char *value);
+static int no_setprop(int node, char *name, char *value, int len);
+static char *no_nextprop(int node, char *name);
+
+static struct property PROM_TEXT *find_property(int node, char *name);
+static int PROM_TEXT leon_strcmp(const char *s1, const char *s2);
+static void *PROM_TEXT leon_memcpy(void *dest, const void *src, size_t n);
+static void PROM_TEXT leon_reboot_physical(char *bcommand);
+
+void __inline__ leon_flush_cache_all(void)
+{
+	__asm__ __volatile__(" flush ");
+      __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"::"i"(ASI_DFLUSH):"memory");
+}
+
+void __inline__ leon_flush_tlb_all(void)
+{
+	leon_flush_cache_all();
+	__asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(0x400),
+			     "i"(ASI_MMUFLUSH):"memory");
+}
+
+typedef struct {
+	unsigned int ctx_table[256];
+	unsigned int pgd_table[256];
+} sparc_srmmu_setup;
+
+sparc_srmmu_setup srmmu_tables PROM_PGT = {
+	{0},
+	{0x1e,
+	 0x10001e,
+	 0x20001e,
+	 0x30001e,
+	 0x40001e,
+	 0x50001e,
+	 0x60001e,
+	 0x70001e,
+	 0x80001e,
+	 0x90001e,
+	 0xa0001e,
+	 0xb0001e,
+	 0xc0001e,
+	 0xd0001e,
+	 0xe0001e,
+	 0xf0001e,
+	 0x100001e,
+	 0x110001e,
+	 0x120001e,
+	 0x130001e,
+	 0x140001e,
+	 0x150001e,
+	 0x160001e,
+	 0x170001e,
+	 0x180001e,
+	 0x190001e,
+	 0x1a0001e,
+	 0x1b0001e,
+	 0x1c0001e,
+	 0x1d0001e,
+	 0x1e0001e,
+	 0x1f0001e,
+	 0x200001e,
+	 0x210001e,
+	 0x220001e,
+	 0x230001e,
+	 0x240001e,
+	 0x250001e,
+	 0x260001e,
+	 0x270001e,
+	 0x280001e,
+	 0x290001e,
+	 0x2a0001e,
+	 0x2b0001e,
+	 0x2c0001e,
+	 0x2d0001e,
+	 0x2e0001e,
+	 0x2f0001e,
+	 0x300001e,
+	 0x310001e,
+	 0x320001e,
+	 0x330001e,
+	 0x340001e,
+	 0x350001e,
+	 0x360001e,
+	 0x370001e,
+	 0x380001e,
+	 0x390001e,
+	 0x3a0001e,
+	 0x3b0001e,
+	 0x3c0001e,
+	 0x3d0001e,
+	 0x3e0001e,
+	 0x3f0001e,
+	 0x400001e,
+	 0x410001e,
+	 0x420001e,
+	 0x430001e,
+	 0x440001e,
+	 0x450001e,
+	 0x460001e,
+	 0x470001e,
+	 0x480001e,
+	 0x490001e,
+	 0x4a0001e,
+	 0x4b0001e,
+	 0x4c0001e,
+	 0x4d0001e,
+	 0x4e0001e,
+	 0x4f0001e,
+	 0x500001e,
+	 0x510001e,
+	 0x520001e,
+	 0x530001e,
+	 0x540001e,
+	 0x550001e,
+	 0x560001e,
+	 0x570001e,
+	 0x580001e,
+	 0x590001e,
+	 0x5a0001e,
+	 0x5b0001e,
+	 0x5c0001e,
+	 0x5d0001e,
+	 0x5e0001e,
+	 0x5f0001e,
+	 0x600001e,
+	 0x610001e,
+	 0x620001e,
+	 0x630001e,
+	 0x640001e,
+	 0x650001e,
+	 0x660001e,
+	 0x670001e,
+	 0x680001e,
+	 0x690001e,
+	 0x6a0001e,
+	 0x6b0001e,
+	 0x6c0001e,
+	 0x6d0001e,
+	 0x6e0001e,
+	 0x6f0001e,
+	 0x700001e,
+	 0x710001e,
+	 0x720001e,
+	 0x730001e,
+	 0x740001e,
+	 0x750001e,
+	 0x760001e,
+	 0x770001e,
+	 0x780001e,
+	 0x790001e,
+	 0x7a0001e,
+	 0x7b0001e,
+	 0x7c0001e,
+	 0x7d0001e,
+	 0x7e0001e,
+	 0x7f0001e,
+	 0x800001e,
+	 0x810001e,
+	 0x820001e,
+	 0x830001e,
+	 0x840001e,
+	 0x850001e,
+	 0x860001e,
+	 0x870001e,
+	 0x880001e,
+	 0x890001e,
+	 0x8a0001e,
+	 0x8b0001e,
+	 0x8c0001e,
+	 0x8d0001e,
+	 0x8e0001e,
+	 0x8f0001e,
+	 0x900001e,
+	 0x910001e,
+	 0x920001e,
+	 0x930001e,
+	 0x940001e,
+	 0x950001e,
+	 0x960001e,
+	 0x970001e,
+	 0x980001e,
+	 0x990001e,
+	 0x9a0001e,
+	 0x9b0001e,
+	 0x9c0001e,
+	 0x9d0001e,
+	 0x9e0001e,
+	 0x9f0001e,
+	 0xa00001e,
+	 0xa10001e,
+	 0xa20001e,
+	 0xa30001e,
+	 0xa40001e,
+	 0xa50001e,
+	 0xa60001e,
+	 0xa70001e,
+	 0xa80001e,
+	 0xa90001e,
+	 0xaa0001e,
+	 0xab0001e,
+	 0xac0001e,
+	 0xad0001e,
+	 0xae0001e,
+	 0xaf0001e,
+	 0xb00001e,
+	 0xb10001e,
+	 0xb20001e,
+	 0xb30001e,
+	 0xb40001e,
+	 0xb50001e,
+	 0xb60001e,
+	 0xb70001e,
+	 0xb80001e,
+	 0xb90001e,
+	 0xba0001e,
+	 0xbb0001e,
+	 0xbc0001e,
+	 0xbd0001e,
+	 0xbe0001e,
+	 0xbf0001e,
+	 0xc00001e,
+	 0xc10001e,
+	 0xc20001e,
+	 0xc30001e,
+	 0xc40001e,
+	 0xc50001e,
+	 0xc60001e,
+	 0xc70001e,
+	 0xc80001e,
+	 0xc90001e,
+	 0xca0001e,
+	 0xcb0001e,
+	 0xcc0001e,
+	 0xcd0001e,
+	 0xce0001e,
+	 0xcf0001e,
+	 0xd00001e,
+	 0xd10001e,
+	 0xd20001e,
+	 0xd30001e,
+	 0xd40001e,
+	 0xd50001e,
+	 0xd60001e,
+	 0xd70001e,
+	 0xd80001e,
+	 0xd90001e,
+	 0xda0001e,
+	 0xdb0001e,
+	 0xdc0001e,
+	 0xdd0001e,
+	 0xde0001e,
+	 0xdf0001e,
+	 0xe00001e,
+	 0xe10001e,
+	 0xe20001e,
+	 0xe30001e,
+	 0xe40001e,
+	 0xe50001e,
+	 0xe60001e,
+	 0xe70001e,
+	 0xe80001e,
+	 0xe90001e,
+	 0xea0001e,
+	 0xeb0001e,
+	 0xec0001e,
+	 0xed0001e,
+	 0xee0001e,
+	 0xef0001e,
+	 0x400001e		/* default */
+	 }
+};
+
+/* a self contained prom info structure */
+struct leon_reloc_func {
+	struct property *(*find_property) (int node, char *name);
+	int (*strcmp) (char *s1, char *s2);
+	void *(*memcpy) (void *dest, const void *src, size_t n);
+	void (*reboot_physical) (char *cmd);
+};
+
+struct leon_prom_info {
+	int freq_khz;
+	int leon_nctx;
+	int mids[32];
+	int baudrates[2];
+	struct leon_reloc_func reloc_funcs;
+	struct property root_properties[4];
+	struct property cpu_properties[7];
+#undef  CPUENTRY
+#define CPUENTRY(idx) struct property cpu_properties##idx[4]
+	 CPUENTRY(1);
+	 CPUENTRY(2);
+	 CPUENTRY(3);
+	 CPUENTRY(4);
+	 CPUENTRY(5);
+	 CPUENTRY(6);
+	 CPUENTRY(7);
+	 CPUENTRY(8);
+	 CPUENTRY(9);
+	 CPUENTRY(10);
+	 CPUENTRY(11);
+	 CPUENTRY(12);
+	 CPUENTRY(13);
+	 CPUENTRY(14);
+	 CPUENTRY(15);
+	 CPUENTRY(16);
+	 CPUENTRY(17);
+	 CPUENTRY(18);
+	 CPUENTRY(19);
+	 CPUENTRY(20);
+	 CPUENTRY(21);
+	 CPUENTRY(22);
+	 CPUENTRY(23);
+	 CPUENTRY(24);
+	 CPUENTRY(25);
+	 CPUENTRY(26);
+	 CPUENTRY(27);
+	 CPUENTRY(28);
+	 CPUENTRY(29);
+	 CPUENTRY(30);
+	 CPUENTRY(31);
+	struct idprom idprom;
+	struct linux_nodeops nodeops;
+	struct linux_mlist_v0 *totphys_p;
+	struct linux_mlist_v0 totphys;
+	struct linux_mlist_v0 *avail_p;
+	struct linux_mlist_v0 avail;
+	struct linux_mlist_v0 *prommap_p;
+	void (*synchook) (void);
+	struct linux_arguments_v0 *bootargs_p;
+	struct linux_arguments_v0 bootargs;
+	struct linux_romvec romvec;
+	struct node nodes[35];
+	char s_device_type[12];
+	char s_cpu[4];
+	char s_mid[4];
+	char s_idprom[7];
+	char s_compatability[14];
+	char s_leon2[6];
+	char s_mmu_nctx[9];
+	char s_frequency[16];
+	char s_uart1_baud[11];
+	char s_uart2_baud[11];
+	char arg[256];
+};
+
+/* static prom info */
+static struct leon_prom_info PROM_DATA spi = {
+	CONFIG_SYS_CLK_FREQ / 1000,
+	256,
+	{
+#undef	CPUENTRY
+#define	CPUENTRY(idx) idx
+	 CPUENTRY(0),
+	 CPUENTRY(1),
+	 CPUENTRY(2),
+	 CPUENTRY(3),
+	 CPUENTRY(4),
+	 CPUENTRY(5),
+	 CPUENTRY(6),
+	 CPUENTRY(7),
+	 CPUENTRY(8),
+	 CPUENTRY(9),
+	 CPUENTRY(10),
+	 CPUENTRY(11),
+	 CPUENTRY(12),
+	 CPUENTRY(13),
+	 CPUENTRY(14),
+	 CPUENTRY(15),
+	 CPUENTRY(16),
+	 CPUENTRY(17),
+	 CPUENTRY(18),
+	 CPUENTRY(19),
+	 CPUENTRY(20),
+	 CPUENTRY(21),
+	 CPUENTRY(22),
+	 CPUENTRY(23),
+	 CPUENTRY(24),
+	 CPUENTRY(25),
+	 CPUENTRY(26),
+	 CPUENTRY(27),
+	 CPUENTRY(28),
+	 CPUENTRY(29),
+	 CPUENTRY(30),
+	 31},
+	{38400, 38400},
+	{
+	 __va(find_property),
+	 __va(leon_strcmp),
+	 __va(leon_memcpy),
+	 __phy(leon_reboot_physical),
+	 },
+	{
+	 {__va(spi.s_device_type), __va(spi.s_idprom), 4},
+	 {__va(spi.s_idprom), (char *)__va(&spi.idprom), sizeof(struct idprom)},
+	 {__va(spi.s_compatability), __va(spi.s_leon2), 5},
+	 {NULL, NULL, -1}
+	 },
+	{
+	 {__va(spi.s_device_type), __va(spi.s_cpu), 4},
+	 {__va(spi.s_mid), __va(&spi.mids[0]), 4},
+	 {__va(spi.s_mmu_nctx), (char *)__va(&spi.leon_nctx), 4},
+	 {__va(spi.s_frequency), (char *)__va(&spi.freq_khz), 4},
+	 {__va(spi.s_uart1_baud), (char *)__va(&spi.baudrates[0]), 4},
+	 {__va(spi.s_uart2_baud), (char *)__va(&spi.baudrates[1]), 4},
+	 {NULL, NULL, -1}
+	 },
+#undef  CPUENTRY
+#define CPUENTRY(idx) \
+	{ /* cpu_properties */						\
+		{__va(spi.s_device_type), __va(spi.s_cpu), 4},		\
+		{__va(spi.s_mid), __va(&spi.mids[idx]), 4},			\
+		{__va(spi.s_frequency), (char *)__va(&spi.freq_khz), 4},	\
+		{NULL, NULL, -1}						\
+	}
+	CPUENTRY(1),
+	CPUENTRY(2),
+	CPUENTRY(3),
+	CPUENTRY(4),
+	CPUENTRY(5),
+	CPUENTRY(6),
+	CPUENTRY(7),
+	CPUENTRY(8),
+	CPUENTRY(9),
+	CPUENTRY(10),
+	CPUENTRY(11),
+	CPUENTRY(12),
+	CPUENTRY(13),
+	CPUENTRY(14),
+	CPUENTRY(15),
+	CPUENTRY(16),
+	CPUENTRY(17),
+	CPUENTRY(18),
+	CPUENTRY(19),
+	CPUENTRY(20),
+	CPUENTRY(21),
+	CPUENTRY(22),
+	CPUENTRY(23),
+	CPUENTRY(24),
+	CPUENTRY(25),
+	CPUENTRY(26),
+	CPUENTRY(27),
+	CPUENTRY(28),
+	CPUENTRY(29),
+	CPUENTRY(30),
+	CPUENTRY(31),
+	{
+	 0x01,			/* format */
+	 M_LEON2 | M_LEON2_SOC,	/* machine type */
+	 {0, 0, 0, 0, 0, 0},	/* eth */
+	 0,			/* date */
+	 0,			/* sernum */
+	 0,			/* checksum */
+	 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}	/* reserved */
+	 },
+	{
+	 __va(no_nextnode),
+	 __va(no_child),
+	 __va(no_proplen),
+	 __va(no_getprop),
+	 __va(no_setprop),
+	 __va(no_nextprop)
+	 },
+	__va(&spi.totphys),
+	{
+	 NULL,
+	 (char *)CFG_SDRAM_BASE,
+	 0,
+	 },
+	__va(&spi.avail),
+	{
+	 NULL,
+	 (char *)CFG_SDRAM_BASE,
+	 0,
+	 },
+	NULL,			/* prommap_p */
+	NULL,
+	__va(&spi.bootargs),
+	{
+	 {NULL, __va(spi.arg), NULL /*... */ },
+	 /*... */
+	 },
+	{
+	 0,
+	 0,			/* sun4c v0 prom */
+	 0, 0,
+	 {__va(&spi.totphys_p), __va(&spi.prommap_p), __va(&spi.avail_p)},
+	 __va(&spi.nodeops),
+	 NULL, {NULL /* ... */ },
+	 NULL, NULL,
+	 NULL, NULL,		/* pv_getchar, pv_putchar */
+	 __va(leon_nbgetchar), __va(leon_nbputchar),
+	 NULL,
+	 __va(leon_reboot),
+	 NULL,
+	 NULL,
+	 NULL,
+	 __va(leon_halt),
+	 __va(&spi.synchook),
+	 {NULL},
+	 __va(&spi.bootargs_p)
+	 /*... */
+	 },
+	{
+	 {0, __va(spi.root_properties + 3) /* NULL, NULL, -1 */ },
+	 {0, __va(spi.root_properties)},
+	 /* cpu 0, must be spi.nodes[2] see leon_prom_init() */
+	 {1, __va(spi.cpu_properties)},
+
+#undef  CPUENTRY
+#define CPUENTRY(idx) \
+	  {1, __va(spi.cpu_properties##idx) }	/* cpu <idx> */
+	 CPUENTRY(1),
+	 CPUENTRY(2),
+	 CPUENTRY(3),
+	 CPUENTRY(4),
+	 CPUENTRY(5),
+	 CPUENTRY(6),
+	 CPUENTRY(7),
+	 CPUENTRY(8),
+	 CPUENTRY(9),
+	 CPUENTRY(10),
+	 CPUENTRY(11),
+	 CPUENTRY(12),
+	 CPUENTRY(13),
+	 CPUENTRY(14),
+	 CPUENTRY(15),
+	 CPUENTRY(16),
+	 CPUENTRY(17),
+	 CPUENTRY(18),
+	 CPUENTRY(19),
+	 CPUENTRY(20),
+	 CPUENTRY(21),
+	 CPUENTRY(22),
+	 CPUENTRY(23),
+	 CPUENTRY(24),
+	 CPUENTRY(25),
+	 CPUENTRY(26),
+	 CPUENTRY(27),
+	 CPUENTRY(28),
+	 CPUENTRY(29),
+	 CPUENTRY(30),
+	 CPUENTRY(31),
+	 {-1, __va(spi.root_properties + 3) /* NULL, NULL, -1 */ }
+	 },
+	"device_type",
+	"cpu",
+	"mid",
+	"idprom",
+	"compatability",
+	"leon2",
+	"mmu-nctx",
+	"clock-frequency",
+	"uart1_baud",
+	"uart2_baud",
+	CONFIG_DEFAULT_KERNEL_COMMAND_LINE
+};
+
+/* from arch/sparc/kernel/setup.c */
+#define RAMDISK_LOAD_FLAG 0x4000
+extern unsigned short root_flags;
+extern unsigned short root_dev;
+extern unsigned short ram_flags;
+extern unsigned int sparc_ramdisk_image;
+extern unsigned int sparc_ramdisk_size;
+extern int root_mountflags;
+
+extern char initrd_end, initrd_start;
+
+/* Reboot the CPU = jump to beginning of flash again.
+ *
+ * Make sure that all function are inlined here.
+ */
+static void PROM_TEXT leon_reboot(char *bcommand)
+{
+	register char *arg = bcommand;
+	void __attribute__ ((noreturn)) (*reboot_physical) (char *cmd);
+
+	/* get physical address */
+	struct leon_prom_info *pspi =
+	    (void *)(CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	unsigned int *srmmu_ctx_table;
+
+	/* Turn of Interrupts */
+	set_pil(0xf);
+
+	/* Set kernel's context, context zero */
+	srmmu_set_context(0);
+
+	/* Get physical address of the MMU shutdown routine */
+	reboot_physical = (void *)
+	    SPARC_BYPASS_READ(&pspi->reloc_funcs.reboot_physical);
+
+	/* Now that we know the physical address of the function
+	 * we can make the MMU allow jumping to it.
+	 */
+	srmmu_ctx_table = (unsigned int *)srmmu_get_ctable_ptr();
+
+	srmmu_ctx_table = (unsigned int *)SPARC_BYPASS_READ(srmmu_ctx_table);
+
+	/* get physical address of kernel's context table (assume ptd) */
+	srmmu_ctx_table = (unsigned int *)
+	    (((unsigned int)srmmu_ctx_table & 0xfffffffc) << 4);
+
+	/* enable access to physical address of MMU shutdown function */
+	SPARC_BYPASS_WRITE(&srmmu_ctx_table
+			   [((unsigned int)reboot_physical) >> 24],
+			   (((unsigned int)reboot_physical & 0xff000000) >> 4) |
+			   0x1e);
+
+	/* flush TLB cache */
+	leon_flush_tlb_all();
+
+	/* flash instruction & data cache */
+	sparc_icache_flush_all();
+	sparc_dcache_flush_all();
+
+	/* jump to physical address function
+	 * so that when the MMU is disabled
+	 * we can continue to execute
+	 */
+	reboot_physical(arg);
+}
+
+static void PROM_TEXT leon_reboot_physical(char *bcommand)
+{
+	void __attribute__ ((noreturn)) (*reset) (void);
+
+	/* Turn off MMU */
+	srmmu_set_mmureg(0);
+
+	/* Hardcoded start address */
+	reset = CFG_MONITOR_BASE;
+
+	/* flush data cache */
+	sparc_dcache_flush_all();
+
+	/* flush instruction cache */
+	sparc_icache_flush_all();
+
+	/* Jump to start in Flash */
+	reset();
+}
+
+static void PROM_TEXT leon_halt(void)
+{
+	while (1) ;
+}
+
+/* get single char, don't care for blocking*/
+static int PROM_TEXT leon_nbgetchar(void)
+{
+	return -1;
+}
+
+/* put single char, don't care for blocking*/
+static int PROM_TEXT leon_nbputchar(int c)
+{
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+
+	/***** put char in buffer... ***********
+	 * Make sure all functions are inline! *
+	 ***************************************/
+
+	/* Wait for last character to go. */
+	while (!(SPARC_BYPASS_READ(&leon2->UART_Status_1)
+		 & LEON2_UART_STAT_THE)) ;
+
+	/* Send data */
+	SPARC_BYPASS_WRITE(&leon2->UART_Channel_1, c);
+
+	/* Wait for data to be sent */
+	while (!(SPARC_BYPASS_READ(&leon2->UART_Status_1)
+		 & LEON2_UART_STAT_TSE)) ;
+
+	return 0;
+}
+
+/* node ops */
+
+/*#define nodes ((struct node *)__va(&pspi->nodes))*/
+#define nodes ((struct node *)(pspi->nodes))
+
+static int PROM_TEXT no_nextnode(int node)
+{
+	/* get physical address */
+	struct leon_prom_info *pspi =
+	    (void *)(CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	/* convert into virtual address */
+	pspi = (struct leon_prom_info *)
+	    (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET);
+
+	if (nodes[node].level == nodes[node + 1].level)
+		return node + 1;
+	return -1;
+}
+
+static int PROM_TEXT no_child(int node)
+{
+	/* get physical address */
+	struct leon_prom_info *pspi = (struct leon_prom_info *)
+	    (CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	/* convert into virtual address */
+	pspi = (struct leon_prom_info *)
+	    (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET);
+
+	if (nodes[node].level == nodes[node + 1].level - 1)
+		return node + 1;
+	return -1;
+}
+
+static struct property PROM_TEXT *find_property(int node, char *name)
+{
+	/* get physical address */
+	struct leon_prom_info *pspi = (struct leon_prom_info *)
+	    (CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	/* convert into virtual address */
+	pspi = (struct leon_prom_info *)
+	    (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET);
+
+	struct property *prop = &nodes[node].properties[0];
+	while (prop && prop->name) {
+		if (pspi->reloc_funcs.strcmp(prop->name, name) == 0)
+			return prop;
+		prop++;
+	}
+	return NULL;
+}
+
+static int PROM_TEXT no_proplen(int node, char *name)
+{
+	/* get physical address */
+	struct leon_prom_info *pspi = (struct leon_prom_info *)
+	    (CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	/* convert into virtual address */
+	pspi = (struct leon_prom_info *)
+	    (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET);
+
+	struct property *prop = pspi->reloc_funcs.find_property(node, name);
+	if (prop)
+		return prop->length;
+	return -1;
+}
+
+static int PROM_TEXT no_getprop(int node, char *name, char *value)
+{
+	/* get physical address */
+	struct leon_prom_info *pspi = (struct leon_prom_info *)
+	    (CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	/* convert into virtual address */
+	pspi = (struct leon_prom_info *)
+	    (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET);
+
+	struct property *prop = pspi->reloc_funcs.find_property(node, name);
+	if (prop) {
+		pspi->reloc_funcs.memcpy(value, prop->value, prop->length);
+		return 1;
+	}
+	return -1;
+}
+
+static int PROM_TEXT no_setprop(int node, char *name, char *value, int len)
+{
+	return -1;
+}
+
+static char PROM_TEXT *no_nextprop(int node, char *name)
+{
+	/* get physical address */
+	struct leon_prom_info *pspi = (struct leon_prom_info *)
+	    (CFG_PROM_OFFSET + sizeof(srmmu_tables));
+	struct property *prop;
+
+	/* convert into virtual address */
+	pspi = (struct leon_prom_info *)
+	    (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET);
+
+	if (!name || !name[0])
+		return nodes[node].properties[0].name;
+
+	prop = pspi->reloc_funcs.find_property(node, name);
+	if (prop)
+		return prop[1].name;
+	return NULL;
+}
+
+static int PROM_TEXT leon_strcmp(const char *s1, const char *s2)
+{
+	register char result;
+
+	while (1) {
+		result = *s1 - *s2;
+		if (result || !*s1)
+			break;
+		s2++;
+		s1++;
+	}
+
+	return result;
+}
+
+static void *PROM_TEXT leon_memcpy(void *dest, const void *src, size_t n)
+{
+	char *dst = (char *)dest, *source = (char *)src;
+
+	while (n--) {
+		*dst = *source;
+		dst++;
+		source++;
+	}
+	return dest;
+}
+
+#define GETREGSP(sp) __asm__ __volatile__("mov %%sp, %0" : "=r" (sp))
+
+void leon_prom_init(struct leon_prom_info *pspi)
+{
+	unsigned long i;
+	unsigned char cksum, *ptr;
+	char *addr_str, *end;
+	unsigned long sp;
+	GETREGSP(sp);
+
+	pspi->freq_khz = CONFIG_SYS_CLK_FREQ / 1000;
+
+	/* Set Available main memory size */
+	pspi->totphys.num_bytes = CFG_PROM_OFFSET - CFG_SDRAM_BASE;
+	pspi->avail.num_bytes = pspi->totphys.num_bytes;
+
+#undef nodes
+	pspi->nodes[3].level = -1;
+	pspi->nodes[3].properties = __va(spi.root_properties + 3);
+
+	/* Set Ethernet MAC address from environment */
+	if ((addr_str = getenv("ethaddr")) != NULL) {
+		for (i = 0; i < 6; i++) {
+			pspi->idprom.id_ethaddr[i] = addr_str ?
+			    simple_strtoul(addr_str, &end, 16) : 0;
+			if (addr_str) {
+				addr_str = (*end) ? end + 1 : end;
+			}
+		}
+	} else {
+		/* HW Address not found in environment,
+		 * Set default HW address
+		 */
+		pspi->idprom.id_ethaddr[0] = 0;
+		pspi->idprom.id_ethaddr[1] = 0;
+		pspi->idprom.id_ethaddr[2] = 0;
+		pspi->idprom.id_ethaddr[3] = 0;
+		pspi->idprom.id_ethaddr[4] = 0;
+		pspi->idprom.id_ethaddr[5] = 0;
+	}
+
+	ptr = (unsigned char *)&pspi->idprom;
+	for (i = cksum = 0; i <= 0x0E; i++)
+		cksum ^= *ptr++;
+	pspi->idprom.id_cksum = cksum;
+}
+
+static inline void set_cache(unsigned long regval)
+{
+	asm volatile ("sta %0, [%%g0] %1\n\t":: "r" (regval), "i"(2):"memory");
+}
+
+extern unsigned short bss_start, bss_end;
+
+/* mark as section .img.main.text, to be referenced in linker script */
+int prom_init(void)
+{
+	struct leon_prom_info *pspi = (void *)
+	    ((((unsigned int)&spi) & PROM_SIZE_MASK) + CFG_PROM_OFFSET);
+
+	/* disable mmu */
+	srmmu_set_mmureg(0x00000000);
+	__asm__ __volatile__("flush\n\t");
+
+	/* init prom info struct */
+	leon_prom_init(pspi);
+
+	kernel_arg_promvec = &pspi->romvec;
+#ifdef PRINT_ROM_VEC
+	printf("Kernel rom vec: 0x%lx\n", (unsigned int)(&pspi->romvec));
+#endif
+	return 0;
+}
+
+/* Copy current kernel boot argument to ROMvec */
+void prepare_bootargs(char *bootargs)
+{
+	struct leon_prom_info *pspi;
+	char *src, *dst;
+	int left;
+
+	/* if no bootargs set, skip copying ==> default bootline */
+	if (bootargs && (*bootargs != '\0')) {
+		pspi = (void *)((((unsigned int)&spi) & PROM_SIZE_MASK) +
+				CFG_PROM_OFFSET);
+		src = bootargs;
+		dst = &pspi->arg[0];
+		left = 255;	/* max len */
+		while (*src && left > 0) {
+			*dst++ = *src++;
+			left--;
+		}
+		/* terminate kernel command line string */
+		*dst = 0;
+	}
+}
+
+void srmmu_init_cpu(unsigned int entry)
+{
+	sparc_srmmu_setup *psrmmu_tables = (void *)
+	    ((((unsigned int)&srmmu_tables) & PROM_SIZE_MASK) +
+	     CFG_PROM_OFFSET);
+
+	/* Make context 0 (kernel's context) point
+	 * to our prepared memory mapping
+	 */
+#define PTD 1
+	psrmmu_tables->ctx_table[0] =
+	    ((unsigned int)&psrmmu_tables->pgd_table[0x00]) >> 4 | PTD;
+
+	/* Set virtual kernel address 0xf0000000
+	 * to SRAM/SDRAM address.
+	 * Make it READ/WRITE/EXEC to SuperUser
+	 */
+#define PTE 2
+#define ACC_SU_ALL 0x1c
+	psrmmu_tables->pgd_table[0xf0] =
+	    (CFG_SDRAM_BASE >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf1] =
+	    ((CFG_SDRAM_BASE + 0x1000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf2] =
+	    ((CFG_SDRAM_BASE + 0x2000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf3] =
+	    ((CFG_SDRAM_BASE + 0x3000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf4] =
+	    ((CFG_SDRAM_BASE + 0x4000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf5] =
+	    ((CFG_SDRAM_BASE + 0x5000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf6] =
+	    ((CFG_SDRAM_BASE + 0x6000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf7] =
+	    ((CFG_SDRAM_BASE + 0x7000000) >> 4) | ACC_SU_ALL | PTE;
+
+	/* convert rom vec pointer to virtual address */
+	kernel_arg_promvec = (struct linux_romvec *)
+	    (((unsigned int)kernel_arg_promvec & 0x0fffffff) | 0xf0000000);
+
+	/* Set Context pointer to point to context table
+	 * 256 contexts supported.
+	 */
+	srmmu_set_ctable_ptr((unsigned int)&psrmmu_tables->ctx_table[0]);
+
+	/* Set kernel's context, context zero */
+	srmmu_set_context(0);
+
+	/* Invalidate all Cache */
+	__asm__ __volatile__("flush\n\t");
+
+	srmmu_set_mmureg(0x00000001);
+	leon_flush_tlb_all();
+	leon_flush_cache_all();
+}
diff --git a/cpu/leon2/serial.c b/cpu/leon2/serial.c
new file mode 100644
index 0000000..ce9457f
--- /dev/null
+++ b/cpu/leon2/serial.c
@@ -0,0 +1,165 @@
+/* GRLIB APBUART Serial controller driver
+ *
+ * (C) Copyright 2008
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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/processor.h>
+#include <asm/leon.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Force cache miss each time a serial controller reg is read */
+#define CACHE_BYPASS 1
+
+#ifdef CACHE_BYPASS
+#define READ_BYTE(var)  SPARC_NOCACHE_READ_BYTE((unsigned int)&(var))
+#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)&(var))
+#define READ_WORD(var)  SPARC_NOCACHE_READ((unsigned int)&(var))
+#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)&(var))
+#endif
+
+int serial_init(void)
+{
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+	LEON2_Uart_regs *regs;
+	unsigned int tmp;
+
+	/* Init LEON2 UART
+	 *
+	 * Set scaler / baud rate
+	 *
+	 * Receiver & transmitter enable
+	 */
+#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
+	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
+#else
+	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
+#endif
+
+	regs->UART_Scaler = CFG_LEON2_UART1_SCALER;
+
+	/* Let bit 11 be unchanged (debug bit for GRMON) */
+	tmp = READ_WORD(regs->UART_Control);
+
+	regs->UART_Control = ((tmp & LEON2_UART_CTRL_DBG) |
+			      (LEON2_UART1_LOOPBACK_ENABLE << 7) |
+			      (LEON2_UART1_FLOWCTRL_ENABLE << 6) |
+			      (LEON2_UART1_PARITY_ENABLE << 5) |
+			      (LEON2_UART1_ODDPAR_ENABLE << 4) |
+			      LEON2_UART_CTRL_RE | LEON2_UART_CTRL_TE);
+
+	return 0;
+}
+
+void serial_putc(const char c)
+{
+	if (c == '\n')
+		serial_putc_raw('\r');
+
+	serial_putc_raw(c);
+}
+
+void serial_putc_raw(const char c)
+{
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+	LEON2_Uart_regs *regs;
+
+#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
+	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
+#else
+	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
+#endif
+
+	/* Wait for last character to go. */
+	while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_THE)) ;
+
+	/* Send data */
+	regs->UART_Channel = c;
+
+#ifdef LEON_DEBUG
+	/* Wait for data to be sent */
+	while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_TSE)) ;
+#endif
+}
+
+void serial_puts(const char *s)
+{
+	while (*s) {
+		serial_putc(*s++);
+	}
+}
+
+int serial_getc(void)
+{
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+	LEON2_Uart_regs *regs;
+
+#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
+	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
+#else
+	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
+#endif
+
+	/* Wait for a character to arrive. */
+	while (!(READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR)) ;
+
+	/* read data */
+	return READ_WORD(regs->UART_Channel);
+}
+
+int serial_tstc(void)
+{
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+	LEON2_Uart_regs *regs;
+
+#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
+	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
+#else
+	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
+#endif
+
+	return (READ_WORD(regs->UART_Status) & LEON2_UART_STAT_DR);
+}
+
+/* set baud rate for uart */
+void serial_setbrg(void)
+{
+	/* update baud rate settings, read it from gd->baudrate */
+	unsigned int scaler;
+	LEON2_regs *leon2 = (LEON2_regs *) LEON2_PREGS;
+	LEON2_Uart_regs *regs;
+
+#if LEON2_CONSOLE_SELECT == LEON_CONSOLE_UART1
+	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_1;
+#else
+	regs = (LEON2_Uart_regs *) & leon2->UART_Channel_2;
+#endif
+
+	if (gd->baudrate > 0) {
+		scaler =
+		    (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
+		     5) / 10;
+		regs->UART_Scaler = scaler;
+	}
+}
diff --git a/cpu/leon2/start.S b/cpu/leon2/start.S
new file mode 100644
index 0000000..937ea1e
--- /dev/null
+++ b/cpu/leon2/start.S
@@ -0,0 +1,661 @@
+/* This is where the SPARC/LEON3 starts
+ * Copyright (C) 2007,
+ * Daniel Hellstrom, daniel@gaisler.com
+ *
+ * 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 <config.h>
+#include <asm/asmmacro.h>
+#include <asm/winmacro.h>
+#include <asm/psr.h>
+#include <asm/stack.h>
+#include <asm/leon.h>
+#include <version.h>
+
+/* Entry for traps which jump to a programmer-specified trap handler.  */
+#define TRAPR(H)  \
+	wr 	%g0, 0xfe0, %psr; \
+	mov 	%g0, %tbr; \
+	ba 	(H); \
+	mov 	%g0, %wim;
+
+#define TRAP(H) \
+	mov	%psr, %l0; \
+	ba	(H); \
+	nop; nop;
+
+#define TRAPI(ilevel) \
+	mov 	ilevel, %l7; \
+	mov 	%psr, %l0; \
+	b 	_irq_entry; \
+	mov 	%wim, %l3
+
+/* Unexcpected trap will halt the processor by forcing it to error state */
+#undef BAD_TRAP
+#define BAD_TRAP ta 0; nop; nop; nop;
+
+/* Software trap. Treat as BAD_TRAP for the time being... */
+#define SOFT_TRAP TRAP(_hwerr)
+
+#define PSR_INIT   0x1FC0	/* Disable traps, set s and ps */
+#define WIM_INIT   2
+
+/* All traps low-level code here must end with this macro. */
+#define RESTORE_ALL b ret_trap_entry; clr %l6;
+
+#define WRITE_PAUSE nop;nop;nop
+
+WINDOWSIZE = (16 * 4)
+ARGPUSHSIZE = (6 * 4)
+ARGPUSH = (WINDOWSIZE + 4)
+MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4)
+
+/* Number of register windows */
+#ifndef CFG_SPARC_NWINDOWS
+#error Must define number of SPARC register windows, default is 8
+#endif
+
+#define STACK_ALIGN	8
+#define SA(X)	(((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
+
+	.section ".start", "ax"
+	.globl 	_start, start, _trap_table
+	.globl  _irq_entry, nmi_trap
+	.globl  _reset_reloc
+
+/* at address 0
+ * Hardware traps
+ */
+start:
+_start:
+_trap_table:
+	TRAPR(_hardreset);		! 00 reset trap
+	BAD_TRAP;			! 01 instruction_access_exception
+	BAD_TRAP;			! 02 illegal_instruction
+	BAD_TRAP;			! 03 priveleged_instruction
+	BAD_TRAP;			! 04 fp_disabled
+	TRAP(_window_overflow);		! 05 window_overflow
+	TRAP(_window_underflow);	! 06 window_underflow
+	BAD_TRAP;			! 07 Memory Address Not Aligned
+	BAD_TRAP;			! 08 Floating Point Exception
+	BAD_TRAP;			! 09 Data Miss Exception
+	BAD_TRAP;			! 0a Tagged Instruction Ovrflw
+	BAD_TRAP;			! 0b Watchpoint Detected
+	BAD_TRAP;			! 0c
+	BAD_TRAP;			! 0d
+	BAD_TRAP;			! 0e
+	BAD_TRAP;			! 0f
+	BAD_TRAP;			! 10
+	TRAPI(1);			! 11 IRQ level 1
+	TRAPI(2);			! 12 IRQ level 2
+	TRAPI(3);			! 13 IRQ level 3
+	TRAPI(4);			! 14 IRQ level 4
+	TRAPI(5);			! 15 IRQ level 5
+	TRAPI(6);			! 16 IRQ level 6
+	TRAPI(7);			! 17 IRQ level 7
+	TRAPI(8);			! 18 IRQ level 8
+	TRAPI(9);			! 19 IRQ level 9
+	TRAPI(10);			! 1a IRQ level 10
+	TRAPI(11);			! 1b IRQ level 11
+	TRAPI(12);			! 1c IRQ level 12
+	TRAPI(13);			! 1d IRQ level 13
+	TRAPI(14);			! 1e IRQ level 14
+	TRAP(_nmi_trap);		! 1f IRQ level 15 /
+	                		! NMI (non maskable interrupt)
+	BAD_TRAP;			! 20 r_register_access_error
+	BAD_TRAP;			! 21 instruction access error
+	BAD_TRAP;			! 22
+	BAD_TRAP;			! 23
+	BAD_TRAP;			! 24 co-processor disabled
+	BAD_TRAP;			! 25 uniplemented FLUSH
+	BAD_TRAP;			! 26
+	BAD_TRAP;			! 27
+	BAD_TRAP;			! 28 co-processor exception
+	BAD_TRAP;			! 29 data access error
+	BAD_TRAP;			! 2a division by zero
+	BAD_TRAP;			! 2b data store error
+	BAD_TRAP;			! 2c data access MMU miss
+	BAD_TRAP;			! 2d
+	BAD_TRAP;			! 2e
+	BAD_TRAP;			! 2f
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30-33
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34-37
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38-3b
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3c-3f
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40-43
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44-47
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48-4b
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4c-4f
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50-53
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54-57
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58-5b
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5c-5f
+
+	/* implementaion dependent */
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60-63
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64-67
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68-6b
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6c-6f
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70-73
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74-77
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78-7b
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7c-7f
+
+	/* Software traps, not handled */
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 80-83
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 84-87
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 88-8b
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 8c-8f
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 90-93
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 94-97
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 98-9b
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 9c-9f
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! a0-a3
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! a4-a7
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! a8-ab
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! ac-af
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! b0-b3
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! b4-b7
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! b8-bb
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! bc-bf
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! c0-c3
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! c4-c7
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! c8-cb
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! cc-cf
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! d0-d3
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! d4-d7
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! d8-db
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! dc-df
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! e0-e3
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! e4-e7
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! e8-eb
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! ec-ef
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! f0-f3
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! f4-f7
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! f8-fb
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! fc-ff
+/*
+ * Version string
+ */
+
+	.data
+	.globl	version_string
+version_string:
+	.ascii U_BOOT_VERSION
+	.ascii " (", __DATE__, " - ", __TIME__, ")"
+	.ascii CONFIG_IDENT_STRING, "\0"
+
+	.section	".text"
+	.align 4
+
+_hardreset:
+1000:
+	flush
+	nop
+	nop
+	nop
+
+	/* Init Cache */
+        set     (LEON2_PREGS+LEON_REG_CACHECTRL_OFFSET), %g1
+        set     0x0081000f, %g2
+        st      %g2, [%g1]
+
+	mov	%g0, %y
+	clr	%g1
+	clr	%g2
+	clr	%g3
+	clr	%g4
+	clr	%g5
+	clr	%g6
+	clr	%g7
+
+	mov	%asr17, %g3
+	and	%g3, 0x1f, %g3
+clear_window:
+	mov	%g0, %l0
+	mov	%g0, %l1
+	mov	%g0, %l2
+	mov	%g0, %l3
+	mov	%g0, %l4
+	mov	%g0, %l5
+	mov	%g0, %l6
+	mov	%g0, %l7
+	mov	%g0, %o0
+	mov	%g0, %o1
+	mov	%g0, %o2
+	mov	%g0, %o3
+	mov	%g0, %o4
+	mov	%g0, %o5
+	mov	%g0, %o6
+	mov	%g0, %o7
+	subcc	%g3, 1, %g3
+	bge	clear_window
+	save
+
+leon2_init:
+	/* LEON2 Register Base in g1 */
+	set	LEON2_PREGS, %g1
+
+leon2_init_cache:
+	/* Set Cache control register */
+	set	0x1000f, %g2
+	st	%g2, [%g1 + 0x14]
+
+leon2_init_clear:
+
+	/* Clear LEON2 registers */
+	st	%g0, [%g1 + LEON2_ECTRL]
+	st	%g0, [%g1 + LEON2_IMASK]
+	st	%g0, [%g1 + LEON2_IPEND]
+	st	%g0, [%g1 + LEON2_IFORCE]
+	st	%g0, [%g1 + LEON2_ICLEAR]
+	st	%g0, [%g1 + LEON2_IOREG]
+	st	%g0, [%g1 + LEON2_IODIR]
+	st	%g0, [%g1 + LEON2_IOICONF]
+	st	%g0, [%g1 + LEON2_UCTRL0]
+	st	%g0, [%g1 + LEON2_UCTRL1]
+
+leon2_init_ioport:
+	/* I/O port initialization */
+	set	0xaa00, %g2
+	st	%g2, [%g1 + LEON2_IOREG]
+
+leon2_init_mctrl:
+
+	/* memory config register 1 */
+	set	CFG_GRLIB_MEMCFG1, %g2
+	ld	[%g1], %g3		!
+	and	%g3, 0x300, %g3
+	or	%g2, %g3, %g2
+	st	%g2, [%g1 + LEON2_MCFG1]
+	set	CFG_GRLIB_MEMCFG2, %g2		! Load memory config register 2
+#if !( defined(TSIM) || !defined(BZIMAGE))
+	st	%g2, [%g1 + LEON2_MCFG2]	! only for prom version, else done by "dumon -i"
+#endif
+	set	CFG_GRLIB_MEMCFG3, %g2		! Init FT register
+	st	%g2, [%g1 + LEON2_ECTRL]
+	ld	[%g1 + LEON2_ECTRL], %g2
+	srl	%g2, 30, %g2
+	andcc	%g2, 3, %g6
+	bne,a	leon2_init_wim
+	mov	%g0, %asr16		! clear err_reg
+
+leon2_init_wim:
+	set	WIM_INIT, %g3
+	mov	%g3, %wim
+
+leon2_init_psr:
+	set	0x1000, %g3
+	mov	%psr, %g2
+	wr	%g2, %g3, %psr
+	nop
+	nop
+	nop
+
+leon2_init_stackp:
+	set	CFG_INIT_SP_OFFSET, %fp
+	andn	%fp, 0x0f, %fp
+	sub	%fp, 64, %sp
+
+cpu_init_unreloc:
+	call	cpu_init_f
+	nop
+
+/* un relocated start address of monitor */
+#define TEXT_START _text
+
+/* un relocated end address of monitor */
+#define DATA_END __init_end
+
+reloc:
+	set	TEXT_START,%g2
+	set	DATA_END,%g3
+	set	CFG_RELOC_MONITOR_BASE,%g4
+reloc_loop:
+	ldd	[%g2],%l0
+	ldd	[%g2+8],%l2
+	std	%l0,[%g4]
+	std	%l2,[%g4+8]
+	inc	16,%g2
+	subcc	%g3,%g2,%g0
+	bne	reloc_loop
+	inc	16,%g4
+
+	clr	%l0
+	clr	%l1
+	clr	%l2
+	clr	%l3
+	clr	%g2
+
+/* register g4 contain address to start
+ * This means that BSS must be directly after data and code segments
+ *
+ * g3 is length of bss = (__bss_end-__bss_start)
+ *
+ */
+
+clr_bss:
+/* clear bss area (the relocated) */
+	set	__bss_start,%g2
+	set	__bss_end,%g3
+	sub	%g3,%g2,%g3
+	add	%g3,%g4,%g3
+	clr	%g1	/* std %g0 uses g0 and g1 */
+/* clearing 16byte a time ==> linker script need to align to 16 byte offset */
+clr_bss_16:
+	std	%g0,[%g4]
+	std	%g0,[%g4+8]
+	inc	16,%g4
+	cmp	%g3,%g4
+	bne	clr_bss_16
+	nop
+
+/* add offsets to GOT table */
+fixup_got:
+	set	__got_start,%g4
+	set	__got_end,%g3
+/*
+ * new got offset = (old GOT-PTR (read with ld) -
+ *   CFG_RELOC_MONITOR_BASE(from define) ) +
+ *   Destination Address (from define)
+ */
+	set	CFG_RELOC_MONITOR_BASE,%g2
+	set	TEXT_START, %g1
+	add	%g4,%g2,%g4
+	sub	%g4,%g1,%g4
+	add	%g3,%g2,%g3
+	sub	%g3,%g1,%g3
+	sub	%g2,%g1,%g2	! prepare register with (new base address) -
+				!  (old base address)
+got_loop:
+	ld	[%g4],%l0	! load old GOT-PTR
+	add	%l0,%g2,%l0	! increase with (new base address) -
+				!  (old base)
+	st	%l0,[%g4]
+	inc	4,%g4
+	cmp	%g3,%g4
+	bne	got_loop
+	nop
+
+prom_relocate:
+	set	__prom_start, %g2
+	set	__prom_end, %g3
+	set	CFG_PROM_OFFSET, %g4
+
+prom_relocate_loop:
+	ldd	[%g2],%l0
+	ldd	[%g2+8],%l2
+	std	%l0,[%g4]
+	std	%l2,[%g4+8]
+	inc	16,%g2
+	subcc	%g3,%g2,%g0
+	bne	prom_relocate_loop
+	inc	16,%g4
+
+/* Trap table has been moved, lets tell CPU about
+ * the new trap table address
+ */
+
+	set	CFG_RELOC_MONITOR_BASE, %g2
+	wr	%g0, %g2, %tbr
+
+/*	call	relocate*/
+	nop
+/* Call relocated init functions */
+jump:
+	set	cpu_init_f2,%o1
+	set	CFG_RELOC_MONITOR_BASE,%o2
+	add	%o1,%o2,%o1
+	sub	%o1,%g1,%o1
+	call	%o1
+	clr	%o0
+
+	set	board_init_f,%o1
+	set	CFG_RELOC_MONITOR_BASE,%o2
+	add	%o1,%o2,%o1
+	sub	%o1,%g1,%o1
+	call	%o1
+	clr	%o0
+
+dead:	ta 0				! if call returns...
+	nop
+
+/* Interrupt handler caller,
+ * reg L7: interrupt number
+ * reg L0: psr after interrupt
+ * reg L1: PC
+ * reg L2: next PC
+ * reg L3: wim
+ */
+_irq_entry:
+	SAVE_ALL
+
+	or	%l0, PSR_PIL, %g2
+	wr	%g2, 0x0, %psr
+	WRITE_PAUSE
+	wr	%g2, PSR_ET, %psr
+	WRITE_PAUSE
+	mov	%l7, %o0		! irq level
+	set	handler_irq, %o1
+	set	(CFG_RELOC_MONITOR_BASE-TEXT_BASE), %o2
+	add	%o1, %o2, %o1
+	call	%o1
+	add	%sp, SF_REGS_SZ, %o1	! pt_regs ptr
+	or	%l0, PSR_PIL, %g2	! restore PIL after handler_irq
+	wr	%g2, PSR_ET, %psr	! keep ET up
+	WRITE_PAUSE
+
+	RESTORE_ALL
+
+!Window overflow trap handler.
+	.global _window_overflow
+
+_window_overflow:
+
+	mov	%wim, %l3		! Calculate next WIM
+	mov	%g1, %l7
+	srl	%l3, 1, %g1
+	sll	%l3, (CFG_SPARC_NWINDOWS-1) , %l4
+	or	%l4, %g1, %g1
+
+	save				! Get into window to be saved.
+	mov	%g1, %wim
+	nop;
+	nop;
+	nop
+	st	%l0, [%sp + 0];
+	st	%l1, [%sp + 4];
+	st	%l2, [%sp + 8];
+	st	%l3, [%sp + 12];
+	st	%l4, [%sp + 16];
+	st	%l5, [%sp + 20];
+	st	%l6, [%sp + 24];
+	st	%l7, [%sp + 28];
+	st	%i0, [%sp + 32];
+	st	%i1, [%sp + 36];
+	st	%i2, [%sp + 40];
+	st	%i3, [%sp + 44];
+	st	%i4, [%sp + 48];
+	st	%i5, [%sp + 52];
+	st	%i6, [%sp + 56];
+	st	%i7, [%sp + 60];
+	restore				! Go back to trap window.
+	mov	%l7, %g1
+	jmp	%l1			! Re-execute save.
+	rett	%l2
+
+/* Window underflow trap handler.  */
+
+	.global  _window_underflow
+
+_window_underflow:
+
+	mov  %wim, %l3			! Calculate next WIM
+	sll  %l3, 1, %l4
+	srl  %l3, (CFG_SPARC_NWINDOWS-1), %l5
+	or   %l5, %l4, %l5
+	mov  %l5, %wim
+	nop; nop; nop
+	restore				! Two restores to get into the
+	restore				! window to restore
+	ld	[%sp + 0], %l0; 	! Restore window from the stack
+	ld	[%sp + 4], %l1;
+	ld	[%sp + 8], %l2;
+	ld	[%sp + 12], %l3;
+	ld	[%sp + 16], %l4;
+	ld	[%sp + 20], %l5;
+	ld	[%sp + 24], %l6;
+	ld	[%sp + 28], %l7;
+	ld	[%sp + 32], %i0;
+	ld	[%sp + 36], %i1;
+	ld	[%sp + 40], %i2;
+	ld	[%sp + 44], %i3;
+	ld	[%sp + 48], %i4;
+	ld	[%sp + 52], %i5;
+	ld	[%sp + 56], %i6;
+	ld	[%sp + 60], %i7;
+	save				! Get back to the trap window.
+	save
+	jmp	%l1			! Re-execute restore.
+	rett	%l2
+
+	retl
+
+_nmi_trap:
+	nop
+	jmp %l1
+	rett %l2
+
+_hwerr:
+	ta 0
+	nop
+	nop
+	b _hwerr 			! loop infinite
+	nop
+
+/* Registers to not touch at all. */
+#define t_psr      l0 /* Set by caller */
+#define t_pc       l1 /* Set by caller */
+#define t_npc      l2 /* Set by caller */
+#define t_wim      l3 /* Set by caller */
+#define t_twinmask l4 /* Set at beginning of this entry routine. */
+#define t_kstack   l5 /* Set right before pt_regs frame is built */
+#define t_retpc    l6 /* If you change this, change winmacro.h header file */
+#define t_systable l7 /* Never touch this, could be the syscall table ptr. */
+#define curptr     g6 /* Set after pt_regs frame is built */
+
+trap_setup:
+/* build a pt_regs trap frame. */
+	sub	%fp, (SF_REGS_SZ + PT_REGS_SZ), %t_kstack
+	PT_STORE_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
+
+	/* See if we are in the trap window. */
+	mov	1, %t_twinmask
+	sll	%t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
+	andcc	%t_twinmask, %t_wim, %g0
+	beq	1f		! in trap window, clean up
+	nop
+
+	/*-------------------------------------------------
+	 * Spill , adjust %wim and go.
+	 */
+	srl	%t_wim, 0x1, %g2		! begin computation of new %wim
+
+	set	(CFG_SPARC_NWINDOWS-1), %g3	!NWINDOWS-1
+
+	sll	%t_wim, %g3, %t_wim	! NWINDOWS-1
+	or	%t_wim, %g2, %g2
+	and	%g2, 0xff, %g2
+
+	save	%g0, %g0, %g0           ! get in window to be saved
+
+	/* Set new %wim value */
+	wr	%g2, 0x0, %wim
+
+	/* Save the kernel window onto the corresponding stack. */
+	RW_STORE(sp)
+
+	restore	%g0, %g0, %g0
+	/*-------------------------------------------------*/
+
+1:
+	/* Trap from kernel with a window available.
+	 * Just do it...
+	 */
+	jmpl	%t_retpc + 0x8, %g0	! return to caller
+	 mov	%t_kstack, %sp		! jump onto new stack
+
+#define twin_tmp1 l4
+#define glob_tmp  g4
+#define curptr    g6
+ret_trap_entry:
+	wr	%t_psr, 0x0, %psr       ! enable nesting again, clear ET
+
+	/* Will the rett land us in the invalid window? */
+	mov	2, %g1
+	sll	%g1, %t_psr, %g1
+
+	set	CFG_SPARC_NWINDOWS, %g2	!NWINDOWS
+
+	srl	%g1, %g2, %g2
+	or	%g1, %g2, %g1
+	rd	%wim, %g2
+	andcc	%g2, %g1, %g0
+	be	1f		! Nope, just return from the trap
+	 sll	%g2, 0x1, %g1
+
+	/* We have to grab a window before returning. */
+	set	(CFG_SPARC_NWINDOWS-1), %g3	!NWINDOWS-1
+
+	srl	%g2, %g3,  %g2
+	or	%g1, %g2, %g1
+	and	%g1, 0xff, %g1
+
+	wr	%g1, 0x0, %wim
+
+	/* Grrr, make sure we load from the right %sp... */
+	PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
+
+	restore	%g0, %g0, %g0
+	RW_LOAD(sp)
+	b	2f
+	save	%g0, %g0, %g0
+
+	/* Reload the entire frame in case this is from a
+	 * kernel system call or whatever...
+	 */
+1:
+	PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
+2:
+	wr	%t_psr, 0x0, %psr
+	nop;
+	nop;
+	nop
+
+	jmp	%t_pc
+	rett	%t_npc
+
+/* This is called from relocated C-code.
+ * It resets the system by jumping to _start
+ */
+_reset_reloc:
+	set	start, %l0
+	call	%l0
+	nop
diff --git a/cpu/leon3/Makefile b/cpu/leon3/Makefile
new file mode 100644
index 0000000..182543d
--- /dev/null
+++ b/cpu/leon3/Makefile
@@ -0,0 +1,54 @@
+#
+# (C) Copyright 2003-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(CPU).a
+
+START	= start.o
+SOBJS	=
+COBJS	= cpu_init.o serial.o cpu.o ambapp.o interrupts.o prom.o usb_uhci.o
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+$(START): $(START:.o=.S)
+	$(CC) -D__ASSEMBLY__ $(DBGFLAGS) $(OPTFLAGS) -D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) \
+	-I$(TOPDIR)/include -fno-builtin -ffreestanding -nostdinc -isystem $(gccincdir) -pipe \
+	$(PLATFORM_CPPFLAGS) -Wall -Wstrict-prototypes \
+	-I$(TOPDIR)/board -c -o $(START) $(START:.o=.S)
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/leon3/ambapp.c b/cpu/leon3/ambapp.c
new file mode 100644
index 0000000..efd41ae
--- /dev/null
+++ b/cpu/leon3/ambapp.c
@@ -0,0 +1,359 @@
+/* Gaisler AMBA Plug&Play bus scanning. Functions
+ * ending on _nomem is inteded to be used only during
+ * initialization, only registers are used (no ram).
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ *
+ * 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 <command.h>
+#include <ambapp.h>
+
+#if defined(CONFIG_CMD_AMBAPP)
+extern void ambapp_print_apb(apbctrl_pp_dev * apb,
+			     ambapp_ahbdev * apbmst, int index);
+extern void ambapp_print_ahb(ahbctrl_pp_dev * ahb, int index);
+extern int ambapp_apb_print;
+extern int ambapp_ahb_print;
+#endif
+
+static int ambapp_apb_scan(unsigned int vendor,	/* Plug&Play Vendor ID */
+			   unsigned int driver,	/* Plug&Play Device ID */
+			   ambapp_apbdev * dev,	/* Result(s) is placed here */
+			   int index,	/* Index of device to start copying Plug&Play
+					 * info into dev
+					 */
+			   int max_cnt	/* Maximal count that dev can hold, if dev
+					 * is NULL function will stop scanning after
+					 * max_cnt devices are found.
+					 */
+    )
+{
+	int i, cnt = 0;
+	unsigned int apbmst_base;
+	ambapp_ahbdev apbmst;
+	apbctrl_pp_dev *apb;
+
+	if (max_cnt == 0)
+		return 0;
+
+	/* Get AMBA APB Master */
+	if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_APBMST, &apbmst) != 1) {
+		return 0;
+	}
+
+	/* Get APB CTRL Plug&Play info area */
+	apbmst_base = apbmst.address[0] & LEON3_IO_AREA;
+	apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
+
+	for (i = 0; i < LEON3_APB_SLAVES; i++) {
+#if defined(CONFIG_CMD_AMBAPP)
+		if (ambapp_apb_print && amba_vendor(apb->conf)
+		    && amba_device(apb->conf)) {
+			ambapp_print_apb(apb, &apbmst, i);
+		}
+#endif
+		if ((amba_vendor(apb->conf) == vendor) &&
+		    (amba_device(apb->conf) == driver) && ((index < 0)
+							   || (index-- == 0))) {
+			/* Convert Plug&Play info into a more readable format */
+			cnt++;
+			if (dev) {
+				dev->irq = amba_irq(apb->conf);
+				dev->ver = amba_ver(apb->conf);
+				dev->address =
+				    (apbmst_base |
+				     (((apb->
+					bar & 0xfff00000) >> 12))) & (((apb->
+									bar &
+									0x0000fff0)
+								       << 4) |
+								      0xfff00000);
+				dev++;
+			}
+			/* found max devices? */
+			if (cnt >= max_cnt)
+				return cnt;
+		}
+		/* Get next Plug&Play entry */
+		apb++;
+	}
+	return cnt;
+}
+
+unsigned int ambapp_apb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
+				   register unsigned int driver,	/* Plug&Play Device ID */
+				   register int index)
+{
+	register int i;
+	register ahbctrl_pp_dev *apbmst;
+	register apbctrl_pp_dev *apb;
+	register unsigned int apbmst_base;
+
+	/* APBMST is a AHB Slave */
+	apbmst = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
+	if (!apbmst)
+		return 0;
+
+	apbmst_base = amba_membar_start(apbmst->bars[0]);
+	if (amba_membar_type(apbmst->bars[0]) == AMBA_TYPE_AHBIO)
+		apbmst_base = AMBA_TYPE_AHBIO_ADDR(apbmst_base);
+	apbmst_base &= LEON3_IO_AREA;
+
+	/* Find the vendor/driver device on the first APB bus */
+	apb = (apbctrl_pp_dev *) (apbmst_base | LEON3_CONF_AREA);
+
+	for (i = 0; i < LEON3_APB_SLAVES; i++) {
+		if ((amba_vendor(apb->conf) == vendor) &&
+		    (amba_device(apb->conf) == driver) && ((index < 0)
+							   || (index-- == 0))) {
+			/* Convert Plug&Play info info a more readable format */
+			return (apbmst_base | (((apb->bar & 0xfff00000) >> 12)))
+			    & (((apb->bar & 0x0000fff0) << 4) | 0xfff00000);
+		}
+		/* Get next Plug&Play entry */
+		apb++;
+	}
+	return 0;
+}
+
+/****************************** APB SLAVES ******************************/
+
+int ambapp_apb_count(unsigned int vendor, unsigned int driver)
+{
+	return ambapp_apb_scan(vendor, driver, NULL, 0, LEON3_APB_SLAVES);
+}
+
+int ambapp_apb_first(unsigned int vendor,
+		     unsigned int driver, ambapp_apbdev * dev)
+{
+	return ambapp_apb_scan(vendor, driver, dev, 0, 1);
+}
+
+int ambapp_apb_next(unsigned int vendor,
+		    unsigned int driver, ambapp_apbdev * dev, int index)
+{
+	return ambapp_apb_scan(vendor, driver, dev, index, 1);
+}
+
+int ambapp_apbs_first(unsigned int vendor,
+		      unsigned int driver, ambapp_apbdev * dev, int max_cnt)
+{
+	return ambapp_apb_scan(vendor, driver, dev, 0, max_cnt);
+}
+
+enum {
+	AHB_SCAN_MASTER = 0,
+	AHB_SCAN_SLAVE = 1
+};
+
+/* Scan AMBA Plug&Play bus for AMBA AHB Masters or AHB Slaves
+ * for a certain matching Vendor and Device ID.
+ *
+ * Return number of devices found.
+ *
+ * Compact edition...
+ */
+static int ambapp_ahb_scan(unsigned int vendor,	/* Plug&Play Vendor ID */
+			   unsigned int driver,	/* Plug&Play Device ID */
+			   ambapp_ahbdev * dev,	/* Result(s) is placed here */
+			   int index,	/* Index of device to start copying Plug&Play
+					 * info into dev
+					 */
+			   int max_cnt,	/* Maximal count that dev can hold, if dev
+					 * is NULL function will stop scanning after
+					 * max_cnt devices are found.
+					 */
+			   int type	/* Selectes what type of devices to scan.
+					 * 0=AHB Masters
+					 * 1=AHB Slaves
+					 */
+    )
+{
+	int i, j, cnt = 0, max_pp_devs;
+	unsigned int addr;
+	ahbctrl_info *info = (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
+	ahbctrl_pp_dev *ahb;
+
+	if (max_cnt == 0)
+		return 0;
+
+	if (type == 0) {
+		max_pp_devs = LEON3_AHB_MASTERS;
+		ahb = info->masters;
+	} else {
+		max_pp_devs = LEON3_AHB_SLAVES;
+		ahb = info->slaves;
+	}
+
+	for (i = 0; i < max_pp_devs; i++) {
+#if defined(CONFIG_CMD_AMBAPP)
+		if (ambapp_ahb_print && amba_vendor(ahb->conf) &&
+		    amba_device(ahb->conf)) {
+			ambapp_print_ahb(ahb, i);
+		}
+#endif
+		if ((amba_vendor(ahb->conf) == vendor) &&
+		    (amba_device(ahb->conf) == driver) &&
+		    ((index < 0) || (index-- == 0))) {
+			/* Convert Plug&Play info info a more readable format */
+			cnt++;
+			if (dev) {
+				dev->irq = amba_irq(ahb->conf);
+				dev->ver = amba_ver(ahb->conf);
+				dev->userdef[0] = ahb->userdef[0];
+				dev->userdef[1] = ahb->userdef[1];
+				dev->userdef[2] = ahb->userdef[2];
+				for (j = 0; j < 4; j++) {
+					addr = amba_membar_start(ahb->bars[j]);
+					if (amba_membar_type(ahb->bars[j]) ==
+					    AMBA_TYPE_AHBIO)
+						addr =
+						    AMBA_TYPE_AHBIO_ADDR(addr);
+					dev->address[j] = addr;
+				}
+				dev++;
+			}
+			/* found max devices? */
+			if (cnt >= max_cnt)
+				return cnt;
+		}
+		/* Get next Plug&Play entry */
+		ahb++;
+	}
+	return cnt;
+}
+
+unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info)
+{
+	register unsigned int ret;
+
+	if (!ahb)
+		return 0;
+
+	switch (info) {
+	default:
+		info = 0;
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+		/* Get Address from PnP Info */
+		ret = amba_membar_start(ahb->bars[info]);
+		if (amba_membar_type(ahb->bars[info]) == AMBA_TYPE_AHBIO)
+			ret = AMBA_TYPE_AHBIO_ADDR(ret);
+		return ret;
+	}
+	return 0;
+
+}
+
+ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
+				      register unsigned int driver,	/* Plug&Play Device ID */
+				      register unsigned int opts,	/* 1=slave, 0=master */
+				      register int index)
+{
+	register ahbctrl_pp_dev *ahb;
+	register ahbctrl_info *info =
+	    (ahbctrl_info *) (LEON3_IO_AREA | LEON3_CONF_AREA);
+	register int i;
+	register int max_pp_devs;
+
+	if (opts == 0) {
+		max_pp_devs = LEON3_AHB_MASTERS;
+		ahb = info->masters;
+	} else {
+		max_pp_devs = LEON3_AHB_SLAVES;
+		ahb = info->slaves;
+	}
+
+	for (i = 0; i < max_pp_devs; i++) {
+		if ((amba_vendor(ahb->conf) == vendor) &&
+		    (amba_device(ahb->conf) == driver) &&
+		    ((index < 0) || (index-- == 0))) {
+			/* Convert Plug&Play info info a more readable format */
+			return ahb;
+		}
+		/* Get next Plug&Play entry */
+		ahb++;
+	}
+	return 0;
+}
+
+/****************************** AHB MASTERS ******************************/
+int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver)
+{
+	/* Get number of devices of this vendor&device ID */
+	return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_MASTERS,
+			       AHB_SCAN_MASTER);
+}
+
+int ambapp_ahbmst_first(unsigned int vendor, unsigned int driver,
+			ambapp_ahbdev * dev)
+{
+	/* find first device of this */
+	return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_MASTER);
+}
+
+int ambapp_ahbmst_next(unsigned int vendor,
+		       unsigned int driver, ambapp_ahbdev * dev, int index)
+{
+	/* find first device of this */
+	return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_MASTER);
+}
+
+int ambapp_ahbmsts_first(unsigned int vendor,
+			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
+{
+	/* find first device of this */
+	return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt,
+			       AHB_SCAN_MASTER);
+}
+
+/****************************** AHB SLAVES ******************************/
+int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver)
+{
+	/* Get number of devices of this vendor&device ID */
+	return ambapp_ahb_scan(vendor, driver, NULL, 0, LEON3_AHB_SLAVES,
+			       AHB_SCAN_SLAVE);
+}
+
+int ambapp_ahbslv_first(unsigned int vendor, unsigned int driver,
+			ambapp_ahbdev * dev)
+{
+	/* find first device of this */
+	return ambapp_ahb_scan(vendor, driver, dev, 0, 1, AHB_SCAN_SLAVE);
+}
+
+int ambapp_ahbslv_next(unsigned int vendor,
+		       unsigned int driver, ambapp_ahbdev * dev, int index)
+{
+	/* find first device of this */
+	return ambapp_ahb_scan(vendor, driver, dev, index, 1, AHB_SCAN_SLAVE);
+}
+
+int ambapp_ahbslvs_first(unsigned int vendor,
+			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt)
+{
+	/* find first device of this */
+	return ambapp_ahb_scan(vendor, driver, dev, 0, max_cnt, AHB_SCAN_SLAVE);
+}
diff --git a/cpu/leon3/config.mk b/cpu/leon3/config.mk
new file mode 100644
index 0000000..30b224a
--- /dev/null
+++ b/cpu/leon3/config.mk
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2003
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+PLATFORM_RELFLAGS += -fPIC
+
+PLATFORM_CPPFLAGS += -DCONFIG_LEON
diff --git a/cpu/leon3/cpu.c b/cpu/leon3/cpu.c
new file mode 100644
index 0000000..306a210
--- /dev/null
+++ b/cpu/leon3/cpu.c
@@ -0,0 +1,67 @@
+/* CPU specific code for the LEON3 CPU
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ *
+ * 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 <watchdog.h>
+#include <command.h>
+
+#include <asm/io.h>
+#include <asm/processor.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern void _reset_reloc(void);
+
+int checkcpu(void)
+{
+	/* check LEON version here */
+	printf("CPU: LEON3\n");
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+void cpu_reset(void)
+{
+	/* Interrupts off */
+	disable_interrupts();
+
+	/* jump to restart in flash */
+	_reset_reloc();
+}
+
+int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	cpu_reset();
+
+	return 1;
+
+}
+
+u64 flash_read64(void *addr)
+{
+	return __raw_readq(addr);
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/cpu/leon3/cpu_init.c b/cpu/leon3/cpu_init.c
new file mode 100644
index 0000000..4fe7d4b
--- /dev/null
+++ b/cpu/leon3/cpu_init.c
@@ -0,0 +1,254 @@
+/* Initializes CPU and basic hardware such as memory
+ * controllers, IRQ controller and system timer 0.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ *
+ * 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/asi.h>
+#include <asm/leon.h>
+#include <ambapp.h>
+
+#include <config.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* reset CPU (jump to 0, without reset) */
+void start(void);
+
+/* find & initialize the memory controller */
+int init_memory_ctrl(void);
+
+ambapp_dev_irqmp *irqmp = NULL;
+ambapp_dev_mctrl memctrl;
+ambapp_dev_gptimer *gptimer = NULL;
+unsigned int gptimer_irq = 0;
+int leon3_snooping_avail = 0;
+
+struct {
+	gd_t gd_area;
+	bd_t bd;
+} global_data;
+
+/*
+ * Breath some life into the CPU...
+ *
+ * Set up the memory map,
+ * initialize a bunch of registers.
+ *
+ * Run from FLASH/PROM:
+ *  - until memory controller is set up, only registers avaiable
+ *  - no global variables available for writing
+ *  - constants avaiable
+ */
+
+void cpu_init_f(void)
+{
+	/* these varaiable must not be initialized */
+	ambapp_dev_irqmp *irqmp;
+	ambapp_apbdev apbdev;
+	register unsigned int apbmst;
+
+	/* find AMBA APB Master */
+	apbmst = (unsigned int)
+	    ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_APBMST, 1, 0);
+	if (!apbmst) {
+		/*
+		 * no AHB/APB bridge, something is wrong
+		 * ==> jump to start (or hang)
+		 */
+		while (1) ;
+	}
+	/* Init memory controller */
+	if (init_memory_ctrl()) {
+		while (1) ;
+	}
+
+	/****************************************************
+	 * From here we can use the main memory and the stack.
+	 */
+
+	/* Find AMBA APB IRQMP Controller */
+	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev) != 1) {
+		/* no IRQ controller, something is wrong
+		 * ==> jump to start (or hang)
+		 */
+		while (1) ;
+	}
+	irqmp = (ambapp_dev_irqmp *) apbdev.address;
+
+	/* initialize the IRQMP */
+	irqmp->ilevel = 0xf;	/* all IRQ off */
+	irqmp->iforce = 0;
+	irqmp->ipend = 0;
+	irqmp->iclear = 0xfffe;	/* clear all old pending interrupts */
+	irqmp->cpu_mask[0] = 0;	/* mask all IRQs on CPU 0 */
+	irqmp->cpu_force[0] = 0;	/* no force IRQ on CPU 0 */
+
+	/* cache */
+}
+
+void cpu_init_f2(void)
+{
+
+}
+
+/*
+ * initialize higher level parts of CPU like time base and timers
+ */
+int cpu_init_r(void)
+{
+	ambapp_apbdev apbdev;
+
+	/*
+	 * Find AMBA APB IRQMP Controller,
+	 * When we come so far we know there is a IRQMP available
+	 */
+	ambapp_apb_first(VENDOR_GAISLER, GAISLER_IRQMP, &apbdev);
+	irqmp = (ambapp_dev_irqmp *) apbdev.address;
+
+	/* timer */
+	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_GPTIMER, &apbdev) != 1) {
+		printf("cpu_init_r: gptimer not found!\n");
+		return 1;
+	}
+	gptimer = (ambapp_dev_gptimer *) apbdev.address;
+	gptimer_irq = apbdev.irq;
+
+	/* initialize prescaler common to all timers to 1MHz */
+	gptimer->scalar = gptimer->scalar_reload =
+	    (((CONFIG_SYS_CLK_FREQ / 1000) + 500) / 1000) - 1;
+
+	return (0);
+}
+
+/* find & setup memory controller */
+int init_memory_ctrl()
+{
+	register ambapp_dev_mctrl *mctrl;
+	register ambapp_dev_sdctrl *sdctrl;
+	register ambapp_dev_ddrspa *ddrspa;
+	register ambapp_dev_ddr2spa *ddr2spa;
+	register ahbctrl_pp_dev *ahb;
+	register unsigned int base;
+	register int not_found_mctrl = -1;
+
+	/* find ESA Memory controller */
+	base = ambapp_apb_next_nomem(VENDOR_ESA, ESA_MCTRL, 0);
+	if (base) {
+		mctrl = (ambapp_dev_mctrl *) base;
+
+		/* config MCTRL memory controller */
+		mctrl->mcfg1 = CFG_GRLIB_MEMCFG1 | (mctrl->mcfg1 & 0x300);
+		mctrl->mcfg2 = CFG_GRLIB_MEMCFG2;
+		mctrl->mcfg3 = CFG_GRLIB_MEMCFG3;
+		not_found_mctrl = 0;
+	}
+
+	/* find Gaisler Fault Tolerant Memory controller */
+	base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_FTMCTRL, 0);
+	if (base) {
+		mctrl = (ambapp_dev_mctrl *) base;
+
+		/* config MCTRL memory controller */
+		mctrl->mcfg1 = CFG_GRLIB_FT_MEMCFG1 | (mctrl->mcfg1 & 0x300);
+		mctrl->mcfg2 = CFG_GRLIB_FT_MEMCFG2;
+		mctrl->mcfg3 = CFG_GRLIB_FT_MEMCFG3;
+		not_found_mctrl = 0;
+	}
+
+	/* find SDRAM controller */
+	base = ambapp_apb_next_nomem(VENDOR_GAISLER, GAISLER_SDCTRL, 0);
+	if (base) {
+		sdctrl = (ambapp_dev_sdctrl *) base;
+
+		/* config memory controller */
+		sdctrl->sdcfg = CFG_GRLIB_SDRAM;
+		not_found_mctrl = 0;
+	}
+
+	ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDR2SPA, 1, 0);
+	if (ahb) {
+		ddr2spa = (ambapp_dev_ddr2spa *) ambapp_ahb_get_info(ahb, 1);
+
+		/* Config DDR2 memory controller */
+		ddr2spa->cfg1 = CFG_GRLIB_DDR2_CFG1;
+		ddr2spa->cfg3 = CFG_GRLIB_DDR2_CFG3;
+		not_found_mctrl = 0;
+	}
+
+	ahb = ambapp_ahb_next_nomem(VENDOR_GAISLER, GAISLER_DDRSPA, 1, 0);
+	if (ahb) {
+		ddrspa = (ambapp_dev_ddrspa *) ambapp_ahb_get_info(ahb, 1);
+
+		/* Config DDR memory controller */
+		ddrspa->ctrl = CFG_GRLIB_DDR_CFG;
+		not_found_mctrl = 0;
+	}
+
+	/* failed to find any memory controller */
+	return not_found_mctrl;
+}
+
+/* Uses Timer 0 to get accurate
+ * pauses. Max 2 raised to 32 ticks
+ *
+ */
+void cpu_wait_ticks(unsigned long ticks)
+{
+	unsigned long start = get_timer(0);
+	while (get_timer(start) < ticks) ;
+}
+
+/* initiate and setup timer0 interrupt to 1MHz
+ * Return irq number for timer int or a negative number for
+ * dealing with self
+ */
+int timer_interrupt_init_cpu(void)
+{
+	/* 1ms ticks */
+	gptimer->e[0].val = 0;
+	gptimer->e[0].rld = 999;	/* (((1000000 / 100) - 1)) */
+	gptimer->e[0].ctrl =
+	    (LEON3_GPTIMER_EN |
+	     LEON3_GPTIMER_RL | LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
+
+	return gptimer_irq;
+}
+
+/*
+ * This function is intended for SHORT delays only.
+ */
+unsigned long cpu_usec2ticks(unsigned long usec)
+{
+	/* timer set to 1kHz ==> 1 clk tick = 1 msec */
+	if (usec < 1000)
+		return 1;
+	return (usec / 1000);
+}
+
+unsigned long cpu_ticks2usec(unsigned long ticks)
+{
+	/* 1tick = 1usec */
+	return ticks * 1000;
+}
diff --git a/cpu/leon3/interrupts.c b/cpu/leon3/interrupts.c
new file mode 100644
index 0000000..2692632
--- /dev/null
+++ b/cpu/leon3/interrupts.c
@@ -0,0 +1,219 @@
+/*
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ *
+ * (C) Copyright 2006
+ * Detlev Zundel, DENX Software Engineering, dzu@denx.de
+ *
+ * (C) Copyright -2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001
+ * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
+ *
+ * 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/stack.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <command.h>
+#include <asm/irq.h>
+
+#include <asm/leon.h>
+#include <ambapp.h>
+
+/* 15 normal irqs and a non maskable interrupt */
+#define NR_IRQS 15
+
+struct irq_action {
+	interrupt_handler_t *handler;
+	void *arg;
+	unsigned int count;
+};
+
+extern ambapp_dev_irqmp *irqmp;
+extern ambapp_dev_gptimer *gptimer;
+
+static struct irq_action irq_handlers[NR_IRQS] = { {0}, };
+static int spurious_irq_cnt = 0;
+static int spurious_irq = 0;
+
+static inline unsigned int irqmp_get_irqmask(unsigned int irq)
+{
+	if ((irq < 0) || (irq >= NR_IRQS)) {
+		return 0;
+	} else {
+		return (1 << irq);
+	}
+
+}
+
+static void leon3_ic_disable(unsigned int irq)
+{
+	unsigned int mask, pil;
+	if (!irqmp)
+		return;
+
+	pil = intLock();
+
+	/* get mask of interrupt */
+	mask = irqmp_get_irqmask(irq);
+
+	/* set int level */
+	irqmp->cpu_mask[0] = SPARC_NOCACHE_READ(&irqmp->cpu_mask[0]) & (~mask);
+
+	intUnlock(pil);
+}
+
+static void leon3_ic_enable(unsigned int irq)
+{
+	unsigned int mask, pil;
+	if (!irqmp)
+		return;
+
+	pil = intLock();
+
+	/* get mask of interrupt */
+	mask = irqmp_get_irqmask(irq);
+
+	/* set int level */
+	irqmp->cpu_mask[0] = SPARC_NOCACHE_READ(&irqmp->cpu_mask[0]) | mask;
+
+	intUnlock(pil);
+
+}
+
+void handler_irq(int irq, struct pt_regs *regs)
+{
+	if (irq_handlers[irq].handler) {
+		if (((unsigned int)irq_handlers[irq].handler > CFG_RAM_END) ||
+		    ((unsigned int)irq_handlers[irq].handler < CFG_RAM_BASE)
+		    ) {
+			printf("handler_irq: bad handler: %x, irq number %d\n",
+			       (unsigned int)irq_handlers[irq].handler, irq);
+			return;
+		}
+		irq_handlers[irq].handler(irq_handlers[irq].arg);
+		irq_handlers[irq].count++;
+	} else {
+		spurious_irq_cnt++;
+		spurious_irq = irq;
+	}
+}
+
+void leon3_force_int(int irq)
+{
+	if (!irqmp || (irq >= NR_IRQS) || (irq < 0))
+		return;
+	printf("Forcing interrupt %d\n", irq);
+
+	irqmp->iforce = SPARC_NOCACHE_READ(&irqmp->iforce) | (1 << irq);
+}
+
+/****************************************************************************/
+
+int interrupt_init_cpu(void)
+{
+
+	return (0);
+}
+
+/****************************************************************************/
+
+/* Handle Timer 0 IRQ */
+void timer_interrupt_cpu(void *arg)
+{
+	gptimer->e[0].ctrl = (LEON3_GPTIMER_EN |
+			      LEON3_GPTIMER_RL |
+			      LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
+	/* nothing to do here */
+	return;
+}
+
+/****************************************************************************/
+
+/*
+ * Install and free a interrupt handler.
+ */
+
+void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg)
+{
+	if (irq < 0 || irq >= NR_IRQS) {
+		printf("irq_install_handler: bad irq number %d\n", irq);
+		return;
+	}
+
+	if (irq_handlers[irq].handler != NULL)
+		printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
+		       (ulong) handler, (ulong) irq_handlers[irq].handler);
+
+	if (((unsigned int)handler > CFG_RAM_END) ||
+	    ((unsigned int)handler < CFG_RAM_BASE)
+	    ) {
+		printf("irq_install_handler: bad handler: %x, irq number %d\n",
+		       (unsigned int)handler, irq);
+		return;
+	}
+	irq_handlers[irq].handler = handler;
+	irq_handlers[irq].arg = arg;
+
+	/* enable irq on IRQMP hardware */
+	leon3_ic_enable(irq);
+
+}
+
+void irq_free_handler(int irq)
+{
+	if (irq < 0 || irq >= NR_IRQS) {
+		printf("irq_free_handler: bad irq number %d\n", irq);
+		return;
+	}
+
+	/* disable irq on IRQMP hardware */
+	leon3_ic_disable(irq);
+
+	irq_handlers[irq].handler = NULL;
+	irq_handlers[irq].arg = NULL;
+}
+
+/****************************************************************************/
+
+#if defined(CONFIG_CMD_IRQ)
+void do_irqinfo(cmd_tbl_t * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
+{
+	int irq;
+	unsigned int pil = get_pil();
+	printf("PIL level: %u\n\r", pil);
+	printf("Spurious IRQ: %u, last unknown IRQ: %d\n",
+	       spurious_irq_cnt, spurious_irq);
+
+	puts("\nInterrupt-Information:\n" "Nr  Routine   Arg       Count\n");
+
+	for (irq = 0; irq < NR_IRQS; irq++) {
+		if (irq_handlers[irq].handler != NULL) {
+			printf("%02d  %08lx  %08lx  %ld\n", irq,
+			       (unsigned int)irq_handlers[irq].handler,
+			       (unsigned int)irq_handlers[irq].arg,
+			       irq_handlers[irq].count);
+		}
+	}
+}
+#endif
diff --git a/cpu/leon3/prom.c b/cpu/leon3/prom.c
new file mode 100644
index 0000000..9fa2d04
--- /dev/null
+++ b/cpu/leon3/prom.c
@@ -0,0 +1,1078 @@
+/* prom.c - emulates a sparc v0 PROM for the linux kernel.
+ *
+ * Copyright (C) 2003 Konrad Eisele <eiselekd@web.de>
+ * Copyright (C) 2004 Stefan Holst <mail@s-holst.de>
+ * Copyright (C) 2007 Daniel Hellstrom <daniel@gaisler.com>
+ *
+ * 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/prom.h>
+#include <asm/machines.h>
+#include <asm/srmmu.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/leon.h>
+#include <ambapp.h>
+
+#include <config.h>
+/*
+#define PRINT_ROM_VEC
+*/
+extern struct linux_romvec *kernel_arg_promvec;
+extern ambapp_dev_apbuart *leon3_apbuart;
+
+#define PROM_PGT __attribute__ ((__section__ (".prom.pgt")))
+#define PROM_TEXT __attribute__ ((__section__ (".prom.text")))
+#define PROM_DATA __attribute__ ((__section__ (".prom.data")))
+
+ambapp_dev_gptimer *gptimer;
+
+/* for __va */
+extern int __prom_start;
+#define PAGE_OFFSET 0xf0000000
+#define phys_base CFG_SDRAM_BASE
+#define PROM_OFFS 8192
+#define PROM_SIZE_MASK (PROM_OFFS-1)
+#define __va(x) ( \
+	(void *)( ((unsigned long)(x))-PROM_OFFS+ \
+	(CFG_PROM_OFFSET-phys_base)+PAGE_OFFSET-TEXT_BASE ) \
+	)
+#define __phy(x) ((void *)(((unsigned long)(x))-PROM_OFFS+CFG_PROM_OFFSET-TEXT_BASE))
+
+struct property {
+	char *name;
+	char *value;
+	int length;
+};
+
+struct node {
+	int level;
+	struct property *properties;
+};
+
+static void leon_reboot(char *bcommand);
+static void leon_halt(void);
+static int leon_nbputchar(int c);
+static int leon_nbgetchar(void);
+
+static int no_nextnode(int node);
+static int no_child(int node);
+static int no_proplen(int node, char *name);
+static int no_getprop(int node, char *name, char *value);
+static int no_setprop(int node, char *name, char *value, int len);
+static char *no_nextprop(int node, char *name);
+
+static struct property PROM_TEXT *find_property(int node, char *name);
+static int PROM_TEXT leon_strcmp(const char *s1, const char *s2);
+static void *PROM_TEXT leon_memcpy(void *dest, const void *src, size_t n);
+static void PROM_TEXT leon_reboot_physical(char *bcommand);
+
+void __inline__ leon_flush_cache_all(void)
+{
+	__asm__ __volatile__(" flush ");
+      __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"::"i"(ASI_DFLUSH):"memory");
+}
+
+void __inline__ leon_flush_tlb_all(void)
+{
+	leon_flush_cache_all();
+	__asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(0x400),
+			     "i"(ASI_MMUFLUSH):"memory");
+}
+
+typedef struct {
+	unsigned int ctx_table[256];
+	unsigned int pgd_table[256];
+} sparc_srmmu_setup;
+
+sparc_srmmu_setup srmmu_tables PROM_PGT = {
+	{0},
+	{0x1e,
+	 0x10001e,
+	 0x20001e,
+	 0x30001e,
+	 0x40001e,
+	 0x50001e,
+	 0x60001e,
+	 0x70001e,
+	 0x80001e,
+	 0x90001e,
+	 0xa0001e,
+	 0xb0001e,
+	 0xc0001e,
+	 0xd0001e,
+	 0xe0001e,
+	 0xf0001e,
+	 0x100001e,
+	 0x110001e,
+	 0x120001e,
+	 0x130001e,
+	 0x140001e,
+	 0x150001e,
+	 0x160001e,
+	 0x170001e,
+	 0x180001e,
+	 0x190001e,
+	 0x1a0001e,
+	 0x1b0001e,
+	 0x1c0001e,
+	 0x1d0001e,
+	 0x1e0001e,
+	 0x1f0001e,
+	 0x200001e,
+	 0x210001e,
+	 0x220001e,
+	 0x230001e,
+	 0x240001e,
+	 0x250001e,
+	 0x260001e,
+	 0x270001e,
+	 0x280001e,
+	 0x290001e,
+	 0x2a0001e,
+	 0x2b0001e,
+	 0x2c0001e,
+	 0x2d0001e,
+	 0x2e0001e,
+	 0x2f0001e,
+	 0x300001e,
+	 0x310001e,
+	 0x320001e,
+	 0x330001e,
+	 0x340001e,
+	 0x350001e,
+	 0x360001e,
+	 0x370001e,
+	 0x380001e,
+	 0x390001e,
+	 0x3a0001e,
+	 0x3b0001e,
+	 0x3c0001e,
+	 0x3d0001e,
+	 0x3e0001e,
+	 0x3f0001e,
+	 0x400001e,
+	 0x410001e,
+	 0x420001e,
+	 0x430001e,
+	 0x440001e,
+	 0x450001e,
+	 0x460001e,
+	 0x470001e,
+	 0x480001e,
+	 0x490001e,
+	 0x4a0001e,
+	 0x4b0001e,
+	 0x4c0001e,
+	 0x4d0001e,
+	 0x4e0001e,
+	 0x4f0001e,
+	 0x500001e,
+	 0x510001e,
+	 0x520001e,
+	 0x530001e,
+	 0x540001e,
+	 0x550001e,
+	 0x560001e,
+	 0x570001e,
+	 0x580001e,
+	 0x590001e,
+	 0x5a0001e,
+	 0x5b0001e,
+	 0x5c0001e,
+	 0x5d0001e,
+	 0x5e0001e,
+	 0x5f0001e,
+	 0x600001e,
+	 0x610001e,
+	 0x620001e,
+	 0x630001e,
+	 0x640001e,
+	 0x650001e,
+	 0x660001e,
+	 0x670001e,
+	 0x680001e,
+	 0x690001e,
+	 0x6a0001e,
+	 0x6b0001e,
+	 0x6c0001e,
+	 0x6d0001e,
+	 0x6e0001e,
+	 0x6f0001e,
+	 0x700001e,
+	 0x710001e,
+	 0x720001e,
+	 0x730001e,
+	 0x740001e,
+	 0x750001e,
+	 0x760001e,
+	 0x770001e,
+	 0x780001e,
+	 0x790001e,
+	 0x7a0001e,
+	 0x7b0001e,
+	 0x7c0001e,
+	 0x7d0001e,
+	 0x7e0001e,
+	 0x7f0001e,
+	 0x800001e,
+	 0x810001e,
+	 0x820001e,
+	 0x830001e,
+	 0x840001e,
+	 0x850001e,
+	 0x860001e,
+	 0x870001e,
+	 0x880001e,
+	 0x890001e,
+	 0x8a0001e,
+	 0x8b0001e,
+	 0x8c0001e,
+	 0x8d0001e,
+	 0x8e0001e,
+	 0x8f0001e,
+	 0x900001e,
+	 0x910001e,
+	 0x920001e,
+	 0x930001e,
+	 0x940001e,
+	 0x950001e,
+	 0x960001e,
+	 0x970001e,
+	 0x980001e,
+	 0x990001e,
+	 0x9a0001e,
+	 0x9b0001e,
+	 0x9c0001e,
+	 0x9d0001e,
+	 0x9e0001e,
+	 0x9f0001e,
+	 0xa00001e,
+	 0xa10001e,
+	 0xa20001e,
+	 0xa30001e,
+	 0xa40001e,
+	 0xa50001e,
+	 0xa60001e,
+	 0xa70001e,
+	 0xa80001e,
+	 0xa90001e,
+	 0xaa0001e,
+	 0xab0001e,
+	 0xac0001e,
+	 0xad0001e,
+	 0xae0001e,
+	 0xaf0001e,
+	 0xb00001e,
+	 0xb10001e,
+	 0xb20001e,
+	 0xb30001e,
+	 0xb40001e,
+	 0xb50001e,
+	 0xb60001e,
+	 0xb70001e,
+	 0xb80001e,
+	 0xb90001e,
+	 0xba0001e,
+	 0xbb0001e,
+	 0xbc0001e,
+	 0xbd0001e,
+	 0xbe0001e,
+	 0xbf0001e,
+	 0xc00001e,
+	 0xc10001e,
+	 0xc20001e,
+	 0xc30001e,
+	 0xc40001e,
+	 0xc50001e,
+	 0xc60001e,
+	 0xc70001e,
+	 0xc80001e,
+	 0xc90001e,
+	 0xca0001e,
+	 0xcb0001e,
+	 0xcc0001e,
+	 0xcd0001e,
+	 0xce0001e,
+	 0xcf0001e,
+	 0xd00001e,
+	 0xd10001e,
+	 0xd20001e,
+	 0xd30001e,
+	 0xd40001e,
+	 0xd50001e,
+	 0xd60001e,
+	 0xd70001e,
+	 0xd80001e,
+	 0xd90001e,
+	 0xda0001e,
+	 0xdb0001e,
+	 0xdc0001e,
+	 0xdd0001e,
+	 0xde0001e,
+	 0xdf0001e,
+	 0xe00001e,
+	 0xe10001e,
+	 0xe20001e,
+	 0xe30001e,
+	 0xe40001e,
+	 0xe50001e,
+	 0xe60001e,
+	 0xe70001e,
+	 0xe80001e,
+	 0xe90001e,
+	 0xea0001e,
+	 0xeb0001e,
+	 0xec0001e,
+	 0xed0001e,
+	 0xee0001e,
+	 0xef0001e,
+	 0x400001e		/* default */
+	 }
+};
+
+/* a self contained prom info structure */
+struct leon_reloc_func {
+	struct property *(*find_property) (int node, char *name);
+	int (*strcmp) (char *s1, char *s2);
+	void *(*memcpy) (void *dest, const void *src, size_t n);
+	void (*reboot_physical) (char *cmd);
+	ambapp_dev_apbuart *leon3_apbuart;
+};
+
+struct leon_prom_info {
+	int freq_khz;
+	int leon_nctx;
+	int mids[32];
+	int baudrates[2];
+	struct leon_reloc_func reloc_funcs;
+	struct property root_properties[4];
+	struct property cpu_properties[7];
+#undef  CPUENTRY
+#define CPUENTRY(idx) struct property cpu_properties##idx[4]
+	 CPUENTRY(1);
+	 CPUENTRY(2);
+	 CPUENTRY(3);
+	 CPUENTRY(4);
+	 CPUENTRY(5);
+	 CPUENTRY(6);
+	 CPUENTRY(7);
+	 CPUENTRY(8);
+	 CPUENTRY(9);
+	 CPUENTRY(10);
+	 CPUENTRY(11);
+	 CPUENTRY(12);
+	 CPUENTRY(13);
+	 CPUENTRY(14);
+	 CPUENTRY(15);
+	 CPUENTRY(16);
+	 CPUENTRY(17);
+	 CPUENTRY(18);
+	 CPUENTRY(19);
+	 CPUENTRY(20);
+	 CPUENTRY(21);
+	 CPUENTRY(22);
+	 CPUENTRY(23);
+	 CPUENTRY(24);
+	 CPUENTRY(25);
+	 CPUENTRY(26);
+	 CPUENTRY(27);
+	 CPUENTRY(28);
+	 CPUENTRY(29);
+	 CPUENTRY(30);
+	 CPUENTRY(31);
+	struct idprom idprom;
+	struct linux_nodeops nodeops;
+	struct linux_mlist_v0 *totphys_p;
+	struct linux_mlist_v0 totphys;
+	struct linux_mlist_v0 *avail_p;
+	struct linux_mlist_v0 avail;
+	struct linux_mlist_v0 *prommap_p;
+	void (*synchook) (void);
+	struct linux_arguments_v0 *bootargs_p;
+	struct linux_arguments_v0 bootargs;
+	struct linux_romvec romvec;
+	struct node nodes[35];
+	char s_device_type[12];
+	char s_cpu[4];
+	char s_mid[4];
+	char s_idprom[7];
+	char s_compatability[14];
+	char s_leon2[6];
+	char s_mmu_nctx[9];
+	char s_frequency[16];
+	char s_uart1_baud[11];
+	char s_uart2_baud[11];
+	char arg[256];
+};
+
+/* static prom info */
+static struct leon_prom_info PROM_DATA spi = {
+	CONFIG_SYS_CLK_FREQ / 1000,
+	256,
+	{
+#undef	CPUENTRY
+#define	CPUENTRY(idx) idx
+	 CPUENTRY(0),
+	 CPUENTRY(1),
+	 CPUENTRY(2),
+	 CPUENTRY(3),
+	 CPUENTRY(4),
+	 CPUENTRY(5),
+	 CPUENTRY(6),
+	 CPUENTRY(7),
+	 CPUENTRY(8),
+	 CPUENTRY(9),
+	 CPUENTRY(10),
+	 CPUENTRY(11),
+	 CPUENTRY(12),
+	 CPUENTRY(13),
+	 CPUENTRY(14),
+	 CPUENTRY(15),
+	 CPUENTRY(16),
+	 CPUENTRY(17),
+	 CPUENTRY(18),
+	 CPUENTRY(19),
+	 CPUENTRY(20),
+	 CPUENTRY(21),
+	 CPUENTRY(22),
+	 CPUENTRY(23),
+	 CPUENTRY(24),
+	 CPUENTRY(25),
+	 CPUENTRY(26),
+	 CPUENTRY(27),
+	 CPUENTRY(28),
+	 CPUENTRY(29),
+	 CPUENTRY(30),
+	 31},
+	{38400, 38400},
+	{
+	 __va(find_property),
+	 __va(leon_strcmp),
+	 __va(leon_memcpy),
+	 __phy(leon_reboot_physical),
+	 },
+	{
+	 {__va(spi.s_device_type), __va(spi.s_idprom), 4},
+	 {__va(spi.s_idprom), (char *)__va(&spi.idprom), sizeof(struct idprom)},
+	 {__va(spi.s_compatability), __va(spi.s_leon2), 5},
+	 {NULL, NULL, -1}
+	 },
+	{
+	 {__va(spi.s_device_type), __va(spi.s_cpu), 4},
+	 {__va(spi.s_mid), __va(&spi.mids[0]), 4},
+	 {__va(spi.s_mmu_nctx), (char *)__va(&spi.leon_nctx), 4},
+	 {__va(spi.s_frequency), (char *)__va(&spi.freq_khz), 4},
+	 {__va(spi.s_uart1_baud), (char *)__va(&spi.baudrates[0]), 4},
+	 {__va(spi.s_uart2_baud), (char *)__va(&spi.baudrates[1]), 4},
+	 {NULL, NULL, -1}
+	 },
+#undef  CPUENTRY
+#define CPUENTRY(idx) \
+	{ /* cpu_properties */						\
+		{__va(spi.s_device_type), __va(spi.s_cpu), 4},		\
+		{__va(spi.s_mid), __va(&spi.mids[idx]), 4},			\
+		{__va(spi.s_frequency), (char *)__va(&spi.freq_khz), 4},	\
+		{NULL, NULL, -1}						\
+	}
+	CPUENTRY(1),
+	CPUENTRY(2),
+	CPUENTRY(3),
+	CPUENTRY(4),
+	CPUENTRY(5),
+	CPUENTRY(6),
+	CPUENTRY(7),
+	CPUENTRY(8),
+	CPUENTRY(9),
+	CPUENTRY(10),
+	CPUENTRY(11),
+	CPUENTRY(12),
+	CPUENTRY(13),
+	CPUENTRY(14),
+	CPUENTRY(15),
+	CPUENTRY(16),
+	CPUENTRY(17),
+	CPUENTRY(18),
+	CPUENTRY(19),
+	CPUENTRY(20),
+	CPUENTRY(21),
+	CPUENTRY(22),
+	CPUENTRY(23),
+	CPUENTRY(24),
+	CPUENTRY(25),
+	CPUENTRY(26),
+	CPUENTRY(27),
+	CPUENTRY(28),
+	CPUENTRY(29),
+	CPUENTRY(30),
+	CPUENTRY(31),
+	{
+	 0x01,			/* format */
+	 M_LEON2 | M_LEON2_SOC,	/* machine type */
+	 {0, 0, 0, 0, 0, 0},	/* eth */
+	 0,			/* date */
+	 0,			/* sernum */
+	 0,			/* checksum */
+	 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}	/* reserved */
+	 },
+	{
+	 __va(no_nextnode),
+	 __va(no_child),
+	 __va(no_proplen),
+	 __va(no_getprop),
+	 __va(no_setprop),
+	 __va(no_nextprop)
+	 },
+	__va(&spi.totphys),
+	{
+	 NULL,
+	 (char *)CFG_SDRAM_BASE,
+	 0,
+	 },
+	__va(&spi.avail),
+	{
+	 NULL,
+	 (char *)CFG_SDRAM_BASE,
+	 0,
+	 },
+	NULL,			/* prommap_p */
+	NULL,
+	__va(&spi.bootargs),
+	{
+	 {NULL, __va(spi.arg), NULL /*... */ },
+	 /*... */
+	 },
+	{
+	 0,
+	 0,			/* sun4c v0 prom */
+	 0, 0,
+	 {__va(&spi.totphys_p), __va(&spi.prommap_p), __va(&spi.avail_p)},
+	 __va(&spi.nodeops),
+	 NULL, {NULL /* ... */ },
+	 NULL, NULL,
+	 NULL, NULL,		/* pv_getchar, pv_putchar */
+	 __va(leon_nbgetchar), __va(leon_nbputchar),
+	 NULL,
+	 __va(leon_reboot),
+	 NULL,
+	 NULL,
+	 NULL,
+	 __va(leon_halt),
+	 __va(&spi.synchook),
+	 {NULL},
+	 __va(&spi.bootargs_p)
+	 /*... */
+	 },
+	{
+	 {0, __va(spi.root_properties + 3) /* NULL, NULL, -1 */ },
+	 {0, __va(spi.root_properties)},
+	 /* cpu 0, must be spi.nodes[2] see leon_prom_init() */
+	 {1, __va(spi.cpu_properties)},
+
+#undef  CPUENTRY
+#define CPUENTRY(idx) \
+	  {1, __va(spi.cpu_properties##idx) }	/* cpu <idx> */
+	 CPUENTRY(1),
+	 CPUENTRY(2),
+	 CPUENTRY(3),
+	 CPUENTRY(4),
+	 CPUENTRY(5),
+	 CPUENTRY(6),
+	 CPUENTRY(7),
+	 CPUENTRY(8),
+	 CPUENTRY(9),
+	 CPUENTRY(10),
+	 CPUENTRY(11),
+	 CPUENTRY(12),
+	 CPUENTRY(13),
+	 CPUENTRY(14),
+	 CPUENTRY(15),
+	 CPUENTRY(16),
+	 CPUENTRY(17),
+	 CPUENTRY(18),
+	 CPUENTRY(19),
+	 CPUENTRY(20),
+	 CPUENTRY(21),
+	 CPUENTRY(22),
+	 CPUENTRY(23),
+	 CPUENTRY(24),
+	 CPUENTRY(25),
+	 CPUENTRY(26),
+	 CPUENTRY(27),
+	 CPUENTRY(28),
+	 CPUENTRY(29),
+	 CPUENTRY(30),
+	 CPUENTRY(31),
+	 {-1, __va(spi.root_properties + 3) /* NULL, NULL, -1 */ }
+	 },
+	"device_type",
+	"cpu",
+	"mid",
+	"idprom",
+	"compatability",
+	"leon2",
+	"mmu-nctx",
+	"clock-frequency",
+	"uart1_baud",
+	"uart2_baud",
+	CONFIG_DEFAULT_KERNEL_COMMAND_LINE
+};
+
+/* from arch/sparc/kernel/setup.c */
+#define RAMDISK_LOAD_FLAG 0x4000
+extern unsigned short root_flags;
+extern unsigned short root_dev;
+extern unsigned short ram_flags;
+extern unsigned int sparc_ramdisk_image;
+extern unsigned int sparc_ramdisk_size;
+extern int root_mountflags;
+
+extern char initrd_end, initrd_start;
+
+/* Reboot the CPU = jump to beginning of flash again.
+ *
+ * Make sure that all function are inlined here.
+ */
+static void PROM_TEXT leon_reboot(char *bcommand)
+{
+	register char *arg = bcommand;
+	void __attribute__ ((noreturn)) (*reboot_physical) (char *cmd);
+
+	/* get physical address */
+	struct leon_prom_info *pspi =
+	    (void *)(CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	unsigned int *srmmu_ctx_table;
+
+	/* Turn of Interrupts */
+	set_pil(0xf);
+
+	/* Set kernel's context, context zero */
+	srmmu_set_context(0);
+
+	/* Get physical address of the MMU shutdown routine */
+	reboot_physical = (void *)
+	    SPARC_BYPASS_READ(&pspi->reloc_funcs.reboot_physical);
+
+	/* Now that we know the physical address of the function
+	 * we can make the MMU allow jumping to it.
+	 */
+	srmmu_ctx_table = (unsigned int *)srmmu_get_ctable_ptr();
+
+	srmmu_ctx_table = (unsigned int *)SPARC_BYPASS_READ(srmmu_ctx_table);
+
+	/* get physical address of kernel's context table (assume ptd) */
+	srmmu_ctx_table = (unsigned int *)
+	    (((unsigned int)srmmu_ctx_table & 0xfffffffc) << 4);
+
+	/* enable access to physical address of MMU shutdown function */
+	SPARC_BYPASS_WRITE(&srmmu_ctx_table
+			   [((unsigned int)reboot_physical) >> 24],
+			   (((unsigned int)reboot_physical & 0xff000000) >> 4) |
+			   0x1e);
+
+	/* flush TLB cache */
+	leon_flush_tlb_all();
+
+	/* flash instruction & data cache */
+	sparc_icache_flush_all();
+	sparc_dcache_flush_all();
+
+	/* jump to physical address function
+	 * so that when the MMU is disabled
+	 * we can continue to execute
+	 */
+	reboot_physical(arg);
+}
+
+static void PROM_TEXT leon_reboot_physical(char *bcommand)
+{
+	void __attribute__ ((noreturn)) (*reset) (void);
+
+	/* Turn off MMU */
+	srmmu_set_mmureg(0);
+
+	/* Hardcoded start address */
+	reset = CFG_MONITOR_BASE;
+
+	/* flush data cache */
+	sparc_dcache_flush_all();
+
+	/* flush instruction cache */
+	sparc_icache_flush_all();
+
+	/* Jump to start in Flash */
+	reset();
+}
+
+static void PROM_TEXT leon_halt(void)
+{
+	while (1) ;
+}
+
+/* get single char, don't care for blocking*/
+static int PROM_TEXT leon_nbgetchar(void)
+{
+	return -1;
+}
+
+/* put single char, don't care for blocking*/
+static int PROM_TEXT leon_nbputchar(int c)
+{
+	ambapp_dev_apbuart *uart;
+
+	/* get physical address */
+	struct leon_prom_info *pspi =
+	    (void *)(CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	uart = (ambapp_dev_apbuart *)
+	    SPARC_BYPASS_READ(&pspi->reloc_funcs.leon3_apbuart);
+
+	/* no UART? */
+	if (!uart)
+		return 0;
+
+	/***** put char in buffer... ***********
+	 * Make sure all functions are inline! *
+	 ***************************************/
+
+	/* Wait for last character to go. */
+	while (!(SPARC_BYPASS_READ(&uart->status)
+		 & LEON_REG_UART_STATUS_THE)) ;
+
+	/* Send data */
+	SPARC_BYPASS_WRITE(&uart->data, c);
+
+	/* Wait for data to be sent */
+	while (!(SPARC_BYPASS_READ(&uart->status)
+		 & LEON_REG_UART_STATUS_TSE)) ;
+
+	return 0;
+}
+
+/* node ops */
+
+/*#define nodes ((struct node *)__va(&pspi->nodes))*/
+#define nodes ((struct node *)(pspi->nodes))
+
+static int PROM_TEXT no_nextnode(int node)
+{
+	/* get physical address */
+	struct leon_prom_info *pspi =
+	    (void *)(CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	/* convert into virtual address */
+	pspi = (struct leon_prom_info *)
+	    (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET);
+
+	if (nodes[node].level == nodes[node + 1].level)
+		return node + 1;
+	return -1;
+}
+
+static int PROM_TEXT no_child(int node)
+{
+	/* get physical address */
+	struct leon_prom_info *pspi = (struct leon_prom_info *)
+	    (CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	/* convert into virtual address */
+	pspi = (struct leon_prom_info *)
+	    (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET);
+
+	if (nodes[node].level == nodes[node + 1].level - 1)
+		return node + 1;
+	return -1;
+}
+
+static struct property PROM_TEXT *find_property(int node, char *name)
+{
+	/* get physical address */
+	struct leon_prom_info *pspi = (struct leon_prom_info *)
+	    (CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	/* convert into virtual address */
+	pspi = (struct leon_prom_info *)
+	    (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET);
+
+	struct property *prop = &nodes[node].properties[0];
+	while (prop && prop->name) {
+		if (pspi->reloc_funcs.strcmp(prop->name, name) == 0)
+			return prop;
+		prop++;
+	}
+	return NULL;
+}
+
+static int PROM_TEXT no_proplen(int node, char *name)
+{
+	/* get physical address */
+	struct leon_prom_info *pspi = (struct leon_prom_info *)
+	    (CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	/* convert into virtual address */
+	pspi = (struct leon_prom_info *)
+	    (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET);
+
+	struct property *prop = pspi->reloc_funcs.find_property(node, name);
+	if (prop)
+		return prop->length;
+	return -1;
+}
+
+static int PROM_TEXT no_getprop(int node, char *name, char *value)
+{
+	/* get physical address */
+	struct leon_prom_info *pspi = (struct leon_prom_info *)
+	    (CFG_PROM_OFFSET + sizeof(srmmu_tables));
+
+	/* convert into virtual address */
+	pspi = (struct leon_prom_info *)
+	    (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET);
+
+	struct property *prop = pspi->reloc_funcs.find_property(node, name);
+	if (prop) {
+		pspi->reloc_funcs.memcpy(value, prop->value, prop->length);
+		return 1;
+	}
+	return -1;
+}
+
+static int PROM_TEXT no_setprop(int node, char *name, char *value, int len)
+{
+	return -1;
+}
+
+static char PROM_TEXT *no_nextprop(int node, char *name)
+{
+	/* get physical address */
+	struct leon_prom_info *pspi = (struct leon_prom_info *)
+	    (CFG_PROM_OFFSET + sizeof(srmmu_tables));
+	struct property *prop;
+
+	/* convert into virtual address */
+	pspi = (struct leon_prom_info *)
+	    (((unsigned int)pspi & 0x0fffffff) | PAGE_OFFSET);
+
+	if (!name || !name[0])
+		return nodes[node].properties[0].name;
+
+	prop = pspi->reloc_funcs.find_property(node, name);
+	if (prop)
+		return prop[1].name;
+	return NULL;
+}
+
+static int PROM_TEXT leon_strcmp(const char *s1, const char *s2)
+{
+	register char result;
+
+	while (1) {
+		result = *s1 - *s2;
+		if (result || !*s1)
+			break;
+		s2++;
+		s1++;
+	}
+
+	return result;
+}
+
+static void *PROM_TEXT leon_memcpy(void *dest, const void *src, size_t n)
+{
+	char *dst = (char *)dest, *source = (char *)src;
+
+	while (n--) {
+		*dst = *source;
+		dst++;
+		source++;
+	}
+	return dest;
+}
+
+#define GETREGSP(sp) __asm__ __volatile__("mov %%sp, %0" : "=r" (sp))
+
+void leon_prom_init(struct leon_prom_info *pspi)
+{
+	unsigned long i;
+	unsigned char cksum, *ptr;
+	char *addr_str, *end;
+	unsigned long sp;
+	GETREGSP(sp);
+
+	pspi->freq_khz = CONFIG_SYS_CLK_FREQ / 1000;
+
+	/* Set Available main memory size */
+	pspi->totphys.num_bytes = CFG_PROM_OFFSET - CFG_SDRAM_BASE;
+	pspi->avail.num_bytes = pspi->totphys.num_bytes;
+
+	/* Set the pointer to the Console UART in romvec */
+	pspi->reloc_funcs.leon3_apbuart = leon3_apbuart;
+
+	{
+		int j = 1;
+#ifdef CONFIG_SMP
+		ambapp_dev_irqmp *b;
+		b = (ambapp_dev_irqmp *) leon3_getapbbase(VENDOR_GAISLER,
+							  GAISLER_IRQMP);
+		if (b) {
+			j = 1 + ((LEON3_BYPASS_LOAD_PA(&(b->mpstatus))
+				  >> LEON3_IRQMPSTATUS_CPUNR) & 0xf);
+		}
+#endif
+#undef nodes
+		pspi->nodes[2 + j].level = -1;
+		pspi->nodes[2 + j].properties = __va(spi.root_properties + 3);
+	}
+
+	/* Set Ethernet MAC address from environment */
+	if ((addr_str = getenv("ethaddr")) != NULL) {
+		for (i = 0; i < 6; i++) {
+			pspi->idprom.id_ethaddr[i] = addr_str ?
+			    simple_strtoul(addr_str, &end, 16) : 0;
+			if (addr_str) {
+				addr_str = (*end) ? end + 1 : end;
+			}
+		}
+	} else {
+		/* HW Address not found in environment,
+		 * Set default HW address
+		 */
+		pspi->idprom.id_ethaddr[0] = 0;
+		pspi->idprom.id_ethaddr[1] = 0;
+		pspi->idprom.id_ethaddr[2] = 0;
+		pspi->idprom.id_ethaddr[3] = 0;
+		pspi->idprom.id_ethaddr[4] = 0;
+		pspi->idprom.id_ethaddr[5] = 0;
+	}
+
+	ptr = (unsigned char *)&pspi->idprom;
+	for (i = cksum = 0; i <= 0x0E; i++)
+		cksum ^= *ptr++;
+	pspi->idprom.id_cksum = cksum;
+}
+
+static inline void set_cache(unsigned long regval)
+{
+	asm volatile ("sta %0, [%%g0] %1\n\t":: "r" (regval), "i"(2):"memory");
+}
+
+extern unsigned short bss_start, bss_end;
+
+/* mark as section .img.main.text, to be referenced in linker script */
+int prom_init(void)
+{
+	struct leon_prom_info *pspi = (void *)
+	    ((((unsigned int)&spi) & PROM_SIZE_MASK) + CFG_PROM_OFFSET);
+
+	/* disable mmu */
+	srmmu_set_mmureg(0x00000000);
+	__asm__ __volatile__("flush\n\t");
+
+	/* init prom info struct */
+	leon_prom_init(pspi);
+
+	kernel_arg_promvec = &pspi->romvec;
+#ifdef PRINT_ROM_VEC
+	printf("Kernel rom vec: 0x%lx\n", (unsigned int)(&pspi->romvec));
+#endif
+	return 0;
+}
+
+/* Copy current kernel boot argument to ROMvec */
+void prepare_bootargs(char *bootargs)
+{
+	struct leon_prom_info *pspi;
+	char *src, *dst;
+	int left;
+
+	/* if no bootargs set, skip copying ==> default bootline */
+	if (bootargs && (*bootargs != '\0')) {
+		pspi = (void *)((((unsigned int)&spi) & PROM_SIZE_MASK) +
+				CFG_PROM_OFFSET);
+		src = bootargs;
+		dst = &pspi->arg[0];
+		left = 255;	/* max len */
+		while (*src && left > 0) {
+			*dst++ = *src++;
+			left--;
+		}
+		/* terminate kernel command line string */
+		*dst = 0;
+	}
+}
+
+void srmmu_init_cpu(unsigned int entry)
+{
+	sparc_srmmu_setup *psrmmu_tables = (void *)
+	    ((((unsigned int)&srmmu_tables) & PROM_SIZE_MASK) +
+	     CFG_PROM_OFFSET);
+
+	/* Make context 0 (kernel's context) point
+	 * to our prepared memory mapping
+	 */
+#define PTD 1
+	psrmmu_tables->ctx_table[0] =
+	    ((unsigned int)&psrmmu_tables->pgd_table[0x00]) >> 4 | PTD;
+
+	/* Set virtual kernel address 0xf0000000
+	 * to SRAM/SDRAM address.
+	 * Make it READ/WRITE/EXEC to SuperUser
+	 */
+#define PTE 2
+#define ACC_SU_ALL 0x1c
+	psrmmu_tables->pgd_table[0xf0] =
+	    (CFG_SDRAM_BASE >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf1] =
+	    ((CFG_SDRAM_BASE + 0x1000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf2] =
+	    ((CFG_SDRAM_BASE + 0x2000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf3] =
+	    ((CFG_SDRAM_BASE + 0x3000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf4] =
+	    ((CFG_SDRAM_BASE + 0x4000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf5] =
+	    ((CFG_SDRAM_BASE + 0x5000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf6] =
+	    ((CFG_SDRAM_BASE + 0x6000000) >> 4) | ACC_SU_ALL | PTE;
+	psrmmu_tables->pgd_table[0xf7] =
+	    ((CFG_SDRAM_BASE + 0x7000000) >> 4) | ACC_SU_ALL | PTE;
+
+	/* convert rom vec pointer to virtual address */
+	kernel_arg_promvec = (struct linux_romvec *)
+	    (((unsigned int)kernel_arg_promvec & 0x0fffffff) | 0xf0000000);
+
+	/* Set Context pointer to point to context table
+	 * 256 contexts supported.
+	 */
+	srmmu_set_ctable_ptr((unsigned int)&psrmmu_tables->ctx_table[0]);
+
+	/* Set kernel's context, context zero */
+	srmmu_set_context(0);
+
+	/* Invalidate all Cache */
+	__asm__ __volatile__("flush\n\t");
+
+	srmmu_set_mmureg(0x00000001);
+	leon_flush_tlb_all();
+	leon_flush_cache_all();
+}
diff --git a/cpu/leon3/serial.c b/cpu/leon3/serial.c
new file mode 100644
index 0000000..27d5cd3
--- /dev/null
+++ b/cpu/leon3/serial.c
@@ -0,0 +1,139 @@
+/* GRLIB APBUART Serial controller driver
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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/processor.h>
+#include <asm/leon.h>
+#include <ambapp.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Force cache miss each time a serial controller reg is read */
+#define CACHE_BYPASS 1
+
+#ifdef CACHE_BYPASS
+#define READ_BYTE(var)  SPARC_NOCACHE_READ_BYTE((unsigned int)&(var))
+#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)&(var))
+#define READ_WORD(var)  SPARC_NOCACHE_READ((unsigned int)&(var))
+#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)&(var))
+#endif
+
+ambapp_dev_apbuart *leon3_apbuart = NULL;
+
+int serial_init(void)
+{
+	ambapp_apbdev apbdev;
+	unsigned int tmp;
+
+	/* find UART */
+	if (ambapp_apb_first(VENDOR_GAISLER, GAISLER_APBUART, &apbdev) == 1) {
+
+		leon3_apbuart = (ambapp_dev_apbuart *) apbdev.address;
+
+		/* found apbuart, let's init...
+		 *
+		 * Set scaler / baud rate
+		 *
+		 * Receiver & transmitter enable
+		 */
+		leon3_apbuart->scaler = CFG_GRLIB_APBUART_SCALER;
+
+		/* Let bit 11 be unchanged (debug bit for GRMON) */
+		tmp = READ_WORD(leon3_apbuart->ctrl);
+
+		leon3_apbuart->ctrl = ((tmp & LEON_REG_UART_CTRL_DBG) |
+				       LEON_REG_UART_CTRL_RE |
+				       LEON_REG_UART_CTRL_TE);
+
+		return 0;
+	}
+	return -1;		/* didn't find hardware */
+}
+
+void serial_putc(const char c)
+{
+	if (c == '\n')
+		serial_putc_raw('\r');
+
+	serial_putc_raw(c);
+}
+
+void serial_putc_raw(const char c)
+{
+	if (!leon3_apbuart)
+		return;
+
+	/* Wait for last character to go. */
+	while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_THE)) ;
+
+	/* Send data */
+	leon3_apbuart->data = c;
+
+#ifdef LEON_DEBUG
+	/* Wait for data to be sent */
+	while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_TSE)) ;
+#endif
+}
+
+void serial_puts(const char *s)
+{
+	while (*s) {
+		serial_putc(*s++);
+	}
+}
+
+int serial_getc(void)
+{
+	if (!leon3_apbuart)
+		return 0;
+
+	/* Wait for a character to arrive. */
+	while (!(READ_WORD(leon3_apbuart->status) & LEON_REG_UART_STATUS_DR)) ;
+
+	/* read data */
+	return READ_WORD(leon3_apbuart->data);
+}
+
+int serial_tstc(void)
+{
+	if (leon3_apbuart)
+		return (READ_WORD(leon3_apbuart->status) &
+			LEON_REG_UART_STATUS_DR);
+	return 0;
+}
+
+/* set baud rate for uart */
+void serial_setbrg(void)
+{
+	/* update baud rate settings, read it from gd->baudrate */
+	unsigned int scaler;
+	if (leon3_apbuart && (gd->baudrate > 0)) {
+		scaler =
+		    (((CONFIG_SYS_CLK_FREQ * 10) / (gd->baudrate * 8)) -
+		     5) / 10;
+		leon3_apbuart->scaler = scaler;
+	}
+	return;
+}
diff --git a/cpu/leon3/start.S b/cpu/leon3/start.S
new file mode 100644
index 0000000..807f7e8
--- /dev/null
+++ b/cpu/leon3/start.S
@@ -0,0 +1,616 @@
+/* This is where the SPARC/LEON3 starts
+ * Copyright (C) 2007,
+ * Daniel Hellstrom, daniel@gaisler.com
+ *
+ * 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 <config.h>
+#include <asm/asmmacro.h>
+#include <asm/winmacro.h>
+#include <asm/psr.h>
+#include <asm/stack.h>
+#include <asm/leon.h>
+#include <version.h>
+
+/* Entry for traps which jump to a programmer-specified trap handler.  */
+#define TRAPR(H)  \
+	wr 	%g0, 0xfe0, %psr; \
+	mov 	%g0, %tbr; \
+	ba 	(H); \
+	mov 	%g0, %wim;
+
+#define TRAP(H) \
+	mov	%psr, %l0; \
+	ba	(H); \
+	nop; nop;
+
+#define TRAPI(ilevel) \
+	mov 	ilevel, %l7; \
+	mov 	%psr, %l0; \
+	b 	_irq_entry; \
+	mov 	%wim, %l3
+
+/* Unexcpected trap will halt the processor by forcing it to error state */
+#undef BAD_TRAP
+#define BAD_TRAP ta 0; nop; nop; nop;
+
+/* Software trap. Treat as BAD_TRAP for the time being... */
+#define SOFT_TRAP TRAP(_hwerr)
+
+#define PSR_INIT   0x1FC0	/* Disable traps, set s and ps */
+#define WIM_INIT   2
+
+/* All traps low-level code here must end with this macro. */
+#define RESTORE_ALL b ret_trap_entry; clr %l6;
+
+#define WRITE_PAUSE nop;nop;nop
+
+WINDOWSIZE = (16 * 4)
+ARGPUSHSIZE = (6 * 4)
+ARGPUSH = (WINDOWSIZE + 4)
+MINFRAME = (WINDOWSIZE + ARGPUSHSIZE + 4)
+
+/* Number of register windows */
+#ifndef CFG_SPARC_NWINDOWS
+#error Must define number of SPARC register windows, default is 8
+#endif
+
+#define STACK_ALIGN	8
+#define SA(X)	(((X)+(STACK_ALIGN-1)) & ~(STACK_ALIGN-1))
+
+	.section ".start", "ax"
+	.globl 	_start, start, _trap_table
+	.globl  _irq_entry, nmi_trap
+	.globl  _reset_reloc
+
+/* at address 0
+ * Hardware traps
+ */
+start:
+_start:
+_trap_table:
+	TRAPR(_hardreset);		! 00 reset trap
+	BAD_TRAP;			! 01 instruction_access_exception
+	BAD_TRAP;			! 02 illegal_instruction
+	BAD_TRAP;			! 03 priveleged_instruction
+	BAD_TRAP;			! 04 fp_disabled
+	TRAP(_window_overflow);		! 05 window_overflow
+	TRAP(_window_underflow);	! 06 window_underflow
+	BAD_TRAP;			! 07 Memory Address Not Aligned
+	BAD_TRAP;			! 08 Floating Point Exception
+	BAD_TRAP;			! 09 Data Miss Exception
+	BAD_TRAP;			! 0a Tagged Instruction Ovrflw
+	BAD_TRAP;			! 0b Watchpoint Detected
+	BAD_TRAP;			! 0c
+	BAD_TRAP;			! 0d
+	BAD_TRAP;			! 0e
+	BAD_TRAP;			! 0f
+	BAD_TRAP;			! 10
+	TRAPI(1);			! 11 IRQ level 1
+	TRAPI(2);			! 12 IRQ level 2
+	TRAPI(3);			! 13 IRQ level 3
+	TRAPI(4);			! 14 IRQ level 4
+	TRAPI(5);			! 15 IRQ level 5
+	TRAPI(6);			! 16 IRQ level 6
+	TRAPI(7);			! 17 IRQ level 7
+	TRAPI(8);			! 18 IRQ level 8
+	TRAPI(9);			! 19 IRQ level 9
+	TRAPI(10);			! 1a IRQ level 10
+	TRAPI(11);			! 1b IRQ level 11
+	TRAPI(12);			! 1c IRQ level 12
+	TRAPI(13);			! 1d IRQ level 13
+	TRAPI(14);			! 1e IRQ level 14
+	TRAP(_nmi_trap);		! 1f IRQ level 15 /
+	                		! NMI (non maskable interrupt)
+	BAD_TRAP;			! 20 r_register_access_error
+	BAD_TRAP;			! 21 instruction access error
+	BAD_TRAP;			! 22
+	BAD_TRAP;			! 23
+	BAD_TRAP;			! 24 co-processor disabled
+	BAD_TRAP;			! 25 uniplemented FLUSH
+	BAD_TRAP;			! 26
+	BAD_TRAP;			! 27
+	BAD_TRAP;			! 28 co-processor exception
+	BAD_TRAP;			! 29 data access error
+	BAD_TRAP;			! 2a division by zero
+	BAD_TRAP;			! 2b data store error
+	BAD_TRAP;			! 2c data access MMU miss
+	BAD_TRAP;			! 2d
+	BAD_TRAP;			! 2e
+	BAD_TRAP;			! 2f
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 30-33
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 34-37
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 38-3b
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 3c-3f
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 40-43
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 44-47
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 48-4b
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 4c-4f
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 50-53
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 54-57
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 58-5b
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 5c-5f
+
+	/* implementaion dependent */
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 60-63
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 64-67
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 68-6b
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 6c-6f
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 70-73
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 74-77
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 78-7b
+	BAD_TRAP; BAD_TRAP; BAD_TRAP; BAD_TRAP; ! 7c-7f
+
+	/* Software traps, not handled */
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 80-83
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 84-87
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 88-8b
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 8c-8f
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 90-93
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 94-97
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 98-9b
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! 9c-9f
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! a0-a3
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! a4-a7
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! a8-ab
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! ac-af
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! b0-b3
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! b4-b7
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! b8-bb
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! bc-bf
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! c0-c3
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! c4-c7
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! c8-cb
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! cc-cf
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! d0-d3
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! d4-d7
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! d8-db
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! dc-df
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! e0-e3
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! e4-e7
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! e8-eb
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! ec-ef
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! f0-f3
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! f4-f7
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! f8-fb
+	SOFT_TRAP; SOFT_TRAP; SOFT_TRAP; SOFT_TRAP;	! fc-ff
+/*
+ * Version string
+ */
+
+	.data
+	.extern leon3_snooping_avail
+	.globl	version_string
+version_string:
+	.ascii U_BOOT_VERSION
+	.ascii " (", __DATE__, " - ", __TIME__, ")"
+	.ascii CONFIG_IDENT_STRING, "\0"
+
+	.section	".text"
+	.align 4
+
+_hardreset:
+1000:
+	flush
+
+	/* Enable I/D-Cache and Snooping */
+	set	0x0081000f, %g2
+	sta	%g2, [%g0] 2
+
+	mov	%g0, %y
+	clr	%g1
+	clr	%g2
+	clr	%g3
+	clr	%g4
+	clr	%g5
+	clr	%g6
+	clr	%g7
+
+	mov	%asr17, %g3
+	and	%g3, 0x1f, %g3
+clear_window:
+	mov	%g0, %l0
+	mov	%g0, %l1
+	mov	%g0, %l2
+	mov	%g0, %l3
+	mov	%g0, %l4
+	mov	%g0, %l5
+	mov	%g0, %l6
+	mov	%g0, %l7
+	mov	%g0, %o0
+	mov	%g0, %o1
+	mov	%g0, %o2
+	mov	%g0, %o3
+	mov	%g0, %o4
+	mov	%g0, %o5
+	mov	%g0, %o6
+	mov	%g0, %o7
+	subcc	%g3, 1, %g3
+	bge	clear_window
+	save
+
+wininit:
+	set	WIM_INIT, %g3
+	mov	%g3, %wim
+
+stackp:
+	set	CFG_INIT_SP_OFFSET, %fp
+	andn	%fp, 0x0f, %fp
+	sub	%fp, 64, %sp
+
+cpu_init_unreloc:
+	call	cpu_init_f
+	nop
+
+/* un relocated start address of monitor */
+#define TEXT_START _text
+
+/* un relocated end address of monitor */
+#define DATA_END __init_end
+
+reloc:
+	set	TEXT_START,%g2
+	set	DATA_END,%g3
+	set	CFG_RELOC_MONITOR_BASE,%g4
+reloc_loop:
+	ldd	[%g2],%l0
+	ldd	[%g2+8],%l2
+	std	%l0,[%g4]
+	std	%l2,[%g4+8]
+	inc	16,%g2
+	subcc	%g3,%g2,%g0
+	bne	reloc_loop
+	inc	16,%g4
+
+	clr	%l0
+	clr	%l1
+	clr	%l2
+	clr	%l3
+	clr	%g2
+
+/* register g4 contain address to start
+ * This means that BSS must be directly after data and code segments
+ *
+ * g3 is length of bss = (__bss_end-__bss_start)
+ *
+ */
+
+clr_bss:
+/* clear bss area (the relocated) */
+	set	__bss_start,%g2
+	set	__bss_end,%g3
+	sub	%g3,%g2,%g3
+	add	%g3,%g4,%g3
+	clr	%g1	/* std %g0 uses g0 and g1 */
+/* clearing 16byte a time ==> linker script need to align to 16 byte offset */
+clr_bss_16:
+	std	%g0,[%g4]
+	std	%g0,[%g4+8]
+	inc	16,%g4
+	cmp	%g3,%g4
+	bne	clr_bss_16
+	nop
+
+/* add offsets to GOT table */
+fixup_got:
+	set	__got_start,%g4
+	set	__got_end,%g3
+/*
+ * new got offset = (old GOT-PTR (read with ld) -
+ *   CFG_RELOC_MONITOR_BASE(from define) ) +
+ *   Destination Address (from define)
+ */
+	set	CFG_RELOC_MONITOR_BASE,%g2
+	set	TEXT_START, %g1
+	add	%g4,%g2,%g4
+	sub	%g4,%g1,%g4
+	add	%g3,%g2,%g3
+	sub	%g3,%g1,%g3
+	sub	%g2,%g1,%g2	! prepare register with (new base address) -
+				!  (old base address)
+got_loop:
+	ld	[%g4],%l0	! load old GOT-PTR
+	add	%l0,%g2,%l0	! increase with (new base address) -
+				!  (old base)
+	st	%l0,[%g4]
+	inc	4,%g4
+	cmp	%g3,%g4
+	bne	got_loop
+	nop
+
+prom_relocate:
+	set	__prom_start, %g2
+	set	__prom_end, %g3
+	set	CFG_PROM_OFFSET, %g4
+
+prom_relocate_loop:
+	ldd	[%g2],%l0
+	ldd	[%g2+8],%l2
+	std	%l0,[%g4]
+	std	%l2,[%g4+8]
+	inc	16,%g2
+	subcc	%g3,%g2,%g0
+	bne	prom_relocate_loop
+	inc	16,%g4
+
+/* Trap table has been moved, lets tell CPU about
+ * the new trap table address
+ */
+
+	set	CFG_RELOC_MONITOR_BASE, %g2
+	wr	%g0, %g2, %tbr
+	nop
+	nop
+	nop
+	
+/* If CACHE snooping is available in hardware the 
+ * variable leon3_snooping_avail will be set to
+ * 0x800000 else 0.
+ */
+snoop_detect:
+	sethi	%hi(0x00800000), %o0
+	lda	[%g0] 2, %o1
+	and	%o0, %o1, %o0
+	sethi	%hi(leon3_snooping_avail+CFG_RELOC_MONITOR_BASE-TEXT_BASE), %o1
+	st	%o0, [%lo(leon3_snooping_avail+CFG_RELOC_MONITOR_BASE-TEXT_BASE)+%o1]
+
+/*	call	relocate*/
+	nop
+/* Call relocated init functions */
+jump:
+	set	cpu_init_f2,%o1
+	set	CFG_RELOC_MONITOR_BASE,%o2
+	add	%o1,%o2,%o1
+	sub	%o1,%g1,%o1
+	call	%o1
+	clr	%o0
+
+	set	board_init_f,%o1
+	set	CFG_RELOC_MONITOR_BASE,%o2
+	add	%o1,%o2,%o1
+	sub	%o1,%g1,%o1
+	call	%o1
+	clr	%o0
+
+dead:	ta 0				! if call returns...
+	nop
+
+/* Interrupt handler caller,
+ * reg L7: interrupt number
+ * reg L0: psr after interrupt
+ * reg L1: PC
+ * reg L2: next PC
+ * reg L3: wim
+ */
+_irq_entry:
+	SAVE_ALL
+
+	or	%l0, PSR_PIL, %g2
+	wr	%g2, 0x0, %psr
+	WRITE_PAUSE
+	wr	%g2, PSR_ET, %psr
+	WRITE_PAUSE
+	mov	%l7, %o0		! irq level
+	set	handler_irq, %o1
+	set	(CFG_RELOC_MONITOR_BASE-TEXT_BASE), %o2
+	add	%o1, %o2, %o1
+	call	%o1
+	add	%sp, SF_REGS_SZ, %o1	! pt_regs ptr
+	or	%l0, PSR_PIL, %g2	! restore PIL after handler_irq
+	wr	%g2, PSR_ET, %psr	! keep ET up
+	WRITE_PAUSE
+
+	RESTORE_ALL
+
+!Window overflow trap handler.
+	.global _window_overflow
+
+_window_overflow:
+
+	mov	%wim, %l3		! Calculate next WIM
+	mov	%g1, %l7
+	srl	%l3, 1, %g1
+	sll	%l3, (CFG_SPARC_NWINDOWS-1) , %l4
+	or	%l4, %g1, %g1
+
+	save				! Get into window to be saved.
+	mov	%g1, %wim
+	nop;
+	nop;
+	nop
+	st	%l0, [%sp + 0];
+	st	%l1, [%sp + 4];
+	st	%l2, [%sp + 8];
+	st	%l3, [%sp + 12];
+	st	%l4, [%sp + 16];
+	st	%l5, [%sp + 20];
+	st	%l6, [%sp + 24];
+	st	%l7, [%sp + 28];
+	st	%i0, [%sp + 32];
+	st	%i1, [%sp + 36];
+	st	%i2, [%sp + 40];
+	st	%i3, [%sp + 44];
+	st	%i4, [%sp + 48];
+	st	%i5, [%sp + 52];
+	st	%i6, [%sp + 56];
+	st	%i7, [%sp + 60];
+	restore				! Go back to trap window.
+	mov	%l7, %g1
+	jmp	%l1			! Re-execute save.
+	rett	%l2
+
+/* Window underflow trap handler.  */
+
+	.global  _window_underflow
+
+_window_underflow:
+
+	mov  %wim, %l3			! Calculate next WIM
+	sll  %l3, 1, %l4
+	srl  %l3, (CFG_SPARC_NWINDOWS-1), %l5
+	or   %l5, %l4, %l5
+	mov  %l5, %wim
+	nop; nop; nop
+	restore				! Two restores to get into the
+	restore				! window to restore
+	ld	[%sp + 0], %l0; 	! Restore window from the stack
+	ld	[%sp + 4], %l1;
+	ld	[%sp + 8], %l2;
+	ld	[%sp + 12], %l3;
+	ld	[%sp + 16], %l4;
+	ld	[%sp + 20], %l5;
+	ld	[%sp + 24], %l6;
+	ld	[%sp + 28], %l7;
+	ld	[%sp + 32], %i0;
+	ld	[%sp + 36], %i1;
+	ld	[%sp + 40], %i2;
+	ld	[%sp + 44], %i3;
+	ld	[%sp + 48], %i4;
+	ld	[%sp + 52], %i5;
+	ld	[%sp + 56], %i6;
+	ld	[%sp + 60], %i7;
+	save				! Get back to the trap window.
+	save
+	jmp	%l1			! Re-execute restore.
+	rett	%l2
+
+	retl
+
+_nmi_trap:
+	nop
+	jmp %l1
+	rett %l2
+
+_hwerr:
+	ta 0
+	nop
+	nop
+	b _hwerr 			! loop infinite
+	nop
+
+/* Registers to not touch at all. */
+#define t_psr      l0 /* Set by caller */
+#define t_pc       l1 /* Set by caller */
+#define t_npc      l2 /* Set by caller */
+#define t_wim      l3 /* Set by caller */
+#define t_twinmask l4 /* Set at beginning of this entry routine. */
+#define t_kstack   l5 /* Set right before pt_regs frame is built */
+#define t_retpc    l6 /* If you change this, change winmacro.h header file */
+#define t_systable l7 /* Never touch this, could be the syscall table ptr. */
+#define curptr     g6 /* Set after pt_regs frame is built */
+
+trap_setup:
+/* build a pt_regs trap frame. */
+	sub	%fp, (SF_REGS_SZ + PT_REGS_SZ), %t_kstack
+	PT_STORE_ALL(t_kstack, t_psr, t_pc, t_npc, g2)
+
+	/* See if we are in the trap window. */
+	mov	1, %t_twinmask
+	sll	%t_twinmask, %t_psr, %t_twinmask ! t_twinmask = (1 << psr)
+	andcc	%t_twinmask, %t_wim, %g0
+	beq	1f		! in trap window, clean up
+	nop
+
+	/*-------------------------------------------------
+	 * Spill , adjust %wim and go.
+	 */
+	srl	%t_wim, 0x1, %g2		! begin computation of new %wim
+
+	set	(CFG_SPARC_NWINDOWS-1), %g3	!NWINDOWS-1
+
+	sll	%t_wim, %g3, %t_wim	! NWINDOWS-1
+	or	%t_wim, %g2, %g2
+	and	%g2, 0xff, %g2
+
+	save	%g0, %g0, %g0           ! get in window to be saved
+
+	/* Set new %wim value */
+	wr	%g2, 0x0, %wim
+
+	/* Save the kernel window onto the corresponding stack. */
+	RW_STORE(sp)
+
+	restore	%g0, %g0, %g0
+	/*-------------------------------------------------*/
+
+1:
+	/* Trap from kernel with a window available.
+	 * Just do it...
+	 */
+	jmpl	%t_retpc + 0x8, %g0	! return to caller
+	 mov	%t_kstack, %sp		! jump onto new stack
+
+#define twin_tmp1 l4
+#define glob_tmp  g4
+#define curptr    g6
+ret_trap_entry:
+	wr	%t_psr, 0x0, %psr       ! enable nesting again, clear ET
+
+	/* Will the rett land us in the invalid window? */
+	mov	2, %g1
+	sll	%g1, %t_psr, %g1
+
+	set	CFG_SPARC_NWINDOWS, %g2	!NWINDOWS
+
+	srl	%g1, %g2, %g2
+	or	%g1, %g2, %g1
+	rd	%wim, %g2
+	andcc	%g2, %g1, %g0
+	be	1f		! Nope, just return from the trap
+	 sll	%g2, 0x1, %g1
+
+	/* We have to grab a window before returning. */
+	set	(CFG_SPARC_NWINDOWS-1), %g3	!NWINDOWS-1
+
+	srl	%g2, %g3,  %g2
+	or	%g1, %g2, %g1
+	and	%g1, 0xff, %g1
+
+	wr	%g1, 0x0, %wim
+
+	/* Grrr, make sure we load from the right %sp... */
+	PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
+
+	restore	%g0, %g0, %g0
+	RW_LOAD(sp)
+	b	2f
+	save	%g0, %g0, %g0
+
+	/* Reload the entire frame in case this is from a
+	 * kernel system call or whatever...
+	 */
+1:
+	PT_LOAD_ALL(sp, t_psr, t_pc, t_npc, g1)
+2:
+	wr	%t_psr, 0x0, %psr
+	nop;
+	nop;
+	nop
+
+	jmp	%t_pc
+	rett	%t_npc
+
+/* This is called from relocated C-code.
+ * It resets the system by jumping to _start
+ */
+_reset_reloc:
+	set	start, %l0
+	call	%l0
+	nop
diff --git a/cpu/leon3/usb_uhci.c b/cpu/leon3/usb_uhci.c
new file mode 100644
index 0000000..7910beb
--- /dev/null
+++ b/cpu/leon3/usb_uhci.c
@@ -0,0 +1,1313 @@
+/*
+ * Part of this code has been derived from linux:
+ * Universal Host Controller Interface driver for USB (take II).
+ *
+ * (c) 1999-2001 Georg Acher, acher@in.tum.de (executive slave) (base guitar)
+ *               Deti Fliegl, deti@fliegl.de (executive slave) (lead voice)
+ *               Thomas Sailer, sailer@ife.ee.ethz.ch (chief consultant) (cheer leader)
+ *               Roman Weissgaerber, weissg@vienna.at (virt root hub) (studio porter)
+ * (c) 2000      Yggdrasil Computing, Inc. (port of new PCI interface support
+ *               from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
+ * (C) 2000      David Brownell, david-b@pacbell.net (usb-ohci.c)
+ *
+ * HW-initalization based on material of
+ *
+ * (C) Copyright 1999 Linus Torvalds
+ * (C) Copyright 1999 Johannes Erdfelt
+ * (C) Copyright 1999 Randy Dunlap
+ * (C) Copyright 1999 Gregory P. Smith
+ *
+ *
+ * Adapted for U-Boot:
+ * (C) Copyright 2001 Denis Peter, MPL AG Switzerland
+ * (C) Copyright 2008, Daniel Hellström, daniel@gaisler.com
+ *     Added AMBA Plug&Play detection of GRUSB, modified interrupt handler.
+ *     Added cache flushes where needed.
+ *
+ * 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
+ *
+ *
+ */
+
+/**********************************************************************
+ * How it works:
+ * -------------
+ * The framelist / Transfer descriptor / Queue Heads are similar like
+ * in the linux usb_uhci.c.
+ *
+ * During initialization, the following skeleton is allocated in init_skel:
+ *
+ *         framespecific           |           common chain
+ *
+ * framelist[]
+ * [  0 ]-----> TD ---------\
+ * [  1 ]-----> TD ----------> TD ------> QH -------> QH -------> QH ---> NULL
+ *   ...        TD ---------/
+ * [1023]-----> TD --------/
+ *
+ *              ^^             ^^         ^^          ^^          ^^
+ *              7 TDs for      1 TD for   Start of    Start of    End Chain
+ *              INT (2-128ms)  1ms-INT    CTRL Chain  BULK Chain
+ *
+ *
+ * Since this is a bootloader, the isochronous transfer descriptor have been removed.
+ *
+ * Interrupt Transfers.
+ * --------------------
+ * For Interupt transfers USB_MAX_TEMP_INT_TD Transfer descriptor are available. They
+ * will be inserted after the appropriate (depending the interval setting) skeleton TD.
+ * If an interrupt has been detected the dev->irqhandler is called. The status and number
+ * of transfered bytes is stored in dev->irq_status resp. dev->irq_act_len. If the
+ * dev->irqhandler returns 0, the interrupt TD is removed and disabled. If an 1 is returned,
+ * the interrupt TD will be reactivated.
+ *
+ * Control Transfers
+ * -----------------
+ * Control Transfers are issued by filling the tmp_td with the appropriate data and connect
+ * them to the qh_cntrl queue header. Before other control/bulk transfers can be issued,
+ * the programm has to wait for completion. This does not allows asynchronous data transfer.
+ *
+ * Bulk Transfers
+ * --------------
+ * Bulk Transfers are issued by filling the tmp_td with the appropriate data and connect
+ * them to the qh_bulk queue header. Before other control/bulk transfers can be issued,
+ * the programm has to wait for completion. This does not allows asynchronous data transfer.
+ *
+ *
+ */
+
+#include <common.h>
+#include <ambapp.h>
+#include <asm/leon.h>
+#include <asm/leon3.h>
+#include <asm/processor.h>
+
+#ifdef CONFIG_USB_UHCI
+
+#include <usb.h>
+#include "usb_uhci.h"
+
+#define USB_MAX_TEMP_TD      128	/* number of temporary TDs for bulk and control transfers */
+#define USB_MAX_TEMP_INT_TD  32	/* number of temporary TDs for Interrupt transfers */
+
+extern int leon3_snooping_avail;
+/*
+#define out16r(address,data) (*(unsigned short *)(address) = \
+ (unsigned short)( \
+ (((unsigned short)(data)&0xff)<<8) | \
+ (((unsigned short)(data)&0xff00)>>8) \
+ ))
+ */
+#define out16r(address,data) _out16r((unsigned int)(address), (unsigned short)(data))
+void _out16r(unsigned int address, unsigned short data)
+{
+	unsigned short val = (unsigned short)((((unsigned short)(data) & 0xff)
+					       << 8) | (((unsigned short)(data)
+							 & 0xff00) >> 8));
+#ifdef UHCI_DEBUG_REGS
+	printf("out16r(0x%lx,0x%04x = 0x%04x)\n", address, val, data);
+#endif
+	*(unsigned short *)(address) = val;
+}
+
+#define out32r(address,data) _out32r((unsigned int)(address), (unsigned int)(data))
+void _out32r(unsigned int address, unsigned int data)
+{
+	unsigned int val = (unsigned int)((((unsigned int)(data) & 0x000000ff)
+					   << 24) | (((unsigned int)(data) &
+						      0x0000ff00) << 8) |
+					  (((unsigned int)(data) & 0x00ff0000)
+					   >> 8) | (((unsigned int)(data) &
+						     0xff000000) >> 24));
+#ifdef UHCI_DEBUG_REGS
+	printf("out32r(0x%lx,0x%lx = 0x%lx)\n", address, val, data);
+#endif
+	*(unsigned int *)address = val;
+}
+
+#define in16r(address) _in16r((unsigned int)(address))
+unsigned short _in16r(unsigned int address)
+{
+	unsigned short val = sparc_load_reg_cachemiss_word(address);
+	val = ((val << 8) & 0xff00) | ((val >> 8) & 0xff);
+#ifdef UHCI_DEBUG_REGS
+	printf("in16r(0x%lx): 0x%04x\n", address, val);
+#endif
+	return val;
+}
+
+#define in32r(address) _in32r((unsigned int)(address))
+unsigned int _in32r(unsigned int address)
+{
+	unsigned int val = sparc_load_reg_cachemiss(address);
+	val =
+	    ((val << 24) & 0xff000000) | ((val << 8) & 0xff0000) | ((val >> 8) &
+								    0xff00) |
+	    ((val >> 24) & 0xff);
+#ifdef UHCI_DEBUG_REGS
+	printf("in32r(0x%lx): 0x%08x\n", address, val);
+#endif
+	return val;
+}
+
+#define READ32(address) sparc_load_reg_cachemiss((unsigned int)(address))
+
+/*#define USB_UHCI_DEBUG*/
+#undef USB_UHCI_DEBUG
+
+void usb_show_td(int max);
+#ifdef	USB_UHCI_DEBUG
+void grusb_show_regs(void);
+#define	USB_UHCI_PRINTF(fmt,args...)	printf (fmt ,##args)
+#else
+#define USB_UHCI_PRINTF(fmt,args...)
+#endif
+
+static int grusb_irq = -1;	/* irq vector, if -1 uhci is stopped / reseted */
+unsigned int usb_base_addr;	/* base address */
+
+static uhci_td_t td_int[8] __attribute__ ((aligned(16)));	/* Interrupt Transfer descriptors */
+static uhci_qh_t qh_cntrl __attribute__ ((aligned(16)));	/* control Queue Head */
+static uhci_qh_t qh_bulk __attribute__ ((aligned(16)));	/*  bulk Queue Head */
+static uhci_qh_t qh_end __attribute__ ((aligned(16)));	/* end Queue Head */
+static uhci_td_t td_last __attribute__ ((aligned(16)));	/* last TD (linked with end chain) */
+
+/* temporary tds */
+static uhci_td_t tmp_td[USB_MAX_TEMP_TD] __attribute__ ((aligned(16)));	/* temporary bulk/control td's  */
+static uhci_td_t tmp_int_td[USB_MAX_TEMP_INT_TD] __attribute__ ((aligned(16)));	/* temporary interrupt td's  */
+
+static unsigned long framelist[1024] __attribute__ ((aligned(0x1000)));	/* frame list */
+
+static struct virt_root_hub rh;	/* struct for root hub */
+
+/**********************************************************************
+ * some forward decleration
+ */
+int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+		       void *buffer, int transfer_len,
+		       struct devrequest *setup);
+
+/* fill a td with the approproiate data. Link, status, info and buffer
+ * are used by the USB controller itselfes, dev is used to identify the
+ * "connected" device
+ */
+void usb_fill_td(uhci_td_t * td, unsigned long link, unsigned long status,
+		 unsigned long info, unsigned long buffer, unsigned long dev)
+{
+	td->link = swap_32(link);
+	td->status = swap_32(status);
+	if ((info & UHCI_PID) == 0)
+		info |= USB_PID_OUT;
+	td->info = swap_32(info);
+	td->buffer = swap_32(buffer);
+	td->dev_ptr = dev;
+}
+
+/* fill a qh with the approproiate data. Head and element are used by the USB controller
+ * itselfes. As soon as a valid dev_ptr is filled, a td chain is connected to the qh.
+ * Please note, that after completion of the td chain, the entry element is removed /
+ * marked invalid by the USB controller.
+ */
+void usb_fill_qh(uhci_qh_t * qh, unsigned long head, unsigned long element)
+{
+	qh->head = swap_32(head);
+	qh->element = swap_32(element);
+	qh->dev_ptr = 0L;
+}
+
+/* get the status of a td->status
+ */
+unsigned long usb_uhci_td_stat(unsigned long status)
+{
+	unsigned long result = 0;
+	result |= (status & TD_CTRL_NAK) ? USB_ST_NAK_REC : 0;
+	result |= (status & TD_CTRL_STALLED) ? USB_ST_STALLED : 0;
+	result |= (status & TD_CTRL_DBUFERR) ? USB_ST_BUF_ERR : 0;
+	result |= (status & TD_CTRL_BABBLE) ? USB_ST_BABBLE_DET : 0;
+	result |= (status & TD_CTRL_CRCTIMEO) ? USB_ST_CRC_ERR : 0;
+	result |= (status & TD_CTRL_BITSTUFF) ? USB_ST_BIT_ERR : 0;
+	result |= (status & TD_CTRL_ACTIVE) ? USB_ST_NOT_PROC : 0;
+	return result;
+}
+
+/* get the status and the transfered len of a td chain.
+ * called from the completion handler
+ */
+int usb_get_td_status(uhci_td_t * td, struct usb_device *dev)
+{
+	unsigned long temp, info;
+	unsigned long stat;
+	uhci_td_t *mytd = td;
+
+	if (dev->devnum == rh.devnum)
+		return 0;
+	dev->act_len = 0;
+	stat = 0;
+	do {
+		temp = swap_32((unsigned long)READ32(&mytd->status));
+		stat = usb_uhci_td_stat(temp);
+		info = swap_32((unsigned long)READ32(&mytd->info));
+		if (((info & 0xff) != USB_PID_SETUP) && (((info >> 21) & 0x7ff) != 0x7ff) && (temp & 0x7FF) != 0x7ff) {	/* if not setup and not null data pack */
+			dev->act_len += (temp & 0x7FF) + 1;	/* the transfered len is act_len + 1 */
+		}
+		if (stat) {	/* status no ok */
+			dev->status = stat;
+			return -1;
+		}
+		temp = swap_32((unsigned long)READ32(&mytd->link));
+		mytd = (uhci_td_t *) (temp & 0xfffffff0);
+	} while ((temp & 0x1) == 0);	/* process all TDs */
+	dev->status = stat;
+	return 0;		/* Ok */
+}
+
+/*-------------------------------------------------------------------
+ *                         LOW LEVEL STUFF
+ *          assembles QHs und TDs for control, bulk and iso
+ *-------------------------------------------------------------------*/
+int dummy(void)
+{
+	USB_UHCI_PRINTF("DUMMY\n");
+	return 0;
+}
+
+/* Submits a control message. That is a Setup, Data and Status transfer.
+ * Routine does not wait for completion.
+ */
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		       int transfer_len, struct devrequest *setup)
+{
+	unsigned long destination, status;
+	int maxsze = usb_maxpacket(dev, pipe);
+	unsigned long dataptr;
+	int len;
+	int pktsze;
+	int i = 0;
+
+	if (!maxsze) {
+		USB_UHCI_PRINTF
+		    ("uhci_submit_control_urb: pipesize for pipe %lx is zero\n",
+		     pipe);
+		return -1;
+	}
+	if (((pipe >> 8) & 0x7f) == rh.devnum) {
+		/* this is the root hub -> redirect it */
+		return uhci_submit_rh_msg(dev, pipe, buffer, transfer_len,
+					  setup);
+	}
+	USB_UHCI_PRINTF("uhci_submit_control start len %x, maxsize %x\n",
+			transfer_len, maxsze);
+	/* The "pipe" thing contains the destination in bits 8--18 */
+	destination = (pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;	/* Setup stage */
+	/* 3 errors */
+	status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
+	/* (urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD); */
+	/*  Build the TD for the control request, try forever, 8 bytes of data */
+	usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status, destination | (7 << 21),
+		    (unsigned long)setup, (unsigned long)dev);
+#ifdef DEBUG_EXTRA
+	{
+		char *sp = (char *)setup;
+		printf("SETUP to pipe %lx: %x %x %x %x %x %x %x %x\n", pipe,
+		       sp[0], sp[1], sp[2], sp[3], sp[4], sp[5], sp[6], sp[7]);
+	}
+#endif
+	dataptr = (unsigned long)buffer;
+	len = transfer_len;
+
+	/* If direction is "send", change the frame from SETUP (0x2D)
+	   to OUT (0xE1). Else change it from SETUP to IN (0x69). */
+	destination =
+	    (pipe & PIPE_DEVEP_MASK) | ((pipe & USB_DIR_IN) ==
+					0 ? USB_PID_OUT : USB_PID_IN);
+	while (len > 0) {
+		/* data stage */
+		pktsze = len;
+		i++;
+		if (pktsze > maxsze)
+			pktsze = maxsze;
+		destination ^= 1 << TD_TOKEN_TOGGLE;	/* toggle DATA0/1 */
+		usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status, destination | ((pktsze - 1) << 21), dataptr, (unsigned long)dev);	/* Status, pktsze bytes of data */
+		tmp_td[i - 1].link = swap_32((unsigned long)&tmp_td[i]);
+
+		dataptr += pktsze;
+		len -= pktsze;
+	}
+
+	/*  Build the final TD for control status */
+	/* It's only IN if the pipe is out AND we aren't expecting data */
+
+	destination &= ~UHCI_PID;
+	if (((pipe & USB_DIR_IN) == 0) || (transfer_len == 0))
+		destination |= USB_PID_IN;
+	else
+		destination |= USB_PID_OUT;
+	destination |= 1 << TD_TOKEN_TOGGLE;	/* End in Data1 */
+	i++;
+	status &= ~TD_CTRL_SPD;
+	/* no limit on errors on final packet , 0 bytes of data */
+	usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status | TD_CTRL_IOC,
+		    destination | (UHCI_NULL_DATA_SIZE << 21), 0,
+		    (unsigned long)dev);
+	tmp_td[i - 1].link = swap_32((unsigned long)&tmp_td[i]);	/* queue status td */
+	/* usb_show_td(i+1); */
+	USB_UHCI_PRINTF("uhci_submit_control end (%d tmp_tds used)\n", i);
+	/* first mark the control QH element terminated */
+	qh_cntrl.element = 0xffffffffL;
+	/* set qh active */
+	qh_cntrl.dev_ptr = (unsigned long)dev;
+	/* fill in tmp_td_chain */
+	dummy();
+	qh_cntrl.element = swap_32((unsigned long)&tmp_td[0]);
+	return 0;
+}
+
+/*-------------------------------------------------------------------
+ * Prepare TDs for bulk transfers.
+ */
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		    int transfer_len)
+{
+	unsigned long destination, status, info;
+	unsigned long dataptr;
+	int maxsze = usb_maxpacket(dev, pipe);
+	int len;
+	int i = 0;
+
+	if (transfer_len < 0) {
+		printf("Negative transfer length in submit_bulk\n");
+		return -1;
+	}
+	if (!maxsze)
+		return -1;
+	/* The "pipe" thing contains the destination in bits 8--18. */
+	destination = (pipe & PIPE_DEVEP_MASK) | usb_packetid(pipe);
+	/* 3 errors */
+	status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | (3 << 27);
+	/*      ((urb->transfer_flags & USB_DISABLE_SPD) ? 0 : TD_CTRL_SPD) | (3 << 27); */
+	/* Build the TDs for the bulk request */
+	len = transfer_len;
+	dataptr = (unsigned long)buffer;
+	do {
+		int pktsze = len;
+		if (pktsze > maxsze)
+			pktsze = maxsze;
+		/* pktsze bytes of data  */
+		info =
+		    destination | (((pktsze - 1) & UHCI_NULL_DATA_SIZE) << 21) |
+		    (usb_gettoggle
+		     (dev, usb_pipeendpoint(pipe),
+		      usb_pipeout(pipe)) << TD_TOKEN_TOGGLE);
+
+		if ((len - pktsze) == 0)
+			status |= TD_CTRL_IOC;	/* last one generates INT */
+
+		usb_fill_td(&tmp_td[i], UHCI_PTR_TERM, status, info, dataptr, (unsigned long)dev);	/* Status, pktsze bytes of data */
+		if (i > 0)
+			tmp_td[i - 1].link = swap_32((unsigned long)&tmp_td[i]);
+		i++;
+		dataptr += pktsze;
+		len -= pktsze;
+		usb_dotoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
+	} while (len > 0);
+	/* first mark the bulk QH element terminated */
+	qh_bulk.element = 0xffffffffL;
+	/* set qh active */
+	qh_bulk.dev_ptr = (unsigned long)dev;
+	/* fill in tmp_td_chain */
+	qh_bulk.element = swap_32((unsigned long)&tmp_td[0]);
+	return 0;
+}
+
+/* search a free interrupt td
+ */
+uhci_td_t *uhci_alloc_int_td(void)
+{
+	int i;
+	for (i = 0; i < USB_MAX_TEMP_INT_TD; i++) {
+		if (tmp_int_td[i].dev_ptr == 0)	/* no device assigned -> free TD */
+			return &tmp_int_td[i];
+	}
+	return NULL;
+}
+
+/*-------------------------------------------------------------------
+ * submits USB interrupt (ie. polling ;-)
+ */
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		   int transfer_len, int interval)
+{
+	int nint, n;
+	unsigned long status, destination;
+	unsigned long info, tmp;
+	uhci_td_t *mytd;
+	if (interval < 0 || interval >= 256)
+		return -1;
+
+	if (interval == 0)
+		nint = 0;
+	else {
+		for (nint = 0, n = 1; nint <= 8; nint++, n += n) {	/* round interval down to 2^n */
+			if (interval < n) {
+				interval = n / 2;
+				break;
+			}
+		}
+		nint--;
+	}
+
+	USB_UHCI_PRINTF("Rounded interval to %i, chain  %i\n", interval, nint);
+	mytd = uhci_alloc_int_td();
+	if (mytd == NULL) {
+		printf("No free INT TDs found\n");
+		return -1;
+	}
+	status = (pipe & TD_CTRL_LS) | TD_CTRL_ACTIVE | TD_CTRL_IOC | (3 << 27);
+/*		(urb->transfer_flags & USB_DISABLE_SPD ? 0 : TD_CTRL_SPD) | (3 << 27);
+*/
+
+	destination =
+	    (pipe & PIPE_DEVEP_MASK) | usb_packetid(pipe) |
+	    (((transfer_len - 1) & 0x7ff) << 21);
+
+	info =
+	    destination |
+	    (usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe)) <<
+	     TD_TOKEN_TOGGLE);
+	tmp = swap_32(td_int[nint].link);
+	usb_fill_td(mytd, tmp, status, info, (unsigned long)buffer,
+		    (unsigned long)dev);
+	/* Link it */
+	tmp = swap_32((unsigned long)mytd);
+	td_int[nint].link = tmp;
+
+	usb_dotoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
+
+	return 0;
+}
+
+/**********************************************************************
+ * Low Level functions
+ */
+
+void reset_hc(void)
+{
+
+	/* Global reset for 100ms */
+	out16r(usb_base_addr + USBPORTSC1, 0x0204);
+	out16r(usb_base_addr + USBPORTSC2, 0x0204);
+	out16r(usb_base_addr + USBCMD, USBCMD_GRESET | USBCMD_RS);
+	/* Turn off all interrupts */
+	out16r(usb_base_addr + USBINTR, 0);
+	wait_ms(50);
+	out16r(usb_base_addr + USBCMD, 0);
+	wait_ms(10);
+}
+
+void start_hc(void)
+{
+	int timeout = 1000;
+
+	while (in16r(usb_base_addr + USBCMD) & USBCMD_HCRESET) {
+		if (!--timeout) {
+			printf("USBCMD_HCRESET timed out!\n");
+			break;
+		}
+	}
+	/* Turn on all interrupts */
+	out16r(usb_base_addr + USBINTR,
+	       USBINTR_TIMEOUT | USBINTR_RESUME | USBINTR_IOC | USBINTR_SP);
+	/* Start at frame 0 */
+	out16r(usb_base_addr + USBFRNUM, 0);
+	/* set Framebuffer base address */
+	out32r(usb_base_addr + USBFLBASEADD, (unsigned long)&framelist);
+	/* Run and mark it configured with a 64-byte max packet */
+	out16r(usb_base_addr + USBCMD, USBCMD_RS | USBCMD_CF | USBCMD_MAXP);
+}
+
+/* Initialize the skeleton
+ */
+void usb_init_skel(void)
+{
+	unsigned long temp;
+	int n;
+
+	for (n = 0; n < USB_MAX_TEMP_INT_TD; n++)
+		tmp_int_td[n].dev_ptr = 0L;	/* no devices connected */
+	/* last td */
+	usb_fill_td(&td_last, UHCI_PTR_TERM, TD_CTRL_IOC, USB_PID_OUT, 0, 0L);
+	/* usb_fill_td(&td_last,UHCI_PTR_TERM,0,0,0); */
+	/* End Queue Header */
+	usb_fill_qh(&qh_end, UHCI_PTR_TERM, (unsigned long)&td_last);
+	/* Bulk Queue Header */
+	temp = (unsigned long)&qh_end;
+	usb_fill_qh(&qh_bulk, temp | UHCI_PTR_QH, UHCI_PTR_TERM);
+	/* Control Queue Header */
+	temp = (unsigned long)&qh_bulk;
+	usb_fill_qh(&qh_cntrl, temp | UHCI_PTR_QH, UHCI_PTR_TERM);
+	/* 1ms Interrupt td */
+	temp = (unsigned long)&qh_cntrl;
+	usb_fill_td(&td_int[0], temp | UHCI_PTR_QH, 0, USB_PID_OUT, 0, 0L);
+	temp = (unsigned long)&td_int[0];
+	for (n = 1; n < 8; n++)
+		usb_fill_td(&td_int[n], temp, 0, USB_PID_OUT, 0, 0L);
+	for (n = 0; n < 1024; n++) {
+		/* link all framelist pointers to one of the interrupts */
+		int m, o;
+		if ((n & 127) == 127)
+			framelist[n] = swap_32((unsigned long)&td_int[0]);
+		else
+			for (o = 1, m = 2; m <= 128; o++, m += m)
+				if ((n & (m - 1)) == ((m - 1) / 2))
+					framelist[n] =
+					    swap_32((unsigned long)&td_int[o]);
+
+	}
+}
+
+/* check the common skeleton for completed transfers, and update the status
+ * of the "connected" device. Called from the IRQ routine.
+ */
+void usb_check_skel(void)
+{
+	struct usb_device *dev;
+	/* start with the control qh */
+	if (qh_cntrl.dev_ptr != 0) {	/* it's a device assigned check if this caused IRQ */
+		dev = (struct usb_device *)qh_cntrl.dev_ptr;
+		/* Flush cache now that hardware updated DATA and TDs/QHs */
+		if (!leon3_snooping_avail)
+			sparc_dcache_flush_all();
+		usb_get_td_status(&tmp_td[0], dev);	/* update status */
+		if (!(dev->status & USB_ST_NOT_PROC)) {	/* is not active anymore, disconnect devices */
+			qh_cntrl.dev_ptr = 0;
+		}
+	}
+	/* now process the bulk */
+	if (qh_bulk.dev_ptr != 0) {	/* it's a device assigned check if this caused IRQ */
+		dev = (struct usb_device *)qh_bulk.dev_ptr;
+		/* Flush cache now that hardware updated DATA and TDs/QHs */
+		if (!leon3_snooping_avail)
+			sparc_dcache_flush_all();
+		usb_get_td_status(&tmp_td[0], dev);	/* update status */
+		if (!(dev->status & USB_ST_NOT_PROC)) {	/* is not active anymore, disconnect devices */
+			qh_bulk.dev_ptr = 0;
+		}
+	}
+}
+
+/* check the interrupt chain, ubdate the status of the appropriate device,
+ * call the appropriate irqhandler and reactivate the TD if the irqhandler
+ * returns with 1
+ */
+void usb_check_int_chain(void)
+{
+	int i, res;
+	unsigned long link, status;
+	struct usb_device *dev;
+	uhci_td_t *td, *prevtd;
+
+	for (i = 0; i < 8; i++) {
+		prevtd = &td_int[i];	/* the first previous td is the skeleton td */
+		link = swap_32(READ32(&td_int[i].link)) & 0xfffffff0;	/* next in chain */
+		td = (uhci_td_t *) link;	/* assign it */
+		/* all interrupt TDs are finally linked to the td_int[0].
+		 * so we process all until we find the td_int[0].
+		 * if int0 chain points to a QH, we're also done
+		 */
+		while (((i > 0) && (link != (unsigned long)&td_int[0])) ||
+		       ((i == 0)
+			&& !(swap_32(READ32(&td->link)) & UHCI_PTR_QH))) {
+			/* check if a device is assigned with this td */
+			status = swap_32(READ32(&td->status));
+			if ((td->dev_ptr != 0L) && !(status & TD_CTRL_ACTIVE)) {
+				/* td is not active and a device is assigned -> call irqhandler */
+				dev = (struct usb_device *)td->dev_ptr;
+				dev->irq_act_len = ((status & 0x7FF) == 0x7FF) ? 0 : (status & 0x7FF) + 1;	/* transfered length */
+				dev->irq_status = usb_uhci_td_stat(status);	/* get status */
+				res = dev->irq_handle(dev);	/* call irqhandler */
+				if (res == 1) {
+					/* reactivate */
+					status |= TD_CTRL_ACTIVE;
+					td->status = swap_32(status);
+					prevtd = td;	/* previous td = this td */
+				} else {
+					prevtd->link = READ32(&td->link);	/* link previous td directly to the nex td -> unlinked */
+					/* remove device pointer */
+					td->dev_ptr = 0L;
+				}
+			}	/* if we call the irq handler */
+			link = swap_32(READ32(&td->link)) & 0xfffffff0;	/* next in chain */
+			td = (uhci_td_t *) link;	/* assign it */
+		}		/* process all td in this int chain */
+	}			/* next interrupt chain */
+}
+
+/* usb interrupt service routine.
+ */
+void handle_usb_interrupt(void)
+{
+	unsigned short status;
+	static int error = 0;
+
+	/*
+	 * Read the interrupt status, and write it back to clear the
+	 * interrupt cause
+	 */
+
+	status = in16r(usb_base_addr + USBSTS);
+
+	if (!status)		/* shared interrupt, not mine */
+		return;
+	if (status != 1) {
+		/* remove host controller halted state */
+		if ((status & (USBSTS_HCPE | USBSTS_HCH)) ==
+		    (USBSTS_HCPE | USBSTS_HCH)) {
+			/* Stop due to bug in driver, or hardware */
+			out16r(usb_base_addr + USBSTS, status);
+			out16r(usb_base_addr + USBCMD,
+			       USBCMD_HCRESET | USBCMD_GRESET);
+			printf
+			    ("GRUSB: HW detected error(s) in USB Descriptors (STS: 0x%x)\n",
+			     status);
+			usb_show_td(8);
+			return;
+		} else if ((status & 0x20)
+			   && ((in16r(usb_base_addr + USBCMD) & USBCMD_RS) ==
+			       0)) {
+			if (error < 10) {
+				out16r(usb_base_addr + USBCMD,
+				       USBCMD_RS | in16r(usb_base_addr +
+							 USBCMD));
+				error++;
+			}
+		} else
+			error = 0;
+	}
+	usb_check_int_chain();	/* call interrupt handlers for int tds */
+	usb_check_skel();	/* call completion handler for common transfer routines */
+	out16r(usb_base_addr + USBSTS, status);
+}
+
+/* init uhci
+ */
+int usb_lowlevel_init(void)
+{
+	unsigned char temp;
+	ambapp_ahbdev ahbdev;
+
+	/* Find GRUSB core using AMBA Plug&Play information */
+	if (ambapp_ahbslv_first(VENDOR_GAISLER, GAISLER_UHCI, &ahbdev) != 1) {
+		printf("USB UHCI: Failed to find GRUSB controller\n");
+		return -1;
+	}
+	usb_base_addr = ahbdev.address[0];
+	grusb_irq = ahbdev.irq;
+	/*
+	   usb_base_addr = 0xfffa0000;
+	   grusb_irq = 10;
+	 */
+#ifdef USB_UHCI_DEBUG
+	grusb_show_regs();
+#endif
+	memset(td_int, 0, sizeof(td_int));
+	memset(tmp_td, 0, sizeof(tmp_td));
+	memset(tmp_int_td, 0, sizeof(tmp_int_td));
+	memset(&qh_cntrl, 0, sizeof(qh_cntrl));
+	memset(&qh_end, 0, sizeof(qh_end));
+	memset(&td_last, 0, sizeof(td_last));
+
+	irq_free_handler(grusb_irq);
+	USB_UHCI_PRINTF("GRUSB: at 0x%lx irq %d\n", usb_base_addr, grusb_irq);
+	rh.devnum = 0;
+	usb_init_skel();
+	reset_hc();
+	start_hc();
+	irq_install_handler(grusb_irq,
+			    (interrupt_handler_t *) handle_usb_interrupt, NULL);
+	return 0;
+}
+
+/* stop uhci
+ */
+int usb_lowlevel_stop(void)
+{
+	if (grusb_irq == -1)
+		return 1;
+	irq_free_handler(grusb_irq);
+	reset_hc();
+	grusb_irq = -1;
+	return 0;
+}
+
+/*******************************************************************************************
+ * Virtual Root Hub
+ * Since the uhci does not have a real HUB, we simulate one ;-)
+ */
+#undef	USB_RH_DEBUG
+
+#ifdef	USB_RH_DEBUG
+#define	USB_RH_PRINTF(fmt,args...)	printf (fmt ,##args)
+static void usb_display_wValue(unsigned short wValue, unsigned short wIndex);
+static void usb_display_Req(unsigned short req);
+#else
+#define USB_RH_PRINTF(fmt,args...)
+static void usb_display_wValue(unsigned short wValue, unsigned short wIndex)
+{
+}
+static void usb_display_Req(unsigned short req)
+{
+}
+#endif
+
+static unsigned char root_hub_dev_des[] = {
+	0x12,			/*  __u8  bLength; */
+	0x01,			/*  __u8  bDescriptorType; Device */
+	0x00,			/*  __u16 bcdUSB; v1.0 */
+	0x01,
+	0x09,			/*  __u8  bDeviceClass; HUB_CLASSCODE */
+	0x00,			/*  __u8  bDeviceSubClass; */
+	0x00,			/*  __u8  bDeviceProtocol; */
+	0x08,			/*  __u8  bMaxPacketSize0; 8 Bytes */
+	0x00,			/*  __u16 idVendor; */
+	0x00,
+	0x00,			/*  __u16 idProduct; */
+	0x00,
+	0x00,			/*  __u16 bcdDevice; */
+	0x00,
+	0x01,			/*  __u8  iManufacturer; */
+	0x00,			/*  __u8  iProduct; */
+	0x00,			/*  __u8  iSerialNumber; */
+	0x01			/*  __u8  bNumConfigurations; */
+};
+
+/* Configuration descriptor */
+static unsigned char root_hub_config_des[] = {
+	0x09,			/*  __u8  bLength; */
+	0x02,			/*  __u8  bDescriptorType; Configuration */
+	0x19,			/*  __u16 wTotalLength; */
+	0x00,
+	0x01,			/*  __u8  bNumInterfaces; */
+	0x01,			/*  __u8  bConfigurationValue; */
+	0x00,			/*  __u8  iConfiguration; */
+	0x40,			/*  __u8  bmAttributes;
+				   Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
+	0x00,			/*  __u8  MaxPower; */
+
+	/* interface */
+	0x09,			/*  __u8  if_bLength; */
+	0x04,			/*  __u8  if_bDescriptorType; Interface */
+	0x00,			/*  __u8  if_bInterfaceNumber; */
+	0x00,			/*  __u8  if_bAlternateSetting; */
+	0x01,			/*  __u8  if_bNumEndpoints; */
+	0x09,			/*  __u8  if_bInterfaceClass; HUB_CLASSCODE */
+	0x00,			/*  __u8  if_bInterfaceSubClass; */
+	0x00,			/*  __u8  if_bInterfaceProtocol; */
+	0x00,			/*  __u8  if_iInterface; */
+
+	/* endpoint */
+	0x07,			/*  __u8  ep_bLength; */
+	0x05,			/*  __u8  ep_bDescriptorType; Endpoint */
+	0x81,			/*  __u8  ep_bEndpointAddress; IN Endpoint 1 */
+	0x03,			/*  __u8  ep_bmAttributes; Interrupt */
+	0x08,			/*  __u16 ep_wMaxPacketSize; 8 Bytes */
+	0x00,
+	0xff			/*  __u8  ep_bInterval; 255 ms */
+};
+
+static unsigned char root_hub_hub_des[] = {
+	0x09,			/*  __u8  bLength; */
+	0x29,			/*  __u8  bDescriptorType; Hub-descriptor */
+	0x02,			/*  __u8  bNbrPorts; */
+	0x00,			/* __u16  wHubCharacteristics; */
+	0x00,
+	0x01,			/*  __u8  bPwrOn2pwrGood; 2ms */
+	0x00,			/*  __u8  bHubContrCurrent; 0 mA */
+	0x00,			/*  __u8  DeviceRemovable; *** 7 Ports max *** */
+	0xff			/*  __u8  PortPwrCtrlMask; *** 7 ports max *** */
+};
+
+static unsigned char root_hub_str_index0[] = {
+	0x04,			/*  __u8  bLength; */
+	0x03,			/*  __u8  bDescriptorType; String-descriptor */
+	0x09,			/*  __u8  lang ID */
+	0x04,			/*  __u8  lang ID */
+};
+
+static unsigned char root_hub_str_index1[] = {
+	28,			/*  __u8  bLength; */
+	0x03,			/*  __u8  bDescriptorType; String-descriptor */
+	'U',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'H',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'C',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'I',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	' ',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'R',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'o',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'o',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	't',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	' ',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'H',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'u',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+	'b',			/*  __u8  Unicode */
+	0,			/*  __u8  Unicode */
+};
+
+/*
+ * Root Hub Control Pipe (interrupt Pipes are not supported)
+ */
+
+int uhci_submit_rh_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+		       int transfer_len, struct devrequest *cmd)
+{
+	void *data = buffer;
+	int leni = transfer_len;
+	int len = 0;
+	int status = 0;
+	int stat = 0;
+	int i;
+
+	unsigned short cstatus;
+
+	unsigned short bmRType_bReq;
+	unsigned short wValue;
+	unsigned short wIndex;
+	unsigned short wLength;
+
+	if ((pipe & PIPE_INTERRUPT) == PIPE_INTERRUPT) {
+		printf("Root-Hub submit IRQ: NOT implemented\n");
+		return 0;
+	}
+	bmRType_bReq = cmd->requesttype | cmd->request << 8;
+	wValue = swap_16(cmd->value);
+	wIndex = swap_16(cmd->index);
+	wLength = swap_16(cmd->length);
+	usb_display_Req(bmRType_bReq);
+	for (i = 0; i < 8; i++)
+		rh.c_p_r[i] = 0;
+	USB_RH_PRINTF("Root-Hub: adr: %2x cmd(%1x): %02x%02x %04x %04x %04x\n",
+		      dev->devnum, 8, cmd->requesttype, cmd->request, wValue,
+		      wIndex, wLength);
+
+	switch (bmRType_bReq) {
+		/* Request Destination:
+		   without flags: Device,
+		   RH_INTERFACE: interface,
+		   RH_ENDPOINT: endpoint,
+		   RH_CLASS means HUB here,
+		   RH_OTHER | RH_CLASS  almost ever means HUB_PORT here
+		 */
+
+	case RH_GET_STATUS:
+		*(unsigned short *)data = swap_16(1);
+		len = 2;
+		break;
+	case RH_GET_STATUS | RH_INTERFACE:
+		*(unsigned short *)data = swap_16(0);
+		len = 2;
+		break;
+	case RH_GET_STATUS | RH_ENDPOINT:
+		*(unsigned short *)data = swap_16(0);
+		len = 2;
+		break;
+	case RH_GET_STATUS | RH_CLASS:
+		*(unsigned long *)data = swap_32(0);
+		len = 4;
+		break;		/* hub power ** */
+	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+
+		status = in16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1));
+		cstatus = ((status & USBPORTSC_CSC) >> (1 - 0)) |
+		    ((status & USBPORTSC_PEC) >> (3 - 1)) |
+		    (rh.c_p_r[wIndex - 1] << (0 + 4));
+		status = (status & USBPORTSC_CCS) | ((status & USBPORTSC_PE) >> (2 - 1)) | ((status & USBPORTSC_SUSP) >> (12 - 2)) | ((status & USBPORTSC_PR) >> (9 - 4)) | (1 << 8) |	/* power on ** */
+		    ((status & USBPORTSC_LSDA) << (-8 + 9));
+
+		*(unsigned short *)data = swap_16(status);
+		*(unsigned short *)(data + 2) = swap_16(cstatus);
+		len = 4;
+		break;
+	case RH_CLEAR_FEATURE | RH_ENDPOINT:
+		switch (wValue) {
+		case (RH_ENDPOINT_STALL):
+			len = 0;
+			break;
+		}
+		break;
+
+	case RH_CLEAR_FEATURE | RH_CLASS:
+		switch (wValue) {
+		case (RH_C_HUB_OVER_CURRENT):
+			len = 0;	/* hub power over current ** */
+			break;
+		}
+		break;
+
+	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+		usb_display_wValue(wValue, wIndex);
+		switch (wValue) {
+		case (RH_PORT_ENABLE):
+			status =
+			    in16r(usb_base_addr + USBPORTSC1 +
+				  2 * (wIndex - 1));
+			status = (status & 0xfff5) & ~USBPORTSC_PE;
+			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
+			       status);
+			len = 0;
+			break;
+		case (RH_PORT_SUSPEND):
+			status =
+			    in16r(usb_base_addr + USBPORTSC1 +
+				  2 * (wIndex - 1));
+			status = (status & 0xfff5) & ~USBPORTSC_SUSP;
+			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
+			       status);
+			len = 0;
+			break;
+		case (RH_PORT_POWER):
+			len = 0;	/* port power ** */
+			break;
+		case (RH_C_PORT_CONNECTION):
+			status =
+			    in16r(usb_base_addr + USBPORTSC1 +
+				  2 * (wIndex - 1));
+			status = (status & 0xfff5) | USBPORTSC_CSC;
+			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
+			       status);
+			len = 0;
+			break;
+		case (RH_C_PORT_ENABLE):
+			status =
+			    in16r(usb_base_addr + USBPORTSC1 +
+				  2 * (wIndex - 1));
+			status = (status & 0xfff5) | USBPORTSC_PEC;
+			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
+			       status);
+			len = 0;
+			break;
+		case (RH_C_PORT_SUSPEND):
+/*** WR_RH_PORTSTAT(RH_PS_PSSC); */
+			len = 0;
+			break;
+		case (RH_C_PORT_OVER_CURRENT):
+			len = 0;
+			break;
+		case (RH_C_PORT_RESET):
+			rh.c_p_r[wIndex - 1] = 0;
+			len = 0;
+			break;
+		}
+		break;
+	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+		usb_display_wValue(wValue, wIndex);
+		switch (wValue) {
+		case (RH_PORT_SUSPEND):
+			status =
+			    in16r(usb_base_addr + USBPORTSC1 +
+				  2 * (wIndex - 1));
+			status = (status & 0xfff5) | USBPORTSC_SUSP;
+			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
+			       status);
+			len = 0;
+			break;
+		case (RH_PORT_RESET):
+			status =
+			    in16r(usb_base_addr + USBPORTSC1 +
+				  2 * (wIndex - 1));
+			status = (status & 0xfff5) | USBPORTSC_PR;
+			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
+			       status);
+			wait_ms(10);
+			status = (status & 0xfff5) & ~USBPORTSC_PR;
+			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
+			       status);
+			udelay(10);
+			status = (status & 0xfff5) | USBPORTSC_PE;
+			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
+			       status);
+			wait_ms(10);
+			status = (status & 0xfff5) | 0xa;
+			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
+			       status);
+			len = 0;
+			break;
+		case (RH_PORT_POWER):
+			len = 0;	/* port power ** */
+			break;
+		case (RH_PORT_ENABLE):
+			status =
+			    in16r(usb_base_addr + USBPORTSC1 +
+				  2 * (wIndex - 1));
+			status = (status & 0xfff5) | USBPORTSC_PE;
+			out16r(usb_base_addr + USBPORTSC1 + 2 * (wIndex - 1),
+			       status);
+			len = 0;
+			break;
+		}
+		break;
+
+	case RH_SET_ADDRESS:
+		rh.devnum = wValue;
+		len = 0;
+		break;
+	case RH_GET_DESCRIPTOR:
+		switch ((wValue & 0xff00) >> 8) {
+		case (0x01):	/* device descriptor */
+			i = sizeof(root_hub_config_des);
+			status = i > wLength ? wLength : i;
+			len = leni > status ? status : leni;
+			memcpy(data, root_hub_dev_des, len);
+			break;
+		case (0x02):	/* configuration descriptor */
+			i = sizeof(root_hub_config_des);
+			status = i > wLength ? wLength : i;
+			len = leni > status ? status : leni;
+			memcpy(data, root_hub_config_des, len);
+			break;
+		case (0x03):	/*string descriptors */
+			if (wValue == 0x0300) {
+				i = sizeof(root_hub_str_index0);
+				status = i > wLength ? wLength : i;
+				len = leni > status ? status : leni;
+				memcpy(data, root_hub_str_index0, len);
+				break;
+			}
+			if (wValue == 0x0301) {
+				i = sizeof(root_hub_str_index1);
+				status = i > wLength ? wLength : i;
+				len = leni > status ? status : leni;
+				memcpy(data, root_hub_str_index1, len);
+				break;
+			}
+			stat = USB_ST_STALLED;
+		}
+		break;
+
+	case RH_GET_DESCRIPTOR | RH_CLASS:
+		root_hub_hub_des[2] = 2;
+		i = sizeof(root_hub_hub_des);
+		status = i > wLength ? wLength : i;
+		len = leni > status ? status : leni;
+		memcpy(data, root_hub_hub_des, len);
+		break;
+	case RH_GET_CONFIGURATION:
+		*(unsigned char *)data = 0x01;
+		len = 1;
+		break;
+	case RH_SET_CONFIGURATION:
+		len = 0;
+		break;
+	default:
+		stat = USB_ST_STALLED;
+	}
+	USB_RH_PRINTF("Root-Hub stat %lx port1: %x port2: %x\n\n", stat,
+		      in16r(usb_base_addr + USBPORTSC1),
+		      in16r(usb_base_addr + USBPORTSC2));
+	dev->act_len = len;
+	dev->status = stat;
+	return stat;
+
+}
+
+/********************************************************************************
+ * Some Debug Routines
+ */
+
+#ifdef	USB_RH_DEBUG
+
+static void usb_display_Req(unsigned short req)
+{
+	USB_RH_PRINTF("- Root-Hub Request: ");
+	switch (req) {
+	case RH_GET_STATUS:
+		USB_RH_PRINTF("Get Status ");
+		break;
+	case RH_GET_STATUS | RH_INTERFACE:
+		USB_RH_PRINTF("Get Status Interface ");
+		break;
+	case RH_GET_STATUS | RH_ENDPOINT:
+		USB_RH_PRINTF("Get Status Endpoint ");
+		break;
+	case RH_GET_STATUS | RH_CLASS:
+		USB_RH_PRINTF("Get Status Class");
+		break;		/* hub power ** */
+	case RH_GET_STATUS | RH_OTHER | RH_CLASS:
+		USB_RH_PRINTF("Get Status Class Others");
+		break;
+	case RH_CLEAR_FEATURE | RH_ENDPOINT:
+		USB_RH_PRINTF("Clear Feature Endpoint ");
+		break;
+	case RH_CLEAR_FEATURE | RH_CLASS:
+		USB_RH_PRINTF("Clear Feature Class ");
+		break;
+	case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
+		USB_RH_PRINTF("Clear Feature Other Class ");
+		break;
+	case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
+		USB_RH_PRINTF("Set Feature Other Class ");
+		break;
+	case RH_SET_ADDRESS:
+		USB_RH_PRINTF("Set Address ");
+		break;
+	case RH_GET_DESCRIPTOR:
+		USB_RH_PRINTF("Get Descriptor ");
+		break;
+	case RH_GET_DESCRIPTOR | RH_CLASS:
+		USB_RH_PRINTF("Get Descriptor Class ");
+		break;
+	case RH_GET_CONFIGURATION:
+		USB_RH_PRINTF("Get Configuration ");
+		break;
+	case RH_SET_CONFIGURATION:
+		USB_RH_PRINTF("Get Configuration ");
+		break;
+	default:
+		USB_RH_PRINTF("****UNKNOWN**** 0x%04X ", req);
+	}
+	USB_RH_PRINTF("\n");
+
+}
+
+static void usb_display_wValue(unsigned short wValue, unsigned short wIndex)
+{
+	switch (wValue) {
+	case (RH_PORT_ENABLE):
+		USB_RH_PRINTF("Root-Hub: Enable Port %d\n", wIndex);
+		break;
+	case (RH_PORT_SUSPEND):
+		USB_RH_PRINTF("Root-Hub: Suspend Port %d\n", wIndex);
+		break;
+	case (RH_PORT_POWER):
+		USB_RH_PRINTF("Root-Hub: Port Power %d\n", wIndex);
+		break;
+	case (RH_C_PORT_CONNECTION):
+		USB_RH_PRINTF("Root-Hub: C Port Connection Port %d\n", wIndex);
+		break;
+	case (RH_C_PORT_ENABLE):
+		USB_RH_PRINTF("Root-Hub: C Port Enable Port %d\n", wIndex);
+		break;
+	case (RH_C_PORT_SUSPEND):
+		USB_RH_PRINTF("Root-Hub: C Port Suspend Port %d\n", wIndex);
+		break;
+	case (RH_C_PORT_OVER_CURRENT):
+		USB_RH_PRINTF("Root-Hub: C Port Over Current Port %d\n",
+			      wIndex);
+		break;
+	case (RH_C_PORT_RESET):
+		USB_RH_PRINTF("Root-Hub: C Port reset Port %d\n", wIndex);
+		break;
+	default:
+		USB_RH_PRINTF("Root-Hub: unknown %x %x\n", wValue, wIndex);
+		break;
+	}
+}
+
+#endif
+
+/*#ifdef	USB_UHCI_DEBUG*/
+
+static int usb_display_td(uhci_td_t * td)
+{
+	unsigned long tmp;
+	int valid;
+
+	printf("TD at %p:\n", td);
+
+	tmp = swap_32(READ32(&td->link));
+	printf("Link points to 0x%08lX, %s first, %s, %s\n", tmp & 0xfffffff0,
+	       ((tmp & 0x4) == 0x4) ? "Depth" : "Breath",
+	       ((tmp & 0x2) == 0x2) ? "QH" : "TD",
+	       ((tmp & 0x1) == 0x1) ? "invalid" : "valid");
+	valid = ((tmp & 0x1) == 0x0);
+	tmp = swap_32(READ32(&td->status));
+	printf
+	    ("     %s %ld Errors %s %s %s \n     %s %s %s %s %s %s\n     Len 0x%lX\n",
+	     (((tmp >> 29) & 0x1) == 0x1) ? "SPD Enable" : "SPD Disable",
+	     ((tmp >> 28) & 0x3),
+	     (((tmp >> 26) & 0x1) == 0x1) ? "Low Speed" : "Full Speed",
+	     (((tmp >> 25) & 0x1) == 0x1) ? "ISO " : "",
+	     (((tmp >> 24) & 0x1) == 0x1) ? "IOC " : "",
+	     (((tmp >> 23) & 0x1) == 0x1) ? "Active " : "Inactive ",
+	     (((tmp >> 22) & 0x1) == 0x1) ? "Stalled" : "",
+	     (((tmp >> 21) & 0x1) == 0x1) ? "Data Buffer Error" : "",
+	     (((tmp >> 20) & 0x1) == 0x1) ? "Babble" : "",
+	     (((tmp >> 19) & 0x1) == 0x1) ? "NAK" : "",
+	     (((tmp >> 18) & 0x1) == 0x1) ? "Bitstuff Error" : "",
+	     (tmp & 0x7ff));
+	tmp = swap_32(READ32(&td->info));
+	printf("     MaxLen 0x%lX\n", ((tmp >> 21) & 0x7FF));
+	printf("     %sEndpoint 0x%lX Dev Addr 0x%lX PID 0x%lX\n",
+	       ((tmp >> 19) & 0x1) == 0x1 ? "TOGGLE " : "", ((tmp >> 15) & 0xF),
+	       ((tmp >> 8) & 0x7F), tmp & 0xFF);
+	tmp = swap_32(READ32(&td->buffer));
+	printf("     Buffer 0x%08lX\n", tmp);
+	printf("     DEV %08lX\n", td->dev_ptr);
+	return valid;
+}
+
+void usb_show_td(int max)
+{
+	int i;
+	if (max > 0) {
+		for (i = 0; i < max; i++) {
+			usb_display_td(&tmp_td[i]);
+		}
+	} else {
+		i = 0;
+		do {
+			printf("tmp_td[%d]\n", i);
+		} while (usb_display_td(&tmp_td[i++]));
+	}
+}
+
+void grusb_show_regs(void)
+{
+	unsigned int tmp;
+
+	tmp = in16r(usb_base_addr + USBCMD);
+	printf(" USBCMD:   0x%04x\n", tmp);
+	tmp = in16r(usb_base_addr + USBSTS);
+	printf(" USBSTS:   0x%04x\n", tmp);
+	tmp = in16r(usb_base_addr + USBINTR);
+	printf(" USBINTR:   0x%04x\n", tmp);
+	tmp = in16r(usb_base_addr + USBFRNUM);
+	printf(" FRNUM:   0x%04x\n", tmp);
+	tmp = in32r(usb_base_addr + USBFLBASEADD);
+	printf(" FLBASEADD:   0x%08x\n", tmp);
+	tmp = in16r(usb_base_addr + USBSOF);
+	printf(" SOFMOD:   0x%04x\n", tmp);
+	tmp = in16r(usb_base_addr + USBPORTSC1);
+	printf(" PORTSC1:   0x%04x\n", tmp);
+}
+
+/*#endif*/
+#endif				/* CONFIG_USB_UHCI */
+
+/* EOF */
diff --git a/cpu/leon3/usb_uhci.h b/cpu/leon3/usb_uhci.h
new file mode 100644
index 0000000..bf572a6
--- /dev/null
+++ b/cpu/leon3/usb_uhci.h
@@ -0,0 +1,184 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter, MPL AG Switzerland
+ *
+ * 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
+ *
+ * Note: Part of this code has been derived from linux
+ *
+ */
+#ifndef _USB_UHCI_H_
+#define _USB_UHCI_H_
+
+/* Command register */
+#define USBCMD		0
+#define   USBCMD_RS       0x0001	/* Run/Stop */
+#define   USBCMD_HCRESET  0x0002	/* Host reset */
+#define   USBCMD_GRESET   0x0004	/* Global reset */
+#define   USBCMD_EGSM     0x0008	/* Global Suspend Mode */
+#define   USBCMD_FGR      0x0010	/* Force Global Resume */
+#define   USBCMD_SWDBG    0x0020	/* SW Debug mode */
+#define   USBCMD_CF       0x0040	/* Config Flag (sw only) */
+#define   USBCMD_MAXP     0x0080	/* Max Packet (0 = 32, 1 = 64) */
+
+/* Status register */
+#define USBSTS		2
+#define   USBSTS_USBINT   0x0001	/* Interrupt due to IOC */
+#define   USBSTS_ERROR    0x0002	/* Interrupt due to error */
+#define   USBSTS_RD       0x0004	/* Resume Detect */
+#define   USBSTS_HSE      0x0008	/* Host System Error - basically PCI problems */
+#define   USBSTS_HCPE     0x0010	/* Host Controller Process Error - the scripts were buggy */
+#define   USBSTS_HCH      0x0020	/* HC Halted */
+
+/* Interrupt enable register */
+#define USBINTR		4
+#define   USBINTR_TIMEOUT 0x0001	/* Timeout/CRC error enable */
+#define   USBINTR_RESUME  0x0002	/* Resume interrupt enable */
+#define   USBINTR_IOC     0x0004	/* Interrupt On Complete enable */
+#define   USBINTR_SP      0x0008	/* Short packet interrupt enable */
+
+#define USBFRNUM      6
+#define USBFLBASEADD  8
+#define USBSOF        12
+
+/* USB port status and control registers */
+#define USBPORTSC1	16
+#define USBPORTSC2	18
+#define   USBPORTSC_CCS   0x0001	/* Current Connect Status ("device present") */
+#define   USBPORTSC_CSC   0x0002	/* Connect Status Change */
+#define   USBPORTSC_PE    0x0004	/* Port Enable */
+#define   USBPORTSC_PEC   0x0008	/* Port Enable Change */
+#define   USBPORTSC_LS    0x0030	/* Line Status */
+#define   USBPORTSC_RD    0x0040	/* Resume Detect */
+#define   USBPORTSC_LSDA  0x0100	/* Low Speed Device Attached */
+#define   USBPORTSC_PR    0x0200	/* Port Reset */
+#define   USBPORTSC_SUSP  0x1000	/* Suspend */
+
+/* Legacy support register */
+#define USBLEGSUP 0xc0
+#define USBLEGSUP_DEFAULT 0x2000	/* only PIRQ enable set */
+
+#define UHCI_NULL_DATA_SIZE 0x7ff	/* for UHCI controller TD */
+#define UHCI_PID            0xff	/* PID MASK */
+
+#define UHCI_PTR_BITS       0x000F
+#define UHCI_PTR_TERM       0x0001
+#define UHCI_PTR_QH         0x0002
+#define UHCI_PTR_DEPTH      0x0004
+
+/* for TD <status>: */
+#define TD_CTRL_SPD         (1 << 29)	/* Short Packet Detect */
+#define TD_CTRL_C_ERR_MASK  (3 << 27)	/* Error Counter bits */
+#define TD_CTRL_LS          (1 << 26)	/* Low Speed Device */
+#define TD_CTRL_IOS         (1 << 25)	/* Isochronous Select */
+#define TD_CTRL_IOC         (1 << 24)	/* Interrupt on Complete */
+#define TD_CTRL_ACTIVE      (1 << 23)	/* TD Active */
+#define TD_CTRL_STALLED     (1 << 22)	/* TD Stalled */
+#define TD_CTRL_DBUFERR     (1 << 21)	/* Data Buffer Error */
+#define TD_CTRL_BABBLE      (1 << 20)	/* Babble Detected */
+#define TD_CTRL_NAK         (1 << 19)	/* NAK Received */
+#define TD_CTRL_CRCTIMEO    (1 << 18)	/* CRC/Time Out Error */
+#define TD_CTRL_BITSTUFF    (1 << 17)	/* Bit Stuff Error */
+#define TD_CTRL_ACTLEN_MASK 0x7ff	/* actual length, encoded as n - 1 */
+
+#define TD_CTRL_ANY_ERROR	(TD_CTRL_STALLED | TD_CTRL_DBUFERR | \
+				 TD_CTRL_BABBLE | TD_CTRL_CRCTIME | TD_CTRL_BITSTUFF)
+
+#define TD_TOKEN_TOGGLE		19
+
+/* ------------------------------------------------------------------------------------
+   Virtual Root HUB
+   ------------------------------------------------------------------------------------ */
+/* destination of request */
+#define RH_INTERFACE               0x01
+#define RH_ENDPOINT                0x02
+#define RH_OTHER                   0x03
+
+#define RH_CLASS                   0x20
+#define RH_VENDOR                  0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS           0x0080
+#define RH_CLEAR_FEATURE        0x0100
+#define RH_SET_FEATURE          0x0300
+#define RH_SET_ADDRESS          0x0500
+#define RH_GET_DESCRIPTOR       0x0680
+#define RH_SET_DESCRIPTOR       0x0700
+#define RH_GET_CONFIGURATION    0x0880
+#define RH_SET_CONFIGURATION    0x0900
+#define RH_GET_STATE            0x0280
+#define RH_GET_INTERFACE        0x0A80
+#define RH_SET_INTERFACE        0x0B00
+#define RH_SYNC_FRAME           0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP               0x2000
+
+/* Hub port features */
+#define RH_PORT_CONNECTION         0x00
+#define RH_PORT_ENABLE             0x01
+#define RH_PORT_SUSPEND            0x02
+#define RH_PORT_OVER_CURRENT       0x03
+#define RH_PORT_RESET              0x04
+#define RH_PORT_POWER              0x08
+#define RH_PORT_LOW_SPEED          0x09
+#define RH_C_PORT_CONNECTION       0x10
+#define RH_C_PORT_ENABLE           0x11
+#define RH_C_PORT_SUSPEND          0x12
+#define RH_C_PORT_OVER_CURRENT     0x13
+#define RH_C_PORT_RESET            0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER       0x00
+#define RH_C_HUB_OVER_CURRENT      0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP    0x00
+#define RH_ENDPOINT_STALL          0x01
+
+/* Our Vendor Specific feature */
+#define RH_REMOVE_EP               0x00
+
+#define RH_ACK                     0x01
+#define RH_REQ_ERR                 -1
+#define RH_NACK                    0x00
+
+/* Transfer descriptor structure */
+typedef struct {
+	unsigned long link;	/* next td/qh (LE) */
+	unsigned long status;	/* status of the td */
+	unsigned long info;	/* Max Lenght / Endpoint / device address and PID */
+	unsigned long buffer;	/* pointer to data buffer (LE) */
+	unsigned long dev_ptr;	/* pointer to the assigned device (BE) */
+	unsigned long res[3];	/* reserved (TDs must be 8Byte aligned) */
+} uhci_td_t, *puhci_td_t;
+
+/* Queue Header structure */
+typedef struct {
+	unsigned long head;	/* Next QH (LE) */
+	unsigned long element;	/* Queue element pointer (LE) */
+	unsigned long res[5];	/* reserved */
+	unsigned long dev_ptr;	/* if 0 no tds have been assigned to this qh */
+} uhci_qh_t, *puhci_qh_t;
+
+struct virt_root_hub {
+	int devnum;		/* Address of Root Hub endpoint */
+	int numports;		/* number of ports */
+	int c_p_r[8];		/* C_PORT_RESET */
+};
+
+#endif				/* _USB_UHCI_H_ */
diff --git a/cpu/mpc83xx/spd_sdram.c b/cpu/mpc83xx/spd_sdram.c
index 97ac7bb..70cd410 100644
--- a/cpu/mpc83xx/spd_sdram.c
+++ b/cpu/mpc83xx/spd_sdram.c
@@ -601,7 +601,7 @@
 	debug("DDR:timing_cfg_2=0x%08x\n", ddr->timing_cfg_2);
 
 	/* Check DIMM data bus width */
-	if (spd.dataw_lsb == 0x20) {
+	if (spd.dataw_lsb < 64) {
 		if (spd.mem_type == SPD_MEMTYPE_DDR)
 			burstlen = 0x03; /* 32 bit data bus, burst len is 8 */
 		else
@@ -763,7 +763,7 @@
 		sdram_cfg |= SDRAM_CFG_RD_EN;
 
 	/* The DIMM is 32bit width */
-	if (spd.dataw_lsb == 0x20) {
+	if (spd.dataw_lsb < 64) {
 		if (spd.mem_type == SPD_MEMTYPE_DDR)
 			sdram_cfg |= SDRAM_CFG_32_BE | SDRAM_CFG_8_BE;
 		if (spd.mem_type == SPD_MEMTYPE_DDR2)
diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c
index fce0c48..e3240b5 100644
--- a/cpu/mpc85xx/cpu_init.c
+++ b/cpu/mpc85xx/cpu_init.c
@@ -272,7 +272,7 @@
 	uint l2srbar;
 
 	svr = get_svr();
-	ver = SVR_VER(svr);
+	ver = SVR_SOC_VER(svr);
 
 	asm("msync;isync");
 	cache_ctl = l2cache->l2ctl;
diff --git a/cpu/mpc85xx/mp.c b/cpu/mpc85xx/mp.c
index 7b10fba..e733f7b 100644
--- a/cpu/mpc85xx/mp.c
+++ b/cpu/mpc85xx/mp.c
@@ -154,7 +154,7 @@
 	while (timeout) {
 		int i;
 		for (i = 1; i < CONFIG_NR_CPUS; i++) {
-			if (table[i * NUM_BOOT_ENTRY])
+			if (table[i * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER])
 				cpu_up_mask |= (1 << i);
 		};
 
@@ -165,6 +165,10 @@
 		timeout--;
 	}
 
+	if (timeout == 0)
+		printf("CPU up timeout. CPU up mask is %x should be %x\n",
+			cpu_up_mask, up);
+
 	/* enable time base at the platform */
 	if (whoami)
 		devdisr |= MPC85xx_DEVDISR_TB1;
diff --git a/cpu/mpc85xx/spd_sdram.c b/cpu/mpc85xx/spd_sdram.c
index abc63c4..435458a 100644
--- a/cpu/mpc85xx/spd_sdram.c
+++ b/cpu/mpc85xx/spd_sdram.c
@@ -306,7 +306,7 @@
 	 * Adjust DDR II IO voltage biasing.
 	 * Only 8548 rev 1 needs the fix
 	 */
-	if ((SVR_VER(get_svr()) == SVR_8548_E) &&
+	if ((SVR_SOC_VER(get_svr()) == SVR_8548_E) &&
 			(SVR_MJREV(get_svr()) == 1) &&
 			(spd.mem_type == SPD_MEMTYPE_DDR2)) {
 		volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index 40fddcd..e3cfb8a 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -844,25 +844,29 @@
 	void *dst = map_physmem(dest, len, MAP_NOCACHE);
 	void *dst2 = dst;
 	int flag = 0;
+	uint offset = 0;
+	unsigned int shift;
 
 	switch (info->portwidth) {
 	case FLASH_CFI_8BIT:
-		cnt = len;
+		shift = 0;
 		break;
 	case FLASH_CFI_16BIT:
-		cnt = len >> 1;
+		shift = 1;
 		break;
 	case FLASH_CFI_32BIT:
-		cnt = len >> 2;
+		shift = 2;
 		break;
 	case FLASH_CFI_64BIT:
-		cnt = len >> 3;
+		shift = 3;
 		break;
 	default:
 		retcode = ERR_INVAL;
 		goto out_unmap;
 	}
 
+	cnt = len >> shift;
+
 	while ((cnt-- > 0) && (flag == 0)) {
 		switch (info->portwidth) {
 		case FLASH_CFI_8BIT:
@@ -906,23 +910,7 @@
 		if (retcode == ERR_OK) {
 			/* reduce the number of loops by the width of
 			 * the port */
-			switch (info->portwidth) {
-			case FLASH_CFI_8BIT:
-				cnt = len;
-				break;
-			case FLASH_CFI_16BIT:
-				cnt = len >> 1;
-				break;
-			case FLASH_CFI_32BIT:
-				cnt = len >> 2;
-				break;
-			case FLASH_CFI_64BIT:
-				cnt = len >> 3;
-				break;
-			default:
-				retcode = ERR_INVAL;
-				goto out_unmap;
-			}
+			cnt = len >> shift;
 			flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
 			while (cnt-- > 0) {
 				switch (info->portwidth) {
@@ -959,36 +947,34 @@
 	case CFI_CMDSET_AMD_STANDARD:
 	case CFI_CMDSET_AMD_EXTENDED:
 		flash_unlock_seq(info,0);
-		flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_TO_BUFFER);
+
+#ifdef CONFIG_FLASH_SPANSION_S29WS_N
+		offset = ((unsigned long)dst - info->start[sector]) >> shift;
+#endif
+		flash_write_cmd(info, sector, offset, AMD_CMD_WRITE_TO_BUFFER);
+		cnt = len >> shift;
+		flash_write_cmd(info, sector, offset, (uchar)cnt - 1);
 
 		switch (info->portwidth) {
 		case FLASH_CFI_8BIT:
-			cnt = len;
-			flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
 			while (cnt-- > 0) {
 				flash_write8(flash_read8(src), dst);
 				src += 1, dst += 1;
 			}
 			break;
 		case FLASH_CFI_16BIT:
-			cnt = len >> 1;
-			flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
 			while (cnt-- > 0) {
 				flash_write16(flash_read16(src), dst);
 				src += 2, dst += 2;
 			}
 			break;
 		case FLASH_CFI_32BIT:
-			cnt = len >> 2;
-			flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
 			while (cnt-- > 0) {
 				flash_write32(flash_read32(src), dst);
 				src += 4, dst += 4;
 			}
 			break;
 		case FLASH_CFI_64BIT:
-			cnt = len >> 3;
-			flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
 			while (cnt-- > 0) {
 				flash_write64(flash_read64(src), dst);
 				src += 8, dst += 8;
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index eafd267..a4c1768 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -60,6 +60,8 @@
 COBJS-y += tsi108_eth.o
 COBJS-y += uli526x.o
 COBJS-y += vsc7385.o
+COBJS-$(CONFIG_XILINX_EMAC) += xilinx_emac.o
+COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
 
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/drivers/net/xilinx_emac.c b/drivers/net/xilinx_emac.c
new file mode 100644
index 0000000..c7f1a2a
--- /dev/null
+++ b/drivers/net/xilinx_emac.c
@@ -0,0 +1,462 @@
+/******************************************************************************
+ *
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+ * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+ * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
+ * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+ * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+ * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+ * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+ * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
+ * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+ * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+ * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+ * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * (C) Copyright 2007-2008 Michal Simek
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * (c) Copyright 2003 Xilinx Inc.
+ * All rights reserved.
+ *
+ ******************************************************************************/
+
+#include <config.h>
+#include <common.h>
+#include <net.h>
+#include <asm/io.h>
+
+#include <asm/asm.h>
+
+#undef DEBUG
+
+typedef struct {
+	u32 regbaseaddress;	/* Base address of registers */
+	u32 databaseaddress;	/* Base address of data for FIFOs */
+} xpacketfifov100b;
+
+typedef struct {
+	u32 baseaddress;	/* Base address (of IPIF) */
+	u32 isstarted;		/* Device is currently started 0-no, 1-yes */
+	xpacketfifov100b recvfifo;	/* FIFO used to receive frames */
+	xpacketfifov100b sendfifo;	/* FIFO used to send frames */
+} xemac;
+
+#define XIIF_V123B_IISR_OFFSET	32UL /* IP interrupt status register */
+#define XIIF_V123B_RESET_MASK		0xAUL
+#define XIIF_V123B_RESETR_OFFSET	64UL /* reset register */
+
+/* This constant is used with the Reset Register */
+#define XPF_RESET_FIFO_MASK		0x0000000A
+#define XPF_COUNT_STATUS_REG_OFFSET	4UL
+
+/* These constants are used with the Occupancy/Vacancy Count Register. This
+ * register also contains FIFO status */
+#define XPF_COUNT_MASK			0x0000FFFF
+#define XPF_DEADLOCK_MASK		0x20000000
+
+/* Offset of the MAC registers from the IPIF base address */
+#define XEM_REG_OFFSET		0x1100UL
+
+/*
+ * Register offsets for the Ethernet MAC. Each register is 32 bits.
+ */
+#define XEM_ECR_OFFSET	(XEM_REG_OFFSET + 0x4)	/* MAC Control */
+#define XEM_SAH_OFFSET	(XEM_REG_OFFSET + 0xC)	/* Station addr, high */
+#define XEM_SAL_OFFSET	(XEM_REG_OFFSET + 0x10)	/* Station addr, low */
+#define XEM_RPLR_OFFSET	(XEM_REG_OFFSET + 0x1C)	/* Rx packet length */
+#define XEM_TPLR_OFFSET	(XEM_REG_OFFSET + 0x20)	/* Tx packet length */
+#define XEM_TSR_OFFSET	(XEM_REG_OFFSET + 0x24)	/* Tx status */
+
+#define XEM_PFIFO_OFFSET	0x2000UL
+/* Tx registers */
+#define XEM_PFIFO_TXREG_OFFSET	(XEM_PFIFO_OFFSET + 0x0)
+/* Rx registers */
+#define XEM_PFIFO_RXREG_OFFSET	(XEM_PFIFO_OFFSET + 0x10)
+/* Tx keyhole */
+#define XEM_PFIFO_TXDATA_OFFSET	(XEM_PFIFO_OFFSET + 0x100)
+/* Rx keyhole */
+#define XEM_PFIFO_RXDATA_OFFSET	(XEM_PFIFO_OFFSET + 0x200)
+
+/*
+ * EMAC Interrupt Registers (Status and Enable) masks. These registers are
+ * part of the IPIF IP Interrupt registers
+ */
+/* A mask for all transmit interrupts, used in polled mode */
+#define XEM_EIR_XMIT_ALL_MASK	(XEM_EIR_XMIT_DONE_MASK |\
+				XEM_EIR_XMIT_ERROR_MASK | \
+				XEM_EIR_XMIT_SFIFO_EMPTY_MASK |\
+				XEM_EIR_XMIT_LFIFO_FULL_MASK)
+
+/* Xmit complete */
+#define XEM_EIR_XMIT_DONE_MASK		0x00000001UL
+/* Recv complete */
+#define XEM_EIR_RECV_DONE_MASK		0x00000002UL
+/* Xmit error */
+#define XEM_EIR_XMIT_ERROR_MASK		0x00000004UL
+/* Recv error */
+#define XEM_EIR_RECV_ERROR_MASK		0x00000008UL
+/* Xmit status fifo empty */
+#define XEM_EIR_XMIT_SFIFO_EMPTY_MASK	0x00000010UL
+/* Recv length fifo empty */
+#define XEM_EIR_RECV_LFIFO_EMPTY_MASK	0x00000020UL
+/* Xmit length fifo full */
+#define XEM_EIR_XMIT_LFIFO_FULL_MASK	0x00000040UL
+/* Recv length fifo overrun */
+#define XEM_EIR_RECV_LFIFO_OVER_MASK	0x00000080UL
+/* Recv length fifo underrun */
+#define XEM_EIR_RECV_LFIFO_UNDER_MASK	0x00000100UL
+/* Xmit status fifo overrun */
+#define XEM_EIR_XMIT_SFIFO_OVER_MASK	0x00000200UL
+/* Transmit status fifo underrun */
+#define XEM_EIR_XMIT_SFIFO_UNDER_MASK	0x00000400UL
+/* Transmit length fifo overrun */
+#define XEM_EIR_XMIT_LFIFO_OVER_MASK	0x00000800UL
+/* Transmit length fifo underrun */
+#define XEM_EIR_XMIT_LFIFO_UNDER_MASK	0x00001000UL
+/* Transmit pause pkt received */
+#define XEM_EIR_XMIT_PAUSE_MASK		0x00002000UL
+
+/*
+ * EMAC Control Register (ECR)
+ */
+/* Full duplex mode */
+#define XEM_ECR_FULL_DUPLEX_MASK	0x80000000UL
+/* Reset transmitter */
+#define XEM_ECR_XMIT_RESET_MASK		0x40000000UL
+/* Enable transmitter */
+#define XEM_ECR_XMIT_ENABLE_MASK	0x20000000UL
+/* Reset receiver */
+#define XEM_ECR_RECV_RESET_MASK		0x10000000UL
+/* Enable receiver */
+#define XEM_ECR_RECV_ENABLE_MASK	0x08000000UL
+/* Enable PHY */
+#define XEM_ECR_PHY_ENABLE_MASK		0x04000000UL
+/* Enable xmit pad insert */
+#define XEM_ECR_XMIT_PAD_ENABLE_MASK	0x02000000UL
+/* Enable xmit FCS insert */
+#define XEM_ECR_XMIT_FCS_ENABLE_MASK	0x01000000UL
+/* Enable unicast addr */
+#define XEM_ECR_UNICAST_ENABLE_MASK	0x00020000UL
+/* Enable broadcast addr */
+#define XEM_ECR_BROAD_ENABLE_MASK	0x00008000UL
+
+/*
+ * Transmit Status Register (TSR)
+ */
+/* Transmit excess deferral */
+#define XEM_TSR_EXCESS_DEFERRAL_MASK	0x80000000UL
+/* Transmit late collision */
+#define XEM_TSR_LATE_COLLISION_MASK	0x01000000UL
+
+#define ENET_MAX_MTU		PKTSIZE
+#define ENET_ADDR_LENGTH	6
+
+static unsigned int etherrxbuff[PKTSIZE_ALIGN/4]; /* Receive buffer */
+
+static u8 emacaddr[ENET_ADDR_LENGTH] = { 0x00, 0x0a, 0x35, 0x00, 0x22, 0x01 };
+
+static xemac emac;
+
+void eth_halt(void)
+{
+	debug ("eth_halt\n");
+}
+
+int eth_init(bd_t * bis)
+{
+	u32 helpreg;
+	debug ("EMAC Initialization Started\n\r");
+
+	if (emac.isstarted) {
+		puts("Emac is started\n");
+		return 0;
+	}
+
+	memset (&emac, 0, sizeof (xemac));
+
+	emac.baseaddress = XILINX_EMAC_BASEADDR;
+
+	/* Setting up FIFOs */
+	emac.recvfifo.regbaseaddress = emac.baseaddress +
+					XEM_PFIFO_RXREG_OFFSET;
+	emac.recvfifo.databaseaddress = emac.baseaddress +
+					XEM_PFIFO_RXDATA_OFFSET;
+	out_be32 (emac.recvfifo.regbaseaddress, XPF_RESET_FIFO_MASK);
+
+	emac.sendfifo.regbaseaddress = emac.baseaddress +
+					XEM_PFIFO_TXREG_OFFSET;
+	emac.sendfifo.databaseaddress = emac.baseaddress +
+					XEM_PFIFO_TXDATA_OFFSET;
+	out_be32 (emac.sendfifo.regbaseaddress, XPF_RESET_FIFO_MASK);
+
+	/* Reset the entire IPIF */
+	out_be32 (emac.baseaddress + XIIF_V123B_RESETR_OFFSET,
+					XIIF_V123B_RESET_MASK);
+
+	/* Stopping EMAC for setting up MAC */
+	helpreg = in_be32 (emac.baseaddress + XEM_ECR_OFFSET);
+	helpreg &= ~(XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK);
+	out_be32 (emac.baseaddress + XEM_ECR_OFFSET, helpreg);
+
+	if (!getenv("ethaddr")) {
+		memcpy(bis->bi_enetaddr, emacaddr, ENET_ADDR_LENGTH);
+	}
+
+	/* Set the device station address high and low registers */
+	helpreg = (bis->bi_enetaddr[0] << 8) | bis->bi_enetaddr[1];
+	out_be32 (emac.baseaddress + XEM_SAH_OFFSET, helpreg);
+	helpreg = (bis->bi_enetaddr[2] << 24) | (bis->bi_enetaddr[3] << 16) |
+			(bis->bi_enetaddr[4] << 8) | bis->bi_enetaddr[5];
+	out_be32 (emac.baseaddress + XEM_SAL_OFFSET, helpreg);
+
+	helpreg = XEM_ECR_UNICAST_ENABLE_MASK | XEM_ECR_BROAD_ENABLE_MASK |
+		XEM_ECR_FULL_DUPLEX_MASK | XEM_ECR_XMIT_FCS_ENABLE_MASK |
+		XEM_ECR_XMIT_PAD_ENABLE_MASK | XEM_ECR_PHY_ENABLE_MASK;
+	out_be32 (emac.baseaddress + XEM_ECR_OFFSET, helpreg);
+
+	emac.isstarted = 1;
+
+	/* Enable the transmitter, and receiver */
+	helpreg = in_be32 (emac.baseaddress + XEM_ECR_OFFSET);
+	helpreg &= ~(XEM_ECR_XMIT_RESET_MASK | XEM_ECR_RECV_RESET_MASK);
+	helpreg |= (XEM_ECR_XMIT_ENABLE_MASK | XEM_ECR_RECV_ENABLE_MASK);
+	out_be32 (emac.baseaddress + XEM_ECR_OFFSET, helpreg);
+
+	printf("EMAC Initialization complete\n\r");
+	return 0;
+}
+
+int eth_send(volatile void *ptr, int len)
+{
+	u32 intrstatus;
+	u32 xmitstatus;
+	u32 fifocount;
+	u32 wordcount;
+	u32 extrabytecount;
+	u32 *wordbuffer = (u32 *) ptr;
+
+	if (len > ENET_MAX_MTU)
+		len = ENET_MAX_MTU;
+
+	/*
+	 * Check for overruns and underruns for the transmit status and length
+	 * FIFOs and make sure the send packet FIFO is not deadlocked.
+	 * Any of these conditions is bad enough that we do not want to
+	 * continue. The upper layer software should reset the device to resolve
+	 * the error.
+	 */
+	intrstatus = in_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET);
+	if (intrstatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
+			XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
+		debug ("Transmitting overrun error\n");
+		return 0;
+	} else if (intrstatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
+			XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
+		debug ("Transmitting underrun error\n");
+		return 0;
+	} else if (in_be32 (emac.sendfifo.regbaseaddress +
+			XPF_COUNT_STATUS_REG_OFFSET) & XPF_DEADLOCK_MASK) {
+		debug ("Transmitting fifo error\n");
+		return 0;
+	}
+
+	/*
+	 * Before writing to the data FIFO, make sure the length FIFO is not
+	 * full. The data FIFO might not be full yet even though the length FIFO
+	 * is. This avoids an overrun condition on the length FIFO and keeps the
+	 * FIFOs in sync.
+	 *
+	 * Clear the latched LFIFO_FULL bit so next time around the most
+	 * current status is represented
+	 */
+	if (intrstatus & XEM_EIR_XMIT_LFIFO_FULL_MASK) {
+		out_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET,
+			intrstatus & XEM_EIR_XMIT_LFIFO_FULL_MASK);
+		debug ("Fifo is full\n");
+		return 0;
+	}
+
+	/* get the count of how many words may be inserted into the FIFO */
+	fifocount = in_be32 (emac.sendfifo.regbaseaddress +
+				XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK;
+	wordcount = len >> 2;
+	extrabytecount = len & 0x3;
+
+	if (fifocount < wordcount) {
+		debug ("Sending packet is larger then size of FIFO\n");
+		return 0;
+	}
+
+	for (fifocount = 0; fifocount < wordcount; fifocount++) {
+		out_be32 (emac.sendfifo.databaseaddress, wordbuffer[fifocount]);
+	}
+	if (extrabytecount > 0) {
+		u32 lastword = 0;
+		u8 *extrabytesbuffer = (u8 *) (wordbuffer + wordcount);
+
+		if (extrabytecount == 1) {
+			lastword = extrabytesbuffer[0] << 24;
+		} else if (extrabytecount == 2) {
+			lastword = extrabytesbuffer[0] << 24 |
+				extrabytesbuffer[1] << 16;
+		} else if (extrabytecount == 3) {
+			lastword = extrabytesbuffer[0] << 24 |
+				extrabytesbuffer[1] << 16 |
+				extrabytesbuffer[2] << 8;
+		}
+		out_be32 (emac.sendfifo.databaseaddress, lastword);
+	}
+
+	/* Loop on the MAC's status to wait for any pause to complete */
+	intrstatus = in_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET);
+	while ((intrstatus & XEM_EIR_XMIT_PAUSE_MASK) != 0) {
+		intrstatus = in_be32 ((emac.baseaddress) +
+					XIIF_V123B_IISR_OFFSET);
+		/* Clear the pause status from the transmit status register */
+		out_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET,
+				intrstatus & XEM_EIR_XMIT_PAUSE_MASK);
+	}
+
+	/*
+	 * Set the MAC's transmit packet length register to tell it to transmit
+	 */
+	out_be32 (emac.baseaddress + XEM_TPLR_OFFSET, len);
+
+	/*
+	 * Loop on the MAC's status to wait for the transmit to complete.
+	 * The transmit status is in the FIFO when the XMIT_DONE bit is set.
+	 */
+	do {
+		intrstatus = in_be32 ((emac.baseaddress) +
+						XIIF_V123B_IISR_OFFSET);
+	}
+	while ((intrstatus & XEM_EIR_XMIT_DONE_MASK) == 0);
+
+	xmitstatus = in_be32 (emac.baseaddress + XEM_TSR_OFFSET);
+
+	if (intrstatus & (XEM_EIR_XMIT_SFIFO_OVER_MASK |
+					XEM_EIR_XMIT_LFIFO_OVER_MASK)) {
+		debug ("Transmitting overrun error\n");
+		return 0;
+	} else if (intrstatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |
+					XEM_EIR_XMIT_LFIFO_UNDER_MASK)) {
+		debug ("Transmitting underrun error\n");
+		return 0;
+	}
+
+	/* Clear the interrupt status register of transmit statuses */
+	out_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET,
+				intrstatus & XEM_EIR_XMIT_ALL_MASK);
+
+	/*
+	 * Collision errors are stored in the transmit status register
+	 * instead of the interrupt status register
+	 */
+	if ((xmitstatus & XEM_TSR_EXCESS_DEFERRAL_MASK) ||
+				(xmitstatus & XEM_TSR_LATE_COLLISION_MASK)) {
+		debug ("Transmitting collision error\n");
+		return 0;
+	}
+	return 1;
+}
+
+int eth_rx(void)
+{
+	u32 pktlength;
+	u32 intrstatus;
+	u32 fifocount;
+	u32 wordcount;
+	u32 extrabytecount;
+	u32 lastword;
+	u8 *extrabytesbuffer;
+
+	if (in_be32 (emac.recvfifo.regbaseaddress + XPF_COUNT_STATUS_REG_OFFSET)
+			& XPF_DEADLOCK_MASK) {
+		out_be32 (emac.recvfifo.regbaseaddress, XPF_RESET_FIFO_MASK);
+		debug ("Receiving FIFO deadlock\n");
+		return 0;
+	}
+
+	/*
+	 * Get the interrupt status to know what happened (whether an error
+	 * occurred and/or whether frames have been received successfully).
+	 * When clearing the intr status register, clear only statuses that
+	 * pertain to receive.
+	 */
+	intrstatus = in_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET);
+	/*
+	 * Before reading from the length FIFO, make sure the length FIFO is not
+	 * empty. We could cause an underrun error if we try to read from an
+	 * empty FIFO.
+	 */
+	if (!(intrstatus & XEM_EIR_RECV_DONE_MASK)) {
+		/* debug ("Receiving FIFO is empty\n"); */
+		return 0;
+	}
+
+	/*
+	 * Determine, from the MAC, the length of the next packet available
+	 * in the data FIFO (there should be a non-zero length here)
+	 */
+	pktlength = in_be32 (emac.baseaddress + XEM_RPLR_OFFSET);
+	if (!pktlength) {
+		return 0;
+	}
+
+	/*
+	 * Write the RECV_DONE bit in the status register to clear it. This bit
+	 * indicates the RPLR is non-empty, and we know it's set at this point.
+	 * We clear it so that subsequent entry into this routine will reflect
+	 * the current status. This is done because the non-empty bit is latched
+	 * in the IPIF, which means it may indicate a non-empty condition even
+	 * though there is something in the FIFO.
+	 */
+	out_be32 ((emac.baseaddress) + XIIF_V123B_IISR_OFFSET,
+						XEM_EIR_RECV_DONE_MASK);
+
+	fifocount = in_be32 (emac.recvfifo.regbaseaddress +
+				XPF_COUNT_STATUS_REG_OFFSET) & XPF_COUNT_MASK;
+
+	if ((fifocount * 4) < pktlength) {
+		debug ("Receiving FIFO is smaller than packet size.\n");
+		return 0;
+	}
+
+	wordcount = pktlength >> 2;
+	extrabytecount = pktlength & 0x3;
+
+	for (fifocount = 0; fifocount < wordcount; fifocount++) {
+		etherrxbuff[fifocount] =
+				in_be32 (emac.recvfifo.databaseaddress);
+	}
+
+	/*
+	 * if there are extra bytes to handle, read the last word from the FIFO
+	 * and insert the extra bytes into the buffer
+	 */
+	if (extrabytecount > 0) {
+		extrabytesbuffer = (u8 *) (etherrxbuff + wordcount);
+
+		lastword = in_be32 (emac.recvfifo.databaseaddress);
+
+		/*
+		 * one extra byte in the last word, put the byte into the next
+		 * location of the buffer, bytes in a word of the FIFO are
+		 * ordered from most significant byte to least
+		 */
+		if (extrabytecount == 1) {
+			extrabytesbuffer[0] = (u8) (lastword >> 24);
+		} else if (extrabytecount == 2) {
+			extrabytesbuffer[0] = (u8) (lastword >> 24);
+			extrabytesbuffer[1] = (u8) (lastword >> 16);
+		} else if (extrabytecount == 3) {
+			extrabytesbuffer[0] = (u8) (lastword >> 24);
+			extrabytesbuffer[1] = (u8) (lastword >> 16);
+			extrabytesbuffer[2] = (u8) (lastword >> 8);
+		}
+	}
+	NetReceive((uchar *)etherrxbuff, pktlength);
+	return 1;
+}
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
new file mode 100644
index 0000000..9ba4096
--- /dev/null
+++ b/drivers/net/xilinx_emaclite.c
@@ -0,0 +1,351 @@
+/******************************************************************************
+ *
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
+ * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
+ * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
+ * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
+ * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
+ * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
+ * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
+ * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
+ * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
+ * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
+ * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
+ * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * (C) Copyright 2007-2008 Michal Simek
+ * Michal SIMEK <monstr@monstr.eu>
+ *
+ * (c) Copyright 2003 Xilinx Inc.
+ * All rights reserved.
+ *
+ ******************************************************************************/
+
+#include <common.h>
+#include <net.h>
+#include <config.h>
+#include <asm/io.h>
+
+#undef DEBUG
+
+#define ENET_MAX_MTU		PKTSIZE
+#define ENET_MAX_MTU_ALIGNED	PKTSIZE_ALIGN
+#define ENET_ADDR_LENGTH	6
+
+/* EmacLite constants */
+#define XEL_BUFFER_OFFSET	0x0800	/* Next buffer's offset */
+#define XEL_TPLR_OFFSET		0x07F4	/* Tx packet length */
+#define XEL_TSR_OFFSET		0x07FC	/* Tx status */
+#define XEL_RSR_OFFSET		0x17FC	/* Rx status */
+#define XEL_RXBUFF_OFFSET	0x1000	/* Receive Buffer */
+
+/* Xmit complete */
+#define XEL_TSR_XMIT_BUSY_MASK		0x00000001UL
+/* Xmit interrupt enable bit */
+#define XEL_TSR_XMIT_IE_MASK		0x00000008UL
+/* Buffer is active, SW bit only */
+#define XEL_TSR_XMIT_ACTIVE_MASK	0x80000000UL
+/* Program the MAC address */
+#define XEL_TSR_PROGRAM_MASK		0x00000002UL
+/* define for programming the MAC address into the EMAC Lite */
+#define XEL_TSR_PROG_MAC_ADDR	(XEL_TSR_XMIT_BUSY_MASK | XEL_TSR_PROGRAM_MASK)
+
+/* Transmit packet length upper byte */
+#define XEL_TPLR_LENGTH_MASK_HI		0x0000FF00UL
+/* Transmit packet length lower byte */
+#define XEL_TPLR_LENGTH_MASK_LO		0x000000FFUL
+
+/* Recv complete */
+#define XEL_RSR_RECV_DONE_MASK		0x00000001UL
+/* Recv interrupt enable bit */
+#define XEL_RSR_RECV_IE_MASK		0x00000008UL
+
+typedef struct {
+	unsigned int baseaddress;	/* Base address for device (IPIF) */
+	unsigned int nexttxbuffertouse;	/* Next TX buffer to write to */
+	unsigned int nextrxbuffertouse;	/* Next RX buffer to read from */
+	unsigned char deviceid;		/* Unique ID of device - for future */
+} xemaclite;
+
+static xemaclite emaclite;
+
+static char etherrxbuff[PKTSIZE_ALIGN/4]; /* Receive buffer */
+
+/* hardcoded MAC address for the Xilinx EMAC Core when env is nowhere*/
+#ifdef CFG_ENV_IS_NOWHERE
+static u8 emacaddr[ENET_ADDR_LENGTH] = { 0x00, 0x0a, 0x35, 0x00, 0x22, 0x01 };
+#else
+static u8 emacaddr[ENET_ADDR_LENGTH];
+#endif
+
+void xemaclite_alignedread (u32 * srcptr, void *destptr, unsigned bytecount)
+{
+	unsigned int i;
+	u32 alignbuffer;
+	u32 *to32ptr;
+	u32 *from32ptr;
+	u8 *to8ptr;
+	u8 *from8ptr;
+
+	from32ptr = (u32 *) srcptr;
+
+	/* Word aligned buffer, no correction needed. */
+	to32ptr = (u32 *) destptr;
+	while (bytecount > 3) {
+		*to32ptr++ = *from32ptr++;
+		bytecount -= 4;
+	}
+	to8ptr = (u8 *) to32ptr;
+
+	alignbuffer = *from32ptr++;
+	from8ptr = (u8 *) & alignbuffer;
+
+	for (i = 0; i < bytecount; i++) {
+		*to8ptr++ = *from8ptr++;
+	}
+}
+
+void xemaclite_alignedwrite (void *srcptr, u32 destptr, unsigned bytecount)
+{
+	unsigned i;
+	u32 alignbuffer;
+	u32 *to32ptr = (u32 *) destptr;
+	u32 *from32ptr;
+	u8 *to8ptr;
+	u8 *from8ptr;
+
+	from32ptr = (u32 *) srcptr;
+	while (bytecount > 3) {
+
+		*to32ptr++ = *from32ptr++;
+		bytecount -= 4;
+	}
+
+	alignbuffer = 0;
+	to8ptr = (u8 *) & alignbuffer;
+	from8ptr = (u8 *) from32ptr;
+
+	for (i = 0; i < bytecount; i++) {
+		*to8ptr++ = *from8ptr++;
+	}
+
+	*to32ptr++ = alignbuffer;
+}
+
+void eth_halt (void)
+{
+	debug ("eth_halt\n");
+}
+
+int eth_init (bd_t * bis)
+{
+	debug ("EmacLite Initialization Started\n");
+	memset (&emaclite, 0, sizeof (xemaclite));
+	emaclite.baseaddress = XILINX_EMACLITE_BASEADDR;
+
+	if (!getenv("ethaddr")) {
+		memcpy(bis->bi_enetaddr, emacaddr, ENET_ADDR_LENGTH);
+	}
+
+/*
+ * TX - TX_PING & TX_PONG initialization
+ */
+	/* Restart PING TX */
+	out_be32 (emaclite.baseaddress + XEL_TSR_OFFSET, 0);
+	/* Copy MAC address */
+	xemaclite_alignedwrite (bis->bi_enetaddr,
+		emaclite.baseaddress, ENET_ADDR_LENGTH);
+	/* Set the length */
+	out_be32 (emaclite.baseaddress + XEL_TPLR_OFFSET, ENET_ADDR_LENGTH);
+	/* Update the MAC address in the EMAC Lite */
+	out_be32 (emaclite.baseaddress + XEL_TSR_OFFSET, XEL_TSR_PROG_MAC_ADDR);
+	/* Wait for EMAC Lite to finish with the MAC address update */
+	while ((in_be32 (emaclite.baseaddress + XEL_TSR_OFFSET) &
+		XEL_TSR_PROG_MAC_ADDR) != 0) ;
+
+#ifdef CONFIG_XILINX_EMACLITE_TX_PING_PONG
+	/* The same operation with PONG TX */
+	out_be32 (emaclite.baseaddress + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET, 0);
+	xemaclite_alignedwrite (bis->bi_enetaddr, emaclite.baseaddress +
+		XEL_BUFFER_OFFSET, ENET_ADDR_LENGTH);
+	out_be32 (emaclite.baseaddress + XEL_TPLR_OFFSET, ENET_ADDR_LENGTH);
+	out_be32 (emaclite.baseaddress + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET,
+		XEL_TSR_PROG_MAC_ADDR);
+	while ((in_be32 (emaclite.baseaddress + XEL_TSR_OFFSET +
+		XEL_BUFFER_OFFSET) & XEL_TSR_PROG_MAC_ADDR) != 0) ;
+#endif
+
+/*
+ * RX - RX_PING & RX_PONG initialization
+ */
+	/* Write out the value to flush the RX buffer */
+	out_be32 (emaclite.baseaddress + XEL_RSR_OFFSET, XEL_RSR_RECV_IE_MASK);
+#ifdef CONFIG_XILINX_EMACLITE_RX_PING_PONG
+	out_be32 (emaclite.baseaddress + XEL_RSR_OFFSET + XEL_BUFFER_OFFSET,
+		XEL_RSR_RECV_IE_MASK);
+#endif
+
+	debug ("EmacLite Initialization complete\n");
+	return 0;
+}
+
+int xemaclite_txbufferavailable (xemaclite * instanceptr)
+{
+	u32 reg;
+	u32 txpingbusy;
+	u32 txpongbusy;
+	/*
+	 * Read the other buffer register
+	 * and determine if the other buffer is available
+	 */
+	reg = in_be32 (instanceptr->baseaddress +
+			instanceptr->nexttxbuffertouse + 0);
+	txpingbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) ==
+			XEL_TSR_XMIT_BUSY_MASK);
+
+	reg = in_be32 (instanceptr->baseaddress +
+			(instanceptr->nexttxbuffertouse ^ XEL_TSR_OFFSET) + 0);
+	txpongbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) ==
+			XEL_TSR_XMIT_BUSY_MASK);
+
+	return (!(txpingbusy && txpongbusy));
+}
+
+int eth_send (volatile void *ptr, int len) {
+
+	unsigned int reg;
+	unsigned int baseaddress;
+
+	unsigned maxtry = 1000;
+
+	if (len > ENET_MAX_MTU)
+		len = ENET_MAX_MTU;
+
+	while (!xemaclite_txbufferavailable (&emaclite) && maxtry) {
+		udelay (10);
+		maxtry--;
+	}
+
+	if (!maxtry) {
+		printf ("Error: Timeout waiting for ethernet TX buffer\n");
+		/* Restart PING TX */
+		out_be32 (emaclite.baseaddress + XEL_TSR_OFFSET, 0);
+#ifdef CONFIG_XILINX_EMACLITE_TX_PING_PONG
+		out_be32 (emaclite.baseaddress + XEL_TSR_OFFSET +
+		XEL_BUFFER_OFFSET, 0);
+#endif
+		return 0;
+	}
+
+	/* Determine the expected TX buffer address */
+	baseaddress = (emaclite.baseaddress + emaclite.nexttxbuffertouse);
+
+	/* Determine if the expected buffer address is empty */
+	reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
+	if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0)
+		&& ((in_be32 ((baseaddress) + XEL_TSR_OFFSET)
+			& XEL_TSR_XMIT_ACTIVE_MASK) == 0)) {
+
+#ifdef CONFIG_XILINX_EMACLITE_TX_PING_PONG
+		emaclite.nexttxbuffertouse ^= XEL_BUFFER_OFFSET;
+#endif
+		debug ("Send packet from 0x%x\n", baseaddress);
+		/* Write the frame to the buffer */
+		xemaclite_alignedwrite ((void *) ptr, baseaddress, len);
+		out_be32 (baseaddress + XEL_TPLR_OFFSET,(len &
+			(XEL_TPLR_LENGTH_MASK_HI | XEL_TPLR_LENGTH_MASK_LO)));
+		reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
+		reg |= XEL_TSR_XMIT_BUSY_MASK;
+		if ((reg & XEL_TSR_XMIT_IE_MASK) != 0) {
+			reg |= XEL_TSR_XMIT_ACTIVE_MASK;
+		}
+		out_be32 (baseaddress + XEL_TSR_OFFSET, reg);
+		return 1;
+	}
+#ifdef CONFIG_XILINX_EMACLITE_TX_PING_PONG
+	/* Switch to second buffer */
+	baseaddress ^= XEL_BUFFER_OFFSET;
+	/* Determine if the expected buffer address is empty */
+	reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
+	if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0)
+		&& ((in_be32 ((baseaddress) + XEL_TSR_OFFSET)
+			& XEL_TSR_XMIT_ACTIVE_MASK) == 0)) {
+		debug ("Send packet from 0x%x\n", baseaddress);
+		/* Write the frame to the buffer */
+		xemaclite_alignedwrite ((void *) ptr, baseaddress, len);
+		out_be32 (baseaddress + XEL_TPLR_OFFSET,(len &
+			(XEL_TPLR_LENGTH_MASK_HI | XEL_TPLR_LENGTH_MASK_LO)));
+		reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
+		reg |= XEL_TSR_XMIT_BUSY_MASK;
+		if ((reg & XEL_TSR_XMIT_IE_MASK) != 0) {
+			reg |= XEL_TSR_XMIT_ACTIVE_MASK;
+		}
+		out_be32 (baseaddress + XEL_TSR_OFFSET, reg);
+		return 1;
+	}
+#endif
+	puts ("Error while sending frame\n");
+	return 0;
+}
+
+int eth_rx (void)
+{
+	unsigned int length;
+	unsigned int reg;
+	unsigned int baseaddress;
+
+	baseaddress = emaclite.baseaddress + emaclite.nextrxbuffertouse;
+	reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
+	debug ("Testing data at address 0x%x\n", baseaddress);
+	if ((reg & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
+#ifdef CONFIG_XILINX_EMACLITE_RX_PING_PONG
+		emaclite.nextrxbuffertouse ^= XEL_BUFFER_OFFSET;
+#endif
+	} else {
+#ifndef CONFIG_XILINX_EMACLITE_RX_PING_PONG
+		debug ("No data was available - address 0x%x\n", baseaddress);
+		return 0;
+#else
+		baseaddress ^= XEL_BUFFER_OFFSET;
+		reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
+		if ((reg & XEL_RSR_RECV_DONE_MASK) !=
+					XEL_RSR_RECV_DONE_MASK) {
+			debug ("No data was available - address 0x%x\n",
+					baseaddress);
+			return 0;
+		}
+#endif
+	}
+	/* Get the length of the frame that arrived */
+	switch(((in_be32 (baseaddress + XEL_RXBUFF_OFFSET + 0xC)) &
+			0xFFFF0000 ) >> 16) {
+		case 0x806:
+			length = 42 + 20; /* FIXME size of ARP */
+			debug ("ARP Packet\n");
+			break;
+		case 0x800:
+			length = 14 + 14 +
+			(((in_be32 (baseaddress + XEL_RXBUFF_OFFSET + 0x10)) &
+			0xFFFF0000) >> 16); /* FIXME size of IP packet */
+			debug ("IP Packet\n");
+			break;
+		default:
+			debug ("Other Packet\n");
+			length = ENET_MAX_MTU;
+			break;
+	}
+
+	xemaclite_alignedread ((u32 *) (baseaddress + XEL_RXBUFF_OFFSET),
+			etherrxbuff, length);
+
+	/* Acknowledge the frame */
+	reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
+	reg &= ~XEL_RSR_RECV_DONE_MASK;
+	out_be32 (baseaddress + XEL_RSR_OFFSET, reg);
+
+	debug ("Packet receive from 0x%x, length %dB\n", baseaddress, length);
+	NetReceive ((uchar *) etherrxbuff, length);
+	return 1;
+
+}
diff --git a/examples/Makefile b/examples/Makefile
index c5d629b..66b354d 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -69,6 +69,9 @@
 LOAD_ADDR = 0x8C000000
 endif
 
+ifeq ($(ARCH),sparc)
+LOAD_ADDR = 0x00000000 -L $(gcclibdir) -T sparc.lds
+endif
 
 include $(TOPDIR)/config.mk
 
diff --git a/examples/sparc.lds b/examples/sparc.lds
new file mode 100644
index 0000000..7592544
--- /dev/null
+++ b/examples/sparc.lds
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2003, Psyent Corporation <www.psyent.com>
+ * Scott McNutt <smcnutt@psyent.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+OUTPUT_FORMAT("elf32-sparc", "elf32-sparc", "elf32-sparc")
+OUTPUT_ARCH(sparc)
+ENTRY(_start)
+
+SECTIONS
+{
+	.text :
+	{
+	  *(.text)
+	}
+	__text_end = .;
+
+	. = ALIGN(4);
+	.rodata :
+	{
+		*(.rodata)
+	}
+	__rodata_end = .;
+
+	. = ALIGN(4);
+	.data :
+	{
+		*(.data)
+	}
+	. = ALIGN(4);
+	__data_end = .;
+
+	__bss_start = .;
+	. = ALIGN(4);
+	.bss :
+	{
+		*(.bss)
+	}
+	. = ALIGN(4);
+	__bss_end = .;
+	_end = .;
+}
diff --git a/examples/stubs.c b/examples/stubs.c
index b9dbcf9..ec53532 100644
--- a/examples/stubs.c
+++ b/examples/stubs.c
@@ -167,6 +167,22 @@
 		"	nop\n"				\
 		"	nop\n"				\
 		: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r1");
+#elif defined(CONFIG_SPARC)
+/*
+ * g7 holds the pointer to the global_data. g1 is call clobbered.
+ */
+#define EXPORT_FUNC(x)					\
+	asm volatile(					\
+"	.globl\t" #x "\n"				\
+#x ":\n"						\
+"	set %0, %%g1\n"					\
+"	or %%g1, %%g7, %%g1\n"				\
+"	ld [%%g1], %%g1\n"				\
+"	ld [%%g1 + %1], %%g1\n"				\
+"	call %%g1\n"					\
+"	nop\n"						\
+	: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x) : "g1" );
+
 #else
 #error stubs definition missing for this architecture
 #endif
diff --git a/include/ambapp.h b/include/ambapp.h
new file mode 100644
index 0000000..7494e59
--- /dev/null
+++ b/include/ambapp.h
@@ -0,0 +1,394 @@
+/* Interface for accessing Gaisler AMBA Plug&Play Bus.
+ * The AHB bus can be interfaced with a simpler bus -
+ * the APB bus, also freely available in GRLIB at
+ * www.gaisler.com.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __AMBAPP_H__
+#define __AMBAPP_H__
+
+/* Default location of Plug&Play info
+ * normally 0xfffff000 for AHB masters
+ * and 0xfffff800 for AHB slaves.
+ * Normally no need to change this.
+ */
+#define LEON3_IO_AREA 0xfff00000
+#define LEON3_CONF_AREA  0xff000
+#define LEON3_AHB_SLAVE_CONF_AREA (1 << 11)
+
+/* Max devices this software will support */
+#define LEON3_AHB_MASTERS 16
+#define LEON3_AHB_SLAVES 16
+				/*#define LEON3_APB_MASTERS 1*//* Number of APB buses that has Plug&Play */
+#define LEON3_APB_SLAVES 16	/* Total number of APB slaves per APB bus */
+
+/* Vendor codes */
+#define VENDOR_GAISLER       1
+#define VENDOR_PENDER        2
+#define VENDOR_ESA           4
+#define VENDOR_ASTRIUM       6
+#define VENDOR_OPENCHIP      7
+#define VENDOR_OPENCORES     8
+#define VENDOR_CONTRIB       9
+#define VENDOR_EONIC         11
+#define VENDOR_RADIONOR      15
+#define VENDOR_GLEICHMANN    16
+#define VENDOR_MENTA         17
+#define VENDOR_SUN           19
+#define VENDOR_EMBEDDIT      234
+#define VENDOR_CAL           202
+
+/* Gaisler Research device id's */
+#define GAISLER_LEON3    0x003
+#define GAISLER_LEON3DSU 0x004
+#define GAISLER_ETHAHB   0x005
+#define GAISLER_APBMST   0x006
+#define GAISLER_AHBUART  0x007
+#define GAISLER_SRCTRL   0x008
+#define GAISLER_SDCTRL   0x009
+#define GAISLER_APBUART  0x00C
+#define GAISLER_IRQMP    0x00D
+#define GAISLER_AHBRAM   0x00E
+#define GAISLER_GPTIMER  0x011
+#define GAISLER_PCITRG   0x012
+#define GAISLER_PCISBRG  0x013
+#define GAISLER_PCIFBRG  0x014
+#define GAISLER_PCITRACE 0x015
+#define GAISLER_PCIDMA   0x016
+#define GAISLER_AHBTRACE 0x017
+#define GAISLER_ETHDSU   0x018
+#define GAISLER_PIOPORT  0x01A
+#define GAISLER_AHBJTAG  0x01c
+#define GAISLER_SPW      0x01f
+#define GAISLER_ATACTRL  0x024
+#define GAISLER_VGA      0x061
+#define GAISLER_KBD      0X060
+#define GAISLER_ETHMAC   0x01D
+#define GAISLER_DDRSPA   0x025
+#define GAISLER_EHCI     0x026
+#define GAISLER_UHCI     0x027
+#define GAISLER_SPW2     0x029
+#define GAISLER_DDR2SPA  0x02E
+#define GAISLER_AHBSTAT  0x052
+#define GAISLER_FTMCTRL  0x054
+
+#define GAISLER_L2TIME   0xffd	/* internal device: leon2 timer */
+#define GAISLER_L2C      0xffe	/* internal device: leon2compat */
+#define GAISLER_PLUGPLAY 0xfff	/* internal device: plug & play configarea */
+
+/* European Space Agency device id's */
+#define ESA_LEON2        0x2
+#define ESA_MCTRL        0xF
+
+/* Opencores device id's */
+#define OPENCORES_PCIBR  0x4
+#define OPENCORES_ETHMAC 0x5
+
+/* Vendor codes */
+
+/*
+ *
+ * Macros for manipulating Configuration registers
+ *
+ */
+
+#define amba_vendor(x) (((x) >> 24) & 0xff)
+
+#define amba_device(x) (((x) >> 12) & 0xfff)
+
+#define amba_membar_start(mbar) \
+ (((mbar) & 0xfff00000) & (((mbar) & 0xfff0) << 16))
+
+#define amba_iobar_start(base, iobar) \
+ ((base) | ((((iobar) & 0xfff00000)>>12) & (((iobar) & 0xfff0)<<4)) )
+
+#define amba_irq(conf) ((conf) & 0xf)
+
+#define amba_ver(conf) (((conf)>>5) & 0x1f)
+
+#define amba_membar_type(mbar) ((mbar) & 0xf)
+
+#define amba_membar_mask(mbar) (((mbar)>>4) & 0xfff)
+
+#define AMBA_TYPE_APBIO 0x1
+#define AMBA_TYPE_MEM   0x2
+#define AMBA_TYPE_AHBIO 0x3
+
+#define AMBA_TYPE_AHBIO_ADDR(addr) (LEON3_IO_AREA | ((addr) >> 12))
+
+#ifndef __ASSEMBLER__
+
+#ifdef CONFIG_CMD_AMBAPP
+
+/* AMBA Plug&Play relocation & initialization */
+int ambapp_init_reloc(void);
+
+/* AMBA Plug&Play Name of Vendors and devices */
+
+/* Return name of device */
+char *ambapp_device_id2str(int vendor, int id);
+
+/* Return name of vendor */
+char *ambapp_vendor_id2str(int vendor);
+#endif
+
+/*
+ *  Types and structure used for AMBA Plug & Play bus scanning
+ */
+
+/* AMBA Plug&Play AHB information layout */
+typedef struct {
+	unsigned int conf;
+	unsigned int userdef[3];
+	unsigned int bars[4];
+} ahbctrl_pp_dev;
+
+/* Prototypes for scanning AMBA Plug&Play bus for AMBA
+ *  i)   AHB Masters
+ *  ii)  AHB Slaves
+ *  iii) APB Slaves (APB MST is a AHB Slave)
+ */
+
+typedef struct {
+	unsigned char irq;
+	unsigned char ver;
+	unsigned int address;
+} ambapp_apbdev;
+
+typedef struct {
+	unsigned char irq;
+	unsigned char ver;
+	unsigned int userdef[3];
+	unsigned int address[4];
+} ambapp_ahbdev;
+
+/* AMBA Plug&Play AHB Masters & Slaves information locations
+ * Max devices is 64 supported by HW, however often only 8
+ * are used.
+ */
+typedef struct {
+	ahbctrl_pp_dev masters[64];
+	ahbctrl_pp_dev slaves[64];
+} ahbctrl_info;
+
+/* AMBA Plug&Play AHB information layout */
+typedef struct {
+	unsigned int conf;
+	unsigned int bar;
+} apbctrl_pp_dev;
+
+/* All functions return the number of found devices
+ * 0 = no devices found
+ */
+
+/****************************** APB SLAVES ******************************/
+int ambapp_apb_count(unsigned int vendor, unsigned int driver);
+
+int ambapp_apb_first(unsigned int vendor,
+		     unsigned int driver, ambapp_apbdev * dev);
+
+int ambapp_apb_next(unsigned int vendor,
+		    unsigned int driver, ambapp_apbdev * dev, int index);
+
+int ambapp_apbs_first(unsigned int vendor,
+		      unsigned int driver, ambapp_apbdev * dev, int max_cnt);
+
+/****************************** AHB MASTERS ******************************/
+int ambapp_ahbmst_count(unsigned int vendor, unsigned int driver);
+
+int ambapp_ahbmst_first(unsigned int vendor,
+			unsigned int driver, ambapp_ahbdev * dev);
+
+int ambapp_ahbmst_next(unsigned int vendor,
+		       unsigned int driver, ambapp_ahbdev * dev, int index);
+
+int ambapp_ahbmsts_first(unsigned int vendor,
+			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
+
+/****************************** AHB SLAVES ******************************/
+int ambapp_ahbslv_count(unsigned int vendor, unsigned int driver);
+
+int ambapp_ahbslv_first(unsigned int vendor,
+			unsigned int driver, ambapp_ahbdev * dev);
+
+int ambapp_ahbslv_next(unsigned int vendor,
+		       unsigned int driver, ambapp_ahbdev * dev, int index);
+
+int ambapp_ahbslvs_first(unsigned int vendor,
+			 unsigned int driver, ambapp_ahbdev * dev, int max_cnt);
+
+/*************************** AHB/APB only regs functions *************************
+ * During start up, no memory is available we can use the simplified functions
+ * to get to the memory controller.
+ *
+ * Functions uses no stack/memory, only registers.
+ */
+unsigned int ambapp_apb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
+				   register unsigned int driver,	/* Plug&Play Device ID */
+				   register int index);
+
+ahbctrl_pp_dev *ambapp_ahb_next_nomem(register unsigned int vendor,	/* Plug&Play Vendor ID */
+				      register unsigned int driver,	/* Plug&Play Device ID */
+				      register unsigned int opts,	/* scan for AHB 1=slave, 0=masters */
+				      register int index);
+
+unsigned int ambapp_ahb_get_info(ahbctrl_pp_dev * ahb, int info);
+
+/*************************** AMBA Plug&Play device register MAPS *****************/
+
+/*
+ *  The following defines the bits in the LEON UART Status Registers.
+ */
+
+#define LEON_REG_UART_STATUS_DR   0x00000001	/* Data Ready */
+#define LEON_REG_UART_STATUS_TSE  0x00000002	/* TX Send Register Empty */
+#define LEON_REG_UART_STATUS_THE  0x00000004	/* TX Hold Register Empty */
+#define LEON_REG_UART_STATUS_BR   0x00000008	/* Break Error */
+#define LEON_REG_UART_STATUS_OE   0x00000010	/* RX Overrun Error */
+#define LEON_REG_UART_STATUS_PE   0x00000020	/* RX Parity Error */
+#define LEON_REG_UART_STATUS_FE   0x00000040	/* RX Framing Error */
+#define LEON_REG_UART_STATUS_ERR  0x00000078	/* Error Mask */
+
+/*
+ *  The following defines the bits in the LEON UART Ctrl Registers.
+ */
+
+#define LEON_REG_UART_CTRL_RE     0x00000001	/* Receiver enable */
+#define LEON_REG_UART_CTRL_TE     0x00000002	/* Transmitter enable */
+#define LEON_REG_UART_CTRL_RI     0x00000004	/* Receiver interrupt enable */
+#define LEON_REG_UART_CTRL_TI     0x00000008	/* Transmitter interrupt enable */
+#define LEON_REG_UART_CTRL_PS     0x00000010	/* Parity select */
+#define LEON_REG_UART_CTRL_PE     0x00000020	/* Parity enable */
+#define LEON_REG_UART_CTRL_FL     0x00000040	/* Flow control enable */
+#define LEON_REG_UART_CTRL_LB     0x00000080	/* Loop Back enable */
+#define LEON_REG_UART_CTRL_DBG    (1<<11)	/* Debug Bit used by GRMON */
+
+#define LEON3_GPTIMER_EN 1
+#define LEON3_GPTIMER_RL 2
+#define LEON3_GPTIMER_LD 4
+#define LEON3_GPTIMER_IRQEN 8
+
+/*
+ *  The following defines the bits in the LEON PS/2 Status Registers.
+ */
+
+#define LEON_REG_PS2_STATUS_DR   0x00000001	/* Data Ready */
+#define LEON_REG_PS2_STATUS_PE   0x00000002	/* Parity error */
+#define LEON_REG_PS2_STATUS_FE   0x00000004	/* Framing error */
+#define LEON_REG_PS2_STATUS_KI   0x00000008	/* Keyboard inhibit */
+
+/*
+ *  The following defines the bits in the LEON PS/2 Ctrl Registers.
+ */
+
+#define LEON_REG_PS2_CTRL_RE     0x00000001	/* Receiver enable */
+#define LEON_REG_PS2_CTRL_TE     0x00000002	/* Transmitter enable */
+#define LEON_REG_PS2_CTRL_RI     0x00000004	/* Keyboard receive interrupt  */
+#define LEON_REG_PS2_CTRL_TI     0x00000008	/* Keyboard transmit interrupt */
+
+typedef struct {
+	volatile unsigned int ilevel;
+	volatile unsigned int ipend;
+	volatile unsigned int iforce;
+	volatile unsigned int iclear;
+	volatile unsigned int mstatus;
+	volatile unsigned int notused[11];
+	volatile unsigned int cpu_mask[16];
+	volatile unsigned int cpu_force[16];
+} ambapp_dev_irqmp;
+
+typedef struct {
+	volatile unsigned int data;
+	volatile unsigned int status;
+	volatile unsigned int ctrl;
+	volatile unsigned int scaler;
+} ambapp_dev_apbuart;
+
+typedef struct {
+	volatile unsigned int val;
+	volatile unsigned int rld;
+	volatile unsigned int ctrl;
+	volatile unsigned int unused;
+} ambapp_dev_gptimer_element;
+
+#define LEON3_GPTIMER_CTRL_EN	0x1	/* Timer enable */
+#define LEON3_GPTIMER_CTRL_RS	0x2	/* Timer reStart  */
+#define LEON3_GPTIMER_CTRL_LD	0x4	/* Timer reLoad */
+#define LEON3_GPTIMER_CTRL_IE	0x8	/* interrupt enable */
+#define LEON3_GPTIMER_CTRL_IP	0x10	/* interrupt flag/pending */
+#define LEON3_GPTIMER_CTRL_CH	0x20	/* Chain with previous timer */
+
+typedef struct {
+	volatile unsigned int scalar;
+	volatile unsigned int scalar_reload;
+	volatile unsigned int config;
+	volatile unsigned int unused;
+	volatile ambapp_dev_gptimer_element e[8];
+} ambapp_dev_gptimer;
+
+typedef struct {
+	volatile unsigned int iodata;
+	volatile unsigned int ioout;
+	volatile unsigned int iodir;
+	volatile unsigned int irqmask;
+	volatile unsigned int irqpol;
+	volatile unsigned int irqedge;
+} ambapp_dev_ioport;
+
+typedef struct {
+	volatile unsigned int write;
+	volatile unsigned int dummy;
+	volatile unsigned int txcolor;
+	volatile unsigned int bgcolor;
+} ambapp_dev_textvga;
+
+typedef struct {
+	volatile unsigned int data;
+	volatile unsigned int status;
+	volatile unsigned int ctrl;
+} ambapp_dev_apbps2;
+
+typedef struct {
+	unsigned int mcfg1, mcfg2, mcfg3;
+} ambapp_dev_mctrl;
+
+typedef struct {
+	unsigned int sdcfg;
+} ambapp_dev_sdctrl;
+
+typedef struct {
+	unsigned int cfg1;
+	unsigned int cfg2;
+	unsigned int cfg3;
+} ambapp_dev_ddr2spa;
+
+typedef struct {
+	unsigned int ctrl;
+	unsigned int cfg;
+} ambapp_dev_ddrspa;
+
+#endif
+
+#endif
diff --git a/include/asm-sparc/arch-leon2/asi.h b/include/asm-sparc/arch-leon2/asi.h
new file mode 100644
index 0000000..38fdd5c
--- /dev/null
+++ b/include/asm-sparc/arch-leon2/asi.h
@@ -0,0 +1,36 @@
+/* asi.h:  Address Space Identifier values for the LEON2 sparc.
+ *
+ * Copyright (C) 2008 Daniel Hellstrom (daniel@gaisler.com)
+ *
+ * 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
+ *
+ */
+
+#ifndef _LEON2_ASI_H
+#define _LEON2_ASI_H
+
+#define ASI_CACHEMISS		0x01	/* Force D-Cache miss on load (lda) */
+#define ASI_M_FLUSH_PROBE	0x03	/* MMU Flush/Probe */
+#define ASI_IFLUSH		0x05	/* Flush I-Cache */
+#define ASI_DFLUSH		0x06	/* Flush D-Cache */
+#define ASI_BYPASS		0x1c	/* Bypass MMU (Physical address) */
+#define ASI_MMUFLUSH		0x18	/* FLUSH TLB */
+#define ASI_M_MMUREGS		0x19	/* READ/Write MMU Registers */
+
+#endif	/* _LEON2_ASI_H */
diff --git a/include/asm-sparc/arch-leon3/asi.h b/include/asm-sparc/arch-leon3/asi.h
new file mode 100644
index 0000000..700b3ca
--- /dev/null
+++ b/include/asm-sparc/arch-leon3/asi.h
@@ -0,0 +1,36 @@
+/* asi.h:  Address Space Identifier values for the LEON3 sparc.
+ *
+ * Copyright (C) 2008 Daniel Hellstrom (daniel@gaisler.com)
+ *
+ * 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
+ *
+ */
+
+#ifndef _LEON3_ASI_H
+#define _LEON3_ASI_H
+
+#define ASI_CACHEMISS		0x01	/* Force D-Cache miss on load (lda) */
+#define ASI_M_FLUSH_PROBE	0x03	/* MMU Flush/Probe */
+#define ASI_IFLUSH		0x10	/* Flush I-Cache */
+#define ASI_DFLUSH		0x11	/* Flush D-Cache */
+#define ASI_BYPASS		0x1c	/* Bypass MMU (Physical address) */
+#define ASI_MMUFLUSH		0x18	/* FLUSH TLB */
+#define ASI_M_MMUREGS		0x19	/* READ/Write MMU Registers */
+
+#endif	/* _LEON3_ASI_H */
diff --git a/include/asm-sparc/asi.h b/include/asm-sparc/asi.h
new file mode 100644
index 0000000..bf6d70f
--- /dev/null
+++ b/include/asm-sparc/asi.h
@@ -0,0 +1,32 @@
+/* Address Space Identifier (ASI) values for sparc processors.
+ *
+ * (C) Copyright 2008
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef _SPARC_ASI_H
+#define _SPARC_ASI_H
+
+/* ASI numbers are processor implementation specific */
+#include <asm/arch/asi.h>
+
+#endif	/* _SPARC_ASI_H */
diff --git a/include/asm-sparc/asmmacro.h b/include/asm-sparc/asmmacro.h
new file mode 100644
index 0000000..0c4cefd
--- /dev/null
+++ b/include/asm-sparc/asmmacro.h
@@ -0,0 +1,45 @@
+/* Assembler macros for SPARC
+ *
+ * (C) Copyright 2007, taken from linux asm-sparc/asmmacro.h
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __SPARC_ASMMACRO_H__
+#define __SPARC_ASMMACRO_H__
+
+#include <config.h>
+
+/* All trap entry points _must_ begin with this macro or else you
+ * lose.  It makes sure the kernel has a proper window so that
+ * c-code can be called.
+ */
+#define SAVE_ALL_HEAD \
+	sethi	%hi(trap_setup+(CFG_RELOC_MONITOR_BASE-TEXT_BASE)), %l4; \
+	jmpl	%l4 + %lo(trap_setup+(CFG_RELOC_MONITOR_BASE-TEXT_BASE)), %l6;
+#define SAVE_ALL \
+	SAVE_ALL_HEAD \
+	nop;
+
+/* All traps low-level code here must end with this macro. */
+#define RESTORE_ALL b ret_trap_entry; clr %l6;
+
+#endif
diff --git a/include/asm-sparc/atomic.h b/include/asm-sparc/atomic.h
new file mode 100644
index 0000000..636498d
--- /dev/null
+++ b/include/asm-sparc/atomic.h
@@ -0,0 +1,29 @@
+/* SPARC atomic operations
+ *
+ * (C) Copyright 2008
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef _ASM_SPARC_ATOMIC_H_
+#define _ASM_SPARC_ATOMIC_H_
+
+#endif	/* _ASM_SPARC_ATOMIC_H_ */
diff --git a/include/asm-sparc/bitops.h b/include/asm-sparc/bitops.h
new file mode 100644
index 0000000..ceb39f2
--- /dev/null
+++ b/include/asm-sparc/bitops.h
@@ -0,0 +1,29 @@
+/* Bit string operations on the SPARC
+ *
+ * (C) Copyright 2007, taken from asm-ppc/bitops.h
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef _SPARC_BITOPS_H
+#define _SPARC_BITOPS_H
+
+#endif				/* _SPARC_BITOPS_H */
diff --git a/include/asm-sparc/byteorder.h b/include/asm-sparc/byteorder.h
new file mode 100644
index 0000000..b9fc656
--- /dev/null
+++ b/include/asm-sparc/byteorder.h
@@ -0,0 +1,37 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2008
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef _SPARC_BYTEORDER_H
+#define _SPARC_BYTEORDER_H
+
+#include <asm/types.h>
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+#define __BYTEORDER_HAS_U64__
+#endif
+#include <linux/byteorder/big_endian.h>
+#endif				/* _SPARC_BYTEORDER_H */
diff --git a/include/asm-sparc/cache.h b/include/asm-sparc/cache.h
new file mode 100644
index 0000000..03e8d94
--- /dev/null
+++ b/include/asm-sparc/cache.h
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2008,
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __SPARC_CACHE_H__
+#define __SPARC_CACHE_H__
+
+#include <linux/config.h>
+#include <asm/processor.h>
+
+#endif
diff --git a/include/asm-sparc/errno.h b/include/asm-sparc/errno.h
new file mode 100644
index 0000000..3a74f6f
--- /dev/null
+++ b/include/asm-sparc/errno.h
@@ -0,0 +1,162 @@
+/* SPARC errno definitions, taken from asm-ppc/errno.h
+ *
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __SPARC_ERRNO_H__
+#define __SPARC_ERRNO_H__
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EAGAIN		11	/* Try again */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EDEADLK		35	/* Resource deadlock would occur */
+#define	ENAMETOOLONG	36	/* File name too long */
+#define	ENOLCK		37	/* No record locks available */
+#define	ENOSYS		38	/* Function not implemented */
+#define	ENOTEMPTY	39	/* Directory not empty */
+#define	ELOOP		40	/* Too many symbolic links encountered */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	ENOMSG		42	/* No message of desired type */
+#define	EIDRM		43	/* Identifier removed */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+#define	EDEADLOCK	58	/* File locking deadlock error */
+#define	EBFONT		59	/* Bad font file format */
+#define	ENOSTR		60	/* Device not a stream */
+#define	ENODATA		61	/* No data available */
+#define	ETIME		62	/* Timer expired */
+#define	ENOSR		63	/* Out of streams resources */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOPKG		65	/* Package not installed */
+#define	EREMOTE		66	/* Object is remote */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EPROTO		71	/* Protocol error */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EBADMSG		74	/* Not a data message */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	EILSEQ		84	/* Illegal byte sequence */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUSERS		87	/* Too many users */
+#define	ENOTSOCK	88	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	89	/* Destination address required */
+#define	EMSGSIZE	90	/* Message too long */
+#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	92	/* Protocol not available */
+#define	EPROTONOSUPPORT	93	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
+#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	96	/* Protocol family not supported */
+#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
+#define	EADDRINUSE	98	/* Address already in use */
+#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
+#define	ENETDOWN	100	/* Network is down */
+#define	ENETUNREACH	101	/* Network is unreachable */
+#define	ENETRESET	102	/* Network dropped connection because of reset */
+#define	ECONNABORTED	103	/* Software caused connection abort */
+#define	ECONNRESET	104	/* Connection reset by peer */
+#define	ENOBUFS		105	/* No buffer space available */
+#define	EISCONN		106	/* Transport endpoint is already connected */
+#define	ENOTCONN	107	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
+#define	ETIMEDOUT	110	/* Connection timed out */
+#define	ECONNREFUSED	111	/* Connection refused */
+#define	EHOSTDOWN	112	/* Host is down */
+#define	EHOSTUNREACH	113	/* No route to host */
+#define	EALREADY	114	/* Operation already in progress */
+#define	EINPROGRESS	115	/* Operation now in progress */
+#define	ESTALE		116	/* Stale NFS file handle */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+#define	EDQUOT		122	/* Quota exceeded */
+
+#define	ENOMEDIUM	123	/* No medium found */
+#define	EMEDIUMTYPE	124	/* Wrong medium type */
+
+/* Should never be seen by user programs */
+#define ERESTARTSYS	512
+#define ERESTARTNOINTR	513
+#define ERESTARTNOHAND	514	/* restart if no handler.. */
+#define ENOIOCTLCMD	515	/* No ioctl command */
+
+#define _LAST_ERRNO	515
+
+#endif
diff --git a/include/asm-sparc/global_data.h b/include/asm-sparc/global_data.h
new file mode 100644
index 0000000..7c29fc6
--- /dev/null
+++ b/include/asm-sparc/global_data.h
@@ -0,0 +1,85 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ */
+
+#ifndef	__ASM_GBL_DATA_H
+#define __ASM_GBL_DATA_H
+
+#include "asm/types.h"
+
+/*
+ * The following data structure is placed in some memory wich is
+ * available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
+ * some locked parts of the data cache) to allow for a minimum set of
+ * global variables during system initialization (until we have set
+ * up the memory controller so that we can use RAM).
+ *
+ * Keep it *SMALL* and remember to set CFG_GBL_DATA_SIZE > sizeof(gd_t)
+ */
+
+typedef struct global_data {
+	bd_t *bd;
+	unsigned long flags;
+	unsigned long baudrate;
+	unsigned long cpu_clk;	/* CPU clock in Hz!             */
+	unsigned long bus_clk;
+
+	unsigned long ram_size;	/* RAM size */
+	unsigned long reloc_off;	/* Relocation Offset */
+	unsigned long reset_status;	/* reset status register at boot        */
+	unsigned long env_addr;	/* Address  of Environment struct       */
+	unsigned long env_valid;	/* Checksum of Environment valid?       */
+	unsigned long have_console;	/* serial_init() was called */
+
+#if defined(CONFIG_LCD) || defined(CONFIG_VIDEO)
+	unsigned long fb_base;	/* Base address of framebuffer memory   */
+#endif
+#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
+	unsigned long post_log_word;	/* Record POST activities */
+	unsigned long post_init_f_time;	/* When post_init_f started */
+#endif
+#ifdef CONFIG_BOARD_TYPES
+	unsigned long board_type;
+#endif
+#ifdef CONFIG_MODEM_SUPPORT
+	unsigned long do_mdm_init;
+	unsigned long be_quiet;
+#endif
+#ifdef CONFIG_LWMON
+	unsigned long kbd_status;
+#endif
+	void **jt;		/* jump table */
+} gd_t;
+
+/*
+ * Global Data Flags
+ */
+#define	GD_FLG_RELOC	0x00001	/* Code was relocated to RAM            */
+#define	GD_FLG_DEVINIT	0x00002	/* Devices have been initialized        */
+#define	GD_FLG_SILENT	0x00004	/* Silent mode                          */
+
+#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("%g7")
+
+#endif				/* __ASM_GBL_DATA_H */
diff --git a/include/asm-sparc/io.h b/include/asm-sparc/io.h
new file mode 100644
index 0000000..2a27d06
--- /dev/null
+++ b/include/asm-sparc/io.h
@@ -0,0 +1,94 @@
+/* SPARC I/O definitions
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef _SPARC_IO_H
+#define _SPARC_IO_H
+
+/* Nothing to sync, total store ordering (TSO)... */
+#define sync()
+
+/* Forces a cache miss on read/load.
+ * On some architectures we need to bypass the cache when reading
+ * I/O registers so that we are not reading the same status word
+ * over and over again resulting in a hang (until an IRQ if lucky)
+ *
+ */
+#ifndef CFG_HAS_NO_CACHE
+#define READ_BYTE(var)  SPARC_NOCACHE_READ_BYTE((unsigned int)(var))
+#define READ_HWORD(var) SPARC_NOCACHE_READ_HWORD((unsigned int)(var))
+#define READ_WORD(var)  SPARC_NOCACHE_READ((unsigned int)(var))
+#define READ_DWORD(var) SPARC_NOCACHE_READ_DWORD((unsigned int)(var))
+#else
+#define READ_BYTE(var)  (var)
+#define READ_HWORD(var) (var)
+#define READ_WORD(var)  (var)
+#define READ_DWORD(var) (var)
+#endif
+
+/*
+ * Generic virtual read/write.
+ */
+#define __arch_getb(a)			(READ_BYTE(a))
+#define __arch_getw(a)			(READ_HWORD(a))
+#define __arch_getl(a)			(READ_WORD(a))
+#define __arch_getq(a)			(READ_DWORD(a))
+
+#define __arch_putb(v,a)		(*(volatile unsigned char *)(a) = (v))
+#define __arch_putw(v,a)		(*(volatile unsigned short *)(a) = (v))
+#define __arch_putl(v,a)		(*(volatile unsigned int *)(a) = (v))
+
+#define __raw_writeb(v,a)		__arch_putb(v,a)
+#define __raw_writew(v,a)		__arch_putw(v,a)
+#define __raw_writel(v,a)		__arch_putl(v,a)
+
+#define __raw_readb(a)			__arch_getb(a)
+#define __raw_readw(a)			__arch_getw(a)
+#define __raw_readl(a)			__arch_getl(a)
+#define __raw_readq(a)			__arch_getq(a)
+
+/*
+ * Given a physical address and a length, return a virtual address
+ * that can be used to access the memory range with the caching
+ * properties specified by "flags".
+ */
+typedef unsigned long phys_addr_t;
+
+#define MAP_NOCACHE	(0)
+#define MAP_WRCOMBINE	(0)
+#define MAP_WRBACK	(0)
+#define MAP_WRTHROUGH	(0)
+
+static inline void *map_physmem(phys_addr_t paddr, unsigned long len,
+				unsigned long flags)
+{
+	return (void *)paddr;
+}
+
+/*
+ * Take down a mapping set up by map_physmem().
+ */
+static inline void unmap_physmem(void *vaddr, unsigned long flags)
+{
+
+}
+
+#endif
diff --git a/include/asm-sparc/irq.h b/include/asm-sparc/irq.h
new file mode 100644
index 0000000..c5538c0
--- /dev/null
+++ b/include/asm-sparc/irq.h
@@ -0,0 +1,49 @@
+/* IRQ functions
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __SPARC_IRQ_H__
+#define __SPARC_IRQ_H__
+
+#include <asm/psr.h>
+
+/* Set SPARC Processor Interrupt Level */
+extern inline void set_pil(unsigned int level)
+{
+	unsigned int psr = get_psr();
+
+	put_psr((psr & ~PSR_PIL) | ((level & 0xf) << PSR_PIL_OFS));
+}
+
+/* Get SPARC Processor Interrupt Level */
+extern inline unsigned int get_pil(void)
+{
+	unsigned int psr = get_psr();
+	return (psr & PSR_PIL) >> PSR_PIL_OFS;
+}
+
+/* Disables interrupts and return current PIL value */
+extern int intLock(void);
+
+/* Sets the PIL to oldLevel */
+extern void intUnlock(int oldLevel);
+
+#endif
diff --git a/include/asm-sparc/leon.h b/include/asm-sparc/leon.h
new file mode 100644
index 0000000..f7175ee
--- /dev/null
+++ b/include/asm-sparc/leon.h
@@ -0,0 +1,42 @@
+/* LEON Header File select
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __ASM_LEON_H__
+#define __ASM_LEON_H__
+
+#if defined(CONFIG_LEON3)
+
+#include <asm/leon3.h>
+
+#elif defined(CONFIG_LEON2)
+
+#include <asm/leon2.h>
+
+#else
+
+#error Unknown LEON processor
+
+#endif
+
+/* Common stuff */
+
+#endif
diff --git a/include/asm-sparc/leon2.h b/include/asm-sparc/leon2.h
new file mode 100644
index 0000000..fa55cad
--- /dev/null
+++ b/include/asm-sparc/leon2.h
@@ -0,0 +1,236 @@
+/* LEON2 header file. LEON2 is a SOC processor.
+ *
+ * (C) Copyright 2008
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __LEON2_H__
+#define __LEON2_H__
+
+#ifdef CONFIG_LEON2
+
+/* LEON 2 I/O register definitions */
+#define LEON2_PREGS	0x80000000
+#define LEON2_MCFG1	0x00
+#define LEON2_MCFG2	0x04
+#define LEON2_ECTRL	0x08
+#define LEON2_FADDR	0x0C
+#define LEON2_MSTAT	0x10
+#define LEON2_CCTRL	0x14
+#define LEON2_PWDOWN	0x18
+#define LEON2_WPROT1	0x1C
+#define LEON2_WPROT2	0x20
+#define LEON2_LCONF	0x24
+#define LEON2_TCNT0	0x40
+#define LEON2_TRLD0	0x44
+#define LEON2_TCTRL0	0x48
+#define LEON2_TCNT1	0x50
+#define LEON2_TRLD1	0x54
+#define LEON2_TCTRL1	0x58
+#define LEON2_SCNT	0x60
+#define LEON2_SRLD	0x64
+#define LEON2_UART0	0x70
+#define LEON2_UDATA0	0x70
+#define LEON2_USTAT0	0x74
+#define LEON2_UCTRL0	0x78
+#define LEON2_USCAL0	0x7C
+#define LEON2_UART1	0x80
+#define LEON2_UDATA1	0x80
+#define LEON2_USTAT1	0x84
+#define LEON2_UCTRL1	0x88
+#define LEON2_USCAL1	0x8C
+#define LEON2_IMASK	0x90
+#define LEON2_IPEND	0x94
+#define LEON2_IFORCE	0x98
+#define LEON2_ICLEAR	0x9C
+#define LEON2_IOREG	0xA0
+#define LEON2_IODIR	0xA4
+#define LEON2_IOICONF	0xA8
+#define LEON2_IPEND2	0xB0
+#define LEON2_IMASK2	0xB4
+#define LEON2_ISTAT2	0xB8
+#define LEON2_ICLEAR2	0xBC
+
+#ifndef __ASSEMBLER__
+/*
+ *  Structure for LEON memory mapped registers.
+ *
+ *  Source: Section 6.1 - On-chip registers
+ *
+ *  NOTE:  There is only one of these structures per CPU, its base address
+ *         is 0x80000000, and the variable LEON_REG is placed there by the
+ *         linkcmds file.
+ */
+typedef struct {
+	volatile unsigned int Memory_Config_1;
+	volatile unsigned int Memory_Config_2;
+	volatile unsigned int Edac_Control;
+	volatile unsigned int Failed_Address;
+	volatile unsigned int Memory_Status;
+	volatile unsigned int Cache_Control;
+	volatile unsigned int Power_Down;
+	volatile unsigned int Write_Protection_1;
+	volatile unsigned int Write_Protection_2;
+	volatile unsigned int Leon_Configuration;
+	volatile unsigned int dummy2;
+	volatile unsigned int dummy3;
+	volatile unsigned int dummy4;
+	volatile unsigned int dummy5;
+	volatile unsigned int dummy6;
+	volatile unsigned int dummy7;
+	volatile unsigned int Timer_Counter_1;
+	volatile unsigned int Timer_Reload_1;
+	volatile unsigned int Timer_Control_1;
+	volatile unsigned int Watchdog;
+	volatile unsigned int Timer_Counter_2;
+	volatile unsigned int Timer_Reload_2;
+	volatile unsigned int Timer_Control_2;
+	volatile unsigned int dummy8;
+	volatile unsigned int Scaler_Counter;
+	volatile unsigned int Scaler_Reload;
+	volatile unsigned int dummy9;
+	volatile unsigned int dummy10;
+	volatile unsigned int UART_Channel_1;
+	volatile unsigned int UART_Status_1;
+	volatile unsigned int UART_Control_1;
+	volatile unsigned int UART_Scaler_1;
+	volatile unsigned int UART_Channel_2;
+	volatile unsigned int UART_Status_2;
+	volatile unsigned int UART_Control_2;
+	volatile unsigned int UART_Scaler_2;
+	volatile unsigned int Interrupt_Mask;
+	volatile unsigned int Interrupt_Pending;
+	volatile unsigned int Interrupt_Force;
+	volatile unsigned int Interrupt_Clear;
+	volatile unsigned int PIO_Data;
+	volatile unsigned int PIO_Direction;
+	volatile unsigned int PIO_Interrupt;
+} LEON2_regs;
+
+typedef struct {
+	volatile unsigned int UART_Channel;
+	volatile unsigned int UART_Status;
+	volatile unsigned int UART_Control;
+	volatile unsigned int UART_Scaler;
+} LEON2_Uart_regs;
+
+#endif
+
+/*
+ *  The following constants are intended to be used ONLY in assembly
+ *  language files.
+ *
+ *  NOTE:  The intended style of usage is to load the address of LEON REGS
+ *         into a register and then use these as displacements from
+ *         that register.
+ */
+#define  LEON_REG_MEMCFG1_OFFSET                                  0x00
+#define  LEON_REG_MEMCFG2_OFFSET                                  0x04
+#define  LEON_REG_EDACCTRL_OFFSET                                 0x08
+#define  LEON_REG_FAILADDR_OFFSET                                 0x0C
+#define  LEON_REG_MEMSTATUS_OFFSET                                0x10
+#define  LEON_REG_CACHECTRL_OFFSET                                0x14
+#define  LEON_REG_POWERDOWN_OFFSET                                0x18
+#define  LEON_REG_WRITEPROT1_OFFSET                               0x1C
+#define  LEON_REG_WRITEPROT2_OFFSET                               0x20
+#define  LEON_REG_LEONCONF_OFFSET                                 0x24
+#define  LEON_REG_UNIMPLEMENTED_2_OFFSET                          0x28
+#define  LEON_REG_UNIMPLEMENTED_3_OFFSET                          0x2C
+#define  LEON_REG_UNIMPLEMENTED_4_OFFSET                          0x30
+#define  LEON_REG_UNIMPLEMENTED_5_OFFSET                          0x34
+#define  LEON_REG_UNIMPLEMENTED_6_OFFSET                          0x38
+#define  LEON_REG_UNIMPLEMENTED_7_OFFSET                          0x3C
+#define  LEON_REG_TIMERCNT1_OFFSET                                0x40
+#define  LEON_REG_TIMERLOAD1_OFFSET                               0x44
+#define  LEON_REG_TIMERCTRL1_OFFSET                               0x48
+#define  LEON_REG_WDOG_OFFSET                                     0x4C
+#define  LEON_REG_TIMERCNT2_OFFSET                                0x50
+#define  LEON_REG_TIMERLOAD2_OFFSET                               0x54
+#define  LEON_REG_TIMERCTRL2_OFFSET                               0x58
+#define  LEON_REG_UNIMPLEMENTED_8_OFFSET                          0x5C
+#define  LEON_REG_SCALERCNT_OFFSET                                0x60
+#define  LEON_REG_SCALER_LOAD_OFFSET                              0x64
+#define  LEON_REG_UNIMPLEMENTED_9_OFFSET                          0x68
+#define  LEON_REG_UNIMPLEMENTED_10_OFFSET                         0x6C
+#define  LEON_REG_UARTDATA1_OFFSET                                0x70
+#define  LEON_REG_UARTSTATUS1_OFFSET                              0x74
+#define  LEON_REG_UARTCTRL1_OFFSET                                0x78
+#define  LEON_REG_UARTSCALER1_OFFSET                              0x7C
+#define  LEON_REG_UARTDATA2_OFFSET                                0x80
+#define  LEON_REG_UARTSTATUS2_OFFSET                              0x84
+#define  LEON_REG_UARTCTRL2_OFFSET                                0x88
+#define  LEON_REG_UARTSCALER2_OFFSET                              0x8C
+#define  LEON_REG_IRQMASK_OFFSET                                  0x90
+#define  LEON_REG_IRQPEND_OFFSET                                  0x94
+#define  LEON_REG_IRQFORCE_OFFSET                                 0x98
+#define  LEON_REG_IRQCLEAR_OFFSET                                 0x9C
+#define  LEON_REG_PIODATA_OFFSET                                  0xA0
+#define  LEON_REG_PIODIR_OFFSET                                   0xA4
+#define  LEON_REG_PIOIRQ_OFFSET                                   0xA8
+#define  LEON_REG_SIM_RAM_SIZE_OFFSET                             0xF4
+#define  LEON_REG_SIM_ROM_SIZE_OFFSET                             0xF8
+
+/*
+ *  Interrupt Sources
+ *
+ *  The interrupt source numbers directly map to the trap type and to
+ *  the bits used in the Interrupt Clear, Interrupt Force, Interrupt Mask,
+ *  and the Interrupt Pending Registers.
+ */
+#define LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR	1
+#define LEON_INTERRUPT_UART_1_RX_TX		2
+#define LEON_INTERRUPT_UART_0_RX_TX		3
+#define LEON_INTERRUPT_EXTERNAL_0		4
+#define LEON_INTERRUPT_EXTERNAL_1		5
+#define LEON_INTERRUPT_EXTERNAL_2		6
+#define LEON_INTERRUPT_EXTERNAL_3		7
+#define LEON_INTERRUPT_TIMER1			8
+#define LEON_INTERRUPT_TIMER2			9
+#define LEON_INTERRUPT_EMPTY1			10
+#define LEON_INTERRUPT_EMPTY2			11
+#define LEON_INTERRUPT_OPEN_ETH			12
+#define LEON_INTERRUPT_EMPTY4			13
+#define LEON_INTERRUPT_EMPTY5			14
+#define LEON_INTERRUPT_EMPTY6			15
+
+/* Timer Bits */
+#define LEON2_TIMER_CTRL_EN	0x1	/* Timer enable */
+#define LEON2_TIMER_CTRL_RS	0x2	/* Timer reStart  */
+#define LEON2_TIMER_CTRL_LD	0x4	/* Timer reLoad */
+#define LEON2_TIMER1_IRQNO	8	/* Timer 1 IRQ number */
+#define LEON2_TIMER2_IRQNO	9	/* Timer 2 IRQ number */
+#define LEON2_TIMER1_IE		(1<<LEON2_TIMER1_IRQNO)	/* Timer 1 interrupt enable */
+#define LEON2_TIMER2_IE		(1<<LEON2_TIMER2_IRQNO)	/* Timer 2 interrupt enable */
+
+/* UART bits */
+#define LEON2_UART_CTRL_RE	1	/* UART Receiver enable */
+#define LEON2_UART_CTRL_TE	2	/* UART Transmitter enable */
+#define LEON2_UART_CTRL_RI	4	/* UART Receiver Interrupt enable */
+#define LEON2_UART_CTRL_TI	8	/* UART Transmitter Interrupt enable */
+#define LEON2_UART_CTRL_DBG (1<<11)	/* Debug Bit used by GRMON */
+
+#define LEON2_UART_STAT_DR	1	/* UART Data Ready */
+#define LEON2_UART_STAT_TSE	2	/* UART Transmit Shift Reg empty */
+#define LEON2_UART_STAT_THE	4	/* UART Transmit Hold Reg empty */
+
+#else
+#error Include LEON2 header file only if LEON2 processor
+#endif
+
+#endif
diff --git a/include/asm-sparc/leon3.h b/include/asm-sparc/leon3.h
new file mode 100644
index 0000000..84d0e2e
--- /dev/null
+++ b/include/asm-sparc/leon3.h
@@ -0,0 +1,37 @@
+/* LEON3 header file. LEON3 is a free GPL SOC processor available
+ * at www.gaisler.com.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __LEON3_H__
+#define __LEON3_H__
+
+#ifndef CONFIG_LEON3
+#error Include LEON3 header file only if LEON3 processor
+#endif
+
+/* Not much to define, most is Plug and Play and GRLIB dependent 
+ * not LEON3 dependent. See <ambapp.h> for GRLIB timers, interrupt 
+ * ctrl, memory controllers etc.
+ */
+
+
+#endif
diff --git a/include/asm-sparc/machines.h b/include/asm-sparc/machines.h
new file mode 100644
index 0000000..1e26195
--- /dev/null
+++ b/include/asm-sparc/machines.h
@@ -0,0 +1,92 @@
+/* machines.h:  Defines for taking apart the machine type value in the
+ *              idprom and determining the kind of machine we are on.
+ *
+ * Taken from the SPARC port of Linux.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2007 Daniel Hellstrom (daniel@gaisler.com)
+ *
+ * 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
+ *
+ */
+
+#ifndef __SPARC_MACHINES_H__
+#define __SPARC_MACHINES_H__
+
+struct Sun_Machine_Models {
+	char *name;
+	unsigned char id_machtype;
+};
+
+/* Current number of machines we know about that has an IDPROM
+ * machtype entry including one entry for the 0x80 OBP machines.
+ */
+#define NUM_SUN_MACHINES   16
+
+extern struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES];
+
+/* The machine type in the idprom area looks like this:
+ *
+ * ---------------
+ * | ARCH | MACH |
+ * ---------------
+ *  7    4 3    0
+ *
+ * The ARCH field determines the architecture line (sun4, sun4c, etc).
+ * The MACH field determines the machine make within that architecture.
+ */
+
+#define SM_ARCH_MASK  0xf0
+#define SM_SUN4       0x20
+#define  M_LEON2      0x30
+#define SM_SUN4C      0x50
+#define SM_SUN4M      0x70
+#define SM_SUN4M_OBP  0x80
+
+#define SM_TYP_MASK   0x0f
+/* Sun4 machines */
+#define SM_4_260      0x01	/* Sun 4/200 series */
+#define SM_4_110      0x02	/* Sun 4/100 series */
+#define SM_4_330      0x03	/* Sun 4/300 series */
+#define SM_4_470      0x04	/* Sun 4/400 series */
+
+/* Leon machines */
+#define M_LEON2_SOC   0x01	/* Leon2 SoC */
+
+/* Sun4c machines                Full Name              - PROM NAME */
+#define SM_4C_SS1     0x01	/* Sun4c SparcStation 1   - Sun 4/60  */
+#define SM_4C_IPC     0x02	/* Sun4c SparcStation IPC - Sun 4/40  */
+#define SM_4C_SS1PLUS 0x03	/* Sun4c SparcStation 1+  - Sun 4/65  */
+#define SM_4C_SLC     0x04	/* Sun4c SparcStation SLC - Sun 4/20  */
+#define SM_4C_SS2     0x05	/* Sun4c SparcStation 2   - Sun 4/75  */
+#define SM_4C_ELC     0x06	/* Sun4c SparcStation ELC - Sun 4/25  */
+#define SM_4C_IPX     0x07	/* Sun4c SparcStation IPX - Sun 4/50  */
+
+/* Sun4m machines, these predate the OpenBoot.  These values only mean
+ * something if the value in the ARCH field is SM_SUN4M, if it is
+ * SM_SUN4M_OBP then you have the following situation:
+ * 1) You either have a sun4d, a sun4e, or a recently made sun4m.
+ * 2) You have to consult OpenBoot to determine which machine this is.
+ */
+#define SM_4M_SS60    0x01	/* Sun4m SparcSystem 600                  */
+#define SM_4M_SS50    0x02	/* Sun4m SparcStation 10                  */
+#define SM_4M_SS40    0x03	/* Sun4m SparcStation 5                   */
+
+/* Sun4d machines -- N/A */
+/* Sun4e machines -- N/A */
+/* Sun4u machines -- N/A */
+
+#endif				/* !(_SPARC_MACHINES_H) */
diff --git a/include/asm-sparc/page.h b/include/asm-sparc/page.h
new file mode 100644
index 0000000..484953a
--- /dev/null
+++ b/include/asm-sparc/page.h
@@ -0,0 +1,43 @@
+/* page.h:  Various defines and such for MMU operations on the Sparc for
+ *          the Linux kernel.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2007 Daniel Hellstrom (daniel@gaisler.com)
+ *
+ * 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
+ *
+ */
+
+#ifndef _SPARC_PAGE_H
+#define _SPARC_PAGE_H
+
+#include <linux/config.h>
+#ifdef CONFIG_SUN4
+#define PAGE_SHIFT   13
+#else
+#define PAGE_SHIFT   12
+#endif
+
+#ifndef __ASSEMBLY__
+/* I have my suspicions... -DaveM */
+#define PAGE_SIZE    (1UL << PAGE_SHIFT)
+#else
+#define PAGE_SIZE    (1 << PAGE_SHIFT)
+#endif
+
+#define PAGE_MASK    (~(PAGE_SIZE-1))
+
+#endif				/* _SPARC_PAGE_H */
diff --git a/include/asm-sparc/posix_types.h b/include/asm-sparc/posix_types.h
new file mode 100644
index 0000000..8d98b2a
--- /dev/null
+++ b/include/asm-sparc/posix_types.h
@@ -0,0 +1,139 @@
+/*
+ * (C) Copyright 2000 - 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007, taken from asm-ppc/posix_types.h
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __SPARC_POSIX_TYPES_H__
+#define __SPARC_POSIX_TYPES_H__
+
+/*
+ * This file is generally used by user-level software, so you need to
+ * be a little careful about namespace pollution etc.  Also, we cannot
+ * assume GCC is being used.
+ */
+
+typedef unsigned int __kernel_dev_t;
+typedef unsigned int __kernel_ino_t;
+typedef unsigned int __kernel_mode_t;
+typedef unsigned short __kernel_nlink_t;
+typedef long __kernel_off_t;
+typedef int __kernel_pid_t;
+typedef unsigned int __kernel_uid_t;
+typedef unsigned int __kernel_gid_t;
+typedef unsigned int __kernel_size_t;
+typedef int __kernel_ssize_t;
+typedef long __kernel_ptrdiff_t;
+typedef long __kernel_time_t;
+typedef long __kernel_suseconds_t;
+typedef long __kernel_clock_t;
+typedef int __kernel_daddr_t;
+typedef char *__kernel_caddr_t;
+typedef short __kernel_ipc_pid_t;
+typedef unsigned short __kernel_uid16_t;
+typedef unsigned short __kernel_gid16_t;
+typedef unsigned int __kernel_uid32_t;
+typedef unsigned int __kernel_gid32_t;
+
+typedef unsigned int __kernel_old_uid_t;
+typedef unsigned int __kernel_old_gid_t;
+
+#ifdef __GNUC__
+typedef long long __kernel_loff_t;
+#endif
+
+typedef struct {
+	int val[2];
+} __kernel_fsid_t;
+
+#ifndef __GNUC__
+
+#define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
+#define	__FD_CLR(d, set)	((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
+#define	__FD_ISSET(d, set)	((set)->fds_bits[__FDELT(d)] & __FDMASK(d))
+#define	__FD_ZERO(set)	\
+  ((void) memset ((__ptr_t) (set), 0, sizeof (__kernel_fd_set)))
+
+#else				/* __GNUC__ */
+
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) \
+    || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
+/* With GNU C, use inline functions instead so args are evaluated only once: */
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set * fdsetp)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	fdsetp->fds_bits[_tmp] |= (1UL << _rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set * fdsetp)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	fdsetp->fds_bits[_tmp] &= ~(1UL << _rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long fd, __kernel_fd_set * p)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	return (p->fds_bits[_tmp] & (1UL << _rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(__kernel_fd_set * p)
+{
+	unsigned int *tmp = (unsigned int *)p->fds_bits;
+	int i;
+
+	if (__builtin_constant_p(__FDSET_LONGS)) {
+		switch (__FDSET_LONGS) {
+		case 8:
+			tmp[0] = 0;
+			tmp[1] = 0;
+			tmp[2] = 0;
+			tmp[3] = 0;
+			tmp[4] = 0;
+			tmp[5] = 0;
+			tmp[6] = 0;
+			tmp[7] = 0;
+			return;
+		}
+	}
+	i = __FDSET_LONGS;
+	while (i) {
+		i--;
+		*tmp = 0;
+		tmp++;
+	}
+}
+
+#endif				/* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+#endif				/* __GNUC__ */
+#endif				/* _SPARC_POSIX_TYPES_H */
diff --git a/include/asm-sparc/processor.h b/include/asm-sparc/processor.h
new file mode 100644
index 0000000..d518389
--- /dev/null
+++ b/include/asm-sparc/processor.h
@@ -0,0 +1,116 @@
+/* SPARC Processor specifics
+ * taken from the SPARC port of Linux (ptrace.h).
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __ASM_SPARC_PROCESSOR_H
+#define __ASM_SPARC_PROCESSOR_H
+
+#include <asm/arch/asi.h>
+
+#ifdef CONFIG_LEON
+
+/* All LEON processors supported */
+#include <asm/leon.h>
+
+#else
+/* other processors */
+#error Unknown SPARC Processor
+#endif
+
+#ifndef __ASSEMBLY__
+
+/* flush data cache */
+static __inline__ void sparc_dcache_flush_all(void)
+{
+      __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"::"i"(ASI_DFLUSH):"memory");
+}
+
+/* flush instruction cache */
+static __inline__ void sparc_icache_flush_all(void)
+{
+      __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t"::"i"(ASI_IFLUSH):"memory");
+}
+
+/* do a cache miss load */
+static __inline__ unsigned long long sparc_load_reg_cachemiss_qword(unsigned
+								    long paddr)
+{
+	unsigned long long retval;
+	__asm__ __volatile__("ldda [%1] %2, %0\n\t":
+			     "=r"(retval):"r"(paddr), "i"(ASI_CACHEMISS));
+	return retval;
+}
+
+static __inline__ unsigned long sparc_load_reg_cachemiss(unsigned long paddr)
+{
+	unsigned long retval;
+	__asm__ __volatile__("lda [%1] %2, %0\n\t":
+			     "=r"(retval):"r"(paddr), "i"(ASI_CACHEMISS));
+	return retval;
+}
+
+static __inline__ unsigned short sparc_load_reg_cachemiss_word(unsigned long
+							       paddr)
+{
+	unsigned short retval;
+	__asm__ __volatile__("lduha [%1] %2, %0\n\t":
+			     "=r"(retval):"r"(paddr), "i"(ASI_CACHEMISS));
+	return retval;
+}
+
+static __inline__ unsigned char sparc_load_reg_cachemiss_byte(unsigned long
+							      paddr)
+{
+	unsigned char retval;
+	__asm__ __volatile__("lduba [%1] %2, %0\n\t":
+			     "=r"(retval):"r"(paddr), "i"(ASI_CACHEMISS));
+	return retval;
+}
+
+/* do a physical address bypass write, i.e. for 0x80000000 */
+static __inline__ void sparc_store_reg_bypass(unsigned long paddr,
+					      unsigned long value)
+{
+	__asm__ __volatile__("sta %0, [%1] %2\n\t"::"r"(value), "r"(paddr),
+			     "i"(ASI_BYPASS):"memory");
+}
+
+static __inline__ unsigned long sparc_load_reg_bypass(unsigned long paddr)
+{
+	unsigned long retval;
+	__asm__ __volatile__("lda [%1] %2, %0\n\t":
+			     "=r"(retval):"r"(paddr), "i"(ASI_BYPASS));
+	return retval;
+}
+
+/* Macros for bypassing cache when reading */
+#define SPARC_NOCACHE_READ_DWORD(address) sparc_load_reg_cachemiss_qword((unsigned int)(address))
+#define SPARC_NOCACHE_READ(address)       sparc_load_reg_cachemiss((unsigned int)(address))
+#define SPARC_NOCACHE_READ_HWORD(address) sparc_load_reg_cachemiss_word((unsigned int)(address))
+#define SPARC_NOCACHE_READ_BYTE(address)  sparc_load_reg_cachemiss_byte((unsigned int)(address))
+
+#define SPARC_BYPASS_READ(address)        sparc_load_reg_bypass((unsigned int)(address))
+#define SPARC_BYPASS_WRITE(address,value) sparc_store_reg_bypass((unsigned int)(address),(unsigned int)(value))
+
+#endif
+
+#endif				/* __ASM_SPARC_PROCESSOR_H */
diff --git a/include/asm-sparc/prom.h b/include/asm-sparc/prom.h
new file mode 100644
index 0000000..d55cc86
--- /dev/null
+++ b/include/asm-sparc/prom.h
@@ -0,0 +1,297 @@
+/* OpenProm defines mainly taken from linux kernel header files
+ *
+ * openprom.h:  Prom structures and defines for access to the OPENBOOT
+ *              prom routines and data areas.
+ *
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2007 Daniel Hellstrom (daniel@gaisler.com)
+ *
+ * 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
+ *
+ */
+
+#ifndef __SPARC_OPENPROM_H__
+#define __SPARC_OPENPROM_H__
+
+/* Empirical constants... */
+#define	LINUX_OPPROM_MAGIC      0x10010407
+
+#ifndef __ASSEMBLY__
+/* V0 prom device operations. */
+struct linux_dev_v0_funcs {
+	int (*v0_devopen) (char *device_str);
+	int (*v0_devclose) (int dev_desc);
+	int (*v0_rdblkdev) (int dev_desc, int num_blks, int blk_st, char *buf);
+	int (*v0_wrblkdev) (int dev_desc, int num_blks, int blk_st, char *buf);
+	int (*v0_wrnetdev) (int dev_desc, int num_bytes, char *buf);
+	int (*v0_rdnetdev) (int dev_desc, int num_bytes, char *buf);
+	int (*v0_rdchardev) (int dev_desc, int num_bytes, int dummy, char *buf);
+	int (*v0_wrchardev) (int dev_desc, int num_bytes, int dummy, char *buf);
+	int (*v0_seekdev) (int dev_desc, long logical_offst, int from);
+};
+
+/* V2 and later prom device operations. */
+struct linux_dev_v2_funcs {
+	int (*v2_inst2pkg) (int d);	/* Convert ihandle to phandle */
+	char *(*v2_dumb_mem_alloc) (char *va, unsigned sz);
+	void (*v2_dumb_mem_free) (char *va, unsigned sz);
+
+	/* To map devices into virtual I/O space. */
+	char *(*v2_dumb_mmap) (char *virta, int which_io, unsigned paddr,
+			       unsigned sz);
+	void (*v2_dumb_munmap) (char *virta, unsigned size);
+
+	int (*v2_dev_open) (char *devpath);
+	void (*v2_dev_close) (int d);
+	int (*v2_dev_read) (int d, char *buf, int nbytes);
+	int (*v2_dev_write) (int d, char *buf, int nbytes);
+	int (*v2_dev_seek) (int d, int hi, int lo);
+
+	/* Never issued (multistage load support) */
+	void (*v2_wheee2) (void);
+	void (*v2_wheee3) (void);
+};
+
+struct linux_mlist_v0 {
+	struct linux_mlist_v0 *theres_more;
+	char *start_adr;
+	unsigned num_bytes;
+};
+
+struct linux_mem_v0 {
+	struct linux_mlist_v0 **v0_totphys;
+	struct linux_mlist_v0 **v0_prommap;
+	struct linux_mlist_v0 **v0_available;	/* What we can use */
+};
+
+/* Arguments sent to the kernel from the boot prompt. */
+struct linux_arguments_v0 {
+	char *argv[8];
+	char args[100];
+	char boot_dev[2];
+	int boot_dev_ctrl;
+	int boot_dev_unit;
+	int dev_partition;
+	char *kernel_file_name;
+	void *aieee1;		/* XXX */
+};
+
+/* V2 and up boot things. */
+struct linux_bootargs_v2 {
+	char **bootpath;
+	char **bootargs;
+	int *fd_stdin;
+	int *fd_stdout;
+};
+
+/* The top level PROM vector. */
+struct linux_romvec {
+	/* Version numbers. */
+	unsigned int pv_magic_cookie;
+	unsigned int pv_romvers;
+	unsigned int pv_plugin_revision;
+	unsigned int pv_printrev;
+
+	/* Version 0 memory descriptors. */
+	struct linux_mem_v0 pv_v0mem;
+
+	/* Node operations. */
+	struct linux_nodeops *pv_nodeops;
+
+	char **pv_bootstr;
+	struct linux_dev_v0_funcs pv_v0devops;
+
+	char *pv_stdin;
+	char *pv_stdout;
+#define	PROMDEV_KBD	0	/* input from keyboard */
+#define	PROMDEV_SCREEN	0	/* output to screen */
+#define	PROMDEV_TTYA	1	/* in/out to ttya */
+#define	PROMDEV_TTYB	2	/* in/out to ttyb */
+
+	/* Blocking getchar/putchar.  NOT REENTRANT! (grr) */
+	int (*pv_getchar) (void);
+	void (*pv_putchar) (int ch);
+
+	/* Non-blocking variants. */
+	int (*pv_nbgetchar) (void);
+	int (*pv_nbputchar) (int ch);
+
+	void (*pv_putstr) (char *str, int len);
+
+	/* Miscellany. */
+	void (*pv_reboot) (char *bootstr);
+	void (*pv_printf) (__const__ char *fmt, ...);
+	void (*pv_abort) (void);
+	__volatile__ int *pv_ticks;
+	void (*pv_halt) (void);
+	void (**pv_synchook) (void);
+
+	/* Evaluate a forth string, not different proto for V0 and V2->up. */
+	union {
+		void (*v0_eval) (int len, char *str);
+		void (*v2_eval) (char *str);
+	} pv_fortheval;
+
+	struct linux_arguments_v0 **pv_v0bootargs;
+
+	/* Get ether address. */
+	unsigned int (*pv_enaddr) (int d, char *enaddr);
+
+	struct linux_bootargs_v2 pv_v2bootargs;
+	struct linux_dev_v2_funcs pv_v2devops;
+
+	int filler[15];
+
+	/* This one is sun4c/sun4 only. */
+	void (*pv_setctxt) (int ctxt, char *va, int pmeg);
+
+	/* Prom version 3 Multiprocessor routines. This stuff is crazy.
+	 * No joke. Calling these when there is only one cpu probably
+	 * crashes the machine, have to test this. :-)
+	 */
+
+	/* v3_cpustart() will start the cpu 'whichcpu' in mmu-context
+	 * 'thiscontext' executing at address 'prog_counter'
+	 */
+	int (*v3_cpustart) (unsigned int whichcpu, int ctxtbl_ptr,
+			    int thiscontext, char *prog_counter);
+
+	/* v3_cpustop() will cause cpu 'whichcpu' to stop executing
+	 * until a resume cpu call is made.
+	 */
+	int (*v3_cpustop) (unsigned int whichcpu);
+
+	/* v3_cpuidle() will idle cpu 'whichcpu' until a stop or
+	 * resume cpu call is made.
+	 */
+	int (*v3_cpuidle) (unsigned int whichcpu);
+
+	/* v3_cpuresume() will resume processor 'whichcpu' executing
+	 * starting with whatever 'pc' and 'npc' were left at the
+	 * last 'idle' or 'stop' call.
+	 */
+	int (*v3_cpuresume) (unsigned int whichcpu);
+};
+
+/* Routines for traversing the prom device tree. */
+struct linux_nodeops {
+	int (*no_nextnode) (int node);
+	int (*no_child) (int node);
+	int (*no_proplen) (int node, char *name);
+	int (*no_getprop) (int node, char *name, char *val);
+	int (*no_setprop) (int node, char *name, char *val, int len);
+	char *(*no_nextprop) (int node, char *name);
+};
+
+/* More fun PROM structures for device probing. */
+#define PROMREG_MAX     16
+#define PROMVADDR_MAX   16
+#define PROMINTR_MAX    15
+
+struct linux_prom_registers {
+	unsigned int which_io;	/* is this in OBIO space? */
+	unsigned int phys_addr;	/* The physical address of this register */
+	unsigned int reg_size;	/* How many bytes does this register take up? */
+};
+
+struct linux_prom_irqs {
+	int pri;		/* IRQ priority */
+	int vector;		/* This is foobar, what does it do? */
+};
+
+/* Element of the "ranges" vector */
+struct linux_prom_ranges {
+	unsigned int ot_child_space;
+	unsigned int ot_child_base;	/* Bus feels this */
+	unsigned int ot_parent_space;
+	unsigned int ot_parent_base;	/* CPU looks from here */
+	unsigned int or_size;
+};
+
+/* Ranges and reg properties are a bit different for PCI. */
+struct linux_prom_pci_registers {
+	/*
+	 * We don't know what information this field contain.
+	 * We guess, PCI device function is in bits 15:8
+	 * So, ...
+	 */
+	unsigned int which_io;	/* Let it be which_io */
+
+	unsigned int phys_hi;
+	unsigned int phys_lo;
+
+	unsigned int size_hi;
+	unsigned int size_lo;
+};
+
+struct linux_prom_pci_ranges {
+	unsigned int child_phys_hi;	/* Only certain bits are encoded here. */
+	unsigned int child_phys_mid;
+	unsigned int child_phys_lo;
+
+	unsigned int parent_phys_hi;
+	unsigned int parent_phys_lo;
+
+	unsigned int size_hi;
+	unsigned int size_lo;
+};
+
+struct linux_prom_pci_assigned_addresses {
+	unsigned int which_io;
+
+	unsigned int phys_hi;
+	unsigned int phys_lo;
+
+	unsigned int size_hi;
+	unsigned int size_lo;
+};
+
+struct linux_prom_ebus_ranges {
+	unsigned int child_phys_hi;
+	unsigned int child_phys_lo;
+
+	unsigned int parent_phys_hi;
+	unsigned int parent_phys_mid;
+	unsigned int parent_phys_lo;
+
+	unsigned int size;
+};
+
+/* Offset into the EEPROM where the id PROM is located on the 4c */
+#define IDPROM_OFFSET  0x7d8
+
+/* On sun4m; physical. */
+/* MicroSPARC(-II) does not decode 31rd bit, but it works. */
+#define IDPROM_OFFSET_M  0xfd8
+
+struct idprom {
+	unsigned char id_format;	/* Format identifier (always 0x01) */
+	unsigned char id_machtype;	/* Machine type */
+	unsigned char id_ethaddr[6];	/* Hardware ethernet address */
+	long id_date;		/* Date of manufacture */
+	unsigned int id_sernum:24;	/* Unique serial number */
+	unsigned char id_cksum;	/* Checksum - xor of the data bytes */
+	unsigned char reserved[16];
+};
+
+extern struct idprom *idprom;
+extern void idprom_init(void);
+
+#define IDPROM_SIZE  (sizeof(struct idprom))
+
+#endif				/* !(__ASSEMBLY__) */
+
+#endif
diff --git a/include/asm-sparc/psr.h b/include/asm-sparc/psr.h
new file mode 100644
index 0000000..fc77947
--- /dev/null
+++ b/include/asm-sparc/psr.h
@@ -0,0 +1,97 @@
+/* psr.h: This file holds the macros for masking off various parts of
+ *        the processor status register on the Sparc. This is valid
+ *        for Version 8. On the V9 this is renamed to the PSTATE
+ *        register and its members are accessed as fields like
+ *        PSTATE.PRIV for the current CPU privilege level.
+ *
+ * taken from the SPARC port of Linux,
+ *
+ * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 2007 Daniel Hellstrom (daniel@gaisler.com)
+ *
+ * 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
+ *
+ */
+
+#ifndef __SPARC_PSR_H__
+#define __SPARC_PSR_H__
+
+/* The Sparc PSR fields are laid out as the following:
+ *
+ *  ------------------------------------------------------------------------
+ *  | impl  | vers  | icc   | resv  | EC | EF | PIL  | S | PS | ET |  CWP  |
+ *  | 31-28 | 27-24 | 23-20 | 19-14 | 13 | 12 | 11-8 | 7 | 6  | 5  |  4-0  |
+ *  ------------------------------------------------------------------------
+ */
+#define PSR_CWP     0x0000001f	/* current window pointer     */
+#define PSR_ET      0x00000020	/* enable traps field         */
+#define PSR_PS      0x00000040	/* previous privilege level   */
+#define PSR_S       0x00000080	/* current privilege level    */
+#define PSR_PIL     0x00000f00	/* processor interrupt level  */
+#define PSR_EF      0x00001000	/* enable floating point      */
+#define PSR_EC      0x00002000	/* enable co-processor        */
+#define PSR_LE      0x00008000	/* SuperSparcII little-endian */
+#define PSR_ICC     0x00f00000	/* integer condition codes    */
+#define PSR_C       0x00100000	/* carry bit                  */
+#define PSR_V       0x00200000	/* overflow bit               */
+#define PSR_Z       0x00400000	/* zero bit                   */
+#define PSR_N       0x00800000	/* negative bit               */
+#define PSR_VERS    0x0f000000	/* cpu-version field          */
+#define PSR_IMPL    0xf0000000	/* cpu-implementation field   */
+
+#define PSR_PIL_OFS  8
+
+#ifndef __ASSEMBLY__
+/* Get the %psr register. */
+extern __inline__ unsigned int get_psr(void)
+{
+	unsigned int psr;
+	__asm__ __volatile__("rd	%%psr, %0\n\t"
+			     "nop\n\t" "nop\n\t" "nop\n\t":"=r"(psr)
+			     :	/* no inputs */
+			     :"memory");
+
+	return psr;
+}
+
+extern __inline__ void put_psr(unsigned int new_psr)
+{
+	__asm__ __volatile__("wr	%0, 0x0, %%psr\n\t" "nop\n\t" "nop\n\t" "nop\n\t":	/* no outputs */
+			     :"r"(new_psr)
+			     :"memory", "cc");
+}
+
+/* Get the %fsr register.  Be careful, make sure the floating point
+ * enable bit is set in the %psr when you execute this or you will
+ * incur a trap.
+ */
+
+extern unsigned int fsr_storage;
+
+extern __inline__ unsigned int get_fsr(void)
+{
+	unsigned int fsr = 0;
+
+	__asm__ __volatile__("st	%%fsr, %1\n\t"
+			     "ld	%1, %0\n\t":"=r"(fsr)
+			     :"m"(fsr_storage));
+
+	return fsr;
+}
+
+#endif				/* !(__ASSEMBLY__) */
+
+#endif				/* !(__SPARC_PSR_H__) */
diff --git a/include/asm-sparc/ptrace.h b/include/asm-sparc/ptrace.h
new file mode 100644
index 0000000..12a9c56
--- /dev/null
+++ b/include/asm-sparc/ptrace.h
@@ -0,0 +1,181 @@
+/* Contain the Stack frame layout on interrupt. pt_regs.
+ * taken from the SPARC port of Linux (ptrace.h).
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __SPARC_PTRACE_H__
+#define __SPARC_PTRACE_H__
+
+#include <asm/psr.h>
+
+/* This struct defines the way the registers are stored on the
+ * stack during a system call and basically all traps.
+ */
+
+#ifndef __ASSEMBLY__
+
+struct pt_regs {
+	unsigned long psr;
+	unsigned long pc;
+	unsigned long npc;
+	unsigned long y;
+	unsigned long u_regs[16];	/* globals and ins */
+};
+
+#define UREG_G0        0
+#define UREG_G1        1
+#define UREG_G2        2
+#define UREG_G3        3
+#define UREG_G4        4
+#define UREG_G5        5
+#define UREG_G6        6
+#define UREG_G7        7
+#define UREG_I0        8
+#define UREG_I1        9
+#define UREG_I2        10
+#define UREG_I3        11
+#define UREG_I4        12
+#define UREG_I5        13
+#define UREG_I6        14
+#define UREG_I7        15
+#define UREG_WIM       UREG_G0
+#define UREG_FADDR     UREG_G0
+#define UREG_FP        UREG_I6
+#define UREG_RETPC     UREG_I7
+
+/* A register window */
+struct reg_window {
+	unsigned long locals[8];
+	unsigned long ins[8];
+};
+
+/* A Sparc stack frame */
+struct sparc_stackf {
+	unsigned long locals[8];
+	unsigned long ins[6];
+	struct sparc_stackf *fp;
+	unsigned long callers_pc;
+	char *structptr;
+	unsigned long xargs[6];
+	unsigned long xxargs[1];
+};
+
+#define TRACEREG_SZ   sizeof(struct pt_regs)
+#define STACKFRAME_SZ sizeof(struct sparc_stackf)
+
+#else				/* __ASSEMBLY__ */
+/* For assembly code. */
+#define TRACEREG_SZ       0x50
+#define STACKFRAME_SZ     0x60
+#endif
+
+/*
+ * The asm_offsets.h is a generated file, so we cannot include it.
+ * It may be OK for glibc headers, but it's utterly pointless for C code.
+ * The assembly code using those offsets has to include it explicitly.
+ */
+/* #include <asm/asm_offsets.h> */
+
+/* These are for pt_regs. */
+#define PT_PSR    0x0
+#define PT_PC     0x4
+#define PT_NPC    0x8
+#define PT_Y      0xc
+#define PT_G0     0x10
+#define PT_WIM    PT_G0
+#define PT_G1     0x14
+#define PT_G2     0x18
+#define PT_G3     0x1c
+#define PT_G4     0x20
+#define PT_G5     0x24
+#define PT_G6     0x28
+#define PT_G7     0x2c
+#define PT_I0     0x30
+#define PT_I1     0x34
+#define PT_I2     0x38
+#define PT_I3     0x3c
+#define PT_I4     0x40
+#define PT_I5     0x44
+#define PT_I6     0x48
+#define PT_FP     PT_I6
+#define PT_I7     0x4c
+
+/* Reg_window offsets */
+#define RW_L0     0x00
+#define RW_L1     0x04
+#define RW_L2     0x08
+#define RW_L3     0x0c
+#define RW_L4     0x10
+#define RW_L5     0x14
+#define RW_L6     0x18
+#define RW_L7     0x1c
+#define RW_I0     0x20
+#define RW_I1     0x24
+#define RW_I2     0x28
+#define RW_I3     0x2c
+#define RW_I4     0x30
+#define RW_I5     0x34
+#define RW_I6     0x38
+#define RW_I7     0x3c
+
+/* Stack_frame offsets */
+#define SF_L0     0x00
+#define SF_L1     0x04
+#define SF_L2     0x08
+#define SF_L3     0x0c
+#define SF_L4     0x10
+#define SF_L5     0x14
+#define SF_L6     0x18
+#define SF_L7     0x1c
+#define SF_I0     0x20
+#define SF_I1     0x24
+#define SF_I2     0x28
+#define SF_I3     0x2c
+#define SF_I4     0x30
+#define SF_I5     0x34
+#define SF_FP     0x38
+#define SF_PC     0x3c
+#define SF_RETP   0x40
+#define SF_XARG0  0x44
+#define SF_XARG1  0x48
+#define SF_XARG2  0x4c
+#define SF_XARG3  0x50
+#define SF_XARG4  0x54
+#define SF_XARG5  0x58
+#define SF_XXARG  0x5c
+
+/* Stuff for the ptrace system call */
+#define PTRACE_SUNATTACH          10
+#define PTRACE_SUNDETACH          11
+#define PTRACE_GETREGS            12
+#define PTRACE_SETREGS            13
+#define PTRACE_GETFPREGS          14
+#define PTRACE_SETFPREGS          15
+#define PTRACE_READDATA           16
+#define PTRACE_WRITEDATA          17
+#define PTRACE_READTEXT           18
+#define PTRACE_WRITETEXT          19
+#define PTRACE_GETFPAREGS         20
+#define PTRACE_SETFPAREGS         21
+
+#define PTRACE_GETUCODE           29	/* stupid bsd-ism */
+
+#endif				/* !(_SPARC_PTRACE_H) */
diff --git a/include/asm-sparc/srmmu.h b/include/asm-sparc/srmmu.h
new file mode 100644
index 0000000..5214d96
--- /dev/null
+++ b/include/asm-sparc/srmmu.h
@@ -0,0 +1,301 @@
+/* SRMMU page table defines and code,
+ * taken from the SPARC port of Linux
+ *
+ * Copyright (C) 2007 Daniel Hellstrom (daniel@gaisler.com)
+ * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *
+ * 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
+ *
+ */
+
+#ifndef __SPARC_SRMMU_H__
+#define __SPARC_SRMMU_H__
+
+#include <asm/asi.h>
+#include <asm/page.h>
+
+/* Number of contexts is implementation-dependent; 64k is the most we support */
+#define SRMMU_MAX_CONTEXTS	65536
+
+/* PMD_SHIFT determines the size of the area a second-level page table entry can map */
+#define SRMMU_REAL_PMD_SHIFT		18
+#define SRMMU_REAL_PMD_SIZE		(1UL << SRMMU_REAL_PMD_SHIFT)
+#define SRMMU_REAL_PMD_MASK		(~(SRMMU_REAL_PMD_SIZE-1))
+#define SRMMU_REAL_PMD_ALIGN(__addr)	(((__addr)+SRMMU_REAL_PMD_SIZE-1)&SRMMU_REAL_PMD_MASK)
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define SRMMU_PGDIR_SHIFT       24
+#define SRMMU_PGDIR_SIZE        (1UL << SRMMU_PGDIR_SHIFT)
+#define SRMMU_PGDIR_MASK        (~(SRMMU_PGDIR_SIZE-1))
+#define SRMMU_PGDIR_ALIGN(addr) (((addr)+SRMMU_PGDIR_SIZE-1)&SRMMU_PGDIR_MASK)
+
+#define SRMMU_REAL_PTRS_PER_PTE	64
+#define SRMMU_REAL_PTRS_PER_PMD	64
+#define SRMMU_PTRS_PER_PGD	256
+
+#define SRMMU_REAL_PTE_TABLE_SIZE	(SRMMU_REAL_PTRS_PER_PTE*4)
+#define SRMMU_PMD_TABLE_SIZE		(SRMMU_REAL_PTRS_PER_PMD*4)
+#define SRMMU_PGD_TABLE_SIZE		(SRMMU_PTRS_PER_PGD*4)
+
+/*
+ * To support pagetables in highmem, Linux introduces APIs which
+ * return struct page* and generally manipulate page tables when
+ * they are not mapped into kernel space. Our hardware page tables
+ * are smaller than pages. We lump hardware tabes into big, page sized
+ * software tables.
+ *
+ * PMD_SHIFT determines the size of the area a second-level page table entry
+ * can map, and our pmd_t is 16 times larger than normal.  The values which
+ * were once defined here are now generic for 4c and srmmu, so they're
+ * found in pgtable.h.
+ */
+#define SRMMU_PTRS_PER_PMD	4
+
+/* Definition of the values in the ET field of PTD's and PTE's */
+#define SRMMU_ET_MASK         0x3
+#define SRMMU_ET_INVALID      0x0
+#define SRMMU_ET_PTD          0x1
+#define SRMMU_ET_PTE          0x2
+#define SRMMU_ET_REPTE        0x3	/* AIEEE, SuperSparc II reverse endian page! */
+
+/* Physical page extraction from PTP's and PTE's. */
+#define SRMMU_CTX_PMASK    0xfffffff0
+#define SRMMU_PTD_PMASK    0xfffffff0
+#define SRMMU_PTE_PMASK    0xffffff00
+
+/* The pte non-page bits.  Some notes:
+ * 1) cache, dirty, valid, and ref are frobbable
+ *    for both supervisor and user pages.
+ * 2) exec and write will only give the desired effect
+ *    on user pages
+ * 3) use priv and priv_readonly for changing the
+ *    characteristics of supervisor ptes
+ */
+#define SRMMU_CACHE        0x80
+#define SRMMU_DIRTY        0x40
+#define SRMMU_REF          0x20
+#define SRMMU_NOREAD       0x10
+#define SRMMU_EXEC         0x08
+#define SRMMU_WRITE        0x04
+#define SRMMU_VALID        0x02	/* SRMMU_ET_PTE */
+#define SRMMU_PRIV         0x1c
+#define SRMMU_PRIV_RDONLY  0x18
+
+#define SRMMU_FILE         0x40	/* Implemented in software */
+
+#define SRMMU_PTE_FILE_SHIFT     8	/* == 32-PTE_FILE_MAX_BITS */
+
+#define SRMMU_CHG_MASK    (0xffffff00 | SRMMU_REF | SRMMU_DIRTY)
+
+/* SRMMU swap entry encoding
+ *
+ * We use 5 bits for the type and 19 for the offset.  This gives us
+ * 32 swapfiles of 4GB each.  Encoding looks like:
+ *
+ * oooooooooooooooooootttttRRRRRRRR
+ * fedcba9876543210fedcba9876543210
+ *
+ * The bottom 8 bits are reserved for protection and status bits, especially
+ * FILE and PRESENT.
+ */
+#define SRMMU_SWP_TYPE_MASK	0x1f
+#define SRMMU_SWP_TYPE_SHIFT	SRMMU_PTE_FILE_SHIFT
+#define SRMMU_SWP_OFF_MASK	0x7ffff
+#define SRMMU_SWP_OFF_SHIFT	(SRMMU_PTE_FILE_SHIFT + 5)
+
+/* Some day I will implement true fine grained access bits for
+ * user pages because the SRMMU gives us the capabilities to
+ * enforce all the protection levels that vma's can have.
+ * XXX But for now...
+ */
+#define SRMMU_PAGE_NONE    __pgprot(SRMMU_CACHE | \
+				    SRMMU_PRIV | SRMMU_REF)
+#define SRMMU_PAGE_SHARED  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
+				    SRMMU_EXEC | SRMMU_WRITE | SRMMU_REF)
+#define SRMMU_PAGE_COPY    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
+				    SRMMU_EXEC | SRMMU_REF)
+#define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
+				    SRMMU_EXEC | SRMMU_REF)
+#define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
+				    SRMMU_DIRTY | SRMMU_REF)
+
+/* SRMMU Register addresses in ASI 0x4.  These are valid for all
+ * current SRMMU implementations that exist.
+ */
+#define SRMMU_CTRL_REG           0x00000000
+#define SRMMU_CTXTBL_PTR         0x00000100
+#define SRMMU_CTX_REG            0x00000200
+#define SRMMU_FAULT_STATUS       0x00000300
+#define SRMMU_FAULT_ADDR         0x00000400
+
+#define WINDOW_FLUSH(tmp1, tmp2)					\
+	mov	0, tmp1;						\
+98:	ld	[%g6 + TI_UWINMASK], tmp2;				\
+	orcc	%g0, tmp2, %g0;						\
+	add	tmp1, 1, tmp1;						\
+	bne	98b;							\
+	 save	%sp, -64, %sp;						\
+99:	subcc	tmp1, 1, tmp1;						\
+	bne	99b;							\
+	 restore %g0, %g0, %g0;
+
+#ifndef __ASSEMBLY__
+
+/* This makes sense. Honest it does - Anton */
+/* XXX Yes but it's ugly as sin.  FIXME. -KMW */
+extern void *srmmu_nocache_pool;
+#define __nocache_pa(VADDR) (((unsigned long)VADDR) - SRMMU_NOCACHE_VADDR + __pa((unsigned long)srmmu_nocache_pool))
+#define __nocache_va(PADDR) (__va((unsigned long)PADDR) - (unsigned long)srmmu_nocache_pool + SRMMU_NOCACHE_VADDR)
+#define __nocache_fix(VADDR) __va(__nocache_pa(VADDR))
+
+/* Accessing the MMU control register. */
+extern __inline__ unsigned int srmmu_get_mmureg(void)
+{
+	unsigned int retval;
+	__asm__ __volatile__("lda [%%g0] %1, %0\n\t":
+			     "=r"(retval):"i"(ASI_M_MMUREGS));
+	return retval;
+}
+
+extern __inline__ void srmmu_set_mmureg(unsigned long regval)
+{
+	__asm__ __volatile__("sta %0, [%%g0] %1\n\t"::"r"(regval),
+			     "i"(ASI_M_MMUREGS):"memory");
+
+}
+
+extern __inline__ void srmmu_set_ctable_ptr(unsigned long paddr)
+{
+	paddr = ((paddr >> 4) & SRMMU_CTX_PMASK);
+	__asm__ __volatile__("sta %0, [%1] %2\n\t"::"r"(paddr),
+			     "r"(SRMMU_CTXTBL_PTR),
+			     "i"(ASI_M_MMUREGS):"memory");
+}
+
+extern __inline__ unsigned long srmmu_get_ctable_ptr(void)
+{
+	unsigned int retval;
+
+	__asm__ __volatile__("lda [%1] %2, %0\n\t":
+			     "=r"(retval):
+			     "r"(SRMMU_CTXTBL_PTR), "i"(ASI_M_MMUREGS));
+	return (retval & SRMMU_CTX_PMASK) << 4;
+}
+
+extern __inline__ void srmmu_set_context(int context)
+{
+	__asm__ __volatile__("sta %0, [%1] %2\n\t"::"r"(context),
+			     "r"(SRMMU_CTX_REG), "i"(ASI_M_MMUREGS):"memory");
+}
+
+extern __inline__ int srmmu_get_context(void)
+{
+	register int retval;
+	__asm__ __volatile__("lda [%1] %2, %0\n\t":
+			     "=r"(retval):
+			     "r"(SRMMU_CTX_REG), "i"(ASI_M_MMUREGS));
+	return retval;
+}
+
+extern __inline__ unsigned int srmmu_get_fstatus(void)
+{
+	unsigned int retval;
+
+	__asm__ __volatile__("lda [%1] %2, %0\n\t":
+			     "=r"(retval):
+			     "r"(SRMMU_FAULT_STATUS), "i"(ASI_M_MMUREGS));
+	return retval;
+}
+
+extern __inline__ unsigned int srmmu_get_faddr(void)
+{
+	unsigned int retval;
+
+	__asm__ __volatile__("lda [%1] %2, %0\n\t":
+			     "=r"(retval):
+			     "r"(SRMMU_FAULT_ADDR), "i"(ASI_M_MMUREGS));
+	return retval;
+}
+
+/* This is guaranteed on all SRMMU's. */
+extern __inline__ void srmmu_flush_whole_tlb(void)
+{
+	__asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(0x400),	/* Flush entire TLB!! */
+			     "i"(ASI_M_FLUSH_PROBE):"memory");
+
+}
+
+/* These flush types are not available on all chips... */
+extern __inline__ void srmmu_flush_tlb_ctx(void)
+{
+	__asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(0x300),	/* Flush TLB ctx.. */
+			     "i"(ASI_M_FLUSH_PROBE):"memory");
+
+}
+
+extern __inline__ void srmmu_flush_tlb_region(unsigned long addr)
+{
+	addr &= SRMMU_PGDIR_MASK;
+	__asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(addr | 0x200),	/* Flush TLB region.. */
+			     "i"(ASI_M_FLUSH_PROBE):"memory");
+
+}
+
+extern __inline__ void srmmu_flush_tlb_segment(unsigned long addr)
+{
+	addr &= SRMMU_REAL_PMD_MASK;
+	__asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(addr | 0x100),	/* Flush TLB segment.. */
+			     "i"(ASI_M_FLUSH_PROBE):"memory");
+
+}
+
+extern __inline__ void srmmu_flush_tlb_page(unsigned long page)
+{
+	page &= PAGE_MASK;
+	__asm__ __volatile__("sta %%g0, [%0] %1\n\t"::"r"(page),	/* Flush TLB page.. */
+			     "i"(ASI_M_FLUSH_PROBE):"memory");
+
+}
+
+extern __inline__ unsigned long srmmu_hwprobe(unsigned long vaddr)
+{
+	unsigned long retval;
+
+	vaddr &= PAGE_MASK;
+	__asm__ __volatile__("lda [%1] %2, %0\n\t":
+			     "=r"(retval):
+			     "r"(vaddr | 0x400), "i"(ASI_M_FLUSH_PROBE));
+
+	return retval;
+}
+
+extern __inline__ int srmmu_get_pte(unsigned long addr)
+{
+	register unsigned long entry;
+
+	__asm__ __volatile__("\n\tlda [%1] %2,%0\n\t":
+			     "=r"(entry):
+			     "r"((addr & 0xfffff000) | 0x400),
+			     "i"(ASI_M_FLUSH_PROBE));
+	return entry;
+}
+
+extern unsigned long (*srmmu_read_physical) (unsigned long paddr);
+extern void (*srmmu_write_physical) (unsigned long paddr, unsigned long word);
+
+#endif				/* !(__ASSEMBLY__) */
+
+#endif				/* !(__SPARC_SRMMU_H__) */
diff --git a/include/asm-sparc/stack.h b/include/asm-sparc/stack.h
new file mode 100644
index 0000000..b40a9f3
--- /dev/null
+++ b/include/asm-sparc/stack.h
@@ -0,0 +1,162 @@
+/* SPARC stack layout Macros and structures,
+ * mainly taken from BCC (the Bare C compiler for
+ * SPARC LEON2/3) sources.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef __SPARC_STACK_H__
+#define __SPARC_STACK_H__
+
+#include <asm/ptrace.h>
+
+#ifndef __ASSEMBLER__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PT_REGS_SZ   sizeof(struct pt_regs)
+
+/* A Sparc stack frame */
+	struct sparc_stackframe_regs {
+		unsigned long sf_locals[8];
+		unsigned long sf_ins[6];
+		struct sparc_stackframe_regs *sf_fp;
+		unsigned long sf_callers_pc;
+		char *sf_structptr;
+		unsigned long sf_xargs[6];
+		unsigned long sf_xxargs[1];
+	};
+#define SF_REGS_SZ sizeof(struct sparc_stackframe_regs)
+
+/* A register window */
+	struct sparc_regwindow_regs {
+		unsigned long locals[8];
+		unsigned long ins[8];
+	};
+#define RW_REGS_SZ sizeof(struct sparc_regwindow_regs)
+
+/* A fpu window */
+	struct sparc_fpuwindow_regs {
+		unsigned long locals[32];
+		unsigned long fsr;
+		unsigned long lastctx;
+	};
+#define FW_REGS_SZ sizeof(struct sparc_fpuwindow_regs)
+
+#ifdef __cplusplus
+}
+#endif
+#else
+#define PT_REGS_SZ	0x50	/* 20*4 */
+#define SF_REGS_SZ	0x60	/* 24*4 */
+#define RW_REGS_SZ	0x20	/* 16*4 */
+#define FW_REGS_SZ	0x88	/* 34*4 */
+#endif				/* !ASM */
+
+/* These are for pt_regs. */
+#define PT_PSR		0x0
+#define PT_PC		0x4
+#define PT_NPC		0x8
+#define PT_Y		0xc
+#define PT_G0		0x10
+#define PT_WIM		PT_G0
+#define PT_G1		0x14
+#define PT_G2		0x18
+#define PT_G3		0x1c
+#define PT_G4		0x20
+#define PT_G5		0x24
+#define PT_G6		0x28
+#define PT_G7		0x2c
+#define PT_I0		0x30
+#define PT_I1		0x34
+#define PT_I2		0x38
+#define PT_I3		0x3c
+#define PT_I4		0x40
+#define PT_I5		0x44
+#define PT_I6		0x48
+#define PT_FP		PT_I6
+#define PT_I7		0x4c
+
+/* Stack_frame offsets */
+#define SF_L0		0x00
+#define SF_L1		0x04
+#define SF_L2		0x08
+#define SF_L3		0x0c
+#define SF_L4		0x10
+#define SF_L5		0x14
+#define SF_L6		0x18
+#define SF_L7		0x1c
+#define SF_I0		0x20
+#define SF_I1		0x24
+#define SF_I2		0x28
+#define SF_I3		0x2c
+#define SF_I4		0x30
+#define SF_I5		0x34
+#define SF_FP		0x38
+#define SF_PC		0x3c
+#define SF_RETP		0x40
+#define SF_XARG0	0x44
+#define	SF_XARG1	0x48
+#define	SF_XARG2	0x4c
+#define	SF_XARG3	0x50
+#define	SF_XARG4	0x54
+#define	SF_XARG5	0x58
+#define	SF_XXARG	0x5c
+
+/* Reg_window offsets */
+#define RW_L0		0x00
+#define RW_L1		0x04
+#define RW_L2		0x08
+#define RW_L3		0x0c
+#define RW_L4		0x10
+#define RW_L5		0x14
+#define RW_L6		0x18
+#define RW_L7		0x1c
+#define RW_I0		0x20
+#define RW_I1		0x24
+#define RW_I2		0x28
+#define RW_I3		0x2c
+#define RW_I4		0x30
+#define RW_I5		0x34
+#define RW_I6		0x38
+#define RW_I7		0x3c
+
+/* Fpu_window offsets */
+#define FW_F0		0x00
+#define FW_F2		0x08
+#define FW_F4		0x10
+#define FW_F6		0x18
+#define FW_F8		0x20
+#define FW_F10		0x28
+#define FW_F12		0x30
+#define FW_F14		0x38
+#define FW_F16		0x40
+#define FW_F18		0x48
+#define FW_F20		0x50
+#define FW_F22		0x58
+#define FW_F24		0x60
+#define FW_F26		0x68
+#define FW_F28		0x70
+#define FW_F30		0x78
+#define FW_FSR		0x80
+
+#endif
diff --git a/include/asm-sparc/string.h b/include/asm-sparc/string.h
new file mode 100644
index 0000000..c6bbc20
--- /dev/null
+++ b/include/asm-sparc/string.h
@@ -0,0 +1,55 @@
+/*
+ * (C) Copyright 2000 - 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ */
+
+#ifndef _SPARC_STRING_H_
+#define _SPARC_STRING_H_
+
+/*
+#define __HAVE_ARCH_STRCPY
+#define __HAVE_ARCH_STRNCPY
+#define __HAVE_ARCH_STRLEN
+#define __HAVE_ARCH_STRCMP
+#define __HAVE_ARCH_STRCAT
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_BCOPY
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+#define __HAVE_ARCH_MEMCMP
+#define __HAVE_ARCH_MEMCHR
+*/
+
+extern int strcasecmp(const char *, const char *);
+extern int strncasecmp(const char *, const char *, int);
+extern char *strcpy(char *, const char *);
+extern char *strncpy(char *, const char *, __kernel_size_t);
+extern __kernel_size_t strlen(const char *);
+extern int strcmp(const char *, const char *);
+extern char *strcat(char *, const char *);
+extern void *memset(void *, int, __kernel_size_t);
+extern void *memcpy(void *, const void *, __kernel_size_t);
+extern void *memmove(void *, const void *, __kernel_size_t);
+extern int memcmp(const void *, const void *, __kernel_size_t);
+extern void *memchr(const void *, int, __kernel_size_t);
+
+#endif
diff --git a/include/asm-sparc/types.h b/include/asm-sparc/types.h
new file mode 100644
index 0000000..69f93d6
--- /dev/null
+++ b/include/asm-sparc/types.h
@@ -0,0 +1,71 @@
+/*
+ * (C) Copyright 2000 - 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ *
+ */
+
+#ifndef _SPARC_TYPES_H
+#define _SPARC_TYPES_H
+
+#ifndef __ASSEMBLY__
+
+typedef unsigned short umode_t;
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+typedef struct {
+	__u32 u[4];
+} __attribute((aligned(16))) vector128;
+
+#ifdef __KERNEL__
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+/* DMA addresses are 32-bits wide */
+typedef u32 dma_addr_t;
+
+#endif				/* __KERNEL__ */
+#endif				/* __ASSEMBLY__ */
+
+#endif
diff --git a/include/asm-sparc/u-boot.h b/include/asm-sparc/u-boot.h
new file mode 100644
index 0000000..9c594e1
--- /dev/null
+++ b/include/asm-sparc/u-boot.h
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright 2000 - 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007, From asm-ppc/u-boot.h
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ *
+ ********************************************************************
+ * NOTE: This header file defines an interface to U-Boot. Including
+ * this (unmodified) header file in another file is considered normal
+ * use of U-Boot, and does *not* fall under the heading of "derived
+ * work".
+ ********************************************************************
+ */
+
+#ifndef __U_BOOT_H__
+#define __U_BOOT_H__
+
+/*
+ * Currently, this Board information is not passed to
+ * Linux kernel from U-Boot, but may be passed to other
+ * Operating systems. This is because U-boot emulates
+ * a SUN PROM loader (from Linux point of view).
+ *
+ * include/asm-sparc/u-boot.h
+ */
+
+#ifndef __ASSEMBLY__
+
+typedef struct bd_info {
+	unsigned long bi_memstart;	/* start of DRAM memory */
+	unsigned long bi_memsize;	/* size  of DRAM memory in bytes */
+	unsigned long bi_flashstart;	/* start of FLASH memory */
+	unsigned long bi_flashsize;	/* size  of FLASH memory */
+	unsigned long bi_flashoffset;	/* reserved area for startup monitor */
+	unsigned long bi_sramstart;	/* start of SRAM memory */
+	unsigned long bi_sramsize;	/* size  of SRAM memory */
+	unsigned long bi_bootflags;	/* boot / reboot flag (for LynxOS) */
+	unsigned long bi_ip_addr;	/* IP Address */
+	unsigned char bi_enetaddr[6];	/* Ethernet adress */
+	unsigned short bi_ethspeed;	/* Ethernet speed in Mbps */
+	unsigned long bi_intfreq;	/* Internal Freq, in MHz */
+	unsigned long bi_busfreq;	/* Bus Freq, in MHz */
+	unsigned long bi_baudrate;	/* Console Baudrate */
+#ifdef CONFIG_HAS_ETH1
+	/* second onboard ethernet port */
+	unsigned char bi_enet1addr[6];
+#endif
+#ifdef CONFIG_HAS_ETH2
+	/* third onboard ethernet port */
+	unsigned char bi_enet2addr[6];
+#endif
+#ifdef CONFIG_HAS_ETH3
+	unsigned char bi_enet3addr[6];
+#endif
+} bd_t;
+
+#endif				/* __ASSEMBLY__ */
+#endif				/* __U_BOOT_H__ */
diff --git a/include/asm-sparc/winmacro.h b/include/asm-sparc/winmacro.h
new file mode 100644
index 0000000..66fc639
--- /dev/null
+++ b/include/asm-sparc/winmacro.h
@@ -0,0 +1,151 @@
+/*
+ * Added to U-boot,
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+ * Copyright (C) 2007
+ *
+ * LEON2/3 LIBIO low-level routines
+ * Written by Jiri Gaisler.
+ * Copyright (C) 2004  Gaisler Research AB
+
+ * 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
+
+*/
+
+#ifndef __SPARC_WINMACRO_H__
+#define __SPARC_WINMACRO_H__
+
+#include <asm/asmmacro.h>
+#include <asm/stack.h>
+
+/* Store the register window onto the 8-byte aligned area starting
+ * at %reg.  It might be %sp, it might not, we don't care.
+ */
+#define RW_STORE(reg) \
+	std	%l0, [%reg + RW_L0]; \
+	std	%l2, [%reg + RW_L2]; \
+	std	%l4, [%reg + RW_L4]; \
+	std	%l6, [%reg + RW_L6]; \
+	std	%i0, [%reg + RW_I0]; \
+	std	%i2, [%reg + RW_I2]; \
+	std	%i4, [%reg + RW_I4]; \
+	std	%i6, [%reg + RW_I6];
+
+/* Load a register window from the area beginning at %reg. */
+#define RW_LOAD(reg) \
+	ldd	[%reg + RW_L0], %l0; \
+	ldd	[%reg + RW_L2], %l2; \
+	ldd	[%reg + RW_L4], %l4; \
+	ldd	[%reg + RW_L6], %l6; \
+	ldd	[%reg + RW_I0], %i0; \
+	ldd	[%reg + RW_I2], %i2; \
+	ldd	[%reg + RW_I4], %i4; \
+	ldd	[%reg + RW_I6], %i6;
+
+/* Loading and storing struct pt_reg trap frames. */
+#define PT_LOAD_INS(base_reg) \
+	ldd	[%base_reg + SF_REGS_SZ + PT_I0], %i0; \
+	ldd	[%base_reg + SF_REGS_SZ + PT_I2], %i2; \
+	ldd	[%base_reg + SF_REGS_SZ + PT_I4], %i4; \
+	ldd	[%base_reg + SF_REGS_SZ + PT_I6], %i6;
+
+#define PT_LOAD_GLOBALS(base_reg) \
+	ld	[%base_reg + SF_REGS_SZ + PT_G1], %g1; \
+	ldd	[%base_reg + SF_REGS_SZ + PT_G2], %g2; \
+	ldd	[%base_reg + SF_REGS_SZ + PT_G4], %g4; \
+	ldd	[%base_reg + SF_REGS_SZ + PT_G6], %g6;
+
+#define PT_LOAD_YREG(base_reg, scratch) \
+	ld	[%base_reg + SF_REGS_SZ + PT_Y], %scratch; \
+	wr	%scratch, 0x0, %y;
+
+#define PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
+	ld	[%base_reg + SF_REGS_SZ + PT_PSR], %pt_psr; \
+	ld	[%base_reg + SF_REGS_SZ + PT_PC], %pt_pc; \
+	ld	[%base_reg + SF_REGS_SZ + PT_NPC], %pt_npc;
+
+#define PT_LOAD_ALL(base_reg, pt_psr, pt_pc, pt_npc, scratch) \
+	PT_LOAD_YREG(base_reg, scratch) \
+	PT_LOAD_INS(base_reg) \
+	PT_LOAD_GLOBALS(base_reg) \
+	PT_LOAD_PRIV(base_reg, pt_psr, pt_pc, pt_npc)
+
+#define PT_STORE_INS(base_reg) \
+	std	%i0, [%base_reg + SF_REGS_SZ + PT_I0]; \
+	std	%i2, [%base_reg + SF_REGS_SZ + PT_I2]; \
+	std	%i4, [%base_reg + SF_REGS_SZ + PT_I4]; \
+	std	%i6, [%base_reg + SF_REGS_SZ + PT_I6];
+
+#define PT_STORE_GLOBALS(base_reg) \
+	st	%g1, [%base_reg + SF_REGS_SZ + PT_G1]; \
+	std	%g2, [%base_reg + SF_REGS_SZ + PT_G2]; \
+	std	%g4, [%base_reg + SF_REGS_SZ + PT_G4]; \
+	std	%g6, [%base_reg + SF_REGS_SZ + PT_G6];
+
+#define PT_STORE_YREG(base_reg, scratch) \
+	rd	%y, %scratch; \
+	st	%scratch, [%base_reg + SF_REGS_SZ + PT_Y];
+
+#define PT_STORE_PRIV(base_reg, pt_psr, pt_pc, pt_npc) \
+	st	%pt_psr, [%base_reg + SF_REGS_SZ + PT_PSR]; \
+	st	%pt_pc,  [%base_reg + SF_REGS_SZ + PT_PC]; \
+	st	%pt_npc, [%base_reg + SF_REGS_SZ + PT_NPC];
+
+#define PT_STORE_ALL(base_reg, reg_psr, reg_pc, reg_npc, g_scratch) \
+	PT_STORE_PRIV(base_reg, reg_psr, reg_pc, reg_npc) \
+	PT_STORE_GLOBALS(base_reg) \
+	PT_STORE_YREG(base_reg, g_scratch) \
+	PT_STORE_INS(base_reg)
+
+/* Store the fpu register window*/
+#define FW_STORE(reg) \
+	std	%f0, [reg + FW_F0]; \
+	std	%f2, [reg + FW_F2]; \
+	std	%f4, [reg + FW_F4]; \
+	std	%f6, [reg + FW_F6]; \
+	std	%f8, [reg + FW_F8]; \
+	std	%f10, [reg + FW_F10]; \
+	std	%f12, [reg + FW_F12]; \
+	std	%f14, [reg + FW_F14]; \
+	std	%f16, [reg + FW_F16]; \
+	std	%f18, [reg + FW_F18]; \
+	std	%f20, [reg + FW_F20]; \
+	std	%f22, [reg + FW_F22]; \
+	std	%f24, [reg + FW_F24]; \
+	std	%f26, [reg + FW_F26]; \
+	std	%f28, [reg + FW_F28]; \
+	std	%f30, [reg + FW_F30]; \
+	st	%fsr, [reg + FW_FSR];
+
+/* Load a fpu register window from the area beginning at reg. */
+#define FW_LOAD(reg) \
+	ldd	[reg + FW_F0], %f0; \
+	ldd	[reg + FW_F2], %f2; \
+	ldd	[reg + FW_F4], %f4; \
+	ldd	[reg + FW_F6], %f6; \
+	ldd	[reg + FW_F8], %f8; \
+	ldd	[reg + FW_F10], %f10; \
+	ldd	[reg + FW_F12], %f12; \
+	ldd	[reg + FW_F14], %f14; \
+	ldd	[reg + FW_F16], %f16; \
+	ldd	[reg + FW_F18], %f18; \
+	ldd	[reg + FW_F20], %f20; \
+	ldd	[reg + FW_F22], %f22; \
+	ldd	[reg + FW_F24], %f24; \
+	ldd	[reg + FW_F26], %f26; \
+	ldd	[reg + FW_F28], %f28; \
+	ldd	[reg + FW_F30], %f30; \
+	ld	[reg + FW_FSR], %fsr;
+
+#endif
diff --git a/include/config_cmd_all.h b/include/config_cmd_all.h
index 69276a3..d1b5ffb 100644
--- a/include/config_cmd_all.h
+++ b/include/config_cmd_all.h
@@ -13,6 +13,7 @@
  * Alphabetical list of all possible commands.
  */
 
+#define CONFIG_CMD_AMBAPP	/* AMBA Plug & Play Bus print utility */
 #define CONFIG_CMD_ASKENV	/* ask for env variable		*/
 #define CONFIG_CMD_AUTOSCRIPT	/* Autoscript Support		*/
 #define CONFIG_CMD_BDI	       	/* bdinfo			*/
diff --git a/include/configs/MPC837XEMDS.h b/include/configs/MPC837XEMDS.h
index 7c4e76e..7fc0f7e 100644
--- a/include/configs/MPC837XEMDS.h
+++ b/include/configs/MPC837XEMDS.h
@@ -96,7 +96,7 @@
  */
 #define CFG_SCCR_TSEC1CM	1	/* CSB:eTSEC1 = 1:1 */
 #define CFG_SCCR_TSEC2CM	1	/* CSB:eTSEC2 = 1:1 */
-#define CFG_SCCR_SATACM		SCCR_SATACM_1	/* CSB:SATA[0:3] = 1:1 */
+#define CFG_SCCR_SATACM		SCCR_SATACM_2	/* CSB:SATA[0:3] = 2:1 */
 
 /*
  * System IO Config
diff --git a/include/configs/MPC837XERDB.h b/include/configs/MPC837XERDB.h
index eaac525..c698ff8 100644
--- a/include/configs/MPC837XERDB.h
+++ b/include/configs/MPC837XERDB.h
@@ -108,7 +108,7 @@
 /* System Clock Configuration Register */
 #define CFG_SCCR_TSEC1CM	1		/* eTSEC1 clock mode (0-3) */
 #define CFG_SCCR_TSEC2CM	1		/* eTSEC2 clock mode (0-3) */
-#define CFG_SCCR_SATACM		SCCR_SATACM_1	/* SATA1-4 clock mode (0-3) */
+#define CFG_SCCR_SATACM		SCCR_SATACM_2	/* SATA1-4 clock mode (0-3) */
 
 /*
  * System IO Config
diff --git a/include/configs/canyonlands.h b/include/configs/canyonlands.h
index a1c6674..be9432b 100644
--- a/include/configs/canyonlands.h
+++ b/include/configs/canyonlands.h
@@ -330,19 +330,17 @@
 		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
 		":${hostname}:${netdev}:off panic=1\0"			\
 	"addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}\0"\
-	"net_nfs=tftp 200000 ${bootfile};"				\
-		"run nfsargs addip addtty;"				\
-		"bootm 200000\0"					\
-	"net_nfs_fdt=tftp 200000 ${bootfile};"				\
+	"net_nfs=tftp 400000 ${bootfile};"				\
 		"tftp ${fdt_addr} ${fdt_file};"				\
 		"run nfsargs addip addtty;"				\
-		"bootm 200000 - ${fdt_addr}\0"				\
+		"bootm 400000 - ${fdt_addr}\0"				\
+	"net_nfs_fdt=net_nfs\0"						\
 	"flash_nfs=run nfsargs addip addtty;"				\
 		"bootm ${kernel_addr}\0"				\
 	"flash_self=run ramargs addip addtty;"				\
 		"bootm ${kernel_addr} ${ramdisk_addr}\0"		\
 	"rootpath=/opt/eldk/ppc_4xxFP\0"				\
-	"fdt_addr=400000\0"						\
+	"fdt_addr=800000\0"						\
 	"kernel_addr=fc000000\0"					\
 	"ramdisk_addr=fc200000\0"					\
 	"initrd_high=30000000\0"					\
@@ -352,7 +350,7 @@
 		"setenv filesize;saveenv\0"				\
 	"upd=run load update\0"						\
 	"nload=tftp 200000 ${hostname}/u-boot-nand.bin\0"		\
-	"nupdate=nand erase 0 60000;nand write 200000 0 60000;"		\
+	"nupdate=nand erase 0 100000;nand write 200000 0 100000;"	\
 		"setenv filesize;saveenv\0"				\
 	"nupd=run nload nupdate\0"					\
 	"pciconfighost=1\0"						\
diff --git a/include/configs/gr_cpci_ax2000.h b/include/configs/gr_cpci_ax2000.h
new file mode 100644
index 0000000..1276f4d
--- /dev/null
+++ b/include/configs/gr_cpci_ax2000.h
@@ -0,0 +1,380 @@
+/* Configuration header file for Gaisler GR-CPCI-AX2000
+ * AX board. Note that since the AX is removable the configuration
+ * for this board must be edited below.
+ *
+ * (C) Copyright 2003-2005
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2008
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_LEON3		/* This is an LEON3 CPU */
+#define CONFIG_LEON		1	/* This is an LEON CPU */
+#define CONFIG_CPCI_AX2000	1	/* ... on GR-CPCI-AX2000 board */
+
+#define CONFIG_LEON_RAM_SRAM 1
+#define CONFIG_LEON_RAM_SDRAM 2
+#define CONFIG_LEON_RAM_SDRAM_NOSRAM 3
+
+/* Select Memory to run from
+ *
+ * SRAM          - UBoot is run in SRAM, SRAM-0x40000000, SDRAM-0x60000000
+ * SDRAM         - UBoot is run in SDRAM, SRAM-0x40000000 and SDRAM-0x60000000
+ * SDRAM_NOSRAM  - UBoot is run in SDRAM, SRAM not available, SDRAM at 0x40000000
+ *
+ * Note, if Linux is to be used, SDRAM or SDRAM_NOSRAM is required since
+ * it doesn't fit into the 4Mb SRAM.
+ *
+ * SRAM is default since it will work for all systems, however will not
+ * be able to boot linux.
+ */
+#define CONFIG_LEON_RAM_SELECT CONFIG_LEON_RAM_SRAM
+
+/* CPU / AMBA BUS configuration */
+#define CONFIG_SYS_CLK_FREQ 	20000000	/* 20MHz */
+
+/* Number of SPARC register windows */
+#define CFG_SPARC_NWINDOWS 8
+
+/*
+ * Serial console configuration
+ */
+#define CONFIG_BAUDRATE		38400	/* ... at 38400 bps */
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 230400 }
+
+/* Partitions */
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
+#define CONFIG_ISO_PARTITION
+
+/*
+ * Supported commands
+ */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_AMBAPP
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_IRQ
+
+/*
+ * Autobooting
+ */
+#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds */
+
+#define CONFIG_PREBOOT	"echo;"	\
+	"echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \
+	"echo"
+
+#undef	CONFIG_BOOTARGS
+
+#define	CONFIG_EXTRA_ENV_SETTINGS_BASE					\
+	"netdev=eth0\0"							\
+	"nfsargs=setenv bootargs console=ttyS0,38400 root=/dev/nfs rw "	\
+		"nfsroot=${serverip}:${rootpath}\0"			\
+	"ramargs=setenv bootargs console=ttyS0,${baudrate} root=/dev/ram rw\0"			\
+	"addip=setenv bootargs ${bootargs} "				\
+		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
+		":${hostname}:${netdev}:off panic=1\0"			\
+	"flash_nfs=run nfsargs addip;"					\
+		"bootm ${kernel_addr}\0"				\
+	"flash_self=run ramargs addip;"					\
+		"bootm ${kernel_addr} ${ramdisk_addr}\0"		\
+	"getkernel=tftpboot \$\(scratch\)\ \$\(bootfile\)\0" \
+	"bootargs=console=ttyS0,38400 root=/dev/nfs rw nfsroot=192.168.0.20:/export/rootfs ip=192.168.0.206:192.168.0.20:192.168.0.1:255.255.255.0:ax2000:eth0\0"
+
+#if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SRAM
+#define CONFIG_EXTRA_ENV_SETTINGS_SELECT \
+	"net_nfs=tftp 40000000 ${bootfile};run nfsargs addip;bootm\0"	\
+	"scratch=40200000\0"					\
+	""
+#elif CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM
+#define CONFIG_EXTRA_ENV_SETTINGS_SELECT \
+	"net_nfs=tftp 60000000 ${bootfile};run nfsargs addip;bootm\0"	\
+	"scratch=60800000\0"					\
+	""
+#else
+/* More than 4Mb is assumed when running from SDRAM */
+#define CONFIG_EXTRA_ENV_SETTINGS_SELECT \
+	"net_nfs=tftp 40000000 ${bootfile};run nfsargs addip;bootm\0"	\
+	"scratch=40800000\0"					\
+	""
+#endif
+
+#define	CONFIG_EXTRA_ENV_SETTINGS CONFIG_EXTRA_ENV_SETTINGS_BASE CONFIG_EXTRA_ENV_SETTINGS_SELECT
+
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_GATEWAYIP 192.168.0.1
+#define CONFIG_SERVERIP 192.168.0.20
+#define CONFIG_IPADDR 192.168.0.206
+#define CONFIG_ROOTPATH /export/rootfs
+#define CONFIG_HOSTNAME  ax2000
+#define CONFIG_BOOTFILE  /uImage
+
+#define CONFIG_BOOTCOMMAND	"run flash_self"
+
+/* Memory MAP
+ *
+ *  Flash:
+ *  |--------------------------------|
+ *  | 0x00000000 Text & Data & BSS   | *
+ *  |            for Monitor         | *
+ *  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| *
+ *  | UNUSED / Growth                | * 256kb
+ *  |--------------------------------|
+ *  | 0x00050000 Base custom area    | *
+ *  |            kernel / FS         | *
+ *  |                                | * Rest of Flash
+ *  |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
+ *  | END-0x00008000 Environment     | * 32kb
+ *  |--------------------------------|
+ *
+ *
+ *
+ *  Main Memory (4Mb SRAM or XMb SDRAM):
+ *  |--------------------------------|
+ *  | UNUSED / scratch area          |
+ *  |                                |
+ *  |                                |
+ *  |                                |
+ *  |                                |
+ *  |--------------------------------|
+ *  | Monitor .Text / .DATA / .BSS   | * 256kb
+ *  | Relocated!                     | *
+ *  |--------------------------------|
+ *  | Monitor Malloc                 | * 128kb (contains relocated environment)
+ *  |--------------------------------|
+ *  | Monitor/kernel STACK           | * 64kb
+ *  |--------------------------------|
+ *  | Page Table for MMU systems     | * 2k
+ *  |--------------------------------|
+ *  | PROM Code accessed from Linux  | * 6kb-128b
+ *  |--------------------------------|
+ *  | Global data (avail from kernel)| * 128b
+ *  |--------------------------------|
+ *
+ */
+
+/*
+ * Flash configuration (8,16 or 32 MB)
+ * TEXT base always at 0xFFF00000
+ * ENV_ADDR always at  0xFFF40000
+ * FLASH_BASE at 0xFC000000 for 64 MB
+ *               0xFE000000 for 32 MB
+ *               0xFF000000 for 16 MB
+ *               0xFF800000 for  8 MB
+ */
+/*#define CFG_NO_FLASH		1*/
+#define CFG_FLASH_BASE		0x00000000
+#define CFG_FLASH_SIZE		0x00800000
+
+#define PHYS_FLASH_SECT_SIZE	0x00020000	/* 128 KB sectors */
+#define CFG_MAX_FLASH_SECT	64	/* max num of sects on one chip */
+#define CFG_MAX_FLASH_BANKS	1	/* max num of memory banks      */
+
+#define CFG_FLASH_ERASE_TOUT	240000	/* Flash Erase Timeout (in ms)  */
+#define CFG_FLASH_WRITE_TOUT	500	/* Flash Write Timeout (in ms)  */
+#define CFG_FLASH_LOCK_TOUT	5	/* Timeout for Flash Set Lock Bit (in ms) */
+#define CFG_FLASH_UNLOCK_TOUT	10000	/* Timeout for Flash Clear Lock Bits (in ms) */
+#define CFG_FLASH_PROTECTION	/* "Real" (hardware) sectors protection */
+
+/*** CFI CONFIG ***/
+#define CFG_FLASH_CFI_WIDTH	FLASH_CFI_8BIT
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_CFI
+/* Bypass cache when reading regs from flash memory */
+#define CFG_FLASH_CFI_BYPASS_READ
+/* Buffered writes (32byte/go) instead of single accesses */
+#define CFG_FLASH_USE_BUFFER_WRITE
+
+/*
+ * Environment settings
+ */
+/*#define CFG_ENV_IS_NOWHERE 1*/
+#define CFG_ENV_IS_IN_FLASH	1
+/* CFG_ENV_ADDR need to be at sector boundary */
+#define CFG_ENV_SIZE		0x8000
+#define CFG_ENV_SECT_SIZE	0x20000
+#define CFG_ENV_ADDR		(CFG_FLASH_BASE+CFG_FLASH_SIZE-CFG_ENV_SECT_SIZE)
+#define CONFIG_ENV_OVERWRITE	1
+
+/*
+ * Memory map
+ *
+ * Always 4Mb SRAM available
+ * SDRAM module may be available on 0x60000000, SDRAM
+ * is configured as if a 128Mb SDRAM module is available.
+ */
+
+#if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM
+#define CFG_SDRAM_BASE		0x40000000
+#else
+#define CFG_SDRAM_BASE		0x60000000
+#endif
+
+#define CFG_SDRAM_SIZE		0x08000000
+#define CFG_SDRAM_END		(CFG_SDRAM_BASE+CFG_SDRAM_SIZE)
+
+/* 4Mb SRAM available */
+#if CONFIG_LEON_RAM_SELECT != CONFIG_LEON_RAM_SDRAM_NOSRAM
+#define CFG_SRAM_BASE 0x40000000
+#define CFG_SRAM_SIZE 0x400000
+#define CFG_SRAM_END  (CFG_SRAM_BASE+CFG_SRAM_SIZE)
+#endif
+
+/* Select RAM used to run U-BOOT from... */
+#if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SRAM
+#define CFG_RAM_BASE CFG_SRAM_BASE
+#define CFG_RAM_SIZE CFG_SRAM_SIZE
+#define CFG_RAM_END CFG_SRAM_END
+#else
+#define CFG_RAM_BASE CFG_SDRAM_BASE
+#define CFG_RAM_SIZE CFG_SDRAM_SIZE
+#define CFG_RAM_END CFG_SDRAM_END
+#endif
+
+#define CFG_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET	(CFG_RAM_END - CFG_GBL_DATA_SIZE)
+
+#define CFG_PROM_SIZE		(8192-CFG_GBL_DATA_SIZE)
+#define CFG_PROM_OFFSET		(CFG_GBL_DATA_OFFSET-CFG_PROM_SIZE)
+
+#define CFG_INIT_SP_OFFSET	(CFG_PROM_OFFSET-32)
+#define CFG_STACK_SIZE		(0x10000-32)
+
+#define CFG_MONITOR_BASE    TEXT_BASE
+#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
+#   define CFG_RAMBOOT		1
+#endif
+
+#define CFG_MONITOR_LEN		(256 << 10)	/* Reserve 256 kB for Monitor   */
+#define CFG_MALLOC_LEN		(128 << 10)	/* Reserve 128 kB for malloc()  */
+#define CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */
+
+#define CFG_MALLOC_END		(CFG_INIT_SP_OFFSET-CFG_STACK_SIZE)
+#define CFG_MALLOC_BASE		(CFG_MALLOC_END-CFG_MALLOC_LEN)
+
+/* relocated monitor area */
+#define CFG_RELOC_MONITOR_MAX_END   CFG_MALLOC_BASE
+#define CFG_RELOC_MONITOR_BASE     (CFG_RELOC_MONITOR_MAX_END-CFG_MONITOR_LEN)
+
+/* make un relocated address from relocated address */
+#define UN_RELOC(address) (address-(CFG_RELOC_MONITOR_BASE-TEXT_BASE))
+
+/*
+ * Ethernet configuration uses on board SMC91C111
+ */
+#define CONFIG_DRIVER_SMC91111          1
+#define CONFIG_SMC91111_BASE		0x20000300	/* chip select 3         */
+#define CONFIG_SMC_USE_32_BIT		1	/* 32 bit bus  */
+#undef  CONFIG_SMC_91111_EXT_PHY	/* we use internal phy   */
+/*#define CONFIG_SHOW_ACTIVITY*/
+#define CONFIG_NET_RETRY_COUNT		10	/* # of retries          */
+
+#define CONFIG_ETHADDR   00:00:7a:cc:00:13
+#define CONFIG_PHY_ADDR	 0x00
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP		/* undef to save memory     */
+#define CFG_PROMPT		"=> "	/* Monitor Command Prompt   */
+#if defined(CONFIG_CMD_KGDB)
+#define CFG_CBSIZE		1024	/* Console I/O Buffer Size  */
+#else
+#define CFG_CBSIZE		256	/* Console I/O Buffer Size  */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print Buffer Size */
+#define CFG_MAXARGS		16	/* max number of command args   */
+#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size    */
+
+#define CFG_MEMTEST_START	0x00100000	/* memtest works on */
+#define CFG_MEMTEST_END		0x00f00000	/* 1 ... 15 MB in DRAM  */
+
+#define CFG_LOAD_ADDR		0x100000	/* default load address */
+
+#define CFG_HZ			1000	/* decrementer freq: 1 ms ticks */
+
+/*
+ * Various low-level settings
+ */
+
+/*-----------------------------------------------------------------------
+ * USB stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_USB_CLOCK	0x0001BBBB
+#define CONFIG_USB_CONFIG	0x00005000
+
+/***** Gaisler GRLIB IP-Cores Config ********/
+
+/* AMBA Plug & Play info display on startup */
+/*#define CFG_AMBAPP_PRINT_ON_STARTUP*/
+
+#define CFG_GRLIB_SDRAM    0
+
+/* See, GRLIB Docs (grip.pdf) on how to set up
+ * These the memory controller registers.
+ */
+#define CFG_GRLIB_MEMCFG1   (0x10f800ff | (1<<11))
+#if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM
+#define CFG_GRLIB_MEMCFG2   0x82206000
+#else
+#define CFG_GRLIB_MEMCFG2   0x82205260
+#endif
+#define CFG_GRLIB_MEMCFG3   0x0809a000
+
+#define CFG_GRLIB_FT_MEMCFG1   (0x10f800ff | (1<<11))
+#if CONFIG_LEON_RAM_SELECT == CONFIG_LEON_RAM_SDRAM_NOSRAM
+#define CFG_GRLIB_FT_MEMCFG2   0x82206000
+#else
+#define CFG_GRLIB_FT_MEMCFG2   0x82205260
+#endif
+#define CFG_GRLIB_FT_MEMCFG3   0x0809a000
+
+/* no DDR controller */
+#define CFG_GRLIB_DDR_CFG   0x00000000
+
+/* no DDR2 Controller */
+#define CFG_GRLIB_DDR2_CFG1 0x00000000
+#define CFG_GRLIB_DDR2_CFG3 0x00000000
+
+/* Calculate scaler register value from default baudrate */
+#define CFG_GRLIB_APBUART_SCALER \
+ ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+
+/* Identification string */
+#define CONFIG_IDENT_STRING "GAISLER LEON3 GR-CPCI-AX2000"
+
+/* default kernel command line */
+#define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0"
+
+#endif				/* __CONFIG_H */
diff --git a/include/configs/gr_ep2s60.h b/include/configs/gr_ep2s60.h
new file mode 100644
index 0000000..710a082
--- /dev/null
+++ b/include/configs/gr_ep2s60.h
@@ -0,0 +1,356 @@
+/* Configuration header file for Gaisler Research AB's Template
+ * design (GPL Open Source SPARC/LEON3 96MHz) for Altera NIOS
+ * Development board Stratix II edition, with the FPGA device
+ * EP2S60.
+ *
+ * (C) Copyright 2003-2005
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2008
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_LEON3		/* This is an LEON3 CPU */
+#define CONFIG_LEON		1	/* This is an LEON CPU */
+/* Altera NIOS Development board, Stratix II board */
+#define CONFIG_GR_EP2S60 	1
+
+/* CPU / AMBA BUS configuration */
+#define CONFIG_SYS_CLK_FREQ 	96000000	/* 96MHz */
+
+/* Number of SPARC register windows */
+#define CFG_SPARC_NWINDOWS 8
+
+/* Define this is the GR-2S60-MEZZ mezzanine is available and you
+ * want to use the USB and GRETH functionality of the board
+ */
+#undef GR_2S60_MEZZ
+
+#ifdef GR_2S60_MEZZ
+#define USE_GRETH 1
+#define USE_GRUSB 1
+#endif
+
+/*
+ * Serial console configuration
+ */
+#define CONFIG_BAUDRATE		38400	/* ... at 38400 bps */
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 230400 }
+
+/* Partitions */
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
+#define CONFIG_ISO_PARTITION
+
+/*
+ * Supported commands
+ */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_AMBAPP
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_IRQ
+
+/* USB support */
+#if USE_GRUSB
+#define CONFIG_USB_UHCI
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_USB
+#define CONFIG_USB_STORAGE
+/* Enable needed helper functions */
+#define CFG_DEVICE_DEREGISTER	/* needs device_deregister */
+#endif
+
+/*
+ * Autobooting
+ */
+#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds */
+
+#define CONFIG_PREBOOT	"echo;"	\
+	"echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \
+	"echo"
+
+#undef	CONFIG_BOOTARGS
+
+#define	CONFIG_EXTRA_ENV_SETTINGS					\
+	"netdev=eth0\0"							\
+	"nfsargs=setenv bootargs console=ttyS0,38400 root=/dev/nfs rw "	\
+		"nfsroot=${serverip}:${rootpath}\0"			\
+	"ramargs=setenv bootargs console=ttyS0,${baudrate} root=/dev/ram rw\0"			\
+	"addip=setenv bootargs ${bootargs} "				\
+		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
+		":${hostname}:${netdev}:off panic=1\0"			\
+	"flash_nfs=run nfsargs addip;"					\
+		"bootm ${kernel_addr}\0"				\
+	"flash_self=run ramargs addip;"					\
+		"bootm ${kernel_addr} ${ramdisk_addr}\0"		\
+	"net_nfs=tftp 40000000 ${bootfile};run nfsargs addip;bootm\0"	\
+	"scratch=40800000\0"					\
+	"getkernel=tftpboot \$\(scratch\)\ \$\(bootfile\)\0" \
+	"bootargs=console=ttyS0,38400 root=/dev/nfs rw nfsroot=192.168.0.20:/export/rootfs ip=192.168.0.207:192.168.0.20:192.168.0.1:255.255.255.0:ml401:eth0\0" \
+	""
+
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_GATEWAYIP 192.168.0.1
+#define CONFIG_SERVERIP 192.168.0.20
+#define CONFIG_IPADDR 192.168.0.207
+#define CONFIG_ROOTPATH /export/rootfs
+#define CONFIG_HOSTNAME  ml401
+#define CONFIG_BOOTFILE  /uImage
+
+#define CONFIG_BOOTCOMMAND	"run flash_self"
+
+/* Memory MAP
+ *
+ *  Flash:
+ *  |--------------------------------|
+ *  | 0x00000000 Text & Data & BSS   | *
+ *  |            for Monitor         | *
+ *  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| *
+ *  | UNUSED / Growth                | * 256kb
+ *  |--------------------------------|
+ *  | 0x00050000 Base custom area    | *
+ *  |            kernel / FS         | *
+ *  |                                | * Rest of Flash
+ *  |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
+ *  | END-0x00008000 Environment     | * 32kb
+ *  |--------------------------------|
+ *
+ *
+ *
+ *  Main Memory:
+ *  |--------------------------------|
+ *  | UNUSED / scratch area          |
+ *  |                                |
+ *  |                                |
+ *  |                                |
+ *  |                                |
+ *  |--------------------------------|
+ *  | Monitor .Text / .DATA / .BSS   | * 512kb
+ *  | Relocated!                     | *
+ *  |--------------------------------|
+ *  | Monitor Malloc                 | * 128kb (contains relocated environment)
+ *  |--------------------------------|
+ *  | Monitor/kernel STACK           | * 64kb
+ *  |--------------------------------|
+ *  | Page Table for MMU systems     | * 2k
+ *  |--------------------------------|
+ *  | PROM Code accessed from Linux  | * 6kb-128b
+ *  |--------------------------------|
+ *  | Global data (avail from kernel)| * 128b
+ *  |--------------------------------|
+ *
+ */
+
+/*
+ * Flash configuration (8,16 or 32 MB)
+ * TEXT base always at 0xFFF00000
+ * ENV_ADDR always at  0xFFF40000
+ * FLASH_BASE at 0xFC000000 for 64 MB
+ *               0xFE000000 for 32 MB
+ *               0xFF000000 for 16 MB
+ *               0xFF800000 for  8 MB
+ */
+/*#define CFG_NO_FLASH		1*/
+#define CFG_FLASH_BASE		0x00000000
+#define CFG_FLASH_SIZE		0x00400000	/* FPGA Bit file is in top of FLASH, we only ues the bottom 4Mb */
+
+#define PHYS_FLASH_SECT_SIZE	0x00010000	/* 64 KB sectors */
+#define CFG_MAX_FLASH_SECT	256	/* max num of sects on one chip */
+#define CFG_MAX_FLASH_BANKS	1	/* max num of memory banks      */
+
+#define CFG_FLASH_ERASE_TOUT	240000	/* Flash Erase Timeout (in ms)  */
+#define CFG_FLASH_WRITE_TOUT	500	/* Flash Write Timeout (in ms)  */
+#define CFG_FLASH_LOCK_TOUT	5	/* Timeout for Flash Set Lock Bit (in ms) */
+#define CFG_FLASH_UNLOCK_TOUT	10000	/* Timeout for Flash Clear Lock Bits (in ms) */
+#define CFG_FLASH_PROTECTION	/* "Real" (hardware) sectors protection */
+
+/*** CFI CONFIG ***/
+#define CFG_FLASH_CFI_WIDTH	FLASH_CFI_8BIT
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_CFI
+/* Bypass cache when reading regs from flash memory */
+#define CFG_FLASH_CFI_BYPASS_READ
+/* Buffered writes (32byte/go) instead of single accesses */
+#define CFG_FLASH_USE_BUFFER_WRITE
+
+/*
+ * Environment settings
+ */
+/*#define CFG_ENV_IS_NOWHERE 1*/
+#define CFG_ENV_IS_IN_FLASH	1
+/* CFG_ENV_ADDR need to be at sector boundary */
+#define CFG_ENV_SIZE		0x8000
+#define CFG_ENV_SECT_SIZE	0x20000
+#define CFG_ENV_ADDR		(CFG_FLASH_BASE+CFG_FLASH_SIZE-CFG_ENV_SECT_SIZE)
+#define CONFIG_ENV_OVERWRITE	1
+
+/*
+ * Memory map
+ */
+#define CFG_SDRAM_BASE		0x40000000
+#define CFG_SDRAM_SIZE		0x02000000
+#define CFG_SDRAM_END		(CFG_SDRAM_BASE+CFG_SDRAM_SIZE)
+
+/* no SRAM available */
+#undef CFG_SRAM_BASE
+#undef CFG_SRAM_SIZE
+
+#define CFG_RAM_BASE CFG_SDRAM_BASE
+#define CFG_RAM_SIZE CFG_SDRAM_SIZE
+#define CFG_RAM_END CFG_SDRAM_END
+
+#define CFG_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET	(CFG_SDRAM_END - CFG_GBL_DATA_SIZE)
+
+#define CFG_PROM_SIZE		(8192-CFG_GBL_DATA_SIZE)
+#define CFG_PROM_OFFSET		(CFG_GBL_DATA_OFFSET-CFG_PROM_SIZE)
+
+#define CFG_INIT_SP_OFFSET	(CFG_PROM_OFFSET-32)
+#define CFG_STACK_SIZE		(0x10000-32)
+
+#define CFG_MONITOR_BASE    TEXT_BASE
+#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
+#   define CFG_RAMBOOT		1
+#endif
+
+#define CFG_MONITOR_LEN		(512 << 10)	/* Reserve 512 kB for Monitor   */
+#define CFG_MALLOC_LEN		(128 << 10)	/* Reserve 128 kB for malloc()  */
+#define CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */
+
+#define CFG_MALLOC_END		(CFG_INIT_SP_OFFSET-CFG_STACK_SIZE)
+#define CFG_MALLOC_BASE		(CFG_MALLOC_END-CFG_MALLOC_LEN)
+
+/* relocated monitor area */
+#define CFG_RELOC_MONITOR_MAX_END   CFG_MALLOC_BASE
+#define CFG_RELOC_MONITOR_BASE     (CFG_RELOC_MONITOR_MAX_END-CFG_MONITOR_LEN)
+
+/* make un relocated address from relocated address */
+#define UN_RELOC(address) (address-(CFG_RELOC_MONITOR_BASE-TEXT_BASE))
+
+/*
+ * Ethernet configuration uses on board SMC91C111, however if a mezzanine
+ * with a PHY is attached the GRETH can be used on this board.
+ * Define USE_GRETH in order to use the mezzanine provided PHY with the
+ * onchip GRETH network MAC, note that this is not supported by the
+ * template design.
+ */
+#ifndef USE_GRETH
+
+/* USE SMC91C111 MAC */
+#define CONFIG_DRIVER_SMC91111          1
+#define CONFIG_SMC91111_BASE		0x20000300	/* chip select 3         */
+#define CONFIG_SMC_USE_32_BIT		1	/* 32 bit bus  */
+#undef  CONFIG_SMC_91111_EXT_PHY	/* we use internal phy   */
+/*#define CONFIG_SHOW_ACTIVITY*/
+#define CONFIG_NET_RETRY_COUNT		10	/* # of retries          */
+
+#else
+
+/* USE GRETH Ethernet Driver */
+#define CONFIG_NET_MULTI	1
+#define CONFIG_GRETH	1
+
+/* Default GRETH Ethernet HARDWARE address */
+#define GRETH_HWADDR_0 0x00
+#define GRETH_HWADDR_1 0x00
+#define GRETH_HWADDR_2 0x7a
+#define GRETH_HWADDR_3 0xcc
+#define GRETH_HWADDR_4 0x00
+#define GRETH_HWADDR_5 0x13
+#endif
+
+#define CONFIG_ETHADDR   00:00:7a:cc:00:13
+#define CONFIG_PHY_ADDR	 0x00
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP		/* undef to save memory     */
+#define CFG_PROMPT		"=> "	/* Monitor Command Prompt   */
+#if defined(CONFIG_CMD_KGDB)
+#define CFG_CBSIZE		1024	/* Console I/O Buffer Size  */
+#else
+#define CFG_CBSIZE		256	/* Console I/O Buffer Size  */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print Buffer Size */
+#define CFG_MAXARGS		16	/* max number of command args   */
+#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size    */
+
+#define CFG_MEMTEST_START	0x00100000	/* memtest works on */
+#define CFG_MEMTEST_END		0x00f00000	/* 1 ... 15 MB in DRAM  */
+
+#define CFG_LOAD_ADDR		0x100000	/* default load address */
+
+#define CFG_HZ			1000	/* decrementer freq: 1 ms ticks */
+
+/*-----------------------------------------------------------------------
+ * USB stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_USB_CLOCK	0x0001BBBB
+#define CONFIG_USB_CONFIG	0x00005000
+
+/***** Gaisler GRLIB IP-Cores Config ********/
+
+/* AMBA Plug & Play info display on startup */
+/*#define CFG_AMBAPP_PRINT_ON_STARTUP*/
+
+#define CFG_GRLIB_SDRAM    0
+
+/* See, GRLIB Docs (grip.pdf) on how to set up
+ * These the memory controller registers.
+ */
+#define CFG_GRLIB_MEMCFG1  (0x10f800ff | (1<<11))
+#define CFG_GRLIB_MEMCFG2  0x00000000
+#define CFG_GRLIB_MEMCFG3  0x00000000
+
+#define CFG_GRLIB_FT_MEMCFG1  (0x10f800ff | (1<<11))
+#define CFG_GRLIB_FT_MEMCFG2  0x00000000
+#define CFG_GRLIB_FT_MEMCFG3  0x00000000
+
+#define CFG_GRLIB_DDR_CFG  0xa900830a
+
+#define CFG_GRLIB_DDR2_CFG1 0x00000000
+#define CFG_GRLIB_DDR2_CFG3 0x00000000
+
+/* Calculate scaler register value from default baudrate */
+#define CFG_GRLIB_APBUART_SCALER \
+ ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+
+/* Identification string */
+#define CONFIG_IDENT_STRING "GAISLER LEON3 EP2S60"
+
+/* default kernel command line */
+#define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0"
+
+#endif				/* __CONFIG_H */
diff --git a/include/configs/gr_xc3s_1500.h b/include/configs/gr_xc3s_1500.h
new file mode 100644
index 0000000..1fdef3d
--- /dev/null
+++ b/include/configs/gr_xc3s_1500.h
@@ -0,0 +1,321 @@
+/* Configuration header file for Gaisler GR-XC3S-1500
+ * spartan board.
+ *
+ * (C) Copyright 2003-2005
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#define CONFIG_LEON3		/* This is an LEON3 CPU */
+#define CONFIG_LEON		1	/* This is an LEON CPU */
+#define CONFIG_GRXC3S1500	1	/* ... on GR-XC3S-1500 board */
+
+/* CPU / AMBA BUS configuration */
+#define CONFIG_SYS_CLK_FREQ 	40000000	/* 40MHz */
+
+/* Number of SPARC register windows */
+#define CFG_SPARC_NWINDOWS 8
+
+/*
+ * Serial console configuration
+ */
+#define CONFIG_BAUDRATE		38400	/* ... at 38400 bps */
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 230400 }
+
+/* Partitions */
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
+#define CONFIG_ISO_PARTITION
+
+/*
+ * Supported commands
+ */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_AMBAPP
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_IRQ
+
+/*
+ * Autobooting
+ */
+#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds */
+
+#define CONFIG_PREBOOT	"echo;"	\
+	"echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \
+	"echo"
+
+#undef	CONFIG_BOOTARGS
+
+#define	CONFIG_EXTRA_ENV_SETTINGS					\
+	"netdev=eth0\0"							\
+	"nfsargs=setenv bootargs console=ttyS0,38400 root=/dev/nfs rw "	\
+		"nfsroot=${serverip}:${rootpath}\0"			\
+	"ramargs=setenv bootargs console=ttyS0,${baudrate} root=/dev/ram rw\0"			\
+	"addip=setenv bootargs ${bootargs} "				\
+		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
+		":${hostname}:${netdev}:off panic=1\0"			\
+	"flash_nfs=run nfsargs addip;"					\
+		"bootm ${kernel_addr}\0"				\
+	"flash_self=run ramargs addip;"					\
+		"bootm ${kernel_addr} ${ramdisk_addr}\0"		\
+	"net_nfs=tftp 40000000 ${bootfile};run nfsargs addip;bootm\0"	\
+	"scratch=40200000\0"					\
+	"getkernel=tftpboot \$\(scratch\)\ \$\(bootfile\)\0" \
+	"bootargs=console=ttyS0,38400 root=/dev/nfs rw nfsroot=192.168.0.20:/export/rootfs ip=192.168.0.206:192.168.0.20:192.168.0.1:255.255.255.0:grxc3s1500_daniel:eth0\0" \
+	""
+
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_GATEWAYIP 192.168.0.1
+#define CONFIG_SERVERIP 192.168.0.20
+#define CONFIG_IPADDR 192.168.0.206
+#define CONFIG_ROOTPATH /export/rootfs
+#define CONFIG_HOSTNAME  grxc3s1500
+#define CONFIG_BOOTFILE  /uImage
+
+#define CONFIG_BOOTCOMMAND	"run flash_self"
+
+/* Memory MAP
+ *
+ *  Flash:
+ *  |--------------------------------|
+ *  | 0x00000000 Text & Data & BSS   | *
+ *  |            for Monitor         | *
+ *  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| *
+ *  | UNUSED / Growth                | * 256kb
+ *  |--------------------------------|
+ *  | 0x00050000 Base custom area    | *
+ *  |            kernel / FS         | *
+ *  |                                | * Rest of Flash
+ *  |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
+ *  | END-0x00008000 Environment     | * 32kb
+ *  |--------------------------------|
+ *
+ *
+ *
+ *  Main Memory:
+ *  |--------------------------------|
+ *  | UNUSED / scratch area          |
+ *  |                                |
+ *  |                                |
+ *  |                                |
+ *  |                                |
+ *  |--------------------------------|
+ *  | Monitor .Text / .DATA / .BSS   | * 256kb
+ *  | Relocated!                     | *
+ *  |--------------------------------|
+ *  | Monitor Malloc                 | * 128kb (contains relocated environment)
+ *  |--------------------------------|
+ *  | Monitor/kernel STACK           | * 64kb
+ *  |--------------------------------|
+ *  | Page Table for MMU systems     | * 2k
+ *  |--------------------------------|
+ *  | PROM Code accessed from Linux  | * 6kb-128b
+ *  |--------------------------------|
+ *  | Global data (avail from kernel)| * 128b
+ *  |--------------------------------|
+ *
+ */
+
+/*
+ * Flash configuration (8,16 or 32 MB)
+ * TEXT base always at 0xFFF00000
+ * ENV_ADDR always at  0xFFF40000
+ * FLASH_BASE at 0xFC000000 for 64 MB
+ *               0xFE000000 for 32 MB
+ *               0xFF000000 for 16 MB
+ *               0xFF800000 for  8 MB
+ */
+/*#define CFG_NO_FLASH		1*/
+#define CFG_FLASH_BASE		0x00000000
+#define CFG_FLASH_SIZE		0x00800000
+
+#define PHYS_FLASH_SECT_SIZE	0x00020000	/* 128 KB sectors */
+#define CFG_MAX_FLASH_SECT	64	/* max num of sects on one chip */
+#define CFG_MAX_FLASH_BANKS	1	/* max num of memory banks      */
+
+#define CFG_FLASH_ERASE_TOUT	240000	/* Flash Erase Timeout (in ms)  */
+#define CFG_FLASH_WRITE_TOUT	500	/* Flash Write Timeout (in ms)  */
+#define CFG_FLASH_LOCK_TOUT	5	/* Timeout for Flash Set Lock Bit (in ms) */
+#define CFG_FLASH_UNLOCK_TOUT	10000	/* Timeout for Flash Clear Lock Bits (in ms) */
+#define CFG_FLASH_PROTECTION	/* "Real" (hardware) sectors protection */
+
+/*** CFI CONFIG ***/
+#define CFG_FLASH_CFI_WIDTH	FLASH_CFI_8BIT
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_CFI
+/* Bypass cache when reading regs from flash memory */
+#define CFG_FLASH_CFI_BYPASS_READ
+/* Buffered writes (32byte/go) instead of single accesses */
+#define CFG_FLASH_USE_BUFFER_WRITE
+
+/*
+ * Environment settings
+ */
+/*#define CFG_ENV_IS_NOWHERE 1*/
+#define CFG_ENV_IS_IN_FLASH	1
+/* CFG_ENV_ADDR need to be at sector boundary */
+#define CFG_ENV_SIZE		0x8000
+#define CFG_ENV_SECT_SIZE	0x20000
+#define CFG_ENV_ADDR		(CFG_FLASH_BASE+CFG_FLASH_SIZE-CFG_ENV_SECT_SIZE)
+#define CONFIG_ENV_OVERWRITE	1
+
+/*
+ * Memory map
+ */
+#define CFG_SDRAM_BASE		0x40000000
+#define CFG_SDRAM_SIZE		0x4000000
+#define CFG_SDRAM_END		(CFG_SDRAM_BASE+CFG_SDRAM_SIZE)
+
+/* no SRAM available */
+#undef CFG_SRAM_BASE
+#undef CFG_SRAM_SIZE
+
+/* Always Run U-Boot from SDRAM */
+#define CFG_RAM_BASE CFG_SDRAM_BASE
+#define CFG_RAM_SIZE CFG_SDRAM_SIZE
+#define CFG_RAM_END CFG_SDRAM_END
+
+#define CFG_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET	(CFG_RAM_END - CFG_GBL_DATA_SIZE)
+
+#define CFG_PROM_SIZE		(8192-CFG_GBL_DATA_SIZE)
+#define CFG_PROM_OFFSET		(CFG_GBL_DATA_OFFSET-CFG_PROM_SIZE)
+
+#define CFG_INIT_SP_OFFSET	(CFG_PROM_OFFSET-32)
+#define CFG_STACK_SIZE		(0x10000-32)
+
+#define CFG_MONITOR_BASE    TEXT_BASE
+#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
+#   define CFG_RAMBOOT		1
+#endif
+
+#define CFG_MONITOR_LEN		(256 << 10)	/* Reserve 256 kB for Monitor   */
+#define CFG_MALLOC_LEN		(128 << 10)	/* Reserve 128 kB for malloc()  */
+#define CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */
+
+#define CFG_MALLOC_END		(CFG_INIT_SP_OFFSET-CFG_STACK_SIZE)
+#define CFG_MALLOC_BASE		(CFG_MALLOC_END-CFG_MALLOC_LEN)
+
+/* relocated monitor area */
+#define CFG_RELOC_MONITOR_MAX_END   CFG_MALLOC_BASE
+#define CFG_RELOC_MONITOR_BASE     (CFG_RELOC_MONITOR_MAX_END-CFG_MONITOR_LEN)
+
+/* make un relocated address from relocated address */
+#define UN_RELOC(address) (address-(CFG_RELOC_MONITOR_BASE-TEXT_BASE))
+
+/*
+ * Ethernet configuration
+ */
+#define CONFIG_GRETH	1
+#define CONFIG_NET_MULTI	1
+
+/* Default GRETH Ethernet HARDWARE address */
+#define GRETH_HWADDR_0 0x00
+#define GRETH_HWADDR_1 0x00
+#define GRETH_HWADDR_2 0x7a
+#define GRETH_HWADDR_3 0xcc
+#define GRETH_HWADDR_4 0x00
+#define GRETH_HWADDR_5 0x12
+
+#define CONFIG_ETHADDR   00:00:7a:cc:00:12
+#define CONFIG_PHY_ADDR	 0x00
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP		/* undef to save memory     */
+#define CFG_PROMPT		"=> "	/* Monitor Command Prompt   */
+#if defined(CONFIG_CMD_KGDB)
+#define CFG_CBSIZE		1024	/* Console I/O Buffer Size  */
+#else
+#define CFG_CBSIZE		256	/* Console I/O Buffer Size  */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print Buffer Size */
+#define CFG_MAXARGS		16	/* max number of command args   */
+#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size    */
+
+#define CFG_MEMTEST_START	0x00100000	/* memtest works on */
+#define CFG_MEMTEST_END		0x00f00000	/* 1 ... 15 MB in DRAM  */
+
+#define CFG_LOAD_ADDR		0x100000	/* default load address */
+
+#define CFG_HZ			1000	/* decrementer freq: 1 ms ticks */
+
+/*
+ * Various low-level settings
+ */
+
+/*-----------------------------------------------------------------------
+ * USB stuff
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_USB_CLOCK	0x0001BBBB
+#define CONFIG_USB_CONFIG	0x00005000
+
+/***** Gaisler GRLIB IP-Cores Config ********/
+
+/* AMBA Plug & Play info display on startup */
+/*#define CFG_AMBAPP_PRINT_ON_STARTUP*/
+
+#define CFG_GRLIB_SDRAM    0
+
+/* See, GRLIB Docs (grip.pdf) on how to set up
+ * These the memory controller registers.
+ */
+#define CFG_GRLIB_MEMCFG1   (0x000000ff | (1<<11))
+#define CFG_GRLIB_MEMCFG2   0x82206000
+#define CFG_GRLIB_MEMCFG3   0x00136000
+
+#define CFG_GRLIB_FT_MEMCFG1   (0x000000ff | (1<<11))
+#define CFG_GRLIB_FT_MEMCFG2   0x82206000
+#define CFG_GRLIB_FT_MEMCFG3   0x00136000
+
+/* no DDR controller */
+#define CFG_GRLIB_DDR_CFG   0x00000000
+
+/* no DDR2 Controller */
+#define CFG_GRLIB_DDR2_CFG1 0x00000000
+#define CFG_GRLIB_DDR2_CFG3 0x00000000
+
+/* Calculate scaler register value from default baudrate */
+#define CFG_GRLIB_APBUART_SCALER \
+ ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+
+/* Identification string */
+#define CONFIG_IDENT_STRING "GAISLER LEON3 GR-XC3S-1500"
+
+/* default kernel command line */
+#define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0"
+
+#endif				/* __CONFIG_H */
diff --git a/include/configs/grsim.h b/include/configs/grsim.h
new file mode 100644
index 0000000..60ad396
--- /dev/null
+++ b/include/configs/grsim.h
@@ -0,0 +1,340 @@
+/* Configuration header file for LEON3 GRSIM, trying to be similar
+ * to Gaisler's GR-XC3S-1500 board.
+ *
+ * (C) Copyright 2003-2005
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ *
+ * Select between TSIM or GRSIM by setting CONFIG_GRSIM or CONFIG_TSIM to 1.
+ *
+ * TSIM command
+ *  tsim-leon3 -sdram 0 -ram 32000 -rom 8192 -mmu
+ *
+ */
+
+#define CONFIG_LEON3			/* This is an LEON3 CPU */
+#define CONFIG_LEON		1	/* This is an LEON CPU */
+#define CONFIG_GRSIM		0	/* ... not running on GRSIM */
+#define CONFIG_TSIM		1	/* ... running on TSIM */
+
+/* CPU / AMBA BUS configuration */
+#define CONFIG_SYS_CLK_FREQ 	40000000	/* 40MHz */
+
+/* Number of SPARC register windows */
+#define CFG_SPARC_NWINDOWS 8
+
+/*
+ * Serial console configuration
+ */
+#define CONFIG_BAUDRATE		38400	/* ... at 38400 bps */
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 230400 }
+
+/* Partitions */
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
+#define CONFIG_ISO_PARTITION
+
+/*
+ * Supported commands
+ */
+#define CONFIG_CMD_AMBAPP	/* AMBA Plyg&Play information   */
+#define CONFIG_CMD_AUTOSCRIPT	/* Autoscript Support           */
+#define CONFIG_CMD_BDI		/* bdinfo                       */
+#define CONFIG_CMD_CONSOLE	/* coninfo                      */
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_ECHO		/* echo arguments               */
+#define CONFIG_CMD_FPGA		/* FPGA configuration Support   */
+#define CONFIG_CMD_IRQ
+#define CONFIG_CMD_ITEST	/* Integer (and string) test    */
+#define CONFIG_CMD_LOADB	/* loadb                        */
+#define CONFIG_CMD_LOADS	/* loads                        */
+#define CONFIG_CMD_MISC		/* Misc functions like sleep etc */
+#define CONFIG_CMD_NET		/* bootp, tftpboot, rarpboot    */
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_RUN		/* run command in env variable  */
+#define CONFIG_CMD_SETGETDCR	/* DCR support on 4xx           */
+#define CONFIG_CMD_XIMG		/* Load part of Multi Image     */
+
+/*
+ * Autobooting
+ */
+#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds */
+
+#define CONFIG_PREBOOT	"echo;"	\
+	"echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \
+	"echo"
+
+#undef	CONFIG_BOOTARGS
+/*#define CFG_HUSH_PARSER 0*/
+#ifdef	CFG_HUSH_PARSER
+#define	CFG_PROMPT_HUSH_PS2	"> "
+#endif
+
+#define	CONFIG_EXTRA_ENV_SETTINGS					\
+	"netdev=eth0\0"							\
+	"nfsargs=setenv bootargs root=/dev/nfs rw "			\
+		"nfsroot=${serverip}:${rootpath}\0"			\
+	"ramargs=setenv bootargs root=/dev/ram rw\0"			\
+	"addip=setenv bootargs ${bootargs} "				\
+		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
+		":${hostname}:${netdev}:off panic=1\0"			\
+	"flash_nfs=run nfsargs addip;"					\
+		"bootm ${kernel_addr}\0"				\
+	"flash_self=run ramargs addip;"					\
+		"bootm ${kernel_addr} ${ramdisk_addr}\0"		\
+	"net_nfs=tftp 40000000 ${bootfile};run nfsargs addip;bootm\0"	\
+	"rootpath=/export/roofs\0"					\
+	"scratch=40000000\0"					\
+	"getkernel=tftpboot \$\(scratch\)\ \$\(bootfile\)\0" \
+	"ethaddr=00:00:7A:CC:00:12\0" \
+	"bootargs=console=ttyS0,38400" \
+	""
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_GATEWAYIP 192.168.0.1
+#define CONFIG_SERVERIP 192.168.0.81
+#define CONFIG_IPADDR 192.168.0.80
+#define CONFIG_ROOTPATH /export/rootfs
+#define CONFIG_HOSTNAME  grxc3s1500
+#define CONFIG_BOOTFILE  /uImage
+
+#define CONFIG_BOOTCOMMAND	"run flash_self"
+
+/* Memory MAP
+ *
+ *  Flash:
+ *  |--------------------------------|
+ *  | 0x00000000 Text & Data & BSS   | *
+ *  |            for Monitor         | *
+ *  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| *
+ *  | UNUSED / Growth                | * 256kb
+ *  |--------------------------------|
+ *  | 0x00050000 Base custom area    | *
+ *  |            kernel / FS         | *
+ *  |                                | * Rest of Flash
+ *  |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
+ *  | END-0x00008000 Environment     | * 32kb
+ *  |--------------------------------|
+ *
+ *
+ *
+ *  Main Memory:
+ *  |--------------------------------|
+ *  | UNUSED / scratch area          |
+ *  |                                |
+ *  |                                |
+ *  |                                |
+ *  |                                |
+ *  |--------------------------------|
+ *  | Monitor .Text / .DATA / .BSS   | * 256kb
+ *  | Relocated!                     | *
+ *  |--------------------------------|
+ *  | Monitor Malloc                 | * 128kb (contains relocated environment)
+ *  |--------------------------------|
+ *  | Monitor/kernel STACK           | * 64kb
+ *  |--------------------------------|
+ *  | Page Table for MMU systems     | * 2k
+ *  |--------------------------------|
+ *  | PROM Code accessed from Linux  | * 6kb-128b
+ *  |--------------------------------|
+ *  | Global data (avail from kernel)| * 128b
+ *  |--------------------------------|
+ *
+ */
+
+/*
+ * Flash configuration (8,16 or 32 MB)
+ * TEXT base always at 0xFFF00000
+ * ENV_ADDR always at  0xFFF40000
+ * FLASH_BASE at 0xFC000000 for 64 MB
+ *               0xFE000000 for 32 MB
+ *               0xFF000000 for 16 MB
+ *               0xFF800000 for  8 MB
+ */
+#define CFG_NO_FLASH		1
+#define CFG_FLASH_BASE		0x00000000
+#define CFG_FLASH_SIZE		0x00800000
+#define CFG_ENV_SIZE		0x8000
+
+#define CFG_ENV_ADDR		(CFG_FLASH_BASE+CFG_FLASH_SIZE-CFG_ENV_SIZE)
+
+#define PHYS_FLASH_SECT_SIZE	0x00020000	/* 128 KB sectors */
+#define CFG_MAX_FLASH_SECT	64	/* max num of sects on one chip */
+#define CFG_MAX_FLASH_BANKS	1	/* max num of memory banks      */
+
+#define CFG_FLASH_ERASE_TOUT	240000	/* Flash Erase Timeout (in ms)  */
+#define CFG_FLASH_WRITE_TOUT	500	/* Flash Write Timeout (in ms)  */
+#define CFG_FLASH_LOCK_TOUT	5	/* Timeout for Flash Set Lock Bit (in ms) */
+#define CFG_FLASH_UNLOCK_TOUT	10000	/* Timeout for Flash Clear Lock Bits (in ms) */
+
+#ifdef ENABLE_FLASH_SUPPORT
+/* For use with grsim FLASH emulation extension */
+#define CFG_FLASH_PROTECTION	/* "Real" (hardware) sectors protection */
+
+#undef CONFIG_FLASH_8BIT	/* Flash is 32-bit */
+
+/*** CFI CONFIG ***/
+#define CFG_FLASH_CFI_WIDTH	FLASH_CFI_8BIT
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_CFI
+#endif
+
+/*
+ * Environment settings
+ */
+#define CFG_ENV_IS_NOWHERE 1
+/*#define CFG_ENV_IS_IN_FLASH	0*/
+/*#define CFG_ENV_SIZE		0x8000*/
+#define CFG_ENV_SECT_SIZE	0x40000
+#define CONFIG_ENV_OVERWRITE	1
+
+/*
+ * Memory map
+ */
+#define CFG_SDRAM_BASE		0x40000000
+#define CFG_SDRAM_SIZE		0x02000000
+#define CFG_SDRAM_END		(CFG_SDRAM_BASE+CFG_SDRAM_SIZE)
+
+/* no SRAM available */
+#undef CFG_SRAM_BASE
+#undef CFG_SRAM_SIZE
+
+/* Always Run U-Boot from SDRAM */
+#define CFG_RAM_BASE CFG_SDRAM_BASE
+#define CFG_RAM_SIZE CFG_SDRAM_SIZE
+#define CFG_RAM_END CFG_SDRAM_END
+
+#define CFG_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET	(CFG_RAM_END - CFG_GBL_DATA_SIZE)
+
+#define CFG_PROM_SIZE		(8192-CFG_GBL_DATA_SIZE)
+#define CFG_PROM_OFFSET		(CFG_GBL_DATA_OFFSET-CFG_PROM_SIZE)
+
+#define CFG_INIT_SP_OFFSET	(CFG_PROM_OFFSET-32)
+#define CFG_STACK_SIZE		(0x10000-32)
+
+#define CFG_MONITOR_BASE    TEXT_BASE
+#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
+#   define CFG_RAMBOOT		1
+#endif
+
+#define CFG_MONITOR_LEN		(256 << 10)	/* Reserve 256 kB for Monitor   */
+#define CFG_MALLOC_LEN		(128 << 10)	/* Reserve 128 kB for malloc()  */
+#define CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */
+
+#define CFG_MALLOC_END		(CFG_INIT_SP_OFFSET-CFG_STACK_SIZE)
+#define CFG_MALLOC_BASE		(CFG_MALLOC_END-CFG_MALLOC_LEN)
+
+/* relocated monitor area */
+#define CFG_RELOC_MONITOR_MAX_END   CFG_MALLOC_BASE
+#define CFG_RELOC_MONITOR_BASE     (CFG_RELOC_MONITOR_MAX_END-CFG_MONITOR_LEN)
+
+/* make un relocated address from relocated address */
+#define UN_RELOC(address) (address-(CFG_RELOC_MONITOR_BASE-TEXT_BASE))
+
+/*
+ * Ethernet configuration
+ */
+#define CONFIG_GRETH	1
+#define CONFIG_NET_MULTI	1
+
+/* Default HARDWARE address */
+#define GRETH_HWADDR_0 0x00
+#define GRETH_HWADDR_1 0x00
+#define GRETH_HWADDR_2 0x7A
+#define GRETH_HWADDR_3 0xcc
+#define GRETH_HWADDR_4 0x00
+#define GRETH_HWADDR_5 0x12
+
+#define CONFIG_ETHADDR   00:00:7a:cc:00:12
+
+/*
+ * Define CONFIG_GRETH_10MBIT to force GRETH at 10Mb/s
+ */
+/* #define CONFIG_GRETH_10MBIT 1 */
+#define CONFIG_PHY_ADDR		0x00
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP		/* undef to save memory     */
+#define CFG_PROMPT		"=> "	/* Monitor Command Prompt   */
+#if defined(CONFIG_CMD_KGDB)
+#define CFG_CBSIZE		1024	/* Console I/O Buffer Size  */
+#else
+#define CFG_CBSIZE		256	/* Console I/O Buffer Size  */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print Buffer Size */
+#define CFG_MAXARGS		16	/* max number of command args   */
+#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size    */
+
+#define CFG_MEMTEST_START	0x00100000	/* memtest works on */
+#define CFG_MEMTEST_END		0x00f00000	/* 1 ... 15 MB in DRAM  */
+
+#define CFG_LOAD_ADDR		0x100000	/* default load address */
+
+#define CFG_HZ			1000	/* decrementer freq: 1 ms ticks */
+
+/***** Gaisler GRLIB IP-Cores Config ********/
+
+/* AMBA Plug & Play info display on startup */
+/*#define CFG_AMBAPP_PRINT_ON_STARTUP*/
+
+#define CFG_GRLIB_SDRAM     0
+#define CFG_GRLIB_MEMCFG1   (0x000000ff | (1<<11))
+#if CONFIG_GRSIM
+/* GRSIM configuration */
+#define CFG_GRLIB_MEMCFG2   0x82206000
+#else
+/* TSIM configuration */
+#define CFG_GRLIB_MEMCFG2   0x00001820
+#endif
+#define CFG_GRLIB_MEMCFG3   0x00136000
+
+#define CFG_GRLIB_FT_MEMCFG1   (0x000000ff | (1<<11))
+#define CFG_GRLIB_FT_MEMCFG2   0x82206000
+#define CFG_GRLIB_FT_MEMCFG3   0x00136000
+
+/* no DDR controller */
+#define CFG_GRLIB_DDR_CFG   0x00000000
+
+/* no DDR2 Controller */
+#define CFG_GRLIB_DDR2_CFG1 0x00000000
+#define CFG_GRLIB_DDR2_CFG3 0x00000000
+
+#define CFG_GRLIB_APBUART_SCALER \
+ ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+
+/* default kernel command line */
+#define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0"
+
+#define CONFIG_IDENT_STRING "Gaisler GRSIM"
+
+#endif				/* __CONFIG_H */
diff --git a/include/configs/grsim_leon2.h b/include/configs/grsim_leon2.h
new file mode 100644
index 0000000..47f13d0
--- /dev/null
+++ b/include/configs/grsim_leon2.h
@@ -0,0 +1,349 @@
+/* Configuration header file for LEON2 GRSIM.
+ *
+ * (C) Copyright 2003-2005
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ *
+ * Select between TSIM or GRSIM by setting CONFIG_GRSIM or CONFIG_TSIM to 1.
+ *
+ * TSIM command
+ *  tsim-leon -sdram 0 -ram 32000 -rom 8192 -mmu
+ *
+ */
+
+#define CONFIG_LEON2		/* This is an LEON2 CPU */
+#define CONFIG_LEON		1	/* This is an LEON CPU */
+#define CONFIG_GRSIM		0	/* ... not running on GRSIM */
+#define CONFIG_TSIM		1	/* ... running on TSIM */
+
+/* CPU / AMBA BUS configuration */
+#define CONFIG_SYS_CLK_FREQ 	40000000	/* 40MHz */
+
+/* Number of SPARC register windows */
+#define CFG_SPARC_NWINDOWS 8
+
+/*
+ * Serial console configuration
+ */
+#define CONFIG_BAUDRATE		38400	/* ... at 38400 bps */
+#define CFG_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 230400 }
+
+/* Partitions */
+#define CONFIG_DOS_PARTITION
+#define CONFIG_MAC_PARTITION
+#define CONFIG_ISO_PARTITION
+
+/*
+ * Supported commands
+ */
+#define CONFIG_CMD_AUTOSCRIPT	/* Autoscript Support           */
+#define CONFIG_CMD_BDI		/* bdinfo                       */
+#define CONFIG_CMD_CONSOLE	/* coninfo                      */
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_ECHO		/* echo arguments               */
+#define CONFIG_CMD_FPGA		/* FPGA configuration Support   */
+#define CONFIG_CMD_IRQ
+#define CONFIG_CMD_ITEST	/* Integer (and string) test    */
+#define CONFIG_CMD_LOADB	/* loadb                        */
+#define CONFIG_CMD_LOADS	/* loads                        */
+#define CONFIG_CMD_MISC		/* Misc functions like sleep etc */
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_RUN		/* run command in env variable  */
+#define CONFIG_CMD_SETGETDCR	/* DCR support on 4xx           */
+#define CONFIG_CMD_XIMG		/* Load part of Multi Image     */
+
+/*
+ * Autobooting
+ */
+#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds */
+
+#define CONFIG_PREBOOT	"echo;"	\
+	"echo Type \"run flash_nfs\" to mount root filesystem over NFS;" \
+	"echo"
+
+#undef	CONFIG_BOOTARGS
+/*#define CFG_HUSH_PARSER 0*/
+#ifdef	CFG_HUSH_PARSER
+#define	CFG_PROMPT_HUSH_PS2	"> "
+#endif
+
+#define	CONFIG_EXTRA_ENV_SETTINGS					\
+	"netdev=eth0\0"							\
+	"nfsargs=setenv bootargs root=/dev/nfs rw "			\
+		"nfsroot=${serverip}:${rootpath}\0"			\
+	"ramargs=setenv bootargs root=/dev/ram rw\0"			\
+	"addip=setenv bootargs ${bootargs} "				\
+		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
+		":${hostname}:${netdev}:off panic=1\0"			\
+	"flash_nfs=run nfsargs addip;"					\
+		"bootm ${kernel_addr}\0"				\
+	"flash_self=run ramargs addip;"					\
+		"bootm ${kernel_addr} ${ramdisk_addr}\0"		\
+	"net_nfs=tftp 40000000 ${bootfile};run nfsargs addip;bootm\0"	\
+	"rootpath=/export/roofs\0"					\
+	"scratch=40000000\0"					\
+	"getkernel=tftpboot \$\(scratch\)\ \$\(bootfile\)\0" \
+	"ethaddr=00:00:7A:CC:00:12\0" \
+	"bootargs=console=ttyS0,38400" \
+	""
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_GATEWAYIP 192.168.0.1
+#define CONFIG_SERVERIP 192.168.0.81
+#define CONFIG_IPADDR 192.168.0.80
+#define CONFIG_ROOTPATH /export/rootfs
+#define CONFIG_HOSTNAME  grxc3s1500
+#define CONFIG_BOOTFILE  /uImage
+
+#define CONFIG_BOOTCOMMAND	"run flash_self"
+
+/* Memory MAP
+ *
+ *  Flash:
+ *  |--------------------------------|
+ *  | 0x00000000 Text & Data & BSS   | *
+ *  |            for Monitor         | *
+ *  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| *
+ *  | UNUSED / Growth                | * 256kb
+ *  |--------------------------------|
+ *  | 0x00050000 Base custom area    | *
+ *  |            kernel / FS         | *
+ *  |                                | * Rest of Flash
+ *  |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
+ *  | END-0x00008000 Environment     | * 32kb
+ *  |--------------------------------|
+ *
+ *
+ *
+ *  Main Memory:
+ *  |--------------------------------|
+ *  | UNUSED / scratch area          |
+ *  |                                |
+ *  |                                |
+ *  |                                |
+ *  |                                |
+ *  |--------------------------------|
+ *  | Monitor .Text / .DATA / .BSS   | * 256kb
+ *  | Relocated!                     | *
+ *  |--------------------------------|
+ *  | Monitor Malloc                 | * 128kb (contains relocated environment)
+ *  |--------------------------------|
+ *  | Monitor/kernel STACK           | * 64kb
+ *  |--------------------------------|
+ *  | Page Table for MMU systems     | * 2k
+ *  |--------------------------------|
+ *  | PROM Code accessed from Linux  | * 6kb-128b
+ *  |--------------------------------|
+ *  | Global data (avail from kernel)| * 128b
+ *  |--------------------------------|
+ *
+ */
+
+/*
+ * Flash configuration (8,16 or 32 MB)
+ * TEXT base always at 0xFFF00000
+ * ENV_ADDR always at  0xFFF40000
+ * FLASH_BASE at 0xFC000000 for 64 MB
+ *               0xFE000000 for 32 MB
+ *               0xFF000000 for 16 MB
+ *               0xFF800000 for  8 MB
+ */
+#define CFG_NO_FLASH		1
+#define CFG_FLASH_BASE		0x00000000
+#define CFG_FLASH_SIZE		0x00800000
+#define CFG_ENV_SIZE		0x8000
+
+#define CFG_ENV_ADDR		(CFG_FLASH_BASE+CFG_FLASH_SIZE-CFG_ENV_SIZE)
+
+#define PHYS_FLASH_SECT_SIZE	0x00020000	/* 128 KB sectors */
+#define CFG_MAX_FLASH_SECT	64	/* max num of sects on one chip */
+#define CFG_MAX_FLASH_BANKS	1	/* max num of memory banks      */
+
+#define CFG_FLASH_ERASE_TOUT	240000	/* Flash Erase Timeout (in ms)  */
+#define CFG_FLASH_WRITE_TOUT	500	/* Flash Write Timeout (in ms)  */
+#define CFG_FLASH_LOCK_TOUT	5	/* Timeout for Flash Set Lock Bit (in ms) */
+#define CFG_FLASH_UNLOCK_TOUT	10000	/* Timeout for Flash Clear Lock Bits (in ms) */
+
+#ifdef ENABLE_FLASH_SUPPORT
+/* For use with grsim FLASH emulation extension */
+#define CFG_FLASH_PROTECTION	/* "Real" (hardware) sectors protection */
+
+#undef CONFIG_FLASH_8BIT	/* Flash is 32-bit */
+
+/*** CFI CONFIG ***/
+#define CFG_FLASH_CFI_WIDTH	FLASH_CFI_8BIT
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_CFI
+#endif
+
+/*
+ * Environment settings
+ */
+#define CFG_ENV_IS_NOWHERE 1
+/*#define CFG_ENV_IS_IN_FLASH	0*/
+/*#define CFG_ENV_SIZE		0x8000*/
+#define CFG_ENV_SECT_SIZE	0x40000
+#define CONFIG_ENV_OVERWRITE	1
+
+/*
+ * Memory map
+ */
+#define CFG_SDRAM_BASE		0x40000000
+#define CFG_SDRAM_SIZE		0x00800000
+#define CFG_SDRAM_END		(CFG_SDRAM_BASE+CFG_SDRAM_SIZE)
+
+/* no SRAM available */
+#undef CFG_SRAM_BASE
+#undef CFG_SRAM_SIZE
+
+
+/* Always Run U-Boot from SDRAM */
+#define CFG_RAM_BASE CFG_SDRAM_BASE
+#define CFG_RAM_SIZE CFG_SDRAM_SIZE
+#define CFG_RAM_END CFG_SDRAM_END
+
+#define CFG_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET	(CFG_RAM_END - CFG_GBL_DATA_SIZE)
+
+#define CFG_PROM_SIZE		(8192-CFG_GBL_DATA_SIZE)
+#define CFG_PROM_OFFSET		(CFG_GBL_DATA_OFFSET-CFG_PROM_SIZE)
+
+#define CFG_INIT_SP_OFFSET	(CFG_PROM_OFFSET-32)
+#define CFG_STACK_SIZE		(0x10000-32)
+
+#define CFG_MONITOR_BASE    TEXT_BASE
+#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
+#   define CFG_RAMBOOT		1
+#endif
+
+#define CFG_MONITOR_LEN		(256 << 10)	/* Reserve 256 kB for Monitor   */
+#define CFG_MALLOC_LEN		(128 << 10)	/* Reserve 128 kB for malloc()  */
+#define CFG_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */
+
+#define CFG_MALLOC_END		(CFG_INIT_SP_OFFSET-CFG_STACK_SIZE)
+#define CFG_MALLOC_BASE		(CFG_MALLOC_END-CFG_MALLOC_LEN)
+
+/* relocated monitor area */
+#define CFG_RELOC_MONITOR_MAX_END   CFG_MALLOC_BASE
+#define CFG_RELOC_MONITOR_BASE     (CFG_RELOC_MONITOR_MAX_END-CFG_MONITOR_LEN)
+
+/* make un relocated address from relocated address */
+#define UN_RELOC(address) (address-(CFG_RELOC_MONITOR_BASE-TEXT_BASE))
+
+/*
+ * Ethernet configuration
+ */
+/*#define CONFIG_GRETH	1*/
+/*#define CONFIG_NET_MULTI	1*/
+
+/* Default HARDWARE address */
+#define GRETH_HWADDR_0 0x00
+#define GRETH_HWADDR_1 0x00
+#define GRETH_HWADDR_2 0x7A
+#define GRETH_HWADDR_3 0xcc
+#define GRETH_HWADDR_4 0x00
+#define GRETH_HWADDR_5 0x12
+
+#define CONFIG_ETHADDR   00:00:7a:cc:00:12
+
+/*
+ * Define CONFIG_GRETH_10MBIT to force GRETH at 10Mb/s
+ */
+/* #define CONFIG_GRETH_10MBIT 1 */
+#define CONFIG_PHY_ADDR		0x00
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP		/* undef to save memory     */
+#define CFG_PROMPT		"=> "	/* Monitor Command Prompt   */
+#if defined(CONFIG_CMD_KGDB)
+#define CFG_CBSIZE		1024	/* Console I/O Buffer Size  */
+#else
+#define CFG_CBSIZE		256	/* Console I/O Buffer Size  */
+#endif
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)	/* Print Buffer Size */
+#define CFG_MAXARGS		16	/* max number of command args   */
+#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size    */
+
+#define CFG_MEMTEST_START	0x00100000	/* memtest works on */
+#define CFG_MEMTEST_END		0x00f00000	/* 1 ... 15 MB in DRAM  */
+
+#define CFG_LOAD_ADDR		0x100000	/* default load address */
+
+#define CFG_HZ			1000	/* decrementer freq: 1 ms ticks */
+
+/***** Gaisler GRLIB IP-Cores Config ********/
+
+#define CFG_GRLIB_SDRAM    0
+#define CFG_GRLIB_MEMCFG1  (0x000000ff | (1<<11))
+#if CONFIG_GRSIM
+#define CFG_GRLIB_MEMCFG2  0x82206000
+#else
+#define CFG_GRLIB_MEMCFG2  0x00001820
+#endif
+#define CFG_GRLIB_MEMCFG3  0x00136000
+
+/*** LEON2 UART 1 ***/
+#define CFG_LEON2_UART1_SCALER \
+ ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+ 
+/* UART1 Define to 1 or 0 */
+#define LEON2_UART1_LOOPBACK_ENABLE 0
+#define LEON2_UART1_FLOWCTRL_ENABLE 0
+#define LEON2_UART1_PARITY_ENABLE 0
+#define LEON2_UART1_ODDPAR_ENABLE 0
+
+/*** LEON2 UART 2 ***/
+
+#define CFG_LEON2_UART2_SCALER \
+ ((((CONFIG_SYS_CLK_FREQ*10)/(CONFIG_BAUDRATE*8))-5)/10)
+
+/* UART2 Define to 1 or 0 */
+#define LEON2_UART2_LOOPBACK_ENABLE 0
+#define LEON2_UART2_FLOWCTRL_ENABLE 0
+#define LEON2_UART2_PARITY_ENABLE 0
+#define LEON2_UART2_ODDPAR_ENABLE 0
+
+#define LEON_CONSOLE_UART1 1
+#define LEON_CONSOLE_UART2 2
+
+/* Use UART2 as console */
+#define LEON2_CONSOLE_SELECT LEON_CONSOLE_UART1
+
+/* LEON2 I/O Port */
+/*#define LEON2_IO_PORT_DIR 0x0000aa00*/
+
+/* default kernel command line */
+#define CONFIG_DEFAULT_KERNEL_COMMAND_LINE "console=ttyS0,38400\0\0"
+
+#define CONFIG_IDENT_STRING "Gaisler GRSIM LEON2"
+
+#endif				/* __CONFIG_H */
diff --git a/include/configs/kilauea.h b/include/configs/kilauea.h
index 3f4b8e6..f4cf42c 100644
--- a/include/configs/kilauea.h
+++ b/include/configs/kilauea.h
@@ -243,22 +243,27 @@
 		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
 		":${hostname}:${netdev}:off panic=1\0"			\
 	"addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}\0"\
-	"net_nfs=tftp 200000 ${bootfile};"				\
-		"run nfsargs addip addtty;"				\
-		"bootm 200000\0"					\
-	"net_nfs_fdt=tftp 200000 ${bootfile};"				\
-		"tftp ${fdt_addr} ${fdt_file};"				\
-		"run nfsargs addip addtty;"				\
-		"bootm 200000 - ${fdt_addr}\0"				\
-	"flash_nfs=run nfsargs addip addtty;"				\
-		"bootm ${kernel_addr}\0"				\
-	"flash_self=run ramargs addip addtty;"				\
+	"flash_self_old=run ramargs addip addtty;"			\
 		"bootm ${kernel_addr} ${ramdisk_addr}\0"		\
+	"flash_self=run ramargs addip addtty;"				\
+		"bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}\0"	\
+	"flash_nfs_old=run nfsargs addip addtty;"			\
+		"bootm ${kernel_addr}\0"				\
+	"flash_nfs=run nfsargs addip addtty;"				\
+		"bootm ${kernel_addr} - ${fdt_addr}\0"			\
+	"net_nfs_old=tftp ${kernel_addr_r} ${bootfile};"		\
+		"run nfsargs addip addtty;bootm ${kernel_addr_r}\0"	\
+	"net_nfs=tftp ${kernel_addr_r} ${bootfile}; "			\
+		"tftp ${fdt_addr_r} ${fdt_file}; "			\
+		"run nfsargs addip addtty;"				\
+		"bootm ${kernel_addr_r} - ${fdt_addr_r}\0"		\
 	"rootpath=/opt/eldk/ppc_4xx\0"					\
 	"bootfile=kilauea/uImage\0"					\
 	"fdt_file=kilauea/kilauea.dtb\0"				\
-	"fdt_addr=400000\0"						\
+	"kernel_addr_r=400000\0"					\
+	"fdt_addr_r=800000\0"						\
 	"kernel_addr=fc000000\0"					\
+	"fdt_addr=fc1e0000\0"						\
 	"ramdisk_addr=fc200000\0"					\
 	"initrd_high=30000000\0"					\
 	"load=tftp 200000 kilauea/u-boot.bin\0"				\
diff --git a/include/configs/ml401.h b/include/configs/ml401.h
index b320438..360e2e1 100644
--- a/include/configs/ml401.h
+++ b/include/configs/ml401.h
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2007 Michal Simek
+ * (C) Copyright 2007-2008 Michal Simek
  *
  * Michal SIMEK <monstr@monstr.eu>
  *
@@ -32,21 +32,42 @@
 #define	CONFIG_ML401		1	/* ML401 Board */
 
 /* uart */
+#ifdef XILINX_UARTLITE_BASEADDR
 #define	CONFIG_XILINX_UARTLITE
-#define	CONFIG_SERIAL_BASE	XILINX_UART_BASEADDR
-#define	CONFIG_BAUDRATE		XILINX_UART_BAUDRATE
+#define	CONFIG_SERIAL_BASE	XILINX_UARTLITE_BASEADDR
+#define	CONFIG_BAUDRATE		XILINX_UARTLITE_BAUDRATE
 #define	CFG_BAUDRATE_TABLE	{ CONFIG_BAUDRATE }
+#else
+#ifdef XILINX_UART16550_BASEADDR
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+#define CFG_NS16550_REG_SIZE	4
+#define CONFIG_CONS_INDEX	1
+#define CFG_NS16550_COM1	XILINX_UART16550_BASEADDR
+#define CFG_NS16550_CLK		XILINX_UART16550_CLOCK_HZ
+#define	CONFIG_BAUDRATE		115200
+#define	CFG_BAUDRATE_TABLE	{ 9600, 115200 }
+#endif
+#endif
 
 /* setting reset address */
 /*#define	CFG_RESET_ADDRESS	TEXT_BASE*/
 
 /* ethernet */
-#define CONFIG_EMACLITE		1
-#define XPAR_EMAC_0_DEVICE_ID	XPAR_OPB_ETHERNET_0_DEVICE_ID
+#ifdef XILINX_EMAC_BASEADDR
+#define CONFIG_XILINX_EMAC	1
+#else
+#ifdef XILINX_EMACLITE_BASEADDR
+#define CONFIG_XILINX_EMACLITE	1
+#endif
+#endif
+#undef ET_DEBUG
 
 /* gpio */
+#ifdef XILINX_GPIO_BASEADDR
 #define	CFG_GPIO_0		1
 #define	CFG_GPIO_0_ADDR		XILINX_GPIO_BASEADDR
+#endif
 
 /* interrupt controller */
 #define	CFG_INTC_0		1
@@ -62,8 +83,8 @@
 #define	CONFIG_XILINX_CLOCK_FREQ	XILINX_CLOCK_FREQ
 
 /* FSL */
-#define	CFG_FSL_2
-#define	FSL_INTR_2	1
+/* #define	CFG_FSL_2 */
+/* #define	FSL_INTR_2	1 */
 
 /*
  * memory layout - Example
@@ -134,9 +155,9 @@
 
 	#else	/* !RAMENV */
 		#define	CFG_ENV_IS_IN_FLASH	1
-		#define	CFG_ENV_ADDR		0x40000
 		#define	CFG_ENV_SECT_SIZE	0x40000	/* 256K(one sector) for env */
-		#define	CFG_ENV_SIZE		0x2000
+		#define	CFG_ENV_ADDR		(CFG_FLASH_BASE + (2 * CFG_ENV_SECT_SIZE))
+		#define	CFG_ENV_SIZE		0x40000
 	#endif /* !RAMBOOT */
 #else /* !FLASH */
 	/* ENV in RAM */
@@ -235,4 +256,7 @@
 					"256k(u-boot),256k(env),3m(kernel),"\
 					"1m(romfs),1m(cramfs),-(jffs2)\0"
 
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_OF_LIBFDT	1
+
 #endif	/* __CONFIG_H */
diff --git a/include/configs/xupv2p.h b/include/configs/xupv2p.h
index c9320c2..30fb303 100644
--- a/include/configs/xupv2p.h
+++ b/include/configs/xupv2p.h
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2007 Michal Simek
+ * (C) Copyright 2007-2008 Michal Simek
  *
  * Michal SIMEK <monstr@monstr.eu>
  *
@@ -31,14 +31,23 @@
 #define	CONFIG_XUPV2P		1
 
 /* uart */
+#ifdef XILINX_UARTLITE_BASEADDR
 #define	CONFIG_XILINX_UARTLITE
-#define	CONFIG_SERIAL_BASE	XILINX_UART_BASEADDR
-#define	CONFIG_BAUDRATE		XILINX_UART_BAUDRATE
+#define	CONFIG_SERIAL_BASE	XILINX_UARTLITE_BASEADDR
+#define	CONFIG_BAUDRATE		XILINX_UARTLITE_BAUDRATE
 #define	CFG_BAUDRATE_TABLE	{ CONFIG_BAUDRATE }
-
-/* ethernet */
-#define CONFIG_EMAC	1
-#define XPAR_EMAC_0_DEVICE_ID	XPAR_XEMAC_NUM_INSTANCES
+#else
+#ifdef XILINX_UART16550_BASEADDR
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+#define CFG_NS16550_REG_SIZE	4
+#define CONFIG_CONS_INDEX	1
+#define CFG_NS16550_COM1	XILINX_UART16550_BASEADDR
+#define CFG_NS16550_CLK		XILINX_UART16550_CLOCK_HZ
+#define	CONFIG_BAUDRATE		115200
+#define	CFG_BAUDRATE_TABLE	{ 9600, 115200 }
+#endif
+#endif
 
 /*
  * setting reset address
@@ -51,6 +60,16 @@
  */
 /* #define	CFG_RESET_ADDRESS	0x36000000 */
 
+/* ethernet */
+#ifdef XILINX_EMAC_BASEADDR
+#define CONFIG_XILINX_EMAC	1
+#else
+#ifdef XILINX_EMACLITE_BASEADDR
+#define CONFIG_XILINX_EMACLITE	1
+#endif
+#endif
+#undef ET_DEBUG
+
 /* gpio */
 #ifdef XILINX_GPIO_BASEADDR
 #define	CFG_GPIO_0		1
@@ -137,6 +156,7 @@
 #include <config_cmd_default.h>
 
 #undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_JFFS2
 #undef CONFIG_CMD_IMLS
 
 #define CONFIG_CMD_ASKENV
@@ -184,4 +204,7 @@
 #define	CONFIG_DOS_PARTITION
 #endif
 
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_OF_LIBFDT	1 /* flat device tree */
+
 #endif	/* __CONFIG_H */
diff --git a/include/image.h b/include/image.h
index 36143e2..c1a6cbb 100644
--- a/include/image.h
+++ b/include/image.h
@@ -419,6 +419,8 @@
 	if (!image_check_arch (hdr, IH_ARCH_PPC))
 #elif defined(__sh__)
 	if (!image_check_arch (hdr, IH_ARCH_SH))
+#elif defined(__sparc__)
+	if (!image_check_arch (hdr, IH_ARCH_SPARC))
 #else
 # error Unknown CPU type
 #endif
@@ -571,6 +573,8 @@
 	if (!fit_image_check_arch (fdt, node, IH_ARCH_PPC))
 #elif defined(__sh__)
 	if (!fit_image_check_arch (fdt, node, IH_ARCH_SH))
+#elif defined(__sparc__)
+	if (!fit_image_check_arch (fdt, node, IH_ARCH_SPARC))
 #else
 # error Unknown CPU type
 #endif
diff --git a/include/ppc440.h b/include/ppc440.h
index 642d1de..bb39ad6 100644
--- a/include/ppc440.h
+++ b/include/ppc440.h
@@ -1731,17 +1731,10 @@
 #else
 #define CNTRL_DCR_BASE 0x0b0
 #endif
-#if defined(CONFIG_440GX) || \
-    defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
-    defined(CONFIG_460EX) || defined(CONFIG_460GT)
+
 #define cpc0_er		(CNTRL_DCR_BASE+0x00)	/* CPM enable register		*/
 #define cpc0_fr		(CNTRL_DCR_BASE+0x01)	/* CPM force register		*/
 #define cpc0_sr		(CNTRL_DCR_BASE+0x02)	/* CPM status register		*/
-#else
-#define cpc0_sr		(CNTRL_DCR_BASE+0x00)	/* CPM status register		*/
-#define cpc0_er		(CNTRL_DCR_BASE+0x01)	/* CPM enable register		*/
-#define cpc0_fr		(CNTRL_DCR_BASE+0x02)	/* CPM force register		*/
-#endif
 
 #define cpc0_sys0	(CNTRL_DCR_BASE+0x30)	/* System configuration reg 0	*/
 #define cpc0_sys1	(CNTRL_DCR_BASE+0x31)	/* System configuration reg 1	*/
diff --git a/lib_ppc/board.c b/lib_ppc/board.c
index 7d33914..b2bc4eb 100644
--- a/lib_ppc/board.c
+++ b/lib_ppc/board.c
@@ -440,7 +440,7 @@
 	 *  - monitor code
 	 *  - board info struct
 	 */
-	len = (ulong)&_end - (ulong)&_start + EXC_OFF_SYS_RESET;
+	len = (ulong)&_end - CFG_MONITOR_BASE;
 
 	/*
 	 * Subtract specified amount of memory to hide so that it won't
diff --git a/lib_sparc/Makefile b/lib_sparc/Makefile
new file mode 100644
index 0000000..1a354b6
--- /dev/null
+++ b/lib_sparc/Makefile
@@ -0,0 +1,45 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(ARCH).a
+
+SOBJS	=
+
+COBJS	= board.o cache.o interrupts.o time.o bootm.o
+
+SRCS 	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/lib_sparc/board.c b/lib_sparc/board.c
new file mode 100644
index 0000000..af301c0
--- /dev/null
+++ b/lib_sparc/board.c
@@ -0,0 +1,521 @@
+/* SPARC Board initialization
+ *
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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 <command.h>
+#include <malloc.h>
+#include <devices.h>
+#include <config.h>
+#if defined(CONFIG_CMD_IDE)
+#include <ide.h>
+#endif
+#ifdef CONFIG_STATUS_LED
+#include <status_led.h>
+#endif
+#include <net.h>
+#include <serial.h>
+#include <version.h>
+#if defined(CONFIG_POST)
+#include <post.h>
+#endif
+#ifdef CONFIG_PS2KBD
+#include <keyboard.h>
+#endif
+#ifdef CONFIG_CMD_AMBAPP
+#include <ambapp.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Debug options
+#define DEBUG_INIT_SEQUENCE
+#define DEBUG_MEM_LAYOUT
+#define DEBUG_COMMANDS
+*/
+
+extern void timer_interrupt_init(void);
+extern void malloc_bin_reloc(void);
+extern int do_ambapp_print(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
+extern int prom_init(void);
+
+#if defined(CONFIG__CMD_DOC)
+void doc_init(void);
+#endif
+
+#if !defined(CFG_NO_FLASH)
+static char *failed = "*** failed ***\n";
+#endif
+
+#include <environment.h>
+
+ulong monitor_flash_len;
+
+/*
+ * Begin and End of memory area for malloc(), and current "brk"
+ */
+static ulong mem_malloc_start = 0;
+static ulong mem_malloc_end = 0;
+static ulong mem_malloc_brk = 0;
+
+/************************************************************************
+ * Utilities								*
+ ************************************************************************
+ */
+
+/*
+ * The Malloc area is immediately below the monitor copy in RAM
+ */
+static void mem_malloc_init(void)
+{
+	mem_malloc_start = CFG_MALLOC_BASE;
+	mem_malloc_end = CFG_MALLOC_END;
+	mem_malloc_brk = mem_malloc_start;
+	memset((void *)mem_malloc_start, 0, mem_malloc_end - mem_malloc_start);
+}
+
+void *sbrk(ptrdiff_t increment)
+{
+	ulong old = mem_malloc_brk;
+	ulong new = old + increment;
+
+	if ((new < mem_malloc_start) || (new > mem_malloc_end)) {
+		return (NULL);
+	}
+	mem_malloc_brk = new;
+	return ((void *)old);
+}
+
+/***********************************************************************/
+
+/************************************************************************
+ * Init Utilities							*
+ ************************************************************************
+ * Some of this code should be moved into the core functions,
+ * but let's get it working (again) first...
+ */
+
+static int init_baudrate(void)
+{
+	char tmp[64];		/* long enough for environment variables */
+	int i = getenv_r("baudrate", tmp, sizeof(tmp));
+
+	gd->baudrate = (i > 0)
+	    ? (int)simple_strtoul(tmp, NULL, 10)
+	    : CONFIG_BAUDRATE;
+	return (0);
+}
+
+/***********************************************************************/
+
+/*
+ * All attempts to come up with a "common" initialization sequence
+ * that works for all boards and architectures failed: some of the
+ * requirements are just _too_ different. To get rid of the resulting
+ * mess of board dependend #ifdef'ed code we now make the whole
+ * initialization sequence configurable to the user.
+ *
+ * The requirements for any new initalization function is simple: it
+ * receives a pointer to the "global data" structure as it's only
+ * argument, and returns an integer return code, where 0 means
+ * "continue" and != 0 means "fatal error, hang the system".
+ */
+typedef int (init_fnc_t) (void);
+
+#define WATCHDOG_RESET(x)
+
+/************************************************************************
+ * Initialization sequence						*
+ ************************************************************************
+ */
+
+init_fnc_t *init_sequence[] = {
+
+#if defined(CONFIG_BOARD_EARLY_INIT_F)
+	board_early_init_f,
+#endif
+	serial_init,
+
+	init_timebase,
+
+#if defined(CONFIG_CMD_AMBAPP)
+	ambapp_init_reloc,
+#endif
+
+	env_init,
+
+	init_baudrate,
+
+	console_init_f,
+	display_options,
+
+	checkcpu,
+	checkboard,
+#if defined(CONFIG_MISC_INIT_F)
+	misc_init_f,
+#endif
+
+#ifdef CONFIG_POST
+	post_init_f,
+#endif
+
+	NULL,			/* Terminate this list,
+				 * beware: this list will be relocated
+				 * which means that NULL will become
+				 * NULL+RELOC_OFFSET. We simply make
+				 * NULL be -RELOC_OFFSET instead.
+				 */
+};
+
+/************************************************************************
+ *
+ * This is the SPARC board initialization routine, running from RAM.
+ *
+ ************************************************************************
+ */
+#ifdef DEBUG_INIT_SEQUENCE
+char *str_init_seq = "INIT_SEQ 00\n";
+char *str_init_seq_done = "\n\rInit sequence done...\r\n\r\n";
+#endif
+
+void board_init_f(ulong bootflag)
+{
+	cmd_tbl_t *cmdtp;
+	bd_t *bd;
+	unsigned char *s;
+	init_fnc_t **init_fnc_ptr;
+	int j;
+	int i;
+	char *e;
+
+#ifndef CFG_NO_FLASH
+	ulong flash_size;
+#endif
+
+	gd = (gd_t *) (CFG_GBL_DATA_OFFSET);
+
+	/* Clear initial global data */
+	memset((void *)gd, 0, sizeof(gd_t));
+
+	gd->bd = (bd_t *) (gd + 1);	/* At end of global data */
+	gd->baudrate = CONFIG_BAUDRATE;
+	gd->cpu_clk = CONFIG_SYS_CLK_FREQ;
+
+	bd = gd->bd;
+	bd->bi_memstart = CFG_RAM_BASE;
+	bd->bi_memsize = CFG_RAM_SIZE;
+	bd->bi_flashstart = CFG_FLASH_BASE;
+#if	defined(CFG_SRAM_BASE) && defined(CFG_SRAM_SIZE)
+	bd->bi_sramstart = CFG_SRAM_BASE;
+	bd->bi_sramsize = CFG_SRAM_SIZE;
+#endif
+	bd->bi_baudrate = CONFIG_BAUDRATE;
+	bd->bi_bootflags = bootflag;	/* boot / reboot flag (for LynxOS)    */
+
+	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
+	gd->reloc_off = CFG_RELOC_MONITOR_BASE - CFG_MONITOR_BASE;
+
+	for (init_fnc_ptr = init_sequence, j = 0; *init_fnc_ptr;
+	     ++init_fnc_ptr, j++) {
+#ifdef DEBUG_INIT_SEQUENCE
+		if (j > 9)
+			str_init_seq[9] = '0' + (j / 10);
+		str_init_seq[10] = '0' + (j - (j / 10) * 10);
+		serial_puts(str_init_seq);
+#endif
+		if ((*init_fnc_ptr + gd->reloc_off) () != 0) {
+			hang();
+		}
+	}
+#ifdef DEBUG_INIT_SEQUENCE
+	serial_puts(str_init_seq_done);
+#endif
+
+	/*
+	 * Now that we have DRAM mapped and working, we can
+	 * relocate the code and continue running from DRAM.
+	 *
+	 * Reserve memory at end of RAM for (top down in that order):
+	 *  - kernel log buffer
+	 *  - protected RAM
+	 *  - LCD framebuffer
+	 *  - monitor code
+	 *  - board info struct
+	 */
+#ifdef DEBUG_MEM_LAYOUT
+	printf("CFG_MONITOR_BASE:       0x%lx\n", CFG_MONITOR_BASE);
+	printf("CFG_ENV_ADDR:           0x%lx\n", CFG_ENV_ADDR);
+	printf("CFG_RELOC_MONITOR_BASE: 0x%lx (%d)\n", CFG_RELOC_MONITOR_BASE,
+	       CFG_MONITOR_LEN);
+	printf("CFG_MALLOC_BASE:        0x%lx (%d)\n", CFG_MALLOC_BASE,
+	       CFG_MALLOC_LEN);
+	printf("CFG_INIT_SP_OFFSET:     0x%lx (%d)\n", CFG_INIT_SP_OFFSET,
+	       CFG_STACK_SIZE);
+	printf("CFG_PROM_OFFSET:        0x%lx (%d)\n", CFG_PROM_OFFSET,
+	       CFG_PROM_SIZE);
+	printf("CFG_GBL_DATA_OFFSET:    0x%lx (%d)\n", CFG_GBL_DATA_OFFSET,
+	       CFG_GBL_DATA_SIZE);
+#endif
+
+#ifdef CONFIG_POST
+	post_bootmode_init();
+	post_run(NULL, POST_ROM | post_bootmode_get(0));
+#endif
+
+	/*
+	 * We have to relocate the command table manually
+	 */
+	for (cmdtp = &__u_boot_cmd_start; cmdtp != &__u_boot_cmd_end; cmdtp++) {
+		ulong addr;
+		addr = (ulong) (cmdtp->cmd) + gd->reloc_off;
+#if DEBUG_COMMANDS
+		printf("Command \"%s\": 0x%08lx => 0x%08lx\n",
+		       cmdtp->name, (ulong) (cmdtp->cmd), addr);
+#endif
+		cmdtp->cmd =
+		    (int (*)(struct cmd_tbl_s *, int, int, char *[]))addr;
+
+		addr = (ulong) (cmdtp->name) + gd->reloc_off;
+		cmdtp->name = (char *)addr;
+
+		if (cmdtp->usage) {
+			addr = (ulong) (cmdtp->usage) + gd->reloc_off;
+			cmdtp->usage = (char *)addr;
+		}
+#ifdef	CFG_LONGHELP
+		if (cmdtp->help) {
+			addr = (ulong) (cmdtp->help) + gd->reloc_off;
+			cmdtp->help = (char *)addr;
+		}
+#endif
+	}
+
+#if defined(CONFIG_CMD_AMBAPP) && defined(CFG_AMBAPP_PRINT_ON_STARTUP)
+	puts("AMBA:\n");
+	do_ambapp_print(NULL, 0, 0, NULL);
+#endif
+
+	/* initialize higher level parts of CPU like time base and timers */
+	cpu_init_r();
+
+	/* start timer */
+	timer_interrupt_init();
+
+	/*
+	 * Enable Interrupts before any calls to udelay,
+	 * the flash driver may use udelay resulting in
+	 * a hang if not timer0 IRQ is enabled.
+	 */
+	interrupt_init();
+
+#if !defined(CFG_NO_FLASH)
+	puts("FLASH: ");
+
+	if ((flash_size = flash_init()) > 0) {
+# ifdef CFG_FLASH_CHECKSUM
+		print_size(flash_size, "");
+		/*
+		 * Compute and print flash CRC if flashchecksum is set to 'y'
+		 *
+		 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
+		 */
+		s = getenv("flashchecksum");
+		if (s && (*s == 'y')) {
+			printf("  CRC: %08lX",
+			       crc32(0, (const unsigned char *)CFG_FLASH_BASE,
+				     flash_size)
+			    );
+		}
+		putc('\n');
+# else				/* !CFG_FLASH_CHECKSUM */
+		print_size(flash_size, "\n");
+# endif				/* CFG_FLASH_CHECKSUM */
+	} else {
+		puts(failed);
+		hang();
+	}
+
+	bd->bi_flashstart = CFG_FLASH_BASE;	/* update start of FLASH memory    */
+	bd->bi_flashsize = flash_size;	/* size of FLASH memory (final value) */
+#if CFG_MONITOR_BASE == CFG_FLASH_BASE
+	bd->bi_flashoffset = monitor_flash_len;	/* reserved area for startup monitor  */
+#else
+	bd->bi_flashoffset = 0;
+#endif
+#else				/* CFG_NO_FLASH */
+	bd->bi_flashsize = 0;
+	bd->bi_flashstart = 0;
+	bd->bi_flashoffset = 0;
+#endif				/* !CFG_NO_FLASH */
+
+	/* initialize malloc() area */
+	mem_malloc_init();
+
+	malloc_bin_reloc();
+
+#ifdef CONFIG_SPI
+# if !defined(CFG_ENV_IS_IN_EEPROM)
+	spi_init_f();
+# endif
+	spi_init_r();
+#endif
+
+	/* relocate environment function pointers etc. */
+	env_relocate();
+
+#if defined(CONFIG_BOARD_LATE_INIT)
+	board_late_init();
+#endif
+
+	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;
+	}
+
+#ifdef CONFIG_HAS_ETH1
+	/* handle the 2nd ethernet address */
+
+	s = getenv("eth1addr");
+
+	for (i = 0; i < 6; ++i) {
+		bd->bi_enet1addr[i] = s ? simple_strtoul(s, &e, 16) : 0;
+		if (s)
+			s = (*e) ? e + 1 : e;
+	}
+#endif
+
+#ifdef CFG_ID_EEPROM
+	mac_read_from_eeprom();
+#endif
+
+	/* IP Address */
+	bd->bi_ip_addr = getenv_IPaddr("ipaddr");
+#if defined(CONFIG_PCI)
+	/*
+	 * Do pci configuration
+	 */
+	pci_init();
+#endif
+
+	/* Initialize devices */
+	devices_init();
+
+	/* Initialize the jump table for applications */
+	jumptable_init();
+
+	/* Initialize the console (after the relocation and devices init) */
+	console_init_r();
+
+#ifdef CONFIG_SERIAL_SOFTWARE_FIFO
+	serial_buffered_init();
+#endif
+
+#ifdef CONFIG_STATUS_LED
+	status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING);
+#endif
+
+	udelay(20);
+
+	set_timer(0);
+
+	/* Initialize from environment */
+	if ((s = getenv("loadaddr")) != NULL) {
+		load_addr = simple_strtoul(s, NULL, 16);
+	}
+#if defined(CONFIG_CMD_NET)
+	if ((s = getenv("bootfile")) != NULL) {
+		copy_filename(BootFile, s, sizeof(BootFile));
+	}
+#endif				/* CFG_CMD_NET */
+
+	WATCHDOG_RESET();
+
+#if defined(CONFIG_CMD_DOC)
+	WATCHDOG_RESET();
+	puts("DOC:   ");
+	doc_init();
+#endif
+
+#if defined(CONFIG_CMD_NET)
+#if defined(CONFIG_NET_MULTI)
+	WATCHDOG_RESET();
+	puts("Net:   ");
+#endif
+	eth_initialize(bd);
+#endif
+
+#if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R)
+	WATCHDOG_RESET();
+	debug("Reset Ethernet PHY\n");
+	reset_phy();
+#endif
+
+#ifdef CONFIG_POST
+	post_run(NULL, POST_RAM | post_bootmode_get(0));
+#endif
+
+#if defined(CONFIG_CMD_IDE)
+	WATCHDOG_RESET();
+	puts("IDE:   ");
+	ide_init();
+#endif				/* CFG_CMD_IDE */
+
+#ifdef CONFIG_LAST_STAGE_INIT
+	WATCHDOG_RESET();
+	/*
+	 * Some parts can be only initialized if all others (like
+	 * Interrupts) are up and running (i.e. the PC-style ISA
+	 * keyboard).
+	 */
+	last_stage_init();
+#endif
+
+#ifdef CONFIG_PS2KBD
+	puts("PS/2:  ");
+	kbd_init();
+#endif
+	prom_init();
+
+	/* main_loop */
+	for (;;) {
+		WATCHDOG_RESET();
+		main_loop();
+	}
+
+}
+
+void hang(void)
+{
+	puts("### ERROR ### Please RESET the board ###\n");
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+	show_boot_progress(-30);
+#endif
+	for (;;) ;
+}
+
+/************************************************************************/
diff --git a/lib_sparc/bootm.c b/lib_sparc/bootm.c
new file mode 100644
index 0000000..8900b2e
--- /dev/null
+++ b/lib_sparc/bootm.c
@@ -0,0 +1,226 @@
+/* SPARC code for booting linux 2.6
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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 <command.h>
+#include <asm/byteorder.h>
+#include <asm/prom.h>
+#include <asm/cache.h>
+
+#define PRINT_KERNEL_HEADER
+
+extern image_header_t header;
+extern void srmmu_init_cpu(unsigned int entry);
+extern void prepare_bootargs(char *bootargs);
+extern int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);
+
+#ifdef CONFIG_USB_UHCI
+extern int usb_lowlevel_stop(void);
+#endif
+
+/* sparc kernel argument (the ROM vector) */
+struct linux_romvec *kernel_arg_promvec;
+
+/* page szie is 4k */
+#define PAGE_SIZE 0x1000
+#define RAMDISK_IMAGE_START_MASK	0x07FF
+#define RAMDISK_PROMPT_FLAG		0x8000
+#define RAMDISK_LOAD_FLAG		0x4000
+struct __attribute__ ((packed)) {
+	char traptable[PAGE_SIZE];
+	char swapper_pg_dir[PAGE_SIZE];
+	char pg0[PAGE_SIZE];
+	char pg1[PAGE_SIZE];
+	char pg2[PAGE_SIZE];
+	char pg3[PAGE_SIZE];
+	char empty_bad_page[PAGE_SIZE];
+	char empty_bad_page_table[PAGE_SIZE];
+	char empty_zero_page[PAGE_SIZE];
+	unsigned char hdr[4];	/* ascii "HdrS" */
+	/* 00.02.06.0b is for Linux kernel 2.6.11 */
+	unsigned char linuxver_mega_major;
+	unsigned char linuxver_major;
+	unsigned char linuxver_minor;
+	unsigned char linuxver_revision;
+	/* header version 0x0203 */
+	unsigned short hdr_ver;
+	union __attribute__ ((packed)) {
+		struct __attribute__ ((packed)) {
+			unsigned short root_flags;
+			unsigned short root_dev;
+			unsigned short ram_flags;
+			unsigned int sparc_ramdisk_image;
+			unsigned int sparc_ramdisk_size;
+			unsigned int reboot_command;
+			unsigned int resv[3];
+			unsigned int end;
+		} ver_0203;
+	} hdr_input;
+} *linux_hdr;
+
+/* temporary initrd image holder */
+image_header_t ihdr;
+
+/* boot the linux kernel */
+void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],
+		    bootm_headers_t * images)
+{
+	char *bootargs;
+	ulong ep, load;
+	ulong initrd_start, initrd_end;
+	ulong rd_data_start, rd_data_end, rd_len;
+	unsigned int data, len, checksum;
+	unsigned int initrd_addr, kernend;
+	void (*kernel) (struct linux_romvec *, void *);
+	struct lmb *lmb = images->lmb;
+	int ret;
+
+	if (images->legacy_hdr_valid) {
+		ep = image_get_ep(images->legacy_hdr_os);
+		load = image_get_load(images->legacy_hdr_os);
+#if defined(CONFIG_FIT)
+	} else if (images->fit_uname_os) {
+		int ret = fit_image_get_entry(images->fit_hdr_os,
+					      images->fit_noffset_os, &ep);
+		if (ret) {
+			puts("Can't get entry point property!\n");
+			goto error;
+		}
+
+		ret = fit_image_get_load(images->fit_hdr_os,
+					 images->fit_noffset_os, &load);
+		if (ret) {
+			puts("Can't get load address property!\n");
+			goto error;
+		}
+#endif
+	} else {
+		puts("Could not find kernel entry point!\n");
+		goto error;
+	}
+
+	/* Get virtual address of kernel start */
+	linux_hdr = (void *)load;
+
+	/* */
+	kernel = (void (*)(struct linux_romvec *, void *))ep;
+
+	/* check for a SPARC kernel */
+	if ((linux_hdr->hdr[0] != 'H') ||
+	    (linux_hdr->hdr[1] != 'd') ||
+	    (linux_hdr->hdr[2] != 'r') || (linux_hdr->hdr[3] != 'S')) {
+		puts("Error reading header of SPARC Linux kernel, aborting\n");
+		goto error;
+	}
+#ifdef PRINT_KERNEL_HEADER
+	printf("## Found SPARC Linux kernel %d.%d.%d ...\n",
+	       linux_hdr->linuxver_major,
+	       linux_hdr->linuxver_minor, linux_hdr->linuxver_revision);
+#endif
+
+#ifdef CONFIG_USB_UHCI
+	usb_lowlevel_stop();
+#endif
+
+	/* set basic boot params in kernel header now that it has been
+	 * extracted and is writeable.
+	 */
+
+	/*
+	 * Are we going to use an initrd image?
+	 */
+	ret = boot_get_ramdisk(argc, argv, images, IH_ARCH_SPARC,
+			       &rd_data_start, &rd_data_end);
+	if (ret) {
+		/* RAM disk found but was corrupt */
+		puts("RAM Disk corrupt\n");
+		goto error;
+	}
+
+	/* Calc length of RAM disk, if zero no ramdisk available */
+	rd_len = rd_data_end - rd_data_start;
+
+	if (rd_len) {
+
+		/* Reserve the space used by PROM and stack. This is done
+		 * to avoid that the RAM image is copied over stack or
+		 * PROM.
+		 */
+		lmb_reserve(lmb, CFG_RELOC_MONITOR_BASE, CFG_RAM_END);
+
+		ret = boot_ramdisk_high(lmb, rd_data_start, rd_len,
+					&initrd_start, &initrd_end);
+		if (ret) {
+			puts("### Failed to relocate RAM disk\n");
+			goto error;
+		}
+
+		/* Update SPARC kernel header so that Linux knows
+		 * what is going on and where to find RAM disk.
+		 *
+		 * Set INITRD Image address relative to RAM Start
+		 */
+		linux_hdr->hdr_input.ver_0203.sparc_ramdisk_image =
+		    initrd_start - CFG_RAM_BASE;
+		linux_hdr->hdr_input.ver_0203.sparc_ramdisk_size = rd_len;
+		/* Clear READ ONLY flag if set to non-zero */
+		linux_hdr->hdr_input.ver_0203.root_flags = 1;
+		/* Set root device to: Root_RAM0 */
+		linux_hdr->hdr_input.ver_0203.root_dev = 0x100;
+		linux_hdr->hdr_input.ver_0203.ram_flags = 0;
+	} else {
+		/* NOT using RAMDISK image, overwriting kernel defaults */
+		linux_hdr->hdr_input.ver_0203.sparc_ramdisk_image = 0;
+		linux_hdr->hdr_input.ver_0203.sparc_ramdisk_size = 0;
+		/* Leave to kernel defaults
+		   linux_hdr->hdr_input.ver_0203.root_flags = 1;
+		   linux_hdr->hdr_input.ver_0203.root_dev = 0;
+		   linux_hdr->hdr_input.ver_0203.ram_flags = 0;
+		 */
+	}
+
+	/* Copy bootargs from bootargs variable to kernel readable area */
+	bootargs = getenv("bootargs");
+	prepare_bootargs(bootargs);
+
+	if (!images->autostart)
+		return;
+
+	/* turn on mmu & setup context table & page table for process 0 (kernel) */
+	srmmu_init_cpu((unsigned int)kernel);
+
+	/* Enter SPARC Linux kernel
+	 * From now on the only code in u-boot that will be
+	 * executed is the PROM code.
+	 */
+	kernel(kernel_arg_promvec, (void *)ep);
+
+	/* It will never come to this... */
+	while (1) ;
+
+      error:
+	if (images->autostart)
+		do_reset(cmdtp, flag, argc, argv);
+	return;
+}
diff --git a/lib_sparc/cache.c b/lib_sparc/cache.c
new file mode 100644
index 0000000..59d9bbe
--- /dev/null
+++ b/lib_sparc/cache.c
@@ -0,0 +1,33 @@
+/* Sparc cache library
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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/processor.h>
+
+void flush_cache(ulong start_addr, ulong size)
+{
+	/* Flush All Cache */
+	sparc_dcache_flush_all();
+	sparc_icache_flush_all();
+}
diff --git a/lib_sparc/interrupts.c b/lib_sparc/interrupts.c
new file mode 100644
index 0000000..4c73b82
--- /dev/null
+++ b/lib_sparc/interrupts.c
@@ -0,0 +1,122 @@
+/*
+ * (C) Copyright 2000-2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2003
+ * Gleb Natapov <gnatapov@mrv.com>
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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/processor.h>
+#include <asm/irq.h>
+
+/* Implemented by SPARC CPUs */
+extern int interrupt_init_cpu(void);
+extern void timer_interrupt_cpu(void *arg);
+extern int timer_interrupt_init_cpu(void);
+
+int intLock(void)
+{
+	unsigned int pil;
+
+	pil = get_pil();
+
+	/* set PIL to 15 ==> no pending interrupts will interrupt CPU */
+	set_pil(15);
+
+	return pil;
+}
+
+void intUnlock(int oldLevel)
+{
+	set_pil(oldLevel);
+}
+
+void enable_interrupts(void)
+{
+	set_pil(0);		/* enable all interrupts */
+}
+
+int disable_interrupts(void)
+{
+	return intLock();
+}
+
+int interrupt_init(void)
+{
+	int ret;
+
+	/* call cpu specific function from $(CPU)/interrupts.c */
+	ret = interrupt_init_cpu();
+
+	/* enable global interrupts */
+	enable_interrupts();
+
+	return ret;
+}
+
+/* timer interrupt/overflow counter */
+static volatile ulong timestamp = 0;
+
+/* regs can not be used here! regs is actually the pointer given in
+ * irq_install_handler
+ */
+void timer_interrupt(struct pt_regs *regs)
+{
+	/* call cpu specific function from $(CPU)/interrupts.c */
+	timer_interrupt_cpu((void *)regs);
+
+	timestamp++;
+}
+
+void reset_timer(void)
+{
+	timestamp = 0;
+}
+
+ulong get_timer(ulong base)
+{
+	return (timestamp - base);
+}
+
+void set_timer(ulong t)
+{
+	timestamp = t;
+}
+
+void timer_interrupt_init(void)
+{
+	int irq;
+
+	reset_timer();
+
+	irq = timer_interrupt_init_cpu();
+
+	if (irq < 0) {
+		/* cpu specific code handled the interrupt registration it self */
+		return;
+	}
+	/* register interrupt handler for timer */
+	irq_install_handler(irq, (void (*)(void *))timer_interrupt, NULL);
+}
diff --git a/lib_sparc/time.c b/lib_sparc/time.c
new file mode 100644
index 0000000..433f3eb
--- /dev/null
+++ b/lib_sparc/time.c
@@ -0,0 +1,78 @@
+/*
+ * (C) Copyright 2000, 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007
+ * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com.
+ *
+ * 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>
+
+/* Implemented by SPARC CPUs */
+extern void cpu_wait_ticks(unsigned long ticks);
+extern unsigned long cpu_usec2ticks(unsigned long usec);
+extern unsigned long cpu_ticks2usec(unsigned long ticks);
+
+/* ------------------------------------------------------------------------- */
+
+void wait_ticks(unsigned long ticks)
+{
+	cpu_wait_ticks(ticks);
+}
+
+/*
+ * This function is intended for SHORT delays only.
+ */
+unsigned long usec2ticks(unsigned long usec)
+{
+	return cpu_usec2ticks(usec);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * We implement the delay by converting the delay (the number of
+ * microseconds to wait) into a number of time base ticks; then we
+ * watch the time base until it has incremented by that amount.
+ */
+void udelay(unsigned long usec)
+{
+	ulong ticks = usec2ticks(usec);
+
+	wait_ticks(ticks);
+}
+
+/* ------------------------------------------------------------------------- */
+
+unsigned long ticks2usec(unsigned long ticks)
+{
+	return cpu_ticks2usec(ticks);
+}
+
+/* ------------------------------------------------------------------------- */
+
+int init_timebase(void)
+{
+
+	return (0);
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/microblaze_config.mk b/microblaze_config.mk
index 06ddefa..e44c79e 100644
--- a/microblaze_config.mk
+++ b/microblaze_config.mk
@@ -1,6 +1,8 @@
 #
-# (C) Copyright 2004 Atmark Techno, Inc.
+# (C) Copyright 2007-2008 Michal Simek
+# Michal SIMEK <monstr@monstr.eu>
 #
+# (C) Copyright 2004 Atmark Techno, Inc.
 # Yasushi SHOJI <yashi@atmark-techno.com>
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,15 +25,3 @@
 #
 
 PLATFORM_CPPFLAGS += -ffixed-r31 -D__microblaze__
-
-ifdef CONFIG_MICROBLAZE_HARD_MULT
-PLATFORM_CPPFLAGS += -mno-xl-soft-mul
-endif
-
-ifdef CONFIG_MICROBLAZE_HARD_DIV
-PLATFORM_CPPFLAGS += -mno-xl-soft-div
-endif
-
-ifdef CONFIG_MICROBLAZE_HARD_BARREL
-PLATFORM_CPPFLAGS += -mxl-barrel-shift
-endif
diff --git a/sparc_config.mk b/sparc_config.mk
new file mode 100644
index 0000000..87f745f
--- /dev/null
+++ b/sparc_config.mk
@@ -0,0 +1,24 @@
+#
+# (C) Copyright 2007
+# Daniel Hellstrom, Gaisler Research, daniel@gaisler.com
+#
+# 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
+#
+
+PLATFORM_CPPFLAGS += -DCONFIG_SPARC -D__sparc__