Browse Source

Merge git://www.denx.de/git/u-boot into uboot

Gerald Van Baren 17 years ago
parent
commit
3596d55eb2
100 changed files with 6950 additions and 2411 deletions
  1. 1337 0
      CHANGELOG
  2. 17 13
      Makefile
  3. 196 81
      README
  4. 11 0
      board/adder/adder.c
  5. 1 1
      board/atum8548/tlb.c
  6. 1 1
      board/bf537-stamp/Makefile
  7. 9 2
      board/cray/L1/L1.c
  8. 52 40
      board/esd/common/auto_update.c
  9. 10 2
      board/freescale/common/Makefile
  10. 0 0
      board/freescale/common/cds_eeprom.c
  11. 0 0
      board/freescale/common/cds_pci_ft.c
  12. 0 0
      board/freescale/common/cds_via.c
  13. 0 0
      board/freescale/mpc7448hpc2/Makefile
  14. 0 0
      board/freescale/mpc7448hpc2/asm_init.S
  15. 0 0
      board/freescale/mpc7448hpc2/config.mk
  16. 0 0
      board/freescale/mpc7448hpc2/mpc7448hpc2.c
  17. 0 0
      board/freescale/mpc7448hpc2/tsi108_init.c
  18. 0 0
      board/freescale/mpc7448hpc2/u-boot.lds
  19. 0 0
      board/freescale/mpc8260ads/Makefile
  20. 0 0
      board/freescale/mpc8260ads/config.mk
  21. 0 0
      board/freescale/mpc8260ads/flash.c
  22. 0 0
      board/freescale/mpc8260ads/mpc8260ads.c
  23. 0 0
      board/freescale/mpc8266ads/Makefile
  24. 0 0
      board/freescale/mpc8266ads/config.mk
  25. 0 0
      board/freescale/mpc8266ads/flash.c
  26. 0 0
      board/freescale/mpc8266ads/mpc8266ads.c
  27. 21 0
      board/freescale/mpc8313erdb/mpc8313erdb.c
  28. 14 1
      board/freescale/mpc8349itx/mpc8349itx.c
  29. 3 1
      board/freescale/mpc8360erdk/Makefile
  30. 17 0
      board/freescale/mpc8360erdk/mpc8360erdk.c
  31. 72 0
      board/freescale/mpc8360erdk/nand.c
  32. 60 5
      board/freescale/mpc837xerdb/mpc837xerdb.c
  33. 1 1
      board/freescale/mpc8540ads/tlb.c
  34. 6 11
      board/freescale/mpc8541cds/Makefile
  35. 1 1
      board/freescale/mpc8541cds/tlb.c
  36. 1 1
      board/freescale/mpc8544ds/tlb.c
  37. 6 11
      board/freescale/mpc8548cds/Makefile
  38. 1 1
      board/freescale/mpc8548cds/tlb.c
  39. 6 11
      board/freescale/mpc8555cds/Makefile
  40. 1 1
      board/freescale/mpc8555cds/tlb.c
  41. 1 1
      board/freescale/mpc8560ads/tlb.c
  42. 0 3
      board/freescale/mpc8568mds/Makefile
  43. 1 1
      board/freescale/mpc8568mds/tlb.c
  44. 0 4
      board/freescale/mpc8610hpcd/Makefile
  45. 6 0
      board/incaip/incaip.c
  46. 6 0
      board/incaip/lowlevel_init.S
  47. 52 38
      board/mcc200/auto_update.c
  48. 1 1
      board/mpc8540eval/tlb.c
  49. 23 23
      board/mpl/common/common_util.c
  50. 1 1
      board/pm854/tlb.c
  51. 1 1
      board/pm856/tlb.c
  52. 9 2
      board/pn62/cmd_pn62.c
  53. 8 0
      board/purple/purple.c
  54. 1 1
      board/sbc8548/tlb.c
  55. 1 1
      board/sbc8560/tlb.c
  56. 27 21
      board/siemens/common/fpga.c
  57. 1 1
      board/stxgp3/tlb.c
  58. 1 1
      board/stxssa/tlb.c
  59. 8 1
      board/tb0229/tb0229.c
  60. 1 1
      board/tqm85xx/tlb.c
  61. 65 49
      board/trab/auto_update.c
  62. 6 1
      common/Makefile
  63. 107 46
      common/cmd_autoscript.c
  64. 603 814
      common/cmd_bootm.c
  65. 31 7
      common/cmd_doc.c
  66. 42 17
      common/cmd_fdc.c
  67. 0 17
      common/cmd_fdt.c
  68. 94 15
      common/cmd_fpga.c
  69. 40 18
      common/cmd_ide.c
  70. 9 2
      common/cmd_load.c
  71. 93 0
      common/cmd_mp.c
  72. 65 15
      common/cmd_nand.c
  73. 9 2
      common/cmd_net.c
  74. 124 643
      common/cmd_sata.c
  75. 34 13
      common/cmd_scsi.c
  76. 70 0
      common/cmd_setexpr.c
  77. 36 17
      common/cmd_usb.c
  78. 107 61
      common/cmd_ximg.c
  79. 25 193
      common/fdt_support.c
  80. 113 0
      common/gunzip.c
  81. 2541 0
      common/image.c
  82. 23 23
      common/lynxkdi.c
  83. 7 4
      common/usb_storage.c
  84. 129 80
      cpu/mips/cache.S
  85. 28 7
      cpu/mips/cpu.c
  86. 29 19
      cpu/mips/start.S
  87. 5 1
      cpu/mpc5xxx/cpu.c
  88. 1 1
      cpu/mpc8260/cpu.c
  89. 13 2
      cpu/mpc83xx/Makefile
  90. 6 0
      cpu/mpc83xx/cpu_init.c
  91. 8 4
      cpu/mpc83xx/fdt.c
  92. 0 2
      cpu/mpc83xx/pci.c
  93. 0 3
      cpu/mpc83xx/qe_io.c
  94. 145 0
      cpu/mpc83xx/serdes.c
  95. 3 0
      cpu/mpc85xx/Makefile
  96. 57 45
      cpu/mpc85xx/cpu.c
  97. 7 3
      cpu/mpc85xx/cpu_init.c
  98. 52 0
      cpu/mpc85xx/fdt.c
  99. 210 0
      cpu/mpc85xx/mp.c
  100. 20 0
      cpu/mpc85xx/mp.h

File diff suppressed because it is too large
+ 1337 - 0
CHANGELOG


+ 17 - 13
Makefile

@@ -339,10 +339,12 @@ $(U_BOOT_NAND):	$(NAND_SPL) $(obj)u-boot.bin $(obj)include/autoconf.mk
 		cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin
 
 $(ONENAND_IPL):	$(VERSION_FILE)	$(obj)include/autoconf.mk
-		$(MAKE) -C onenand_ipl/board/$(BOARDDIR) all
+		$(MAKE) -C $(obj)onenand_ipl/board/$(BOARDDIR) all
 
 $(U_BOOT_ONENAND):	$(ONENAND_IPL) $(obj)u-boot.bin $(obj)include/autoconf.mk
+		$(MAKE) -C $(obj)onenand_ipl/board/$(BOARDDIR) all
 		cat $(obj)onenand_ipl/onenand-ipl-2k.bin $(obj)u-boot.bin > $(obj)u-boot-onenand.bin
+		cat $(obj)onenand_ipl/onenand-ipl-4k.bin $(obj)u-boot.bin > $(obj)u-boot-flexonenand.bin
 
 $(VERSION_FILE):
 		@( echo -n "#define U_BOOT_VERSION \"U-Boot " ; \
@@ -1609,7 +1611,7 @@ PQ2FADS-ZU_66MHz_config	\
 PQ2FADS-ZU_66MHz_lowboot_config	\
 	:		unconfig
 	@mkdir -p $(obj)include
-	@mkdir -p $(obj)board/mpc8260ads
+	@mkdir -p $(obj)board/freescale/mpc8260ads
 	$(if $(findstring PQ2FADS,$@), \
 	@echo "#define CONFIG_ADSTYPE CFG_PQ2FADS" > $(obj)include/config.h, \
 	@echo "#define CONFIG_ADSTYPE CFG_"$(subst MPC,,$(word 1,$(subst _, ,$@))) > $(obj)include/config.h)
@@ -1618,13 +1620,13 @@ PQ2FADS-ZU_66MHz_lowboot_config	\
 	$(if $(findstring VR,$@), \
 	@echo "#define CONFIG_8260_CLKIN 66000000" >> $(obj)include/config.h))
 	@[ -z "$(findstring lowboot_,$@)" ] || \
-		{ echo "TEXT_BASE = 0xFF800000" >$(obj)board/mpc8260ads/config.tmp ; \
+		{ echo "TEXT_BASE = 0xFF800000" >$(obj)board/freescale/mpc8260ads/config.tmp ; \
 		  $(XECHO) "... with lowboot configuration" ; \
 		}
-	@$(MKCONFIG) -a MPC8260ADS ppc mpc8260 mpc8260ads
+	@$(MKCONFIG) -a MPC8260ADS ppc mpc8260 mpc8260ads freescale
 
 MPC8266ADS_config:	unconfig
-	@$(MKCONFIG) $(@:_config=) ppc mpc8260 mpc8266ads
+	@$(MKCONFIG) $(@:_config=) ppc mpc8260 mpc8266ads freescale
 
 # PM825/PM826 default configuration:  small (= 8 MB) Flash / boot from 64-bit flash
 PM825_config	\
@@ -2243,7 +2245,7 @@ EVB64260_750CX_config:	unconfig
 	@$(MKCONFIG) EVB64260 ppc 74xx_7xx evb64260
 
 mpc7448hpc2_config:  unconfig
-	@$(MKCONFIG) $(@:_config=) ppc 74xx_7xx mpc7448hpc2
+	@$(MKCONFIG) $(@:_config=) ppc 74xx_7xx mpc7448hpc2 freescale
 
 P3G4_config: unconfig
 	@$(MKCONFIG) $(@:_config=) ppc 74xx_7xx evb64260
@@ -2470,11 +2472,6 @@ cm4008_config	:	unconfig
 cm41xx_config	:	unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm920t cm41xx NULL ks8695
 
-gth2_config		:	unconfig
-	@mkdir -p $(obj)include
-	@echo "#define CONFIG_GTH2 1" >$(obj)include/config.h
-	@$(MKCONFIG) -a gth2 mips mips gth2
-
 #########################################################################
 ## S3C44B0 Systems
 #########################################################################
@@ -2677,6 +2674,11 @@ pb1000_config		:	unconfig
 	@echo "#define CONFIG_PB1000 1" >$(obj)include/config.h
 	@$(MKCONFIG) -a pb1x00 mips mips pb1x00
 
+gth2_config:	unconfig
+	@mkdir -p $(obj)include
+	@echo "#define CONFIG_GTH2 1" >$(obj)include/config.h
+	@$(MKCONFIG) -a gth2 mips mips gth2
+
 qemu_mips_config: unconfig
 	@mkdir -p $(obj)include
 	@echo "#define CONFIG_QEMU_MIPS 1" >$(obj)include/config.h
@@ -2873,7 +2875,7 @@ clean:
 	       $(obj)board/{integratorap,integratorcp}/u-boot.lds	  \
 	       $(obj)board/{bf533-ezkit,bf533-stamp,bf537-stamp,bf561-ezkit}/u-boot.lds
 	@rm -f $(obj)include/bmp_logo.h $(obj)nand_spl/{u-boot-spl,u-boot-spl.map}
-	@rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl-2k.bin,ipl.map}
+	@rm -f $(obj)onenand_ipl/onenand-{ipl,ipl.bin,ipl-2k.bin,ipl-4k.bin,ipl.map}
 	@rm -f $(obj)api_examples/demo $(VERSION_FILE)
 	@find $(OBJTREE) -type f \
 		\( -name 'core' -o -name '*.bak' -o -name '*~' \
@@ -2888,7 +2890,9 @@ clobber:	clean
 	@rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS \
 		$(obj)cscope.* $(obj)*.*~
 	@rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL)
-	@rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,sha1.c,inca-swap-bytes}
+	@rm -f $(obj)tools/{crc32.c,environment.c,env/crc32.c,md5.c,sha1.c,inca-swap-bytes}
+	@rm -f $(obj)tools/{image.c,fdt.c,fdt_ro.c,fdt_rw.c,fdt_strerror.c}
+	@rm -f $(obj)tools/{fdt_wip.c,libfdt_internal.h}
 	@rm -f $(obj)cpu/mpc824x/bedbug_603e.c
 	@rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
 	@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f

+ 196 - 81
README

@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2000 - 2005
+# (C) Copyright 2000 - 2008
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -51,7 +51,8 @@ Makefile have been tested to some extent and can be considered
 "working". In fact, many of them are used in production systems.
 
 In case of problems see the CHANGELOG and CREDITS files to find out
-who contributed the specific port.
+who contributed the specific port. The MAINTAINERS file lists board
+maintainers.
 
 
 Where to get help:
@@ -65,6 +66,22 @@ before asking FAQ's. Please see
 http://lists.sourceforge.net/lists/listinfo/u-boot-users/
 
 
+Where to get source code:
+=========================
+
+The U-Boot source code is maintained in the git repository at
+git://www.denx.de/git/u-boot.git ; you can browse it online at
+http://www.denx.de/cgi-bin/gitweb.cgi?p=u-boot.git;a=summary
+
+The "snapshot" links on this page allow you to download tarballs of
+any version you might be interested in. Ofifcial releases are also
+available for FTP download from the ftp://ftp.denx.de/pub/u-boot/
+directory.
+
+Pre-built (and tested) images are available from
+ftp://ftp.denx.de/pub/u-boot/images/
+
+
 Where we come from:
 ===================
 
@@ -81,6 +98,7 @@ Where we come from:
 - create ARMBoot project (http://sourceforge.net/projects/armboot)
 - add other CPU families (starting with ARM)
 - create U-Boot project (http://sourceforge.net/projects/u-boot)
+- current project page: see http://www.denx.de/wiki/UBoot
 
 
 Names and Spelling:
@@ -168,7 +186,7 @@ Directory Hierarchy:
 - lib_mips	Files generic to MIPS	 architecture
 - lib_nios	Files generic to NIOS	 architecture
 - lib_ppc	Files generic to PowerPC architecture
-- libfdt 	Library files to support flattened device trees
+- libfdt	Library files to support flattened device trees
 - net		Networking code
 - post		Power On Self Test
 - rtc		Real Time Clock drivers
@@ -320,7 +338,7 @@ The following options need to be configured:
 		converts clock data to MHZ before passing it to the
 		Linux kernel.
 		When CONFIG_CLOCKS_IN_MHZ is defined, a definition of
-		"clocks_in_mhz=1" is  automatically  included  in  the
+		"clocks_in_mhz=1" is automatically included in the
 		default environment.
 
 		CONFIG_MEMSIZE_IN_BYTES		[relevant for MIPS only]
@@ -671,6 +689,7 @@ The following options need to be configured:
 		CONFIG_RTC_DS164x	- use Dallas DS164x RTC
 		CONFIG_RTC_ISL1208	- use Intersil ISL1208 RTC
 		CONFIG_RTC_MAX6900	- use Maxim, Inc. MAX6900 RTC
+		CFG_RTC_DS1337_NOOSC	- Turn off the OSC output for DS1337
 
 		Note that if the RTC uses I2C, then the I2C interface
 		must also be configured. See I2C Support, below.
@@ -686,9 +705,9 @@ The following options need to be configured:
 		CONFIG_MAC_PARTITION and/or CONFIG_DOS_PARTITION
 		and/or CONFIG_ISO_PARTITION
 
-		If IDE or SCSI support	is  enabled  (CONFIG_CMD_IDE or
-		CONFIG_CMD_SCSI) you must configure support for at least
-		one partition type as well.
+		If IDE or SCSI support is enabled (CONFIG_CMD_IDE or
+		CONFIG_CMD_SCSI) you must configure support for at
+		least one partition type as well.
 
 - IDE Reset method:
 		CONFIG_IDE_RESET_ROUTINE - this is defined in several
@@ -1325,7 +1344,7 @@ The following options need to be configured:
 		This option specifies a list of I2C devices that will be skipped
 		when the 'i2c probe' command is issued (or 'iprobe' using the legacy
 		command).  If CONFIG_I2C_MULTI_BUS is set, specify a list of bus-device
-		pairs.  Otherwise, specify a 1D array of device addresses
+		pairs.	Otherwise, specify a 1D array of device addresses
 
 		e.g.
 			#undef	CONFIG_I2C_MULTI_BUS
@@ -1660,6 +1679,8 @@ The following options need to be configured:
 		example, some LED's) on your board. At the moment,
 		the following checkpoints are implemented:
 
+Legacy uImage format:
+
   Arg	Where			When
     1	common/cmd_bootm.c	before attempting to boot an image
    -1	common/cmd_bootm.c	Image header has bad	 magic number
@@ -1670,25 +1691,26 @@ The following options need to be configured:
     4	common/cmd_bootm.c	Image data   has correct checksum
    -4	common/cmd_bootm.c	Image is for unsupported architecture
     5	common/cmd_bootm.c	Architecture check OK
-   -5	common/cmd_bootm.c	Wrong Image Type (not kernel, multi, standalone)
+   -5	common/cmd_bootm.c	Wrong Image Type (not kernel, multi)
     6	common/cmd_bootm.c	Image Type check OK
    -6	common/cmd_bootm.c	gunzip uncompression error
    -7	common/cmd_bootm.c	Unimplemented compression type
     7	common/cmd_bootm.c	Uncompression OK
-   -8	common/cmd_bootm.c	Wrong Image Type (not kernel, multi, standalone)
-    8	common/cmd_bootm.c	Image Type check OK
+    8	common/cmd_bootm.c	No uncompress/copy overwrite error
    -9	common/cmd_bootm.c	Unsupported OS (not Linux, BSD, VxWorks, QNX)
-    9	common/cmd_bootm.c	Start initial ramdisk verification
-  -10	common/cmd_bootm.c	Ramdisk header has bad	   magic number
-  -11	common/cmd_bootm.c	Ramdisk header has bad	   checksum
-   10	common/cmd_bootm.c	Ramdisk header is OK
-  -12	common/cmd_bootm.c	Ramdisk data   has bad	   checksum
-   11	common/cmd_bootm.c	Ramdisk data   has correct checksum
-   12	common/cmd_bootm.c	Ramdisk verification complete, start loading
-  -13	common/cmd_bootm.c	Wrong Image Type (not PPC Linux Ramdisk)
-   13	common/cmd_bootm.c	Start multifile image verification
-   14	common/cmd_bootm.c	No initial ramdisk, no multifile, continue.
-   15	common/cmd_bootm.c	All preparation done, transferring control to OS
+
+    9	common/image.c		Start initial ramdisk verification
+  -10	common/image.c		Ramdisk header has bad	   magic number
+  -11	common/image.c		Ramdisk header has bad	   checksum
+   10	common/image.c		Ramdisk header is OK
+  -12	common/image.c		Ramdisk data   has bad	   checksum
+   11	common/image.c		Ramdisk data   has correct checksum
+   12	common/image.c		Ramdisk verification complete, start loading
+  -13	common/image.c		Wrong Image Type (not PPC Linux Ramdisk)
+   13	common/image.c		Start multifile image verification
+   14	common/image.c		No initial ramdisk, no multifile, continue.
+
+   15	lib_<arch>/bootm.c	All preparation done, transferring control to OS
 
   -30	lib_ppc/board.c		Fatal error, hang the system
   -31	post/post.c		POST test failed, detected by post_output_backlog()
@@ -1758,6 +1780,59 @@ The following options need to be configured:
   -83	common/cmd_net.c	some error in automatic boot or autoscript
    84	common/cmd_net.c	end without errors
 
+FIT uImage format:
+
+  Arg	Where			When
+  100	common/cmd_bootm.c	Kernel FIT Image has correct format
+ -100	common/cmd_bootm.c	Kernel FIT Image has incorrect format
+  101	common/cmd_bootm.c	No Kernel subimage unit name, using configuration
+ -101	common/cmd_bootm.c	Can't get configuration for kernel subimage
+  102	common/cmd_bootm.c	Kernel unit name specified
+ -103	common/cmd_bootm.c	Can't get kernel subimage node offset
+  103	common/cmd_bootm.c	Found configuration node
+  104	common/cmd_bootm.c	Got kernel subimage node offset
+ -104	common/cmd_bootm.c	Kernel subimage hash verification failed
+  105	common/cmd_bootm.c	Kernel subimage hash verification OK
+ -105	common/cmd_bootm.c	Kernel subimage is for unsupported architecture
+  106	common/cmd_bootm.c	Architecture check OK
+ -106	common/cmd_bootm.c	Kernel subimage has wrong typea
+  107	common/cmd_bootm.c	Kernel subimge type OK
+ -107	common/cmd_bootm.c	Can't get kernel subimage data/size
+  108	common/cmd_bootm.c	Got kernel subimage data/size
+ -108	common/cmd_bootm.c	Wrong image type (not legacy, FIT)
+ -109	common/cmd_bootm.c	Can't get kernel subimage type
+ -110	common/cmd_bootm.c	Can't get kernel subimage comp
+ -111	common/cmd_bootm.c	Can't get kernel subimage os
+ -112	common/cmd_bootm.c	Can't get kernel subimage load address
+ -113	common/cmd_bootm.c	Image uncompress/copy overwrite error
+
+  120	common/image.c		Start initial ramdisk verification
+ -120	common/image.c		Ramdisk FIT image has incorrect format
+  121	common/image.c		Ramdisk FIT image has correct format
+  122	common/image.c		No Ramdisk subimage unit name, using configuration
+ -122	common/image.c		Can't get configuration for ramdisk subimage
+  123	common/image.c		Ramdisk unit name specified
+ -124	common/image.c		Can't get ramdisk subimage node offset
+  125	common/image.c		Got ramdisk subimage node offset
+ -125	common/image.c		Ramdisk subimage hash verification failed
+  126	common/image.c		Ramdisk subimage hash verification OK
+ -126	common/image.c		Ramdisk subimage for unsupported architecture
+  127	common/image.c		Architecture check OK
+ -127	common/image.c		Can't get ramdisk subimage data/size
+  128	common/image.c		Got ramdisk subimage data/size
+  129	common/image.c		Can't get ramdisk load address
+ -129	common/image.c		Got ramdisk load address
+
+ -130	common/cmd_doc.c	Icorrect FIT image format
+  131	common/cmd_doc.c	FIT image format OK
+
+ -140	common/cmd_ide.c	Icorrect FIT image format
+  141	common/cmd_ide.c	FIT image format OK
+
+ -150	common/cmd_nand.c	Icorrect FIT image format
+  151	common/cmd_nand.c	FIT image format OK
+
+
 Modem Support:
 --------------
 
@@ -1946,6 +2021,11 @@ Configuration Settings:
 		is useful, if some of the configured banks are only
 		optionally available.
 
+- CONFIG_FLASH_SHOW_PROGRESS
+		If defined (must be an integer), print out countdown
+		digits and dots.  Recommended value: 45 (9..1) for 80
+		column displays, 15 (3..1) for 40 column displays.
+
 - CFG_RX_ETH_BUFFER:
 		Defines the number of ethernet receive buffers. On some
 		ethernet controllers it is recommended to set this value
@@ -2319,22 +2399,24 @@ Low Level (hardware related) configuration options:
 		Overrides the default PCI memory map in cpu/mpc8260/pci.c if set.
 
 - CONFIG_SPD_EEPROM
-		Get DDR timing information from an I2C EEPROM.  Common with pluggable
-		memory modules such as SODIMMs
+		Get DDR timing information from an I2C EEPROM. Common
+		with pluggable memory modules such as SODIMMs
+
   SPD_EEPROM_ADDRESS
 		I2C address of the SPD EEPROM
 
 - CFG_SPD_BUS_NUM
-		If SPD EEPROM is on an I2C bus other than the first one, specify here.
-		Note that the value must resolve to something your driver can deal with.
+		If SPD EEPROM is on an I2C bus other than the first
+		one, specify here. Note that the value must resolve
+		to something your driver can deal with.
 
 - CFG_83XX_DDR_USES_CS0
-		Only for 83xx systems. If specified, then DDR should be configured
-		using CS0 and CS1 instead of CS2 and CS3.
+		Only for 83xx systems. If specified, then DDR should
+		be configured using CS0 and CS1 instead of CS2 and CS3.
 
 - CFG_83XX_DDR_USES_CS0
-		Only for 83xx systems. If specified, then DDR should be configured
-		using CS0 and CS1 instead of CS2 and CS3.
+		Only for 83xx systems. If specified, then DDR should
+		be configured using CS0 and CS1 instead of CS2 and CS3.
 
 - CONFIG_ETHER_ON_FEC[12]
 		Define to enable FEC[12] on a 8xx series processor.
@@ -2400,29 +2482,30 @@ Low Level (hardware related) configuration options:
 Building the Software:
 ======================
 
-Building U-Boot has been tested in native PPC environments (on a
-PowerBook G3 running LinuxPPC 2000) and in cross environments
-(running RedHat 6.x and 7.x Linux on x86, Solaris 2.6 on a SPARC, and
-NetBSD 1.5 on x86).
-
-If you are not using a native PPC environment, it is assumed that you
-have the GNU cross compiling tools available in your path and named
-with a prefix of "powerpc-linux-". If this is not the case, (e.g. if
-you are using Monta Vista's Hard Hat Linux CDK 1.2) you must change
-the definition of CROSS_COMPILE in Makefile. For HHL on a 4xx CPU,
-change it to:
+Building U-Boot has been tested in several native build environments
+and in many different cross environments. Of course we cannot support
+all possibly existing versions of cross development tools in all
+(potentially obsolete) versions. In case of tool chain problems we
+recommend to use the ELDK (see http://www.denx.de/wiki/DULG/ELDK)
+which is extensively used to build and test U-Boot.
 
-	CROSS_COMPILE = ppc_4xx-
+If you are not using a native environment, it is assumed that you
+have GNU cross compiling tools available in your path. In this case,
+you must set the environment variable CROSS_COMPILE in your shell.
+Note that no changes to the Makefile or any other source files are
+necessary. For example using the ELDK on a 4xx CPU, please enter:
 
+	$ CROSS_COMPILE=ppc_4xx-
+	$ export CROSS_COMPILE
 
-U-Boot is intended to be  simple  to  build.  After  installing	 the
-sources	 you must configure U-Boot for one specific board type. This
+U-Boot is intended to be simple to build. After installing the
+sources you must configure U-Boot for one specific board type. This
 is done by typing:
 
 	make NAME_config
 
-where "NAME_config" is the name of one of the existing
-configurations; see the main Makefile for supported names.
+where "NAME_config" is the name of one of the existing configu-
+rations; see the main Makefile for supported names.
 
 Note: for some board special configuration names may exist; check if
       additional information is available from the board vendor; for
@@ -2498,20 +2581,20 @@ steps:
 Testing of U-Boot Modifications, Ports to New Hardware, etc.:
 ==============================================================
 
-If you have modified U-Boot sources (for instance added a new	board
-or  support  for  new  devices,	 a new CPU, etc.) you are expected to
+If you have modified U-Boot sources (for instance added a new board
+or support for new devices, a new CPU, etc.) you are expected to
 provide feedback to the other developers. The feedback normally takes
 the form of a "patch", i. e. a context diff against a certain (latest
-official or latest in CVS) version of U-Boot sources.
+official or latest in the git repository) version of U-Boot sources.
 
-But before you submit such a patch, please verify that	your  modifi-
-cation	did not break existing code. At least make sure that *ALL* of
+But before you submit such a patch, please verify that your modifi-
+cation did not break existing code. At least make sure that *ALL* of
 the supported boards compile WITHOUT ANY compiler warnings. To do so,
 just run the "MAKEALL" script, which will configure and build U-Boot
-for ALL supported system. Be warned, this will take a while. You  can
-select	which  (cross)	compiler  to use by passing a `CROSS_COMPILE'
-environment variable to the script, i. e. to use the cross tools from
-MontaVista's Hard Hat Linux you can type
+for ALL supported system. Be warned, this will take a while. You can
+select which (cross) compiler to use by passing a `CROSS_COMPILE'
+environment variable to the script, i. e. to use the ELDK cross tools
+you can type
 
 	CROSS_COMPILE=ppc_8xx- MAKEALL
 
@@ -2519,20 +2602,21 @@ or to build on a native PowerPC system you can type
 
 	CROSS_COMPILE=' ' MAKEALL
 
-When using the MAKEALL script, the default behaviour is to build U-Boot
-in the source directory. This location can be changed by setting the
-BUILD_DIR environment variable. Also, for each target built, the MAKEALL
-script saves two log files (<target>.ERR and <target>.MAKEALL) in the
-<source dir>/LOG directory. This default location can be changed by
-setting the MAKEALL_LOGDIR environment variable. For example:
+When using the MAKEALL script, the default behaviour is to build
+U-Boot in the source directory. This location can be changed by
+setting the BUILD_DIR environment variable. Also, for each target
+built, the MAKEALL script saves two log files (<target>.ERR and
+<target>.MAKEALL) in the <source dir>/LOG directory. This default
+location can be changed by setting the MAKEALL_LOGDIR environment
+variable. For example:
 
 	export BUILD_DIR=/tmp/build
 	export MAKEALL_LOGDIR=/tmp/log
 	CROSS_COMPILE=ppc_8xx- MAKEALL
 
-With the above settings build objects are saved in the /tmp/build, log
-files are saved in the /tmp/log and the source tree remains clean during
-the whole build process.
+With the above settings build objects are saved in the /tmp/build,
+log files are saved in the /tmp/log and the source tree remains clean
+during the whole build process.
 
 
 See also "U-Boot Porting Guide" below.
@@ -2629,6 +2713,14 @@ Some configuration options can be set using Environment Variables:
 		  configuration from the BOOTP server, but not try to
 		  load any image using TFTP
 
+  autoscript	- if set to "yes" commands like "loadb", "loady",
+		  "bootp", "tftpb", "rarpboot" and "nfs" will attempt
+		  to automatically run script images (by internally
+		  calling "autoscript").
+
+  autoscript_uname - if script image is in a format (FIT) this
+		     variable is used to get script subimage unit name.
+
   autostart	- if set to "yes", an image loaded using the "bootp",
 		  "rarpboot", "tftpboot" or "diskboot" commands will
 		  be automatically started (by internally calling
@@ -2843,10 +2935,24 @@ o If neither SROM nor the environment contain a MAC address, an error
 Image Formats:
 ==============
 
-The "boot" commands of this monitor operate on "image" files which
-can be basicly anything, preceeded by a special header; see the
-definitions in include/image.h for details; basicly, the header
-defines the following image properties:
+U-Boot is capable of booting (and performing other auxiliary operations on)
+images in two formats:
+
+New uImage format (FIT)
+-----------------------
+
+Flexible and powerful format based on Flattened Image Tree -- FIT (similar
+to Flattened Device Tree). It allows the use of images with multiple
+components (several kernels, ramdisks, etc.), with contents protected by
+SHA1, MD5 or CRC32. More details are found in the doc/uImage.FIT directory.
+
+
+Old uImage format
+-----------------
+
+Old image format is based on binary files which can be basically anything,
+preceded by a special header; see the definitions in include/image.h for
+details; basically, the header defines the following image properties:
 
 * Target Operating System (Provisions for OpenBSD, NetBSD, FreeBSD,
   4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks,
@@ -3088,7 +3194,7 @@ TQM8xxL is in the first Flash bank):
 
 
 You can check the success of the download using the 'iminfo' command;
-this includes a checksum verification so you  can  be  sure  no	 data
+this includes a checksum verification so you can be sure no data
 corruption happened:
 
 	=> imi 40100000
@@ -3433,7 +3539,7 @@ models provide on-chip memory (like the IMMR area on MPC8xx and
 MPC826x processors), on others (parts of) the data cache can be
 locked as (mis-) used as memory, etc.
 
-	Chris Hallinan posted a good summary of	 these	issues	to  the
+	Chris Hallinan posted a good summary of these issues to the
 	u-boot-users mailing list:
 
 	Subject: RE: [U-Boot-Users] RE: More On Memory Bank x (nothingness)?
@@ -3723,6 +3829,8 @@ may be rejected, even when they contain important and valuable stuff.
 
 Patches shall be sent to the u-boot-users mailing list.
 
+Please see http://www.denx.de/wiki/UBoot/Patches for details.
+
 When you send a patch, please include the following information with
 it:
 
@@ -3743,18 +3851,23 @@ it:
 * If your patch adds new configuration options, don't forget to
   document these in the README file.
 
-* The patch itself. If you are accessing the CVS repository use "cvs
-  update; cvs diff -puRN"; else, use "diff -purN OLD NEW". If your
-  version of diff does not support these options, then get the latest
-  version of GNU diff.
+* The patch itself. If you are using git (which is *strongly*
+  recommended) you can easily generate the patch using the
+  "git-format-patch". If you then use "git-send-email" to send it to
+  the U-Boot mailing list, you will avoid most of the common problems
+  with some other mail clients.
+
+  If you cannot use git, use "diff -purN OLD NEW". If your version of
+  diff does not support these options, then get the latest version of
+  GNU diff.
 
-  The current directory when running this command shall be the top
-  level directory of the U-Boot source tree, or it's parent directory
-  (i. e. please make sure that your patch includes sufficient
-  directory information for the affected files).
+  The current directory when running this command shall be the parent
+  directory of the U-Boot source tree (i. e. please make sure that
+  your patch includes sufficient directory information for the
+  affected files).
 
-  We accept patches as plain text, MIME attachments or as uuencoded
-  gzipped text.
+  We prefer patches as plain text. MIME attachments are discouraged,
+  and compressed attachments must not be used.
 
 * If one logical set of modifications affects or creates several
   files, all these changes shall be submitted in a SINGLE patch file.
@@ -3781,4 +3894,6 @@ Notes:
   modification.
 
 * Remember that there is a size limit of 40 kB per message on the
-  u-boot-users mailing list. Compression may help.
+  u-boot-users mailing list. Bigger patches will be moderated. If
+  they are reasonable and not bigger than 100 kB, they will be
+  acknowledged. Even bigger patches should be avoided.

+ 11 - 0
board/adder/adder.c

@@ -26,6 +26,9 @@
 
 #include <common.h>
 #include <mpc8xx.h>
+#if defined(CONFIG_OF_LIBFDT)
+	#include <libfdt.h>
+#endif
 
 /*
  * SDRAM is single Samsung K4S643232F-T70   chip (8MB)
@@ -111,3 +114,11 @@ int checkboard( void )
 
 	return 0;
 }
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+void ft_board_setup(void *blob, bd_t *bd)
+{
+	ft_cpu_setup(blob, bd);
+
+}
+#endif

+ 1 - 1
board/atum8548/tlb.c

@@ -82,7 +82,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe210_0000	1M	PCI2 IO
 	 * 0xe300_0000	1M	PCIe IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 5, BOOKE_PAGESZ_64M, 1),
 };

+ 1 - 1
board/bf537-stamp/Makefile

@@ -29,7 +29,7 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	:= $(BOARD).o ether_bf537.o post-memory.o stm_m25p64.o cmd_bf537led.o nand.o
+COBJS	:= $(BOARD).o post-memory.o stm_m25p64.o cmd_bf537led.o nand.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))

+ 9 - 2
board/cray/L1/L1.c

@@ -139,8 +139,15 @@ int misc_init_r (void)
 	struct rtc_time tm;
 	char bootcmd[32];
 
-	hdr = (image_header_t *) (CFG_MONITOR_BASE - sizeof (image_header_t));
-	timestamp = (time_t) hdr->ih_time;
+	hdr = (image_header_t *) (CFG_MONITOR_BASE - image_get_header_size ());
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
+
+	timestamp = (time_t)image_get_time (hdr);
 	to_tm (timestamp, &tm);
 	printf ("Welcome to U-Boot on Cray L1. Compiled %4d-%02d-%02d  %2d:%02d:%02d (UTC)\n", tm.tm_year, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
 

+ 52 - 40
board/esd/common/auto_update.c

@@ -89,24 +89,28 @@ extern block_dev_desc_t ide_dev_desc[CFG_IDE_MAXDEVICE];
 int au_check_cksum_valid(int i, long nbytes)
 {
 	image_header_t *hdr;
-	unsigned long checksum;
 
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
 
-	if ((au_image[i].type == AU_FIRMWARE) && (au_image[i].size != ntohl(hdr->ih_size))) {
+	if ((au_image[i].type == AU_FIRMWARE) &&
+	    (au_image[i].size != image_get_data_size (hdr))) {
 		printf ("Image %s has wrong size\n", au_image[i].name);
 		return -1;
 	}
 
-	if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) {
+	if (nbytes != (image_get_image_size (hdr))) {
 		printf ("Image %s bad total SIZE\n", au_image[i].name);
 		return -1;
 	}
-	/* check the data CRC */
-	checksum = ntohl(hdr->ih_dcrc);
 
-	if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size))
-		!= checksum) {
+	/* check the data CRC */
+	if (!image_check_dcrc (hdr)) {
 		printf ("Image %s bad data checksum\n", au_image[i].name);
 		return -1;
 	}
@@ -120,51 +124,53 @@ int au_check_header_valid(int i, long nbytes)
 	unsigned long checksum;
 
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
+
 	/* check the easy ones first */
 #undef CHECK_VALID_DEBUG
 #ifdef CHECK_VALID_DEBUG
-	printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC);
-	printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_PPC);
-	printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes);
-	printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL);
+	printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC);
+	printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_PPC);
+	printf("size %#x %#lx ", image_get_data_size (hdr), nbytes);
+	printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL);
 #endif
