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