>-----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