summaryrefslogtreecommitdiff
path: root/cmd/mvebu
diff options
context:
space:
mode:
authorJoel Johnson <mrjoel@lixil.net>2020-04-17 09:38:04 -0600
committerStefan Roese <sr@denx.de>2020-04-22 14:28:15 +0200
commit8ec6db7813fbde251c786777b522b5e11dbf5c6b (patch)
tree6a1d4cf846e0a322052db2ea0cd2a13f16ed8f6f /cmd/mvebu
parentab2f757eb0513118ac16cab488ea1257ab7d9b83 (diff)
cmd: mvebu: bubt: add A38x support
Add support for Armada 38x devices in bubt flashing utility. This is based on (and streamlined from) the support in the SolidRun master-a38x vendor fork. Signed-off-by: Joel Johnson <mrjoel@lixil.net> Reviewed-by: Stefan Roese <sr@denx.de>
Diffstat (limited to 'cmd/mvebu')
-rw-r--r--cmd/mvebu/bubt.c69
1 files changed, 68 insertions, 1 deletions
diff --git a/cmd/mvebu/bubt.c b/cmd/mvebu/bubt.c
index 2041a7a29a..d399fb6da4 100644
--- a/cmd/mvebu/bubt.c
+++ b/cmd/mvebu/bubt.c
@@ -85,7 +85,29 @@ struct mvebu_image_info {
u32 encrypt_start_offset;
u32 encrypt_size;
};
-#endif /* CONFIG_ARMADA_XXX */
+#elif defined(CONFIG_ARMADA_38X) /* A38X */
+
+/* Structure of the main header, version 1 (Armada 370/38x/XP) */
+struct a38x_main_hdr_v1 {
+ u8 blockid; /* 0x0 */
+ u8 flags; /* 0x1 */
+ u16 reserved2; /* 0x2-0x3 */
+ u32 blocksize; /* 0x4-0x7 */
+ u8 version; /* 0x8 */
+ u8 headersz_msb; /* 0x9 */
+ u16 headersz_lsb; /* 0xA-0xB */
+ u32 srcaddr; /* 0xC-0xF */
+ u32 destaddr; /* 0x10-0x13 */
+ u32 execaddr; /* 0x14-0x17 */
+ u8 options; /* 0x18 */
+ u8 nandblocksize; /* 0x19 */
+ u8 nandbadblklocation; /* 0x1A */
+ u8 reserved4; /* 0x1B */
+ u16 reserved5; /* 0x1C-0x1D */
+ u8 ext; /* 0x1E */
+ u8 checksum; /* 0x1F */
+};
+#endif
struct bubt_dev {
char name[8];
@@ -621,7 +643,52 @@ static int check_image_header(void)
return 0;
}
+#elif defined(CONFIG_ARMADA_38X)
+static size_t a38x_header_size(const struct a38x_main_hdr_v1 *h)
+{
+ if (h->version == 1)
+ return (h->headersz_msb << 16) | le16_to_cpu(h->headersz_lsb);
+
+ printf("Error: Invalid A38x image (header version 0x%x unknown)!\n",
+ h->version);
+ return 0;
+}
+
+static uint8_t image_checksum8(const void *start, size_t len)
+{
+ u8 csum = 0;
+ const u8 *p = start;
+
+ while (len) {
+ csum += *p;
+ ++p;
+ --len;
+ }
+
+ return csum;
+}
+static int check_image_header(void)
+{
+ u8 checksum;
+ const struct a38x_main_hdr_v1 *hdr =
+ (struct a38x_main_hdr_v1 *)get_load_addr();
+ const size_t image_size = a38x_header_size(hdr);
+
+ if (!image_size)
+ return -ENOEXEC;
+
+ checksum = image_checksum8(hdr, image_size);
+ checksum -= hdr->checksum;
+ if (checksum != hdr->checksum) {
+ printf("Error: Bad A38x image checksum. 0x%x != 0x%x\n",
+ checksum, hdr->checksum);
+ return -ENOEXEC;
+ }
+
+ printf("Image checksum...OK!\n");
+ return 0;
+}
#else /* Not ARMADA? */
static int check_image_header(void)
{