[new uImage] Factor out common image_get_ramdisk() routine

Architecture specific do_bootm_linux() routines share common
ramdisk image processing code. Move this code to a common
helper routine.

Signed-off-by: Marian Balakowicz <m8@semihalf.com>
diff --git a/common/image.c b/common/image.c
index 6726f03..e4be4ca 100644
--- a/common/image.c
+++ b/common/image.c
@@ -23,10 +23,20 @@
  * MA 02111-1307 USA
  */
 #ifndef USE_HOSTCC
-# include <common.h>
-# include <watchdog.h>
+#include <common.h>
+#include <watchdog.h>
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+#include <status_led.h>
+#endif
+
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+#endif
+
+extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 #else
-# include "mkimage.h"
+#include "mkimage.h"
 #endif
 
 #include <image.h>
@@ -280,4 +290,191 @@
 
 	return name;
 }
+
+/**
+ * image_get_ramdisk - get and verify ramdisk image
+ * @cmdtp: command table pointer
+ * @flag: command flag
+ * @argc: command argument count
+ * @argv: command argument list
+ * @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, board is reset
+ */
+image_header_t* image_get_ramdisk (cmd_tbl_t *cmdtp, int flag,
+		int argc, char *argv[],
+		ulong rd_addr, uint8_t arch, int verify)
+{
+	image_header_t *rd_hdr;
+
+	show_boot_progress (9);
+
+#ifdef CONFIG_HAS_DATAFLASH
+	if (addr_dataflash (rd_addr)) {
+		rd_hdr = (image_header_t *)CFG_LOAD_ADDR;
+		debug ("   Reading Ramdisk image header from dataflash address "
+			"%08lx to %08lx\n", rd_addr, (ulong)rd_hdr);
+		read_dataflash (rd_addr, image_get_header_size (),
+				(char *)rd_hdr);
+	} else
 #endif
+	rd_hdr = (image_header_t *)rd_addr;
+
+	if (!image_check_magic (rd_hdr)) {
+		puts ("Bad Magic Number\n");
+		show_boot_progress (-10);
+		do_reset (cmdtp, flag, argc, argv);
+	}
+
+	if (!image_check_hcrc (rd_hdr)) {
+		puts ("Bad Header Checksum\n");
+		show_boot_progress (-11);
+		do_reset (cmdtp, flag, argc, argv);
+	}
+
+	show_boot_progress (10);
+	print_image_hdr (rd_hdr);
+
+#ifdef CONFIG_HAS_DATAFLASH
+	if (addr_dataflash (rd_addr)) {
+		debug ("   Reading Ramdisk image data from dataflash address "
+			"%08lx to %08lx\n", rd_addr + image_get_header_size,
+			(ulong)image_get_data (rd_hdr));
+
+		read_dataflash (rd_addr + image_get_header_size (),
+				image_get_data_size (rd_hdr),
+				(char *)image_get_data (rd_hdr));
+	}
+#endif
+
+	if (verify) {
+		puts("   Verifying Checksum ... ");
+		if (!image_check_dcrc_wd (rd_hdr, CHUNKSZ)) {
+			puts ("Bad Data CRC\n");
+			show_boot_progress (-12);
+			do_reset (cmdtp, flag, argc, argv);
+		}
+		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",
+				image_get_arch_name(arch));
+		show_boot_progress (-13);
+		do_reset (cmdtp, flag, argc, argv);
+	}
+
+	return rd_hdr;
+}
+
+/**
+ * get_ramdisk - main ramdisk handling routine
+ * @cmdtp: command table pointer
+ * @flag: command flag
+ * @argc: command argument count
+ * @argv: command argument list
+ * @hdr: pointer to the posiibly multi componet kernel image
+ * @verify: checksum verification flag
+ * @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
+ *
+ * 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:
+ *     rd_start and rd_end are set to ramdisk start/end addresses if
+ *     ramdisk image is found and valid
+ *     rd_start and rd_end are set to 0 if no ramdisk exists
+ *     board is reset if ramdisk image is found but corrupted
+ */
+void get_ramdisk (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+		image_header_t *hdr, int verify, uint8_t arch,
+		ulong *rd_start, ulong *rd_end)
+{
+	ulong rd_addr;
+	ulong rd_data, rd_len;
+	image_header_t *rd_hdr;
+
+	if (argc >= 3) {
+		/*
+		 * Look for a '-' which indicates to ignore the
+		 * ramdisk argument
+		 */
+		if (strcmp(argv[2], "-") ==  0) {
+			debug ("## Skipping init Ramdisk\n");
+			rd_len = rd_data = 0;
+		} else {
+			/*
+			 * Check if there is an initrd image at the
+			 * address provided in the second bootm argument
+			 */
+			rd_addr = simple_strtoul (argv[2], NULL, 16);
+			printf ("## Loading init Ramdisk Image at %08lx ...\n",
+					rd_addr);
+
+			rd_hdr = image_get_ramdisk (cmdtp, flag, argc, argv,
+						rd_addr, arch, verify);
+
+			rd_data = image_get_data (rd_hdr);
+			rd_len = image_get_data_size (rd_hdr);
+
+#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)
+			/*
+			 *we need to copy the ramdisk to SRAM to let Linux boot
+			 */
+			memmove ((void *)image_get_load (rd_hdr),
+					(uchar *)rd_data, rd_len);
+
+			rd_data = image_get_load (rd_hdr);
+#endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */
+		}
+
+	} else if (image_check_type (hdr, IH_TYPE_MULTI)) {
+		/*
+		 * Now check if we have a multifile image
+		 * Get second entry data start address and len
+		 */
+		show_boot_progress (13);
+		printf ("## Loading init Ramdisk from multi component "
+				"Image at %08lx ...\n", (ulong)hdr);
+		image_multi_getimg (hdr, 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");
+		*rd_start = 0;
+		*rd_end = 0;
+	} 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);
+}
+#endif /* USE_HOSTCC */
+