xref: /rk3399_rockchip-uboot/arch/arm/mach-rockchip/fit_misc.c (revision 26663c2dc5b80cce67e4f8ad77e5efbb7ae05b88)
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)
48 {
49 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS)
50 	const void *prop;
51 #endif
52 	u64 len = *src_len;
53 	int ret;
54 	u8 comp;
55 
56 	if (fit_image_get_comp(fit, node, &comp))
57 		return 0;
58 
59 	if (comp != IH_COMP_GZIP)
60 		return 0;
61 
62 #ifndef CONFIG_SPL_BUILD
63 	/* handled late in bootm_decomp_image() */
64 	if (fit_image_check_type(fit, node, IH_TYPE_KERNEL))
65 		return 0;
66 #endif
67 	/*
68 	 * For smaller spl size, we don't use misc_decompress_process()
69 	 * inside the gunzip().
70 	 */
71 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS)
72 	ret = misc_decompress_process((ulong)(*load_addr),
73 				      (ulong)(*src_addr), (ulong)(*src_len),
74 				      DECOM_GZIP, false, &len);
75 #else
76 	ret = gunzip((void *)(*load_addr), ALIGN(len, FIT_MAX_SPL_IMAGE_SZ),
77 		     (void *)(*src_addr), (void *)(&len));
78 #endif
79 	if (ret) {
80 		printf("%s: decompress error, ret=%d\n",
81 		       fdt_get_name(fit, node, NULL), ret);
82 		return ret;
83 	}
84 
85 	/* check uncompressed data hash */
86 	ret = fit_image_check_uncomp_hash(fit, node, (void *)(*load_addr), len);
87 	if (!ret)
88 		puts("+ ");
89 	else
90 		return ret;
91 
92 	*src_addr = (ulong *)*load_addr;
93 	*src_len = len;
94 
95 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS)
96 	/* mark for misc_decompress_cleanup() */
97 	prop = fdt_getprop(fit, node, "decomp-async", NULL);
98 	if (prop)
99 		misc_decompress_async(comp);
100 	else
101 		misc_decompress_sync(comp);
102 #endif
103 
104 	return 0;
105 }
106 #endif
107 
108 void board_fit_image_post_process(void *fit, int node, ulong *load_addr,
109 				  ulong **src_addr, size_t *src_len)
110 {
111 #if CONFIG_IS_ENABLED(MISC_DECOMPRESS) || CONFIG_IS_ENABLED(GZIP)
112 	fit_gunzip_image(fit, node, load_addr, src_addr, src_len);
113 #endif
114 
115 #if CONFIG_IS_ENABLED(USING_KERNEL_DTB)
116 	/* Avoid overriding processed(overlay, hw-dtb, ...) kernel dtb */
117 	if (fit_image_check_type(fit, node, IH_TYPE_FLATDT)) {
118 		if ((gd->flags & GD_FLG_KDTB_READY) && !gd->fdt_blob_kern) {
119 			*src_addr = (void *)gd->fdt_blob;
120 			*src_len = (size_t)fdt_totalsize(gd->fdt_blob);
121 		} else {
122 			printf("   Using fdt from load-in fdt\n");
123 		}
124 	}
125 #endif
126 }
127 #endif /* FIT_IMAGE_POST_PROCESS */
128 
129 /*
130  * Override __weak fit_rollback_index_verify() for SPL & U-Boot proper.
131  */
132 #if CONFIG_IS_ENABLED(FIT_ROLLBACK_PROTECT)
133 int fit_rollback_index_verify(const void *fit, uint32_t rollback_fd,
134 			      uint32_t *fit_index, uint32_t *otp_index)
135 {
136 	int conf_noffset, ret;
137 
138 	conf_noffset = fit_conf_get_node(fit, NULL); /* NULL for default conf */
139 	if (conf_noffset < 0)
140 		return conf_noffset;
141 
142 	ret = fit_image_get_rollback_index(fit, conf_noffset, fit_index);
143 	if (ret) {
144 		printf("Failed to get rollback-index from FIT, ret=%d\n", ret);
145 		return ret;
146 	}
147 
148 	ret = fit_read_otp_rollback_index(*fit_index, otp_index);
149 	if (ret) {
150 		printf("Failed to get rollback-index from otp, ret=%d\n", ret);
151 		return ret;
152 	}
153 
154 	/* Should update rollback index to otp ! */
155 	if (*otp_index < *fit_index)
156 		gd->rollback_index = *fit_index;
157 
158 	return 0;
159 }
160 #endif
161 
162 /*
163  * Override __weak fit_board_verify_required_sigs() for SPL & U-Boot proper.
164  */
165 int fit_board_verify_required_sigs(void)
166 {
167 	uint8_t vboot = 0;
168 
169 #ifdef CONFIG_SPL_BUILD
170 #if defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP_V1) || \
171     defined(CONFIG_SPL_ROCKCHIP_SECURE_OTP_V2)
172 	struct udevice *dev;
173 
174 	dev = misc_otp_get_device(OTP_S);
175 	if (!dev)
176 		return 1;
177 
178 	if (misc_otp_read(dev, OTP_SECURE_BOOT_ENABLE_ADDR, &vboot, 1)) {
179 		printf("Can't read verified-boot flag\n");
180 		return 1;
181 	}
182 
183 	vboot = (vboot == 0xff);
184 #endif
185 #else /* !CONFIG_SPL_BUILD */
186 #ifdef CONFIG_OPTEE_CLIENT
187 	int ret;
188 
189 	ret = trusty_read_vbootkey_enable_flag(&vboot);
190 	if (ret) {
191 		printf("Can't read verified-boot flag, ret=%d\n", ret);
192 		return 1;
193 	}
194 #endif
195 #endif /* CONFIG_SPL_BUILD*/
196 
197 	printf("## Verified-boot: %d\n", vboot);
198 
199 	return vboot;
200 }
201 
202 #endif /* CONFIG_IS_ENABLED(FIT) */
203