Drop genboardscfg.py
[platform/kernel/u-boot.git] / tools / mtk_image.c
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 <time.h>
10 #include <image.h>
11 #include <u-boot/crc.h>
12 #include <u-boot/sha256.h>
13 #include "imagetool.h"
14 #include "mtk_image.h"
15
16 /* NAND header for SPI-NAND with 2KB page + 64B spare */
17 static const union nand_boot_header snand_hdr_2k_64_data = {
18         .data = {
19                 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
20                 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
21                 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
22                 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
23                 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 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, 0x00, 0x00, 0x00, 0x00,
30                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31                 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
32                 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
33                 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
34                 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
35         }
36 };
37
38 /* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
39 static const union nand_boot_header snand_hdr_2k_128_data = {
40         .data = {
41                 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
42                 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
43                 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
44                 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
45                 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 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, 0x00, 0x00, 0x00, 0x00,
52                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53                 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
54                 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
55                 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
56                 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
57         }
58 };
59
60 /* NAND header for SPI-NAND with 4KB page + 256B spare */
61 static const union nand_boot_header snand_hdr_4k_256_data = {
62         .data = {
63                 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
64                 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
65                 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
66                 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
67                 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 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, 0x00, 0x00, 0x00, 0x00,
74                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75                 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
76                 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
77                 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
78                 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
79         }
80 };
81
82 /* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
83 static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
84         .data = {
85                 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
86                 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
87                 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
88                 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
89                 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 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, 0x00, 0x00, 0x00, 0x00,
96                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97                 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
98                 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
99                 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
100                 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
101         }
102 };
103
104 /* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
105 static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
106         .data = {
107                 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
108                 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
109                 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
110                 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
111                 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 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, 0x00, 0x00, 0x00, 0x00,
118                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119                 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
120                 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
121                 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
122                 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
123         }
124 };
125
126 /* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
127 static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
128         .data = {
129                 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
130                 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
131                 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
132                 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
133                 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 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, 0x00, 0x00, 0x00, 0x00,
140                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141                 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
142                 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
143                 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
144                 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
145         }
146 };
147
148 /* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
149 static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
150         .data = {
151                 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
152                 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
153                 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
154                 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
155                 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 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, 0x00, 0x00, 0x00, 0x00,
162                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163                 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
164                 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
165                 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
166                 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
167         }
168 };
169
170 /* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
171 static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
172         .data = {
173                 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
174                 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
175                 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
176                 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
177                 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 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, 0x00, 0x00, 0x00, 0x00,
184                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185                 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
186                 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
187                 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
188                 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
189         }
190 };
191
192 static const struct nand_header_type {
193         const char *name;
194         const union nand_boot_header *data;
195 } nand_headers[] = {
196         {
197                 .name = "2k+64",
198                 .data = &snand_hdr_2k_64_data
199         }, {
200                 .name = "2k+120",
201                 .data = &snand_hdr_2k_128_data
202         }, {
203                 .name = "2k+128",
204                 .data = &snand_hdr_2k_128_data
205         }, {
206                 .name = "4k+256",
207                 .data = &snand_hdr_4k_256_data
208         }, {
209                 .name = "1g:2k+64",
210                 .data = &nand_hdr_1gb_2k_64_data
211         }, {
212                 .name = "2g:2k+64",
213                 .data = &nand_hdr_2gb_2k_64_data
214         }, {
215                 .name = "4g:2k+64",
216                 .data = &nand_hdr_4gb_2k_64_data
217         }, {
218                 .name = "2g:2k+128",
219                 .data = &nand_hdr_2gb_2k_128_data
220         }, {
221                 .name = "4g:2k+128",
222                 .data = &nand_hdr_4gb_2k_128_data
223         }
224 };
225
226 static const struct brom_img_type {
227         const char *name;
228         enum brlyt_img_type type;
229 } brom_images[] = {
230         {
231                 .name = "nand",
232                 .type = BRLYT_TYPE_NAND
233         }, {
234                 .name = "emmc",
235                 .type = BRLYT_TYPE_EMMC
236         }, {
237                 .name = "nor",
238                 .type = BRLYT_TYPE_NOR
239         }, {
240                 .name = "sdmmc",
241                 .type = BRLYT_TYPE_SDMMC
242         }, {
243                 .name = "snand",
244                 .type = BRLYT_TYPE_SNAND
245         }
246 };
247
248 /* Indicates whether we're generating or verifying */
249 static bool img_gen;
250 static uint32_t img_size;
251
252 /* Image type selected by user */
253 static enum brlyt_img_type hdr_media;
254 static uint32_t hdr_offset;
255 static int use_lk_hdr;
256 static int use_mt7621_hdr;
257 static bool is_arm64_image;
258
259 /* LK image name */
260 static char lk_name[32] = "U-Boot";
261
262 /* CRC32 normal table required by MT7621 image */
263 static uint32_t crc32tbl[256];
264
265 /* NAND header selected by user */
266 static const union nand_boot_header *hdr_nand;
267
268 /* GFH header + 2 * 4KB pages of NAND */
269 static char hdr_tmp[sizeof(struct gfh_header) + 0x2000];
270
271 static uint32_t crc32_normal_cal(uint32_t crc, const void *data, size_t length,
272                                  const uint32_t *crc32c_table)
273 {
274         const uint8_t *p = data;
275
276         while (length--)
277                 crc = crc32c_table[(uint8_t)((crc >> 24) ^ *p++)] ^ (crc << 8);
278
279         return crc;
280 }
281
282 static void crc32_normal_init(uint32_t *crc32c_table, uint32_t poly)
283 {
284         uint32_t v, i, j;
285
286         for (i = 0; i < 256; i++) {
287                 v = i << 24;
288                 for (j = 0; j < 8; j++)
289                         v = (v << 1) ^ ((v & (1 << 31)) ? poly : 0);
290
291                 crc32c_table[i] = v;
292         }
293 }
294
295 static int mtk_image_check_image_types(uint8_t type)
296 {
297         if (type == IH_TYPE_MTKIMAGE)
298                 return EXIT_SUCCESS;
299         else
300                 return EXIT_FAILURE;
301 }
302
303 static int mtk_brom_parse_imagename(const char *imagename)
304 {
305 #define is_blank_char(c) \
306         ((c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == ' ')
307
308         char *buf = strdup(imagename), *key, *val, *end, *next;
309         int i;
310
311         /* User passed arguments from image name */
312         static const char *media = "";
313         static const char *hdr_offs = "";
314         static const char *nandinfo = "";
315         static const char *lk = "";
316         static const char *mt7621 = "";
317         static const char *arm64_param = "";
318
319         key = buf;
320         while (key) {
321                 next = strchr(key, ';');
322                 if (next)
323                         *next = 0;
324
325                 val = strchr(key, '=');
326                 if (val) {
327                         *val++ = 0;
328
329                         /* Trim key */
330                         while (is_blank_char(*key))
331                                 key++;
332
333                         end = key + strlen(key) - 1;
334                         while ((end >= key) && is_blank_char(*end))
335                                 end--;
336                         end++;
337
338                         if (is_blank_char(*end))
339                                 *end = 0;
340
341                         /* Trim value */
342                         while (is_blank_char(*val))
343                                 val++;
344
345                         end = val + strlen(val) - 1;
346                         while ((end >= val) && is_blank_char(*end))
347                                 end--;
348                         end++;
349
350                         if (is_blank_char(*end))
351                                 *end = 0;
352
353                         /* record user passed arguments */
354                         if (!strcmp(key, "media"))
355                                 media = val;
356
357                         if (!strcmp(key, "hdroffset"))
358                                 hdr_offs = val;
359
360                         if (!strcmp(key, "nandinfo"))
361                                 nandinfo = val;
362
363                         if (!strcmp(key, "lk"))
364                                 lk = val;
365
366                         if (!strcmp(key, "mt7621"))
367                                 mt7621 = val;
368
369                         if (!strcmp(key, "lkname"))
370                                 snprintf(lk_name, sizeof(lk_name), "%s", val);
371
372                         if (!strcmp(key, "arm64"))
373                                 arm64_param = val;
374                 }
375
376                 if (next)
377                         key = next + 1;
378                 else
379                         break;
380         }
381
382         /* if user specified LK image header, skip following checks */
383         if (lk && lk[0] == '1') {
384                 use_lk_hdr = 1;
385                 free(buf);
386                 return 0;
387         }
388
389         /* if user specified MT7621 image header, skip following checks */
390         if (mt7621 && mt7621[0] == '1') {
391                 use_mt7621_hdr = 1;
392                 free(buf);
393                 return 0;
394         }
395
396         /* parse media type */
397         for (i = 0; i < ARRAY_SIZE(brom_images); i++) {
398                 if (!strcmp(brom_images[i].name, media)) {
399                         hdr_media = brom_images[i].type;
400                         break;
401                 }
402         }
403
404         /* parse nand header type */
405         for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
406                 if (!strcmp(nand_headers[i].name, nandinfo)) {
407                         hdr_nand = nand_headers[i].data;
408                         break;
409                 }
410         }
411
412         /* parse device header offset */
413         if (hdr_offs && hdr_offs[0])
414                 hdr_offset = strtoul(hdr_offs, NULL, 0);
415
416         if (arm64_param && arm64_param[0] == '1')
417                 is_arm64_image = true;
418
419         free(buf);
420
421         if (hdr_media == BRLYT_TYPE_INVALID) {
422                 fprintf(stderr, "Error: media type is invalid or missing.\n");
423                 fprintf(stderr, "       Please specify -n \"media=<type>\"\n");
424                 return -EINVAL;
425         }
426
427         if ((hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) &&
428             !hdr_nand) {
429                 fprintf(stderr, "Error: nand info is invalid or missing.\n");
430                 fprintf(stderr, "       Please specify -n \"media=%s;"
431                                 "nandinfo=<info>\"\n", media);
432                 return -EINVAL;
433         }
434
435         return 0;
436 }
437
438 static int mtk_image_check_params(struct image_tool_params *params)
439 {
440         if (!params->addr) {
441                 fprintf(stderr, "Error: Load Address must be set.\n");
442                 return -EINVAL;
443         }
444
445         if (!params->imagename) {
446                 fprintf(stderr, "Error: Image Name must be set.\n");
447                 return -EINVAL;
448         }
449
450         return mtk_brom_parse_imagename(params->imagename);
451 }
452
453 static int mtk_image_vrec_header(struct image_tool_params *params,
454                                  struct image_type_params *tparams)
455 {
456         if (use_lk_hdr) {
457                 tparams->header_size = sizeof(union lk_hdr);
458                 tparams->hdr = &hdr_tmp;
459                 memset(&hdr_tmp, 0xff, tparams->header_size);
460                 return 0;
461         }
462
463         if (use_mt7621_hdr) {
464                 tparams->header_size = image_get_header_size();
465                 tparams->hdr = &hdr_tmp;
466                 memset(&hdr_tmp, 0, tparams->header_size);
467                 return 0;
468         }
469
470         if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
471                 tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize);
472         else
473                 tparams->header_size = sizeof(struct gen_device_header);
474
475         tparams->header_size += sizeof(struct gfh_header);
476         tparams->hdr = &hdr_tmp;
477
478         memset(&hdr_tmp, 0xff, tparams->header_size);
479
480         return SHA256_SUM_LEN;
481 }
482
483 static int mtk_image_verify_gen_header(const uint8_t *ptr, int print)
484 {
485         union gen_boot_header *gbh = (union gen_boot_header *)ptr;
486         uint32_t gfh_offset, total_size, devh_size;
487         struct brom_layout_header *bh;
488         struct gfh_header *gfh;
489         const char *bootmedia;
490
491         if (!strcmp(gbh->name, SF_BOOT_NAME))
492                 bootmedia = "Serial NOR";
493         else if (!strcmp(gbh->name, EMMC_BOOT_NAME))
494                 bootmedia = "eMMC";
495         else if (!strcmp(gbh->name, SDMMC_BOOT_NAME))
496                 bootmedia = "SD/MMC";
497         else
498                 return -1;
499
500         if (print)
501                 printf("Boot Media:   %s\n", bootmedia);
502
503         if (le32_to_cpu(gbh->version) != 1 ||
504             le32_to_cpu(gbh->size) != sizeof(union gen_boot_header))
505                 return -1;
506
507         bh = (struct brom_layout_header *)(ptr + le32_to_cpu(gbh->size));
508
509         if (strcmp(bh->name, BRLYT_NAME))
510                 return -1;
511
512         if (le32_to_cpu(bh->magic) != BRLYT_MAGIC ||
513             (le32_to_cpu(bh->type) != BRLYT_TYPE_NOR &&
514             le32_to_cpu(bh->type) != BRLYT_TYPE_EMMC &&
515             le32_to_cpu(bh->type) != BRLYT_TYPE_SDMMC))
516                 return -1;
517
518         devh_size = sizeof(struct gen_device_header);
519
520         if (img_gen) {
521                 gfh_offset = devh_size;
522         } else {
523                 gfh_offset = le32_to_cpu(bh->header_size);
524
525                 if (gfh_offset + sizeof(struct gfh_header) > img_size) {
526                         /*
527                          * This may happen if the hdr_offset used to generate
528                          * this image is not zero.
529                          * Since device header size is not fixed, we can't
530                          * cover all possible cases.
531                          * Assuming the image is valid only if the real
532                          * device header size equals to devh_size.
533                          */
534                         total_size = le32_to_cpu(bh->total_size);
535
536                         if (total_size - gfh_offset > img_size - devh_size)
537                                 return -1;
538
539                         gfh_offset = devh_size;
540                 }
541         }
542
543         gfh = (struct gfh_header *)(ptr + gfh_offset);
544
545         if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
546                 return -1;
547
548         if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN)
549                 return -1;
550
551         if (print)
552                 printf("Load Address: %08x\n",
553                        le32_to_cpu(gfh->file_info.load_addr) +
554                        le32_to_cpu(gfh->file_info.jump_offset));
555
556         if (print)
557                 printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
558
559         return 0;
560 }
561
562 static int mtk_image_verify_nand_header(const uint8_t *ptr, int print)
563 {
564         union nand_boot_header *nh = (union nand_boot_header *)ptr;
565         struct brom_layout_header *bh;
566         struct gfh_header *gfh;
567         const char *bootmedia;
568
569         if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
570             strcmp(nh->id, NAND_BOOT_ID))
571                 return -1;
572
573         bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize));
574
575         if (strcmp(bh->name, BRLYT_NAME))
576                 return -1;
577
578         if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) {
579                 return -1;
580         } else {
581                 if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND)
582                         bootmedia = "Parallel NAND";
583                 else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND)
584                         bootmedia = "Serial NAND";
585                 else
586                         return -1;
587         }
588
589         if (print) {
590                 printf("Boot Media: %s\n", bootmedia);
591
592                 if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) {
593                         uint64_t capacity =
594                                 (uint64_t)le16_to_cpu(nh->numblocks) *
595                                 (uint64_t)le16_to_cpu(nh->pages_of_block) *
596                                 (uint64_t)le16_to_cpu(nh->pagesize) * 8;
597                         printf("Capacity:     %dGb\n",
598                                (uint32_t)(capacity >> 30));
599                 }
600
601                 if (le16_to_cpu(nh->pagesize) >= 1024)
602                         printf("Page Size:    %dKB\n",
603                                le16_to_cpu(nh->pagesize) >> 10);
604                 else
605                         printf("Page Size:    %dB\n",
606                                le16_to_cpu(nh->pagesize));
607
608                 printf("Spare Size:   %dB\n", le16_to_cpu(nh->oobsize));
609         }
610
611         gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize));
612
613         if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME))
614                 return -1;
615
616         if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND)
617                 return -1;
618
619         if (print)
620                 printf("Load Address: %08x\n",
621                        le32_to_cpu(gfh->file_info.load_addr) +
622                        le32_to_cpu(gfh->file_info.jump_offset));
623
624         if (print)
625                 printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM");
626
627         return 0;
628 }
629
630 static uint32_t crc32be_cal(const void *data, size_t length)
631 {
632         uint32_t crc = 0;
633         uint8_t c;
634
635         if (crc32tbl[1] != MT7621_IH_CRC_POLYNOMIAL)
636                 crc32_normal_init(crc32tbl, MT7621_IH_CRC_POLYNOMIAL);
637
638         crc = crc32_normal_cal(crc, data, length, crc32tbl);
639
640         for (; length; length >>= 8) {
641                 c = length & 0xff;
642                 crc = crc32_normal_cal(crc, &c, 1, crc32tbl);
643         }
644
645         return ~crc;
646 }
647
648 static int mtk_image_verify_mt7621_header(const uint8_t *ptr, int print)
649 {
650         const image_header_t *hdr = (const image_header_t *)ptr;
651         struct mt7621_nand_header *nhdr;
652         uint32_t spl_size, crcval;
653         image_header_t header;
654         int ret;
655
656         spl_size = image_get_size(hdr);
657
658         if (spl_size > img_size) {
659                 if (print)
660                         printf("Incomplete SPL image\n");
661                 return -1;
662         }
663
664         ret = image_check_hcrc(hdr);
665         if (!ret) {
666                 if (print)
667                         printf("Bad header CRC\n");
668                 return -1;
669         }
670
671         ret = image_check_dcrc(hdr);
672         if (!ret) {
673                 if (print)
674                         printf("Bad data CRC\n");
675                 return -1;
676         }
677
678         /* Copy header so we can blank CRC field for re-calculation */
679         memmove(&header, hdr, image_get_header_size());
680         image_set_hcrc(&header, 0);
681
682         nhdr = (struct mt7621_nand_header *)header.ih_name;
683         crcval = be32_to_cpu(nhdr->crc);
684         nhdr->crc = 0;
685
686         if (crcval != crc32be_cal(&header, image_get_header_size())) {
687                 if (print)
688                         printf("Bad NAND header CRC\n");
689                 return -1;
690         }
691
692         if (print) {
693                 printf("Load Address: %08x\n", image_get_load(hdr));
694
695                 printf("Image Name:   %.*s\n", MT7621_IH_NMLEN,
696                        image_get_name(hdr));
697
698                 if (IMAGE_ENABLE_TIMESTAMP) {
699                         printf("Created:      ");
700                         genimg_print_time((time_t)image_get_time(hdr));
701                 }
702
703                 printf("Data Size:    ");
704                 genimg_print_size(image_get_data_size(hdr));
705         }
706
707         return 0;
708 }
709
710 static int mtk_image_verify_header(unsigned char *ptr, int image_size,
711                                    struct image_tool_params *params)
712 {
713         image_header_t *hdr = (image_header_t *)ptr;
714         union lk_hdr *lk = (union lk_hdr *)ptr;
715
716         /* nothing to verify for LK image header */
717         if (le32_to_cpu(lk->magic) == LK_PART_MAGIC)
718                 return 0;
719
720         img_size = image_size;
721
722         if (image_get_magic(hdr) == IH_MAGIC)
723                 return mtk_image_verify_mt7621_header(ptr, 0);
724
725         if (!strcmp((char *)ptr, NAND_BOOT_NAME))
726                 return mtk_image_verify_nand_header(ptr, 0);
727         else
728                 return mtk_image_verify_gen_header(ptr, 0);
729
730         return -1;
731 }
732
733 static void mtk_image_print_header(const void *ptr)
734 {
735         image_header_t *hdr = (image_header_t *)ptr;
736         union lk_hdr *lk = (union lk_hdr *)ptr;
737
738         if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) {
739                 printf("Image Type:   MediaTek LK Image\n");
740                 printf("Load Address: %08x\n", le32_to_cpu(lk->loadaddr));
741                 return;
742         }
743
744         printf("Image Type:   MediaTek BootROM Loadable Image\n");
745
746         if (image_get_magic(hdr) == IH_MAGIC) {
747                 mtk_image_verify_mt7621_header(ptr, 1);
748                 return;
749         }
750
751         if (!strcmp((char *)ptr, NAND_BOOT_NAME))
752                 mtk_image_verify_nand_header(ptr, 1);
753         else
754                 mtk_image_verify_gen_header(ptr, 1);
755 }
756
757 static void put_brom_layout_header(struct brom_layout_header *hdr, int type)
758 {
759         strncpy(hdr->name, BRLYT_NAME, sizeof(hdr->name));
760         hdr->version = cpu_to_le32(1);
761         hdr->magic = cpu_to_le32(BRLYT_MAGIC);
762         hdr->type = cpu_to_le32(type);
763 }
764
765 static void put_ghf_common_header(struct gfh_common_header *gfh, int size,
766                                   int type, int ver)
767 {
768         memcpy(gfh->magic, GFH_HEADER_MAGIC, sizeof(gfh->magic));
769         gfh->version = ver;
770         gfh->size = cpu_to_le16(size);
771         gfh->type = cpu_to_le16(type);
772 }
773
774 static void put_ghf_header(struct gfh_header *gfh, int file_size,
775                            int dev_hdr_size, int load_addr, int flash_type)
776 {
777         uint32_t cfg_bits;
778
779         memset(gfh, 0, sizeof(struct gfh_header));
780
781         /* GFH_FILE_INFO header */
782         put_ghf_common_header(&gfh->file_info.gfh, sizeof(gfh->file_info),
783                               GFH_TYPE_FILE_INFO, 1);
784         strncpy(gfh->file_info.name, GFH_FILE_INFO_NAME,
785                 sizeof(gfh->file_info.name));
786         gfh->file_info.unused = cpu_to_le32(1);
787         gfh->file_info.file_type = cpu_to_le16(1);
788         gfh->file_info.flash_type = flash_type;
789         gfh->file_info.sig_type = GFH_SIG_TYPE_SHA256;
790         gfh->file_info.load_addr = cpu_to_le32(load_addr - sizeof(*gfh));
791         gfh->file_info.total_size = cpu_to_le32(file_size - dev_hdr_size);
792         gfh->file_info.max_size = cpu_to_le32(file_size);
793         gfh->file_info.hdr_size = sizeof(*gfh);
794         gfh->file_info.sig_size = SHA256_SUM_LEN;
795         gfh->file_info.jump_offset = sizeof(*gfh);
796         gfh->file_info.processed = cpu_to_le32(1);
797
798         /* GFH_BL_INFO header */
799         put_ghf_common_header(&gfh->bl_info.gfh, sizeof(gfh->bl_info),
800                               GFH_TYPE_BL_INFO, 1);
801         gfh->bl_info.attr = cpu_to_le32(1);
802
803         /* GFH_BROM_CFG header */
804         put_ghf_common_header(&gfh->brom_cfg.gfh, sizeof(gfh->brom_cfg),
805                               GFH_TYPE_BROM_CFG, 3);
806         cfg_bits = GFH_BROM_CFG_USBDL_AUTO_DETECT_DIS |
807                    GFH_BROM_CFG_USBDL_BY_KCOL0_TIMEOUT_EN |
808                    GFH_BROM_CFG_USBDL_BY_FLAG_TIMEOUT_EN;
809         gfh->brom_cfg.usbdl_by_kcol0_timeout_ms = cpu_to_le32(5000);
810         if (is_arm64_image) {
811                 gfh->brom_cfg.jump_bl_arm64 = GFH_BROM_CFG_JUMP_BL_ARM64;
812                 cfg_bits |= GFH_BROM_CFG_JUMP_BL_ARM64_EN;
813         }
814         gfh->brom_cfg.cfg_bits = cpu_to_le32(cfg_bits);
815
816         /* GFH_BL_SEC_KEY header */
817         put_ghf_common_header(&gfh->bl_sec_key.gfh, sizeof(gfh->bl_sec_key),
818                               GFH_TYPE_BL_SEC_KEY, 1);
819
820         /* GFH_ANTI_CLONE header */
821         put_ghf_common_header(&gfh->anti_clone.gfh, sizeof(gfh->anti_clone),
822                               GFH_TYPE_ANTI_CLONE, 1);
823         gfh->anti_clone.ac_offset = cpu_to_le32(0x10);
824         gfh->anti_clone.ac_len = cpu_to_le32(0x80);
825
826         /* GFH_BROM_SEC_CFG header */
827         put_ghf_common_header(&gfh->brom_sec_cfg.gfh,
828                               sizeof(gfh->brom_sec_cfg),
829                               GFH_TYPE_BROM_SEC_CFG, 1);
830         gfh->brom_sec_cfg.cfg_bits =
831                 cpu_to_le32(BROM_SEC_CFG_JTAG_EN | BROM_SEC_CFG_UART_EN);
832 }
833
834 static void put_hash(uint8_t *buff, int size)
835 {
836         sha256_context ctx;
837
838         sha256_starts(&ctx);
839         sha256_update(&ctx, buff, size);
840         sha256_finish(&ctx, buff + size);
841 }
842
843 static void mtk_image_set_gen_header(void *ptr, off_t filesize,
844                                      uint32_t loadaddr)
845 {
846         struct gen_device_header *hdr = (struct gen_device_header *)ptr;
847         struct gfh_header *gfh;
848         const char *bootname = NULL;
849
850         if (hdr_media == BRLYT_TYPE_NOR)
851                 bootname = SF_BOOT_NAME;
852         else if (hdr_media == BRLYT_TYPE_EMMC)
853                 bootname = EMMC_BOOT_NAME;
854         else if (hdr_media == BRLYT_TYPE_SDMMC)
855                 bootname = SDMMC_BOOT_NAME;
856
857         /* Generic device header */
858         snprintf(hdr->boot.name, sizeof(hdr->boot.name), "%s", bootname);
859         hdr->boot.version = cpu_to_le32(1);
860         hdr->boot.size = cpu_to_le32(sizeof(hdr->boot));
861
862         /* BRLYT header */
863         put_brom_layout_header(&hdr->brlyt, hdr_media);
864         hdr->brlyt.header_size = cpu_to_le32(hdr_offset + sizeof(*hdr));
865         hdr->brlyt.total_size = cpu_to_le32(hdr_offset + filesize);
866         hdr->brlyt.header_size_2 = hdr->brlyt.header_size;
867         hdr->brlyt.total_size_2 = hdr->brlyt.total_size;
868
869         /* GFH header */
870         gfh = (struct gfh_header *)(ptr + sizeof(struct gen_device_header));
871         put_ghf_header(gfh, filesize, sizeof(struct gen_device_header),
872                        loadaddr, GFH_FLASH_TYPE_GEN);
873
874         /* Generate SHA256 hash */
875         put_hash((uint8_t *)gfh,
876                  filesize - sizeof(struct gen_device_header) - SHA256_SUM_LEN);
877 }
878
879 static void mtk_image_set_nand_header(void *ptr, off_t filesize,
880                                       uint32_t loadaddr)
881 {
882         union nand_boot_header *nh = (union nand_boot_header *)ptr;
883         struct brom_layout_header *brlyt;
884         struct gfh_header *gfh;
885         uint32_t payload_pages;
886         int i;
887
888         /* NAND device header, repeat 4 times */
889         for (i = 0; i < 4; i++)
890                 memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
891
892         /* BRLYT header */
893         payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) /
894                         le16_to_cpu(hdr_nand->pagesize);
895         brlyt = (struct brom_layout_header *)
896                 (ptr + le16_to_cpu(hdr_nand->pagesize));
897         put_brom_layout_header(brlyt, hdr_media);
898         brlyt->header_size = cpu_to_le32(2);
899         brlyt->total_size = cpu_to_le32(payload_pages);
900         brlyt->header_size_2 = brlyt->header_size;
901         brlyt->total_size_2 = brlyt->total_size;
902         brlyt->unused = cpu_to_le32(1);
903
904         /* GFH header */
905         gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize));
906         put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize),
907                        loadaddr, GFH_FLASH_TYPE_NAND);
908
909         /* Generate SHA256 hash */
910         put_hash((uint8_t *)gfh,
911                  filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN);
912 }
913
914 static void mtk_image_set_mt7621_header(void *ptr, off_t filesize,
915                                         uint32_t loadaddr)
916 {
917         image_header_t *hdr = (image_header_t *)ptr;
918         struct mt7621_stage1_header *shdr;
919         struct mt7621_nand_header *nhdr;
920         uint32_t datasize, crcval;
921
922         datasize = filesize - image_get_header_size();
923         nhdr = (struct mt7621_nand_header *)hdr->ih_name;
924         shdr = (struct mt7621_stage1_header *)(ptr + image_get_header_size());
925
926         shdr->ep = cpu_to_be32(loadaddr);
927         shdr->stage_size = cpu_to_be32(datasize);
928
929         image_set_magic(hdr, IH_MAGIC);
930         image_set_time(hdr, time(NULL));
931         image_set_size(hdr, datasize);
932         image_set_load(hdr, loadaddr);
933         image_set_ep(hdr, loadaddr);
934         image_set_os(hdr, IH_OS_U_BOOT);
935         image_set_arch(hdr, IH_ARCH_MIPS);
936         image_set_type(hdr, IH_TYPE_STANDALONE);
937         image_set_comp(hdr, IH_COMP_NONE);
938
939         crcval = crc32(0, (uint8_t *)shdr, datasize);
940         image_set_dcrc(hdr, crcval);
941
942         strncpy(nhdr->ih_name, "MT7621 NAND", MT7621_IH_NMLEN);
943
944         nhdr->ih_stage_offset = cpu_to_be32(image_get_header_size());
945
946         crcval = crc32be_cal(hdr, image_get_header_size());
947         nhdr->crc = cpu_to_be32(crcval);
948
949         crcval = crc32(0, (uint8_t *)hdr, image_get_header_size());
950         image_set_hcrc(hdr, crcval);
951 }
952
953 static void mtk_image_set_header(void *ptr, struct stat *sbuf, int ifd,
954                                  struct image_tool_params *params)
955 {
956         union lk_hdr *lk = (union lk_hdr *)ptr;
957
958         if (use_lk_hdr) {
959                 lk->magic = cpu_to_le32(LK_PART_MAGIC);
960                 lk->size = cpu_to_le32(sbuf->st_size - sizeof(union lk_hdr));
961                 lk->loadaddr = cpu_to_le32(params->addr);
962                 lk->mode = 0xffffffff; /* must be non-zero */
963                 memset(lk->name, 0, sizeof(lk->name));
964                 strncpy(lk->name, lk_name, sizeof(lk->name));
965                 return;
966         }
967
968         img_gen = true;
969         img_size = sbuf->st_size;
970
971         if (use_mt7621_hdr) {
972                 mtk_image_set_mt7621_header(ptr, sbuf->st_size, params->addr);
973                 return;
974         }
975
976         if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND)
977                 mtk_image_set_nand_header(ptr, sbuf->st_size, params->addr);
978         else
979                 mtk_image_set_gen_header(ptr, sbuf->st_size, params->addr);
980 }
981
982 U_BOOT_IMAGE_TYPE(
983         mtk_image,
984         "MediaTek BootROM Loadable Image support",
985         0,
986         NULL,
987         mtk_image_check_params,
988         mtk_image_verify_header,
989         mtk_image_print_header,
990         mtk_image_set_header,
991         NULL,
992         mtk_image_check_image_types,
993         NULL,
994         mtk_image_vrec_header
995 );