diff options
author | Michael Tretter <m.tretter@pengutronix.de> | 2019-10-25 12:55:42 +0000 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-10-28 11:58:37 +0100 |
commit | f21fd69259d1a3a1215be37dfcc268808e8c5c9b (patch) | |
tree | 064a843ef16c25470a03dd46fcc1ca0ea7fb395a /drivers | |
parent | fe9c64eb2f3797c38946d432438c11163e899c5b (diff) | |
download | barebox-f21fd69259d1a3a1215be37dfcc268808e8c5c9b.tar.gz barebox-f21fd69259d1a3a1215be37dfcc268808e8c5c9b.tar.xz |
firmware: zynqmp-fpga: print Xilinx bitstream header
The bitstream header has 5 fields, that start with a char for the type.
Four fields have a big-ending length and a null-terminated string for
the design name, the part number, and the date and time of creation. The
last field is a big-endian 32 bit unsigned int for the size of the
bitstream.
Print this info when loading the bitstream.
Signed-off-by: Michael Tretter <m.tretter@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/firmware/zynqmp-fpga.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/firmware/zynqmp-fpga.c b/drivers/firmware/zynqmp-fpga.c index 47862a7e3d..887865883a 100644 --- a/drivers/firmware/zynqmp-fpga.c +++ b/drivers/firmware/zynqmp-fpga.c @@ -45,6 +45,19 @@ struct fpgamgr { u32 features; }; +struct bs_header { + __be16 length; + u8 padding[9]; + __be16 size; + char entries[0]; +} __attribute__ ((packed)); + +struct bs_header_entry { + char type; + __be16 length; + char data[0]; +} __attribute__ ((packed)); + /* * Xilinx KU040 Bitstream Composition: * Bitstream can be provided with an optinal header (`struct bs_header`). @@ -143,6 +156,42 @@ static int get_header_length(const char *header, size_t size) return -EINVAL; } +static void zynqmp_fpga_show_header(const struct device_d *dev, + struct bs_header *header, size_t size) +{ + struct bs_header_entry *entry; + unsigned int i; + unsigned int length; + + for (i = 0; i < size - sizeof(*header); i += sizeof(*entry) + length) { + entry = (struct bs_header_entry *)&header->entries[i]; + length = __be16_to_cpu(entry->length); + + switch (entry->type) { + case 'a': + printf("Design: %s\n", entry->data); + break; + case 'b': + printf("Part number: %s\n", entry->data); + break; + case 'c': + printf("Date: %s\n", entry->data); + break; + case 'd': + printf("Time: %s\n", entry->data); + break; + case 'e': + /* Size entry does not have a length but is be32 int */ + printf("Size: %d bytes\n", + (length << 16) + (entry->data[0] << 8) + entry->data[1]); + return; + default: + dev_warn(dev, "Invalid header entry: %c", entry->type); + return; + } + } +} + static int fpgamgr_program_finish(struct firmware_handler *fh) { struct fpgamgr *mgr = container_of(fh, struct fpgamgr, fh); @@ -167,6 +216,8 @@ static int fpgamgr_program_finish(struct firmware_handler *fh) status = header_length; goto err_free; } + zynqmp_fpga_show_header(&mgr->dev, + (struct bs_header *)mgr->buf, header_length); body = (u32 *)&mgr->buf[header_length]; body_length = mgr->size - header_length; |