aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2024-01-17 09:27:43 -0500
committerTom Rini <trini@konsulko.com>2024-01-17 09:27:43 -0500
commit002764d7399091082f644c022d9b0088855e7797 (patch)
tree9f34ed0da52a10c77eae7ff522191274cd12c10f /tools
parentbdaa0b27b3b384a8dbe2dc9d48ce870b0854d6ec (diff)
parent0a4595b538cc601563e828270ca822720c6eb6fe (diff)
downloadu-boot-002764d7399091082f644c022d9b0088855e7797.zip
u-boot-002764d7399091082f644c022d9b0088855e7797.tar.gz
u-boot-002764d7399091082f644c022d9b0088855e7797.tar.bz2
Merge tag 'xilinx-for-v2024.04-rc1-v2' of https://source.denx.de/u-boot/custodians/u-boot-microblaze
Xilinx changes for v2024.04-rc1-v2 xilinx: - Enable NFS, WGET, DNS and BLKMAP by default zynqmp: - Support new power-management node - Remove multiple blank lines from DTSes - Wire multiboot with DFU infrastructure - Fix i2c-gpio pinctrl group name - SOM DT changes (phy on kd240, kv260 cleanups - Cleanup i2c bus on zcu1285 - DT cleanup (fix node names not to use _) - Fix USB interrupts - Cleanup zcu100 DT - Add support for kaslr-seed zynqmp_r5: - Fix W=1 issue with missing dir tools: - Improve zynqmpimage mkimage support
Diffstat (limited to 'tools')
-rw-r--r--tools/zynqmpimage.c113
-rw-r--r--tools/zynqmpimage.h107
2 files changed, 199 insertions, 21 deletions
diff --git a/tools/zynqmpimage.c b/tools/zynqmpimage.c
index bb54f41..4db9877 100644
--- a/tools/zynqmpimage.c
+++ b/tools/zynqmpimage.c
@@ -135,10 +135,59 @@ static int zynqmpimage_verify_header(unsigned char *ptr, int image_size,
return 0;
}
+static struct image_header *
+find_partition_image(const struct zynqmp_header *zynqhdr,
+ const struct partition_header *ph)
+{
+ struct partition_header *ph_walk;
+ struct image_header *ih;
+ int i;
+
+ for_each_zynqmp_image(zynqhdr, ih) {
+ for_each_zynqmp_part_in_image(zynqhdr, i, ph_walk, ih) {
+ if (ph == ph_walk)
+ return ih;
+ }
+ }
+
+ return NULL;
+}
+
+static void print_partition_name(const struct zynqmp_header *zynqhdr,
+ const struct partition_header *ph)
+{
+ const struct image_header *ih;
+ size_t word_len;
+ char *name;
+ int i;
+
+ ih = find_partition_image(zynqhdr, ph);
+ if (!ih)
+ return;
+
+ /* Name is stored in big-endian words, find the terminating word and
+ * byte-swap into a new buffer
+ */
+ word_len = strlen((char *)ih->image_name);
+ word_len = ALIGN(word_len + 1, 4);
+
+ name = calloc(1, word_len);
+ if (!name)
+ return;
+
+ for (i = 0; i < word_len / 4; i++)
+ ((uint32_t *)name)[i] = uswap_32(ih->image_name[i]);
+
+ printf(" Image name : %s\n", name);
+ free(name);
+}
+
static void print_partition(const void *ptr, const struct partition_header *ph)
{
uint32_t attr = le32_to_cpu(ph->attributes);
unsigned long len = le32_to_cpu(ph->len) * 4;
+ unsigned long len_enc = le32_to_cpu(ph->len_enc) * 4;
+ unsigned long len_unenc = le32_to_cpu(ph->len_unenc) * 4;
const char *part_owner;
const char *dest_devs[0x8] = {
"none", "PS", "PL", "PMU", "unknown", "unknown", "unknown",
@@ -161,8 +210,13 @@ static void print_partition(const void *ptr, const struct partition_header *ph)
dest_cpus[(attr & PART_ATTR_DEST_CPU_MASK) >> 8],
dest_devs[(attr & PART_ATTR_DEST_DEVICE_MASK) >> 4]);
+ print_partition_name(ptr, ph);
printf(" Offset : 0x%08x\n", le32_to_cpu(ph->offset) * 4);
printf(" Size : %lu (0x%lx) bytes\n", len, len);
+ if (len != len_unenc)
+ printf(" Size Data : %lu (0x%lx) bytes\n", len_unenc, len_unenc);
+ if (len_unenc != len_enc)
+ printf(" Size Enc : %lu (0x%lx) bytes\n", len_unenc, len_unenc);
printf(" Load : 0x%08llx",
(unsigned long long)le64_to_cpu(ph->load_address));
if (ph->load_address != ph->entry_point)
@@ -212,6 +266,7 @@ static void print_partition(const void *ptr, const struct partition_header *ph)
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");
@@ -249,25 +304,8 @@ void zynqmpimage_print_header(const void *ptr, struct image_tool_params *params)
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;
-
- /* Partition 0 is the base image itself */
- if (i)
- print_partition(ptr, ph);
-
- ph = (void *)ptr + next;
- }
+ for_each_zynqmp_part(zynqhdr, i, ph) {
+ print_partition(ptr, ph);
}
free(dynamic_header);
@@ -292,7 +330,7 @@ static int zynqmpimage_check_params(struct image_tool_params *params)
return -1;
}
- return !(params->lflag || params->dflag);
+ return !(params->lflag || params->dflag || params->outfile);
}
static int zynqmpimage_check_image_types(uint8_t type)
@@ -427,6 +465,39 @@ static void zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
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)
{
@@ -480,7 +551,7 @@ U_BOOT_IMAGE_TYPE(
zynqmpimage_verify_header,
zynqmpimage_print_header,
zynqmpimage_set_header,
- NULL,
+ zynqmpimage_extract_contents,
zynqmpimage_check_image_types,
NULL,
zynqmpimage_vrec_header
diff --git a/tools/zynqmpimage.h b/tools/zynqmpimage.h
index ca74898..7c47dc0 100644
--- a/tools/zynqmpimage.h
+++ b/tools/zynqmpimage.h
@@ -51,6 +51,14 @@ struct image_header_table {
uint32_t checksum; /* 0x3c */
};
+struct image_header {
+ uint32_t next_image_header_offset; /* 0x00 */
+ uint32_t corresponding_partition_header; /* 0x04 */
+ uint32_t __reserved1; /* 0x08 */
+ uint32_t partition_count; /* 0x0c */
+ uint32_t image_name[]; /* 0x10 */
+};
+
#define PART_ATTR_VEC_LOCATION 0x800000
#define PART_ATTR_BS_BLOCK_SIZE_MASK 0x700000
#define PART_ATTR_BS_BLOCK_SIZE_DEFAULT 0x000000
@@ -135,4 +143,103 @@ struct zynqmp_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))
+
+static inline struct partition_header *
+zynqmp_part_in_image_first(const struct zynqmp_header *zynqhdr,
+ const struct image_header *ih)
+{
+ return zynqmp_get_offset(zynqhdr, ih->corresponding_partition_header);
+}
+
+static inline size_t zynqmp_part_in_image_count(const struct image_header *ih)
+{
+ return le32_to_cpu(ih->partition_count);
+}
+
+#define for_each_zynqmp_part_in_image(_zynqhdr, _iter, _ph, _ih) \
+ _for_each_zynqmp_part(_zynqhdr, _iter, _ph, \
+ zynqmp_part_in_image_first(_zynqhdr, _ih), \
+ zynqmp_part_in_image_count(_ih))
+
+static inline struct image_header *
+zynqmp_image_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->image_header_offset);
+}
+
+static inline struct image_header *
+zynqmp_image_next(const struct zynqmp_header *zynqhdr,
+ const struct image_header *ih)
+{
+ return zynqmp_get_offset(zynqhdr, ih->next_image_header_offset);
+}
+
+#define for_each_zynqmp_image(_zynqhdr, _ih) \
+ for (_ih = zynqmp_image_first(_zynqhdr); \
+ _ih; \
+ _ih = zynqmp_image_next(_zynqhdr, _ih))
+
#endif /* _ZYNQMPIMAGE_H_ */