-	if (nbytes < sizeof(*hdr))
+	if (nbytes < image_get_header_size ())
 	{
 		printf ("Image %s bad header SIZE\n", au_image[i].name);
 		return -1;
 	}
-	if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC)
+	if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC))
 	{
 		printf ("Image %s bad MAGIC or ARCH\n", au_image[i].name);
 		return -1;
 	}
-	/* check the hdr CRC */
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
-
-	if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
+	if (!image_check_hcrc (hdr)) {
 		printf ("Image %s bad header checksum\n", au_image[i].name);
 		return -1;
 	}
-	hdr->ih_hcrc = htonl(checksum);
 
 	/* check the type - could do this all in one gigantic if() */
-	if ((au_image[i].type == AU_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
+	if ((au_image[i].type == AU_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) {
 		printf ("Image %s wrong type\n", au_image[i].name);
 		return -1;
 	}
-	if ((au_image[i].type == AU_SCRIPT) && (hdr->ih_type != IH_TYPE_SCRIPT)) {
+	if ((au_image[i].type == AU_SCRIPT) && !image_check_type (hdr, IH_TYPE_SCRIPT)) {
 		printf ("Image %s wrong type\n", au_image[i].name);
 		return -1;
 	}
 
 	/* recycle checksum */
-	checksum = ntohl(hdr->ih_size);
+	checksum = image_get_data_size (hdr);
 
 #if 0 /* test-only */
 	/* for kernel and app the image header must also fit into flash */
 	if (idx != IDX_DISK)
-		checksum += sizeof(*hdr);
+		checksum += image_get_header_size ();
 	/* check the size does not exceed space in flash. HUSH scripts */
 	/* all have ausize[] set to 0 */
 	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
@@ -190,17 +196,23 @@ int au_do_update(int i, long sz)
 #endif
 
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
 
 	switch (au_image[i].type) {
 	case AU_SCRIPT:
 		printf("Executing script %s\n", au_image[i].name);
 
 		/* execute a script */
-		if (hdr->ih_type == IH_TYPE_SCRIPT) {
-			addr = (char *)((char *)hdr + sizeof(*hdr));
+		if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
+			addr = (char *)((char *)hdr + image_get_header_size ());
 			/* stick a NULL at the end of the script, otherwise */
 			/* parse_string_outer() runs off the end. */
-			addr[ntohl(hdr->ih_size)] = 0;
+			addr[image_get_data_size (hdr)] = 0;
 			addr += 8;
 
 			/*
@@ -231,8 +243,8 @@ int au_do_update(int i, long sz)
 		 */
 		if (au_image[i].type == AU_FIRMWARE) {
 			char *orig = (char*)start;
-			char *new  = (char *)((char *)hdr + sizeof(*hdr));
-			nbytes = ntohl(hdr->ih_size);
+			char *new  = (char *)((char *)hdr + image_get_header_size ());
+			nbytes = image_get_data_size (hdr);
 
 			while(--nbytes) {
 				if (*orig++ != *new++) {
@@ -272,12 +284,12 @@ int au_do_update(int i, long sz)
 		/* strip the header - except for the kernel and ramdisk */
 		if (au_image[i].type != AU_FIRMWARE) {
 			addr = (char *)hdr;
-			off = sizeof(*hdr);
-			nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);
+			off = image_get_header_size ();
+			nbytes = image_get_image_size (hdr);
 		} else {
-			addr = (char *)((char *)hdr + sizeof(*hdr));
+			addr = (char *)((char *)hdr + image_get_header_size ());
 			off = 0;
-			nbytes = ntohl(hdr->ih_size);
+			nbytes = image_get_data_size (hdr);
 		}
 
 		/*
@@ -305,15 +317,15 @@ int au_do_update(int i, long sz)
 		 * check the dcrc of the copy
 		 */
 		if (au_image[i].type != AU_NAND) {
-			rc = crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size));
+			rc = crc32 (0, (uchar *)(start + off), image_get_data_size (hdr));
 		} else {
 #if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
 			rc = nand_legacy_rw(nand_dev_desc, NANDRW_READ | NANDRW_JFFS2 | NANDRW_JFFS2_SKIP,
 				     start, nbytes, (size_t *)&total, (uchar *)addr);
-			rc = crc32 (0, (uchar *)(addr + off), ntohl(hdr->ih_size));
+			rc = crc32 (0, (uchar *)(addr + off), image_get_data_size (hdr));
 #endif
 		}
-		if (rc != ntohl(hdr->ih_dcrc)) {
+		if (rc != image_get_dcrc (hdr)) {
 			printf ("Image %s Bad Data Checksum After COPY\n", au_image[i].name);
 			return -1;
 		}
@@ -497,10 +509,10 @@ int do_auto_update(void)
 
 		printf("Reading %s ...", au_image[i].name);
 		/* just read the header */
-		sz = do_fat_read(au_image[i].name, LOAD_ADDR, sizeof(image_header_t), LS_NO);
+		sz = do_fat_read(au_image[i].name, LOAD_ADDR, image_get_header_size (), LS_NO);
 		debug ("read %s sz %ld hdr %d\n",
-			au_image[i].name, sz, sizeof(image_header_t));
-		if (sz <= 0 || sz < sizeof(image_header_t)) {
+			au_image[i].name, sz, image_get_header_size ());
+		if (sz <= 0 || sz < image_get_header_size ()) {
 			puts(" not found\n");
 			continue;
 		}
@@ -510,8 +522,8 @@ int do_auto_update(void)
 		}
 		sz = do_fat_read(au_image[i].name, LOAD_ADDR, MAX_LOADSZ, LS_NO);
 		debug ("read %s sz %ld hdr %d\n",
-			au_image[i].name, sz, sizeof(image_header_t));
-		if (sz <= 0 || sz <= sizeof(image_header_t)) {
+			au_image[i].name, sz, image_get_header_size ());
+		if (sz <= 0 || sz <= image_get_header_size ()) {
 			puts(" not found\n");
 			continue;
 		}

+ 10 - 2
board/freescale/common/Makefile

@@ -29,10 +29,18 @@ endif
 
 LIB	= $(obj)lib$(VENDOR).a
 
-COBJS-${CONFIG_PQ_MDS_PIB}	+= pq-mds-pib.o
-COBJS-${CONFIG_ID_EEPROM}	+= sys_eeprom.o
+COBJS-${CONFIG_FSL_CADMUS}	+= cadmus.o
+COBJS-${CONFIG_FSL_CDS_EEPROM}	+= cds_eeprom.o
+COBJS-${CONFIG_FSL_VIA}		+= cds_via.o
 COBJS-${CONFIG_FSL_DIU_FB}	+= fsl_diu_fb.o fsl_logo_bmp.o
 COBJS-${CONFIG_FSL_PIXIS}	+= pixis.o
+COBJS-${CONFIG_PQ_MDS_PIB}	+= pq-mds-pib.o
+COBJS-${CONFIG_ID_EEPROM}	+= sys_eeprom.o
+
+COBJS-${CONFIG_MPC8541CDS}	+= cds_pci_ft.o
+COBJS-${CONFIG_MPC8548CDS}	+= cds_pci_ft.o
+COBJS-${CONFIG_MPC8555CDS}	+= cds_pci_ft.o
+
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS-y))

+ 0 - 0
board/freescale/common/eeprom.c → board/freescale/common/cds_eeprom.c


+ 0 - 0
board/freescale/common/ft_board.c → board/freescale/common/cds_pci_ft.c


+ 0 - 0
board/freescale/common/via.c → board/freescale/common/cds_via.c


+ 0 - 0
board/mpc7448hpc2/Makefile → board/freescale/mpc7448hpc2/Makefile


+ 0 - 0
board/mpc7448hpc2/asm_init.S → board/freescale/mpc7448hpc2/asm_init.S


+ 0 - 0
board/mpc7448hpc2/config.mk → board/freescale/mpc7448hpc2/config.mk


+ 0 - 0
board/mpc7448hpc2/mpc7448hpc2.c → board/freescale/mpc7448hpc2/mpc7448hpc2.c


+ 0 - 0
board/mpc7448hpc2/tsi108_init.c → board/freescale/mpc7448hpc2/tsi108_init.c


+ 0 - 0
board/mpc7448hpc2/u-boot.lds → board/freescale/mpc7448hpc2/u-boot.lds


+ 0 - 0
board/mpc8260ads/Makefile → board/freescale/mpc8260ads/Makefile


+ 0 - 0
board/mpc8260ads/config.mk → board/freescale/mpc8260ads/config.mk


+ 0 - 0
board/mpc8260ads/flash.c → board/freescale/mpc8260ads/flash.c


+ 0 - 0
board/mpc8260ads/mpc8260ads.c → board/freescale/mpc8260ads/mpc8260ads.c


+ 0 - 0
board/mpc8266ads/Makefile → board/freescale/mpc8266ads/Makefile


+ 0 - 0
board/mpc8266ads/config.mk → board/freescale/mpc8266ads/config.mk


+ 0 - 0
board/mpc8266ads/flash.c → board/freescale/mpc8266ads/flash.c


+ 0 - 0
board/mpc8266ads/mpc8266ads.c → board/freescale/mpc8266ads/mpc8266ads.c


+ 21 - 0
board/freescale/mpc8313erdb/mpc8313erdb.c

@@ -28,6 +28,7 @@
 #endif
 #include <pci.h>
 #include <mpc83xx.h>
+#include <vsc7385.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -98,6 +99,26 @@ void pci_init_board(void)
 	mpc83xx_pci_init(1, reg, warmboot);
 }
 
+/*
+ * Miscellaneous late-boot configurations
+ *
+ * If a VSC7385 microcode image is present, then upload it.
+*/
+int misc_init_r(void)
+{
+	int rc = 0;
+
+#ifdef CONFIG_VSC7385_IMAGE
+	if (vsc7385_upload_firmware((void *) CONFIG_VSC7385_IMAGE,
+		CONFIG_VSC7385_IMAGE_SIZE)) {
+		puts("Failure uploading VSC7385 microcode.\n");
+		rc = 1;
+	}
+#endif
+
+	return rc;
+}
+
 #if defined(CONFIG_OF_BOARD_SETUP)
 void ft_board_setup(void *blob, bd_t *bd)
 {

+ 14 - 1
board/freescale/mpc8349itx/mpc8349itx.c

@@ -25,6 +25,7 @@
 #include <mpc83xx.h>
 #include <i2c.h>
 #include <miiphy.h>
+#include <vsc7385.h>
 #ifdef CONFIG_PCI
 #include <asm/mpc8349_pci.h>
 #include <pci.h>
@@ -177,7 +178,7 @@ int checkboard(void)
  */
 int misc_init_f(void)
 {
-#ifdef CONFIG_VSC7385
+#ifdef CONFIG_VSC7385_ENET
 	volatile u32 *vsc7385_cpuctrl;
 
 	/* 0x1c0c0 is the VSC7385 CPU Control (CPUCTRL) Register.  The power up
@@ -239,6 +240,8 @@ int misc_init_f(void)
 }
 
 /*
+ * Miscellaneous late-boot configurations
+ *
  * Make sure the EEPROM has the HRCW correctly programmed.
  * Make sure the RTC is correctly programmed.
  *
@@ -250,6 +253,8 @@ int misc_init_f(void)
  *
  * This function makes sure that the I2C EEPROM is programmed
  * correctly.
+ *
+ * If a VSC7385 microcode image is present, then upload it.
  */
 int misc_init_r(void)
 {
@@ -375,6 +380,14 @@ int misc_init_r(void)
 	i2c_set_bus_num(orig_bus);
 #endif
 
+#ifdef CONFIG_VSC7385_IMAGE
+	if (vsc7385_upload_firmware((void *) CONFIG_VSC7385_IMAGE,
+		CONFIG_VSC7385_IMAGE_SIZE)) {
+		puts("Failure uploading VSC7385 microcode.\n");
+		rc = 1;
+	}
+#endif
+
 	return rc;
 }
 

+ 3 - 1
board/freescale/mpc8360erdk/Makefile

@@ -25,8 +25,10 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	:= $(BOARD).o
+COBJS-y += $(BOARD).o
+COBJS-$(CONFIG_CMD_NAND) += nand.o
 
+COBJS	:= $(COBJS-y)
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
 SOBJS	:= $(addprefix $(obj),$(SOBJS))

+ 17 - 0
board/freescale/mpc8360erdk/mpc8360erdk.c

@@ -186,6 +186,23 @@ const qe_iop_conf_t qe_iop_conf_tab[] = {
 	{1,  7, 1, 0, 0}, /* LVDS_BKLT_CTR */
 	{2, 16, 1, 0, 0}, /* LVDS_BKLT_EN */
 
+	/* AD7843 ADC/Touchscreen controller */
+	{4, 14, 1, 0, 0}, /* SPI_nCS0 */
+	{4, 28, 3, 0, 3}, /* SPI_MOSI */
+	{4, 29, 3, 0, 3}, /* SPI_MISO */
+	{4, 30, 3, 0, 3}, /* SPI_CLK */
+
+	/* Freescale QUICC Engine USB Host Controller (FHCI) */
+	{1,  2, 1, 0, 3}, /* USBOE */
+	{1,  3, 1, 0, 3}, /* USBTP */
+	{1,  8, 1, 0, 1}, /* USBTN */
+	{1,  9, 2, 1, 3}, /* USBRP */
+	{1, 10, 2, 0, 3}, /* USBRXD */
+	{1, 11, 2, 1, 3}, /* USBRN */
+	{2, 20, 2, 0, 1}, /* CLK21 */
+	{4, 20, 1, 0, 0}, /* SPEED */
+	{4, 21, 1, 0, 0}, /* SUSPND */
+
 	/* END of table */
 	{0,  0, 0, 0, QE_IOP_TAB_END},
 };

+ 72 - 0
board/freescale/mpc8360erdk/nand.c

@@ -0,0 +1,72 @@
+/*
+ * MPC8360E-RDK support for the NAND on FSL UPM
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *                    Anton Vorontsov <avorontsov@ru.mvista.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.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/immap_83xx.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/fsl_upm.h>
+#include <nand.h>
+
+static struct immap *im = (struct immap *)CFG_IMMR;
+
+static const u32 upm_array[] = {
+	0x0ff03c30, 0x0ff03c30, 0x0ff03c34, 0x0ff33c30, /* Words  0 to  3 */
+	0xfff33c31, 0xfffffc30, 0xfffffc30, 0xfffffc30, /* Words  4 to  7 */
+	0x0faf3c30, 0x0faf3c30, 0x0faf3c30, 0x0fff3c34, /* Words  8 to 11 */
+	0xffff3c31, 0xfffffc30, 0xfffffc30, 0xfffffc30, /* Words 12 to 15 */
+	0x0fa3fc30, 0x0fa3fc30, 0x0fa3fc30, 0x0ff3fc34, /* Words 16 to 19 */
+	0xfff3fc31, 0xfffffc30, 0xfffffc30, 0xfffffc30, /* Words 20 to 23 */
+	0x0ff33c30, 0x0fa33c30, 0x0fa33c34, 0x0ff33c30, /* Words 24 to 27 */
+	0xfff33c31, 0xfff0fc30, 0xfff0fc30, 0xfff0fc30, /* Words 28 to 31 */
+	0xfff3fc30, 0xfff3fc30, 0xfff6fc30, 0xfffcfc30, /* Words 32 to 35 */
+	0xfffcfc30, 0xfffcfc30, 0xfffcfc30, 0xfffcfc30, /* Words 36 to 39 */
+	0xfffcfc30, 0xfffcfc30, 0xfffcfc30, 0xfffcfc30, /* Words 40 to 43 */
+	0xfffdfc30, 0xfffffc30, 0xfffffc30, 0xfffffc31, /* Words 44 to 47 */
+	0xfffffc30, 0xfffffc00, 0xfffffc00, 0xfffffc00, /* Words 48 to 51 */
+	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, /* Words 52 to 55 */
+	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, /* Words 56 to 59 */
+	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, /* Words 60 to 63 */
+};
+
+static int dev_ready(void)
+{
+	if (in_be32(&im->qepio.ioport[4].pdat) & 0x00002000) {
+		debug("nand ready\n");
+		return 1;
+	}
+
+	debug("nand busy\n");
+	return 0;
+}
+
+static struct fsl_upm_nand fun = {
+	.upm = {
+		.array = upm_array,
+		.io_addr = (void *)CFG_NAND_BASE,
+	},
+	.width = 1,
+	.upm_cmd_offset = 8,
+	.upm_addr_offset = 16,
+	.dev_ready = dev_ready,
+	.wait_pattern = 1,
+	.chip_delay = 50,
+};
+
+int board_nand_init(struct nand_chip *nand)
+{
+	fun.upm.mxmr = &im->lbus.mamr;
+	fun.upm.mdr = &im->lbus.mdr;
+	fun.upm.mar = &im->lbus.mar;
+	return fsl_upm_nand_init(nand, &fun);
+}

+ 60 - 5
board/freescale/mpc837xerdb/mpc837xerdb.c

@@ -15,7 +15,10 @@
 #include <common.h>
 #include <i2c.h>
 #include <asm/io.h>
+#include <asm/fsl_serdes.h>
 #include <spd_sdram.h>
+#include <vsc7385.h>
+
 
 #if defined(CFG_DRAM_TEST)
 int
@@ -56,11 +59,6 @@ testdram(void)
 }
 #endif
 
-int board_early_init_f(void)
-{
-	return 0;
-}
-
 #if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRC)
 void ddr_enable_ecc(unsigned int dram_size);
 #endif
@@ -135,6 +133,62 @@ int checkboard(void)
 	return 0;
 }
 
+int board_early_init_f(void)
+{
+#ifdef CONFIG_FSL_SERDES
+	immap_t *immr = (immap_t *)CFG_IMMR;
+	u32 spridr = in_be32(&immr->sysconf.spridr);
+
+	/* we check only part num, and don't look for CPU revisions */
+	switch (spridr >> 16) {
+	case SPR_8379E_REV10 >> 16:
+	case SPR_8379_REV10 >> 16:
+		fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA,
+				 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
+		fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_SATA,
+				 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
+		break;
+	case SPR_8378E_REV10 >> 16:
+	case SPR_8378_REV10 >> 16:
+		fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX,
+				 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
+		break;
+	case SPR_8377E_REV10 >> 16:
+	case SPR_8377_REV10 >> 16:
+		fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_SATA,
+				 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
+		fsl_setup_serdes(CONFIG_FSL_SERDES2, FSL_SERDES_PROTO_PEX,
+				 FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
+		break;
+	default:
+		printf("serdes not configured: unknown CPU part number: "
+		       "%04x\n", spridr >> 16);
+		break;
+	}
+#endif /* CONFIG_FSL_SERDES */
+	return 0;
+}
+
+/*
+ * Miscellaneous late-boot configurations
+ *
+ * If a VSC7385 microcode image is present, then upload it.
+*/
+int misc_init_r(void)
+{
+	int rc = 0;
+
+#ifdef CONFIG_VSC7385_IMAGE
+	if (vsc7385_upload_firmware((void *) CONFIG_VSC7385_IMAGE,
+		CONFIG_VSC7385_IMAGE_SIZE)) {
+		puts("Failure uploading VSC7385 microcode.\n");
+		rc = 1;
+	}
+#endif
+
+	return rc;
+}
+
 #if defined(CONFIG_OF_BOARD_SETUP)
 
 void ft_board_setup(void *blob, bd_t *bd)
@@ -143,5 +197,6 @@ void ft_board_setup(void *blob, bd_t *bd)
 	ft_pci_setup(blob, bd);
 #endif
 	ft_cpu_setup(blob, bd);
+	fdt_fixup_dr_usb(blob, bd);
 }
 #endif /* CONFIG_OF_BOARD_SETUP */

+ 1 - 1
board/freescale/mpc8540ads/tlb.c

@@ -87,7 +87,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe000_0000	1M	CCSRBAR
 	 * 0xe200_0000	16M	PCI1 IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 5, BOOKE_PAGESZ_64M, 1),
 

+ 6 - 11
board/freescale/mpc8541cds/Makefile

@@ -23,21 +23,16 @@
 #
 
 include $(TOPDIR)/config.mk
-ifneq ($(OBJTREE),$(SRCTREE))
-$(shell mkdir -p $(obj)../common)
-endif
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	:= $(BOARD).o law.o tlb.o \
-	   ../common/cadmus.o \
-	   ../common/eeprom.o \
-	   ../common/ft_board.o \
-	   ../common/via.o
+COBJS-y	+= $(BOARD).o
+COBJS-y	+= law.o
+COBJS-y	+= tlb.o
 
-SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(COBJS))
-SOBJS	:= $(addprefix $(obj),$(SOBJS))
+SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS-y))
+SOBJS	:= $(addprefix $(obj),$(SOBJS-y))
 
 $(LIB):	$(obj).depend $(OBJS) $(SOBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 1 - 1
board/freescale/mpc8541cds/tlb.c

@@ -88,7 +88,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe200_0000	16M	PCI1 IO
 	 * 0xe300_0000	16M	PCI2 IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 5, BOOKE_PAGESZ_64M, 1),
 

+ 1 - 1
board/freescale/mpc8544ds/tlb.c

@@ -75,7 +75,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe000_0000	1M	CCSRBAR
 	 * 0xe100_0000	255M	PCI IO range
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 4, BOOKE_PAGESZ_64M, 1),
 

+ 6 - 11
board/freescale/mpc8548cds/Makefile

@@ -23,21 +23,16 @@
 #
 
 include $(TOPDIR)/config.mk
-ifneq ($(OBJTREE),$(SRCTREE))
-$(shell mkdir -p $(obj)../common)
-endif
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	:= $(BOARD).o law.o tlb.o \
-	   ../common/cadmus.o \
-	   ../common/eeprom.o \
-	   ../common/ft_board.o \
-	   ../common/via.o
+COBJS-y	+= $(BOARD).o
+COBJS-y	+= law.o
+COBJS-y	+= tlb.o
 
-SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(COBJS))
-SOBJS	:= $(addprefix $(obj),$(SOBJS))
+SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS-y))
+SOBJS	:= $(addprefix $(obj),$(SOBJS-y))
 
 $(LIB):	$(obj).depend $(OBJS) $(SOBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 1 - 1
board/freescale/mpc8548cds/tlb.c

@@ -80,7 +80,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe210_0000	1M	PCI2 IO
 	 * 0xe300_0000	1M	PCIe IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 5, BOOKE_PAGESZ_64M, 1),
 

+ 6 - 11
board/freescale/mpc8555cds/Makefile

@@ -23,21 +23,16 @@
 #
 
 include $(TOPDIR)/config.mk
-ifneq ($(OBJTREE),$(SRCTREE))
-$(shell mkdir -p $(obj)../common)
-endif
 
 LIB	= $(obj)lib$(BOARD).a
 
-COBJS	:= $(BOARD).o law.o tlb.o \
-	   ../common/cadmus.o \
-	   ../common/eeprom.o \
-	   ../common/ft_board.o \
-	   ../common/via.o
+COBJS-y	+= $(BOARD).o
+COBJS-y	+= law.o
+COBJS-y	+= tlb.o
 
-SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(COBJS))
-SOBJS	:= $(addprefix $(obj),$(SOBJS))
+SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS-y))
+SOBJS	:= $(addprefix $(obj),$(SOBJS-y))
 
 $(LIB):	$(obj).depend $(OBJS) $(SOBJS)
 	$(AR) $(ARFLAGS) $@ $(OBJS)

+ 1 - 1
board/freescale/mpc8555cds/tlb.c

@@ -88,7 +88,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe200_0000	16M	PCI1 IO
 	 * 0xe300_0000	16M	PCI2 IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 5, BOOKE_PAGESZ_64M, 1),
 

+ 1 - 1
board/freescale/mpc8560ads/tlb.c

@@ -87,7 +87,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe000_0000	1M	CCSRBAR
 	 * 0xe200_0000	16M	PCI1 IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 5, BOOKE_PAGESZ_64M, 1),
 

+ 0 - 3
board/freescale/mpc8568mds/Makefile

@@ -23,9 +23,6 @@
 #
 
 include $(TOPDIR)/config.mk
-ifneq ($(OBJTREE),$(SRCTREE))
-$(shell mkdir -p $(obj)../common)
-endif
 
 LIB	= $(obj)lib$(BOARD).a
 

+ 1 - 1
board/freescale/mpc8568mds/tlb.c

@@ -74,7 +74,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe200_0000	8M	PCI1 IO
 	 * 0xe280_0000	8M	PCIe IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 3, BOOKE_PAGESZ_64M, 1),
 

+ 0 - 4
board/freescale/mpc8610hpcd/Makefile

@@ -21,10 +21,6 @@
 
 include $(TOPDIR)/config.mk
 
-ifneq ($(OBJTREE),$(SRCTREE))
-$(shell mkdir -p $(obj)../common)
-endif
-
 LIB	= $(obj)lib$(BOARD).a
 
 COBJS	:= $(BOARD).o law.o

+ 6 - 0
board/incaip/incaip.c

@@ -26,9 +26,15 @@
 #include <asm/addrspace.h>
 #include <asm/inca-ip.h>
 #include <asm/io.h>
+#include <asm/reboot.h>
 
 extern uint incaip_get_cpuclk(void);
 
+void _machine_restart(void)
+{
+	*INCA_IP_WDT_RST_REQ = 0x3f;
+}
+
 static ulong max_sdram_size(void)
 {
 	/* The only supported SDRAM data width is 16bit.

+ 6 - 0
board/incaip/lowlevel_init.S

@@ -276,6 +276,12 @@ __sdram_init:
 	.ent	lowlevel_init
 lowlevel_init:
 
+	/* Disable Watchdog.
+	 */
+	la	t9, disable_incaip_wdt
+	jalr	t9
+	nop
+
 	/* EBU, CGU and SDRAM Initialization.
 	 */
 	li	a0, CPU_CLOCK_RATE

+ 52 - 38
board/mcc200/auto_update.c

@@ -141,18 +141,21 @@ extern void lcd_enable(void);
 int au_check_cksum_valid(int idx, long nbytes)
 {
 	image_header_t *hdr;
-	unsigned long checksum;
 
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
 
-	if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) {
+	if (nbytes != image_get_image_size (hdr)) {
 		printf ("Image %s bad total SIZE\n", aufile[idx]);
 		return -1;
 	}
 	/* check the data CRC */
-	checksum = ntohl(hdr->ih_dcrc);
-
-	if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) != checksum) {
+	if (!image_check_dcrc (hdr)) {
 		printf ("Image %s bad data checksum\n", aufile[idx]);
 		return -1;
 	}
@@ -165,59 +168,62 @@ int au_check_header_valid(int idx, long nbytes)
 	unsigned long checksum, fsize;
 
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
+
 	/* check the easy ones first */
 #undef CHECK_VALID_DEBUG
 #ifdef CHECK_VALID_DEBUG
-	printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC);
-	printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_ARM);
-	printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes);
-	printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL);
+	printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC);
+	printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_ARM);
+	printf("size %#x %#lx ", image_get_data_size (hdr), nbytes);
+	printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL);
 #endif
-	if (nbytes < sizeof(*hdr)) {
+	if (nbytes < image_get_header_size ()) {
 		printf ("Image %s bad header SIZE\n", aufile[idx]);
 		ausize[idx] = 0;
 		return -1;
 	}
-	if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_PPC) {
+	if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC)) {
 		printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]);
 		ausize[idx] = 0;
 		return -1;
 	}
 	/* check the hdr CRC */
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
-
-	if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
+	if (!image_check_hcrc (hdr)) {
 		printf ("Image %s bad header checksum\n", aufile[idx]);
 		ausize[idx] = 0;
 		return -1;
 	}
-	hdr->ih_hcrc = htonl(checksum);
 	/* check the type - could do this all in one gigantic if() */
-	if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
+	if ((idx == IDX_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		ausize[idx] = 0;
 		return -1;
 	}
-	if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) {
+	if ((idx == IDX_KERNEL) && !image_check_type (hdr, IH_TYPE_KERNEL)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		ausize[idx] = 0;
 		return -1;
 	}
 	if ((idx == IDX_ROOTFS) &&
-		( (hdr->ih_type != IH_TYPE_RAMDISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM) )
-	   ) {
+			(!image_check_type (hdr, IH_TYPE_RAMDISK) &&
+			!image_check_type (hdr, IH_TYPE_FILESYSTEM))) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		ausize[idx] = 0;
 		return -1;
 	}
 	/* recycle checksum */
-	checksum = ntohl(hdr->ih_size);
+	checksum = image_get_data_size (hdr);
 
-	fsize = checksum + sizeof(*hdr);
+	fsize = checksum + image_get_header_size ();
 	/* for kernel and ramdisk the image header must also fit into flash */
-	if (idx == IDX_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK)
-		checksum += sizeof(*hdr);
+	if (idx == IDX_KERNEL || image_check_type (hdr, IH_TYPE_RAMDISK))
+		checksum += image_get_header_size ();
 
 	/* check the size does not exceed space in flash. HUSH scripts */
 	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
@@ -240,13 +246,19 @@ int au_do_update(int idx, long sz)
 	uint nbytes;
 
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
 
 	/* execute a script */
-	if (hdr->ih_type == IH_TYPE_SCRIPT) {
-		addr = (char *)((char *)hdr + sizeof(*hdr));
+	if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
+		addr = (char *)((char *)hdr + image_get_header_size ());
 		/* stick a NULL at the end of the script, otherwise */
 		/* parse_string_outer() runs off the end. */
-		addr[ntohl(hdr->ih_size)] = 0;
+		addr[image_get_data_size (hdr)] = 0;
 		addr += 8;
 		parse_string_outer(addr, FLAG_PARSE_SEMICOLON);
 		return 0;
@@ -278,19 +290,20 @@ int au_do_update(int idx, long sz)
 #endif
 
 	/* strip the header - except for the kernel and ramdisk */
-	if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) {
+	if (image_check_type (hdr, IH_TYPE_KERNEL) ||
+			image_check_type (hdr, IH_TYPE_RAMDISK)) {
 		addr = (char *)hdr;
-		off = sizeof(*hdr);
-		nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);
+		off = image_get_header_size ();
+		nbytes = image_get_image_size (hdr);
 	} else {
-		addr = (char *)((char *)hdr + sizeof(*hdr));
+		addr = (char *)((char *)hdr + image_get_header_size ());
 #ifdef AU_UPDATE_TEST
 		/* copy it to where Linux goes */
 		if (idx == IDX_FIRMWARE)
 			start = aufl_layout[1].start;
 #endif
 		off = 0;
-		nbytes = ntohl(hdr->ih_size);
+		nbytes = image_get_data_size (hdr);
 	}
 
 	/* copy the data from RAM to FLASH */
@@ -306,7 +319,8 @@ int au_do_update(int idx, long sz)
 #endif
 
 	/* check the data CRC of the copy */
-	if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) {
+	if (crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)) !=
+	    image_get_dcrc (hdr)) {
 		printf ("Image %s Bad Data Checksum after COPY\n", aufile[idx]);
 		return -1;
 	}
@@ -442,10 +456,10 @@ int do_auto_update(void)
 	for (i = 0; i < AU_MAXFILES; i++) {
 		ulong imsize;
 		/* just read the header */
-		sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t));
+		sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ());
 		debug ("read %s sz %ld hdr %d\n",
-			aufile[i], sz, sizeof(image_header_t));
-		if (sz <= 0 || sz < sizeof(image_header_t)) {
+			aufile[i], sz, image_get_header_size ());
+		if (sz <= 0 || sz < image_get_header_size ()) {
 			debug ("%s not found\n", aufile[i]);
 			ausize[i] = 0;
 			continue;
@@ -474,14 +488,14 @@ int do_auto_update(void)
 		sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]);
 
 		debug ("read %s sz %ld hdr %d\n",
-			aufile[i], sz, sizeof(image_header_t));
+			aufile[i], sz, image_get_header_size ());
 
 		if (sz != ausize[i]) {
 			printf ("%s: size %d read %d?\n", aufile[i], ausize[i], sz);
 			continue;
 		}
 
