Interleaving the FIT handling with the generic bootm code makes the
generic code harder to follow. Let's factor it out into a dedicated
file.

Signed-off-by: Ahmad Fatoum <[email protected]>
---
 common/Makefile     |   1 +
 common/bootm-fit.c  | 185 ++++++++++++++++++++++++++++++++++++++++++++
 common/bootm.c      | 156 ++++---------------------------------
 include/bootm-fit.h |  70 +++++++++++++++++
 4 files changed, 271 insertions(+), 141 deletions(-)
 create mode 100644 common/bootm-fit.c
 create mode 100644 include/bootm-fit.h

diff --git a/common/Makefile b/common/Makefile
index 36dee5f7a98a..45bd00758e4a 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_RATP)            += ratp/
 obj-$(CONFIG_BOOTCHOOSER)      += bootchooser.o
 obj-$(CONFIG_UIMAGE)           += uimage_types.o uimage.o
 obj-$(CONFIG_FITIMAGE)         += image-fit.o
+obj-$(CONFIG_BOOTM_FITIMAGE)   += bootm-fit.o
 obj-$(CONFIG_MENUTREE)         += menutree.o
 lwl-$(CONFIG_IMD)              += imd-barebox.o
 obj-$(CONFIG_IMD)              += imd.o
diff --git a/common/bootm-fit.c b/common/bootm-fit.c
new file mode 100644
index 000000000000..f9c8bff43912
--- /dev/null
+++ b/common/bootm-fit.c
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <bootm.h>
+#include <image-fit.h>
+#include <bootm-fit.h>
+#include <memory.h>
+#include <zero_page.h>
+
+/*
+ * bootm_load_fit_os() - load OS from FIT to RAM
+ *
+ * @data:              image data context
+ * @load_address:      The address where the OS should be loaded to
+ *
+ * This loads the OS to a RAM location. load_address must be a valid
+ * address. If the image_data doesn't have a OS specified it's considered
+ * an error.
+ *
+ * Return: 0 on success, negative error code otherwise
+ */
+int bootm_load_fit_os(struct image_data *data, unsigned long load_address)
+{
+       const void *kernel = data->fit_kernel;
+       unsigned long kernel_size = data->fit_kernel_size;
+
+       data->os_res = request_sdram_region("kernel",
+                       load_address, kernel_size,
+                       MEMTYPE_LOADER_CODE, MEMATTRS_RWX);
+       if (!data->os_res) {
+               pr_err("unable to request SDRAM region for kernel at"
+                               " 0x%08llx-0x%08llx\n",
+                       (unsigned long long)load_address,
+                       (unsigned long long)load_address + kernel_size - 1);
+               return -ENOMEM;
+       }
+       zero_page_memcpy((void *)load_address, kernel, kernel_size);
+       return 0;
+}
+
+static bool fitconfig_has_ramdisk(struct image_data *data)
+{
+       return fit_has_image(data->os_fit, data->fit_config, "ramdisk");
+}
+
+/*
+ * bootm_load_fit_initrd() - load initrd from FIT to RAM
+ *
+ * @data:              image data context
+ * @load_address:      The address where the initrd should be loaded to
+ *
+ * This loads the initrd to a RAM location. load_address must be a valid
+ * address. If the image_data doesn't have a initrd specified this function
+ * still returns successful as an initrd is optional.
+ *
+ * Return: initrd resource on success, NULL if no initrd is present or
+ *         an error pointer if an error occurred.
+ */
+struct resource *bootm_load_fit_initrd(struct image_data *data, unsigned long 
load_address)
+{
+       struct resource *res;
+       const void *initrd;
+       unsigned long initrd_size;
+       int ret;
+
+       if (!fitconfig_has_ramdisk(data))
+               return NULL;
+
+       ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk",
+                            &initrd, &initrd_size);
+       if (ret) {
+               pr_err("Cannot open ramdisk image in FIT image: %pe\n",
+                               ERR_PTR(ret));
+               return ERR_PTR(ret);
+       }
+       res = request_sdram_region("initrd",
+                                  load_address, initrd_size,
+                                  MEMTYPE_LOADER_DATA, MEMATTRS_RW);
+       if (!res) {
+               pr_err("unable to request SDRAM region for initrd at"
+                               " 0x%08llx-0x%08llx\n",
+                       (unsigned long long)load_address,
+                       (unsigned long long)load_address + initrd_size - 1);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       memcpy((void *)load_address, initrd, initrd_size);
+       return res;
+}
+
+/*
+ * bootm_get_fit_devicetree() - get devicetree
+ *
+ * @data:              image data context
+ *
+ * This gets the fixed devicetree from the various image sources or the 
internal
+ * devicetree. It returns a pointer to the allocated devicetree which must be
+ * freed after use.
+ *
+ * Return: pointer to the fixed devicetree, NULL if image_data has an empty DT
+ *         or a ERR_PTR() on failure.
+ */
+void *bootm_get_fit_devicetree(struct image_data *data)
+{
+       int ret;
+       const void *of_tree;
+       unsigned long of_size;
+
+       ret = fit_open_image(data->os_fit, data->fit_config, "fdt",
+                            &of_tree, &of_size);
+       if (ret)
+               return ERR_PTR(ret);
+
+       return of_unflatten_dtb(of_tree, of_size);
+}
+
+static bool bootm_fit_config_valid(struct fit_handle *fit,
+                                  struct device_node *config)
+{
+       /*
+        * Consider only FIT configurations which do provide a loadable kernel
+        * image.
+        */
+       return !!fit_has_image(fit, config, "kernel");
+}
+
+int bootm_open_fit(struct image_data *data)
+{
+       struct fit_handle *fit;
+       struct fdt_header *header;
+       static const char *kernel_img = "kernel";
+       size_t flen, hlen;
+       int ret;
+
+       header = (struct fdt_header *)data->os_header;
+       flen = bootm_get_os_size(data);
+       hlen = fdt32_to_cpu(header->totalsize);
+
+       fit = fit_open(data->os_file, data->verbose, data->verify,
+                      min(flen, hlen));
+       if (IS_ERR(fit)) {
+               pr_err("Loading FIT image %s failed with: %pe\n", 
data->os_file, fit);
+               return PTR_ERR(fit);
+       }
+
+       data->os_fit = fit;
+
+       data->fit_config = fit_open_configuration(data->os_fit,
+                                                 data->os_part,
+                                                 bootm_fit_config_valid);
+       if (IS_ERR(data->fit_config)) {
+               pr_err("Cannot open FIT image configuration '%s'\n",
+                      data->os_part ? data->os_part : "default");
+               return PTR_ERR(data->fit_config);
+       }
+
+       ret = fit_open_image(data->os_fit, data->fit_config, kernel_img,
+                            &data->fit_kernel, &data->fit_kernel_size);
+       if (ret)
+               return ret;
+       if (data->os_address == UIMAGE_SOME_ADDRESS) {
+               ret = fit_get_image_address(data->os_fit,
+                                           data->fit_config,
+                                           kernel_img,
+                                           "load", &data->os_address);
+               if (!ret)
+                       pr_info("Load address from FIT '%s': 0x%lx\n",
+                               kernel_img, data->os_address);
+               /* Note: Error case uses default value. */
+       }
+       if (data->os_entry == UIMAGE_SOME_ADDRESS) {
+               unsigned long entry;
+               ret = fit_get_image_address(data->os_fit,
+                                           data->fit_config,
+                                           kernel_img,
+                                           "entry", &entry);
+               if (!ret) {
+                       data->os_entry = entry - data->os_address;
+                       pr_info("Entry address from FIT '%s': 0x%lx\n",
+                               kernel_img, entry);
+               }
+               /* Note: Error case uses default value. */
+       }
+
+       return 0;
+}
diff --git a/common/bootm.c b/common/bootm.c
index e60c81a9021e..dced46f3e067 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -11,6 +11,7 @@
 #include <memory.h>
 #include <block.h>
 #include <libfile.h>
