xref: /openbmc/u-boot/common/boot_fit.c (revision fbe502e9aba098b5ad500d1cdb6b376f56f9ddbb)
1  // SPDX-License-Identifier: GPL-2.0+
2  /*
3   * (C) Copyright 2017
4   * Texas Instruments, <www.ti.com>
5   *
6   * Franklin S Cooper Jr. <fcooper@ti.com>
7   */
8  
9  #include <boot_fit.h>
10  #include <common.h>
11  #include <errno.h>
12  #include <image.h>
13  #include <linux/libfdt.h>
14  
15  static int fdt_offset(const void *fit)
16  {
17  	int images, node, fdt_len, fdt_node, fdt_offset;
18  	const char *fdt_name;
19  
20  	node = fit_find_config_node(fit);
21  	if (node < 0)
22  		return node;
23  
24  	images = fdt_path_offset(fit, FIT_IMAGES_PATH);
25  	if (images < 0) {
26  		debug("%s: Cannot find /images node: %d\n", __func__, images);
27  		return -EINVAL;
28  	}
29  
30  	fdt_name = fdt_getprop(fit, node, FIT_FDT_PROP, &fdt_len);
31  	if (!fdt_name) {
32  		debug("%s: Cannot find fdt name property: %d\n",
33  		      __func__, fdt_len);
34  		return -EINVAL;
35  	}
36  
37  	fdt_node = fdt_subnode_offset(fit, images, fdt_name);
38  	if (fdt_node < 0) {
39  		debug("%s: Cannot find fdt node '%s': %d\n",
40  		      __func__, fdt_name, fdt_node);
41  		return -EINVAL;
42  	}
43  
44  	fdt_offset = fdt_getprop_u32(fit, fdt_node, "data-offset");
45  
46  	if (fdt_offset == FDT_ERROR)
47  		return -ENOENT;
48  
49  	fdt_len = fdt_getprop_u32(fit, fdt_node, "data-size");
50  
51  	if (fdt_len < 0)
52  		return fdt_len;
53  
54  	return fdt_offset;
55  }
56  
57  void *locate_dtb_in_fit(const void *fit)
58  {
59  	struct image_header *header;
60  	int size;
61  	int ret;
62  
63  	size = fdt_totalsize(fit);
64  	size = (size + 3) & ~3;
65  
66  	header = (struct image_header *)fit;
67  
68  	if (image_get_magic(header) != FDT_MAGIC) {
69  		debug("No FIT image appended to U-boot\n");
70  		return NULL;
71  	}
72  
73  	ret = fdt_offset(fit);
74  
75  	if (ret < 0)
76  		return NULL;
77  	else
78  		return (void *)fit+size+ret;
79  }
80