xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/fit_misc.c (revision a962a5fdb4271e59bab38d4e9b59b4839b88656d)
1 /*
2  * (C) Copyright 2020 Rockchip Electronics Co., Ltd
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  */
6 
7 #include <common.h>
8 #include <boot_rkimg.h>
9 #include <misc.h>
10 #ifdef CONFIG_SPL_BUILD
11 #include <spl.h>
12 #endif
13 #include <optee_include/OpteeClientInterface.h>
14 #include <optee_include/tee_api_defines.h>
15 
16 DECLARE_GLOBAL_DATA_PTR;
17 
18 #if CONFIG_IS_ENABLED(FIT)
19 
20 /*
21  * Override __weak board_fit_image_post_process() for SPL & U-Boot proper.
22  */
23 #if CONFIG_IS_ENABLED(FIT_IMAGE_POST_PROCESS)
24 
25 #define FIT_UNCOMP_HASH_NODENAME	"digest"
26 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS) || CONFIG_IS_ENABLED(GZIP)
27 static int fit_image_check_uncomp_hash(const void *fit, int parent_noffset,
28 				       const void *data, size_t size)
29 {
30 	const char *name;
31 	char *err_msgp;
32 	int noffset;
33 
34 	fdt_for_each_subnode(noffset, fit, parent_noffset) {
35 		name = fit_get_name(fit, noffset, NULL);
36 		if (!strncmp(name, FIT_UNCOMP_HASH_NODENAME,
37 			     strlen(FIT_UNCOMP_HASH_NODENAME))) {
38 			return fit_image_check_hash(fit, noffset, data,
39 						    size, &err_msgp);
40 		}
41 	}
42 
43 	return 0;
44 }
45 
46 static int fit_gunzip_image(void *fit, int node, ulong *load_addr,
47 			    ulong **src_addr, size_t *src_len, void *spec)
48 {
49 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS)
50 	const void *prop;
51 	u32 flags = 0;
52 #endif
53 	u64 len = *src_len;
54 	int ret;
55 	u8 comp;
56 
57 	if (fit_image_get_comp(fit, node, &comp))
58 		return 0;
59 
60 	if (comp != IH_COMP_GZIP)
61 		return 0;
62 
63 #ifndef CONFIG_SPL_BUILD
64 	/*
65 	 * U-Boot:
66 	 *	handled late in bootm_decomp_image()
67 	 */
68 	if (fit_image_check_type(fit, node, IH_TYPE_KERNEL))
69 		return 0;
70 #elif defined(CONFIG_SPL_MTD_SUPPORT) && defined(CONFIG_SPL_MISC_DECOMPRESS) && \
71       defined(CONFIG_SPL_KERNEL_BOOT)
72 	/*
73 	 * SPL Thunder-boot policty on spi-nand:
74 	 *	enable and use interrupt status as a sync signal for
75 	 *	kernel to poll that whether ramdisk decompress is done.
76 	 */
77 	struct spl_load_info *info = spec;
78 	struct blk_desc *desc;
79 
80 	if (info && info->dev) {
81 		desc = info->dev;
82 		if ((desc->if_type == IF_TYPE_MTD) &&
83 		    (desc->devnum == BLK_MTD_SPI_NAND) &&
84 		    fit_image_check_type(fit, node, IH_TYPE_RAMDISK)) {
85 			flags |= DCOMP_FLG_IRQ_ONESHOT;
86 		}
87 	}
88 #endif
89 	/*
90 	 * For smaller spl size, we don't use misc_decompress_process()
91 	 * inside the gunzip().
92 	 */
93 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS)
94 	ret = misc_decompress_process((ulong)(*load_addr),
95 				      (ulong)(*src_addr), (ulong)(*src_len),
96 				      DECOM_GZIP, false, &len, flags);
97 #else
98 	ret = gunzip((void *)(*load_addr), ALIGN(len, FIT_MAX_SPL_IMAGE_SZ),
99 		     (void *)(*src_addr), (void *)(&len));
100 #endif
101 	if (ret) {
102 		printf("%s: decompress error, ret=%d\n",
103 		       fdt_get_name(fit, node, NULL), ret);
104 		return ret;
105 	}
106 
107 	/* check uncompressed data hash */
108 	ret = fit_image_check_uncomp_hash(fit, node, (void *)(*load_addr), len);
109 	if (!ret)
110 		puts("+ ");
111 	else
112 		return ret;
113 
114 	*src_addr = (ulong *)*load_addr;
115 	*src_len = len;
116 
117 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS)
118 	/* mark for misc_decompress_cleanup() */
119 	prop = fdt_getprop(fit, node, "decomp-async", NULL);
120 	if (prop)
121 		misc_decompress_async(comp);
122 	else
123 		misc_decompress_sync(comp);
124 #endif
125 
126 	return 0;
127 }
128 #endif
129 
130 void board_fit_image_post_process(void *fit, int node, ulong *load_addr,
131 				  ulong **src_addr, size_t *src_len, void *spec)
132 {
133 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS) || CONFIG_IS_ENABLED(GZIP)
134 	fit_gunzip_image(fit, node, load_addr, src_addr, src_len, spec);
135 #endif
136 
137 #if CONFIG_IS_ENABLED(USING_KERNEL_DTB)
138 	/* Avoid overriding processed(overlay, hw-dtb, ...) kernel dtb */
139 	if (fit_image_check_type(fit, node, IH_TYPE_FLATDT)) {
140 		if ((gd->flags & GD_FLG_KDTB_READY) && !gd->fdt_blob_kern) {
141 			*src_addr = (void *)gd->fdt_blob;
142 			*src_len = (size_t)fdt_totalsize(gd->fdt_blob);
143 		} else {
144 			printf("   Using fdt from load-in fdt\n");
145 		}
146 	}
147 #endif
148 }
149 #endif /* FIT_IMAGE_POST_PROCESS */
150 
151 /*
152  * Override __weak fit_rollback_index_verify() for SPL & U-Boot proper.
153  */
154 #if CONFIG_IS_ENABLED(FIT_ROLLBACK_PROTECT)
155 int fit_rollback_index_verify(const void *fit, uint32_t rollback_fd,
156 			      uint32_t *fit_index, uint32_t *otp_index)
157 {
158 	int conf_noffset, ret;
159 
160 	conf_noffset = fit_conf_get_node(fit, NULL); /* NULL for default conf */
161 	if (conf_noffset < 0)
162 		return conf_noffset;
163 
164 	ret = fit_image_get_rollback_index(fit, conf_noffset, fit_index);
165 	if (ret) {
166 		printf("Failed to get rollback-index from FIT, ret=%d\n", ret);
167 		return ret;
168 	}
169 
170 	ret = fit_read_otp_rollback_index(*fit_index, otp_index);
171 	if (ret) {
172 		printf("Failed to get rollback-index from otp, ret=%d\n", ret);
173 		return ret;
174 	}
175 
176 	/* Should update rollback index to otp ! */
177 	if (*otp_index < *fit_index)
178 		gd->rollback_index = *fit_index;
179 
180 	return 0;
181 }
182 #endif
183 
184 /*
185  * Override __weak fit_board_verify_required_sigs() for SPL & U-Boot proper.
186  */
187 int fit_board_verify_required_sigs(void)
188 {
189 	uint8_t vboot = 0;
190 
191 #ifdef CONFIG_SPL_BUILD
192 #if defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP)
193 	struct udevice *dev;
194 
195 	dev = misc_otp_get_device(OTP_S);
196 	if (!dev)
197 		return 1;
198 
199 	if (misc_otp_read(dev, OTP_SECURE_BOOT_ENABLE_ADDR, &vboot, 1)) {
200 		printf("Can't read verified-boot flag\n");
201 		return 1;
202 	}
203 
204 	vboot = (vboot == 0xff);
205 #endif
206 #else /* !CONFIG_SPL_BUILD */
207 #ifdef CONFIG_OPTEE_CLIENT
208 	int ret;
209 
210 	ret = trusty_read_vbootkey_enable_flag(&vboot);
211 	if (ret) {
212 		printf("Can't read verified-boot flag, ret=%d\n", ret);
213 		return 1;
214 	}
215 #endif
216 #endif /* CONFIG_SPL_BUILD*/
217 
218 	printf("## Verified-boot: %d\n", vboot);
219 
220 	return vboot;
221 }
222 
223 #endif /* CONFIG_IS_ENABLED(FIT) */
224