Before, only 1 write_dcd_command table was built.
Now, a new table is built when the size changes.

Signed-off-by: Troy Kisky <troy.ki...@boundarydevices.com>
---
 tools/imximage.c |  153 ++++++++++++++++++++++++++----------------------------
 tools/imximage.h |   15 ++----
 2 files changed, 77 insertions(+), 91 deletions(-)

diff --git a/tools/imximage.c b/tools/imximage.c
index 0bfbec3..21c49e6 100644
--- a/tools/imximage.c
+++ b/tools/imximage.c
@@ -68,10 +68,9 @@ static table_entry_t imximage_versions[] = {
 static uint32_t imximage_version;
 
 static set_dcd_val_t set_dcd_val;
-static set_dcd_rst_t set_dcd_rst;
 static set_imx_hdr_t set_imx_hdr;
 static set_imx_size_t set_imx_size;
-static uint32_t max_dcd_entries;
+static uint32_t *p_max_dcd;
 static uint32_t g_flash_offset;
 
 static struct image_type_params imximage_params;
@@ -119,8 +118,10 @@ static void err_imximage_version(int version)
        exit(EXIT_FAILURE);
 }
 
+static uint32_t *p_entry;
+
 static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno,
-                                       int fld, uint32_t value, uint32_t off)
+                                       int fld, uint32_t value)
 {
        dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
 
@@ -133,13 +134,15 @@ static void set_dcd_val_v1(struct imx_header *imxhdr, 
char *name, int lineno,
                                name, lineno, value);
                        exit(EXIT_FAILURE);
                }
-               dcd_v1->addr_data[off].type = value;
+               *p_entry++ = value;
                break;
        case CFG_REG_ADDRESS:
-               dcd_v1->addr_data[off].addr = value;
+               *p_entry++ = value;
                break;
        case CFG_REG_VALUE:
-               dcd_v1->addr_data[off].value = value;
+               *p_entry++ = value;
+               dcd_v1->preamble.length = (char *)p_entry
+                               - (char *)&dcd_v1->addr_data[0].type;
                break;
        default:
                break;
@@ -147,17 +150,45 @@ static void set_dcd_val_v1(struct imx_header *imxhdr, 
char *name, int lineno,
        }
 }
 
+static write_dcd_command_t *p_dcd;
+
 static void set_dcd_val_v2(struct imx_header *imxhdr, char *name, int lineno,
-                                       int fld, uint32_t value, uint32_t off)
+                                       int fld, uint32_t value)
 {
+       uint32_t len;
        dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
 
        switch (fld) {
+       case CFG_REG_SIZE:
+               /* Byte, halfword, word */
+               if ((value != 1) && (value != 2) && (value != 4)) {
+                       fprintf(stderr, "Error: %s[%d] - "
+                               "Invalid register size " "(%d)\n",
+                               name, lineno, value);
+                       exit(EXIT_FAILURE);
+               }
+               if (p_dcd && (p_dcd->param == value))
+                       break;
+               if (!p_dcd) {
+                       dcd_v2->header.tag = DCD_HEADER_TAG;
+                       dcd_v2->header.version = DCD_VERSION;
+                       p_dcd = &dcd_v2->write_dcd_command;
+               } else {
+                       p_dcd = (write_dcd_command_t *)p_entry;
+               }
+               p_dcd->param = value;
+               p_dcd->tag = DCD_COMMAND_TAG;
+               p_entry = (uint32_t *)(p_dcd + 1);
+               break;
        case CFG_REG_ADDRESS:
-               dcd_v2->addr_data[off].addr = cpu_to_be32(value);
+               *p_entry++ = cpu_to_be32(value);
                break;
        case CFG_REG_VALUE:
-               dcd_v2->addr_data[off].value = cpu_to_be32(value);
+               *p_entry++ = cpu_to_be32(value);
+               len = (char *)p_entry - (char *)&dcd_v2->header;
+               dcd_v2->header.length = cpu_to_be16(len);
+               len = (char *)p_entry - (char *)p_dcd;
+               p_dcd->length = cpu_to_be16(len);
                break;
        default:
                break;
@@ -165,47 +196,13 @@ static void set_dcd_val_v2(struct imx_header *imxhdr, 
char *name, int lineno,
        }
 }
 
-/*
- * Complete setting up the rest field of DCD of V1
- * such as barker code and DCD data length.
- */
-static void set_dcd_rst_v1(struct imx_header *imxhdr, uint32_t dcd_len,
-                                               char *name, int lineno)
-{
-       dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
-
-       dcd_v1->preamble.barker = DCD_BARKER;
-       dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t);
-}
-
-/*
- * Complete setting up the reset field of DCD of V2
- * such as DCD tag, version, length, etc.
- */
-static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
-                                               char *name, int lineno)
-{
-       dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
-
-       dcd_v2->header.tag = DCD_HEADER_TAG;
-       dcd_v2->header.length = cpu_to_be16(
-                       dcd_len * sizeof(dcd_addr_data_t) + 8);
-       dcd_v2->header.version = DCD_VERSION;
-       dcd_v2->write_dcd_command.tag = DCD_COMMAND_TAG;
-       dcd_v2->write_dcd_command.length = cpu_to_be16(
-                       dcd_len * sizeof(dcd_addr_data_t) + 4);
-       dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;
-}
-
-static int set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
+static int set_imx_hdr_v1(struct imx_header *imxhdr,
                uint32_t entry_point, uint32_t flash_offset)
 {
        imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;
        flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
-       dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table;
        uint32_t hdr_base;
-       uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr)
-                       - ((char *)imxhdr));
+       uint32_t header_length = ((char *)p_entry) + 4 - ((char *)imxhdr);
 
        /* Set magic number */
        fhdr_v1->app_code_barker = APP_CODE_BARKER;
