1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
292926bc8SCooper Jr., Franklin /*
392926bc8SCooper Jr., Franklin * (C) Copyright 2017
492926bc8SCooper Jr., Franklin * Texas Instruments, <www.ti.com>
592926bc8SCooper Jr., Franklin *
692926bc8SCooper Jr., Franklin * Franklin S Cooper Jr. <fcooper@ti.com>
792926bc8SCooper Jr., Franklin */
892926bc8SCooper Jr., Franklin
992926bc8SCooper Jr., Franklin #include <boot_fit.h>
1092926bc8SCooper Jr., Franklin #include <common.h>
1192926bc8SCooper Jr., Franklin #include <errno.h>
1292926bc8SCooper Jr., Franklin #include <image.h>
13b08c8c48SMasahiro Yamada #include <linux/libfdt.h>
1492926bc8SCooper Jr., Franklin
fdt_offset(const void * fit)15906a9dbbSJean-Jacques Hiblot static int fdt_offset(const void *fit)
1692926bc8SCooper Jr., Franklin {
1792926bc8SCooper Jr., Franklin int images, node, fdt_len, fdt_node, fdt_offset;
1892926bc8SCooper Jr., Franklin const char *fdt_name;
1992926bc8SCooper Jr., Franklin
2092926bc8SCooper Jr., Franklin node = fit_find_config_node(fit);
2192926bc8SCooper Jr., Franklin if (node < 0)
2292926bc8SCooper Jr., Franklin return node;
2392926bc8SCooper Jr., Franklin
2492926bc8SCooper Jr., Franklin images = fdt_path_offset(fit, FIT_IMAGES_PATH);
2592926bc8SCooper Jr., Franklin if (images < 0) {
2692926bc8SCooper Jr., Franklin debug("%s: Cannot find /images node: %d\n", __func__, images);
27160cfc4bSNobuhiro Iwamatsu return -EINVAL;
2892926bc8SCooper Jr., Franklin }
2992926bc8SCooper Jr., Franklin
3092926bc8SCooper Jr., Franklin fdt_name = fdt_getprop(fit, node, FIT_FDT_PROP, &fdt_len);
3192926bc8SCooper Jr., Franklin if (!fdt_name) {
3292926bc8SCooper Jr., Franklin debug("%s: Cannot find fdt name property: %d\n",
3392926bc8SCooper Jr., Franklin __func__, fdt_len);
3492926bc8SCooper Jr., Franklin return -EINVAL;
3592926bc8SCooper Jr., Franklin }
3692926bc8SCooper Jr., Franklin
3792926bc8SCooper Jr., Franklin fdt_node = fdt_subnode_offset(fit, images, fdt_name);
3892926bc8SCooper Jr., Franklin if (fdt_node < 0) {
3992926bc8SCooper Jr., Franklin debug("%s: Cannot find fdt node '%s': %d\n",
4092926bc8SCooper Jr., Franklin __func__, fdt_name, fdt_node);
4192926bc8SCooper Jr., Franklin return -EINVAL;
4292926bc8SCooper Jr., Franklin }
4392926bc8SCooper Jr., Franklin
4492926bc8SCooper Jr., Franklin fdt_offset = fdt_getprop_u32(fit, fdt_node, "data-offset");
4592926bc8SCooper Jr., Franklin
4692926bc8SCooper Jr., Franklin if (fdt_offset == FDT_ERROR)
4792926bc8SCooper Jr., Franklin return -ENOENT;
4892926bc8SCooper Jr., Franklin
4992926bc8SCooper Jr., Franklin fdt_len = fdt_getprop_u32(fit, fdt_node, "data-size");
5092926bc8SCooper Jr., Franklin
5192926bc8SCooper Jr., Franklin if (fdt_len < 0)
5292926bc8SCooper Jr., Franklin return fdt_len;
5392926bc8SCooper Jr., Franklin
5492926bc8SCooper Jr., Franklin return fdt_offset;
5592926bc8SCooper Jr., Franklin }
5692926bc8SCooper Jr., Franklin
locate_dtb_in_fit(const void * fit)57906a9dbbSJean-Jacques Hiblot void *locate_dtb_in_fit(const void *fit)
5892926bc8SCooper Jr., Franklin {
5992926bc8SCooper Jr., Franklin struct image_header *header;
6092926bc8SCooper Jr., Franklin int size;
6192926bc8SCooper Jr., Franklin int ret;
6292926bc8SCooper Jr., Franklin
6392926bc8SCooper Jr., Franklin size = fdt_totalsize(fit);
6492926bc8SCooper Jr., Franklin size = (size + 3) & ~3;
6592926bc8SCooper Jr., Franklin
6692926bc8SCooper Jr., Franklin header = (struct image_header *)fit;
6792926bc8SCooper Jr., Franklin
6892926bc8SCooper Jr., Franklin if (image_get_magic(header) != FDT_MAGIC) {
6992926bc8SCooper Jr., Franklin debug("No FIT image appended to U-boot\n");
7092926bc8SCooper Jr., Franklin return NULL;
7192926bc8SCooper Jr., Franklin }
7292926bc8SCooper Jr., Franklin
7392926bc8SCooper Jr., Franklin ret = fdt_offset(fit);
7492926bc8SCooper Jr., Franklin
75d56b86eeSJean-Jacques Hiblot if (ret < 0)
7692926bc8SCooper Jr., Franklin return NULL;
7792926bc8SCooper Jr., Franklin else
7892926bc8SCooper Jr., Franklin return (void *)fit+size+ret;
7992926bc8SCooper Jr., Franklin }
80