]> Git Repo - J-u-boot.git/blobdiff - tools/kwbimage.c
tools: kwbimage: Set BOOT_FROM by default to SPI
[J-u-boot.git] / tools / kwbimage.c
index 944a108cee8b286754062949188d64597bca1cd2..38b6e2fed201c5fdb8c7435b54dc0759f4607c3a 100644 (file)
@@ -1,7 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Image manipulator for Marvell SoCs
- *  supports Kirkwood, Dove, Armada 370, Armada XP, and Armada 38x
+ *  supports Kirkwood, Dove, Armada 370, Armada XP, Armada 375, Armada 38x and
+ *  Armada 39x
  *
  * (C) Copyright 2013 Thomas Petazzoni
@@ -100,6 +101,8 @@ enum image_cfg_type {
        IMAGE_CFG_DATA,
        IMAGE_CFG_DATA_DELAY,
        IMAGE_CFG_BAUDRATE,
+       IMAGE_CFG_UART_PORT,
+       IMAGE_CFG_UART_MPP,
        IMAGE_CFG_DEBUG,
        IMAGE_CFG_KAK,
        IMAGE_CFG_CSK,
@@ -128,6 +131,8 @@ static const char * const id_strs[] = {
        [IMAGE_CFG_DATA] = "DATA",
        [IMAGE_CFG_DATA_DELAY] = "DATA_DELAY",
        [IMAGE_CFG_BAUDRATE] = "BAUDRATE",
+       [IMAGE_CFG_UART_PORT] = "UART_PORT",
+       [IMAGE_CFG_UART_MPP] = "UART_MPP",
        [IMAGE_CFG_DEBUG] = "DEBUG",
        [IMAGE_CFG_KAK] = "KAK",
        [IMAGE_CFG_CSK] = "CSK",
@@ -160,6 +165,8 @@ struct image_cfg_element {
                struct ext_hdr_v0_reg regdata;
                unsigned int regdata_delay;
                unsigned int baudrate;
+               unsigned int uart_port;
+               unsigned int uart_mpp;
                unsigned int debug;
                const char *key_name;
                int csk_idx;
@@ -259,6 +266,18 @@ static bool image_get_spezialized_img(void)
        return e->sec_specialized_img;
 }
 
+static int image_get_bootfrom(void)
+{
+       struct image_cfg_element *e;
+
+       e = image_find_option(IMAGE_CFG_BOOT_FROM);
+       if (!e)
+               /* fallback to SPI if no BOOT_FROM is not provided */
+               return IBR_HDR_SPI_ID;
+
+       return e->bootfrom;
+}
+
 /*
  * Compute a 8-bit checksum of a memory area. This algorithm follows
  * the requirements of the Marvell SoC BootROM specifications.
@@ -280,14 +299,6 @@ static uint8_t image_checksum8(void *start, uint32_t len)
        return csum;
 }
 
-size_t kwbimage_header_size(unsigned char *ptr)
-{
-       if (kwbimage_version((void *)ptr) == 0)
-               return sizeof(struct main_hdr_v0);
-       else
-               return KWBHEADER_V1_SIZE((struct main_hdr_v1 *)ptr);
-}
-
 /*
  * Verify checksum over a complete header that includes the checksum field.
  * Return 1 when OK, otherwise 0.
@@ -298,7 +309,7 @@ static int main_hdr_checksum_ok(void *hdr)
        struct main_hdr_v0 *main_hdr = (struct main_hdr_v0 *)hdr;
        uint8_t checksum;
 
-       checksum = image_checksum8(hdr, kwbimage_header_size(hdr));
+       checksum = image_checksum8(hdr, kwbheader_size_for_csum(hdr));
        /* Calculated checksum includes the header checksum field. Compensate
         * for that.
         */
@@ -882,12 +893,11 @@ static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
                cpu_to_le32(payloadsz - headersz);
        main_hdr->srcaddr   = cpu_to_le32(headersz);
        main_hdr->ext       = has_ext;
+       main_hdr->version   = 0;
        main_hdr->destaddr  = cpu_to_le32(params->addr);
        main_hdr->execaddr  = cpu_to_le32(params->ep);
+       main_hdr->blockid   = image_get_bootfrom();
 
-       e = image_find_option(IMAGE_CFG_BOOT_FROM);
-       if (e)
-               main_hdr->blockid = e->bootfrom;
        e = image_find_option(IMAGE_CFG_NAND_ECC_MODE);
        if (e)
                main_hdr->nandeccmode = e->nandeccmode;
@@ -939,6 +949,12 @@ static size_t image_headersz_v1(int *hasext)
         */
        headersz = sizeof(struct main_hdr_v1);
 
+       if (image_get_csk_index() >= 0) {
+               headersz += sizeof(struct secure_hdr_v1);
+               if (hasext)
+                       *hasext = 1;
+       }
+
        count = image_count_options(IMAGE_CFG_DATA);
        if (count > 0)
                headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4;
@@ -970,15 +986,10 @@ static size_t image_headersz_v1(int *hasext)
                        return 0;
                }
 
-               headersz += sizeof(struct opt_hdr_v1) +
-                       ALIGN(s.st_size, 4) +
-                       (binarye->binary.nargs + 2) * sizeof(uint32_t);
-               if (hasext)
-                       *hasext = 1;
-       }
-
-       if (image_get_csk_index() >= 0) {
-               headersz += sizeof(struct secure_hdr_v1);
+               headersz += sizeof(struct opt_hdr_v1) + sizeof(uint32_t) +
+                       (binarye->binary.nargs) * sizeof(uint32_t);
+               headersz = ALIGN(headersz, 16);
+               headersz += ALIGN(s.st_size, 4) + sizeof(uint32_t);
                if (hasext)
                        *hasext = 1;
        }
