[U-Boot] [PATCH V4 08/11] imximage: enable word writes for version2 header

Liu Hui-R64343 r64343 at freescale.com
Wed Nov 28 11:47:57 CET 2012


>-----Original Message-----
>From: Troy Kisky [mailto:troy.kisky at boundarydevices.com]
>Sent: Wednesday, November 28, 2012 9:32 AM
>To: sbabic at denx.de
>Cc: dirk.behme at googlemail.com; u-boot at lists.denx.de; Liu Hui-R64343;
>festevam at 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.kisky at boundarydevices.com>

Acked-by: Jason Liu <r64343 at 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
>




More information about the U-Boot mailing list