void zynqmpimage_print_header(const void *ptr, struct image_tool_params *params)
{
struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr;
+ struct partition_header *ph;
int i;
printf("Image Type : Xilinx ZynqMP Boot Image support\n");
le32_to_cpu(zynqhdr->register_init[i].data));
}
- if (zynqhdr->image_header_table_offset) {
- struct image_header_table *iht = (void *)ptr +
- zynqhdr->image_header_table_offset;
- struct partition_header *ph;
- uint32_t ph_offset;
- uint32_t next;
- int i;
-
- ph_offset = le32_to_cpu(iht->partition_header_offset) * 4;
- ph = (void *)ptr + ph_offset;
- for (i = 0; i < le32_to_cpu(iht->nr_parts); i++) {
- next = le32_to_cpu(ph->next_partition_offset) * 4;
-
- print_partition(ptr, ph);
-
- ph = (void *)ptr + next;
- }
+ for_each_zynqmp_part(zynqhdr, i, ph) {
+ print_partition(ptr, ph);
}
free(dynamic_header);
return -1;
}
- return !(params->lflag || params->dflag);
+ return !(params->lflag || params->dflag || params->outfile);
}
static int zynqmpimage_check_image_types(uint8_t type)
zynqhdr->checksum = zynqmpimage_checksum(zynqhdr);
}
+static int zynqmpimage_partition_extract(struct zynqmp_header *zynqhdr,
+ const struct partition_header *ph,
+ const char *filename)
+{
+ ulong data = (ulong)zynqmp_get_offset(zynqhdr, ph->offset);
+ unsigned long len = le32_to_cpu(ph->len_enc) * 4;
+
+ return imagetool_save_subimage(filename, data, len);
+}
+
+/**
+ * zynqmpimage_extract_contents - retrieve a sub-image component from the image
+ * @ptr: pointer to the image header
+ * @params: command line parameters
+ *
+ * returns:
+ * zero in case of success or a negative value if fail.
+ */
+static int zynqmpimage_extract_contents(void *ptr, struct image_tool_params *params)
+{
+ struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr;
+ struct partition_header *ph;
+ int i;
+
+ for_each_zynqmp_part(zynqhdr, i, ph) {
+ if (i == params->pflag)
+ return zynqmpimage_partition_extract(ptr, ph, params->outfile);
+ }
+
+ printf("No partition found\n");
+ return -1;
+}
+
static int zynqmpimage_vrec_header(struct image_tool_params *params,
struct image_type_params *tparams)
{
zynqmpimage_verify_header,
zynqmpimage_print_header,
zynqmpimage_set_header,
- NULL,
+ zynqmpimage_extract_contents,
zynqmpimage_check_image_types,
NULL,
zynqmpimage_vrec_header
void zynqmpimage_default_header(struct zynqmp_header *ptr);
void zynqmpimage_print_header(const void *ptr, struct image_tool_params *params);
+static inline struct image_header_table *
+zynqmp_get_iht(const struct zynqmp_header *zynqhdr)
+{
+ if (!zynqhdr->image_header_table_offset)
+ return NULL;
+ return (struct image_header_table *)((void *)zynqhdr + zynqhdr->image_header_table_offset);
+}
+
+static inline void *zynqmp_get_offset(const struct zynqmp_header *zynqhdr,
+ uint32_t offset)
+{
+ uint32_t offset_cpu = le32_to_cpu(offset);
+
+ if (!offset_cpu)
+ return NULL;
+ return (void *)zynqhdr + offset_cpu * 4;
+}
+
+static inline struct partition_header *
+zynqmp_part_first(const struct zynqmp_header *zynqhdr)
+{
+ struct image_header_table *iht;
+
+ iht = zynqmp_get_iht(zynqhdr);
+ if (!iht)
+ return NULL;
+
+ return zynqmp_get_offset(zynqhdr, iht->partition_header_offset);
+}
+
+static inline struct partition_header *
+zynqmp_part_next(const struct zynqmp_header *zynqhdr,
+ const struct partition_header *ph)
+{
+ return zynqmp_get_offset(zynqhdr, ph->next_partition_offset);
+}
+
+static inline size_t zynqmp_part_count(const struct zynqmp_header *zynqhdr)
+{
+ struct image_header_table *iht;
+
+ iht = zynqmp_get_iht(zynqhdr);
+ if (!iht)
+ return 0;
+
+ return le32_to_cpu(iht->nr_parts);
+}
+
+#define _for_each_zynqmp_part(_zynqhdr, _iter, _ph, _start, _count) \
+ for (_iter = 0, _ph = _start; \
+ _iter < (_count) && _ph; \
+ _iter++, _ph = zynqmp_part_next(_zynqhdr, _ph))
+
+#define for_each_zynqmp_part(_zynqhdr, _iter, _ph) \
+ _for_each_zynqmp_part(_zynqhdr, _iter, _ph, \
+ zynqmp_part_first(_zynqhdr), \
+ zynqmp_part_count(_zynqhdr))
+
#endif /* _ZYNQMPIMAGE_H_ */