spl: Make image loader infrastructure more universal
The current U-Boot SPL image loader infrastructure is very powerful, able to initialize and load from a variety of boot media however it is strongly geared towards loading specific types of images in a very specific way. To address the need being able to use this infrastructure to load arbitrary image files go ahead and refactor it as follows: - Refactor existing spl_mmc_load_image function into superset function, accepting additional arguments such as filenames and media load offset (same concept can also be applied toother spl_XXX_load_image functions) - Extend the loader function to "remember" their peripheral initialization status so that the init is only done once during the boot process, - Extend the FIT image loading function to allow skipping the parsing/ processing of the FIT contents (so that this can be done separately in a more customized fashion) - Populate the SPL_LOAD_IMAGE_METHOD() list with a trampoline function, invoking the newly refactored superset functions in a way to maintain compatibility with the existing behavior This refactoring initially covers MMC/SD card loading (RAW and FS-based). Signed-off-by: Andreas Dannenberg <dannenberg@ti.com> Reviewed-by: Tom Rini <trini@konsulko.com>
This commit is contained in:
		
							parent
							
								
									a5a5d997b4
								
							
						
					
					
						commit
						e1eb6ada4e
					
				|  | @ -340,6 +340,16 @@ static int spl_fit_image_get_os(const void *fit, int noffset, uint8_t *os) | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * Weak default function to allow customizing SPL fit loading for load-only | ||||||
