spl: Make image loader infrastructure more universal
authorAndreas Dannenberg <dannenberg@ti.com>
Tue, 4 Jun 2019 22:55:46 +0000 (17:55 -0500)
committerTom Rini <trini@konsulko.com>
Wed, 17 Jul 2019 15:12:54 +0000 (11:12 -0400)
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>
common/spl/spl_fit.c
common/spl/spl_mmc.c
include/spl.h

index 87ecf0bb9e5046f0edfffcec5146d107d469701e..969f7775c18f5fcd65d1ea3c07caaa297bc862f5 100644 (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) {
index 324d91c88404b6e86d4e58f5ee0b77c8e00300b4..b3619889f794bdb714beeb85965bcf27af7fcf0d 100644 (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);
index a9aaef345faf3821272d56bd7633da80984f1c28..a90f971a2393eae6171ae001b723e8e62e1a41d5 100644 (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
  */