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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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