Selaa lähdekoodia

Merge branch 'master' of /home/wd/git/u-boot/custodians

Wolfgang Denk 17 vuotta sitten
vanhempi
commit
8c8428a576
100 muutettua tiedostoa jossa 13975 lisäystä ja 99 poistoa
  1. 8 1
      MAKEALL
  2. 36 1
      Makefile
  3. 10 0
      README
  4. 1 1
      board/freescale/mpc837xemds/mpc837xemds.c
  5. 1 1
      board/freescale/mpc837xerdb/mpc837xerdb.c
  6. 52 0
      board/gaisler/gr_cpci_ax2000/Makefile
  7. 37 0
      board/gaisler/gr_cpci_ax2000/config.mk
  8. 39 0
      board/gaisler/gr_cpci_ax2000/gr_cpci_ax2000.c
  9. 160 0
      board/gaisler/gr_cpci_ax2000/u-boot.lds
  10. 52 0
      board/gaisler/gr_ep2s60/Makefile
  11. 35 0
      board/gaisler/gr_ep2s60/config.mk
  12. 39 0
      board/gaisler/gr_ep2s60/gr_ep2s60.c
  13. 160 0
      board/gaisler/gr_ep2s60/u-boot.lds
  14. 52 0
      board/gaisler/gr_xc3s_1500/Makefile
  15. 34 0
      board/gaisler/gr_xc3s_1500/config.mk
  16. 39 0
      board/gaisler/gr_xc3s_1500/gr_xc3s_1500.c
  17. 162 0
      board/gaisler/gr_xc3s_1500/u-boot.lds
  18. 50 0
      board/gaisler/grsim/Makefile
  19. 34 0
      board/gaisler/grsim/config.mk
  20. 43 0
      board/gaisler/grsim/grsim.c
  21. 161 0
      board/gaisler/grsim/u-boot.lds
  22. 50 0
      board/gaisler/grsim_leon2/Makefile
  23. 34 0
      board/gaisler/grsim_leon2/config.mk
  24. 43 0
      board/gaisler/grsim_leon2/grsim_leon2.c
  25. 159 0
      board/gaisler/grsim_leon2/u-boot.lds
  26. 1 16
      board/xilinx/ml401/Makefile
  27. 3 9
      board/xilinx/ml401/xparameters.h
  28. 1 16
      board/xilinx/xupv2p/Makefile
  29. 3 9
      board/xilinx/xupv2p/xparameters.h
  30. 1 0
      common/Makefile
  31. 278 0
      common/cmd_ambapp.c
  32. 39 0
      common/cmd_bdinfo.c
  33. 1 1
      common/image.c
  34. 54 0
      cpu/leon2/Makefile
  35. 26 0
      cpu/leon2/config.mk
  36. 58 0
      cpu/leon2/cpu.c
  37. 142 0
      cpu/leon2/cpu_init.c
  38. 217 0
      cpu/leon2/interrupts.c
  39. 1047 0
      cpu/leon2/prom.c
  40. 165 0
      cpu/leon2/serial.c
  41. 661 0
      cpu/leon2/start.S
  42. 54 0
      cpu/leon3/Makefile
  43. 359 0
      cpu/leon3/ambapp.c
  44. 26 0
      cpu/leon3/config.mk
  45. 67 0
      cpu/leon3/cpu.c
  46. 254 0
      cpu/leon3/cpu_init.c
  47. 219 0
      cpu/leon3/interrupts.c
  48. 1078 0
      cpu/leon3/prom.c
  49. 139 0
      cpu/leon3/serial.c
  50. 616 0
      cpu/leon3/start.S
  51. 1313 0
      cpu/leon3/usb_uhci.c
  52. 184 0
      cpu/leon3/usb_uhci.h
  53. 2 2
      cpu/mpc83xx/spd_sdram.c
  54. 1 1
      cpu/mpc85xx/cpu_init.c
  55. 5 1
      cpu/mpc85xx/mp.c
  56. 1 1
      cpu/mpc85xx/spd_sdram.c
  57. 16 30
      drivers/mtd/cfi_flash.c
  58. 2 0
      drivers/net/Makefile
  59. 462 0
      drivers/net/xilinx_emac.c
  60. 351 0
      drivers/net/xilinx_emaclite.c
  61. 3 0
      examples/Makefile
  62. 61 0
      examples/sparc.lds
  63. 16 0
      examples/stubs.c
  64. 394 0
      include/ambapp.h
  65. 36 0
      include/asm-sparc/arch-leon2/asi.h
  66. 36 0
      include/asm-sparc/arch-leon3/asi.h
  67. 32 0
      include/asm-sparc/asi.h
  68. 45 0
      include/asm-sparc/asmmacro.h
  69. 29 0
      include/asm-sparc/atomic.h
  70. 29 0
      include/asm-sparc/bitops.h
  71. 37 0
      include/asm-sparc/byteorder.h
  72. 31 0
      include/asm-sparc/cache.h
  73. 162 0
      include/asm-sparc/errno.h
  74. 85 0
      include/asm-sparc/global_data.h
  75. 94 0
      include/asm-sparc/io.h
  76. 49 0
      include/asm-sparc/irq.h
  77. 42 0
      include/asm-sparc/leon.h
  78. 236 0
      include/asm-sparc/leon2.h
  79. 37 0
      include/asm-sparc/leon3.h
  80. 92 0
      include/asm-sparc/machines.h
  81. 43 0
      include/asm-sparc/page.h
  82. 139 0
      include/asm-sparc/posix_types.h
  83. 116 0
      include/asm-sparc/processor.h
  84. 297 0
      include/asm-sparc/prom.h
  85. 97 0
      include/asm-sparc/psr.h
  86. 181 0
      include/asm-sparc/ptrace.h
  87. 301 0
      include/asm-sparc/srmmu.h
  88. 162 0
      include/asm-sparc/stack.h
  89. 55 0
      include/asm-sparc/string.h
  90. 71 0
      include/asm-sparc/types.h
  91. 74 0
      include/asm-sparc/u-boot.h
  92. 151 0
      include/asm-sparc/winmacro.h
  93. 1 0
      include/config_cmd_all.h
  94. 1 1
      include/configs/MPC837XEMDS.h
  95. 1 1
      include/configs/MPC837XERDB.h
  96. 5 7
      include/configs/canyonlands.h
  97. 380 0
      include/configs/gr_cpci_ax2000.h
  98. 356 0
      include/configs/gr_ep2s60.h
  99. 321 0
      include/configs/gr_xc3s_1500.h
  100. 340 0
      include/configs/grsim.h

