2 * Copyright (C) 2018 Alexander Graf <agraf@suse.de>
4 * SPDX-License-Identifier: GPL-2.0+
9 #include "zynqmpimage.h"
28 BIF_FLAG_HEADERSIGNATURE
,
33 BIF_FLAG_SPKSIGNATURE
,
36 BIF_FLAG_KEYSRC_ENCRYPTION
,
44 BIF_FLAG_PART_OWNER_UBOOT
,
55 char *(*parse
)(char *line
, struct bif_entry
*bf
);
58 struct bif_file_type
{
61 int (*add
)(struct bif_entry
*bf
);
67 struct image_header_table
*imgheader
;
68 struct zynqmp_header
*header
;
69 struct partition_header
*last_part
;
72 struct bif_output bif_output
;
74 static uint32_t zynqmp_csum(void *start
, void *end
)
76 uint32_t checksum
= 0;
77 uint32_t *ptr32
= start
;
79 while (ptr32
!= end
) {
80 checksum
+= le32_to_cpu(*ptr32
);
87 static int zynqmpbif_check_params(struct image_tool_params
*params
)
92 if (params
->addr
!= 0x0) {
93 fprintf(stderr
, "Error: Load Address can not be specified.\n");
98 fprintf(stderr
, "Error: Entry Point can not be specified.\n");
102 return !(params
->lflag
|| params
->dflag
);
105 static int zynqmpbif_check_image_types(uint8_t type
)
107 return (type
== IH_TYPE_ZYNQMPBIF
) ? EXIT_SUCCESS
: EXIT_FAILURE
;
110 static char *parse_dest_cpu(char *line
, struct bif_entry
*bf
)
114 for (i
= 0; i
< ARRAY_SIZE(dest_cpus
); i
++) {
115 if (!strncmp(line
, dest_cpus
[i
], strlen(dest_cpus
[i
]))) {
116 bf
->dest_cpu
= i
<< PART_ATTR_DEST_CPU_SHIFT
;
117 return line
+ strlen(dest_cpus
[i
]);
120 /* a5x can also be written as a53 */
121 if (!strncmp(dest_cpus
[i
], "a5x", 3)) {
122 char a53
[] = "a53-X";
124 a53
[4] = dest_cpus
[i
][4];
125 if (!strncmp(line
, a53
, strlen(a53
))) {
126 bf
->dest_cpu
= i
<< PART_ATTR_DEST_CPU_SHIFT
;
127 return line
+ strlen(a53
);
135 static char *parse_el(char *line
, struct bif_entry
*bf
)
137 const char *dest_els
[] = { "none", "el-0", "el-1", "el-2", "el-3" };
140 for (i
= 0; i
< ARRAY_SIZE(dest_els
); i
++) {
141 if (!strncmp(line
, dest_els
[i
], strlen(dest_els
[i
]))) {
143 return line
+ strlen(dest_els
[i
]);
150 static char *parse_load(char *line
, struct bif_entry
*bf
)
154 bf
->load
= strtoll(line
, &endptr
, 0);
159 static char *parse_entry(char *line
, struct bif_entry
*bf
)
163 bf
->entry
= strtoll(line
, &endptr
, 0);
168 static char *parse_offset(char *line
, struct bif_entry
*bf
)
172 bf
->offset
= strtoll(line
, &endptr
, 0);
177 static char *parse_partition_owner(char *line
, struct bif_entry
*bf
)
181 if (!strncmp(line
, "fsbl", 4)) {
183 } else if (!strncmp(line
, "uboot", 5)) {
184 bf
->flags
|= 1ULL << BIF_FLAG_PART_OWNER_UBOOT
;
187 printf("ERROR: Unknown partition type '%s'\n", line
);
193 static const struct bif_flags bif_flags
[] = {
194 { "fsbl_config", BIF_FLAG_FSBL_CONFIG
},
195 { "trustzone", BIF_FLAG_TZ
},
196 { "pmufw_image", BIF_FLAG_PMUFW_IMAGE
},
197 { "bootloader", BIF_FLAG_BOOTLOADER
},
198 { "destination_cpu=", 0, parse_dest_cpu
},
199 { "exception_level=", 0, parse_el
},
200 { "load=", 0, parse_load
},
201 { "startup=", 0, parse_entry
},
202 { "offset=", 0, parse_offset
},
203 { "partition_owner=", 0, parse_partition_owner
},
206 static char *read_full_file(const char *filename
, size_t *size
)
212 fd
= open(filename
, O_RDONLY
);
216 if (fstat(fd
, &sbuf
) < 0)
220 *size
= sbuf
.st_size
;
222 buf
= malloc(sbuf
.st_size
);
227 while (len
< sbuf
.st_size
) {
228 r
= read(fd
, bufp
, sbuf
.st_size
- len
);
240 static int bif_add_blob(const void *data
, size_t len
, size_t *offset
)
243 uintptr_t header_off
;
244 uintptr_t last_part_off
;
245 uintptr_t imgheader_off
;
246 uintptr_t old_data
= (uintptr_t)bif_output
.data
;
249 header_off
= (uintptr_t)bif_output
.header
- old_data
;
250 last_part_off
= (uintptr_t)bif_output
.last_part
- old_data
;
251 imgheader_off
= (uintptr_t)bif_output
.imgheader
- old_data
;
253 if (offset
&& *offset
) {
254 /* Pad to a given offset */
255 if (bif_output
.data_len
> *offset
) {
256 printf("Can not pad to offset %zx\n", *offset
);
260 bif_output
.data_len
= *offset
;
263 new_size
= ROUND(bif_output
.data_len
+ len
, 64);
264 new_data
= realloc(bif_output
.data
, new_size
);
265 memcpy(new_data
+ bif_output
.data_len
, data
, len
);
267 *offset
= bif_output
.data_len
;
268 bif_output
.data
= new_data
;
269 bif_output
.data_len
= new_size
;
271 /* Readjust internal pointers */
272 if (bif_output
.header
)
273 bif_output
.header
= new_data
+ header_off
;
274 if (bif_output
.last_part
)
275 bif_output
.last_part
= new_data
+ last_part_off
;
276 if (bif_output
.imgheader
)
277 bif_output
.imgheader
= new_data
+ imgheader_off
;
282 static int bif_init(void)
284 struct zynqmp_header header
= { { 0 } };
287 zynqmpimage_default_header(&header
);
289 r
= bif_add_blob(&header
, sizeof(header
), NULL
);
293 bif_output
.header
= (void *)bif_output
.data
;
298 static int bif_add_pmufw(struct bif_entry
*bf
, const char *data
, size_t len
)
302 if (bif_output
.header
->image_offset
) {
303 printf("PMUFW expected before bootloader in your .bif file!\n");
307 r
= bif_add_blob(data
, len
, &bf
->offset
);
311 len
= ROUND(len
, 64);
312 bif_output
.header
->pfw_image_length
= cpu_to_le32(len
);
313 bif_output
.header
->total_pfw_image_length
= cpu_to_le32(len
);
314 bif_output
.header
->image_offset
= cpu_to_le32(bf
->offset
);
319 static int bif_add_part(struct bif_entry
*bf
, const char *data
, size_t len
)
321 size_t parthdr_offset
= 0;
322 size_t len_padded
= ROUND(len
, 4);
324 struct partition_header parthdr
= {
325 .len_enc
= cpu_to_le32(len_padded
/ 4),
326 .len_unenc
= cpu_to_le32(len_padded
/ 4),
327 .len
= cpu_to_le32(len_padded
/ 4),
328 .entry_point
= cpu_to_le64(bf
->entry
),
329 .load_address
= cpu_to_le64(bf
->load
),
334 if (len
< len_padded
) {
335 char *newdata
= malloc(len_padded
);
336 memcpy(newdata
, data
, len
);
337 memset(newdata
+ len
, 0, len_padded
- len
);
341 if (bf
->flags
& (1ULL << BIF_FLAG_PMUFW_IMAGE
))
342 return bif_add_pmufw(bf
, data
, len
);
344 r
= bif_add_blob(data
, len
, &bf
->offset
);
348 parthdr
.offset
= cpu_to_le32(bf
->offset
/ 4);
350 if (bf
->flags
& (1ULL << BIF_FLAG_BOOTLOADER
)) {
351 if (bif_output
.last_part
) {
352 printf("ERROR: Bootloader expected before others\n");
356 parthdr
.offset
= cpu_to_le32(bif_output
.header
->image_offset
);
357 parthdr
.len
= cpu_to_le32((bf
->offset
+ len
-
358 bif_output
.header
->image_offset
) / 4);
359 parthdr
.len_enc
= parthdr
.len
;
360 parthdr
.len_unenc
= parthdr
.len
;
364 bf
->exp_lvl
= bf
->exp_lvl
? bf
->exp_lvl
- 1 : 3;
365 parthdr
.attributes
|= bf
->exp_lvl
<< PART_ATTR_TARGET_EL_SHIFT
;
366 parthdr
.attributes
|= bf
->dest_dev
;
367 parthdr
.attributes
|= bf
->dest_cpu
;
368 if (bf
->flags
& (1ULL << BIF_FLAG_TZ
))
369 parthdr
.attributes
|= PART_ATTR_TZ_SECURE
;
370 if (bf
->flags
& (1ULL << BIF_FLAG_PART_OWNER_UBOOT
))
371 parthdr
.attributes
|= PART_ATTR_PART_OWNER_UBOOT
;
372 switch (bf
->dest_cpu
) {
373 case PART_ATTR_DEST_CPU_NONE
:
374 case PART_ATTR_DEST_CPU_A53_0
:
375 case PART_ATTR_DEST_CPU_A53_1
:
376 case PART_ATTR_DEST_CPU_A53_2
:
377 case PART_ATTR_DEST_CPU_A53_3
:
378 if (bf
->flags
& (1ULL << BIF_FLAG_AARCH32
))
379 parthdr
.attributes
|= PART_ATTR_A53_EXEC_AARCH32
;
382 csum
= zynqmp_csum(&parthdr
, &parthdr
.checksum
);
383 parthdr
.checksum
= cpu_to_le32(csum
);
385 r
= bif_add_blob(&parthdr
, sizeof(parthdr
), &parthdr_offset
);
389 /* Add image header table if not there yet */
390 if (!bif_output
.imgheader
) {
391 size_t imghdr_off
= 0;
392 struct image_header_table imghdr
= {
393 .version
= cpu_to_le32(0x01020000),
397 r
= bif_add_blob(&imghdr
, sizeof(imghdr
), &imghdr_off
);
401 bif_output
.header
->image_header_table_offset
= imghdr_off
;
402 bif_output
.imgheader
= (void *)(bif_output
.data
+ imghdr_off
);
405 bif_output
.imgheader
->nr_parts
= cpu_to_le32(le32_to_cpu(
406 bif_output
.imgheader
->nr_parts
) + 1);
408 /* Link to this partition header */
409 if (bif_output
.last_part
) {
410 bif_output
.last_part
->next_partition_offset
=
411 cpu_to_le32(parthdr_offset
/ 4);
413 /* Recalc checksum of last_part */
414 csum
= zynqmp_csum(bif_output
.last_part
,
415 &bif_output
.last_part
->checksum
);
416 bif_output
.last_part
->checksum
= cpu_to_le32(csum
);
418 bif_output
.imgheader
->partition_header_offset
=
419 cpu_to_le32(parthdr_offset
/ 4);
421 bif_output
.last_part
= (void *)(bif_output
.data
+ parthdr_offset
);
423 if (bf
->flags
& (1ULL << BIF_FLAG_BOOTLOADER
)) {
424 bif_output
.header
->image_load
= cpu_to_le32(bf
->load
);
425 if (!bif_output
.header
->image_offset
)
426 bif_output
.header
->image_offset
=
427 cpu_to_le32(bf
->offset
);
428 bif_output
.header
->image_size
= cpu_to_le32(len_padded
);
429 bif_output
.header
->image_stored_size
= cpu_to_le32(len_padded
);
431 bif_output
.header
->image_attributes
&= ~HEADER_CPU_SELECT_MASK
;
432 switch (bf
->dest_cpu
) {
434 case PART_ATTR_DEST_CPU_A53_0
:
435 if (bf
->flags
& BIF_FLAG_AARCH32
)
436 bif_output
.header
->image_attributes
|=
437 HEADER_CPU_SELECT_A53_32BIT
;
439 bif_output
.header
->image_attributes
|=
440 HEADER_CPU_SELECT_A53_64BIT
;
442 case PART_ATTR_DEST_CPU_R5_0
:
443 bif_output
.header
->image_attributes
|=
444 HEADER_CPU_SELECT_R5_SINGLE
;
446 case PART_ATTR_DEST_CPU_R5_L
:
447 bif_output
.header
->image_attributes
|=
448 HEADER_CPU_SELECT_R5_DUAL
;
456 /* Add .bit bitstream */
457 static int bif_add_bit(struct bif_entry
*bf
)
459 char *bit
= read_full_file(bf
->filename
, NULL
);
461 uint8_t initial_header
[] = { 0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
462 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01, 0x61 };
470 /* Skip initial header */
471 if (memcmp(bit
, initial_header
, sizeof(initial_header
)))
474 bit
+= sizeof(initial_header
);
477 len
= be16_to_cpu(*(uint16_t *)bit
);
478 bit
+= sizeof(uint16_t);
479 debug("Design: %s\n", bit
);
482 /* Device identifier */
486 len
= be16_to_cpu(*(uint16_t *)bit
);
487 bit
+= sizeof(uint16_t);
488 debug("Device: %s\n", bit
);
495 len
= be16_to_cpu(*(uint16_t *)bit
);
496 bit
+= sizeof(uint16_t);
497 debug("Date: %s\n", bit
);
504 len
= be16_to_cpu(*(uint16_t *)bit
);
505 bit
+= sizeof(uint16_t);
506 debug("Time: %s\n", bit
);
509 /* Bitstream length */
513 bitlen
= be32_to_cpu(*(uint32_t *)bit
);
514 bit
+= sizeof(uint32_t);
517 debug("Bitstream Length: 0x%x\n", bitlen
);
518 for (i
= 0; i
< bitlen
; i
+= sizeof(uint32_t)) {
519 uint32_t *bitbin32
= (uint32_t *)&bitbin
[i
];
520 *bitbin32
= __swab32(*bitbin32
);
524 bf
->dest_dev
= PART_ATTR_DEST_DEVICE_PL
;
526 bf
->load
= 0xffffffff;
529 bf
->flags
|= 1ULL << BIF_FLAG_BIT_FILE
;
530 return bif_add_part(bf
, bit
, bitlen
);
533 /* Add .bin bitstream */
534 static int bif_add_bin(struct bif_entry
*bf
)
537 char *bin
= read_full_file(bf
->filename
, &size
);
540 bf
->dest_dev
= PART_ATTR_DEST_DEVICE_PS
;
542 bf
->flags
|= 1ULL << BIF_FLAG_BIN_FILE
;
543 return bif_add_part(bf
, bin
, size
);
547 static char *elf2flat64(char *elf
, size_t *flat_size
, size_t *load_addr
)
551 size_t min_addr
= -1, max_addr
= 0;
556 shdr
= (void *)(elf
+ le64_to_cpu(ehdr
->e_shoff
));
558 /* Look for smallest / biggest address */
559 for (i
= 0; i
< le64_to_cpu(ehdr
->e_shnum
); i
++, shdr
++) {
560 if (!shdr
->sh_size
|| !shdr
->sh_addr
||
561 !(shdr
->sh_flags
& SHF_ALLOC
) ||
562 (shdr
->sh_type
== SHT_NOBITS
))
565 if (le64_to_cpu(shdr
->sh_addr
) < min_addr
)
566 min_addr
= le64_to_cpu(shdr
->sh_addr
);
567 if ((le64_to_cpu(shdr
->sh_addr
) + le64_to_cpu(shdr
->sh_size
)) >
569 max_addr
= le64_to_cpu(shdr
->sh_addr
) +
570 le64_to_cpu(shdr
->sh_size
);
573 *load_addr
= min_addr
;
574 *flat_size
= max_addr
- min_addr
;
575 flat
= calloc(1, *flat_size
);
579 shdr
= (void *)(elf
+ le64_to_cpu(ehdr
->e_shoff
));
580 for (i
= 0; i
< le64_to_cpu(ehdr
->e_shnum
); i
++, shdr
++) {
581 char *dst
= flat
+ le64_to_cpu(shdr
->sh_addr
) - min_addr
;
582 char *src
= elf
+ le64_to_cpu(shdr
->sh_offset
);
584 if (!shdr
->sh_size
|| !shdr
->sh_addr
||
585 !(shdr
->sh_flags
& SHF_ALLOC
))
588 if (shdr
->sh_type
!= SHT_NOBITS
)
589 memcpy(dst
, src
, le64_to_cpu(shdr
->sh_size
));
595 static char *elf2flat32(char *elf
, size_t *flat_size
, size_t *load_addr
)
599 size_t min_addr
= -1, max_addr
= 0;
604 shdr
= (void *)(elf
+ le32_to_cpu(ehdr
->e_shoff
));
606 /* Look for smallest / biggest address */
607 for (i
= 0; i
< le32_to_cpu(ehdr
->e_shnum
); i
++, shdr
++) {
608 if (!shdr
->sh_size
|| !shdr
->sh_addr
||
609 !(shdr
->sh_flags
& SHF_ALLOC
) ||
610 (shdr
->sh_type
== SHT_NOBITS
))
613 if (le32_to_cpu(shdr
->sh_addr
) < min_addr
)
614 min_addr
= le32_to_cpu(shdr
->sh_addr
);
615 if ((le32_to_cpu(shdr
->sh_addr
) + le32_to_cpu(shdr
->sh_size
)) >
617 max_addr
= le32_to_cpu(shdr
->sh_addr
) +
618 le32_to_cpu(shdr
->sh_size
);
621 *load_addr
= min_addr
;
622 *flat_size
= max_addr
- min_addr
;
623 flat
= calloc(1, *flat_size
);
627 shdr
= (void *)(elf
+ le32_to_cpu(ehdr
->e_shoff
));
628 for (i
= 0; i
< le32_to_cpu(ehdr
->e_shnum
); i
++, shdr
++) {
629 char *dst
= flat
+ le32_to_cpu(shdr
->sh_addr
) - min_addr
;
630 char *src
= elf
+ le32_to_cpu(shdr
->sh_offset
);
632 if (!shdr
->sh_size
|| !shdr
->sh_addr
||
633 !(shdr
->sh_flags
& SHF_ALLOC
))
636 if (shdr
->sh_type
!= SHT_NOBITS
)
637 memcpy(dst
, src
, le32_to_cpu(shdr
->sh_size
));
643 static int bif_add_elf(struct bif_entry
*bf
)
653 elf
= read_full_file(bf
->filename
, &elf_size
);
657 ehdr32
= (void *)elf
;
658 ehdr64
= (void *)elf
;
660 switch (ehdr32
->e_ident
[EI_CLASS
]) {
662 flat
= elf2flat32(elf
, &size
, &load_addr
);
663 bf
->entry
= le32_to_cpu(ehdr32
->e_entry
);
664 bf
->flags
|= 1ULL << BIF_FLAG_AARCH32
;
667 flat
= elf2flat64(elf
, &size
, &load_addr
);
668 bf
->entry
= le64_to_cpu(ehdr64
->e_entry
);
671 printf("Unknown ELF class: %d\n", ehdr32
->e_ident
[EI_CLASS
]);
678 bf
->load
= load_addr
;
680 bf
->dest_dev
= PART_ATTR_DEST_DEVICE_PS
;
682 bf
->flags
|= 1ULL << BIF_FLAG_ELF_FILE
;
683 return bif_add_part(bf
, flat
, size
);
686 static const struct bif_file_type bif_file_types
[] = {
688 .name
= "bitstream (.bit)",
689 .header
= 0x00090ff0,
695 .header
= 0x7f454c46,
699 /* Anything else is a .bin file */
706 static int bif_fsbl_config(struct bif_entry
*fsbl_config
,
707 struct bif_entry
*entries
, int nr_entries
)
716 { .name
= "a5x_x64", .dest_cpu
= PART_ATTR_DEST_CPU_A53_0
},
717 { .name
= "a53_x64", .dest_cpu
= PART_ATTR_DEST_CPU_A53_0
},
718 { .name
= "a5x_x32", .dest_cpu
= PART_ATTR_DEST_CPU_A53_0
,
719 .flags
= 1ULL << BIF_FLAG_AARCH32
},
720 { .name
= "a53_x32", .dest_cpu
= PART_ATTR_DEST_CPU_A53_0
,
721 .flags
= 1ULL << BIF_FLAG_AARCH32
},
722 { .name
= "r5_single", .dest_cpu
= PART_ATTR_DEST_CPU_R5_0
},
723 { .name
= "r5_dual", .dest_cpu
= PART_ATTR_DEST_CPU_R5_L
},
726 /* Set target CPU of bootloader entry */
727 for (i
= 0; i
< nr_entries
; i
++) {
728 struct bif_entry
*b
= &entries
[i
];
729 const char *config_attr
= fsbl_config
->filename
;
732 if (!(b
->flags
& (1ULL << BIF_FLAG_BOOTLOADER
)))
735 for (j
= 0; j
< ARRAY_SIZE(configs
); j
++) {
736 if (!strncmp(config_attr
, configs
[j
].name
,
737 strlen(configs
[j
].name
))) {
738 b
->dest_cpu
= configs
[j
].dest_cpu
;
739 b
->flags
|= configs
[j
].flags
;
745 printf("ERROR: Unsupported fsbl_config: %s\n",
752 printf("ERROR: fsbl_config w/o bootloader\n");
759 static const struct bif_flags
*find_flag(char *str
)
761 const struct bif_flags
*bf
;
764 for (i
= 0; i
< ARRAY_SIZE(bif_flags
); i
++) {
766 if (!strncmp(bf
->name
, str
, strlen(bf
->name
)))
770 printf("ERROR: Flag '%s' not found\n", str
);
775 static int bif_open_file(struct bif_entry
*entry
)
777 int fd
= open(entry
->filename
, O_RDONLY
);
780 printf("Error opening file %s\n", entry
->filename
);
785 static const struct bif_file_type
*get_file_type(struct bif_entry
*entry
)
787 int fd
= bif_open_file(entry
);
794 if (read(fd
, &header
, sizeof(header
)) != sizeof(header
)) {
795 printf("Error reading file %s", entry
->filename
);
801 for (i
= 0; i
< ARRAY_SIZE(bif_file_types
); i
++) {
802 const struct bif_file_type
*type
= &bif_file_types
[i
];
806 if (type
->header
== be32_to_cpu(header
))
813 #define NEXT_CHAR(str, chr) ({ \
814 char *_n = strchr(str, chr); \
820 static char *skip_whitespace(char *str
)
822 while (*str
== ' ' || *str
== '\t')
828 int zynqmpbif_copy_image(int outfd
, struct image_tool_params
*mparams
)
830 char *bif
, *bifp
, *bifpn
;
832 struct bif_entry entries
[32] = { { 0 } };
834 struct bif_entry
*entry
= entries
;
842 /* Read .bif input file */
843 bif
= read_full_file(mparams
->datafile
, NULL
);
847 /* Interpret .bif file */
850 /* A bif description starts with a { section */
851 bifp
= NEXT_CHAR(bifp
, '{') + 1;
853 /* Read every line */
855 bifpn
= NEXT_CHAR(bifp
, '\n');
857 if (bifpn
[-1] == '\r')
864 line
= skip_whitespace(line
);
870 const struct bif_flags
*bf
;
872 line
= skip_whitespace(line
);
873 bf
= find_flag(line
);
877 line
+= strlen(bf
->name
);
879 line
= bf
->parse(line
, entry
);
881 entry
->flags
|= 1ULL << bf
->flag
;
886 /* Go to next attribute or quit */
896 /* End of image description */
901 line
= skip_whitespace(line
);
902 entry
->filename
= line
;
911 for (i
= 0; i
< nr_entries
; i
++) {
912 debug("Entry flags=%#lx name=%s\n", entries
[i
].flags
,
913 entries
[i
].filename
);
917 * Some entries are actually configuration option for other ones,
918 * let's apply them in an intermediate step.
920 for (i
= 0; i
< nr_entries
; i
++) {
921 struct bif_entry
*entry
= &entries
[i
];
923 if (entry
->flags
& (1ULL << BIF_FLAG_FSBL_CONFIG
))
924 if (bif_fsbl_config(entry
, entries
, nr_entries
))
928 /* Make sure PMUFW comes before bootloader */
929 for (i
= 0; i
< nr_entries
; i
++) {
930 struct bif_entry
*entry
= &entries
[i
];
932 if (entry
->flags
& (1ULL << BIF_FLAG_BOOTLOADER
))
934 if (entry
->flags
& (1ULL << BIF_FLAG_PMUFW_IMAGE
)) {
936 struct bif_entry tmp
= *entry
;
938 *entry
= entries
[bldr
];
944 for (i
= 0; i
< nr_entries
; i
++) {
945 struct bif_entry
*entry
= &entries
[i
];
946 const struct bif_file_type
*type
;
949 if (entry
->flags
& (1ULL << BIF_FLAG_FSBL_CONFIG
))
952 type
= get_file_type(entry
);
956 debug("type=%s file=%s\n", type
->name
, entry
->filename
);
957 r
= type
->add(entry
);
962 /* Calculate checksums */
963 csum
= zynqmp_csum(&bif_output
.header
->width_detection
,
964 &bif_output
.header
->checksum
);
965 bif_output
.header
->checksum
= cpu_to_le32(csum
);
967 if (bif_output
.imgheader
) {
968 csum
= zynqmp_csum(bif_output
.imgheader
,
969 &bif_output
.imgheader
->checksum
);
970 bif_output
.imgheader
->checksum
= cpu_to_le32(csum
);
973 /* Write headers and components */
974 if (lseek(outfd
, 0, SEEK_SET
) != 0)
977 len
= bif_output
.data_len
;
978 bifp
= bif_output
.data
;
982 r
= write(outfd
, bifp
, len
);
992 fprintf(stderr
, "Error: Failed to create image.\n");
996 /* Needs to be stubbed out so we can print after creation */
997 static void zynqmpbif_set_header(void *ptr
, struct stat
*sbuf
, int ifd
,
998 struct image_tool_params
*params
)
1002 static struct zynqmp_header zynqmpimage_header
;
1006 "Xilinx ZynqMP Boot Image support (bif)",
1007 sizeof(struct zynqmp_header
),
1008 (void *)&zynqmpimage_header
,
1009 zynqmpbif_check_params
,
1011 zynqmpimage_print_header
,
1012 zynqmpbif_set_header
,
1014 zynqmpbif_check_image_types
,