@@ -234,15 +231,13 @@ static void set_imx_size_v1(struct imx_header *imxhdr, 
uint32_t file_size,
        p[-1] = file_size + flash_offset;
 }
 
-static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+static int set_imx_hdr_v2(struct imx_header *imxhdr,
                uint32_t entry_point, uint32_t flash_offset)
 {
        imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
        flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
        uint32_t hdr_base;
-       uint32_t header_length = (dcd_len) ?
-               (char *)&hdr_v2->dcd_table.addr_data[dcd_len] - ((char*)imxhdr)
-               : offsetof(imx_header_v2_t, dcd_table);
+       uint32_t header_length = ((char *)p_entry) - ((char *)imxhdr);
 
        /* Set magic number */
        fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
@@ -253,7 +248,7 @@ static int set_imx_hdr_v2(struct imx_header *imxhdr, 
uint32_t dcd_len,
        fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
        fhdr_v2->self = hdr_base = entry_point - header_length;
 
-       fhdr_v2->dcd_ptr = (dcd_len) ? hdr_base
+       fhdr_v2->dcd_ptr = (p_dcd) ? hdr_base
                        + offsetof(imx_header_v2_t, dcd_table) : 0;
        fhdr_v2->boot_data_ptr = hdr_base
                        + offsetof(imx_header_v2_t, boot_data);
@@ -277,17 +272,19 @@ static void set_hdr_func(struct imx_header *imxhdr)
        switch (imximage_version) {
        case IMXIMAGE_V1:
                set_dcd_val = set_dcd_val_v1;
-               set_dcd_rst = set_dcd_rst_v1;
                set_imx_hdr = set_imx_hdr_v1;
                set_imx_size = set_imx_size_v1;
-               max_dcd_entries = MAX_HW_CFG_SIZE_V1;
+               p_entry = &imxhdr->header.hdr_v1.dcd_table.addr_data[0].type;
+               p_max_dcd = &imxhdr->header.hdr_v1.dcd_table
+                               .addr_data[MAX_HW_CFG_SIZE_V1].type;
+               imxhdr->header.hdr_v1.dcd_table.preamble.barker = DCD_BARKER;
                break;
        case IMXIMAGE_V2:
                set_dcd_val = set_dcd_val_v2;
-               set_dcd_rst = set_dcd_rst_v2;
                set_imx_hdr = set_imx_hdr_v2;
                set_imx_size = set_imx_size_v2;
-               max_dcd_entries = MAX_HW_CFG_SIZE_V2;
+               p_entry = (uint32_t *)&imxhdr->header.hdr_v2.dcd_table;
+               p_max_dcd = (uint32_t *)((char *)imxhdr + MAX_HEADER_SIZE);
                break;
        default:
                err_imximage_version(imximage_version);
@@ -351,7 +348,7 @@ static void print_hdr_v2(struct imx_header *imx_hdr)
 }
 
 static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
-                               char *name, int lineno, int fld, int dcd_len)
+                               char *name, int lineno, int fld)
 {
        int value;
        static int cmd_ver_first = ~0;
@@ -381,7 +378,7 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, 
int32_t cmd, char *token,
                break;
        case CMD_DATA:
                value = get_cfg_value(token, name, lineno);
-               (*set_dcd_val)(imxhdr, name, lineno, fld, value, dcd_len);
+               (*set_dcd_val)(imxhdr, name, lineno, fld, value);
                if (unlikely(cmd_ver_first != 1))
                        cmd_ver_first = 0;
                break;
@@ -389,7 +386,7 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, 
int32_t cmd, char *token,
 }
 
 static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