|  |  * use cases by allowing to skip the parsing/processing of the FIT contents | ||||||
|  |  * (so that this can be done separately in a more customized fashion) | ||||||
|  |  */ | ||||||
|  | __weak bool spl_load_simple_fit_skip_processing(void) | ||||||
|  | { | ||||||
|  | 	return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int spl_load_simple_fit(struct spl_image_info *spl_image, | int spl_load_simple_fit(struct spl_image_info *spl_image, | ||||||
| 			struct spl_load_info *info, ulong sector, void *fit) | 			struct spl_load_info *info, ulong sector, void *fit) | ||||||
| { | { | ||||||
|  | @ -389,6 +399,10 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, | ||||||
| 	if (count == 0) | 	if (count == 0) | ||||||
| 		return -EIO; | 		return -EIO; | ||||||
| 
 | 
 | ||||||
|  | 	/* skip further processing if requested to enable load-only use cases */ | ||||||
|  | 	if (spl_load_simple_fit_skip_processing()) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
| 	/* find the node holding the images information */ | 	/* find the node holding the images information */ | ||||||
| 	images = fdt_path_offset(fit, FIT_IMAGES_PATH); | 	images = fdt_path_offset(fit, FIT_IMAGES_PATH); | ||||||
| 	if (images < 0) { | 	if (images < 0) { | ||||||
|  |  | ||||||
|  | @ -151,7 +151,8 @@ static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device) | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION | #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION | ||||||
| static int mmc_load_image_raw_partition(struct spl_image_info *spl_image, | static int mmc_load_image_raw_partition(struct spl_image_info *spl_image, | ||||||
| 					struct mmc *mmc, int partition) | 					struct mmc *mmc, int partition, | ||||||
|  | 					unsigned long sector) | ||||||
| { | { | ||||||
| 	disk_partition_t info; | 	disk_partition_t info; | ||||||
| 	int err; | 	int err; | ||||||
|  | @ -180,8 +181,7 @@ static int mmc_load_image_raw_partition(struct spl_image_info *spl_image, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR | #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR | ||||||
| 	return mmc_load_image_raw_sector(spl_image, mmc, | 	return mmc_load_image_raw_sector(spl_image, mmc, info.start + sector); | ||||||
| 			info.start + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); |  | ||||||
| #else | #else | ||||||
| 	return mmc_load_image_raw_sector(spl_image, mmc, info.start); | 	return mmc_load_image_raw_sector(spl_image, mmc, info.start); | ||||||
| #endif | #endif | ||||||
|  | @ -234,7 +234,8 @@ static int mmc_load_image_raw_os(struct spl_image_info *spl_image, | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION | #ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION | ||||||
| static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc) | static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc, | ||||||
|  | 			      const char *filename) | ||||||
| { | { | ||||||
| 	int err = -ENOSYS; | 	int err = -ENOSYS; | ||||||
| 
 | 
 | ||||||
|  | @ -248,7 +249,7 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc) | ||||||
| #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME | #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME | ||||||
| 	err = spl_load_image_fat(spl_image, mmc_get_blk_desc(mmc), | 	err = spl_load_image_fat(spl_image, mmc_get_blk_desc(mmc), | ||||||
| 				 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, | 				 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, | ||||||
| 				 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); | 				 filename); | ||||||
| 	if (!err) | 	if (!err) | ||||||
| 		return err; | 		return err; | ||||||
| #endif | #endif | ||||||
|  | @ -263,7 +264,7 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc) | ||||||
| #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME | #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME | ||||||
| 	err = spl_load_image_ext(spl_image, mmc_get_blk_desc(mmc), | 	err = spl_load_image_ext(spl_image, mmc_get_blk_desc(mmc), | ||||||
| 				 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, | 				 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, | ||||||
| 				 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); | 				 filename); | ||||||
| 	if (!err) | 	if (!err) | ||||||
| 		return err; | 		return err; | ||||||
| #endif | #endif | ||||||
|  | @ -276,7 +277,8 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc) | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
| #else | #else | ||||||
| static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc) | static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc, | ||||||
|  | 			      const char *filename) | ||||||
| { | { | ||||||
| 	return -ENOSYS; | 	return -ENOSYS; | ||||||
| } | } | ||||||
|  | @ -301,24 +303,31 @@ int spl_boot_partition(const u32 boot_device) | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| int spl_mmc_load_image(struct spl_image_info *spl_image, | int spl_mmc_load(struct spl_image_info *spl_image, | ||||||
| 		       struct spl_boot_device *bootdev) | 		 struct spl_boot_device *bootdev, | ||||||
|  | 		 const char *filename, | ||||||
|  | 		 int raw_part, | ||||||
|  | 		 unsigned long raw_sect) | ||||||
| { | { | ||||||
| 	struct mmc *mmc = NULL; | 	static struct mmc *mmc; | ||||||
| 	u32 boot_mode; | 	u32 boot_mode; | ||||||
| 	int err = 0; | 	int err = 0; | ||||||
| 	__maybe_unused int part; | 	__maybe_unused int part; | ||||||
| 
 | 
 | ||||||
| 	err = spl_mmc_find_device(&mmc, bootdev->boot_device); | 	/* Perform peripheral init only once */ | ||||||
| 	if (err) | 	if (!mmc) { | ||||||
| 		return err; | 		err = spl_mmc_find_device(&mmc, bootdev->boot_device); | ||||||
|  | 		if (err) | ||||||
|  | 			return err; | ||||||
| 
 | 
 | ||||||
| 	err = mmc_init(mmc); | 		err = mmc_init(mmc); | ||||||
| 	if (err) { | 		if (err) { | ||||||
|  | 			mmc = NULL; | ||||||
| #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT | #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT | ||||||
| 		printf("spl: mmc init failed with error: %d\n", err); | 			printf("spl: mmc init failed with error: %d\n", err); | ||||||
| #endif | #endif | ||||||
| 		return err; | 			return err; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	boot_mode = spl_boot_mode(bootdev->boot_device); | 	boot_mode = spl_boot_mode(bootdev->boot_device); | ||||||
|  | @ -356,17 +365,13 @@ int spl_mmc_load_image(struct spl_image_info *spl_image, | ||||||
| 				return err; | 				return err; | ||||||
| 		} | 		} | ||||||
| #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION | #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION | ||||||
| 		err = spl_boot_partition(bootdev->boot_device); | 		err = mmc_load_image_raw_partition(spl_image, mmc, raw_part, | ||||||
| 		if (!err) | 						   raw_sect); | ||||||
| 			return err; |  | ||||||
| 
 |  | ||||||
| 		err = mmc_load_image_raw_partition(spl_image, mmc, err); |  | ||||||
| 		if (!err) | 		if (!err) | ||||||
| 			return err; | 			return err; | ||||||
| #endif | #endif | ||||||
| #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR | #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR | ||||||
| 		err = mmc_load_image_raw_sector(spl_image, mmc, | 		err = mmc_load_image_raw_sector(spl_image, mmc, raw_sect); | ||||||
| 			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); |  | ||||||
| 		if (!err) | 		if (!err) | ||||||
| 			return err; | 			return err; | ||||||
| #endif | #endif | ||||||
|  | @ -374,7 +379,7 @@ int spl_mmc_load_image(struct spl_image_info *spl_image, | ||||||
| 	case MMCSD_MODE_FS: | 	case MMCSD_MODE_FS: | ||||||
| 		debug("spl: mmc boot mode: fs\n"); | 		debug("spl: mmc boot mode: fs\n"); | ||||||
| 
 | 
 | ||||||
| 		err = spl_mmc_do_fs_boot(spl_image, mmc); | 		err = spl_mmc_do_fs_boot(spl_image, mmc, filename); | ||||||
| 		if (!err) | 		if (!err) | ||||||
| 			return err; | 			return err; | ||||||
| 
 | 
 | ||||||
|  | @ -388,6 +393,27 @@ int spl_mmc_load_image(struct spl_image_info *spl_image, | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int spl_mmc_load_image(struct spl_image_info *spl_image, | ||||||
|  | 		       struct spl_boot_device *bootdev) | ||||||
|  | { | ||||||
|  | 	return spl_mmc_load(spl_image, bootdev, | ||||||
|  | #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME | ||||||
|  | 			    CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, | ||||||
|  | #else | ||||||
|  | 			    NULL, | ||||||
|  | #endif | ||||||
|  | #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION | ||||||
|  | 			    spl_boot_partition(bootdev->boot_device), | ||||||
|  | #else | ||||||
|  | 			    0, | ||||||
|  | #endif | ||||||
|  | #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR | ||||||
|  | 			    CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); | ||||||
|  | #else | ||||||
|  | 			    0); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
| SPL_LOAD_IMAGE_METHOD("MMC1", 0, BOOT_DEVICE_MMC1, spl_mmc_load_image); | SPL_LOAD_IMAGE_METHOD("MMC1", 0, BOOT_DEVICE_MMC1, spl_mmc_load_image); | ||||||
| SPL_LOAD_IMAGE_METHOD("MMC2", 0, BOOT_DEVICE_MMC2, spl_mmc_load_image); | SPL_LOAD_IMAGE_METHOD("MMC2", 0, BOOT_DEVICE_MMC2, spl_mmc_load_image); | ||||||
| SPL_LOAD_IMAGE_METHOD("MMC2_2", 0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image); | SPL_LOAD_IMAGE_METHOD("MMC2_2", 0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image); | ||||||
|  |  | ||||||
|  | @ -108,6 +108,15 @@ struct spl_load_info { | ||||||
|  */ |  */ | ||||||
| binman_sym_extern(ulong, u_boot_any, image_pos); | binman_sym_extern(ulong, u_boot_any, image_pos); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * spl_load_simple_fit_skip_processing() - Hook to allow skipping the FIT | ||||||
|  |  *	image processing during spl_load_simple_fit(). | ||||||
|  |  * | ||||||
|  |  * Return true to skip FIT processing, false to preserve the full code flow | ||||||
|  |  * of spl_load_simple_fit(). | ||||||
|  |  */ | ||||||
|  | bool spl_load_simple_fit_skip_processing(void); | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * spl_load_simple_fit() - Loads a fit image from a device. |  * spl_load_simple_fit() - Loads a fit image from a device. | ||||||
|  * @spl_image:	Image description to set up |  * @spl_image:	Image description to set up | ||||||
|  | @ -330,6 +339,23 @@ int spl_dfu_cmd(int usbctrl, char *dfu_alt_info, char *interface, char *devstr); | ||||||
| int spl_mmc_load_image(struct spl_image_info *spl_image, | int spl_mmc_load_image(struct spl_image_info *spl_image, | ||||||
| 		       struct spl_boot_device *bootdev); | 		       struct spl_boot_device *bootdev); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * spl_mmc_load() - Load an image file from MMC/SD media | ||||||
|  |  * | ||||||
|  |  * @param spl_image	Image data filled in by loading process | ||||||
|  |  * @param bootdev	Describes which device to load from | ||||||
|  |  * @param filename	Name of file to load (in FS mode) | ||||||
|  |  * @param raw_part	Partition to load from (in RAW mode) | ||||||
|  |  * @param raw_sect	Sector to load from (in RAW mode) | ||||||
|  |  * | ||||||
|  |  * @return 0 on success, otherwise error code | ||||||
|  |  */ | ||||||
|  | int spl_mmc_load(struct spl_image_info *spl_image, | ||||||
|  | 		 struct spl_boot_device *bootdev, | ||||||
|  | 		 const char *filename, | ||||||
|  | 		 int raw_part, | ||||||
|  | 		 unsigned long raw_sect); | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * spl_invoke_atf - boot using an ARM trusted firmware image |  * spl_invoke_atf - boot using an ARM trusted firmware image | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue