cmd: mvebu: bubt: add A38x support
authorJoel Johnson <mrjoel@lixil.net>
Fri, 17 Apr 2020 15:38:04 +0000 (09:38 -0600)
committerStefan Roese <sr@denx.de>
Wed, 22 Apr 2020 12:28:15 +0000 (14:28 +0200)
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>
cmd/mvebu/bubt.c

index 2041a7a29aa91b184bc1bcbe263c5f04edf54430..d399fb6da4d5d1c6c219d28902ae437208a23cf9 100644 (file)
@@ -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)
 {