-               char *token, char *name, int lineno, int fld, int *dcd_len)
+               char *token, char *name, int lineno, int fld)
 {
        int value;
 
@@ -404,7 +401,7 @@ static void parse_cfg_fld(struct imx_header *imxhdr, 
int32_t *cmd,
                }
                break;
        case CFG_REG_SIZE:
-               parse_cfg_cmd(imxhdr, *cmd, token, name, lineno, fld, *dcd_len);
+               parse_cfg_cmd(imxhdr, *cmd, token, name, lineno, fld);
                break;
        case CFG_REG_ADDRESS:
        case CFG_REG_VALUE:
@@ -412,23 +409,20 @@ static void parse_cfg_fld(struct imx_header *imxhdr, 
int32_t *cmd,
                        return;
 
                value = get_cfg_value(token, name, lineno);
-               (*set_dcd_val)(imxhdr, name, lineno, fld, value, *dcd_len);
-
-               if (fld == CFG_REG_VALUE) {
-                       (*dcd_len)++;
-                       if (*dcd_len > max_dcd_entries) {
-                               fprintf(stderr, "Error: %s[%d] -"
-                                       "DCD table exceeds maximum size(%d)\n",
-                                       name, lineno, max_dcd_entries);
-                               exit(EXIT_FAILURE);
-                       }
+               (*set_dcd_val)(imxhdr, name, lineno, fld, value);
+               if (p_entry > p_max_dcd) {
+                       uint32_t size = (char *)p_max_dcd - (char *)imxhdr;
+                       fprintf(stderr, "Error: %s[%d] -"
+                                       "header exceeds maximum size(%d)\n",
+                                       name, lineno, size);
+                       exit(EXIT_FAILURE);
                }
                break;
        default:
                break;
        }
 }
-static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
+static void parse_cfg_file(struct imx_header *imxhdr, char *name)
 {
        FILE *fd = NULL;
        char *line = NULL;
@@ -436,7 +430,6 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, 
char *name)
        int lineno = 0;
        int fld;
        size_t len;
-       int dcd_len = 0;
        int32_t cmd;
 
        fd = fopen(name, "r");
@@ -467,15 +460,12 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, 
char *name)
                                break;
 
                        parse_cfg_fld(imxhdr, &cmd, token, name,
-                                       lineno, fld, &dcd_len);
+                                       lineno, fld);
                }
 
        }
-
-       (*set_dcd_rst)(imxhdr, dcd_len, name, lineno);
        fclose(fd);
-
-       return dcd_len;
+       return;
 }
 
 
@@ -520,9 +510,12 @@ int imximage_vrec_header(struct mkimage_params *params,
                struct image_type_params *tparams)
 {
        struct imx_header *imxhdr;
-       uint32_t dcd_len;
 
-       imxhdr = calloc(1, MAX_HEADER_SIZE);
+       /*
+        * A little extra space to avoid access violation on dcd table overflow.
+        * Overflow is checked after entry is added.
+        */
+       imxhdr = calloc(1, MAX_HEADER_SIZE + 32);
        if (!imxhdr) {
                fprintf(stderr, "Error: out of memory\n");
                exit(EXIT_FAILURE);
@@ -538,7 +531,7 @@ int imximage_vrec_header(struct mkimage_params *params,
        set_hdr_func(imxhdr);
 
        /* Parse dcd configuration file */
-       dcd_len = parse_cfg_file(imxhdr, params->imagename);
+       parse_cfg_file(imxhdr, params->imagename);
 
        /* Exit if there is no BOOT_FROM field specifying the flash_offset */
        if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {
@@ -547,8 +540,8 @@ int imximage_vrec_header(struct mkimage_params *params,
                exit(EXIT_FAILURE);
        }
        /* Set the imx header */
-       imximage_params.header_size = (*set_imx_hdr)(imxhdr, dcd_len,
-                       params->ep, g_flash_offset);
+       imximage_params.header_size = (*set_imx_hdr)(imxhdr, params->ep,
+                       g_flash_offset);
        imximage_params.hdr = imxhdr;
        return 0;
 }
diff --git a/tools/imximage.h b/tools/imximage.h
index 5fe3a8a..0319c02 100644
--- a/tools/imximage.h
+++ b/tools/imximage.h
@@ -47,7 +47,6 @@
 #define DCD_HEADER_TAG 0xD2
 #define DCD_COMMAND_TAG 0xCC
 #define DCD_VERSION 0x40
-#define DCD_COMMAND_PARAM 0x4
 
 enum imximage_cmd {
        CMD_INVALID,
@@ -159,17 +158,11 @@ struct imx_header {
        } header;
 };
 
-typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
-                                       char *name, int lineno,
-                                       int fld, uint32_t value,
-                                       uint32_t off);
+typedef void (*set_dcd_val_t)(struct imx_header *imxhdr, char *name,
+               int lineno, int fld, uint32_t value);
 
-typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr,
-                                       uint32_t dcd_len,
-                                       char *name, int lineno);
-
-typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
-               uint32_t entry_point, uint32_t flash_offset);
+typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t entry_point,
+               uint32_t flash_offset);
 typedef void (*set_imx_size_t)(struct imx_header *imxhdr, uint32_t file_size,
                uint32_t flash_offset);
 
-- 
1.7.9.5

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to