@@ -991,9 +1002,12 @@ static size_t image_headersz_v1(int *hasext)
 }
 
 int add_binary_header_v1(uint8_t **cur, uint8_t **next_ext,
-                        struct image_cfg_element *binarye)
+                        struct image_cfg_element *binarye,
+                        struct main_hdr_v1 *main_hdr)
 {
        struct opt_hdr_v1 *hdr = (struct opt_hdr_v1 *)*cur;
+       uint32_t add_args;
+       uint32_t offset;
        uint32_t *args;
        size_t binhdrsz;
        struct stat s;
@@ -1016,12 +1030,6 @@ int add_binary_header_v1(uint8_t **cur, uint8_t **next_ext,
                goto err_close;
        }
 
-       binhdrsz = sizeof(struct opt_hdr_v1) +
-               (binarye->binary.nargs + 2) * sizeof(uint32_t) +
-               ALIGN(s.st_size, 4);
-       hdr->headersz_lsb = cpu_to_le16(binhdrsz & 0xFFFF);
-       hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16;
-
        *cur += sizeof(struct opt_hdr_v1);
 
        args = (uint32_t *)*cur;
@@ -1032,6 +1040,19 @@ int add_binary_header_v1(uint8_t **cur, uint8_t **next_ext,
 
        *cur += (binarye->binary.nargs + 1) * sizeof(uint32_t);
 
+       /*
+        * ARM executable code inside the BIN header on some mvebu platforms
+        * (e.g. A370, AXP) must always be aligned with the 128-bit boundary.
+        * This requirement can be met by inserting dummy arguments into
+        * BIN header, if needed.
+        */
+       offset = *cur - (uint8_t *)main_hdr;
+       add_args = ((16 - offset % 16) % 16) / sizeof(uint32_t);
+       if (add_args) {
+               *(args - 1) = cpu_to_le32(binarye->binary.nargs + add_args);
+               *cur += add_args * sizeof(uint32_t);
+       }
+
        ret = fread(*cur, s.st_size, 1, bin);
        if (ret != 1) {
                fprintf(stderr,
@@ -1050,6 +1071,12 @@ int add_binary_header_v1(uint8_t **cur, uint8_t **next_ext,
 
        *cur += sizeof(uint32_t);
 
+       binhdrsz = sizeof(struct opt_hdr_v1) +
+               (binarye->binary.nargs + add_args + 2) * sizeof(uint32_t) +
+               ALIGN(s.st_size, 4);
+       hdr->headersz_lsb = cpu_to_le16(binhdrsz & 0xFFFF);
+       hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16;
+
        return 0;
 
 err_close:
@@ -1215,18 +1242,26 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
        main_hdr->srcaddr      = cpu_to_le32(headersz);
        main_hdr->ext          = hasext;
        main_hdr->version      = 1;
-       e = image_find_option(IMAGE_CFG_BOOT_FROM);
-       if (e)
-               main_hdr->blockid = e->bootfrom;
+       main_hdr->blockid      = image_get_bootfrom();
+
        e = image_find_option(IMAGE_CFG_NAND_BLKSZ);
        if (e)
                main_hdr->nandblocksize = e->nandblksz / (64 * 1024);
+       e = image_find_option(IMAGE_CFG_NAND_PAGESZ);
+       if (e)
+               main_hdr->nandpagesize = cpu_to_le16(e->nandpagesz);
        e = image_find_option(IMAGE_CFG_NAND_BADBLK_LOCATION);
        if (e)
                main_hdr->nandbadblklocation = e->nandbadblklocation;
        e = image_find_option(IMAGE_CFG_BAUDRATE);
        if (e)
-               main_hdr->options = baudrate_to_option(e->baudrate);
+               main_hdr->options |= baudrate_to_option(e->baudrate);
+       e = image_find_option(IMAGE_CFG_UART_PORT);
+       if (e)
+               main_hdr->options |= (e->uart_port & 3) << 3;
+       e = image_find_option(IMAGE_CFG_UART_MPP);
+       if (e)
+               main_hdr->options |= (e->uart_mpp & 7) << 5;
        e = image_find_option(IMAGE_CFG_DEBUG);
        if (e)
                main_hdr->flags = e->debug ? 0x1 : 0;
@@ -1306,7 +1341,7 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
                if (e->type != IMAGE_CFG_BINARY)
                        continue;
 
-               if (add_binary_header_v1(&cur, &next_ext, e))
+               if (add_binary_header_v1(&cur, &next_ext, e, main_hdr))
                        return NULL;
        }
 
@@ -1428,6 +1463,12 @@ static int image_create_config_parse_oneline(char *line,
        case IMAGE_CFG_BAUDRATE:
                el->baudrate = strtoul(value1, NULL, 10);
                break;
+       case IMAGE_CFG_UART_PORT:
+               el->uart_port = strtoul(value1, NULL, 16);
+               break;
+       case IMAGE_CFG_UART_MPP:
+               el->uart_mpp = strtoul(value1, NULL, 16);
+               break;
        case IMAGE_CFG_DEBUG:
                el->debug = strtoul(value1, NULL, 10);
                break;
@@ -1527,17 +1568,6 @@ static int image_get_version(void)
        return e->version;
 }
 
-static int image_get_bootfrom(void)
-{
-       struct image_cfg_element *e;
-
-       e = image_find_option(IMAGE_CFG_BOOT_FROM);
-       if (!e)
-               return -1;
-
-       return e->bootfrom;
-}
-
 static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
                                struct image_tool_params *params)
 {
@@ -1649,8 +1679,8 @@ static int kwbimage_check_image_types(uint8_t type)
 static int kwbimage_verify_header(unsigned char *ptr, int image_size,
                                  struct image_tool_params *params)
 {
-       uint8_t checksum;
-       size_t header_size = kwbimage_header_size(ptr);
+       size_t header_size = kwbheader_size(ptr);
+       uint8_t csum;
 
        if (header_size > image_size)
                return -FDT_ERR_BADSTRUCTURE;
@@ -1663,17 +1693,10 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size,
                struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
 
                if (mhdr->ext & 0x1) {
-                       struct ext_hdr_v0 *ext_hdr;
-
-                       if (header_size + sizeof(*ext_hdr) > image_size)
-                               return -FDT_ERR_BADSTRUCTURE;
+                       struct ext_hdr_v0 *ext_hdr = (void *)(mhdr + 1);
 
-                       ext_hdr = (struct ext_hdr_v0 *)
-                               (ptr + sizeof(struct main_hdr_v0));
-                       checksum = image_checksum8(ext_hdr,
-                                                  sizeof(struct ext_hdr_v0)
-                                                  - sizeof(uint8_t));
-                       if (checksum != ext_hdr->checksum)
+                       csum = image_checksum8(ext_hdr, sizeof(*ext_hdr) - 1);
+                       if (csum != ext_hdr->checksum)
                                return -FDT_ERR_BADSTRUCTURE;
                }
        } else if (kwbimage_version(ptr) == 1) {
@@ -1832,7 +1855,7 @@ static int kwbimage_generate(struct image_tool_params *params,
 static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params)
 {
        struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
-       size_t header_size = kwbimage_header_size(ptr);
+       size_t header_size = kwbheader_size(ptr);
        struct opt_hdr_v1 *ohdr;
        int idx = params->pflag;
        int cur_idx = 0;
This page took 0.036627 seconds and 4 git commands to generate.