>-----Original Message-----
>From: Troy Kisky [mailto:troy.ki...@boundarydevices.com]
>Sent: Wednesday, November 28, 2012 9:32 AM
>To: sba...@denx.de
>Cc: dirk.be...@googlemail.com; u-boot@lists.denx.de; Liu Hui-R64343;
>feste...@gmail.com; Troy Kisky
>Subject: [PATCH V4 08/11] imximage: enable word writes for version2 header
>
>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>

Acked-by: Jason Liu <r64...@freescale.com>

>
>---
>v3: moved static variables together
>---
> tools/imximage.c |  143 ++++++++++++++++++++++++++----------------------------
> tools/imximage.h |   18 +++----
> 2 files changed, 76 insertions(+), 85 deletions(-)
>
>diff --git a/tools/imximage.c b/tools/imximage.c index 6d5cfa7..2f5ee14
>100644
>--- a/tools/imximage.c
>+++ b/tools/imximage.c
>@@ -65,8 +65,6 @@ static table_entry_t imximage_versions[] = {
>       {-1,            "",     " (Invalid)",                 },
> };
>
>-static set_dcd_rst_t set_dcd_rst;
>-static uint32_t max_dcd_entries;
> static uint32_t *header_size_ptr;
> static uint32_t g_flash_offset;
>
>@@ -115,7 +113,7 @@ static void err_imximage_version(int version)  }
>
> static void set_dcd_val_v1(struct data_src *ds, char *name, int lineno,
>-                                      int fld, uint32_t value, uint32_t off)
>+                                      int fld, uint32_t value)
> {
>       dcd_v1_t *dcd_v1 = &ds->imxhdr->header.hdr_v1.dcd_table;
>
>@@ -128,13 +126,15 @@ static void set_dcd_val_v1(struct data_src *ds, char
>*name, int lineno,
>                               name, lineno, value);
>                       exit(EXIT_FAILURE);
>               }
>-              dcd_v1->addr_data[off].type = value;
>+              *ds->p_entry++ = value;
>               break;
>       case CFG_REG_ADDRESS:
>-              dcd_v1->addr_data[off].addr = value;
>+              *ds->p_entry++ = value;
>               break;
>       case CFG_REG_VALUE:
>-              dcd_v1->addr_data[off].value = value;
>+              *ds->p_entry++ = value;
>+              dcd_v1->preamble.length = (char *)ds->p_entry
>+                              - (char *)&dcd_v1->addr_data[0].type;
>               break;
>       default:
>               break;
>@@ -143,16 +143,42 @@ static void set_dcd_val_v1(struct data_src *ds, char
>*name, int lineno,  }
>
> static void set_dcd_val_v2(struct data_src *ds, 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 = &ds->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 (ds->p_dcd && (ds->p_dcd->param == value))
>+                      break;
>+              if (!ds->p_dcd) {
>+                      dcd_v2->header.tag = DCD_HEADER_TAG;
>+                      dcd_v2->header.version = DCD_VERSION;
>+                      ds->p_dcd = &dcd_v2->write_dcd_command;
>+              } else {
>+                      ds->p_dcd = (write_dcd_command_t *)ds->p_entry;
>+              }
>+              ds->p_dcd->param = value;
>+              ds->p_dcd->tag = DCD_COMMAND_TAG;
>+              ds->p_entry = (uint32_t *)(ds->p_dcd + 1);
>+              break;
>       case CFG_REG_ADDRESS:
>-              dcd_v2->addr_data[off].addr = cpu_to_be32(value);
>+              *ds->p_entry++ = cpu_to_be32(value);
>               break;
>       case CFG_REG_VALUE:
>-              dcd_v2->addr_data[off].value = cpu_to_be32(value);
>+              *ds->p_entry++ = cpu_to_be32(value);
>+              len = (char *)ds->p_entry - (char *)&dcd_v2->header;
>+              dcd_v2->header.length = cpu_to_be16(len);
>+              len = (char *)ds->p_entry - (char *)ds->p_dcd;
>+              ds->p_dcd->length = cpu_to_be16(len);
>               break;
>       default:
>               break;
>@@ -160,47 +186,14 @@ static void set_dcd_val_v2(struct data_src *ds, 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 data_src *ds, uint32_t dcd_len,
>+static int set_imx_hdr_v1(struct data_src *ds,
>               uint32_t entry_point, uint32_t flash_offset)  {
>       imx_header_v1_t *hdr_v1 = &ds->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 *)ds->imxhdr));
>+      uint32_t header_length = ((char *)ds->p_entry) + 4
>+                      - ((char *)ds->imxhdr);
>
>       /* Set magic number */
>       fhdr_v1->app_code_barker = APP_CODE_BARKER; @@ -220,15
>+213,13 @@ static int set_imx_hdr_v1(struct data_src *ds, uint32_t dcd_len,
>       return header_length;
> }
>
>-static int set_imx_hdr_v2(struct data_src *ds, uint32_t dcd_len,
>+static int set_imx_hdr_v2(struct data_src *ds,
>               uint32_t entry_point, uint32_t flash_offset)  {
>       imx_header_v2_t *hdr_v2 = &ds->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 *)ds->imxhdr) : offsetof(imx_header_v2_t, dcd_table);
>+      uint32_t header_length = ((char *)ds->p_entry) - ((char *)ds->imxhdr);
>
>       /* Set magic number */
>       fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */ @@ -239,7
>+230,7 @@ static int set_imx_hdr_v2(struct data_src *ds, 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 = (ds->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); @@ -256,15
>+247,20 @@ static void set_hdr_func(struct data_src *ds, uint32_t
>imximage_version)
>       switch (imximage_version) {
>       case IMXIMAGE_V1:
>               ds->set_dcd_val = set_dcd_val_v1;
>-              set_dcd_rst = set_dcd_rst_v1;
>               ds->set_imx_hdr = set_imx_hdr_v1;
>-              max_dcd_entries = MAX_HW_CFG_SIZE_V1;
>+              ds->p_entry = &ds->imxhdr->header.hdr_v1.dcd_table
>+                              .addr_data[0].type;
>+              ds->p_max_dcd = &ds->imxhdr->header.hdr_v1.dcd_table
>+                              .addr_data[MAX_HW_CFG_SIZE_V1].type;
>+              ds->imxhdr->header.hdr_v1.dcd_table.preamble.barker =
>+                              DCD_BARKER;
>               break;
>       case IMXIMAGE_V2:
>               ds->set_dcd_val = set_dcd_val_v2;
>-              set_dcd_rst = set_dcd_rst_v2;
>               ds->set_imx_hdr = set_imx_hdr_v2;
>-              max_dcd_entries = MAX_HW_CFG_SIZE_V2;
>+              ds->p_entry = (uint32_t *)&ds->imxhdr-
>>header.hdr_v2.dcd_table;
>+              ds->p_max_dcd = (uint32_t *)
>+                              ((char *)ds->imxhdr + MAX_HEADER_SIZE);
>               break;
>       default:
>               err_imximage_version(imximage_version);
>@@ -328,7 +324,7 @@ static void print_hdr_v2(struct imx_header
>*imx_hdr)  }
>
> static void parse_cfg_cmd(struct data_src *ds, 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;
>@@ -359,7 +355,7 @@ static void parse_cfg_cmd(struct data_src *ds, int32_t
>cmd, char *token,
>               break;
>       case CMD_DATA:
>               value = get_cfg_value(token, name, lineno);
>-              (*ds->set_dcd_val)(ds, name, lineno, fld, value, dcd_len);
>+              (*ds->set_dcd_val)(ds, name, lineno, fld, value);
>               if (unlikely(cmd_ver_first != 1))
>                       cmd_ver_first = 0;
>               break;
>@@ -367,7 +363,7 @@ static void parse_cfg_cmd(struct data_src *ds, int32_t
>cmd, char *token,  }
>
> static void parse_cfg_fld(struct data_src *ds, int32_t *cmd,
>-              char *token, char *name, int lineno, int fld, int *dcd_len)
>+              char *token, char *name, int lineno, int fld)
> {
>       int value;
>
>@@ -382,7 +378,7 @@ static void parse_cfg_fld(struct data_src *ds, int32_t
>*cmd,
>               }
>               break;
>       case CFG_REG_SIZE:
>-              parse_cfg_cmd(ds, *cmd, token, name, lineno, fld, *dcd_len);
>+              parse_cfg_cmd(ds, *cmd, token, name, lineno, fld);
>               break;
>       case CFG_REG_ADDRESS:
>       case CFG_REG_VALUE:
>@@ -390,16 +386,14 @@ static void parse_cfg_fld(struct data_src *ds,
>int32_t *cmd,
>                       return;
>
>               value = get_cfg_value(token, name, lineno);
>-              (*ds->set_dcd_val)(ds, 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);
>-                      }
>+              (*ds->set_dcd_val)(ds, name, lineno, fld, value);
>+              if (ds->p_entry > ds->p_max_dcd) {
>+                      uint32_t size = (char *)ds->p_max_dcd -
>+                                      (char *)ds->imxhdr;
>+                      fprintf(stderr, "Error: %s[%d] -"
>+                                      "header exceeds maximum size(%d)\n",
>+                                      name, lineno, size);
>+                      exit(EXIT_FAILURE);
>               }
>               break;
>       default:
>@@ -417,7 +411,6 @@ static int parse_cfg_file(struct imx_header *imxhdr,
>char *name,
>       int lineno = 0;
>       int fld;
>       size_t len;
>-      int dcd_len = 0;
>       int32_t cmd;
>
>       /* Be able to detect if the cfg file has no BOOT_FROM tag */ @@ -
>458,12 +451,10 @@ static int parse_cfg_file(struct imx_header *imxhdr, char
>*name,
>                               break;
>
>                       parse_cfg_fld(&ds, &cmd, token, name,
>-                                      lineno, fld, &dcd_len);
>+                                      lineno, fld);
>               }
>
>       }
>-
>-      (*set_dcd_rst)(imxhdr, dcd_len, name, lineno);
>       fclose(fd);
>
>       /* Exit if there is no BOOT_FROM field specifying the flash_offset */
>@@ -472,7 +463,7 @@ static int parse_cfg_file(struct imx_header *imxhdr,
>char *name,
>               exit(EXIT_FAILURE);
>       }
>       /* Set the imx header */
>-      return (*ds.set_imx_hdr)(&ds, dcd_len, entry_point, g_flash_offset);
>+      return (*ds.set_imx_hdr)(&ds, entry_point, g_flash_offset);
> }
>
> static int imximage_check_image_types(uint8_t type) @@ -517,7 +508,11
>@@ int imximage_vrec_header(struct mkimage_params *params,  {
>       struct imx_header *imxhdr;
>
>-      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);
>diff --git a/tools/imximage.h b/tools/imximage.h index 444ddce..196bb51
>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,
>@@ -160,21 +159,18 @@ struct imx_header {  };
>
> struct data_src;
>-typedef void (*set_dcd_val_t)(struct data_src *ds,
>-                                      char *name, int lineno,
>-                                      int fld, uint32_t value,
>-                                      uint32_t off);
>+typedef void (*set_dcd_val_t)(struct data_src *ds, 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 data_src *ds, uint32_t dcd_len,
>-              uint32_t entry_point, uint32_t flash_offset);
>+typedef int (*set_imx_hdr_t)(struct data_src *ds, uint32_t entry_point,
>+              uint32_t flash_offset);
>
> struct data_src {
>       struct imx_header *imxhdr;
>       set_imx_hdr_t set_imx_hdr;
>       set_dcd_val_t set_dcd_val;
>+      uint32_t *p_max_dcd;
>+      uint32_t *p_entry;
>+      write_dcd_command_t *p_dcd;
> };
> #endif /* _IMXIMAGE_H_ */
>--
>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