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 /* Indicates whether we're generating or verifying */
247 static bool img_gen;
248 static uint32_t img_size;
249 
250 /* Image type selected by user */
251 static enum brlyt_img_type hdr_media;
252 static uint32_t hdr_offset;
253 static int use_lk_hdr;
254 static bool is_arm64_image;
255 
256 /* LK image name */
257 static char lk_name[32] = "U-Boot";
258 
259 /* NAND header selected by user */
260 static const union nand_boot_header *hdr_nand;
261 
262 /* GFH header + 2 * 4KB pages of NAND */
263 static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
264 
mtk_image_check_image_types(uint8_t type)265 static int mtk_image_check_image_types(uint8_t type)
266 {
267 	if (type == IH_TYPE_MTKIMAGE)
268 		return EXIT_SUCCESS;
269 	else
270 		return EXIT_FAILURE;
271 }
272 
mtk_brom_parse_imagename(const char * imagename)273 static int mtk_brom_parse_imagename(const char *imagename)
274 {
275 #define is_blank_char(c) \
276 	((c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == ' ')
277 
278 	char *buf = strdup(imagename), *key, *val, *end, *next;
279 	int i;
280 
281 	/* User passed arguments from image name */
282 	static const char *media = "";
283 	static const char *hdr_offs = "";
284 	static const char *nandinfo = "";
285 	static const char *lk = "";
286 	static const char *arm64_param = "";
287 
288 	key = buf;
289 	while (key) {
290 		next = strchr(key, ';');
291 		if (next)
292 			*next = 0;
293 
294 		val = strchr(key, '=');
295 		if (val) {
296 			*val++ = 0;
297 
298 			/* Trim key */
299 			while (is_blank_char(*key))
300 				key++;
301 
302 			end = key + strlen(key) - 1;
303 			while ((end >= key) && is_blank_char(*end))
304 				end--;
305 			end++;
306 
307 			if (is_blank_char(*end))
308 				*end = 0;
309 
310 			/* Trim value */
311 			while (is_blank_char(*val))
312 				val++;
313 
314 			end = val + strlen(val) - 1;
315 			while ((end >= val) && is_blank_char(*end))
316 				end--;
317 			end++;
318 
319 			if (is_blank_char(*end))
320 				*end = 0;
321 
322 			/* record user passed arguments */
323 			if (!strcmp(key, "media"))
324 				media = val;
325 
326 			if (!strcmp(key, "hdroffset"))
327 				hdr_offs = val;
328 
329 			if (!strcmp(key, "nandinfo"))
330 				nandinfo = val;
331 
332 			if (!strcmp(key, "lk"))
333 				lk = val;
334 
335 			if (!strcmp(key, "lkname"))
336 				snprintf(lk_name, sizeof(lk_name), "%s", val);
337 
338 			if (!strcmp(key, "arm64"))
339 				arm64_param = val;
340 		}
341 
342 		if (next)
343 			key = next + 1;
344 		else
345 			break;
346 	}
347 
348 	/* if user specified LK image header, skip following checks */
349 	if (lk && lk[0] == '1') {
350 		use_lk_hdr = 1;
351 		free(buf);
352 		return 0;
353 	}
354 
355 	/* parse media type */
356 	for (i = 0; i < ARRAY_SIZE(brom_images); i++) {
357 		if (!strcmp(brom_images[i].name, media)) {
358 			hdr_media = brom_images[i].type;
359 			break;
360 		}
361 	}
362 
363 	/* parse nand header type */
364 	for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
365 		if (!strcmp(nand_headers[i].name, nandinfo)) {
366 			hdr_nand = nand_headers[i].data;
367 			break;
368 		}
369 	}
370 
371 	/* parse device header offset */
372 	if (hdr_offs && hdr_offs[0])
373 		hdr_offset = strtoul(hdr_offs, NULL, 0);
374 
375 	if (arm64_param && arm64_param[0] == '1')
376 		is_arm64_image = true;
377 
378 	free(buf);
379 
380 	if (hdr_media == BRLYT_TYPE_INVALID) {
381 		fprintf(stderr, "Error: media type is invalid or missing.\n");
382 		fprintf(stderr, "       Please specify -n \"media=<type>\"\n");
383 		return -EINVAL;
384 	}
385 
386 	if ((hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) &&
387 	    !hdr_nand) {
388 		fprintf(stderr, "Error: nand info is invalid or missing.\n");
389 		fprintf(stderr, "       Please specify -n \"media=%s;"
390 				"nandinfo=<info>\"\n", media);
391 		return -EINVAL;
392 	}
393 
394 	return 0;
395 }
396 
mtk_image_check_params(struct image_tool_params * params)397 static int mtk_image_check_params(struct image_tool_params *params)
398 {
399 	if (!params->addr) {
400 		fprintf(stderr, "Error: Load Address must be set.\n");
401 		return -EINVAL;
402 	}
403 
404 	if (!params->imagename) {
405 		fprintf(stderr, "Error: Image Name must be set.\n");
406 		return -EINVAL;
407 	}
408 
409 	return mtk_brom_parse_imagename(params->imagename);
410 }
411 
mtk_image_vrec_header(struct image_tool_params * params,struct image_type_params * tparams)412 static int mtk_image_vrec_header(struct image_tool_params *params,
413 				 struct image_type_params *tparams)
414 {
415 	if (use_lk_hdr) {
416 		tparams->header_size = sizeof(union lk_hdr);
417 		tparams->hdr = &hdr_tmp;
418 		memset(&hdr_tmp, 0xff, tparams->header_size);
419 		return 0;
420 	}
421 
422 	if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
423 		tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
424 	else
425 		tparams->header_size = sizeof(struct gen_device_header);
426 
427 	tparams->header_size += sizeof(struct gfh_header);
428 	tparams->hdr = &hdr_tmp;
429 
430 	memset(&hdr_tmp, 0xff, tparams->header_size);
431 
432 	return SHA256_SUM_LEN;
433 }
434 
mtk_image_verify_gen_header(const uint8_t * ptr,int print)435 static int mtk_image_verify_gen_header(const uint8_t *ptr, int print)
436 {
437 	union gen_boot_header *gbh = (union gen_boot_header *)ptr;
438 	uint32_t gfh_offset, total_size, devh_size;
439 	struct brom_layout_header *bh;
440 	struct gfh_header *gfh;
441 	const char *bootmedia;
442 
443 	if (!strcmp(gbh->name, SF_BOOT_NAME))
444 		bootmedia = "Serial NOR";
445 	else if (!strcmp(gbh->name, EMMC_BOOT_NAME))
446 		bootmedia = "eMMC";
447 	else if (!strcmp(gbh->name, SDMMC_BOOT_NAME))
448 		bootmedia = "SD/MMC";
449 	else
450 		return -1;
451 
452 	if (print)
453 		printf("Boot Media:   %s\n", bootmedia);
454 
455 	if (le32_to_cpu(gbh->version) != 1 ||
456 	    le32_to_cpu(gbh->size) != sizeof(union gen_boot_header))
457 		return -1;
458 
459 	bh = (struct brom_layout_header *)(ptr + le32_to_cpu(gbh->size));
460 
461 	if (strcmp(bh->name, BRLYT_NAME))
462 		return -1;
463 
464 	if (le32_to_cpu(bh->magic) != BRLYT_MAGIC ||
465 	    (le32_to_cpu(bh->type) != BRLYT_TYPE_NOR &&
466 	    le32_to_cpu(bh->type) != BRLYT_TYPE_EMMC &&
467 	    le32_to_cpu(bh->type) != BRLYT_TYPE_SDMMC))
468 		return -1;
469 
470 	devh_size = sizeof(struct gen_device_header);
471 
472 	if (img_gen) {
473 		gfh_offset = devh_size;
474 	} else {
475 		gfh_offset = le32_to_cpu(bh->header_size);
476 
477 		if (gfh_offset + sizeof(struct gfh_header) > img_size) {
478 			/*
479 			 * This may happen if the hdr_offset used to generate
480 			 * this image is not zero.
481 			 * Since device header size is not fixed, we can't
482 			 * cover all possible cases.
483 			 * Assuming the image is valid only if the real
484 			 * device header size equals to devh_size.
485 			 */
486 			total_size = le32_to_cpu(bh->total_size);
487 
488 			if (total_size - gfh_offset > img_size - devh_size)
489 				return -1;
490 
491 			gfh_offset = devh_size;
492 		}
493 	}
494 
495 	gfh = (struct gfh_header *)(ptr + gfh_offset);
496 
497 	if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
498 		return -1;
499 
500 	if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN)
501 		return -1;
502 
503 	if (print)
504 		printf("Load Address: %08x\n",
505 		       le32_to_cpu(gfh->file_info.load_addr) +
506 		       le32_to_cpu(gfh->file_info.jump_offset));
507 
508 	if (print)
509 		printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
510 
511 	return 0;
512 }
513 
mtk_image_verify_nand_header(const uint8_t * ptr,int print)514 static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
515 {
516 	union nand_boot_header *nh = (union nand_boot_header *)ptr;
517 	struct brom_layout_header *bh;
518 	struct gfh_header *gfh;
519 	const char *bootmedia;
520 
521 	if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
522 	    strcmp(nh->id, NAND_BOOT_ID))
523 		return -1;
524 
525 	bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize));
526 
527 	if (strcmp(bh->name, BRLYT_NAME))
528 		return -1;
529 
530 	if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) {
531 		return -1;
532 	} else {
533 		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
534 			bootmedia = "Parallel NAND";
535 		else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
536 			bootmedia = "Serial NAND";
537 		else
538 			return -1;
539 	}
540 
541 	if (print) {
542 		printf("Boot Media: %s\n", bootmedia);
543 
544 		if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
545 			uint64_t capacity =
546 				(uint64_t)le16_to_cpu(nh->numblocks) *
547 				(uint64_t)le16_to_cpu(nh->pages_of_block) *
548 				(uint64_t)le16_to_cpu(nh->pagesize) * 8;
549 			printf("Capacity:     %dGb\n",
550 			       (uint32_t)(capacity >> 30));
551 		}
552 
553 		if (le16_to_cpu(nh->pagesize) >= 1024)
554 			printf("Page Size:    %dKB\n",
555 			       le16_to_cpu(nh->pagesize) >> 10);
556 		else
557 			printf("Page Size:    %dB\n",
558 			       le16_to_cpu(nh->pagesize));
559 
560 		printf("Spare Size:   %dB\n", le16_to_cpu(nh->oobsize));
561 	}
562 
563 	gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
564 
565 	if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
566 		return -1;
567 
568 	if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND)
569 		return -1;
570 
571 	if (print)
572 		printf("Load Address: %08x\n",
573 		       le32_to_cpu(gfh->file_info.load_addr) +
574 		       le32_to_cpu(gfh->file_info.jump_offset));
575 
576 	if (print)
577 		printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
578 
579 	return 0;
580 }
581 
mtk_image_verify_header(unsigned char * ptr,int image_size,struct image_tool_params * params)582 static int mtk_image_verify_header(unsigned char *ptr, int image_size,
583 				   struct image_tool_params *params)
584 {
585 	union lk_hdr *lk = (union lk_hdr *)ptr;
586 
587 	/* nothing to verify for LK image header */
588 	if (le32_to_cpu(lk->magic) == LK_PART_MAGIC)
589 		return 0;
590 
591 	img_size = image_size;
592 
593 	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
594 		return mtk_image_verify_nand_header(ptr, 0);
595 	else
596 		return mtk_image_verify_gen_header(ptr, 0);
597 
598 	return -1;
599 }
600 
mtk_image_print_header(const void * ptr)601 static void mtk_image_print_header(const void *ptr)
602 {
603 	union lk_hdr *lk = (union lk_hdr *)ptr;
604 
605 	if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) {
606 		printf("Image Type:   MediaTek LK Image\n");
607 		printf("Load Address: %08x\n", le32_to_cpu(lk->loadaddr));
608 		return;
609 	}
610 
611 	printf("Image Type:   MediaTek BootROM Loadable Image\n");
612 
613 	if (!strcmp((char *)ptr, NAND_BOOT_NAME))
614 		mtk_image_verify_nand_header(ptr, 1);
615 	else
616 		mtk_image_verify_gen_header(ptr, 1);
617 }
618 
put_brom_layout_header(struct brom_layout_header * hdr,int type)619 static void put_brom_layout_header(struct brom_layout_header *hdr, int type)
620 {
621 	strncpy(hdr->name, BRLYT_NAME, sizeof(hdr->name));
622 	hdr->version = cpu_to_le32(1);
623 	hdr->magic = cpu_to_le32(BRLYT_MAGIC);
624 	hdr->type = cpu_to_le32(type);
625 }
626 
put_ghf_common_header(struct gfh_common_header * gfh,int size,int type,int ver)627 static void put_ghf_common_header(struct gfh_common_header *gfh, int size,
628 				  int type, int ver)
629 {
630 	memcpy(gfh->magic, GFH_HEADER_MAGIC, sizeof(gfh->magic));
631 	gfh->version = ver;
632 	gfh->size = cpu_to_le16(size);
633 	gfh->type = cpu_to_le16(type);
634 }
635 
put_ghf_header(struct gfh_header * gfh,int file_size,int dev_hdr_size,int load_addr,int flash_type)636 static void put_ghf_header(struct gfh_header *gfh, int file_size,
637 			   int dev_hdr_size, int load_addr, int flash_type)
638 {
639 	uint32_t cfg_bits;
640 
641 	memset(gfh, 0, sizeof(struct gfh_header));
642 
643 	/* GFH_FILE_INFO header */
644 	put_ghf_common_header(&gfh->file_info.gfh, sizeof(gfh->file_info),
645 			      GFH_TYPE_FILE_INFO, 1);
646 	strncpy(gfh->file_info.name, GFH_FILE_INFO_NAME,
647 		sizeof(gfh->file_info.name));
648 	gfh->file_info.unused = cpu_to_le32(1);
649 	gfh->file_info.file_type = cpu_to_le16(1);
650 	gfh->file_info.flash_type = flash_type;
651 	gfh->file_info.sig_type = GFH_SIG_TYPE_SHA256;
652 	gfh->file_info.load_addr = cpu_to_le32(load_addr - sizeof(*gfh));
653 	gfh->file_info.total_size = cpu_to_le32(file_size - dev_hdr_size);
654 	gfh->file_info.max_size = cpu_to_le32(file_size);
655 	gfh->file_info.hdr_size = sizeof(*gfh);
656 	gfh->file_info.sig_size = SHA256_SUM_LEN;
657 	gfh->file_info.jump_offset = sizeof(*gfh);
658 	gfh->file_info.processed = cpu_to_le32(1);
659 
660 	/* GFH_BL_INFO header */
661 	put_ghf_common_header(&gfh->bl_info.gfh, sizeof(gfh->bl_info),
662 			      GFH_TYPE_BL_INFO, 1);
663 	gfh->bl_info.attr = cpu_to_le32(1);
664 
665 	/* GFH_BROM_CFG header */
666 	put_ghf_common_header(&gfh->brom_cfg.gfh, sizeof(gfh->brom_cfg),
667 			      GFH_TYPE_BROM_CFG, 3);
668 	cfg_bits = GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS |
669 		   GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN |
670 		   GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN;
671 	gfh->brom_cfg.usbdl_by_kcol0_timeout_ms = cpu_to_le32(5000);
672 	if (is_arm64_image) {
673 		gfh->brom_cfg.jump_bl_arm64 = GFH_BROM_CFG_JUMP_BL_ARM64;
674 		cfg_bits |= GFH_BROM_CFG_JUMP_BL_ARM64_EN;
675 	}
676 	gfh->brom_cfg.cfg_bits = cpu_to_le32(cfg_bits);
677 
678 	/* GFH_BL_SEC_KEY header */
679 	put_ghf_common_header(&gfh->bl_sec_key.gfh, sizeof(gfh->bl_sec_key),
680 			      GFH_TYPE_BL_SEC_KEY, 1);
681 
682 	/* GFH_ANTI_CLONE header */
683 	put_ghf_common_header(&gfh->anti_clone.gfh, sizeof(gfh->anti_clone),
684 			      GFH_TYPE_ANTI_CLONE, 1);
685 	gfh->anti_clone.ac_offset = cpu_to_le32(0x10);
686 	gfh->anti_clone.ac_len = cpu_to_le32(0x80);
687 
688 	/* GFH_BROM_SEC_CFG header */
689 	put_ghf_common_header(&gfh->brom_sec_cfg.gfh,
690 			      sizeof(gfh->brom_sec_cfg),
691 			      GFH_TYPE_BROM_SEC_CFG, 1);
692 	gfh->brom_sec_cfg.cfg_bits =
693 		cpu_to_le32(BROM_SEC_CFG_JTAG_EN | BROM_SEC_CFG_UART_EN);
694 }
695 
put_hash(uint8_t * buff,int size)696 static void put_hash(uint8_t *buff, int size)
697 {
698 	sha256_context ctx;
699 
700 	sha256_starts(&ctx);
701 	sha256_update(&ctx, buff, size);
702 	sha256_finish(&ctx, buff + size);
703 }
704 
mtk_image_set_gen_header(void * ptr,off_t filesize,uint32_t loadaddr)705 static void mtk_image_set_gen_header(void *ptr, off_t filesize,
706 				     uint32_t loadaddr)
707 {
708 	struct gen_device_header *hdr = (struct gen_device_header *)ptr;
709 	struct gfh_header *gfh;
710 	const char *bootname = NULL;
711 
712 	if (hdr_media == BRLYT_TYPE_NOR)
713 		bootname = SF_BOOT_NAME;
714 	else if (hdr_media == BRLYT_TYPE_EMMC)
715 		bootname = EMMC_BOOT_NAME;
716 	else if (hdr_media == BRLYT_TYPE_SDMMC)
717 		bootname = SDMMC_BOOT_NAME;
718 
719 	/* Generic device header */
720 	snprintf(hdr->boot.name, sizeof(hdr->boot.name), "%s", bootname);
721 	hdr->boot.version = cpu_to_le32(1);
722 	hdr->boot.size = cpu_to_le32(sizeof(hdr->boot));
723 
724 	/* BRLYT header */
725 	put_brom_layout_header(&hdr->brlyt, hdr_media);
726 	hdr->brlyt.header_size = cpu_to_le32(hdr_offset + sizeof(*hdr));
727 	hdr->brlyt.total_size = cpu_to_le32(hdr_offset + filesize);
728 	hdr->brlyt.header_size_2 = hdr->brlyt.header_size;
729 	hdr->brlyt.total_size_2 = hdr->brlyt.total_size;
730 
731 	/* GFH header */
732 	gfh = (struct gfh_header *)(ptr + sizeof(struct gen_device_header));
733 	put_ghf_header(gfh, filesize, sizeof(struct gen_device_header),
734 		       loadaddr, GFH_FLASH_TYPE_GEN);
735 
736 	/* Generate SHA256 hash */
737 	put_hash((uint8_t *)gfh,
738 		 filesize - sizeof(struct gen_device_header) - SHA256_SUM_LEN);
739 }
740 
mtk_image_set_nand_header(void * ptr,off_t filesize,uint32_t loadaddr)741 static void mtk_image_set_nand_header(void *ptr, off_t filesize,
742 				      uint32_t loadaddr)
743 {
744 	union nand_boot_header *nh = (union nand_boot_header *)ptr;
745 	struct brom_layout_header *brlyt;
746 	struct gfh_header *gfh;
747 	uint32_t payload_pages;
748 	int i;
749 
750 	/* NAND device header, repeat 4 times */
751 	for (i = 0; i < 4; i++)
752 		memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
753 
754 	/* BRLYT header */
755 	payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) /
756 			le16_to_cpu(hdr_nand->pagesize);
757 	brlyt = (struct brom_layout_header *)
758 		(ptr + le16_to_cpu(hdr_nand->pagesize));
759 	put_brom_layout_header(brlyt, hdr_media);
760 	brlyt->header_size = cpu_to_le32(2);
761 	brlyt->total_size = cpu_to_le32(payload_pages);
762 	brlyt->header_size_2 = brlyt->header_size;
763 	brlyt->total_size_2 = brlyt->total_size;
764 	brlyt->unused = cpu_to_le32(1);
765 
766 	/* GFH header */
767 	gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize));
768 	put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize),
769 		       loadaddr, GFH_FLASH_TYPE_NAND);
770 
771 	/* Generate SHA256 hash */
772 	put_hash((uint8_t *)gfh,
773 		 filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
774 }
775 
mtk_image_set_header(void * ptr,struct stat * sbuf,int ifd,struct image_tool_params * params)776 static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
777 				 struct image_tool_params *params)
778 {
779 	union lk_hdr *lk = (union lk_hdr *)ptr;
780 
781 	if (use_lk_hdr) {
782 		lk->magic = cpu_to_le32(LK_PART_MAGIC);
783 		lk->size = cpu_to_le32(sbuf->st_size - sizeof(union lk_hdr));
784 		lk->loadaddr = cpu_to_le32(params->addr);
785 		lk->mode = 0xffffffff; /* must be non-zero */
786 		memset(lk->name, 0, sizeof(lk->name));
787 		strncpy(lk->name, lk_name, sizeof(lk->name));
788 		return;
789 	}
790 
791 	img_gen = true;
792 	img_size = sbuf->st_size;
793 
794 	if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
795 		mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr);
796 	else
797 		mtk_image_set_gen_header(ptr, sbuf->st_size, params->addr);
798 }
799 
800 U_BOOT_IMAGE_TYPE(
801 	mtk_image,
802 	"MediaTek BootROM Loadable Image support",
803 	0,
804 	NULL,
805 	mtk_image_check_params,
806 	mtk_image_verify_header,
807 	mtk_image_print_header,
808 	mtk_image_set_header,
809 	NULL,
810 	mtk_image_check_image_types,
811 	NULL,
812 	mtk_image_vrec_header
813 );
814