-		if (sz <= 0 || sz <= sizeof(image_header_t)) {
+		if (sz <= 0 || sz <= image_get_header_size ()) {
 			debug ("%s not found\n", aufile[i]);
 			continue;
 		}

+ 1 - 1
board/mpc8540eval/tlb.c

@@ -27,7 +27,7 @@
 #include <asm/mmu.h>
 
 struct fsl_e_tlb_entry tlb_table[] = {
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 1, BOOKE_PAGESZ_1M, 1),
 

+ 23 - 23
board/mpl/common/common_util.c

@@ -57,9 +57,6 @@ extern int mem_test(ulong start, ulong ramsize, int quiet);
 
 extern flash_info_t flash_info[];	/* info for FLASH chips */
 
-static image_header_t header;
-
-
 static int
 mpl_prg(uchar *src, ulong size)
 {
@@ -77,7 +74,7 @@ mpl_prg(uchar *src, ulong size)
 	info = &flash_info[0];
 
 #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)
-	if (ntohl(magic[0]) != IH_MAGIC) {
+	if (uimage_to_cpu (magic[0]) != IH_MAGIC) {
 		puts("Bad Magic number\n");
 		return -1;
 	}
@@ -179,44 +176,46 @@ mpl_prg(uchar *src, ulong size)
 static int
 mpl_prg_image(uchar *ld_addr)
 {
-	unsigned long len, checksum;
+	unsigned long len;
 	uchar *data;
-	image_header_t *hdr = &header;
+	image_header_t *hdr = (image_header_t *)ld_addr;
 	int rc;
 
-	/* Copy header so we can blank CRC field for re-calculation */
-	memcpy (&header, (char *)ld_addr, sizeof(image_header_t));
-	if (ntohl(hdr->ih_magic)  != IH_MAGIC) {
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
+
+	if (!image_check_magic (hdr)) {
 		puts("Bad Magic Number\n");
 		return 1;
 	}
-	print_image_hdr(hdr);
-	if (hdr->ih_os  != IH_OS_U_BOOT) {
+	image_print_contents (hdr);
+	if (!image_check_os (hdr, IH_OS_U_BOOT)) {
 		puts("No U-Boot Image\n");
 		return 1;
 	}
-	if (hdr->ih_type  != IH_TYPE_FIRMWARE) {
+	if (!image_check_type (hdr, IH_TYPE_FIRMWARE)) {
 		puts("No Firmware Image\n");
 		return 1;
 	}
-	data = (uchar *)&header;
-	len  = sizeof(image_header_t);
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
-	if (crc32 (0, (uchar *)data, len) != checksum) {
+	if (!image_check_hcrc (hdr)) {
 		puts("Bad Header Checksum\n");
 		return 1;
 	}
-	data = ld_addr + sizeof(image_header_t);
-	len  = ntohl(hdr->ih_size);
 	puts("Verifying Checksum ... ");
-	if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {
+	if (!image_check_dcrc (hdr)) {
 		puts("Bad Data CRC\n");
 		return 1;
 	}
 	puts("OK\n");
 
-	if (hdr->ih_comp != IH_COMP_NONE) {
+	data = (uchar *)image_get_data (hdr);
+	len = image_get_data_size (hdr);
+
+	if (image_get_comp (hdr) != IH_COMP_NONE) {
 		uchar *buf;
 		/* reserve space for uncompressed image */
 		if ((buf = malloc(IMAGE_SIZE)) == NULL) {
@@ -224,7 +223,7 @@ mpl_prg_image(uchar *ld_addr)
 			return 1;
 		}
 
-		switch (hdr->ih_comp) {
+		switch (image_get_comp (hdr)) {
 		case IH_COMP_GZIP:
 			puts("Uncompressing (GZIP) ... ");
 			rc = gunzip ((void *)(buf), IMAGE_SIZE, data, &len);
@@ -253,7 +252,8 @@ mpl_prg_image(uchar *ld_addr)
 			break;
 #endif
 		default:
-			printf ("Unimplemented compression type %d\n", hdr->ih_comp);
+			printf ("Unimplemented compression type %d\n",
+				image_get_comp (hdr));
 			free(buf);
 			return 1;
 		}

+ 1 - 1
board/pm854/tlb.c

@@ -87,7 +87,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe000_0000	1M	CCSRBAR
 	 * 0xe200_0000	16M	PCI1 IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 5, BOOKE_PAGESZ_64M, 1),
 

+ 1 - 1
board/pm856/tlb.c

@@ -87,7 +87,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe000_0000	1M	CCSRBAR
 	 * 0xe200_0000	16M	PCI1 IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 5, BOOKE_PAGESZ_64M, 1),
 

+ 9 - 2
board/pn62/cmd_pn62.c

@@ -157,8 +157,15 @@ int do_loadpci (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	char *s;
 
 	if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
-	    printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
-	    rcode = autoscript (bd, load_addr);
+		printf ("Running autoscript at addr 0x%08lX", load_addr);
+
+		s = getenv ("autoscript_uname");
+		if (s)
+			printf (":%s ...\n", s);
+		else
+			puts (" ...\n");
+
+		rcode = autoscript (load_addr, s);
 	}
     }
 #endif

+ 8 - 0
board/purple/purple.c

@@ -29,6 +29,7 @@
 #include <asm/io.h>
 #include <asm/addrspace.h>
 #include <asm/cacheops.h>
+#include <asm/reboot.h>
 
 #include "sconsole.h"
 
@@ -52,6 +53,13 @@ extern int	asc_serial_getc 	(void);
 extern int	asc_serial_tstc 	(void);
 extern void	asc_serial_setbrg 	(void);
 
+void _machine_restart(void)
+{
+	void (*f)(void) = (void *) 0xbfc00000;
+
+	f();
+}
+
 static void sdram_timing_init (ulong size)
 {
 	register uint pass;

+ 1 - 1
board/sbc8548/tlb.c

@@ -81,7 +81,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe0000000	1M	CCSRBAR
 	 * 0xe2000000	16M	PCI1 IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 4, BOOKE_PAGESZ_64M, 1),
 

+ 1 - 1
board/sbc8560/tlb.c

@@ -28,7 +28,7 @@
 
 struct fsl_e_tlb_entry tlb_table[] = {
 /* TLB for CCSRBAR (IMMR) */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 1, BOOKE_PAGESZ_1M, 1),
 

+ 27 - 21
board/siemens/common/fpga.c

@@ -131,45 +131,44 @@ static int fpga_reset (fpga_t* fpga)
 static int fpga_load (fpga_t* fpga, ulong addr, int checkall)
 {
     volatile uchar *fpga_addr = (volatile uchar *)fpga->conf_base;
-    image_header_t hdr;
-    ulong len, checksum;
-    uchar *data = (uchar *)&hdr;
-    char *s, msg[32];
+    image_header_t *hdr = (image_header_t *)addr;
+    ulong len;
+    uchar *data;
+    char msg[32];
     int verify, i;
 
+#if defined(CONFIG_FIT)
+    if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+	puts ("Non legacy image format not supported\n");
+	return -1;
+    }
+#endif
+
     /*
      * Check the image header and data of the net-list
      */
-    memcpy (&hdr, (char *)addr, sizeof(image_header_t));
-
-    if (hdr.ih_magic != IH_MAGIC) {
+    if (!image_check_magic (hdr)) {
 	strcpy (msg, "Bad Image Magic Number");
 	goto failure;
     }
 
-    len  = sizeof(image_header_t);
-
-    checksum = hdr.ih_hcrc;
-    hdr.ih_hcrc = 0;
-
-    if (crc32 (0, data, len) != checksum) {
+    if (!image_check_hcrc (hdr)) {
 	strcpy (msg, "Bad Image Header CRC");
 	goto failure;
     }
 
-    data = (uchar*)(addr + sizeof(image_header_t));
-    len  = hdr.ih_size;
+    data = (uchar*)image_get_data (hdr);
+    len  = image_get_data_size (hdr);
 
-    s = getenv ("verify");
-    verify = (s && (*s == 'n')) ? 0 : 1;
+    verify = getenv_verify ();
     if (verify) {
-	if (crc32 (0, data, len) != hdr.ih_dcrc) {
+	if (!image_check_dcrc (hdr)) {
 	    strcpy (msg, "Bad Image Data CRC");
 	    goto failure;
 	}
     }
 
-    if (checkall && fpga_get_version(fpga, (char *)(hdr.ih_name)) < 0)
+    if (checkall && fpga_get_version(fpga, image_get_name (hdr)) < 0)
 	return 1;
 
     /* align length */
@@ -184,7 +183,7 @@ static int fpga_load (fpga_t* fpga, ulong addr, int checkall)
 	goto failure;
     }
 
-    printf ("(%s)... ", hdr.ih_name);
+    printf ("(%s)... ", image_get_name (hdr));
     /*
      * Copy data to FPGA
      */
@@ -341,7 +340,14 @@ int fpga_init (void)
 	}
 
 	hdr = (image_header_t *)addr;
-	if ((new_id = fpga_get_version(fpga, (char *)(hdr->ih_name))) == -1)
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+	   puts ("Non legacy image format not supported\n");
+	   return -1;
+	}
+#endif
+
+	if ((new_id = fpga_get_version(fpga, image_get_name (hdr))) == -1)
 	    return 1;
 
 	do_load = 1;

+ 1 - 1
board/stxgp3/tlb.c

@@ -87,7 +87,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe000_0000	1M	CCSRBAR
 	 * 0xe200_0000	16M	PCI1 IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 5, BOOKE_PAGESZ_64M, 1),
 

+ 1 - 1
board/stxssa/tlb.c

@@ -88,7 +88,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe200_0000	16M	PCI1 IO
 	 * 0xe300_0000	16M	PCI2 IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 5, BOOKE_PAGESZ_64M, 1),
 

+ 8 - 1
board/tb0229/tb0229.c

@@ -12,10 +12,17 @@
 #include <common.h>
 #include <command.h>
 #include <asm/addrspace.h>
-#include <asm/inca-ip.h>
 #include <asm/io.h>
+#include <asm/reboot.h>
 #include <pci.h>
 
+void _machine_restart(void)
+{
+	void (*f)(void) = (void *) 0xbfc00000;
+
+	f();
+}
+
 #if defined(CONFIG_PCI)
 static struct pci_controller hose;
 

+ 1 - 1
board/tqm85xx/tlb.c

@@ -91,7 +91,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	 * 0xe000_0000	1M	CCSRBAR
 	 * 0xe200_0000	16M	PCI1 IO
 	 */
-	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR,
+	SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 6, BOOKE_PAGESZ_64M, 1),
 

+ 65 - 49
board/trab/auto_update.c

@@ -209,21 +209,21 @@ int
 au_check_cksum_valid(int idx, long nbytes)
 {
 	image_header_t *hdr;
-	unsigned long checksum;
 
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
 
-	if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size)))
-	{
+	if (nbytes != image_get_image_size (hdr)) {
 		printf ("Image %s bad total SIZE\n", aufile[idx]);
 		return -1;
 	}
 	/* check the data CRC */
-	checksum = ntohl(hdr->ih_dcrc);
-
-	if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size))
-		!= checksum)
-	{
+	if (!image_check_dcrc (hdr)) {
 		printf ("Image %s bad data checksum\n", aufile[idx]);
 		return -1;
 	}
@@ -238,54 +238,55 @@ au_check_header_valid(int idx, long nbytes)
 	unsigned char buf[4];
 
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
+
 	/* check the easy ones first */
 #undef CHECK_VALID_DEBUG
 #ifdef CHECK_VALID_DEBUG
-	printf("magic %#x %#x ", ntohl(hdr->ih_magic), IH_MAGIC);
-	printf("arch %#x %#x ", hdr->ih_arch, IH_CPU_ARM);
-	printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes);
-	printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL);
+	printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC);
+	printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_ARM);
+	printf("size %#x %#lx ", image_get_data_size (hdr), nbytes);
+	printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL);
 #endif
-	if (nbytes < sizeof(*hdr))
-	{
+	if (nbytes < image_get_header_size ()) {
 		printf ("Image %s bad header SIZE\n", aufile[idx]);
 		return -1;
 	}
-	if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_ARM)
-	{
+	if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_ARM)) {
 		printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]);
 		return -1;
 	}
 	/* check the hdr CRC */
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
-
-	if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) {
+	if (!image_check_hcrc (hdr)) {
 		printf ("Image %s bad header checksum\n", aufile[idx]);
 		return -1;
 	}
-	hdr->ih_hcrc = htonl(checksum);
 	/* check the type - could do this all in one gigantic if() */
-	if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) {
+	if ((idx == IDX_FIRMWARE) &&
+		!image_check_type (hdr, IH_TYPE_FIRMWARE)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		return -1;
 	}
-	if ((idx == IDX_KERNEL) && (hdr->ih_type != IH_TYPE_KERNEL)) {
+	if ((idx == IDX_KERNEL) && !image_check_type (hdr, IH_TYPE_KERNEL)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		return -1;
 	}
-	if ((idx == IDX_DISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM)) {
+	if ((idx == IDX_DISK) && !image_check_type (hdr, IH_TYPE_FILESYSTEM)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		return -1;
 	}
-	if ((idx == IDX_APP) && (hdr->ih_type != IH_TYPE_RAMDISK)
-	    && (hdr->ih_type != IH_TYPE_FILESYSTEM)) {
+	if ((idx == IDX_APP) && !image_check_type (hdr, IH_TYPE_RAMDISK)
+		&& !image_check_type (hdr, IH_TYPE_FILESYSTEM)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		return -1;
 	}
 	if ((idx == IDX_PREPARE || idx == IDX_PREINST || idx == IDX_POSTINST)
-		&& (hdr->ih_type != IH_TYPE_SCRIPT))
-	{
+		&& !image_check_type (hdr, IH_TYPE_SCRIPT)) {
 		printf ("Image %s wrong type\n", aufile[idx]);
 		return -1;
 	}
@@ -293,10 +294,10 @@ au_check_header_valid(int idx, long nbytes)
 	if (idx == IDX_PREPARE)
 		return 0;
 	/* recycle checksum */
-	checksum = ntohl(hdr->ih_size);
+	checksum = image_get_data_size (hdr);
 	/* for kernel and app the image header must also fit into flash */
 	if ((idx != IDX_DISK) && (idx != IDX_FIRMWARE))
-		checksum += sizeof(*hdr);
+		checksum += image_get_header_size ();
 	/* check the size does not exceed space in flash. HUSH scripts */
 	/* all have ausize[] set to 0 */
 	if ((ausize[idx] != 0) && (ausize[idx] < checksum)) {
@@ -310,10 +311,10 @@ au_check_header_valid(int idx, long nbytes)
 	printf ("buf[0] %#x buf[1] %#x buf[2] %#x buf[3] %#x "
 		"as int %#x time %#x\n",
 		buf[0], buf[1], buf[2], buf[3],
-		*((unsigned int *)buf), ntohl(hdr->ih_time));
+		*((unsigned int *)buf), image_get_time (hdr));
 #endif
 	/* check it */
-	if (*((unsigned int *)buf) >= ntohl(hdr->ih_time)) {
+	if (*((unsigned int *)buf) >= image_get_time (hdr)) {
 		printf ("Image %s is too old\n", aufile[idx]);
 		return -1;
 	}
@@ -335,16 +336,22 @@ au_do_update(int idx, long sz)
 	uint nbytes;
 
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
 
 	/* disable the power switch */
 	*CPLD_VFD_BK |= POWER_OFF;
 
 	/* execute a script */
-	if (hdr->ih_type == IH_TYPE_SCRIPT) {
-		addr = (char *)((char *)hdr + sizeof(*hdr));
+	if (image_check_type (hdr, IH_TYPE_SCRIPT)) {
+		addr = (char *)((char *)hdr + image_get_header_size ());
 		/* stick a NULL at the end of the script, otherwise */
 		/* parse_string_outer() runs off the end. */
-		addr[ntohl(hdr->ih_size)] = 0;
+		addr[image_get_data_size (hdr)] = 0;
 		addr += 8;
 		parse_string_outer(addr, FLAG_PARSE_SEMICOLON);
 		return 0;
@@ -372,19 +379,20 @@ au_do_update(int idx, long sz)
 	flash_sect_erase(start, end);
 	wait_ms(100);
 	/* strip the header - except for the kernel and ramdisk */
-	if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) {
+	if (image_check_type (hdr, IH_TYPE_KERNEL) ||
+			image_check_type (hdr, IH_TYPE_RAMDISK)) {
 		addr = (char *)hdr;
-		off = sizeof(*hdr);
-		nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);
+		off = image_get_header_size ();
+		nbytes = image_get_image_size (hdr);
 	} else {
-		addr = (char *)((char *)hdr + sizeof(*hdr));
+		addr = (char *)((char *)hdr + image_get_header_size ());
 #ifdef AU_UPDATE_TEST
 		/* copy it to where Linux goes */
 		if (idx == IDX_FIRMWARE)
 			start = aufl_layout[1].start;
 #endif
 		off = 0;
-		nbytes = ntohl(hdr->ih_size);
+		nbytes = image_get_data_size (hdr);
 	}
 
 	/* copy the data from RAM to FLASH */
@@ -396,7 +404,8 @@ au_do_update(int idx, long sz)
 	}
 
 	/* check the dcrc of the copy */
-	if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) {
+	if (crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)) !=
+	    image_get_dcrc (hdr)) {
 		printf ("Image %s Bad Data Checksum After COPY\n", aufile[idx]);
 		return -1;
 	}
@@ -423,17 +432,24 @@ au_update_eeprom(int idx)
 	}
 
 	hdr = (image_header_t *)LOAD_ADDR;
+#if defined(CONFIG_FIT)
+	if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) {
+		puts ("Non legacy image format not supported\n");
+		return -1;
+	}
+#endif
+
 	/* write the time field into EEPROM */
 	off = auee_off[idx].time;
-	val = ntohl(hdr->ih_time);
+	val = image_get_time (hdr);
 	i2c_write_multiple(0x54, off, 1, &val, sizeof(val));
 	/* write the size field into EEPROM */
 	off = auee_off[idx].size;
-	val = ntohl(hdr->ih_size);
+	val = image_get_data_size (hdr);
 	i2c_write_multiple(0x54, off, 1, &val, sizeof(val));
 	/* write the dcrc field into EEPROM */
 	off = auee_off[idx].dcrc;
-	val = ntohl(hdr->ih_dcrc);
+	val = image_get_dcrc (hdr);
 	i2c_write_multiple(0x54, off, 1, &val, sizeof(val));
 	/* enable the power switch */
 	*CPLD_VFD_BK &= ~POWER_OFF;
@@ -577,10 +593,10 @@ do_auto_update(void)
 	/* just loop thru all the possible files */
 	for (i = 0; i < AU_MAXFILES; i++) {
 		/* just read the header */
-		sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t));
+		sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ());
 		debug ("read %s sz %ld hdr %d\n",
-			aufile[i], sz, sizeof(image_header_t));
-		if (sz <= 0 || sz < sizeof(image_header_t)) {
+			aufile[i], sz, image_get_header_size ());
+		if (sz <= 0 || sz < image_get_header_size ()) {
 			debug ("%s not found\n", aufile[i]);
 			continue;
 		}
@@ -590,8 +606,8 @@ do_auto_update(void)
 		}
 		sz = file_fat_read(aufile[i], LOAD_ADDR, MAX_LOADSZ);
 		debug ("read %s sz %ld hdr %d\n",
-			aufile[i], sz, sizeof(image_header_t));
-		if (sz <= 0 || sz <= sizeof(image_header_t)) {
+			aufile[i], sz, image_get_header_size ());
+		if (sz <= 0 || sz <= image_get_header_size ()) {
 			debug ("%s not found\n", aufile[i]);
 			continue;
 		}

+ 6 - 1
common/Makefile

@@ -36,6 +36,8 @@ COBJS-y += cmd_autoscript.o
 COBJS-$(CONFIG_CMD_BDI) += cmd_bdinfo.o
 COBJS-$(CONFIG_CMD_BEDBUG) += cmd_bedbug.o
 COBJS-$(CONFIG_CMD_BMP) += cmd_bmp.o
+COBJS-y += image.o
+COBJS-y += gunzip.o
 COBJS-y += cmd_boot.o
 COBJS-$(CONFIG_CMD_BOOTLDR) += cmd_bootldr.o
 COBJS-y += cmd_bootm.o
@@ -86,13 +88,15 @@ COBJS-y += cmd_pcmcia.o
 COBJS-$(CONFIG_CMD_PORTIO) += cmd_portio.o
 COBJS-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o
 COBJS-$(CONFIG_CMD_REISER) += cmd_reiser.o
-COBJS-y += cmd_sata.o
+COBJS-$(CONFIG_CMD_SATA) += cmd_sata.o
 COBJS-$(CONFIG_CMD_SCSI) += cmd_scsi.o
+COBJS-$(CONFIG_CMD_SETEXPR) += cmd_setexpr.o
 COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o
 COBJS-$(CONFIG_CMD_STRINGS) += cmd_strings.o
 COBJS-$(CONFIG_CMD_TERMINAL) += cmd_terminal.o
 COBJS-$(CONFIG_CMD_UNIVERSE) += cmd_universe.o
 COBJS-$(CONFIG_CMD_USB) += cmd_usb.o
+COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
 COBJS-y += cmd_vfd.o
 COBJS-y += command.o
 COBJS-y += console.o
@@ -136,6 +140,7 @@ COBJS-y += crc16.o
 COBJS-y += xyzModem.o
 COBJS-y += cmd_mac.o
 COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o
+COBJS-$(CONFIG_MP) += cmd_mp.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(AOBJS:.o=.S) $(COBJS:.o=.c)

+ 107 - 46
common/cmd_autoscript.c

@@ -49,57 +49,110 @@
 
 #if defined(CONFIG_AUTOSCRIPT) || defined(CONFIG_CMD_AUTOSCRIPT)
 
-extern image_header_t header;		/* from cmd_bootm.c */
 int
-autoscript (ulong addr)
+autoscript (ulong addr, const char *fit_uname)
 {
-	ulong crc, data, len;
-	image_header_t *hdr = &header;
-	ulong *len_ptr;
-	char *cmd;
-	int rcode = 0;
-	int verify;
+	ulong 		len;
+	image_header_t	*hdr;
+	ulong		*data;
+	char		*cmd;
+	int		rcode = 0;
+	int		verify;
+#if defined(CONFIG_FIT)
+	const void*	fit_hdr;
+	int		noffset;
+	const void	*fit_data;
+	size_t		fit_len;
+#endif
 
-	cmd = getenv ("verify");
-	verify = (cmd && (*cmd == 'n')) ? 0 : 1;
+	verify = getenv_verify ();
 
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
 
-	memmove (hdr, (char *)addr, sizeof(image_header_t));
+		if (!image_check_magic (hdr)) {
+			puts ("Bad magic number\n");
+			return 1;
+		}
 
-	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-		puts ("Bad magic number\n");
-		return 1;
-	}
+		if (!image_check_hcrc (hdr)) {
+			puts ("Bad header crc\n");
+			return 1;
+		}
 
-	crc = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
-	len = sizeof (image_header_t);
-	data = (ulong)hdr;
-	if (crc32(0, (uchar *)data, len) != crc) {
-		puts ("Bad header crc\n");
-		return 1;
-	}
+		if (verify) {
+			if (!image_check_dcrc (hdr)) {
+				puts ("Bad data crc\n");
+				return 1;
+			}
+		}
 
-	data = addr + sizeof(image_header_t);
-	len = ntohl(hdr->ih_size);
+		if (!image_check_type (hdr, IH_TYPE_SCRIPT)) {
+			puts ("Bad image type\n");
+			return 1;
+		}
+
+		/* get length of script */
+		data = (ulong *)image_get_data (hdr);
 
-	if (verify) {
-		if (crc32(0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {
-			puts ("Bad data crc\n");
+		if ((len = uimage_to_cpu (*data)) == 0) {
+			puts ("Empty Script\n");
 			return 1;
 		}
-	}
 
-	if (hdr->ih_type != IH_TYPE_SCRIPT) {
-		puts ("Bad image type\n");
-		return 1;
-	}
+		/*
+		 * scripts are just multi-image files with one component, seek
+		 * past the zero-terminated sequence of image lengths to get
+		 * to the actual image data
+		 */
+		while (*data++);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		if (fit_uname == NULL) {
+			puts ("No FIT subimage unit name\n");
+			return 1;
+		}
 
-	/* get length of script */
-	len_ptr = (ulong *)data;
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			puts ("Bad FIT image format\n");
+			return 1;
+		}
+
+		/* get script component image node offset */
+		noffset = fit_image_get_node (fit_hdr, fit_uname);
+		if (noffset < 0) {
+			printf ("Can't find '%s' FIT subimage\n", fit_uname);
+			return 1;
+		}
+
+		if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) {
+			puts ("Not a image image\n");
+			return 1;
+		}
+
+		/* verify integrity */
+		if (verify) {
+			if (!fit_image_check_hashes (fit_hdr, noffset)) {
+				puts ("Bad Data Hash\n");
+				return 1;
+			}
+		}
 
-	if ((len = ntohl(*len_ptr)) == 0) {
-		puts ("Empty Script\n");
+		/* get script subimage data address and length */
+		if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) {
+			puts ("Could not find script subimage data\n");
+			return 1;
+		}
+
+		data = (ulong *)fit_data;
+		len = (ulong)fit_len;
+		break;
+#endif
+	default:
+		puts ("Wrong image format for autoscript\n");
 		return 1;
 	}
 
@@ -109,10 +162,8 @@ autoscript (ulong addr)
 		return 1;
 	}
 
-	while (*len_ptr++);
-
 	/* make sure cmd is null terminated */
-	memmove (cmd, (char *)len_ptr, len);
+	memmove (cmd, (char *)data, len);
 	*(cmd + len) = 0;
 
 #ifdef CFG_HUSH_PARSER /*?? */
@@ -158,25 +209,35 @@ do_autoscript (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	ulong addr;
 	int rcode;
+	const char *fit_uname = NULL;
 
+	/* Find script image */
 	if (argc < 2) {
 		addr = CFG_LOAD_ADDR;
+		debug ("*  autoscr: default load address = 0x%08lx\n", addr);
+#if defined(CONFIG_FIT)
+	} else if (fit_parse_subimage (argv[1], load_addr, &addr, &fit_uname)) {
+		debug ("*  autoscr: subimage '%s' from FIT image at 0x%08lx\n",
+				fit_uname, addr);
+#endif
 	} else {
-		addr = simple_strtoul (argv[1],0,16);
+		addr = simple_strtoul(argv[1], NULL, 16);
+		debug ("*  autoscr: cmdline image address = 0x%08lx\n", addr);
 	}
 
-	printf ("## Executing script at %08lx\n",addr);
-	rcode = autoscript (addr);
+	printf ("## Executing script at %08lx\n", addr);
+	rcode = autoscript (addr, fit_uname);
 	return rcode;
 }
 
-#if defined(CONFIG_CMD_AUTOSCRIPT)
 U_BOOT_CMD(
 	autoscr, 2, 0,	do_autoscript,
 	"autoscr - run script from memory\n",
 	"[addr] - run script starting at addr"
 	" - A valid autoscr header must be present\n"
-);
+#if defined(CONFIG_FIT)
+	"For FIT format uImage addr must include subimage\n"
+	"unit name in the form of addr:<subimg_uname>\n"
 #endif
-
+);
 #endif

File diff suppressed because it is too large
+ 603 - 814
common/cmd_bootm.c


+ 31 - 7
common/cmd_doc.c

@@ -205,6 +205,9 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	ulong offset = 0;
 	image_header_t *hdr;
 	int rcode = 0;
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
 
 	show_boot_progress (34);
 	switch (argc) {
@@ -261,21 +264,36 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 	show_boot_progress (38);
 
-	hdr = (image_header_t *)addr;
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
 
-	if (hdr->ih_magic == IH_MAGIC) {
+		image_print_contents (hdr);
 
-		print_image_hdr (hdr);
+		cnt = image_get_image_size (hdr);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			show_boot_progress (-130);
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		show_boot_progress (131);
+		puts ("Fit image detected...\n");
 
-		cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
-		cnt -= SECTORSIZE;
-	} else {
-		puts ("\n** Bad Magic Number **\n");
+		cnt = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
 		show_boot_progress (-39);
+		puts ("** Unknown image type\n");
 		return 1;
 	}
 	show_boot_progress (39);
 
+	cnt -= SECTORSIZE;
 	if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt,
 		    NULL, (u_char *)(addr+SECTORSIZE))) {
 		printf ("** Read error on %d\n", dev);
@@ -284,6 +302,12 @@ int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 	show_boot_progress (40);
 
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
+
 	/* Loading ok, update default load address */
 
 	load_addr = addr;

+ 42 - 17
common/cmd_fdc.c

@@ -788,6 +788,9 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	int i,nrofblk;
 	char *ep;
 	int rcode = 0;
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
 
 	switch (argc) {
 	case 1:
@@ -835,14 +838,31 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 			printf("result%d: 0x%02X\n",i,pCMD->result[i]);
 		return 1;
 	}
-	hdr = (image_header_t *)addr;
-	if (ntohl(hdr->ih_magic)  != IH_MAGIC) {
-		printf ("Bad Magic Number\n");
+
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
+		image_print_contents (hdr);
+
+		imsize = image_get_image_size (hdr);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		puts ("Fit image detected...\n");
+
+		imsize = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
+		puts ("** Unknown image type\n");
 		return 1;
 	}
-	print_image_hdr(hdr);
 
-	imsize= ntohl(hdr->ih_size)+sizeof(image_header_t);
 	nrofblk=imsize/512;
 	if((imsize%512)>0)
 		nrofblk++;
@@ -858,23 +878,28 @@ int do_fdcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	printf("OK %ld Bytes loaded.\n",imsize);
 
 	flush_cache (addr, imsize);
-	/* Loading ok, update default load address */
 
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
+
+	/* Loading ok, update default load address */
 	load_addr = addr;
-	if(hdr->ih_type  == IH_TYPE_KERNEL) {
-		/* Check if we should attempt an auto-start */
-		if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
-			char *local_args[2];
-			extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
 
-			local_args[0] = argv[0];
-			local_args[1] = NULL;
+	/* Check if we should attempt an auto-start */
+	if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
+		char *local_args[2];
+		extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
 
-			printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
+		local_args[0] = argv[0];
+		local_args[1] = NULL;
 
-			do_bootm (cmdtp, 0, 1, local_args);
-			rcode ++;
-		}
+		printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
+
+		do_bootm (cmdtp, 0, 1, local_args);
+		rcode ++;
 	}
 	return rcode;
 }

+ 0 - 17
common/cmd_fdt.c

@@ -410,17 +410,6 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 	/* Create a chosen node */
 	else if (argv[1][0] == 'c')
 		fdt_chosen(fdt, 0, 0, 1);
-
-#ifdef CONFIG_OF_HAS_UBOOT_ENV
-	/* Create a u-boot-env node */
-	else if (argv[1][0] == 'e')
-		fdt_env(fdt);
-#endif
-#ifdef CONFIG_OF_HAS_BD_T
-	/* Create a bd_t node */
-	else if (argv[1][0] == 'b')
-		fdt_bd_t(fdt);
-#endif
 	else {
 		/* Unrecognized command */
 		printf ("Usage:\n%s\n", cmdtp->usage);
@@ -801,12 +790,6 @@ U_BOOT_CMD(
 	"fdt rsvmem add <addr> <size>        - Add a mem reserve\n"
 	"fdt rsvmem delete <index>           - Delete a mem reserves\n"
 	"fdt chosen - Add/update the /chosen branch in the tree\n"
-#ifdef CONFIG_OF_HAS_UBOOT_ENV
-	"fdt env    - Add/replace the /u-boot-env branch in the tree\n"
-#endif
-#ifdef CONFIG_OF_HAS_BD_T
-	"fdt bd_t   - Add/replace the /bd_t branch in the tree\n"
-#endif
 	"NOTE: If the path or property you are setting/printing has a '#' character\n"
 	"     or spaces, you MUST escape it with a \\ character or quote it with \".\n"
 );

+ 94 - 15
common/cmd_fpga.c

@@ -164,6 +164,10 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 	char *devstr = getenv ("fpga");
 	char *datastr = getenv ("fpgadata");
 	int rc = FPGA_FAIL;
+#if defined (CONFIG_FIT)
+	const char *fit_uname = NULL;
+	ulong fit_addr;
+#endif
 
 	if (devstr)
 		dev = (int) simple_strtoul (devstr, NULL, 16);
@@ -173,9 +177,22 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 	switch (argc) {
 	case 5:		/* fpga <op> <dev> <data> <datasize> */
 		data_size = simple_strtoul (argv[4], NULL, 16);
+
 	case 4:		/* fpga <op> <dev> <data> */
-		fpga_data = (void *) simple_strtoul (argv[3], NULL, 16);
+#if defined(CONFIG_FIT)
+		if (fit_parse_subimage (argv[3], (ulong)fpga_data,
+					&fit_addr, &fit_uname)) {
+			fpga_data = (void *)fit_addr;
+			debug ("*  fpga: subimage '%s' from FIT image at 0x%08lx\n",
+					fit_uname, fit_addr);
+		} else
+#endif
+		{
+			fpga_data = (void *) simple_strtoul (argv[3], NULL, 16);
+			debug ("*  fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data);
+		}
 		PRINTF ("%s: fpga_data = 0x%x\n", __FUNCTION__, (uint) fpga_data);
+
 	case 3:		/* fpga <op> <dev | data addr> */
 		dev = (int) simple_strtoul (argv[2], NULL, 16);
 		PRINTF ("%s: device = %d\n", __FUNCTION__, dev);
@@ -183,14 +200,29 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 		if ((argc == 3) && (dev > fpga_count ())) {	/* must be buffer ptr */
 			PRINTF ("%s: Assuming buffer pointer in arg 3\n",
 				__FUNCTION__);
-			fpga_data = (void *) dev;
+
+#if defined(CONFIG_FIT)
+			if (fit_parse_subimage (argv[2], (ulong)fpga_data,
+						&fit_addr, &fit_uname)) {
+				fpga_data = (void *)fit_addr;
+				debug ("*  fpga: subimage '%s' from FIT image at 0x%08lx\n",
+						fit_uname, fit_addr);
+			} else
+#endif
+			{
+				fpga_data = (void *) dev;
+				debug ("*  fpga: cmdline image address = 0x%08lx\n", (ulong)fpga_data);
+			}
+
 			PRINTF ("%s: fpga_data = 0x%x\n",
 				__FUNCTION__, (uint) fpga_data);
 			dev = FPGA_INVALID_DEVICE;	/* reset device num */
 		}
+
 	case 2:		/* fpga <op> */
 		op = (int) fpga_get_op (argv[1]);
 		break;
+
 	default:
 		PRINTF ("%s: Too many or too few args (%d)\n",
 			__FUNCTION__, argc);
@@ -216,19 +248,61 @@ int do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 		break;
 
 	case FPGA_LOADMK:
-		{
-			image_header_t header;
-			image_header_t *hdr = &header;
-			ulong	data;
-
-			memmove (&header, (char *)fpga_data, sizeof(image_header_t));
-			if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-				puts ("Bad Magic Number\n");
-				return 1;
+		switch (genimg_get_format (fpga_data)) {
+		case IMAGE_FORMAT_LEGACY:
+			{
+				image_header_t *hdr = (image_header_t *)fpga_data;
+				ulong	data;
+
+				data = (ulong)image_get_data (hdr);
+				data_size = image_get_data_size (hdr);
+				rc = fpga_load (dev, (void *)data, data_size);
+			}
+			break;
+#if defined(CONFIG_FIT)
+		case IMAGE_FORMAT_FIT:
+			{
+				const void *fit_hdr = (const void *)fpga_data;
+				int noffset;
+				void *fit_data;
+
+				if (fit_uname == NULL) {
+					puts ("No FIT subimage unit name\n");
+					return 1;
+				}
+
+				if (!fit_check_format (fit_hdr)) {
+					puts ("Bad FIT image format\n");
+					return 1;
+				}
+
+				/* get fpga component image node offset */
+				noffset = fit_image_get_node (fit_hdr, fit_uname);
+				if (noffset < 0) {
+					printf ("Can't find '%s' FIT subimage\n", fit_uname);
+					return 1;
+				}
+
+				/* verify integrity */
+				if (!fit_image_check_hashes (fit_hdr, noffset)) {
+					puts ("Bad Data Hash\n");
+					return 1;
+				}
+
+				/* get fpga subimage data address and length */
+				if (fit_image_get_data (fit_hdr, noffset, &fit_data, &data_size)) {
+					puts ("Could not find fpga subimage data\n");
+					return 1;
+				}
+
+				rc = fpga_load (dev, fit_data, data_size);
 			}
-			data = ((ulong)fpga_data + sizeof(image_header_t));
-			data_size  = ntohl(hdr->ih_size);
-			rc = fpga_load (dev, (void *)data, data_size);
+			break;
+#endif
+		default:
+			puts ("** Unknown image type\n");
+			rc = FPGA_FAIL;
+			break;
 		}
 		break;
 
@@ -283,4 +357,9 @@ U_BOOT_CMD (fpga, 6, 1, do_fpga,
 	    "\tload\tLoad device from memory buffer\n"
 	    "\tloadb\tLoad device from bitstream buffer (Xilinx devices only)\n"
 	    "\tloadmk\tLoad device generated with mkimage\n"
-	    "\tdump\tLoad device to memory buffer\n");
+	    "\tdump\tLoad device to memory buffer\n"
+#if defined(CONFIG_FIT)
+	    "\tFor loadmk operating on FIT format uImage address must include\n"
+	    "\tsubimage unit name in the form of addr:<subimg_uname>\n"
+#endif
+);

+ 40 - 18
common/cmd_ide.c

@@ -366,10 +366,13 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	char *boot_device = NULL;
 	char *ep;
 	int dev, part = 0;
-	ulong addr, cnt, checksum;
+	ulong addr, cnt;
 	disk_partition_t info;
 	image_header_t *hdr;
 	int rcode = 0;
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
 
 	show_boot_progress (41);
 	switch (argc) {
@@ -446,29 +449,43 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 	show_boot_progress (48);
 
-	hdr = (image_header_t *)addr;
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
 
-	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-		printf("\n** Bad Magic Number **\n");
-		show_boot_progress (-49);
-		return 1;
-	}
-	show_boot_progress (49);
+		show_boot_progress (49);
 
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
+		if (!image_check_hcrc (hdr)) {
+			puts ("\n** Bad Header Checksum **\n");
+			show_boot_progress (-50);
+			return 1;
+		}
+		show_boot_progress (50);
+
+		image_print_contents (hdr);
 
-	if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) {
-		puts ("\n** Bad Header Checksum **\n");
-		show_boot_progress (-50);
+		cnt = image_get_image_size (hdr);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			show_boot_progress (-140);
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		show_boot_progress (141);
+		puts ("Fit image detected...\n");
+
+		cnt = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
+		show_boot_progress (-49);
+		puts ("** Unknown image type\n");
 		return 1;
 	}
-	show_boot_progress (50);
-	hdr->ih_hcrc = htonl(checksum); /* restore checksum for later use */
 
-	print_image_hdr (hdr);
-
-	cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
 	cnt += info.blksz - 1;
 	cnt /= info.blksz;
 	cnt -= 1;
@@ -481,6 +498,11 @@ int do_diskboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 	show_boot_progress (51);
 
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
 
 	/* Loading ok, update default load address */
 

+ 9 - 2
common/cmd_load.c

@@ -521,8 +521,15 @@ int do_load_serial_bin (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		char *s;
 
 		if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
-			printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
-			rcode = autoscript (load_addr);
+			printf ("Running autoscript at addr 0x%08lX", load_addr);
+
+			s = getenv ("autoscript_uname");
+			if (s)
+				printf (":%s ...\n", s);
+			else
+				puts (" ...\n");
+
+			rcode = autoscript (load_addr, s);
 		}
 	}
 #endif

+ 93 - 0
common/cmd_mp.c

@@ -0,0 +1,93 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, 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 <common.h>
+#include <command.h>
+
+int
+cpu_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	unsigned long cpuid;
+
+	if (argc < 3) {
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+	}
+
+	cpuid = simple_strtoul(argv[1], NULL, 10);
+	if (cpuid >= CONFIG_NR_CPUS) {
+		printf ("Core num: %d is out of range[0..%d]\n",
+				cpuid, CONFIG_NR_CPUS - 1);
+		return 1;
+	}
+
+
+	if (argc == 3) {
+		if (strncmp(argv[2], "reset", 5) == 0) {
+			cpu_reset(cpuid);
+		} else if (strncmp(argv[2], "status", 6) == 0) {
+			cpu_status(cpuid);
+		} else {
+			printf ("Usage:\n%s\n", cmdtp->usage);
+			return 1;
+		}
+		return 0;
+	}
+
+	/* 4 or greater, make sure its release */
+	if (strncmp(argv[2], "release", 7) != 0) {
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+	}
+
+	if (cpu_release(cpuid, argc - 3, argv + 3)) {
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_PPC
+#define CPU_ARCH_HELP \
+	"                         [args] : <pir> <r3> <r6>\n" \
+	"                                   pir - processor id (if writeable)\n" \
+	"                                    r3 - value for gpr 3\n" \
+	"                                    r6 - value for gpr 6\n" \
+	"\n" \
+	"     Use '-' for any arg if you want the default value.\n" \
+	"     Default for r3 is <num> and r6 is 0\n" \
+	"\n" \
+	"     When cpu <num> is released r4 and r5 = 0.\n" \
+	"     r7 will contain the size of the initial mapped area\n"
+#endif
+
+U_BOOT_CMD(
+	cpu, CFG_MAXARGS, 1, cpu_cmd,
+	"cpu     - Multiprocessor CPU boot manipulation and release\n",
+	    "<num> reset                 - Reset cpu <num>\n"
+	"cpu <num> status                - Status of cpu <num>\n"
+	"cpu <num> release <addr> [args] - Release cpu <num> at <addr> with [args]\n"
+#ifdef CPU_ARCH_HELP
+	CPU_ARCH_HELP
+#endif
+	);

+ 65 - 15
common/cmd_nand.c

@@ -484,6 +484,9 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
 	ulong cnt;
 	image_header_t *hdr;
 	int jffs2 = 0;
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
 
 	s = strchr(cmd, '.');
 	if (s != NULL &&
@@ -512,18 +515,35 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
 	}
 	show_boot_progress (56);
 
-	hdr = (image_header_t *) addr;
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
+
+		show_boot_progress (57);
+		image_print_contents (hdr);
 
-	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-		printf("\n** Bad Magic Number 0x%x **\n", hdr->ih_magic);
+		cnt = image_get_image_size (hdr);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			show_boot_progress (-150);
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		show_boot_progress (151);
+		puts ("Fit image detected...\n");
+
+		cnt = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
 		show_boot_progress (-57);
+		puts ("** Unknown image type\n");
 		return 1;
 	}
-	show_boot_progress (57);
-
-	print_image_hdr(hdr);
 
-	cnt = (ntohl(hdr->ih_size) + sizeof (image_header_t));
 	if (jffs2) {
 		nand_read_options_t opts;
 		memset(&opts, 0, sizeof(opts));
@@ -543,6 +563,12 @@ static int nand_load_image(cmd_tbl_t *cmdtp, nand_info_t *nand,
 	}
 	show_boot_progress (58);
 
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
+
 	/* Loading ok, update default load address */
 
 	load_addr = addr;
@@ -925,6 +951,10 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	ulong offset = 0;
 	image_header_t *hdr;
 	int rcode = 0;
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
+
 	show_boot_progress (52);
 	switch (argc) {
 	case 1:
@@ -980,17 +1010,31 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 	show_boot_progress (56);
 
-	hdr = (image_header_t *)addr;
-
-	if (ntohl(hdr->ih_magic) == IH_MAGIC) {
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
+		image_print_contents (hdr);
 
-		print_image_hdr (hdr);
-
-		cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
+		cnt = image_get_image_size (hdr);
 		cnt -= SECTORSIZE;
-	} else {
-		printf ("\n** Bad Magic Number 0x%x **\n", ntohl(hdr->ih_magic));
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			show_boot_progress (-150);
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		show_boot_progress (151);
+		puts ("Fit image detected...\n");
+
+		cnt = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
 		show_boot_progress (-57);
+		puts ("** Unknown image type\n");
 		return 1;
 	}
 	show_boot_progress (57);
@@ -1004,6 +1048,12 @@ int do_nandboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 	show_boot_progress (58);
 
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
+
 	/* Loading ok, update default load address */
 
 	load_addr = addr;

+ 9 - 2
common/cmd_net.c

@@ -220,9 +220,16 @@ netboot_common (proto_t proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
 
 #ifdef CONFIG_AUTOSCRIPT
 	if (((s = getenv("autoscript")) != NULL) && (strcmp(s,"yes") == 0)) {
-		printf("Running autoscript at addr 0x%08lX ...\n", load_addr);
+		printf ("Running autoscript at addr 0x%08lX", load_addr);
+
+		s = getenv ("autoscript_uname");
+		if (s)
+			printf (":%s ...\n", s);
+		else
+			puts (" ...\n");
+
 		show_boot_progress (83);
-		rcode = autoscript (load_addr);
+		rcode = autoscript (load_addr, s);
 	}
 #endif
 	if (rcode < 0)

+ 124 - 643
common/cmd_sata.c

@@ -1,8 +1,11 @@
 /*
+ * Copyright (C) 2000-2005, DENX Software Engineering
+ *		Wolfgang Denk <wd@denx.de>
  * Copyright (C) Procsys. All rights reserved.
- * Author: Mushtaq Khan <mushtaq_k@procsys.com>
+ *		Mushtaq Khan <mushtaq_k@procsys.com>
  *			<mushtaqk_921@yahoo.co.in>
- *
+ * Copyright (C) 2008 Freescale Semiconductor, Inc.
+ *		Dave Liu <daveliu@freescale.com>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -11,702 +14,180 @@
  *
  * 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
+ * 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
- *
- * with the reference to libata in kernel 2.4.32
- *
  */
 
-/*
- * File contains SATA read-write and other utility functions.
- */
 #include <common.h>
-#include <asm/io.h>
-#include <pci.h>
 #include <command.h>
-#include <config.h>
-#include <ide.h>
-#include <ata.h>
-
-#ifdef CFG_SATA_SUPPORTED
-/*For debug prints set macro DEBUG_SATA to 1 */
-#define DEBUG_SATA 0
-/*Macro for SATA library specific declarations */
-#define SATA_DECL
+#include <part.h>
 #include <sata.h>
-#undef SATA_DECL
-
-static u8 __inline__
-sata_inb (unsigned long ioaddr)
-{
-	return inb (ioaddr);
-}
-
-static void __inline__
-sata_outb (unsigned char val, unsigned long ioaddr)
-{
-	outb (val, ioaddr);
-}
-
-static void
-output_data (struct sata_ioports *ioaddr, ulong * sect_buf, int words)
-{
-	outsw (ioaddr->data_addr, sect_buf, words << 1);
-}
-
-static int
-input_data (struct sata_ioports *ioaddr, ulong * sect_buf, int words)
-{
-	insw (ioaddr->data_addr, sect_buf, words << 1);
-	return 0;
-}
-
-static void
-sata_cpy (unsigned char *dst, unsigned char *src, unsigned int len)
-{
-	unsigned char *end, *last;
-
-	last = dst;
-	end = src + len - 1;
-
-	/* reserve space for '\0' */
-	if (len < 2)
-		goto OUT;
-
-	/* skip leading white space */
-	while ((*src) && (src < end) && (*src == ' '))
-		++src;
-
-	/* copy string, omitting trailing white space */
-	while ((*src) && (src < end)) {
-		*dst++ = *src;
-		if (*src++ != ' ')
-			last = dst;
-	}
-      OUT:
-	*last = '\0';
-}
-
-int
-sata_bus_softreset (int num)
-{
-	u8 dev = 0, status = 0, i;
-
-	port[num].dev_mask = 0;
-
-	for (i = 0; i < CFG_SATA_DEVS_PER_BUS; i++) {
-		if (!(sata_devchk (&port[num].ioaddr, i))) {
-			PRINTF ("dev_chk failed for dev#%d\n", i);
-		} else {
-			port[num].dev_mask |= (1 << i);
-			PRINTF ("dev_chk passed for dev#%d\n", i);
-		}
-	}
-
-	if (!(port[num].dev_mask)) {
-		printf ("no devices on port%d\n", num);
-		return 1;
-	}
-
-	dev_select (&port[num].ioaddr, dev);
-
-	port[num].ctl_reg = 0x08;	/*Default value of control reg */
-	sata_outb (port[num].ctl_reg, port[num].ioaddr.ctl_addr);
-	udelay (10);
-	sata_outb (port[num].ctl_reg | ATA_SRST, port[num].ioaddr.ctl_addr);
-	udelay (10);
-	sata_outb (port[num].ctl_reg, port[num].ioaddr.ctl_addr);
-
-	/* spec mandates ">= 2ms" before checking status.
-	 * We wait 150ms, because that was the magic delay used for
-	 * ATAPI devices in Hale Landis's ATADRVR, for the period of time
-	 * between when the ATA command register is written, and then
-	 * status is checked.  Because waiting for "a while" before
-	 * checking status is fine, post SRST, we perform this magic
-	 * delay here as well.
-	 */
-	msleep (150);
-	status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 300);
-	while ((status & ATA_BUSY)) {
-		msleep (100);
-		status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 3);
-	}
-
-	if (status & ATA_BUSY)
-		printf ("ata%u is slow to respond,plz be patient\n", port);
-
-	while ((status & ATA_BUSY)) {
-		msleep (100);
-		status = sata_chk_status (&port[num].ioaddr);
-	}
-
-	if (status & ATA_BUSY) {
-		printf ("ata%u failed to respond : ", port);
-		printf ("bus reset failed\n");
-		return 1;
-	}
-	return 0;
-}
-
-void
-sata_identify (int num, int dev)
-{
-	u8 cmd = 0, status = 0, devno = num * CFG_SATA_DEVS_PER_BUS + dev;
-	u16 iobuf[ATA_SECT_SIZE];
-	u64 n_sectors = 0;
-	u8 mask = 0;
-
-	memset (iobuf, 0, sizeof (iobuf));
-	hd_driveid_t *iop = (hd_driveid_t *) iobuf;
-
-	if (dev == 0)
-		mask = 0x01;
-	else
-		mask = 0x02;
-
-	if (!(port[num].dev_mask & mask)) {
-		printf ("dev%d is not present on port#%d\n", dev, num);
-		return;
-	}
-
-	printf ("port=%d dev=%d\n", num, dev);
-
-	dev_select (&port[num].ioaddr, dev);
-
-	status = 0;
-	cmd = ATA_CMD_IDENT;	/*Device Identify Command */
-	sata_outb (cmd, port[num].ioaddr.command_addr);
-	sata_inb (port[num].ioaddr.altstatus_addr);
-	udelay (10);
-
-	status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 1000);
-	if (status & ATA_ERR) {
-		printf ("\ndevice not responding\n");
-		port[num].dev_mask &= ~mask;
-		return;
-	}
-
-	input_data (&port[num].ioaddr, (ulong *) iobuf, ATA_SECTORWORDS);
-
-	PRINTF ("\nata%u: dev %u cfg 49:%04x 82:%04x 83:%04x 84:%04x85:%04x"
-		"86:%04x" "87:%04x 88:%04x\n", num, dev, iobuf[49],
-		iobuf[82], iobuf[83], iobuf[84], iobuf[85], iobuf[86],
-		iobuf[87], iobuf[88]);
-
-	/* we require LBA and DMA support (bits 8 & 9 of word 49) */
-	if (!ata_id_has_dma (iobuf) || !ata_id_has_lba (iobuf)) {
-		PRINTF ("ata%u: no dma/lba\n", num);
-	}
-	ata_dump_id (iobuf);
-
-	if (ata_id_has_lba48 (iobuf)) {
-		n_sectors = ata_id_u64 (iobuf, 100);
-	} else {
-		n_sectors = ata_id_u32 (iobuf, 60);
-	}
-	PRINTF ("no. of sectors %u\n", ata_id_u64 (iobuf, 100));
-	PRINTF ("no. of sectors %u\n", ata_id_u32 (iobuf, 60));
-
-	if (n_sectors == 0) {
-		port[num].dev_mask &= ~mask;
-		return;
-	}
-
-	sata_cpy (sata_dev_desc[devno].revision, iop->fw_rev,
-		  sizeof (sata_dev_desc[devno].revision));
-	sata_cpy (sata_dev_desc[devno].vendor, iop->model,
-		  sizeof (sata_dev_desc[devno].vendor));
-	sata_cpy (sata_dev_desc[devno].product, iop->serial_no,
-		  sizeof (sata_dev_desc[devno].product));
-	strswab (sata_dev_desc[devno].revision);
-	strswab (sata_dev_desc[devno].vendor);
-
-	if ((iop->config & 0x0080) == 0x0080) {
-		sata_dev_desc[devno].removable = 1;
-	} else {
-		sata_dev_desc[devno].removable = 0;
-	}
 
-	sata_dev_desc[devno].lba = iop->lba_capacity;
-	PRINTF ("lba=0x%x", sata_dev_desc[devno].lba);
+int curr_device = -1;
+block_dev_desc_t sata_dev_desc[CFG_SATA_MAX_DEVICE];
 
-#ifdef CONFIG_LBA48
-	if (iop->command_set_2 & 0x0400) {
-		sata_dev_desc[devno].lba48 = 1;
-		lba = (unsigned long long) iop->lba48_capacity[0] |
-		    ((unsigned long long) iop->lba48_capacity[1] << 16) |
-		    ((unsigned long long) iop->lba48_capacity[2] << 32) |
-		    ((unsigned long long) iop->lba48_capacity[3] << 48);
-	} else {
-		sata_dev_desc[devno].lba48 = 0;
-	}
-#endif
-
-	/* assuming HD */
-	sata_dev_desc[devno].type = DEV_TYPE_HARDDISK;
-	sata_dev_desc[devno].blksz = ATA_BLOCKSIZE;
-	sata_dev_desc[devno].lun = 0;	/* just to fill something in... */
-}
-
-void
-set_Feature_cmd (int num, int dev)
-{
-	u8 mask = 0x00, status = 0;
-
-	if (dev == 0)
-		mask = 0x01;
-	else
-		mask = 0x02;
-
-	if (!(port[num].dev_mask & mask)) {
-		PRINTF ("dev%d is not present on port#%d\n", dev, num);
-		return;
-	}
-
-	dev_select (&port[num].ioaddr, dev);
-
-	sata_outb (SETFEATURES_XFER, port[num].ioaddr.feature_addr);
-	sata_outb (XFER_PIO_4, port[num].ioaddr.nsect_addr);
-	sata_outb (0, port[num].ioaddr.lbal_addr);
-	sata_outb (0, port[num].ioaddr.lbam_addr);
-	sata_outb (0, port[num].ioaddr.lbah_addr);
-
-	sata_outb (ATA_DEVICE_OBS, port[num].ioaddr.device_addr);
-	sata_outb (ATA_CMD_SETF, port[num].ioaddr.command_addr);
-
-	udelay (50);
-	msleep (150);
-
-	status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 5000);
-	if ((status & (ATA_STAT_BUSY | ATA_STAT_ERR))) {
-		printf ("Error  : status 0x%02x\n", status);
-		port[num].dev_mask &= ~mask;
-	}
-}
-
-void
-sata_port (struct sata_ioports *ioport)
-{
-	ioport->data_addr = ioport->cmd_addr + ATA_REG_DATA;
-	ioport->error_addr = ioport->cmd_addr + ATA_REG_ERR;
-	ioport->feature_addr = ioport->cmd_addr + ATA_REG_FEATURE;
-	ioport->nsect_addr = ioport->cmd_addr + ATA_REG_NSECT;
-	ioport->lbal_addr = ioport->cmd_addr + ATA_REG_LBAL;
-	ioport->lbam_addr = ioport->cmd_addr + ATA_REG_LBAM;
-	ioport->lbah_addr = ioport->cmd_addr + ATA_REG_LBAH;
-	ioport->device_addr = ioport->cmd_addr + ATA_REG_DEVICE;
-	ioport->status_addr = ioport->cmd_addr + ATA_REG_STATUS;
-	ioport->command_addr = ioport->cmd_addr + ATA_REG_CMD;
-}
-
-int
-sata_devchk (struct sata_ioports *ioaddr, int dev)
-{
-	u8 nsect, lbal;
-
-	dev_select (ioaddr, dev);
-
-	sata_outb (0x55, ioaddr->nsect_addr);
-	sata_outb (0xaa, ioaddr->lbal_addr);
-
-	sata_outb (0xaa, ioaddr->nsect_addr);
-	sata_outb (0x55, ioaddr->lbal_addr);
-
-	sata_outb (0x55, ioaddr->nsect_addr);
-	sata_outb (0xaa, ioaddr->lbal_addr);
-
-	nsect = sata_inb (ioaddr->nsect_addr);
-	lbal = sata_inb (ioaddr->lbal_addr);
-
-	if ((nsect == 0x55) && (lbal == 0xaa))
-		return 1;	/* we found a device */
-	else
-		return 0;	/* nothing found */
-}
-
-void
-dev_select (struct sata_ioports *ioaddr, int dev)
-{
-	u8 tmp = 0;
-
-	if (dev == 0)
-		tmp = ATA_DEVICE_OBS;
-	else
-		tmp = ATA_DEVICE_OBS | ATA_DEV1;
-
-	sata_outb (tmp, ioaddr->device_addr);
-	sata_inb (ioaddr->altstatus_addr);
-	udelay (5);
-}
-
-u8
-sata_busy_wait (struct sata_ioports *ioaddr, int bits, unsigned int max)
-{
-	u8 status;
-
-	do {
-		udelay (1000);
-		status = sata_chk_status (ioaddr);
-		max--;
-	} while ((status & bits) && (max > 0));
-
-	return status;
-}
-
-u8
-sata_chk_status (struct sata_ioports * ioaddr)
-{
-	return sata_inb (ioaddr->status_addr);
-}
-
-void
-msleep (int count)
+int sata_initialize(void)
 {
+	int rc;
 	int i;
 
-	for (i = 0; i < count; i++)
-		udelay (1000);
-}
-
-ulong
-sata_read (int device, ulong blknr,lbaint_t blkcnt, void * buff)
-{
-	ulong n = 0, *buffer = (ulong *)buff;
-	u8 dev = 0, num = 0, mask = 0, status = 0;
-
-#ifdef CONFIG_LBA48
-	unsigned char lba48 = 0;
-
-	if (blknr & 0x0000fffff0000000) {
-		if (!sata_dev_desc[devno].lba48) {
-			printf ("Drive doesn't support 48-bit addressing\n");
-			return 0;
-		}
-		/* more than 28 bits used, use 48bit mode */
-		lba48 = 1;
-	}
-#endif
-	/*Port Number */
-	num = device / CFG_SATA_DEVS_PER_BUS;
-	/*dev on the port */
-	if (device >= CFG_SATA_DEVS_PER_BUS)
-		dev = device - CFG_SATA_DEVS_PER_BUS;
-	else
-		dev = device;
-
-	if (dev == 0)
-		mask = 0x01;
-	else
-		mask = 0x02;
-
-	if (!(port[num].dev_mask & mask)) {
-		printf ("dev%d is not present on port#%d\n", dev, num);
-		return 0;
-	}
+	for (i = 0; i < CFG_SATA_MAX_DEVICE; i++) {
+		memset(&sata_dev_desc[i], 0, sizeof(struct block_dev_desc));
+		sata_dev_desc[i].if_type = IF_TYPE_SATA;
+		sata_dev_desc[i].dev = i;
+		sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
+		sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
+		sata_dev_desc[i].lba = 0;
+		sata_dev_desc[i].blksz = 512;
+		sata_dev_desc[i].block_read = sata_read;
+		sata_dev_desc[i].block_write = sata_write;
 
-	/* Select device */
-	dev_select (&port[num].ioaddr, dev);
-
-	status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500);
-	if (status & ATA_BUSY) {
-		printf ("ata%u failed to respond\n", port[num].port_no);
-		return n;
+		rc = init_sata(i);
+		rc = scan_sata(i);
+		if ((sata_dev_desc[i].lba > 0) && (sata_dev_desc[i].blksz > 0))
+			init_part(&sata_dev_desc[i]);
 	}
-	while (blkcnt-- > 0) {
-		status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500);
-		if (status & ATA_BUSY) {
-			printf ("ata%u failed to respond\n", 0);
-			return n;
-		}
-#ifdef CONFIG_LBA48
-		if (lba48) {
-			/* write high bits */
-			sata_outb (0, port[num].ioaddr.nsect_addr);
-			sata_outb ((blknr >> 24) & 0xFF,
-				   port[num].ioaddr.lbal_addr);
-			sata_outb ((blknr >> 32) & 0xFF,
-				   port[num].ioaddr.lbam_addr);
-			sata_outb ((blknr >> 40) & 0xFF,
-				   port[num].ioaddr.lbah_addr);
-		}
-#endif
-		sata_outb (1, port[num].ioaddr.nsect_addr);
-		sata_outb (((blknr) >> 0) & 0xFF,
-			   port[num].ioaddr.lbal_addr);
-		sata_outb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr);
-		sata_outb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr);
-
-#ifdef CONFIG_LBA48
-		if (lba48) {
-			sata_outb (ATA_LBA, port[num].ioaddr.device_addr);
-			sata_outb (ATA_CMD_READ_EXT,
-				   port[num].ioaddr.command_addr);
-		} else
-#endif
-		{
-			sata_outb (ATA_LBA | ((blknr >> 24) & 0xF),
-				   port[num].ioaddr.device_addr);
-			sata_outb (ATA_CMD_READ,
-				   port[num].ioaddr.command_addr);
-		}
-
-		msleep (50);
-		/*may take up to 4 sec */
-		status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000);
-
-		if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR))
-		    != ATA_STAT_DRQ) {
-			u8 err = 0;
-
-			printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
-				device, (ulong) blknr, status);
-			err = sata_inb (port[num].ioaddr.error_addr);
-			printf ("Error reg = 0x%x\n", err);
-			return (n);
-		}
-		input_data (&port[num].ioaddr, buffer, ATA_SECTORWORDS);
-		sata_inb (port[num].ioaddr.altstatus_addr);
-		udelay (50);
-
-		++n;
-		++blknr;
-		buffer += ATA_SECTORWORDS;
-	}
-	return n;
+	curr_device = 0;
+	return rc;
 }
 
-ulong
-sata_write (int device, ulong blknr,lbaint_t blkcnt, void * buff)
+block_dev_desc_t *sata_get_dev(int dev)
 {
-	ulong n = 0, *buffer = (ulong *)buff;
-	unsigned char status = 0, num = 0, dev = 0, mask = 0;
-
-#ifdef CONFIG_LBA48
-	unsigned char lba48 = 0;
-
-	if (blknr & 0x0000fffff0000000) {
-		if (!sata_dev_desc[devno].lba48) {
-			printf ("Drive doesn't support 48-bit addressing\n");
-			return 0;
-		}
-		/* more than 28 bits used, use 48bit mode */
-		lba48 = 1;
-	}
-#endif
-	/*Port Number */
-	num = device / CFG_SATA_DEVS_PER_BUS;
-	/*dev on the Port */
-	if (device >= CFG_SATA_DEVS_PER_BUS)
-		dev = device - CFG_SATA_DEVS_PER_BUS;
-	else
-		dev = device;
-
-	if (dev == 0)
-		mask = 0x01;
-	else
-		mask = 0x02;
-
-	/* Select device */
-	dev_select (&port[num].ioaddr, dev);
-
-	status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500);
-	if (status & ATA_BUSY) {
-		printf ("ata%u failed to respond\n", port[num].port_no);
-		return n;
-	}
-
-	while (blkcnt-- > 0) {
-		status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 500);
-		if (status & ATA_BUSY) {
-			printf ("ata%u failed to respond\n",
-				port[num].port_no);
-			return n;
-		}
-#ifdef CONFIG_LBA48
-		if (lba48) {
-			/* write high bits */
-			sata_outb (0, port[num].ioaddr.nsect_addr);
-			sata_outb ((blknr >> 24) & 0xFF,
-				   port[num].ioaddr.lbal_addr);
-			sata_outb ((blknr >> 32) & 0xFF,
-				   port[num].ioaddr.lbam_addr);
-			sata_outb ((blknr >> 40) & 0xFF,
-				   port[num].ioaddr.lbah_addr);
-		}
-#endif
-		sata_outb (1, port[num].ioaddr.nsect_addr);
-		sata_outb ((blknr >> 0) & 0xFF, port[num].ioaddr.lbal_addr);
-		sata_outb ((blknr >> 8) & 0xFF, port[num].ioaddr.lbam_addr);
-		sata_outb ((blknr >> 16) & 0xFF, port[num].ioaddr.lbah_addr);
-#ifdef CONFIG_LBA48
-		if (lba48) {
-			sata_outb (ATA_LBA, port[num].ioaddr.device_addr);
-			sata_outb (ATA_CMD_WRITE_EXT,
-				   port[num].ioaddr.command_addr);
-		} else
-#endif
-		{
-			sata_outb (ATA_LBA | ((blknr >> 24) & 0xF),
-				   port[num].ioaddr.device_addr);
-			sata_outb (ATA_CMD_WRITE,
-				   port[num].ioaddr.command_addr);
-		}
-
-		msleep (50);
-		/*may take up to 4 sec */
-		status = sata_busy_wait (&port[num].ioaddr, ATA_BUSY, 4000);
-		if ((status & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR))
-		    != ATA_STAT_DRQ) {
-			printf ("Error no DRQ dev %d blk %ld: sts 0x%02x\n",
-				device, (ulong) blknr, status);
-			return (n);
-		}
-
-		output_data (&port[num].ioaddr, buffer, ATA_SECTORWORDS);
-		sata_inb (port[num].ioaddr.altstatus_addr);
-		udelay (50);
-
-		++n;
-		++blknr;
-		buffer += ATA_SECTORWORDS;
-	}
-	return n;
+	return (dev < CFG_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL;
 }
 
-block_dev_desc_t *sata_get_dev (int dev);
-
-block_dev_desc_t *
-sata_get_dev (int dev)
-{
-	return ((block_dev_desc_t *) & sata_dev_desc[dev]);
-}
-
-int
-do_sata (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+int do_sata(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
+	int rc = 0;
 
 	switch (argc) {
 	case 0:
 	case 1:
-		printf ("Usage:\n%s\n", cmdtp->usage);
+		printf("Usage:\n%s\n", cmdtp->usage);
 		return 1;
 	case 2:
-		if (strncmp (argv[1], "init", 4) == 0) {
-			int rcode = 0;
-
-			rcode = init_sata ();
-			if (rcode)
-				printf ("Sata initialization Failed\n");
-			return rcode;
-		} else if (strncmp (argv[1], "inf", 3) == 0) {
+		if (strncmp(argv[1],"inf", 3) == 0) {
 			int i;
-
-			putc ('\n');
-			for (i = 0; i < CFG_SATA_MAXDEVICES; ++i) {
-				/*List only known devices */
-				if (sata_dev_desc[i].type ==
-				    DEV_TYPE_UNKNOWN)
+			putc('\n');
+			for (i = 0; i < CFG_SATA_MAX_DEVICE; ++i) {
+				if (sata_dev_desc[i].type == DEV_TYPE_UNKNOWN)
 					continue;
-				printf ("sata dev %d: ", i);
-				dev_print (&sata_dev_desc[i]);
+				printf ("SATA device %d: ", i);
+				dev_print(&sata_dev_desc[i]);
 			}
 			return 0;
+		} else if (strncmp(argv[1],"dev", 3) == 0) {
+			if ((curr_device < 0) || (curr_device >= CFG_SATA_MAX_DEVICE)) {
+				puts("\nno SATA devices available\n");
+				return 1;
+			}
+			printf("\nSATA device %d: ", curr_device);
+			dev_print(&sata_dev_desc[curr_device]);
+			return 0;
+		} else if (strncmp(argv[1],"part",4) == 0) {
+			int dev, ok;
+
+			for (ok = 0, dev = 0; dev < CFG_SATA_MAX_DEVICE; ++dev) {
+				if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) {
+					++ok;
+					if (dev)
+						putc ('\n');
+					print_part(&sata_dev_desc[dev]);
+				}
+			}
+			if (!ok) {
+				puts("\nno SATA devices available\n");
+				rc ++;
+			}
+			return rc;
 		}
-		printf ("Usage:\n%s\n", cmdtp->usage);
+		printf("Usage:\n%s\n", cmdtp->usage);
 		return 1;
 	case 3:
-		if (strcmp (argv[1], "dev") == 0) {
-			int dev = (int) simple_strtoul (argv[2], NULL, 10);
+		if (strncmp(argv[1], "dev", 3) == 0) {
+			int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
-			if (dev >= CFG_SATA_MAXDEVICES) {
-				printf ("\nSata dev %d not available\n",
-					dev);
+			printf("\nSATA device %d: ", dev);
+			if (dev >= CFG_SATA_MAX_DEVICE) {
+				puts ("unknown device\n");
 				return 1;
 			}
-			printf ("\nSATA dev %d: ", dev);
-			dev_print (&sata_dev_desc[dev]);
+			dev_print(&sata_dev_desc[dev]);
+
 			if (sata_dev_desc[dev].type == DEV_TYPE_UNKNOWN)
 				return 1;
-			curr_dev = dev;
+
+			curr_device = dev;
+
+			puts("... is now current device\n");
+
 			return 0;
-		} else if (strcmp (argv[1], "part") == 0) {
-			int dev = (int) simple_strtoul (argv[2], NULL, 10);
+		} else if (strncmp(argv[1], "part", 4) == 0) {
+			int dev = (int)simple_strtoul(argv[2], NULL, 10);
 
-			if (dev >= CFG_SATA_MAXDEVICES) {
-				printf ("\nSata dev %d not available\n",
-					dev);
-				return 1;
-			}
-			PRINTF ("\nSATA dev %d: ", dev);
-			if (sata_dev_desc[dev].part_type !=
-			    PART_TYPE_UNKNOWN) {
-				print_part (&sata_dev_desc[dev]);
+			if (sata_dev_desc[dev].part_type != PART_TYPE_UNKNOWN) {
+				print_part(&sata_dev_desc[dev]);
 			} else {
-				printf ("\nSata dev %d partition type "
-					"unknown\n", dev);
-				return 1;
+				printf("\nSATA device %d not available\n", dev);
+				rc = 1;
 			}
-			return 0;
+			return rc;
 		}
 		printf ("Usage:\n%s\n", cmdtp->usage);
 		return 1;
-	default:
-		if (argc < 5) {
-			printf ("Usage:\n%s\n", cmdtp->usage);
-			return 1;
-		}
-		if (strcmp (argv[1], "read") == 0) {
-			ulong addr = simple_strtoul (argv[2], NULL, 16);
-			ulong cnt = simple_strtoul (argv[4], NULL, 16);
+
+	default: /* at least 4 args */
+		if (strcmp(argv[1], "read") == 0) {
+			ulong addr = simple_strtoul(argv[2], NULL, 16);
+			ulong cnt = simple_strtoul(argv[4], NULL, 16);
 			ulong n;
-			lbaint_t blk = simple_strtoul (argv[3], NULL, 16);
+			lbaint_t blk = simple_strtoul(argv[3], NULL, 16);
+
+			printf("\nSATA read: device %d block # %ld, count %ld ... ",
+				curr_device, blk, cnt);
+
+			n = sata_read(curr_device, blk, cnt, (u32 *)addr);
 
-			memset ((int *) addr, 0, cnt * 512);
-			printf ("\nSATA read: dev %d blk # %ld,"
-				"count %ld ... ", curr_dev, blk, cnt);
-			n = sata_read (curr_dev, blk, cnt, (ulong *) addr);
 			/* flush cache after read */
-			flush_cache (addr, cnt * 512);
-			printf ("%ld blocks read: %s\n", n,
-				(n == cnt) ? "OK" : "ERR");
-			if (n == cnt)
-				return 1;
-			else
-				return 0;
-		} else if (strcmp (argv[1], "write") == 0) {
-			ulong addr = simple_strtoul (argv[2], NULL, 16);
-			ulong cnt = simple_strtoul (argv[4], NULL, 16);
+			flush_cache(addr, cnt * sata_dev_desc[curr_device].blksz);
+
+			printf("%ld blocks read: %s\n",
+				n, (n==cnt) ? "OK" : "ERROR");
+			return (n == cnt) ? 0 : 1;
+		} else if (strcmp(argv[1], "write") == 0) {
+			ulong addr = simple_strtoul(argv[2], NULL, 16);
+			ulong cnt = simple_strtoul(argv[4], NULL, 16);
 			ulong n;
-			lbaint_t blk = simple_strtoul (argv[3], NULL, 16);
 
-			printf ("\nSata write: dev %d blk # %ld,"
-				"count %ld ... ", curr_dev, blk, cnt);
-			n = sata_write (curr_dev, blk, cnt, (ulong *) addr);
-			printf ("%ld blocks written: %s\n", n,
-				(n == cnt) ? "OK" : "ERR");
-			if (n == cnt)
-				return 1;
-			else
-				return 0;
+			lbaint_t blk = simple_strtoul(argv[3], NULL, 16);
+
+			printf("\nSATA write: device %d block # %ld, count %ld ... ",
+				curr_device, blk, cnt);
+
+			n = sata_write(curr_device, blk, cnt, (u32 *)addr);
+
+			printf("%ld blocks written: %s\n",
+				n, (n == cnt) ? "OK" : "ERROR");
+			return (n == cnt) ? 0 : 1;
 		} else {
-			printf ("Usage:\n%s\n", cmdtp->usage);
-			return 1;
+			printf("Usage:\n%s\n", cmdtp->usage);
+			rc = 1;
 		}
-	}			/*End OF SWITCH */
-}
 
-U_BOOT_CMD (sata, 5, 1, do_sata,
-	    "sata init\n"
-	    "sata info\n"
-	    "sata part device\n"
-	    "sata dev device\n"
-	    "sata read  addr blk# cnt\n"
-	    "sata write  addr blk# cnt\n", "cmd for init,rw and dev-info\n");
+		return rc;
+	}
+}
 
-#endif
+U_BOOT_CMD(
+	sata, 5, 1, do_sata,
+	"sata	- SATA sub system\n",
+	"sata info - show available SATA devices\n"
+	"sata device [dev] - show or set current device\n"
+	"sata part [dev] - print partition table\n"
+	"sata read addr blk# cnt\n"
+	"sata write addr blk# cnt\n");

+ 34 - 13
common/cmd_scsi.c

@@ -207,10 +207,13 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	char *boot_device = NULL;
 	char *ep;
 	int dev, part = 0;
-	ulong addr, cnt, checksum;
+	ulong addr, cnt;
 	disk_partition_t info;
 	image_header_t *hdr;
 	int rcode = 0;
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
 
 	switch (argc) {
 	case 1:
@@ -273,24 +276,35 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		return 1;
 	}
 
-	hdr = (image_header_t *)addr;
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
 
-	if (ntohl(hdr->ih_magic) == IH_MAGIC) {
-		printf("\n** Bad Magic Number **\n");
-		return 1;
-	}
+		if (!image_check_hcrc (hdr)) {
+			puts ("\n** Bad Header Checksum **\n");
+			return 1;
+		}
 
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
+		image_print_contents (hdr);
+		cnt = image_get_image_size (hdr);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		puts ("Fit image detected...\n");
 
-	if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) {
-		puts ("\n** Bad Header Checksum **\n");
+		cnt = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
+		puts ("** Unknown image type\n");
 		return 1;
 	}
-	hdr->ih_hcrc = htonl(checksum);	/* restore checksum for later use */
 
-	print_image_hdr (hdr);
-	cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
 	cnt += info.blksz - 1;
 	cnt /= info.blksz;
 	cnt -= 1;
@@ -300,6 +314,13 @@ int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		printf ("** Read error on %d:%d\n", dev, part);
 		return 1;
 	}
+
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
+
 	/* Loading ok, update default load address */
 	load_addr = addr;
 

+ 70 - 0
common/cmd_setexpr.c

@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, 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
+ */
+
+/*
+ * This file provides a shell like 'expr' function to return.
+ */
+
+#include <common.h>
+#include <config.h>
+#include <command.h>
+
+int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	ulong a, b;
+	char buf[16];
+
+	/* Validate arguments */
+	if ((argc != 5) || (strlen(argv[3]) != 1)) {
+		printf("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+	}
+
+	a = simple_strtoul(argv[2], NULL, 16);
+	b = simple_strtoul(argv[4], NULL, 16);
+
+	switch (argv[3][0]) {
+	case '|': sprintf(buf, "%lx", (a | b)); break;
+	case '&': sprintf(buf, "%lx", (a & b)); break;
+	case '+': sprintf(buf, "%lx", (a + b)); break;
+	case '^': sprintf(buf, "%lx", (a ^ b)); break;
+	case '-': sprintf(buf, "%lx", (a - b)); break;
+	case '*': sprintf(buf, "%lx", (a * b)); break;
+	case '/': sprintf(buf, "%lx", (a / b)); break;
+	case '%': sprintf(buf, "%lx", (a % b)); break;
+	default:
+		printf("invalid op\n");
+		return 1;
+	}
+
+	setenv(argv[1], buf);
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	setexpr, 5, 0, do_setexpr,
+	"setexpr - set environment variable as the result of eval expression\n",
+	"name value1 <op> value2\n"
+	"    - set environment variable 'name' to the result of the evaluated\n"
+	"      express specified by <op>.  <op> can be &, |, ^, +, -, *, /, %\n"
+);

+ 36 - 17
common/cmd_usb.c

@@ -311,11 +311,13 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	char *boot_device = NULL;
 	char *ep;
 	int dev, part=1, rcode;
-	ulong addr, cnt, checksum;
+	ulong addr, cnt;
 	disk_partition_t info;
 	image_header_t *hdr;
 	block_dev_desc_t *stor_dev;
-
+#if defined(CONFIG_FIT)
+	const void *fit_hdr;
+#endif
 
 	switch (argc) {
 	case 1:
@@ -386,25 +388,36 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		return 1;
 	}
 
-	hdr = (image_header_t *)addr;
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
+		hdr = (image_header_t *)addr;
 
-	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
-		printf("\n** Bad Magic Number **\n");
-		return 1;
-	}
+		if (!image_check_hcrc (hdr)) {
+			puts ("\n** Bad Header Checksum **\n");
+			return 1;
+		}
+
+		image_print_contents (hdr);
 
-	checksum = ntohl(hdr->ih_hcrc);
-	hdr->ih_hcrc = 0;
+		cnt = image_get_image_size (hdr);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			puts ("** Bad FIT image format\n");
+			return 1;
+		}
+		puts ("Fit image detected...\n");
 
-	if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) {
-		puts ("\n** Bad Header Checksum **\n");
+		cnt = fit_get_size (fit_hdr);
+		break;
+#endif
+	default:
+		puts ("** Unknown image type\n");
 		return 1;
 	}
-	hdr->ih_hcrc = htonl(checksum);	/* restore checksum for later use */
 
-	print_image_hdr (hdr);
-
-	cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
 	cnt += info.blksz - 1;
 	cnt /= info.blksz;
 	cnt -= 1;
@@ -414,6 +427,13 @@ int do_usbboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 		printf ("\n** Read error on %d:%d\n", dev, part);
 		return 1;
 	}
+
+#if defined(CONFIG_FIT)
+	/* This cannot be done earlier, we need complete FIT image in RAM first */
+	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT)
+		fit_print_contents ((const void *)addr);
+#endif
+
 	/* Loading ok, update default load address */
 	load_addr = addr;
 
@@ -529,8 +549,7 @@ int do_usb (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 	}
 
 	if (strncmp(argv[1], "stor", 4) == 0) {
-		usb_stor_info();
-		return 0;
+		return usb_stor_info();
 	}
 
 	if (strncmp(argv[1],"part",4) == 0) {

+ 107 - 61
common/cmd_ximg.c

@@ -24,7 +24,6 @@
  * MA 02111-1307 USA
  */
 
-#if defined(CONFIG_CMD_XIMG)
 
 /*
  * Multi Image extract
@@ -37,92 +36,136 @@
 int
 do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 {
-	ulong addr = load_addr, dest = 0;
-	ulong data, len, checksum;
-	ulong *len_ptr;
-	int i, verify, part = 0;
-	char pbuf[10], *s;
-	image_header_t header;
+	ulong		addr = load_addr;
+	ulong		dest = 0;
+	ulong		data, len, count;
+	int		verify;
+	int		part = 0;
+	char		pbuf[10];
+	image_header_t	*hdr;
+#if defined(CONFIG_FIT)
+	const char	*uname = NULL;
+	const void*	fit_hdr;
+	int		noffset;
+	const void	*fit_data;
+	size_t		fit_len;
+#endif
 
-	s = getenv("verify");
-	verify = (s && (*s == 'n')) ? 0 : 1;
+	verify = getenv_verify ();
 
 	if (argc > 1) {
 		addr = simple_strtoul(argv[1], NULL, 16);
 	}
 	if (argc > 2) {
 		part = simple_strtoul(argv[2], NULL, 16);
+#if defined(CONFIG_FIT)
+		uname = argv[2];
+#endif
 	}
 	if (argc > 3) {
 		dest = simple_strtoul(argv[3], NULL, 16);
 	}
 
-	printf("## Copying from image at %08lx ...\n", addr);
-
-	/* Copy header so we can blank CRC field for re-calculation */
-	memmove(&header, (char *) addr, sizeof (image_header_t));
-
-	if (ntohl(header.ih_magic) != IH_MAGIC) {
-		printf("Bad Magic Number\n");
-		return 1;
-	}
+	switch (genimg_get_format ((void *)addr)) {
+	case IMAGE_FORMAT_LEGACY:
 
-	data = (ulong) & header;
-	len = sizeof (image_header_t);
+		printf("## Copying part %d from legacy image "
+			"at %08lx ...\n", part, addr);
 
-	checksum = ntohl(header.ih_hcrc);
-	header.ih_hcrc = 0;
+		hdr = (image_header_t *)addr;
+		if (!image_check_magic (hdr)) {
+			printf("Bad Magic Number\n");
+			return 1;
+		}
 
-	if (crc32(0, (char *) data, len) != checksum) {
-		printf("Bad Header Checksum\n");
-		return 1;
-	}
+		if (!image_check_hcrc (hdr)) {
+			printf("Bad Header Checksum\n");
+			return 1;
+		}
 #ifdef DEBUG
-	print_image_hdr((image_header_t *) addr);
+		image_print_contents (hdr);
 #endif
 
-	data = addr + sizeof (image_header_t);
-	len = ntohl(header.ih_size);
+		if (!image_check_type (hdr, IH_TYPE_MULTI)) {
+			printf("Wrong Image Type for %s command\n",
+					cmdtp->name);
+			return 1;
+		}
 
-	if (header.ih_type != IH_TYPE_MULTI) {
-		printf("Wrong Image Type for %s command\n", cmdtp->name);
-		return 1;
-	}
+		if (image_get_comp (hdr) != IH_COMP_NONE) {
+			printf("Wrong Compression Type for %s command\n",
+					cmdtp->name);
+			return 1;
+		}
 
-	if (header.ih_comp != IH_COMP_NONE) {
-		printf("Wrong Compression Type for %s command\n", cmdtp->name);
-		return 1;
-	}
+		if (verify) {
+			printf("   Verifying Checksum ... ");
+			if (!image_check_dcrc (hdr)) {
+				printf("Bad Data CRC\n");
+				return 1;
+			}
+			printf("OK\n");
+		}
 
-	if (verify) {
-		printf("   Verifying Checksum ... ");
-		if (crc32(0, (char *) data, len) != ntohl(header.ih_dcrc)) {
-			printf("Bad Data CRC\n");
+		count = image_multi_count (hdr);
+		if (part >= count) {
+			printf("Bad Image Part\n");
+			return 1;
+		}
+
+		image_multi_getimg (hdr, part, &data, &len);
+		break;
+#if defined(CONFIG_FIT)
+	case IMAGE_FORMAT_FIT:
+		if (uname == NULL) {
+			puts ("No FIT subimage unit name\n");
+			return 1;
+		}
+
+		printf("## Copying '%s' subimage from FIT image "
+			"at %08lx ...\n", uname, addr);
+
+		fit_hdr = (const void *)addr;
+		if (!fit_check_format (fit_hdr)) {
+			puts ("Bad FIT image format\n");
+			return 1;
+		}
+
+		/* get subimage node offset */
+		noffset = fit_image_get_node (fit_hdr, uname);
+		if (noffset < 0) {
+			printf ("Can't find '%s' FIT subimage\n", uname);
 			return 1;
 		}
-		printf("OK\n");
-	}
 
-	len_ptr = (ulong *) data;
-
-	data += 4;		/* terminator */
-	for (i = 0; len_ptr[i]; ++i) {
-		data += 4;
-		if (argc > 2 && part > i) {
-			u_long tail;
-			len = ntohl(len_ptr[i]);
-			tail = len % 4;
-			data += len;
-			if (tail) {
-				data += 4 - tail;
+		if (fit_image_check_comp (fit_hdr, noffset, IH_COMP_NONE)) {
+			printf("Wrong Compression Type for %s command\n",
+					cmdtp->name);
+			return 1;
+		}
+
+		/* verify integrity */
+		if (verify) {
+			if (!fit_image_check_hashes (fit_hdr, noffset)) {
+				puts ("Bad Data Hash\n");
+				return 1;
 			}
 		}
-	}
-	if (argc > 2 && part >= i) {
-		printf("Bad Image Part\n");
+
+		/* get subimage data address and length */
+		if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) {
+			puts ("Could not find script subimage data\n");
+			return 1;
+		}
+
+		data = (ulong)fit_data;
+		len = (ulong)fit_len;
+		break;
+#endif
+	default:
+		puts ("Invalid image type for imxtract\n");
 		return 1;
 	}
-	len = ntohl(len_ptr[part]);
 
 	if (argc > 3) {
 		memcpy((char *) dest, (char *) data, len);
@@ -139,6 +182,9 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
 U_BOOT_CMD(imxtract, 4, 1, do_imgextract,
 	   "imxtract- extract a part of a multi-image\n",
 	   "addr part [dest]\n"
-	   "    - extract <part> from image at <addr> and copy to <dest>\n");
-
+	   "    - extract <part> from legacy image at <addr> and copy to <dest>\n"
+#if defined(CONFIG_FIT)
+	   "addr uname [dest]\n"
+	   "    - extract <uname> subimage from FIT image at <addr> and copy to <dest>\n"
 #endif
+);

+ 25 - 193
common/fdt_support.c

@@ -40,7 +40,6 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 struct fdt_header *fdt;
 
-/********************************************************************/
 
 /**
  * fdt_find_and_setprop: Find a node and set it's property
@@ -218,198 +217,6 @@ int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force)
 	return err;
 }
 
-/********************************************************************/
-
-#ifdef CONFIG_OF_HAS_UBOOT_ENV
-
-/* Function that returns a character from the environment */
-extern uchar(*env_get_char) (int);
-
-
-int fdt_env(void *fdt)
-{
-	int   nodeoffset;
-	int   err;
-	int   k, nxt;
-	int i;
-	static char tmpenv[256];
-
-	err = fdt_check_header(fdt);
-	if (err < 0) {
-		printf("fdt_env: %s\n", fdt_strerror(err));
-		return err;
-	}
-
-	/*
-	 * See if we already have a "u-boot-env" node, delete it if so.
-	 * Then create a new empty node.
-	 */
-	nodeoffset = fdt_path_offset (fdt, "/u-boot-env");
-	if (nodeoffset >= 0) {
-		err = fdt_del_node(fdt, nodeoffset);
-		if (err < 0) {
-			printf("fdt_env: %s\n", fdt_strerror(err));
-			return err;
-		}
-	}
-	/*
-	 * Create a new node "/u-boot-env" (offset 0 is root level)
-	 */
-	nodeoffset = fdt_add_subnode(fdt, 0, "u-boot-env");
-	if (nodeoffset < 0) {
-		printf("WARNING: could not create /u-boot-env %s.\n",
-			fdt_strerror(nodeoffset));
-		return nodeoffset;
-	}
-
-	for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) {
-		char *s, *lval, *rval;
-
-		/*
-		 * Find the end of the name=definition
-		 */
-		for (nxt = i; env_get_char(nxt) != '\0'; ++nxt)
-			;
-		s = tmpenv;
-		for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k)
-			*s++ = env_get_char(k);
-		*s++ = '\0';
-		lval = tmpenv;
-		/*
-		 * Find the first '=': it separates the name from the value
-		 */
-		s = strchr(tmpenv, '=');
-		if (s != NULL) {
-			*s++ = '\0';
-			rval = s;
-		} else
-			continue;
-		err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1);
-		if (err < 0) {
-			printf("WARNING: could not set %s %s.\n",
-				lval, fdt_strerror(err));
-			return err;
-		}
-	}
-	return 0;
-}
-#endif /* ifdef CONFIG_OF_HAS_UBOOT_ENV */
-
-/********************************************************************/
-
-#ifdef CONFIG_OF_HAS_BD_T
-
-#define BDM(x)	{	.name = #x, .offset = offsetof(bd_t, bi_ ##x ) }
-
-static const struct {
-	const char *name;
-	int offset;
-} bd_map[] = {
-	BDM(memstart),
-	BDM(memsize),
-	BDM(flashstart),
-	BDM(flashsize),
-	BDM(flashoffset),
-	BDM(sramstart),
-	BDM(sramsize),
-#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \
-	|| defined(CONFIG_E500)
-	BDM(immr_base),
-#endif
-#if defined(CONFIG_MPC5xxx)
-	BDM(mbar_base),
-#endif
-#if defined(CONFIG_MPC83XX)
-	BDM(immrbar),
-#endif
-#if defined(CONFIG_MPC8220)
-	BDM(mbar_base),
-	BDM(inpfreq),
-	BDM(pcifreq),
-	BDM(pevfreq),
-	BDM(flbfreq),
-	BDM(vcofreq),
-#endif
-	BDM(bootflags),
-	BDM(ip_addr),
-	BDM(intfreq),
-	BDM(busfreq),
-#ifdef CONFIG_CPM2
-	BDM(cpmfreq),
-	BDM(brgfreq),
-	BDM(sccfreq),
-	BDM(vco),
-#endif
-#if defined(CONFIG_MPC5xxx)
-	BDM(ipbfreq),
-	BDM(pcifreq),
-#endif
-	BDM(baudrate),
-};
-
-
-int fdt_bd_t(void *fdt)
-{
-	bd_t *bd = gd->bd;
-	int   nodeoffset;
-	int   err;
-	u32   tmp;		/* used to set 32 bit integer properties */
-	int i;
-
-	err = fdt_check_header(fdt);
-	if (err < 0) {
-		printf("fdt_bd_t: %s\n", fdt_strerror(err));
-		return err;
-	}
-
-	/*
-	 * See if we already have a "bd_t" node, delete it if so.
-	 * Then create a new empty node.
-	 */
-	nodeoffset = fdt_path_offset (fdt, "/bd_t");
-	if (nodeoffset >= 0) {
-		err = fdt_del_node(fdt, nodeoffset);
-		if (err < 0) {
-			printf("fdt_bd_t: %s\n", fdt_strerror(err));
-			return err;
-		}
-	}
-	/*
-	 * Create a new node "/bd_t" (offset 0 is root level)
-	 */
-	nodeoffset = fdt_add_subnode(fdt, 0, "bd_t");
-	if (nodeoffset < 0) {
-		printf("WARNING: could not create /bd_t %s.\n",
-			fdt_strerror(nodeoffset));
-		printf("fdt_bd_t: %s\n", fdt_strerror(nodeoffset));
-		return nodeoffset;
-	}
-	/*
-	 * Use the string/pointer structure to create the entries...
-	 */
-	for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) {
-		tmp = cpu_to_be32(getenv("bootargs"));
-		err = fdt_setprop(fdt, nodeoffset,
-			bd_map[i].name, &tmp, sizeof(tmp));
-		if (err < 0)
-			printf("WARNING: could not set %s %s.\n",
-				bd_map[i].name, fdt_strerror(err));
-	}
-	/*
-	 * Add a couple of oddball entries...
-	 */
-	err = fdt_setprop(fdt, nodeoffset, "enetaddr", &bd->bi_enetaddr, 6);
-	if (err < 0)
-		printf("WARNING: could not set enetaddr %s.\n",
-			fdt_strerror(err));
-	err = fdt_setprop(fdt, nodeoffset, "ethspeed", &bd->bi_ethspeed, 4);
-	if (err < 0)
-		printf("WARNING: could not set ethspeed %s.\n",
-			fdt_strerror(err));
-	return 0;
-}
-#endif /* ifdef CONFIG_OF_HAS_BD_T */
-
 void do_fixup_by_path(void *fdt, const char *path, const char *prop,
 		      const void *val, int len, int create)
 {
@@ -615,3 +422,28 @@ void fdt_fixup_ethernet(void *fdt, bd_t *bd)
 	}
 }
 #endif
+
+#ifdef CONFIG_HAS_FSL_DR_USB
+void fdt_fixup_dr_usb(void *blob, bd_t *bd)
+{
+	char *mode;
+	const char *compat = "fsl-usb2-dr";
+	const char *prop = "dr_mode";
+	int node_offset;
+	int err;
+
+	mode = getenv("usb_dr_mode");
+	if (!mode)
+		return;
+
+	node_offset = fdt_node_offset_by_compatible(blob, 0, compat);
+	if (node_offset < 0)
+		printf("WARNING: could not find compatible node %s: %s.\n",
+			compat, fdt_strerror(node_offset));
+
+	err = fdt_setprop(blob, node_offset, prop, mode, strlen(mode) + 1);
+	if (err < 0)
+		printf("WARNING: could not set %s for %s: %s.\n",
+		       prop, compat, fdt_strerror(err));
+}
+#endif /* CONFIG_HAS_FSL_DR_USB */

+ 113 - 0
common/gunzip.c

@@ -0,0 +1,113 @@
+/*
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <image.h>
+#include <malloc.h>
+#include <zlib.h>
+
+#define	ZALLOC_ALIGNMENT	16
+#define HEAD_CRC		2
+#define EXTRA_FIELD		4
+#define ORIG_NAME		8
+#define COMMENT			0x10
+#define RESERVED		0xe0
+#define DEFLATED		8
+
+int gunzip(void *, int, unsigned char *, unsigned long *);
+void *zalloc(void *, unsigned, unsigned);
+void zfree(void *, void *, unsigned);
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+	void *p;
+
+	size *= items;
+	size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
+
+	p = malloc (size);
+
+	return (p);
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+	free (addr);
+}
+
+int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp)
+{
+	z_stream s;
+	int r, i, flags;
+
+	/* skip header */
+	i = 10;
+	flags = src[3];
+	if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+		puts ("Error: Bad gzipped data\n");
+		return (-1);
+	}
+	if ((flags & EXTRA_FIELD) != 0)
+		i = 12 + src[10] + (src[11] << 8);
+	if ((flags & ORIG_NAME) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & COMMENT) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & HEAD_CRC) != 0)
+		i += 2;
+	if (i >= *lenp) {
+		puts ("Error: gunzip out of data in header\n");
+		return (-1);
+	}
+
+	s.zalloc = zalloc;
+	s.zfree = zfree;
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	s.outcb = (cb_func)WATCHDOG_RESET;
+#else
+	s.outcb = Z_NULL;
+#endif	/* CONFIG_HW_WATCHDOG */
+
+	r = inflateInit2(&s, -MAX_WBITS);
+	if (r != Z_OK) {
+		printf ("Error: inflateInit2() returned %d\n", r);
+		return (-1);
+	}
+	s.next_in = src + i;
+	s.avail_in = *lenp - i;
+	s.next_out = dst;
+	s.avail_out = dstlen;
+	r = inflate(&s, Z_FINISH);
+	if (r != Z_OK && r != Z_STREAM_END) {
+		printf ("Error: inflate() returned %d\n", r);
+		return (-1);
+	}
+	*lenp = s.next_out - (unsigned char *) dst;
+	inflateEnd(&s);
+
+	return (0);
+}

+ 2541 - 0
common/image.c

@@ -0,0 +1,2541 @@
+/*
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2006
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+
+#ifndef USE_HOSTCC
+#include <common.h>
+#include <watchdog.h>
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+#include <status_led.h>
+#endif
+
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+#endif
+
+#ifdef CONFIG_LOGBUFFER
+#include <logbuff.h>
+#endif
+
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)
+#include <rtc.h>
+#endif
+
+#include <image.h>
+
+#if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT)
+#include <fdt.h>
+#include <libfdt.h>
+#include <fdt_support.h>
+#endif
+
+#if defined(CONFIG_FIT)
+#include <md5.h>
+#include <sha1.h>
+
+static int fit_check_ramdisk (const void *fit, int os_noffset,
+		uint8_t arch, int verify);
+#endif
+
+#ifdef CONFIG_CMD_BDI
+extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
+						int verify);
+#else
+#include "mkimage.h"
+#include <md5.h>
+#include <time.h>
+#include <image.h>
+#endif /* !USE_HOSTCC*/
+
+typedef struct table_entry {
+	int	id;		/* as defined in image.h	*/
+	char	*sname;		/* short (input) name		*/
+	char	*lname;		/* long (output) name		*/
+} table_entry_t;
+
+static table_entry_t uimage_arch[] = {
+	{	IH_ARCH_INVALID,	NULL,		"Invalid ARCH",	},
+	{	IH_ARCH_ALPHA,		"alpha",	"Alpha",	},
+	{	IH_ARCH_ARM,		"arm",		"ARM",		},
+	{	IH_ARCH_I386,		"x86",		"Intel x86",	},
+	{	IH_ARCH_IA64,		"ia64",		"IA64",		},
+	{	IH_ARCH_M68K,		"m68k",		"M68K",		},
+	{	IH_ARCH_MICROBLAZE,	"microblaze",	"MicroBlaze",	},
+	{	IH_ARCH_MIPS,		"mips",		"MIPS",		},
+	{	IH_ARCH_MIPS64,		"mips64",	"MIPS 64 Bit",	},
+	{	IH_ARCH_NIOS,		"nios",		"NIOS",		},
+	{	IH_ARCH_NIOS2,		"nios2",	"NIOS II",	},
+	{	IH_ARCH_PPC,		"ppc",		"PowerPC",	},
+	{	IH_ARCH_S390,		"s390",		"IBM S390",	},
+	{	IH_ARCH_SH,		"sh",		"SuperH",	},
+	{	IH_ARCH_SPARC,		"sparc",	"SPARC",	},
+	{	IH_ARCH_SPARC64,	"sparc64",	"SPARC 64 Bit",	},
+	{	IH_ARCH_BLACKFIN,	"blackfin",	"Blackfin",	},
+	{	IH_ARCH_AVR32,		"avr32",	"AVR32",	},
+	{	-1,			"",		"",		},
+};
+
+static table_entry_t uimage_os[] = {
+	{	IH_OS_INVALID,	NULL,		"Invalid OS",		},
+#if defined(CONFIG_ARTOS) || defined(USE_HOSTCC)
+	{	IH_OS_ARTOS,	"artos",	"ARTOS",		},
+#endif
+	{	IH_OS_LINUX,	"linux",	"Linux",		},
+#if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)
+	{	IH_OS_LYNXOS,	"lynxos",	"LynxOS",		},
+#endif
+	{	IH_OS_NETBSD,	"netbsd",	"NetBSD",		},
+	{	IH_OS_RTEMS,	"rtems",	"RTEMS",		},
+	{	IH_OS_U_BOOT,	"u-boot",	"U-Boot",		},
+#if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
+	{	IH_OS_QNX,	"qnx",		"QNX",			},
+	{	IH_OS_VXWORKS,	"vxworks",	"VxWorks",		},
+#endif
+#ifdef USE_HOSTCC
+	{	IH_OS_4_4BSD,	"4_4bsd",	"4_4BSD",		},
+	{	IH_OS_DELL,	"dell",		"Dell",			},
+	{	IH_OS_ESIX,	"esix",		"Esix",			},
+	{	IH_OS_FREEBSD,	"freebsd",	"FreeBSD",		},
+	{	IH_OS_IRIX,	"irix",		"Irix",			},
+	{	IH_OS_NCR,	"ncr",		"NCR",			},
+	{	IH_OS_OPENBSD,	"openbsd",	"OpenBSD",		},
+	{	IH_OS_PSOS,	"psos",		"pSOS",			},
+	{	IH_OS_SCO,	"sco",		"SCO",			},
+	{	IH_OS_SOLARIS,	"solaris",	"Solaris",		},
+	{	IH_OS_SVR4,	"svr4",		"SVR4",			},
+#endif
+	{	-1,		"",		"",			},
+};
+
+static table_entry_t uimage_type[] = {
+	{	IH_TYPE_INVALID,    NULL,	  "Invalid Image",	},
+	{	IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",	},
+	{	IH_TYPE_FIRMWARE,   "firmware",	  "Firmware",		},
+	{	IH_TYPE_KERNEL,	    "kernel",	  "Kernel Image",	},
+	{	IH_TYPE_MULTI,	    "multi",	  "Multi-File Image",	},
+	{	IH_TYPE_RAMDISK,    "ramdisk",	  "RAMDisk Image",	},
+	{	IH_TYPE_SCRIPT,     "script",	  "Script",		},
+	{	IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
+	{	IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",	},
+	{	-1,		    "",		  "",			},
+};
+
+static table_entry_t uimage_comp[] = {
+	{	IH_COMP_NONE,	"none",		"uncompressed",		},
+	{	IH_COMP_BZIP2,	"bzip2",	"bzip2 compressed",	},
+	{	IH_COMP_GZIP,	"gzip",		"gzip compressed",	},
+	{	-1,		"",		"",			},
+};
+
+unsigned long crc32 (unsigned long, const unsigned char *, unsigned int);
+static void genimg_print_size (uint32_t size);
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
+static void genimg_print_time (time_t timestamp);
+#endif
+
+/*****************************************************************************/
+/* Legacy format routines */
+/*****************************************************************************/
+int image_check_hcrc (image_header_t *hdr)
+{
+	ulong hcrc;
+	ulong len = image_get_header_size ();
+	image_header_t header;
+
+	/* Copy header so we can blank CRC field for re-calculation */
+	memmove (&header, (char *)hdr, image_get_header_size ());
+	image_set_hcrc (&header, 0);
+
+	hcrc = crc32 (0, (unsigned char *)&header, len);
+
+	return (hcrc == image_get_hcrc (hdr));
+}
+
+int image_check_dcrc (image_header_t *hdr)
+{
+	ulong data = image_get_data (hdr);
+	ulong len = image_get_data_size (hdr);
+	ulong dcrc = crc32 (0, (unsigned char *)data, len);
+
+	return (dcrc == image_get_dcrc (hdr));
+}
+
+#ifndef USE_HOSTCC
+int image_check_dcrc_wd (image_header_t *hdr, ulong chunksz)
+{
+	ulong dcrc = 0;
+	ulong len = image_get_data_size (hdr);
+	ulong data = image_get_data (hdr);
+
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	ulong cdata = data;
+	ulong edata = cdata + len;
+
+	while (cdata < edata) {
+		ulong chunk = edata - cdata;
+
+		if (chunk > chunksz)
+			chunk = chunksz;
+		dcrc = crc32 (dcrc, (unsigned char *)cdata, chunk);
+		cdata += chunk;
+
+		WATCHDOG_RESET ();
+	}
+#else
+	dcrc = crc32 (0, (unsigned char *)data, len);
+#endif
+
+	return (dcrc == image_get_dcrc (hdr));
+}
+#endif /* !USE_HOSTCC */
+
+/**
+ * image_multi_count - get component (sub-image) count
+ * @hdr: pointer to the header of the multi component image
+ *
+ * image_multi_count() returns number of components in a multi
+ * component image.
+ *
+ * Note: no checking of the image type is done, caller must pass
+ * a valid multi component image.
+ *
+ * returns:
+ *     number of components
+ */
+ulong image_multi_count (image_header_t *hdr)
+{
+	ulong i, count = 0;
+	uint32_t *size;
+
+	/* get start of the image payload, which in case of multi
+	 * component images that points to a table of component sizes */
+	size = (uint32_t *)image_get_data (hdr);
+
+	/* count non empty slots */
+	for (i = 0; size[i]; ++i)
+		count++;
+
+	return count;
+}
+
+/**
+ * image_multi_getimg - get component data address and size
+ * @hdr: pointer to the header of the multi component image
+ * @idx: index of the requested component
+ * @data: pointer to a ulong variable, will hold component data address
+ * @len: pointer to a ulong variable, will hold component size
+ *
+ * image_multi_getimg() returns size and data address for the requested
+ * component in a multi component image.
+ *
+ * Note: no checking of the image type is done, caller must pass
+ * a valid multi component image.
+ *
+ * returns:
+ *     data address and size of the component, if idx is valid
+ *     0 in data and len, if idx is out of range
+ */
+void image_multi_getimg (image_header_t *hdr, ulong idx,
+			ulong *data, ulong *len)
+{
+	int i;
+	uint32_t *size;
+	ulong offset, tail, count, img_data;
+
+	/* get number of component */
+	count = image_multi_count (hdr);
+
+	/* get start of the image payload, which in case of multi
+	 * component images that points to a table of component sizes */
+	size = (uint32_t *)image_get_data (hdr);
+
+	/* get address of the proper component data start, which means
+	 * skipping sizes table (add 1 for last, null entry) */
+	img_data = image_get_data (hdr) + (count + 1) * sizeof (uint32_t);
+
+	if (idx < count) {
+		*len = uimage_to_cpu (size[idx]);
+		offset = 0;
+		tail = 0;
+
+		/* go over all indices preceding requested component idx */
+		for (i = 0; i < idx; i++) {
+			/* add up i-th component size */
+			offset += uimage_to_cpu (size[i]);
+
+			/* add up alignment for i-th component */
+			tail += (4 - uimage_to_cpu (size[i]) % 4);
+		}
+
+		/* calculate idx-th component data address */
+		*data = img_data + offset + tail;
+	} else {
+		*len = 0;
+		*data = 0;
+	}
+}
+
+static void image_print_type (image_header_t *hdr)
+{
+	const char *os, *arch, *type, *comp;
+
+	os = genimg_get_os_name (image_get_os (hdr));
+	arch = genimg_get_arch_name (image_get_arch (hdr));
+	type = genimg_get_type_name (image_get_type (hdr));
+	comp = genimg_get_comp_name (image_get_comp (hdr));
+
+	printf ("%s %s %s (%s)\n", arch, os, type, comp);
+}
+
+/**
+ * __image_print_contents - prints out the contents of the legacy format image
+ * @hdr: pointer to the legacy format image header
+ * @p: pointer to prefix string
+ *
+ * __image_print_contents() formats a multi line legacy image contents description.
+ * The routine prints out all header fields followed by the size/offset data
+ * for MULTI/SCRIPT images.
+ *
+ * returns:
+ *     no returned results
+ */
+static void __image_print_contents (image_header_t *hdr, const char *p)
+{
+	printf ("%sImage Name:   %.*s\n", p, IH_NMLEN, image_get_name (hdr));
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
+	printf ("%sCreated:      ", p);
+	genimg_print_time ((time_t)image_get_time (hdr));
+#endif
+	printf ("%sImage Type:   ", p);
+	image_print_type (hdr);
+	printf ("%sData Size:    ", p);
+	genimg_print_size (image_get_data_size (hdr));
+	printf ("%sLoad Address: %08x\n", p, image_get_load (hdr));
+	printf ("%sEntry Point:  %08x\n", p, image_get_ep (hdr));
+
+	if (image_check_type (hdr, IH_TYPE_MULTI) ||
+			image_check_type (hdr, IH_TYPE_SCRIPT)) {
+		int i;
+		ulong data, len;
+		ulong count = image_multi_count (hdr);
+
+		printf ("%sContents:\n", p);
+		for (i = 0; i < count; i++) {
+			image_multi_getimg (hdr, i, &data, &len);
+
+			printf ("%s   Image %d: ", p, i);
+			genimg_print_size (len);
+
+			if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) {
+				/*
+				 * the user may need to know offsets
+				 * if planning to do something with
+				 * multiple files
+				 */
+				printf ("%s    Offset = 0x%08lx\n", p, data);
+			}
+		}
+	}
+}
+
+inline void image_print_contents (image_header_t *hdr)
+{
+	__image_print_contents (hdr, "   ");
+}
+
+inline void image_print_contents_noindent (image_header_t *hdr)
+{
+	__image_print_contents (hdr, "");
+}
+
+#ifndef USE_HOSTCC
+/**
+ * image_get_ramdisk - get and verify ramdisk image
+ * @rd_addr: ramdisk image start address
+ * @arch: expected ramdisk architecture
+ * @verify: checksum verification flag
+ *
+ * image_get_ramdisk() returns a pointer to the verified ramdisk image
+ * header. Routine receives image start address and expected architecture
+ * flag. Verification done covers data and header integrity and os/type/arch
+ * fields checking.
+ *
+ * If dataflash support is enabled routine checks for dataflash addresses
+ * and handles required dataflash reads.
+ *
+ * returns:
+ *     pointer to a ramdisk image header, if image was found and valid
+ *     otherwise, return NULL
+ */
+static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,
+						int verify)
+{
+	image_header_t *rd_hdr = (image_header_t *)rd_addr;
+
+	if (!image_check_magic (rd_hdr)) {
+		puts ("Bad Magic Number\n");
+		show_boot_progress (-10);
+		return NULL;
+	}
+
+	if (!image_check_hcrc (rd_hdr)) {
+		puts ("Bad Header Checksum\n");
+		show_boot_progress (-11);
+		return NULL;
+	}
+
+	show_boot_progress (10);
+	image_print_contents (rd_hdr);
+
+	if (verify) {
+		puts("   Verifying Checksum ... ");
+		if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
+			puts ("Bad Data CRC\n");
+			show_boot_progress (-12);
+			return NULL;
+		}
+		puts("OK\n");
+	}
+
+	show_boot_progress (11);
+
+	if (!image_check_os (rd_hdr, IH_OS_LINUX) ||
+	    !image_check_arch (rd_hdr, arch) ||
+	    !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {
+		printf ("No Linux %s Ramdisk Image\n",
+				genimg_get_arch_name(arch));
+		show_boot_progress (-13);
+		return NULL;
+	}
+
+	return rd_hdr;
+}
+#endif /* !USE_HOSTCC */
+
+/*****************************************************************************/
+/* Shared dual-format routines */
+/*****************************************************************************/
+#ifndef USE_HOSTCC
+int getenv_verify (void)
+{
+	char *s = getenv ("verify");
+	return (s && (*s == 'n')) ? 0 : 1;
+}
+
+int getenv_autostart (void)
+{
+	char *s = getenv ("autostart");
+	return (s && (*s == 'n')) ? 0 : 1;
+}
+
+ulong getenv_bootm_low(void)
+{
+	char *s = getenv ("bootm_low");
+	if (s) {
+		ulong tmp = simple_strtoul (s, NULL, 16);
+		return tmp;
+	}
+
+#if defined(CFG_SDRAM_BASE)
+	return CFG_SDRAM_BASE;
+#elif defined(CONFIG_ARM)
+	return gd->bd->bi_dram[0].start;
+#else
+	return 0;
+#endif
+}
+
+ulong getenv_bootm_size(void)
+{
+	char *s = getenv ("bootm_size");
+	if (s) {
+		ulong tmp = simple_strtoul (s, NULL, 16);
+		return tmp;
+	}
+
+#if defined(CONFIG_ARM)
+	return gd->bd->bi_dram[0].size;
+#else
+	return gd->bd->bi_memsize;
+#endif
+}
+
+void memmove_wd (void *to, void *from, size_t len, ulong chunksz)
+{
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+	while (len > 0) {
+		size_t tail = (len > chunksz) ? chunksz : len;
+		WATCHDOG_RESET ();
+		memmove (to, from, tail);
+		to += tail;
+		from += tail;
+		len -= tail;
+	}
+#else	/* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
+	memmove (to, from, len);
+#endif	/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
+}
+#endif /* !USE_HOSTCC */
+
+static void genimg_print_size (uint32_t size)
+{
+#ifndef USE_HOSTCC
+	printf ("%d Bytes = ", size);
+	print_size (size, "\n");
+#else
+	printf ("%d Bytes = %.2f kB = %.2f MB\n",
+			size, (double)size / 1.024e3,
+			(double)size / 1.048576e6);
+#endif
+}
+
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
+static void genimg_print_time (time_t timestamp)
+{
+#ifndef USE_HOSTCC
+	struct rtc_time tm;
+
+	to_tm (timestamp, &tm);
+	printf ("%4d-%02d-%02d  %2d:%02d:%02d UTC\n",
+			tm.tm_year, tm.tm_mon, tm.tm_mday,
+			tm.tm_hour, tm.tm_min, tm.tm_sec);
+#else
+	printf ("%s", ctime(&timestamp));
+#endif
+}
+#endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC */
+
+/**
+ * get_table_entry_name - translate entry id to long name
+ * @table: pointer to a translation table for entries of a specific type
+ * @msg: message to be returned when translation fails
+ * @id: entry id to be translated
+ *
+ * get_table_entry_name() will go over translation table trying to find
+ * entry that matches given id. If matching entry is found, its long
+ * name is returned to the caller.
+ *
+ * returns:
+ *     long entry name if translation succeeds
+ *     msg otherwise
+ */
+static char *get_table_entry_name (table_entry_t *table, char *msg, int id)
+{
+	for (; table->id >= 0; ++table) {
+		if (table->id == id)
+			return (table->lname);
+	}
+	return (msg);
+}
+
+const char *genimg_get_os_name (uint8_t os)
+{
+	return (get_table_entry_name (uimage_os, "Unknown OS", os));
+}
+
+const char *genimg_get_arch_name (uint8_t arch)
+{
+	return (get_table_entry_name (uimage_arch, "Unknown Architecture", arch));
+}
+
+const char *genimg_get_type_name (uint8_t type)
+{
+	return (get_table_entry_name (uimage_type, "Unknown Image", type));
+}
+
+const char *genimg_get_comp_name (uint8_t comp)
+{
+	return (get_table_entry_name (uimage_comp, "Unknown Compression", comp));
+}
+
+/**
+ * get_table_entry_id - translate short entry name to id
+ * @table: pointer to a translation table for entries of a specific type
+ * @table_name: to be used in case of error
+ * @name: entry short name to be translated
+ *
+ * get_table_entry_id() will go over translation table trying to find
+ * entry that matches given short name. If matching entry is found,
+ * its id returned to the caller.
+ *
+ * returns:
+ *     entry id if translation succeeds
+ *     -1 otherwise
+ */
+static int get_table_entry_id (table_entry_t *table,
+		const char *table_name, const char *name)
+{
+	table_entry_t *t;
+#ifdef USE_HOSTCC
+	int first = 1;
+
+	for (t = table; t->id >= 0; ++t) {
+		if (t->sname && strcasecmp(t->sname, name) == 0)
+			return (t->id);
+	}
+
+	fprintf (stderr, "\nInvalid %s Type - valid names are", table_name);
+	for (t = table; t->id >= 0; ++t) {
+		if (t->sname == NULL)
+			continue;
+		fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname);
+		first = 0;
+	}
+	fprintf (stderr, "\n");
+#else
+	for (t = table; t->id >= 0; ++t) {
+		if (t->sname && strcmp(t->sname, name) == 0)
+			return (t->id);
+	}
+	debug ("Invalid %s Type: %s\n", table_name, name);
+#endif /* USE_HOSTCC */
+	return (-1);
+}
+
+int genimg_get_os_id (const char *name)
+{
+	return (get_table_entry_id (uimage_os, "OS", name));
+}
+
+int genimg_get_arch_id (const char *name)
+{
+	return (get_table_entry_id (uimage_arch, "CPU", name));
+}
+
+int genimg_get_type_id (const char *name)
+{
+	return (get_table_entry_id (uimage_type, "Image", name));
+}
+
+int genimg_get_comp_id (const char *name)
+{
+	return (get_table_entry_id (uimage_comp, "Compression", name));
+}
+
+#ifndef USE_HOSTCC
+/**
+ * genimg_get_format - get image format type
+ * @img_addr: image start address
+ *
+ * genimg_get_format() checks whether provided address points to a valid
+ * legacy or FIT image.
+ *
+ * New uImage format and FDT blob are based on a libfdt. FDT blob
+ * may be passed directly or embedded in a FIT image. In both situations
+ * genimg_get_format() must be able to dectect libfdt header.
+ *
+ * returns:
+ *     image format type or IMAGE_FORMAT_INVALID if no image is present
+ */
+int genimg_get_format (void *img_addr)
+{
+	ulong		format = IMAGE_FORMAT_INVALID;
+	image_header_t	*hdr;
+#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
+	char		*fit_hdr;
+#endif
+
+	hdr = (image_header_t *)img_addr;
+	if (image_check_magic(hdr))
+		format = IMAGE_FORMAT_LEGACY;
+#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
+	else {
+		fit_hdr = (char *)img_addr;
+		if (fdt_check_header (fit_hdr) == 0)
+			format = IMAGE_FORMAT_FIT;
+	}
+#endif
+
+	return format;
+}
+
+/**
+ * genimg_get_image - get image from special storage (if necessary)
+ * @img_addr: image start address
+ *
+ * genimg_get_image() checks if provided image start adddress is located
+ * in a dataflash storage. If so, image is moved to a system RAM memory.
+ *
+ * returns:
+ *     image start address after possible relocation from special storage
+ */
+ulong genimg_get_image (ulong img_addr)
+{
+	ulong ram_addr = img_addr;
+
+#ifdef CONFIG_HAS_DATAFLASH
+	ulong h_size, d_size;
+
+	if (addr_dataflash (img_addr)){
+		/* ger RAM address */
+		ram_addr = CFG_LOAD_ADDR;
+
+		/* get header size */
+		h_size = image_get_header_size ();
+#if defined(CONFIG_FIT)
+		if (sizeof(struct fdt_header) > h_size)
+			h_size = sizeof(struct fdt_header);
+#endif
+
+		/* read in header */
+		debug ("   Reading image header from dataflash address "
+			"%08lx to RAM address %08lx\n", img_addr, ram_addr);
+
+		read_dataflash (img_addr, h_size, (char *)ram_addr);
+
+		/* get data size */
+		switch (genimg_get_format ((void *)ram_addr)) {
+		case IMAGE_FORMAT_LEGACY:
+			d_size = image_get_data_size ((image_header_t *)ram_addr);
+			debug ("   Legacy format image found at 0x%08lx, size 0x%08lx\n",
+					ram_addr, d_size);
+			break;
+#if defined(CONFIG_FIT)
+		case IMAGE_FORMAT_FIT:
+			d_size = fit_get_size ((const void *)ram_addr) - h_size;
+			debug ("   FIT/FDT format image found at 0x%08lx, size 0x%08lx\n",
+					ram_addr, d_size);
+			break;
+#endif
+		default:
+			printf ("   No valid image found at 0x%08lx\n", img_addr);
+			return ram_addr;
+		}
+
+		/* read in image data */
+		debug ("   Reading image remaining data from dataflash address "
+			"%08lx to RAM address %08lx\n", img_addr + h_size,
+			ram_addr + h_size);
+
+		read_dataflash (img_addr + h_size, d_size,
+				(char *)(ram_addr + h_size));
+
+	}
+#endif /* CONFIG_HAS_DATAFLASH */
+
+	return ram_addr;
+}
+
+/**
+ * fit_has_config - check if there is a valid FIT configuration
+ * @images: pointer to the bootm command headers structure
+ *
+ * fit_has_config() checks if there is a FIT configuration in use
+ * (if FTI support is present).
+ *
+ * returns:
+ *     0, no FIT support or no configuration found
+ *     1, configuration found
+ */
+int genimg_has_config (bootm_headers_t *images)
+{
+#if defined(CONFIG_FIT)
+	if (images->fit_uname_cfg)
+		return 1;
+#endif
+	return 0;
+}
+
+/**
+ * boot_get_ramdisk - main ramdisk handling routine
+ * @argc: command argument count
+ * @argv: command argument list
+ * @images: pointer to the bootm images structure
+ * @arch: expected ramdisk architecture
+ * @rd_start: pointer to a ulong variable, will hold ramdisk start address
+ * @rd_end: pointer to a ulong variable, will hold ramdisk end
+ *
+ * boot_get_ramdisk() is responsible for finding a valid ramdisk image.
+ * Curently supported are the following ramdisk sources:
+ *      - multicomponent kernel/ramdisk image,
+ *      - commandline provided address of decicated ramdisk image.
+ *
+ * returns:
+ *     0, if ramdisk image was found and valid, or skiped
+ *     rd_start and rd_end are set to ramdisk start/end addresses if
+ *     ramdisk image is found and valid
+ *
+ *     1, if ramdisk image is found but corrupted
+ *     rd_start and rd_end are set to 0 if no ramdisk exists
+ */
+int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
+		uint8_t arch, ulong *rd_start, ulong *rd_end)
+{
+	ulong rd_addr, rd_load;
+	ulong rd_data, rd_len;
+	image_header_t *rd_hdr;
+#if defined(CONFIG_FIT)
+	void		*fit_hdr;
+	const char	*fit_uname_config = NULL;
+	const char	*fit_uname_ramdisk = NULL;
+	ulong		default_addr;
+	int		rd_noffset;
+	int		cfg_noffset;
+	const void	*data;
+	size_t		size;
+#endif
+
+	*rd_start = 0;
+	*rd_end = 0;
+
+	/*
+	 * Look for a '-' which indicates to ignore the
+	 * ramdisk argument
+	 */
+	if ((argc >= 3) && (strcmp(argv[2], "-") ==  0)) {
+		debug ("## Skipping init Ramdisk\n");
+		rd_len = rd_data = 0;
+	} else if (argc >= 3 || genimg_has_config (images)) {
+#if defined(CONFIG_FIT)
+		if (argc >= 3) {
+			/*
+			 * If the init ramdisk comes from the FIT image and
+			 * the FIT image address is omitted in the command
+			 * line argument, try to use os FIT image address or
+			 * default load address.
+			 */
+			if (images->fit_uname_os)
+				default_addr = (ulong)images->fit_hdr_os;
+			else
+				default_addr = load_addr;
+
+			if (fit_parse_conf (argv[2], default_addr,
+						&rd_addr, &fit_uname_config)) {
+				debug ("*  ramdisk: config '%s' from image at 0x%08lx\n",
+						fit_uname_config, rd_addr);
+			} else if (fit_parse_subimage (argv[2], default_addr,
+						&rd_addr, &fit_uname_ramdisk)) {
+				debug ("*  ramdisk: subimage '%s' from image at 0x%08lx\n",
+						fit_uname_ramdisk, rd_addr);
+			} else
+#endif
+			{
+				rd_addr = simple_strtoul(argv[2], NULL, 16);
+				debug ("*  ramdisk: cmdline image address = 0x%08lx\n",
+						rd_addr);
+			}
+#if defined(CONFIG_FIT)
+		} else {
+			/* use FIT configuration provided in first bootm
+			 * command argument
+			 */
+			rd_addr = (ulong)images->fit_hdr_os;
+			fit_uname_config = images->fit_uname_cfg;
+			debug ("*  ramdisk: using config '%s' from image at 0x%08lx\n",
+					fit_uname_config, rd_addr);
+
+			/*
+			 * Check whether configuration has ramdisk defined,
+			 * if not, don't try to use it, quit silently.
+			 */
+			fit_hdr = (void *)rd_addr;
+			cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
+			if (cfg_noffset < 0) {
+				debug ("*  ramdisk: no such config\n");
+				return 0;
+			}
+
+			rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
+			if (rd_noffset < 0) {
+				debug ("*  ramdisk: no ramdisk in config\n");
+				return 0;
+			}
+		}
+#endif
+
+		/* copy from dataflash if needed */
+		rd_addr = genimg_get_image (rd_addr);
+
+		/*
+		 * Check if there is an initrd image at the
+		 * address provided in the second bootm argument
+		 * check image type, for FIT images get FIT node.
+		 */
+		switch (genimg_get_format ((void *)rd_addr)) {
+		case IMAGE_FORMAT_LEGACY:
+			printf ("## Loading init Ramdisk from Legacy "
+					"Image at %08lx ...\n", rd_addr);
+
+			show_boot_progress (9);
+			rd_hdr = image_get_ramdisk (rd_addr, arch,
+							images->verify);
+
+			if (rd_hdr == NULL)
+				return 1;
+
+			rd_data = image_get_data (rd_hdr);
+			rd_len = image_get_data_size (rd_hdr);
+			rd_load = image_get_load (rd_hdr);
+			break;
+#if defined(CONFIG_FIT)
+		case IMAGE_FORMAT_FIT:
+			fit_hdr = (void *)rd_addr;
+			printf ("## Loading init Ramdisk from FIT "
+					"Image at %08lx ...\n", rd_addr);
+
+			show_boot_progress (120);
+			if (!fit_check_format (fit_hdr)) {
+				puts ("Bad FIT ramdisk image format!\n");
+				show_boot_progress (-120);
+				return 0;
+			}
+			show_boot_progress (121);
+
+			if (!fit_uname_ramdisk) {
+				/*
+				 * no ramdisk image node unit name, try to get config
+				 * node first. If config unit node name is NULL
+				 * fit_conf_get_node() will try to find default config node
+				 */
+				show_boot_progress (122);
+				cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);
+				if (cfg_noffset < 0) {
+					puts ("Could not find configuration node\n");
+					show_boot_progress (-122);
+					return 0;
+				}
+				fit_uname_config = fdt_get_name (fit_hdr, cfg_noffset, NULL);
+				printf ("   Using '%s' configuration\n", fit_uname_config);
+
+				rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);
+				fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL);
+			} else {
+				/* get ramdisk component image node offset */
+				show_boot_progress (123);
+				rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk);
+			}
+			if (rd_noffset < 0) {
+				puts ("Could not find subimage node\n");
+				show_boot_progress (-124);
+				return 0;
+			}
+
+			printf ("   Trying '%s' ramdisk subimage\n", fit_uname_ramdisk);
+
+			show_boot_progress (125);
+			if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify))
+				return 0;
+
+			/* get ramdisk image data address and length */
+			if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) {
+				puts ("Could not find ramdisk subimage data!\n");
+				show_boot_progress (-127);
+				return 0;
+			}
+			show_boot_progress (128);
+
+			rd_data = (ulong)data;
+			rd_len = size;
+
+			if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) {
+				puts ("Can't get ramdisk subimage load address!\n");
+				show_boot_progress (-129);
+				return 0;
+			}
+			show_boot_progress (129);
+
+			images->fit_hdr_rd = fit_hdr;
+			images->fit_uname_rd = fit_uname_ramdisk;
+			images->fit_noffset_rd = rd_noffset;
+			break;
+#endif
+		default:
+			puts ("Wrong Ramdisk Image Format\n");
+			rd_data = rd_len = rd_load = 0;
+		}
+
+#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)
+		/*
+		 * We need to copy the ramdisk to SRAM to let Linux boot
+		 */
+		if (rd_data) {
+			memmove ((void *)rd_load, (uchar *)rd_data, rd_len);
+			rd_data = rd_load;
+		}
+#endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */
+
+	} else if (images->legacy_hdr_valid &&
+			image_check_type (images->legacy_hdr_os, IH_TYPE_MULTI)) {
+		/*
+		 * Now check if we have a legacy mult-component image,
+		 * get second entry data start address and len.
+		 */
+		show_boot_progress (13);
+		printf ("## Loading init Ramdisk from multi component "
+				"Legacy Image at %08lx ...\n",
+				(ulong)images->legacy_hdr_os);
+
+		image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len);
+	} else {
+		/*
+		 * no initrd image
+		 */
+		show_boot_progress (14);
+		rd_len = rd_data = 0;
+	}
+
+	if (!rd_data) {
+		debug ("## No init Ramdisk\n");
+	} else {
+		*rd_start = rd_data;
+		*rd_end = rd_data + rd_len;
+	}
+	debug ("   ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
+			*rd_start, *rd_end);
+
+	return 0;
+}
+
+#if defined(CONFIG_PPC) || defined(CONFIG_M68K)
+/**
+ * boot_ramdisk_high - relocate init ramdisk
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @rd_data: ramdisk data start address
+ * @rd_len: ramdisk data length
+ * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
+ *      start address (after possible relocation)
+ * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
+ *      end address (after possible relocation)
+ *
+ * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement
+ * variable and if requested ramdisk data is moved to a specified location.
+ *
+ * Initrd_start and initrd_end are set to final (after relocation) ramdisk
+ * start/end addresses if ramdisk image start and len were provided,
+ * otherwise set initrd_start and initrd_end set to zeros.
+ *
+ * returns:
+ *      0 - success
+ *     -1 - failure
+ */
+int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
+		  ulong *initrd_start, ulong *initrd_end)
+{
+	char	*s;
+	ulong	initrd_high;
+	int	initrd_copy_to_ram = 1;
+
+	if ((s = getenv ("initrd_high")) != NULL) {
+		/* a value of "no" or a similar string will act like 0,
+		 * turning the "load high" feature off. This is intentional.
+		 */
+		initrd_high = simple_strtoul (s, NULL, 16);
+		if (initrd_high == ~0)
+			initrd_copy_to_ram = 0;
+	} else {
+		/* not set, no restrictions to load high */
+		initrd_high = ~0;
+	}
+
+	debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
+			initrd_high, initrd_copy_to_ram);
+
+	if (rd_data) {
+		if (!initrd_copy_to_ram) {	/* zero-copy ramdisk support */
+			debug ("   in-place initrd\n");
+			*initrd_start = rd_data;
+			*initrd_end = rd_data + rd_len;
+			lmb_reserve(lmb, rd_data, rd_len);
+		} else {
+			if (initrd_high)
+				*initrd_start = lmb_alloc_base (lmb, rd_len, 0x1000, initrd_high);
+			else
+				*initrd_start = lmb_alloc (lmb, rd_len, 0x1000);
+
+			if (*initrd_start == 0) {
+				puts ("ramdisk - allocation error\n");
+				goto error;
+			}
+			show_boot_progress (12);
+
+			*initrd_end = *initrd_start + rd_len;
+			printf ("   Loading Ramdisk to %08lx, end %08lx ... ",
+					*initrd_start, *initrd_end);
+
+			memmove_wd ((void *)*initrd_start,
+					(void *)rd_data, rd_len, CHUNKSZ);
+
+			puts ("OK\n");
+		}
+	} else {
+		*initrd_start = 0;
+		*initrd_end = 0;
+	}
+	debug ("   ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
+			*initrd_start, *initrd_end);
+
+	return 0;
+
+error:
+	return -1;
+}
+
+/**
+ * boot_get_cmdline - allocate and initialize kernel cmdline
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @cmd_start: pointer to a ulong variable, will hold cmdline start
+ * @cmd_end: pointer to a ulong variable, will hold cmdline end
+ * @bootmap_base: ulong variable, holds offset in physical memory to
+ * base of bootmap
+ *
+ * boot_get_cmdline() allocates space for kernel command line below
+ * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt
+ * variable is present its contents is copied to allocated kernel
+ * command line.
+ *
+ * returns:
+ *      0 - success
+ *     -1 - failure
+ */
+int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,
+			ulong bootmap_base)
+{
+	char *cmdline;
+	char *s;
+
+	cmdline = (char *)lmb_alloc_base(lmb, CFG_BARGSIZE, 0xf,
+					 CFG_BOOTMAPSZ + bootmap_base);
+
+	if (cmdline == NULL)
+		return -1;
+
+	if ((s = getenv("bootargs")) == NULL)
+		s = "";
+
+	strcpy(cmdline, s);
+
+	*cmd_start = (ulong) & cmdline[0];
+	*cmd_end = *cmd_start + strlen(cmdline);
+
+	debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);
+
+	return 0;
+}
+
+/**
+ * boot_get_kbd - allocate and initialize kernel copy of board info
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @kbd: double pointer to board info data
+ * @bootmap_base: ulong variable, holds offset in physical memory to
+ * base of bootmap
+ *
+ * boot_get_kbd() allocates space for kernel copy of board info data below
+ * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with
+ * the current u-boot board info data.
+ *
+ * returns:
+ *      0 - success
+ *     -1 - failure
+ */
+int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base)
+{
+	*kbd = (bd_t *)lmb_alloc_base(lmb, sizeof(bd_t), 0xf,
+				      CFG_BOOTMAPSZ + bootmap_base);
+	if (*kbd == NULL)
+		return -1;
+
+	**kbd = *(gd->bd);
+
+	debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd);
+
+#if defined(DEBUG) && defined(CONFIG_CMD_BDI)
+	do_bdinfo(NULL, 0, 0, NULL);
+#endif
+
+	return 0;
+}
+#endif /* CONFIG_PPC || CONFIG_M68K */
+#endif /* !USE_HOSTCC */
+
+#if defined(CONFIG_FIT)
+/*****************************************************************************/
+/* New uImage format routines */
+/*****************************************************************************/
+#ifndef USE_HOSTCC
+static int fit_parse_spec (const char *spec, char sepc, ulong addr_curr,
+		ulong *addr, const char **name)
+{
+	const char *sep;
+
+	*addr = addr_curr;
+	*name = NULL;
+
+	sep = strchr (spec, sepc);
+	if (sep) {
+		if (sep - spec > 0)
+			*addr = simple_strtoul (spec, NULL, 16);
+
+		*name = sep + 1;
+		return 1;
+	}
+
+	return 0;
+}
+
+/**
+ * fit_parse_conf - parse FIT configuration spec
+ * @spec: input string, containing configuration spec
+ * @add_curr: current image address (to be used as a possible default)
+ * @addr: pointer to a ulong variable, will hold FIT image address of a given
+ * configuration
+ * @conf_name double pointer to a char, will hold pointer to a configuration
+ * unit name
+ *
+ * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>,
+ * where <addr> is a FIT image address that contains configuration
+ * with a <conf> unit name.
+ *
+ * Address part is optional, and if omitted default add_curr will
+ * be used instead.
+ *
+ * returns:
+ *     1 if spec is a valid configuration string,
+ *     addr and conf_name are set accordingly
+ *     0 otherwise
+ */
+inline int fit_parse_conf (const char *spec, ulong addr_curr,
+		ulong *addr, const char **conf_name)
+{
+	return fit_parse_spec (spec, '#', addr_curr, addr, conf_name);
+}
+
+/**
+ * fit_parse_subimage - parse FIT subimage spec
+ * @spec: input string, containing subimage spec
+ * @add_curr: current image address (to be used as a possible default)
+ * @addr: pointer to a ulong variable, will hold FIT image address of a given
+ * subimage
+ * @image_name: double pointer to a char, will hold pointer to a subimage name
+ *
+ * fit_parse_subimage() expects subimage spec in the for of
+ * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
+ * subimage with a <subimg> unit name.
+ *
+ * Address part is optional, and if omitted default add_curr will
+ * be used instead.
+ *
+ * returns:
+ *     1 if spec is a valid subimage string,
+ *     addr and image_name are set accordingly
+ *     0 otherwise
+ */
+inline int fit_parse_subimage (const char *spec, ulong addr_curr,
+		ulong *addr, const char **image_name)
+{
+	return fit_parse_spec (spec, ':', addr_curr, addr, image_name);
+}
+#endif /* !USE_HOSTCC */
+
+static void fit_get_debug (const void *fit, int noffset,
+		char *prop_name, int err)
+{
+	debug ("Can't get '%s' property from FIT 0x%08lx, "
+		"node: offset %d, name %s (%s)\n",
+		prop_name, (ulong)fit, noffset,
+		fit_get_name (fit, noffset, NULL),
+		fdt_strerror (err));
+}
+
+/**
+ * __fit_print_contents - prints out the contents of the FIT format image
+ * @fit: pointer to the FIT format image header
+ * @p: pointer to prefix string
+ *
+ * __fit_print_contents() formats a multi line FIT image contents description.
+ * The routine prints out FIT image properties (root node level) follwed by
+ * the details of each component image.
+ *
+ * returns:
+ *     no returned results
+ */
+static void __fit_print_contents (const void *fit, const char *p)
+{
+	char *desc;
+	char *uname;
+	int images_noffset;
+	int confs_noffset;
+	int noffset;
+	int ndepth;
+	int count = 0;
+	int ret;
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
+	time_t timestamp;
+#endif
+
+	/* Root node properties */
+	ret = fit_get_desc (fit, 0, &desc);
+	printf ("%sFIT description: ", p);
+	if (ret)
+		printf ("unavailable\n");
+	else
+		printf ("%s\n", desc);
+
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
+	ret = fit_get_timestamp (fit, 0, &timestamp);
+	printf ("%sCreated:         ", p);
+	if (ret)
+		printf ("unavailable\n");
+	else
+		genimg_print_time (timestamp);
+#endif
+
+	/* Find images parent node offset */
+	images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
+	if (images_noffset < 0) {
+		printf ("Can't find images parent node '%s' (%s)\n",
+			FIT_IMAGES_PATH, fdt_strerror (images_noffset));
+		return;
+	}
+
+	/* Process its subnodes, print out component images details */
+	for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
+	     (noffset >= 0) && (ndepth > 0);
+	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
+		if (ndepth == 1) {
+			/*
+			 * Direct child node of the images parent node,
+			 * i.e. component image node.
+			 */
+			printf ("%s Image %u (%s)\n", p, count++,
+					fit_get_name(fit, noffset, NULL));
+
+			fit_image_print (fit, noffset, p);
+		}
+	}
+
+	/* Find configurations parent node offset */
+	confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
+	if (confs_noffset < 0) {
+		debug ("Can't get configurations parent node '%s' (%s)\n",
+			FIT_CONFS_PATH, fdt_strerror (confs_noffset));
+		return;
+	}
+
+	/* get default configuration unit name from default property */
+	uname = (char *)fdt_getprop (fit, noffset, FIT_DEFAULT_PROP, NULL);
+	if (uname)
+		printf ("%s Default Configuration: '%s'\n", p, uname);
+
+	/* Process its subnodes, print out configurations details */
+	for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, confs_noffset, &ndepth);
+	     (noffset >= 0) && (ndepth > 0);
+	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
+		if (ndepth == 1) {
+			/*
+			 * Direct child node of the configurations parent node,
+			 * i.e. configuration node.
+			 */
+			printf ("%s Configuration %u (%s)\n", p, count++,
+					fit_get_name(fit, noffset, NULL));
+
+			fit_conf_print (fit, noffset, p);
+		}
+	}
+}
+
+inline void fit_print_contents (const void *fit)
+{
+	__fit_print_contents (fit, "   ");
+}
+
+inline void fit_print_contents_noindent (const void *fit)
+{
+	__fit_print_contents (fit, "");
+}
+
+/**
+ * fit_image_print - prints out the FIT component image details
+ * @fit: pointer to the FIT format image header
+ * @image_noffset: offset of the component image node
+ * @p: pointer to prefix string
+ *
+ * fit_image_print() lists all mandatory properies for the processed component
+ * image. If present, hash nodes are printed out as well.
+ *
+ * returns:
+ *     no returned results
+ */
+void fit_image_print (const void *fit, int image_noffset, const char *p)
+{
+	char *desc;
+	uint8_t type, arch, os, comp;
+	size_t size;
+	ulong load, entry;
+	const void *data;
+	int noffset;
+	int ndepth;
+	int ret;
+
+	/* Mandatory properties */
+	ret = fit_get_desc (fit, image_noffset, &desc);
+	printf ("%s  Description:  ", p);
+	if (ret)
+		printf ("unavailable\n");
+	else
+		printf ("%s\n", desc);
+
+	fit_image_get_type (fit, image_noffset, &type);
+	printf ("%s  Type:         %s\n", p, genimg_get_type_name (type));
+
+	fit_image_get_comp (fit, image_noffset, &comp);
+	printf ("%s  Compression:  %s\n", p, genimg_get_comp_name (comp));
+
+	ret = fit_image_get_data (fit, image_noffset, &data, &size);
+
+#ifndef USE_HOSTCC
+	printf ("%s  Data Start:   ", p);
+	if (ret)
+		printf ("unavailable\n");
+	else
+		printf ("0x%08lx\n", (ulong)data);
+#endif
+
+	printf ("%s  Data Size:    ", p);
+	if (ret)
+		printf ("unavailable\n");
+	else
+		genimg_print_size (size);
+
+	/* Remaining, type dependent properties */
+	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
+	    (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
+	    (type == IH_TYPE_FLATDT)) {
+		fit_image_get_arch (fit, image_noffset, &arch);
+		printf ("%s  Architecture: %s\n", p, genimg_get_arch_name (arch));
+	}
+
+	if (type == IH_TYPE_KERNEL) {
+		fit_image_get_os (fit, image_noffset, &os);
+		printf ("%s  OS:           %s\n", p, genimg_get_os_name (os));
+	}
+
+	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) {
+		ret = fit_image_get_load (fit, image_noffset, &load);
+		printf ("%s  Load Address: ", p);
+		if (ret)
+			printf ("unavailable\n");
+		else
+			printf ("0x%08lx\n", load);
+
+		fit_image_get_entry (fit, image_noffset, &entry);
+		printf ("%s  Entry Point:  ", p);
+		if (ret)
+			printf ("unavailable\n");
+		else
+			printf ("0x%08lx\n", entry);
+	}
+
+	/* Process all hash subnodes of the component image node */
+	for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
+	     (noffset >= 0) && (ndepth > 0);
+	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
+		if (ndepth == 1) {
+			/* Direct child node of the component image node */
+			fit_image_print_hash (fit, noffset, p);
+		}
+	}
+}
+
+/**
+ * fit_image_print_hash - prints out the hash node details
+ * @fit: pointer to the FIT format image header
+ * @noffset: offset of the hash node
+ * @p: pointer to prefix string
+ *
+ * fit_image_print_hash() lists properies for the processed hash node
+ *
+ * returns:
+ *     no returned results
+ */
+void fit_image_print_hash (const void *fit, int noffset, const char *p)
+{
+	char *algo;
+	uint8_t *value;
+	int value_len;
+	int i, ret;
+
+	/*
+	 * Check subnode name, must be equal to "hash".
+	 * Multiple hash nodes require unique unit node
+	 * names, e.g. hash@1, hash@2, etc.
+	 */
+	if (strncmp (fit_get_name(fit, noffset, NULL),
+			FIT_HASH_NODENAME,
+			strlen(FIT_HASH_NODENAME)) != 0)
+		return;
+
+	debug ("%s  Hash node:    '%s'\n", p,
+			fit_get_name (fit, noffset, NULL));
+
+	printf ("%s  Hash algo:    ", p);
+	if (fit_image_hash_get_algo (fit, noffset, &algo)) {
+		printf ("invalid/unsupported\n");
+		return;
+	}
+	printf ("%s\n", algo);
+
+	ret = fit_image_hash_get_value (fit, noffset, &value,
+					&value_len);
+	printf ("%s  Hash value:   ", p);
+	if (ret) {
+		printf ("unavailable\n");
+	} else {
+		for (i = 0; i < value_len; i++)
+			printf ("%02x", value[i]);
+		printf ("\n");
+	}
+
+	debug  ("%s  Hash len:     %d\n", p, value_len);
+}
+
+/**
+ * fit_get_desc - get node description property
+ * @fit: pointer to the FIT format image header
+ * @noffset: node offset
+ * @desc: double pointer to the char, will hold pointer to the descrption
+ *
+ * fit_get_desc() reads description property from a given node, if
+ * description is found pointer to it is returened in third call argument.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_get_desc (const void *fit, int noffset, char **desc)
+{
+	int len;
+
+	*desc = (char *)fdt_getprop (fit, noffset, FIT_DESC_PROP, &len);
+	if (*desc == NULL) {
+		fit_get_debug (fit, noffset, FIT_DESC_PROP, len);
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * fit_get_timestamp - get node timestamp property
+ * @fit: pointer to the FIT format image header
+ * @noffset: node offset
+ * @timestamp: pointer to the time_t, will hold read timestamp
+ *
+ * fit_get_timestamp() reads timestamp poperty from given node, if timestamp
+ * is found and has a correct size its value is retured in third call
+ * argument.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on property read failure
+ *     -2, on wrong timestamp size
+ */
+int fit_get_timestamp (const void *fit, int noffset, time_t *timestamp)
+{
+	int len;
+	const void *data;
+
+	data = fdt_getprop (fit, noffset, FIT_TIMESTAMP_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_TIMESTAMP_PROP, len);
+		return -1;
+	}
+	if (len != sizeof (uint32_t)) {
+		debug ("FIT timestamp with incorrect size of (%u)\n", len);
+		return -2;
+	}
+
+	*timestamp = uimage_to_cpu (*((uint32_t *)data));
+	return 0;
+}
+
+/**
+ * fit_image_get_node - get node offset for component image of a given unit name
+ * @fit: pointer to the FIT format image header
+ * @image_uname: component image node unit name
+ *
+ * fit_image_get_node() finds a component image (withing the '/images'
+ * node) of a provided unit name. If image is found its node offset is
+ * returned to the caller.
+ *
+ * returns:
+ *     image node offset when found (>=0)
+ *     negative number on failure (FDT_ERR_* code)
+ */
+int fit_image_get_node (const void *fit, const char *image_uname)
+{
+	int noffset, images_noffset;
+
+	images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
+	if (images_noffset < 0) {
+		debug ("Can't find images parent node '%s' (%s)\n",
+			FIT_IMAGES_PATH, fdt_strerror (images_noffset));
+		return images_noffset;
+	}
+
+	noffset = fdt_subnode_offset (fit, images_noffset, image_uname);
+	if (noffset < 0) {
+		debug ("Can't get node offset for image unit name: '%s' (%s)\n",
+			image_uname, fdt_strerror (noffset));
+	}
+
+	return noffset;
+}
+
+/**
+ * fit_image_get_os - get os id for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @os: pointer to the uint8_t, will hold os numeric id
+ *
+ * fit_image_get_os() finds os property in a given component image node.
+ * If the property is found, its (string) value is translated to the numeric
+ * id which is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_os (const void *fit, int noffset, uint8_t *os)
+{
+	int len;
+	const void *data;
+
+	/* Get OS name from property data */
+	data = fdt_getprop (fit, noffset, FIT_OS_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_OS_PROP, len);
+		*os = -1;
+		return -1;
+	}
+
+	/* Translate OS name to id */
+	*os = genimg_get_os_id (data);
+	return 0;
+}
+
+/**
+ * fit_image_get_arch - get arch id for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @arch: pointer to the uint8_t, will hold arch numeric id
+ *
+ * fit_image_get_arch() finds arch property in a given component image node.
+ * If the property is found, its (string) value is translated to the numeric
+ * id which is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_arch (const void *fit, int noffset, uint8_t *arch)
+{
+	int len;
+	const void *data;
+
+	/* Get architecture name from property data */
+	data = fdt_getprop (fit, noffset, FIT_ARCH_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_ARCH_PROP, len);
+		*arch = -1;
+		return -1;
+	}
+
+	/* Translate architecture name to id */
+	*arch = genimg_get_arch_id (data);
+	return 0;
+}
+
+/**
+ * fit_image_get_type - get type id for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @type: pointer to the uint8_t, will hold type numeric id
+ *
+ * fit_image_get_type() finds type property in a given component image node.
+ * If the property is found, its (string) value is translated to the numeric
+ * id which is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_type (const void *fit, int noffset, uint8_t *type)
+{
+	int len;
+	const void *data;
+
+	/* Get image type name from property data */
+	data = fdt_getprop (fit, noffset, FIT_TYPE_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_TYPE_PROP, len);
+		*type = -1;
+		return -1;
+	}
+
+	/* Translate image type name to id */
+	*type = genimg_get_type_id (data);
+	return 0;
+}
+
+/**
+ * fit_image_get_comp - get comp id for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @comp: pointer to the uint8_t, will hold comp numeric id
+ *
+ * fit_image_get_comp() finds comp property in a given component image node.
+ * If the property is found, its (string) value is translated to the numeric
+ * id which is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_comp (const void *fit, int noffset, uint8_t *comp)
+{
+	int len;
+	const void *data;
+
+	/* Get compression name from property data */
+	data = fdt_getprop (fit, noffset, FIT_COMP_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_COMP_PROP, len);
+		*comp = -1;
+		return -1;
+	}
+
+	/* Translate compression name to id */
+	*comp = genimg_get_comp_id (data);
+	return 0;
+}
+
+/**
+ * fit_image_get_load - get load address property for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @load: pointer to the uint32_t, will hold load address
+ *
+ * fit_image_get_load() finds load address property in a given component image node.
+ * If the property is found, its value is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_load (const void *fit, int noffset, ulong *load)
+{
+	int len;
+	const uint32_t *data;
+
+	data = fdt_getprop (fit, noffset, FIT_LOAD_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_LOAD_PROP, len);
+		return -1;
+	}
+
+	*load = uimage_to_cpu (*data);
+	return 0;
+}
+
+/**
+ * fit_image_get_entry - get entry point address property for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @entry: pointer to the uint32_t, will hold entry point address
+ *
+ * fit_image_get_entry() finds entry point address property in a given component image node.
+ * If the property is found, its value is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_entry (const void *fit, int noffset, ulong *entry)
+{
+	int len;
+	const uint32_t *data;
+
+	data = fdt_getprop (fit, noffset, FIT_ENTRY_PROP, &len);
+	if (data == NULL) {
+		fit_get_debug (fit, noffset, FIT_ENTRY_PROP, len);
+		return -1;
+	}
+
+	*entry = uimage_to_cpu (*data);
+	return 0;
+}
+
+/**
+ * fit_image_get_data - get data property and its size for a given component image node
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @data: double pointer to void, will hold data property's data address
+ * @size: pointer to size_t, will hold data property's data size
+ *
+ * fit_image_get_data() finds data property in a given component image node.
+ * If the property is found its data start address and size are returned to
+ * the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_get_data (const void *fit, int noffset,
+		const void **data, size_t *size)
+{
+	int len;
+
+	*data = fdt_getprop (fit, noffset, FIT_DATA_PROP, &len);
+	if (*data == NULL) {
+		fit_get_debug (fit, noffset, FIT_DATA_PROP, len);
+		*size = 0;
+		return -1;
+	}
+
+	*size = len;
+	return 0;
+}
+
+/**
+ * fit_image_hash_get_algo - get hash algorithm name
+ * @fit: pointer to the FIT format image header
+ * @noffset: hash node offset
+ * @algo: double pointer to char, will hold pointer to the algorithm name
+ *
+ * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
+ * If the property is found its data start address is returned to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_hash_get_algo (const void *fit, int noffset, char **algo)
+{
+	int len;
+
+	*algo = (char *)fdt_getprop (fit, noffset, FIT_ALGO_PROP, &len);
+	if (*algo == NULL) {
+		fit_get_debug (fit, noffset, FIT_ALGO_PROP, len);
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * fit_image_hash_get_value - get hash value and length
+ * @fit: pointer to the FIT format image header
+ * @noffset: hash node offset
+ * @value: double pointer to uint8_t, will hold address of a hash value data
+ * @value_len: pointer to an int, will hold hash data length
+ *
+ * fit_image_hash_get_value() finds hash value property in a given hash node.
+ * If the property is found its data start address and size are returned to
+ * the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_hash_get_value (const void *fit, int noffset, uint8_t **value,
+				int *value_len)
+{
+	int len;
+
+	*value = (uint8_t *)fdt_getprop (fit, noffset, FIT_VALUE_PROP, &len);
+	if (*value == NULL) {
+		fit_get_debug (fit, noffset, FIT_VALUE_PROP, len);
+		*value_len = 0;
+		return -1;
+	}
+
+	*value_len = len;
+	return 0;
+}
+
+/**
+ * fit_set_timestamp - set node timestamp property
+ * @fit: pointer to the FIT format image header
+ * @noffset: node offset
+ * @timestamp: timestamp value to be set
+ *
+ * fit_set_timestamp() attempts to set timestamp property in the requested
+ * node and returns operation status to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on property read failure
+ */
+int fit_set_timestamp (void *fit, int noffset, time_t timestamp)
+{
+	uint32_t t;
+	int ret;
+
+	t = cpu_to_uimage (timestamp);
+	ret = fdt_setprop (fit, noffset, FIT_TIMESTAMP_PROP, &t,
+				sizeof (uint32_t));
+	if (ret) {
+		printf ("Can't set '%s' property for '%s' node (%s)\n",
+			FIT_TIMESTAMP_PROP, fit_get_name (fit, noffset, NULL),
+			fdt_strerror (ret));
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * calculate_hash - calculate and return hash for provided input data
+ * @data: pointer to the input data
+ * @data_len: data length
+ * @algo: requested hash algorithm
+ * @value: pointer to the char, will hold hash value data (caller must
+ * allocate enough free space)
+ * value_len: length of the calculated hash
+ *
+ * calculate_hash() computes input data hash according to the requested algorithm.
+ * Resulting hash value is placed in caller provided 'value' buffer, length
+ * of the calculated hash is returned via value_len pointer argument.
+ *
+ * returns:
+ *     0, on success
+ *    -1, when algo is unsupported
+ */
+static int calculate_hash (const void *data, int data_len, const char *algo,
+			uint8_t *value, int *value_len)
+{
+	if (strcmp (algo, "crc32") == 0 ) {
+		*((uint32_t *)value) = crc32 (0, data, data_len);
+		*((uint32_t *)value) = cpu_to_uimage (*((uint32_t *)value));
+		*value_len = 4;
+	} else if (strcmp (algo, "sha1") == 0 ) {
+		sha1_csum ((unsigned char *) data, data_len,
+				(unsigned char *) value);
+		*value_len = 20;
+	} else if (strcmp (algo, "md5") == 0 ) {
+		md5 ((unsigned char *)data, data_len, value);
+		*value_len = 16;
+	} else {
+		debug ("Unsupported hash alogrithm\n");
+		return -1;
+	}
+	return 0;
+}
+
+#ifdef USE_HOSTCC
+/**
+ * fit_set_hashes - process FIT component image nodes and calculate hashes
+ * @fit: pointer to the FIT format image header
+ *
+ * fit_set_hashes() adds hash values for all component images in the FIT blob.
+ * Hashes are calculated for all component images which have hash subnodes
+ * with algorithm property set to one of the supported hash algorithms.
+ *
+ * returns
+ *     0, on success
+ *     libfdt error code, on failure
+ */
+int fit_set_hashes (void *fit)
+{
+	int images_noffset;
+	int noffset;
+	int ndepth;
+	int ret;
+
+	/* Find images parent node offset */
+	images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);
+	if (images_noffset < 0) {
+		printf ("Can't find images parent node '%s' (%s)\n",
+			FIT_IMAGES_PATH, fdt_strerror (images_noffset));
+		return images_noffset;
+	}
+
+	/* Process its subnodes, print out component images details */
+	for (ndepth = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);
+	     (noffset >= 0) && (ndepth > 0);
+	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
+		if (ndepth == 1) {
+			/*
+			 * Direct child node of the images parent node,
+			 * i.e. component image node.
+			 */
+			ret = fit_image_set_hashes (fit, noffset);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * fit_image_set_hashes - calculate/set hashes for given component image node
+ * @fit: pointer to the FIT format image header
+ * @image_noffset: requested component image node
+ *
+ * fit_image_set_hashes() adds hash values for an component image node. All
+ * existing hash subnodes are checked, if algorithm property is set to one of
+ * the supported hash algorithms, hash value is computed and corresponding
+ * hash node property is set, for example:
+ *
+ * Input component image node structure:
+ *
+ * o image@1 (at image_noffset)
+ *   | - data = [binary data]
+ *   o hash@1
+ *     |- algo = "sha1"
+ *
+ * Output component image node structure:
+ *
+ * o image@1 (at image_noffset)
+ *   | - data = [binary data]
+ *   o hash@1
+ *     |- algo = "sha1"
+ *     |- value = sha1(data)
+ *
+ * returns:
+ *     0 on sucess
+ *    <0 on failure
+ */
+int fit_image_set_hashes (void *fit, int image_noffset)
+{
+	const void *data;
+	size_t size;
+	char *algo;
+	uint8_t value[FIT_MAX_HASH_LEN];
+	int value_len;
+	int noffset;
+	int ndepth;
+
+	/* Get image data and data length */
+	if (fit_image_get_data (fit, image_noffset, &data, &size)) {
+		printf ("Can't get image data/size\n");
+		return -1;
+	}
+
+	/* Process all hash subnodes of the component image node */
+	for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
+	     (noffset >= 0) && (ndepth > 0);
+	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
+		if (ndepth == 1) {
+			/* Direct child node of the component image node */
+
+			/*
+			 * Check subnode name, must be equal to "hash".
+			 * Multiple hash nodes require unique unit node
+			 * names, e.g. hash@1, hash@2, etc.
+			 */
+			if (strncmp (fit_get_name(fit, noffset, NULL),
+						FIT_HASH_NODENAME,
+						strlen(FIT_HASH_NODENAME)) != 0) {
+				/* Not a hash subnode, skip it */
+				continue;
+			}
+
+			if (fit_image_hash_get_algo (fit, noffset, &algo)) {
+				printf ("Can't get hash algo property for "
+					"'%s' hash node in '%s' image node\n",
+					fit_get_name (fit, noffset, NULL),
+					fit_get_name (fit, image_noffset, NULL));
+				return -1;
+			}
+
+			if (calculate_hash (data, size, algo, value, &value_len)) {
+				printf ("Unsupported hash algorithm (%s) for "
+					"'%s' hash node in '%s' image node\n",
+					algo, fit_get_name (fit, noffset, NULL),
+					fit_get_name (fit, image_noffset, NULL));
+				return -1;
+			}
+
+			if (fit_image_hash_set_value (fit, noffset, value,
+							value_len)) {
+				printf ("Can't set hash value for "
+					"'%s' hash node in '%s' image node\n",
+					fit_get_name (fit, noffset, NULL),
+					fit_get_name (fit, image_noffset, NULL));
+				return -1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * fit_image_hash_set_value - set hash value in requested has node
+ * @fit: pointer to the FIT format image header
+ * @noffset: hash node offset
+ * @value: hash value to be set
+ * @value_len: hash value length
+ *
+ * fit_image_hash_set_value() attempts to set hash value in a node at offset
+ * given and returns operation status to the caller.
+ *
+ * returns
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_hash_set_value (void *fit, int noffset, uint8_t *value,
+				int value_len)
+{
+	int ret;
+
+	ret = fdt_setprop (fit, noffset, FIT_VALUE_PROP, value, value_len);
+	if (ret) {
+		printf ("Can't set hash '%s' property for '%s' node (%s)\n",
+			FIT_VALUE_PROP, fit_get_name (fit, noffset, NULL),
+			fdt_strerror (ret));
+		return -1;
+	}
+
+	return 0;
+}
+#endif /* USE_HOSTCC */
+
+/**
+ * fit_image_check_hashes - verify data intergity
+ * @fit: pointer to the FIT format image header
+ * @image_noffset: component image node offset
+ *
+ * fit_image_check_hashes() goes over component image hash nodes,
+ * re-calculates each data hash and compares with the value stored in hash
+ * node.
+ *
+ * returns:
+ *     1, if all hashes are valid
+ *     0, otherwise (or on error)
+ */
+int fit_image_check_hashes (const void *fit, int image_noffset)
+{
+	const void	*data;
+	size_t		size;
+	char		*algo;
+	uint8_t		*fit_value;
+	int		fit_value_len;
+	uint8_t		value[FIT_MAX_HASH_LEN];
+	int		value_len;
+	int		noffset;
+	int		ndepth;
+	char		*err_msg = "";
+
+	/* Get image data and data length */
+	if (fit_image_get_data (fit, image_noffset, &data, &size)) {
+		printf ("Can't get image data/size\n");
+		return 0;
+	}
+
+	/* Process all hash subnodes of the component image node */
+	for (ndepth = 0, noffset = fdt_next_node (fit, image_noffset, &ndepth);
+	     (noffset >= 0) && (ndepth > 0);
+	     noffset = fdt_next_node (fit, noffset, &ndepth)) {
+		if (ndepth == 1) {
+			/* Direct child node of the component image node */
+
+			/*
+			 * Check subnode name, must be equal to "hash".
+			 * Multiple hash nodes require unique unit node
+			 * names, e.g. hash@1, hash@2, etc.
+			 */
+			if (strncmp (fit_get_name(fit, noffset, NULL),
+					FIT_HASH_NODENAME,
+					strlen(FIT_HASH_NODENAME)) != 0)
+				continue;
+
+			if (fit_image_hash_get_algo (fit, noffset, &algo)) {
+				err_msg = "Can't get hash algo property";
+				goto error;
+			}
+			printf ("%s", algo);
+
+			if (fit_image_hash_get_value (fit, noffset, &fit_value,
+							&fit_value_len)) {
+				err_msg = "Can't get hash value property";
+				goto error;
+			}
+
+			if (calculate_hash (data, size, algo, value, &value_len)) {
+				err_msg = "Unsupported hash algorithm";
+				goto error;
+			}
+
+			if (value_len != fit_value_len) {
+				err_msg = "Bad hash value len";
+				goto error;
+			} else if (memcmp (value, fit_value, value_len) != 0) {
+				err_msg = "Bad hash value";
+				goto error;
+			}
+			printf ("+ ");
+		}
+	}
+
+	return 1;
+
+error:
+	printf ("%s for '%s' hash node in '%s' image node\n",
+			err_msg, fit_get_name (fit, noffset, NULL),
+			fit_get_name (fit, image_noffset, NULL));
+	return 0;
+}
+
+/**
+ * fit_image_check_os - check whether image node is of a given os type
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @os: requested image os
+ *
+ * fit_image_check_os() reads image os property and compares its numeric
+ * id with the requested os. Comparison result is returned to the caller.
+ *
+ * returns:
+ *     1 if image is of given os type
+ *     0 otherwise (or on error)
+ */
+int fit_image_check_os (const void *fit, int noffset, uint8_t os)
+{
+	uint8_t image_os;
+
+	if (fit_image_get_os (fit, noffset, &image_os))
+		return 0;
+	return (os == image_os);
+}
+
+/**
+ * fit_image_check_arch - check whether image node is of a given arch
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @arch: requested imagearch
+ *
+ * fit_image_check_arch() reads image arch property and compares its numeric
+ * id with the requested arch. Comparison result is returned to the caller.
+ *
+ * returns:
+ *     1 if image is of given arch
+ *     0 otherwise (or on error)
+ */
+int fit_image_check_arch (const void *fit, int noffset, uint8_t arch)
+{
+	uint8_t image_arch;
+
+	if (fit_image_get_arch (fit, noffset, &image_arch))
+		return 0;
+	return (arch == image_arch);
+}
+
+/**
+ * fit_image_check_type - check whether image node is of a given type
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @type: requested image type
+ *
+ * fit_image_check_type() reads image type property and compares its numeric
+ * id with the requested type. Comparison result is returned to the caller.
+ *
+ * returns:
+ *     1 if image is of given type
+ *     0 otherwise (or on error)
+ */
+int fit_image_check_type (const void *fit, int noffset, uint8_t type)
+{
+	uint8_t image_type;
+
+	if (fit_image_get_type (fit, noffset, &image_type))
+		return 0;
+	return (type == image_type);
+}
+
+/**
+ * fit_image_check_comp - check whether image node uses given compression
+ * @fit: pointer to the FIT format image header
+ * @noffset: component image node offset
+ * @comp: requested image compression type
+ *
+ * fit_image_check_comp() reads image compression property and compares its
+ * numeric id with the requested compression type. Comparison result is
+ * returned to the caller.
+ *
+ * returns:
+ *     1 if image uses requested compression
+ *     0 otherwise (or on error)
+ */
+int fit_image_check_comp (const void *fit, int noffset, uint8_t comp)
+{
+	uint8_t image_comp;
+
+	if (fit_image_get_comp (fit, noffset, &image_comp))
+		return 0;
+	return (comp == image_comp);
+}
+
+/**
+ * fit_check_format - sanity check FIT image format
+ * @fit: pointer to the FIT format image header
+ *
+ * fit_check_format() runs a basic sanity FIT image verification.
+ * Routine checks for mandatory properties, nodes, etc.
+ *
+ * returns:
+ *     1, on success
+ *     0, on failure
+ */
+int fit_check_format (const void *fit)
+{
+	/* mandatory / node 'description' property */
+	if (fdt_getprop (fit, 0, FIT_DESC_PROP, NULL) == NULL) {
+		debug ("Wrong FIT format: no description\n");
+		return 0;
+	}
+
+#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)
+	/* mandatory / node 'timestamp' property */
+	if (fdt_getprop (fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) {
+		debug ("Wrong FIT format: no description\n");
+		return 0;
+	}
+#endif
+
+	/* mandatory subimages parent '/images' node */
+	if (fdt_path_offset (fit, FIT_IMAGES_PATH) < 0) {
+		debug ("Wrong FIT format: no images parent node\n");
+		return 0;
+	}
+
+	return 1;
+}
+
+/**
+ * fit_conf_get_node - get node offset for configuration of a given unit name
+ * @fit: pointer to the FIT format image header
+ * @conf_uname: configuration node unit name
+ *
+ * fit_conf_get_node() finds a configuration (withing the '/configurations'
+ * parant node) of a provided unit name. If configuration is found its node offset
+ * is returned to the caller.
+ *
+ * When NULL is provided in second argument fit_conf_get_node() will search
+ * for a default configuration node instead. Default configuration node unit name
+ * is retrived from FIT_DEFAULT_PROP property of the '/configurations' node.
+ *
+ * returns:
+ *     configuration node offset when found (>=0)
+ *     negative number on failure (FDT_ERR_* code)
+ */
+int fit_conf_get_node (const void *fit, const char *conf_uname)
+{
+	int noffset, confs_noffset;
+	int len;
+
+	confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);
+	if (confs_noffset < 0) {
+		debug ("Can't find configurations parent node '%s' (%s)\n",
+			FIT_CONFS_PATH, fdt_strerror (confs_noffset));
+		return confs_noffset;
+	}
+
+	if (conf_uname == NULL) {
+		/* get configuration unit name from the default property */
+		debug ("No configuration specified, trying default...\n");
+		conf_uname = (char *)fdt_getprop (fit, confs_noffset, FIT_DEFAULT_PROP, &len);
+		if (conf_uname == NULL) {
+			fit_get_debug (fit, confs_noffset, FIT_DEFAULT_PROP, len);
+			return len;
+		}
+		debug ("Found default configuration: '%s'\n", conf_uname);
+	}
+
+	noffset = fdt_subnode_offset (fit, confs_noffset, conf_uname);
+	if (noffset < 0) {
+		debug ("Can't get node offset for configuration unit name: '%s' (%s)\n",
+			conf_uname, fdt_strerror (noffset));
+	}
+
+	return noffset;
+}
+
+static int __fit_conf_get_prop_node (const void *fit, int noffset,
+		const char *prop_name)
+{
+	char *uname;
+	int len;
+
+	/* get kernel image unit name from configuration kernel property */
+	uname = (char *)fdt_getprop (fit, noffset, prop_name, &len);
+	if (uname == NULL)
+		return len;
+
+	return fit_image_get_node (fit, uname);
+}
+
+/**
+ * fit_conf_get_kernel_node - get kernel image node offset that corresponds to
+ * a given configuration
+ * @fit: pointer to the FIT format image header
+ * @noffset: configuration node offset
+ *
+ * fit_conf_get_kernel_node() retrives kernel image node unit name from
+ * configuration FIT_KERNEL_PROP property and translates it to the node
+ * offset.
+ *
+ * returns:
+ *     image node offset when found (>=0)
+ *     negative number on failure (FDT_ERR_* code)
+ */
+int fit_conf_get_kernel_node (const void *fit, int noffset)
+{
+	return __fit_conf_get_prop_node (fit, noffset, FIT_KERNEL_PROP);
+}
+
+/**
+ * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to
+ * a given configuration
+ * @fit: pointer to the FIT format image header
+ * @noffset: configuration node offset
+ *
+ * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from
+ * configuration FIT_KERNEL_PROP property and translates it to the node
+ * offset.
+ *
+ * returns:
+ *     image node offset when found (>=0)
+ *     negative number on failure (FDT_ERR_* code)
+ */
+int fit_conf_get_ramdisk_node (const void *fit, int noffset)
+{
+	return __fit_conf_get_prop_node (fit, noffset, FIT_RAMDISK_PROP);
+}
+
+/**
+ * fit_conf_get_fdt_node - get fdt image node offset that corresponds to
+ * a given configuration
+ * @fit: pointer to the FIT format image header
+ * @noffset: configuration node offset
+ *
+ * fit_conf_get_fdt_node() retrives fdt image node unit name from
+ * configuration FIT_KERNEL_PROP property and translates it to the node
+ * offset.
+ *
+ * returns:
+ *     image node offset when found (>=0)
+ *     negative number on failure (FDT_ERR_* code)
+ */
+int fit_conf_get_fdt_node (const void *fit, int noffset)
+{
+	return __fit_conf_get_prop_node (fit, noffset, FIT_FDT_PROP);
+}
+
+/**
+ * fit_conf_print - prints out the FIT configuration details
+ * @fit: pointer to the FIT format image header
+ * @noffset: offset of the configuration node
+ * @p: pointer to prefix string
+ *
+ * fit_conf_print() lists all mandatory properies for the processed
+ * configuration node.
+ *
+ * returns:
+ *     no returned results
+ */
+void fit_conf_print (const void *fit, int noffset, const char *p)
+{
+	char *desc;
+	char *uname;
+	int ret;
+
+	/* Mandatory properties */
+	ret = fit_get_desc (fit, noffset, &desc);
+	printf ("%s  Description:  ", p);
+	if (ret)
+		printf ("unavailable\n");
+	else
+		printf ("%s\n", desc);
+
+	uname = (char *)fdt_getprop (fit, noffset, FIT_KERNEL_PROP, NULL);
+	printf ("%s  Kernel:       ", p);
+	if (uname == NULL)
+		printf ("unavailable\n");
+	else
+		printf ("%s\n", uname);
+
+	/* Optional properties */
+	uname = (char *)fdt_getprop (fit, noffset, FIT_RAMDISK_PROP, NULL);
+	if (uname)
+		printf ("%s  Init Ramdisk: %s\n", p, uname);
+
+	uname = (char *)fdt_getprop (fit, noffset, FIT_FDT_PROP, NULL);
+	if (uname)
+		printf ("%s  FDT:          %s\n", p, uname);
+}
+
+/**
+ * fit_check_ramdisk - verify FIT format ramdisk subimage
+ * @fit_hdr: pointer to the FIT ramdisk header
+ * @rd_noffset: ramdisk subimage node offset within FIT image
+ * @arch: requested ramdisk image architecture type
+ * @verify: data CRC verification flag
+ *
+ * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from
+ * specified FIT image.
+ *
+ * returns:
+ *     1, on success
+ *     0, on failure
+ */
+#ifndef USE_HOSTCC
+static int fit_check_ramdisk (const void *fit, int rd_noffset, uint8_t arch, int verify)
+{
+	fit_image_print (fit, rd_noffset, "   ");
+
+	if (verify) {
+		puts ("   Verifying Hash Integrity ... ");
+		if (!fit_image_check_hashes (fit, rd_noffset)) {
+			puts ("Bad Data Hash\n");
+			show_boot_progress (-125);
+			return 0;
+		}
+		puts ("OK\n");
+	}
+
+	show_boot_progress (126);
+	if (!fit_image_check_os (fit, rd_noffset, IH_OS_LINUX) ||
+	    !fit_image_check_arch (fit, rd_noffset, arch) ||
+	    !fit_image_check_type (fit, rd_noffset, IH_TYPE_RAMDISK)) {
+		printf ("No Linux %s Ramdisk Image\n",
+				genimg_get_arch_name(arch));
+		show_boot_progress (-126);
+		return 0;
+	}
+
+	show_boot_progress (127);
+	return 1;
+}
+#endif /* USE_HOSTCC */
+#endif /* CONFIG_FIT */

+ 23 - 23
common/lynxkdi.c

@@ -23,45 +23,45 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_MPC8260) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
-void lynxkdi_boot ( image_header_t *hdr )
+void lynxkdi_boot (image_header_t *hdr)
 {
-	void (*lynxkdi)(void) = (void(*)(void)) ntohl(hdr->ih_ep);
+	void (*lynxkdi)(void) = (void(*)(void))image_get_ep (hdr);
 	lynxos_bootparms_t *parms = (lynxos_bootparms_t *)0x0020;
 	bd_t *kbd;
-	u32 *psz = (u32 *)(ntohl(hdr->ih_load) + 0x0204);
+	u32 *psz = (u32 *)(image_get_load (hdr) + 0x0204);
 
-	memset( parms, 0, sizeof(*parms));
+	memset (parms, 0, sizeof(*parms));
 	kbd = gd->bd;
 	parms->clock_ref = kbd->bi_busfreq;
 	parms->dramsz = kbd->bi_memsize;
-	memcpy(parms->ethaddr, kbd->bi_enetaddr, 6);
-	mtspr(SPRN_SPRG2, 0x0020);
+	memcpy (parms->ethaddr, kbd->bi_enetaddr, 6);
+	mtspr (SPRN_SPRG2, 0x0020);
 
 	/* Do a simple check for Bluecat so we can pass the
 	 * kernel command line parameters.
 	 */
-	if( le32_to_cpu(*psz) == ntohl(hdr->ih_size) ){	/* FIXME: NOT SURE HERE ! */
-	    char *args;
-	    char *cmdline = (char *)(ntohl(hdr->ih_load) + 0x020c);
-	    int len;
+	if (le32_to_cpu (*psz) == image_get_data_size (hdr)) {	/* FIXME: NOT SURE HERE ! */
+		char *args;
+		char *cmdline = (char *)(image_get_load (hdr) + 0x020c);
+		int len;
 
-	    printf("Booting Bluecat KDI ...\n");
-	    udelay(200*1000); /* Allow serial port to flush */
-	    if ((args = getenv("bootargs")) == NULL)
-		    args = "";
-	    /* Prepend the cmdline */
-	    len = strlen(args);
-	    if( len && (len + strlen(cmdline) + 2 < (0x0400 - 0x020c))) {
-		memmove( cmdline + strlen(args) + 1, cmdline, strlen(cmdline) );
-		strcpy( cmdline, args );
-		cmdline[len] = ' ';
-	    }
+		printf ("Booting Bluecat KDI ...\n");
+		udelay (200*1000); /* Allow serial port to flush */
+		if ((args = getenv ("bootargs")) == NULL)
+			args = "";
+		/* Prepend the cmdline */
+		len = strlen (args);
+		if (len && (len + strlen (cmdline) + 2 < (0x0400 - 0x020c))) {
+			memmove (cmdline + strlen (args) + 1, cmdline, strlen (cmdline));
+			strcpy (cmdline, args);
+			cmdline[len] = ' ';
+		}
 	}
 	else {
-	    printf("Booting LynxOS KDI ...\n");
+		printf ("Booting LynxOS KDI ...\n");
 	}
 
-	lynxkdi();
+	lynxkdi ();
 }
 #else
 #error "Lynx KDI support not implemented for configured CPU"

+ 7 - 4
common/usb_storage.c

@@ -188,17 +188,20 @@ void usb_show_progress(void)
  * show info on storage devices; 'usb start/init' must be invoked earlier
  * as we only retrieve structures populated during devices initialization
  */
-void usb_stor_info(void)
+int usb_stor_info(void)
 {
 	int i;
 
-	if (usb_max_devs > 0)
+	if (usb_max_devs > 0) {
 		for (i = 0; i < usb_max_devs; i++) {
 			printf ("  Device %d: ", i);
 			dev_print(&usb_dev_desc[i]);
 		}
-	else
-		printf("No storage devices, perhaps not 'usb start'ed..?\n");
+		return 0;
+	}
+	
+	printf("No storage devices, perhaps not 'usb start'ed..?\n");
+	return 1;
 }
 
 /*********************************************************************************

+ 129 - 80
cpu/mips/cache.S

@@ -1,5 +1,5 @@
 /*
- *  Cache-handling routined for MIPS 4K CPUs
+ *  Cache-handling routined for MIPS CPUs
  *
  *  Copyright (c) 2003	Wolfgang Denk <wd@denx.de>
  *
@@ -24,15 +24,32 @@
 
 #include <config.h>
 #include <version.h>
+#include <asm/asm.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
 #include <asm/addrspace.h>
 #include <asm/cacheops.h>
 
-	/* 16KB is the maximum size of instruction and data caches on
-	 * MIPS 4K.
-	 */
-#define MIPS_MAX_CACHE_SIZE	0x4000
+#define RA		t8
+
+/*
+ * 16kB is the maximum size of instruction and data caches on MIPS 4K,
+ * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
+ *
+ * Note that the above size is the maximum size of primary cache. U-Boot
+ * doesn't have L2 cache support for now.
+ */
+#define MIPS_MAX_CACHE_SIZE	0x10000
+
+#define INDEX_BASE	KSEG0
+
+	.macro	cache_op op addr
+	.set	push
+	.set	noreorder
+	.set	mips3
+	cache	\op, 0(\addr)
+	.set	pop
+	.endm
 
 /*
  * cacheop macro to automate cache operations
@@ -103,6 +120,77 @@
 #define icacheop(kva, n, cacheSize, cacheLineSize, op) \
    icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))
 
+	.macro	f_fill64 dst, offset, val
+	LONG_S	\val, (\offset +  0 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset +  1 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset +  2 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset +  3 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset +  4 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset +  5 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset +  6 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset +  7 * LONGSIZE)(\dst)
+#if LONGSIZE == 4
+	LONG_S	\val, (\offset +  8 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset +  9 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset + 10 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset + 11 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset + 12 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset + 13 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset + 14 * LONGSIZE)(\dst)
+	LONG_S	\val, (\offset + 15 * LONGSIZE)(\dst)
+#endif
+	.endm
+
+/*
+ * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
+ */
+LEAF(mips_init_icache)
+	blez	a1, 9f
+	mtc0	zero, CP0_TAGLO
+	/* clear tag to invalidate */
+	PTR_LI		t0, INDEX_BASE
+	PTR_ADDU	t1, t0, a1
+1:	cache_op	Index_Store_Tag_I t0
+	PTR_ADDU	t0, a2
+	bne		t0, t1, 1b
+	/* fill once, so data field parity is correct */
+	PTR_LI		t0, INDEX_BASE
+2:	cache_op	Fill t0
+	PTR_ADDU	t0, a2
+	bne		t0, t1, 2b
+	/* invalidate again - prudent but not strictly neccessary */
+	PTR_LI		t0, INDEX_BASE
+1:	cache_op	Index_Store_Tag_I t0
+	PTR_ADDU	t0, a2
+	bne		t0, t1, 1b
+9:	jr	ra
+	END(mips_init_icache)
+
+/*
+ * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
+ */
+LEAF(mips_init_dcache)
+	blez	a1, 9f
+	mtc0	zero, CP0_TAGLO
+	/* clear all tags */
+	PTR_LI		t0, INDEX_BASE
+	PTR_ADDU	t1, t0, a1
+1:	cache_op	Index_Store_Tag_D t0
+	PTR_ADDU	t0, a2
+	bne		t0, t1, 1b
+	/* load from each line (in cached space) */
+	PTR_LI		t0, INDEX_BASE
+2:	LONG_L		zero, 0(t0)
+	PTR_ADDU	t0, a2
+	bne		t0, t1, 2b
+	/* clear all tags */
+	PTR_LI		t0, INDEX_BASE
+1:	cache_op	Index_Store_Tag_D t0
+	PTR_ADDU	t0, a2
+	bne		t0, t1, 1b
+9:	jr	ra
+	END(mips_init_dcache)
+
 /*******************************************************************************
 *
 * mips_cache_reset - low level initialisation of the primary caches
@@ -119,10 +207,8 @@
 * RETURNS: N/A
 *
 */
-	.globl	mips_cache_reset
-	.ent	mips_cache_reset
-mips_cache_reset:
-
+NESTED(mips_cache_reset, 0, ra)
+	move	RA, ra
 	li	t2, CFG_ICACHE_SIZE
 	li	t3, CFG_DCACHE_SIZE
 	li	t4, CFG_CACHELINE_SIZE
@@ -130,27 +216,14 @@ mips_cache_reset:
 
 	li	v0, MIPS_MAX_CACHE_SIZE
 
-	/* Now clear that much memory starting from zero.
-	 */
-
-	li	a0, KSEG1
-	addu	a1, a0, v0
-2:
-	sw	zero, 0(a0)
-	sw	zero, 4(a0)
-	sw	zero, 8(a0)
-	sw	zero, 12(a0)
-	sw	zero, 16(a0)
-	sw	zero, 20(a0)
-	sw	zero, 24(a0)
-	sw	zero, 28(a0)
-	addu	a0, 32
-	bltu	a0, a1, 2b
-
-	/* Set invalid tag.
+	/*
+	 * Now clear that much memory starting from zero.
 	 */
-
-	mtc0	zero, CP0_TAGLO
+	PTR_LI		a0, KSEG1
+	PTR_ADDU	a1, a0, v0
+2:	PTR_ADDIU	a0, 64
+	f_fill64	a0, -64, zero
+	bne		a0, a1, 2b
 
 	/*
 	 * The caches are probably in an indeterminate state,
@@ -158,48 +231,26 @@ mips_cache_reset:
 	 * invalidate, load/fill, invalidate for each line.
 	 */
 
-	/* Assume bottom of RAM will generate good parity for the cache.
-	 */
-
-	li	a0, K0BASE
-	move	a2, t2		# icacheSize
-	move	a3, t4		# icacheLineSize
-	move	a1, a2
-	icacheopn(a0,a1,a2,a3,121,(Index_Store_Tag_I,Fill))
-
-	/* To support Orion/R4600, we initialise the data cache in 3 passes.
-	 */
-
-	/* 1: initialise dcache tags.
+	/*
+	 * Assume bottom of RAM will generate good parity for the cache.
 	 */
 
-	li	a0, K0BASE
-	move	a2, t3		# dcacheSize
-	move	a3, t5		# dcacheLineSize
-	move	a1, a2
-	icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
-
-	/* 2: fill dcache.
+	/*
+	 * Initialize the I-cache first,
 	 */
+	move	a1, t2
+	move	a2, t4
+	bal	mips_init_icache
 
-	li	a0, K0BASE
-	move	a2, t3		# dcacheSize
-	move	a3, t5		# dcacheLineSize
-	move	a1, a2
-	icacheopn(a0,a1,a2,a3,1lw,(dummy))
-
-	/* 3: clear dcache tags.
+	/*
+	 * then initialize D-cache.
 	 */
+	move	a1, t3
+	move	a2, t5
+	bal	mips_init_dcache
 
-	li	a0, K0BASE
-	move	a2, t3		# dcacheSize
-	move	a3, t5		# dcacheLineSize
-	move	a1, a2
-	icacheop(a0,a1,a2,a3,Index_Store_Tag_D)
-
-	j	ra
-
-	.end	mips_cache_reset
+	jr	RA
+	END(mips_cache_reset)
 
 /*******************************************************************************
 *
@@ -208,15 +259,15 @@ mips_cache_reset:
 * RETURNS: 0 - cache disabled; 1 - cache enabled
 *
 */
-	.globl	dcache_status
-	.ent	dcache_status
-dcache_status:
-
-	mfc0	v0, CP0_CONFIG
-	andi	v0, v0, 1
-	j	ra
-
-	.end	dcache_status
+LEAF(dcache_status)
+	mfc0	t0, CP0_CONFIG
+	li	t1, CONF_CM_UNCACHED
+	andi	t0, t0, CONF_CM_CMASK
+	move	v0, zero
+	beq	t0, t1, 2f
+	li	v0, 1
+2:	jr	ra
+	END(dcache_status)
 
 /*******************************************************************************
 *
@@ -225,19 +276,16 @@ dcache_status:
 * RETURNS: N/A
 *
 */
-	.globl	dcache_disable
-	.ent	dcache_disable
-dcache_disable:
-
+LEAF(dcache_disable)
 	mfc0	t0, CP0_CONFIG
 	li	t1, -8
 	and	t0, t0, t1
 	ori	t0, t0, CONF_CM_UNCACHED
 	mtc0	t0, CP0_CONFIG
 	j	ra
+	END(dcache_disable)
 
-	.end	dcache_disable
-
+#ifdef CFG_INIT_RAM_LOCK_MIPS
 /*******************************************************************************
 *
 * mips_cache_lock - lock RAM area pointed to by a0 in cache.
@@ -263,3 +311,4 @@ mips_cache_lock:
 	j	ra
 
 	.end	mips_cache_lock
+#endif /* CFG_INIT_RAM_LOCK_MIPS */

+ 28 - 7
cpu/mips/cpu.c

@@ -23,24 +23,45 @@
 
 #include <common.h>
 #include <command.h>
-#include <asm/inca-ip.h>
 #include <asm/mipsregs.h>
+#include <asm/cacheops.h>
+#include <asm/reboot.h>
+
+#define cache_op(op,addr)						\
+	__asm__ __volatile__(						\
+	"	.set	push					\n"	\
+	"	.set	noreorder				\n"	\
+	"	.set	mips3\n\t				\n"	\
+	"	cache	%0, %1					\n"	\
+	"	.set	pop					\n"	\
+	:								\
+	: "i" (op), "R" (*(unsigned char *)(addr)))
+
+void __attribute__((weak)) _machine_restart(void)
+{
+}
 
 int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
-#if defined(CONFIG_INCA_IP)
-	*INCA_IP_WDT_RST_REQ = 0x3f;
-#elif defined(CONFIG_PURPLE) || defined(CONFIG_TB0229)
-	void (*f)(void) = (void *) 0xbfc00000;
+	_machine_restart();
 
-	f();
-#endif
 	fprintf(stderr, "*** reset failed ***\n");
 	return 0;
 }
 
 void flush_cache(ulong start_addr, ulong size)
 {
+	unsigned long lsize = CFG_CACHELINE_SIZE;
+	unsigned long addr = start_addr & ~(lsize - 1);
+	unsigned long aend = (start_addr + size - 1) & ~(lsize - 1);
+
+	while (1) {
+		cache_op(Hit_Writeback_Inv_D, start_addr);
+		cache_op(Hit_Invalidate_I, start_addr);
+		if (addr == aend)
+			break;
+		addr += lsize;
+	}
 }
 
 void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)

+ 29 - 19
cpu/mips/start.S

@@ -27,6 +27,30 @@
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
 
+	/*
+	 * For the moment disable interrupts, mark the kernel mode and
+	 * set ST0_KX so that the CPU does not spit fire when using
+	 * 64-bit addresses.
+	 */
+	.macro	setup_c0_status set clr
+	.set	push
+	mfc0	t0, CP0_STATUS
+	or	t0, ST0_CU0 | \set | 0x1f | \clr
+	xor	t0, 0x1f | \clr
+	mtc0	t0, CP0_STATUS
+	.set	noreorder
+	sll	zero, 3				# ehb
+	.set	pop
+	.endm
+
+	.macro	setup_c0_status_reset
+#ifdef CONFIG_64BIT
+	setup_c0_status ST0_KX 0
+#else
+	setup_c0_status 0 0
+#endif
+	.endm
+
 #define RVECENT(f,n) \
    b f; nop
 #define XVECENT(f,bev) \
@@ -211,19 +235,11 @@ reset:
 	mtc0	zero, CP0_WATCHLO
 	mtc0	zero, CP0_WATCHHI
 
-	/* STATUS register */
-#ifdef  CONFIG_TB0229
-	li	k0, ST0_CU0
-#else
-	mfc0	k0, CP0_STATUS
-#endif
-	li	k1, ~ST0_IE
-	and	k0, k1
-	mtc0	k0, CP0_STATUS
-
-	/* CAUSE register */
+	/* WP(Watch Pending), SW0/1 should be cleared. */
 	mtc0	zero, CP0_CAUSE
 
+	setup_c0_status_reset
+
 	/* Init Timer */
 	mtc0	zero, CP0_COUNT
 	mtc0	zero, CP0_COMPARE
@@ -240,14 +256,6 @@ reset:
 1:
 	lw	gp, 0(ra)
 
-#ifdef CONFIG_INCA_IP
-	/* Disable INCA-IP Watchdog.
-	 */
-	la	t9, disable_incaip_wdt
-	jalr	t9
-	nop
-#endif
-
 	/* Initialize any external memory.
 	 */
 	la	t9, lowlevel_init
@@ -267,10 +275,12 @@ reset:
 
 	/* Set up temporary stack.
 	 */
+#ifdef CFG_INIT_RAM_LOCK_MIPS
 	li	a0, CFG_INIT_SP_OFFSET
 	la	t9, mips_cache_lock
 	jalr	t9
 	nop
+#endif
 
 	li	t0, CFG_SDRAM_BASE + CFG_INIT_SP_OFFSET
 	la	sp, 0(t0)

+ 5 - 1
cpu/mpc5xxx/cpu.c

@@ -114,12 +114,14 @@ unsigned long get_tbclk (void)
 
 /* ------------------------------------------------------------------------- */
 
-#ifdef CONFIG_OF_LIBFDT
+#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP)
 void ft_cpu_setup(void *blob, bd_t *bd)
 {
 	int div = in_8((void*)CFG_MBAR + 0x204) & 0x0020 ? 8 : 4;
 	char * cpu_path = "/cpus/" OF_CPU;
+#ifdef CONFIG_MPC5xxx_FEC
 	char * eth_path = "/" OF_SOC "/ethernet@3000";
+#endif
 
 	do_fixup_by_path_u32(blob, cpu_path, "timebase-frequency", OF_TBCLK, 1);
 	do_fixup_by_path_u32(blob, cpu_path, "bus-frequency", bd->bi_busfreq, 1);
@@ -127,7 +129,9 @@ void ft_cpu_setup(void *blob, bd_t *bd)
 	do_fixup_by_path_u32(blob, "/" OF_SOC, "bus-frequency", bd->bi_ipbfreq, 1);
 	do_fixup_by_path_u32(blob, "/" OF_SOC, "system-frequency",
 				bd->bi_busfreq*div, 1);
+#ifdef CONFIG_MPC5xxx_FEC
 	do_fixup_by_path(blob, eth_path, "mac-address", bd->bi_enetaddr, 6, 0);
 	do_fixup_by_path(blob, eth_path, "local-mac-address", bd->bi_enetaddr, 6, 0);
+#endif
 }
 #endif

+ 1 - 1
cpu/mpc8260/cpu.c

@@ -300,7 +300,7 @@ void watchdog_reset (void)
 #endif /* CONFIG_WATCHDOG */
 
 /* ------------------------------------------------------------------------- */
-#if defined(CONFIG_OF_LIBFDT)
+#if defined(CONFIG_OF_LIBFDT) && defined (CONFIG_OF_BOARD_SETUP)
 void ft_cpu_setup (void *blob, bd_t *bd)
 {
 	char * cpu_path = "/cpus/" OF_CPU;

+ 13 - 2
cpu/mpc83xx/Makefile

@@ -28,9 +28,20 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(CPU).a
 
 START	= start.o
-COBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o \
-	  spd_sdram.o ecc.o qe_io.o pci.o fdt.o
 
+COBJS-y += traps.o
+COBJS-y += cpu.o
+COBJS-y += cpu_init.o
+COBJS-y += speed.o
+COBJS-y += interrupts.o
+COBJS-y += spd_sdram.o
+COBJS-y += ecc.o
+COBJS-$(CONFIG_QE) += qe_io.o
+COBJS-$(CONFIG_FSL_SERDES) += serdes.o
+COBJS-$(CONFIG_83XX_GENERIC_PCI) += pci.o
+COBJS-$(CONFIG_OF_LIBFDT) += fdt.o
+
+COBJS	:= $(COBJS-y)
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
 START	:= $(addprefix $(obj),$(START))

+ 6 - 0
cpu/mpc83xx/cpu_init.c

@@ -79,6 +79,12 @@ void cpu_init_f (volatile immap_t * im)
 			  (CFG_ACR_RPTCNT << ACR_RPTCNT_SHIFT);
 #endif
 
+#ifdef CFG_SPCR_OPT
+	/* Optimize transactions between CSB and other devices */
+	im->sysconf.spcr = (im->sysconf.spcr & ~SPCR_OPT) |
+			   (CFG_SPCR_OPT << SPCR_OPT_SHIFT);
+#endif
+
 #ifdef CFG_SPCR_TSECEP
 	/* all eTSEC's Emergency priority */
 	im->sysconf.spcr = (im->sysconf.spcr & ~SPCR_TSECEP) |

+ 8 - 4
cpu/mpc83xx/fdt.c

@@ -24,9 +24,6 @@
  */
 
 #include <common.h>
-
-#if defined(CONFIG_OF_LIBFDT)
-
 #include <libfdt.h>
 #include <fdt_support.h>
 
@@ -49,6 +46,14 @@ void ft_cpu_setup(void *blob, bd_t *bd)
 		"clock-frequency", gd->core_clk, 1);
 	do_fixup_by_prop_u32(blob, "device_type", "soc", 4,
 		"bus-frequency", bd->bi_busfreq, 1);
+	do_fixup_by_compat_u32(blob, "fsl,soc",
+		"bus-frequency", bd->bi_busfreq, 1);
+	do_fixup_by_compat_u32(blob, "fsl,soc",
+		"clock-frequency", bd->bi_busfreq, 1);
+	do_fixup_by_compat_u32(blob, "fsl,immr",
+		"bus-frequency", bd->bi_busfreq, 1);
+	do_fixup_by_compat_u32(blob, "fsl,immr",
+		"clock-frequency", bd->bi_busfreq, 1);
 #ifdef CONFIG_QE
 	ft_qe_setup(blob);
 #endif
@@ -68,4 +73,3 @@ void ft_cpu_setup(void *blob, bd_t *bd)
 
 	fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
 }
-#endif /* CONFIG_OF_LIBFDT */

+ 0 - 2
cpu/mpc83xx/pci.c

@@ -33,7 +33,6 @@
 
 #include <asm/mpc8349_pci.h>
 
-#ifdef CONFIG_83XX_GENERIC_PCI
 #define MAX_BUSES 2
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -209,4 +208,3 @@ void ft_pci_setup(void *blob, bd_t *bd)
 	}
 }
 #endif /* CONFIG_OF_LIBFDT */
-#endif /* CONFIG_83XX_GENERIC_PCI */

+ 0 - 3
cpu/mpc83xx/qe_io.c

@@ -25,7 +25,6 @@
 #include "asm/io.h"
 #include "asm/immap_83xx.h"
 
-#if defined(CONFIG_QE)
 #define	NUM_OF_PINS	32
 void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign)
 {
@@ -81,5 +80,3 @@ void qe_config_iopin(u8 port, u8 pin, int dir, int open_drain, int assign)
 		out_be32(&par_io->ioport[port].ppar1, pin_2bit_assign | tmp_val);
 	}
 }
-
-#endif /* CONFIG_QE */

+ 145 - 0
cpu/mpc83xx/serdes.c

@@ -0,0 +1,145 @@
+/*
+ * Freescale SerDes initialization routine
+ *
+ * Copyright (C) 2007 Freescale Semicondutor, Inc. All rights reserved.
+ * Copyright (C) 2008 MontaVista Software, Inc. All rights reserved.
+ *
+ * Author: Li Yang <leoli@freescale.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.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/fsl_serdes.h>
+
+/* SerDes registers */
+#define FSL_SRDSCR0_OFFS		0x0
+#define FSL_SRDSCR0_DPP_1V2		0x00008800
+#define FSL_SRDSCR1_OFFS		0x4
+#define FSL_SRDSCR1_PLLBW		0x00000040
+#define FSL_SRDSCR2_OFFS		0x8
+#define FSL_SRDSCR2_VDD_1V2		0x00800000
+#define FSL_SRDSCR2_SEIC_MASK		0x00001c1c
+#define FSL_SRDSCR2_SEIC_SATA		0x00001414
+#define FSL_SRDSCR2_SEIC_PEX		0x00001010
+#define FSL_SRDSCR2_SEIC_SGMII		0x00000101
+#define FSL_SRDSCR3_OFFS		0xc
+#define FSL_SRDSCR3_KFR_SATA		0x10100000
+#define FSL_SRDSCR3_KPH_SATA		0x04040000
+#define FSL_SRDSCR3_SDFM_SATA_PEX	0x01010000
+#define FSL_SRDSCR3_SDTXL_SATA		0x00000505
+#define FSL_SRDSCR4_OFFS		0x10
+#define FSL_SRDSCR4_PROT_SATA		0x00000808
+#define FSL_SRDSCR4_PROT_PEX		0x00000101
+#define FSL_SRDSCR4_PROT_SGMII		0x00000505
+#define FSL_SRDSCR4_PLANE_X2		0x01000000
+#define FSL_SRDSRSTCTL_OFFS		0x20
+#define FSL_SRDSRSTCTL_RST		0x80000000
+#define FSL_SRDSRSTCTL_SATA_RESET	0xf
+
+void fsl_setup_serdes(u32 offset, char proto, char rfcks, char vdd)
+{
+	void *regs = (void *)CFG_IMMR + offset;
+	u32 tmp;
+
+	/* 1.0V corevdd */
+	if (vdd) {
+		/* DPPE/DPPA = 0 */
+		tmp = in_be32(regs + FSL_SRDSCR0_OFFS);
+		tmp &= ~FSL_SRDSCR0_DPP_1V2;
+		out_be32(regs + FSL_SRDSCR0_OFFS, tmp);
+
+		/* VDD = 0 */
+		tmp = in_be32(regs + FSL_SRDSCR2_OFFS);
+		tmp &= ~FSL_SRDSCR2_VDD_1V2;
+		out_be32(regs + FSL_SRDSCR2_OFFS, tmp);
+	}
+
+	/* protocol specific configuration */
+	switch (proto) {
+	case FSL_SERDES_PROTO_SATA:
+		/* Set and clear reset bits */
+		tmp = in_be32(regs + FSL_SRDSRSTCTL_OFFS);
+		tmp |= FSL_SRDSRSTCTL_SATA_RESET;
+		out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp);
+		udelay(1000);
+		tmp &= ~FSL_SRDSRSTCTL_SATA_RESET;
+		out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp);
+
+		/* Configure SRDSCR1 */
+		tmp = in_be32(regs + FSL_SRDSCR1_OFFS);
+		tmp &= ~FSL_SRDSCR1_PLLBW;
+		out_be32(regs + FSL_SRDSCR1_OFFS, tmp);
+
+		/* Configure SRDSCR2 */
+		tmp = in_be32(regs + FSL_SRDSCR2_OFFS);
+		tmp &= ~FSL_SRDSCR2_SEIC_MASK;
+		tmp |= FSL_SRDSCR2_SEIC_SATA;
+		out_be32(regs + FSL_SRDSCR2_OFFS, tmp);
+
+		/* Configure SRDSCR3 */
+		tmp = FSL_SRDSCR3_KFR_SATA | FSL_SRDSCR3_KPH_SATA |
+			FSL_SRDSCR3_SDFM_SATA_PEX |
+			FSL_SRDSCR3_SDTXL_SATA;
+		out_be32(regs + FSL_SRDSCR3_OFFS, tmp);
+
+		/* Configure SRDSCR4 */
+		tmp = rfcks | FSL_SRDSCR4_PROT_SATA;
+		out_be32(regs + FSL_SRDSCR4_OFFS, tmp);
+		break;
+	case FSL_SERDES_PROTO_PEX:
+	case FSL_SERDES_PROTO_PEX_X2:
+		/* Configure SRDSCR1 */
+		tmp = in_be32(regs + FSL_SRDSCR1_OFFS);
+		tmp |= FSL_SRDSCR1_PLLBW;
+		out_be32(regs + FSL_SRDSCR1_OFFS, tmp);
+
+		/* Configure SRDSCR2 */
+		tmp = in_be32(regs + FSL_SRDSCR2_OFFS);
+		tmp &= ~FSL_SRDSCR2_SEIC_MASK;
+		tmp |= FSL_SRDSCR2_SEIC_PEX;
+		out_be32(regs + FSL_SRDSCR2_OFFS, tmp);
+
+		/* Configure SRDSCR3 */
+		tmp = FSL_SRDSCR3_SDFM_SATA_PEX;
+		out_be32(regs + FSL_SRDSCR3_OFFS, tmp);
+
+		/* Configure SRDSCR4 */
+		tmp = rfcks | FSL_SRDSCR4_PROT_PEX;
+		if (proto == FSL_SERDES_PROTO_PEX_X2)
+			tmp |= FSL_SRDSCR4_PLANE_X2;
+		out_be32(regs + FSL_SRDSCR4_OFFS, tmp);
+		break;
+	case FSL_SERDES_PROTO_SGMII:
+		/* Configure SRDSCR1 */
+		tmp = in_be32(regs + FSL_SRDSCR1_OFFS);
+		tmp &= ~FSL_SRDSCR1_PLLBW;
+		out_be32(regs + FSL_SRDSCR1_OFFS, tmp);
+
+		/* Configure SRDSCR2 */
+		tmp = in_be32(regs + FSL_SRDSCR2_OFFS);
+		tmp &= ~FSL_SRDSCR2_SEIC_MASK;
+		tmp |= FSL_SRDSCR2_SEIC_SGMII;
+		out_be32(regs + FSL_SRDSCR2_OFFS, tmp);
+
+		/* Configure SRDSCR3 */
+		out_be32(regs + FSL_SRDSCR3_OFFS, 0);
+
+		/* Configure SRDSCR4 */
+		tmp = rfcks | FSL_SRDSCR4_PROT_SGMII;
+		out_be32(regs + FSL_SRDSCR4_OFFS, tmp);
+		break;
+	default:
+		return;
+	}
+
+	/* Do a software reset */
+	tmp = in_be32(regs + FSL_SRDSRSTCTL_OFFS);
+	tmp |= FSL_SRDSRSTCTL_RST;
+	out_be32(regs + FSL_SRDSRSTCTL_OFFS, tmp);
+}

