From 1487e970bd7e6e9108398b2768b0af869a9c12bb Mon Sep 17 00:00:00 2001 From: Matthew Hagan Date: Thu, 5 Aug 2021 22:24:40 +0000 Subject: [PATCH] firmware-utils: mkmerakifw-old: Add le32 support MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit mkmerakifw-old was created for the z1 which uses the AR9344 SoC with be32 addressing. The MX64/MX65 devices use the same header style, however these boards use a BCM NSP SoC with le32 addressing. Since we may be booting initramfs images with this header, which may be of any size, within reason, board->imagelen is set to 0. The kernel image shoule be limited in the image Makefile. Signed-off-by: Matthew Hagan Signed-off-by: Rafał Miłecki --- src/mkmerakifw-old.c | 63 ++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/src/mkmerakifw-old.c b/src/mkmerakifw-old.c index 76fd487..a3e7a72 100644 --- a/src/mkmerakifw-old.c +++ b/src/mkmerakifw-old.c @@ -44,6 +44,7 @@ struct board_info { uint32_t imagelen; uint32_t load_addr; uint32_t entry; + bool le32; }; /* @@ -62,7 +63,16 @@ static const struct board_info boards[] = { .magic = 0x4d495053, .imagelen = 0x007e0000, .load_addr = 0x80060000, - .entry = 0x80060000 + .entry = 0x80060000, + .le32 = 0, + }, { + .id = "mx64", + .description = "Meraki MX64/MX65", + .magic = 0x4d495053, + .imagelen = 0x00000000, + .load_addr = 0x60008000, + .entry = 0x60008000, + .le32 = 1, }, { /* terminating entry */ } @@ -123,9 +133,11 @@ static void usage(int status) exit(status); } -static void writel(unsigned char *buf, size_t offset, uint32_t value) +static void writel(unsigned char *buf, size_t offset, uint32_t value, bool le32) { - value = htonl(value); + if (!le32) + value = htonl(value); + memcpy(buf + offset, &value, sizeof(uint32_t)); } @@ -201,21 +213,25 @@ static inline uint32_t crc32_accumulate_8(const uint32_t crc, const uint8_t ch) return crc32_table[(crc ^ ch) & 0xff] ^ (crc >> 8); } -static void crc32_csum(uint8_t *buf, const size_t len) +static void crc32_csum(uint8_t *buf, const size_t len, bool le32) { + int j, k, l, m; uint32_t crc; size_t i; crc = ~0; + k = le32 * 3; + l = le32 * -2 + 1; + for (i = 0; i < len; i += 4) { - crc = crc32_accumulate_8(crc, buf[i + 3]); - crc = crc32_accumulate_8(crc, buf[i + 2]); - crc = crc32_accumulate_8(crc, buf[i + 1]); - crc = crc32_accumulate_8(crc, buf[i]); + for (j = 3; j >= 0; j -= 1) { + m = (j - k) * l; + crc = crc32_accumulate_8(crc, buf[i + m]); + } } crc = ~crc; - writel(buf, HDR_OFF_CHECKSUM, crc); + writel(buf, HDR_OFF_CHECKSUM, crc, le32); } @@ -229,11 +245,14 @@ static int meraki_build_hdr(const struct board_info *board, const size_t klen, size_t rc; buflen = board->imagelen; - kspace = buflen - HDR_LENGTH; - if (klen > kspace) { - ERR("kernel file is too big - max size: 0x%08lX\n", kspace); - return EXIT_FAILURE; + if (buflen > 0) { + kspace = buflen - HDR_LENGTH; + + if (klen > kspace) { + ERR("kernel file is too big - max size: 0x%08lX\n", kspace); + return EXIT_FAILURE; + } } /* If requested, resize buffer to remove padding */ @@ -253,23 +272,23 @@ static int meraki_build_hdr(const struct board_info *board, const size_t klen, fread(kernel, klen, 1, in); /* Write magic values and filler */ - writel(buf, HDR_OFF_MAGIC1, board->magic); - writel(buf, HDR_OFF_FILLER0, 0); - writel(buf, HDR_OFF_FILLER1, 0); - writel(buf, HDR_OFF_FILLER2, 0); + writel(buf, HDR_OFF_MAGIC1, board->magic, board->le32); + writel(buf, HDR_OFF_FILLER0, 0, board->le32); + writel(buf, HDR_OFF_FILLER1, 0, board->le32); + writel(buf, HDR_OFF_FILLER2, 0, board->le32); /* Write load and kernel entry point address */ - writel(buf, HDR_OFF_LOAD_ADDR, board->load_addr); - writel(buf, HDR_OFF_ENTRY, board->entry); + writel(buf, HDR_OFF_LOAD_ADDR, board->load_addr, board->le32); + writel(buf, HDR_OFF_ENTRY, board->entry, board->le32); /* Write header and image length */ - writel(buf, HDR_OFF_IMAGELEN, klen); + writel(buf, HDR_OFF_IMAGELEN, klen, board->le32); /* this gets replaced later, after the checksum has been calculated */ - writel(buf, HDR_OFF_CHECKSUM, 0); + writel(buf, HDR_OFF_CHECKSUM, 0, board->le32); /* Write checksum */ - crc32_csum(buf, klen + HDR_LENGTH); + crc32_csum(buf, klen + HDR_LENGTH, board->le32); rc = fwrite(buf, buflen, 1, out); -- 2.30.2