+ 8 - 1
MAKEALL

@@ -645,8 +645,8 @@ LIST_nios2="		\
 #########################################################################
 #########################################################################
 
 
 LIST_microblaze="	\
 LIST_microblaze="	\
-	suzaku		\
 	ml401		\
 	ml401		\
+	suzaku		\
 	xupv2p		\
 	xupv2p		\
 "
 "
 
 
@@ -719,6 +719,12 @@ LIST_sh="		\
 	${LIST_sh4}	\
 	${LIST_sh4}	\
 "
 "
 
 
+#########################################################################
+## SPARC Systems
+#########################################################################
+
+LIST_sparc="gr_xc3s_1500	gr_cpci_ax2000	gr_ep2s60	grsim	grsim_leon2"
+
 #-----------------------------------------------------------------------
 #-----------------------------------------------------------------------
 
 
 #----- for now, just run PPC by default -----
 #----- for now, just run PPC by default -----
@@ -747,6 +753,7 @@ do
 	case "$arg" in
 	case "$arg" in
 	arm|SA|ARM7|ARM9|ARM10|ARM11|ixp|pxa| \
 	arm|SA|ARM7|ARM9|ARM10|ARM11|ixp|pxa| \
 	avr32| \
 	avr32| \
+	sparc| \
 	blackfin| \
 	blackfin| \
 	coldfire| \
 	coldfire| \
 	microblaze| \
 	microblaze| \