+ 3 - 0
cpu/mpc85xx/Makefile

@@ -29,6 +29,9 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(CPU).a
 
 START	= start.o resetvec.o
+SOBJS-$(CONFIG_MP) += release.o
+SOBJS	= $(SOBJS-y)
+COBJS-$(CONFIG_MP) += mp.o
 COBJS-$(CONFIG_OF_LIBFDT) += fdt.o
 COBJS	= traps.o cpu.o cpu_init.o speed.o interrupts.o tlb.o \
 	  pci.o serial_scc.o commproc.o ether_fcc.o spd_sdram.o qe_io.o \

+ 57 - 45
cpu/mpc85xx/cpu.c

@@ -1,5 +1,5 @@
 /*
- * Copyright 2004,2007 Freescale Semiconductor, Inc.
+ * Copyright 2004,2007,2008 Freescale Semiconductor, Inc.
  * (C) Copyright 2002, 2003 Motorola Inc.
  * Xianghua Xiao (X.Xiao@motorola.com)
  *
@@ -30,6 +30,41 @@
 #include <command.h>
 #include <asm/cache.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
+struct cpu_type {
+	char name[15];
+	u32 soc_ver;
+};
+
+#define CPU_TYPE_ENTRY(x) {#x, SVR_##x}
+
+struct cpu_type cpu_type_list [] = {
+	CPU_TYPE_ENTRY(8533),
+	CPU_TYPE_ENTRY(8533_E),
+	CPU_TYPE_ENTRY(8540),
+	CPU_TYPE_ENTRY(8541),
+	CPU_TYPE_ENTRY(8541_E),
+	CPU_TYPE_ENTRY(8543),
+	CPU_TYPE_ENTRY(8543_E),
+	CPU_TYPE_ENTRY(8544),
+	CPU_TYPE_ENTRY(8544_E),
+	CPU_TYPE_ENTRY(8545),
+	CPU_TYPE_ENTRY(8545_E),
+	CPU_TYPE_ENTRY(8547_E),
+	CPU_TYPE_ENTRY(8548),
+	CPU_TYPE_ENTRY(8548_E),
+	CPU_TYPE_ENTRY(8555),
+	CPU_TYPE_ENTRY(8555_E),
+	CPU_TYPE_ENTRY(8560),
+	CPU_TYPE_ENTRY(8567),
+	CPU_TYPE_ENTRY(8567_E),
+	CPU_TYPE_ENTRY(8568),
+	CPU_TYPE_ENTRY(8568_E),
+	CPU_TYPE_ENTRY(8572),
+	CPU_TYPE_ENTRY(8572_E),
+};
+
 int checkcpu (void)
 {
 	sys_info_t sysinfo;
@@ -39,47 +74,26 @@ int checkcpu (void)
 	uint fam;
 	uint ver;
 	uint major, minor;
+	int i;
 	u32 ddr_ratio;
 	volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
 
 	svr = get_svr();
-	ver = SVR_VER(svr);
+	ver = SVR_SOC_VER(svr);
 	major = SVR_MAJ(svr);
 	minor = SVR_MIN(svr);
 
 	puts("CPU:   ");
-	switch (ver) {
-	case SVR_8540:
-		puts("8540");
-		break;
-	case SVR_8541:
-		puts("8541");
-		break;
-	case SVR_8555:
-		puts("8555");
-		break;
-	case SVR_8560:
-		puts("8560");
-		break;
-	case SVR_8548:
-		puts("8548");
-		break;
-	case SVR_8548_E:
-		puts("8548_E");
-		break;
-	case SVR_8544:
-		puts("8544");
-		break;
-	case SVR_8544_E:
-		puts("8544_E");
-		break;
-	case SVR_8568_E:
-		puts("8568_E");
-		break;
-	default:
+
+	for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++)
+		if (cpu_type_list[i].soc_ver == ver) {
+			puts(cpu_type_list[i].name);
+			break;
+		}
+
+	if (i == ARRAY_SIZE(cpu_type_list))
 		puts("Unknown");
-		break;
-	}
+
 	printf(", Version: %d.%d, (0x%08x)\n", major, minor, svr);
 
 	pvr = get_pvr();
@@ -108,13 +122,16 @@ int checkcpu (void)
 	ddr_ratio = ((gur->porpllsr) & 0x00003e00) >> 9;
 	switch (ddr_ratio) {
 	case 0x0:
-		printf("       DDR:%4lu MHz, ", sysinfo.freqDDRBus / 2000000);
+		printf("       DDR:%4lu MHz (%lu MT/s data rate), ",
+		sysinfo.freqDDRBus / 2000000, sysinfo.freqDDRBus / 1000000);
 		break;
 	case 0x7:
-		printf("       DDR:%4lu MHz (Synchronous), ", sysinfo.freqDDRBus / 2000000);
+		printf("       DDR:%4lu MHz (%lu MT/s data rate) (Synchronous), ",
+		sysinfo.freqDDRBus / 2000000, sysinfo.freqDDRBus / 1000000);
 		break;
 	default:
-		printf("       DDR:%4lu MHz (Asynchronous), ", sysinfo.freqDDRBus / 2000000);
+		printf("       DDR:%4lu MHz (%lu MT/s data rate) (Asynchronous), ",
+		sysinfo.freqDDRBus / 2000000, sysinfo.freqDDRBus / 1000000);
 		break;
 	}
 
@@ -142,10 +159,9 @@ int checkcpu (void)
 		printf("LBC: unknown (lcrr: 0x%08x)\n", lcrr);
 	}
 
-	if (ver == SVR_8560) {
-		printf("CPM:  %lu Mhz\n",
-		       sysinfo.freqSystemBus / 1000000);
-	}
+#ifdef CONFIG_CPM2
+	printf("CPM:  %lu Mhz\n", sysinfo.freqSystemBus / 1000000);
+#endif
 
 	puts("L1:    D-cache 32 kB enabled\n       I-cache 32 kB enabled\n");
 
@@ -190,11 +206,7 @@ int do_reset (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[])
  */
 unsigned long get_tbclk (void)
 {
-
-	sys_info_t  sys_info;
-
-	get_sys_info(&sys_info);
-	return ((sys_info.freqSystemBus + 7L) / 8L);
+	return (gd->bus_clk + 4UL)/8UL;
 }
 
 

+ 7 - 3
cpu/mpc85xx/cpu_init.c

@@ -33,6 +33,7 @@
 #include <asm/io.h>
 #include <asm/mmu.h>
 #include <asm/fsl_law.h>
+#include "mp.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -127,12 +128,12 @@ void config_8560_ioports (volatile ccsr_cpm_t * cpm)
 /* We run cpu_init_early_f in AS = 1 */
 void cpu_init_early_f(void)
 {
-	set_tlb(0, CFG_CCSRBAR, CFG_CCSRBAR,
+	set_tlb(0, CFG_CCSRBAR, CFG_CCSRBAR_PHYS,
 		MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		1, 0, BOOKE_PAGESZ_4K, 0);
 
 	/* set up CCSR if we want it moved */
-#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR)
+#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR_PHYS)
 	{
 		u32 temp;
 
@@ -141,7 +142,7 @@ void cpu_init_early_f(void)
 			1, 1, BOOKE_PAGESZ_4K, 0);
 
 		temp = in_be32((volatile u32 *)CFG_CCSRBAR_DEFAULT);
-		out_be32((volatile u32 *)CFG_CCSRBAR_DEFAULT, CFG_CCSRBAR >> 12);
+		out_be32((volatile u32 *)CFG_CCSRBAR_DEFAULT, CFG_CCSRBAR_PHYS >> 12);
 
 		temp = in_be32((volatile u32 *)CFG_CCSRBAR);
 	}
@@ -328,5 +329,8 @@ int cpu_init_r(void)
 	qe_reset();
 #endif
 
+#if defined(CONFIG_MP)
+	setup_mp();
+#endif
 	return 0;
 }

+ 52 - 0
cpu/mpc85xx/fdt.c

@@ -28,6 +28,54 @@
 #include <fdt_support.h>
 
 extern void ft_qe_setup(void *blob);
+#ifdef CONFIG_MP
+#include "mp.h"
+DECLARE_GLOBAL_DATA_PTR;
+
+void ft_fixup_cpu(void *blob, u64 memory_limit)
+{
+	int off;
+	ulong spin_tbl_addr = get_spin_addr();
+	u32 bootpg, id = get_my_id();
+
+	/* if we have 4G or more of memory, put the boot page at 4Gb-4k */
+	if ((u64)gd->ram_size > 0xfffff000)
+		bootpg = 0xfffff000;
+	else
+		bootpg = gd->ram_size - 4096;
+
+	off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
+	while (off != -FDT_ERR_NOTFOUND) {
+		u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0);
+
+		if (reg) {
+			if (*reg == id) {
+				fdt_setprop_string(blob, off, "status", "okay");
+			} else {
+				u32 val = *reg * SIZE_BOOT_ENTRY + spin_tbl_addr;
+				val = cpu_to_fdt32(val);
+				fdt_setprop_string(blob, off, "status",
+								"disabled");
+				fdt_setprop_string(blob, off, "enable-method",
+								"spin-table");
+				fdt_setprop(blob, off, "cpu-release-addr",
+						&val, sizeof(val));
+			}
+		} else {
+			printf ("cpu NULL\n");
+		}
+		off = fdt_node_offset_by_prop_value(blob, off,
+				"device_type", "cpu", 4);
+	}
+
+	/* Reserve the boot page so OSes dont use it */
+	if ((u64)bootpg < memory_limit) {
+		off = fdt_add_mem_rsv(blob, bootpg, (u64)4096);
+		if (off < 0)
+			printf("%s: %s\n", __FUNCTION__, fdt_strerror(off));
+	}
+}
+#endif
 
 void ft_cpu_setup(void *blob, bd_t *bd)
 {
@@ -62,4 +110,8 @@ void ft_cpu_setup(void *blob, bd_t *bd)
 #endif
 
 	fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
+
+#ifdef CONFIG_MP
+	ft_fixup_cpu(blob, (u64)bd->bi_memstart + (u64)bd->bi_memsize);
+#endif
 }

+ 210 - 0
cpu/mpc85xx/mp.c

@@ -0,0 +1,210 @@
+/*
+ * Copyright 2008 Freescale Semiconductor.
+ *
+ * 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 <ioports.h>
+#include <lmb.h>
+#include <asm/io.h>
+#include "mp.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+u32 get_my_id()
+{
+	return mfspr(SPRN_PIR);
+}
+
+int cpu_reset(int nr)
+{
+	volatile ccsr_pic_t *pic = (void *)(CFG_MPC85xx_PIC_ADDR);
+	out_be32(&pic->pir, 1 << nr);
+	(void)in_be32(&pic->pir);
+	out_be32(&pic->pir, 0x0);
+
+	return 0;
+}
+
+int cpu_status(int nr)
+{
+	u32 *table, id = get_my_id();
+
+	if (nr == id) {
+		table = (u32 *)get_spin_addr();
+		printf("table base @ 0x%08x\n", table);
+	} else {
+		table = (u32 *)get_spin_addr() + nr * NUM_BOOT_ENTRY;
+		printf("Running on cpu %d\n", id);
+		printf("\n");
+		printf("table @ 0x%08x:\n", table);
+		printf("   addr - 0x%08x\n", table[BOOT_ENTRY_ADDR_LOWER]);
+		printf("   pir  - 0x%08x\n", table[BOOT_ENTRY_PIR]);
+		printf("   r3   - 0x%08x\n", table[BOOT_ENTRY_R3_LOWER]);
+		printf("   r6   - 0x%08x\n", table[BOOT_ENTRY_R6_LOWER]);
+	}
+
+	return 0;
+}
+
+static u8 boot_entry_map[4] = {
+	0,
+	BOOT_ENTRY_PIR,
+	BOOT_ENTRY_R3_LOWER,
+	BOOT_ENTRY_R6_LOWER,
+};
+
+int cpu_release(int nr, int argc, char *argv[])
+{
+	u32 i, val, *table = (u32 *)get_spin_addr() + nr * NUM_BOOT_ENTRY;
+	u64 boot_addr;
+
+	if (nr == get_my_id()) {
+		printf("Invalid to release the boot core.\n\n");
+		return 1;
+	}
+
+	if (argc != 4) {
+		printf("Invalid number of arguments to release.\n\n");
+		return 1;
+	}
+
+#ifdef CFG_64BIT_STRTOUL
+	boot_addr = simple_strtoull(argv[0], NULL, 16);
+#else
+	boot_addr = simple_strtoul(argv[0], NULL, 16);
+#endif
+
+	/* handle pir, r3, r6 */
+	for (i = 1; i < 4; i++) {
+		if (argv[i][0] != '-') {
+			u8 entry = boot_entry_map[i];
+			val = simple_strtoul(argv[i], NULL, 16);
+			table[entry] = val;
+		}
+	}
+
+	table[BOOT_ENTRY_ADDR_UPPER] = (u32)(boot_addr >> 32);
+	table[BOOT_ENTRY_ADDR_LOWER] = (u32)(boot_addr & 0xffffffff);
+
+	return 0;
+}
+
+ulong get_spin_addr(void)
+{
+	extern ulong __secondary_start_page;
+	extern ulong __spin_table;
+
+	ulong addr =
+		(ulong)&__spin_table - (ulong)&__secondary_start_page;
+	addr += 0xfffff000;
+
+	return addr;
+}
+
+static void pq3_mp_up(unsigned long bootpg)
+{
+	u32 up, cpu_up_mask, whoami;
+	u32 *table = (u32 *)get_spin_addr();
+	volatile u32 bpcr;
+	volatile ccsr_local_ecm_t *ecm = (void *)(CFG_MPC85xx_ECM_ADDR);
+	volatile ccsr_gur_t *gur = (void *)(CFG_MPC85xx_GUTS_ADDR);
+	volatile ccsr_pic_t *pic = (void *)(CFG_MPC85xx_PIC_ADDR);
+	u32 devdisr;
+	int timeout = 10;
+
+	whoami = in_be32(&pic->whoami);
+	out_be32(&ecm->bptr, 0x80000000 | (bootpg >> 12));
+
+	/* disable time base at the platform */
+	devdisr = in_be32(&gur->devdisr);
+	if (whoami)
+		devdisr |= MPC85xx_DEVDISR_TB0;
+	else
+		devdisr |= MPC85xx_DEVDISR_TB1;
+	out_be32(&gur->devdisr, devdisr);
+
+	/* release the hounds */
+	up = ((1 << CONFIG_NR_CPUS) - 1);
+	bpcr = in_be32(&ecm->eebpcr);
+	bpcr |= (up << 24);
+	out_be32(&ecm->eebpcr, bpcr);
+	asm("sync; isync; msync");
+
+	cpu_up_mask = 1 << whoami;
+	/* wait for everyone */
+	while (timeout) {
+		int i;
+		for (i = 1; i < CONFIG_NR_CPUS; i++) {
+			if (table[i * NUM_BOOT_ENTRY])
+				cpu_up_mask |= (1 << i);
+		};
+
+		if ((cpu_up_mask & up) == up)
+			break;
+
+		udelay(100);
+		timeout--;
+	}
+
+	/* enable time base at the platform */
+	if (whoami)
+		devdisr |= MPC85xx_DEVDISR_TB1;
+	else
+		devdisr |= MPC85xx_DEVDISR_TB0;
+	out_be32(&gur->devdisr, devdisr);
+	mtspr(SPRN_TBWU, 0);
+	mtspr(SPRN_TBWL, 0);
+
+	devdisr &= ~(MPC85xx_DEVDISR_TB0 | MPC85xx_DEVDISR_TB1);
+	out_be32(&gur->devdisr, devdisr);
+}
+
+void cpu_mp_lmb_reserve(struct lmb *lmb)
+{
+	u32 bootpg;
+
+	/* if we have 4G or more of memory, put the boot page at 4Gb-4k */
+	if ((u64)gd->ram_size > 0xfffff000)
+		bootpg = 0xfffff000;
+	else
+		bootpg = gd->ram_size - 4096;
+
+	lmb_reserve(lmb, bootpg, 4096);
+}
+
+void setup_mp(void)
+{
+	extern ulong __secondary_start_page;
+	ulong fixup = (ulong)&__secondary_start_page;
+	u32 bootpg;
+
+	/* if we have 4G or more of memory, put the boot page at 4Gb-4k */
+	if ((u64)gd->ram_size > 0xfffff000)
+		bootpg = 0xfffff000;
+	else
+		bootpg = gd->ram_size - 4096;
+
+	memcpy((void *)bootpg, (void *)fixup, 4096);
+	flush_cache(bootpg, 4096);
+
+	pq3_mp_up(bootpg);
+}

+ 20 - 0
cpu/mpc85xx/mp.h

@@ -0,0 +1,20 @@
+#ifndef __MPC85XX_MP_H_
+#define __MPC85XX_MP_H_
+
+ulong get_spin_addr(void);
+void setup_mp(void);
+u32 get_my_id(void);
+void cpu_mp_lmb_reserve(struct lmb *lmb);
+
+#define BOOT_ENTRY_ADDR_UPPER	0
+#define BOOT_ENTRY_ADDR_LOWER	1
+#define BOOT_ENTRY_R3_UPPER	2
+#define BOOT_ENTRY_R3_LOWER	3
+#define BOOT_ENTRY_RESV		4
+#define BOOT_ENTRY_PIR		5
+#define BOOT_ENTRY_R6_UPPER	6
+#define BOOT_ENTRY_R6_LOWER	7
+#define NUM_BOOT_ENTRY		8
+#define SIZE_BOOT_ENTRY		(NUM_BOOT_ENTRY * sizeof(u32))
+
+#endif

Some files were not shown because too many files changed in this diff