+#include <bootm-fit.h>
 #include <image-fit.h>
 #include <globalvar.h>
 #include <init.h>
@@ -246,23 +247,8 @@ int bootm_load_os(struct image_data *data, unsigned long 
load_address)
        if (load_address == UIMAGE_INVALID_ADDRESS)
                return -EINVAL;
 
-       if (data->os_fit) {
-               const void *kernel = data->fit_kernel;
-               unsigned long kernel_size = data->fit_kernel_size;
-
-               data->os_res = request_sdram_region("kernel",
-                               load_address, kernel_size,
-                               MEMTYPE_LOADER_CODE, MEMATTRS_RWX);
-               if (!data->os_res) {
-                       pr_err("unable to request SDRAM region for kernel at"
-                                       " 0x%08llx-0x%08llx\n",
-                               (unsigned long long)load_address,
-                               (unsigned long long)load_address + kernel_size 
- 1);
-                       return -ENOMEM;
-               }
-               zero_page_memcpy((void *)load_address, kernel, kernel_size);
-               return 0;
-       }
+       if (data->os_fit)
+               return bootm_load_fit_os(data, load_address);
 
        if (image_is_uimage(data)) {
                int num;
@@ -287,14 +273,6 @@ int bootm_load_os(struct image_data *data, unsigned long 
load_address)
        return 0;
 }
 
-static bool fitconfig_has_ramdisk(struct image_data *data)
-{
-       if (!IS_ENABLED(CONFIG_FITIMAGE) || !data->os_fit)
-               return false;
-
-       return fit_has_image(data->os_fit, data->fit_config, "ramdisk");
-}
-
 static int bootm_open_initrd_uimage(struct image_data *data)
 {
        int ret;
@@ -352,28 +330,13 @@ bootm_load_initrd(struct image_data *data, unsigned long 
load_address)
        if (data->initrd_res)
                return data->initrd_res;
 
-       if (fitconfig_has_ramdisk(data)) {
-               const void *initrd;
-               unsigned long initrd_size;
+       if (data->os_fit) {
+               res = bootm_load_fit_initrd(data, load_address);
+               if (IS_ERR(res))
+                       return res;
+               if (res)
+                       pr_info("Loaded initrd from FIT image\n");
 
-               ret = fit_open_image(data->os_fit, data->fit_config, "ramdisk",
-                                    &initrd, &initrd_size);
-               if (ret) {
-                       pr_err("Cannot open ramdisk image in FIT image: %pe\n",
-                                       ERR_PTR(ret));
-                       return ERR_PTR(ret);
-               }
-               res = request_sdram_region("initrd", load_address, initrd_size,
-                                          MEMTYPE_LOADER_DATA, MEMATTRS_RW);
-               if (!res) {
-                       pr_err("unable to request SDRAM region for initrd at"
-                                       " 0x%08llx-0x%08llx\n",
-                               (unsigned long long)load_address,
-                               (unsigned long long)load_address + initrd_size 
- 1);
-                       return ERR_PTR(-ENOMEM);
-               }
-               memcpy((void *)load_address, initrd, initrd_size);
-               pr_info("Loaded initrd from FIT image\n");
                goto done1;
        }
 
@@ -416,7 +379,8 @@ bootm_load_initrd(struct image_data *data, unsigned long 
load_address)
                pr_info(", multifile image %s", data->initrd_part);
        pr_info("\n");
 done1:
-       pr_info("initrd is at %pa-%pa\n", &res->start, &res->end);
+       if (res)
+               pr_info("initrd is at %pa-%pa\n", &res->start, &res->end);
 
        data->initrd_res = res;
        return data->initrd_res;
@@ -464,14 +428,6 @@ static int bootm_open_oftree_uimage(struct image_data 
*data, size_t *size,
        return 0;
 }
 
-static bool fitconfig_has_fdt(struct image_data *data)
-{
-       if (!IS_ENABLED(CONFIG_FITIMAGE) || !data->os_fit)
-               return false;
-
-       return fit_has_image(data->os_fit, data->fit_config, "fdt");
-}
-
 /*
  * bootm_get_devicetree() - get devicetree
  *
@@ -494,20 +450,12 @@ void *bootm_get_devicetree(struct image_data *data)
        if (!IS_ENABLED(CONFIG_OFTREE))
                return ERR_PTR(-ENOSYS);
 
-       from_fit = fitconfig_has_fdt(data);
+       from_fit = bootm_fit_has_fdt(data);
        if (bootm_get_override(&data->oftree_file, bootm_overrides.oftree_file))
                from_fit = false;
 
        if (from_fit) {
-               const void *of_tree;
-               unsigned long of_size;
-
-               ret = fit_open_image(data->os_fit, data->fit_config, "fdt",
-                                    &of_tree, &of_size);
-               if (ret)
-                       return ERR_PTR(ret);
-
-               data->of_root_node = of_unflatten_dtb(of_tree, of_size);
+               data->of_root_node = bootm_get_fit_devicetree(data);
        } else if (data->oftree_file) {
                size_t size;
 
@@ -671,80 +619,6 @@ static int bootm_open_os_uimage(struct image_data *data)
        return 0;
 }
 
-static bool bootm_fit_config_valid(struct fit_handle *fit,
-                                  struct device_node *config)
-{
-       /*
-        * Consider only FIT configurations which do provide a loadable kernel
-        * image.
-        */
-       return !!fit_has_image(fit, config, "kernel");
-}
-
-static int bootm_open_fit(struct image_data *data)
-{
-       struct fit_handle *fit;
-       struct fdt_header *header;
-       static const char *kernel_img = "kernel";
-       size_t flen, hlen;
-       int ret;
-
-       if (!IS_ENABLED(CONFIG_FITIMAGE))
-               return -ENOSYS;
-
-       header = (struct fdt_header *)data->os_header;
-       flen = bootm_get_os_size(data);
-       hlen = fdt32_to_cpu(header->totalsize);
-
-       fit = fit_open(data->os_file, data->verbose, data->verify,
-                      min(flen, hlen));
-       if (IS_ERR(fit)) {
-               pr_err("Loading FIT image %s failed with: %pe\n", 
data->os_file, fit);
-               return PTR_ERR(fit);
-       }
-
-       data->os_fit = fit;
-
-       data->fit_config = fit_open_configuration(data->os_fit,
-                                                 data->os_part,
-                                                 bootm_fit_config_valid);
-       if (IS_ERR(data->fit_config)) {
-               pr_err("Cannot open FIT image configuration '%s'\n",
-                      data->os_part ? data->os_part : "default");
-               return PTR_ERR(data->fit_config);
-       }
-
-       ret = fit_open_image(data->os_fit, data->fit_config, kernel_img,
-                            &data->fit_kernel, &data->fit_kernel_size);
-       if (ret)
-               return ret;
-       if (data->os_address == UIMAGE_SOME_ADDRESS) {
-               ret = fit_get_image_address(data->os_fit,
-                                           data->fit_config,
-                                           kernel_img,
-                                           "load", &data->os_address);
-               if (!ret)
-                       pr_info("Load address from FIT '%s': 0x%lx\n",
-                               kernel_img, data->os_address);
-               /* Note: Error case uses default value. */
-       }
-       if (data->os_entry == UIMAGE_SOME_ADDRESS) {
-               unsigned long entry;
-               ret = fit_get_image_address(data->os_fit,
-                                           data->fit_config,
-                                           kernel_img,
-                                           "entry", &entry);
-               if (!ret) {
-                       data->os_entry = entry - data->os_address;
-                       pr_info("Entry address from FIT '%s': 0x%lx\n",
-                               kernel_img, entry);
-               }
-               /* Note: Error case uses default value. */
-       }
-
-       return 0;
-}
-
 static void bootm_print_info(struct image_data *data)
 {
        if (data->os_res)
@@ -1028,8 +902,8 @@ int bootm_boot(struct bootm_data *bootm_data)
                        uimage_close(data->initrd);
                uimage_close(data->os);
        }
-       if (IS_ENABLED(CONFIG_FITIMAGE) && data->os_fit)
-               fit_close(data->os_fit);
+       if (data->os_fit)
+               bootm_close_fit(data);
        if (data->of_root_node)
                of_delete_node(data->of_root_node);
 
diff --git a/include/bootm-fit.h b/include/bootm-fit.h
new file mode 100644
index 000000000000..8deddd62e328
--- /dev/null
+++ b/include/bootm-fit.h
@@ -0,0 +1,70 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __BOOTM_FIT_H
+#define __BOOTM_FIT_H
+
+#include <linux/types.h>
+#include <image-fit.h>
+#include <bootm.h>
+
+struct resource;
+
+#ifdef CONFIG_BOOTM_FITIMAGE
+
+int bootm_load_fit_os(struct image_data *data, unsigned long load_address);
+
+struct resource *bootm_load_fit_initrd(struct image_data *data,
+                                      unsigned long load_address);
+
+void *bootm_get_fit_devicetree(struct image_data *data);
+
+int bootm_open_fit(struct image_data *data);
+
+static inline void bootm_close_fit(struct image_data *data)
+{
+       fit_close(data->os_fit);
+}
+
+static inline bool bootm_fit_has_fdt(struct image_data *data)
+{
+       if (!data->os_fit)
+               return false;
+
+       return fit_has_image(data->os_fit, data->fit_config, "fdt");
+}
+
+#else
+
+static inline int bootm_load_fit_os(struct image_data *data,
+                                   unsigned long load_address)
+{
+       return -ENOSYS;
+}
+
+static inline struct resource *bootm_load_fit_initrd(struct image_data *data,
+                                                    unsigned long load_address)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline void *bootm_get_fit_devicetree(struct image_data *data)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline int bootm_open_fit(struct image_data *data)
+{
+       return -ENOSYS;
+}
+
+static inline void bootm_close_fit(struct image_data *data)
+{
+}
+
+static inline bool bootm_fit_has_fdt(struct image_data *data)
+{
+       return false;
+}
+
+#endif
+
+#endif
-- 
2.47.3


Reply via email to