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:
Andreas Dannenberg 2019-06-04 17:55:46 -05:00 committed by Tom Rini
parent a5a5d997b4
commit e1eb6ada4e
3 changed files with 91 additions and 25 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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
*/