Interleaving the uImage 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-uimage.c  | 176 +++++++++++++++++++++++++++++++++++++++++
 common/bootm.c         | 143 +++------------------------------
 include/bootm-uimage.h |  57 +++++++++++++
 4 files changed, 243 insertions(+), 134 deletions(-)
 create mode 100644 common/bootm-uimage.c
 create mode 100644 include/bootm-uimage.h

diff --git a/common/Makefile b/common/Makefile
index 45bd00758e4a..751f3ba20293 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_TLV)             += tlv/
 obj-$(CONFIG_RATP)             += ratp/
 obj-$(CONFIG_BOOTCHOOSER)      += bootchooser.o
 obj-$(CONFIG_UIMAGE)           += uimage_types.o uimage.o
+obj-$(CONFIG_BOOTM_UIMAGE)     += bootm-uimage.o
 obj-$(CONFIG_FITIMAGE)         += image-fit.o
 obj-$(CONFIG_BOOTM_FITIMAGE)   += bootm-fit.o
 obj-$(CONFIG_MENUTREE)         += menutree.o
diff --git a/common/bootm-uimage.c b/common/bootm-uimage.c
new file mode 100644
index 000000000000..609b678e1d4a
--- /dev/null
+++ b/common/bootm-uimage.c
@@ -0,0 +1,176 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <bootm.h>
+#include <bootm-uimage.h>
+#include <linux/kstrtox.h>
+
+static int uimage_part_num(const char *partname)
+{
+       if (!partname)
+               return 0;
+       return simple_strtoul(partname, NULL, 0);
+}
+
+/*
+ * bootm_load_uimage_os() - load uImage OS 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_uimage_os(struct image_data *data, unsigned long load_address)
+{
+       int num;
+
+       num = uimage_part_num(data->os_part);
+
+       data->os_res = uimage_load_to_sdram(data->os,
+               num, load_address);
+       if (!data->os_res)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static int bootm_open_initrd_uimage(struct image_data *data)
+{
+       int ret;
+
+       if (strcmp(data->os_file, data->initrd_file)) {
+               data->initrd = uimage_open(data->initrd_file);
+               if (!data->initrd)
+                       return -EINVAL;
+
+               if (bootm_get_verify_mode() > BOOTM_VERIFY_NONE) {
+                       ret = uimage_verify(data->initrd);
+                       if (ret) {
+                               pr_err("Checking data crc failed with %pe\n",
+                                       ERR_PTR(ret));
+                               return ret;
+                       }
+               }
+               uimage_print_contents(data->initrd);
+       } else {
+               data->initrd = data->os;
+       }
+
+       return 0;
+}
+
+/*
+ * bootm_load_uimage_initrd() - load initrd from uimage 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_uimage_initrd(struct image_data *data, unsigned long load_address)
+{
+       struct resource *res;
+       int ret;
+
+       int num;
+       ret = bootm_open_initrd_uimage(data);
+       if (ret) {
+               pr_err("loading initrd failed with %pe\n", ERR_PTR(ret));
+               return ERR_PTR(ret);
+       }
+
+       num = uimage_part_num(data->initrd_part);
+
+       res = uimage_load_to_sdram(data->initrd,
+               num, load_address);
+       if (!res)
+               return ERR_PTR(-ENOMEM);
+
+       return res;
+}
+
+int bootm_open_oftree_uimage(struct image_data *data, size_t *size,
+                            struct fdt_header **fdt)
+{
+       enum filetype ft;
+       const char *oftree = data->oftree_file;
+       int num = uimage_part_num(data->oftree_part);
+       struct uimage_handle *of_handle;
+       int release = 0;
+
+       pr_info("Loading devicetree from '%s'@%d\n", oftree, num);
+
+       if (!strcmp(data->os_file, oftree)) {
+               of_handle = data->os;
+       } else if (!strcmp(data->initrd_file, oftree)) {
+               of_handle = data->initrd;
+       } else {
+               of_handle = uimage_open(oftree);
+               if (!of_handle)
+                       return -ENODEV;
+               uimage_print_contents(of_handle);
+               release = 1;
+       }
+
+       *fdt = uimage_load_to_buf(of_handle, num, size);
+
+       if (release)
+               uimage_close(of_handle);
+
+       ft = file_detect_type(*fdt, *size);
+       if (ft != filetype_oftree) {
+               pr_err("%s is not an oftree but %s\n",
+                       data->oftree_file, file_type_to_string(ft));
+               free(*fdt);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+int bootm_open_uimage(struct image_data *data)
+{
+       int ret;
+
+       data->os = uimage_open(data->os_file);
+       if (!data->os)
+               return -EINVAL;
+
+       if (bootm_get_verify_mode() > BOOTM_VERIFY_NONE) {
+               ret = uimage_verify(data->os);
+               if (ret) {
+                       pr_err("Checking data crc failed with %pe\n",
+                                       ERR_PTR(ret));
+                       return ret;
+               }
+       }
+
+       uimage_print_contents(data->os);
+
+       if (IH_ARCH == IH_ARCH_INVALID || data->os->header.ih_arch != IH_ARCH) {
+               pr_err("Unsupported Architecture 0x%x\n",
+                      data->os->header.ih_arch);
+               return -EINVAL;
+       }
+
+       if (data->os_address == UIMAGE_SOME_ADDRESS)
+               data->os_address = data->os->header.ih_load;
+
+       return 0;
+}
+
+void bootm_close_uimage(struct image_data *data)
+{
+       if (data->initrd && data->initrd != data->os)
+               uimage_close(data->initrd);
+       uimage_close(data->os);
+}
diff --git a/common/bootm.c b/common/bootm.c
index dced46f3e067..f1beac52ec15 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -13,6 +13,7 @@
 #include <libfile.h>
 #include <bootm-fit.h>
 #include <image-fit.h>
+#include <bootm-uimage.h>
 #include <globalvar.h>
 #include <init.h>
 #include <environment.h>
@@ -250,18 +251,8 @@ int bootm_load_os(struct image_data *data, unsigned long 
load_address)
        if (data->os_fit)
                return bootm_load_fit_os(data, load_address);
 
-       if (image_is_uimage(data)) {
-               int num;
-
-               num = uimage_part_num(data->os_part);
-
-               data->os_res = uimage_load_to_sdram(data->os,
-                       num, load_address);
-               if (!data->os_res)
-                       return -ENOMEM;
-
-               return 0;
-       }
+       if (image_is_uimage(data))
+               return bootm_load_uimage_os(data, load_address);
 
        if (!data->os_file)
                return -EINVAL;
@@ -273,34 +264,6 @@ int bootm_load_os(struct image_data *data, unsigned long 
load_address)
        return 0;
 }
 
-static int bootm_open_initrd_uimage(struct image_data *data)
-{
-       int ret;
-
-       if (!IS_ENABLED(CONFIG_BOOTM_UIMAGE))
-               return -ENOSYS;
-
-       if (strcmp(data->os_file, data->initrd_file)) {
-               data->initrd = uimage_open(data->initrd_file);
-               if (!data->initrd)
-                       return -EINVAL;
-
-               if (bootm_get_verify_mode() > BOOTM_VERIFY_NONE) {
-                       ret = uimage_verify(data->initrd);
-                       if (ret) {
-                               pr_err("Checking data crc failed with %pe\n",
-                                       ERR_PTR(ret));
-                               return ret;
-                       }
-               }
-               uimage_print_contents(data->initrd);
-       } else {
-               data->initrd = data->os;
-       }
-
-       return 0;
-}
-
 /*
  * bootm_load_initrd() - load initrd to RAM
  *
@@ -351,18 +314,9 @@ bootm_load_initrd(struct image_data *data, unsigned long 
load_address)
        }
 
        if (type == filetype_uimage) {
-               int num;
-               ret = bootm_open_initrd_uimage(data);
-               if (ret) {
-                       pr_err("loading initrd failed with %pe\n", 
ERR_PTR(ret));
-                       return ERR_PTR(ret);
-               }
-
-               num = uimage_part_num(data->initrd_part);
-
-               res = uimage_load_to_sdram(data->initrd, num, load_address);
-               if (!res)
-                       return ERR_PTR(-ENOMEM);
+               res = bootm_load_uimage_initrd(data, load_address);
+               if (IS_ERR(res))
+                       return res;
 
                goto done;
        }
@@ -386,48 +340,6 @@ bootm_load_initrd(struct image_data *data, unsigned long 
load_address)
        return data->initrd_res;
 }
 
-static int bootm_open_oftree_uimage(struct image_data *data, size_t *size,
-                                   struct fdt_header **fdt)
-{
-       enum filetype ft;
-       const char *oftree = data->oftree_file;
-       int num = uimage_part_num(data->oftree_part);
-       struct uimage_handle *of_handle;
-       int release = 0;
-
-       pr_info("Loading devicetree from '%s'@%d\n", oftree, num);
-
-       if (!IS_ENABLED(CONFIG_BOOTM_OFTREE_UIMAGE))
-               return -EINVAL;
-
-       if (!strcmp(data->os_file, oftree)) {
-               of_handle = data->os;
-       } else if (!strcmp(data->initrd_file, oftree)) {
-               of_handle = data->initrd;
-       } else {
-               of_handle = uimage_open(oftree);
-               if (!of_handle)
-                       return -ENODEV;
-               uimage_print_contents(of_handle);
-               release = 1;
-       }
-
-       *fdt = uimage_load_to_buf(of_handle, num, size);
-
-       if (release)
-               uimage_close(of_handle);
-
-       ft = file_detect_type(*fdt, *size);
-       if (ft != filetype_oftree) {
-               pr_err("%s is not an oftree but %s\n",
-                       data->oftree_file, file_type_to_string(ft));
-               free(*fdt);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
 /*
  * bootm_get_devicetree() - get devicetree
  *
@@ -585,40 +497,6 @@ int bootm_get_os_size(struct image_data *data)
        return s.st_size;
 }
 
-static int bootm_open_os_uimage(struct image_data *data)
-{
-       int ret;
-
-       if (!IS_ENABLED(CONFIG_BOOTM_UIMAGE))
-               return -ENOSYS;
-
-       data->os = uimage_open(data->os_file);
-       if (!data->os)
-               return -EINVAL;
-
-       if (bootm_get_verify_mode() > BOOTM_VERIFY_NONE) {
-               ret = uimage_verify(data->os);
-               if (ret) {
-                       pr_err("Checking data crc failed with %pe\n",
-                                       ERR_PTR(ret));
-                       return ret;
-               }
-       }
-
-       uimage_print_contents(data->os);
-
-       if (IH_ARCH == IH_ARCH_INVALID || data->os->header.ih_arch != IH_ARCH) {
-               pr_err("Unsupported Architecture 0x%x\n",
-                      data->os->header.ih_arch);
-               return -EINVAL;
-       }
-
-       if (data->os_address == UIMAGE_SOME_ADDRESS)
-               data->os_address = data->os->header.ih_load;
-
-       return 0;
-}
-
 static void bootm_print_info(struct image_data *data)
 {
        if (data->os_res)
@@ -727,7 +605,7 @@ int bootm_boot(struct bootm_data *bootm_data)
                os_type_str = "FIT";
                break;
        case filetype_uimage:
-               ret = bootm_open_os_uimage(data);
+               ret = bootm_open_uimage(data);
                break;
        default:
                ret = 0;
@@ -897,11 +775,8 @@ int bootm_boot(struct bootm_data *bootm_data)
                release_sdram_region(data->oftree_res);
        if (data->tee_res)
                release_sdram_region(data->tee_res);
-       if (image_is_uimage(data)) {
-               if (data->initrd && data->initrd != data->os)
-                       uimage_close(data->initrd);
-               uimage_close(data->os);
-       }
+       if (image_is_uimage(data))
+               bootm_close_uimage(data);
        if (data->os_fit)
                bootm_close_fit(data);
        if (data->of_root_node)
diff --git a/include/bootm-uimage.h b/include/bootm-uimage.h
new file mode 100644
index 000000000000..aac2beb35e2a
--- /dev/null
+++ b/include/bootm-uimage.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef __BOOTM_UIMAGE_H
+#define __BOOTM_UIMAGE_H
+
+#include <linux/types.h>
+#include <linux/err.h>
+
+struct image_data;
+struct fdt_header;
+struct resource;
+
+#ifdef CONFIG_BOOTM_UIMAGE
+
+int bootm_load_uimage_os(struct image_data *data, unsigned long load_address);
+
+struct resource *bootm_load_uimage_initrd(struct image_data *data,
+                                         unsigned long load_address);
+
+int bootm_open_oftree_uimage(struct image_data *data, size_t *size,
+                            struct fdt_header **fdt);
+int bootm_open_uimage(struct image_data *data);
+
+void bootm_close_uimage(struct image_data *data);
+
+#else
+
+static inline int bootm_load_uimage_os(struct image_data *data,
+                                      unsigned long load_address)
+{
+       return -ENOSYS;
+}
+
+static inline struct resource *
+bootm_load_uimage_initrd(struct image_data *data, unsigned long load_address)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+static inline int bootm_open_oftree_uimage(struct image_data *data,
+                                          size_t *size,
+                                          struct fdt_header **fdt)
+{
+       return -ENOSYS;
+}
+
+static inline int bootm_open_uimage(struct image_data *data)
+{
+       return -ENOSYS;
+}
+
+static inline void bootm_close_uimage(struct image_data *data)
+{
+}
+
+#endif
+
+#endif
-- 
2.47.3


Reply via email to