+ 36 - 1
Makefile

@@ -165,7 +165,10 @@ CROSS_COMPILE = avr32-linux-
 endif
 endif
 ifeq ($(ARCH),sh)
 ifeq ($(ARCH),sh)
 CROSS_COMPILE = sh4-linux-
 CROSS_COMPILE = sh4-linux-
-endif	# sh
+endif
+ifeq ($(ARCH),sparc)
+CROSS_COMPILE = sparc-elf-
+endif	# sparc
 endif	# HOSTARCH,ARCH
 endif	# HOSTARCH,ARCH
 endif	# CROSS_COMPILE
 endif	# CROSS_COMPILE
 
 
@@ -2880,6 +2883,38 @@ r2dplus_config  :   unconfig
 	@echo "#define CONFIG_R2DPLUS 1" >> include/config.h
 	@echo "#define CONFIG_R2DPLUS 1" >> include/config.h
 	@./mkconfig -a $(@:_config=) sh sh4 r2dplus
 	@./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
+
 #########################################################################
 #########################################################################
 #########################################################################
 #########################################################################
 #########################################################################
 #########################################################################

+ 10 - 0
README

@@ -153,6 +153,8 @@ Directory Hierarchy:
   - at32ap	Files specific to Atmel AVR32 AP CPUs
   - at32ap	Files specific to Atmel AVR32 AP CPUs
   - i386	Files specific to i386 CPUs
   - i386	Files specific to i386 CPUs
   - ixp		Files specific to Intel XScale IXP 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
   - mcf52x2	Files specific to Freescale ColdFire MCF52x2 CPUs
   - mcf5227x	Files specific to Freescale ColdFire MCF5227x CPUs
   - mcf5227x	Files specific to Freescale ColdFire MCF5227x CPUs
   - mcf532x	Files specific to Freescale ColdFire MCF5329 CPUs
   - mcf532x	Files specific to Freescale ColdFire MCF5329 CPUs
@@ -186,6 +188,7 @@ Directory Hierarchy:
 - lib_mips	Files generic to MIPS	 architecture
 - lib_mips	Files generic to MIPS	 architecture
 - lib_nios	Files generic to NIOS	 architecture
 - lib_nios	Files generic to NIOS	 architecture
 - lib_ppc	Files generic to PowerPC architecture
 - lib_ppc	Files generic to PowerPC architecture
+- lib_sparc	Files generic to SPARC	 architecture
 - libfdt	Library files to support flattened device trees
 - libfdt	Library files to support flattened device trees
 - net		Networking code
 - net		Networking code
 - post		Power On Self Test
 - post		Power On Self Test
@@ -2040,6 +2043,13 @@ Configuration Settings:
 		This option also enables the building of the cfi_flash driver
 		This option also enables the building of the cfi_flash driver
 		in the drivers directory
 		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
 - CFG_FLASH_QUIET_TEST
 		If this option is defined, the common CFI flash doesn't
 		If this option is defined, the common CFI flash doesn't
 		print it's warning upon not recognized FLASH banks. This
 		print it's warning upon not recognized FLASH banks. This

+ 1 - 1
board/freescale/mpc837xemds/mpc837xemds.c

@@ -36,7 +36,7 @@ int board_early_init_f(void)
 	u32 spridr = in_be32(&immr->sysconf.spridr);
 	u32 spridr = in_be32(&immr->sysconf.spridr);
 
 
 	/* we check only part num, and don't look for CPU revisions */
 	/* we check only part num, and don't look for CPU revisions */
-	switch (spridr) {
+	switch (PARTID_NO_E(spridr)) {
 	case SPR_8377:
 	case SPR_8377:
 		fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA,
 		fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA,
 				 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
 				 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);

+ 1 - 1
board/freescale/mpc837xerdb/mpc837xerdb.c

@@ -16,10 +16,10 @@
 #include <i2c.h>
 #include <i2c.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/fsl_serdes.h>
 #include <asm/fsl_serdes.h>
+#include <fdt_support.h>
 #include <spd_sdram.h>
 #include <spd_sdram.h>
 #include <vsc7385.h>
 #include <vsc7385.h>
 
 
-
 #if defined(CFG_DRAM_TEST)
 #if defined(CFG_DRAM_TEST)
 int
 int
 testdram(void)
 testdram(void)

+ 52 - 0
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
+
+#########################################################################

+ 37 - 0
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

+ 39 - 0
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;
+}

+ 160 - 0
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) }
+
+}

+ 52 - 0
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
+
+#########################################################################

+ 35 - 0
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

+ 39 - 0
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;
+}

+ 160 - 0
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) }
+
+}

+ 52 - 0
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
+
+#########################################################################

+ 34 - 0
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

+ 39 - 0
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;
+}

+ 162 - 0
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) }
+
+}

+ 50 - 0
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
+
+#########################################################################

+ 34 - 0
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

+ 43 - 0
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;
+}

+ 161 - 0
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) }
+
+}

+ 50 - 0
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
+
+#########################################################################

+ 34 - 0
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

+ 43 - 0
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;
+}

+ 159 - 0
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) }
+
+}

+ 1 - 16
board/xilinx/ml401/Makefile

@@ -22,25 +22,10 @@
 #
 #
 
 
 include $(TOPDIR)/config.mk
 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
 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)
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
 OBJS	:= $(addprefix $(obj),$(COBJS))

+ 3 - 9
board/xilinx/ml401/xparameters.h

@@ -41,8 +41,8 @@
 #define XILINX_TIMER_IRQ	0
 #define XILINX_TIMER_IRQ	0
 
 
 /* Uart pheriphery is RS232_Uart */
 /* 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 */
 /* IIC pheriphery is IIC_EEPROM */
 #define XILINX_IIC_0_BASEADDR	0x40800000
 #define XILINX_IIC_0_BASEADDR	0x40800000
@@ -66,10 +66,4 @@
 #define XILINX_SYSACE_MEM_WIDTH	16
 #define XILINX_SYSACE_MEM_WIDTH	16
 
 
 /* Ethernet controller is Ethernet_MAC */
 /* 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

+ 1 - 16
board/xilinx/xupv2p/Makefile

@@ -22,25 +22,10 @@
 #
 #
 
 
 include $(TOPDIR)/config.mk
 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
 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)
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
 OBJS	:= $(addprefix $(obj),$(COBJS))

+ 3 - 9
board/xilinx/xupv2p/xparameters.h

@@ -37,8 +37,8 @@
 #define XILINX_TIMER_IRQ	1
 #define XILINX_TIMER_IRQ	1
 
 
 /* Uart pheriphery is RS232_Uart_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*/
 /* GPIO is LEDs_4Bit*/
 #define XILINX_GPIO_BASEADDR	0x40000000
 #define XILINX_GPIO_BASEADDR	0x40000000
@@ -55,10 +55,4 @@
 #define XILINX_SYSACE_MEM_WIDTH	16
 #define XILINX_SYSACE_MEM_WIDTH	16
 
 
 /* Ethernet controller is Ethernet_MAC */
 /* 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

+ 1 - 0
common/Makefile

@@ -32,6 +32,7 @@ COBJS-y += ACEX1K.o
 COBJS-y += altera.o
 COBJS-y += altera.o
 COBJS-y += bedbug.o
 COBJS-y += bedbug.o
 COBJS-y += circbuf.o
 COBJS-y += circbuf.o
+COBJS-$(CONFIG_CMD_AMBAPP) += cmd_ambapp.o
 COBJS-y += cmd_autoscript.o
 COBJS-y += cmd_autoscript.o
 COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
 COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
 COBJS-$(CONFIG_CMD_BEDBUG) += cmd_bedbug.o
 COBJS-$(CONFIG_CMD_BEDBUG) += cmd_bedbug.o

+ 278 - 0
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");

+ 39 - 0
common/cmd_bdinfo.c

@@ -208,6 +208,45 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	return 0;
 	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 */
 #elif defined(CONFIG_M68K) /* M68K */
 static void print_str(const char *, const char *);
 static void print_str(const char *, const char *);
 
 

+ 1 - 1
common/image.c

@@ -1014,7 +1014,7 @@ int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
 	return 0;
 	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
  * boot_ramdisk_high - relocate init ramdisk
  * @lmb: pointer to lmb handle, will be used for memory mgmt
  * @lmb: pointer to lmb handle, will be used for memory mgmt

+ 54 - 0
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
+
+#########################################################################

+ 26 - 0
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

+ 58 - 0
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;
+}
+
+/* ------------------------------------------------------------------------- */

+ 142 - 0
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;
+}

+ 217 - 0
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

+ 1047 - 0
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();
+}

+ 165 - 0
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;
+	}
+}

+ 661 - 0
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

+ 54 - 0
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
+
+#########################################################################

+ 359 - 0
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);
+}

+ 26 - 0
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

+ 67 - 0
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);
+}
+
+/* ------------------------------------------------------------------------- */

+ 254 - 0
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;
+}

+ 219 - 0
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

+ 1078 - 0
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();
+}

+ 139 - 0
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;
+}

+ 616 - 0
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

+ 1313 - 0
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 */

+ 184 - 0
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_ */

+ 2 - 2
cpu/mpc83xx/spd_sdram.c

@@ -601,7 +601,7 @@ long int spd_sdram()
 	debug("DDR:timing_cfg_2=0x%08x\n", ddr->timing_cfg_2);
 	debug("DDR:timing_cfg_2=0x%08x\n", ddr->timing_cfg_2);
 
 
 	/* Check DIMM data bus width */
 	/* Check DIMM data bus width */
-	if (spd.dataw_lsb == 0x20) {
+	if (spd.dataw_lsb < 64) {
 		if (spd.mem_type == SPD_MEMTYPE_DDR)
 		if (spd.mem_type == SPD_MEMTYPE_DDR)
 			burstlen = 0x03; /* 32 bit data bus, burst len is 8 */
 			burstlen = 0x03; /* 32 bit data bus, burst len is 8 */
 		else
 		else
@@ -763,7 +763,7 @@ long int spd_sdram()
 		sdram_cfg |= SDRAM_CFG_RD_EN;
 		sdram_cfg |= SDRAM_CFG_RD_EN;
 
 
 	/* The DIMM is 32bit width */
 	/* The DIMM is 32bit width */
-	if (spd.dataw_lsb == 0x20) {
+	if (spd.dataw_lsb < 64) {
 		if (spd.mem_type == SPD_MEMTYPE_DDR)
 		if (spd.mem_type == SPD_MEMTYPE_DDR)
 			sdram_cfg |= SDRAM_CFG_32_BE | SDRAM_CFG_8_BE;
 			sdram_cfg |= SDRAM_CFG_32_BE | SDRAM_CFG_8_BE;
 		if (spd.mem_type == SPD_MEMTYPE_DDR2)
 		if (spd.mem_type == SPD_MEMTYPE_DDR2)

+ 1 - 1
cpu/mpc85xx/cpu_init.c

@@ -272,7 +272,7 @@ int cpu_init_r(void)
 	uint l2srbar;
 	uint l2srbar;
 
 
 	svr = get_svr();
 	svr = get_svr();
-	ver = SVR_VER(svr);
+	ver = SVR_SOC_VER(svr);
 
 
 	asm("msync;isync");
 	asm("msync;isync");
 	cache_ctl = l2cache->l2ctl;
 	cache_ctl = l2cache->l2ctl;

+ 5 - 1
cpu/mpc85xx/mp.c

@@ -154,7 +154,7 @@ static void pq3_mp_up(unsigned long bootpg)
 	while (timeout) {
 	while (timeout) {
 		int i;
 		int i;
 		for (i = 1; i < CONFIG_NR_CPUS; 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);
 				cpu_up_mask |= (1 << i);
 		};
 		};
 
 
@@ -165,6 +165,10 @@ static void pq3_mp_up(unsigned long bootpg)
 		timeout--;
 		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 */
 	/* enable time base at the platform */
 	if (whoami)
 	if (whoami)
 		devdisr |= MPC85xx_DEVDISR_TB1;
 		devdisr |= MPC85xx_DEVDISR_TB1;

+ 1 - 1
cpu/mpc85xx/spd_sdram.c

@@ -306,7 +306,7 @@ spd_sdram(void)
 	 * Adjust DDR II IO voltage biasing.
 	 * Adjust DDR II IO voltage biasing.
 	 * Only 8548 rev 1 needs the fix
 	 * 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) &&
 			(SVR_MJREV(get_svr()) == 1) &&
 			(spd.mem_type == SPD_MEMTYPE_DDR2)) {
 			(spd.mem_type == SPD_MEMTYPE_DDR2)) {
 		volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
 		volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);

+ 16 - 30
drivers/mtd/cfi_flash.c

@@ -844,25 +844,29 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
 	void *dst = map_physmem(dest, len, MAP_NOCACHE);
 	void *dst = map_physmem(dest, len, MAP_NOCACHE);
 	void *dst2 = dst;
 	void *dst2 = dst;
 	int flag = 0;
 	int flag = 0;
+	uint offset = 0;
+	unsigned int shift;
 
 
 	switch (info->portwidth) {
 	switch (info->portwidth) {
 	case FLASH_CFI_8BIT:
 	case FLASH_CFI_8BIT:
-		cnt = len;
+		shift = 0;
 		break;
 		break;
 	case FLASH_CFI_16BIT:
 	case FLASH_CFI_16BIT:
-		cnt = len >> 1;
+		shift = 1;
 		break;
 		break;
 	case FLASH_CFI_32BIT:
 	case FLASH_CFI_32BIT:
-		cnt = len >> 2;
+		shift = 2;
 		break;
 		break;
 	case FLASH_CFI_64BIT:
 	case FLASH_CFI_64BIT:
-		cnt = len >> 3;
+		shift = 3;
 		break;
 		break;
 	default:
 	default:
 		retcode = ERR_INVAL;
 		retcode = ERR_INVAL;
 		goto out_unmap;
 		goto out_unmap;
 	}
 	}
 
 
+	cnt = len >> shift;
+
 	while ((cnt-- > 0) && (flag == 0)) {
 	while ((cnt-- > 0) && (flag == 0)) {
 		switch (info->portwidth) {
 		switch (info->portwidth) {
 		case FLASH_CFI_8BIT:
 		case FLASH_CFI_8BIT:
@@ -906,23 +910,7 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
 		if (retcode == ERR_OK) {
 		if (retcode == ERR_OK) {
 			/* reduce the number of loops by the width of
 			/* reduce the number of loops by the width of
 			 * the port */
 			 * 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);
 			flash_write_cmd (info, sector, 0, (uchar) cnt - 1);
 			while (cnt-- > 0) {
 			while (cnt-- > 0) {
 				switch (info->portwidth) {
 				switch (info->portwidth) {
@@ -959,36 +947,34 @@ static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
 	case CFI_CMDSET_AMD_STANDARD:
 	case CFI_CMDSET_AMD_STANDARD:
 	case CFI_CMDSET_AMD_EXTENDED:
 	case CFI_CMDSET_AMD_EXTENDED:
 		flash_unlock_seq(info,0);
 		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) {
 		switch (info->portwidth) {
 		case FLASH_CFI_8BIT:
 		case FLASH_CFI_8BIT:
-			cnt = len;
-			flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
 			while (cnt-- > 0) {
 			while (cnt-- > 0) {
 				flash_write8(flash_read8(src), dst);
 				flash_write8(flash_read8(src), dst);
 				src += 1, dst += 1;
 				src += 1, dst += 1;
 			}
 			}
 			break;
 			break;
 		case FLASH_CFI_16BIT:
 		case FLASH_CFI_16BIT:
-			cnt = len >> 1;
-			flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
 			while (cnt-- > 0) {
 			while (cnt-- > 0) {
 				flash_write16(flash_read16(src), dst);
 				flash_write16(flash_read16(src), dst);
 				src += 2, dst += 2;
 				src += 2, dst += 2;
 			}
 			}
 			break;
 			break;
 		case FLASH_CFI_32BIT:
 		case FLASH_CFI_32BIT:
-			cnt = len >> 2;
-			flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
 			while (cnt-- > 0) {
 			while (cnt-- > 0) {
 				flash_write32(flash_read32(src), dst);
 				flash_write32(flash_read32(src), dst);
 				src += 4, dst += 4;
 				src += 4, dst += 4;
 			}
 			}
 			break;
 			break;
 		case FLASH_CFI_64BIT:
 		case FLASH_CFI_64BIT:
-			cnt = len >> 3;
-			flash_write_cmd (info, sector, 0,  (uchar) cnt - 1);
 			while (cnt-- > 0) {
 			while (cnt-- > 0) {
 				flash_write64(flash_read64(src), dst);
 				flash_write64(flash_read64(src), dst);
 				src += 8, dst += 8;
 				src += 8, dst += 8;

+ 2 - 0
drivers/net/Makefile

@@ -60,6 +60,8 @@ COBJS-y += tsec.o
 COBJS-y += tsi108_eth.o
 COBJS-y += tsi108_eth.o
 COBJS-y += uli526x.o
 COBJS-y += uli526x.o
 COBJS-y += vsc7385.o
 COBJS-y += vsc7385.o
+COBJS-$(CONFIG_XILINX_EMAC) += xilinx_emac.o
+COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o
 
 
 COBJS	:= $(COBJS-y)
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 SRCS 	:= $(COBJS:.o=.c)

+ 462 - 0
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;
+}

+ 351 - 0
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;
+
+}

+ 3 - 0
examples/Makefile

@@ -69,6 +69,9 @@ ifeq ($(ARCH),sh)
 LOAD_ADDR = 0x8C000000
 LOAD_ADDR = 0x8C000000
 endif
 endif
 
 
+ifeq ($(ARCH),sparc)
+LOAD_ADDR = 0x00000000 -L $(gcclibdir) -T sparc.lds
+endif
 
 
 include $(TOPDIR)/config.mk
 include $(TOPDIR)/config.mk
 
 

+ 61 - 0
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 = .;
+}

+ 16 - 0
examples/stubs.c

@@ -167,6 +167,22 @@ gd_t *global_data;
 		"	nop\n"				\
 		"	nop\n"				\
 		"	nop\n"				\
 		"	nop\n"				\
 		: : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r1");
 		: : "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
 #else
 #error stubs definition missing for this architecture
 #error stubs definition missing for this architecture
 #endif
 #endif

+ 394 - 0
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

+ 36 - 0
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 */

+ 36 - 0
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 */

+ 32 - 0
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 */

+ 45 - 0
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

+ 29 - 0
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_ */

+ 29 - 0
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 */

+ 37 - 0
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 */

+ 31 - 0
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

+ 162 - 0
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

+ 85 - 0
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 */

+ 94 - 0
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

+ 49 - 0
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

+ 42 - 0
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

+ 236 - 0
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

+ 37 - 0
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

+ 92 - 0
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) */

+ 43 - 0
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 */

+ 139 - 0
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 */

+ 116 - 0
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 */

+ 297 - 0
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

+ 97 - 0
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__) */

+ 181 - 0
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) */

+ 301 - 0
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__) */

+ 162 - 0
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

+ 55 - 0
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

+ 71 - 0
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

+ 74 - 0
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__ */

+ 151 - 0
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

+ 1 - 0
include/config_cmd_all.h

@@ -13,6 +13,7 @@
  * Alphabetical list of all possible commands.
  * 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_ASKENV	/* ask for env variable		*/
 #define CONFIG_CMD_AUTOSCRIPT	/* Autoscript Support		*/
 #define CONFIG_CMD_AUTOSCRIPT	/* Autoscript Support		*/
 #define CONFIG_CMD_BDI	       	/* bdinfo			*/
 #define CONFIG_CMD_BDI	       	/* bdinfo			*/

+ 1 - 1
include/configs/MPC837XEMDS.h

@@ -96,7 +96,7 @@
  */
  */
 #define CFG_SCCR_TSEC1CM	1	/* CSB:eTSEC1 = 1:1 */
 #define CFG_SCCR_TSEC1CM	1	/* CSB:eTSEC1 = 1:1 */
 #define CFG_SCCR_TSEC2CM	1	/* CSB:eTSEC2 = 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
  * System IO Config

+ 1 - 1
include/configs/MPC837XERDB.h

@@ -108,7 +108,7 @@
 /* System Clock Configuration Register */
 /* System Clock Configuration Register */
 #define CFG_SCCR_TSEC1CM	1		/* eTSEC1 clock mode (0-3) */
 #define CFG_SCCR_TSEC1CM	1		/* eTSEC1 clock mode (0-3) */
 #define CFG_SCCR_TSEC2CM	1		/* eTSEC2 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
  * System IO Config

+ 5 - 7
include/configs/canyonlands.h

@@ -330,19 +330,17 @@
 		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
 		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
 		":${hostname}:${netdev}:off panic=1\0"			\
 		":${hostname}:${netdev}:off panic=1\0"			\
 	"addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}\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};"				\
 		"tftp ${fdt_addr} ${fdt_file};"				\
 		"run nfsargs addip addtty;"				\
 		"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;"				\
 	"flash_nfs=run nfsargs addip addtty;"				\
 		"bootm ${kernel_addr}\0"				\
 		"bootm ${kernel_addr}\0"				\
 	"flash_self=run ramargs addip addtty;"				\
 	"flash_self=run ramargs addip addtty;"				\
 		"bootm ${kernel_addr} ${ramdisk_addr}\0"		\
 		"bootm ${kernel_addr} ${ramdisk_addr}\0"		\
 	"rootpath=/opt/eldk/ppc_4xxFP\0"				\
 	"rootpath=/opt/eldk/ppc_4xxFP\0"				\
-	"fdt_addr=400000\0"						\
+	"fdt_addr=800000\0"						\
 	"kernel_addr=fc000000\0"					\
 	"kernel_addr=fc000000\0"					\
 	"ramdisk_addr=fc200000\0"					\
 	"ramdisk_addr=fc200000\0"					\
 	"initrd_high=30000000\0"					\
 	"initrd_high=30000000\0"					\
@@ -352,7 +350,7 @@
 		"setenv filesize;saveenv\0"				\
 		"setenv filesize;saveenv\0"				\
 	"upd=run load update\0"						\
 	"upd=run load update\0"						\
 	"nload=tftp 200000 ${hostname}/u-boot-nand.bin\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"				\
 		"setenv filesize;saveenv\0"				\
 	"nupd=run nload nupdate\0"					\
 	"nupd=run nload nupdate\0"					\
 	"pciconfighost=1\0"						\
 	"pciconfighost=1\0"						\

+ 380 - 0
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 */

+ 356 - 0
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 */

+ 321 - 0
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 */

+ 340 - 0
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 */

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä