From e1eb6ada4e38086d3d7cfd11c898a360098f7681 Mon Sep 17 00:00:00 2001 From: Andreas Dannenberg Date: Tue, 4 Jun 2019 17:55:46 -0500 Subject: [PATCH] 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 Reviewed-by: Tom Rini --- common/spl/spl_fit.c | 14 ++++++++ common/spl/spl_mmc.c | 76 +++++++++++++++++++++++++++++--------------- include/spl.h | 26 +++++++++++++++ 3 files changed, 91 insertions(+), 25 deletions(-) diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 87ecf0bb9e..969f7775c1 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -340,6 +340,16 @@ static int spl_fit_image_get_os(const void *fit, int noffset, uint8_t *os) #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, 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) 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 */ images = fdt_path_offset(fit, FIT_IMAGES_PATH); if (images < 0) { diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 324d91c884..b3619889f7 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -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 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; 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 - return mmc_load_image_raw_sector(spl_image, mmc, - info.start + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); + return mmc_load_image_raw_sector(spl_image, mmc, info.start + sector); #else return mmc_load_image_raw_sector(spl_image, mmc, info.start); #endif @@ -234,7 +234,8 @@ static int mmc_load_image_raw_os(struct spl_image_info *spl_image, #endif #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; @@ -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 err = spl_load_image_fat(spl_image, mmc_get_blk_desc(mmc), CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, - CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); + filename); if (!err) return err; #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 err = spl_load_image_ext(spl_image, mmc_get_blk_desc(mmc), CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, - CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); + filename); if (!err) return err; #endif @@ -276,7 +277,8 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc) return err; } #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; } @@ -301,24 +303,31 @@ int spl_boot_partition(const u32 boot_device) } #endif -int spl_mmc_load_image(struct spl_image_info *spl_image, - struct spl_boot_device *bootdev) +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) { - struct mmc *mmc = NULL; + static struct mmc *mmc; u32 boot_mode; int err = 0; __maybe_unused int part; - err = spl_mmc_find_device(&mmc, bootdev->boot_device); - if (err) - return err; + /* Perform peripheral init only once */ + if (!mmc) { + err = spl_mmc_find_device(&mmc, bootdev->boot_device); + if (err) + return err; - err = mmc_init(mmc); - if (err) { + err = mmc_init(mmc); + if (err) { + mmc = NULL; #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 - return err; + return err; + } } 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; } #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION - err = spl_boot_partition(bootdev->boot_device); - if (!err) - return err; - - err = mmc_load_image_raw_partition(spl_image, mmc, err); + err = mmc_load_image_raw_partition(spl_image, mmc, raw_part, + raw_sect); if (!err) return err; #endif #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR - err = mmc_load_image_raw_sector(spl_image, mmc, - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); + err = mmc_load_image_raw_sector(spl_image, mmc, raw_sect); if (!err) return err; #endif @@ -374,7 +379,7 @@ int spl_mmc_load_image(struct spl_image_info *spl_image, case MMCSD_MODE_FS: 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) return err; @@ -388,6 +393,27 @@ int spl_mmc_load_image(struct spl_image_info *spl_image, 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("MMC2", 0, BOOT_DEVICE_MMC2, spl_mmc_load_image); SPL_LOAD_IMAGE_METHOD("MMC2_2", 0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image); diff --git a/include/spl.h b/include/spl.h index a9aaef345f..a90f971a23 100644 --- a/include/spl.h +++ b/include/spl.h @@ -108,6 +108,15 @@ struct spl_load_info { */ 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_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, 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 */ -- 2.39.5