All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kumar Gala <galak@kernel.crashing.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [WIP][PATCH 06/11] bootm: refactor fdt locating and relocation code
Date: Tue, 12 Aug 2008 08:44:31 -0500	[thread overview]
Message-ID: <1218548676-25159-7-git-send-email-galak@kernel.crashing.org> (raw)
In-Reply-To: <1218548676-25159-6-git-send-email-galak@kernel.crashing.org>

Move the code that handles finding a device tree blob and relocating
it (if needed) into common code so all arch's have access to it.

Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
---
 common/cmd_bootm.c |   10 +
 common/image.c     |  502 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/image.h    |   13 ++
 lib_ppc/bootm.c    |  492 +--------------------------------------------------
 4 files changed, 533 insertions(+), 484 deletions(-)

diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 56236b9..918ea98 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -258,6 +258,16 @@ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 			puts ("Ramdisk image is corrupt\n");
 			return 1;
 		}
+
+#if defined(CONFIG_OF_LIBFDT)
+		/* find flattened device tree */
+		ret = boot_get_fdt (cmdtp, flag, argc, argv,
+				    &images, &images.ft_addr, &images.ft_len);
+		if (ret) {
+			puts ("Could not find a valid device tree\n");
+			return 1;
+		}
+#endif
 	}
 
 	image_start = (ulong)os_hdr;
diff --git a/common/image.c b/common/image.c
index 6d2ce32..e7cb57c 100644
--- a/common/image.c
+++ b/common/image.c
@@ -1070,6 +1070,508 @@ error:
 	return -1;
 }
 
+#ifdef CONFIG_OF_LIBFDT
+static void fdt_error (const char *msg)
+{
+	puts ("ERROR: ");
+	puts (msg);
+	puts (" - must RESET the board to recover.\n");
+}
+
+static image_header_t *image_get_fdt (ulong fdt_addr)
+{
+	image_header_t *fdt_hdr = (image_header_t *)fdt_addr;
+
+	image_print_contents (fdt_hdr);
+
+	puts ("   Verifying Checksum ... ");
+	if (!image_check_hcrc (fdt_hdr)) {
+		fdt_error ("fdt header checksum invalid");
+		return NULL;
+	}
+
+	if (!image_check_dcrc (fdt_hdr)) {
+		fdt_error ("fdt checksum invalid");
+		return NULL;
+	}
+	puts ("OK\n");
+
+	if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) {
+		fdt_error ("uImage is not a fdt");
+		return NULL;
+	}
+	if (image_get_comp (fdt_hdr) != IH_COMP_NONE) {
+		fdt_error ("uImage is compressed");
+		return NULL;
+	}
+	if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) {
+		fdt_error ("uImage data is not a fdt");
+		return NULL;
+	}
+	return fdt_hdr;
+}
+
+/**
+ * fit_check_fdt - verify FIT format FDT subimage
+ * @fit_hdr: pointer to the FIT  header
+ * fdt_noffset: FDT subimage node offset within FIT image
+ * @verify: data CRC verification flag
+ *
+ * fit_check_fdt() verifies integrity of the FDT subimage and from
+ * specified FIT image.
+ *
+ * returns:
+ *     1, on success
+ *     0, on failure
+ */
+#if defined(CONFIG_FIT)
+static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
+{
+	fit_image_print (fit, fdt_noffset, "   ");
+
+	if (verify) {
+		puts ("   Verifying Hash Integrity ... ");
+		if (!fit_image_check_hashes (fit, fdt_noffset)) {
+			fdt_error ("Bad Data Hash");
+			return 0;
+		}
+		puts ("OK\n");
+	}
+
+	if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) {
+		fdt_error ("Not a FDT image");
+		return 0;
+	}
+
+	if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) {
+		fdt_error ("FDT image is compressed");
+		return 0;
+	}
+
+	return 1;
+}
+#endif /* CONFIG_FIT */
+
+#ifndef CFG_FDT_PAD
+#define CFG_FDT_PAD 0x3000
+#endif
+
+/**
+ * boot_relocate_fdt - relocate flat device tree
+ * @lmb: pointer to lmb handle, will be used for memory mgmt
+ * @bootmap_base: base address of the bootmap region
+ * @of_flat_tree: pointer to a char* variable, will hold fdt start address
+ * @of_size: pointer to a ulong variable, will hold fdt length
+ *
+ * boot_relocate_fdt() determines if the of_flat_tree address is within
+ * the bootmap and if not relocates it into that region
+ *
+ * of_flat_tree and of_size are set to final (after relocation) values
+ *
+ * returns:
+ *      0 - success
+ *      1 - failure
+ */
+int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
+		char **of_flat_tree, ulong *of_size)
+{
+	char	*fdt_blob = *of_flat_tree;
+	ulong	relocate = 0;
+	ulong	of_len = 0;
+
+	/* nothing to do */
+	if (*of_size == 0)
+		return 0;
+
+	if (fdt_check_header (fdt_blob) != 0) {
+		fdt_error ("image is not a fdt");
+		goto error;
+	}
+
+#ifndef CFG_NO_FLASH
+	/* move the blob if it is in flash (set relocate) */
+	if (addr2info ((ulong)fdt_blob) != NULL)
+		relocate = 1;
+#endif
+
+	/*
+	 * The blob needs to be inside the boot mapping.
+	 */
+	if (fdt_blob < (char *)bootmap_base)
+		relocate = 1;
+
+	if ((fdt_blob + *of_size + CFG_FDT_PAD) >=
+			((char *)CFG_BOOTMAPSZ + bootmap_base))
+		relocate = 1;
+
+	/* move flattend device tree if needed */
+	if (relocate) {
+		int err;
+		ulong of_start = 0;
+
+		/* position on a 4K boundary before the alloc_current */
+		/* Pad the FDT by a specified amount */
+		of_len = *of_size + CFG_FDT_PAD;
+		of_start = (unsigned long)lmb_alloc_base(lmb, of_len, 0x1000,
+				(CFG_BOOTMAPSZ + bootmap_base));
+
+		if (of_start == 0) {
+			puts("device tree - allocation error\n");
+			goto error;
+		}
+
+		debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
+			(ulong)fdt_blob, (ulong)fdt_blob + *of_size - 1,
+			of_len, of_len);
+
+		printf ("   Loading Device Tree to %08lx, end %08lx ... ",
+			of_start, of_start + of_len - 1);
+
+		err = fdt_open_into (fdt_blob, (void *)of_start, of_len);
+		if (err != 0) {
+			fdt_error ("fdt move failed");
+			goto error;
+		}
+		puts ("OK\n");
+
+		*of_flat_tree = (char *)of_start;
+		*of_size = of_len;
+	} else {
+		*of_flat_tree = fdt_blob;
+		of_len = (CFG_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob;
+		lmb_reserve(lmb, (ulong)fdt_blob, of_len);
+		fdt_set_totalsize(*of_flat_tree, of_len);
+
+		*of_size = of_len;
+	}
+
+	return 0;
+
+error:
+	return 1;
+}
+
+/**
+ * boot_get_fdt - main fdt handling routine
+ * @argc: command argument count
+ * @argv: command argument list
+ * @images: pointer to the bootm images structure
+ * @of_flat_tree: pointer to a char* variable, will hold fdt start address
+ * @of_size: pointer to a ulong variable, will hold fdt length
+ *
+ * boot_get_fdt() is responsible for finding a valid flat device tree image.
+ * Curently supported are the following ramdisk sources:
+ *      - multicomponent kernel/ramdisk image,
+ *      - commandline provided address of decicated ramdisk image.
+ *
+ * returns:
+ *     0, if fdt image was found and valid, or skipped
+ *     of_flat_tree and of_size are set to fdt start address and length if
+ *     fdt image is found and valid
+ *
+ *     1, if fdt image is found but corrupted
+ *     of_flat_tree and of_size are set to 0 if no fdt exists
+ */
+int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+		bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
+{
+	ulong		fdt_addr;
+	image_header_t	*fdt_hdr;
+	char		*fdt_blob = NULL;
+	ulong		image_start, image_end;
+	ulong		load_start, load_end;
+#if defined(CONFIG_FIT)
+	void		*fit_hdr;
+	const char	*fit_uname_config = NULL;
+	const char	*fit_uname_fdt = NULL;
+	ulong		default_addr;
+	int		cfg_noffset;
+	int		fdt_noffset;
+	const void	*data;
+	size_t		size;
+#endif
+
+	*of_flat_tree = NULL;
+	*of_size = 0;
+
+	if (argc > 3 || genimg_has_config (images)) {
+#if defined(CONFIG_FIT)
+		if (argc > 3) {
+			/*
+			 * If the FDT blob comes from the FIT image and the
+			 * FIT image address is omitted in the command line
+			 * argument, try to use ramdisk or os FIT image
+			 * address or default load address.
+			 */
+			if (images->fit_uname_rd)
+				default_addr = (ulong)images->fit_hdr_rd;
+			else if (images->fit_uname_os)
+				default_addr = (ulong)images->fit_hdr_os;
+			else
+				default_addr = load_addr;
+
+			if (fit_parse_conf (argv[3], default_addr,
+						&fdt_addr, &fit_uname_config)) {
+				debug ("*  fdt: config '%s' from image at 0x%08lx\n",
+						fit_uname_config, fdt_addr);
+			} else if (fit_parse_subimage (argv[3], default_addr,
+						&fdt_addr, &fit_uname_fdt)) {
+				debug ("*  fdt: subimage '%s' from image at 0x%08lx\n",
+						fit_uname_fdt, fdt_addr);
+			} else
+#endif
+			{
+				fdt_addr = simple_strtoul(argv[3], NULL, 16);
+				debug ("*  fdt: cmdline image address = 0x%08lx\n",
+						fdt_addr);
+			}
+#if defined(CONFIG_FIT)
+		} else {
+			/* use FIT configuration provided in first bootm
+			 * command argument
+			 */
+			fdt_addr = (ulong)images->fit_hdr_os;
+			fit_uname_config = images->fit_uname_cfg;
+			debug ("*  fdt: using config '%s' from image at 0x%08lx\n",
+					fit_uname_config, fdt_addr);
+
+			/*
+			 * Check whether configuration has FDT blob defined,
+			 * if not quit silently.
+			 */
+			fit_hdr = (void *)fdt_addr;
+			cfg_noffset = fit_conf_get_node (fit_hdr,
+					fit_uname_config);
+			if (cfg_noffset < 0) {
+				debug ("*  fdt: no such config\n");
+				return 0;
+			}
+
+			fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
+					cfg_noffset);
+			if (fdt_noffset < 0) {
+				debug ("*  fdt: no fdt in config\n");
+				return 0;
+			}
+		}
+#endif
+
+		debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n",
+				fdt_addr);
+
+		/* copy from dataflash if needed */
+		fdt_addr = genimg_get_image (fdt_addr);
+
+		/*
+		 * Check if there is an FDT image at the
+		 * address provided in the second bootm argument
+		 * check image type, for FIT images get a FIT node.
+		 */
+		switch (genimg_get_format ((void *)fdt_addr)) {
+		case IMAGE_FORMAT_LEGACY:
+			/* verify fdt_addr points to a valid image header */
+			printf ("## Flattened Device Tree from Legacy Image@%08lx\n",
+					fdt_addr);
+			fdt_hdr = image_get_fdt (fdt_addr);
+			if (!fdt_hdr)
+				goto error;
+
+			/*
+			 * move image data to the load address,
+			 * make sure we don't overwrite initial image
+			 */
+			image_start = (ulong)fdt_hdr;
+			image_end = image_get_image_end (fdt_hdr);
+
+			load_start = image_get_load (fdt_hdr);
+			load_end = load_start + image_get_data_size (fdt_hdr);
+
+			if ((load_start < image_end) && (load_end > image_start)) {
+				fdt_error ("fdt overwritten");
+				goto error;
+			}
+
+			debug ("   Loading FDT from 0x%08lx to 0x%08lx\n",
+					image_get_data (fdt_hdr), load_start);
+
+			memmove ((void *)load_start,
+					(void *)image_get_data (fdt_hdr),
+					image_get_data_size (fdt_hdr));
+
+			fdt_blob = (char *)load_start;
+			break;
+		case IMAGE_FORMAT_FIT:
+			/*
+			 * This case will catch both: new uImage format
+			 * (libfdt based) and raw FDT blob (also libfdt
+			 * based).
+			 */
+#if defined(CONFIG_FIT)
+			/* check FDT blob vs FIT blob */
+			if (fit_check_format ((const void *)fdt_addr)) {
+				/*
+				 * FIT image
+				 */
+				fit_hdr = (void *)fdt_addr;
+				printf ("## Flattened Device Tree from FIT Image at %08lx\n",
+						fdt_addr);
+
+				if (!fit_uname_fdt) {
+					/*
+					 * no FDT blob 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
+					 */
+					cfg_noffset = fit_conf_get_node (fit_hdr,
+							fit_uname_config);
+
+					if (cfg_noffset < 0) {
+						fdt_error ("Could not find configuration node\n");
+						goto error;
+					}
+
+					fit_uname_config = fdt_get_name (fit_hdr,
+							cfg_noffset, NULL);
+					printf ("   Using '%s' configuration\n",
+							fit_uname_config);
+
+					fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
+							cfg_noffset);
+					fit_uname_fdt = fit_get_name (fit_hdr,
+							fdt_noffset, NULL);
+				} else {
+					/* get FDT component image node offset */
+					fdt_noffset = fit_image_get_node (fit_hdr,
+							fit_uname_fdt);
+				}
+				if (fdt_noffset < 0) {
+					fdt_error ("Could not find subimage node\n");
+					goto error;
+				}
+
+				printf ("   Trying '%s' FDT blob subimage\n",
+						fit_uname_fdt);
+
+				if (!fit_check_fdt (fit_hdr, fdt_noffset,
+							images->verify))
+					goto error;
+
+				/* get ramdisk image data address and length */
+				if (fit_image_get_data (fit_hdr, fdt_noffset,
+							&data, &size)) {
+					fdt_error ("Could not find FDT subimage data");
+					goto error;
+				}
+
+				/* verift that image data is a proper FDT blob */
+				if (fdt_check_header ((char *)data) != 0) {
+					fdt_error ("Subimage data is not a FTD");
+					goto error;
+				}
+
+				/*
+				 * move image data to the load address,
+				 * make sure we don't overwrite initial image
+				 */
+				image_start = (ulong)fit_hdr;
+				image_end = fit_get_end (fit_hdr);
+
+				if (fit_image_get_load (fit_hdr, fdt_noffset,
+							&load_start) == 0) {
+					load_end = load_start + size;
+
+					if ((load_start < image_end) &&
+							(load_end > image_start)) {
+						fdt_error ("FDT overwritten");
+						goto error;
+					}
+
+					printf ("   Loading FDT from 0x%08lx to 0x%08lx\n",
+							(ulong)data, load_start);
+
+					memmove ((void *)load_start,
+							(void *)data, size);
+
+					fdt_blob = (char *)load_start;
+				} else {
+					fdt_blob = (char *)data;
+				}
+
+				images->fit_hdr_fdt = fit_hdr;
+				images->fit_uname_fdt = fit_uname_fdt;
+				images->fit_noffset_fdt = fdt_noffset;
+				break;
+			} else
+#endif
+			{
+				/*
+				 * FDT blob
+				 */
+				fdt_blob = (char *)fdt_addr;
+				debug ("*  fdt: raw FDT blob\n");
+				printf ("## Flattened Device Tree blob at %08lx\n", (long)fdt_blob);
+			}
+			break;
+		default:
+			fdt_error ("Did not find a cmdline Flattened Device Tree");
+			goto error;
+		}
+
+		printf ("   Booting using the fdt blob at 0x%x\n", (int)fdt_blob);
+
+	} else if (images->legacy_hdr_valid &&
+			image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
+
+		ulong fdt_data, fdt_len;
+
+		/*
+		 * Now check if we have a legacy multi-component image,
+		 * get second entry data start address and len.
+		 */
+		printf ("## Flattened Device Tree from multi "
+			"component Image at %08lX\n",
+			(ulong)images->legacy_hdr_os);
+
+		image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len);
+		if (fdt_len) {
+
+			fdt_blob = (char *)fdt_data;
+			printf ("   Booting using the fdt at 0x%x\n", (int)fdt_blob);
+
+			if (fdt_check_header (fdt_blob) != 0) {
+				fdt_error ("image is not a fdt");
+				goto error;
+			}
+
+			if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) {
+				fdt_error ("fdt size != image size");
+				goto error;
+			}
+		} else {
+			debug ("## No Flattened Device Tree\n");
+			return 0;
+		}
+	} else {
+		debug ("## No Flattened Device Tree\n");
+		return 0;
+	}
+
+	*of_flat_tree = fdt_blob;
+	*of_size = be32_to_cpu (fdt_totalsize (fdt_blob));
+	debug ("   of_flat_tree at 0x%08lx size 0x%08lx\n",
+			*of_flat_tree, *of_size);
+
+	return 0;
+
+error:
+	*of_flat_tree = 0;
+	*of_size = 0;
+	return 1;
+}
+#endif /* CONFIG_OF_LIBFDT */
+
 /**
  * boot_get_cmdline - allocate and initialize kernel cmdline
  * @lmb: pointer to lmb handle, will be used for memory mgmt
diff --git a/include/image.h b/include/image.h
index b8577a0..04dd7d2 100644
--- a/include/image.h
+++ b/include/image.h
@@ -223,6 +223,11 @@ typedef struct bootm_headers {
 
 	ulong		rd_start, rd_end;/* ramdisk start/end */
 
+#ifdef CONFIG_OF_LIBFDT
+	char		*ft_addr;	/* flat dev tree address */
+	ulong		ft_len;		/* length of flat device tree */
+#endif
+
 	int		verify;		/* getenv("verify")[0] != 'n' */
 	struct lmb	*lmb;		/* for memory mgmt */
 } bootm_headers_t;
@@ -273,6 +278,14 @@ ulong genimg_get_image (ulong img_addr);
 int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,
 		uint8_t arch, ulong *rd_start, ulong *rd_end);
 
+
+#ifdef CONFIG_OF_LIBFDT
+int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
+		bootm_headers_t *images, char **of_flat_tree, ulong *of_size);
+int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
+		char **of_flat_tree, ulong *of_size);
+#endif
+
 #if defined(CONFIG_PPC) || defined(CONFIG_M68K)
 int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,
 		  ulong *initrd_start, ulong *initrd_end);
diff --git a/lib_ppc/bootm.c b/lib_ppc/bootm.c
index 942b891..45f6a47 100644
--- a/lib_ppc/bootm.c
+++ b/lib_ppc/bootm.c
@@ -39,22 +39,12 @@
 #include <libfdt.h>
 #include <fdt_support.h>
 
-static void fdt_error (const char *msg);
-static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		bootm_headers_t *images, char **of_flat_tree, ulong *of_size);
-static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
-		cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		char **of_flat_tree, ulong *of_size);
 #endif
 
 #ifdef CFG_INIT_RAM_LOCK
 #include <asm/cache.h>
 #endif
 
-#ifndef CFG_FDT_PAD
-#define CFG_FDT_PAD 0x3000
-#endif
-
 DECLARE_GLOBAL_DATA_PTR;
 
 extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
@@ -82,11 +72,11 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 	void	(*kernel)(bd_t *, ulong r4, ulong r5, ulong r6,
 			  ulong r7, ulong r8, ulong r9);
 	int	ret;
-	ulong	of_size = 0;
+	ulong	of_size = images->ft_len;
 	struct lmb *lmb = images->lmb;
 
 #if defined(CONFIG_OF_LIBFDT)
-	char	*of_flat_tree = NULL;
+	char	*of_flat_tree = images->ft_addr;
 #endif
 
 	kernel = (void (*)(bd_t *, ulong, ulong, ulong,
@@ -128,14 +118,6 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 	sp -= 1024;
 	lmb_reserve(lmb, sp, (CFG_SDRAM_BASE + get_effective_memsize() - sp));
 
-#if defined(CONFIG_OF_LIBFDT)
-	/* find flattened device tree */
-	ret = boot_get_fdt (cmdtp, flag, argc, argv, images, &of_flat_tree, &of_size);
-
-	if (ret)
-		goto error;
-#endif
-
 	if (!of_size) {
 		/* allocate space and init command line */
 		ret = boot_get_cmdline (lmb, &cmd_start, &cmd_end, bootmap_base);
@@ -156,8 +138,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 	rd_len = images->rd_end - images->rd_start;
 
 #if defined(CONFIG_OF_LIBFDT)
-	ret = boot_relocate_fdt (lmb, bootmap_base,
-		cmdtp, flag, argc, argv, &of_flat_tree, &of_size);
+	ret = boot_relocate_fdt(lmb, bootmap_base, &of_flat_tree, &of_size);
+	if (ret)
+		goto error;
 
 	/*
 	 * Add the chosen node if it doesn't exist, add the env and bd_t
@@ -166,7 +149,9 @@ do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 	if (of_size) {
 		/* pass in dummy initrd info, we'll fix up later */
 		if (fdt_chosen(of_flat_tree, images->rd_start, images->rd_end, 0) < 0) {
-			fdt_error ("/chosen node create failed");
+			puts ("ERROR: ");
+			puts ("/chosen node create failed");
+			puts (" - must RESET the board to recover.\n");
 			goto error;
 		}
 #ifdef CONFIG_OF_BOARD_SETUP
@@ -340,464 +325,3 @@ static void set_clocks_in_mhz (bd_t *kbd)
 #endif /* CONFIG_MPC5xxx */
 	}
 }
-
-#if defined(CONFIG_OF_LIBFDT)
-static void fdt_error (const char *msg)
-{
-	puts ("ERROR: ");
-	puts (msg);
-	puts (" - must RESET the board to recover.\n");
-}
-
-static image_header_t *image_get_fdt (ulong fdt_addr)
-{
-	image_header_t *fdt_hdr = (image_header_t *)fdt_addr;
-
-	image_print_contents (fdt_hdr);
-
-	puts ("   Verifying Checksum ... ");
-	if (!image_check_hcrc (fdt_hdr)) {
-		fdt_error ("fdt header checksum invalid");
-		return NULL;
-	}
-
-	if (!image_check_dcrc (fdt_hdr)) {
-		fdt_error ("fdt checksum invalid");
-		return NULL;
-	}
-	puts ("OK\n");
-
-	if (!image_check_type (fdt_hdr, IH_TYPE_FLATDT)) {
-		fdt_error ("uImage is not a fdt");
-		return NULL;
-	}
-	if (image_get_comp (fdt_hdr) != IH_COMP_NONE) {
-		fdt_error ("uImage is compressed");
-		return NULL;
-	}
-	if (fdt_check_header ((char *)image_get_data (fdt_hdr)) != 0) {
-		fdt_error ("uImage data is not a fdt");
-		return NULL;
-	}
-	return fdt_hdr;
-}
-
-/**
- * fit_check_fdt - verify FIT format FDT subimage
- * @fit_hdr: pointer to the FIT  header
- * fdt_noffset: FDT subimage node offset within FIT image
- * @verify: data CRC verification flag
- *
- * fit_check_fdt() verifies integrity of the FDT subimage and from
- * specified FIT image.
- *
- * returns:
- *     1, on success
- *     0, on failure
- */
-#if defined(CONFIG_FIT)
-static int fit_check_fdt (const void *fit, int fdt_noffset, int verify)
-{
-	fit_image_print (fit, fdt_noffset, "   ");
-
-	if (verify) {
-		puts ("   Verifying Hash Integrity ... ");
-		if (!fit_image_check_hashes (fit, fdt_noffset)) {
-			fdt_error ("Bad Data Hash");
-			return 0;
-		}
-		puts ("OK\n");
-	}
-
-	if (!fit_image_check_type (fit, fdt_noffset, IH_TYPE_FLATDT)) {
-		fdt_error ("Not a FDT image");
-		return 0;
-	}
-
-	if (!fit_image_check_comp (fit, fdt_noffset, IH_COMP_NONE)) {
-		fdt_error ("FDT image is compressed");
-		return 0;
-	}
-
-	return 1;
-}
-#endif /* CONFIG_FIT */
-
-static int boot_get_fdt (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
-{
-	ulong		fdt_addr;
-	image_header_t	*fdt_hdr;
-	char		*fdt_blob = NULL;
-	ulong		image_start, image_end;
-	ulong		load_start, load_end;
-#if defined(CONFIG_FIT)
-	void		*fit_hdr;
-	const char	*fit_uname_config = NULL;
-	const char	*fit_uname_fdt = NULL;
-	ulong		default_addr;
-	int		cfg_noffset;
-	int		fdt_noffset;
-	const void	*data;
-	size_t		size;
-#endif
-
-	*of_flat_tree = NULL;
-	*of_size = 0;
-
-	if (argc > 3 || genimg_has_config (images)) {
-#if defined(CONFIG_FIT)
-		if (argc > 3) {
-			/*
-			 * If the FDT blob comes from the FIT image and the
-			 * FIT image address is omitted in the command line
-			 * argument, try to use ramdisk or os FIT image
-			 * address or default load address.
-			 */
-			if (images->fit_uname_rd)
-				default_addr = (ulong)images->fit_hdr_rd;
-			else if (images->fit_uname_os)
-				default_addr = (ulong)images->fit_hdr_os;
-			else
-				default_addr = load_addr;
-
-			if (fit_parse_conf (argv[3], default_addr,
-						&fdt_addr, &fit_uname_config)) {
-				debug ("*  fdt: config '%s' from image at 0x%08lx\n",
-						fit_uname_config, fdt_addr);
-			} else if (fit_parse_subimage (argv[3], default_addr,
-						&fdt_addr, &fit_uname_fdt)) {
-				debug ("*  fdt: subimage '%s' from image at 0x%08lx\n",
-						fit_uname_fdt, fdt_addr);
-			} else
-#endif
-			{
-				fdt_addr = simple_strtoul(argv[3], NULL, 16);
-				debug ("*  fdt: cmdline image address = 0x%08lx\n",
-						fdt_addr);
-			}
-#if defined(CONFIG_FIT)
-		} else {
-			/* use FIT configuration provided in first bootm
-			 * command argument
-			 */
-			fdt_addr = (ulong)images->fit_hdr_os;
-			fit_uname_config = images->fit_uname_cfg;
-			debug ("*  fdt: using config '%s' from image at 0x%08lx\n",
-					fit_uname_config, fdt_addr);
-
-			/*
-			 * Check whether configuration has FDT blob defined,
-			 * if not quit silently.
-			 */
-			fit_hdr = (void *)fdt_addr;
-			cfg_noffset = fit_conf_get_node (fit_hdr,
-					fit_uname_config);
-			if (cfg_noffset < 0) {
-				debug ("*  fdt: no such config\n");
-				return 0;
-			}
-
-			fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
-					cfg_noffset);
-			if (fdt_noffset < 0) {
-				debug ("*  fdt: no fdt in config\n");
-				return 0;
-			}
-		}
-#endif
-
-		debug ("## Checking for 'FDT'/'FDT Image' at %08lx\n",
-				fdt_addr);
-
-		/* copy from dataflash if needed */
-		fdt_addr = genimg_get_image (fdt_addr);
-
-		/*
-		 * Check if there is an FDT image at the
-		 * address provided in the second bootm argument
-		 * check image type, for FIT images get a FIT node.
-		 */
-		switch (genimg_get_format ((void *)fdt_addr)) {
-		case IMAGE_FORMAT_LEGACY:
-			/* verify fdt_addr points to a valid image header */
-			printf ("## Flattened Device Tree from Legacy Image@%08lx\n",
-					fdt_addr);
-			fdt_hdr = image_get_fdt (fdt_addr);
-			if (!fdt_hdr)
-				goto error;
-
-			/*
-			 * move image data to the load address,
-			 * make sure we don't overwrite initial image
-			 */
-			image_start = (ulong)fdt_hdr;
-			image_end = image_get_image_end (fdt_hdr);
-
-			load_start = image_get_load (fdt_hdr);
-			load_end = load_start + image_get_data_size (fdt_hdr);
-
-			if ((load_start < image_end) && (load_end > image_start)) {
-				fdt_error ("fdt overwritten");
-				goto error;
-			}
-
-			debug ("   Loading FDT from 0x%08lx to 0x%08lx\n",
-					image_get_data (fdt_hdr), load_start);
-
-			memmove ((void *)load_start,
-					(void *)image_get_data (fdt_hdr),
-					image_get_data_size (fdt_hdr));
-
-			fdt_blob = (char *)load_start;
-			break;
-		case IMAGE_FORMAT_FIT:
-			/*
-			 * This case will catch both: new uImage format
-			 * (libfdt based) and raw FDT blob (also libfdt
-			 * based).
-			 */
-#if defined(CONFIG_FIT)
-			/* check FDT blob vs FIT blob */
-			if (fit_check_format ((const void *)fdt_addr)) {
-				/*
-				 * FIT image
-				 */
-				fit_hdr = (void *)fdt_addr;
-				printf ("## Flattened Device Tree from FIT Image at %08lx\n",
-						fdt_addr);
-
-				if (!fit_uname_fdt) {
-					/*
-					 * no FDT blob 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
-					 */
-					cfg_noffset = fit_conf_get_node (fit_hdr,
-							fit_uname_config);
-
-					if (cfg_noffset < 0) {
-						fdt_error ("Could not find configuration node\n");
-						goto error;
-					}
-
-					fit_uname_config = fdt_get_name (fit_hdr,
-							cfg_noffset, NULL);
-					printf ("   Using '%s' configuration\n",
-							fit_uname_config);
-
-					fdt_noffset = fit_conf_get_fdt_node (fit_hdr,
-							cfg_noffset);
-					fit_uname_fdt = fit_get_name (fit_hdr,
-							fdt_noffset, NULL);
-				} else {
-					/* get FDT component image node offset */
-					fdt_noffset = fit_image_get_node (fit_hdr,
-							fit_uname_fdt);
-				}
-				if (fdt_noffset < 0) {
-					fdt_error ("Could not find subimage node\n");
-					goto error;
-				}
-
-				printf ("   Trying '%s' FDT blob subimage\n",
-						fit_uname_fdt);
-
-				if (!fit_check_fdt (fit_hdr, fdt_noffset,
-							images->verify))
-					goto error;
-
-				/* get ramdisk image data address and length */
-				if (fit_image_get_data (fit_hdr, fdt_noffset,
-							&data, &size)) {
-					fdt_error ("Could not find FDT subimage data");
-					goto error;
-				}
-
-				/* verift that image data is a proper FDT blob */
-				if (fdt_check_header ((char *)data) != 0) {
-					fdt_error ("Subimage data is not a FTD");
-					goto error;
-				}
-
-				/*
-				 * move image data to the load address,
-				 * make sure we don't overwrite initial image
-				 */
-				image_start = (ulong)fit_hdr;
-				image_end = fit_get_end (fit_hdr);
-
-				if (fit_image_get_load (fit_hdr, fdt_noffset,
-							&load_start) == 0) {
-					load_end = load_start + size;
-
-					if ((load_start < image_end) &&
-							(load_end > image_start)) {
-						fdt_error ("FDT overwritten");
-						goto error;
-					}
-
-					printf ("   Loading FDT from 0x%08lx to 0x%08lx\n",
-							(ulong)data, load_start);
-
-					memmove ((void *)load_start,
-							(void *)data, size);
-
-					fdt_blob = (char *)load_start;
-				} else {
-					fdt_blob = (char *)data;
-				}
-
-				images->fit_hdr_fdt = fit_hdr;
-				images->fit_uname_fdt = fit_uname_fdt;
-				images->fit_noffset_fdt = fdt_noffset;
-				break;
-			} else
-#endif
-			{
-				/*
-				 * FDT blob
-				 */
-				fdt_blob = (char *)fdt_addr;
-				debug ("*  fdt: raw FDT blob\n");
-				printf ("## Flattened Device Tree blob at %08lx\n", (long)fdt_blob);
-			}
-			break;
-		default:
-			fdt_error ("Did not find a cmdline Flattened Device Tree");
-			goto error;
-		}
-
-		printf ("   Booting using the fdt blob at 0x%x\n", (int)fdt_blob);
-
-	} else if (images->legacy_hdr_valid &&
-			image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
-
-		ulong fdt_data, fdt_len;
-
-		/*
-		 * Now check if we have a legacy multi-component image,
-		 * get second entry data start address and len.
-		 */
-		printf ("## Flattened Device Tree from multi "
-			"component Image at %08lX\n",
-			(ulong)images->legacy_hdr_os);
-
-		image_multi_getimg (images->legacy_hdr_os, 2, &fdt_data, &fdt_len);
-		if (fdt_len) {
-
-			fdt_blob = (char *)fdt_data;
-			printf ("   Booting using the fdt at 0x%x\n", (int)fdt_blob);
-
-			if (fdt_check_header (fdt_blob) != 0) {
-				fdt_error ("image is not a fdt");
-				goto error;
-			}
-
-			if (be32_to_cpu (fdt_totalsize (fdt_blob)) != fdt_len) {
-				fdt_error ("fdt size != image size");
-				goto error;
-			}
-		} else {
-			debug ("## No Flattened Device Tree\n");
-			return 0;
-		}
-	} else {
-		debug ("## No Flattened Device Tree\n");
-		return 0;
-	}
-
-	*of_flat_tree = fdt_blob;
-	*of_size = be32_to_cpu (fdt_totalsize (fdt_blob));
-	debug ("   of_flat_tree at 0x%08lx size 0x%08lx\n",
-			*of_flat_tree, *of_size);
-
-	return 0;
-
-error:
-	do_reset (cmdtp, flag, argc, argv);
-	return 1;
-}
-
-static int boot_relocate_fdt (struct lmb *lmb, ulong bootmap_base,
-		cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
-		char **of_flat_tree, ulong *of_size)
-{
-	char	*fdt_blob = *of_flat_tree;
-	ulong	relocate = 0;
-	ulong	of_len = 0;
-
-	/* nothing to do */
-	if (*of_size == 0)
-		return 0;
-
-	if (fdt_check_header (fdt_blob) != 0) {
-		fdt_error ("image is not a fdt");
-		goto error;
-	}
-
-#ifndef CFG_NO_FLASH
-	/* move the blob if it is in flash (set relocate) */
-	if (addr2info ((ulong)fdt_blob) != NULL)
-		relocate = 1;
-#endif
-
-	/*
-	 * The blob needs to be inside the boot mapping.
-	 */
-	if (fdt_blob < (char *)bootmap_base)
-		relocate = 1;
-
-	if ((fdt_blob + *of_size + CFG_FDT_PAD) >=
-			((char *)CFG_BOOTMAPSZ + bootmap_base))
-		relocate = 1;
-
-	/* move flattend device tree if needed */
-	if (relocate) {
-		int err;
-		ulong of_start = 0;
-
-		/* position on a 4K boundary before the alloc_current */
-		/* Pad the FDT by a specified amount */
-		of_len = *of_size + CFG_FDT_PAD;
-		of_start = (unsigned long)lmb_alloc_base(lmb, of_len, 0x1000,
-				(CFG_BOOTMAPSZ + bootmap_base));
-
-		if (of_start == 0) {
-			puts("device tree - allocation error\n");
-			goto error;
-		}
-
-		debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",
-			(ulong)fdt_blob, (ulong)fdt_blob + *of_size - 1,
-			of_len, of_len);
-
-		printf ("   Loading Device Tree to %08lx, end %08lx ... ",
-			of_start, of_start + of_len - 1);
-
-		err = fdt_open_into (fdt_blob, (void *)of_start, of_len);
-		if (err != 0) {
-			fdt_error ("fdt move failed");
-			goto error;
-		}
-		puts ("OK\n");
-
-		*of_flat_tree = (char *)of_start;
-		*of_size = of_len;
-	} else {
-		*of_flat_tree = fdt_blob;
-		of_len = (CFG_BOOTMAPSZ + bootmap_base) - (ulong)fdt_blob;
-		lmb_reserve(lmb, (ulong)fdt_blob, of_len);
-		fdt_set_totalsize(*of_flat_tree, of_len);
-
-		*of_size = of_len;
-	}
-
-	return 0;
-
-error:
-	return 1;
-}
-#endif
-- 
1.5.5.1

  reply	other threads:[~2008-08-12 13:44 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-12 13:44 [U-Boot] [WIP][PATCH 00/11] bootm refactoring Kumar Gala
2008-08-12 13:44 ` [U-Boot] [WIP][PATCH 01/11] Update linux bootm to support ePAPR client interface Kumar Gala
2008-08-12 13:44   ` [U-Boot] [WIP][PATCH 02/11] add ability to disable ft_board_setup as part of bootm Kumar Gala
2008-08-12 13:44     ` [U-Boot] [WIP][PATCH 03/11] Clean up usage of icache_disable/dcache_disable Kumar Gala
2008-08-12 13:44       ` [U-Boot] [WIP][PATCH 04/11] bootm: refactor entry point code Kumar Gala
2008-08-12 13:44         ` [U-Boot] [WIP][PATCH 05/11] bootm: refactor ramdisk locating code Kumar Gala
2008-08-12 13:44           ` Kumar Gala [this message]
2008-08-12 13:44             ` [U-Boot] [WIP][PATCH 07/11] bootm: Set working fdt address as part of the bootm flow Kumar Gala
2008-08-12 13:44               ` [U-Boot] [WIP][PATCH 08/11] bootm: move lmb into the bootm_headers_t structure Kumar Gala
2008-08-12 13:44                 ` [U-Boot] [WIP][PATCH 09/11] bootm: refactor image detection and os load steps Kumar Gala
2008-08-12 13:44                   ` [U-Boot] [WIP][PATCH 10/11] fdt: refactor fdt resize code Kumar Gala
2008-08-12 13:44                     ` [U-Boot] [WIP][PATCH 11/11] fdt: refactor initrd related code Kumar Gala
2008-08-13  5:12                   ` [U-Boot] [WIP][PATCH 09/11] bootm: refactor image detection and os load steps Jerry Van Baren
2008-08-12 20:12 ` [U-Boot] [WIP][PATCH 00/11] bootm refactoring Wolfgang Denk
2008-08-12 20:17   ` Kumar Gala
2008-08-12 23:15     ` Wolfgang Denk
2008-08-13  1:01       ` Kumar Gala
2008-08-13  5:12         ` Jerry Van Baren

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=1218548676-25159-7-git-send-email-galak@kernel.crashing.org \
    --to=galak@kernel.crashing.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

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

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