arm: Remove aspenite board
[platform/kernel/u-boot.git] / common / image-fit.c
index b972042..5a0a0cc 100644 (file)
@@ -17,6 +17,7 @@
 #include <u-boot/crc.h>
 #else
 #include <linux/compiler.h>
+#include <linux/sizes.h>
 #include <common.h>
 #include <errno.h>
 #include <log.h>
 #include <asm/io.h>
 #include <malloc.h>
 #include <asm/global_data.h>
+#ifdef CONFIG_DM_HASH
+#include <dm.h>
+#include <u-boot/hash.h>
+#endif
 DECLARE_GLOBAL_DATA_PTR;
 #endif /* !USE_HOSTCC*/
 
@@ -52,7 +57,7 @@ static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr,
        sep = strchr(spec, sepc);
        if (sep) {
                if (sep - spec > 0)
-                       *addr = simple_strtoul(spec, NULL, 16);
+                       *addr = hextoul(spec, NULL);
 
                *name = sep + 1;
                return 1;
@@ -1210,37 +1215,47 @@ int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
  *     0, on success
  *    -1, when algo is unsupported
  */
-int calculate_hash(const void *data, int data_len, const char *algo,
+int calculate_hash(const void *data, int data_len, const char *name,
                        uint8_t *value, int *value_len)
 {
-       if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) {
-               *((uint32_t *)value) = crc32_wd(0, data, data_len,
-                                                       CHUNKSZ_CRC32);
-               *((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value));
-               *value_len = 4;
-       } else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) {
-               sha1_csum_wd((unsigned char *)data, data_len,
-                            (unsigned char *)value, CHUNKSZ_SHA1);
-               *value_len = 20;
-       } else if (IMAGE_ENABLE_SHA256 && strcmp(algo, "sha256") == 0) {
-               sha256_csum_wd((unsigned char *)data, data_len,
-                              (unsigned char *)value, CHUNKSZ_SHA256);
-               *value_len = SHA256_SUM_LEN;
-       } else if (IMAGE_ENABLE_SHA384 && strcmp(algo, "sha384") == 0) {
-               sha384_csum_wd((unsigned char *)data, data_len,
-                              (unsigned char *)value, CHUNKSZ_SHA384);
-               *value_len = SHA384_SUM_LEN;
-       } else if (IMAGE_ENABLE_SHA512 && strcmp(algo, "sha512") == 0) {
-               sha512_csum_wd((unsigned char *)data, data_len,
-                              (unsigned char *)value, CHUNKSZ_SHA512);
-               *value_len = SHA512_SUM_LEN;
-       } else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) {
-               md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5);
-               *value_len = 16;
-       } else {
+#if !defined(USE_HOSTCC) && defined(CONFIG_DM_HASH)
+       int rc;
+       enum HASH_ALGO hash_algo;
+       struct udevice *dev;
+
+       rc = uclass_get_device(UCLASS_HASH, 0, &dev);
+       if (rc) {
+               debug("failed to get hash device, rc=%d\n", rc);
+               return -1;
+       }
+
+       hash_algo = hash_algo_lookup_by_name(algo);
+       if (hash_algo == HASH_ALGO_INVALID) {
+               debug("Unsupported hash algorithm\n");
+               return -1;
+       };
+
+       rc = hash_digest_wd(dev, hash_algo, data, data_len, value, CHUNKSZ);
+       if (rc) {
+               debug("failed to get hash value, rc=%d\n", rc);
+               return -1;
+       }
+
+       *value_len = hash_algo_digest_size(hash_algo);
+#else
+       struct hash_algo *algo;
+       int ret;
+
+       ret = hash_lookup_algo(name, &algo);
+       if (ret < 0) {
                debug("Unsupported hash alogrithm\n");
                return -1;
        }
+
+       algo->hash_func_ws(data, data_len, value, algo->chunk_size);
+       *value_len = algo->digest_size;
+#endif
+
        return 0;
 }
 
@@ -1376,7 +1391,7 @@ int fit_image_verify(const void *fit, int image_noffset)
        size_t          size;
        char            *err_msg = "";
 
-       if (strchr(name, '@')) {
+       if (IS_ENABLED(CONFIG_FIT_SIGNATURE) && strchr(name, '@')) {
                /*
                 * We don't support this since libfdt considers names with the
                 * name root but different @ suffix to be equal
@@ -1776,7 +1791,8 @@ int fit_conf_find_compat(const void *fit, const void *fdt)
                        }
 
                        /* search in this config's kernel FDT */
-                       if (fit_image_get_data(fit, kfdt_noffset, &fdt, &sz)) {
+                       if (fit_image_get_data_and_size(fit, kfdt_noffset,
+                                                       &fdt, &sz)) {
                                debug("Failed to get fdt \"%s\".\n", kfdt_name);
                                continue;
                        }
@@ -1959,6 +1975,8 @@ static const char *fit_get_image_type_property(int type)
                return FIT_FDT_PROP;
        case IH_TYPE_KERNEL:
                return FIT_KERNEL_PROP;
+       case IH_TYPE_FIRMWARE:
+               return FIT_FIRMWARE_PROP;
        case IH_TYPE_RAMDISK:
                return FIT_RAMDISK_PROP;
        case IH_TYPE_X86_SETUP:
@@ -2024,7 +2042,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
                 * fit_conf_get_node() will try to find default config node
                 */
                bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
-               if (IMAGE_ENABLE_BEST_MATCH && !fit_uname_config) {
+               if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config) {
                        cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
                } else {
                        cfg_noffset = fit_conf_get_node(fit,
@@ -2091,6 +2109,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
        type_ok = fit_image_check_type(fit, noffset, image_type) ||
                  fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
+                 fit_image_check_type(fit, noffset, IH_TYPE_TEE) ||
                  (image_type == IH_TYPE_KERNEL &&
                   fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));
 
@@ -2098,6 +2117,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
                image_type == IH_TYPE_FPGA ||
                fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
                fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
+               fit_image_check_os(fit, noffset, IH_OS_TEE) ||
                fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
                fit_image_check_os(fit, noffset, IH_OS_EFI) ||
                fit_image_check_os(fit, noffset, IH_OS_VXWORKS);
@@ -2139,7 +2159,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
 
        /* perform any post-processing on the image data */
        if (!host_build() && IS_ENABLED(CONFIG_FIT_IMAGE_POST_PROCESS))
-               board_fit_image_post_process(&buf, &size);
+               board_fit_image_post_process(fit, noffset, &buf, &size);
 
        len = (ulong)size;
 
@@ -2263,10 +2283,10 @@ int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
        ulong load, len;
 #ifdef CONFIG_OF_LIBFDT_OVERLAY
        ulong image_start, image_end;
-       ulong ovload, ovlen;
+       ulong ovload, ovlen, ovcopylen;
        const char *uconfig;
        const char *uname;
-       void *base, *ov;
+       void *base, *ov, *ovcopy = NULL;
        int i, err, noffset, ov_noffset;
 #endif
 
@@ -2356,7 +2376,7 @@ int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
                        addr, &uname, &uconfig,
                        arch, IH_TYPE_FLATDT,
                        BOOTSTAGE_ID_FIT_FDT_START,
-                       FIT_LOAD_REQUIRED, &ovload, &ovlen);
+                       FIT_LOAD_IGNORED, &ovload, &ovlen);
                if (ov_noffset < 0) {
                        printf("load of %s failed\n", uname);
                        continue;
@@ -2365,6 +2385,21 @@ int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
                                uname, ovload, ovlen);
                ov = map_sysmem(ovload, ovlen);
 
+               ovcopylen = ALIGN(fdt_totalsize(ov), SZ_4K);
+               ovcopy = malloc(ovcopylen);
+               if (!ovcopy) {
+                       printf("failed to duplicate DTO before application\n");
+                       fdt_noffset = -ENOMEM;
+                       goto out;
+               }
+
+               err = fdt_open_into(ov, ovcopy, ovcopylen);
+               if (err < 0) {
+                       printf("failed on fdt_open_into for DTO\n");
+                       fdt_noffset = err;
+                       goto out;
+               }
+
                base = map_sysmem(load, len + ovlen);
                err = fdt_open_into(base, base, len + ovlen);
                if (err < 0) {
@@ -2372,14 +2407,18 @@ int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
                        fdt_noffset = err;
                        goto out;
                }
+
                /* the verbose method prints out messages on error */
-               err = fdt_overlay_apply_verbose(base, ov);
+               err = fdt_overlay_apply_verbose(base, ovcopy);
                if (err < 0) {
                        fdt_noffset = err;
                        goto out;
                }
                fdt_pack(base);
                len = fdt_totalsize(base);
+
+               free(ovcopy);
+               ovcopy = NULL;
        }
 #else
        printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
@@ -2396,6 +2435,10 @@ out:
        if (fit_uname_configp)
                *fit_uname_configp = fit_uname_config;
 
+#ifdef CONFIG_OF_LIBFDT_OVERLAY
+       if (ovcopy)
+               free(ovcopy);
+#endif
        if (fit_uname_config_copy)
                free(fit_uname_config_copy);
        return fdt_noffset;