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