diff options
Diffstat (limited to 'common/image-fdt.c')
| -rw-r--r-- | common/image-fdt.c | 245 | 
1 files changed, 135 insertions, 110 deletions
| diff --git a/common/image-fdt.c b/common/image-fdt.c index b698e961fe7..7aad6d57b89 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -252,59 +252,29 @@ error:  }  /** - * boot_get_fdt - main fdt handling routine - * @argc: command argument count - * @argv: command argument list - * @arch: architecture (IH_ARCH_...) - * @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 + * select_fdt() - Select and locate the FDT to use   * - *     1, if fdt image is found but corrupted - *     of_flat_tree and of_size are set to 0 if no fdt exists + * @images: pointer to the bootm images structure + * @select: name of FDT to select, or NULL for any + * @arch: expected FDT architecture + * @fdt_addrp: pointer to a ulong variable, will hold FDT pointer + * @return 0 if OK, -ENOPKG if no FDT (but an error should not be reported), + *	other -ve value on other error   */ -int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, -		 bootm_headers_t *images, char **of_flat_tree, ulong *of_size) -{ -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) -	const image_header_t *fdt_hdr; -	ulong		load, load_end; -	ulong		image_start, image_data, image_end; -#endif -	ulong		img_addr; -	ulong		fdt_addr; -	char		*fdt_blob = NULL; -	void		*buf; -#if CONFIG_IS_ENABLED(FIT) -	const char	*fit_uname_config = images->fit_uname_cfg; -	const char	*fit_uname_fdt = NULL; -	ulong		default_addr; -	int		fdt_noffset; -#endif -	const char *select = NULL; -	*of_flat_tree = NULL; -	*of_size = 0; - -	img_addr = (argc == 0) ? image_load_addr : -			hextoul(argv[0], NULL); -	buf = map_sysmem(img_addr, 0); +static int select_fdt(bootm_headers_t *images, const char *select, u8 arch, +		      ulong *fdt_addrp) +{ +	const char *buf; +	ulong fdt_addr; -	if (argc > 2) -		select = argv[2]; -	if (select || genimg_has_config(images)) {  #if CONFIG_IS_ENABLED(FIT) -		if (select) { +	const char *fit_uname_config = images->fit_uname_cfg; +	const char *fit_uname_fdt = NULL; +	ulong default_addr; +	int fdt_noffset; + +	if (select) {  			/*  			 * If the FDT blob comes from the FIT image and the  			 * FIT image address is omitted in the command line @@ -318,54 +288,57 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,  			else  				default_addr = image_load_addr; -			if (fit_parse_conf(select, default_addr, -					   &fdt_addr, &fit_uname_config)) { +			if (fit_parse_conf(select, 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(select, default_addr, -				   &fdt_addr, &fit_uname_fdt)) { +			} else if (fit_parse_subimage(select, 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 = hextoul(select, NULL); -				debug("*  fdt: cmdline image address = 0x%08lx\n", -				      fdt_addr); -			} -#if CONFIG_IS_ENABLED(FIT) -		} else { -			/* use FIT configuration provided in first bootm -			 * command argument -			 */ -			fdt_addr = map_to_sysmem(images->fit_hdr_os); -			fdt_noffset = fit_get_node_from_config(images, -							       FIT_FDT_PROP, -							       fdt_addr); -			if (fdt_noffset == -ENOENT) -				return 0; -			else if (fdt_noffset < 0) -				return 1; +		{ +			fdt_addr = hextoul(select, NULL); +			debug("*  fdt: cmdline image address = 0x%08lx\n", +			      fdt_addr);  		} -#endif -		debug("## Checking for 'FDT'/'FDT Image' at %08lx\n", -		      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. +#if CONFIG_IS_ENABLED(FIT) +	} else { +		/* use FIT configuration provided in first bootm +		 * command argument  		 */ -		buf = map_sysmem(fdt_addr, 0); -		switch (genimg_get_format(buf)) { +		fdt_addr = map_to_sysmem(images->fit_hdr_os); +		fdt_noffset = fit_get_node_from_config(images, FIT_FDT_PROP, +						       fdt_addr); +		if (fdt_noffset == -ENOENT) +			return -ENOPKG; +		else if (fdt_noffset < 0) +			return fdt_noffset; +	} +#endif +	debug("## Checking for 'FDT'/'FDT Image' at %08lx\n", +	      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. +	 */ +	buf = map_sysmem(fdt_addr, 0); +	switch (genimg_get_format(buf)) {  #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) -		case IMAGE_FORMAT_LEGACY: +	case IMAGE_FORMAT_LEGACY: { +			const image_header_t *fdt_hdr; +			ulong load, load_end; +			ulong image_start, image_data, image_end; +  			/* verify fdt_addr points to a valid image header */  			printf("## Flattened Device Tree from Legacy Image at %08lx\n",  			       fdt_addr);  			fdt_hdr = image_get_fdt(fdt_addr);  			if (!fdt_hdr) -				goto no_fdt; +				return -ENOPKG;  			/*  			 * move image data to the load address, @@ -386,7 +359,7 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,  			if ((load < image_end) && (load_end > image_start)) {  				fdt_error("fdt overwritten"); -				goto error; +				return -EFAULT;  			}  			debug("   Loading FDT from 0x%08lx to 0x%08lx\n", @@ -398,25 +371,26 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,  			fdt_addr = load;  			break; +		}  #endif -		case IMAGE_FORMAT_FIT: -			/* -			 * This case will catch both: new uImage format -			 * (libfdt based) and raw FDT blob (also libfdt -			 * based). -			 */ +	case IMAGE_FORMAT_FIT: +		/* +		 * This case will catch both: new uImage format +		 * (libfdt based) and raw FDT blob (also libfdt +		 * based). +		 */  #if CONFIG_IS_ENABLED(FIT)  			/* check FDT blob vs FIT blob */  			if (!fit_check_format(buf, IMAGE_SIZE_INVAL)) {  				ulong load, len; -				fdt_noffset = boot_get_fdt_fit(images, -					fdt_addr, &fit_uname_fdt, -					&fit_uname_config, -					arch, &load, &len); +				fdt_noffset = boot_get_fdt_fit(images, fdt_addr, +							       &fit_uname_fdt, +							       &fit_uname_config, +							       arch, &load, &len);  				if (fdt_noffset < 0) -					goto error; +					return -ENOENT;  				images->fit_hdr_fdt = map_sysmem(fdt_addr, 0);  				images->fit_uname_fdt = fit_uname_fdt; @@ -424,22 +398,73 @@ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch,  				fdt_addr = load;  				break; -			} else +		} else  #endif -			{ -				/* -				 * FDT blob -				 */ -				debug("*  fdt: raw FDT blob\n"); -				printf("## Flattened Device Tree blob at %08lx\n", -				       (long)fdt_addr); -			} -			break; -		default: -			puts("ERROR: Did not find a cmdline Flattened Device Tree\n"); -			goto error; +		{ +			/* +			 * FDT blob +			 */ +			debug("*  fdt: raw FDT blob\n"); +			printf("## Flattened Device Tree blob at %08lx\n", +			       (long)fdt_addr);  		} +		break; +	default: +		puts("ERROR: Did not find a cmdline Flattened Device Tree\n"); +		return -ENOENT; +	} +	*fdt_addrp = fdt_addr; + +	return 0; +} + +/** + * boot_get_fdt - main fdt handling routine + * @argc: command argument count + * @argv: command argument list + * @arch: architecture (IH_ARCH_...) + * @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. + * Currently 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(int flag, int argc, char *const argv[], uint8_t arch, +		 bootm_headers_t *images, char **of_flat_tree, ulong *of_size) +{ +	ulong		img_addr; +	ulong		fdt_addr; +	char		*fdt_blob = NULL; +	void		*buf; +	const char *select = NULL; +	*of_flat_tree = NULL; +	*of_size = 0; + +	img_addr = (argc == 0) ? image_load_addr : hextoul(argv[0], NULL); +	buf = map_sysmem(img_addr, 0); + +	if (argc > 2) +		select = argv[2]; +	if (select || genimg_has_config(images)) { +		int ret; + +		ret = select_fdt(images, select, arch, &fdt_addr); +		if (ret == -ENOPKG) +			goto no_fdt; +		else if (ret) +			return 1;  		printf("   Booting using the fdt blob at %#08lx\n", fdt_addr);  		fdt_blob = map_sysmem(fdt_addr, 0);  	} else if (images->legacy_hdr_valid && @@ -582,7 +607,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,  	/* Append PStore configuration */  	fdt_fixup_pstore(blob);  #endif -	if (IMAGE_OF_BOARD_SETUP) { +	if (IS_ENABLED(CONFIG_OF_BOARD_SETUP)) {  		const char *skip_board_fixup;  		skip_board_fixup = env_get("skip_board_fixup"); @@ -597,7 +622,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,  			}  		}  	} -	if (IMAGE_OF_SYSTEM_SETUP) { +	if (IS_ENABLED(CONFIG_OF_SYSTEM_SETUP)) {  		fdt_ret = ft_system_setup(blob, gd->bd);  		if (fdt_ret) {  			printf("ERROR: system-specific fdt fixup failed: %s\n", @@ -629,7 +654,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,  		goto err;  #if defined(CONFIG_ARCH_KEYSTONE) -	if (IMAGE_OF_BOARD_SETUP) +	if (IS_ENABLED(CONFIG_OF_BOARD_SETUP))  		ft_board_setup_ex(blob, gd->bd);  #endif | 
