1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Generate MediaTek BootROM header for SPL/U-Boot images
4  *
5  * Copyright (C) 2018 MediaTek Inc.
6  * Author: Weijie Gao <weijie.gao@mediatek.com>
7  */
8 
9 #include <image.h>
10 #include <u-boot/sha256.h>
11 #include "imagetool.h"
12 #include "mtk_image.h"
13 
14 /* NAND header for SPI-NAND with 2KB page + 64B spare */
15 static const union nand_boot_header snand_hdr_2k_64_data = {
16 	.data = {
17 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
18 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
19 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
20 		0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
21 		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
22 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 		0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
30 		0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
31 		0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
32 		0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
33 	}
34 };
35 
36 /* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
37 static const union nand_boot_header snand_hdr_2k_128_data = {
38 	.data = {
39 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
40 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
41 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
42 		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
43 		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
44 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 		0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
52 		0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
53 		0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
54 		0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
55 	}
56 };
57 
58 /* NAND header for SPI-NAND with 4KB page + 256B spare */
59 static const union nand_boot_header snand_hdr_4k_256_data = {
60 	.data = {
61 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
62 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
63 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
64 		0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
65 		0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
66 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 		0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
74 		0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
75 		0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
76 		0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
77 	}
78 };
79 
80 /* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
81 static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
82 	.data = {
83 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
84 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
85 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
86 		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
87 		0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
88 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 		0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
96 		0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
97 		0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
98 		0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
99 	}
100 };
101 
102 /* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
103 static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
104 	.data = {
105 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
106 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
107 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
108 		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
109 		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
110 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 		0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
118 		0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
119 		0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
120 		0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
121 	}
122 };
123 
124 /* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
125 static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
126 	.data = {
127 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
128 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
129 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
130 		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
131 		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
132 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 		0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
140 		0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
141 		0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
142 		0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
143 	}
144 };
145 
146 /* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
147 static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
148 	.data = {
149 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
150 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
151 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
152 		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
153 		0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
154 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 		0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
162 		0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
163 		0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
164 		0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
165 	}
166 };
167 
168 /* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
169 static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
170 	.data = {
171 		0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
172 		0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
173 		0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
174 		0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
175 		0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
176 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
177 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 		0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
184 		0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
185 		0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
186 		0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
187 	}
188 };
189 
190 static const struct nand_header_type {
191 	const char *name;
192 	const union nand_boot_header *data;
193 } nand_headers[] = {
194 	{
195 		.name = "2k+64",
196 		.data = &snand_hdr_2k_64_data
197 	}, {
198 		.name = "2k+120",
199 		.data = &snand_hdr_2k_128_data
200 	}, {
201 		.name = "2k+128",
202 		.data = &snand_hdr_2k_128_data
203 	}, {
204 		.name = "4k+256",
205 		.data = &snand_hdr_4k_256_data
206 	}, {
207 		.name = "1g:2k+64",
208 		.data = &nand_hdr_1gb_2k_64_data
209 	}, {
210 		.name = "2g:2k+64",
211 		.data = &nand_hdr_2gb_2k_64_data
212 	}, {
213 		.name = "4g:2k+64",
214 		.data = &nand_hdr_4gb_2k_64_data
215 	}, {
216 		.name = "2g:2k+128",
217 		.data = &nand_hdr_2gb_2k_128_data
218 	}, {
219 		.name = "4g:2k+128",
220 		.data = &nand_hdr_4gb_2k_128_data
221 	}
222 };
223 
224 static const struct brom_img_type {
225 	const char *name;
226 	enum brlyt_img_type type;
227 } brom_images[] = {
228 	{
229 		.name = "nand",
230 		.type = BRLYT_TYPE_NAND
231 	}, {
232 		.name = "emmc",
233 		.type = BRLYT_TYPE_EMMC
234 	}, {
235 		.name = "nor",
236 		.type = BRLYT_TYPE_NOR
237 	}, {
238 		.name = "sdmmc",
239 		.type = BRLYT_TYPE_SDMMC
240 	}, {
241 		.name = "snand",
242 		.type = BRLYT_TYPE_SNAND
243 	}
244 };
245 
246 /* Image type selected by user */
247 static enum brlyt_img_type hdr_media;
248 static int use_lk_hdr;
249 static bool is_arm64_image;
250 
251 /* LK image name */
252 static char lk_name[32] = "U-Boot";
253 
254 /* NAND header selected by user */
255 static const union nand_boot_header *hdr_nand;
256 
257 /* GFH header + 2 * 4KB pages of NAND */
258 static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
259 
mtk_image_check_image_types(uint8_t type)260 static int mtk_image_check_image_types(uint8_t type)
261 {
262 	if (type == IH_TYPE_MTKIMAGE)
263 		return EXIT_SUCCESS;
264 	else
265 		return EXIT_FAILURE;
266 }
267 
mtk_brom_parse_imagename(const char * imagename)268 static int mtk_brom_parse_imagename(const char *imagename)
269 {
270 #define is_blank_char(c) \
271 	((c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == ' ')
272 
273 	char *buf = strdup(imagename), *key, *val, *end, *next;
274 	int i;
275 
276 	/* User passed arguments from image name */
277 	static const char *media = "";
278 	static const char *nandinfo = "";
279 	static const char *lk = "";
280 	static const char *arm64_param = "";
281 
282 	key = buf;
283 	while (key) {
284 		next = strchr(key, ';');
285 		if (next)
286 			*next = 0;
287 
288 		val = strchr(key, '=');
289 		if (val) {
290 			*val++ = 0;
291 
292 			/* Trim key */
293 			while (is_blank_char(*key))
294 				key++;
295 
296 			end = key + strlen(key) - 1;
297 			while ((end >= key) && is_blank_char(*end))
298 				end--;
299 			end++;
300 
301 			if (is_blank_char(*end))
302 				*end = 0;
303 
304 			/* Trim value */
305 			while (is_blank_char(*val))
306 				val++;
307 
308 			end = val + strlen(val) - 1;
309 			while ((end >= val) && is_blank_char(*end))
310 				end--;
311 			end++;
312 
313 			if (is_blank_char(*end))
314 				*end = 0;
315 
316 			/* record user passed arguments */
317 			if (!strcmp(key, "media"))
318 				media = val;
319 
320 			if (!strcmp(key, "nandinfo"))
321 				nandinfo = val;
322 
323 			if (!strcmp(key, "lk"))
324 				lk = val;
325 
326 			if (!strcmp(key, "lkname"))
327 				snprintf(lk_name, sizeof(lk_name), "%s", val);
328 
329 			if (!strcmp(key, "arm64"))
330 				arm64_param = val;
331 		}
332 
333 		if (next)
334 			key = next + 1;
335 		else
336 			break;
337 	}
338 
339 	/* if user specified LK image header, skip following checks */
340 	if (lk && lk[0] == '1') {
341 		use_lk_hdr = 1;
342 		free(buf);
343 		return 0;
344 	}
345 
346 	/* parse media type */
347 	for (i = 0; i < ARRAY_SIZE(brom_images); i++) {
348 		if (!strcmp(brom_images[i].name, media)) {
349 			hdr_media = brom_images[i].type;
350 			break;
351 		}
352 	}
353 
354 	/* parse nand header type */
355 	for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
356 		if (!strcmp(nand_headers[i].name, nandinfo)) {
357 			hdr_nand = nand_headers[i].data;
358 			break;
359 		}
360 	}
361 
362 	if (arm64_param && arm64_param[0] == '1')
363 		is_arm64_image = true;
364 
365 	free(buf);
366 
367 	if (hdr_media == BRLYT_TYPE_INVALID) {
368 		fprintf(stderr, "Error: media type is invalid or missing.\n");
369 		fprintf(stderr, "       Please specify -n \"media=<type>\"\n");
370 		return -EINVAL;
371 	}
372 
373 	if ((hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) &&
374 	    !hdr_nand) {
375 		fprintf(stderr, "Error: nand info is invalid or missing.\n");
376 		fprintf(stderr, "       Please specify -n \"media=%s;"
377 				"nandinfo=<info>\"\n", media);
378 		return -EINVAL;
379 	}
380 
381 	return 0;
382 }
383 
mtk_image_check_params(struct image_tool_params * params)384 static int mtk_image_check_params(struct image_tool_params *params)
385 {
386 	if (!params->addr) {
387 		fprintf(stderr, "Error: Load Address must be set.\n");
388 		return -EINVAL;
389 	}
390 
391 	if (!params->imagename) {
392 		fprintf(stderr, "Error: Image Name must be set.\n");
393 		return -EINVAL;
394 	}
395 
396 	return mtk_brom_parse_imagename(params->imagename);
397 }
398 
mtk_image_vrec_header(struct image_tool_params * params,struct image_type_params * tparams)399 static int mtk_image_vrec_header(struct image_tool_params *params,
400 				 struct image_type_params *tparams)
401 {
402 	if (use_lk_hdr) {
403 		tparams->header_size = sizeof(union lk_hdr);
404 		tparams->hdr = &hdr_tmp;
405 		memset(&hdr_tmp, 0xff, tparams->header_size);
406 		return 0;
407 	}
408 
409 	if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
410 		tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
411 	else
412 		tparams->header_size = sizeof(struct gen_device_header);
413 
414 	tparams->header_size += sizeof(struct gfh_header);
415 	tparams->hdr = &hdr_tmp;
416 
417 	memset(&hdr_tmp, 0xff, tparams->header_size);
418 
419 	return SHA256_SUM_LEN;
420 }
421 
mtk_image_verify_gen_header(const uint8_t * ptr,int print)422 static int mtk_image_verify_gen_header(const uint8_t *ptr, int print)
423 {
424 	union gen_boot_header *gbh = (union gen_boot_header *)ptr;
425 	struct brom_layout_header *bh;
426 	struct gfh_header *gfh;
427 	const char *bootmedia;
428 
429 	if (!strcmp(gbh->name, SF_BOOT_NAME))
430 		bootmedia = "Serial NOR";
431 	else if (!strcmp(gbh->name, EMMC_BOOT_NAME))
432 		bootmedia = "eMMC";
433 	else if (!strcmp(gbh->name, SDMMC_BOOT_NAME))
434 		bootmedia = "SD/MMC";
435 	else
436 		return -1;
437 
438 	if (print)
439 		printf("Boot Media:   %s\n", bootmedia);
440 
441 	if (le32_to_cpu(gbh->version) != 1 ||
442 	    le32_to_cpu(gbh->size) != sizeof(union gen_boot_header))
443 		return -1;
444 
445 	bh = (struct brom_layout_header *)(ptr + le32_to_cpu(gbh->size));
446 
447 	if (strcmp(bh->name, BRLYT_NAME))
448 		return -1;
449 
450 	if (le32_to_cpu(bh->magic) != BRLYT_MAGIC ||
451 	    (le32_to_cpu(bh->type) != BRLYT_TYPE_NOR &&
452 	    le32_to_cpu(bh->type) != BRLYT_TYPE_EMMC &&
453 	    le32_to_cpu(bh->type) != BRLYT_TYPE_SDMMC))
454 		return -1;
455 
456 	gfh = (struct gfh_header *)(ptr + le32_to_cpu(bh->header_size));
457 
458 	if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
459 		return -1;
460 
461 	if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN)
462 		return -1;
463 
464 	if (print)
465 		printf("Load Address: %08x\n",
466 		       le32_to_cpu(gfh->file_info.load_addr) +
467 		       le32_to_cpu(gfh->file_info.jump_offset));
468 
469 	if (print)
470 		printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
471 
472 	return 0;
473 }
474 
mtk_image_verify_nand_header(const uint8_t * ptr,int print)475 static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
476 {
477 	union nand_boot_header *nh = (union nand_boot_header *)ptr;
478 	struct brom_layout_header *bh;
479 	struct gfh_header *gfh;
480 	const char *bootmedia;
481 
482 	if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
483 	    strcmp(nh->id, NAND_BOOT_ID))
484 		return -1;
485 
486 	bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize));
487 
488 	if (strcmp(bh->name, BRLYT_NAME))
489 		return -1;
490 
491 	if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) {
492 		return -1;
493 	} else {
494 		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
495 			bootmedia = "Parallel NAND";
496 		else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
497 			bootmedia = "Serial NAND";
498 		else
499 			return -1;
500 	}
501 
502 	if (print) {
503 		printf("Boot Media: %s\n", bootmedia);
504 
505 		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
506 			uint64_t capacity =
507 				(uint64_t)le16_to_cpu(nh->numblocks) *
508 				(uint64_t)le16_to_cpu(nh->pages_of_block) *
509 				(uint64_t)le16_to_cpu(nh->pagesize) * 8;
510 			printf("Capacity:     %dGb\n",
511 			       (uint32_t)(capacity >> 30));
512 		}
513 
514 		if (le16_to_cpu(nh->pagesize) >= 1024)
515 			printf("Page Size:    %dKB\n",
516 			       le16_to_cpu(nh->pagesize) >> 10);
517 		else
518 			printf("Page Size:    %dB\n",
519 			       le16_to_cpu(nh->pagesize));
520 
521 		printf("Spare Size:   %dB\n", le16_to_cpu(nh->oobsize));
522 	}
523 
524 	gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
525 
526 	if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
527 		return -1;
528 
529 	if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND)
530 		return -1;
531 
532 	if (print)
533 		printf("Load Address: %08x\n",
534 		       le32_to_cpu(gfh->file_info.load_addr) +
535 		       le32_to_cpu(gfh->file_info.jump_offset));
536 
537 	if (print)
538 		printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
539 
540 	return 0;
541 }
542 
mtk_image_verify_header(unsigned char * ptr,int image_size,struct image_tool_params * params)543 static int mtk_image_verify_header(unsigned char *ptr, int image_size,
544 				   struct image_tool_params *params)
545 {
546 	union lk_hdr *lk = (union lk_hdr *)ptr;
547 
548 	/* nothing to verify for LK image header */
549 	if (le32_to_cpu(lk->magic) == LK_PART_MAGIC)
550 		return 0;
551 
552 	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
553 		return mtk_image_verify_nand_header(ptr, 0);
554 	else
555 		return mtk_image_verify_gen_header(ptr, 0);
556 
557 	return -1;
558 }
559 
mtk_image_print_header(const void * ptr)560 static void mtk_image_print_header(const void *ptr)
561 {
562 	union lk_hdr *lk = (union lk_hdr *)ptr;
563 
564 	if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) {
565 		printf("Image Type:   MediaTek LK Image\n");
566 		printf("Load Address: %08x\n", le32_to_cpu(lk->loadaddr));
567 		return;
568 	}
569 
570 	printf("Image Type:   MediaTek BootROM Loadable Image\n");
571 
572 	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
573 		mtk_image_verify_nand_header(ptr, 1);
574 	else
575 		mtk_image_verify_gen_header(ptr, 1);
576 }
577 
put_brom_layout_header(struct brom_layout_header * hdr,int type)578 static void put_brom_layout_header(struct brom_layout_header *hdr, int type)
579 {
580 	strncpy(hdr->name, BRLYT_NAME, sizeof(hdr->name));
581 	hdr->version = cpu_to_le32(1);
582 	hdr->magic = cpu_to_le32(BRLYT_MAGIC);
583 	hdr->type = cpu_to_le32(type);
584 }
585 
put_ghf_common_header(struct gfh_common_header * gfh,int size,int type,int ver)586 static void put_ghf_common_header(struct gfh_common_header *gfh, int size,
587 				  int type, int ver)
588 {
589 	memcpy(gfh->magic, GFH_HEADER_MAGIC, sizeof(gfh->magic));
590 	gfh->version = ver;
591 	gfh->size = cpu_to_le16(size);
592 	gfh->type = cpu_to_le16(type);
593 }
594 
put_ghf_header(struct gfh_header * gfh,int file_size,int dev_hdr_size,int load_addr,int flash_type)595 static void put_ghf_header(struct gfh_header *gfh, int file_size,
596 			   int dev_hdr_size, int load_addr, int flash_type)
597 {
598 	uint32_t cfg_bits;
599 
600 	memset(gfh, 0, sizeof(struct gfh_header));
601 
602 	/* GFH_FILE_INFO header */
603 	put_ghf_common_header(&gfh->file_info.gfh, sizeof(gfh->file_info),
604 			      GFH_TYPE_FILE_INFO, 1);
605 	strncpy(gfh->file_info.name, GFH_FILE_INFO_NAME,
606 		sizeof(gfh->file_info.name));
607 	gfh->file_info.unused = cpu_to_le32(1);
608 	gfh->file_info.file_type = cpu_to_le16(1);
609 	gfh->file_info.flash_type = flash_type;
610 	gfh->file_info.sig_type = GFH_SIG_TYPE_SHA256;
611 	gfh->file_info.load_addr = cpu_to_le32(load_addr - sizeof(*gfh));
612 	gfh->file_info.total_size = cpu_to_le32(file_size - dev_hdr_size);
613 	gfh->file_info.max_size = cpu_to_le32(file_size);
614 	gfh->file_info.hdr_size = sizeof(*gfh);
615 	gfh->file_info.sig_size = SHA256_SUM_LEN;
616 	gfh->file_info.jump_offset = sizeof(*gfh);
617 	gfh->file_info.processed = cpu_to_le32(1);
618 
619 	/* GFH_BL_INFO header */
620 	put_ghf_common_header(&gfh->bl_info.gfh, sizeof(gfh->bl_info),
621 			      GFH_TYPE_BL_INFO, 1);
622 	gfh->bl_info.attr = cpu_to_le32(1);
623 
624 	/* GFH_BROM_CFG header */
625 	put_ghf_common_header(&gfh->brom_cfg.gfh, sizeof(gfh->brom_cfg),
626 			      GFH_TYPE_BROM_CFG, 3);
627 	cfg_bits = GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS |
628 		   GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN |
629 		   GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN;
630 	gfh->brom_cfg.usbdl_by_kcol0_timeout_ms = cpu_to_le32(5000);
631 	if (is_arm64_image) {
632 		gfh->brom_cfg.jump_bl_arm64 = GFH_BROM_CFG_JUMP_BL_ARM64;
633 		cfg_bits |= GFH_BROM_CFG_JUMP_BL_ARM64_EN;
634 	}
635 	gfh->brom_cfg.cfg_bits = cpu_to_le32(cfg_bits);
636 
637 	/* GFH_BL_SEC_KEY header */
638 	put_ghf_common_header(&gfh->bl_sec_key.gfh, sizeof(gfh->bl_sec_key),
639 			      GFH_TYPE_BL_SEC_KEY, 1);
640 
641 	/* GFH_ANTI_CLONE header */
642 	put_ghf_common_header(&gfh->anti_clone.gfh, sizeof(gfh->anti_clone),
643 			      GFH_TYPE_ANTI_CLONE, 1);
644 	gfh->anti_clone.ac_offset = cpu_to_le32(0x10);
645 	gfh->anti_clone.ac_len = cpu_to_le32(0x80);
646 
647 	/* GFH_BROM_SEC_CFG header */
648 	put_ghf_common_header(&gfh->brom_sec_cfg.gfh,
649 			      sizeof(gfh->brom_sec_cfg),
650 			      GFH_TYPE_BROM_SEC_CFG, 1);
651 	gfh->brom_sec_cfg.cfg_bits =
652 		cpu_to_le32(BROM_SEC_CFG_JTAG_EN | BROM_SEC_CFG_UART_EN);
653 }
654 
put_hash(uint8_t * buff,int size)655 static void put_hash(uint8_t *buff, int size)
656 {
657 	sha256_context ctx;
658 
659 	sha256_starts(&ctx);
660 	sha256_update(&ctx, buff, size);
661 	sha256_finish(&ctx, buff + size);
662 }
663 
mtk_image_set_gen_header(void * ptr,off_t filesize,uint32_t loadaddr)664 static void mtk_image_set_gen_header(void *ptr, off_t filesize,
665 				     uint32_t loadaddr)
666 {
667 	struct gen_device_header *hdr = (struct gen_device_header *)ptr;
668 	struct gfh_header *gfh;
669 	const char *bootname = NULL;
670 
671 	if (hdr_media == BRLYT_TYPE_NOR)
672 		bootname = SF_BOOT_NAME;
673 	else if (hdr_media == BRLYT_TYPE_EMMC)
674 		bootname = EMMC_BOOT_NAME;
675 	else if (hdr_media == BRLYT_TYPE_SDMMC)
676 		bootname = SDMMC_BOOT_NAME;
677 
678 	/* Generic device header */
679 	snprintf(hdr->boot.name, sizeof(hdr->boot.name), "%s", bootname);
680 	hdr->boot.version = cpu_to_le32(1);
681 	hdr->boot.size = cpu_to_le32(sizeof(hdr->boot));
682 
683 	/* BRLYT header */
684 	put_brom_layout_header(&hdr->brlyt, hdr_media);
685 	hdr->brlyt.header_size = cpu_to_le32(sizeof(struct gen_device_header));
686 	hdr->brlyt.total_size = cpu_to_le32(filesize);
687 	hdr->brlyt.header_size_2 = hdr->brlyt.header_size;
688 	hdr->brlyt.total_size_2 = hdr->brlyt.total_size;
689 
690 	/* GFH header */
691 	gfh = (struct gfh_header *)(ptr + sizeof(struct gen_device_header));
692 	put_ghf_header(gfh, filesize, sizeof(struct gen_device_header),
693 		       loadaddr, GFH_FLASH_TYPE_GEN);
694 
695 	/* Generate SHA256 hash */
696 	put_hash((uint8_t *)gfh,
697 		 filesize - sizeof(struct gen_device_header) - SHA256_SUM_LEN);
698 }
699 
mtk_image_set_nand_header(void * ptr,off_t filesize,uint32_t loadaddr)700 static void mtk_image_set_nand_header(void *ptr, off_t filesize,
701 				      uint32_t loadaddr)
702 {
703 	union nand_boot_header *nh = (union nand_boot_header *)ptr;
704 	struct brom_layout_header *brlyt;
705 	struct gfh_header *gfh;
706 	uint32_t payload_pages;
707 	int i;
708 
709 	/* NAND device header, repeat 4 times */
710 	for (i = 0; i < 4; i++)
711 		memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
712 
713 	/* BRLYT header */
714 	payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) /
715 			le16_to_cpu(hdr_nand->pagesize);
716 	brlyt = (struct brom_layout_header *)
717 		(ptr + le16_to_cpu(hdr_nand->pagesize));
718 	put_brom_layout_header(brlyt, hdr_media);
719 	brlyt->header_size = cpu_to_le32(2);
720 	brlyt->total_size = cpu_to_le32(payload_pages);
721 	brlyt->header_size_2 = brlyt->header_size;
722 	brlyt->total_size_2 = brlyt->total_size;
723 	brlyt->unused = cpu_to_le32(1);
724 
725 	/* GFH header */
726 	gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize));
727 	put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize),
728 		       loadaddr, GFH_FLASH_TYPE_NAND);
729 
730 	/* Generate SHA256 hash */
731 	put_hash((uint8_t *)gfh,
732 		 filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
733 }
734 
mtk_image_set_header(void * ptr,struct stat * sbuf,int ifd,struct image_tool_params * params)735 static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
736 				 struct image_tool_params *params)
737 {
738 	union lk_hdr *lk = (union lk_hdr *)ptr;
739 
740 	if (use_lk_hdr) {
741 		lk->magic = cpu_to_le32(LK_PART_MAGIC);
742 		lk->size = cpu_to_le32(sbuf->st_size - sizeof(union lk_hdr));
743 		lk->loadaddr = cpu_to_le32(params->addr);
744 		lk->mode = 0xffffffff; /* must be non-zero */
745 		memset(lk->name, 0, sizeof(lk->name));
746 		strncpy(lk->name, lk_name, sizeof(lk->name));
747 		return;
748 	}
749 
750 	if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
751 		mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr);
752 	else
753 		mtk_image_set_gen_header(ptr, sbuf->st_size, params->addr);
754 }
755 
756 U_BOOT_IMAGE_TYPE(
757 	mtk_image,
758 	"MediaTek BootROM Loadable Image support",
759 	0,
760 	NULL,
761 	mtk_image_check_params,
762 	mtk_image_verify_header,
763 	mtk_image_print_header,
764 	mtk_image_set_header,
765 	NULL,
766 	mtk_image_check_image_types,
767 	NULL,
768 	mtk_image_vrec_header
769 );
770