]> git.ipfire.org Git - thirdparty/u-boot.git/blame - tools/kwbimage.c
mtd: nand: pxa3xx: simplify ECC hardware parameters
[thirdparty/u-boot.git] / tools / kwbimage.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
aa0c7a86 2/*
4acd2d24 3 * Image manipulator for Marvell SoCs
8010f4ff
T
4 * supports Kirkwood, Dove, Armada 370, Armada XP, Armada 375, Armada 38x and
5 * Armada 39x
4acd2d24
SR
6 *
7 * (C) Copyright 2013 Thomas Petazzoni
8 * <thomas.petazzoni@free-electrons.com>
43558a02
T
9 *
10 * (C) Copyright 2022 Pali Rohár <pali@kernel.org>
aa0c7a86
PW
11 */
12
3a8b9199
HS
13#define OPENSSL_API_COMPAT 0x10101000L
14
f86ed6a8 15#include "imagetool.h"
e5f1a586 16#include <limits.h>
aa0c7a86 17#include <image.h>
a1b6b0a9 18#include <stdarg.h>
4acd2d24 19#include <stdint.h>
aa0c7a86
PW
20#include "kwbimage.h"
21
e15843b1 22#include <openssl/bn.h>
a1b6b0a9
MS
23#include <openssl/rsa.h>
24#include <openssl/pem.h>
25#include <openssl/err.h>
26#include <openssl/evp.h>
e15843b1 27
a2d5efd7
JG
28#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
29 (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
e15843b1
JW
30static void RSA_get0_key(const RSA *r,
31 const BIGNUM **n, const BIGNUM **e, const BIGNUM **d)
32{
33 if (n != NULL)
34 *n = r->n;
35 if (e != NULL)
36 *e = r->e;
37 if (d != NULL)
38 *d = r->d;
39}
40
a2d5efd7 41#elif !defined(LIBRESSL_VERSION_NUMBER)
e15843b1
JW
42void EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
43{
44 EVP_MD_CTX_reset(ctx);
45}
46#endif
a1b6b0a9 47
f76ae257
T
48/* fls - find last (most-significant) bit set in 4-bit integer */
49static inline int fls4(int num)
50{
51 if (num & 0x8)
52 return 4;
53 else if (num & 0x4)
54 return 3;
55 else if (num & 0x2)
56 return 2;
57 else if (num & 0x1)
58 return 1;
59 else
60 return 0;
61}
62
4acd2d24
SR
63static struct image_cfg_element *image_cfg;
64static int cfgn;
a1b6b0a9 65static int verbose_mode;
4acd2d24
SR
66
67struct boot_mode {
68 unsigned int id;
69 const char *name;
70};
71
a1b6b0a9
MS
72/*
73 * SHA2-256 hash
74 */
75struct hash_v1 {
76 uint8_t hash[32];
77};
78
4acd2d24 79struct boot_mode boot_modes[] = {
e515a330
T
80 { IBR_HDR_I2C_ID, "i2c" },
81 { IBR_HDR_SPI_ID, "spi" },
82 { IBR_HDR_NAND_ID, "nand" },
83 { IBR_HDR_SATA_ID, "sata" },
84 { IBR_HDR_PEX_ID, "pex" },
85 { IBR_HDR_UART_ID, "uart" },
86 { IBR_HDR_SDIO_ID, "sdio" },
4acd2d24 87 {},
aa0c7a86
PW
88};
89
4acd2d24
SR
90struct nand_ecc_mode {
91 unsigned int id;
92 const char *name;
93};
94
95struct nand_ecc_mode nand_ecc_modes[] = {
e515a330
T
96 { IBR_HDR_ECC_DEFAULT, "default" },
97 { IBR_HDR_ECC_FORCED_HAMMING, "hamming" },
98 { IBR_HDR_ECC_FORCED_RS, "rs" },
99 { IBR_HDR_ECC_DISABLED, "disabled" },
4acd2d24
SR
100 {},
101};
102
103/* Used to identify an undefined execution or destination address */
104#define ADDR_INVALID ((uint32_t)-1)
105
6c7f152e 106#define BINARY_MAX_ARGS 255
4acd2d24
SR
107
108/* In-memory representation of a line of the configuration file */
4991b4f7
MS
109
110enum image_cfg_type {
111 IMAGE_CFG_VERSION = 0x1,
112 IMAGE_CFG_BOOT_FROM,
113 IMAGE_CFG_DEST_ADDR,
114 IMAGE_CFG_EXEC_ADDR,
115 IMAGE_CFG_NAND_BLKSZ,
116 IMAGE_CFG_NAND_BADBLK_LOCATION,
117 IMAGE_CFG_NAND_ECC_MODE,
118 IMAGE_CFG_NAND_PAGESZ,
af49605b 119 IMAGE_CFG_CPU,
4991b4f7 120 IMAGE_CFG_BINARY,
4991b4f7 121 IMAGE_CFG_DATA,
f63c583f 122 IMAGE_CFG_DATA_DELAY,
4991b4f7 123 IMAGE_CFG_BAUDRATE,
12f2c03f
T
124 IMAGE_CFG_UART_PORT,
125 IMAGE_CFG_UART_MPP,
4991b4f7 126 IMAGE_CFG_DEBUG,
a1b6b0a9
MS
127 IMAGE_CFG_KAK,
128 IMAGE_CFG_CSK,
129 IMAGE_CFG_CSK_INDEX,
130 IMAGE_CFG_JTAG_DELAY,
131 IMAGE_CFG_BOX_ID,
132 IMAGE_CFG_FLASH_ID,
133 IMAGE_CFG_SEC_COMMON_IMG,
134 IMAGE_CFG_SEC_SPECIALIZED_IMG,
135 IMAGE_CFG_SEC_BOOT_DEV,
136 IMAGE_CFG_SEC_FUSE_DUMP,
4991b4f7
MS
137
138 IMAGE_CFG_COUNT
139} type;
140
141static const char * const id_strs[] = {
142 [IMAGE_CFG_VERSION] = "VERSION",
143 [IMAGE_CFG_BOOT_FROM] = "BOOT_FROM",
144 [IMAGE_CFG_DEST_ADDR] = "DEST_ADDR",
145 [IMAGE_CFG_EXEC_ADDR] = "EXEC_ADDR",
146 [IMAGE_CFG_NAND_BLKSZ] = "NAND_BLKSZ",
147 [IMAGE_CFG_NAND_BADBLK_LOCATION] = "NAND_BADBLK_LOCATION",
148 [IMAGE_CFG_NAND_ECC_MODE] = "NAND_ECC_MODE",
149 [IMAGE_CFG_NAND_PAGESZ] = "NAND_PAGE_SIZE",
af49605b 150 [IMAGE_CFG_CPU] = "CPU",
4991b4f7 151 [IMAGE_CFG_BINARY] = "BINARY",
4991b4f7 152 [IMAGE_CFG_DATA] = "DATA",
f63c583f 153 [IMAGE_CFG_DATA_DELAY] = "DATA_DELAY",
4991b4f7 154 [IMAGE_CFG_BAUDRATE] = "BAUDRATE",
12f2c03f
T
155 [IMAGE_CFG_UART_PORT] = "UART_PORT",
156 [IMAGE_CFG_UART_MPP] = "UART_MPP",
4991b4f7 157 [IMAGE_CFG_DEBUG] = "DEBUG",
a1b6b0a9
MS
158 [IMAGE_CFG_KAK] = "KAK",
159 [IMAGE_CFG_CSK] = "CSK",
160 [IMAGE_CFG_CSK_INDEX] = "CSK_INDEX",
161 [IMAGE_CFG_JTAG_DELAY] = "JTAG_DELAY",
162 [IMAGE_CFG_BOX_ID] = "BOX_ID",
163 [IMAGE_CFG_FLASH_ID] = "FLASH_ID",
164 [IMAGE_CFG_SEC_COMMON_IMG] = "SEC_COMMON_IMG",
165 [IMAGE_CFG_SEC_SPECIALIZED_IMG] = "SEC_SPECIALIZED_IMG",
166 [IMAGE_CFG_SEC_BOOT_DEV] = "SEC_BOOT_DEV",
167 [IMAGE_CFG_SEC_FUSE_DUMP] = "SEC_FUSE_DUMP"
4991b4f7
MS
168};
169
4acd2d24 170struct image_cfg_element {
4991b4f7 171 enum image_cfg_type type;
4acd2d24
SR
172 union {
173 unsigned int version;
af49605b 174 unsigned int cpu_sheeva;
4acd2d24
SR
175 unsigned int bootfrom;
176 struct {
177 const char *file;
0aca27ea 178 unsigned int loadaddr;
4acd2d24
SR
179 unsigned int args[BINARY_MAX_ARGS];
180 unsigned int nargs;
181 } binary;
4acd2d24
SR
182 unsigned int dstaddr;
183 unsigned int execaddr;
184 unsigned int nandblksz;
185 unsigned int nandbadblklocation;
186 unsigned int nandeccmode;
187 unsigned int nandpagesz;
188 struct ext_hdr_v0_reg regdata;
f63c583f 189 unsigned int regdata_delay;
4bdb5479 190 unsigned int baudrate;
12f2c03f
T
191 unsigned int uart_port;
192 unsigned int uart_mpp;
2611c05e 193 unsigned int debug;
a1b6b0a9
MS
194 const char *key_name;
195 int csk_idx;
196 uint8_t jtag_delay;
197 uint32_t boxid;
198 uint32_t flashid;
199 bool sec_specialized_img;
200 unsigned int sec_boot_dev;
201 const char *name;
4acd2d24
SR
202 };
203};
204
205#define IMAGE_CFG_ELEMENT_MAX 256
aa0c7a86 206
4acd2d24
SR
207/*
208 * Utility functions to manipulate boot mode and ecc modes (convert
209 * them back and forth between description strings and the
210 * corresponding numerical identifiers).
211 */
212
213static const char *image_boot_mode_name(unsigned int id)
214{
215 int i;
94490a4a 216
4acd2d24
SR
217 for (i = 0; boot_modes[i].name; i++)
218 if (boot_modes[i].id == id)
219 return boot_modes[i].name;
220 return NULL;
221}
222
6eb20bbf 223static int image_boot_mode_id(const char *boot_mode_name)
4acd2d24
SR
224{
225 int i;
94490a4a 226
4acd2d24
SR
227 for (i = 0; boot_modes[i].name; i++)
228 if (!strcmp(boot_modes[i].name, boot_mode_name))
229 return boot_modes[i].id;
230
231 return -1;
232}
233
1a8e6b63
T
234static const char *image_nand_ecc_mode_name(unsigned int id)
235{
236 int i;
237
238 for (i = 0; nand_ecc_modes[i].name; i++)
239 if (nand_ecc_modes[i].id == id)
240 return nand_ecc_modes[i].name;
241
242 return NULL;
243}
244
6eb20bbf 245static int image_nand_ecc_mode_id(const char *nand_ecc_mode_name)
4acd2d24
SR
246{
247 int i;
94490a4a 248
4acd2d24
SR
249 for (i = 0; nand_ecc_modes[i].name; i++)
250 if (!strcmp(nand_ecc_modes[i].name, nand_ecc_mode_name))
251 return nand_ecc_modes[i].id;
252 return -1;
aa0c7a86
PW
253}
254
4acd2d24
SR
255static struct image_cfg_element *
256image_find_option(unsigned int optiontype)
aa0c7a86 257{
4acd2d24 258 int i;
aa0c7a86 259
4acd2d24
SR
260 for (i = 0; i < cfgn; i++) {
261 if (image_cfg[i].type == optiontype)
262 return &image_cfg[i];
aa0c7a86 263 }
4acd2d24
SR
264
265 return NULL;
266}
267
268static unsigned int
269image_count_options(unsigned int optiontype)
270{
271 int i;
272 unsigned int count = 0;
273
274 for (i = 0; i < cfgn; i++)
275 if (image_cfg[i].type == optiontype)
276 count++;
277
278 return count;
aa0c7a86
PW
279}
280
a1b6b0a9
MS
281static int image_get_csk_index(void)
282{
283 struct image_cfg_element *e;
284
285 e = image_find_option(IMAGE_CFG_CSK_INDEX);
286 if (!e)
287 return -1;
288
289 return e->csk_idx;
290}
291
292static bool image_get_spezialized_img(void)
293{
294 struct image_cfg_element *e;
295
296 e = image_find_option(IMAGE_CFG_SEC_SPECIALIZED_IMG);
297 if (!e)
298 return false;
299
300 return e->sec_specialized_img;
301}
302
d1547b36
T
303static int image_get_bootfrom(void)
304{
305 struct image_cfg_element *e;
306
307 e = image_find_option(IMAGE_CFG_BOOT_FROM);
308 if (!e)
309 /* fallback to SPI if no BOOT_FROM is not provided */
310 return IBR_HDR_SPI_ID;
311
312 return e->bootfrom;
313}
314
af49605b
T
315static int image_is_cpu_sheeva(void)
316{
317 struct image_cfg_element *e;
318
319 e = image_find_option(IMAGE_CFG_CPU);
320 if (!e)
321 return 0;
322
323 return e->cpu_sheeva;
324}
325
aa0c7a86 326/*
4acd2d24
SR
327 * Compute a 8-bit checksum of a memory area. This algorithm follows
328 * the requirements of the Marvell SoC BootROM specifications.
aa0c7a86 329 */
4acd2d24 330static uint8_t image_checksum8(void *start, uint32_t len)
aa0c7a86 331{
4acd2d24
SR
332 uint8_t csum = 0;
333 uint8_t *p = start;
aa0c7a86
PW
334
335 /* check len and return zero checksum if invalid */
336 if (!len)
337 return 0;
338
339 do {
4acd2d24 340 csum += *p;
aa0c7a86
PW
341 p++;
342 } while (--len);
4acd2d24
SR
343
344 return csum;
aa0c7a86
PW
345}
346
db7cd4ed
BS
347/*
348 * Verify checksum over a complete header that includes the checksum field.
349 * Return 1 when OK, otherwise 0.
350 */
351static int main_hdr_checksum_ok(void *hdr)
352{
353 /* Offsets of checksum in v0 and v1 headers are the same */
354 struct main_hdr_v0 *main_hdr = (struct main_hdr_v0 *)hdr;
355 uint8_t checksum;
356
fe2fd73d 357 checksum = image_checksum8(hdr, kwbheader_size_for_csum(hdr));
db7cd4ed
BS
358 /* Calculated checksum includes the header checksum field. Compensate
359 * for that.
360 */
361 checksum -= main_hdr->checksum;
362
363 return checksum == main_hdr->checksum;
364}
365
4acd2d24 366static uint32_t image_checksum32(void *start, uint32_t len)
aa0c7a86 367{
4acd2d24
SR
368 uint32_t csum = 0;
369 uint32_t *p = start;
aa0c7a86
PW
370
371 /* check len and return zero checksum if invalid */
372 if (!len)
373 return 0;
374
375 if (len % sizeof(uint32_t)) {
4acd2d24
SR
376 fprintf(stderr, "Length %d is not in multiple of %zu\n",
377 len, sizeof(uint32_t));
aa0c7a86
PW
378 return 0;
379 }
380
381 do {
4acd2d24 382 csum += *p;
aa0c7a86
PW
383 p++;
384 len -= sizeof(uint32_t);
385 } while (len > 0);
4acd2d24
SR
386
387 return csum;
aa0c7a86
PW
388}
389
1a8e6b63
T
390static unsigned int options_to_baudrate(uint8_t options)
391{
392 switch (options & 0x7) {
393 case MAIN_HDR_V1_OPT_BAUD_2400:
394 return 2400;
395 case MAIN_HDR_V1_OPT_BAUD_4800:
396 return 4800;
397 case MAIN_HDR_V1_OPT_BAUD_9600:
398 return 9600;
399 case MAIN_HDR_V1_OPT_BAUD_19200:
400 return 19200;
401 case MAIN_HDR_V1_OPT_BAUD_38400:
402 return 38400;
403 case MAIN_HDR_V1_OPT_BAUD_57600:
404 return 57600;
405 case MAIN_HDR_V1_OPT_BAUD_115200:
406 return 115200;
407 case MAIN_HDR_V1_OPT_BAUD_DEFAULT:
408 default:
409 return 0;
410 }
411}
412
4bdb5479
CP
413static uint8_t baudrate_to_option(unsigned int baudrate)
414{
415 switch (baudrate) {
416 case 2400:
417 return MAIN_HDR_V1_OPT_BAUD_2400;
418 case 4800:
419 return MAIN_HDR_V1_OPT_BAUD_4800;
420 case 9600:
421 return MAIN_HDR_V1_OPT_BAUD_9600;
422 case 19200:
423 return MAIN_HDR_V1_OPT_BAUD_19200;
424 case 38400:
425 return MAIN_HDR_V1_OPT_BAUD_38400;
426 case 57600:
427 return MAIN_HDR_V1_OPT_BAUD_57600;
428 case 115200:
429 return MAIN_HDR_V1_OPT_BAUD_115200;
430 default:
431 return MAIN_HDR_V1_OPT_BAUD_DEFAULT;
432 }
433}
434
a1b6b0a9
MS
435static void kwb_msg(const char *fmt, ...)
436{
437 if (verbose_mode) {
438 va_list ap;
439
440 va_start(ap, fmt);
441 vfprintf(stdout, fmt, ap);
442 va_end(ap);
443 }
444}
445
446static int openssl_err(const char *msg)
447{
448 unsigned long ssl_err = ERR_get_error();
449
450 fprintf(stderr, "%s", msg);
451 fprintf(stderr, ": %s\n",
452 ERR_error_string(ssl_err, 0));
453
454 return -1;
455}
456
457static int kwb_load_rsa_key(const char *keydir, const char *name, RSA **p_rsa)
458{
459 char path[PATH_MAX];
460 RSA *rsa;
461 FILE *f;
462
463 if (!keydir)
464 keydir = ".";
465
466 snprintf(path, sizeof(path), "%s/%s.key", keydir, name);
467 f = fopen(path, "r");
468 if (!f) {
469 fprintf(stderr, "Couldn't open RSA private key: '%s': %s\n",
470 path, strerror(errno));
471 return -ENOENT;
472 }
473
474 rsa = PEM_read_RSAPrivateKey(f, 0, NULL, "");
475 if (!rsa) {
476 openssl_err("Failure reading private key");
477 fclose(f);
478 return -EPROTO;
479 }
480 fclose(f);
481 *p_rsa = rsa;
482
483 return 0;
484}
485
486static int kwb_load_cfg_key(struct image_tool_params *params,
487 unsigned int cfg_option, const char *key_name,
488 RSA **p_key)
489{
490 struct image_cfg_element *e_key;
491 RSA *key;
492 int res;
493
494 *p_key = NULL;
495
496 e_key = image_find_option(cfg_option);
497 if (!e_key) {
498 fprintf(stderr, "%s not configured\n", key_name);
499 return -ENOENT;
500 }
501
502 res = kwb_load_rsa_key(params->keydir, e_key->key_name, &key);
503 if (res < 0) {
504 fprintf(stderr, "Failed to load %s\n", key_name);
505 return -ENOENT;
506 }
507
508 *p_key = key;
509
510 return 0;
511}
512
513static int kwb_load_kak(struct image_tool_params *params, RSA **p_kak)
514{
515 return kwb_load_cfg_key(params, IMAGE_CFG_KAK, "KAK", p_kak);
516}
517
518static int kwb_load_csk(struct image_tool_params *params, RSA **p_csk)
519{
520 return kwb_load_cfg_key(params, IMAGE_CFG_CSK, "CSK", p_csk);
521}
522
523static int kwb_compute_pubkey_hash(struct pubkey_der_v1 *pk,
524 struct hash_v1 *hash)
525{
526 EVP_MD_CTX *ctx;
527 unsigned int key_size;
528 unsigned int hash_size;
529 int ret = 0;
530
531 if (!pk || !hash || pk->key[0] != 0x30 || pk->key[1] != 0x82)
532 return -EINVAL;
533
534 key_size = (pk->key[2] << 8) + pk->key[3] + 4;
535
536 ctx = EVP_MD_CTX_create();
537 if (!ctx)
538 return openssl_err("EVP context creation failed");
539
540 EVP_MD_CTX_init(ctx);
541 if (!EVP_DigestInit(ctx, EVP_sha256())) {
542 ret = openssl_err("Digest setup failed");
543 goto hash_err_ctx;
544 }
545
546 if (!EVP_DigestUpdate(ctx, pk->key, key_size)) {
547 ret = openssl_err("Hashing data failed");
548 goto hash_err_ctx;
549 }
550
551 if (!EVP_DigestFinal(ctx, hash->hash, &hash_size)) {
552 ret = openssl_err("Could not obtain hash");
553 goto hash_err_ctx;
554 }
555
556 EVP_MD_CTX_cleanup(ctx);
557
558hash_err_ctx:
559 EVP_MD_CTX_destroy(ctx);
560 return ret;
561}
562
563static int kwb_import_pubkey(RSA **key, struct pubkey_der_v1 *src, char *keyname)
564{
565 RSA *rsa;
566 const unsigned char *ptr;
567
568 if (!key || !src)
569 goto fail;
570
571 ptr = src->key;
572 rsa = d2i_RSAPublicKey(key, &ptr, sizeof(src->key));
573 if (!rsa) {
574 openssl_err("error decoding public key");
575 goto fail;
576 }
577
578 return 0;
579fail:
580 fprintf(stderr, "Failed to decode %s pubkey\n", keyname);
581 return -EINVAL;
582}
583
584static int kwb_export_pubkey(RSA *key, struct pubkey_der_v1 *dst, FILE *hashf,
585 char *keyname)
586{
587 int size_exp, size_mod, size_seq;
e15843b1 588 const BIGNUM *key_e, *key_n;
a1b6b0a9
MS
589 uint8_t *cur;
590 char *errmsg = "Failed to encode %s\n";
591
e15843b1
JW
592 RSA_get0_key(key, NULL, &key_e, NULL);
593 RSA_get0_key(key, &key_n, NULL, NULL);
594
595 if (!key || !key_e || !key_n || !dst) {
a1b6b0a9 596 fprintf(stderr, "export pk failed: (%p, %p, %p, %p)",
e15843b1 597 key, key_e, key_n, dst);
a1b6b0a9
MS
598 fprintf(stderr, errmsg, keyname);
599 return -EINVAL;
600 }
601
602 /*
603 * According to the specs, the key should be PKCS#1 DER encoded.
604 * But unfortunately the really required encoding seems to be different;
605 * it violates DER...! (But it still conformes to BER.)
606 * (Length always in long form w/ 2 byte length code; no leading zero
607 * when MSB of first byte is set...)
608 * So we cannot use the encoding func provided by OpenSSL and have to
609 * do the encoding manually.
610 */
611
e15843b1
JW
612 size_exp = BN_num_bytes(key_e);
613 size_mod = BN_num_bytes(key_n);
a1b6b0a9
MS
614 size_seq = 4 + size_mod + 4 + size_exp;
615
616 if (size_mod > 256) {
617 fprintf(stderr, "export pk failed: wrong mod size: %d\n",
618 size_mod);
619 fprintf(stderr, errmsg, keyname);
620 return -EINVAL;
621 }
622
623 if (4 + size_seq > sizeof(dst->key)) {
3b5da64e 624 fprintf(stderr, "export pk failed: seq too large (%d, %zu)\n",
a1b6b0a9
MS
625 4 + size_seq, sizeof(dst->key));
626 fprintf(stderr, errmsg, keyname);
627 return -ENOBUFS;
628 }
629
630 cur = dst->key;
631
632 /* PKCS#1 (RFC3447) RSAPublicKey structure */
633 *cur++ = 0x30; /* SEQUENCE */
634 *cur++ = 0x82;
635 *cur++ = (size_seq >> 8) & 0xFF;
636 *cur++ = size_seq & 0xFF;
637 /* Modulus */
638 *cur++ = 0x02; /* INTEGER */
639 *cur++ = 0x82;
640 *cur++ = (size_mod >> 8) & 0xFF;
641 *cur++ = size_mod & 0xFF;
e15843b1 642 BN_bn2bin(key_n, cur);
a1b6b0a9
MS
643 cur += size_mod;
644 /* Exponent */
645 *cur++ = 0x02; /* INTEGER */
646 *cur++ = 0x82;
647 *cur++ = (size_exp >> 8) & 0xFF;
648 *cur++ = size_exp & 0xFF;
e15843b1 649 BN_bn2bin(key_e, cur);
a1b6b0a9
MS
650
651 if (hashf) {
652 struct hash_v1 pk_hash;
653 int i;
654 int ret = 0;
655
656 ret = kwb_compute_pubkey_hash(dst, &pk_hash);
657 if (ret < 0) {
658 fprintf(stderr, errmsg, keyname);
659 return ret;
660 }
661
662 fprintf(hashf, "SHA256 = ");
663 for (i = 0 ; i < sizeof(pk_hash.hash); ++i)
664 fprintf(hashf, "%02X", pk_hash.hash[i]);
665 fprintf(hashf, "\n");
666 }
667
668 return 0;
669}
670
6eb20bbf
T
671static int kwb_sign(RSA *key, void *data, int datasz, struct sig_v1 *sig,
672 char *signame)
a1b6b0a9
MS
673{
674 EVP_PKEY *evp_key;
675 EVP_MD_CTX *ctx;
676 unsigned int sig_size;
677 int size;
678 int ret = 0;
679
680 evp_key = EVP_PKEY_new();
681 if (!evp_key)
682 return openssl_err("EVP_PKEY object creation failed");
683
684 if (!EVP_PKEY_set1_RSA(evp_key, key)) {
685 ret = openssl_err("EVP key setup failed");
686 goto err_key;
687 }
688
689 size = EVP_PKEY_size(evp_key);
690 if (size > sizeof(sig->sig)) {
691 fprintf(stderr, "Buffer to small for signature (%d bytes)\n",
692 size);
693 ret = -ENOBUFS;
694 goto err_key;
695 }
696
697 ctx = EVP_MD_CTX_create();
698 if (!ctx) {
699 ret = openssl_err("EVP context creation failed");
700 goto err_key;
701 }
702 EVP_MD_CTX_init(ctx);
703 if (!EVP_SignInit(ctx, EVP_sha256())) {
704 ret = openssl_err("Signer setup failed");
705 goto err_ctx;
706 }
707
708 if (!EVP_SignUpdate(ctx, data, datasz)) {
709 ret = openssl_err("Signing data failed");
710 goto err_ctx;
711 }
712
713 if (!EVP_SignFinal(ctx, sig->sig, &sig_size, evp_key)) {
714 ret = openssl_err("Could not obtain signature");
715 goto err_ctx;
716 }
717
718 EVP_MD_CTX_cleanup(ctx);
719 EVP_MD_CTX_destroy(ctx);
720 EVP_PKEY_free(evp_key);
721
722 return 0;
723
724err_ctx:
725 EVP_MD_CTX_destroy(ctx);
726err_key:
727 EVP_PKEY_free(evp_key);
728 fprintf(stderr, "Failed to create %s signature\n", signame);
729 return ret;
730}
731
6eb20bbf
T
732static int kwb_verify(RSA *key, void *data, int datasz, struct sig_v1 *sig,
733 char *signame)
a1b6b0a9
MS
734{
735 EVP_PKEY *evp_key;
736 EVP_MD_CTX *ctx;
737 int size;
738 int ret = 0;
739
740 evp_key = EVP_PKEY_new();
741 if (!evp_key)
742 return openssl_err("EVP_PKEY object creation failed");
743
744 if (!EVP_PKEY_set1_RSA(evp_key, key)) {
745 ret = openssl_err("EVP key setup failed");
746 goto err_key;
747 }
748
749 size = EVP_PKEY_size(evp_key);
750 if (size > sizeof(sig->sig)) {
751 fprintf(stderr, "Invalid signature size (%d bytes)\n",
752 size);
753 ret = -EINVAL;
754 goto err_key;
755 }
756
757 ctx = EVP_MD_CTX_create();
758 if (!ctx) {
759 ret = openssl_err("EVP context creation failed");
760 goto err_key;
761 }
762 EVP_MD_CTX_init(ctx);
763 if (!EVP_VerifyInit(ctx, EVP_sha256())) {
764 ret = openssl_err("Verifier setup failed");
765 goto err_ctx;
766 }
767
768 if (!EVP_VerifyUpdate(ctx, data, datasz)) {
769 ret = openssl_err("Hashing data failed");
770 goto err_ctx;
771 }
772
22515123 773 if (EVP_VerifyFinal(ctx, sig->sig, sizeof(sig->sig), evp_key) != 1) {
a1b6b0a9
MS
774 ret = openssl_err("Could not verify signature");
775 goto err_ctx;
776 }
777
778 EVP_MD_CTX_cleanup(ctx);
779 EVP_MD_CTX_destroy(ctx);
780 EVP_PKEY_free(evp_key);
781
782 return 0;
783
784err_ctx:
785 EVP_MD_CTX_destroy(ctx);
786err_key:
787 EVP_PKEY_free(evp_key);
788 fprintf(stderr, "Failed to verify %s signature\n", signame);
789 return ret;
790}
791
6eb20bbf
T
792static int kwb_sign_and_verify(RSA *key, void *data, int datasz,
793 struct sig_v1 *sig, char *signame)
a1b6b0a9
MS
794{
795 if (kwb_sign(key, data, datasz, sig, signame) < 0)
796 return -1;
797
798 if (kwb_verify(key, data, datasz, sig, signame) < 0)
799 return -1;
800
801 return 0;
802}
803
804
6eb20bbf 805static int kwb_dump_fuse_cmds_38x(FILE *out, struct secure_hdr_v1 *sec_hdr)
a1b6b0a9
MS
806{
807 struct hash_v1 kak_pub_hash;
808 struct image_cfg_element *e;
809 unsigned int fuse_line;
810 int i, idx;
811 uint8_t *ptr;
812 uint32_t val;
813 int ret = 0;
814
815 if (!out || !sec_hdr)
816 return -EINVAL;
817
818 ret = kwb_compute_pubkey_hash(&sec_hdr->kak, &kak_pub_hash);
819 if (ret < 0)
820 goto done;
821
822 fprintf(out, "# burn KAK pub key hash\n");
823 ptr = kak_pub_hash.hash;
824 for (fuse_line = 26; fuse_line <= 30; ++fuse_line) {
825 fprintf(out, "fuse prog -y %u 0 ", fuse_line);
826
827 for (i = 4; i-- > 0;)
828 fprintf(out, "%02hx", (ushort)ptr[i]);
829 ptr += 4;
830 fprintf(out, " 00");
831
832 if (fuse_line < 30) {
833 for (i = 3; i-- > 0;)
834 fprintf(out, "%02hx", (ushort)ptr[i]);
835 ptr += 3;
836 } else {
837 fprintf(out, "000000");
838 }
839
840 fprintf(out, " 1\n");
841 }
842
843 fprintf(out, "# burn CSK selection\n");
844
845 idx = image_get_csk_index();
846 if (idx < 0 || idx > 15) {
847 ret = -EINVAL;
848 goto done;
849 }
850 if (idx > 0) {
851 for (fuse_line = 31; fuse_line < 31 + idx; ++fuse_line)
852 fprintf(out, "fuse prog -y %u 0 00000001 00000000 1\n",
853 fuse_line);
854 } else {
855 fprintf(out, "# CSK index is 0; no mods needed\n");
856 }
857
858 e = image_find_option(IMAGE_CFG_BOX_ID);
859 if (e) {
860 fprintf(out, "# set box ID\n");
861 fprintf(out, "fuse prog -y 48 0 %08x 00000000 1\n", e->boxid);
862 }
863
864 e = image_find_option(IMAGE_CFG_FLASH_ID);
865 if (e) {
866 fprintf(out, "# set flash ID\n");
867 fprintf(out, "fuse prog -y 47 0 %08x 00000000 1\n", e->flashid);
868 }
869
870 fprintf(out, "# enable secure mode ");
871 fprintf(out, "(must be the last fuse line written)\n");
872
873 val = 1;
874 e = image_find_option(IMAGE_CFG_SEC_BOOT_DEV);
875 if (!e) {
876 fprintf(stderr, "ERROR: secured mode boot device not given\n");
877 ret = -EINVAL;
878 goto done;
879 }
880
881 if (e->sec_boot_dev > 0xff) {
882 fprintf(stderr, "ERROR: secured mode boot device invalid\n");
883 ret = -EINVAL;
884 goto done;
885 }
886
887 val |= (e->sec_boot_dev << 8);
888
889 fprintf(out, "fuse prog -y 24 0 %08x 0103e0a9 1\n", val);
890
891 fprintf(out, "# lock (unused) fuse lines (0-23)s\n");
892 for (fuse_line = 0; fuse_line < 24; ++fuse_line)
893 fprintf(out, "fuse prog -y %u 2 1\n", fuse_line);
894
895 fprintf(out, "# OK, that's all :-)\n");
896
897done:
898 return ret;
899}
900
901static int kwb_dump_fuse_cmds(struct secure_hdr_v1 *sec_hdr)
902{
903 int ret = 0;
904 struct image_cfg_element *e;
905
906 e = image_find_option(IMAGE_CFG_SEC_FUSE_DUMP);
907 if (!e)
908 return 0;
909
910 if (!strcmp(e->name, "a38x")) {
911 FILE *out = fopen("kwb_fuses_a38x.txt", "w+");
912
f858bb2e
HS
913 if (!out) {
914 fprintf(stderr, "Couldn't open eFuse settings: '%s': %s\n",
915 "kwb_fuses_a38x.txt", strerror(errno));
916 return -ENOENT;
917 }
918
a1b6b0a9
MS
919 kwb_dump_fuse_cmds_38x(out, sec_hdr);
920 fclose(out);
921 goto done;
922 }
923
924 ret = -ENOSYS;
925
926done:
927 return ret;
928}
929
5cad2e6c
T
930static size_t image_headersz_align(size_t headersz, uint8_t blockid)
931{
932 /*
933 * Header needs to be 4-byte aligned, which is already ensured by code
934 * above. Moreover UART images must have header aligned to 128 bytes
935 * (xmodem block size), NAND images to 256 bytes (ECC calculation),
936 * and SATA and SDIO images to 512 bytes (storage block size).
937 * Note that SPI images do not have to have header size aligned
938 * to 256 bytes because it is possible to read from SPI storage from
939 * any offset (read offset does not have to be aligned to block size).
940 */
941 if (blockid == IBR_HDR_UART_ID)
942 return ALIGN(headersz, 128);
943 else if (blockid == IBR_HDR_NAND_ID)
944 return ALIGN(headersz, 256);
945 else if (blockid == IBR_HDR_SATA_ID || blockid == IBR_HDR_SDIO_ID)
946 return ALIGN(headersz, 512);
947 else
948 return headersz;
949}
950
851114be
T
951static size_t image_headersz_v0(int *hasext)
952{
953 size_t headersz;
954
955 headersz = sizeof(struct main_hdr_v0);
956 if (image_count_options(IMAGE_CFG_DATA) > 0) {
957 headersz += sizeof(struct ext_hdr_v0);
958 if (hasext)
959 *hasext = 1;
960 }
961
962 return image_headersz_align(headersz, image_get_bootfrom());
963}
964
4acd2d24
SR
965static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
966 int payloadsz)
aa0c7a86 967{
4acd2d24
SR
968 struct image_cfg_element *e;
969 size_t headersz;
970 struct main_hdr_v0 *main_hdr;
885fba15 971 uint8_t *image;
4acd2d24
SR
972 int has_ext = 0;
973
974 /*
975 * Calculate the size of the header and the size of the
976 * payload
977 */
851114be 978 headersz = image_headersz_v0(&has_ext);
4acd2d24 979
4acd2d24
SR
980 image = malloc(headersz);
981 if (!image) {
982 fprintf(stderr, "Cannot allocate memory for image\n");
983 return NULL;
aa0c7a86 984 }
aa0c7a86 985
4acd2d24
SR
986 memset(image, 0, headersz);
987
885fba15 988 main_hdr = (struct main_hdr_v0 *)image;
4acd2d24
SR
989
990 /* Fill in the main header */
a8840dce 991 main_hdr->blocksize =
e23ad5d5 992 cpu_to_le32(payloadsz);
a8840dce 993 main_hdr->srcaddr = cpu_to_le32(headersz);
4acd2d24 994 main_hdr->ext = has_ext;
01bdac6d 995 main_hdr->version = 0;
a8840dce
RP
996 main_hdr->destaddr = cpu_to_le32(params->addr);
997 main_hdr->execaddr = cpu_to_le32(params->ep);
d1547b36 998 main_hdr->blockid = image_get_bootfrom();
4acd2d24 999
4acd2d24
SR
1000 e = image_find_option(IMAGE_CFG_NAND_ECC_MODE);
1001 if (e)
1002 main_hdr->nandeccmode = e->nandeccmode;
a6661a0e
T
1003 e = image_find_option(IMAGE_CFG_NAND_BLKSZ);
1004 if (e)
1005 main_hdr->nandblocksize = e->nandblksz / (64 * 1024);
4acd2d24
SR
1006 e = image_find_option(IMAGE_CFG_NAND_PAGESZ);
1007 if (e)
a8840dce 1008 main_hdr->nandpagesize = cpu_to_le16(e->nandpagesz);
a6661a0e
T
1009 e = image_find_option(IMAGE_CFG_NAND_BADBLK_LOCATION);
1010 if (e)
1011 main_hdr->nandbadblklocation = e->nandbadblklocation;
4acd2d24
SR
1012 main_hdr->checksum = image_checksum8(image,
1013 sizeof(struct main_hdr_v0));
1014
5c61710c
T
1015 /*
1016 * For SATA srcaddr is specified in number of sectors starting from
1017 * sector 0. The main header is stored at sector number 1.
1018 * This expects the sector size to be 512 bytes.
1019 * Header size is already aligned.
1020 */
1021 if (main_hdr->blockid == IBR_HDR_SATA_ID)
1022 main_hdr->srcaddr = cpu_to_le32(headersz / 512 + 1);
1023
1024 /*
1025 * For SDIO srcaddr is specified in number of sectors starting from
1026 * sector 0. The main header is stored at sector number 0.
1027 * This expects sector size to be 512 bytes.
1028 * Header size is already aligned.
1029 */
1030 if (main_hdr->blockid == IBR_HDR_SDIO_ID)
1031 main_hdr->srcaddr = cpu_to_le32(headersz / 512);
1032
1033 /* For PCIe srcaddr is not used and must be set to 0xFFFFFFFF. */
1034 if (main_hdr->blockid == IBR_HDR_PEX_ID)
1035 main_hdr->srcaddr = cpu_to_le32(0xFFFFFFFF);
1036
4acd2d24
SR
1037 /* Generate the ext header */
1038 if (has_ext) {
e89016c4 1039 struct ext_hdr_v0 *ext_hdr;
4acd2d24
SR
1040 int cfgi, datai;
1041
885fba15
MS
1042 ext_hdr = (struct ext_hdr_v0 *)
1043 (image + sizeof(struct main_hdr_v0));
a8840dce 1044 ext_hdr->offset = cpu_to_le32(0x40);
4acd2d24
SR
1045
1046 for (cfgi = 0, datai = 0; cfgi < cfgn; cfgi++) {
1047 e = &image_cfg[cfgi];
1048 if (e->type != IMAGE_CFG_DATA)
1049 continue;
1050
a8840dce
RP
1051 ext_hdr->rcfg[datai].raddr =
1052 cpu_to_le32(e->regdata.raddr);
1053 ext_hdr->rcfg[datai].rdata =
1054 cpu_to_le32(e->regdata.rdata);
4acd2d24
SR
1055 datai++;
1056 }
1057
1058 ext_hdr->checksum = image_checksum8(ext_hdr,
1059 sizeof(struct ext_hdr_v0));
1060 }
1061
1062 *imagesz = headersz;
1063 return image;
aa0c7a86
PW
1064}
1065
e93cf53f 1066static size_t image_headersz_v1(int *hasext)
4acd2d24 1067{
0aca27ea 1068 struct image_cfg_element *e;
02ba70ad 1069 unsigned int count;
4acd2d24 1070 size_t headersz;
0aca27ea
T
1071 int cpu_sheeva;
1072 struct stat s;
d9fb82c5 1073 int cfgi;
0aca27ea 1074 int ret;
4acd2d24
SR
1075
1076 /*
1077 * Calculate the size of the header and the size of the
1078 * payload
1079 */
1080 headersz = sizeof(struct main_hdr_v1);
1081
e58f08b4
T
1082 if (image_get_csk_index() >= 0) {
1083 headersz += sizeof(struct secure_hdr_v1);
1084 if (hasext)
1085 *hasext = 1;
1086 }
1087
0aca27ea
T
1088 cpu_sheeva = image_is_cpu_sheeva();
1089
d737d5d2
T
1090 count = 0;
1091 for (cfgi = 0; cfgi < cfgn; cfgi++) {
1092 e = &image_cfg[cfgi];
1093
1094 if (e->type == IMAGE_CFG_DATA)
1095 count++;
1096
3db9c417
T
1097 if (e->type == IMAGE_CFG_DATA_DELAY ||
1098 (e->type == IMAGE_CFG_BINARY && count > 0)) {
d737d5d2
T
1099 headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4;
1100 count = 0;
1101 }
4acd2d24 1102
0aca27ea 1103 if (e->type != IMAGE_CFG_BINARY)
d9fb82c5
T
1104 continue;
1105
0aca27ea 1106 ret = stat(e->binary.file, &s);
4acd2d24 1107 if (ret < 0) {
e5f1a586
AB
1108 char cwd[PATH_MAX];
1109 char *dir = cwd;
1110
1111 memset(cwd, 0, sizeof(cwd));
1112 if (!getcwd(cwd, sizeof(cwd))) {
1113 dir = "current working directory";
1114 perror("getcwd() failed");
1115 }
1116
4acd2d24
SR
1117 fprintf(stderr,
1118 "Didn't find the file '%s' in '%s' which is mandatory to generate the image\n"
1119 "This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n"
107d587f 1120 "image for your board. Use 'dumpimage -T kwbimage -p 1' to extract it from an existing image.\n",
0aca27ea 1121 e->binary.file, dir);
4acd2d24
SR
1122 return 0;
1123 }
aa0c7a86 1124
e58f08b4 1125 headersz += sizeof(struct opt_hdr_v1) + sizeof(uint32_t) +
0aca27ea
T
1126 (e->binary.nargs) * sizeof(uint32_t);
1127
1128 if (e->binary.loadaddr) {
1129 /*
1130 * BootROM loads kwbimage header (in which the
1131 * executable code is also stored) to address
1132 * 0x40004000 or 0x40000000. Thus there is
1133 * restriction for the load address of the N-th
1134 * BINARY image.
1135 */
1136 unsigned int base_addr, low_addr, high_addr;
1137
1138 base_addr = cpu_sheeva ? 0x40004000 : 0x40000000;
1139 low_addr = base_addr + headersz;
1140 high_addr = low_addr +
1141 (BINARY_MAX_ARGS - e->binary.nargs) * sizeof(uint32_t);
1142
1143 if (cpu_sheeva && e->binary.loadaddr % 16) {
1144 fprintf(stderr,
1145 "Invalid LOAD_ADDRESS 0x%08x for BINARY %s with %d args.\n"
1146 "Address for CPU SHEEVA must be 16-byte aligned.\n",
1147 e->binary.loadaddr, e->binary.file, e->binary.nargs);
1148 return 0;
1149 }
1150
1151 if (e->binary.loadaddr % 4 || e->binary.loadaddr < low_addr ||
1152 e->binary.loadaddr > high_addr) {
1153 fprintf(stderr,
1154 "Invalid LOAD_ADDRESS 0x%08x for BINARY %s with %d args.\n"
1155 "Address must be 4-byte aligned and in range 0x%08x-0x%08x.\n",
1156 e->binary.loadaddr, e->binary.file,
1157 e->binary.nargs, low_addr, high_addr);
1158 return 0;
1159 }
1160 headersz = e->binary.loadaddr - base_addr;
bdf8c9f2 1161 } else if (cpu_sheeva) {
0aca27ea 1162 headersz = ALIGN(headersz, 16);
bdf8c9f2
T
1163 } else {
1164 headersz = ALIGN(headersz, 4);
0aca27ea
T
1165 }
1166
e58f08b4 1167 headersz += ALIGN(s.st_size, 4) + sizeof(uint32_t);
a1b6b0a9
MS
1168 if (hasext)
1169 *hasext = 1;
1170 }
a1b6b0a9 1171
0aca27ea
T
1172 if (count > 0)
1173 headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4;
1174
5cad2e6c 1175 return image_headersz_align(headersz, image_get_bootfrom());
4acd2d24 1176}
aa0c7a86 1177
6eb20bbf
T
1178static int add_binary_header_v1(uint8_t **cur, uint8_t **next_ext,
1179 struct image_cfg_element *binarye,
1180 struct main_hdr_v1 *main_hdr)
79066ef8 1181{
d9fb82c5 1182 struct opt_hdr_v1 *hdr = (struct opt_hdr_v1 *)*cur;
0aca27ea 1183 uint32_t base_addr;
e58f08b4
T
1184 uint32_t add_args;
1185 uint32_t offset;
79066ef8
MS
1186 uint32_t *args;
1187 size_t binhdrsz;
0aca27ea 1188 int cpu_sheeva;
79066ef8
MS
1189 struct stat s;
1190 int argi;
1191 FILE *bin;
1192 int ret;
1193
79066ef8
MS
1194 hdr->headertype = OPT_HDR_V1_BINARY_TYPE;
1195
1196 bin = fopen(binarye->binary.file, "r");
1197 if (!bin) {
1198 fprintf(stderr, "Cannot open binary file %s\n",
1199 binarye->binary.file);
1200 return -1;
1201 }
1202
1f6c8a57
MS
1203 if (fstat(fileno(bin), &s)) {
1204 fprintf(stderr, "Cannot stat binary file %s\n",
1205 binarye->binary.file);
1206 goto err_close;
1207 }
79066ef8 1208
d9fb82c5 1209 *cur += sizeof(struct opt_hdr_v1);
79066ef8 1210
d9fb82c5 1211 args = (uint32_t *)*cur;
79066ef8
MS
1212 *args = cpu_to_le32(binarye->binary.nargs);
1213 args++;
1214 for (argi = 0; argi < binarye->binary.nargs; argi++)
1215 args[argi] = cpu_to_le32(binarye->binary.args[argi]);
1216
d9fb82c5 1217 *cur += (binarye->binary.nargs + 1) * sizeof(uint32_t);
79066ef8 1218
e58f08b4 1219 /*
bdf8c9f2
T
1220 * ARM executable code inside the BIN header on platforms with Sheeva
1221 * CPU (A370 and AXP) must always be aligned with the 128-bit boundary.
0aca27ea
T
1222 * In the case when this code is not position independent (e.g. ARM
1223 * SPL), it must be placed at fixed load and execute address.
e58f08b4
T
1224 * This requirement can be met by inserting dummy arguments into
1225 * BIN header, if needed.
1226 */
0aca27ea
T
1227 cpu_sheeva = image_is_cpu_sheeva();
1228 base_addr = cpu_sheeva ? 0x40004000 : 0x40000000;
e58f08b4 1229 offset = *cur - (uint8_t *)main_hdr;
0aca27ea
T
1230 if (binarye->binary.loadaddr)
1231 add_args = (binarye->binary.loadaddr - base_addr - offset) / sizeof(uint32_t);
bdf8c9f2 1232 else if (cpu_sheeva)
0aca27ea 1233 add_args = ((16 - offset % 16) % 16) / sizeof(uint32_t);
bdf8c9f2
T
1234 else
1235 add_args = 0;
e58f08b4
T
1236 if (add_args) {
1237 *(args - 1) = cpu_to_le32(binarye->binary.nargs + add_args);
1238 *cur += add_args * sizeof(uint32_t);
1239 }
1240
d9fb82c5 1241 ret = fread(*cur, s.st_size, 1, bin);
79066ef8
MS
1242 if (ret != 1) {
1243 fprintf(stderr,
1244 "Could not read binary image %s\n",
1245 binarye->binary.file);
1f6c8a57 1246 goto err_close;
79066ef8
MS
1247 }
1248
1249 fclose(bin);
1250
d9fb82c5 1251 *cur += ALIGN(s.st_size, 4);
79066ef8 1252
d9fb82c5
T
1253 *((uint32_t *)*cur) = 0x00000000;
1254 **next_ext = 1;
1255 *next_ext = *cur;
79066ef8 1256
d9fb82c5 1257 *cur += sizeof(uint32_t);
79066ef8 1258
e58f08b4
T
1259 binhdrsz = sizeof(struct opt_hdr_v1) +
1260 (binarye->binary.nargs + add_args + 2) * sizeof(uint32_t) +
1261 ALIGN(s.st_size, 4);
1262 hdr->headersz_lsb = cpu_to_le16(binhdrsz & 0xFFFF);
1263 hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16;
1264
79066ef8 1265 return 0;
1f6c8a57
MS
1266
1267err_close:
1268 fclose(bin);
1269
1270 return -1;
79066ef8
MS
1271}
1272
6eb20bbf 1273static int export_pub_kak_hash(RSA *kak, struct secure_hdr_v1 *secure_hdr)
a1b6b0a9
MS
1274{
1275 FILE *hashf;
1276 int res;
1277
1278 hashf = fopen("pub_kak_hash.txt", "w");
f858bb2e
HS
1279 if (!hashf) {
1280 fprintf(stderr, "Couldn't open hash file: '%s': %s\n",
1281 "pub_kak_hash.txt", strerror(errno));
1282 return 1;
1283 }
a1b6b0a9
MS
1284
1285 res = kwb_export_pubkey(kak, &secure_hdr->kak, hashf, "KAK");
1286
1287 fclose(hashf);
1288
1289 return res < 0 ? 1 : 0;
1290}
1291
6eb20bbf
T
1292static int kwb_sign_csk_with_kak(struct image_tool_params *params,
1293 struct secure_hdr_v1 *secure_hdr, RSA *csk)
a1b6b0a9
MS
1294{
1295 RSA *kak = NULL;
1296 RSA *kak_pub = NULL;
1297 int csk_idx = image_get_csk_index();
1298 struct sig_v1 tmp_sig;
1299
f0317d78 1300 if (csk_idx < 0 || csk_idx > 15) {
a1b6b0a9
MS
1301 fprintf(stderr, "Invalid CSK index %d\n", csk_idx);
1302 return 1;
1303 }
1304
1305 if (kwb_load_kak(params, &kak) < 0)
1306 return 1;
1307
1308 if (export_pub_kak_hash(kak, secure_hdr))
1309 return 1;
1310
1311 if (kwb_import_pubkey(&kak_pub, &secure_hdr->kak, "KAK") < 0)
1312 return 1;
1313
1314 if (kwb_export_pubkey(csk, &secure_hdr->csk[csk_idx], NULL, "CSK") < 0)
1315 return 1;
1316
1317 if (kwb_sign_and_verify(kak, &secure_hdr->csk,
1318 sizeof(secure_hdr->csk) +
1319 sizeof(secure_hdr->csksig),
1320 &tmp_sig, "CSK") < 0)
1321 return 1;
1322
1323 if (kwb_verify(kak_pub, &secure_hdr->csk,
1324 sizeof(secure_hdr->csk) +
1325 sizeof(secure_hdr->csksig),
1326 &tmp_sig, "CSK (2)") < 0)
1327 return 1;
1328
1329 secure_hdr->csksig = tmp_sig;
1330
1331 return 0;
1332}
1333
6eb20bbf
T
1334static int add_secure_header_v1(struct image_tool_params *params, uint8_t *ptr,
1335 int payloadsz, size_t headersz, uint8_t *image,
1336 struct secure_hdr_v1 *secure_hdr)
a1b6b0a9
MS
1337{
1338 struct image_cfg_element *e_jtagdelay;
1339 struct image_cfg_element *e_boxid;
1340 struct image_cfg_element *e_flashid;
1341 RSA *csk = NULL;
1342 unsigned char *image_ptr;
1343 size_t image_size;
1344 struct sig_v1 tmp_sig;
1345 bool specialized_img = image_get_spezialized_img();
1346
1347 kwb_msg("Create secure header content\n");
1348
1349 e_jtagdelay = image_find_option(IMAGE_CFG_JTAG_DELAY);
1350 e_boxid = image_find_option(IMAGE_CFG_BOX_ID);
1351 e_flashid = image_find_option(IMAGE_CFG_FLASH_ID);
1352
1353 if (kwb_load_csk(params, &csk) < 0)
1354 return 1;
1355
1356 secure_hdr->headertype = OPT_HDR_V1_SECURE_TYPE;
1357 secure_hdr->headersz_msb = 0;
1358 secure_hdr->headersz_lsb = cpu_to_le16(sizeof(struct secure_hdr_v1));
1359 if (e_jtagdelay)
1360 secure_hdr->jtag_delay = e_jtagdelay->jtag_delay;
1361 if (e_boxid && specialized_img)
1362 secure_hdr->boxid = cpu_to_le32(e_boxid->boxid);
1363 if (e_flashid && specialized_img)
1364 secure_hdr->flashid = cpu_to_le32(e_flashid->flashid);
1365
1366 if (kwb_sign_csk_with_kak(params, secure_hdr, csk))
1367 return 1;
1368
1369 image_ptr = ptr + headersz;
1370 image_size = payloadsz - headersz;
1371
1372 if (kwb_sign_and_verify(csk, image_ptr, image_size,
1373 &secure_hdr->imgsig, "image") < 0)
1374 return 1;
1375
1376 if (kwb_sign_and_verify(csk, image, headersz, &tmp_sig, "header") < 0)
1377 return 1;
1378
1379 secure_hdr->hdrsig = tmp_sig;
1380
1381 kwb_dump_fuse_cmds(secure_hdr);
1382
1383 return 0;
1384}
a1b6b0a9 1385
9ac1def0
T
1386static void finish_register_set_header_v1(uint8_t **cur, uint8_t **next_ext,
1387 struct register_set_hdr_v1 *register_set_hdr,
1388 int *datai, uint8_t delay)
1389{
1390 int size = sizeof(struct register_set_hdr_v1) + 8 * (*datai) + 4;
1391
1392 register_set_hdr->headertype = OPT_HDR_V1_REGISTER_TYPE;
1393 register_set_hdr->headersz_lsb = cpu_to_le16(size & 0xFFFF);
1394 register_set_hdr->headersz_msb = size >> 16;
1395 register_set_hdr->data[*datai].last_entry.delay = delay;
1396 *cur += size;
1397 **next_ext = 1;
1398 *next_ext = &register_set_hdr->data[*datai].last_entry.next;
1399 *datai = 0;
1400}
1401
4acd2d24 1402static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
a1b6b0a9 1403 uint8_t *ptr, int payloadsz)
4acd2d24 1404{
79066ef8 1405 struct image_cfg_element *e;
4acd2d24 1406 struct main_hdr_v1 *main_hdr;
2b0980c2 1407 struct opt_hdr_v1 *ohdr;
02ba70ad 1408 struct register_set_hdr_v1 *register_set_hdr;
a1b6b0a9 1409 struct secure_hdr_v1 *secure_hdr = NULL;
4acd2d24 1410 size_t headersz;
885fba15 1411 uint8_t *image, *cur;
4acd2d24 1412 int hasext = 0;
a1b6b0a9 1413 uint8_t *next_ext = NULL;
9ac1def0 1414 int cfgi, datai;
3db9c417 1415 uint8_t delay;
4acd2d24
SR
1416
1417 /*
1418 * Calculate the size of the header and the size of the
1419 * payload
1420 */
e93cf53f 1421 headersz = image_headersz_v1(&hasext);
4acd2d24
SR
1422 if (headersz == 0)
1423 return NULL;
1424
1425 image = malloc(headersz);
1426 if (!image) {
1427 fprintf(stderr, "Cannot allocate memory for image\n");
1428 return NULL;
1429 }
aa0c7a86 1430
4acd2d24
SR
1431 memset(image, 0, headersz);
1432
885fba15 1433 main_hdr = (struct main_hdr_v1 *)image;
a1b6b0a9
MS
1434 cur = image;
1435 cur += sizeof(struct main_hdr_v1);
1436 next_ext = &main_hdr->ext;
4acd2d24
SR
1437
1438 /* Fill the main header */
a8840dce 1439 main_hdr->blocksize =
e23ad5d5 1440 cpu_to_le32(payloadsz);
a8840dce 1441 main_hdr->headersz_lsb = cpu_to_le16(headersz & 0xFFFF);
4acd2d24 1442 main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16;
cc3443ff 1443 main_hdr->destaddr = cpu_to_le32(params->addr);
a8840dce
RP
1444 main_hdr->execaddr = cpu_to_le32(params->ep);
1445 main_hdr->srcaddr = cpu_to_le32(headersz);
4acd2d24
SR
1446 main_hdr->ext = hasext;
1447 main_hdr->version = 1;
d1547b36
T
1448 main_hdr->blockid = image_get_bootfrom();
1449
4acd2d24
SR
1450 e = image_find_option(IMAGE_CFG_NAND_BLKSZ);
1451 if (e)
1452 main_hdr->nandblocksize = e->nandblksz / (64 * 1024);
2fdba4f6
T
1453 e = image_find_option(IMAGE_CFG_NAND_PAGESZ);
1454 if (e)
1455 main_hdr->nandpagesize = cpu_to_le16(e->nandpagesz);
4acd2d24
SR
1456 e = image_find_option(IMAGE_CFG_NAND_BADBLK_LOCATION);
1457 if (e)
1458 main_hdr->nandbadblklocation = e->nandbadblklocation;
4bdb5479
CP
1459 e = image_find_option(IMAGE_CFG_BAUDRATE);
1460 if (e)
12f2c03f
T
1461 main_hdr->options |= baudrate_to_option(e->baudrate);
1462 e = image_find_option(IMAGE_CFG_UART_PORT);
1463 if (e)
1464 main_hdr->options |= (e->uart_port & 3) << 3;
1465 e = image_find_option(IMAGE_CFG_UART_MPP);
1466 if (e)
1467 main_hdr->options |= (e->uart_mpp & 7) << 5;
2611c05e
CP
1468 e = image_find_option(IMAGE_CFG_DEBUG);
1469 if (e)
1470 main_hdr->flags = e->debug ? 0x1 : 0;
4acd2d24 1471
501a54a2
T
1472 /*
1473 * For SATA srcaddr is specified in number of sectors starting from
1474 * sector 0. The main header is stored at sector number 1.
1475 * This expects the sector size to be 512 bytes.
1476 * Header size is already aligned.
1477 */
1478 if (main_hdr->blockid == IBR_HDR_SATA_ID)
1479 main_hdr->srcaddr = cpu_to_le32(headersz / 512 + 1);
1480
1481 /*
1482 * For SDIO srcaddr is specified in number of sectors starting from
1483 * sector 0. The main header is stored at sector number 0.
1484 * This expects sector size to be 512 bytes.
1485 * Header size is already aligned.
1486 */
1487 if (main_hdr->blockid == IBR_HDR_SDIO_ID)
1488 main_hdr->srcaddr = cpu_to_le32(headersz / 512);
1489
1490 /* For PCIe srcaddr is not used and must be set to 0xFFFFFFFF. */
1491 if (main_hdr->blockid == IBR_HDR_PEX_ID)
1492 main_hdr->srcaddr = cpu_to_le32(0xFFFFFFFF);
1493
a1b6b0a9
MS
1494 if (image_get_csk_index() >= 0) {
1495 /*
1496 * only reserve the space here; we fill the header later since
1497 * we need the header to be complete to compute the signatures
1498 */
1499 secure_hdr = (struct secure_hdr_v1 *)cur;
1500 cur += sizeof(struct secure_hdr_v1);
d9fb82c5 1501 *next_ext = 1;
a1b6b0a9
MS
1502 next_ext = &secure_hdr->next;
1503 }
a1b6b0a9 1504
02ba70ad 1505 datai = 0;
02ba70ad
T
1506 for (cfgi = 0; cfgi < cfgn; cfgi++) {
1507 e = &image_cfg[cfgi];
f63c583f 1508 if (e->type != IMAGE_CFG_DATA &&
3db9c417
T
1509 e->type != IMAGE_CFG_DATA_DELAY &&
1510 e->type != IMAGE_CFG_BINARY)
02ba70ad 1511 continue;
3db9c417 1512
d737d5d2
T
1513 if (datai == 0)
1514 register_set_hdr = (struct register_set_hdr_v1 *)cur;
3db9c417
T
1515
1516 /* If delay is not specified, use the smallest possible value. */
1517 if (e->type == IMAGE_CFG_DATA_DELAY)
1518 delay = e->regdata_delay;
1519 else
1520 delay = REGISTER_SET_HDR_OPT_DELAY_MS(0);
1521
1522 /*
1523 * DATA_DELAY command is the last entry in the register set
1524 * header and BINARY command inserts new binary header.
1525 * Therefore BINARY command requires to finish register set
1526 * header if some DATA command was specified. And DATA_DELAY
1527 * command automatically finish register set header even when
1528 * there was no DATA command.
1529 */
1530 if (e->type == IMAGE_CFG_DATA_DELAY ||
1531 (e->type == IMAGE_CFG_BINARY && datai != 0))
9ac1def0 1532 finish_register_set_header_v1(&cur, &next_ext, register_set_hdr,
3db9c417
T
1533 &datai, delay);
1534
1535 if (e->type == IMAGE_CFG_DATA) {
1536 register_set_hdr->data[datai].entry.address =
1537 cpu_to_le32(e->regdata.raddr);
1538 register_set_hdr->data[datai].entry.value =
1539 cpu_to_le32(e->regdata.rdata);
1540 datai++;
1541 }
1542
1543 if (e->type == IMAGE_CFG_BINARY) {
1544 if (add_binary_header_v1(&cur, &next_ext, e, main_hdr))
1545 return NULL;
f63c583f 1546 }
02ba70ad
T
1547 }
1548 if (datai != 0) {
9ac1def0 1549 /* Set delay to the smallest possible value. */
3db9c417 1550 delay = REGISTER_SET_HDR_OPT_DELAY_MS(0);
9ac1def0 1551 finish_register_set_header_v1(&cur, &next_ext, register_set_hdr,
3db9c417 1552 &datai, delay);
d9fb82c5 1553 }
4acd2d24 1554
e23ad5d5 1555 if (secure_hdr && add_secure_header_v1(params, ptr, payloadsz + headersz,
a1b6b0a9
MS
1556 headersz, image, secure_hdr))
1557 return NULL;
a1b6b0a9 1558
4acd2d24 1559 *imagesz = headersz;
2b0980c2
T
1560
1561 /* Fill the real header size without padding into the main header */
1562 headersz = sizeof(*main_hdr);
1563 for_each_opt_hdr_v1 (ohdr, main_hdr)
1564 headersz += opt_hdr_v1_size(ohdr);
1565 main_hdr->headersz_lsb = cpu_to_le16(headersz & 0xFFFF);
1566 main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16;
1567
9203c738
PB
1568 /* Calculate and set the header checksum */
1569 main_hdr->checksum = image_checksum8(main_hdr, headersz);
1570
4acd2d24
SR
1571 return image;
1572}
1573
6eb20bbf 1574static int recognize_keyword(char *keyword)
4991b4f7
MS
1575{
1576 int kw_id;
1577
1578 for (kw_id = 1; kw_id < IMAGE_CFG_COUNT; ++kw_id)
1579 if (!strcmp(keyword, id_strs[kw_id]))
1580 return kw_id;
1581
1582 return 0;
1583}
1584
4acd2d24
SR
1585static int image_create_config_parse_oneline(char *line,
1586 struct image_cfg_element *el)
1587{
4991b4f7
MS
1588 char *keyword, *saveptr, *value1, *value2;
1589 char delimiters[] = " \t";
1590 int keyword_id, ret, argi;
1591 char *unknown_msg = "Ignoring unknown line '%s'\n";
1592
1593 keyword = strtok_r(line, delimiters, &saveptr);
1594 keyword_id = recognize_keyword(keyword);
1595
1596 if (!keyword_id) {
1597 fprintf(stderr, unknown_msg, line);
1598 return 0;
1599 }
4acd2d24 1600
4991b4f7 1601 el->type = keyword_id;
94490a4a 1602
4991b4f7
MS
1603 value1 = strtok_r(NULL, delimiters, &saveptr);
1604
1605 if (!value1) {
1606 fprintf(stderr, "Parameter missing in line '%s'\n", line);
1607 return -1;
1608 }
1609
1610 switch (keyword_id) {
1611 case IMAGE_CFG_VERSION:
1612 el->version = atoi(value1);
1613 break;
af49605b
T
1614 case IMAGE_CFG_CPU:
1615 if (strcmp(value1, "FEROCEON") == 0)
1616 el->cpu_sheeva = 0;
1617 else if (strcmp(value1, "SHEEVA") == 0)
1618 el->cpu_sheeva = 1;
1619 else if (strcmp(value1, "A9") == 0)
1620 el->cpu_sheeva = 0;
1621 else {
1622 fprintf(stderr, "Invalid CPU %s\n", value1);
1623 return -1;
1624 }
1625 break;
4991b4f7
MS
1626 case IMAGE_CFG_BOOT_FROM:
1627 ret = image_boot_mode_id(value1);
94490a4a 1628
f411b8f2 1629 if (ret < 0) {
4991b4f7 1630 fprintf(stderr, "Invalid boot media '%s'\n", value1);
4acd2d24
SR
1631 return -1;
1632 }
f411b8f2 1633 el->bootfrom = ret;
4991b4f7
MS
1634 break;
1635 case IMAGE_CFG_NAND_BLKSZ:
1636 el->nandblksz = strtoul(value1, NULL, 16);
1637 break;
1638 case IMAGE_CFG_NAND_BADBLK_LOCATION:
1639 el->nandbadblklocation = strtoul(value1, NULL, 16);
1640 break;
1641 case IMAGE_CFG_NAND_ECC_MODE:
1642 ret = image_nand_ecc_mode_id(value1);
94490a4a 1643
f411b8f2 1644 if (ret < 0) {
4991b4f7 1645 fprintf(stderr, "Invalid NAND ECC mode '%s'\n", value1);
4acd2d24
SR
1646 return -1;
1647 }
f411b8f2 1648 el->nandeccmode = ret;
4991b4f7
MS
1649 break;
1650 case IMAGE_CFG_NAND_PAGESZ:
1651 el->nandpagesz = strtoul(value1, NULL, 16);
1652 break;
1653 case IMAGE_CFG_BINARY:
1654 argi = 0;
1655
1656 el->binary.file = strdup(value1);
4acd2d24 1657 while (1) {
4991b4f7 1658 char *value = strtok_r(NULL, delimiters, &saveptr);
0aca27ea 1659 char *endptr;
4991b4f7 1660
4acd2d24
SR
1661 if (!value)
1662 break;
0aca27ea
T
1663
1664 if (!strcmp(value, "LOAD_ADDRESS")) {
1665 value = strtok_r(NULL, delimiters, &saveptr);
1666 if (!value) {
1667 fprintf(stderr,
1668 "Missing address argument for BINARY LOAD_ADDRESS\n");
1669 return -1;
1670 }
1671 el->binary.loadaddr = strtoul(value, &endptr, 16);
1672 if (*endptr) {
1673 fprintf(stderr,
1674 "Invalid argument '%s' for BINARY LOAD_ADDRESS\n",
1675 value);
1676 return -1;
1677 }
1678 value = strtok_r(NULL, delimiters, &saveptr);
1679 if (value) {
1680 fprintf(stderr,
1681 "Unexpected argument '%s' after BINARY LOAD_ADDRESS\n",
1682 value);
1683 return -1;
1684 }
1685 break;
1686 }
1687
1688 el->binary.args[argi] = strtoul(value, &endptr, 16);
1689 if (*endptr) {
1690 fprintf(stderr, "Invalid argument '%s' for BINARY\n", value);
1691 return -1;
1692 }
4acd2d24
SR
1693 argi++;
1694 if (argi >= BINARY_MAX_ARGS) {
1695 fprintf(stderr,
4991b4f7 1696 "Too many arguments for BINARY\n");
4acd2d24 1697 return -1;
aa0c7a86 1698 }
aa0c7a86 1699 }
4acd2d24 1700 el->binary.nargs = argi;
4991b4f7
MS
1701 break;
1702 case IMAGE_CFG_DATA:
1703 value2 = strtok_r(NULL, delimiters, &saveptr);
4acd2d24
SR
1704
1705 if (!value1 || !value2) {
1706 fprintf(stderr,
1707 "Invalid number of arguments for DATA\n");
1708 return -1;
1709 }
1710
4acd2d24
SR
1711 el->regdata.raddr = strtoul(value1, NULL, 16);
1712 el->regdata.rdata = strtoul(value2, NULL, 16);
4991b4f7 1713 break;
f63c583f
T
1714 case IMAGE_CFG_DATA_DELAY:
1715 if (!strcmp(value1, "SDRAM_SETUP"))
1716 el->regdata_delay = REGISTER_SET_HDR_OPT_DELAY_SDRAM_SETUP;
1717 else
1718 el->regdata_delay = REGISTER_SET_HDR_OPT_DELAY_MS(strtoul(value1, NULL, 10));
fdcae261
T
1719 if (el->regdata_delay > 255) {
1720 fprintf(stderr, "Maximal DATA_DELAY is 255\n");
1721 return -1;
1722 }
f63c583f 1723 break;
4991b4f7
MS
1724 case IMAGE_CFG_BAUDRATE:
1725 el->baudrate = strtoul(value1, NULL, 10);
1726 break;
12f2c03f
T
1727 case IMAGE_CFG_UART_PORT:
1728 el->uart_port = strtoul(value1, NULL, 16);
1729 break;
1730 case IMAGE_CFG_UART_MPP:
1731 el->uart_mpp = strtoul(value1, NULL, 16);
1732 break;
4991b4f7
MS
1733 case IMAGE_CFG_DEBUG:
1734 el->debug = strtoul(value1, NULL, 10);
1735 break;
a1b6b0a9
MS
1736 case IMAGE_CFG_KAK:
1737 el->key_name = strdup(value1);
1738 break;
1739 case IMAGE_CFG_CSK:
1740 el->key_name = strdup(value1);
1741 break;
1742 case IMAGE_CFG_CSK_INDEX:
1743 el->csk_idx = strtol(value1, NULL, 0);
1744 break;
1745 case IMAGE_CFG_JTAG_DELAY:
1746 el->jtag_delay = strtoul(value1, NULL, 0);
1747 break;
1748 case IMAGE_CFG_BOX_ID:
1749 el->boxid = strtoul(value1, NULL, 0);
1750 break;
1751 case IMAGE_CFG_FLASH_ID:
1752 el->flashid = strtoul(value1, NULL, 0);
1753 break;
1754 case IMAGE_CFG_SEC_SPECIALIZED_IMG:
1755 el->sec_specialized_img = true;
1756 break;
1757 case IMAGE_CFG_SEC_COMMON_IMG:
1758 el->sec_specialized_img = false;
1759 break;
1760 case IMAGE_CFG_SEC_BOOT_DEV:
1761 el->sec_boot_dev = strtoul(value1, NULL, 0);
1762 break;
1763 case IMAGE_CFG_SEC_FUSE_DUMP:
1764 el->name = strdup(value1);
1765 break;
4991b4f7
MS
1766 default:
1767 fprintf(stderr, unknown_msg, line);
aa0c7a86 1768 }
aa0c7a86 1769
4acd2d24
SR
1770 return 0;
1771}
aa0c7a86
PW
1772
1773/*
4acd2d24
SR
1774 * Parse the configuration file 'fcfg' into the array of configuration
1775 * elements 'image_cfg', and return the number of configuration
1776 * elements in 'cfgn'.
aa0c7a86 1777 */
4acd2d24
SR
1778static int image_create_config_parse(FILE *fcfg)
1779{
1780 int ret;
1781 int cfgi = 0;
1782
1783 /* Parse the configuration file */
1784 while (!feof(fcfg)) {
1785 char *line;
1786 char buf[256];
1787
1788 /* Read the current line */
1789 memset(buf, 0, sizeof(buf));
1790 line = fgets(buf, sizeof(buf), fcfg);
1791 if (!line)
1792 break;
1793
1794 /* Ignore useless lines */
1795 if (line[0] == '\n' || line[0] == '#')
1796 continue;
1797
1798 /* Strip final newline */
1799 if (line[strlen(line) - 1] == '\n')
1800 line[strlen(line) - 1] = 0;
1801
1802 /* Parse the current line */
1803 ret = image_create_config_parse_oneline(line,
1804 &image_cfg[cfgi]);
1805 if (ret)
1806 return ret;
1807
1808 cfgi++;
1809
1810 if (cfgi >= IMAGE_CFG_ELEMENT_MAX) {
1811 fprintf(stderr,
1812 "Too many configuration elements in .cfg file\n");
1813 return -1;
1814 }
1815 }
1816
1817 cfgn = cfgi;
1818 return 0;
1819}
1820
1821static int image_get_version(void)
1822{
1823 struct image_cfg_element *e;
1824
1825 e = image_find_option(IMAGE_CFG_VERSION);
1826 if (!e)
1827 return -1;
1828
1829 return e->version;
1830}
1831
4acd2d24 1832static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
f86ed6a8 1833 struct image_tool_params *params)
aa0c7a86 1834{
4acd2d24
SR
1835 FILE *fcfg;
1836 void *image = NULL;
1837 int version;
93e9371f 1838 size_t headersz = 0;
e23ad5d5 1839 size_t datasz;
aa0c7a86 1840 uint32_t checksum;
e23ad5d5 1841 struct stat s;
4acd2d24 1842 int ret;
aa0c7a86 1843
e23ad5d5
T
1844 /*
1845 * Do not use sbuf->st_size as it contains size with padding.
1846 * We need original image data size, so stat original file.
1847 */
1848 if (stat(params->datafile, &s)) {
1849 fprintf(stderr, "Could not stat data file %s: %s\n",
1850 params->datafile, strerror(errno));
1851 exit(EXIT_FAILURE);
1852 }
1853 datasz = ALIGN(s.st_size, 4);
1854
4acd2d24
SR
1855 fcfg = fopen(params->imagename, "r");
1856 if (!fcfg) {
1857 fprintf(stderr, "Could not open input file %s\n",
1858 params->imagename);
1859 exit(EXIT_FAILURE);
1860 }
1861
1862 image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX *
1863 sizeof(struct image_cfg_element));
1864 if (!image_cfg) {
1865 fprintf(stderr, "Cannot allocate memory\n");
1866 fclose(fcfg);
1867 exit(EXIT_FAILURE);
1868 }
1869
1870 memset(image_cfg, 0,
1871 IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element));
1872 rewind(fcfg);
1873
1874 ret = image_create_config_parse(fcfg);
1875 fclose(fcfg);
1876 if (ret) {
1877 free(image_cfg);
1878 exit(EXIT_FAILURE);
1879 }
1880
1881 version = image_get_version();
934a529f
SR
1882 switch (version) {
1883 /*
1884 * Fallback to version 0 if no version is provided in the
1885 * cfg file
1886 */
1887 case -1:
1888 case 0:
e23ad5d5 1889 image = image_create_v0(&headersz, params, datasz + 4);
934a529f
SR
1890 break;
1891
1892 case 1:
e23ad5d5 1893 image = image_create_v1(&headersz, params, ptr, datasz + 4);
934a529f
SR
1894 break;
1895
1896 default:
1897 fprintf(stderr, "Unsupported version %d\n", version);
1898 free(image_cfg);
1899 exit(EXIT_FAILURE);
1900 }
4acd2d24
SR
1901
1902 if (!image) {
1903 fprintf(stderr, "Could not create image\n");
1904 free(image_cfg);
1905 exit(EXIT_FAILURE);
1906 }
1907
1908 free(image_cfg);
aa0c7a86 1909
e23ad5d5 1910 /* Build and add image data checksum */
37cb9c15 1911 checksum = cpu_to_le32(image_checksum32((uint8_t *)ptr + headersz,
e23ad5d5
T
1912 datasz));
1913 memcpy((uint8_t *)ptr + headersz + datasz, &checksum, sizeof(uint32_t));
aa0c7a86 1914
4acd2d24
SR
1915 /* Finally copy the header into the image area */
1916 memcpy(ptr, image, headersz);
aa0c7a86 1917
4acd2d24 1918 free(image);
aa0c7a86
PW
1919}
1920
4acd2d24 1921static void kwbimage_print_header(const void *ptr)
aa0c7a86 1922{
4acd2d24 1923 struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
f76ae257 1924 struct bin_hdr_v0 *bhdr;
732c930b 1925 struct opt_hdr_v1 *ohdr;
4acd2d24
SR
1926
1927 printf("Image Type: MVEBU Boot from %s Image\n",
1928 image_boot_mode_name(mhdr->blockid));
acb0b38d 1929 printf("Image version:%d\n", kwbimage_version(ptr));
34dcf952 1930
732c930b
MB
1931 for_each_opt_hdr_v1 (ohdr, mhdr) {
1932 if (ohdr->headertype == OPT_HDR_V1_BINARY_TYPE) {
c934c9a6 1933 printf("BIN Img Size: ");
732c930b
MB
1934 genimg_print_size(opt_hdr_v1_size(ohdr) - 12 -
1935 4 * ohdr->data[0]);
c934c9a6
T
1936 printf("BIN Img Offs: %08x\n",
1937 (unsigned)((uint8_t *)ohdr - (uint8_t *)mhdr) +
1938 8 + 4 * ohdr->data[0]);
34dcf952
T
1939 }
1940 }
732c930b 1941
f76ae257
T
1942 for_each_bin_hdr_v0(bhdr, mhdr) {
1943 printf("BIN Img Size: ");
1944 genimg_print_size(le32_to_cpu(bhdr->size));
1945 printf("BIN Img Addr: %08x\n", le32_to_cpu(bhdr->destaddr));
1946 printf("BIN Img Entr: %08x\n", le32_to_cpu(bhdr->execaddr));
1947 }
1948
26f195c7 1949 printf("Data Size: ");
4acd2d24
SR
1950 genimg_print_size(mhdr->blocksize - sizeof(uint32_t));
1951 printf("Load Address: %08x\n", mhdr->destaddr);
1952 printf("Entry Point: %08x\n", mhdr->execaddr);
aa0c7a86
PW
1953}
1954
4acd2d24 1955static int kwbimage_check_image_types(uint8_t type)
aa0c7a86
PW
1956{
1957 if (type == IH_TYPE_KWBIMAGE)
1958 return EXIT_SUCCESS;
94490a4a
MS
1959
1960 return EXIT_FAILURE;
aa0c7a86
PW
1961}
1962
4acd2d24
SR
1963static int kwbimage_verify_header(unsigned char *ptr, int image_size,
1964 struct image_tool_params *params)
1965{
fe2fd73d 1966 size_t header_size = kwbheader_size(ptr);
700ea98b
T
1967 uint8_t blockid;
1968 uint32_t offset;
1969 uint32_t size;
fe2fd73d 1970 uint8_t csum;
6cd5678c
AG
1971
1972 if (header_size > image_size)
1973 return -FDT_ERR_BADSTRUCTURE;
4acd2d24 1974
db7cd4ed 1975 if (!main_hdr_checksum_ok(ptr))
4acd2d24
SR
1976 return -FDT_ERR_BADSTRUCTURE;
1977
1978 /* Only version 0 extended header has checksum */
acb0b38d 1979 if (kwbimage_version(ptr) == 0) {
fe2c0e25 1980 struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
f76ae257
T
1981 struct ext_hdr_v0 *ext_hdr;
1982 struct bin_hdr_v0 *bhdr;
e89016c4 1983
f76ae257 1984 for_each_ext_hdr_v0(ext_hdr, ptr) {
fe2fd73d
MB
1985 csum = image_checksum8(ext_hdr, sizeof(*ext_hdr) - 1);
1986 if (csum != ext_hdr->checksum)
fe2c0e25
T
1987 return -FDT_ERR_BADSTRUCTURE;
1988 }
700ea98b 1989
f76ae257
T
1990 for_each_bin_hdr_v0(bhdr, ptr) {
1991 csum = image_checksum8(bhdr, (uint8_t *)&bhdr->checksum - (uint8_t *)bhdr - 1);
1992 if (csum != bhdr->checksum)
1993 return -FDT_ERR_BADSTRUCTURE;
1994
1995 if (bhdr->offset > sizeof(*bhdr) || bhdr->offset % 4 != 0)
1996 return -FDT_ERR_BADSTRUCTURE;
1997
1998 if (bhdr->offset + bhdr->size + 4 > sizeof(*bhdr) || bhdr->size % 4 != 0)
1999 return -FDT_ERR_BADSTRUCTURE;
2000
2001 if (image_checksum32((uint8_t *)bhdr + bhdr->offset, bhdr->size) !=
2002 *(uint32_t *)((uint8_t *)bhdr + bhdr->offset + bhdr->size))
2003 return -FDT_ERR_BADSTRUCTURE;
2004 }
2005
700ea98b
T
2006 blockid = mhdr->blockid;
2007 offset = le32_to_cpu(mhdr->srcaddr);
2008 size = le32_to_cpu(mhdr->blocksize);
acb0b38d 2009 } else if (kwbimage_version(ptr) == 1) {
9380445f 2010 struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
732c930b
MB
2011 const uint8_t *mhdr_end;
2012 struct opt_hdr_v1 *ohdr;
9380445f 2013
732c930b
MB
2014 mhdr_end = (uint8_t *)mhdr + header_size;
2015 for_each_opt_hdr_v1 (ohdr, ptr)
2016 if (!opt_hdr_v1_valid_size(ohdr, mhdr_end))
2017 return -FDT_ERR_BADSTRUCTURE;
e0c243c3 2018
700ea98b 2019 blockid = mhdr->blockid;
e0c243c3 2020 offset = le32_to_cpu(mhdr->srcaddr);
700ea98b
T
2021 size = le32_to_cpu(mhdr->blocksize);
2022 } else {
2023 return -FDT_ERR_BADSTRUCTURE;
2024 }
e0c243c3 2025
700ea98b
T
2026 /*
2027 * For SATA srcaddr is specified in number of sectors.
2028 * The main header is must be stored at sector number 1.
2029 * This expects that sector size is 512 bytes and recalculates
2030 * data offset to bytes relative to the main header.
2031 */
2032 if (blockid == IBR_HDR_SATA_ID) {
2033 if (offset < 1)
2034 return -FDT_ERR_BADSTRUCTURE;
2035 offset -= 1;
2036 offset *= 512;
2037 }
e0c243c3 2038
700ea98b
T
2039 /*
2040 * For SDIO srcaddr is specified in number of sectors.
2041 * This expects that sector size is 512 bytes and recalculates
2042 * data offset to bytes.
2043 */
2044 if (blockid == IBR_HDR_SDIO_ID)
2045 offset *= 512;
e0c243c3 2046
700ea98b
T
2047 /*
2048 * For PCIe srcaddr is always set to 0xFFFFFFFF.
2049 * This expects that data starts after all headers.
2050 */
2051 if (blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF)
2052 offset = header_size;
e0c243c3 2053
700ea98b
T
2054 if (offset > image_size || offset % 4 != 0)
2055 return -FDT_ERR_BADSTRUCTURE;
e0c243c3 2056
700ea98b
T
2057 if (size < 4 || offset + size > image_size || size % 4 != 0)
2058 return -FDT_ERR_BADSTRUCTURE;
e0c243c3 2059
700ea98b
T
2060 if (image_checksum32(ptr + offset, size - 4) !=
2061 *(uint32_t *)(ptr + offset + size - 4))
b984056f 2062 return -FDT_ERR_BADSTRUCTURE;
9380445f 2063
4acd2d24
SR
2064 return 0;
2065}
2066
2067static int kwbimage_generate(struct image_tool_params *params,
2068 struct image_type_params *tparams)
2069{
6cbf7eda 2070 FILE *fcfg;
37cb9c15 2071 struct stat s;
4acd2d24 2072 int alloc_len;
c934aad0 2073 int bootfrom;
6cbf7eda 2074 int version;
4acd2d24 2075 void *hdr;
6cbf7eda 2076 int ret;
4acd2d24 2077
6cbf7eda
PW
2078 fcfg = fopen(params->imagename, "r");
2079 if (!fcfg) {
2080 fprintf(stderr, "Could not open input file %s\n",
2081 params->imagename);
2082 exit(EXIT_FAILURE);
2083 }
2084
37cb9c15
T
2085 if (stat(params->datafile, &s)) {
2086 fprintf(stderr, "Could not stat data file %s: %s\n",
2087 params->datafile, strerror(errno));
2088 exit(EXIT_FAILURE);
2089 }
2090
6cbf7eda
PW
2091 image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX *
2092 sizeof(struct image_cfg_element));
2093 if (!image_cfg) {
2094 fprintf(stderr, "Cannot allocate memory\n");
2095 fclose(fcfg);
2096 exit(EXIT_FAILURE);
2097 }
2098
2099 memset(image_cfg, 0,
2100 IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element));
2101 rewind(fcfg);
2102
2103 ret = image_create_config_parse(fcfg);
2104 fclose(fcfg);
2105 if (ret) {
2106 free(image_cfg);
2107 exit(EXIT_FAILURE);
2108 }
2109
c934aad0 2110 bootfrom = image_get_bootfrom();
6cbf7eda
PW
2111 version = image_get_version();
2112 switch (version) {
2113 /*
2114 * Fallback to version 0 if no version is provided in the
2115 * cfg file
2116 */
2117 case -1:
2118 case 0:
851114be 2119 alloc_len = image_headersz_v0(NULL);
6cbf7eda
PW
2120 break;
2121
2122 case 1:
e93cf53f 2123 alloc_len = image_headersz_v1(NULL);
252e7c3a
T
2124 if (!alloc_len) {
2125 free(image_cfg);
2126 exit(EXIT_FAILURE);
2127 }
78d997f9
T
2128 if (alloc_len > 192*1024) {
2129 fprintf(stderr, "Header is too big (%u bytes), maximal kwbimage header size is %u bytes\n", alloc_len, 192*1024);
2130 free(image_cfg);
2131 exit(EXIT_FAILURE);
2132 }
6cbf7eda
PW
2133 break;
2134
2135 default:
2136 fprintf(stderr, "Unsupported version %d\n", version);
2137 free(image_cfg);
2138 exit(EXIT_FAILURE);
4acd2d24
SR
2139 }
2140
6cbf7eda
PW
2141 free(image_cfg);
2142
4acd2d24
SR
2143 hdr = malloc(alloc_len);
2144 if (!hdr) {
2145 fprintf(stderr, "%s: malloc return failure: %s\n",
2146 params->cmdname, strerror(errno));
2147 exit(EXIT_FAILURE);
2148 }
2149
2150 memset(hdr, 0, alloc_len);
2151 tparams->header_size = alloc_len;
2152 tparams->hdr = hdr;
2153
77720859
SR
2154 /*
2155 * The resulting image needs to be 4-byte aligned. At least
2156 * the Marvell hdrparser tool complains if its unaligned.
37cb9c15 2157 * After the image data is stored 4-byte checksum.
188099ed 2158 * Final UART image must be aligned to 128 bytes.
c934aad0 2159 * Final SPI and NAND images must be aligned to 256 bytes.
501a54a2 2160 * Final SATA and SDIO images must be aligned to 512 bytes.
77720859 2161 */
c934aad0
T
2162 if (bootfrom == IBR_HDR_SPI_ID || bootfrom == IBR_HDR_NAND_ID)
2163 return 4 + (256 - (alloc_len + s.st_size + 4) % 256) % 256;
501a54a2
T
2164 else if (bootfrom == IBR_HDR_SATA_ID || bootfrom == IBR_HDR_SDIO_ID)
2165 return 4 + (512 - (alloc_len + s.st_size + 4) % 512) % 512;
188099ed
T
2166 else if (bootfrom == IBR_HDR_UART_ID)
2167 return 4 + (128 - (alloc_len + s.st_size + 4) % 128) % 128;
c934aad0
T
2168 else
2169 return 4 + (4 - s.st_size % 4) % 4;
4acd2d24
SR
2170}
2171
1a8e6b63
T
2172static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
2173{
2174 struct main_hdr_v0 *mhdr0 = (struct main_hdr_v0 *)ptr;
2175 struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
2176 size_t header_size = kwbheader_size(ptr);
2177 struct register_set_hdr_v1 *regset_hdr;
2178 struct ext_hdr_v0_reg *regdata;
2179 struct ext_hdr_v0 *ehdr0;
f76ae257 2180 struct bin_hdr_v0 *bhdr0;
1a8e6b63 2181 struct opt_hdr_v1 *ohdr;
f76ae257 2182 int params_count;
1a8e6b63 2183 unsigned offset;
f76ae257 2184 int is_v0_ext;
1a8e6b63
T
2185 int cur_idx;
2186 int version;
2187 FILE *f;
2188 int i;
2189
2190 f = fopen(params->outfile, "w");
2191 if (!f) {
2192 fprintf(stderr, "Can't open \"%s\": %s\n", params->outfile, strerror(errno));
2193 return -1;
2194 }
2195
2196 version = kwbimage_version(ptr);
2197
f76ae257
T
2198 is_v0_ext = 0;
2199 if (version == 0) {
2200 if (mhdr0->ext > 1 || mhdr0->bin ||
2201 ((ehdr0 = ext_hdr_v0_first(ptr)) &&
2202 (ehdr0->match_addr || ehdr0->match_mask || ehdr0->match_value)))
2203 is_v0_ext = 1;
2204 }
2205
1a8e6b63
T
2206 if (version != 0)
2207 fprintf(f, "VERSION %d\n", version);
2208
2209 fprintf(f, "BOOT_FROM %s\n", image_boot_mode_name(mhdr->blockid) ?: "<unknown>");
2210
2211 if (version == 0 && mhdr->blockid == IBR_HDR_NAND_ID)
2212 fprintf(f, "NAND_ECC_MODE %s\n", image_nand_ecc_mode_name(mhdr0->nandeccmode));
2213
2214 if (mhdr->blockid == IBR_HDR_NAND_ID)
2215 fprintf(f, "NAND_PAGE_SIZE 0x%x\n", (unsigned)mhdr->nandpagesize);
2216
f76ae257 2217 if (version != 0 && mhdr->blockid == IBR_HDR_NAND_ID)
1a8e6b63 2218 fprintf(f, "NAND_BLKSZ 0x%x\n", (unsigned)mhdr->nandblocksize);
f76ae257
T
2219
2220 if (mhdr->blockid == IBR_HDR_NAND_ID && (mhdr->nandbadblklocation != 0 || is_v0_ext))
1a8e6b63 2221 fprintf(f, "NAND_BADBLK_LOCATION 0x%x\n", (unsigned)mhdr->nandbadblklocation);
1a8e6b63
T
2222
2223 if (version == 0 && mhdr->blockid == IBR_HDR_SATA_ID)
2224 fprintf(f, "SATA_PIO_MODE %u\n", (unsigned)mhdr0->satapiomode);
2225
2226 /*
2227 * Addresses and sizes which are specified by mkimage command line
2228 * arguments and not in kwbimage config file
2229 */
2230
2231 if (version != 0)
2232 fprintf(f, "#HEADER_SIZE 0x%x\n",
2233 ((unsigned)mhdr->headersz_msb << 8) | le16_to_cpu(mhdr->headersz_lsb));
2234
2235 fprintf(f, "#SRC_ADDRESS 0x%x\n", le32_to_cpu(mhdr->srcaddr));
2236 fprintf(f, "#BLOCK_SIZE 0x%x\n", le32_to_cpu(mhdr->blocksize));
2237 fprintf(f, "#DEST_ADDRESS 0x%08x\n", le32_to_cpu(mhdr->destaddr));
2238 fprintf(f, "#EXEC_ADDRESS 0x%08x\n", le32_to_cpu(mhdr->execaddr));
2239
2240 if (version != 0) {
2241 if (options_to_baudrate(mhdr->options))
2242 fprintf(f, "BAUDRATE %u\n", options_to_baudrate(mhdr->options));
2243 if (options_to_baudrate(mhdr->options) ||
2244 ((mhdr->options >> 3) & 0x3) || ((mhdr->options >> 5) & 0x7)) {
2245 fprintf(f, "UART_PORT %u\n", (unsigned)((mhdr->options >> 3) & 0x3));
2246 fprintf(f, "UART_MPP 0x%x\n", (unsigned)((mhdr->options >> 5) & 0x7));
2247 }
2248 if (mhdr->flags & 0x1)
2249 fprintf(f, "DEBUG 1\n");
2250 }
2251
2252 cur_idx = 1;
2253 for_each_opt_hdr_v1(ohdr, ptr) {
2254 if (ohdr->headertype == OPT_HDR_V1_SECURE_TYPE) {
2255 fprintf(f, "#SECURE_HEADER\n");
2256 } else if (ohdr->headertype == OPT_HDR_V1_BINARY_TYPE) {
2257 fprintf(f, "BINARY binary%d.bin", cur_idx);
2258 for (i = 0; i < ohdr->data[0]; i++)
2259 fprintf(f, " 0x%x", le32_to_cpu(((uint32_t *)ohdr->data)[i + 1]));
2260 offset = (unsigned)((uint8_t *)ohdr - (uint8_t *)mhdr) + 8 + 4 * ohdr->data[0];
2261 fprintf(f, " LOAD_ADDRESS 0x%08x\n", 0x40000000 + offset);
2262 fprintf(f, " # for CPU SHEEVA: LOAD_ADDRESS 0x%08x\n", 0x40004000 + offset);
2263 cur_idx++;
2264 } else if (ohdr->headertype == OPT_HDR_V1_REGISTER_TYPE) {
2265 regset_hdr = (struct register_set_hdr_v1 *)ohdr;
2266 for (i = 0;
2267 i < opt_hdr_v1_size(ohdr) - sizeof(struct opt_hdr_v1) -
2268 sizeof(regset_hdr->data[0].last_entry);
2269 i++)
2270 fprintf(f, "DATA 0x%08x 0x%08x\n",
2271 le32_to_cpu(regset_hdr->data[i].entry.address),
2272 le32_to_cpu(regset_hdr->data[i].entry.value));
2273 if (opt_hdr_v1_size(ohdr) - sizeof(struct opt_hdr_v1) >=
2274 sizeof(regset_hdr->data[0].last_entry)) {
2275 if (regset_hdr->data[0].last_entry.delay)
2276 fprintf(f, "DATA_DELAY %u\n",
2277 (unsigned)regset_hdr->data[0].last_entry.delay);
2278 else
2279 fprintf(f, "DATA_DELAY SDRAM_SETUP\n");
2280 }
2281 }
2282 }
2283
f76ae257
T
2284 if (version == 0 && !is_v0_ext && le16_to_cpu(mhdr0->ddrinitdelay))
2285 fprintf(f, "DDR_INIT_DELAY %u\n", (unsigned)le16_to_cpu(mhdr0->ddrinitdelay));
2286
2287 for_each_ext_hdr_v0(ehdr0, ptr) {
2288 if (is_v0_ext) {
2289 fprintf(f, "\nMATCH ADDRESS 0x%08x MASK 0x%08x VALUE 0x%08x\n",
2290 le32_to_cpu(ehdr0->match_addr),
2291 le32_to_cpu(ehdr0->match_mask),
2292 le32_to_cpu(ehdr0->match_value));
2293 if (ehdr0->rsvd1[0] || ehdr0->rsvd1[1] || ehdr0->rsvd1[2] ||
2294 ehdr0->rsvd1[3] || ehdr0->rsvd1[4] || ehdr0->rsvd1[5] ||
2295 ehdr0->rsvd1[6] || ehdr0->rsvd1[7])
2296 fprintf(f, "#DDR_RSVD1 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
2297 ehdr0->rsvd1[0], ehdr0->rsvd1[1], ehdr0->rsvd1[2],
2298 ehdr0->rsvd1[3], ehdr0->rsvd1[4], ehdr0->rsvd1[5],
2299 ehdr0->rsvd1[6], ehdr0->rsvd1[7]);
2300 if (ehdr0->rsvd2[0] || ehdr0->rsvd2[1] || ehdr0->rsvd2[2] ||
2301 ehdr0->rsvd2[3] || ehdr0->rsvd2[4] || ehdr0->rsvd2[5] ||
2302 ehdr0->rsvd2[6])
2303 fprintf(f, "#DDR_RSVD2 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
2304 ehdr0->rsvd2[0], ehdr0->rsvd2[1], ehdr0->rsvd2[2],
2305 ehdr0->rsvd2[3], ehdr0->rsvd2[4], ehdr0->rsvd2[5],
2306 ehdr0->rsvd2[6]);
2307 if (ehdr0->ddrwritetype)
2308 fprintf(f, "DDR_WRITE_TYPE %u\n", (unsigned)ehdr0->ddrwritetype);
2309 if (ehdr0->ddrresetmpp)
2310 fprintf(f, "DDR_RESET_MPP 0x%x\n", (unsigned)ehdr0->ddrresetmpp);
2311 if (ehdr0->ddrclkenmpp)
2312 fprintf(f, "DDR_CLKEN_MPP 0x%x\n", (unsigned)ehdr0->ddrclkenmpp);
2313 if (ehdr0->ddrinitdelay)
2314 fprintf(f, "DDR_INIT_DELAY %u\n", (unsigned)ehdr0->ddrinitdelay);
2315 }
2316
1a8e6b63
T
2317 if (ehdr0->offset) {
2318 for (regdata = (struct ext_hdr_v0_reg *)((uint8_t *)ptr + ehdr0->offset);
a2389213
T
2319 (uint8_t *)regdata < (uint8_t *)ptr + header_size &&
2320 (regdata->raddr || regdata->rdata);
1a8e6b63
T
2321 regdata++)
2322 fprintf(f, "DATA 0x%08x 0x%08x\n", le32_to_cpu(regdata->raddr),
2323 le32_to_cpu(regdata->rdata));
a2389213
T
2324 if ((uint8_t *)regdata != (uint8_t *)ptr + ehdr0->offset)
2325 fprintf(f, "DATA 0x0 0x0\n");
1a8e6b63 2326 }
f76ae257
T
2327
2328 if (le32_to_cpu(ehdr0->enddelay))
2329 fprintf(f, "DATA_DELAY %u\n", le32_to_cpu(ehdr0->enddelay));
2330 else if (is_v0_ext)
2331 fprintf(f, "DATA_DELAY SDRAM_SETUP\n");
1a8e6b63
T
2332 }
2333
f76ae257
T
2334 cur_idx = 1;
2335 for_each_bin_hdr_v0(bhdr0, ptr) {
2336 fprintf(f, "\nMATCH ADDRESS 0x%08x MASK 0x%08x VALUE 0x%08x\n",
2337 le32_to_cpu(bhdr0->match_addr),
2338 le32_to_cpu(bhdr0->match_mask),
2339 le32_to_cpu(bhdr0->match_value));
2340
2341 fprintf(f, "BINARY binary%d.bin", cur_idx);
2342 params_count = fls4(bhdr0->params_flags & 0xF);
2343 for (i = 0; i < params_count; i++)
2344 fprintf(f, " 0x%x", (bhdr0->params[i] & (1 << i)) ? bhdr0->params[i] : 0);
2345 fprintf(f, " LOAD_ADDRESS 0x%08x", le32_to_cpu(bhdr0->destaddr));
2346 fprintf(f, " EXEC_ADDRESS 0x%08x", le32_to_cpu(bhdr0->execaddr));
2347 fprintf(f, "\n");
2348
2349 fprintf(f, "#BINARY_OFFSET 0x%x\n", le32_to_cpu(bhdr0->offset));
2350 fprintf(f, "#BINARY_SIZE 0x%x\n", le32_to_cpu(bhdr0->size));
2351
2352 if (bhdr0->rsvd1)
2353 fprintf(f, "#BINARY_RSVD1 0x%x\n", (unsigned)bhdr0->rsvd1);
2354 if (bhdr0->rsvd2)
2355 fprintf(f, "#BINARY_RSVD2 0x%x\n", (unsigned)bhdr0->rsvd2);
2356
2357 cur_idx++;
2358 }
1a8e6b63
T
2359
2360 /* Undocumented reserved fields */
2361
2362 if (version == 0 && (mhdr0->rsvd1[0] || mhdr0->rsvd1[1] || mhdr0->rsvd1[2]))
2363 fprintf(f, "#RSVD1 0x%x 0x%x 0x%x\n", (unsigned)mhdr0->rsvd1[0],
2364 (unsigned)mhdr0->rsvd1[1], (unsigned)mhdr0->rsvd1[2]);
2365
1a8e6b63
T
2366 if (version == 0 && le16_to_cpu(mhdr0->rsvd2))
2367 fprintf(f, "#RSVD2 0x%x\n", (unsigned)le16_to_cpu(mhdr0->rsvd2));
2368
2369 if (version != 0 && mhdr->reserved4)
2370 fprintf(f, "#RESERVED4 0x%x\n", (unsigned)mhdr->reserved4);
2371
2372 if (version != 0 && mhdr->reserved5)
2373 fprintf(f, "#RESERVED5 0x%x\n", (unsigned)le16_to_cpu(mhdr->reserved5));
2374
2375 fclose(f);
2376
2377 return 0;
2378}
2379
aa6943ca
T
2380static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params)
2381{
2382 struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
fe2fd73d 2383 size_t header_size = kwbheader_size(ptr);
f76ae257 2384 struct bin_hdr_v0 *bhdr;
732c930b 2385 struct opt_hdr_v1 *ohdr;
aa6943ca 2386 int idx = params->pflag;
1972c7e3 2387 int cur_idx;
aa6943ca
T
2388 uint32_t offset;
2389 ulong image;
2390 ulong size;
2391
1a8e6b63
T
2392 /* Generate kwbimage config file when '-p -1' is specified */
2393 if (idx == -1)
2394 return kwbimage_generate_config(ptr, params);
2395
1972c7e3
T
2396 image = 0;
2397 size = 0;
2398
2399 if (idx == 0) {
2400 /* Extract data image when -p is not specified or when '-p 0' is specified */
2401 offset = le32_to_cpu(mhdr->srcaddr);
aa6943ca 2402
1972c7e3
T
2403 if (mhdr->blockid == IBR_HDR_SATA_ID) {
2404 offset -= 1;
2405 offset *= 512;
aa6943ca 2406 }
732c930b 2407
1972c7e3
T
2408 if (mhdr->blockid == IBR_HDR_SDIO_ID)
2409 offset *= 512;
aa6943ca 2410
1972c7e3
T
2411 if (mhdr->blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF)
2412 offset = header_size;
aa6943ca 2413
1972c7e3
T
2414 image = (ulong)((uint8_t *)ptr + offset);
2415 size = le32_to_cpu(mhdr->blocksize) - 4;
2416 } else {
2417 /* Extract N-th binary header executabe image when other '-p N' is specified */
2418 cur_idx = 1;
2419 for_each_opt_hdr_v1(ohdr, ptr) {
2420 if (ohdr->headertype != OPT_HDR_V1_BINARY_TYPE)
2421 continue;
aa6943ca 2422
1972c7e3
T
2423 if (idx == cur_idx) {
2424 image = (ulong)&ohdr->data[4 + 4 * ohdr->data[0]];
2425 size = opt_hdr_v1_size(ohdr) - 12 - 4 * ohdr->data[0];
2426 break;
2427 }
aa6943ca 2428
1972c7e3
T
2429 ++cur_idx;
2430 }
f76ae257
T
2431 for_each_bin_hdr_v0(bhdr, ptr) {
2432 if (idx == cur_idx) {
2433 image = (ulong)bhdr + bhdr->offset;
2434 size = bhdr->size;
2435 break;
2436 }
2437 ++cur_idx;
2438 }
aa6943ca 2439
1972c7e3
T
2440 if (!image) {
2441 fprintf(stderr, "Argument -p %d is invalid\n", idx);
2442 fprintf(stderr, "Available subimages:\n");
2443 fprintf(stderr, " -p -1 - kwbimage config file\n");
2444 fprintf(stderr, " -p 0 - data image\n");
2445 if (cur_idx - 1 > 0)
2446 fprintf(stderr, " -p N - Nth binary header image (totally: %d)\n",
2447 cur_idx - 1);
2448 return -1;
2449 }
2450 }
aa6943ca 2451
aa6943ca
T
2452 return imagetool_save_subimage(params->outfile, image, size);
2453}
2454
4acd2d24
SR
2455/*
2456 * Report Error if xflag is set in addition to default
2457 */
2458static int kwbimage_check_params(struct image_tool_params *params)
2459{
e65ea147 2460 if (!params->lflag && !params->iflag && !params->pflag &&
32860b00 2461 (!params->imagename || !strlen(params->imagename))) {
94490a4a
MS
2462 char *msg = "Configuration file for kwbimage creation omitted";
2463
2464 fprintf(stderr, "Error:%s - %s\n", params->cmdname, msg);
56087c1b 2465 return 1;
4acd2d24
SR
2466 }
2467
2468 return (params->dflag && (params->fflag || params->lflag)) ||
2469 (params->fflag && (params->dflag || params->lflag)) ||
2470 (params->lflag && (params->dflag || params->fflag)) ||
aa6943ca 2471 (params->xflag);
4acd2d24
SR
2472}
2473
aa0c7a86
PW
2474/*
2475 * kwbimage type parameters definition
2476 */
a93648d1
GMF
2477U_BOOT_IMAGE_TYPE(
2478 kwbimage,
2479 "Marvell MVEBU Boot Image support",
2480 0,
2481 NULL,
2482 kwbimage_check_params,
2483 kwbimage_verify_header,
2484 kwbimage_print_header,
2485 kwbimage_set_header,
aa6943ca 2486 kwbimage_extract_subimage,
a93648d1
GMF
2487 kwbimage_check_image_types,
2488 NULL,
2489 kwbimage_generate
2490);