Skip to contentSkip to conversation

(no subject)

U-Boot Superseded Troy Kisky 11 participants 202 messages Sep 19, 2012 – Dec 4, 2012 Page 1 of 2

Subsystems (5)
lore
Share & tools
lore

Troy Kisky

author
#0 lore raw

This is the 1st part of a series meant to add mx6solo/mx6duallite support for a saberlite. I stopped at the last patch because with it applied, Linux will no longer boot. However, the same plugin code used under imx-android-r13.3 will work fine.

So, the last patch in the series is not ready to be applied. I also, tried initializing in the normal manner and running the plugin with nothing to do. That also fails to boot Linux.

Any advice????
Thanks
Troy

author
#1 lore raw

PATCH v4 1/11 imximage: make header variable length

Also, the header offset is no longer
right before the code starts.

---
 tools/imximage.c |  142 +++++++++++++++++++++++++++++++-----------------------
 tools/imximage.h |   10 ++--
 2 files changed, 87 insertions(+), 65 deletions(-)
tools/imximage.c +82 -60
index 03a7716..25d3b74 100644
@@ -65,12 +65,15 @@ static table_entry_t imximage_versions[] = {
 	{-1,            "",     " (Invalid)",                 },
 };
 
-static struct imx_header imximage_header;
 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 g_flash_offset;
+
+static struct image_type_params imximage_params;
 
 static uint32_t get_cfg_value(char *token, char *name,  int linenr)
 {
@@ -207,85 +210,79 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;
 }
 
-static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params)
+static int set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
+		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 base_offset;
-
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v1: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}
+	uint32_t hdr_base;
+	uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr)
+			- ((char *)imxhdr));
 
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-	fhdr_v1->app_dest_ptr = params->addr;
-	fhdr_v1->app_dest_ptr = params->ep - imxhdr->flash_offset -
-		sizeof(struct imx_header);
-	fhdr_v1->app_code_jump_vector = params->ep;
+	hdr_base = entry_point - header_length;
+	fhdr_v1->app_dest_ptr = hdr_base - flash_offset;
+	fhdr_v1->app_code_jump_vector = entry_point;
 
-	base_offset = fhdr_v1->app_dest_ptr + imxhdr->flash_offset ;
-	fhdr_v1->dcd_ptr_ptr =
-		(uint32_t) (offsetof(flash_header_v1_t, dcd_ptr) -
-		offsetof(flash_header_v1_t, app_code_jump_vector) +
-		base_offset);
-
-	fhdr_v1->dcd_ptr = base_offset +
-			offsetof(imx_header_v1_t, dcd_table);
-
-	/* The external flash header must be at the end of the DCD table */
-	dcd_v1->addr_data[dcd_len].type = sbuf->st_size +
-				imxhdr->flash_offset +
-				sizeof(struct imx_header);
+	fhdr_v1->dcd_ptr_ptr = hdr_base + offsetof(flash_header_v1_t, dcd_ptr);
+	fhdr_v1->dcd_ptr = hdr_base + offsetof(imx_header_v1_t, dcd_table);
 
 	/* Security feature are not supported */
 	fhdr_v1->app_code_csf = 0;
 	fhdr_v1->super_root_key = 0;
+	return header_length;
+}
+
+static void set_imx_size_v1(struct imx_header *imxhdr, uint32_t file_size,
+		uint32_t flash_offset)
+{
+	uint32_t *p = (uint32_t *)(((char *)imxhdr)
+			+ imximage_params.header_size);
+
+	/* The external flash header must be at the end of the DCD table */
+	/* file_size includes header */
+	p[-1] = file_size + flash_offset;
 }
 
-static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params)
+static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+		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;
-
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v2: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}
+	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);
 
 	/* Set magic number */
 	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
 	fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t));
 	fhdr_v2->header.version = IVT_VERSION; /* 0x40 */
 
-	fhdr_v2->entry = params->ep;
+	fhdr_v2->entry = entry_point;
 	fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
-	fhdr_v2->self = params->ep - sizeof(struct imx_header);
-
-	fhdr_v2->dcd_ptr = fhdr_v2->self +
-			offsetof(imx_header_v2_t, dcd_table);
+	fhdr_v2->self = hdr_base = entry_point - header_length;
 
-	fhdr_v2->boot_data_ptr = fhdr_v2->self +
-			offsetof(imx_header_v2_t, boot_data);
-
-	hdr_v2->boot_data.start = fhdr_v2->self - imxhdr->flash_offset;
-	hdr_v2->boot_data.size = sbuf->st_size +
-			imxhdr->flash_offset +
-			sizeof(struct imx_header);
+	fhdr_v2->dcd_ptr = (dcd_len) ? hdr_base
+			+ offsetof(imx_header_v2_t, dcd_table) : 0;
+	fhdr_v2->boot_data_ptr = hdr_base
+			+ offsetof(imx_header_v2_t, boot_data);
+	hdr_v2->boot_data.start = hdr_base - flash_offset;
 
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
+	return header_length;
+}
+
+static void set_imx_size_v2(struct imx_header *imxhdr, uint32_t file_size,
+		uint32_t flash_offset)
+{
+	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
+	/* file_size includes header */
+	hdr_v2->boot_data.size = file_size + flash_offset;
 }
 
 static void set_hdr_func(struct imx_header *imxhdr)
@@ -295,11 +292,13 @@ static void set_hdr_func(struct imx_header *imxhdr)
 		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;
 		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;
 		break;
 	default:
 		err_imximage_version(imximage_version);
@@ -381,9 +380,9 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
 		set_hdr_func(imxhdr);
 		break;
 	case CMD_BOOT_FROM:
-		imxhdr->flash_offset = get_table_entry_id(imximage_bootops,
+		g_flash_offset = get_table_entry_id(imximage_bootops,
 					"imximage boot option", token);
-		if (imxhdr->flash_offset == -1) {
+		if (g_flash_offset == -1) {
 			fprintf(stderr, "Error: %s[%d] -Invalid boot device"
 				"(%s)\n", name, lineno, token);
 			exit(EXIT_FAILURE);
@@ -521,12 +520,17 @@ static void imximage_print_header(const void *ptr)
 	}
 }
 
-static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
-				struct mkimage_params *params)
+int imximage_vrec_header(struct mkimage_params *params,
+		struct image_type_params *tparams)
 {
-	struct imx_header *imxhdr = (struct imx_header *)ptr;
+	struct imx_header *imxhdr;
 	uint32_t dcd_len;
 
+	imxhdr = calloc(1, MAX_HEADER_SIZE);
+	if (!imxhdr) {
+		fprintf(stderr, "Error: out of memory\n");
+		exit(EXIT_FAILURE);
+	}
 	/*
 	 * In order to not change the old imx cfg file
 	 * by adding VERSION command into it, here need
@@ -534,14 +538,31 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 	 */
 	imximage_version = IMXIMAGE_V1;
 	/* Be able to detect if the cfg file has no BOOT_FROM tag */
-	imxhdr->flash_offset = FLASH_OFFSET_UNDEFINED;
+	g_flash_offset = FLASH_OFFSET_UNDEFINED;
 	set_hdr_func(imxhdr);
 
 	/* Parse dcd configuration file */
 	dcd_len = 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) {
+		fprintf(stderr, "Error: No BOOT_FROM tag in %s\n",
+				params->imagename);
+		exit(EXIT_FAILURE);
+	}
 	/* Set the imx header */
-	(*set_imx_hdr)(imxhdr, dcd_len, sbuf, params);
+	imximage_params.header_size = (*set_imx_hdr)(imxhdr, dcd_len,
+			params->ep, g_flash_offset);
+	imximage_params.hdr = imxhdr;
+	return 0;
+}
+
+static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
+				struct mkimage_params *params)
+{
+	/* Set the size in header */
+	(*set_imx_size)((struct imx_header *)ptr, sbuf->st_size,
+			g_flash_offset);
 }
 
 int imximage_check_params(struct mkimage_params *params)
@@ -571,8 +592,9 @@ int imximage_check_params(struct mkimage_params *params)
  */
 static struct image_type_params imximage_params = {
 	.name		= "Freescale i.MX 5x Boot Image support",
-	.header_size	= sizeof(struct imx_header),
-	.hdr		= (void *)&imximage_header,
+	.header_size	= 0,
+	.hdr		= NULL,
+	.vrec_header	= imximage_vrec_header,
 	.check_image_type = imximage_check_image_types,
 	.verify_header	= imximage_verify_header,
 	.print_header	= imximage_print_header,
tools/imximage.h +5 -5
index 34f293d..5fe3a8a 100644
@@ -30,6 +30,7 @@
 #define DCD_BARKER	0xB17219E9
 
 #define HEADER_OFFSET	0x400
+#define MAX_HEADER_SIZE	(16 << 10)
 
 #define CMD_DATA_STR	"DATA"
 #define FLASH_OFFSET_UNDEFINED	0xFFFFFFFF
@@ -156,7 +157,6 @@ struct imx_header {
 		imx_header_v1_t hdr_v1;
 		imx_header_v2_t hdr_v2;
 	} header;
-	uint32_t flash_offset;
 };
 
 typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
@@ -168,9 +168,9 @@ typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr,
 					uint32_t dcd_len,
 					char *name, int lineno);
 
-typedef void (*set_imx_hdr_t)(struct imx_header *imxhdr,
-					uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params);
+typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
+		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);
 
 #endif /* _IMXIMAGE_H_ */
Signature · 1 line
1.7.9.5
author
#2 lore raw

PATCH v4 2/11 imximage: check dcd_len as entries added

In reply to Troy Kisky

Before the len was checked after the entire file was processed, so it could have already overflowed.

---
 tools/imximage.c |   26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)
tools/imximage.c +11 -15
index 25d3b74..0bfbec3 100644
@@ -71,6 +71,7 @@ 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 g_flash_offset;
 
 static struct image_type_params imximage_params;
@@ -173,13 +174,6 @@ static void set_dcd_rst_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 {
 	dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
 
-	if (dcd_len > MAX_HW_CFG_SIZE_V1) {
-		fprintf(stderr, "Error: %s[%d] -"
-			"DCD table exceeds maximum size(%d)\n",
-			name, lineno, MAX_HW_CFG_SIZE_V1);
-		exit(EXIT_FAILURE);
-	}
-
 	dcd_v1->preamble.barker = DCD_BARKER;
 	dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t);
 }
@@ -193,13 +187,6 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 {
 	dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
 
-	if (dcd_len > MAX_HW_CFG_SIZE_V2) {
-		fprintf(stderr, "Error: %s[%d] -"
-			"DCD table exceeds maximum size(%d)\n",
-			name, lineno, MAX_HW_CFG_SIZE_V2);
-		exit(EXIT_FAILURE);
-	}
-
 	dcd_v2->header.tag = DCD_HEADER_TAG;
 	dcd_v2->header.length = cpu_to_be16(
 			dcd_len * sizeof(dcd_addr_data_t) + 8);
@@ -293,12 +280,14 @@ static void set_hdr_func(struct imx_header *imxhdr)
 		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;
 		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;
 		break;
 	default:
 		err_imximage_version(imximage_version);
@@ -425,8 +414,15 @@ static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
 		value = get_cfg_value(token, name, lineno);
 		(*set_dcd_val)(imxhdr, name, lineno, fld, value, *dcd_len);
 
-		if (fld == CFG_REG_VALUE)
+		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);
+			}
+		}
 		break;
 	default:
 		break;
Signature · 1 line
1.7.9.5
author
#3 lore raw

PATCH v4 3/11 imximage: enable word writes for version2 header

In reply to Troy Kisky

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

---
 tools/imximage.c |  153 ++++++++++++++++++++++++++----------------------------
 tools/imximage.h |   15 ++----
 2 files changed, 77 insertions(+), 91 deletions(-)
tools/imximage.c +73 -80
index 0bfbec3..21c49e6 100644
@@ -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;
 }
tools/imximage.h +4 -11
index 5fe3a8a..0319c02 100644
@@ -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);
 
Signature · 1 line
1.7.9.5
author
#4 lore raw

PATCH v4 4/11 imximage: cleanup parsing

In reply to Troy Kisky

Move to pulling tokens instead of pushing them. Remove need for switch statements to process commands. Add error messages such as "command not finished", "extra data at end of line", and "invalid token" Add ';' as command separator.

---
 tools/imximage.c |  380 ++++++++++++++++++++++++++++++------------------------
 tools/imximage.h |   25 ++--
 2 files changed, 226 insertions(+), 179 deletions(-)
tools/imximage.c +212 -168
index 21c49e6..1e120354 100644
@@ -75,21 +75,6 @@ static uint32_t g_flash_offset;
 
 static struct image_type_params imximage_params;
 
-static uint32_t get_cfg_value(char *token, char *name,  int linenr)
-{
-	char *endptr;
-	uint32_t value;
-
-	errno = 0;
-	value = strtoul(token, &endptr, 16);
-	if (errno || (token == endptr)) {
-		fprintf(stderr, "Error: %s[%d] - Invalid hex data(%s)\n",
-			name,  linenr, token);
-		exit(EXIT_FAILURE);
-	}
-	return value;
-}
-
 static uint32_t detect_imximage_version(struct imx_header *imx_hdr)
 {
 	imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1;
@@ -120,55 +105,38 @@ static void err_imximage_version(int version)
 
 static uint32_t *p_entry;
 
-static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno,
-					int fld, uint32_t value)
+static int set_dcd_val_v1(struct imx_header *imxhdr, uint32_t *data)
 {
 	dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
+	uint32_t val = *data++;
 
-	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);
-		}
-		*p_entry++ = value;
-		break;
-	case CFG_REG_ADDRESS:
-		*p_entry++ = value;
-		break;
-	case CFG_REG_VALUE:
-		*p_entry++ = value;
-		dcd_v1->preamble.length = (char *)p_entry
-				- (char *)&dcd_v1->addr_data[0].type;
-		break;
-	default:
-		break;
-
+	/* Byte, halfword, word */
+	if ((val != 1) && (val != 2) && (val != 4)) {
+		fprintf(stderr, "Error: Invalid register size (%d)\n", val);
+		return -1;
 	}
+	*p_entry++ = val;
+	*p_entry++ = *data++;
+	*p_entry++ = *data++;
+	dcd_v1->preamble.length = (char *)p_entry - (char *)&dcd_v1->
+			addr_data[0].type;
+	return 0;
 }
 
 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)
+static int set_dcd_val_v2(struct imx_header *imxhdr, uint32_t *data)
 {
 	uint32_t len;
 	dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
+	uint32_t val = *data++;
 
-	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;
+	/* Byte, halfword, word */
+	if ((val != 1) && (val != 2) && (val != 4)) {
+		fprintf(stderr, "Error: Invalid register size (%d)\n", val);
+		return -1;
+	}
+	if (!(p_dcd && (p_dcd->param == val))) {
 		if (!p_dcd) {
 			dcd_v2->header.tag = DCD_HEADER_TAG;
 			dcd_v2->header.version = DCD_VERSION;
@@ -176,24 +144,19 @@ static void set_dcd_val_v2(struct imx_header *imxhdr, char *name, int lineno,
 		} else {
 			p_dcd = (write_dcd_command_t *)p_entry;
 		}
-		p_dcd->param = value;
+		p_dcd->param = val;
 		p_dcd->tag = DCD_COMMAND_TAG;
 		p_entry = (uint32_t *)(p_dcd + 1);
-		break;
-	case CFG_REG_ADDRESS:
-		*p_entry++ = cpu_to_be32(value);
-		break;
-	case CFG_REG_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;
-
 	}
+	val = *data++;
+	*p_entry++ = cpu_to_be32(val);
+	val = *data++;
+	*p_entry++ = cpu_to_be32(val);
+	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);
+	return 0;
 }
 
 static int set_imx_hdr_v1(struct imx_header *imxhdr,
@@ -347,93 +310,186 @@ static void print_hdr_v2(struct imx_header *imx_hdr)
 	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v2->entry);
 }
 
-static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
-				char *name, int lineno, int fld)
+static int cmd_cnt;
+
+int skip_separators(struct data_src *ds)
 {
-	int value;
-	static int cmd_ver_first = ~0;
-
-	switch (cmd) {
-	case CMD_IMAGE_VERSION:
-		imximage_version = get_cfg_value(token, name, lineno);
-		if (cmd_ver_first == 0) {
-			fprintf(stderr, "Error: %s[%d] - IMAGE_VERSION "
-				"command need be the first before other "
-				"valid command in the file\n", name, lineno);
-			exit(EXIT_FAILURE);
+	int line_no = ds->lineno;
+	char *p = ds->p;
+
+	for (;;) {
+		char c;
+		if (!p) {
+			if (getline(&ds->line, &ds->len, ds->fd) <= 0)
+				return -1;
+			ds->lineno++;
+			p = ds->line;
+			if (ds->cmd_started) {
+				fprintf(stderr, "warning: continuing command on"
+						" next line, line %s[%d](%s)\n",
+						ds->filename, ds->lineno, p);
+			}
 		}
-		cmd_ver_first = 1;
-		set_hdr_func(imxhdr);
-		break;
-	case CMD_BOOT_FROM:
-		g_flash_offset = get_table_entry_id(imximage_bootops,
-					"imximage boot option", token);
-		if (g_flash_offset == -1) {
-			fprintf(stderr, "Error: %s[%d] -Invalid boot device"
-				"(%s)\n", name, lineno, token);
-			exit(EXIT_FAILURE);
+		c = *p;
+		if ((c == ' ') || (c == '\t')) {
+			p++;
+			continue;
 		}
-		if (unlikely(cmd_ver_first != 1))
-			cmd_ver_first = 0;
-		break;
-	case CMD_DATA:
-		value = get_cfg_value(token, name, lineno);
-		(*set_dcd_val)(imxhdr, name, lineno, fld, value);
-		if (unlikely(cmd_ver_first != 1))
-			cmd_ver_first = 0;
-		break;
+		/* Drop all text starting with '#' as comments */
+		if ((c == '#') || (c == '\r') || (c == '\n')
+				|| !c) {
+			p = NULL;
+			continue;
+		}
+		if (c == ';') {
+			if (ds->cmd_started) {
+				fprintf(stderr, "Error: command not "
+						"finished:%s[%d](%s)\n",
+						ds->filename, ds->lineno, p);
+				exit(EXIT_FAILURE);
+			}
+			p++;
+			continue;
+		}
+		if (!ds->cmd_started && line_no == ds->lineno) {
+			fprintf(stderr, "warning: extra data at end "
+					"of line %s[%d](%s)\n",
+					ds->filename, ds->lineno, p);
+			p = NULL;
+			continue;
+		}
+		ds->p = p;
+		return 0;
 	}
 }
 
-static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
-		char *token, char *name, int lineno, int fld)
+char *grab_token(char *dest, int size, char *src)
 {
-	int value;
-
-	switch (fld) {
-	case CFG_COMMAND:
-		*cmd = get_table_entry_id(imximage_cmds,
-			"imximage commands", token);
-		if (*cmd < 0) {
-			fprintf(stderr, "Error: %s[%d] - Invalid command"
-			"(%s)\n", name, lineno, token);
-			exit(EXIT_FAILURE);
-		}
-		break;
-	case CFG_REG_SIZE:
-		parse_cfg_cmd(imxhdr, *cmd, token, name, lineno, fld);
-		break;
-	case CFG_REG_ADDRESS:
-	case CFG_REG_VALUE:
-		if (*cmd != CMD_DATA)
-			return;
-
-		value = get_cfg_value(token, name, lineno);
-		(*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;
+	while (size) {
+		char c = *src;
+		if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')
+				|| (c == '#') || !c)
+			break;
+		*dest++ = c;
+		size--;
+		src++;
+	}
+	if (!size)
+		return NULL;
+	*dest = 0;
+	return src;
+}
+
+static uint32_t get_cfg_value(struct data_src *ds, uint32_t *pval)
+{
+	char *endptr;
+	uint32_t value;
+
+	if (skip_separators(ds))
+		return -1;
+	errno = 0;
+	value = strtoul(ds->p, &endptr, 16);
+	if (errno || (ds->p == endptr))
+		return -1;
+	*pval = value;
+	ds->p = endptr;
+	return 0;
+}
+
+static int parse_cmd_data(struct data_src *ds)
+{
+	uint32_t data[3];
+	int ret = get_cfg_value(ds, &data[0]);
+
+	if (ret)
+		return ret;
+	ret = get_cfg_value(ds, &data[1]);
+	if (ret)
+		return ret;
+	ret = get_cfg_value(ds, &data[2]);
+	if (ret)
+		return ret;
+	ret = (*set_dcd_val)(ds->imxhdr, data);
+	if (ret)
+		return ret;
+	if (p_entry > p_max_dcd) {
+		uint32_t size = (char *)p_max_dcd - (char *)ds->imxhdr;
+		fprintf(stderr, "Error: header exceeds maximum size(%d)\n",
+				size);
+		return -1;
+	}
+	return 0;
+}
+
+static int parse_image_version(struct data_src *ds)
+{
+	int ret;
+
+	ret = get_cfg_value(ds, &imximage_version);
+	if (ret)
+		return ret;
+	if (cmd_cnt) {
+		fprintf(stderr, "Error: IMAGE_VERSION command needs be "
+				"before other valid commands in the file\n");
+		return -1;
+	}
+	set_hdr_func(ds->imxhdr);
+	return 0;
+}
+
+int get_from_array(struct data_src *ds,
+		const table_entry_t *table, const char *table_name)
+{
+	int val;
+	char token[16];
+	char *p;
+
+	if (skip_separators(ds))
+		return -1;
+	p = grab_token(token, sizeof(token), ds->p);
+	if (!p)
+		return -1;
+	val = get_table_entry_id(table, table_name, token);
+	if (val != -1)
+		ds->p = p;
+	return val;
+}
+
+static int parse_boot_from(struct data_src *ds)
+{
+	g_flash_offset = get_from_array(ds, imximage_bootops,
+			"imximage boot option");
+	if (g_flash_offset == -1) {
+		fprintf(stderr, "Error: Invalid boot device\n");
+		return -1;
 	}
+	return 0;
 }
+
+parse_fld_t cmd_table[] = {
+	parse_image_version, parse_boot_from, parse_cmd_data
+};
+
+static int parse_command(struct data_src *ds)
+{
+	int cmd = get_from_array(ds, imximage_cmds, "imximage commands");
+	if (cmd < 0)
+		return cmd;
+	return cmd_table[cmd](ds);
+}
+
 static void parse_cfg_file(struct imx_header *imxhdr, char *name)
 {
-	FILE *fd = NULL;
-	char *line = NULL;
-	char *token, *saveptr1, *saveptr2;
-	int lineno = 0;
-	int fld;
-	size_t len;
-	int32_t cmd;
-
-	fd = fopen(name, "r");
-	if (fd == 0) {
+	struct data_src ds;
+
+	ds.line = NULL;
+	ds.len = 0;
+	ds.lineno = 0;
+	ds.filename = name;
+	ds.fd = fopen(name, "r");
+	ds.imxhdr = imxhdr;
+	ds.p = NULL;
+	if (ds.fd == 0) {
 		fprintf(stderr, "Error: %s - Can't open DCD file\n", name);
 		exit(EXIT_FAILURE);
 	}
@@ -441,34 +497,22 @@ static void parse_cfg_file(struct imx_header *imxhdr, char *name)
 	/* Very simple parsing, line starting with # are comments
 	 * and are dropped
 	 */
-	while ((getline(&line, &len, fd)) > 0) {
-		lineno++;
-
-		token = strtok_r(line, "\r\n", &saveptr1);
-		if (token == NULL)
-			continue;
-
-		/* Check inside the single line */
-		for (fld = CFG_COMMAND, cmd = CMD_INVALID,
-				line = token; ; line = NULL, fld++) {
-			token = strtok_r(line, " \t", &saveptr2);
-			if (token == NULL)
-				break;
-
-			/* Drop all text starting with '#' as comments */
-			if (token[0] == '#')
-				break;
-
-			parse_cfg_fld(imxhdr, &cmd, token, name,
-					lineno, fld);
+	for (;;) {
+		ds.cmd_started = 0;
+		if (skip_separators(&ds))
+			break;
+		ds.cmd_started = 1;
+		if (parse_command(&ds)) {
+			fprintf(stderr, "Error: invalid token "
+					"%s[%d](%s)\n", name, ds.lineno, ds.p);
+			exit(EXIT_FAILURE);
 		}
-
+		cmd_cnt++;
 	}
-	fclose(fd);
+	fclose(ds.fd);
 	return;
 }
 
-
 static int imximage_check_image_types(uint8_t type)
 {
 	if (type == IH_TYPE_IMXIMAGE)
@@ -557,12 +601,12 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 int imximage_check_params(struct mkimage_params *params)
 {
 	if (!params)
-		return CFG_INVALID;
+		return -1;
 	if (!strlen(params->imagename)) {
 		fprintf(stderr, "Error: %s - Configuration file not specified, "
 			"it is needed for imximage generation\n",
 			params->cmdname);
-		return CFG_INVALID;
+		return -1;
 	}
 	/*
 	 * Check parameters:
tools/imximage.h +14 -11
index 0319c02..efd249b 100644
@@ -49,20 +49,11 @@
 #define DCD_VERSION 0x40
 
 enum imximage_cmd {
-	CMD_INVALID,
 	CMD_IMAGE_VERSION,
 	CMD_BOOT_FROM,
 	CMD_DATA
 };
 
-enum imximage_fld_types {
-	CFG_INVALID = -1,
-	CFG_COMMAND,
-	CFG_REG_SIZE,
-	CFG_REG_ADDRESS,
-	CFG_REG_VALUE
-};
-
 enum imximage_version {
 	IMXIMAGE_VER_INVALID = -1,
 	IMXIMAGE_V1 = 1,
@@ -158,8 +149,20 @@ struct imx_header {
 	} header;
 };
 
-typedef void (*set_dcd_val_t)(struct imx_header *imxhdr, char *name,
-		int lineno, int fld, uint32_t value);
+struct data_src {
+	char *line;
+	size_t len;
+	FILE *fd;
+	int lineno;
+	char cmd_started;
+	char *filename;
+	struct imx_header *imxhdr;
+	char *p;
+};
+
+typedef int (*parse_fld_t)(struct data_src *ds);
+
+typedef int (*set_dcd_val_t)(struct imx_header *imxhdr, uint32_t *data);
 
 typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t entry_point,
 		uint32_t flash_offset);
Signature · 1 line
1.7.9.5
author
#5 lore raw

PATCH v4 5/11 imximage: add expression evaluation

In reply to Troy Kisky

Basic expressions with order precedence is
now supported.
ie. (----3 + ((1+2*3)/--2 + --5 *(8/4))) is 16.

---
 tools/imximage.c |  172 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 162 insertions(+), 10 deletions(-)
tools/imximage.c +162 -10
index 1e120354..2c5a622 100644
@@ -380,20 +380,172 @@ char *grab_token(char *dest, int size, char *src)
 	return src;
 }
 
+char precedence[] = {
+	/* (  +  -  *  /  &  ^  |  ) */
+	   0, 2, 2, 1, 1, 3, 4, 5, 6
+};
+char unary_operations[]  = "(+-";
+char binary_operations[] = " +-*/&^|)";
+
+uint32_t do_func(uint32_t val1, uint32_t val2, int op)
+{
+	switch (op) {
+	case 1:
+		return val1 + val2;
+	case 2:
+		return val1 - val2;
+	case 3:
+		return val1 * val2;
+	case 4:
+		return val1 / val2;
+	case 5:
+		return val1 & val2;
+	case 6:
+		return val1 ^ val2;
+	case 7:
+		return val1 | val2;
+	}
+	fprintf(stderr, "Error: in func %s: val1=%d val2=%d op = %d\n",
+			__func__, val1, val2, op);
+	exit(EXIT_FAILURE);
+}
+
+int find_op(char c, char *p)
+{
+	int i;
+	for (i = 0; ; i++) {
+		if (c == p[i])
+			return i;
+		if (!p[i])
+			break;
+	}
+	return -1;
+}
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
 static uint32_t get_cfg_value(struct data_src *ds, uint32_t *pval)
 {
 	char *endptr;
-	uint32_t value;
+	int op_i = 0;
+	int val_i = 0;
+	unsigned char op[16];
+	uint32_t val[16];
+	int unary = 1;
+	char *p;
 
-	if (skip_separators(ds))
-		return -1;
-	errno = 0;
-	value = strtoul(ds->p, &endptr, 16);
-	if (errno || (ds->p == endptr))
-		return -1;
-	*pval = value;
-	ds->p = endptr;
-	return 0;
+	p = ds->p;
+	for (;;) {
+		char c;
+		int i, j;
+		char *ops = unary ? unary_operations : binary_operations;
+
+		if (unary) {
+			ds->p = p;
+			if (skip_separators(ds))
+				return -1;
+			p = ds->p;
+			c = *p;
+		} else {
+			for (;;) {
+				c = *p;
+				if ((c != ' ') && (c != '\t'))
+					break;
+				p++;
+			}
+		}
+		i = find_op(c, ops);
+		debug("%d,%c,%d:%s\n", i, c, unary, p);
+		if ((i < 0) && unary) {
+			if (val_i >= ARRAY_SIZE(val))
+				return -1;
+			errno = 0;
+			val[val_i++] = strtoul(p, &endptr, 16);
+			if (errno || (p == endptr)) {
+				ds->p = p;
+				return -1;
+			}
+			p = endptr;
+			unary = 0;
+			debug("val[%d]=%x,%d,%d\n", val_i - 1, val[val_i - 1],
+					op_i, val_i);
+do_unary:
+			while (op_i) {
+				j = op[op_i - 1];
+				if (!(j & 0x80))
+					break;
+				op_i--;
+				val[val_i - 1] = do_func(0,
+						val[val_i - 1], j & 0x7f);
+				debug("un:%d,%x,%d,%d\n", val[val_i - 1], j,
+						op_i, val_i);
+			}
+			continue;
+		}
+		if (i < 0) {
+			c = 0;
+			i = 8;
+		} else {
+			p++;
+		}
+		if (c == '(') {
+			if (op_i >= ARRAY_SIZE(op))
+				return -1;
+			op[op_i++] = i;
+			debug("op[%d]=%x,%d,%d\n", op_i - 1, op[op_i - 1],
+					op_i, val_i);
+			unary = 1;
+			continue;
+		}
+		for (;;) {
+			if (!op_i || unary)
+				break;
+			j = op[op_i - 1];
+			if (j == 0) {
+				if (c == ')') {
+					op_i--;
+					goto do_unary;
+				}
+				break;
+			}
+			if ((j & 0x80)) {
+				op_i--;
+				val[val_i - 1] = do_func(0,
+						val[val_i - 1], j & 0x7f);
+				debug("unary:%d,%x\n", val[val_i - 1], j);
+				continue;
+			}
+			if (precedence[i] < precedence[j])
+				break;
+			if (val_i < 2)
+				return -1;
+			op_i--;
+			val[val_i - 2] = do_func(val[val_i - 2],
+					val[val_i - 1], j);
+			val_i--;
+			debug("binary:%d,%x,%d,%d\n", val[val_i - 1], j,
+					op_i, val_i);
+		}
+		if (c == ')') {
+			fprintf(stderr, "Error: unmatched parenthesis\n");
+			return -1;
+		}
+		if (i == 8) {
+			if ((op_i != 0) || (val_i != 1)) {
+				fprintf(stderr, "Error: syntax %d %d\n",
+						op_i, val_i);
+				return -1;
+			}
+			ds->p = p;
+			*pval = val[0];
+			return 0;
+		}
+		if (op_i >= ARRAY_SIZE(op))
+			return -1;
+		op[op_i++] = i | (unary << 7);
+		debug("op[%d]=%x,%d,%d\n", op_i - 1, op[op_i - 1], op_i, val_i);
+		unary = 1;
+	}
 }
 
 static int parse_cmd_data(struct data_src *ds)
Signature · 1 line
1.7.9.5
author
#6 lore raw

PATCH v4 6/11 imximage: add plugin commands

In reply to Troy Kisky

Add commands
plugin address filename
iomux_entry addr, data1 [, data2, [, data3]]
write_entry addr, data1 [, data2, [, data3]]

---
 tools/imximage.c |  338 ++++++++++++++++++++++++++++++++++++++++++++----------
 tools/imximage.h |   11 +-
 2 files changed, 287 insertions(+), 62 deletions(-)
tools/imximage.c +280 -58
index 2c5a622..63252be 100644
@@ -31,7 +31,6 @@
 #include "mkimage.h"
 #include <image.h>
 #include "imximage.h"
-
 /*
  * Supported commands for configuration file
  */
@@ -39,6 +38,9 @@ static table_entry_t imximage_cmds[] = {
 	{CMD_BOOT_FROM,         "BOOT_FROM",            "boot command",	  },
 	{CMD_DATA,              "DATA",                 "Reg Write Data", },
 	{CMD_IMAGE_VERSION,     "IMAGE_VERSION",        "image version",  },
+	{CMD_PLUGIN,		"plugin",		"plugin addr,file",  },
+	{CMD_IOMUX_ENTRY,	"iomux_entry",		"Write iomux reg",  },
+	{CMD_WRITE_ENTRY,	"write_entry",		"Write register",  },
 	{-1,                    "",                     "",	          },
 };
 
@@ -69,8 +71,8 @@ static uint32_t imximage_version;
 
 static set_dcd_val_t set_dcd_val;
 static set_imx_hdr_t set_imx_hdr;
-static set_imx_size_t set_imx_size;
 static uint32_t *p_max_dcd;
+static uint32_t *header_size_ptr;
 static uint32_t g_flash_offset;
 
 static struct image_type_params imximage_params;
@@ -88,8 +90,7 @@ static uint32_t detect_imximage_version(struct imx_header *imx_hdr)
 		return IMXIMAGE_V1;
 
 	/* Try to detect V2 */
-	if ((fhdr_v2->header.tag == IVT_HEADER_TAG) &&
-		(hdr_v2->dcd_table.header.tag == DCD_HEADER_TAG))
+	if ((fhdr_v2->header.tag == IVT_HEADER_TAG))
 		return IMXIMAGE_V2;
 
 	return IMXIMAGE_VER_INVALID;
@@ -160,7 +161,7 @@ static int set_dcd_val_v2(struct imx_header *imxhdr, uint32_t *data)
 }
 
 static int set_imx_hdr_v1(struct imx_header *imxhdr,
-		uint32_t entry_point, uint32_t flash_offset)
+		uint32_t entry_point, uint32_t flash_offset, int plugin)
 {
 	imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;
 	flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
@@ -180,22 +181,12 @@ static int set_imx_hdr_v1(struct imx_header *imxhdr,
 	/* Security feature are not supported */
 	fhdr_v1->app_code_csf = 0;
 	fhdr_v1->super_root_key = 0;
+	header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4);
 	return header_length;
 }
 
-static void set_imx_size_v1(struct imx_header *imxhdr, uint32_t file_size,
-		uint32_t flash_offset)
-{
-	uint32_t *p = (uint32_t *)(((char *)imxhdr)
-			+ imximage_params.header_size);
-
-	/* The external flash header must be at the end of the DCD table */
-	/* file_size includes header */
-	p[-1] = file_size + flash_offset;
-}
-
 static int set_imx_hdr_v2(struct imx_header *imxhdr,
-		uint32_t entry_point, uint32_t flash_offset)
+		uint32_t entry_point, uint32_t flash_offset, int plugin)
 {
 	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
 	flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
@@ -216,27 +207,20 @@ static int set_imx_hdr_v2(struct imx_header *imxhdr,
 	fhdr_v2->boot_data_ptr = hdr_base
 			+ offsetof(imx_header_v2_t, boot_data);
 	hdr_v2->boot_data.start = hdr_base - flash_offset;
+	hdr_v2->boot_data.plugin = plugin;
 
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
+	header_size_ptr = &hdr_v2->boot_data.size;
 	return header_length;
 }
 
-static void set_imx_size_v2(struct imx_header *imxhdr, uint32_t file_size,
-		uint32_t flash_offset)
-{
-	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
-	/* file_size includes header */
-	hdr_v2->boot_data.size = file_size + flash_offset;
-}
-
 static void set_hdr_func(struct imx_header *imxhdr)
 {
 	switch (imximage_version) {
 	case IMXIMAGE_V1:
 		set_dcd_val = set_dcd_val_v1;
 		set_imx_hdr = set_imx_hdr_v1;
-		set_imx_size = set_imx_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;
@@ -245,7 +229,6 @@ static void set_hdr_func(struct imx_header *imxhdr)
 	case IMXIMAGE_V2:
 		set_dcd_val = set_dcd_val_v2;
 		set_imx_hdr = set_imx_hdr_v2;
-		set_imx_size = set_imx_size_v2;
 		p_entry = (uint32_t *)&imxhdr->header.hdr_v2.dcd_table;
 		p_max_dcd = (uint32_t *)((char *)imxhdr + MAX_HEADER_SIZE);
 		break;
@@ -283,31 +266,49 @@ static void print_hdr_v1(struct imx_header *imx_hdr)
 	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v1->app_code_jump_vector);
 }
 
-static void print_hdr_v2(struct imx_header *imx_hdr)
+static void print_header_info2(struct imx_header *imx_hdr)
 {
 	imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2;
 	flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
+
+	printf("Data Size:    ");
+	genimg_print_size(hdr_v2->boot_data.size);
+	printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr);
+	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v2->entry);
+}
+
+static void print_hdr_v2(struct imx_header *imxhdr)
+{
+	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
 	dcd_v2_t *dcd_v2 = &hdr_v2->dcd_table;
 	uint32_t size, version;
 
-	size = be16_to_cpu(dcd_v2->header.length) - 8;
-	if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t))) {
-		fprintf(stderr,
-			"Error: Image corrupt DCD size %d exceed maximum %d\n",
-			(uint32_t)(size / sizeof(dcd_addr_data_t)),
-			MAX_HW_CFG_SIZE_V2);
-		exit(EXIT_FAILURE);
+	if (hdr_v2->fhdr.dcd_ptr) {
+		size = be16_to_cpu(dcd_v2->header.length) - 8;
+		if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t))) {
+			fprintf(stderr,	"Error: Image corrupt DCD size "
+				"%d exceed maximum %d\n",
+				(uint32_t)(size / sizeof(dcd_addr_data_t)),
+				MAX_HW_CFG_SIZE_V2);
+			exit(EXIT_FAILURE);
+		}
 	}
-
-	version = detect_imximage_version(imx_hdr);
+	version = detect_imximage_version(imxhdr);
 
 	printf("Image Type:   Freescale IMX Boot Image\n");
 	printf("Image Ver:    %x", version);
 	printf("%s\n", get_table_entry_name(imximage_versions, NULL, version));
-	printf("Data Size:    ");
-	genimg_print_size(hdr_v2->boot_data.size);
-	printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr);
-	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v2->entry);
+	print_header_info2(imxhdr);
+	if (hdr_v2->boot_data.plugin) {
+		uint32_t flash_offset =
+				hdr_v2->fhdr.self - hdr_v2->boot_data.start;
+		/* The 1st size includes flash offset and the next header */
+		uint32_t plugin_length = hdr_v2->boot_data.size - flash_offset
+				- offsetof(imx_header_v2_t, dcd_table);
+
+		imxhdr = (struct imx_header *)((char *)imxhdr + plugin_length);
+		print_header_info2(imxhdr);
+	}
 }
 
 static int cmd_cnt;
@@ -363,6 +364,24 @@ int skip_separators(struct data_src *ds)
 	}
 }
 
+int skip_comma(struct data_src *ds)
+{
+	char *p = ds->p;
+
+	for (;;) {
+		char c = *p++;
+		if ((c == '#') || (c == '\r') || (c == '\n') || !c)
+			return 0;
+		if (c == ',') {
+			ds->p = p;
+			skip_separators(ds);
+			return 1;
+		}
+		if ((c != ' ') && (c == '\t'))
+			return 0;
+	}
+}
+
 char *grab_token(char *dest, int size, char *src)
 {
 	while (size) {
@@ -551,16 +570,18 @@ do_unary:
 static int parse_cmd_data(struct data_src *ds)
 {
 	uint32_t data[3];
-	int ret = get_cfg_value(ds, &data[0]);
+	int ret, i;
 
-	if (ret)
-		return ret;
-	ret = get_cfg_value(ds, &data[1]);
-	if (ret)
-		return ret;
-	ret = get_cfg_value(ds, &data[2]);
-	if (ret)
-		return ret;
+	if (ds->plugin) {
+		fprintf(stderr, "DATA should be before plug command\n");
+		return -1;
+	}
+	for (i = 0; i < 3; i++) {
+		int ret = get_cfg_value(ds, &data[i]);
+		if (ret)
+			return ret;
+		skip_comma(ds);		/* comma is optional */
+	}
 	ret = (*set_dcd_val)(ds->imxhdr, data);
 	if (ret)
 		return ret;
@@ -573,6 +594,103 @@ static int parse_cmd_data(struct data_src *ds)
 	return 0;
 }
 
+static int get_data(struct data_src *ds, uint32_t *data, int cnt)
+{
+	int i = 0;
+
+	if (!ds->plugin) {
+		fprintf(stderr, "missing plug command\n");
+		return -1;
+	}
+	for (;;) {
+		int ret = get_cfg_value(ds, &data[i++]);
+		if (ret)
+			return ret;
+		if (i >= cnt)
+			break;
+		if (!skip_comma(ds))
+			break;
+	}
+	if (i < 2) {
+		fprintf(stderr, "missing ','\n");
+		return -1;
+	}
+	while (i < 4) {
+		data[i] = data[i - 1];
+		i++;
+	}
+	return 0;
+}
+
+static int store_data(struct data_src *ds, uint32_t *data, int cnt)
+{
+	int i;
+
+	for (i = 0; i < cnt; i++)
+		*p_entry++ = data[i];
+
+	ds->prev[1] = data[1];
+	ds->prev[2] = data[2];
+	ds->prev[3] = data[3];
+	if (p_entry > p_max_dcd) {
+		uint32_t size = (char *)p_max_dcd - (char *)ds->imxhdr;
+		fprintf(stderr, "Error: header exceeds maximum size(%d)\n",
+				size);
+		return -1;
+	}
+	return 0;
+}
+
+static int parse_iomux_entry(struct data_src *ds)
+{
+	uint32_t data[4];
+	int ret, i, j;
+
+	ret = get_data(ds, data, 4);
+	if (ret)
+		return ret;
+	if (data[0] & (3 << 30)) {
+		fprintf(stderr, "bad 1st value\n");
+		return -1;
+	}
+	if ((data[1] == ds->prev[1]) && (data[2] == ds->prev[2])
+			&& (data[3] == ds->prev[3])) {
+		i = j = 1;
+	} else if ((data[1] == data[2]) && (data[2] == data[3])) {
+		i = j = 2;
+	} else {
+		i = 3;
+		j = 4;
+	}
+	data[0] |= (i << 30);
+	return store_data(ds, data, j);
+}
+
+static int parse_write_entry(struct data_src *ds)
+{
+	uint32_t data[4];
+	int ret, i;
+
+	ret = get_data(ds, data, 4);
+	if (ret)
+		return ret;
+	if (data[0] & 3) {
+		fprintf(stderr, "Address must be aligned on word boundary\n");
+		return -1;
+	}
+	if ((data[1] == ds->prev[1]) && (data[2] == ds->prev[2])
+			&& (data[3] == ds->prev[3]))
+		i = 0;
+	else if ((data[1] == data[2]) && (data[2] == data[3]))
+		i = 1;
+	else if (data[2] == data[3])
+		i = 2;
+	else
+		i = 3;
+	data[0] |= i;
+	return store_data(ds, data, i + 1);
+}
+
 static int parse_image_version(struct data_src *ds)
 {
 	int ret;
@@ -618,8 +736,82 @@ static int parse_boot_from(struct data_src *ds)
 	return 0;
 }
 
+static int parse_plugin(struct data_src *ds)
+{
+	struct stat sbuf;
+	int plug_file;
+	unsigned char *ptr;
+	char *p;
+	char c;
+	int ret;
+	uint32_t plug_base;
+	uint32_t header_length;
+
+	if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {
+		fprintf(stderr, "Error: Place BOOT_FROM before plugin\n");
+		return -1;
+	}
+	ret = get_cfg_value(ds, &plug_base);
+	if (ret)
+		return ret;
+
+	if (skip_separators(ds))
+		return -1;
+	p = ds->p;
+	for (;;) {
+		c = *p;
+		if (!c)
+			break;
+		if ((c == ' ') || (c == '\t') || (c == ';') || (c == '#')
+				|| (c == '\r') || (c == '\n')) {
+			*p = 0;
+			break;
+		}
+		p++;
+	}
+	plug_file = open(ds->p, O_RDONLY|O_BINARY);
+	if (plug_file < 0) {
+		fprintf(stderr, "Can't open plugin file %s: %s\n",
+				ds->p, strerror(errno));
+		*p = c;
+		return -1;
+	}
+	if (fstat(plug_file, &sbuf) < 0) {
+		fprintf(stderr, "Can't stat %s: %s\n",
+			ds->p, strerror(errno));
+		close(plug_file);
+		return -1;
+	}
+	ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, plug_file, 0);
+	if (ptr == MAP_FAILED) {
+		fprintf(stderr, "Can't read %s: %s\n",
+			ds->p, strerror(errno));
+		return -1;
+	}
+	*p = c;
+	ds->p = p;
+	/* Set the plugin header */
+	header_length = (*set_imx_hdr)(ds->imxhdr, plug_base,
+			g_flash_offset, 1);
+
+	p = ((char *)ds->imxhdr) + header_length;
+	if ((p + sbuf.st_size) >= (char *)p_max_dcd) {
+		fprintf(stderr, "Out of space\n");
+		return -1;
+	}
+
+	ds->plugin = 1;
+	memcpy(p, ptr, sbuf.st_size);
+	munmap((void *)ptr, sbuf.st_size);
+	close(plug_file);
+
+	p_entry = (uint32_t *)(p + sbuf.st_size);
+	return 0;
+}
+
 parse_fld_t cmd_table[] = {
-	parse_image_version, parse_boot_from, parse_cmd_data
+	parse_image_version, parse_boot_from, parse_cmd_data, parse_plugin,
+	parse_iomux_entry, parse_write_entry
 };
 
 static int parse_command(struct data_src *ds)
@@ -630,9 +822,11 @@ static int parse_command(struct data_src *ds)
 	return cmd_table[cmd](ds);
 }
 
-static void parse_cfg_file(struct imx_header *imxhdr, char *name)
+static void parse_cfg_file(struct imx_header *imxhdr, char *name,
+		uint32_t entry_point)
 {
 	struct data_src ds;
+	uint32_t plugin_length = 0;
 
 	ds.line = NULL;
 	ds.len = 0;
@@ -662,6 +856,35 @@ static void parse_cfg_file(struct imx_header *imxhdr, char *name)
 		cmd_cnt++;
 	}
 	fclose(ds.fd);
+
+	if (ds.plugin) {
+		uint32_t header_length, more;
+		struct imx_header *next_imxhdr;
+
+		*p_entry++ = 0;
+		header_length = ((char *)p_entry) - ((char *)imxhdr);
+		plugin_length = ((header_length - 1) | 0x3f) + 1;
+		more = plugin_length - header_length;
+		if (more)
+			memset(p_entry, 0, more);
+		next_imxhdr = (struct imx_header *)
+				(((char *)imxhdr) + plugin_length);
+		p_entry = (imximage_version == IMXIMAGE_V1) ? (uint32_t *)
+			&next_imxhdr->header.hdr_v1.dcd_table.addr_data[0].type
+			: (uint32_t *)&next_imxhdr->header.hdr_v2.dcd_table;
+		if (p_entry > p_max_dcd) {
+			fprintf(stderr, "Out of space\n");
+			exit(EXIT_FAILURE);
+		}
+
+		/* Set the plugin size in header to include next header */
+		*header_size_ptr = ((char *)p_entry) - ((char *)imxhdr)
+				+ g_flash_offset;
+		imxhdr = next_imxhdr;
+	}
+	/* Set the imx header */
+	imximage_params.header_size = (*set_imx_hdr)(imxhdr, entry_point,
+			g_flash_offset + plugin_length, 0) + plugin_length;
 	return;
 }
 
@@ -727,7 +950,7 @@ int imximage_vrec_header(struct mkimage_params *params,
 	set_hdr_func(imxhdr);
 
 	/* Parse dcd configuration file */
-	parse_cfg_file(imxhdr, params->imagename);
+	parse_cfg_file(imxhdr, params->imagename, params->ep);
 
 	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
 	if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {
@@ -735,9 +958,6 @@ int imximage_vrec_header(struct mkimage_params *params,
 				params->imagename);
 		exit(EXIT_FAILURE);
 	}
-	/* Set the imx header */
-	imximage_params.header_size = (*set_imx_hdr)(imxhdr, params->ep,
-			g_flash_offset);
 	imximage_params.hdr = imxhdr;
 	return 0;
 }
@@ -746,8 +966,10 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 				struct mkimage_params *params)
 {
 	/* Set the size in header */
-	(*set_imx_size)((struct imx_header *)ptr, sbuf->st_size,
-			g_flash_offset);
+	uint32_t offset = (char *)header_size_ptr - (char *)imximage_params.hdr;
+	uint32_t *p = (uint32_t *)((char *)ptr + offset);
+
+	*p = sbuf->st_size + g_flash_offset;
 }
 
 int imximage_check_params(struct mkimage_params *params)
tools/imximage.h +7 -4
index efd249b..79f0156 100644
@@ -51,7 +51,10 @@
 enum imximage_cmd {
 	CMD_IMAGE_VERSION,
 	CMD_BOOT_FROM,
-	CMD_DATA
+	CMD_DATA,
+	CMD_PLUGIN,
+	CMD_IOMUX_ENTRY,
+	CMD_WRITE_ENTRY,
 };
 
 enum imximage_version {
@@ -158,6 +161,8 @@ struct data_src {
 	char *filename;
 	struct imx_header *imxhdr;
 	char *p;
+	int plugin;
+	uint32_t prev[4];
 };
 
 typedef int (*parse_fld_t)(struct data_src *ds);
@@ -165,8 +170,6 @@ typedef int (*parse_fld_t)(struct data_src *ds);
 typedef int (*set_dcd_val_t)(struct imx_header *imxhdr, uint32_t *data);
 
 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);
+		uint32_t flash_offset, int plugin);
 
 #endif /* _IMXIMAGE_H_ */
Signature · 1 line
1.7.9.5
author
#7 lore raw

PATCH v4 7/11 imximage.cfg: run files through C preprocessor

In reply to Troy Kisky

The '#' used as comments in the files cause the preprocessor trouble, so change to /* */.

---
 Makefile                                     |    3 +-
 board/esg/ima3-mx53/imximage.cfg             |  120 ++++++-----
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |   90 ++++----
 board/freescale/mx25pdk/imximage.cfg         |   77 +++----
 board/freescale/mx51evk/imximage.cfg         |  114 +++++-----
 board/freescale/mx53ard/imximage_dd3.cfg     |   83 ++++----
 board/freescale/mx53evk/imximage.cfg         |   86 ++++----
 board/freescale/mx53loco/imximage.cfg        |   83 ++++----
 board/freescale/mx53smd/imximage.cfg         |   83 ++++----
 board/freescale/mx6qarm2/imximage.cfg        |   88 ++++----
 board/genesi/mx51_efikamx/imximage_mx.cfg    |  132 ++++++------
 board/genesi/mx51_efikamx/imximage_sb.cfg    |  126 +++++------
 board/ttcontrol/vision2/imximage_hynix.cfg   |  295 ++++++++++++++------------
 13 files changed, 727 insertions(+), 653 deletions(-)
Makefile +2 -1
index fe2f98c..edf647e 100644
@@ -425,7 +425,8 @@ $(obj)u-boot.img:	$(obj)u-boot.bin
 		-d $< $@
 
 $(obj)u-boot.imx:       $(obj)u-boot.bin
-		$(obj)tools/mkimage -n  $(CONFIG_IMX_CONFIG) -T imximage \
+		$(CC) -E -x c $(CONFIG_IMX_CONFIG) -I./include -o $(obj)imxcfg.imx
+		$(obj)tools/mkimage -n  $(obj)imxcfg.imx -T imximage \
 		-e $(CONFIG_SYS_TEXT_BASE) -d $< $@
 
 $(obj)u-boot.kwb:       $(obj)u-boot.bin
board/esg/ima3-mx53/imximage.cfg +66 -54

153 lines not on this page · raw message

board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +47 -43

109 lines not on this page · raw message

board/freescale/mx25pdk/imximage.cfg +40 -37

93 lines not on this page · raw message

board/freescale/mx51evk/imximage.cfg +60 -54

147 lines not on this page · raw message

board/freescale/mx53ard/imximage_dd3.cfg +43 -40

91 lines not on this page · raw message

board/freescale/mx53evk/imximage.cfg +44 -42

94 lines not on this page · raw message

board/freescale/mx53loco/imximage.cfg +43 -40

91 lines not on this page · raw message

board/freescale/mx53smd/imximage.cfg +43 -40

91 lines not on this page · raw message

board/freescale/mx6qarm2/imximage.cfg +46 -42

101 lines not on this page · raw message

board/genesi/mx51_efikamx/imximage_mx.cfg +70 -62

170 lines not on this page · raw message

board/genesi/mx51_efikamx/imximage_sb.cfg +66 -60

158 lines not on this page · raw message

board/ttcontrol/vision2/imximage_hynix.cfg +157 -138

366 lines not on this page · raw message

Signature · 1 line
1.7.9.5
author
#8 lore raw

PATCH v4 8/11 mx6: add plugin file for use with imximage.cfg

In reply to Troy Kisky

The "plugin" command of mkimage can take this
file as an argument.

---
 arch/arm/cpu/armv7/mx6/Makefile |    5 +-
 arch/arm/cpu/armv7/mx6/plugin.S |  141 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 145 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/armv7/mx6/plugin.S
arch/arm/cpu/armv7/mx6/Makefile +4 -1
index cbce411..b1fce4e 100644
@@ -33,11 +33,14 @@ SOBJS   = lowlevel_init.o
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
 
-all:	$(obj).depend $(LIB)
+all:	$(obj).depend $(LIB) plugin.bin
 
 $(LIB):	$(OBJS)
 	$(call cmd_link_o_target, $(OBJS))
 
+plugin.bin: plugin.o
+	$(OBJCOPY) -O binary --gap-fill 0xff $< $@
+
 #########################################################################
 
 # defines $(obj).depend target
arch/arm/cpu/armv7/mx6/plugin.S new file +141 -0

141 lines not on this page · raw message

Signature · 1 line
1.7.9.5
author
#9 lore raw

PATCH v4 8/11 mx6: add plugin file for use with imximage.cfg

Quoted 11 lines · Troy Kisky

The "plugin" command of mkimage can take this
file as an argument.

---
  arch/arm/cpu/armv7/mx6/Makefile |    5 +-
  arch/arm/cpu/armv7/mx6/plugin.S |  141 +++++++++++++++++++++++++++++++++++++++
  2 files changed, 145 insertions(+), 1 deletion(-)

create mode 100644 arch/arm/cpu/armv7/mx6/plugin.S

Ok, I found the issue with Linux not booting, and I'll need to change this patch to add
disabling of L2 cache and a cache clean.

author
#10 lore raw

PATCH v4 9/11 mx6qsabrelite: imximage.cfg: use symbols instead of hardcoded constants

In reply to Troy Kisky

This allows us to generate plugin data or
DCD rom style data simply by defining USE_PLUGIN

---
 arch/arm/include/asm/arch-mx6/imx-mkimage.h  |  163 +++++++++++++++++
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |  248 +++++++++++++-------------
 2 files changed, 290 insertions(+), 121 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-mx6/imx-mkimage.h
arch/arm/include/asm/arch-mx6/imx-mkimage.h new file +163 -0
new file mode 100644
index 0000000..e61d5b6
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2012 Boundary Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+#ifndef __ASM_ARCH_IMX_MKIMAGE_H__
+#define __ASM_ARCH_IMX_MKIMAGE_H__
+
+/* mx6 duallite and solo have same offsets */
+/*
+ * Bits 31:30 :
+ *  0 : 29:2 absolute address, 1:0 # of data values,
+ *	followed by 0-3 data values in (mx6q, mx6dl, mx6_sololite)
+ *	0 means repeat last data value
+ *  1 : iomuxc relative address, 9:0 mx6q offset, 19:10 mx6dl offset,
+ *	29:20 mx6_sololite offset, 0 offset means skip if this processor
+ *	previous data repeated
+ *  2 : same as 1, but single data value follows
+ *  3 : same as 1. but 3 data values follow
+ */
+#define MA(mx6q, mx6dl, mx6solo_lite)	((mx6q / 4 & 0x3ff) | \
+		((mx6dl / 4 & 0x3ff) * 0x400) | \
+		((mx6solo_lite / 4 & 0x3ff) * 0x100000))
+
+#define IOM_DRAM_DQM0		MA(0x5ac, 0x470, 0x0)
+#define IOM_DRAM_DQM1		MA(0x5b4, 0x474, 0x0)
+#define IOM_DRAM_DQM2		MA(0x528, 0x478, 0x0)
+#define IOM_DRAM_DQM3		MA(0x520, 0x47c, 0x0)
+#define IOM_DRAM_DQM4		MA(0x514, 0x480, 0x0)
+#define IOM_DRAM_DQM5		MA(0x510, 0x484, 0x0)
+#define IOM_DRAM_DQM6		MA(0x5bc, 0x488, 0x0)
+#define IOM_DRAM_DQM7		MA(0x5c4, 0x48c, 0x0)
+
+#define IOM_DRAM_CAS		MA(0x56c, 0x464, 0x0)
+#define IOM_DRAM_RAS		MA(0x578, 0x490, 0x0)
+#define IOM_DRAM_RESET		MA(0x57c, 0x494, 0x0)
+#define IOM_DRAM_SDCLK_0	MA(0x588, 0x4ac, 0x0)
+#define IOM_DRAM_SDCLK_1	MA(0x594, 0x4b0, 0x0)
+#define IOM_DRAM_SDBA2		MA(0x58c, 0x4a0, 0x0)
+#define IOM_DRAM_SDCKE0		MA(0x590, 0x4a4, 0x0)
+#define IOM_DRAM_SDCKE1		MA(0x598, 0x4a8, 0x0)
+#define IOM_DRAM_SDODT0		MA(0x59c, 0x4b4, 0x0)
+#define IOM_DRAM_SDODT1		MA(0x5a0, 0x4b8, 0x0)
+
+#define IOM_DRAM_SDQS0		MA(0x5a8, 0x4bc, 0x0)
+#define IOM_DRAM_SDQS1		MA(0x5b0, 0x4c0, 0x0)
+#define IOM_DRAM_SDQS2		MA(0x524, 0x4c4, 0x0)
+#define IOM_DRAM_SDQS3		MA(0x51c, 0x4c8, 0x0)
+#define IOM_DRAM_SDQS4		MA(0x518, 0x4cc, 0x0)
+#define IOM_DRAM_SDQS5		MA(0x50c, 0x4d0, 0x0)
+#define IOM_DRAM_SDQS6		MA(0x5b8, 0x4d4, 0x0)
+#define IOM_DRAM_SDQS7		MA(0x5c0, 0x4d8, 0x0)
+
+#define IOM_GRP_B0DS		MA(0x784, 0x764, 0x0)
+#define IOM_GRP_B1DS		MA(0x788, 0x770, 0x0)
+#define IOM_GRP_B2DS		MA(0x794, 0x778, 0x0)
+#define IOM_GRP_B3DS		MA(0x79c, 0x77c, 0x0)
+#define IOM_GRP_B4DS		MA(0x7a0, 0x780, 0x0)
+#define IOM_GRP_B5DS		MA(0x7a4, 0x784, 0x0)
+#define IOM_GRP_B6DS		MA(0x7a8, 0x78c, 0x0)
+#define IOM_GRP_B7DS		MA(0x748, 0x748, 0x0)
+#define IOM_GRP_ADDDS		MA(0x74c, 0x74c, 0x0)
+#define IOM_DDRMODE_CTL		MA(0x750, 0x750, 0x0)
+#define IOM_GRP_DDRPKE		MA(0x758, 0x754, 0x0)
+#define IOM_GRP_DDRMODE		MA(0x774, 0x760, 0x0)
+#define IOM_GRP_CTLDS		MA(0x78c, 0x76c, 0x0)
+#define IOM_GRP_DDR_TYPE	MA(0x798, 0x774, 0x0)
+
+#define MMDC_P0		0x021b0000
+#define MMDC_P1		0x021b4000
+#define IOMUXC_BASE_ADDR 0x020e0000
+#define CCM_BASE	0x020C4000
+#define IRAM_FREE_START		0x00907000
+
+#define IOMUXC_GPR4		(IOMUXC_BASE_ADDR + 0x010)
+#define IOMUXC_GPR6		(IOMUXC_BASE_ADDR + 0x018)
+#define IOMUXC_GPR7		(IOMUXC_BASE_ADDR + 0x01c)
+
+#define MMDC_MDCTL		0x000
+#define MMDC_MDPDC		0x004
+#define MMDC_MDOTC		0x008
+#define MMDC_MDCFG0		0x00c
+#define MMDC_MDCFG1		0x010
+#define MMDC_MDCFG2		0x014
+#define MMDC_MDMISC		0x018
+#define MMDC_MDSCR		0x01c
+#define MMDC_MDREF		0x020
+#define MMDC_MDRWD		0x02c
+#define MMDC_MDOR		0x030
+#define MMDC_MDASP		0x040
+#define MMDC_MAPSR		0x404
+#define MMDC_MPZQHWCTRL		0x800
+#define MMDC_MPWLDECTRL0	0x80c
+#define MMDC_MPWLDECTRL1	0x810
+#define MMDC_MPODTCTRL		0x818
+#define MMDC_MPRDDQBY0DL	0x81c
+#define MMDC_MPRDDQBY1DL	0x820
+#define MMDC_MPRDDQBY2DL	0x824
+#define MMDC_MPRDDQBY3DL	0x828
+#define MMDC_MPDGCTRL0		0x83c
+#define MMDC_MPDGCTRL1		0x840
+#define MMDC_MPRDDLCTL		0x848
+#define MMDC_MPWRDLCTL		0x850
+#define MMDC_MPMUR0		0x8b8
+
+#define CCM_CCGR0		0x068
+#define CCM_CCGR1		0x06c
+#define CCM_CCGR2		0x070
+#define CCM_CCGR3		0x074
+#define CCM_CCGR4		0x078
+#define CCM_CCGR5		0x07c
+#define CCM_CCGR6		0x080
+
+#ifdef USE_PLUGIN
+#define IOMUX_ENTRY(addr, args...)	iomux_entry addr, args
+#define IOMUX_ENTRY1 IOMUX_ENTRY
+#define IOMUX_ENTRY2 IOMUX_ENTRY
+#define IOMUX_ENTRY3 IOMUX_ENTRY
+#define WRITE_ENTRY(addr, args...)	write_entry addr, args
+#define WRITE_ENTRY1 WRITE_ENTRY
+#define WRITE_ENTRY2 WRITE_ENTRY
+#define WRITE_ENTRY3 WRITE_ENTRY
+#else
+#ifdef FOR_MX6Q
+#define IOMUX_ENTRY1(addr, mx6q)		DATA 4, \
+		(IOMUXC_BASE_ADDR+(((addr) & 0x3ff) * 4)), mx6q
+#define IOMUX_ENTRY2(addr, mx6q, mx6dl)		DATA 4, \
+		(IOMUXC_BASE_ADDR+(((addr) & 0x3ff) * 4)), mx6q
+#define IOMUX_ENTRY3(addr, mx6q, mx6dl, mx6sl)	DATA 4, \
+		(IOMUXC_BASE_ADDR+(((addr) & 0x3ff) * 4)), mx6q
+#define WRITE_ENTRY1(addr, mx6q)		DATA 4, addr, mx6q
+#define WRITE_ENTRY2(addr, mx6q, mx6dl)		DATA 4, addr, mx6q
+#define WRITE_ENTRY3(addr, mx6q, mx6dl, mx6sl)	DATA 4, addr, mx6q
+#else
+#ifdef FOR_MX6DL
+#define IOMUX_ENTRY1(addr, mx6q)		DATA 4, \
+		(IOMUXC_BASE_ADDR+(((addr) / 0x400 & 0x3ff) * 4)), mx6q
+#define IOMUX_ENTRY2(addr, mx6q, mx6dl)		DATA 4, \
+		(IOMUXC_BASE_ADDR+(((addr) / 0x400 & 0x3ff) * 4)), mx6dl
+#define IOMUX_ENTRY3(addr, mx6q, mx6dl, mx6sl)	DATA 4, \
+		(IOMUXC_BASE_ADDR+(((addr) / 0x400 & 0x3ff) * 4)), mx6dl
+#define WRITE_ENTRY1(addr, mx6q)		DATA 4, addr, mx6q
+#define WRITE_ENTRY2(addr, mx6q, mx6dl)		DATA 4, addr, mx6dl
+#define WRITE_ENTRY3(addr, mx6q, mx6dl, mx6sl)	DATA 4, addr, mx6dl
+#else
+#ifdef FOR_MX6SL
+#define IOMUX_ENTRY1(addr, mx6q)		DATA 4, \
+		(IOMUXC_BASE_ADDR+(((addr) / 0x100000 & 0x3ff) * 4)), mx6q
+#define IOMUX_ENTRY2(addr, mx6q, mx6dl)		DATA 4, \
+		(IOMUXC_BASE_ADDR+(((addr) / 0x100000 & 0x3ff) * 4)), mx6dl
+#define IOMUX_ENTRY3(addr, mx6q, mx6dl, mx6sl)	DATA 4, \
+		(IOMUXC_BASE_ADDR+(((addr) / 0x100000 & 0x3ff) * 4)), mx6sl
+#define WRITE_ENTRY1(addr, mx6q)		DATA 4, addr, mx6q
+#define WRITE_ENTRY2(addr, mx6q, mx6dl)		DATA 4, addr, mx6dl
+#define WRITE_ENTRY3(addr, mx6q, mx6dl, mx6sl)	DATA 4, addr, mx6sl
+#else
+#error "Please select cpu"
+#endif
+#endif
+#endif
+#endif
+
+#endif
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +127 -121

268 lines not on this page · raw message

Signature · 1 line
1.7.9.5
author
#11 lore raw

PATCH v4 10/11 mx6qsabrelite: imximage.cfg: allow plugin to work

In reply to Troy Kisky

Enabling plugin mode seems to require this additional memory write for ddr3 initialization.

---
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |    2 ++
 1 file changed, 2 insertions(+)
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +2 -0
index a95831f..eea8d3a 100644
@@ -111,6 +111,8 @@ WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY0DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY1DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY2DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY3DL, 0x33333333)
+/* MDPDC - CKE pulse width = 3 cycles. CKSRE = 6 cycles, CKSRX = 6 cycles */
+WRITE_ENTRY1(MMDC_P0 + MMDC_MDPDC, 0x00020036)
 
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDMISC, 0x00081740)
 
Signature · 1 line
1.7.9.5
author
#12 lore raw

PATCH v4 11/11 RFC mx6qsabrelite: imximage.cfg: enable plugin mode

In reply to Troy Kisky

Don't apply this patch yet, because although u-boot will boot, Linux won't!!!!

The other CPU's won't come online, and L2 cache
initialization crashes

Calibrating delay loop... 1581.05 BogoMIPS (lpj=7905280)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
Initializing cgroup subsys cpuacct
CPU: Testing write buffer coherency: ok
hw perfevents: enabled with ARMv7 Cortex-A9 PMU driver, 7 counters available
CPU1: failed to come online
CPU2: failed to come online
CPU3: failed to come online
Brought up 1 CPUs
SMP: Total of 1 processors activated (1581.05 BogoMIPS).
print_constraints: dummy:
NET: Registered protocol family 16
print_constraints: vddpu: 725 <--> 1300 mV at 1100 mV fast normal
print_constraints: vddcore: 725 <--> 1300 mV at 1100 mV fast normal
print_constraints: vddsoc: 725 <--> 1300 mV at 1200 mV fast normal
print_constraints: vdd2p5: 2000 <--> 2775 mV at 2400 mV fast normal
print_constraints: vdd1p1: 800 <--> 1400 mV at 1100 mV fast normal
print_constraints: vdd3p0: 2800 <--> 3150 mV at 3000 mV fast normal ------------ Board type Nitrogen6X/W
hw-breakpoint: found 6 breakpoint and 1 watchpoint registers.
hw-breakpoint: 1 breakpoint(s) reserved for watchpoint single-step.
hw-breakpoint: maximum watchpoint size is 4 bytes.
Unhandled fault: imprecise external abort (0x1c06) at 0x1d4c07b4

Internal error: : 1c06 [#1] PREEMPT SMP
Modules linked in:
CPU: 0    Not tainted  (3.0.35-1968-gd3f7f36-03060-ga3844c7 #1)
PC is at mxc_init_l2x0+0x50/0x120

Anyone have a clue?

The same thing under freescale's imx-android-r13.3 works fine. Only mainline doesn't work

---
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +1 -1
index eea8d3a..2af4265 100644
@@ -26,7 +26,7 @@
  * The syntax is taken as close as possible with the kwbimage
  */
 #define FOR_MX6Q
-
+#define USE_PLUGIN
 #include <asm/arch/imx-mkimage.h>
 
 /* image version */
Signature · 1 line
1.7.9.5
author
#13 lore raw

PATCH v4 11/11 RFC mx6qsabrelite: imximage.cfg: enable plugin mode

Quoted 50 lines · Troy Kisky

Don't apply this patch yet, because although u-boot will boot, Linux won't!!!!

The other CPU's won't come online, and L2 cache
initialization crashes

Calibrating delay loop... 1581.05 BogoMIPS (lpj=7905280)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 512
Initializing cgroup subsys cpuacct
CPU: Testing write buffer coherency: ok
hw perfevents: enabled with ARMv7 Cortex-A9 PMU driver, 7 counters available
CPU1: failed to come online
CPU2: failed to come online
CPU3: failed to come online
Brought up 1 CPUs
SMP: Total of 1 processors activated (1581.05 BogoMIPS).
print_constraints: dummy:
NET: Registered protocol family 16
print_constraints: vddpu: 725 <--> 1300 mV at 1100 mV fast normal
print_constraints: vddcore: 725 <--> 1300 mV at 1100 mV fast normal
print_constraints: vddsoc: 725 <--> 1300 mV at 1200 mV fast normal
print_constraints: vdd2p5: 2000 <--> 2775 mV at 2400 mV fast normal
print_constraints: vdd1p1: 800 <--> 1400 mV at 1100 mV fast normal
print_constraints: vdd3p0: 2800 <--> 3150 mV at 3000 mV fast normal ------------ Board type Nitrogen6X/W
hw-breakpoint: found 6 breakpoint and 1 watchpoint registers.
hw-breakpoint: 1 breakpoint(s) reserved for watchpoint single-step.
hw-breakpoint: maximum watchpoint size is 4 bytes.
Unhandled fault: imprecise external abort (0x1c06) at 0x1d4c07b4

Internal error: : 1c06 [#1] PREEMPT SMP
Modules linked in:
CPU: 0    Not tainted  (3.0.35-1968-gd3f7f36-03060-ga3844c7 #1)
PC is at mxc_init_l2x0+0x50/0x120

Anyone have a clue?

The same thing under freescale's imx-android-r13.3 works fine. Only mainline doesn't work

---
  board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |    2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +0 -0
index eea8d3a..2af4265 100644

board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg line 32

Quoted 8 lines
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +1 -1
@@ -26,7 +26,7 @@
   * The syntax is taken as close as possible with the kwbimage
   */
  #define FOR_MX6Q
-
+#define USE_PLUGIN
  #include <asm/arch/imx-mkimage.h>
 
  /* image version */

Never mind. I found the issue. I need to disable the L2 cache before returning from plugin.

Thanks
Troy

author
#14 lore raw

v2 cover Add mx6solo/mx6duallite support

In reply to Troy Kisky

After this series the same binary will run on a Saberlite board using any of the pin compatible processors mx6 quad, mx6 duallite, or mx6 solo. This is accomplished using a plugin and a table built by mkimage.

I made it easy to revert back to the current method by removing
#define USE_PLUGIN

from imximage.cfg file so that it is easy to
support a single processor.

In that case, you should also add
#define FOR_MX6Q/FOR_MX6DL/FOR_MX6SOLO/FOR_MX6SOLOLITE
to select which processor you are building for.

Patches 1-5 of the series are unchanged from version 1.

Troy Kisky (21):
imximage: make header variable length
imximage: check dcd_len as entries added
imximage: enable word writes for version2 header
imximage: cleanup parsing
imximage: add expression evaluation
imximage: add plugin commands
imximage.cfg: run files through C preprocessor
mx6: add plugin file for use with imximage.cfg mx6q_4x_mt41j128.cfg: use symbols instead of hardcoded constants mx6q_4x_mt41j128.cfg: allow plugin to work mx6q_4x_mt41j128.cfg: enable plugin mode mx6q_4x_mt41j128.cfg: add comments mx6q_4x_mt41j128.cfg: use ddr3 mode for reset mx6q_4x_mt41j128.cfg: skip initiailizing non-existent memory mx6q_4x_mt41j128.cfg: reorder for more efficient storage mx6q_4x_mt41j128.cfg: force ZQ calibration
mx6: soc: add get_cpu_type
arch-mx6: add mx6dl_pins.h
mx6qsabrelite: add support for mx6 solo/duallite mx6q_4x_mt41j128.cfg: add mx6 solo/duallite support
mx6qsabrelite: change CONFIG_SYS_PROMPT

 Makefile                                      |    3 +-
 arch/arm/cpu/armv7/mx6/Makefile               |    5 +-
 arch/arm/cpu/armv7/mx6/plugin.S               |  164 +++++
 arch/arm/cpu/armv7/mx6/soc.c                  |   26 +
 arch/arm/include/asm/arch-mx6/imx-mkimage.h   |  177 +++++
 arch/arm/include/asm/arch-mx6/imx-regs.h      |    1 +
 arch/arm/include/asm/arch-mx6/mx6dl_pins.h    |  118 +++
 arch/arm/include/asm/arch-mx6/sys_proto.h     |    6 +
 board/esg/ima3-mx53/imximage.cfg              |  120 +--
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg  |  433 ++++++-----
 board/freescale/mx25pdk/imximage.cfg          |   77 +-
 board/freescale/mx51evk/imximage.cfg          |  114 +--
 board/freescale/mx53ard/imximage_dd3.cfg      |   83 ++-
 board/freescale/mx53evk/imximage.cfg          |   86 +--
 board/freescale/mx53loco/imximage.cfg         |   83 ++-
 board/freescale/mx53smd/imximage.cfg          |   83 ++-
 board/freescale/mx6qarm2/imximage.cfg         |   88 +--
 board/freescale/mx6qsabrelite/mx6qsabrelite.c |  231 ++----
 board/freescale/mx6qsabrelite/pads.h          |  172 +++++
 board/genesi/mx51_efikamx/imximage_mx.cfg     |  132 ++--
 board/genesi/mx51_efikamx/imximage_sb.cfg     |  126 ++--
 board/ttcontrol/vision2/imximage_hynix.cfg    |  295 ++++----
 include/configs/mx6qsabrelite.h               |    2 +-
 tools/imximage.c                              |  967 ++++++++++++++++++-------
 tools/imximage.h                              |   45 +-
 25 files changed, 2389 insertions(+), 1248 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/mx6/plugin.S
 create mode 100644 arch/arm/include/asm/arch-mx6/imx-mkimage.h
 create mode 100644 arch/arm/include/asm/arch-mx6/mx6dl_pins.h
 create mode 100644 board/freescale/mx6qsabrelite/pads.h
Signature · 1 line
1.7.9.5
author
#15 lore raw

PATCH v2 1/21 imximage: make header variable length

Also, the header offset is no longer
right before the code starts.

---
Series tested on an mx51 and mx6q

---
 tools/imximage.c |  142 +++++++++++++++++++++++++++++++-----------------------
 tools/imximage.h |   10 ++--
 2 files changed, 87 insertions(+), 65 deletions(-)
tools/imximage.c +82 -60
index 03a7716..25d3b74 100644
@@ -65,12 +65,15 @@ static table_entry_t imximage_versions[] = {
 	{-1,            "",     " (Invalid)",                 },
 };
 
-static struct imx_header imximage_header;
 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 g_flash_offset;
+
+static struct image_type_params imximage_params;
 
 static uint32_t get_cfg_value(char *token, char *name,  int linenr)
 {
@@ -207,85 +210,79 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;
 }
 
-static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params)
+static int set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
+		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 base_offset;
-
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v1: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}
+	uint32_t hdr_base;
+	uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr)
+			- ((char *)imxhdr));
 
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-	fhdr_v1->app_dest_ptr = params->addr;
-	fhdr_v1->app_dest_ptr = params->ep - imxhdr->flash_offset -
-		sizeof(struct imx_header);
-	fhdr_v1->app_code_jump_vector = params->ep;
+	hdr_base = entry_point - header_length;
+	fhdr_v1->app_dest_ptr = hdr_base - flash_offset;
+	fhdr_v1->app_code_jump_vector = entry_point;
 
-	base_offset = fhdr_v1->app_dest_ptr + imxhdr->flash_offset ;
-	fhdr_v1->dcd_ptr_ptr =
-		(uint32_t) (offsetof(flash_header_v1_t, dcd_ptr) -
-		offsetof(flash_header_v1_t, app_code_jump_vector) +
-		base_offset);
-
-	fhdr_v1->dcd_ptr = base_offset +
-			offsetof(imx_header_v1_t, dcd_table);
-
-	/* The external flash header must be at the end of the DCD table */
-	dcd_v1->addr_data[dcd_len].type = sbuf->st_size +
-				imxhdr->flash_offset +
-				sizeof(struct imx_header);
+	fhdr_v1->dcd_ptr_ptr = hdr_base + offsetof(flash_header_v1_t, dcd_ptr);
+	fhdr_v1->dcd_ptr = hdr_base + offsetof(imx_header_v1_t, dcd_table);
 
 	/* Security feature are not supported */
 	fhdr_v1->app_code_csf = 0;
 	fhdr_v1->super_root_key = 0;
+	return header_length;
+}
+
+static void set_imx_size_v1(struct imx_header *imxhdr, uint32_t file_size,
+		uint32_t flash_offset)
+{
+	uint32_t *p = (uint32_t *)(((char *)imxhdr)
+			+ imximage_params.header_size);
+
+	/* The external flash header must be at the end of the DCD table */
+	/* file_size includes header */
+	p[-1] = file_size + flash_offset;
 }
 
-static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params)
+static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+		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;
-
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v2: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}
+	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);
 
 	/* Set magic number */
 	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
 	fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t));
 	fhdr_v2->header.version = IVT_VERSION; /* 0x40 */
 
-	fhdr_v2->entry = params->ep;
+	fhdr_v2->entry = entry_point;
 	fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
-	fhdr_v2->self = params->ep - sizeof(struct imx_header);
-
-	fhdr_v2->dcd_ptr = fhdr_v2->self +
-			offsetof(imx_header_v2_t, dcd_table);
+	fhdr_v2->self = hdr_base = entry_point - header_length;
 
-	fhdr_v2->boot_data_ptr = fhdr_v2->self +
-			offsetof(imx_header_v2_t, boot_data);
-
-	hdr_v2->boot_data.start = fhdr_v2->self - imxhdr->flash_offset;
-	hdr_v2->boot_data.size = sbuf->st_size +
-			imxhdr->flash_offset +
-			sizeof(struct imx_header);
+	fhdr_v2->dcd_ptr = (dcd_len) ? hdr_base
+			+ offsetof(imx_header_v2_t, dcd_table) : 0;
+	fhdr_v2->boot_data_ptr = hdr_base
+			+ offsetof(imx_header_v2_t, boot_data);
+	hdr_v2->boot_data.start = hdr_base - flash_offset;
 
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
+	return header_length;
+}
+
+static void set_imx_size_v2(struct imx_header *imxhdr, uint32_t file_size,
+		uint32_t flash_offset)
+{
+	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
+	/* file_size includes header */
+	hdr_v2->boot_data.size = file_size + flash_offset;
 }
 
 static void set_hdr_func(struct imx_header *imxhdr)
@@ -295,11 +292,13 @@ static void set_hdr_func(struct imx_header *imxhdr)
 		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;
 		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;
 		break;
 	default:
 		err_imximage_version(imximage_version);
@@ -381,9 +380,9 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
 		set_hdr_func(imxhdr);
 		break;
 	case CMD_BOOT_FROM:
-		imxhdr->flash_offset = get_table_entry_id(imximage_bootops,
+		g_flash_offset = get_table_entry_id(imximage_bootops,
 					"imximage boot option", token);
-		if (imxhdr->flash_offset == -1) {
+		if (g_flash_offset == -1) {
 			fprintf(stderr, "Error: %s[%d] -Invalid boot device"
 				"(%s)\n", name, lineno, token);
 			exit(EXIT_FAILURE);
@@ -521,12 +520,17 @@ static void imximage_print_header(const void *ptr)
 	}
 }
 
-static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
-				struct mkimage_params *params)
+int imximage_vrec_header(struct mkimage_params *params,
+		struct image_type_params *tparams)
 {
-	struct imx_header *imxhdr = (struct imx_header *)ptr;
+	struct imx_header *imxhdr;
 	uint32_t dcd_len;
 
+	imxhdr = calloc(1, MAX_HEADER_SIZE);
+	if (!imxhdr) {
+		fprintf(stderr, "Error: out of memory\n");
+		exit(EXIT_FAILURE);
+	}
 	/*
 	 * In order to not change the old imx cfg file
 	 * by adding VERSION command into it, here need
@@ -534,14 +538,31 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 	 */
 	imximage_version = IMXIMAGE_V1;
 	/* Be able to detect if the cfg file has no BOOT_FROM tag */
-	imxhdr->flash_offset = FLASH_OFFSET_UNDEFINED;
+	g_flash_offset = FLASH_OFFSET_UNDEFINED;
 	set_hdr_func(imxhdr);
 
 	/* Parse dcd configuration file */
 	dcd_len = 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) {
+		fprintf(stderr, "Error: No BOOT_FROM tag in %s\n",
+				params->imagename);
+		exit(EXIT_FAILURE);
+	}
 	/* Set the imx header */
-	(*set_imx_hdr)(imxhdr, dcd_len, sbuf, params);
+	imximage_params.header_size = (*set_imx_hdr)(imxhdr, dcd_len,
+			params->ep, g_flash_offset);
+	imximage_params.hdr = imxhdr;
+	return 0;
+}
+
+static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
+				struct mkimage_params *params)
+{
+	/* Set the size in header */
+	(*set_imx_size)((struct imx_header *)ptr, sbuf->st_size,
+			g_flash_offset);
 }
 
 int imximage_check_params(struct mkimage_params *params)
@@ -571,8 +592,9 @@ int imximage_check_params(struct mkimage_params *params)
  */
 static struct image_type_params imximage_params = {
 	.name		= "Freescale i.MX 5x Boot Image support",
-	.header_size	= sizeof(struct imx_header),
-	.hdr		= (void *)&imximage_header,
+	.header_size	= 0,
+	.hdr		= NULL,
+	.vrec_header	= imximage_vrec_header,
 	.check_image_type = imximage_check_image_types,
 	.verify_header	= imximage_verify_header,
 	.print_header	= imximage_print_header,
tools/imximage.h +5 -5
index 34f293d..5fe3a8a 100644
@@ -30,6 +30,7 @@
 #define DCD_BARKER	0xB17219E9
 
 #define HEADER_OFFSET	0x400
+#define MAX_HEADER_SIZE	(16 << 10)
 
 #define CMD_DATA_STR	"DATA"
 #define FLASH_OFFSET_UNDEFINED	0xFFFFFFFF
@@ -156,7 +157,6 @@ struct imx_header {
 		imx_header_v1_t hdr_v1;
 		imx_header_v2_t hdr_v2;
 	} header;
-	uint32_t flash_offset;
 };
 
 typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
@@ -168,9 +168,9 @@ typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr,
 					uint32_t dcd_len,
 					char *name, int lineno);
 
-typedef void (*set_imx_hdr_t)(struct imx_header *imxhdr,
-					uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params);
+typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
+		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);
 
 #endif /* _IMXIMAGE_H_ */
Signature · 1 line
1.7.9.5
#16 lore raw

PATCH v2 1/21 imximage: make header variable length

On 22/09/2012 04:38, Troy Kisky wrote:

Hi Troy,

Quoted 2 lines

Also, the header offset is no longer
right before the code starts.

Comment and subject of the patch do not match. Can you better explain it ? What have "making header variable length", that is, a new feature, with " the header offset is no longer rigth", that is, a bug ?

Do we already have a variable header the we add a vrec_header function to image_type_params ?

Quoted 38 lines

Series tested on an mx51 and mx6q

---
 tools/imximage.c |  142 +++++++++++++++++++++++++++++++-----------------------
 tools/imximage.h |   10 ++--
 2 files changed, 87 insertions(+), 65 deletions(-)
tools/imximage.c +6 -4
index 03a7716..25d3b74 100644
@@ -65,12 +65,15 @@ static table_entry_t imximage_versions[] = {
 	{-1,            "",     " (Invalid)",                 },
 };
 
-static struct imx_header imximage_header;
 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 g_flash_offset;
+
+static struct image_type_params imximage_params;
 
 static uint32_t get_cfg_value(char *token, char *name,  int linenr)
 {
@@ -207,85 +210,79 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;
 }
 
-static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params)
+static int set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
+		uint32_t entry_point, uint32_t flash_offset)
 {
 	imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;

tools/imximage.c static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, · line 224

Quoted 10 lines
tools/imximage.c +0 -8
 	flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
 	dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table;
-	uint32_t base_offset;
-
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v1: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}

Do you drop BOOT_FROM ? Then this should be documented. Is this to allow that the same image can be loaded from different media, that share the same flash offset ? Then, instead of drop it, I suggest to add more entries in the imximage file, one for each media that is allow.

Something like:
BOOT_FROM sd, nand, spi

and maybe a check in the code if all entries do not share the same start address.

tools/imximage.c static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, · line 222

Quoted 4 lines
tools/imximage.c +3 -0
+	uint32_t hdr_base;
+	uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr)
+			- ((char *)imxhdr));
 

For V1, the header is preallocated with the maximum size, that is the maximum number of DCD entries the SOC in V1 can support. Why do we need a dynamic length for V1 processors ? As far as I know, the number of entries and fields for theses SOCs (i.MX25, i.MX35, i.MX51) is fixed.

Quoted 23 lines
tools/imximage.c +3 -16
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-	fhdr_v1->app_dest_ptr = params->addr;
-	fhdr_v1->app_dest_ptr = params->ep - imxhdr->flash_offset -
-		sizeof(struct imx_header);
-	fhdr_v1->app_code_jump_vector = params->ep;
+	hdr_base = entry_point - header_length;
+	fhdr_v1->app_dest_ptr = hdr_base - flash_offset;
+	fhdr_v1->app_code_jump_vector = entry_point;
 
-	base_offset = fhdr_v1->app_dest_ptr + imxhdr->flash_offset ;
-	fhdr_v1->dcd_ptr_ptr =
-		(uint32_t) (offsetof(flash_header_v1_t, dcd_ptr) -
-		offsetof(flash_header_v1_t, app_code_jump_vector) +
-		base_offset);
-
-	fhdr_v1->dcd_ptr = base_offset +
-			offsetof(imx_header_v1_t, dcd_table);
-
-	/* The external flash header must be at the end of the DCD table */
-	dcd_v1->addr_data[dcd_len].type = sbuf->st_size +
-				imxhdr->flash_offset +

tools/imximage.c static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, · line 238

Quoted 10 lines
tools/imximage.c +5 -1
-				sizeof(struct imx_header);
+	fhdr_v1->dcd_ptr_ptr = hdr_base + offsetof(flash_header_v1_t, dcd_ptr);
+	fhdr_v1->dcd_ptr = hdr_base + offsetof(imx_header_v1_t, dcd_table);
 
 	/* Security feature are not supported */
 	fhdr_v1->app_code_csf = 0;
 	fhdr_v1->super_root_key = 0;
+	return header_length;
+}
+

Ok, I skip review of this part - it depends on your answer on the previous question.

Quoted 10 lines
tools/imximage.c +2 -4
-static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params)
+static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+		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;
-

tools/imximage.c static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, · line 258

Quoted 10 lines
tools/imximage.c +4 -6
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v2: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}
+	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);

So you add a case where there is no DCD table at all. Apart that this van be a use case, but does it happen in the real life ?

Quoted 56 lines
tools/imximage.c +18 -12
 	/* Set magic number */
 	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
 	fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t));
 	fhdr_v2->header.version = IVT_VERSION; /* 0x40 */
 
-	fhdr_v2->entry = params->ep;
+	fhdr_v2->entry = entry_point;
 	fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
-	fhdr_v2->self = params->ep - sizeof(struct imx_header);
-
-	fhdr_v2->dcd_ptr = fhdr_v2->self +
-			offsetof(imx_header_v2_t, dcd_table);
+	fhdr_v2->self = hdr_base = entry_point - header_length;
 
-	fhdr_v2->boot_data_ptr = fhdr_v2->self +
-			offsetof(imx_header_v2_t, boot_data);
-
-	hdr_v2->boot_data.start = fhdr_v2->self - imxhdr->flash_offset;
-	hdr_v2->boot_data.size = sbuf->st_size +
-			imxhdr->flash_offset +
-			sizeof(struct imx_header);
+	fhdr_v2->dcd_ptr = (dcd_len) ? hdr_base
+			+ offsetof(imx_header_v2_t, dcd_table) : 0;
+	fhdr_v2->boot_data_ptr = hdr_base
+			+ offsetof(imx_header_v2_t, boot_data);
+	hdr_v2->boot_data.start = hdr_base - flash_offset;
 
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
+	return header_length;
+}
+
+static void set_imx_size_v2(struct imx_header *imxhdr, uint32_t file_size,
+		uint32_t flash_offset)
+{
+	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
+	/* file_size includes header */
+	hdr_v2->boot_data.size = file_size + flash_offset;
 }
 
 static void set_hdr_func(struct imx_header *imxhdr)
@@ -295,11 +292,13 @@ static void set_hdr_func(struct imx_header *imxhdr)
 		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;
 		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;
 		break;
 	default:
 		err_imximage_version(imximage_version);

tools/imximage.c static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token, · line 386

Quoted 7 lines
tools/imximage.c +1 -2
@@ -381,9 +380,9 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
 		set_hdr_func(imxhdr);
 		break;
 	case CMD_BOOT_FROM:
-		imxhdr->flash_offset = get_table_entry_id(imximage_bootops,
+		g_flash_offset = get_table_entry_id(imximage_bootops,
 					"imximage boot option", token);
-		if (imxhdr->flash_offset == -1) {

Why do we need a global when we have already a way to not use a global ?

Quoted 95 lines
tools/imximage.c +31 -7
+		if (g_flash_offset == -1) {
 			fprintf(stderr, "Error: %s[%d] -Invalid boot device"
 				"(%s)\n", name, lineno, token);
 			exit(EXIT_FAILURE);
@@ -521,12 +520,17 @@ static void imximage_print_header(const void *ptr)
 	}
 }
 
-static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
-				struct mkimage_params *params)
+int imximage_vrec_header(struct mkimage_params *params,
+		struct image_type_params *tparams)
 {
-	struct imx_header *imxhdr = (struct imx_header *)ptr;
+	struct imx_header *imxhdr;
 	uint32_t dcd_len;
 
+	imxhdr = calloc(1, MAX_HEADER_SIZE);
+	if (!imxhdr) {
+		fprintf(stderr, "Error: out of memory\n");
+		exit(EXIT_FAILURE);
+	}
 	/*
 	 * In order to not change the old imx cfg file
 	 * by adding VERSION command into it, here need
@@ -534,14 +538,31 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 	 */
 	imximage_version = IMXIMAGE_V1;
 	/* Be able to detect if the cfg file has no BOOT_FROM tag */
-	imxhdr->flash_offset = FLASH_OFFSET_UNDEFINED;
+	g_flash_offset = FLASH_OFFSET_UNDEFINED;
 	set_hdr_func(imxhdr);
 
 	/* Parse dcd configuration file */
 	dcd_len = 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) {
+		fprintf(stderr, "Error: No BOOT_FROM tag in %s\n",
+				params->imagename);
+		exit(EXIT_FAILURE);
+	}
 	/* Set the imx header */
-	(*set_imx_hdr)(imxhdr, dcd_len, sbuf, params);
+	imximage_params.header_size = (*set_imx_hdr)(imxhdr, dcd_len,
+			params->ep, g_flash_offset);
+	imximage_params.hdr = imxhdr;
+	return 0;
+}
+
+static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
+				struct mkimage_params *params)
+{
+	/* Set the size in header */
+	(*set_imx_size)((struct imx_header *)ptr, sbuf->st_size,
+			g_flash_offset);
 }
 
 int imximage_check_params(struct mkimage_params *params)
@@ -571,8 +592,9 @@ int imximage_check_params(struct mkimage_params *params)
  */
 static struct image_type_params imximage_params = {
 	.name		= "Freescale i.MX 5x Boot Image support",
-	.header_size	= sizeof(struct imx_header),
-	.hdr		= (void *)&imximage_header,
+	.header_size	= 0,
+	.hdr		= NULL,
+	.vrec_header	= imximage_vrec_header,
 	.check_image_type = imximage_check_image_types,
 	.verify_header	= imximage_verify_header,
 	.print_header	= imximage_print_header,
tools/imximage.h +1 -1
index 34f293d..5fe3a8a 100644
@@ -30,6 +30,7 @@
 #define DCD_BARKER	0xB17219E9
 
 #define HEADER_OFFSET	0x400
+#define MAX_HEADER_SIZE	(16 << 10)
 
 #define CMD_DATA_STR	"DATA"
 #define FLASH_OFFSET_UNDEFINED	0xFFFFFFFF
@@ -156,7 +157,6 @@ struct imx_header {
 		imx_header_v1_t hdr_v1;
 		imx_header_v2_t hdr_v2;
 	} header;
-	uint32_t flash_offset;
 };
 
 typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
@@ -168,9 +168,9 @@ typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr,
 					uint32_t dcd_len,

tools/imximage.h typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr, · line 174

Quoted 10 lines
tools/imximage.h +4 -4
 					char *name, int lineno);
 
-typedef void (*set_imx_hdr_t)(struct imx_header *imxhdr,
-					uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params);
+typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
+		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);

I disagree here. mkimage is valid for all architecture, we must not have special entries here for a SOC or SOC family. For all other SOCs, DCD, iMX header have no sense.
Anyway, why do you need to add set_imx_size_t when you call it only in imximage.c ?

tools/imximage.h typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr, · line 176

Quoted 2 lines
tools/imximage.h +0 -0
 #endif /* _IMXIMAGE_H_ */

You should split changes in image.h, that are valid for all architecture, from changes to imximage.c, that are only for i.MX, into different patches.

In my understanding you add additional entry points to have a variable header lenght, but this feature is already used on TI with the AIS image. You use also vrec_header. What am I missing here ?

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#17 lore raw

PATCH v2 1/21 imximage: make header variable length

Quoted 4 lines · Stefano Babic

On 22/09/2012 04:38, Troy Kisky wrote:

Hi Troy,

Quoted 8 lines
Quoted 2 lines

Also, the header offset is no longer
right before the code starts.

Comment and subject of the patch do not match. Can you better explain it ? What have "making header variable length", that is, a new feature, with " the header offset is no longer rigth", that is, a bug ?

Do we already have a variable header the we add a vrec_header function to image_type_params ?

Before this patch we have
000000 402000d1 17800000 00000000 177ffc2c 000010 177ffc20 177ffc00 00000000 00000000 000020 177ff800 00042b58 00000000 402803d2 000030 042403cc a8050e02 30000000 b0050e02 ... more DCD table
000340 cf0000f0 18000e02 7f007f00 1c000e02 000350 7f007f00 00000000 00000000 00000000 000360 00000000 00000000 00000000 00000000
*
0003f0 00000000 00000000 00000000 00000400 000400 ea000014 e59ff014 e59ff014 e59ff014

Notice offset 3fc contains 0x400. This
is the header offset. There is no reason
for this to be in the file, and I have
removed it.

After this patch we have
000000 402000d1 17800000 00000000 177ffcd8 000010 177ffccc 177ffcac 00000000 00000000 000020 177ff8ac 000426ac 00000000 402803d2 000030 042403cc a8050e02 30000000 b0050e02 ... more DCD table
000340 cf0000f0 18000e02 7f007f00 1c000e02 000350 7f007f00 ea000014 e59ff014 e59ff014 000360 e59ff014 e59ff014 e59ff014 e59ff014

Notice the zeros between 0x354 and 0x3fb have been removed. That is what I mean by making it a variable length header.

Quoted 44 lines
Quoted 44 lines

Series tested on an mx51 and mx6q

---
  tools/imximage.c |  142 +++++++++++++++++++++++++++++++-----------------------
  tools/imximage.h |   10 ++--
  2 files changed, 87 insertions(+), 65 deletions(-)
tools/imximage.c +6 -8
index 03a7716..25d3b74 100644
@@ -65,12 +65,15 @@ static table_entry_t imximage_versions[] = {
  	{-1,            "",     " (Invalid)",                 },
  };
 
-static struct imx_header imximage_header;
  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 g_flash_offset;
+
+static struct image_type_params imximage_params;
 
  static uint32_t get_cfg_value(char *token, char *name,  int linenr)
  {
@@ -207,85 +210,79 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
  	dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;
  }
 
-static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params)
+static int set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
+		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 base_offset;
-
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
Quoted 8 lines

tools/imximage.c static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, · line 224

Quoted 4 lines
tools/imximage.c +0 -4
-		fprintf(stderr, "Error: Header v1: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}

Do you drop BOOT_FROM ? Then this should be documented. Is this to allow that the same image can be loaded from different media, that share the same flash offset ? Then, instead of drop it, I suggest to add more entries in the imximage file, one for each media that is allow.

No I did not drop the BOOT_FROM command. I merely moved this check before the function call, as it was common to both set_imx_hdr_v1 and set_imx_hdr_v2

I can make it a separate patch to make it obvious.

Quoted 7 lines

Something like:
BOOT_FROM sd, nand, spi

and maybe a check in the code if all entries do not share the same start address.

Quoted 8 lines

tools/imximage.c static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, · line 222

Quoted 4 lines
tools/imximage.c +3 -0
+	uint32_t hdr_base;
+	uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr)
+			- ((char *)imxhdr));
 

For V1, the header is preallocated with the maximum size, that is the maximum number of DCD entries the SOC in V1 can support. Why do we need a dynamic length for V1 processors ? As far as I know, the number of entries and fields for theses SOCs (i.MX25, i.MX35, i.MX51) is fixed.

You right the DCD table maximum size is fixed. But why should we be forced to use
the maximum size? Why make V1 headers a special case?

Quoted 51 lines
Quoted 24 lines
tools/imximage.c +3 -16
  	/* Set magic number */
  	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-	fhdr_v1->app_dest_ptr = params->addr;
-	fhdr_v1->app_dest_ptr = params->ep - imxhdr->flash_offset -
-		sizeof(struct imx_header);
-	fhdr_v1->app_code_jump_vector = params->ep;
+	hdr_base = entry_point - header_length;
+	fhdr_v1->app_dest_ptr = hdr_base - flash_offset;
+	fhdr_v1->app_code_jump_vector = entry_point;
 
-	base_offset = fhdr_v1->app_dest_ptr + imxhdr->flash_offset ;
-	fhdr_v1->dcd_ptr_ptr =
-		(uint32_t) (offsetof(flash_header_v1_t, dcd_ptr) -
-		offsetof(flash_header_v1_t, app_code_jump_vector) +
-		base_offset);
-
-	fhdr_v1->dcd_ptr = base_offset +
-			offsetof(imx_header_v1_t, dcd_table);
-
-	/* The external flash header must be at the end of the DCD table */
-	dcd_v1->addr_data[dcd_len].type = sbuf->st_size +
-				imxhdr->flash_offset +

tools/imximage.c static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, · line 238

Quoted 10 lines
tools/imximage.c +5 -1
-				sizeof(struct imx_header);
+	fhdr_v1->dcd_ptr_ptr = hdr_base + offsetof(flash_header_v1_t, dcd_ptr);
+	fhdr_v1->dcd_ptr = hdr_base + offsetof(imx_header_v1_t, dcd_table);
 
  	/* Security feature are not supported */
  	fhdr_v1->app_code_csf = 0;
  	fhdr_v1->super_root_key = 0;
+	return header_length;
+}
+

Ok, I skip review of this part - it depends on your answer on the previous question.

Quoted 14 lines
tools/imximage.c +2 -8
-static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params)
+static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+		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;
-
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v2: No BOOT_FROM tag in %s\n",
-			params->imagename);
Quoted 8 lines

tools/imximage.c static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, · line 258

Quoted 6 lines
tools/imximage.c +4 -2
-		exit(EXIT_FAILURE);
-	}
+	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);

So you add a case where there is no DCD table at all. Apart that this van be a use case, but does it happen in the real life ?

Yes, after this patch series, sabrelite with use a plugin with no DCD table at all.
Even your SPL route could use no DCD table.

Quoted 57 lines
Quoted 57 lines
tools/imximage.c +18 -12
  	/* Set magic number */
  	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
  	fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t));
  	fhdr_v2->header.version = IVT_VERSION; /* 0x40 */
 
-	fhdr_v2->entry = params->ep;
+	fhdr_v2->entry = entry_point;
  	fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
-	fhdr_v2->self = params->ep - sizeof(struct imx_header);
-
-	fhdr_v2->dcd_ptr = fhdr_v2->self +
-			offsetof(imx_header_v2_t, dcd_table);
+	fhdr_v2->self = hdr_base = entry_point - header_length;
 
-	fhdr_v2->boot_data_ptr = fhdr_v2->self +
-			offsetof(imx_header_v2_t, boot_data);
-
-	hdr_v2->boot_data.start = fhdr_v2->self - imxhdr->flash_offset;
-	hdr_v2->boot_data.size = sbuf->st_size +
-			imxhdr->flash_offset +
-			sizeof(struct imx_header);
+	fhdr_v2->dcd_ptr = (dcd_len) ? hdr_base
+			+ offsetof(imx_header_v2_t, dcd_table) : 0;
+	fhdr_v2->boot_data_ptr = hdr_base
+			+ offsetof(imx_header_v2_t, boot_data);
+	hdr_v2->boot_data.start = hdr_base - flash_offset;
 
  	/* Security feature are not supported */
  	fhdr_v2->csf = 0;
+	return header_length;
+}
+
+static void set_imx_size_v2(struct imx_header *imxhdr, uint32_t file_size,
+		uint32_t flash_offset)
+{
+	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
+	/* file_size includes header */
+	hdr_v2->boot_data.size = file_size + flash_offset;
  }
 
  static void set_hdr_func(struct imx_header *imxhdr)
@@ -295,11 +292,13 @@ static void set_hdr_func(struct imx_header *imxhdr)
  		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;
  		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;
  		break;
  	default:
  		err_imximage_version(imximage_version);
@@ -381,9 +380,9 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
Quoted 8 lines

tools/imximage.c static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token, · line 386

Quoted 7 lines
tools/imximage.c +1 -2
  		set_hdr_func(imxhdr);
  		break;
  	case CMD_BOOT_FROM:
-		imxhdr->flash_offset = get_table_entry_id(imximage_bootops,
+		g_flash_offset = get_table_entry_id(imximage_bootops,
  					"imximage boot option", token);
-		if (imxhdr->flash_offset == -1) {

Why do we need a global when we have already a way to not use a global ?

Because that flash_offset is unnecessarily taking up space in the output file, and with
variable length headers, I might overwrite it with other data.

Quoted 97 lines
Quoted 97 lines
tools/imximage.c +31 -7
+		if (g_flash_offset == -1) {
  			fprintf(stderr, "Error: %s[%d] -Invalid boot device"
  				"(%s)\n", name, lineno, token);
  			exit(EXIT_FAILURE);
@@ -521,12 +520,17 @@ static void imximage_print_header(const void *ptr)
  	}
  }
 
-static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
-				struct mkimage_params *params)
+int imximage_vrec_header(struct mkimage_params *params,
+		struct image_type_params *tparams)
  {
-	struct imx_header *imxhdr = (struct imx_header *)ptr;
+	struct imx_header *imxhdr;
  	uint32_t dcd_len;
 
+	imxhdr = calloc(1, MAX_HEADER_SIZE);
+	if (!imxhdr) {
+		fprintf(stderr, "Error: out of memory\n");
+		exit(EXIT_FAILURE);
+	}
  	/*
  	 * In order to not change the old imx cfg file
  	 * by adding VERSION command into it, here need
@@ -534,14 +538,31 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
  	 */
  	imximage_version = IMXIMAGE_V1;
  	/* Be able to detect if the cfg file has no BOOT_FROM tag */
-	imxhdr->flash_offset = FLASH_OFFSET_UNDEFINED;
+	g_flash_offset = FLASH_OFFSET_UNDEFINED;
  	set_hdr_func(imxhdr);
 
  	/* Parse dcd configuration file */
  	dcd_len = 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) {
+		fprintf(stderr, "Error: No BOOT_FROM tag in %s\n",
+				params->imagename);
+		exit(EXIT_FAILURE);
+	}
  	/* Set the imx header */
-	(*set_imx_hdr)(imxhdr, dcd_len, sbuf, params);
+	imximage_params.header_size = (*set_imx_hdr)(imxhdr, dcd_len,
+			params->ep, g_flash_offset);
+	imximage_params.hdr = imxhdr;
+	return 0;
+}
+
+static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
+				struct mkimage_params *params)
+{
+	/* Set the size in header */
+	(*set_imx_size)((struct imx_header *)ptr, sbuf->st_size,
+			g_flash_offset);
  }
 
  int imximage_check_params(struct mkimage_params *params)
@@ -571,8 +592,9 @@ int imximage_check_params(struct mkimage_params *params)
   */
  static struct image_type_params imximage_params = {
  	.name		= "Freescale i.MX 5x Boot Image support",
-	.header_size	= sizeof(struct imx_header),
-	.hdr		= (void *)&imximage_header,
+	.header_size	= 0,
+	.hdr		= NULL,
+	.vrec_header	= imximage_vrec_header,
  	.check_image_type = imximage_check_image_types,
  	.verify_header	= imximage_verify_header,
  	.print_header	= imximage_print_header,
tools/imximage.h +1 -1
index 34f293d..5fe3a8a 100644
@@ -30,6 +30,7 @@
  #define DCD_BARKER	0xB17219E9
 
  #define HEADER_OFFSET	0x400
+#define MAX_HEADER_SIZE	(16 << 10)
 
  #define CMD_DATA_STR	"DATA"
  #define FLASH_OFFSET_UNDEFINED	0xFFFFFFFF
@@ -156,7 +157,6 @@ struct imx_header {
  		imx_header_v1_t hdr_v1;
  		imx_header_v2_t hdr_v2;
  	} header;
-	uint32_t flash_offset;
  };
 
  typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
@@ -168,9 +168,9 @@ typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr,
  					uint32_t dcd_len,
  					char *name, int lineno);
 
Quoted 13 lines

tools/imximage.h typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr, · line 174

Quoted 8 lines
tools/imximage.h +4 -4
-typedef void (*set_imx_hdr_t)(struct imx_header *imxhdr,
-					uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params);
+typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
+		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);

I disagree here. mkimage is valid for all architecture, we must not have special entries here for a SOC or SOC family. For all other SOCs, DCD, iMX header have no sense.
Anyway, why do you need to add set_imx_size_t when you call it only in imximage.c ?

I think you misread the file name. This is imximage.h. But I will squash the removal of set_imx_size_t done in a later patch with this one to make it easier to review.

Quoted 10 lines

tools/imximage.h typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr, · line 176

Quoted 3 lines
tools/imximage.h +0 -0
  #endif /* _IMXIMAGE_H_ */

You should split changes in image.h, that are valid for all architecture, from changes to imximage.c, that are only for i.MX, into different patches.

In my understanding you add additional entry points to have a variable header lenght, but this feature is already used on TI with the AIS image. You use also vrec_header. What am I missing here ?

I did not change image.h at all.

Quoted 5 lines

Best regards,
Stefano Babic

#18 lore raw

PATCH v2 1/21 imximage: make header variable length

Quoted 3 lines · Troy Kisky
Quoted 2 lines · Stefano Babic

On 22/09/2012 04:38, Troy Kisky wrote:

Hi Troy,

Quoted 22 lines
Quoted 8 lines
Quoted 2 lines

Also, the header offset is no longer
right before the code starts.

Comment and subject of the patch do not match. Can you better explain it ? What have "making header variable length", that is, a new feature, with " the header offset is no longer rigth", that is, a bug ?

Do we already have a variable header the we add a vrec_header function to image_type_params ?

Before this patch we have
000000 402000d1 17800000 00000000 177ffc2c
000010 177ffc20 177ffc00 00000000 00000000
000020 177ff800 00042b58 00000000 402803d2
000030 042403cc a8050e02 30000000 b0050e02
... more DCD table
000340 cf0000f0 18000e02 7f007f00 1c000e02
000350 7f007f00 00000000 00000000 00000000
000360 00000000 00000000 00000000 00000000
*
0003f0 00000000 00000000 00000000 00000400
000400 ea000014 e59ff014 e59ff014 e59ff014

Quoted 4 lines

Notice offset 3fc contains 0x400. This
is the header offset. There is no reason
for this to be in the file, and I have
removed it.

Right - I do not know anymore the reason why it was explicitely set. It is not useful and not required by the SOC, no reason to have it, agree.

Quoted 12 lines

After this patch we have
000000 402000d1 17800000 00000000 177ffcd8
000010 177ffccc 177ffcac 00000000 00000000
000020 177ff8ac 000426ac 00000000 402803d2
000030 042403cc a8050e02 30000000 b0050e02
... more DCD table
000340 cf0000f0 18000e02 7f007f00 1c000e02
000350 7f007f00 ea000014 e59ff014 e59ff014
000360 e59ff014 e59ff014 e59ff014 e59ff014

Quoted 3 lines

Notice the zeros between 0x354 and 0x3fb have
been removed. That is what I mean by making it
a variable length header.

Ok - I understan that the whole header have a different lenght, but really it is the DCD table that has now a variable length. Please change commit header and comment to explain it. Feel free to add this example

Quoted 54 lines
Quoted 45 lines
Quoted 45 lines

Series tested on an mx51 and mx6q

---
  tools/imximage.c |  142
+++++++++++++++++++++++++++++++-----------------------
  tools/imximage.h |   10 ++--
  2 files changed, 87 insertions(+), 65 deletions(-)
tools/imximage.c +6 -5
index 03a7716..25d3b74 100644
@@ -65,12 +65,15 @@ static table_entry_t imximage_versions[] = {
      {-1,            "",     " (Invalid)",                 },
  };
  -static struct imx_header imximage_header;
  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 g_flash_offset;
+
+static struct image_type_params imximage_params;
    static uint32_t get_cfg_value(char *token, char *name,  int linenr)
  {
@@ -207,85 +210,79 @@ static void set_dcd_rst_v2(struct imx_header
 *imxhdr, uint32_t dcd_len,
      dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;
  }
  -static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t
 dcd_len,
-                    struct stat *sbuf,
-                    struct mkimage_params *params)
+static int set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
+        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 base_offset;
-
-    /* Exit if there is no BOOT_FROM field specifying the

flash_offset */
- if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {

Quoted 8 lines

tools/imximage.c static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, · line 224

Quoted 4 lines
tools/imximage.c +0 -4
-        fprintf(stderr, "Error: Header v1: No BOOT_FROM tag in %s\n",
-            params->imagename);
-        exit(EXIT_FAILURE);
-    }

Do you drop BOOT_FROM ? Then this should be documented. Is this to allow that the same image can be loaded from different media, that share the same flash offset ? Then, instead of drop it, I suggest to add more entries in the imximage file, one for each media that is allow.

Quoted 5 lines

No I did not drop the BOOT_FROM command. I merely moved this check before the function call, as it was common to both set_imx_hdr_v1 and set_imx_hdr_v2

I can make it a separate patch to make it obvious.

Yes, please.

Quoted 12 lines
Quoted 12 lines

Something like:
BOOT_FROM sd, nand, spi

and maybe a check in the code if all entries do not share the same start address.

Quoted 5 lines
tools/imximage.c +2 -0
+    uint32_t hdr_base;
+    uint32_t header_length = (((char

*)&dcd_v1->addr_data[dcd_len].addr)
+ - ((char *)imxhdr));

Quoted 8 lines
Quoted 4 lines

For V1, the header is preallocated with the maximum size, that is the maximum number of DCD entries the SOC in V1 can support. Why do we need a dynamic length for V1 processors ? As far as I know, the number of entries and fields for theses SOCs (i.MX25, i.MX35, i.MX51) is fixed.

You right the DCD table maximum size is fixed. But why should we be forced to use
the maximum size? Why make V1 headers a special case?

No, it should not be - I want only be sure that changes are clear enough. It is absolutely ok that there is no padding after the DCD table. What I see, you fix several different issues with this single patch, and this can make confusion. Split into several patches or at least add a complete and exhaurient commit message.

Quoted 58 lines
Quoted 49 lines
Quoted 24 lines
      /* Set magic number */
      fhdr_v1->app_code_barker = APP_CODE_BARKER;

- fhdr_v1->app_dest_ptr = params->addr;

tools/imximage.c +4 -15
-    fhdr_v1->app_dest_ptr = params->ep - imxhdr->flash_offset -
-        sizeof(struct imx_header);
-    fhdr_v1->app_code_jump_vector = params->ep;
+    hdr_base = entry_point - header_length;
+    fhdr_v1->app_dest_ptr = hdr_base - flash_offset;
+    fhdr_v1->app_code_jump_vector = entry_point;
  -    base_offset = fhdr_v1->app_dest_ptr + imxhdr->flash_offset ;
-    fhdr_v1->dcd_ptr_ptr =
-        (uint32_t) (offsetof(flash_header_v1_t, dcd_ptr) -
-        offsetof(flash_header_v1_t, app_code_jump_vector) +
-        base_offset);
-
-    fhdr_v1->dcd_ptr = base_offset +
-            offsetof(imx_header_v1_t, dcd_table);
-
-    /* The external flash header must be at the end of the DCD table */
-    dcd_v1->addr_data[dcd_len].type = sbuf->st_size +
-                imxhdr->flash_offset +
-                sizeof(struct imx_header);
+    fhdr_v1->dcd_ptr_ptr = hdr_base + offsetof(flash_header_v1_t,

dcd_ptr);

tools/imximage.c static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, · line 238

Quoted 7 lines
tools/imximage.c +4 -0
+    fhdr_v1->dcd_ptr = hdr_base + offsetof(imx_header_v1_t, dcd_table);
        /* Security feature are not supported */
      fhdr_v1->app_code_csf = 0;
      fhdr_v1->super_root_key = 0;
+    return header_length;
+}
+

Ok, I skip review of this part - it depends on your answer on the previous question.

Quoted 15 lines

-static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t
dcd_len,

tools/imximage.c +2 -4
-                    struct stat *sbuf,
-                    struct mkimage_params *params)
+static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+        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;
-
-    /* Exit if there is no BOOT_FROM field specifying the

flash_offset */

tools/imximage.c +0 -3
-    if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-        fprintf(stderr, "Error: Header v2: No BOOT_FROM tag in %s\n",
-            params->imagename);
Quoted 8 lines

tools/imximage.c static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, · line 258

Quoted 6 lines
tools/imximage.c +4 -2
-        exit(EXIT_FAILURE);
-    }
+    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);

So you add a case where there is no DCD table at all. Apart that this van be a use case, but does it happen in the real life ?

Quoted 3 lines

Yes, after this patch series, sabrelite with use a plugin with no DCD table at all.
Even your SPL route could use no DCD table.

Ok - then this is also a bug fix. The SOCs support an empty DCD table, and the current imximage does not. Add also this fix in the commit message, or move it into a separate patch if you can.

Quoted 110 lines
Quoted 101 lines
Quoted 101 lines
tools/imximage.c +9 -3
+        if (g_flash_offset == -1) {
              fprintf(stderr, "Error: %s[%d] -Invalid boot device"
                  "(%s)\n", name, lineno, token);
              exit(EXIT_FAILURE);
@@ -521,12 +520,17 @@ static void imximage_print_header(const void *ptr)
      }
  }
  -static void imximage_set_header(void *ptr, struct stat *sbuf, int
 ifd,
-                struct mkimage_params *params)
+int imximage_vrec_header(struct mkimage_params *params,
+        struct image_type_params *tparams)
  {
-    struct imx_header *imxhdr = (struct imx_header *)ptr;
+    struct imx_header *imxhdr;
      uint32_t dcd_len;
  +    imxhdr = calloc(1, MAX_HEADER_SIZE);
+    if (!imxhdr) {
+        fprintf(stderr, "Error: out of memory\n");
+        exit(EXIT_FAILURE);
+    }
      /*
       * In order to not change the old imx cfg file
       * by adding VERSION command into it, here need
@@ -534,14 +538,31 @@ static void imximage_set_header(void *ptr,
 struct stat *sbuf, int ifd,
       */
      imximage_version = IMXIMAGE_V1;
      /* Be able to detect if the cfg file has no BOOT_FROM tag */
-    imxhdr->flash_offset = FLASH_OFFSET_UNDEFINED;
+    g_flash_offset = FLASH_OFFSET_UNDEFINED;
      set_hdr_func(imxhdr);
        /* Parse dcd configuration file */
      dcd_len = parse_cfg_file(imxhdr, params->imagename);
  +    /* Exit if there is no BOOT_FROM field specifying the

flash_offset */

tools/imximage.c +20 -3
+    if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {
+        fprintf(stderr, "Error: No BOOT_FROM tag in %s\n",
+                params->imagename);
+        exit(EXIT_FAILURE);
+    }
      /* Set the imx header */
-    (*set_imx_hdr)(imxhdr, dcd_len, sbuf, params);
+    imximage_params.header_size = (*set_imx_hdr)(imxhdr, dcd_len,
+            params->ep, g_flash_offset);
+    imximage_params.hdr = imxhdr;
+    return 0;
+}
+
+static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
+                struct mkimage_params *params)
+{
+    /* Set the size in header */
+    (*set_imx_size)((struct imx_header *)ptr, sbuf->st_size,
+            g_flash_offset);
  }
    int imximage_check_params(struct mkimage_params *params)
@@ -571,8 +592,9 @@ int imximage_check_params(struct mkimage_params
 *params)
   */
  static struct image_type_params imximage_params = {
      .name        = "Freescale i.MX 5x Boot Image support",
-    .header_size    = sizeof(struct imx_header),
-    .hdr        = (void *)&imximage_header,
+    .header_size    = 0,
+    .hdr        = NULL,
+    .vrec_header    = imximage_vrec_header,
      .check_image_type = imximage_check_image_types,
      .verify_header    = imximage_verify_header,

.print_header = imximage_print_header,

tools/imximage.h +3 -4
index 34f293d..5fe3a8a 100644
@@ -30,6 +30,7 @@
  #define DCD_BARKER    0xB17219E9
    #define HEADER_OFFSET    0x400
+#define MAX_HEADER_SIZE    (16 << 10)
    #define CMD_DATA_STR    "DATA"
  #define FLASH_OFFSET_UNDEFINED    0xFFFFFFFF
@@ -156,7 +157,6 @@ struct imx_header {
          imx_header_v1_t hdr_v1;
          imx_header_v2_t hdr_v2;
      } header;
-    uint32_t flash_offset;
  };
    typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
@@ -168,9 +168,9 @@ typedef void (*set_dcd_rst_t)(struct imx_header
 *imxhdr,
                      uint32_t dcd_len,
                      char *name, int lineno);
  -typedef void (*set_imx_hdr_t)(struct imx_header *imxhdr,
-                    uint32_t dcd_len,
-                    struct stat *sbuf,
-                    struct mkimage_params *params);
+typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t
 dcd_len,
+        uint32_t entry_point, uint32_t flash_offset);
Quoted 8 lines

tools/imximage.h typedef void (*set_dcd_rst_t)(struct imx_header

Quoted 3 lines
tools/imximage.h +2 -0
+typedef void (*set_imx_size_t)(struct imx_header *imxhdr, uint32_t
 file_size,
+        uint32_t flash_offset);

I disagree here. mkimage is valid for all architecture, we must not have special entries here for a SOC or SOC family. For all other SOCs, DCD, iMX header have no sense.
Anyway, why do you need to add set_imx_size_t when you call it only in imximage.c ?

Quoted 1 line

I think you misread the file name. This is imximage.h.

Sorry, my fault here.

Quoted 9 lines

But I will squash the removal of set_imx_size_t done in a later patch with this one to make it easier to review.

Quoted 6 lines
Quoted 2 lines
    #endif /* _IMXIMAGE_H_ */

You should split changes in image.h, that are valid for all architecture, from changes to imximage.c, that are only for i.MX, into different patches.

Quoted 5 lines
Quoted 3 lines

In my understanding you add additional entry points to have a variable header lenght, but this feature is already used on TI with the AIS image. You use also vrec_header. What am I missing here ?

I did not change image.h at all.

That is fine, then.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#19 lore raw

PATCH v2 2/21 imximage: check dcd_len as entries added

In reply to Troy Kisky

Before the len was checked after the entire file was processed, so it could have already overflowed.

---
 tools/imximage.c |   26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)
tools/imximage.c +11 -15
index 25d3b74..0bfbec3 100644
@@ -71,6 +71,7 @@ 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 g_flash_offset;
 
 static struct image_type_params imximage_params;
@@ -173,13 +174,6 @@ static void set_dcd_rst_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 {
 	dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
 
-	if (dcd_len > MAX_HW_CFG_SIZE_V1) {
-		fprintf(stderr, "Error: %s[%d] -"
-			"DCD table exceeds maximum size(%d)\n",
-			name, lineno, MAX_HW_CFG_SIZE_V1);
-		exit(EXIT_FAILURE);
-	}
-
 	dcd_v1->preamble.barker = DCD_BARKER;
 	dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t);
 }
@@ -193,13 +187,6 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 {
 	dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
 
-	if (dcd_len > MAX_HW_CFG_SIZE_V2) {
-		fprintf(stderr, "Error: %s[%d] -"
-			"DCD table exceeds maximum size(%d)\n",
-			name, lineno, MAX_HW_CFG_SIZE_V2);
-		exit(EXIT_FAILURE);
-	}
-
 	dcd_v2->header.tag = DCD_HEADER_TAG;
 	dcd_v2->header.length = cpu_to_be16(
 			dcd_len * sizeof(dcd_addr_data_t) + 8);
@@ -293,12 +280,14 @@ static void set_hdr_func(struct imx_header *imxhdr)
 		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;
 		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;
 		break;
 	default:
 		err_imximage_version(imximage_version);
@@ -425,8 +414,15 @@ static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
 		value = get_cfg_value(token, name, lineno);
 		(*set_dcd_val)(imxhdr, name, lineno, fld, value, *dcd_len);
 
-		if (fld == CFG_REG_VALUE)
+		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);
+			}
+		}
 		break;
 	default:
 		break;
Signature · 1 line
1.7.9.5
#20 lore raw

PATCH v2 2/21 imximage: check dcd_len as entries added

Quoted 3 lines · Troy Kisky

Before the len was checked after the entire file was processed, so it could have already overflowed.

Hi Troy,

Quoted 68 lines
---
 tools/imximage.c |   26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)
tools/imximage.c +4 -15
index 25d3b74..0bfbec3 100644
@@ -71,6 +71,7 @@ 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 g_flash_offset;
 
 static struct image_type_params imximage_params;
@@ -173,13 +174,6 @@ static void set_dcd_rst_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 {
 	dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
 
-	if (dcd_len > MAX_HW_CFG_SIZE_V1) {
-		fprintf(stderr, "Error: %s[%d] -"
-			"DCD table exceeds maximum size(%d)\n",
-			name, lineno, MAX_HW_CFG_SIZE_V1);
-		exit(EXIT_FAILURE);
-	}
-
 	dcd_v1->preamble.barker = DCD_BARKER;
 	dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t);
 }
@@ -193,13 +187,6 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 {
 	dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
 
-	if (dcd_len > MAX_HW_CFG_SIZE_V2) {
-		fprintf(stderr, "Error: %s[%d] -"
-			"DCD table exceeds maximum size(%d)\n",
-			name, lineno, MAX_HW_CFG_SIZE_V2);
-		exit(EXIT_FAILURE);
-	}
-
 	dcd_v2->header.tag = DCD_HEADER_TAG;
 	dcd_v2->header.length = cpu_to_be16(
 			dcd_len * sizeof(dcd_addr_data_t) + 8);
@@ -293,12 +280,14 @@ static void set_hdr_func(struct imx_header *imxhdr)
 		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;
 		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;
 		break;
 	default:
 		err_imximage_version(imximage_version);
@@ -425,8 +414,15 @@ static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
 		value = get_cfg_value(token, name, lineno);
 		(*set_dcd_val)(imxhdr, name, lineno, fld, value, *dcd_len);
 
-		if (fld == CFG_REG_VALUE)
+		if (fld == CFG_REG_VALUE) {
 			(*dcd_len)++;

tools/imximage.c static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd, · line 428

Quoted 10 lines
tools/imximage.c +7 -0
+			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);
+			}
+		}
 		break;
 	default:
 		break;

This patch seems to me unrelated to the rest, and fixes the case when too much DCD entries are put into the imximage.cfg file. What about to rebase it on the current code and post it as separate patch ? I think this can be merged directly, also in the current realease.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#21 lore raw

PATCH v2 2/21 imximage: check dcd_len as entries added

Quoted 89 lines · Stefano Babic
Quoted 3 lines · Troy Kisky

Before the len was checked after the entire file was processed, so it could have already overflowed.

Hi Troy,

Quoted 68 lines
---
  tools/imximage.c |   26 +++++++++++---------------
  1 file changed, 11 insertions(+), 15 deletions(-)
tools/imximage.c +4 -15
index 25d3b74..0bfbec3 100644
@@ -71,6 +71,7 @@ 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 g_flash_offset;
 
  static struct image_type_params imximage_params;
@@ -173,13 +174,6 @@ static void set_dcd_rst_v1(struct imx_header *imxhdr, uint32_t dcd_len,
  {
  	dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
 
-	if (dcd_len > MAX_HW_CFG_SIZE_V1) {
-		fprintf(stderr, "Error: %s[%d] -"
-			"DCD table exceeds maximum size(%d)\n",
-			name, lineno, MAX_HW_CFG_SIZE_V1);
-		exit(EXIT_FAILURE);
-	}
-
  	dcd_v1->preamble.barker = DCD_BARKER;
  	dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t);
  }
@@ -193,13 +187,6 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
  {
  	dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
 
-	if (dcd_len > MAX_HW_CFG_SIZE_V2) {
-		fprintf(stderr, "Error: %s[%d] -"
-			"DCD table exceeds maximum size(%d)\n",
-			name, lineno, MAX_HW_CFG_SIZE_V2);
-		exit(EXIT_FAILURE);
-	}
-
  	dcd_v2->header.tag = DCD_HEADER_TAG;
  	dcd_v2->header.length = cpu_to_be16(
  			dcd_len * sizeof(dcd_addr_data_t) + 8);
@@ -293,12 +280,14 @@ static void set_hdr_func(struct imx_header *imxhdr)
  		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;
  		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;
  		break;
  	default:
  		err_imximage_version(imximage_version);
@@ -425,8 +414,15 @@ static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
  		value = get_cfg_value(token, name, lineno);
  		(*set_dcd_val)(imxhdr, name, lineno, fld, value, *dcd_len);
 
-		if (fld == CFG_REG_VALUE)
+		if (fld == CFG_REG_VALUE) {
  			(*dcd_len)++;

tools/imximage.c static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd, · line 428

Quoted 10 lines
tools/imximage.c +7 -0
+			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);
+			}
+		}
  		break;
  	default:
  		break;

This patch seems to me unrelated to the rest, and fixes the case when too much DCD entries are put into the imximage.cfg file. What about to rebase it on the current code and post it as separate patch ? I think this can be merged directly, also in the current realease.

Quoted 3 lines

Best regards,
Stefano Babic

It is a fix, but for a bug that has never happened. So I think it is very low priority.
But I can reorder the patches so that this is the 1st in the series, in case the other patches are never accepted.
I don't think it belongs in the current release.

Troy

#22 lore raw

PATCH v2 2/21 imximage: check dcd_len as entries added

Quoted 1 line · Troy Kisky

It is a fix, but for a bug that has never happened.

Right, but anyway it is a fix ;-)

Quoted 5 lines

So I think it is
very low priority.
But I can reorder the patches so that this is the 1st in the series, in case
the other patches are never accepted.

The reason is that simply and easy patches could be merged soon.

Quoted 1 line

I don't think it belongs in the current release.

Right, this should go in -next

Best regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#23 lore raw

PATCH v2 3/21 imximage: enable word writes for version2 header

In reply to Troy Kisky

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

---
 tools/imximage.c |  153 ++++++++++++++++++++++++++----------------------------
 tools/imximage.h |   15 ++----
 2 files changed, 77 insertions(+), 91 deletions(-)
tools/imximage.c +73 -80
index 0bfbec3..21c49e6 100644
@@ -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;
 }
tools/imximage.h +4 -11
index 5fe3a8a..0319c02 100644
@@ -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);
 
Signature · 1 line
1.7.9.5
author
#24 lore raw

PATCH v2 4/21 imximage: cleanup parsing

In reply to Troy Kisky

Move to pulling tokens instead of pushing them. Remove need for switch statements to process commands. Add error messages such as "command not finished", "extra data at end of line", and "invalid token" Add ';' as command separator.

---
 tools/imximage.c |  380 ++++++++++++++++++++++++++++++------------------------
 tools/imximage.h |   25 ++--
 2 files changed, 226 insertions(+), 179 deletions(-)
tools/imximage.c +212 -168
index 21c49e6..1e120354 100644
@@ -75,21 +75,6 @@ static uint32_t g_flash_offset;
 
 static struct image_type_params imximage_params;
 
-static uint32_t get_cfg_value(char *token, char *name,  int linenr)
-{
-	char *endptr;
-	uint32_t value;
-
-	errno = 0;
-	value = strtoul(token, &endptr, 16);
-	if (errno || (token == endptr)) {
-		fprintf(stderr, "Error: %s[%d] - Invalid hex data(%s)\n",
-			name,  linenr, token);
-		exit(EXIT_FAILURE);
-	}
-	return value;
-}
-
 static uint32_t detect_imximage_version(struct imx_header *imx_hdr)
 {
 	imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1;
@@ -120,55 +105,38 @@ static void err_imximage_version(int version)
 
 static uint32_t *p_entry;
 
-static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno,
-					int fld, uint32_t value)
+static int set_dcd_val_v1(struct imx_header *imxhdr, uint32_t *data)
 {
 	dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
+	uint32_t val = *data++;
 
-	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);
-		}
-		*p_entry++ = value;
-		break;
-	case CFG_REG_ADDRESS:
-		*p_entry++ = value;
-		break;
-	case CFG_REG_VALUE:
-		*p_entry++ = value;
-		dcd_v1->preamble.length = (char *)p_entry
-				- (char *)&dcd_v1->addr_data[0].type;
-		break;
-	default:
-		break;
-
+	/* Byte, halfword, word */
+	if ((val != 1) && (val != 2) && (val != 4)) {
+		fprintf(stderr, "Error: Invalid register size (%d)\n", val);
+		return -1;
 	}
+	*p_entry++ = val;
+	*p_entry++ = *data++;
+	*p_entry++ = *data++;
+	dcd_v1->preamble.length = (char *)p_entry - (char *)&dcd_v1->
+			addr_data[0].type;
+	return 0;
 }
 
 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)
+static int set_dcd_val_v2(struct imx_header *imxhdr, uint32_t *data)
 {
 	uint32_t len;
 	dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
+	uint32_t val = *data++;
 
-	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;
+	/* Byte, halfword, word */
+	if ((val != 1) && (val != 2) && (val != 4)) {
+		fprintf(stderr, "Error: Invalid register size (%d)\n", val);
+		return -1;
+	}
+	if (!(p_dcd && (p_dcd->param == val))) {
 		if (!p_dcd) {
 			dcd_v2->header.tag = DCD_HEADER_TAG;
 			dcd_v2->header.version = DCD_VERSION;
@@ -176,24 +144,19 @@ static void set_dcd_val_v2(struct imx_header *imxhdr, char *name, int lineno,
 		} else {
 			p_dcd = (write_dcd_command_t *)p_entry;
 		}
-		p_dcd->param = value;
+		p_dcd->param = val;
 		p_dcd->tag = DCD_COMMAND_TAG;
 		p_entry = (uint32_t *)(p_dcd + 1);
-		break;
-	case CFG_REG_ADDRESS:
-		*p_entry++ = cpu_to_be32(value);
-		break;
-	case CFG_REG_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;
-
 	}
+	val = *data++;
+	*p_entry++ = cpu_to_be32(val);
+	val = *data++;
+	*p_entry++ = cpu_to_be32(val);
+	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);
+	return 0;
 }
 
 static int set_imx_hdr_v1(struct imx_header *imxhdr,
@@ -347,93 +310,186 @@ static void print_hdr_v2(struct imx_header *imx_hdr)
 	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v2->entry);
 }
 
-static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
-				char *name, int lineno, int fld)
+static int cmd_cnt;
+
+int skip_separators(struct data_src *ds)
 {
-	int value;
-	static int cmd_ver_first = ~0;
-
-	switch (cmd) {
-	case CMD_IMAGE_VERSION:
-		imximage_version = get_cfg_value(token, name, lineno);
-		if (cmd_ver_first == 0) {
-			fprintf(stderr, "Error: %s[%d] - IMAGE_VERSION "
-				"command need be the first before other "
-				"valid command in the file\n", name, lineno);
-			exit(EXIT_FAILURE);
+	int line_no = ds->lineno;
+	char *p = ds->p;
+
+	for (;;) {
+		char c;
+		if (!p) {
+			if (getline(&ds->line, &ds->len, ds->fd) <= 0)
+				return -1;
+			ds->lineno++;
+			p = ds->line;
+			if (ds->cmd_started) {
+				fprintf(stderr, "warning: continuing command on"
+						" next line, line %s[%d](%s)\n",
+						ds->filename, ds->lineno, p);
+			}
 		}
-		cmd_ver_first = 1;
-		set_hdr_func(imxhdr);
-		break;
-	case CMD_BOOT_FROM:
-		g_flash_offset = get_table_entry_id(imximage_bootops,
-					"imximage boot option", token);
-		if (g_flash_offset == -1) {
-			fprintf(stderr, "Error: %s[%d] -Invalid boot device"
-				"(%s)\n", name, lineno, token);
-			exit(EXIT_FAILURE);
+		c = *p;
+		if ((c == ' ') || (c == '\t')) {
+			p++;
+			continue;
 		}
-		if (unlikely(cmd_ver_first != 1))
-			cmd_ver_first = 0;
-		break;
-	case CMD_DATA:
-		value = get_cfg_value(token, name, lineno);
-		(*set_dcd_val)(imxhdr, name, lineno, fld, value);
-		if (unlikely(cmd_ver_first != 1))
-			cmd_ver_first = 0;
-		break;
+		/* Drop all text starting with '#' as comments */
+		if ((c == '#') || (c == '\r') || (c == '\n')
+				|| !c) {
+			p = NULL;
+			continue;
+		}
+		if (c == ';') {
+			if (ds->cmd_started) {
+				fprintf(stderr, "Error: command not "
+						"finished:%s[%d](%s)\n",
+						ds->filename, ds->lineno, p);
+				exit(EXIT_FAILURE);
+			}
+			p++;
+			continue;
+		}
+		if (!ds->cmd_started && line_no == ds->lineno) {
+			fprintf(stderr, "warning: extra data at end "
+					"of line %s[%d](%s)\n",
+					ds->filename, ds->lineno, p);
+			p = NULL;
+			continue;
+		}
+		ds->p = p;
+		return 0;
 	}
 }
 
-static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
-		char *token, char *name, int lineno, int fld)
+char *grab_token(char *dest, int size, char *src)
 {
-	int value;
-
-	switch (fld) {
-	case CFG_COMMAND:
-		*cmd = get_table_entry_id(imximage_cmds,
-			"imximage commands", token);
-		if (*cmd < 0) {
-			fprintf(stderr, "Error: %s[%d] - Invalid command"
-			"(%s)\n", name, lineno, token);
-			exit(EXIT_FAILURE);
-		}
-		break;
-	case CFG_REG_SIZE:
-		parse_cfg_cmd(imxhdr, *cmd, token, name, lineno, fld);
-		break;
-	case CFG_REG_ADDRESS:
-	case CFG_REG_VALUE:
-		if (*cmd != CMD_DATA)
-			return;
-
-		value = get_cfg_value(token, name, lineno);
-		(*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;
+	while (size) {
+		char c = *src;
+		if ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')
+				|| (c == '#') || !c)
+			break;
+		*dest++ = c;
+		size--;
+		src++;
+	}
+	if (!size)
+		return NULL;
+	*dest = 0;
+	return src;
+}
+
+static uint32_t get_cfg_value(struct data_src *ds, uint32_t *pval)
+{
+	char *endptr;
+	uint32_t value;
+
+	if (skip_separators(ds))
+		return -1;
+	errno = 0;
+	value = strtoul(ds->p, &endptr, 16);
+	if (errno || (ds->p == endptr))
+		return -1;
+	*pval = value;
+	ds->p = endptr;
+	return 0;
+}
+
+static int parse_cmd_data(struct data_src *ds)
+{
+	uint32_t data[3];
+	int ret = get_cfg_value(ds, &data[0]);
+
+	if (ret)
+		return ret;
+	ret = get_cfg_value(ds, &data[1]);
+	if (ret)
+		return ret;
+	ret = get_cfg_value(ds, &data[2]);
+	if (ret)
+		return ret;
+	ret = (*set_dcd_val)(ds->imxhdr, data);
+	if (ret)
+		return ret;
+	if (p_entry > p_max_dcd) {
+		uint32_t size = (char *)p_max_dcd - (char *)ds->imxhdr;
+		fprintf(stderr, "Error: header exceeds maximum size(%d)\n",
+				size);
+		return -1;
+	}
+	return 0;
+}
+
+static int parse_image_version(struct data_src *ds)
+{
+	int ret;
+
+	ret = get_cfg_value(ds, &imximage_version);
+	if (ret)
+		return ret;
+	if (cmd_cnt) {
+		fprintf(stderr, "Error: IMAGE_VERSION command needs be "
+				"before other valid commands in the file\n");
+		return -1;
+	}
+	set_hdr_func(ds->imxhdr);
+	return 0;
+}
+
+int get_from_array(struct data_src *ds,
+		const table_entry_t *table, const char *table_name)
+{
+	int val;
+	char token[16];
+	char *p;
+
+	if (skip_separators(ds))
+		return -1;
+	p = grab_token(token, sizeof(token), ds->p);
+	if (!p)
+		return -1;
+	val = get_table_entry_id(table, table_name, token);
+	if (val != -1)
+		ds->p = p;
+	return val;
+}
+
+static int parse_boot_from(struct data_src *ds)
+{
+	g_flash_offset = get_from_array(ds, imximage_bootops,
+			"imximage boot option");
+	if (g_flash_offset == -1) {
+		fprintf(stderr, "Error: Invalid boot device\n");
+		return -1;
 	}
+	return 0;
 }
+
+parse_fld_t cmd_table[] = {
+	parse_image_version, parse_boot_from, parse_cmd_data
+};
+
+static int parse_command(struct data_src *ds)
+{
+	int cmd = get_from_array(ds, imximage_cmds, "imximage commands");
+	if (cmd < 0)
+		return cmd;
+	return cmd_table[cmd](ds);
+}
+
 static void parse_cfg_file(struct imx_header *imxhdr, char *name)
 {
-	FILE *fd = NULL;
-	char *line = NULL;
-	char *token, *saveptr1, *saveptr2;
-	int lineno = 0;
-	int fld;
-	size_t len;
-	int32_t cmd;
-
-	fd = fopen(name, "r");
-	if (fd == 0) {
+	struct data_src ds;
+
+	ds.line = NULL;
+	ds.len = 0;
+	ds.lineno = 0;
+	ds.filename = name;
+	ds.fd = fopen(name, "r");
+	ds.imxhdr = imxhdr;
+	ds.p = NULL;
+	if (ds.fd == 0) {
 		fprintf(stderr, "Error: %s - Can't open DCD file\n", name);
 		exit(EXIT_FAILURE);
 	}
@@ -441,34 +497,22 @@ static void parse_cfg_file(struct imx_header *imxhdr, char *name)
 	/* Very simple parsing, line starting with # are comments
 	 * and are dropped
 	 */
-	while ((getline(&line, &len, fd)) > 0) {
-		lineno++;
-
-		token = strtok_r(line, "\r\n", &saveptr1);
-		if (token == NULL)
-			continue;
-
-		/* Check inside the single line */
-		for (fld = CFG_COMMAND, cmd = CMD_INVALID,
-				line = token; ; line = NULL, fld++) {
-			token = strtok_r(line, " \t", &saveptr2);
-			if (token == NULL)
-				break;
-
-			/* Drop all text starting with '#' as comments */
-			if (token[0] == '#')
-				break;
-
-			parse_cfg_fld(imxhdr, &cmd, token, name,
-					lineno, fld);
+	for (;;) {
+		ds.cmd_started = 0;
+		if (skip_separators(&ds))
+			break;
+		ds.cmd_started = 1;
+		if (parse_command(&ds)) {
+			fprintf(stderr, "Error: invalid token "
+					"%s[%d](%s)\n", name, ds.lineno, ds.p);
+			exit(EXIT_FAILURE);
 		}
-
+		cmd_cnt++;
 	}
-	fclose(fd);
+	fclose(ds.fd);
 	return;
 }
 
-
 static int imximage_check_image_types(uint8_t type)
 {
 	if (type == IH_TYPE_IMXIMAGE)
@@ -557,12 +601,12 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 int imximage_check_params(struct mkimage_params *params)
 {
 	if (!params)
-		return CFG_INVALID;
+		return -1;
 	if (!strlen(params->imagename)) {
 		fprintf(stderr, "Error: %s - Configuration file not specified, "
 			"it is needed for imximage generation\n",
 			params->cmdname);
-		return CFG_INVALID;
+		return -1;
 	}
 	/*
 	 * Check parameters:
tools/imximage.h +14 -11
index 0319c02..efd249b 100644
@@ -49,20 +49,11 @@
 #define DCD_VERSION 0x40
 
 enum imximage_cmd {
-	CMD_INVALID,
 	CMD_IMAGE_VERSION,
 	CMD_BOOT_FROM,
 	CMD_DATA
 };
 
-enum imximage_fld_types {
-	CFG_INVALID = -1,
-	CFG_COMMAND,
-	CFG_REG_SIZE,
-	CFG_REG_ADDRESS,
-	CFG_REG_VALUE
-};
-
 enum imximage_version {
 	IMXIMAGE_VER_INVALID = -1,
 	IMXIMAGE_V1 = 1,
@@ -158,8 +149,20 @@ struct imx_header {
 	} header;
 };
 
-typedef void (*set_dcd_val_t)(struct imx_header *imxhdr, char *name,
-		int lineno, int fld, uint32_t value);
+struct data_src {
+	char *line;
+	size_t len;
+	FILE *fd;
+	int lineno;
+	char cmd_started;
+	char *filename;
+	struct imx_header *imxhdr;
+	char *p;
+};
+
+typedef int (*parse_fld_t)(struct data_src *ds);
+
+typedef int (*set_dcd_val_t)(struct imx_header *imxhdr, uint32_t *data);
 
 typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t entry_point,
 		uint32_t flash_offset);
Signature · 1 line
1.7.9.5
#25 lore raw

PATCH v2 4/21 imximage: cleanup parsing

Quoted 8 lines · Troy Kisky

Move to pulling tokens instead of pushing them. Remove need for switch statements to process commands. Add error messages such as "command not finished", "extra data at end of line", and "invalid token" Add ';' as command separator.

---

Hi Troy,

you add code in previous patch and you remove it in this one. This makes quite difficult to review them.

Normally, we do do have this case, and code is not added and removed in the same patches series. Should you not squash patches together and / or rearrange them with different topic ?

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#26 lore raw

PATCH v2 4/21 imximage: cleanup parsing

Quoted 14 lines · Stefano Babic
Quoted 8 lines · Troy Kisky

Move to pulling tokens instead of pushing them. Remove need for switch statements to process commands. Add error messages such as "command not finished", "extra data at end of line", and "invalid token" Add ';' as command separator.

---

Hi Troy,

you add code in previous patch and you remove it in this one. This makes quite difficult to review them.

Quoted 8 lines

Normally, we do do have this case, and code is not added and removed in the same patches series. Should you not squash patches together and / or rearrange them with different topic ?

Best regards,
Stefano Babic

Yes, I should have done this. A lot of time passed between when I added it and when I removed it, so I forgot that I was the one that added it! I had finished the series and was debugging before I saw a better way.

Will fix.

author
#27 lore raw

PATCH v2 5/21 imximage: add expression evaluation

In reply to Troy Kisky

Basic expressions with order precedence is
now supported.
ie. (----3 + ((1+2*3)/--2 + --5 *(8/4))) is 16.

---
 tools/imximage.c |  172 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 162 insertions(+), 10 deletions(-)
tools/imximage.c +162 -10
index 1e120354..2c5a622 100644
@@ -380,20 +380,172 @@ char *grab_token(char *dest, int size, char *src)
 	return src;
 }
 
+char precedence[] = {
+	/* (  +  -  *  /  &  ^  |  ) */
+	   0, 2, 2, 1, 1, 3, 4, 5, 6
+};
+char unary_operations[]  = "(+-";
+char binary_operations[] = " +-*/&^|)";
+
+uint32_t do_func(uint32_t val1, uint32_t val2, int op)
+{
+	switch (op) {
+	case 1:
+		return val1 + val2;
+	case 2:
+		return val1 - val2;
+	case 3:
+		return val1 * val2;
+	case 4:
+		return val1 / val2;
+	case 5:
+		return val1 & val2;
+	case 6:
+		return val1 ^ val2;
+	case 7:
+		return val1 | val2;
+	}
+	fprintf(stderr, "Error: in func %s: val1=%d val2=%d op = %d\n",
+			__func__, val1, val2, op);
+	exit(EXIT_FAILURE);
+}
+
+int find_op(char c, char *p)
+{
+	int i;
+	for (i = 0; ; i++) {
+		if (c == p[i])
+			return i;
+		if (!p[i])
+			break;
+	}
+	return -1;
+}
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
 static uint32_t get_cfg_value(struct data_src *ds, uint32_t *pval)
 {
 	char *endptr;
-	uint32_t value;
+	int op_i = 0;
+	int val_i = 0;
+	unsigned char op[16];
+	uint32_t val[16];
+	int unary = 1;
+	char *p;
 
-	if (skip_separators(ds))
-		return -1;
-	errno = 0;
-	value = strtoul(ds->p, &endptr, 16);
-	if (errno || (ds->p == endptr))
-		return -1;
-	*pval = value;
-	ds->p = endptr;
-	return 0;
+	p = ds->p;
+	for (;;) {
+		char c;
+		int i, j;
+		char *ops = unary ? unary_operations : binary_operations;
+
+		if (unary) {
+			ds->p = p;
+			if (skip_separators(ds))
+				return -1;
+			p = ds->p;
+			c = *p;
+		} else {
+			for (;;) {
+				c = *p;
+				if ((c != ' ') && (c != '\t'))
+					break;
+				p++;
+			}
+		}
+		i = find_op(c, ops);
+		debug("%d,%c,%d:%s\n", i, c, unary, p);
+		if ((i < 0) && unary) {
+			if (val_i >= ARRAY_SIZE(val))
+				return -1;
+			errno = 0;
+			val[val_i++] = strtoul(p, &endptr, 16);
+			if (errno || (p == endptr)) {
+				ds->p = p;
+				return -1;
+			}
+			p = endptr;
+			unary = 0;
+			debug("val[%d]=%x,%d,%d\n", val_i - 1, val[val_i - 1],
+					op_i, val_i);
+do_unary:
+			while (op_i) {
+				j = op[op_i - 1];
+				if (!(j & 0x80))
+					break;
+				op_i--;
+				val[val_i - 1] = do_func(0,
+						val[val_i - 1], j & 0x7f);
+				debug("un:%d,%x,%d,%d\n", val[val_i - 1], j,
+						op_i, val_i);
+			}
+			continue;
+		}
+		if (i < 0) {
+			c = 0;
+			i = 8;
+		} else {
+			p++;
+		}
+		if (c == '(') {
+			if (op_i >= ARRAY_SIZE(op))
+				return -1;
+			op[op_i++] = i;
+			debug("op[%d]=%x,%d,%d\n", op_i - 1, op[op_i - 1],
+					op_i, val_i);
+			unary = 1;
+			continue;
+		}
+		for (;;) {
+			if (!op_i || unary)
+				break;
+			j = op[op_i - 1];
+			if (j == 0) {
+				if (c == ')') {
+					op_i--;
+					goto do_unary;
+				}
+				break;
+			}
+			if ((j & 0x80)) {
+				op_i--;
+				val[val_i - 1] = do_func(0,
+						val[val_i - 1], j & 0x7f);
+				debug("unary:%d,%x\n", val[val_i - 1], j);
+				continue;
+			}
+			if (precedence[i] < precedence[j])
+				break;
+			if (val_i < 2)
+				return -1;
+			op_i--;
+			val[val_i - 2] = do_func(val[val_i - 2],
+					val[val_i - 1], j);
+			val_i--;
+			debug("binary:%d,%x,%d,%d\n", val[val_i - 1], j,
+					op_i, val_i);
+		}
+		if (c == ')') {
+			fprintf(stderr, "Error: unmatched parenthesis\n");
+			return -1;
+		}
+		if (i == 8) {
+			if ((op_i != 0) || (val_i != 1)) {
+				fprintf(stderr, "Error: syntax %d %d\n",
+						op_i, val_i);
+				return -1;
+			}
+			ds->p = p;
+			*pval = val[0];
+			return 0;
+		}
+		if (op_i >= ARRAY_SIZE(op))
+			return -1;
+		op[op_i++] = i | (unary << 7);
+		debug("op[%d]=%x,%d,%d\n", op_i - 1, op[op_i - 1], op_i, val_i);
+		unary = 1;
+	}
 }
 
 static int parse_cmd_data(struct data_src *ds)
Signature · 1 line
1.7.9.5
#28 lore raw

PATCH v2 5/21 imximage: add expression evaluation

Quoted 6 lines · Troy Kisky

Basic expressions with order precedence is
now supported.
ie. (----3 + ((1+2*3)/--2 + --5 *(8/4))) is 16.

---

Hi Troy,

tools/imximage.c

Quoted 5 lines
 tools/imximage.c |  172 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 162 insertions(+), 10 deletions(-)
tools/imximage.c +0 -0
index 1e120354..2c5a622 100644

I have some general considerations. First, if you plan to add support for expression evaluation, this feature should be available generally for mkimage, that means also other processors / architecture can profit of it. It should be moved away from imximage.c code.

Then, you want also let that the preprocesso can parse the imximage code. I can imagine that in such terms it could be then possible to define in imximage.cfg something like:

#define DDR_VAL (1 <<17 | 3 << 7)
#define ADDRESS 0x0x53something

DATA 4 ADDRESS DDR_VAL

Else, why do we need the power of C preprocessor ?

If this is true, can you explain us which is the use case using the C preprocessor and which is the one for the expression evaluator ? And why do we need both ?

Quoted 173 lines
tools/imximage.c +153 -10
@@ -380,20 +380,172 @@ char *grab_token(char *dest, int size, char *src)
 	return src;
 }
 
+char precedence[] = {
+	/* (  +  -  *  /  &  ^  |  ) */
+	   0, 2, 2, 1, 1, 3, 4, 5, 6
+};
+char unary_operations[]  = "(+-";
+char binary_operations[] = " +-*/&^|)";
+
+uint32_t do_func(uint32_t val1, uint32_t val2, int op)
+{
+	switch (op) {
+	case 1:
+		return val1 + val2;
+	case 2:
+		return val1 - val2;
+	case 3:
+		return val1 * val2;
+	case 4:
+		return val1 / val2;
+	case 5:
+		return val1 & val2;
+	case 6:
+		return val1 ^ val2;
+	case 7:
+		return val1 | val2;
+	}
+	fprintf(stderr, "Error: in func %s: val1=%d val2=%d op = %d\n",
+			__func__, val1, val2, op);
+	exit(EXIT_FAILURE);
+}
+
+int find_op(char c, char *p)
+{
+	int i;
+	for (i = 0; ; i++) {
+		if (c == p[i])
+			return i;
+		if (!p[i])
+			break;
+	}
+	return -1;
+}
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
 static uint32_t get_cfg_value(struct data_src *ds, uint32_t *pval)
 {
 	char *endptr;
-	uint32_t value;
+	int op_i = 0;
+	int val_i = 0;
+	unsigned char op[16];
+	uint32_t val[16];
+	int unary = 1;
+	char *p;
 
-	if (skip_separators(ds))
-		return -1;
-	errno = 0;
-	value = strtoul(ds->p, &endptr, 16);
-	if (errno || (ds->p == endptr))
-		return -1;
-	*pval = value;
-	ds->p = endptr;
-	return 0;
+	p = ds->p;
+	for (;;) {
+		char c;
+		int i, j;
+		char *ops = unary ? unary_operations : binary_operations;
+
+		if (unary) {
+			ds->p = p;
+			if (skip_separators(ds))
+				return -1;
+			p = ds->p;
+			c = *p;
+		} else {
+			for (;;) {
+				c = *p;
+				if ((c != ' ') && (c != '\t'))
+					break;
+				p++;
+			}
+		}
+		i = find_op(c, ops);
+		debug("%d,%c,%d:%s\n", i, c, unary, p);
+		if ((i < 0) && unary) {
+			if (val_i >= ARRAY_SIZE(val))
+				return -1;
+			errno = 0;
+			val[val_i++] = strtoul(p, &endptr, 16);
+			if (errno || (p == endptr)) {
+				ds->p = p;
+				return -1;
+			}
+			p = endptr;
+			unary = 0;
+			debug("val[%d]=%x,%d,%d\n", val_i - 1, val[val_i - 1],
+					op_i, val_i);
+do_unary:
+			while (op_i) {
+				j = op[op_i - 1];
+				if (!(j & 0x80))
+					break;
+				op_i--;
+				val[val_i - 1] = do_func(0,
+						val[val_i - 1], j & 0x7f);
+				debug("un:%d,%x,%d,%d\n", val[val_i - 1], j,
+						op_i, val_i);
+			}
+			continue;
+		}
+		if (i < 0) {
+			c = 0;
+			i = 8;
+		} else {
+			p++;
+		}
+		if (c == '(') {
+			if (op_i >= ARRAY_SIZE(op))
+				return -1;
+			op[op_i++] = i;
+			debug("op[%d]=%x,%d,%d\n", op_i - 1, op[op_i - 1],
+					op_i, val_i);
+			unary = 1;
+			continue;
+		}
+		for (;;) {
+			if (!op_i || unary)
+				break;
+			j = op[op_i - 1];
+			if (j == 0) {
+				if (c == ')') {
+					op_i--;
+					goto do_unary;
+				}
+				break;
+			}
+			if ((j & 0x80)) {
+				op_i--;
+				val[val_i - 1] = do_func(0,
+						val[val_i - 1], j & 0x7f);
+				debug("unary:%d,%x\n", val[val_i - 1], j);
+				continue;
+			}
+			if (precedence[i] < precedence[j])
+				break;
+			if (val_i < 2)
+				return -1;
+			op_i--;
+			val[val_i - 2] = do_func(val[val_i - 2],
+					val[val_i - 1], j);
+			val_i--;
+			debug("binary:%d,%x,%d,%d\n", val[val_i - 1], j,
+					op_i, val_i);
+		}
+		if (c == ')') {
+			fprintf(stderr, "Error: unmatched parenthesis\n");
+			return -1;
+		}
+		if (i == 8) {
+			if ((op_i != 0) || (val_i != 1)) {
+				fprintf(stderr, "Error: syntax %d %d\n",
+						op_i, val_i);
+				return -1;
+			}
+			ds->p = p;

tools/imximage.c char *grab_token(char *dest, int size, char *src) · line 549

Quoted 10 lines
tools/imximage.c +9 -0
+			*pval = val[0];
+			return 0;
+		}
+		if (op_i >= ARRAY_SIZE(op))
+			return -1;
+		op[op_i++] = i | (unary << 7);
+		debug("op[%d]=%x,%d,%d\n", op_i - 1, op[op_i - 1], op_i, val_i);
+		unary = 1;
+	}
 }

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#29 lore raw

PATCH v2 5/21 imximage: add expression evaluation

Quoted 12 lines · Stefano Babic
Quoted 6 lines · Troy Kisky

Basic expressions with order precedence is
now supported.
ie. (----3 + ((1+2*3)/--2 + --5 *(8/4))) is 16.

---

Hi Troy,

Quoted 3 lines
  tools/imximage.c |  172 ++++++++++++++++++++++++++++++++++++++++++++++++++----
  1 file changed, 162 insertions(+), 10 deletions(-)
Quoted 6 lines

tools/imximage.c

Quoted 2 lines
tools/imximage.c +0 -0
index 1e120354..2c5a622 100644

I have some general considerations. First, if you plan to add support for expression evaluation, this feature should be available generally for mkimage, that means also other processors / architecture can profit of it. It should be moved away from imximage.c code.

That makes sense.

Quoted 8 lines

Then, you want also let that the preprocesso can parse the imximage code. I can imagine that in such terms it could be then possible to define in imximage.cfg something like:

#define DDR_VAL (1 <<17 | 3 << 7)
#define ADDRESS 0x0x53something

Quoted 10 lines

DATA 4 ADDRESS DDR_VAL

Else, why do we need the power of C preprocessor ?

If this is true, can you explain us which is the use case using the C preprocessor and which is the one for the expression evaluator ? And why do we need both ?

I want to easily switch from plugins back to the normal DCD list method. #ifdef 's and and #define's make this possible.

Plus the cfg file is more readable with #define's.

But if plugins are rejected, expressions aren't as important. I can still see a cfg file doing

DATA 4, MMDC_P0 + MMDC_MPZQHWCTRL, 0xA1380003
DATA 4, MMDC_P1 + MMDC_MPZQHWCTRL, 0xA1380003

patch 09/21 mx6q_4x_mt41j128.cfg: use symbols instead of hardcoded constants

has

+#define MA(mx6q, mx6dl_solo, mx6sololite) ((mx6q / 4 & 0x3ff) | \
+ ((mx6dl_solo / 4 & 0x3ff) * 0x400) | \
+ ((mx6sololite / 4 & 0x3ff) * 0x100000))
+
+#define IOM_DRAM_DQM0 MA(0x5ac, 0x470, 0x0)

+#define IOMUX_ADDR(addr, div) (IOMUXC_BASE_ADDR + \
+ ((((addr) / (div)) & 0x3ff) * 4))
+#define IOMUX_ENTRY1(addr, q) DATA 4, IOMUX_ADDR(addr, _FOR_DIV), q
+#define WRITE_ENTRY1(addr, q) DATA 4, addr, q
+#ifdef FOR_MX6Q
+#define _FOR_DIV 1
+#define IOMUX_ENTRY2(addr, q, dl) IOMUX_ENTRY1(addr, q)
+#define WRITE_ENTRY2(addr, q, dl) WRITE_ENTRY1(addr, q)

to choose which offset for IOM_DRAM_DQM0 should be selected.

author
#30 lore raw

PATCH v2 6/21 imximage: add plugin commands

In reply to Troy Kisky

Add commands
plugin address filename
iomux_entry addr, data1 [, data2, [, data3]]
write_entry addr, data1 [, data2, [, data3]]

---
 tools/imximage.c |  334 ++++++++++++++++++++++++++++++++++++++++++++----------
 tools/imximage.h |   11 +-
 2 files changed, 283 insertions(+), 62 deletions(-)
tools/imximage.c +276 -58
index 2c5a622..fae786a 100644
@@ -31,7 +31,6 @@
 #include "mkimage.h"
 #include <image.h>
 #include "imximage.h"
-
 /*
  * Supported commands for configuration file
  */
@@ -39,6 +38,9 @@ static table_entry_t imximage_cmds[] = {
 	{CMD_BOOT_FROM,         "BOOT_FROM",            "boot command",	  },
 	{CMD_DATA,              "DATA",                 "Reg Write Data", },
 	{CMD_IMAGE_VERSION,     "IMAGE_VERSION",        "image version",  },
+	{CMD_PLUGIN,		"plugin",		"plugin addr,file",  },
+	{CMD_IOMUX_ENTRY,	"iomux_entry",		"Write iomux reg",  },
+	{CMD_WRITE_ENTRY,	"write_entry",		"Write register",  },
 	{-1,                    "",                     "",	          },
 };
 
@@ -69,8 +71,8 @@ static uint32_t imximage_version;
 
 static set_dcd_val_t set_dcd_val;
 static set_imx_hdr_t set_imx_hdr;
-static set_imx_size_t set_imx_size;
 static uint32_t *p_max_dcd;
+static uint32_t *header_size_ptr;
 static uint32_t g_flash_offset;
 
 static struct image_type_params imximage_params;
@@ -88,8 +90,7 @@ static uint32_t detect_imximage_version(struct imx_header *imx_hdr)
 		return IMXIMAGE_V1;
 
 	/* Try to detect V2 */
-	if ((fhdr_v2->header.tag == IVT_HEADER_TAG) &&
-		(hdr_v2->dcd_table.header.tag == DCD_HEADER_TAG))
+	if ((fhdr_v2->header.tag == IVT_HEADER_TAG))
 		return IMXIMAGE_V2;
 
 	return IMXIMAGE_VER_INVALID;
@@ -160,7 +161,7 @@ static int set_dcd_val_v2(struct imx_header *imxhdr, uint32_t *data)
 }
 
 static int set_imx_hdr_v1(struct imx_header *imxhdr,
-		uint32_t entry_point, uint32_t flash_offset)
+		uint32_t entry_point, uint32_t flash_offset, int plugin)
 {
 	imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;
 	flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
@@ -180,22 +181,12 @@ static int set_imx_hdr_v1(struct imx_header *imxhdr,
 	/* Security feature are not supported */
 	fhdr_v1->app_code_csf = 0;
 	fhdr_v1->super_root_key = 0;
+	header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4);
 	return header_length;
 }
 
-static void set_imx_size_v1(struct imx_header *imxhdr, uint32_t file_size,
-		uint32_t flash_offset)
-{
-	uint32_t *p = (uint32_t *)(((char *)imxhdr)
-			+ imximage_params.header_size);
-
-	/* The external flash header must be at the end of the DCD table */
-	/* file_size includes header */
-	p[-1] = file_size + flash_offset;
-}
-
 static int set_imx_hdr_v2(struct imx_header *imxhdr,
-		uint32_t entry_point, uint32_t flash_offset)
+		uint32_t entry_point, uint32_t flash_offset, int plugin)
 {
 	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
 	flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
@@ -216,27 +207,20 @@ static int set_imx_hdr_v2(struct imx_header *imxhdr,
 	fhdr_v2->boot_data_ptr = hdr_base
 			+ offsetof(imx_header_v2_t, boot_data);
 	hdr_v2->boot_data.start = hdr_base - flash_offset;
+	hdr_v2->boot_data.plugin = plugin;
 
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
+	header_size_ptr = &hdr_v2->boot_data.size;
 	return header_length;
 }
 
-static void set_imx_size_v2(struct imx_header *imxhdr, uint32_t file_size,
-		uint32_t flash_offset)
-{
-	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
-	/* file_size includes header */
-	hdr_v2->boot_data.size = file_size + flash_offset;
-}
-
 static void set_hdr_func(struct imx_header *imxhdr)
 {
 	switch (imximage_version) {
 	case IMXIMAGE_V1:
 		set_dcd_val = set_dcd_val_v1;
 		set_imx_hdr = set_imx_hdr_v1;
-		set_imx_size = set_imx_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;
@@ -245,7 +229,6 @@ static void set_hdr_func(struct imx_header *imxhdr)
 	case IMXIMAGE_V2:
 		set_dcd_val = set_dcd_val_v2;
 		set_imx_hdr = set_imx_hdr_v2;
-		set_imx_size = set_imx_size_v2;
 		p_entry = (uint32_t *)&imxhdr->header.hdr_v2.dcd_table;
 		p_max_dcd = (uint32_t *)((char *)imxhdr + MAX_HEADER_SIZE);
 		break;
@@ -283,31 +266,49 @@ static void print_hdr_v1(struct imx_header *imx_hdr)
 	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v1->app_code_jump_vector);
 }
 
-static void print_hdr_v2(struct imx_header *imx_hdr)
+static void print_header_info2(struct imx_header *imx_hdr)
 {
 	imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2;
 	flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
+
+	printf("Data Size:    ");
+	genimg_print_size(hdr_v2->boot_data.size);
+	printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr);
+	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v2->entry);
+}
+
+static void print_hdr_v2(struct imx_header *imxhdr)
+{
+	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
 	dcd_v2_t *dcd_v2 = &hdr_v2->dcd_table;
 	uint32_t size, version;
 
-	size = be16_to_cpu(dcd_v2->header.length) - 8;
-	if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t))) {
-		fprintf(stderr,
-			"Error: Image corrupt DCD size %d exceed maximum %d\n",
-			(uint32_t)(size / sizeof(dcd_addr_data_t)),
-			MAX_HW_CFG_SIZE_V2);
-		exit(EXIT_FAILURE);
+	if (hdr_v2->fhdr.dcd_ptr) {
+		size = be16_to_cpu(dcd_v2->header.length) - 8;
+		if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t))) {
+			fprintf(stderr,	"Error: Image corrupt DCD size "
+				"%d exceed maximum %d\n",
+				(uint32_t)(size / sizeof(dcd_addr_data_t)),
+				MAX_HW_CFG_SIZE_V2);
+			exit(EXIT_FAILURE);
+		}
 	}
-
-	version = detect_imximage_version(imx_hdr);
+	version = detect_imximage_version(imxhdr);
 
 	printf("Image Type:   Freescale IMX Boot Image\n");
 	printf("Image Ver:    %x", version);
 	printf("%s\n", get_table_entry_name(imximage_versions, NULL, version));
-	printf("Data Size:    ");
-	genimg_print_size(hdr_v2->boot_data.size);
-	printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr);
-	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v2->entry);
+	print_header_info2(imxhdr);
+	if (hdr_v2->boot_data.plugin) {
+		uint32_t flash_offset =
+				hdr_v2->fhdr.self - hdr_v2->boot_data.start;
+		/* The 1st size includes flash offset and the next header */
+		uint32_t plugin_length = hdr_v2->boot_data.size - flash_offset
+				- offsetof(imx_header_v2_t, dcd_table);
+
+		imxhdr = (struct imx_header *)((char *)imxhdr + plugin_length);
+		print_header_info2(imxhdr);
+	}
 }
 
 static int cmd_cnt;
@@ -363,6 +364,24 @@ int skip_separators(struct data_src *ds)
 	}
 }
 
+int skip_comma(struct data_src *ds)
+{
+	char *p = ds->p;
+
+	for (;;) {
+		char c = *p++;
+		if ((c == '#') || (c == '\r') || (c == '\n') || !c)
+			return 0;
+		if (c == ',') {
+			ds->p = p;
+			skip_separators(ds);
+			return 1;
+		}
+		if ((c != ' ') && (c == '\t'))
+			return 0;
+	}
+}
+
 char *grab_token(char *dest, int size, char *src)
 {
 	while (size) {
@@ -551,16 +570,18 @@ do_unary:
 static int parse_cmd_data(struct data_src *ds)
 {
 	uint32_t data[3];
-	int ret = get_cfg_value(ds, &data[0]);
+	int ret, i;
 
-	if (ret)
-		return ret;
-	ret = get_cfg_value(ds, &data[1]);
-	if (ret)
-		return ret;
-	ret = get_cfg_value(ds, &data[2]);
-	if (ret)
-		return ret;
+	if (ds->plugin) {
+		fprintf(stderr, "DATA should be before plug command\n");
+		return -1;
+	}
+	for (i = 0; i < 3; i++) {
+		int ret = get_cfg_value(ds, &data[i]);
+		if (ret)
+			return ret;
+		skip_comma(ds);		/* comma is optional */
+	}
 	ret = (*set_dcd_val)(ds->imxhdr, data);
 	if (ret)
 		return ret;
@@ -573,6 +594,99 @@ static int parse_cmd_data(struct data_src *ds)
 	return 0;
 }
 
+static int get_data(struct data_src *ds, uint32_t *data, int cnt)
+{
+	int i = 0;
+
+	if (!ds->plugin) {
+		fprintf(stderr, "missing plug command\n");
+		return -1;
+	}
+	for (;;) {
+		int ret = get_cfg_value(ds, &data[i++]);
+		if (ret)
+			return ret;
+		if (i >= cnt)
+			break;
+		if (!skip_comma(ds))
+			break;
+	}
+	if (i < 2) {
+		fprintf(stderr, "missing ','\n");
+		return -1;
+	}
+	while (i < cnt) {
+		data[i] = data[i - 1];
+		i++;
+	}
+	if ((data[1] == ds->prev[1]) && (data[2] == ds->prev[2])
+			&& (data[3] == ds->prev[3])
+			&& (data[4] == ds->prev[4]))
+		i = 0;
+	else if ((data[1] == data[2]) && (data[2] == data[3])
+			&& (data[3] == data[4]))
+		i = 1;
+	else if ((data[2] == data[3]) && (data[3] == data[4]))
+		i = 2;
+	else
+		i = 3;
+	return i;
+}
+
+static int store_data(struct data_src *ds, uint32_t *data, int cnt)
+{
+	int i;
+
+	for (i = 0; i < cnt; i++)
+		*p_entry++ = data[i];
+
+	ds->prev[1] = data[1];
+	ds->prev[2] = data[2];
+	ds->prev[3] = data[3];
+	ds->prev[4] = data[4];
+	if (p_entry > p_max_dcd) {
+		uint32_t size = (char *)p_max_dcd - (char *)ds->imxhdr;
+		fprintf(stderr, "Error: header exceeds maximum size(%d)\n",
+				size);
+		return -1;
+	}
+	return 0;
+}
+
+static int parse_iomux_entry(struct data_src *ds)
+{
+	uint32_t data[5];
+	int i;
+
+	i = get_data(ds, data, 5);
+	if (i < 0)
+		return i;
+	if (data[0] & (3 << 30)) {
+		fprintf(stderr, "bad 1st value\n");
+		return -1;
+	}
+	if (i < 3)
+		i++;
+	data[0] |= (i << 30);
+	return store_data(ds, data, (i == 3) ? 5 : i);
+}
+
+static int parse_write_entry(struct data_src *ds)
+{
+	uint32_t data[5];
+	int i;
+
+	i = get_data(ds, data, 5);
+	if (i < 0)
+		return i;
+	if (data[0] & 3) {
+		fprintf(stderr, "Address must be aligned on word boundary\n");
+		return -1;
+	}
+	data[0] |= i;
+	return store_data(ds, data, (i == 3) ? 5 : (i + 1));
+}
+
 static int parse_image_version(struct data_src *ds)
 {
 	int ret;
@@ -618,8 +732,82 @@ static int parse_boot_from(struct data_src *ds)
 	return 0;
 }
 
+static int parse_plugin(struct data_src *ds)
+{
+	struct stat sbuf;
+	int plug_file;
+	unsigned char *ptr;
+	char *p;
+	char c;
+	int ret;
+	uint32_t plug_base;
+	uint32_t header_length;
+
+	if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {
+		fprintf(stderr, "Error: Place BOOT_FROM before plugin\n");
+		return -1;
+	}
+	ret = get_cfg_value(ds, &plug_base);
+	if (ret)
+		return ret;
+
+	if (skip_separators(ds))
+		return -1;
+	p = ds->p;
+	for (;;) {
+		c = *p;
+		if (!c)
+			break;
+		if ((c == ' ') || (c == '\t') || (c == ';') || (c == '#')
+				|| (c == '\r') || (c == '\n')) {
+			*p = 0;
+			break;
+		}
+		p++;
+	}
+	plug_file = open(ds->p, O_RDONLY|O_BINARY);
+	if (plug_file < 0) {
+		fprintf(stderr, "Can't open plugin file %s: %s\n",
+				ds->p, strerror(errno));
+		*p = c;
+		return -1;
+	}
+	if (fstat(plug_file, &sbuf) < 0) {
+		fprintf(stderr, "Can't stat %s: %s\n",
+			ds->p, strerror(errno));
+		close(plug_file);
+		return -1;
+	}
+	ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, plug_file, 0);
+	if (ptr == MAP_FAILED) {
+		fprintf(stderr, "Can't read %s: %s\n",
+			ds->p, strerror(errno));
+		return -1;
+	}
+	*p = c;
+	ds->p = p;
+	/* Set the plugin header */
+	header_length = (*set_imx_hdr)(ds->imxhdr, plug_base,
+			g_flash_offset, 1);
+
+	p = ((char *)ds->imxhdr) + header_length;
+	if ((p + sbuf.st_size) >= (char *)p_max_dcd) {
+		fprintf(stderr, "Out of space\n");
+		return -1;
+	}
+
+	ds->plugin = 1;
+	memcpy(p, ptr, sbuf.st_size);
+	munmap((void *)ptr, sbuf.st_size);
+	close(plug_file);
+
+	p_entry = (uint32_t *)(p + sbuf.st_size);
+	return 0;
+}
+
 parse_fld_t cmd_table[] = {
-	parse_image_version, parse_boot_from, parse_cmd_data
+	parse_image_version, parse_boot_from, parse_cmd_data, parse_plugin,
+	parse_iomux_entry, parse_write_entry
 };
 
 static int parse_command(struct data_src *ds)
@@ -630,9 +818,11 @@ static int parse_command(struct data_src *ds)
 	return cmd_table[cmd](ds);
 }
 
-static void parse_cfg_file(struct imx_header *imxhdr, char *name)
+static void parse_cfg_file(struct imx_header *imxhdr, char *name,
+		uint32_t entry_point)
 {
 	struct data_src ds;
+	uint32_t plugin_length = 0;
 
 	ds.line = NULL;
 	ds.len = 0;
@@ -662,6 +852,35 @@ static void parse_cfg_file(struct imx_header *imxhdr, char *name)
 		cmd_cnt++;
 	}
 	fclose(ds.fd);
+
+	if (ds.plugin) {
+		uint32_t header_length, more;
+		struct imx_header *next_imxhdr;
+
+		*p_entry++ = 0;
+		header_length = ((char *)p_entry) - ((char *)imxhdr);
+		plugin_length = ((header_length - 1) | 0x3f) + 1;
+		more = plugin_length - header_length;
+		if (more)
+			memset(p_entry, 0, more);
+		next_imxhdr = (struct imx_header *)
+				(((char *)imxhdr) + plugin_length);
+		p_entry = (imximage_version == IMXIMAGE_V1) ? (uint32_t *)
+			&next_imxhdr->header.hdr_v1.dcd_table.addr_data[0].type
+			: (uint32_t *)&next_imxhdr->header.hdr_v2.dcd_table;
+		if (p_entry > p_max_dcd) {
+			fprintf(stderr, "Out of space\n");
+			exit(EXIT_FAILURE);
+		}
+
+		/* Set the plugin size in header to include next header */
+		*header_size_ptr = ((char *)p_entry) - ((char *)imxhdr)
+				+ g_flash_offset;
+		imxhdr = next_imxhdr;
+	}
+	/* Set the imx header */
+	imximage_params.header_size = (*set_imx_hdr)(imxhdr, entry_point,
+			g_flash_offset + plugin_length, 0) + plugin_length;
 	return;
 }
 
@@ -727,7 +946,7 @@ int imximage_vrec_header(struct mkimage_params *params,
 	set_hdr_func(imxhdr);
 
 	/* Parse dcd configuration file */
-	parse_cfg_file(imxhdr, params->imagename);
+	parse_cfg_file(imxhdr, params->imagename, params->ep);
 
 	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
 	if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {
@@ -735,9 +954,6 @@ int imximage_vrec_header(struct mkimage_params *params,
 				params->imagename);
 		exit(EXIT_FAILURE);
 	}
-	/* Set the imx header */
-	imximage_params.header_size = (*set_imx_hdr)(imxhdr, params->ep,
-			g_flash_offset);
 	imximage_params.hdr = imxhdr;
 	return 0;
 }
@@ -746,8 +962,10 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 				struct mkimage_params *params)
 {
 	/* Set the size in header */
-	(*set_imx_size)((struct imx_header *)ptr, sbuf->st_size,
-			g_flash_offset);
+	uint32_t offset = (char *)header_size_ptr - (char *)imximage_params.hdr;
+	uint32_t *p = (uint32_t *)((char *)ptr + offset);
+
+	*p = sbuf->st_size + g_flash_offset;
 }
 
 int imximage_check_params(struct mkimage_params *params)
tools/imximage.h +7 -4
index efd249b..7613386 100644
@@ -51,7 +51,10 @@
 enum imximage_cmd {
 	CMD_IMAGE_VERSION,
 	CMD_BOOT_FROM,
-	CMD_DATA
+	CMD_DATA,
+	CMD_PLUGIN,
+	CMD_IOMUX_ENTRY,
+	CMD_WRITE_ENTRY,
 };
 
 enum imximage_version {
@@ -158,6 +161,8 @@ struct data_src {
 	char *filename;
 	struct imx_header *imxhdr;
 	char *p;
+	int plugin;
+	uint32_t prev[5];
 };
 
 typedef int (*parse_fld_t)(struct data_src *ds);
@@ -165,8 +170,6 @@ typedef int (*parse_fld_t)(struct data_src *ds);
 typedef int (*set_dcd_val_t)(struct imx_header *imxhdr, uint32_t *data);
 
 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);
+		uint32_t flash_offset, int plugin);
 
 #endif /* _IMXIMAGE_H_ */
Signature · 1 line
1.7.9.5
#31 lore raw

PATCH v2 6/21 imximage: add plugin commands

Quoted 4 lines · Troy Kisky

Add commands
plugin address filename
iomux_entry addr, data1 [, data2, [, data3]]
write_entry addr, data1 [, data2, [, data3]]

Why do we need explicitely an IOMUX command ? As far as I can see, the program image defined in V2 defines a plugin, but not an iomux. I am expecting that the imximage generates a iMX header only, without moving some code from the initialization code directly here. In the manula there is a "Write Data" (what we have always had), a "Check data" and an "Unlock" commands.

If we start to add special commands, maybe we are staring again to reimplement U-Boot. We could have some SET_CLK, SET_CPU_FREQ, and so on. What I am really mising in this series is why you are moving a lot of things from U-Boot into the iMX header.

It seems to me we want to put much more code in the iMX header as what it is really required to boot the device.

Adding / modifying the syntax requires to update doc/README.imximage, too.

Quoted 40 lines
---
 tools/imximage.c |  334 ++++++++++++++++++++++++++++++++++++++++++++----------
 tools/imximage.h |   11 +-
 2 files changed, 283 insertions(+), 62 deletions(-)
tools/imximage.c +4 -2
index 2c5a622..fae786a 100644
@@ -31,7 +31,6 @@
 #include "mkimage.h"
 #include <image.h>
 #include "imximage.h"
-
 /*
  * Supported commands for configuration file
  */
@@ -39,6 +38,9 @@ static table_entry_t imximage_cmds[] = {
 	{CMD_BOOT_FROM,         "BOOT_FROM",            "boot command",	  },
 	{CMD_DATA,              "DATA",                 "Reg Write Data", },
 	{CMD_IMAGE_VERSION,     "IMAGE_VERSION",        "image version",  },
+	{CMD_PLUGIN,		"plugin",		"plugin addr,file",  },
+	{CMD_IOMUX_ENTRY,	"iomux_entry",		"Write iomux reg",  },
+	{CMD_WRITE_ENTRY,	"write_entry",		"Write register",  },
 	{-1,                    "",                     "",	          },
 };
 
@@ -69,8 +71,8 @@ static uint32_t imximage_version;
 
 static set_dcd_val_t set_dcd_val;
 static set_imx_hdr_t set_imx_hdr;
-static set_imx_size_t set_imx_size;
 static uint32_t *p_max_dcd;
+static uint32_t *header_size_ptr;
 static uint32_t g_flash_offset;
 
 static struct image_type_params imximage_params;

tools/imximage.c static uint32_t detect_imximage_version(struct imx_header *imx_hdr) · line 94

Quoted 7 lines
tools/imximage.c +1 -2
@@ -88,8 +90,7 @@ static uint32_t detect_imximage_version(struct imx_header *imx_hdr)
 		return IMXIMAGE_V1;
 
 	/* Try to detect V2 */
-	if ((fhdr_v2->header.tag == IVT_HEADER_TAG) &&
-		(hdr_v2->dcd_table.header.tag == DCD_HEADER_TAG))
+	if ((fhdr_v2->header.tag == IVT_HEADER_TAG))
 		return IMXIMAGE_V2;

Help me to understand. I am reading i.MX6 manual and, even if the number of DCD entries could be variable, I do not see why the header tag of DCD is moving. At least, this is what I can see on picture 7-19, Image Vector table.

Quoted 19 lines
tools/imximage.c +2 -1
 	return IMXIMAGE_VER_INVALID;
@@ -160,7 +161,7 @@ static int set_dcd_val_v2(struct imx_header *imxhdr, uint32_t *data)
 }
 
 static int set_imx_hdr_v1(struct imx_header *imxhdr,
-		uint32_t entry_point, uint32_t flash_offset)
+		uint32_t entry_point, uint32_t flash_offset, int plugin)
 {
 	imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;
 	flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
@@ -180,22 +181,12 @@ static int set_imx_hdr_v1(struct imx_header *imxhdr,
 	/* Security feature are not supported */
 	fhdr_v1->app_code_csf = 0;
 	fhdr_v1->super_root_key = 0;
+	header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4);
 	return header_length;
 }
 

tools/imximage.c static int set_imx_hdr_v1(struct imx_header *imxhdr, · line 195

Quoted 10 lines
tools/imximage.c +0 -10
-static void set_imx_size_v1(struct imx_header *imxhdr, uint32_t file_size,
-		uint32_t flash_offset)
-{
-	uint32_t *p = (uint32_t *)(((char *)imxhdr)
-			+ imximage_params.header_size);
-
-	/* The external flash header must be at the end of the DCD table */
-	/* file_size includes header */
-	p[-1] = file_size + flash_offset;
-}

I think you have to squash some of your patches or to defines them in another way. You added this code previously, and you drop now. This makes more difficult to review your patches.

Quoted 405 lines
tools/imximage.c +265 -38
-
 static int set_imx_hdr_v2(struct imx_header *imxhdr,
-		uint32_t entry_point, uint32_t flash_offset)
+		uint32_t entry_point, uint32_t flash_offset, int plugin)
 {
 	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
 	flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
@@ -216,27 +207,20 @@ static int set_imx_hdr_v2(struct imx_header *imxhdr,
 	fhdr_v2->boot_data_ptr = hdr_base
 			+ offsetof(imx_header_v2_t, boot_data);
 	hdr_v2->boot_data.start = hdr_base - flash_offset;
+	hdr_v2->boot_data.plugin = plugin;
 
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
+	header_size_ptr = &hdr_v2->boot_data.size;
 	return header_length;
 }
 
-static void set_imx_size_v2(struct imx_header *imxhdr, uint32_t file_size,
-		uint32_t flash_offset)
-{
-	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
-	/* file_size includes header */
-	hdr_v2->boot_data.size = file_size + flash_offset;
-}
-
 static void set_hdr_func(struct imx_header *imxhdr)
 {
 	switch (imximage_version) {
 	case IMXIMAGE_V1:
 		set_dcd_val = set_dcd_val_v1;
 		set_imx_hdr = set_imx_hdr_v1;
-		set_imx_size = set_imx_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;
@@ -245,7 +229,6 @@ static void set_hdr_func(struct imx_header *imxhdr)
 	case IMXIMAGE_V2:
 		set_dcd_val = set_dcd_val_v2;
 		set_imx_hdr = set_imx_hdr_v2;
-		set_imx_size = set_imx_size_v2;
 		p_entry = (uint32_t *)&imxhdr->header.hdr_v2.dcd_table;
 		p_max_dcd = (uint32_t *)((char *)imxhdr + MAX_HEADER_SIZE);
 		break;
@@ -283,31 +266,49 @@ static void print_hdr_v1(struct imx_header *imx_hdr)
 	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v1->app_code_jump_vector);
 }
 
-static void print_hdr_v2(struct imx_header *imx_hdr)
+static void print_header_info2(struct imx_header *imx_hdr)
 {
 	imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2;
 	flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
+
+	printf("Data Size:    ");
+	genimg_print_size(hdr_v2->boot_data.size);
+	printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr);
+	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v2->entry);
+}
+
+static void print_hdr_v2(struct imx_header *imxhdr)
+{
+	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
 	dcd_v2_t *dcd_v2 = &hdr_v2->dcd_table;
 	uint32_t size, version;
 
-	size = be16_to_cpu(dcd_v2->header.length) - 8;
-	if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t))) {
-		fprintf(stderr,
-			"Error: Image corrupt DCD size %d exceed maximum %d\n",
-			(uint32_t)(size / sizeof(dcd_addr_data_t)),
-			MAX_HW_CFG_SIZE_V2);
-		exit(EXIT_FAILURE);
+	if (hdr_v2->fhdr.dcd_ptr) {
+		size = be16_to_cpu(dcd_v2->header.length) - 8;
+		if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t))) {
+			fprintf(stderr,	"Error: Image corrupt DCD size "
+				"%d exceed maximum %d\n",
+				(uint32_t)(size / sizeof(dcd_addr_data_t)),
+				MAX_HW_CFG_SIZE_V2);
+			exit(EXIT_FAILURE);
+		}
 	}
-
-	version = detect_imximage_version(imx_hdr);
+	version = detect_imximage_version(imxhdr);
 
 	printf("Image Type:   Freescale IMX Boot Image\n");
 	printf("Image Ver:    %x", version);
 	printf("%s\n", get_table_entry_name(imximage_versions, NULL, version));
-	printf("Data Size:    ");
-	genimg_print_size(hdr_v2->boot_data.size);
-	printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr);
-	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v2->entry);
+	print_header_info2(imxhdr);
+	if (hdr_v2->boot_data.plugin) {
+		uint32_t flash_offset =
+				hdr_v2->fhdr.self - hdr_v2->boot_data.start;
+		/* The 1st size includes flash offset and the next header */
+		uint32_t plugin_length = hdr_v2->boot_data.size - flash_offset
+				- offsetof(imx_header_v2_t, dcd_table);
+
+		imxhdr = (struct imx_header *)((char *)imxhdr + plugin_length);
+		print_header_info2(imxhdr);
+	}
 }
 
 static int cmd_cnt;
@@ -363,6 +364,24 @@ int skip_separators(struct data_src *ds)
 	}
 }
 
+int skip_comma(struct data_src *ds)
+{
+	char *p = ds->p;
+
+	for (;;) {
+		char c = *p++;
+		if ((c == '#') || (c == '\r') || (c == '\n') || !c)
+			return 0;
+		if (c == ',') {
+			ds->p = p;
+			skip_separators(ds);
+			return 1;
+		}
+		if ((c != ' ') && (c == '\t'))
+			return 0;
+	}
+}
+
 char *grab_token(char *dest, int size, char *src)
 {
 	while (size) {
@@ -551,16 +570,18 @@ do_unary:
 static int parse_cmd_data(struct data_src *ds)
 {
 	uint32_t data[3];
-	int ret = get_cfg_value(ds, &data[0]);
+	int ret, i;
 
-	if (ret)
-		return ret;
-	ret = get_cfg_value(ds, &data[1]);
-	if (ret)
-		return ret;
-	ret = get_cfg_value(ds, &data[2]);
-	if (ret)
-		return ret;
+	if (ds->plugin) {
+		fprintf(stderr, "DATA should be before plug command\n");
+		return -1;
+	}
+	for (i = 0; i < 3; i++) {
+		int ret = get_cfg_value(ds, &data[i]);
+		if (ret)
+			return ret;
+		skip_comma(ds);		/* comma is optional */
+	}
 	ret = (*set_dcd_val)(ds->imxhdr, data);
 	if (ret)
 		return ret;
@@ -573,6 +594,99 @@ static int parse_cmd_data(struct data_src *ds)
 	return 0;
 }
 
+static int get_data(struct data_src *ds, uint32_t *data, int cnt)
+{
+	int i = 0;
+
+	if (!ds->plugin) {
+		fprintf(stderr, "missing plug command\n");
+		return -1;
+	}
+	for (;;) {
+		int ret = get_cfg_value(ds, &data[i++]);
+		if (ret)
+			return ret;
+		if (i >= cnt)
+			break;
+		if (!skip_comma(ds))
+			break;
+	}
+	if (i < 2) {
+		fprintf(stderr, "missing ','\n");
+		return -1;
+	}
+	while (i < cnt) {
+		data[i] = data[i - 1];
+		i++;
+	}
+	if ((data[1] == ds->prev[1]) && (data[2] == ds->prev[2])
+			&& (data[3] == ds->prev[3])
+			&& (data[4] == ds->prev[4]))
+		i = 0;
+	else if ((data[1] == data[2]) && (data[2] == data[3])
+			&& (data[3] == data[4]))
+		i = 1;
+	else if ((data[2] == data[3]) && (data[3] == data[4]))
+		i = 2;
+	else
+		i = 3;
+	return i;
+}
+
+static int store_data(struct data_src *ds, uint32_t *data, int cnt)
+{
+	int i;
+
+	for (i = 0; i < cnt; i++)
+		*p_entry++ = data[i];
+
+	ds->prev[1] = data[1];
+	ds->prev[2] = data[2];
+	ds->prev[3] = data[3];
+	ds->prev[4] = data[4];
+	if (p_entry > p_max_dcd) {
+		uint32_t size = (char *)p_max_dcd - (char *)ds->imxhdr;
+		fprintf(stderr, "Error: header exceeds maximum size(%d)\n",
+				size);
+		return -1;
+	}
+	return 0;
+}
+
+static int parse_iomux_entry(struct data_src *ds)
+{
+	uint32_t data[5];
+	int i;
+
+	i = get_data(ds, data, 5);
+	if (i < 0)
+		return i;
+	if (data[0] & (3 << 30)) {
+		fprintf(stderr, "bad 1st value\n");
+		return -1;
+	}
+	if (i < 3)
+		i++;
+	data[0] |= (i << 30);
+	return store_data(ds, data, (i == 3) ? 5 : i);
+}
+
+static int parse_write_entry(struct data_src *ds)
+{
+	uint32_t data[5];
+	int i;
+
+	i = get_data(ds, data, 5);
+	if (i < 0)
+		return i;
+	if (data[0] & 3) {
+		fprintf(stderr, "Address must be aligned on word boundary\n");
+		return -1;
+	}
+	data[0] |= i;
+	return store_data(ds, data, (i == 3) ? 5 : (i + 1));
+}
+
 static int parse_image_version(struct data_src *ds)
 {
 	int ret;
@@ -618,8 +732,82 @@ static int parse_boot_from(struct data_src *ds)
 	return 0;
 }
 
+static int parse_plugin(struct data_src *ds)
+{
+	struct stat sbuf;
+	int plug_file;
+	unsigned char *ptr;
+	char *p;
+	char c;
+	int ret;
+	uint32_t plug_base;
+	uint32_t header_length;
+
+	if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {
+		fprintf(stderr, "Error: Place BOOT_FROM before plugin\n");
+		return -1;
+	}
+	ret = get_cfg_value(ds, &plug_base);
+	if (ret)
+		return ret;
+
+	if (skip_separators(ds))
+		return -1;
+	p = ds->p;
+	for (;;) {
+		c = *p;
+		if (!c)
+			break;
+		if ((c == ' ') || (c == '\t') || (c == ';') || (c == '#')
+				|| (c == '\r') || (c == '\n')) {
+			*p = 0;
+			break;
+		}
+		p++;
+	}
+	plug_file = open(ds->p, O_RDONLY|O_BINARY);
+	if (plug_file < 0) {
+		fprintf(stderr, "Can't open plugin file %s: %s\n",
+				ds->p, strerror(errno));
+		*p = c;
+		return -1;
+	}
+	if (fstat(plug_file, &sbuf) < 0) {
+		fprintf(stderr, "Can't stat %s: %s\n",
+			ds->p, strerror(errno));
+		close(plug_file);
+		return -1;
+	}
+	ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, plug_file, 0);
+	if (ptr == MAP_FAILED) {
+		fprintf(stderr, "Can't read %s: %s\n",
+			ds->p, strerror(errno));
+		return -1;
+	}
+	*p = c;
+	ds->p = p;
+	/* Set the plugin header */
+	header_length = (*set_imx_hdr)(ds->imxhdr, plug_base,
+			g_flash_offset, 1);
+
+	p = ((char *)ds->imxhdr) + header_length;
+	if ((p + sbuf.st_size) >= (char *)p_max_dcd) {
+		fprintf(stderr, "Out of space\n");
+		return -1;
+	}
+
+	ds->plugin = 1;
+	memcpy(p, ptr, sbuf.st_size);
+	munmap((void *)ptr, sbuf.st_size);
+	close(plug_file);
+
+	p_entry = (uint32_t *)(p + sbuf.st_size);
+	return 0;
+}
+
 parse_fld_t cmd_table[] = {
-	parse_image_version, parse_boot_from, parse_cmd_data
+	parse_image_version, parse_boot_from, parse_cmd_data, parse_plugin,
+	parse_iomux_entry, parse_write_entry
 };
 
 static int parse_command(struct data_src *ds)
@@ -630,9 +818,11 @@ static int parse_command(struct data_src *ds)
 	return cmd_table[cmd](ds);
 }
 
-static void parse_cfg_file(struct imx_header *imxhdr, char *name)
+static void parse_cfg_file(struct imx_header *imxhdr, char *name,
+		uint32_t entry_point)
 {
 	struct data_src ds;
+	uint32_t plugin_length = 0;
 
 	ds.line = NULL;
 	ds.len = 0;
@@ -662,6 +852,35 @@ static void parse_cfg_file(struct imx_header *imxhdr, char *name)
 		cmd_cnt++;
 	}
 	fclose(ds.fd);
+
+	if (ds.plugin) {
+		uint32_t header_length, more;
+		struct imx_header *next_imxhdr;
+
+		*p_entry++ = 0;
+		header_length = ((char *)p_entry) - ((char *)imxhdr);
+		plugin_length = ((header_length - 1) | 0x3f) + 1;
+		more = plugin_length - header_length;
+		if (more)
+			memset(p_entry, 0, more);
+		next_imxhdr = (struct imx_header *)
+				(((char *)imxhdr) + plugin_length);
+		p_entry = (imximage_version == IMXIMAGE_V1) ? (uint32_t *)
+			&next_imxhdr->header.hdr_v1.dcd_table.addr_data[0].type
+			: (uint32_t *)&next_imxhdr->header.hdr_v2.dcd_table;
+		if (p_entry > p_max_dcd) {
+			fprintf(stderr, "Out of space\n");
+			exit(EXIT_FAILURE);
+		}
+
+		/* Set the plugin size in header to include next header */
+		*header_size_ptr = ((char *)p_entry) - ((char *)imxhdr)
+				+ g_flash_offset;
+		imxhdr = next_imxhdr;
+	}
+	/* Set the imx header */
+	imximage_params.header_size = (*set_imx_hdr)(imxhdr, entry_point,
+			g_flash_offset + plugin_length, 0) + plugin_length;
 	return;
 }
 
@@ -727,7 +946,7 @@ int imximage_vrec_header(struct mkimage_params *params,
 	set_hdr_func(imxhdr);
 
 	/* Parse dcd configuration file */
-	parse_cfg_file(imxhdr, params->imagename);
+	parse_cfg_file(imxhdr, params->imagename, params->ep);
 
 	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
 	if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {

tools/imximage.c int imximage_vrec_header(struct mkimage_params *params, · line 738

Quoted 4 lines
tools/imximage.c +0 -1
@@ -735,9 +954,6 @@ int imximage_vrec_header(struct mkimage_params *params,
 				params->imagename);
 		exit(EXIT_FAILURE);
 	}
-	/* Set the imx header */

---> - imximage_params.header_size = (*set_imx_hdr)(imxhdr, params->ep,

Quoted 44 lines
tools/imximage.c +4 -3
-			g_flash_offset);
 	imximage_params.hdr = imxhdr;
 	return 0;
 }
@@ -746,8 +962,10 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 				struct mkimage_params *params)
 {
 	/* Set the size in header */
-	(*set_imx_size)((struct imx_header *)ptr, sbuf->st_size,
-			g_flash_offset);
+	uint32_t offset = (char *)header_size_ptr - (char *)imximage_params.hdr;
+	uint32_t *p = (uint32_t *)((char *)ptr + offset);
+
+	*p = sbuf->st_size + g_flash_offset;
 }
 
 int imximage_check_params(struct mkimage_params *params)
tools/imximage.h +6 -1
index efd249b..7613386 100644
@@ -51,7 +51,10 @@
 enum imximage_cmd {
 	CMD_IMAGE_VERSION,
 	CMD_BOOT_FROM,
-	CMD_DATA
+	CMD_DATA,
+	CMD_PLUGIN,
+	CMD_IOMUX_ENTRY,
+	CMD_WRITE_ENTRY,
 };
 
 enum imximage_version {
@@ -158,6 +161,8 @@ struct data_src {
 	char *filename;
 	struct imx_header *imxhdr;
 	char *p;
+	int plugin;
+	uint32_t prev[5];
 };
 
 typedef int (*parse_fld_t)(struct data_src *ds);

tools/imximage.h typedef int (*parse_fld_t)(struct data_src *ds); · line 175

Quoted 9 lines
tools/imximage.h +1 -3
@@ -165,8 +170,6 @@ typedef int (*parse_fld_t)(struct data_src *ds);
 typedef int (*set_dcd_val_t)(struct imx_header *imxhdr, uint32_t *data);
 
 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);
+		uint32_t flash_offset, int plugin);
 
 #endif /* _IMXIMAGE_H_ */

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#32 lore raw

PATCH v2 6/21 imximage: add plugin commands

Quoted 11 lines · Stefano Babic
Quoted 4 lines · Troy Kisky

Add commands
plugin address filename
iomux_entry addr, data1 [, data2, [, data3]]
write_entry addr, data1 [, data2, [, data3]]

Why do we need explicitely an IOMUX command ? As far as I can see, the program image defined in V2 defines a plugin, but not an iomux. I am expecting that the imximage generates a iMX header only, without moving some code from the initialization code directly here. In the manula there is a "Write Data" (what we have always had), a "Check data" and an "Unlock" commands.

The table built by iomux_entry and write_entry are not used by the ROM. The plugin.S file that I add will interpret these entries.
I could have repurposed the "DATA" command if I didn't mind bloating the table.
Having separate commands made it easy to generate small tables.

Quoted 5 lines

If we start to add special commands, maybe we are staring again to reimplement U-Boot. We could have some SET_CLK, SET_CPU_FREQ, and so on. What I am really mising in this series is why you are moving a lot of things from U-Boot into the iMX header.

The cfg file after this patch series does no more setup/initialization than before
this series. I don't know what "moving" you are referring to.

Quoted 5 lines

It seems to me we want to put much more code in the iMX header as what it is really required to boot the device.

Adding / modifying the syntax requires to update doc/README.imximage, too.

Yes, if leaning toward acceptance I will add this.

Quoted 42 lines
Quoted 42 lines
---
  tools/imximage.c |  334 ++++++++++++++++++++++++++++++++++++++++++++----------
  tools/imximage.h |   11 +-
  2 files changed, 283 insertions(+), 62 deletions(-)
tools/imximage.c +4 -2
index 2c5a622..fae786a 100644
@@ -31,7 +31,6 @@
  #include "mkimage.h"
  #include <image.h>
  #include "imximage.h"
-
  /*
   * Supported commands for configuration file
   */
@@ -39,6 +38,9 @@ static table_entry_t imximage_cmds[] = {
  	{CMD_BOOT_FROM,         "BOOT_FROM",            "boot command",	  },
  	{CMD_DATA,              "DATA",                 "Reg Write Data", },
  	{CMD_IMAGE_VERSION,     "IMAGE_VERSION",        "image version",  },
+	{CMD_PLUGIN,		"plugin",		"plugin addr,file",  },
+	{CMD_IOMUX_ENTRY,	"iomux_entry",		"Write iomux reg",  },
+	{CMD_WRITE_ENTRY,	"write_entry",		"Write register",  },
  	{-1,                    "",                     "",	          },
  };
 
@@ -69,8 +71,8 @@ static uint32_t imximage_version;
 
  static set_dcd_val_t set_dcd_val;
  static set_imx_hdr_t set_imx_hdr;
-static set_imx_size_t set_imx_size;
  static uint32_t *p_max_dcd;
+static uint32_t *header_size_ptr;
  static uint32_t g_flash_offset;
 
  static struct image_type_params imximage_params;
@@ -88,8 +90,7 @@ static uint32_t detect_imximage_version(struct imx_header *imx_hdr)
  		return IMXIMAGE_V1;
 
Quoted 9 lines

tools/imximage.c static uint32_t detect_imximage_version(struct imx_header *imx_hdr) · line 94

Quoted 5 lines
tools/imximage.c +1 -2
  	/* Try to detect V2 */
-	if ((fhdr_v2->header.tag == IVT_HEADER_TAG) &&
-		(hdr_v2->dcd_table.header.tag == DCD_HEADER_TAG))
+	if ((fhdr_v2->header.tag == IVT_HEADER_TAG))
  		return IMXIMAGE_V2;

Help me to understand. I am reading i.MX6 manual and, even if the number of DCD entries could be variable, I do not see why the header tag of DCD is moving. At least, this is what I can see on picture 7-19, Image Vector table.

If the DCD table is missing, there is no DCD_HEADER_TAG. DCD table is not required, so there is no need to check for it.

Quoted 19 lines
Quoted 19 lines
tools/imximage.c +2 -1
  	return IMXIMAGE_VER_INVALID;
@@ -160,7 +161,7 @@ static int set_dcd_val_v2(struct imx_header *imxhdr, uint32_t *data)
  }
 
  static int set_imx_hdr_v1(struct imx_header *imxhdr,
-		uint32_t entry_point, uint32_t flash_offset)
+		uint32_t entry_point, uint32_t flash_offset, int plugin)
  {
  	imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;
  	flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
@@ -180,22 +181,12 @@ static int set_imx_hdr_v1(struct imx_header *imxhdr,
  	/* Security feature are not supported */
  	fhdr_v1->app_code_csf = 0;
  	fhdr_v1->super_root_key = 0;
+	header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4);
  	return header_length;
  }
 
Quoted 13 lines

tools/imximage.c static int set_imx_hdr_v1(struct imx_header *imxhdr, · line 195

Quoted 10 lines
tools/imximage.c +0 -10
-static void set_imx_size_v1(struct imx_header *imxhdr, uint32_t file_size,
-		uint32_t flash_offset)
-{
-	uint32_t *p = (uint32_t *)(((char *)imxhdr)
-			+ imximage_params.header_size);
-
-	/* The external flash header must be at the end of the DCD table */
-	/* file_size includes header */
-	p[-1] = file_size + flash_offset;
-}

I think you have to squash some of your patches or to defines them in another way. You added this code previously, and you drop now. This makes more difficult to review your patches.

I though this is what you were referring to in patch 4/21 response. So my agreement there, should have been here. Now I don't know what in 4/21 you were referring to, but I'll reexamine before next version.

author
#33 lore raw

PATCH v2 7/21 imximage.cfg: run files through C preprocessor

In reply to Troy Kisky

The '#' used as comments in the files cause the preprocessor trouble, so change to /* */.

---
 Makefile                                     |    3 +-
 board/esg/ima3-mx53/imximage.cfg             |  120 ++++++-----
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |   90 ++++----
 board/freescale/mx25pdk/imximage.cfg         |   77 +++----
 board/freescale/mx51evk/imximage.cfg         |  114 +++++-----
 board/freescale/mx53ard/imximage_dd3.cfg     |   83 ++++----
 board/freescale/mx53evk/imximage.cfg         |   86 ++++----
 board/freescale/mx53loco/imximage.cfg        |   83 ++++----
 board/freescale/mx53smd/imximage.cfg         |   83 ++++----
 board/freescale/mx6qarm2/imximage.cfg        |   88 ++++----
 board/genesi/mx51_efikamx/imximage_mx.cfg    |  132 ++++++------
 board/genesi/mx51_efikamx/imximage_sb.cfg    |  126 +++++------
 board/ttcontrol/vision2/imximage_hynix.cfg   |  295 ++++++++++++++------------
 13 files changed, 727 insertions(+), 653 deletions(-)
Makefile +2 -1
index fe2f98c..edf647e 100644
@@ -425,7 +425,8 @@ $(obj)u-boot.img:	$(obj)u-boot.bin
 		-d $< $@
 
 $(obj)u-boot.imx:       $(obj)u-boot.bin
-		$(obj)tools/mkimage -n  $(CONFIG_IMX_CONFIG) -T imximage \
+		$(CC) -E -x c $(CONFIG_IMX_CONFIG) -I./include -o $(obj)imxcfg.imx
+		$(obj)tools/mkimage -n  $(obj)imxcfg.imx -T imximage \
 		-e $(CONFIG_SYS_TEXT_BASE) -d $< $@
 
 $(obj)u-boot.kwb:       $(obj)u-boot.bin
board/esg/ima3-mx53/imximage.cfg +66 -54

153 lines not on this page · raw message

board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +47 -43

109 lines not on this page · raw message

board/freescale/mx25pdk/imximage.cfg +40 -37

93 lines not on this page · raw message

board/freescale/mx51evk/imximage.cfg +60 -54

147 lines not on this page · raw message

board/freescale/mx53ard/imximage_dd3.cfg +43 -40

91 lines not on this page · raw message

board/freescale/mx53evk/imximage.cfg +44 -42

94 lines not on this page · raw message

board/freescale/mx53loco/imximage.cfg +43 -40

91 lines not on this page · raw message

board/freescale/mx53smd/imximage.cfg +43 -40

91 lines not on this page · raw message

board/freescale/mx6qarm2/imximage.cfg +46 -42

101 lines not on this page · raw message

board/genesi/mx51_efikamx/imximage_mx.cfg +70 -62

170 lines not on this page · raw message

board/genesi/mx51_efikamx/imximage_sb.cfg +66 -60

158 lines not on this page · raw message

board/ttcontrol/vision2/imximage_hynix.cfg +157 -138

366 lines not on this page · raw message

Signature · 1 line
1.7.9.5
author
#34 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

In reply to Troy Kisky

The "plugin" command of mkimage can take this
file as an argument.

---
 arch/arm/cpu/armv7/mx6/Makefile          |    5 +-
 arch/arm/cpu/armv7/mx6/plugin.S          |  164 ++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-mx6/imx-regs.h |    1 +
 3 files changed, 169 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/armv7/mx6/plugin.S
arch/arm/cpu/armv7/mx6/Makefile +4 -1
index cbce411..b1fce4e 100644
@@ -33,11 +33,14 @@ SOBJS   = lowlevel_init.o
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
 
-all:	$(obj).depend $(LIB)
+all:	$(obj).depend $(LIB) plugin.bin
 
 $(LIB):	$(OBJS)
 	$(call cmd_link_o_target, $(OBJS))
 
+plugin.bin: plugin.o
+	$(OBJCOPY) -O binary --gap-fill 0xff $< $@
+
 #########################################################################
 
 # defines $(obj).depend target
arch/arm/cpu/armv7/mx6/plugin.S new file +164 -0

164 lines not on this page · raw message

arch/arm/include/asm/arch-mx6/imx-regs.h +1 -0
index 8834c59..5c133b2 100644
@@ -48,6 +48,7 @@
 #define GLOBAL_TIMER_BASE_ADDR          0x00A00200
 #define PRIVATE_TIMERS_WD_BASE_ADDR     0x00A00600
 #define IC_DISTRIBUTOR_BASE_ADDR        0x00A01000
+#define L2_BASE_ADDR                    0x00A02000
 #define GPV0_BASE_ADDR                  0x00B00000
 #define GPV1_BASE_ADDR                  0x00C00000
 #define PCIE_ARB_BASE_ADDR              0x01000000
Signature · 1 line
1.7.9.5
#35 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

Quoted 2 lines · Troy Kisky

The "plugin" command of mkimage can take this
file as an argument.

An explanation of what is "plugin" and what the file plugin.S does should be better. Not in the subject of the patch, you can place it as a README.

Quoted 211 lines
---
  arch/arm/cpu/armv7/mx6/Makefile          |    5 +-
  arch/arm/cpu/armv7/mx6/plugin.S          |  164 ++++++++++++++++++++++++++++++
  arch/arm/include/asm/arch-mx6/imx-regs.h |    1 +
  3 files changed, 169 insertions(+), 1 deletion(-)

create mode 100644 arch/arm/cpu/armv7/mx6/plugin.S

arch/arm/cpu/armv7/mx6/Makefile +4 -1
index cbce411..b1fce4e 100644
@@ -33,11 +33,14 @@ SOBJS   = lowlevel_init.o
  SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
  OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
 
-all:	$(obj).depend $(LIB)
+all:	$(obj).depend $(LIB) plugin.bin
 
  $(LIB):	$(OBJS)
  	$(call cmd_link_o_target, $(OBJS))
 
+plugin.bin: plugin.o
+	$(OBJCOPY) -O binary --gap-fill 0xff $<  $@
+
  #########################################################################
 
  # defines $(obj).depend target
arch/arm/cpu/armv7/mx6/plugin.S new file +164 -0
new file mode 100644
index 0000000..99c6b20
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2012 Boundary Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+#include<config.h>
+#include<asm/arch/imx-regs.h>
+
+#define HAB_RVT_ENTRY		0x98
+#define HAB_RVT_FAIL_SAFE_VECT	0xbc
+#define HAB_RVT_LOAD_DATA	0xc8
+
+#define HDR_SELF_PTR	0x14
+#define HDR_BOOT_DATA	0x20
+#define HDR_IMAGE_LEN	0x24
+
+#define L2X0_CTRL	0x100
+#define SCU_CONFIG	0x004
+
+/*
+ * Disable L2 cache because ROM will turn it on when a plugin is used.
+ * There are cache coherence problems if cache is on when Linux kernel
+ * expects it to be off.
+ */
+.macro disable_l2_cache
+	ldr	r1, =L2_BASE_ADDR
+	mov	r0, #0x0
+	str	r0, [r1, #L2X0_CTRL]
+.endm
+
+
+/*
+ * plugin_start(void **start, size_t *bytes, UINT32 *ivt_offset)
+ */
+plugin_start:
+/* Save the return address and the function arguments */
+	push	{r0-r8, lr}
+
+/* r0-r2 must be>= 0x100 and must be 4 byte aligned */
+	cmp	r0, #0x100
+	cmphs	r1, #0x100
+	cmphs	r2, #0x100
+
+/* rCPU: 22 - mx6q, 12 - mx6dl, 12|0x100 - solo, 2 - sololite */
+#define rCPU	r2
+#define rIomux	r3
+#define rVal0	r4	/* mx6q value */
+#define rVal1	r5	/* mx6dl value */
+#define rVal2	r6	/* mx6solo value */
+#define rVal3	r7	/* mx6sololite value */
+#define rFlag	lr
+#define rTable	r8
+
+	orr	rFlag, r0, r1
+	orr	rFlag, rFlag, r2
+	orrlo	rFlag, rFlag, #1
+
+	mov	rCPU, #22		/* mx6q */
+	mov	r1, #SCU_BASE_ADDR
+	ldr	r0, [r1, #SCU_CONFIG]
+	and	r0, r0, #3
+	cmp	r0, #3			/* is mx6q? */
+	movne	rCPU, #12		/* mx6dl */
+	cmpne	r0, #1			/* is mx6dl? */
+	movne	rCPU, #2		/* mx6 sololite */
+
+	ldrne	r1, =ANATOP_BASE_ADDR
+	ldrne	r0, [r1, #0x280]
+	movne	r0, r0, LSR #16
+	cmpne	r0, #0x60		/* is mx6 Sololite? */
+	movne	rCPU, #12 | 0x100	/* Solo */
+
+	mov	rVal0, #0
+	mov	rVal1, #0
+	mov	rVal2, #0
+	mov	rVal3, #0
+	ldr	rIomux, =IOMUXC_BASE_ADDR
+	adr	rTable, mx6_table
+	b	3f
+
+1:	movs	r0, r1, LSR #30
+	beq	2f
+	mov	r1, r1, LSL rCPU
+	movs	r1, r1, LSR #32-10
+	addne	r1, rIomux, r1, LSL #2
+	cmp	r0, #3
+	subne	r0, r0, #1
+	orr	r1, r1, r0
+
+2:	ands	r0, r1, #3
+	bic	r1, r1, #3
+	ldrne	rVal0, [rTable], #4
+	movne	rVal1, rVal0
+	movne	rVal2, rVal0
+	movne	rVal3, rVal0
+	subnes	r0, r0, #1
+	ldrne	rVal1, [rTable], #4
+	movne	rVal2, rVal1
+	movne	rVal3, rVal1
+	subnes	r0, r0, #1
+	ldrne	rVal2, [rTable], #4
+	ldrne	rVal3, [rTable], #4
+
+	mov	r0, rVal0
+	cmp	rCPU, #22
+	movne	r0, rVal1
+	cmpne	rCPU, #12
+	movne	r0, rVal2
+	cmpne	rCPU, #12|0x100
+	movne	r0, rVal3
+	cmp	r1, #0
+	strne	r0, [r1]
+3:	ldr	r1, [rTable], #4
+	cmp	r1, #0
+	bne	1b
+
+	tst	rFlag, #3
+	bne	4f		/* Branch if not called as plugin */
+/* Align end of table to 64 byte boundary */
+	sub	rTable, rTable, #1
+	orr	rTable, rTable, #0x3f
+	add	rTable, rTable, #1
+	ldr	r2, [rTable, #HDR_SELF_PTR]
+	ldr	r0, [rTable, #HDR_BOOT_DATA]
+	ldr	r1, [rTable, #HDR_IMAGE_LEN]
+	sub	rTable, r2, r0
+	mov	r2, r0
+	mov	r3, r1
+	mov	r4, #0
+	push	{r0-r4}
+	mov	r0, #HAB_RVT_LOAD_DATA
+	ldr	r4, [r0]
+	mov	r0, sp
+	add	r1, sp, #4
+	add	r2, sp, #8
+	blx	r4
+
+	disable_l2_cache
+	pop	{r4, r5}
+	add	sp, sp, #12
+	pop	{r0-r3}
+/*
+ * Before returning to ROM, we need to fill the return values arguments
+ * to our function.
+ * plugin_start(void **start, size_t *bytes, UINT32 *ivt_offset)
+ */
+
+	str	r4, [r0]
+	str	r5, [r1]
+	str	rTable, [r2]
+	mov	r0, #1
+	pop	{r4-r8, pc}
+
+/* Not called as plugin */
+4:	popne	{r0-r8, lr}
+	mov	r0, #HAB_RVT_ENTRY
+	ldr	lr, [r0]
+	blx	lr
+	mov	r0, #HAB_RVT_FAIL_SAFE_VECT
+	ldr	lr, [r0]
+	blx	lr
+
+	.ltorg
+mx6_table:
arch/arm/include/asm/arch-mx6/imx-regs.h +1 -0
index 8834c59..5c133b2 100644
@@ -48,6 +48,7 @@
  #define GLOBAL_TIMER_BASE_ADDR          0x00A00200
  #define PRIVATE_TIMERS_WD_BASE_ADDR     0x00A00600
  #define IC_DISTRIBUTOR_BASE_ADDR        0x00A01000
+#define L2_BASE_ADDR                    0x00A02000
  #define GPV0_BASE_ADDR                  0x00B00000
  #define GPV1_BASE_ADDR                  0x00C00000
  #define PCIE_ARB_BASE_ADDR              0x01000000
#36 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

In reply to Troy Kisky
Quoted 5 lines · Troy Kisky

The "plugin" command of mkimage can take this
file as an argument.

---

Hi Troy,

I agree with Vikram that a better explanation of what a plugin is can help to understand without reading deeply into the i.MX6 manual.

So a "plugin" is a chunk of code that can be called directly by the BootROM of i.MX processors supporting V2 version of the i.MX header. In my understanding, this is supported by i.MX53, too. After the plugin run, the control is returned to the BootROM.

Now that we have some basis, why do we need this mechanism to boot this board ? Is it not possible to make the same initialization directly in u-boot ?

In principle, this adds stil some code that is not so easy to maintain.

Quoted 12 lines
 arch/arm/cpu/armv7/mx6/Makefile          |    5 +-
 arch/arm/cpu/armv7/mx6/plugin.S          |  164 ++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-mx6/imx-regs.h |    1 +
 3 files changed, 169 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/armv7/mx6/plugin.S
arch/arm/cpu/armv7/mx6/Makefile +0 -0
index cbce411..b1fce4e 100644
@@ -33,11 +33,14 @@ SOBJS   = lowlevel_init.o
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)

arch/arm/cpu/armv7/mx6/Makefile SOBJS = lowlevel_init.o · line 42

Quoted 10 lines
arch/arm/cpu/armv7/mx6/Makefile +3 -1
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
 
-all:	$(obj).depend $(LIB)
+all:	$(obj).depend $(LIB) plugin.bin
 
 $(LIB):	$(OBJS)
 	$(call cmd_link_o_target, $(OBJS))
 
+plugin.bin: plugin.o
+	$(OBJCOPY) -O binary --gap-fill 0xff $< $@

If we add a plugin mechanism, we can have several plugins (booting directly from Net, maybe ?). We should then have a general mechanism. A directory "plugins" here can contain the code, and it is compiled only if a CONFIG_ is set or better if required from imximage.cfg

Quoted 71 lines
arch/arm/cpu/armv7/mx6/Makefile +1 -0
+
 #########################################################################
 
 # defines $(obj).depend target
arch/arm/cpu/armv7/mx6/plugin.S new file +61 -0
new file mode 100644
index 0000000..99c6b20
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2012 Boundary Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+#include <config.h>
+#include <asm/arch/imx-regs.h>
+
+#define HAB_RVT_ENTRY		0x98
+#define HAB_RVT_FAIL_SAFE_VECT	0xbc
+#define HAB_RVT_LOAD_DATA	0xc8
+
+#define HDR_SELF_PTR	0x14
+#define HDR_BOOT_DATA	0x20
+#define HDR_IMAGE_LEN	0x24
+
+#define L2X0_CTRL	0x100
+#define SCU_CONFIG	0x004
+
+/*
+ * Disable L2 cache because ROM will turn it on when a plugin is used.
+ * There are cache coherence problems if cache is on when Linux kernel
+ * expects it to be off.
+ */
+.macro disable_l2_cache
+	ldr	r1, =L2_BASE_ADDR
+	mov	r0, #0x0
+	str	r0, [r1, #L2X0_CTRL]
+.endm
+
+
+/*
+ * plugin_start(void **start, size_t *bytes, UINT32 *ivt_offset)
+ */
+plugin_start:
+/* Save the return address and the function arguments */
+	push	{r0-r8, lr}
+
+/* r0-r2 must be  >= 0x100 and must be 4 byte aligned */
+	cmp	r0, #0x100
+	cmphs	r1, #0x100
+	cmphs	r2, #0x100
+
+/* rCPU: 22 - mx6q, 12 - mx6dl, 12|0x100 - solo, 2 - sololite */
+#define rCPU	r2
+#define rIomux	r3
+#define rVal0	r4	/* mx6q value */
+#define rVal1	r5	/* mx6dl value */
+#define rVal2	r6	/* mx6solo value */
+#define rVal3	r7	/* mx6sololite value */
+#define rFlag	lr
+#define rTable	r8
+
+	orr	rFlag, r0, r1
+	orr	rFlag, rFlag, r2
+	orrlo	rFlag, rFlag, #1
+
+	mov	rCPU, #22		/* mx6q */
+	mov	r1, #SCU_BASE_ADDR
+	ldr	r0, [r1, #SCU_CONFIG]
+	and	r0, r0, #3

arch/arm/cpu/armv7/mx6/plugin.S line 71

Quoted 10 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +10 -0
+	cmp	r0, #3			/* is mx6q? */
+	movne	rCPU, #12		/* mx6dl */
+	cmpne	r0, #1			/* is mx6dl? */
+	movne	rCPU, #2		/* mx6 sololite */
+
+	ldrne	r1, =ANATOP_BASE_ADDR
+	ldrne	r0, [r1, #0x280]
+	movne	r0, r0, LSR #16
+	cmpne	r0, #0x60		/* is mx6 Sololite? */
+	movne	rCPU, #12 | 0x100	/* Solo */

Ok - until here you have checked which processor is running. Now the more obscure code:

Quoted 11 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +8 -0
+
+	mov	rVal0, #0
+	mov	rVal1, #0
+	mov	rVal2, #0
+	mov	rVal3, #0
+	ldr	rIomux, =IOMUXC_BASE_ADDR
+	adr	rTable, mx6_table
+	b	3f
 
 
 

arch/arm/cpu/armv7/mx6/plugin.S line 89

Quoted 10 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +10 -0
+
+1:	movs	r0, r1, LSR #30
+	beq	2f
+	mov	r1, r1, LSL rCPU
+	movs	r1, r1, LSR #32-10
+	addne	r1, rIomux, r1, LSL #2
+	cmp	r0, #3
+	subne	r0, r0, #1
+	orr	r1, r1, r0
+

The reason is to write GPR12 ? But why do we need a plugin for that ? I do not understand why we cannot do it in the initialization code of the SOC, as we usually do.

Quoted 37 lines

+2: ands r0, r1, #3

arch/arm/cpu/armv7/mx6/plugin.S new file +36 -0
+	bic	r1, r1, #3
+	ldrne	rVal0, [rTable], #4
+	movne	rVal1, rVal0
+	movne	rVal2, rVal0
+	movne	rVal3, rVal0
+	subnes	r0, r0, #1
+	ldrne	rVal1, [rTable], #4
+	movne	rVal2, rVal1
+	movne	rVal3, rVal1
+	subnes	r0, r0, #1
+	ldrne	rVal2, [rTable], #4
+	ldrne	rVal3, [rTable], #4
+
+	mov	r0, rVal0
+	cmp	rCPU, #22
+	movne	r0, rVal1
+	cmpne	rCPU, #12
+	movne	r0, rVal2
+	cmpne	rCPU, #12|0x100
+	movne	r0, rVal3
+	cmp	r1, #0
+	strne	r0, [r1]
+3:	ldr	r1, [rTable], #4
+	cmp	r1, #0
+	bne	1b
+
+	tst	rFlag, #3
+	bne	4f		/* Branch if not called as plugin */
+/* Align end of table to 64 byte boundary */
+	sub	rTable, rTable, #1
+	orr	rTable, rTable, #0x3f
+	add	rTable, rTable, #1
+	ldr	r2, [rTable, #HDR_SELF_PTR]
+	ldr	r0, [rTable, #HDR_BOOT_DATA]
+	ldr	r1, [rTable, #HDR_IMAGE_LEN]
+	sub	rTable, r2, r0

arch/arm/cpu/armv7/mx6/plugin.S line 136

Quoted 10 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +10 -0
+	mov	r2, r0
+	mov	r3, r1
+	mov	r4, #0
+	push	{r0-r4}
+	mov	r0, #HAB_RVT_LOAD_DATA
+	ldr	r4, [r0]
+	mov	r0, sp
+	add	r1, sp, #4
+	add	r2, sp, #8
+	blx	r4

Sorry, I need help to understand this code

arch/arm/cpu/armv7/mx6/plugin.S line 145

Quoted 9 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +9 -0
+
+	disable_l2_cache
+	pop	{r4, r5}
+	add	sp, sp, #12
+	pop	{r0-r3}
+/*
+ * Before returning to ROM, we need to fill the return values arguments
+ * to our function.
+ * plugin_start(void **start, size_t *bytes, UINT32 *ivt_offset)

As the i.MX and the API suggest, it should be possible to write C code for a plugin. Or am I wrong ?

arch/arm/include/asm/arch-mx6/imx-regs.h line 54

Quoted 13 lines
arch/arm/include/asm/arch-mx6/imx-regs.h +1 -0
index 8834c59..5c133b2 100644
@@ -48,6 +48,7 @@
 #define GLOBAL_TIMER_BASE_ADDR          0x00A00200
 #define PRIVATE_TIMERS_WD_BASE_ADDR     0x00A00600
 #define IC_DISTRIBUTOR_BASE_ADDR        0x00A01000
+#define L2_BASE_ADDR                    0x00A02000
 #define GPV0_BASE_ADDR                  0x00B00000
 #define GPV1_BASE_ADDR                  0x00C00000
 #define PCIE_ARB_BASE_ADDR              0x01000000

This is useful in any case. I suggest you put this define in a separate patch, that can flow independently into mainline.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#37 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

Quoted 9 lines · Stefano Babic
Quoted 5 lines · Troy Kisky

The "plugin" command of mkimage can take this
file as an argument.

---

Hi Troy,

Quoted 8 lines

I agree with Vikram that a better explanation of what a plugin is can help to understand without reading deeply into the i.MX6 manual.

So a "plugin" is a chunk of code that can be called directly by the BootROM of i.MX processors supporting V2 version of the i.MX header. In my understanding, this is supported by i.MX53, too. After the plugin run, the control is returned to the BootROM.

Hi Stefano,

It seems that there's some general confusion on the list, so I think a little more background and commentary is in order.

The primary rationale for plugins is to allow separate link maps in a single image loaded by the BootROM.

The idea is to allow first-level code to initialize resources (usually DDR) while running in internal RAM, then return to the boot rom for further image loading (typically into DDR). This prevents the need for the first-level code to support all boot sources (SPI-NOR, NAND, SD card, etc) and allows it to focus on machine setup.

The feature is normally needed to allow the first level to access a PMIC. I'm surprised that the 51evk and 53Loco boards aren't using it.

Troy's rationale for using it now is to enable a single image on i.MX6Quad, Dual lite and Solo processors, which have very slight initialization differences. The 6Solo processor has 32-bit DDR bus, so it would otherwise require a separate binary.

By doing this in code (plugin), we can introduce a conditional based on processor type and have a single image that will boot on any of the three.

The other key change for these processors is the location of the iomux controller (moved on 6Solo/Duallite from 6Quad).

6Solo has 32-bit DDR and iomux controller moved from 6Q 6Duallite has 64-bit DDR but same iomux location as 6Q

Note that this highlights a slight down side to the plugin approach.

Because of the movement of the iomux controller, we can't use a universal i.MX6 image header to write any IOMUX registers through imximage.cfg.

Regards,

Eric

#38 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

Quoted 18 lines · Eric Nelson
Quoted 9 lines · Stefano Babic
Quoted 5 lines · Troy Kisky

The "plugin" command of mkimage can take this
file as an argument.

---

Hi Troy,

Quoted 8 lines

I agree with Vikram that a better explanation of what a plugin is can help to understand without reading deeply into the i.MX6 manual.

So a "plugin" is a chunk of code that can be called directly by the BootROM of i.MX processors supporting V2 version of the i.MX header. In my understanding, this is supported by i.MX53, too. After the plugin run, the control is returned to the BootROM.

Quoted 4 lines

Hi Stefano,

It seems that there's some general confusion on the list, so I think a little more background and commentary is in order.

Well, it is - thanks for explanation.

Quoted 10 lines

The primary rationale for plugins is to allow separate link maps in a single image loaded by the BootROM.

The idea is to allow first-level code to initialize resources (usually DDR) while running in internal RAM, then return to the boot rom for further image loading (typically into DDR). This prevents the need for the first-level code to support all boot sources (SPI-NOR, NAND, SD card, etc) and allows it to focus on machine setup.

Quoted 3 lines

The feature is normally needed to allow the first level to access a PMIC. I'm surprised that the 51evk and 53Loco boards aren't using it.

The mx51 uses a V1 header and the plugin feature is not supported at all. So, it can't, simply. The mx53 can, but it is not needed. Both boards boot without plugin. So it seem we have a misunderstanding, and thanks to raise this issue ;-)

The setup is done by the SOC interpreting the DCD data into the iMX header. After this setup, that in any case cannot be very long, the control is still taken by the bootROM, that copies data from the media device to the DDR according to the values set into the iMX header. Still without plugin. After the copy, the bootROM gives the control to U-Boot for the rest that starts with the usual initialization.

There is no need to setup the pMIC on mx51evk and mx53qsb to get the DDR running. However, even if we need it, we can do it in another way, as I will explain now.

Quoted 9 lines

Troy's rationale for using it now is to enable a single image on i.MX6Quad, Dual lite and Solo processors, which have very slight initialization differences. The 6Solo processor has 32-bit DDR bus, so it would otherwise require a separate binary.

By doing this in code (plugin), we can introduce a conditional based on processor type and have a single image that will boot on any of the three.

Ok - but why cannot this check be done directly by U-Boot ?

My understanding is that you want to add a plugin written in assembly to allow different setup of the DDR controller. Let's see how we can do with standard U-Boot code.

Core of the startup is that the SOC copies itself some code into the internal RAM and started. This is done by bootROM, running is own code and running the plugin.

We have already this mechanism with the SPL framework. The big advantage for this approach is that the same mechanism can be used on SOC of different vendors, while the one in this series is a solution strictly bound with (some) Freescale's SOC.

The imx header can be still adapted to copy the SPL code into the internal RAM. When SPL is running, you have all freedom to check which is the CPU running and to adjust your DDR setting, and everything is C code. Both MX5 and MX6 have plenty of internal RAM to do this, because SPL requires ~30KB.

I think the goal to have the same U-Boot binary can be reached using the SPL framework. As you are running U-Boot code, you have the possibility to do whatever you want.

So my question is: if the main reason is to have a single image for all your iMX6 boards, why cannot we do it in a standard way using SPL ?

Quoted 4 lines

The other key change for these processors is the location of the iomux controller (moved on 6Solo/Duallite from 6Quad).

Quoted 8 lines

6Solo has 32-bit DDR and iomux controller moved from 6Q 6Duallite has 64-bit DDR but same iomux location as 6Q

Note that this highlights a slight down side to the plugin approach.

Because of the movement of the iomux controller, we can't use a universal i.MX6 image header to write any IOMUX registers through imximage.cfg.

However, you can do it with this approach:

- you have a general imx header, that does not write into IOMUX It is your choice if this should set the DDR or not. You could also decide to have an empty DCD table.
- your imx Header is generated for your SPL code, and the destination address for the SPL code is put into internal RAM
- the bootROM will start reading the iMX header and DCD data and copies data from media (NAND, SPI, ..) into iRAM. There is no need for any special setup because the iRAM is always available. Then it gives the control to the SPL.
- the SPL starts and performs the setup of the DDR, checking the SOC if it is required. The usual SOC initialization is done here.
- At the end, the SPL loads from media the U-Boot or directly the kernel and starts it. Or whatever image you want.

The further advantage we can have with this approach is that we can profit for further development in u-boot. What I mean really is using TPL, that means putting u-boot into a UBL volume, see:

http://lists.celinuxforum.org/pipermail/celinux-dev/2012-April/000543.html

I know there is not yet activity on this topic, but it does not mean we have not in future.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#39 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

Quoted 81 lines · Stefano Babic
Quoted 18 lines · Eric Nelson
Quoted 9 lines · Stefano Babic
Quoted 5 lines · Troy Kisky

The "plugin" command of mkimage can take this
file as an argument.

---

Hi Troy,

Quoted 8 lines

I agree with Vikram that a better explanation of what a plugin is can help to understand without reading deeply into the i.MX6 manual.

So a "plugin" is a chunk of code that can be called directly by the BootROM of i.MX processors supporting V2 version of the i.MX header. In my understanding, this is supported by i.MX53, too. After the plugin run, the control is returned to the BootROM.

Quoted 4 lines

Hi Stefano,

It seems that there's some general confusion on the list, so I think a little more background and commentary is in order.

Well, it is - thanks for explanation.

Quoted 10 lines

The primary rationale for plugins is to allow separate link maps in a single image loaded by the BootROM.

The idea is to allow first-level code to initialize resources (usually DDR) while running in internal RAM, then return to the boot rom for further image loading (typically into DDR). This prevents the need for the first-level code to support all boot sources (SPI-NOR, NAND, SD card, etc) and allows it to focus on machine setup.

Quoted 3 lines

The feature is normally needed to allow the first level to access a PMIC. I'm surprised that the 51evk and 53Loco boards aren't using it.

The mx51 uses a V1 header and the plugin feature is not supported at all. So, it can't, simply. The mx53 can, but it is not needed. Both boards boot without plugin. So it seem we have a misunderstanding, and thanks to raise this issue ;-)

The setup is done by the SOC interpreting the DCD data into the iMX header. After this setup, that in any case cannot be very long, the control is still taken by the bootROM, that copies data from the media device to the DDR according to the values set into the iMX header. Still without plugin. After the copy, the bootROM gives the control to U-Boot for the rest that starts with the usual initialization.

There is no need to setup the pMIC on mx51evk and mx53qsb to get the DDR running. However, even if we need it, we can do it in another way, as I will explain now.

Quoted 9 lines

Troy's rationale for using it now is to enable a single image on i.MX6Quad, Dual lite and Solo processors, which have very slight initialization differences. The 6Solo processor has 32-bit DDR bus, so it would otherwise require a separate binary.

By doing this in code (plugin), we can introduce a conditional based on processor type and have a single image that will boot on any of the three.

Ok - but why cannot this check be done directly by U-Boot ?

My understanding is that you want to add a plugin written in assembly to allow different setup of the DDR controller. Let's see how we can do with standard U-Boot code.

Core of the startup is that the SOC copies itself some code into the internal RAM and started. This is done by bootROM, running is own code and running the plugin.

We have already this mechanism with the SPL framework. The big advantage for this approach is that the same mechanism can be used on SOC of different vendors, while the one in this series is a solution strictly bound with (some) Freescale's SOC.

Quoted 6 lines

The imx header can be still adapted to copy the SPL code into the internal RAM. When SPL is running, you have all freedom to check which is the CPU running and to adjust your DDR setting, and everything is C code. Both MX5 and MX6 have plenty of internal RAM to do this, because SPL requires ~30KB.

This is the part that gets interesting.

You're right that SPL **can** do the job, but only if it supports the boot media. For the most part, it's reasonable to expect the code to be written in U-Boot for that, since the boot media may also be used to load kernels, RAM disks and the like.

But what about the serial boot modes (especially USB)? We likely wouldn't implement them (we haven't yet pulled in USB slave support) and to paraphrase US bumper stickers:

You can take imx_usb away from me when you pry it from my cold dead hands ;)

If you're not aware of imx_usb, it's a utility that Troy wrote to allow download over the boot ROM's USB protocol.

Some commentary is here:
http://boundarydevices.com/unbricking-nitrogen6x-sabre-lite-i-mx6-board/

The sources are here (requires libusb):
https://github.com/boundarydevices/imx_usb_loader

Quoted 7 lines

I think the goal to have the same U-Boot binary can be reached using the SPL framework. As you are running U-Boot code, you have the possibility to do whatever you want.

So my question is: if the main reason is to have a single image for all your iMX6 boards, why cannot we do it in a standard way using SPL ?

The related question is whether or not the benefits of a single image is worth the carrying cost.

This is probably more useful for those who boot directly to SD card, where the cost of creation or modification of the SD card is high.

Since our boards are booting to SPI-NOR, I'm not completely convinced.

It seems that simply creating three targets for each is okay, since we know what processor we placed on the board and our boot mode switches make it relatively easy to recover from a screw-up.

Quoted 29 lines
Quoted 4 lines

The other key change for these processors is the location of the iomux controller (moved on 6Solo/Duallite from 6Quad).

Quoted 8 lines

6Solo has 32-bit DDR and iomux controller moved from 6Q 6Duallite has 64-bit DDR but same iomux location as 6Q

Note that this highlights a slight down side to the plugin approach.

Because of the movement of the iomux controller, we can't use a universal i.MX6 image header to write any IOMUX registers through imximage.cfg.

However, you can do it with this approach:

- you have a general imx header, that does not write into IOMUX It is your choice if this should set the DDR or not. You could also decide to have an empty DCD table.
- your imx Header is generated for your SPL code, and the destination address for the SPL code is put into internal RAM
- the bootROM will start reading the iMX header and DCD data and copies data from media (NAND, SPI, ..) into iRAM. There is no need for any special setup because the iRAM is always available. Then it gives the control to the SPL.
- the SPL starts and performs the setup of the DDR, checking the SOC if it is required. The usual SOC initialization is done here.
- At the end, the SPL loads from media the U-Boot or directly the kernel and starts it. Or whatever image you want.

Quoted 9 lines

The further advantage we can have with this approach is that we can profit for further development in u-boot. What I mean really is using TPL, that means putting u-boot into a UBL volume, see:

http://lists.celinuxforum.org/pipermail/celinux-dev/2012-April/000543.html

I know there is not yet activity on this topic, but it does not mean we have not in future.

This is a good conversation to have.

Regards,

Eric

#40 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

Quoted 18 lines · Eric Nelson

This is the part that gets interesting.

You're right that SPL **can** do the job, but only if it supports the boot media. For the most part, it's reasonable to expect the code to be written in U-Boot for that, since the boot media may also be used to load kernels, RAM disks and the like.

But what about the serial boot modes (especially USB)? We likely wouldn't implement them (we haven't yet pulled in USB slave support) and to paraphrase US bumper stickers:

You can take imx_usb away from me when you pry it from my cold dead hands ;)

If you're not aware of imx_usb, it's a utility that Troy wrote to allow download over the boot ROM's USB protocol.

Quoted 7 lines

Some commentary is here:
http://boundarydevices.com/unbricking-nitrogen6x-sabre-lite-i-mx6-board/

The sources are here (requires libusb):
https://github.com/boundarydevices/imx_usb_loader

Nice job ! This is very valuable tool !

But I do not get the connection with the imximage and the need for the plugin. If the SOC boots with "Serial Downloader", it polls the USB OTG waiting for command as specified in the protocol. With your tool you set the registers you need and you can download the file you want, independently from the structure of the imxImage.

By the way, I have missed that Troy had implemented this tool - thanks for the tipp and to share it !

Quoted 10 lines
Quoted 7 lines

I think the goal to have the same U-Boot binary can be reached using the SPL framework. As you are running U-Boot code, you have the possibility to do whatever you want.

So my question is: if the main reason is to have a single image for all your iMX6 boards, why cannot we do it in a standard way using SPL ?

The related question is whether or not the benefits of a single image is worth the carrying cost.

I have interpreted from your answers that it was a goal for you. I think the costs are higher than the benefits.

Quoted 11 lines

This is probably more useful for those who boot directly to SD card, where the cost of creation or modification of the SD card is high.

Since our boards are booting to SPI-NOR, I'm not completely convinced.

It seems that simply creating three targets for each is okay, since we know what processor we placed on the board and our boot mode switches make it relatively easy to recover from a screw-up.

Fully agree.

Quoted 34 lines
Quoted 34 lines
Quoted 5 lines

The other key change for these processors is the location of the iomux controller (moved on 6Solo/Duallite from 6Quad).

Quoted 8 lines

6Solo has 32-bit DDR and iomux controller moved from 6Q 6Duallite has 64-bit DDR but same iomux location as 6Q

Note that this highlights a slight down side to the plugin approach.

Because of the movement of the iomux controller, we can't use a universal i.MX6 image header to write any IOMUX registers through imximage.cfg.

However, you can do it with this approach:

- you have a general imx header, that does not write into IOMUX It is your choice if this should set the DDR or not. You could also decide to have an empty DCD table.
- your imx Header is generated for your SPL code, and the destination address for the SPL code is put into internal RAM
- the bootROM will start reading the iMX header and DCD data and copies data from media (NAND, SPI, ..) into iRAM. There is no need for any special setup because the iRAM is always available. Then it gives the control to the SPL.
- the SPL starts and performs the setup of the DDR, checking the SOC if it is required. The usual SOC initialization is done here.
- At the end, the SPL loads from media the U-Boot or directly the kernel and starts it. Or whatever image you want.

The further advantage we can have with this approach is that we can profit for further development in u-boot. What I mean really is using TPL, that means putting u-boot into a UBL volume, see:

Quoted 8 lines
Quoted 6 lines

http://lists.celinuxforum.org/pipermail/celinux-dev/2012-April/000543.html

I know there is not yet activity on this topic, but it does not mean we have not in future.

This is a good conversation to have.

Best regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#41 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

Hi Stefano,

Quoted 27 lines · Stefano Babic
Quoted 18 lines · Eric Nelson

This is the part that gets interesting.

You're right that SPL **can** do the job, but only if it supports the boot media. For the most part, it's reasonable to expect the code to be written in U-Boot for that, since the boot media may also be used to load kernels, RAM disks and the like.

But what about the serial boot modes (especially USB)? We likely wouldn't implement them (we haven't yet pulled in USB slave support) and to paraphrase US bumper stickers:

You can take imx_usb away from me when you pry it from my cold dead hands ;)

If you're not aware of imx_usb, it's a utility that Troy wrote to allow download over the boot ROM's USB protocol.

Quoted 7 lines

Some commentary is here:
http://boundarydevices.com/unbricking-nitrogen6x-sabre-lite-i-mx6-board/

The sources are here (requires libusb):
https://github.com/boundarydevices/imx_usb_loader

Quoted 8 lines

Nice job ! This is very valuable tool !

But I do not get the connection with the imximage and the need for the plugin. If the SOC boots with "Serial Downloader", it polls the USB OTG waiting for command as specified in the protocol. With your tool you set the registers you need and you can download the file you want, independently from the structure of the imxImage.

The relationship is this: if we build a combined SPL image for a universal i.MX6 U-Boot, how would it know/decide that it's being loaded via USB and how would it support this?

imx_usb supports plugins, so we can use it directly with that approach.

Quoted 3 lines

By the way, I have missed that Troy had implemented this tool - thanks for the tipp and to share it !

NP.

It really helps the compile/test cycle time, especially when used with the 'bmode usb' command.

Quoted 74 lines
Quoted 10 lines
Quoted 7 lines

I think the goal to have the same U-Boot binary can be reached using the SPL framework. As you are running U-Boot code, you have the possibility to do whatever you want.

So my question is: if the main reason is to have a single image for all your iMX6 boards, why cannot we do it in a standard way using SPL ?

The related question is whether or not the benefits of a single image is worth the carrying cost.

I have interpreted from your answers that it was a goal for you. I think the costs are higher than the benefits.

Quoted 11 lines

This is probably more useful for those who boot directly to SD card, where the cost of creation or modification of the SD card is high.

Since our boards are booting to SPI-NOR, I'm not completely convinced.

It seems that simply creating three targets for each is okay, since we know what processor we placed on the board and our boot mode switches make it relatively easy to recover from a screw-up.

Fully agree.

Quoted 34 lines
Quoted 34 lines
Quoted 5 lines

The other key change for these processors is the location of the iomux controller (moved on 6Solo/Duallite from 6Quad).

Quoted 8 lines

6Solo has 32-bit DDR and iomux controller moved from 6Q 6Duallite has 64-bit DDR but same iomux location as 6Q

Note that this highlights a slight down side to the plugin approach.

Because of the movement of the iomux controller, we can't use a universal i.MX6 image header to write any IOMUX registers through imximage.cfg.

However, you can do it with this approach:

- you have a general imx header, that does not write into IOMUX It is your choice if this should set the DDR or not. You could also decide to have an empty DCD table.
- your imx Header is generated for your SPL code, and the destination address for the SPL code is put into internal RAM
- the bootROM will start reading the iMX header and DCD data and copies data from media (NAND, SPI, ..) into iRAM. There is no need for any special setup because the iRAM is always available. Then it gives the control to the SPL.
- the SPL starts and performs the setup of the DDR, checking the SOC if it is required. The usual SOC initialization is done here.
- At the end, the SPL loads from media the U-Boot or directly the kernel and starts it. Or whatever image you want.

The further advantage we can have with this approach is that we can profit for further development in u-boot. What I mean really is using TPL, that means putting u-boot into a UBL volume, see:

Quoted 8 lines
Quoted 6 lines

http://lists.celinuxforum.org/pipermail/celinux-dev/2012-April/000543.html

I know there is not yet activity on this topic, but it does not mean we have not in future.

This is a good conversation to have.

Best regards,
Stefano

#42 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

Quoted 2 lines · Eric Nelson

Hi Stefano,

Hi Eric,

Quoted 7 lines
Quoted 6 lines

But I do not get the connection with the imximage and the need for the plugin. If the SOC boots with "Serial Downloader", it polls the USB OTG waiting for command as specified in the protocol. With your tool you set the registers you need and you can download the file you want, independently from the structure of the imxImage.

Quoted 6 lines

The relationship is this: if we build a combined SPL image for a universal i.MX6 U-Boot, how would it know/decide that it's being loaded via USB and how would it support this?

imx_usb supports plugins, so we can use it directly with that approach.

But this seems to me an implementation choice rather a constraint of the SOC. As I see in your code, imx_usb parses the iMX header making decisions according to it. Then there is a hard dependency between imx_usb and u-boot code.

The other way is that they are independently, let's say, openOCD approach ;-).

imx_usb could get an independent file to configure the DDR controller (for example, but it is not limited to), and then load a u-boot (or SPL, or...) where you want. Then there is no strict dependency with the imx_usb tool. The SOC allows this approach, too.

Best regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#43 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

In reply to Stefano Babic
Quoted 119 lines · Stefano Babic
Quoted 17 lines · Eric Nelson
Quoted 8 lines · Stefano Babic
Quoted 5 lines · Troy Kisky

The "plugin" command of mkimage can take this
file as an argument.

---

Hi Troy,

Quoted 8 lines

I agree with Vikram that a better explanation of what a plugin is can help to understand without reading deeply into the i.MX6 manual.

So a "plugin" is a chunk of code that can be called directly by the BootROM of i.MX processors supporting V2 version of the i.MX header. In my understanding, this is supported by i.MX53, too. After the plugin run, the control is returned to the BootROM.

Quoted 4 lines

Hi Stefano,

It seems that there's some general confusion on the list, so I think a little more background and commentary is in order.

Well, it is - thanks for explanation.

Quoted 9 lines

The primary rationale for plugins is to allow separate link maps in a single image loaded by the BootROM.

The idea is to allow first-level code to initialize resources (usually DDR) while running in internal RAM, then return to the boot rom for further image loading (typically into DDR). This prevents the need for the first-level code to support all boot sources (SPI-NOR, NAND, SD card, etc) and allows it to focus on machine setup.

Quoted 3 lines

The feature is normally needed to allow the first level to access a PMIC. I'm surprised that the 51evk and 53Loco boards aren't using it.

The mx51 uses a V1 header and the plugin feature is not supported at all. So, it can't, simply. The mx53 can, but it is not needed. Both boards boot without plugin. So it seem we have a misunderstanding, and thanks to raise this issue ;-)

The setup is done by the SOC interpreting the DCD data into the iMX header. After this setup, that in any case cannot be very long, the control is still taken by the bootROM, that copies data from the media device to the DDR according to the values set into the iMX header. Still without plugin. After the copy, the bootROM gives the control to U-Boot for the rest that starts with the usual initialization.

There is no need to setup the pMIC on mx51evk and mx53qsb to get the DDR running. However, even if we need it, we can do it in another way, as I will explain now.

Quoted 8 lines

Troy's rationale for using it now is to enable a single image on i.MX6Quad, Dual lite and Solo processors, which have very slight initialization differences. The 6Solo processor has 32-bit DDR bus, so it would otherwise require a separate binary.

By doing this in code (plugin), we can introduce a conditional based on processor type and have a single image that will boot on any of the three.

Ok - but why cannot this check be done directly by U-Boot ?

My understanding is that you want to add a plugin written in assembly to allow different setup of the DDR controller. Let's see how we can do with standard U-Boot code.

Core of the startup is that the SOC copies itself some code into the internal RAM and started. This is done by bootROM, running is own code and running the plugin.

We have already this mechanism with the SPL framework. The big advantage for this approach is that the same mechanism can be used on SOC of different vendors, while the one in this series is a solution strictly bound with (some) Freescale's SOC.

The imx header can be still adapted to copy the SPL code into the internal RAM. When SPL is running, you have all freedom to check which is the CPU running and to adjust your DDR setting, and everything is C code. Both MX5 and MX6 have plenty of internal RAM to do this, because SPL requires ~30KB.

I think the goal to have the same U-Boot binary can be reached using the SPL framework. As you are running U-Boot code, you have the possibility to do whatever you want.

So my question is: if the main reason is to have a single image for all your iMX6 boards, why cannot we do it in a standard way using SPL ?

Quoted 11 lines

The other key change for these processors is the location of the iomux controller (moved on 6Solo/Duallite from 6Quad).

6Solo has 32-bit DDR and iomux controller moved from 6Q 6Duallite has 64-bit DDR but same iomux location as 6Q

Note that this highlights a slight down side to the plugin approach.

Because of the movement of the iomux controller, we can't use a universal i.MX6 image header to write any IOMUX registers through imximage.cfg.

However, you can do it with this approach:

- you have a general imx header, that does not write into IOMUX It is your choice if this should set the DDR or not. You could also decide to have an empty DCD table.
- your imx Header is generated for your SPL code, and the destination address for the SPL code is put into internal RAM
- the bootROM will start reading the iMX header and DCD data and copies data from media (NAND, SPI, ..) into iRAM. There is no need for any special setup because the iRAM is always available. Then it gives the control to the SPL.
- the SPL starts and performs the setup of the DDR, checking the SOC if it is required. The usual SOC initialization is done here.
- At the end, the SPL loads from media the U-Boot or directly the kernel and starts it. Or whatever image you want.

The further advantage we can have with this approach is that we can profit for further development in u-boot. What I mean really is using TPL, that means putting u-boot into a UBL volume, see:

Quoted 8 lines

http://lists.celinuxforum.org/pipermail/celinux-dev/2012-April/000543.html

I know there is not yet activity on this topic, but it does not mean we have not in future.

Best regards,
Stefano Babic

The advantages of a plugin over spl are
1. smaller code 0x190 bytes, plus the table.
relying on the ROM to do the heavy lifting.

2. support all boot modes that the ROM does.
NOR/NAND/ONENAND/MMC/eMMC
Hard Disk and SSD devices using SATA
Serial ROM through SPI/I2C

3. Easy to switch back to previous DCD tables for debugging or permanently. I can see that many people will never use either plugin or SPL and will stick with the current method, or have separate cfg files for each processor type. I could still have the separate cfg files #include a common file. ie
#define FOR_MX6Q
#include "imx-common.cfg"
------------
#define FOR_MX6DL
#include "imx-common.cfg"

4. plugin method is already working.

Let me know which features might make it to mainline
1. variable length headers
2. parsing of cfg to pull the file, instead of push
3. C preprocessor
4. expression evaluation.
5 plugins

and I'll post a new series.

Thanks
Troy

#44 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

Quoted 3 lines · Troy Kisky

The advantages of a plugin over spl are
1. smaller code 0x190 bytes, plus the table. relying on the ROM to do the heavy lifting.

This is true. However, as you are writing in the next line, the bootROM boots from devices having much more space as some bytes. Even on small SPI-NOR (the smallest device I used with MX5), this was not an issue.

On the other side, you cannot influence the behavior of the bootROM, and much more job is let to the bootROM, less possibilities to fix some things. SPL is part of U-Boot, all sources are availbale and it is easier to fix.

Quoted 5 lines

2. support all boot modes that the ROM does. NOR/NAND/ONENAND/MMC/eMMC
Hard Disk and SSD devices using SATA
Serial ROM through SPI/I2C

I do not know about booting from SATA, if a plugin is a must - but this means that it fixes a problem in the bootROM.
Apart of that, there are no hardware limitation that avoi to use SPL with these media devices.

Quoted 3 lines

3. Easy to switch back to previous DCD tables for debugging or permanently. I can see that many people will never use either plugin or SPL

I think you are talking specifically about mainlined i.MX boards. This is correct, because patches to make SPL available will be merged now. But if we see U-Boot in its globality, quite all TI's boards have a SPL.

Quoted 7 lines

and will stick
with the current method, or have separate cfg files for each processor type. I could still have the separate cfg files #include a common file. ie
#define FOR_MX6Q
#include "imx-common.cfg"

Using common file is a practice we should improve, definitely. But it has nothing to do with plugin. Agree that similar boards and / or SOCs should better share code.

Quoted 5 lines

------------
#define FOR_MX6DL
#include "imx-common.cfg"

4. plugin method is already working.

ok, this is right

Quoted 2 lines

Let me know which features might make it to mainline
1. variable length headers

Absolutely yes !

Quoted 2 lines

2. parsing of cfg to pull the file, instead of push
3. C preprocessor

Yes, I agree with you that it is useful. As you said, using #define make it more readable.

Quoted 1 line

4. expression evaluation.

As you posted previously, this depends on plugin.

Quoted 1 line

5 plugins

Currently, I do not see that plugin is strictly required and can move iMX away from the rest of U-Boot development.

Quoted 2 lines

and I'll post a new series.

Ok, thanks.

Best regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#45 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

In reply to Stefano Babic
Quoted 16 lines · Stefano Babic
Quoted 5 lines · Troy Kisky

The "plugin" command of mkimage can take this
file as an argument.

---

Hi Troy,

I agree with Vikram that a better explanation of what a plugin is can help to understand without reading deeply into the i.MX6 manual.

So a "plugin" is a chunk of code that can be called directly by the BootROM of i.MX processors supporting V2 version of the i.MX header. In my understanding, this is supported by i.MX53, too. After the plugin run, the control is returned to the BootROM.

Quoted 5 lines

Now that we have some basis, why do we need this mechanism to boot this board ? Is it not possible to make the same initialization directly in u-boot ?

In principle, this adds stil some code that is not so easy to maintain.

I can add to README.imximage. But I'm beginning to doubt if plugins are going
to be accepted at all.

Quoted 21 lines
Quoted 21 lines
  arch/arm/cpu/armv7/mx6/Makefile          |    5 +-
  arch/arm/cpu/armv7/mx6/plugin.S          |  164 ++++++++++++++++++++++++++++++
  arch/arm/include/asm/arch-mx6/imx-regs.h |    1 +
  3 files changed, 169 insertions(+), 1 deletion(-)

create mode 100644 arch/arm/cpu/armv7/mx6/plugin.S

arch/arm/cpu/armv7/mx6/Makefile +1 -1
index cbce411..b1fce4e 100644
@@ -33,11 +33,14 @@ SOBJS   = lowlevel_init.o
  SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
  OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
 
-all:	$(obj).depend $(LIB)
+all:	$(obj).depend $(LIB) plugin.bin
 
  $(LIB):	$(OBJS)
  	$(call cmd_link_o_target, $(OBJS))
 
Quoted 6 lines

arch/arm/cpu/armv7/mx6/Makefile SOBJS = lowlevel_init.o · line 42

Quoted 2 lines
arch/arm/cpu/armv7/mx6/Makefile +2 -0
+plugin.bin: plugin.o
+	$(OBJCOPY) -O binary --gap-fill 0xff $< $@

If we add a plugin mechanism, we can have several plugins (booting directly from Net, maybe ?). We should then have a general mechanism. A directory "plugins" here can contain the code, and it is compiled only if a CONFIG_ is set or better if required from imximage.cfg

CONFIG_xx I understand, but can you describe an implementation from imximage.cfg?

Quoted 96 lines
Quoted 73 lines
arch/arm/cpu/armv7/mx6/Makefile +1 -0
+
  #########################################################################
 
  # defines $(obj).depend target
arch/arm/cpu/armv7/mx6/plugin.S new file +61 -0
new file mode 100644
index 0000000..99c6b20
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2012 Boundary Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+#include <config.h>
+#include <asm/arch/imx-regs.h>
+
+#define HAB_RVT_ENTRY		0x98
+#define HAB_RVT_FAIL_SAFE_VECT	0xbc
+#define HAB_RVT_LOAD_DATA	0xc8
+
+#define HDR_SELF_PTR	0x14
+#define HDR_BOOT_DATA	0x20
+#define HDR_IMAGE_LEN	0x24
+
+#define L2X0_CTRL	0x100
+#define SCU_CONFIG	0x004
+
+/*
+ * Disable L2 cache because ROM will turn it on when a plugin is used.
+ * There are cache coherence problems if cache is on when Linux kernel
+ * expects it to be off.
+ */
+.macro disable_l2_cache
+	ldr	r1, =L2_BASE_ADDR
+	mov	r0, #0x0
+	str	r0, [r1, #L2X0_CTRL]
+.endm
+
+
+/*
+ * plugin_start(void **start, size_t *bytes, UINT32 *ivt_offset)
+ */
+plugin_start:
+/* Save the return address and the function arguments */
+	push	{r0-r8, lr}
+
+/* r0-r2 must be  >= 0x100 and must be 4 byte aligned */
+	cmp	r0, #0x100
+	cmphs	r1, #0x100
+	cmphs	r2, #0x100
+
+/* rCPU: 22 - mx6q, 12 - mx6dl, 12|0x100 - solo, 2 - sololite */
+#define rCPU	r2
+#define rIomux	r3
+#define rVal0	r4	/* mx6q value */
+#define rVal1	r5	/* mx6dl value */
+#define rVal2	r6	/* mx6solo value */
+#define rVal3	r7	/* mx6sololite value */
+#define rFlag	lr
+#define rTable	r8
+
+	orr	rFlag, r0, r1
+	orr	rFlag, rFlag, r2
+	orrlo	rFlag, rFlag, #1
+
+	mov	rCPU, #22		/* mx6q */
+	mov	r1, #SCU_BASE_ADDR
+	ldr	r0, [r1, #SCU_CONFIG]
+	and	r0, r0, #3

arch/arm/cpu/armv7/mx6/plugin.S line 71

Quoted 10 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +10 -0
+	cmp	r0, #3			/* is mx6q? */
+	movne	rCPU, #12		/* mx6dl */
+	cmpne	r0, #1			/* is mx6dl? */
+	movne	rCPU, #2		/* mx6 sololite */
+
+	ldrne	r1, =ANATOP_BASE_ADDR
+	ldrne	r0, [r1, #0x280]
+	movne	r0, r0, LSR #16
+	cmpne	r0, #0x60		/* is mx6 Sololite? */
+	movne	rCPU, #12 | 0x100	/* Solo */

Ok - until here you have checked which processor is running. Now the more obscure code:

Quoted 8 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +8 -0
+
+	mov	rVal0, #0
+	mov	rVal1, #0
+	mov	rVal2, #0
+	mov	rVal3, #0
+	ldr	rIomux, =IOMUXC_BASE_ADDR
+	adr	rTable, mx6_table
+	b	3f
Quoted 13 lines

arch/arm/cpu/armv7/mx6/plugin.S line 89

Quoted 10 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +10 -0
+
+1:	movs	r0, r1, LSR #30
+	beq	2f
+	mov	r1, r1, LSL rCPU
+	movs	r1, r1, LSR #32-10
+	addne	r1, rIomux, r1, LSL #2
+	cmp	r0, #3
+	subne	r0, r0, #1
+	orr	r1, r1, r0
+

The reason is to write GPR12 ? But why do we need a plugin for that ? I do not understand why we cannot do it in the initialization code of the SOC, as we usually do.

This is not GPR12. The address value from the cfg file is actually 3 addresses. One for
mx6q, one for mx6 duallite/solo, one for mx6 sololite. Each is specified as a 10 bit
field which we use as a 12 bit offset within IOMUXC_BASE_ADDR (A0/A1 forced to 0).

Quoted 41 lines
Quoted 41 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +40 -0
+2:	ands	r0, r1, #3
+	bic	r1, r1, #3
+	ldrne	rVal0, [rTable], #4
+	movne	rVal1, rVal0
+	movne	rVal2, rVal0
+	movne	rVal3, rVal0
+	subnes	r0, r0, #1
+	ldrne	rVal1, [rTable], #4
+	movne	rVal2, rVal1
+	movne	rVal3, rVal1
+	subnes	r0, r0, #1
+	ldrne	rVal2, [rTable], #4
+	ldrne	rVal3, [rTable], #4
+
+	mov	r0, rVal0
+	cmp	rCPU, #22
+	movne	r0, rVal1
+	cmpne	rCPU, #12
+	movne	r0, rVal2
+	cmpne	rCPU, #12|0x100
+	movne	r0, rVal3
+	cmp	r1, #0
+	strne	r0, [r1]
+3:	ldr	r1, [rTable], #4
+	cmp	r1, #0
+	bne	1b
+
+	tst	rFlag, #3
+	bne	4f		/* Branch if not called as plugin */
+/* Align end of table to 64 byte boundary */
+	sub	rTable, rTable, #1
+	orr	rTable, rTable, #0x3f
+	add	rTable, rTable, #1
+	ldr	r2, [rTable, #HDR_SELF_PTR]
+	ldr	r0, [rTable, #HDR_BOOT_DATA]
+	ldr	r1, [rTable, #HDR_IMAGE_LEN]
+	sub	rTable, r2, r0
+	mov	r2, r0
+	mov	r3, r1
+	mov	r4, #0
Quoted 8 lines

arch/arm/cpu/armv7/mx6/plugin.S line 136

Quoted 7 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +7 -0
+	push	{r0-r4}
+	mov	r0, #HAB_RVT_LOAD_DATA
+	ldr	r4, [r0]
+	mov	r0, sp
+	add	r1, sp, #4
+	add	r2, sp, #8
+	blx	r4

Sorry, I need help to understand this code

Now that DDR is initialized, this is calling back into the ROM code so that it can finish loading u-boot.

Quoted 12 lines

arch/arm/cpu/armv7/mx6/plugin.S line 145

Quoted 10 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +9 -0
+
+	disable_l2_cache
+	pop	{r4, r5}
+	add	sp, sp, #12
+	pop	{r0-r3}
+/*
+ * Before returning to ROM, we need to fill the return values arguments
+ * to our function.
+ * plugin_start(void **start, size_t *bytes, UINT32 *ivt_offset)

As the i.MX and the API suggest, it should be possible to write C code for a plugin. Or am I wrong ?

I don't see why not. But this code is currently position independent. It would be nice to maintain that.

Quoted 18 lines
Quoted 8 lines
arch/arm/include/asm/arch-mx6/imx-regs.h +0 -0
index 8834c59..5c133b2 100644

arch/arm/include/asm/arch-mx6/imx-regs.h line 54

Quoted 7 lines
arch/arm/include/asm/arch-mx6/imx-regs.h +1 -0
@@ -48,6 +48,7 @@
  #define GLOBAL_TIMER_BASE_ADDR          0x00A00200
  #define PRIVATE_TIMERS_WD_BASE_ADDR     0x00A00600
  #define IC_DISTRIBUTOR_BASE_ADDR        0x00A01000
+#define L2_BASE_ADDR                    0x00A02000
  #define GPV0_BASE_ADDR                  0x00B00000
  #define GPV1_BASE_ADDR                  0x00C00000
  #define PCIE_ARB_BASE_ADDR              0x01000000

This is useful in any case. I suggest you put this define in a separate patch, that can flow independently into mainline.

Quoted 3 lines

Best regards,
Stefano Babic

Hmm, do you suggest moving the L2 disable code to another spot as well ?

#46 lore raw

PATCH v2 8/21 mx6: add plugin file for use with imximage.cfg

Quoted 7 lines · Troy Kisky
Quoted 6 lines · Stefano Babic
Quoted 5 lines · Troy Kisky

The "plugin" command of mkimage can take this
file as an argument.

---

Hi Troy,

Quoted 13 lines
Quoted 13 lines

I agree with Vikram that a better explanation of what a plugin is can help to understand without reading deeply into the i.MX6 manual.

So a "plugin" is a chunk of code that can be called directly by the BootROM of i.MX processors supporting V2 version of the i.MX header. In my understanding, this is supported by i.MX53, too. After the plugin run, the control is returned to the BootROM.

Now that we have some basis, why do we need this mechanism to boot this board ? Is it not possible to make the same initialization directly in u-boot ?

Quoted 5 lines
Quoted 1 line

In principle, this adds stil some code that is not so easy to maintain.

I can add to README.imximage. But I'm beginning to doubt if plugins are going
to be accepted at all.

I have several doubts about using the plugin. First at all, this make the development of new iMX completely different as the rest of U-boot. Plugin ist a feature so strictly bounded to the Freescale's iMX. The risk here is that U-Boot imx diverges from the other SOCs, while we are currently in a phase where we want to uniform as much as possible the behavior with different architectures.

I am also not convinced why introducing the plugin is strictly required. Reading Eric's answer, I get that costs for having and maintaing a single image U-boot for different boards overcomes the benefits, and I fully agree with him. But reading your patch and from your explanation of plugin code, I understand that the plugin is used to detect which CPU is running, and then to set differently registers, because offsets are different. So the goal is again to have a single image.

Quoted 14 lines
Quoted 5 lines
Quoted 5 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +5 -0
+
+1:    movs    r0, r1, LSR #30
+    beq    2f
+    mov    r1, r1, LSL rCPU
+    movs    r1, r1, LSR #32-10
Quoted 8 lines

arch/arm/cpu/armv7/mx6/plugin.S line 89

Quoted 5 lines
arch/arm/cpu/armv7/mx6/plugin.S new file +5 -0
+    addne    r1, rIomux, r1, LSL #2
+    cmp    r0, #3
+    subne    r0, r0, #1
+    orr    r1, r1, r0
+

The reason is to write GPR12 ? But why do we need a plugin for that ? I do not understand why we cannot do it in the initialization code of the SOC, as we usually do.

Quoted 6 lines

This is not GPR12. The address value from the cfg file is actually 3 addresses. One for
mx6q, one for mx6 duallite/solo, one for mx6 sololite. Each is specified as a 10 bit
field which we use as a 12 bit offset within IOMUXC_BASE_ADDR (A0/A1 forced to 0).

Ok, thanks for explanation - I had not understood before.

Quoted 12 lines
Quoted 11 lines

arch/arm/include/asm/arch-mx6/imx-regs.h line 54

Quoted 9 lines
arch/arm/include/asm/arch-mx6/imx-regs.h +1 -0
@@ -48,6 +48,7 @@
  #define GLOBAL_TIMER_BASE_ADDR          0x00A00200
  #define PRIVATE_TIMERS_WD_BASE_ADDR     0x00A00600
  #define IC_DISTRIBUTOR_BASE_ADDR        0x00A01000
+#define L2_BASE_ADDR                    0x00A02000
  #define GPV0_BASE_ADDR                  0x00B00000
  #define GPV1_BASE_ADDR                  0x00C00000
  #define PCIE_ARB_BASE_ADDR              0x01000000

This is useful in any case. I suggest you put this define in a separate patch, that can flow independently into mainline.

Quoted 1 line

Hmm, do you suggest moving the L2 disable code to another spot as well ?

Easier - I suggest you put this define in a separate patch, because it can be accessed by other U-Boot code as well.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#47 lore raw

PATCH v2 9/21 mx6q_4x_mt41j128.cfg: use symbols instead of hardcoded constants

In reply to Troy Kisky

This allows us to generate plugin data or
DCD rom style data simply by defining USE_PLUGIN

---
 arch/arm/include/asm/arch-mx6/imx-mkimage.h  |  177 ++++++++++++++++++
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |  248 +++++++++++++-------------
 2 files changed, 304 insertions(+), 121 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-mx6/imx-mkimage.h
arch/arm/include/asm/arch-mx6/imx-mkimage.h new file +177 -0
new file mode 100644
index 0000000..be71983
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2012 Boundary Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+#ifndef __ASM_ARCH_IMX_MKIMAGE_H__
+#define __ASM_ARCH_IMX_MKIMAGE_H__
+
+/* mx6 duallite and solo have same offsets */
+/*
+ * Bits 31:30 :
+ *  0 : 29:2 absolute address, 1:0 # of data values,
+ *	followed by 0,1,2,4 data values
+ *	0 means repeat last data value
+ *  1 : iomuxc relative address, 9:0 mx6q offset, 19:10 mx6dl/solo offset,
+ *	29:20 mx6_sololite offset, 0 offset means skip if this processor
+ *	previous data repeated
+ *  2 : same as 1, but single data value follows
+ *  3 : same as 1, but 4 data values follow
+ *
+ * data order is mx6q, mx6dl, mx6solo, mx6_sololite
+ * if no data given, repeat previous line data
+ * if not all data given, repeat prior value
+ */
+#define MA(mx6q, mx6dl_solo, mx6sololite)	((mx6q / 4 & 0x3ff) | \
+		((mx6dl_solo / 4 & 0x3ff) * 0x400) | \
+		((mx6sololite / 4 & 0x3ff) * 0x100000))
+
+#define IOM_DRAM_DQM0		MA(0x5ac, 0x470, 0x0)
+#define IOM_DRAM_DQM1		MA(0x5b4, 0x474, 0x0)
+#define IOM_DRAM_DQM2		MA(0x528, 0x478, 0x0)
+#define IOM_DRAM_DQM3		MA(0x520, 0x47c, 0x0)
+#define IOM_DRAM_DQM4		MA(0x514, 0x480, 0x0)
+#define IOM_DRAM_DQM5		MA(0x510, 0x484, 0x0)
+#define IOM_DRAM_DQM6		MA(0x5bc, 0x488, 0x0)
+#define IOM_DRAM_DQM7		MA(0x5c4, 0x48c, 0x0)
+
+#define IOM_DRAM_CAS		MA(0x56c, 0x464, 0x0)
+#define IOM_DRAM_RAS		MA(0x578, 0x490, 0x0)
+#define IOM_DRAM_RESET		MA(0x57c, 0x494, 0x0)
+#define IOM_DRAM_SDCLK_0	MA(0x588, 0x4ac, 0x0)
+#define IOM_DRAM_SDCLK_1	MA(0x594, 0x4b0, 0x0)
+#define IOM_DRAM_SDBA2		MA(0x58c, 0x4a0, 0x0)
+#define IOM_DRAM_SDCKE0		MA(0x590, 0x4a4, 0x0)
+#define IOM_DRAM_SDCKE1		MA(0x598, 0x4a8, 0x0)
+#define IOM_DRAM_SDODT0		MA(0x59c, 0x4b4, 0x0)
+#define IOM_DRAM_SDODT1		MA(0x5a0, 0x4b8, 0x0)
+
+#define IOM_DRAM_SDQS0		MA(0x5a8, 0x4bc, 0x0)
+#define IOM_DRAM_SDQS1		MA(0x5b0, 0x4c0, 0x0)
+#define IOM_DRAM_SDQS2		MA(0x524, 0x4c4, 0x0)
+#define IOM_DRAM_SDQS3		MA(0x51c, 0x4c8, 0x0)
+#define IOM_DRAM_SDQS4		MA(0x518, 0x4cc, 0x0)
+#define IOM_DRAM_SDQS5		MA(0x50c, 0x4d0, 0x0)
+#define IOM_DRAM_SDQS6		MA(0x5b8, 0x4d4, 0x0)
+#define IOM_DRAM_SDQS7		MA(0x5c0, 0x4d8, 0x0)
+
+#define IOM_GRP_B0DS		MA(0x784, 0x764, 0x0)
+#define IOM_GRP_B1DS		MA(0x788, 0x770, 0x0)
+#define IOM_GRP_B2DS		MA(0x794, 0x778, 0x0)
+#define IOM_GRP_B3DS		MA(0x79c, 0x77c, 0x0)
+#define IOM_GRP_B4DS		MA(0x7a0, 0x780, 0x0)
+#define IOM_GRP_B5DS		MA(0x7a4, 0x784, 0x0)
+#define IOM_GRP_B6DS		MA(0x7a8, 0x78c, 0x0)
+#define IOM_GRP_B7DS		MA(0x748, 0x748, 0x0)
+#define IOM_GRP_ADDDS		MA(0x74c, 0x74c, 0x0)
+#define IOM_DDRMODE_CTL		MA(0x750, 0x750, 0x0)
+#define IOM_GRP_DDRPKE		MA(0x758, 0x754, 0x0)
+#define IOM_GRP_DDRMODE		MA(0x774, 0x760, 0x0)
+#define IOM_GRP_CTLDS		MA(0x78c, 0x76c, 0x0)
+#define IOM_GRP_DDR_TYPE	MA(0x798, 0x774, 0x0)
+
+#define MMDC_P0		0x021b0000
+#define MMDC_P1		0x021b4000
+#define IOMUXC_BASE_ADDR 0x020e0000
+#define CCM_BASE	0x020C4000
+#define IRAM_FREE_START		0x00907000
+
+#define IOMUXC_GPR4		(IOMUXC_BASE_ADDR + 0x010)
+#define IOMUXC_GPR6		(IOMUXC_BASE_ADDR + 0x018)
+#define IOMUXC_GPR7		(IOMUXC_BASE_ADDR + 0x01c)
+
+#define MMDC_MDCTL		0x000
+#define MMDC_MDPDC		0x004
+#define MMDC_MDOTC		0x008
+#define MMDC_MDCFG0		0x00c
+#define MMDC_MDCFG1		0x010
+#define MMDC_MDCFG2		0x014
+#define MMDC_MDMISC		0x018
+#define MMDC_MDSCR		0x01c
+#define MMDC_MDREF		0x020
+#define MMDC_MDRWD		0x02c
+#define MMDC_MDOR		0x030
+#define MMDC_MDASP		0x040
+#define MMDC_MAPSR		0x404
+#define MMDC_MPZQHWCTRL		0x800
+#define MMDC_MPWLDECTRL0	0x80c
+#define MMDC_MPWLDECTRL1	0x810
+#define MMDC_MPODTCTRL		0x818
+#define MMDC_MPRDDQBY0DL	0x81c
+#define MMDC_MPRDDQBY1DL	0x820
+#define MMDC_MPRDDQBY2DL	0x824
+#define MMDC_MPRDDQBY3DL	0x828
+#define MMDC_MPDGCTRL0		0x83c
+#define MMDC_MPDGCTRL1		0x840
+#define MMDC_MPRDDLCTL		0x848
+#define MMDC_MPWRDLCTL		0x850
+#define MMDC_MPMUR0		0x8b8
+
+#define CCM_CCGR0		0x068
+#define CCM_CCGR1		0x06c
+#define CCM_CCGR2		0x070
+#define CCM_CCGR3		0x074
+#define CCM_CCGR4		0x078
+#define CCM_CCGR5		0x07c
+#define CCM_CCGR6		0x080
+
+
+#ifdef USE_PLUGIN
+#define IOMUX_ENTRY(addr, args...)	iomux_entry addr, args
+#define IOMUX_ENTRY1(addr, q)		IOMUX_ENTRY(addr, q)
+#define IOMUX_ENTRY2(addr, q, dl)	IOMUX_ENTRY(addr, q, dl)
+#define IOMUX_ENTRY3(addr, q, dl, solo)	IOMUX_ENTRY(addr, q, dl, solo)
+#define IOMUX_ENTRY4(addr, q, dl, solo, sl) IOMUX_ENTRY(addr, q, dl, solo, sl)
+#define WRITE_ENTRY(addr, args...)	write_entry addr, args
+#define WRITE_ENTRY1(addr, q)		WRITE_ENTRY(addr, q)
+#define WRITE_ENTRY2(addr, q, dl)	WRITE_ENTRY(addr, q, dl)
+#define WRITE_ENTRY3(addr, q, dl, solo)	WRITE_ENTRY(addr, q, dl, solo)
+#define WRITE_ENTRY4(addr, q, dl, solo, sl) WRITE_ENTRY(addr, q, dl, solo, sl)
+#else
+
+#define IOMUX_ADDR(addr, div)	(IOMUXC_BASE_ADDR + \
+		((((addr) / (div)) & 0x3ff) * 4))
+#define IOMUX_ENTRY1(addr, q)		DATA 4, IOMUX_ADDR(addr, _FOR_DIV), q
+#define WRITE_ENTRY1(addr, q)		DATA 4, addr, q
+#ifdef FOR_MX6Q
+#define _FOR_DIV	1
+#define IOMUX_ENTRY2(addr, q, dl)		IOMUX_ENTRY1(addr, q)
+#define WRITE_ENTRY2(addr, q, dl)		WRITE_ENTRY1(addr, q)
+#define IOMUX_ENTRY3(addr, q, dl, solo)		IOMUX_ENTRY1(addr, q)
+#define WRITE_ENTRY3(addr, q, dl, solo)		WRITE_ENTRY1(addr, q)
+#define IOMUX_ENTRY4(addr, q, dl, solo, sl)	IOMUX_ENTRY1(addr, q)
+#define WRITE_ENTRY4(addr, q, dl, solo, sl)	WRITE_ENTRY1(addr, q)
+#else
+
+#define IOMUX_ENTRY2(addr, q, dl)		IOMUX_ENTRY1(addr, dl)
+#define WRITE_ENTRY2(addr, q, dl)		WRITE_ENTRY1(addr, dl)
+#ifdef FOR_MX6DL
+#define _FOR_DIV	0x400
+#define IOMUX_ENTRY3(addr, q, dl, solo)		IOMUX_ENTRY1(addr, dl)
+#define WRITE_ENTRY3(addr, q, dl, solo)		WRITE_ENTRY1(addr, dl)
+#define IOMUX_ENTRY4(addr, q, dl, solo, sl)	IOMUX_ENTRY1(addr, dl)
+#define WRITE_ENTRY4(addr, q, dl, solo, sl)	WRITE_ENTRY1(addr, dl)
+#else
+
+#define IOMUX_ENTRY3(addr, q, dl, solo)		IOMUX_ENTRY1(addr, solo)
+#define WRITE_ENTRY3(addr, q, dl, solo)		WRITE_ENTRY1(addr, solo)
+#ifdef FOR_MX6SOLO
+#define _FOR_DIV	0x400
+#define IOMUX_ENTRY4(addr, q, dl, solo, sl)	IOMUX_ENTRY1(addr, solo)
+#define WRITE_ENTRY4(addr, q, dl, solo, sl)	WRITE_ENTRY1(addr, solo)
+#else
+
+#define IOMUX_ENTRY4(addr, q, dl, solo, sl)	IOMUX_ENTRY1(addr, sl)
+#define WRITE_ENTRY4(addr, q, dl, solo, sl)	WRITE_ENTRY1(addr, sl)
+#ifdef FOR_MX6SOLOLITE
+#define _FOR_DIV	0x100000
+#else
+
+#error "Please select cpu"
+#endif	/* FOR_MX6SOLOLITE */
+#endif	/* FOR_MX6SOLO */
+#endif	/* FOR_MX6DL */
+#endif	/* FOR_MX6Q */
+#endif	/* USE_PLUGIN */
+
+#endif	/*__ASM_ARCH_IMX_MKIMAGE_H__ */
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +127 -121

268 lines not on this page · raw message

Signature · 1 line
1.7.9.5
author
#48 lore raw

PATCH v2 10/21 mx6q_4x_mt41j128.cfg: allow plugin to work

In reply to Troy Kisky

Enabling plugin mode seems to require this additional memory write for ddr3 initialization.

---
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |    2 ++
 1 file changed, 2 insertions(+)
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +2 -0
index a95831f..eea8d3a 100644
@@ -111,6 +111,8 @@ WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY0DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY1DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY2DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY3DL, 0x33333333)
+/* MDPDC - CKE pulse width = 3 cycles. CKSRE = 6 cycles, CKSRX = 6 cycles */
+WRITE_ENTRY1(MMDC_P0 + MMDC_MDPDC, 0x00020036)
 
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDMISC, 0x00081740)
 
Signature · 1 line
1.7.9.5
author
#49 lore raw

PATCH v2 11/21 mx6q_4x_mt41j128.cfg: enable plugin mode

In reply to Troy Kisky
---
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +1 -1
index eea8d3a..2af4265 100644
@@ -26,7 +26,7 @@
  * The syntax is taken as close as possible with the kwbimage
  */
 #define FOR_MX6Q
-
+#define USE_PLUGIN
 #include <asm/arch/imx-mkimage.h>
 
 /* image version */
Signature · 1 line
1.7.9.5
author
#50 lore raw

PATCH v2 12/21 mx6q_4x_mt41j128.cfg: add comments

In reply to Troy Kisky
---
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |   56 ++++++++++++++++++++++----
 1 file changed, 48 insertions(+), 8 deletions(-)
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +48 -8
index 2af4265..3a1f1bc 100644
@@ -56,7 +56,6 @@ IOMUX_ENTRY1(IOM_DRAM_SDQS0, 0x00000030)
 IOMUX_ENTRY1(IOM_DRAM_SDQS1, 0x00000030)
 IOMUX_ENTRY1(IOM_DRAM_SDQS2, 0x00000030)
 IOMUX_ENTRY1(IOM_DRAM_SDQS3, 0x00000030)
-
 IOMUX_ENTRY1(IOM_DRAM_SDQS4, 0x00000030)
 IOMUX_ENTRY1(IOM_DRAM_SDQS5, 0x00000030)
 IOMUX_ENTRY1(IOM_DRAM_SDQS6, 0x00000030)
@@ -66,7 +65,6 @@ IOMUX_ENTRY1(IOM_DRAM_DQM0, 0x00020030)
 IOMUX_ENTRY1(IOM_DRAM_DQM1, 0x00020030)
 IOMUX_ENTRY1(IOM_DRAM_DQM2, 0x00020030)
 IOMUX_ENTRY1(IOM_DRAM_DQM3, 0x00020030)
-
 IOMUX_ENTRY1(IOM_DRAM_DQM4, 0x00020030)
 IOMUX_ENTRY1(IOM_DRAM_DQM5, 0x00020030)
 IOMUX_ENTRY1(IOM_DRAM_DQM6, 0x00020030)
@@ -84,67 +82,108 @@ IOMUX_ENTRY1(IOM_DRAM_SDBA2, 0x00000000)
 
 IOMUX_ENTRY1(IOM_DRAM_SDODT0, 0x00003030)
 IOMUX_ENTRY1(IOM_DRAM_SDODT1, 0x00003030)
+
 IOMUX_ENTRY1(IOM_GRP_B0DS, 0x00000030)
 IOMUX_ENTRY1(IOM_GRP_B1DS, 0x00000030)
-
 IOMUX_ENTRY1(IOM_GRP_B2DS, 0x00000030)
 IOMUX_ENTRY1(IOM_GRP_B3DS, 0x00000030)
 IOMUX_ENTRY1(IOM_GRP_B4DS, 0x00000030)
 IOMUX_ENTRY1(IOM_GRP_B5DS, 0x00000030)
-
 IOMUX_ENTRY1(IOM_GRP_B6DS, 0x00000030)
 IOMUX_ENTRY1(IOM_GRP_B7DS, 0x00000030)
+
 IOMUX_ENTRY1(IOM_GRP_ADDDS, 0x00000030)
+/* (differential input) */
 IOMUX_ENTRY1(IOM_DDRMODE_CTL, 0x00020000)
-
+/* disable ddr pullups */
 IOMUX_ENTRY1(IOM_GRP_DDRPKE, 0x00000000)
+/* (differential input) */
 IOMUX_ENTRY1(IOM_GRP_DDRMODE, 0x00020000)
+/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */
 IOMUX_ENTRY1(IOM_GRP_CTLDS, 0x00000030)
 IOMUX_ENTRY1(IOM_GRP_DDR_TYPE, 0x000C0000)
 
+/* Read data DQ Byte0-3 delay */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPRDDQBY0DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPRDDQBY1DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPRDDQBY2DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPRDDQBY3DL, 0x33333333)
-
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY0DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY1DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY2DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY3DL, 0x33333333)
+
 /* MDPDC - CKE pulse width = 3 cycles. CKSRE = 6 cycles, CKSRX = 6 cycles */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDPDC, 0x00020036)
 
+/*
+ * MDMISC, mirroring, interleaved (row/bank/col)
+ */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDMISC, 0x00081740)
 
+/*
+ * MDSCR, con_req
+ */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x00008000)
+/*
+ * MDCFG0, tRFC=0x56 clocks, tXS=0x5b clocks
+ * tXP=4 clocks, tXPDLL=13 clocks
+ * tFAW=24 clocks, cas=8 cycles
+ */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDCFG0, 0x555A7975)
+/*
+ * MDCFG1, tRDC=8, tRP=8, tRC=27,tRAS=20,tRPA=tRP+1,tWR=8
+ * tMRD=4, tCWL=6
+ */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDCFG1, 0xFF538E64)
+/*
+ * MDCFG2,tDLLK=512,tRTP=4,tWTR=4,tRRD=4
+ */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDCFG2, 0x01FF00DB)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDRWD, 0x000026D2)
 
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDOR, 0x005B0E21)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDOTC, 0x09444040)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDPDC, 0x00025576)
+
+/*
+ * Mx6Q - 64 bit wide ddr
+ * last address is  (1<<28 (base) + 1<<30  - 1)  / (1<<25) =
+ * 	1<<3 + 1<<5 - 1 = 8 + 0x20 -1 = 0x27
+ */
+/* MDASP, CS0_END */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDASP, 0x00000027)
+/*
+ * MDCTL, CS0 enable, CS1 disabled, row=14, col=10, burst=8, width=64/32bit
+ * mx6q   : row+col+bank+width=14+10+3+3=30 = 1G
+ */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDCTL, 0x831A0000)
 
+/* MDSCR, con_req, LOAD MR2, CS0, A3,A10 set (CAS Write=6), RZQ/2 */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x04088032)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x0408803A)
+/* LOAD MR3, CS0 */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x00008033)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x0000803B)
+/* LOAD MR1, CS0, A1,A6 set Rtt=RZQ/2, ODI=RZQ/7 */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x00428031)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x00428039)
+/* LOAD MR0, CS0, A6,A8,A11 set CAS=8, WR=8, DLL reset */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x09408030)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x09408038)
 
+/* ZQ calibrate, CS0 */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x04008040)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x04008048)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPZQHWCTRL, 0xA1380003)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPZQHWCTRL, 0xA1380003)
+
+/* MDREF,  32KHz refresh, 4 refeshes each */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDREF, 0x00005800)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPODTCTRL, 0x00022227)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPODTCTRL, 0x00022227)
 
+/* MPDGCTRL0/1 DQS GATE*/
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPDGCTRL0, 0x434B0350)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPDGCTRL1, 0x034C0359)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPDGCTRL0, 0x434B0350)
@@ -153,17 +192,18 @@ WRITE_ENTRY1(MMDC_P0 + MMDC_MPRDDLCTL, 0x4436383B)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDLCTL, 0x39393341)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPWRDLCTL, 0x35373933)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPWRDLCTL, 0x48254A36)
-
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPWLDECTRL0, 0x001F001F)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPWLDECTRL1, 0x001F001F)
-
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPWLDECTRL0, 0x00440044)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPWLDECTRL1, 0x00440044)
 
+/* MPMUR0 - Complete calibration by forced measurement */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPMUR0, 0x00000800)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPMUR0, 0x00000800)
 
+/* MDSCR, enable ddr */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x00000000)
+/* MAPSR, 1024 cycles idle before self-refresh */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MAPSR, 0x00011006)
 
 /* set the default clock gate to save power */
Signature · 1 line
1.7.9.5
author
#51 lore raw

PATCH v2 13/21 mx6q_4x_mt41j128.cfg: use ddr3 mode for reset

In reply to Troy Kisky

Bits 19-18 of IOMUXC_IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET should be 3 for DDR3 mode. The current value of 0 is reserved in TRM.

---
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +1 -1
index 3a1f1bc..904276a 100644
@@ -75,7 +75,7 @@ IOMUX_ENTRY1(IOM_DRAM_RAS, 0x00020030)
 IOMUX_ENTRY1(IOM_DRAM_SDCLK_0, 0x00020030)
 IOMUX_ENTRY1(IOM_DRAM_SDCLK_1, 0x00020030)
 
-IOMUX_ENTRY1(IOM_DRAM_RESET, 0x00020030)
+IOMUX_ENTRY1(IOM_DRAM_RESET, 0x000e0030)
 IOMUX_ENTRY1(IOM_DRAM_SDCKE0, 0x00003000)
 IOMUX_ENTRY1(IOM_DRAM_SDCKE1, 0x00003000)
 IOMUX_ENTRY1(IOM_DRAM_SDBA2, 0x00000000)
Signature · 1 line
1.7.9.5
author
#52 lore raw

PATCH v2 14/21 mx6q_4x_mt41j128.cfg: skip initiailizing non-existent memory

In reply to Troy Kisky

Sabrelite does not have memory associated with CS1

---
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |    5 -----
 1 file changed, 5 deletions(-)
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +0 -5
index 904276a..18cdb7b 100644
@@ -161,20 +161,15 @@ WRITE_ENTRY1(MMDC_P0 + MMDC_MDCTL, 0x831A0000)
 
 /* MDSCR, con_req, LOAD MR2, CS0, A3,A10 set (CAS Write=6), RZQ/2 */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x04088032)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x0408803A)
 /* LOAD MR3, CS0 */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x00008033)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x0000803B)
 /* LOAD MR1, CS0, A1,A6 set Rtt=RZQ/2, ODI=RZQ/7 */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x00428031)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x00428039)
 /* LOAD MR0, CS0, A6,A8,A11 set CAS=8, WR=8, DLL reset */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x09408030)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x09408038)
 
 /* ZQ calibrate, CS0 */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x04008040)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x04008048)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPZQHWCTRL, 0xA1380003)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPZQHWCTRL, 0xA1380003)
 
Signature · 1 line
1.7.9.5
author
#53 lore raw

PATCH v2 15/21 mx6q_4x_mt41j128.cfg: reorder for more efficient storage

In reply to Troy Kisky

Repeating data values can be stored more efficiently.

---
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |   31 +++++++++++++-------------
 1 file changed, 15 insertions(+), 16 deletions(-)
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +15 -16
index 18cdb7b..00712c6 100644
@@ -60,6 +60,17 @@ IOMUX_ENTRY1(IOM_DRAM_SDQS4, 0x00000030)
 IOMUX_ENTRY1(IOM_DRAM_SDQS5, 0x00000030)
 IOMUX_ENTRY1(IOM_DRAM_SDQS6, 0x00000030)
 IOMUX_ENTRY1(IOM_DRAM_SDQS7, 0x00000030)
+IOMUX_ENTRY1(IOM_GRP_B0DS, 0x00000030)
+IOMUX_ENTRY1(IOM_GRP_B1DS, 0x00000030)
+IOMUX_ENTRY1(IOM_GRP_B2DS, 0x00000030)
+IOMUX_ENTRY1(IOM_GRP_B3DS, 0x00000030)
+IOMUX_ENTRY1(IOM_GRP_B4DS, 0x00000030)
+IOMUX_ENTRY1(IOM_GRP_B5DS, 0x00000030)
+IOMUX_ENTRY1(IOM_GRP_B6DS, 0x00000030)
+IOMUX_ENTRY1(IOM_GRP_B7DS, 0x00000030)
+IOMUX_ENTRY1(IOM_GRP_ADDDS, 0x00000030)
+/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */
+IOMUX_ENTRY1(IOM_GRP_CTLDS, 0x00000030)
 
 IOMUX_ENTRY1(IOM_DRAM_DQM0, 0x00020030)
 IOMUX_ENTRY1(IOM_DRAM_DQM1, 0x00020030)
@@ -78,29 +89,17 @@ IOMUX_ENTRY1(IOM_DRAM_SDCLK_1, 0x00020030)
 IOMUX_ENTRY1(IOM_DRAM_RESET, 0x000e0030)
 IOMUX_ENTRY1(IOM_DRAM_SDCKE0, 0x00003000)
 IOMUX_ENTRY1(IOM_DRAM_SDCKE1, 0x00003000)
-IOMUX_ENTRY1(IOM_DRAM_SDBA2, 0x00000000)
 
 IOMUX_ENTRY1(IOM_DRAM_SDODT0, 0x00003030)
 IOMUX_ENTRY1(IOM_DRAM_SDODT1, 0x00003030)
 
-IOMUX_ENTRY1(IOM_GRP_B0DS, 0x00000030)
-IOMUX_ENTRY1(IOM_GRP_B1DS, 0x00000030)
-IOMUX_ENTRY1(IOM_GRP_B2DS, 0x00000030)
-IOMUX_ENTRY1(IOM_GRP_B3DS, 0x00000030)
-IOMUX_ENTRY1(IOM_GRP_B4DS, 0x00000030)
-IOMUX_ENTRY1(IOM_GRP_B5DS, 0x00000030)
-IOMUX_ENTRY1(IOM_GRP_B6DS, 0x00000030)
-IOMUX_ENTRY1(IOM_GRP_B7DS, 0x00000030)
-
-IOMUX_ENTRY1(IOM_GRP_ADDDS, 0x00000030)
 /* (differential input) */
 IOMUX_ENTRY1(IOM_DDRMODE_CTL, 0x00020000)
-/* disable ddr pullups */
-IOMUX_ENTRY1(IOM_GRP_DDRPKE, 0x00000000)
 /* (differential input) */
 IOMUX_ENTRY1(IOM_GRP_DDRMODE, 0x00020000)
-/* 40 Ohm drive strength for cs0/1,sdba2,cke0/1,sdwe */
-IOMUX_ENTRY1(IOM_GRP_CTLDS, 0x00000030)
+/* disable ddr pullups */
+IOMUX_ENTRY1(IOM_GRP_DDRPKE, 0x00000000)
+IOMUX_ENTRY1(IOM_DRAM_SDBA2, 0x00000000)
 IOMUX_ENTRY1(IOM_GRP_DDR_TYPE, 0x000C0000)
 
 /* Read data DQ Byte0-3 delay */
@@ -180,8 +179,8 @@ WRITE_ENTRY1(MMDC_P1 + MMDC_MPODTCTRL, 0x00022227)
 
 /* MPDGCTRL0/1 DQS GATE*/
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPDGCTRL0, 0x434B0350)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MPDGCTRL1, 0x034C0359)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPDGCTRL0, 0x434B0350)
+WRITE_ENTRY1(MMDC_P0 + MMDC_MPDGCTRL1, 0x034C0359)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPDGCTRL1, 0x03650348)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPRDDLCTL, 0x4436383B)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDLCTL, 0x39393341)
Signature · 1 line
1.7.9.5
reviewer
#54 lore raw

PATCH v2 15/21 mx6q_4x_mt41j128.cfg: reorder for more efficient storage

Hi Troy,

Quoted 3 lines · Troy Kisky

Repeating data values can be stored more efficiently.

I am not a ddr init expert, but my understanding is that the DDR init sequence is important and probably we should keep it as is.

Regards,

Fabio Estevam

author
#55 lore raw

PATCH v2 15/21 mx6q_4x_mt41j128.cfg: reorder for more efficient storage

Quoted 6 lines · Fabio Estevam

Hi Troy,

Quoted 2 lines · Troy Kisky

Repeating data values can be stored more efficiently.

Quoted 8 lines
Quoted 1 line

I am not a ddr init expert, but my understanding is that the DDR init sequence is important and probably we should keep it as is.

Regards,

Fabio Estevam

The order of writes to IOMUXC registers is not important, other than to be finished
before accessing the DDR chips.

Troy

author
#56 lore raw

PATCH v2 16/21 mx6q_4x_mt41j128.cfg: force ZQ calibration

In reply to Troy Kisky
---
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +2 -2
index 00712c6..60eae86 100644
@@ -169,8 +169,8 @@ WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x09408030)
 
 /* ZQ calibrate, CS0 */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x04008040)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MPZQHWCTRL, 0xA1380003)
-WRITE_ENTRY1(MMDC_P1 + MMDC_MPZQHWCTRL, 0xA1380003)
+WRITE_ENTRY1(MMDC_P0 + MMDC_MPZQHWCTRL, 0xA1390003)
+WRITE_ENTRY1(MMDC_P1 + MMDC_MPZQHWCTRL, 0xA1390003)
 
 /* MDREF,  32KHz refresh, 4 refeshes each */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDREF, 0x00005800)
Signature · 1 line
1.7.9.5
author
#57 lore raw

PATCH v2 17/21 mx6: soc: add get_cpu_type

In reply to Troy Kisky

Add function to return the processor type.

i.e. MX6Q, MX6DL, MX6SOLO, MX6SOLOLITE

---
 arch/arm/cpu/armv7/mx6/soc.c              |   26 ++++++++++++++++++++++++++
 arch/arm/include/asm/arch-mx6/sys_proto.h |    6 ++++++
 2 files changed, 32 insertions(+)
arch/arm/cpu/armv7/mx6/soc.c +26 -0
index 7380ffe..5fce682 100644
@@ -44,6 +44,32 @@ u32 get_cpu_rev(void)
 	return system_rev;
 }
 
+struct scu_regs {
+	uint32_t	ctrl;
+	uint32_t	config;
+	uint32_t	status;
+	uint32_t	invalidate;
+	uint32_t	fpga_rev;
+};
+
+signed char cpu_type[] = {MXC_CPU_MX6SOLO, MXC_CPU_MX6DL, -1, MXC_CPU_MX6Q};
+
+int get_cpu_type(void)
+{
+	struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR;
+	uint32_t reg = readl(&scu->config) & 3;
+	int type = cpu_type[reg];
+
+	if (!reg) {
+		u32 cpu_type = readl(ANATOP_BASE_ADDR + 0x280);
+
+		cpu_type >>= 16;
+		if (cpu_type == 0x60)
+			type = MXC_CPU_MX6SL;       /* this is a soloLite */
+	}
+	return type;
+}
+
 void init_aips(void)
 {
 	struct aipstz_regs *aips1, *aips2;
arch/arm/include/asm/arch-mx6/sys_proto.h +6 -0
index 711b30d..997fc8e 100644
@@ -28,6 +28,12 @@
 
 u32 get_cpu_rev(void);
 
+#define MXC_CPU_MX6SL		60
+#define MXC_CPU_MX6DL		61
+#define MXC_CPU_MX6SOLO		62
+#define MXC_CPU_MX6Q		63
+
+int get_cpu_type(void);
 void set_vddsoc(u32 mv);
 
 /*
Signature · 1 line
1.7.9.5
reviewer
#58 lore raw

PATCH v2 17/21 mx6: soc: add get_cpu_type

Hi Troy,

Quoted 3 lines · Troy Kisky

Add function to return the processor type.

i.e. MX6Q, MX6DL, MX6SOLO, MX6SOLOLITE

On arch/arm/imx-common/cpu.c we have:

static const char *get_imx_type(u32 imxtype)

{
	switch (imxtype) {
	case 0x63:
		return "6Q";	/* Quad-core version of the mx6 */
	case 0x61:
		return "6DS";	/* Dual/Solo version of the mx6 */
	case 0x60:
		return "6SL";	/* Solo-Lite version of the mx6 */
	case 0x51:
		return "51";
	case 0x53:
		return "53";
	default:
		return "??";
	}
}

,which seems to serve the same purpose.

Regards,

Fabio Estevam

author
#59 lore raw

PATCH v2 17/21 mx6: soc: add get_cpu_type

Quoted 27 lines · Fabio Estevam

Hi Troy,

Quoted 3 lines · Troy Kisky

Add function to return the processor type.

i.e. MX6Q, MX6DL, MX6SOLO, MX6SOLOLITE

On arch/arm/imx-common/cpu.c we have:

static const char *get_imx_type(u32 imxtype)

{
	switch (imxtype) {
	case 0x63:
		return "6Q";	/* Quad-core version of the mx6 */
	case 0x61:
		return "6DS";	/* Dual/Solo version of the mx6 */
	case 0x60:
		return "6SL";	/* Solo-Lite version of the mx6 */
	case 0x51:
		return "51";
	case 0x53:
		return "53";
	default:
		return "??";
	}
}
Quoted 6 lines

,which seems to serve the same purpose.

Regards,

Fabio Estevam

No, not similar to get_imx_type, but it is similar to get_cpu_rev.

I guess I should fix get_imx_type, and get_cpu_rev, instead of adding a new one.

Thanks for the heads up!
Troy

#60 lore raw

PATCH v2 17/21 mx6: soc: add get_cpu_type

Quoted 32 lines · Troy Kisky
Quoted 31 lines · Fabio Estevam

Hi Troy,

Quoted 3 lines · Troy Kisky

Add function to return the processor type.

i.e. MX6Q, MX6DL, MX6SOLO, MX6SOLOLITE

On arch/arm/imx-common/cpu.c we have:

static const char *get_imx_type(u32 imxtype)

{
    switch (imxtype) {
    case 0x63:
        return "6Q";    /* Quad-core version of the mx6 */
    case 0x61:
        return "6DS";    /* Dual/Solo version of the mx6 */
    case 0x60:
        return "6SL";    /* Solo-Lite version of the mx6 */
    case 0x51:
        return "51";
    case 0x53:
        return "53";
    default:
        return "??";
    }
}

,which seems to serve the same purpose.

Regards,

Quoted 8 lines
Quoted 2 lines

Fabio Estevam

No, not similar to get_imx_type, but it is similar to get_cpu_rev.

I guess I should fix get_imx_type, and get_cpu_rev, instead of adding a new one.

Indeed. Try to use as much as possible code in imx-common, avoiding to duplicate code.

Best regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#61 lore raw

PATCH v2 18/21 arch-mx6: add mx6dl_pins.h

In reply to Troy Kisky

Only the values used in the sabrelite board are added currently. Add more as other boards use them.

---
 arch/arm/include/asm/arch-mx6/mx6dl_pins.h |  118 ++++++++++++++++++++++++++++
 1 file changed, 118 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-mx6/mx6dl_pins.h
arch/arm/include/asm/arch-mx6/mx6dl_pins.h new file +118 -0
new file mode 100644
index 0000000..5848013
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef __ASM_ARCH_MX6_MX6DL_PINS_H__
+#define __ASM_ARCH_MX6_MX6DL_PINS_H__
+
+#include <asm/imx-common/iomux-v3.h>
+
+/* Use to set PAD control */
+#define PAD_CTL_HYS		(1 << 16)
+#define PAD_CTL_PUS_100K_DOWN	(0 << 14)
+#define PAD_CTL_PUS_47K_UP	(1 << 14)
+#define PAD_CTL_PUS_100K_UP	(2 << 14)
+#define PAD_CTL_PUS_22K_UP	(3 << 14)
+
+#define PAD_CTL_PUE		(1 << 13)
+#define PAD_CTL_PKE		(1 << 12)
+#define PAD_CTL_ODE		(1 << 11)
+#define PAD_CTL_SPEED_LOW	(1 << 6)
+#define PAD_CTL_SPEED_MED	(2 << 6)
+#define PAD_CTL_SPEED_HIGH	(3 << 6)
+#define PAD_CTL_DSE_DISABLE	(0 << 3)
+#define PAD_CTL_DSE_240ohm	(1 << 3)
+#define PAD_CTL_DSE_120ohm	(2 << 3)
+#define PAD_CTL_DSE_80ohm	(3 << 3)
+#define PAD_CTL_DSE_60ohm	(4 << 3)
+#define PAD_CTL_DSE_48ohm	(5 << 3)
+#define PAD_CTL_DSE_40ohm	(6 << 3)
+#define PAD_CTL_DSE_34ohm	(7 << 3)
+#define PAD_CTL_SRE_FAST	(1 << 0)
+#define PAD_CTL_SRE_SLOW	(0 << 0)
+
+#define IOMUX_CONFIG_SION 0x10
+#define NO_MUX_I                0
+#define NO_PAD_I                0
+enum {
+	MX6DL_PAD_EIM_D16__ECSPI1_SCLK		= IOMUX_PAD(0x0514, 0x0144, 1, 0x07D8, 2, 0),
+	MX6DL_PAD_EIM_D17__ECSPI1_MISO		= IOMUX_PAD(0x0518, 0x0148, 1, 0x07DC, 2, 0),
+	MX6DL_PAD_EIM_D18__ECSPI1_MOSI		= IOMUX_PAD(0x051C, 0x014C, 1, 0x07E0, 2, 0),
+	MX6DL_PAD_EIM_D19__GPIO_3_19		= IOMUX_PAD(0x0520, 0x0150, 5, 0x0000, 0, 0),
+	MX6DL_PAD_EIM_D21__GPIO_3_21		= IOMUX_PAD(0x0528, 0x0158, 5, 0x0000, 0, 0),
+	MX6DL_PAD_EIM_D21__I2C1_SCL		= IOMUX_PAD(0x0528, 0x0158, 6 | IOMUX_CONFIG_SION, 0x0868, 1, 0),
+	MX6DL_PAD_EIM_D23__GPIO_3_23		= IOMUX_PAD(0x0530, 0x0160, 5, 0x0000, 0, 0),
+	MX6DL_PAD_EIM_D26__UART2_TXD		= IOMUX_PAD(0x053C, 0x016C, 4, 0x0000, 0, 0),
+	MX6DL_PAD_EIM_D27__UART2_RXD		= IOMUX_PAD(0x0540, 0x0170, 4, 0x0904, 1, 0),
+	MX6DL_PAD_EIM_D28__I2C1_SDA		= IOMUX_PAD(0x0544, 0x0174, 1 | IOMUX_CONFIG_SION, 0x086C, 1, 0),
+	MX6DL_PAD_EIM_D28__GPIO_3_28		= IOMUX_PAD(0x0544, 0x0174, 5, 0x0000, 0, 0),
+	MX6DL_PAD_ENET_MDC__ENET_MDC		= IOMUX_PAD(0x05B8, 0x01E8, 1, 0x0000, 0,  0),
+	MX6DL_PAD_ENET_MDIO__ENET_MDIO		= IOMUX_PAD(0x05BC, 0x01EC, 1, 0x0810, 0, 0),
+	MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK	= IOMUX_PAD(0x05C0, 0x01F0, 1, 0x0000, 0, 0),
+	MX6DL_PAD_ENET_RXD0__GPIO_1_27		= IOMUX_PAD(0x05C8, 0x01F8, 5, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_16__GPIO_7_11		= IOMUX_PAD(0x05E4, 0x0214, 5, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_16__I2C3_SDA		= IOMUX_PAD(0x05E4, 0x0214, 6 | IOMUX_CONFIG_SION, 0x087C, 1, 0),
+	MX6DL_PAD_GPIO_17__GPIO_7_12		= IOMUX_PAD(0x05E8, 0x0218, 5, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_18__GPIO_7_13		= IOMUX_PAD(0x05EC, 0x021C, 5, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_19__GPIO_4_5		= IOMUX_PAD(0x05F0, 0x0220, 5, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_5__GPIO_1_5		= IOMUX_PAD(0x0600, 0x0230, 5, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_5__I2C3_SCL		= IOMUX_PAD(0x0600, 0x0230, 6 | IOMUX_CONFIG_SION, 0x0878, 2, 0),
+	MX6DL_PAD_KEY_COL3__I2C2_SCL		= IOMUX_PAD(0x0638, 0x0250, 4 | IOMUX_CONFIG_SION, 0x0870, 1, 0),
+	MX6DL_PAD_KEY_COL3__GPIO_4_12		= IOMUX_PAD(0x0638, 0x0250, 5, 0x0000, 0, 0),
+	MX6DL_PAD_KEY_ROW3__I2C2_SDA		= IOMUX_PAD(0x064C, 0x0264, 4 | IOMUX_CONFIG_SION, 0x0874, 1, 0),
+	MX6DL_PAD_KEY_ROW3__GPIO_4_13		= IOMUX_PAD(0x064C, 0x0264, 5, 0x0000, 0, 0),
+	MX6DL_PAD_NANDF_D1__GPIO_2_1		= IOMUX_PAD(0x0670, 0x0288, 5, 0x0000, 0, 0),
+	MX6DL_PAD_NANDF_D2__GPIO_2_2		= IOMUX_PAD(0x0674, 0x028C, 5, 0x0000, 0, 0),
+	MX6DL_PAD_NANDF_D3__GPIO_2_3		= IOMUX_PAD(0x0678, 0x0290, 5, 0x0000, 0, 0),
+	MX6DL_PAD_NANDF_D4__GPIO_2_4		= IOMUX_PAD(0x067C, 0x0294, 5, 0x0000, 0, 0),
+	MX6DL_PAD_NANDF_D6__GPIO_2_6		= IOMUX_PAD(0x0684, 0x029C, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_RD0__ENET_RGMII_RD0     = IOMUX_PAD(0x0694, 0x02AC, 1, 0x0818, 1, 0),
+	MX6DL_PAD_RGMII_RD0__GPIO_6_25		= IOMUX_PAD(0x0694, 0x02AC, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_RD1__ENET_RGMII_RD1	= IOMUX_PAD(0x0698, 0x02B0, 1, 0x081C, 1, 0),
+	MX6DL_PAD_RGMII_RD1__GPIO_6_27		= IOMUX_PAD(0x0698, 0x02B0, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_RD2__ENET_RGMII_RD2	= IOMUX_PAD(0x069C, 0x02B4, 1, 0x0820, 1, 0),
+	MX6DL_PAD_RGMII_RD2__GPIO_6_28		= IOMUX_PAD(0x069C, 0x02B4, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_RD3__ENET_RGMII_RD3	= IOMUX_PAD(0x06A0, 0x02B8, 1, 0x0824, 1, 0),
+	MX6DL_PAD_RGMII_RD3__GPIO_6_29		= IOMUX_PAD(0x06A0, 0x02B8, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	= IOMUX_PAD(0x06A4, 0x02BC, 1, 0x0828, 1, 0),
+	MX6DL_PAD_RGMII_RX_CTL__GPIO_6_24	= IOMUX_PAD(0x06A4, 0x02BC, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_RXC__ENET_RGMII_RXC	= IOMUX_PAD(0x06A8, 0x02C0, 1, 0x0814, 1, 0),
+	MX6DL_PAD_RGMII_RXC__GPIO_6_30		= IOMUX_PAD(0x06A8, 0x02C0, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_TD0__ENET_RGMII_TD0	= IOMUX_PAD(0x06AC, 0x02C4, 1, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_TD1__ENET_RGMII_TD1	= IOMUX_PAD(0x06B0, 0x02C8, 1, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_TD2__ENET_RGMII_TD2	= IOMUX_PAD(0x06B4, 0x02CC, 1, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_TD3__ENET_RGMII_TD3	= IOMUX_PAD(0x06B8, 0x02D0, 1, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	= IOMUX_PAD(0x06BC, 0x02D4, 1, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_TXC__ENET_RGMII_TXC	= IOMUX_PAD(0x06C0, 0x02D8, 1, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_CLK__USDHC3_CLK		= IOMUX_PAD(0x06F4, 0x030C, 0, 0x0934, 1, 0),
+	MX6DL_PAD_SD3_CMD__USDHC3_CMD		= IOMUX_PAD(0x06F8, 0x0310, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT0__USDHC3_DAT0		= IOMUX_PAD(0x06FC, 0x0314, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT1__USDHC3_DAT1		= IOMUX_PAD(0x0700, 0x0318, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT2__USDHC3_DAT2		= IOMUX_PAD(0x0704, 0x031C, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT3__USDHC3_DAT3		= IOMUX_PAD(0x0708, 0x0320, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT5__GPIO_7_0		= IOMUX_PAD(0x0710, 0x0328, 5, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT6__UART1_RXD		= IOMUX_PAD(0x0714, 0x032C, 1, 0x08FC, 2, 0),
+	MX6DL_PAD_SD3_DAT7__UART1_TXD		= IOMUX_PAD(0x0718, 0x0330, 1, 0x0000, 0, 0),
+	MX6DL_PAD_SD4_CLK__USDHC4_CLK		= IOMUX_PAD(0x0720, 0x0338, 0, 0x0938, 1, 0),
+	MX6DL_PAD_SD4_CMD__USDHC4_CMD		= IOMUX_PAD(0x0724, 0x033C, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0),
+	MX6DL_PAD_SD4_DAT0__USDHC4_DAT0		= IOMUX_PAD(0x0728, 0x0340, 1, 0x0000, 0, 0),
+	MX6DL_PAD_SD4_DAT1__USDHC4_DAT1		= IOMUX_PAD(0x072C, 0x0344, 1, 0x0000, 0, 0),
+	MX6DL_PAD_SD4_DAT2__USDHC4_DAT2		= IOMUX_PAD(0x0730, 0x0348, 1, 0x0000, 0, 0),
+	MX6DL_PAD_SD4_DAT3__USDHC4_DAT3		= IOMUX_PAD(0x0734, 0x034C, 1, 0x0000, 0, 0),
+};
+#endif	/* __ASM_ARCH_MX6_MX6DL_PINS_H__ */
Signature · 1 line
1.7.9.5
#62 lore raw

PATCH v2 18/21 arch-mx6: add mx6dl_pins.h

Quoted 2 lines · Troy Kisky

Only the values used in the sabrelite board are added currently. Add more as other boards use them.

Though there are no users, better add it for completeness. This should also avoid people patching this file often.

Quoted 130 lines
---
  arch/arm/include/asm/arch-mx6/mx6dl_pins.h |  118 ++++++++++++++++++++++++++++
  1 file changed, 118 insertions(+)

create mode 100644 arch/arm/include/asm/arch-mx6/mx6dl_pins.h

arch/arm/include/asm/arch-mx6/mx6dl_pins.h new file +118 -0
new file mode 100644
index 0000000..5848013
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef __ASM_ARCH_MX6_MX6DL_PINS_H__
+#define __ASM_ARCH_MX6_MX6DL_PINS_H__
+
+#include<asm/imx-common/iomux-v3.h>
+
+/* Use to set PAD control */
+#define PAD_CTL_HYS		(1<<  16)
+#define PAD_CTL_PUS_100K_DOWN	(0<<  14)
+#define PAD_CTL_PUS_47K_UP	(1<<  14)
+#define PAD_CTL_PUS_100K_UP	(2<<  14)
+#define PAD_CTL_PUS_22K_UP	(3<<  14)
+
+#define PAD_CTL_PUE		(1<<  13)
+#define PAD_CTL_PKE		(1<<  12)
+#define PAD_CTL_ODE		(1<<  11)
+#define PAD_CTL_SPEED_LOW	(1<<  6)
+#define PAD_CTL_SPEED_MED	(2<<  6)
+#define PAD_CTL_SPEED_HIGH	(3<<  6)
+#define PAD_CTL_DSE_DISABLE	(0<<  3)
+#define PAD_CTL_DSE_240ohm	(1<<  3)
+#define PAD_CTL_DSE_120ohm	(2<<  3)
+#define PAD_CTL_DSE_80ohm	(3<<  3)
+#define PAD_CTL_DSE_60ohm	(4<<  3)
+#define PAD_CTL_DSE_48ohm	(5<<  3)
+#define PAD_CTL_DSE_40ohm	(6<<  3)
+#define PAD_CTL_DSE_34ohm	(7<<  3)
+#define PAD_CTL_SRE_FAST	(1<<  0)
+#define PAD_CTL_SRE_SLOW	(0<<  0)
+
+#define IOMUX_CONFIG_SION 0x10
+#define NO_MUX_I                0
+#define NO_PAD_I                0
+enum {
+	MX6DL_PAD_EIM_D16__ECSPI1_SCLK		= IOMUX_PAD(0x0514, 0x0144, 1, 0x07D8, 2, 0),
+	MX6DL_PAD_EIM_D17__ECSPI1_MISO		= IOMUX_PAD(0x0518, 0x0148, 1, 0x07DC, 2, 0),
+	MX6DL_PAD_EIM_D18__ECSPI1_MOSI		= IOMUX_PAD(0x051C, 0x014C, 1, 0x07E0, 2, 0),
+	MX6DL_PAD_EIM_D19__GPIO_3_19		= IOMUX_PAD(0x0520, 0x0150, 5, 0x0000, 0, 0),
+	MX6DL_PAD_EIM_D21__GPIO_3_21		= IOMUX_PAD(0x0528, 0x0158, 5, 0x0000, 0, 0),
+	MX6DL_PAD_EIM_D21__I2C1_SCL		= IOMUX_PAD(0x0528, 0x0158, 6 | IOMUX_CONFIG_SION, 0x0868, 1, 0),
+	MX6DL_PAD_EIM_D23__GPIO_3_23		= IOMUX_PAD(0x0530, 0x0160, 5, 0x0000, 0, 0),
+	MX6DL_PAD_EIM_D26__UART2_TXD		= IOMUX_PAD(0x053C, 0x016C, 4, 0x0000, 0, 0),
+	MX6DL_PAD_EIM_D27__UART2_RXD		= IOMUX_PAD(0x0540, 0x0170, 4, 0x0904, 1, 0),
+	MX6DL_PAD_EIM_D28__I2C1_SDA		= IOMUX_PAD(0x0544, 0x0174, 1 | IOMUX_CONFIG_SION, 0x086C, 1, 0),
+	MX6DL_PAD_EIM_D28__GPIO_3_28		= IOMUX_PAD(0x0544, 0x0174, 5, 0x0000, 0, 0),
+	MX6DL_PAD_ENET_MDC__ENET_MDC		= IOMUX_PAD(0x05B8, 0x01E8, 1, 0x0000, 0,  0),
+	MX6DL_PAD_ENET_MDIO__ENET_MDIO		= IOMUX_PAD(0x05BC, 0x01EC, 1, 0x0810, 0, 0),
+	MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK	= IOMUX_PAD(0x05C0, 0x01F0, 1, 0x0000, 0, 0),
+	MX6DL_PAD_ENET_RXD0__GPIO_1_27		= IOMUX_PAD(0x05C8, 0x01F8, 5, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_16__GPIO_7_11		= IOMUX_PAD(0x05E4, 0x0214, 5, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_16__I2C3_SDA		= IOMUX_PAD(0x05E4, 0x0214, 6 | IOMUX_CONFIG_SION, 0x087C, 1, 0),
+	MX6DL_PAD_GPIO_17__GPIO_7_12		= IOMUX_PAD(0x05E8, 0x0218, 5, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_18__GPIO_7_13		= IOMUX_PAD(0x05EC, 0x021C, 5, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_19__GPIO_4_5		= IOMUX_PAD(0x05F0, 0x0220, 5, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_5__GPIO_1_5		= IOMUX_PAD(0x0600, 0x0230, 5, 0x0000, 0, 0),
+	MX6DL_PAD_GPIO_5__I2C3_SCL		= IOMUX_PAD(0x0600, 0x0230, 6 | IOMUX_CONFIG_SION, 0x0878, 2, 0),
+	MX6DL_PAD_KEY_COL3__I2C2_SCL		= IOMUX_PAD(0x0638, 0x0250, 4 | IOMUX_CONFIG_SION, 0x0870, 1, 0),
+	MX6DL_PAD_KEY_COL3__GPIO_4_12		= IOMUX_PAD(0x0638, 0x0250, 5, 0x0000, 0, 0),
+	MX6DL_PAD_KEY_ROW3__I2C2_SDA		= IOMUX_PAD(0x064C, 0x0264, 4 | IOMUX_CONFIG_SION, 0x0874, 1, 0),
+	MX6DL_PAD_KEY_ROW3__GPIO_4_13		= IOMUX_PAD(0x064C, 0x0264, 5, 0x0000, 0, 0),
+	MX6DL_PAD_NANDF_D1__GPIO_2_1		= IOMUX_PAD(0x0670, 0x0288, 5, 0x0000, 0, 0),
+	MX6DL_PAD_NANDF_D2__GPIO_2_2		= IOMUX_PAD(0x0674, 0x028C, 5, 0x0000, 0, 0),
+	MX6DL_PAD_NANDF_D3__GPIO_2_3		= IOMUX_PAD(0x0678, 0x0290, 5, 0x0000, 0, 0),
+	MX6DL_PAD_NANDF_D4__GPIO_2_4		= IOMUX_PAD(0x067C, 0x0294, 5, 0x0000, 0, 0),
+	MX6DL_PAD_NANDF_D6__GPIO_2_6		= IOMUX_PAD(0x0684, 0x029C, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_RD0__ENET_RGMII_RD0     = IOMUX_PAD(0x0694, 0x02AC, 1, 0x0818, 1, 0),
+	MX6DL_PAD_RGMII_RD0__GPIO_6_25		= IOMUX_PAD(0x0694, 0x02AC, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_RD1__ENET_RGMII_RD1	= IOMUX_PAD(0x0698, 0x02B0, 1, 0x081C, 1, 0),
+	MX6DL_PAD_RGMII_RD1__GPIO_6_27		= IOMUX_PAD(0x0698, 0x02B0, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_RD2__ENET_RGMII_RD2	= IOMUX_PAD(0x069C, 0x02B4, 1, 0x0820, 1, 0),
+	MX6DL_PAD_RGMII_RD2__GPIO_6_28		= IOMUX_PAD(0x069C, 0x02B4, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_RD3__ENET_RGMII_RD3	= IOMUX_PAD(0x06A0, 0x02B8, 1, 0x0824, 1, 0),
+	MX6DL_PAD_RGMII_RD3__GPIO_6_29		= IOMUX_PAD(0x06A0, 0x02B8, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_RX_CTL__RGMII_RX_CTL	= IOMUX_PAD(0x06A4, 0x02BC, 1, 0x0828, 1, 0),
+	MX6DL_PAD_RGMII_RX_CTL__GPIO_6_24	= IOMUX_PAD(0x06A4, 0x02BC, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_RXC__ENET_RGMII_RXC	= IOMUX_PAD(0x06A8, 0x02C0, 1, 0x0814, 1, 0),
+	MX6DL_PAD_RGMII_RXC__GPIO_6_30		= IOMUX_PAD(0x06A8, 0x02C0, 5, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_TD0__ENET_RGMII_TD0	= IOMUX_PAD(0x06AC, 0x02C4, 1, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_TD1__ENET_RGMII_TD1	= IOMUX_PAD(0x06B0, 0x02C8, 1, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_TD2__ENET_RGMII_TD2	= IOMUX_PAD(0x06B4, 0x02CC, 1, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_TD3__ENET_RGMII_TD3	= IOMUX_PAD(0x06B8, 0x02D0, 1, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_TX_CTL__RGMII_TX_CTL	= IOMUX_PAD(0x06BC, 0x02D4, 1, 0x0000, 0, 0),
+	MX6DL_PAD_RGMII_TXC__ENET_RGMII_TXC	= IOMUX_PAD(0x06C0, 0x02D8, 1, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_CLK__USDHC3_CLK		= IOMUX_PAD(0x06F4, 0x030C, 0, 0x0934, 1, 0),
+	MX6DL_PAD_SD3_CMD__USDHC3_CMD		= IOMUX_PAD(0x06F8, 0x0310, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT0__USDHC3_DAT0		= IOMUX_PAD(0x06FC, 0x0314, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT1__USDHC3_DAT1		= IOMUX_PAD(0x0700, 0x0318, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT2__USDHC3_DAT2		= IOMUX_PAD(0x0704, 0x031C, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT3__USDHC3_DAT3		= IOMUX_PAD(0x0708, 0x0320, 0, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT5__GPIO_7_0		= IOMUX_PAD(0x0710, 0x0328, 5, 0x0000, 0, 0),
+	MX6DL_PAD_SD3_DAT6__UART1_RXD		= IOMUX_PAD(0x0714, 0x032C, 1, 0x08FC, 2, 0),
+	MX6DL_PAD_SD3_DAT7__UART1_TXD		= IOMUX_PAD(0x0718, 0x0330, 1, 0x0000, 0, 0),
+	MX6DL_PAD_SD4_CLK__USDHC4_CLK		= IOMUX_PAD(0x0720, 0x0338, 0, 0x0938, 1, 0),
+	MX6DL_PAD_SD4_CMD__USDHC4_CMD		= IOMUX_PAD(0x0724, 0x033C, 0 | IOMUX_CONFIG_SION, 0x0000, 0, 0),
+	MX6DL_PAD_SD4_DAT0__USDHC4_DAT0		= IOMUX_PAD(0x0728, 0x0340, 1, 0x0000, 0, 0),
+	MX6DL_PAD_SD4_DAT1__USDHC4_DAT1		= IOMUX_PAD(0x072C, 0x0344, 1, 0x0000, 0, 0),
+	MX6DL_PAD_SD4_DAT2__USDHC4_DAT2		= IOMUX_PAD(0x0730, 0x0348, 1, 0x0000, 0, 0),
+	MX6DL_PAD_SD4_DAT3__USDHC4_DAT3		= IOMUX_PAD(0x0734, 0x034C, 1, 0x0000, 0, 0),
+};
+#endif	/* __ASM_ARCH_MX6_MX6DL_PINS_H__ */
author
#63 lore raw

PATCH v2 18/21 arch-mx6: add mx6dl_pins.h

Quoted 8 lines · Vikram Narayanan
Quoted 2 lines · Troy Kisky

Only the values used in the sabrelite board are added currently. Add more as other boards use them.

Though there are no users, better add it for completeness. This should also avoid people patching this file often.

U-boot has a policy of not adding dead code. One patch per added board will not cause a burden. Also,
since the entries are sorted, merge conflicts should be rare.

Troy

author
#64 lore raw

PATCH v2 19/21 mx6qsabrelite: add support for mx6 solo/duallite

In reply to Troy Kisky
---
 board/freescale/mx6qsabrelite/mx6qsabrelite.c |  231 ++++++-------------------
 board/freescale/mx6qsabrelite/pads.h          |  172 ++++++++++++++++++
 2 files changed, 226 insertions(+), 177 deletions(-)
 create mode 100644 board/freescale/mx6qsabrelite/pads.h
board/freescale/mx6qsabrelite/mx6qsabrelite.c +54 -177
index 4b4e89b..ad2347d 100644
@@ -26,6 +26,8 @@
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/iomux.h>
 #include <asm/arch/mx6x_pins.h>
+#include <asm/arch/mx6dl_pins.h>
+#include <asm/arch/sys_proto.h>
 #include <asm/errno.h>
 #include <asm/gpio.h>
 #include <asm/imx-common/iomux-v3.h>
@@ -38,163 +40,46 @@
 #include <netdev.h>
 DECLARE_GLOBAL_DATA_PTR;
 
-#define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |	       \
-       PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |	       \
-       PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+#include "pads.h"
+#define FOR_DL_SOLO
+#include "pads.h"
 
-#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |	       \
-       PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW |	       \
-       PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+int cpu_is_mx6q(void)
+{
+	return get_cpu_type() == MXC_CPU_MX6Q;
+}
 
-#define ENET_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
-	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED	  |		\
-	PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
+#define IOMUX_SETUP(list)  iomux_setup(mx6q_##list, ARRAY_SIZE(mx6q_##list), \
+		mx6dl_solo_##list, ARRAY_SIZE(mx6dl_solo_##list))
 
-#define SPI_PAD_CTRL (PAD_CTL_HYS |				\
-	PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED |		\
-	PAD_CTL_DSE_40ohm     | PAD_CTL_SRE_FAST)
+int iomux_setup(iomux_v3_cfg_t *mx6q_pad_list, int mx6q_pad_cnt,
+		iomux_v3_cfg_t *mx6dl_solo_pad_list, int mx6dl_solo_pad_cnt)
+{
+	int mx6q = cpu_is_mx6q();
+	iomux_v3_cfg_t *p =  mx6q ? mx6q_pad_list : mx6dl_solo_pad_list;
+	int cnt = mx6q ? mx6q_pad_cnt : mx6dl_solo_pad_cnt;
 
-#define BUTTON_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |		\
-	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED   |		\
-	PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
+	return imx_iomux_v3_setup_multiple_pads(p, cnt);
+}
 
-#define I2C_PAD_CTRL	(PAD_CTL_PKE | PAD_CTL_PUE |		\
-	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |		\
-	PAD_CTL_DSE_40ohm | PAD_CTL_HYS |			\
-	PAD_CTL_ODE | PAD_CTL_SRE_FAST)
+static const unsigned char col_lookup[] = {9, 10, 11, 8, 12, 9, 9, 9};
+static const unsigned char bank_lookup[] = {3, 2};
 
 int dram_init(void)
 {
-       gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
-
-       return 0;
+	unsigned mdctl = readl(MMDC_P0_BASE_ADDR + 0x000);
+	unsigned mdmisc = readl(MMDC_P0_BASE_ADDR + 0x018);
+	int bits = 11 + 0 + 0 + 1;      /* row+col+bank+width */
+
+	bits += (mdctl >> 24) & 7;      /* row */
+	bits += col_lookup[(mdctl >> 20) & 7];  /* col */
+	bits += bank_lookup[(mdmisc >> 5) & 1]; /* bank */
+	bits += (mdctl >> 16) & 3;      /* width */
+	bits += (mdctl >> 30) & 1;      /* cs1 enabled*/
+	gd->ram_size = 1 << bits;
+	return 0;
 }
 
-iomux_v3_cfg_t uart1_pads[] = {
-	MX6Q_PAD_SD3_DAT6__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
-	MX6Q_PAD_SD3_DAT7__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
-};
-
-iomux_v3_cfg_t uart2_pads[] = {
-       MX6Q_PAD_EIM_D26__UART2_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
-       MX6Q_PAD_EIM_D27__UART2_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
-};
-
-#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
-
-/* I2C1, SGTL5000 */
-struct i2c_pads_info i2c_pad_info0 = {
-	.scl = {
-		.i2c_mode = MX6Q_PAD_EIM_D21__I2C1_SCL | PC,
-		.gpio_mode = MX6Q_PAD_EIM_D21__GPIO_3_21 | PC,
-		.gp = IMX_GPIO_NR(3, 21)
-	},
-	.sda = {
-		.i2c_mode = MX6Q_PAD_EIM_D28__I2C1_SDA | PC,
-		.gpio_mode = MX6Q_PAD_EIM_D28__GPIO_3_28 | PC,
-		.gp = IMX_GPIO_NR(3, 28)
-	}
-};
-
-/* I2C2 Camera, MIPI */
-struct i2c_pads_info i2c_pad_info1 = {
-	.scl = {
-		.i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | PC,
-		.gpio_mode = MX6Q_PAD_KEY_COL3__GPIO_4_12 | PC,
-		.gp = IMX_GPIO_NR(4, 12)
-	},
-	.sda = {
-		.i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
-		.gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO_4_13 | PC,
-		.gp = IMX_GPIO_NR(4, 13)
-	}
-};
-
-/* I2C3, J15 - RGB connector */
-struct i2c_pads_info i2c_pad_info2 = {
-	.scl = {
-		.i2c_mode = MX6Q_PAD_GPIO_5__I2C3_SCL | PC,
-		.gpio_mode = MX6Q_PAD_GPIO_5__GPIO_1_5 | PC,
-		.gp = IMX_GPIO_NR(1, 5)
-	},
-	.sda = {
-		.i2c_mode = MX6Q_PAD_GPIO_16__I2C3_SDA | PC,
-		.gpio_mode = MX6Q_PAD_GPIO_16__GPIO_7_11 | PC,
-		.gp = IMX_GPIO_NR(7, 11)
-	}
-};
-
-iomux_v3_cfg_t usdhc3_pads[] = {
-       MX6Q_PAD_SD3_CLK__USDHC3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6Q_PAD_SD3_CMD__USDHC3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6Q_PAD_SD3_DAT5__GPIO_7_0    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
-};
-
-iomux_v3_cfg_t usdhc4_pads[] = {
-       MX6Q_PAD_SD4_CLK__USDHC4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6Q_PAD_SD4_CMD__USDHC4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
-       MX6Q_PAD_NANDF_D6__GPIO_2_6    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
-};
-
-iomux_v3_cfg_t enet_pads1[] = {
-	MX6Q_PAD_ENET_MDIO__ENET_MDIO		| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_ENET_MDC__ENET_MDC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	/* pin 35 - 1 (PHY_AD2) on reset */
-	MX6Q_PAD_RGMII_RXC__GPIO_6_30		| MUX_PAD_CTRL(NO_PAD_CTRL),
-	/* pin 32 - 1 - (MODE0) all */
-	MX6Q_PAD_RGMII_RD0__GPIO_6_25		| MUX_PAD_CTRL(NO_PAD_CTRL),
-	/* pin 31 - 1 - (MODE1) all */
-	MX6Q_PAD_RGMII_RD1__GPIO_6_27		| MUX_PAD_CTRL(NO_PAD_CTRL),
-	/* pin 28 - 1 - (MODE2) all */
-	MX6Q_PAD_RGMII_RD2__GPIO_6_28		| MUX_PAD_CTRL(NO_PAD_CTRL),
-	/* pin 27 - 1 - (MODE3) all */
-	MX6Q_PAD_RGMII_RD3__GPIO_6_29		| MUX_PAD_CTRL(NO_PAD_CTRL),
-	/* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
-	MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24	| MUX_PAD_CTRL(NO_PAD_CTRL),
-	/* pin 42 PHY nRST */
-	MX6Q_PAD_EIM_D23__GPIO_3_23		| MUX_PAD_CTRL(NO_PAD_CTRL),
-};
-
-iomux_v3_cfg_t enet_pads2[] = {
-	MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-	MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
-};
-
-/* Button assignments for J14 */
-static iomux_v3_cfg_t button_pads[] = {
-	/* Menu */
-	MX6Q_PAD_NANDF_D1__GPIO_2_1	| MUX_PAD_CTRL(BUTTON_PAD_CTRL),
-	/* Back */
-	MX6Q_PAD_NANDF_D2__GPIO_2_2	| MUX_PAD_CTRL(BUTTON_PAD_CTRL),
-	/* Labelled Search (mapped to Power under Android) */
-	MX6Q_PAD_NANDF_D3__GPIO_2_3	| MUX_PAD_CTRL(BUTTON_PAD_CTRL),
-	/* Home */
-	MX6Q_PAD_NANDF_D4__GPIO_2_4	| MUX_PAD_CTRL(BUTTON_PAD_CTRL),
-	/* Volume Down */
-	MX6Q_PAD_GPIO_19__GPIO_4_5	| MUX_PAD_CTRL(BUTTON_PAD_CTRL),
-	/* Volume Up */
-	MX6Q_PAD_GPIO_18__GPIO_7_13	| MUX_PAD_CTRL(BUTTON_PAD_CTRL),
-};
-
 static void setup_iomux_enet(void)
 {
 	gpio_direction_output(IMX_GPIO_NR(3, 23), 0);
@@ -203,30 +88,26 @@ static void setup_iomux_enet(void)
 	gpio_direction_output(IMX_GPIO_NR(6, 27), 1);
 	gpio_direction_output(IMX_GPIO_NR(6, 28), 1);
 	gpio_direction_output(IMX_GPIO_NR(6, 29), 1);
-	imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1));
+	IOMUX_SETUP(enet_pads1);
 	gpio_direction_output(IMX_GPIO_NR(6, 24), 1);
 
 	/* Need delay 10ms according to KSZ9021 spec */
 	udelay(1000 * 10);
 	gpio_set_value(IMX_GPIO_NR(3, 23), 1);
 
-	imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2));
+	IOMUX_SETUP(enet_pads2);
 }
 
-iomux_v3_cfg_t usb_pads[] = {
-	MX6Q_PAD_GPIO_17__GPIO_7_12 | MUX_PAD_CTRL(NO_PAD_CTRL),
-};
-
 static void setup_iomux_uart(void)
 {
-	imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
-       imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
+	IOMUX_SETUP(uart1_pads);
+	IOMUX_SETUP(uart2_pads);
 }
 
 #ifdef CONFIG_USB_EHCI_MX6
 int board_ehci_hcd_init(int port)
 {
-	imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
+	IOMUX_SETUP(usb_pads);
 
 	/* Reset USB hub */
 	gpio_direction_output(IMX_GPIO_NR(7, 12), 0);
@@ -267,12 +148,10 @@ int board_mmc_init(bd_t *bis)
        for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) {
 	       switch (index) {
 	       case 0:
-		       imx_iomux_v3_setup_multiple_pads(
-			       usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
+		       IOMUX_SETUP(usdhc3_pads);
 		       break;
 	       case 1:
-		       imx_iomux_v3_setup_multiple_pads(
-			       usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
+		       IOMUX_SETUP(usdhc4_pads);
 		       break;
 	       default:
 		       printf("Warning: you configured more USDHC controllers"
@@ -294,19 +173,10 @@ u32 get_board_rev(void)
 }
 
 #ifdef CONFIG_MXC_SPI
-iomux_v3_cfg_t ecspi1_pads[] = {
-	/* SS1 */
-	MX6Q_PAD_EIM_D19__GPIO_3_19   | MUX_PAD_CTRL(SPI_PAD_CTRL),
-	MX6Q_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
-	MX6Q_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
-	MX6Q_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
-};
-
 void setup_spi(void)
 {
 	gpio_direction_output(CONFIG_SF_DEFAULT_CS, 1);
-	imx_iomux_v3_setup_multiple_pads(ecspi1_pads,
-					 ARRAY_SIZE(ecspi1_pads));
+	IOMUX_SETUP(ecspi1_pads);
 }
 #endif
 
@@ -342,8 +212,7 @@ int board_eth_init(bd_t *bis)
 
 static void setup_buttons(void)
 {
-	imx_iomux_v3_setup_multiple_pads(button_pads,
-					 ARRAY_SIZE(button_pads));
+	IOMUX_SETUP(button_pads);
 }
 
 #ifdef CONFIG_CMD_SATA
@@ -382,15 +251,18 @@ int board_early_init_f(void)
 
 int board_init(void)
 {
+	struct i2c_pads_info *p = cpu_is_mx6q() ? mx6q_i2c_pad_info :
+			mx6dl_solo_i2c_pad_info;
+
        /* address of boot parameters */
        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 
 #ifdef CONFIG_MXC_SPI
 	setup_spi();
 #endif
-	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
-	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
-	setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
+	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &p[0]);
+	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &p[1]);
+	setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &p[2]);
 
 #ifdef CONFIG_CMD_SATA
 	setup_sata();
@@ -401,9 +273,14 @@ int board_init(void)
 
 int checkboard(void)
 {
-       puts("Board: MX6Q-Sabre Lite\n");
+	int cpu_type = get_cpu_type();
 
-       return 0;
+	puts("Board: MX6");
+	puts((cpu_type == MXC_CPU_MX6Q) ? "Q" :
+		(cpu_type == MXC_CPU_MX6DL) ? "DL" : "SOLO");
+	puts("-Sabre Lite\n");
+
+	return 0;
 }
 
 struct button_key {
board/freescale/mx6qsabrelite/pads.h new file +172 -0

172 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#65 lore raw

PATCH v2 19/21 mx6qsabrelite: add support for mx6 solo/duallite

Quoted 76 lines · Troy Kisky
---
  board/freescale/mx6qsabrelite/mx6qsabrelite.c |  231 ++++++-------------------
  board/freescale/mx6qsabrelite/pads.h          |  172 ++++++++++++++++++
  2 files changed, 226 insertions(+), 177 deletions(-)

create mode 100644 board/freescale/mx6qsabrelite/pads.h

board/freescale/mx6qsabrelite/mx6qsabrelite.c +24 -22
index 4b4e89b..ad2347d 100644
@@ -26,6 +26,8 @@
  #include<asm/arch/imx-regs.h>
  #include<asm/arch/iomux.h>
  #include<asm/arch/mx6x_pins.h>
+#include<asm/arch/mx6dl_pins.h>
+#include<asm/arch/sys_proto.h>
  #include<asm/errno.h>
  #include<asm/gpio.h>
  #include<asm/imx-common/iomux-v3.h>
@@ -38,163 +40,46 @@
  #include<netdev.h>
  DECLARE_GLOBAL_DATA_PTR;
 
-#define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |	       \
-       PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |	       \
-       PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+#include "pads.h"
+#define FOR_DL_SOLO
+#include "pads.h"
 
-#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |	       \
-       PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW |	       \
-       PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+int cpu_is_mx6q(void)
+{
+	return get_cpu_type() == MXC_CPU_MX6Q;
+}
 
-#define ENET_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
-	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED	  |		\
-	PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
+#define IOMUX_SETUP(list)  iomux_setup(mx6q_##list, ARRAY_SIZE(mx6q_##list), \
+		mx6dl_solo_##list, ARRAY_SIZE(mx6dl_solo_##list))
 
-#define SPI_PAD_CTRL (PAD_CTL_HYS |				\
-	PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED |		\
-	PAD_CTL_DSE_40ohm     | PAD_CTL_SRE_FAST)
+int iomux_setup(iomux_v3_cfg_t *mx6q_pad_list, int mx6q_pad_cnt,
+		iomux_v3_cfg_t *mx6dl_solo_pad_list, int mx6dl_solo_pad_cnt)
+{
+	int mx6q = cpu_is_mx6q();
+	iomux_v3_cfg_t *p =  mx6q ? mx6q_pad_list : mx6dl_solo_pad_list;
+	int cnt = mx6q ? mx6q_pad_cnt : mx6dl_solo_pad_cnt;
 
-#define BUTTON_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |		\
-	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED   |		\
-	PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
+	return imx_iomux_v3_setup_multiple_pads(p, cnt);
+}
 
-#define I2C_PAD_CTRL	(PAD_CTL_PKE | PAD_CTL_PUE |		\
-	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |		\
-	PAD_CTL_DSE_40ohm | PAD_CTL_HYS |			\
-	PAD_CTL_ODE | PAD_CTL_SRE_FAST)
+static const unsigned char col_lookup[] = {9, 10, 11, 8, 12, 9, 9, 9};
+static const unsigned char bank_lookup[] = {3, 2};
 
  int dram_init(void)
  {
-       gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
-
-       return 0;
+	unsigned mdctl = readl(MMDC_P0_BASE_ADDR + 0x000);
+	unsigned mdmisc = readl(MMDC_P0_BASE_ADDR + 0x018);
+	int bits = 11 + 0 + 0 + 1;      /* row+col+bank+width */

board/freescale/mx6qsabrelite/mx6qsabrelite.c line 82

Quoted 10 lines
board/freescale/mx6qsabrelite/mx6qsabrelite.c +8 -0
+
+	bits += (mdctl>>  24)&  7;      /* row */
+	bits += col_lookup[(mdctl>>  20)&  7];  /* col */
+	bits += bank_lookup[(mdmisc>>  5)&  1]; /* bank */
+	bits += (mdctl>>  16)&  3;      /* width */
+	bits += (mdctl>>  30)&  1;      /* cs1 enabled*/
+	gd->ram_size = 1<<  bits;
+	return 0;
  }
 

No magic numbers please. Replace it with macros.

Regards,
Vikram

author
#66 lore raw

PATCH v2 19/21 mx6qsabrelite: add support for mx6 solo/duallite

Quoted 86 lines · Vikram Narayanan
Quoted 85 lines · Troy Kisky
---
  board/freescale/mx6qsabrelite/mx6qsabrelite.c |  231 
++++++-------------------
  board/freescale/mx6qsabrelite/pads.h          |  172 
++++++++++++++++++
  2 files changed, 226 insertions(+), 177 deletions(-)

create mode 100644 board/freescale/mx6qsabrelite/pads.h

board/freescale/mx6qsabrelite/mx6qsabrelite.c +28 -22
index 4b4e89b..ad2347d 100644
@@ -26,6 +26,8 @@
  #include<asm/arch/imx-regs.h>
  #include<asm/arch/iomux.h>
  #include<asm/arch/mx6x_pins.h>
+#include<asm/arch/mx6dl_pins.h>
+#include<asm/arch/sys_proto.h>
  #include<asm/errno.h>
  #include<asm/gpio.h>
  #include<asm/imx-common/iomux-v3.h>
@@ -38,163 +40,46 @@
  #include<netdev.h>
  DECLARE_GLOBAL_DATA_PTR;
 
-#define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |           \
-       PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |           \
-       PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+#include "pads.h"
+#define FOR_DL_SOLO
+#include "pads.h"
 
-#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |           \
-       PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW |           \
-       PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+int cpu_is_mx6q(void)
+{
+    return get_cpu_type() == MXC_CPU_MX6Q;
+}
 
-#define ENET_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |        \
-    PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED      |        \
-    PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
+#define IOMUX_SETUP(list)  iomux_setup(mx6q_##list, 
 ARRAY_SIZE(mx6q_##list), \
+        mx6dl_solo_##list, ARRAY_SIZE(mx6dl_solo_##list))
 
-#define SPI_PAD_CTRL (PAD_CTL_HYS |                \
-    PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED |        \
-    PAD_CTL_DSE_40ohm     | PAD_CTL_SRE_FAST)
+int iomux_setup(iomux_v3_cfg_t *mx6q_pad_list, int mx6q_pad_cnt,
+        iomux_v3_cfg_t *mx6dl_solo_pad_list, int mx6dl_solo_pad_cnt)
+{
+    int mx6q = cpu_is_mx6q();
+    iomux_v3_cfg_t *p =  mx6q ? mx6q_pad_list : mx6dl_solo_pad_list;
+    int cnt = mx6q ? mx6q_pad_cnt : mx6dl_solo_pad_cnt;
 
-#define BUTTON_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |        \
-    PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED   |        \
-    PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
+    return imx_iomux_v3_setup_multiple_pads(p, cnt);
+}
 
-#define I2C_PAD_CTRL    (PAD_CTL_PKE | PAD_CTL_PUE |        \
-    PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |        \
-    PAD_CTL_DSE_40ohm | PAD_CTL_HYS |            \
-    PAD_CTL_ODE | PAD_CTL_SRE_FAST)
+static const unsigned char col_lookup[] = {9, 10, 11, 8, 12, 9, 9, 9};
+static const unsigned char bank_lookup[] = {3, 2};
 
  int dram_init(void)
  {
-       gd->ram_size = get_ram_size((void *)PHYS_SDRAM, 
 PHYS_SDRAM_SIZE);
-
-       return 0;
+    unsigned mdctl = readl(MMDC_P0_BASE_ADDR + 0x000);
+    unsigned mdmisc = readl(MMDC_P0_BASE_ADDR + 0x018);
+    int bits = 11 + 0 + 0 + 1;      /* row+col+bank+width */
+
+    bits += (mdctl>>  24)&  7;      /* row */
+    bits += col_lookup[(mdctl>>  20)&  7];  /* col */
+    bits += bank_lookup[(mdmisc>>  5)&  1]; /* bank */
Quoted 8 lines

board/freescale/mx6qsabrelite/mx6qsabrelite.c line 82

Quoted 6 lines
board/freescale/mx6qsabrelite/mx6qsabrelite.c +4 -0
+    bits += (mdctl>>  16)&  3;      /* width */
+    bits += (mdctl>>  30)&  1;      /* cs1 enabled*/
+    gd->ram_size = 1<<  bits;
+    return 0;
  }
 

No magic numbers please. Replace it with macros.

Right, will move to a common file as well so that other may use it.

Troy

author
#67 lore raw

PATCH v2 20/21 mx6q_4x_mt41j128.cfg: add mx6 solo/duallite support

In reply to Troy Kisky
---
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg |  127 +++++++++++++++++++-------
 1 file changed, 92 insertions(+), 35 deletions(-)
board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg +92 -35
index 60eae86..46fd1dc 100644
@@ -52,6 +52,15 @@ BOOT_FROM      sd
  *      Address   absolute address of the register
  *      value     value to be stored in the register
  */
+/*
+ * DDR3 settings
+ * MX6Q    ddr is limited to 1066 Mhz, currently 1056 MHz(528 MHz clock),
+ *	   memory bus width: 64 bits, x16/x32/x64
+ * MX6DL   ddr is limited to 800 MHz(400 MHz clock)
+ *	   memory bus width: 64 bits, x16/x32/x64
+ * MX6SOLO ddr is limited to 800 MHz(400 MHz clock)
+ *	   memory bus width: 32 bits, x16/x32
+ */
 IOMUX_ENTRY1(IOM_DRAM_SDQS0, 0x00000030)
 IOMUX_ENTRY1(IOM_DRAM_SDQS1, 0x00000030)
 IOMUX_ENTRY1(IOM_DRAM_SDQS2, 0x00000030)
@@ -112,8 +121,12 @@ WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY1DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY2DL, 0x33333333)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDQBY3DL, 0x33333333)
 
-/* MDPDC - CKE pulse width = 3 cycles. CKSRE = 6 cycles, CKSRX = 6 cycles */
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDPDC, 0x00020036)
+/*
+ * MDPDC - [17:16](2) => CKE pulse width = 3 cycles.
+ * MX6Q:       [2:0](6) => CKSRE = 6 cycles, [5:3](6) => CKSRX = 6 cycles
+ * MX6DL/SOLO: [2:0](5) => CKSRE = 5 cycles, [5:3](5) => CKSRX = 5 cycles
+ */
+WRITE_ENTRY2(MMDC_P0 + MMDC_MDPDC, 0x00020036, 0x0002002D)
 
 /*
  * MDMISC, mirroring, interleaved (row/bank/col)
@@ -124,48 +137,92 @@ WRITE_ENTRY1(MMDC_P0 + MMDC_MDMISC, 0x00081740)
  * MDSCR, con_req
  */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x00008000)
+
 /*
- * MDCFG0, tRFC=0x56 clocks, tXS=0x5b clocks
- * tXP=4 clocks, tXPDLL=13 clocks
- * tFAW=24 clocks, cas=8 cycles
+ * MDCFG0,
+ * MX6Q:
+ *	tRFC=0x56 clocks, tXS=0x5b clocks, tXP=4 clocks, tXPDLL=13 clocks
+ *	tFAW=24 clocks, cas=8 cycles
+ * MX6DL/SOLO:
+ *	tRFC=0x6a clocks, tXS=0x6e clocks, tXP=3 clocks, tXPDLL=10 clocks
+ *	 tFAW=19 clocks, cas=6 cycles
  */
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDCFG0, 0x555A7975)
+WRITE_ENTRY2(MMDC_P0 + MMDC_MDCFG0, 0x555A7975, 0x696D5323)
+
 /*
- * MDCFG1, tRDC=8, tRP=8, tRC=27,tRAS=20,tRPA=tRP+1,tWR=8
- * tMRD=4, tCWL=6
+ * MDCFG1,
+ * MX6Q:
+ *	tRDC=8, tRP=8, tRC=27, tRAS=20, tRPA=tRP+1, tWR=8, tMRD=4, tCWL=6
+ * MX6DL/SOLO:
+ *	tRDC=6, tRP=6, tRC=20, tRAS=15, tRPA=tRP+1, tWR=7, tMRD=4, tCWL=5
  */
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDCFG1, 0xFF538E64)
+WRITE_ENTRY2(MMDC_P0 + MMDC_MDCFG1, 0xFF538E64, 0xB66E8C63)
+
 /*
  * MDCFG2,tDLLK=512,tRTP=4,tWTR=4,tRRD=4
  */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDCFG2, 0x01FF00DB)
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDRWD, 0x000026D2)
-
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDOR, 0x005B0E21)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDOTC, 0x09444040)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDPDC, 0x00025576)
 
 /*
- * Mx6Q - 64 bit wide ddr
+ * MMDC_MDOTC,
+ * MX6Q:
+ *	tAOFPD=2 cycles, tAONPD=2, tANPD=5, tAXPD=5, tODTLon=5, tODT_idle_off=5
+ * MX6DL/SOLO:
+ *	tAOFPD=1 cycles, tAONPD=1, tANPD=4, tAXPD=4, tODTLon=4, tODT_idle_off=4
+ */
+WRITE_ENTRY2(MMDC_P0 + MMDC_MDOTC, 0x09444040, 0x00333030)
+
+/*
+ * MDPDC - [17:16](2) => CKE pulse width = 3 cycles.
+ * [15:12](5) => PWDT_1 = 256 cycles
+ * [11:8](5) =>PWDR_0 = 256 cycles
+ * MX6Q:       [2:0](6) => CKSRE = 6 cycles, [5:3](6) => CKSRX = 6 cycles
+ * MX6DL/SOLO: [2:0](5) => CKSRE = 5 cycles, [5:3](5) => CKSRX = 5 cycles
+ */
+WRITE_ENTRY2(MMDC_P0 + MMDC_MDPDC, 0x00025576, 0x0002556D)
+
+/*
+ * MX6Q/DL - 64 bit wide ddr
  * last address is  (1<<28 (base) + 1<<30  - 1)  / (1<<25) =
  * 	1<<3 + 1<<5 - 1 = 8 + 0x20 -1 = 0x27
  */
+/*
+ * MX6SOLO - 32 bit wide ddr
+ * last address is  (1<<28 (base) + 1<<29  - 1)  / (1<<25) =
+ *	1<<3 + 1<<4 - 1 = 8 + 0x10 -1 = 0x17
+ */
 /* MDASP, CS0_END */
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDASP, 0x00000027)
+WRITE_ENTRY3(MMDC_P0 + MMDC_MDASP, 0x00000027, 0x00000027, 0x00000017)
 /*
- * MDCTL, CS0 enable, CS1 disabled, row=14, col=10, burst=8, width=64/32bit
- * mx6q   : row+col+bank+width=14+10+3+3=30 = 1G
+ * MDCTL, CS0 enable, CS1 disabled, row=14, col=10, burst=8
+ * MX6Q/DL: width=64bit row+col+bank+width=14+10+3+3=30 = 1G
+ * MX6SOLO: width=32bit row+col+bank+width=14+10+3+2=29 = 512M
  */
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDCTL, 0x831A0000)
+WRITE_ENTRY3(MMDC_P0 + MMDC_MDCTL, 0x831A0000, 0x831A0000, 0x83190000)
 
-/* MDSCR, con_req, LOAD MR2, CS0, A3,A10 set (CAS Write=6), RZQ/2 */
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x04088032)
+/*
+ * LOAD MR2: MDSCR, con_req,  CS0, A10 set - RZQ/2
+ * MX6Q:    A3 set(CAS Write=6)
+ * MX6DL/SOLO: (CAS Write=5)
+ */
+WRITE_ENTRY2(MMDC_P0 + MMDC_MDSCR, 0x04088032, 0x04008032)
 /* LOAD MR3, CS0 */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x00008033)
-/* LOAD MR1, CS0, A1,A6 set Rtt=RZQ/2, ODI=RZQ/7 */
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x00428031)
-/* LOAD MR0, CS0, A6,A8,A11 set CAS=8, WR=8, DLL reset */
-WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x09408030)
+
+/*
+ * LOAD MR1, CS0
+ * MX6Q: A6 set: Rtt=RZQ/2, A1 set: ODI=RZQ/7
+ * MX6DL/SOLO: A2 set: Rtt=RZQ/4, ODI=RZQ/6
+ */
+WRITE_ENTRY2(MMDC_P0 + MMDC_MDSCR, 0x00428031, 0x00048031)
+
+/* LOAD MR0, CS0 A8 set: DLL Reset
+ * MX6Q: A6 set: CAS=8 A11 set: WR=8
+ * MX6DL/SOLO: A4 set: CAS=5, A9,A10 set: WR=7
+ */
+WRITE_ENTRY2(MMDC_P0 + MMDC_MDSCR, 0x09408030, 0x07208030)
 
 /* ZQ calibrate, CS0 */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MDSCR, 0x04008040)
@@ -178,18 +235,18 @@ WRITE_ENTRY1(MMDC_P0 + MMDC_MPODTCTRL, 0x00022227)
 WRITE_ENTRY1(MMDC_P1 + MMDC_MPODTCTRL, 0x00022227)
 
 /* MPDGCTRL0/1 DQS GATE*/
-WRITE_ENTRY1(MMDC_P0 + MMDC_MPDGCTRL0, 0x434B0350)
-WRITE_ENTRY1(MMDC_P1 + MMDC_MPDGCTRL0, 0x434B0350)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MPDGCTRL1, 0x034C0359)
-WRITE_ENTRY1(MMDC_P1 + MMDC_MPDGCTRL1, 0x03650348)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MPRDDLCTL, 0x4436383B)
-WRITE_ENTRY1(MMDC_P1 + MMDC_MPRDDLCTL, 0x39393341)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MPWRDLCTL, 0x35373933)
-WRITE_ENTRY1(MMDC_P1 + MMDC_MPWRDLCTL, 0x48254A36)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MPWLDECTRL0, 0x001F001F)
-WRITE_ENTRY1(MMDC_P0 + MMDC_MPWLDECTRL1, 0x001F001F)
-WRITE_ENTRY1(MMDC_P1 + MMDC_MPWLDECTRL0, 0x00440044)
-WRITE_ENTRY1(MMDC_P1 + MMDC_MPWLDECTRL1, 0x00440044)
+WRITE_ENTRY2(MMDC_P0 + MMDC_MPDGCTRL0, 0x434B0350, 0x42350231)
+WRITE_ENTRY2(MMDC_P1 + MMDC_MPDGCTRL0, 0x434B0350, 0x42350231)
+WRITE_ENTRY2(MMDC_P0 + MMDC_MPDGCTRL1, 0x034C0359, 0x021A0218)
+WRITE_ENTRY2(MMDC_P1 + MMDC_MPDGCTRL1, 0x03650348, 0x021A0218)
+WRITE_ENTRY2(MMDC_P0 + MMDC_MPRDDLCTL, 0x4436383B, 0x4B4B4E49)
+WRITE_ENTRY2(MMDC_P1 + MMDC_MPRDDLCTL, 0x39393341, 0x4B4B4E49)
+WRITE_ENTRY2(MMDC_P0 + MMDC_MPWRDLCTL, 0x35373933, 0x3F3F3035)
+WRITE_ENTRY2(MMDC_P1 + MMDC_MPWRDLCTL, 0x48254A36, 0x3F3F3035)
+WRITE_ENTRY2(MMDC_P0 + MMDC_MPWLDECTRL0, 0x001F001F, 0x0040003C)
+WRITE_ENTRY2(MMDC_P0 + MMDC_MPWLDECTRL1, 0x001F001F, 0x0032003E)
+WRITE_ENTRY2(MMDC_P1 + MMDC_MPWLDECTRL0, 0x00440044, 0x0040003C)
+WRITE_ENTRY2(MMDC_P1 + MMDC_MPWLDECTRL1, 0x00440044, 0x0032003E)
 
 /* MPMUR0 - Complete calibration by forced measurement */
 WRITE_ENTRY1(MMDC_P0 + MMDC_MPMUR0, 0x00000800)
Signature · 1 line
1.7.9.5
author
#68 lore raw

PATCH v2 21/21 mx6qsabrelite: change CONFIG_SYS_PROMPT

In reply to Troy Kisky

The prompt is not appropriate if not running on
a mx6q processor.

---
 include/configs/mx6qsabrelite.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/configs/mx6qsabrelite.h +1 -1
index 72d0154..98fbb8d 100644
@@ -182,7 +182,7 @@
 /* Miscellaneous configurable options */
 #define CONFIG_SYS_LONGHELP
 #define CONFIG_SYS_HUSH_PARSER
-#define CONFIG_SYS_PROMPT	       "MX6QSABRELITE U-Boot > "
+#define CONFIG_SYS_PROMPT	       "U-Boot > "
 #define CONFIG_AUTO_COMPLETE
 #define CONFIG_SYS_CBSIZE	       256
 
Signature · 1 line
1.7.9.5
#69 lore raw

v2 cover Add mx6solo/mx6duallite support

In reply to Troy Kisky

Hi Troy,

Quoted 4 lines · Troy Kisky

After this series the same binary will run on a Saberlite board using any of the pin compatible processors mx6 quad, mx6 duallite, or mx6 solo. This is accomplished using a plugin and a table built by mkimage.

Could you briefly explain or give a link to some documentation how this does work? It sounds to me that the plugin concept is something the boot ROM has to understand? Or in other words: How does the boot ROM decide on which processor it runs and which DCD table to execute then?

Sorry if I misunderstood something, I'm not so familiar with the boot ROM options.

Many thanks

Dirk

author
#70 lore raw

v2 cover Add mx6solo/mx6duallite support

Quoted 14 lines · Dirk Behme

Hi Troy,

Quoted 4 lines · Troy Kisky

After this series the same binary will run on a Saberlite board using any of the pin compatible processors mx6 quad, mx6 duallite, or mx6 solo. This is accomplished using a plugin and a table built by mkimage.

Could you briefly explain or give a link to some documentation how this does work? It sounds to me that the plugin concept is something the boot ROM has to understand? Or in other words: How does the boot ROM decide on which processor it runs and which DCD table to execute then?

Quoted 7 lines

Sorry if I misunderstood something, I'm not so familiar with the boot ROM options.

Many thanks

Dirk

The table generated by mkimage for use with the plugin is not a standard ROM decodable table.
Only the plugin itself will decode the table. After it processes the table to initialize memory,
it calls back into the ROM to finish the u-boot load.

see file arch/arm/include/asm/arch-mx6/imx-mkimage.h

author
#71 lore raw

v3 cover Add mx6solo/mx6duallite support

In reply to Troy Kisky

This series goal is to add support for mx6solo and mx6duallite variants of mx6qsabrelite board. The new targets are called mx6ssabrelite and mx6dlsabrelite.

The 1st 16 patches perform cleanup on imximage

The final 2 patches add support for expressions to mkimage. If found not to be worth the effort, they can be omitted.

Troy Kisky (32):
imximage: check dcd_len as entries added
imximage: remove redundant setting of app_dest_ptr
imximage: move flash_offset check to common location
imximage: fix size of image to load.
imximage: delay setting of image size
imximage: change parameters to set_imx_hdr
imximage: make set_imx_hdr_v1/v2 easier to read
imximage: make header variable length
imximage: remove static imximage_version
imximage: prepare to move static variables to struct data_src
imximage: change parameters for set_dcd_val/set_imx_hdr
imximage: move set_imx_hdr to struct data_src
imximage: move set_dcd_val to struct data_src
imximage: enable word writes for version2 header
tools: add parse_helper file
imximage: use parse_helper functions
imximage.cfg: run files through C preprocessor mx6q_4x_mt41j128.cfg: use symbols instead of hardcoded constants mx6q_4x_mt41j128.cfg: add comments mx6q_4x_mt41j128.cfg: use ddr3 mode for reset mx6q_4x_mt41j128.cfg: skip initiailizing non-existent memory mx6q_4x_mt41j128.cfg: force ZQ calibration
mx6: soc: update get_cpu_rev and get_imx_type for mx6solo/sololite
mx6: use CONFIG_MX6 instead of CONFIG_MX6Q
imx-common: cpu: add imx_ddr_size
arch-mx6: add mx6dl_pins.h
mx6qsabrelite: add support for mx6 solo/duallite mx6q_4x_mt41j128.cfg: add mx6 solo/duallite support
Add boards for sabrelite variants mx6s(solo) and mx6dl(duallite)
mx6qsabrelite: change CONFIG_SYS_PROMPT
parse_helper: add expression evaluation
imx-mkimage.h: use base + offset syntax

 Makefile                                      |    3 +-
 arch/arm/cpu/armv7/mx6/soc.c                  |   32 +-
 arch/arm/imx-common/cpu.c                     |   66 +++-
 arch/arm/include/asm/arch-mx5/sys_proto.h     |   10 +-
 arch/arm/include/asm/arch-mx6/imx-mkimage.h   |  133 +++++++
 arch/arm/include/asm/arch-mx6/imx-regs.h      |    2 +
 arch/arm/include/asm/arch-mx6/mx6dl_pins.h    |  118 ++++++
 arch/arm/include/asm/arch-mx6/sys_proto.h     |   10 +-
 board/esg/ima3-mx53/imximage.cfg              |  120 +++---
 board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg  |  425 ++++++++++++---------
 board/freescale/mx25pdk/imximage.cfg          |   77 ++--
 board/freescale/mx51evk/imximage.cfg          |  114 +++---
 board/freescale/mx53ard/imximage_dd3.cfg      |   83 +++--
 board/freescale/mx53evk/imximage.cfg          |   86 ++---
 board/freescale/mx53loco/imximage.cfg         |   83 +++--
 board/freescale/mx53smd/imximage.cfg          |   83 +++--
 board/freescale/mx6qarm2/imximage.cfg         |   88 ++---
 board/freescale/mx6qsabrelite/mx6qsabrelite.c |  235 +++---------
 board/freescale/mx6qsabrelite/pads.h          |  172 +++++++++
 board/genesi/mx51_efikamx/imximage_mx.cfg     |  132 +++----
 board/genesi/mx51_efikamx/imximage_sb.cfg     |  126 ++++---
 board/ttcontrol/vision2/imximage_hynix.cfg    |  295 ++++++++-------
 boards.cfg                                    |    4 +-
 drivers/gpio/mxc_gpio.c                       |    6 +-
 drivers/video/ipu_regs.h                      |    2 +-
 include/configs/mx6qarm2.h                    |    1 +
 include/configs/mx6qsabre_common.h            |    1 +
 include/configs/mx6qsabrelite.h               |    4 +-
 tools/Makefile                                |    2 +
 tools/imximage.c                              |  487 ++++++++++---------------
 tools/imximage.h                              |   39 +-
 tools/parse_helper.c                          |  325 +++++++++++++++++
 tools/parse_helper.h                          |   28 ++
 33 files changed, 2106 insertions(+), 1286 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-mx6/imx-mkimage.h
 create mode 100644 arch/arm/include/asm/arch-mx6/mx6dl_pins.h
 create mode 100644 board/freescale/mx6qsabrelite/pads.h
 create mode 100644 tools/parse_helper.c
 create mode 100644 tools/parse_helper.h
Signature · 1 line
1.7.9.5
author
#72 lore raw

PATCH v3 1/32 imximage: check dcd_len as entries added

Before the len was checked after the entire file was processed, so it could have already overflowed.

---
v3 changed to the 1st patch of the series

---
 tools/imximage.c |   26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)
tools/imximage.c +11 -15
index 03a7716..c917036 100644
@@ -71,6 +71,7 @@ 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 uint32_t max_dcd_entries;
 
 static uint32_t get_cfg_value(char *token, char *name,  int linenr)
 {
@@ -170,13 +171,6 @@ static void set_dcd_rst_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 {
 	dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
 
-	if (dcd_len > MAX_HW_CFG_SIZE_V1) {
-		fprintf(stderr, "Error: %s[%d] -"
-			"DCD table exceeds maximum size(%d)\n",
-			name, lineno, MAX_HW_CFG_SIZE_V1);
-		exit(EXIT_FAILURE);
-	}
-
 	dcd_v1->preamble.barker = DCD_BARKER;
 	dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t);
 }
@@ -190,13 +184,6 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 {
 	dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
 
-	if (dcd_len > MAX_HW_CFG_SIZE_V2) {
-		fprintf(stderr, "Error: %s[%d] -"
-			"DCD table exceeds maximum size(%d)\n",
-			name, lineno, MAX_HW_CFG_SIZE_V2);
-		exit(EXIT_FAILURE);
-	}
-
 	dcd_v2->header.tag = DCD_HEADER_TAG;
 	dcd_v2->header.length = cpu_to_be16(
 			dcd_len * sizeof(dcd_addr_data_t) + 8);
@@ -295,11 +282,13 @@ static void set_hdr_func(struct imx_header *imxhdr)
 		set_dcd_val = set_dcd_val_v1;
 		set_dcd_rst = set_dcd_rst_v1;
 		set_imx_hdr = set_imx_hdr_v1;
+		max_dcd_entries = MAX_HW_CFG_SIZE_V1;
 		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;
+		max_dcd_entries = MAX_HW_CFG_SIZE_V2;
 		break;
 	default:
 		err_imximage_version(imximage_version);
@@ -426,8 +415,15 @@ static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
 		value = get_cfg_value(token, name, lineno);
 		(*set_dcd_val)(imxhdr, name, lineno, fld, value, *dcd_len);
 
-		if (fld == CFG_REG_VALUE)
+		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);
+			}
+		}
 		break;
 	default:
 		break;
Signature · 1 line
1.7.9.5
#73 lore raw

PATCH v3 1/32 imximage: check dcd_len as entries added

Am 04/10/2012 03:47, schrieb Troy Kisky:

Quoted 6 lines

Before the len was checked after the entire file was processed, so it could have already overflowed.

---

Applied to u-boot-imx, thanks.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#74 lore raw

PATCH v3 2/32 imximage: remove redundant setting of app_dest_ptr

In reply to Troy Kisky

---
v3: split into its own patch

---
 tools/imximage.c |    1 -
 1 file changed, 1 deletion(-)
tools/imximage.c +0 -1
index c917036..bda1a75 100644
@@ -213,7 +213,6 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-	fhdr_v1->app_dest_ptr = params->addr;
 	fhdr_v1->app_dest_ptr = params->ep - imxhdr->flash_offset -
 		sizeof(struct imx_header);
 	fhdr_v1->app_code_jump_vector = params->ep;
Signature · 1 line
1.7.9.5
#75 lore raw

PATCH v3 2/32 imximage: remove redundant setting of app_dest_ptr

Quoted 14 lines · Troy Kisky

---
v3: split into its own patch

---
 tools/imximage.c |    1 -
 1 file changed, 1 deletion(-)
tools/imximage.c +0 -0
index c917036..bda1a75 100644

tools/imximage.c static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len, · line 218

Quoted 7 lines
tools/imximage.c +0 -1
@@ -213,7 +213,6 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-	fhdr_v1->app_dest_ptr = params->addr;
 	fhdr_v1->app_dest_ptr = params->ep - imxhdr->flash_offset -
 		sizeof(struct imx_header);
 	fhdr_v1->app_code_jump_vector = params->ep;

I think we do not need to discuss on this. I put in in my -next queue and I will apply it soon.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#76 lore raw

PATCH v3 2/32 imximage: remove redundant setting of app_dest_ptr

In reply to Troy Kisky

Am 04/10/2012 03:47, schrieb Troy Kisky:

Quoted 14 lines

---
v3: split into its own patch

---
 tools/imximage.c |    1 -
 1 file changed, 1 deletion(-)
tools/imximage.c +0 -0
index c917036..bda1a75 100644

tools/imximage.c static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len, · line 218

Quoted 7 lines
tools/imximage.c +0 -1
@@ -213,7 +213,6 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-	fhdr_v1->app_dest_ptr = params->addr;
 	fhdr_v1->app_dest_ptr = params->ep - imxhdr->flash_offset -
 		sizeof(struct imx_header);
 	fhdr_v1->app_code_jump_vector = params->ep;

Applied to u-boot-imx, thanks.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#77 lore raw

PATCH v3 3/32 imximage: move flash_offset check to common location

In reply to Troy Kisky

Both set_imx_hdr_v1 and set_imx_hdr_v2 perform the same check. Move check to before the set_imx_hdr call.

---
v3: split into its own patch

---
 tools/imximage.c |   19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)
tools/imximage.c +5 -14
index bda1a75..3e9ee6a 100644
@@ -203,13 +203,6 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table;
 	uint32_t base_offset;
 
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v1: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}
-
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
@@ -243,13 +236,6 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
 	flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
 
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v2: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}
-
 	/* Set magic number */
 	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
 	fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t));
@@ -475,6 +461,11 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
 	(*set_dcd_rst)(imxhdr, dcd_len, name, lineno);
 	fclose(fd);
 
+	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
+	if (imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
+		fprintf(stderr, "Error: No BOOT_FROM tag in %s\n", name);
+		exit(EXIT_FAILURE);
+	}
 	return dcd_len;
 }
 
Signature · 1 line
1.7.9.5
#78 lore raw

PATCH v3 3/32 imximage: move flash_offset check to common location

Quoted 45 lines · Troy Kisky

Both set_imx_hdr_v1 and set_imx_hdr_v2 perform the same check. Move check to before the set_imx_hdr call.

---
v3: split into its own patch

---
 tools/imximage.c |   19 +++++--------------
 1 file changed, 5 insertions(+), 14 deletions(-)
tools/imximage.c +0 -14
index bda1a75..3e9ee6a 100644
@@ -203,13 +203,6 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table;
 	uint32_t base_offset;
 
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v1: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}
-
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
@@ -243,13 +236,6 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
 	flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
 
-	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if(imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
-		fprintf(stderr, "Error: Header v2: No BOOT_FROM tag in %s\n",
-			params->imagename);
-		exit(EXIT_FAILURE);
-	}
-
 	/* Set magic number */
 	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
 	fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t));
@@ -475,6 +461,11 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
 	(*set_dcd_rst)(imxhdr, dcd_len, name, lineno);

tools/imximage.c static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name) · line 471

Quoted 10 lines
tools/imximage.c +5 -0
 	fclose(fd);
 
+	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
+	if (imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
+		fprintf(stderr, "Error: No BOOT_FROM tag in %s\n", name);
+		exit(EXIT_FAILURE);
+	}
 	return dcd_len;
 }
 

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#79 lore raw

PATCH v3 3/32 imximage: move flash_offset check to common location

Quoted 12 lines · Stefano Babic
Quoted 11 lines · Troy Kisky

Both set_imx_hdr_v1 and set_imx_hdr_v2 perform the same check. Move check to before the set_imx_hdr call.

---
v3: split into its own patch

---
  tools/imximage.c |   19 +++++--------------
  1 file changed, 5 insertions(+), 14 deletions(-)
Quoted 6 lines

Best regards,
Stefano Babic

Are you going to apply this(and 1/32, 2/23) now, or should I resend in the next version with your ack?

Thanks
Troy

#80 lore raw

PATCH v3 3/32 imximage: move flash_offset check to common location

Am 18/10/2012 20:40, schrieb Troy Kisky:

Quoted 13 lines · Stefano Babic
Quoted 12 lines · Troy Kisky
Quoted 11 lines

Both set_imx_hdr_v1 and set_imx_hdr_v2 perform the same check. Move check to before the set_imx_hdr call.

---
v3: split into its own patch

---
  tools/imximage.c |   19 +++++--------------
  1 file changed, 5 insertions(+), 14 deletions(-)
Quoted 9 lines
Quoted 6 lines

Best regards,
Stefano Babic

Are you going to apply this(and 1/32, 2/23) now, or should I resend in the next version with your ack?

Hi Troy,

I think the best way to proceed would be if I apply the patches for the fixes, so that you have not to resend even the patches that will be not touched. And maybe in this "incremental" way we can speed up the whole process.

In my ready-to-be-applied list I marked already the patches from 1/32 up to 5/32. My way to do this is to set them as "under reviewed" in patchworks, because there is not a "ready-to-be-merged" state.

IMHO even patches up to 9/32 can be applied, they are free of comments and we discussed about them in your previous posting.
So please wait, I will apply the first set of patches.

Best regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#81 lore raw

PATCH v3 3/32 imximage: move flash_offset check to common location

In reply to Troy Kisky

Am 04/10/2012 03:47, schrieb Troy Kisky:

Quoted 6 lines

Both set_imx_hdr_v1 and set_imx_hdr_v2 perform the same check. Move check to before the set_imx_hdr call.

---

Applied to u-boot-imx, thanks.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#82 lore raw

PATCH v3 4/32 imximage: fix size of image to load.

In reply to Troy Kisky

sbuf->st_size already includes sizeof(struct imx_header), so remove extra addition.

---
v3: split into its own patch

---
 tools/imximage.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
tools/imximage.c +2 -4
index 3e9ee6a..7dbf36c 100644
@@ -221,8 +221,7 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 
 	/* The external flash header must be at the end of the DCD table */
 	dcd_v1->addr_data[dcd_len].type = sbuf->st_size +
-				imxhdr->flash_offset +
-				sizeof(struct imx_header);
+				imxhdr->flash_offset;
 
 	/* Security feature are not supported */
 	fhdr_v1->app_code_csf = 0;
@@ -253,8 +252,7 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 
 	hdr_v2->boot_data.start = fhdr_v2->self - imxhdr->flash_offset;
 	hdr_v2->boot_data.size = sbuf->st_size +
-			imxhdr->flash_offset +
-			sizeof(struct imx_header);
+			imxhdr->flash_offset;
 
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
Signature · 1 line
1.7.9.5
#83 lore raw

PATCH v3 4/32 imximage: fix size of image to load.

Am 04/10/2012 03:47, schrieb Troy Kisky:

Quoted 6 lines

sbuf->st_size already includes sizeof(struct imx_header), so remove extra addition.

---

Applied to u-boot-imx, thanks.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#84 lore raw

PATCH v3 5/32 imximage: delay setting of image size

In reply to Troy Kisky

When later we change to variable length
header, we won't know the file size when
set_imx_hdr is called. So this is prep work.

---
v3: split into its own patch

---
 tools/imximage.c |   12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
tools/imximage.c +6 -6
index 7dbf36c..bed53f0 100644
@@ -72,6 +72,7 @@ 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 uint32_t max_dcd_entries;
+static uint32_t *header_size_ptr;
 
 static uint32_t get_cfg_value(char *token, char *name,  int linenr)
 {
@@ -202,6 +203,8 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
 	dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table;
 	uint32_t base_offset;
+	uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr)
+			- ((char *)imxhdr));
 
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
@@ -219,13 +222,10 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	fhdr_v1->dcd_ptr = base_offset +
 			offsetof(imx_header_v1_t, dcd_table);
 
-	/* The external flash header must be at the end of the DCD table */
-	dcd_v1->addr_data[dcd_len].type = sbuf->st_size +
-				imxhdr->flash_offset;
-
 	/* Security feature are not supported */
 	fhdr_v1->app_code_csf = 0;
 	fhdr_v1->super_root_key = 0;
+	header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4);
 }
 
 static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
@@ -251,11 +251,10 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 			offsetof(imx_header_v2_t, boot_data);
 
 	hdr_v2->boot_data.start = fhdr_v2->self - imxhdr->flash_offset;
-	hdr_v2->boot_data.size = sbuf->st_size +
-			imxhdr->flash_offset;
 
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
+	header_size_ptr = &hdr_v2->boot_data.size;
 }
 
 static void set_hdr_func(struct imx_header *imxhdr)
@@ -526,6 +525,7 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 
 	/* Set the imx header */
 	(*set_imx_hdr)(imxhdr, dcd_len, sbuf, params);
+	*header_size_ptr = sbuf->st_size + imxhdr->flash_offset;
 }
 
 int imximage_check_params(struct mkimage_params *params)
Signature · 1 line
1.7.9.5
#85 lore raw

PATCH v3 5/32 imximage: delay setting of image size

Am 04/10/2012 03:47, schrieb Troy Kisky:

Quoted 9 lines

When later we change to variable length
header, we won't know the file size when
set_imx_hdr is called. So this is prep work.

---
v3: split into its own patch
---

Applied to u-boot-imx, thanks.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#86 lore raw

PATCH v3 6/32 imximage: change parameters to set_imx_hdr

In reply to Troy Kisky

Call with the value the function will use
instead of going through a pointer.

---
v3: split into its own patch

---
 tools/imximage.c |   20 +++++++++-----------
 tools/imximage.h |    6 ++----
 2 files changed, 11 insertions(+), 15 deletions(-)
tools/imximage.c +9 -11
index bed53f0..87a6b59 100644
@@ -196,8 +196,7 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 }
 
 static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params)
+		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;
@@ -209,11 +208,11 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-	fhdr_v1->app_dest_ptr = params->ep - imxhdr->flash_offset -
+	fhdr_v1->app_dest_ptr = entry_point - flash_offset -
 		sizeof(struct imx_header);
-	fhdr_v1->app_code_jump_vector = params->ep;
+	fhdr_v1->app_code_jump_vector = entry_point;
 
-	base_offset = fhdr_v1->app_dest_ptr + imxhdr->flash_offset ;
+	base_offset = fhdr_v1->app_dest_ptr + flash_offset;
 	fhdr_v1->dcd_ptr_ptr =
 		(uint32_t) (offsetof(flash_header_v1_t, dcd_ptr) -
 		offsetof(flash_header_v1_t, app_code_jump_vector) +
@@ -229,8 +228,7 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 }
 
 static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params)
+		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;
@@ -240,9 +238,9 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t));
 	fhdr_v2->header.version = IVT_VERSION; /* 0x40 */
 
-	fhdr_v2->entry = params->ep;
+	fhdr_v2->entry = entry_point;
 	fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
-	fhdr_v2->self = params->ep - sizeof(struct imx_header);
+	fhdr_v2->self = entry_point - sizeof(struct imx_header);
 
 	fhdr_v2->dcd_ptr = fhdr_v2->self +
 			offsetof(imx_header_v2_t, dcd_table);
@@ -250,7 +248,7 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	fhdr_v2->boot_data_ptr = fhdr_v2->self +
 			offsetof(imx_header_v2_t, boot_data);
 
-	hdr_v2->boot_data.start = fhdr_v2->self - imxhdr->flash_offset;
+	hdr_v2->boot_data.start = fhdr_v2->self - flash_offset;
 
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
@@ -524,7 +522,7 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 	dcd_len = parse_cfg_file(imxhdr, params->imagename);
 
 	/* Set the imx header */
-	(*set_imx_hdr)(imxhdr, dcd_len, sbuf, params);
+	(*set_imx_hdr)(imxhdr, dcd_len, params->ep, imxhdr->flash_offset);
 	*header_size_ptr = sbuf->st_size + imxhdr->flash_offset;
 }
 
tools/imximage.h +2 -4
index 34f293d..42b6090 100644
@@ -168,9 +168,7 @@ typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr,
 					uint32_t dcd_len,
 					char *name, int lineno);
 
-typedef void (*set_imx_hdr_t)(struct imx_header *imxhdr,
-					uint32_t dcd_len,
-					struct stat *sbuf,
-					struct mkimage_params *params);
+typedef void (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
+		uint32_t entry_point, uint32_t flash_offset);
 
 #endif /* _IMXIMAGE_H_ */
Signature · 1 line
1.7.9.5
#87 lore raw

PATCH v3 6/32 imximage: change parameters to set_imx_hdr

Am 04/10/2012 03:47, schrieb Troy Kisky:

Quoted 6 lines

Call with the value the function will use
instead of going through a pointer.

---

Applied to u-boot-imx, thanks.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#88 lore raw

PATCH v3 7/32 imximage: make set_imx_hdr_v1/v2 easier to read

In reply to Troy Kisky

---
v3: split into own patch

---
 tools/imximage.c |   30 +++++++++++-------------------
 1 file changed, 11 insertions(+), 19 deletions(-)
tools/imximage.c +11 -19
index 87a6b59..63f88b6 100644
@@ -201,25 +201,19 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	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 base_offset;
+	uint32_t hdr_base;
 	uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr)
 			- ((char *)imxhdr));
 
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-	fhdr_v1->app_dest_ptr = entry_point - flash_offset -
-		sizeof(struct imx_header);
+	hdr_base = entry_point - sizeof(struct imx_header);
+	fhdr_v1->app_dest_ptr = hdr_base - flash_offset;
 	fhdr_v1->app_code_jump_vector = entry_point;
 
-	base_offset = fhdr_v1->app_dest_ptr + flash_offset;
-	fhdr_v1->dcd_ptr_ptr =
-		(uint32_t) (offsetof(flash_header_v1_t, dcd_ptr) -
-		offsetof(flash_header_v1_t, app_code_jump_vector) +
-		base_offset);
-
-	fhdr_v1->dcd_ptr = base_offset +
-			offsetof(imx_header_v1_t, dcd_table);
+	fhdr_v1->dcd_ptr_ptr = hdr_base + offsetof(flash_header_v1_t, dcd_ptr);
+	fhdr_v1->dcd_ptr = hdr_base + offsetof(imx_header_v1_t, dcd_table);
 
 	/* Security feature are not supported */
 	fhdr_v1->app_code_csf = 0;
@@ -232,6 +226,7 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 {
 	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
 	flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
+	uint32_t hdr_base;
 
 	/* Set magic number */
 	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
@@ -240,15 +235,12 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 
 	fhdr_v2->entry = entry_point;
 	fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
-	fhdr_v2->self = entry_point - sizeof(struct imx_header);
-
-	fhdr_v2->dcd_ptr = fhdr_v2->self +
-			offsetof(imx_header_v2_t, dcd_table);
-
-	fhdr_v2->boot_data_ptr = fhdr_v2->self +
-			offsetof(imx_header_v2_t, boot_data);
+	fhdr_v2->self = hdr_base = entry_point - sizeof(struct imx_header);
 
-	hdr_v2->boot_data.start = fhdr_v2->self - flash_offset;
+	fhdr_v2->dcd_ptr = hdr_base + offsetof(imx_header_v2_t, dcd_table);
+	fhdr_v2->boot_data_ptr = hdr_base
+			+ offsetof(imx_header_v2_t, boot_data);
+	hdr_v2->boot_data.start = hdr_base - flash_offset;
 
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
Signature · 1 line
1.7.9.5
#89 lore raw

PATCH v3 7/32 imximage: make set_imx_hdr_v1/v2 easier to read

Am 04/10/2012 03:47, schrieb Troy Kisky:

Quoted 5 lines

---
v3: split into own patch
---

Applied to u-boot-imx, thanks.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#90 lore raw

PATCH v3 8/32 imximage: make header variable length

In reply to Troy Kisky

This makes the dcd table options as well for v2. Also, the header offset is no longer right before the code starts.

Before this patch we have
000000 402000d1 17800000 00000000 177ffc2c 000010 177ffc20 177ffc00 00000000 00000000 000020 177ff800 00042b58 00000000 402803d2 000030 042403cc a8050e02 30000000 b0050e02 ... more DCD table
000340 cf0000f0 18000e02 7f007f00 1c000e02 000350 7f007f00 00000000 00000000 00000000 000360 00000000 00000000 00000000 00000000 *
0003f0 00000000 00000000 00000000 00000400 000400 ea000014 e59ff014 e59ff014 e59ff014

Notice offset 3fc contains 0x400. This is the header offset. There is no reason for this to be in the file, and I have removed it.

After this patch we have
000000 402000d1 17800000 00000000 177ffcd8 000010 177ffccc 177ffcac 00000000 00000000 000020 177ff8ac 000426ac 00000000 402803d2 000030 042403cc a8050e02 30000000 b0050e02 ... more DCD table
000340 cf0000f0 18000e02 7f007f00 1c000e02 000350 7f007f00 ea000014 e59ff014 e59ff014 000360 e59ff014 e59ff014 e59ff014 e59ff014

Notice the zeros between 0x354 and 0x3fb have been removed.

---

v3: other patches split from this one

---
 tools/imximage.c |   61 +++++++++++++++++++++++++++++++++++++-----------------
 tools/imximage.h |    4 ++--
 2 files changed, 44 insertions(+), 21 deletions(-)
tools/imximage.c +42 -19
index 63f88b6..1365b1e 100644
@@ -65,7 +65,6 @@ static table_entry_t imximage_versions[] = {
 	{-1,            "",     " (Invalid)",                 },
 };
 
-static struct imx_header imximage_header;
 static uint32_t imximage_version;
 
 static set_dcd_val_t set_dcd_val;
@@ -73,6 +72,9 @@ static set_dcd_rst_t set_dcd_rst;
 static set_imx_hdr_t set_imx_hdr;
 static uint32_t max_dcd_entries;
 static uint32_t *header_size_ptr;
+static uint32_t g_flash_offset;
+
+static struct image_type_params imximage_params;
 
 static uint32_t get_cfg_value(char *token, char *name,  int linenr)
 {
@@ -102,8 +104,7 @@ static uint32_t detect_imximage_version(struct imx_header *imx_hdr)
 		return IMXIMAGE_V1;
 
 	/* Try to detect V2 */
-	if ((fhdr_v2->header.tag == IVT_HEADER_TAG) &&
-		(hdr_v2->dcd_table.header.tag == DCD_HEADER_TAG))
+	if (fhdr_v2->header.tag == IVT_HEADER_TAG)
 		return IMXIMAGE_V2;
 
 	return IMXIMAGE_VER_INVALID;
@@ -195,7 +196,7 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;
 }
 
-static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
+static int set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 		uint32_t entry_point, uint32_t flash_offset)
 {
 	imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;
@@ -208,7 +209,7 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-	hdr_base = entry_point - sizeof(struct imx_header);
+	hdr_base = entry_point - header_length;
 	fhdr_v1->app_dest_ptr = hdr_base - flash_offset;
 	fhdr_v1->app_code_jump_vector = entry_point;
 
@@ -219,14 +220,18 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	fhdr_v1->app_code_csf = 0;
 	fhdr_v1->super_root_key = 0;
 	header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4);
+	return header_length;
 }
 
-static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 		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);
 
 	/* Set magic number */
 	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
@@ -235,9 +240,10 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 
 	fhdr_v2->entry = entry_point;
 	fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
-	fhdr_v2->self = hdr_base = entry_point - sizeof(struct imx_header);
+	fhdr_v2->self = hdr_base = entry_point - header_length;
 
-	fhdr_v2->dcd_ptr = hdr_base + offsetof(imx_header_v2_t, dcd_table);
+	fhdr_v2->dcd_ptr = (dcd_len) ? hdr_base
+			+ offsetof(imx_header_v2_t, dcd_table) : 0;
 	fhdr_v2->boot_data_ptr = hdr_base
 			+ offsetof(imx_header_v2_t, boot_data);
 	hdr_v2->boot_data.start = hdr_base - flash_offset;
@@ -245,6 +251,7 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
 	header_size_ptr = &hdr_v2->boot_data.size;
+	return header_length;
 }
 
 static void set_hdr_func(struct imx_header *imxhdr)
@@ -342,9 +349,9 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
 		set_hdr_func(imxhdr);
 		break;
 	case CMD_BOOT_FROM:
-		imxhdr->flash_offset = get_table_entry_id(imximage_bootops,
+		g_flash_offset = get_table_entry_id(imximage_bootops,
 					"imximage boot option", token);
-		if (imxhdr->flash_offset == -1) {
+		if (g_flash_offset == -1) {
 			fprintf(stderr, "Error: %s[%d] -Invalid boot device"
 				"(%s)\n", name, lineno, token);
 			exit(EXIT_FAILURE);
@@ -449,7 +456,7 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
 	fclose(fd);
 
 	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if (imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
+	if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {
 		fprintf(stderr, "Error: No BOOT_FROM tag in %s\n", name);
 		exit(EXIT_FAILURE);
 	}
@@ -494,12 +501,17 @@ static void imximage_print_header(const void *ptr)
 	}
 }
 
-static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
-				struct mkimage_params *params)
+int imximage_vrec_header(struct mkimage_params *params,
+		struct image_type_params *tparams)
 {
-	struct imx_header *imxhdr = (struct imx_header *)ptr;
+	struct imx_header *imxhdr;
 	uint32_t dcd_len;
 
+	imxhdr = calloc(1, MAX_HEADER_SIZE);
+	if (!imxhdr) {
+		fprintf(stderr, "Error: out of memory\n");
+		exit(EXIT_FAILURE);
+	}
 	/*
 	 * In order to not change the old imx cfg file
 	 * by adding VERSION command into it, here need
@@ -507,15 +519,27 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 	 */
 	imximage_version = IMXIMAGE_V1;
 	/* Be able to detect if the cfg file has no BOOT_FROM tag */
-	imxhdr->flash_offset = FLASH_OFFSET_UNDEFINED;
+	g_flash_offset = FLASH_OFFSET_UNDEFINED;
 	set_hdr_func(imxhdr);
 
 	/* Parse dcd configuration file */
 	dcd_len = parse_cfg_file(imxhdr, params->imagename);
 
 	/* Set the imx header */
-	(*set_imx_hdr)(imxhdr, dcd_len, params->ep, imxhdr->flash_offset);
-	*header_size_ptr = sbuf->st_size + imxhdr->flash_offset;
+	imximage_params.header_size = (*set_imx_hdr)(imxhdr, dcd_len,
+			params->ep, g_flash_offset);
+	imximage_params.hdr = imxhdr;
+	return 0;
+}
+
+static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
+				struct mkimage_params *params)
+{
+	/* Set the size in header */
+	uint32_t offset = (char *)header_size_ptr - (char *)imximage_params.hdr;
+	uint32_t *p = (uint32_t *)((char *)ptr + offset);
+
+	*p = sbuf->st_size + g_flash_offset;
 }
 
 int imximage_check_params(struct mkimage_params *params)
@@ -545,8 +569,7 @@ int imximage_check_params(struct mkimage_params *params)
  */
 static struct image_type_params imximage_params = {
 	.name		= "Freescale i.MX 5x Boot Image support",
-	.header_size	= sizeof(struct imx_header),
-	.hdr		= (void *)&imximage_header,
+	.vrec_header	= imximage_vrec_header,
 	.check_image_type = imximage_check_image_types,
 	.verify_header	= imximage_verify_header,
 	.print_header	= imximage_print_header,
tools/imximage.h +2 -2
index 42b6090..0f39447 100644
@@ -30,6 +30,7 @@
 #define DCD_BARKER	0xB17219E9
 
 #define HEADER_OFFSET	0x400
+#define MAX_HEADER_SIZE	(16 << 10)
 
 #define CMD_DATA_STR	"DATA"
 #define FLASH_OFFSET_UNDEFINED	0xFFFFFFFF
@@ -156,7 +157,6 @@ struct imx_header {
 		imx_header_v1_t hdr_v1;
 		imx_header_v2_t hdr_v2;
 	} header;
-	uint32_t flash_offset;
 };
 
 typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
@@ -168,7 +168,7 @@ typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr,
 					uint32_t dcd_len,
 					char *name, int lineno);
 
-typedef void (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
+typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
 		uint32_t entry_point, uint32_t flash_offset);
 
 #endif /* _IMXIMAGE_H_ */
Signature · 1 line
1.7.9.5
#91 lore raw

PATCH v3 8/32 imximage: make header variable length

Am 04/10/2012 03:47, schrieb Troy Kisky:

Quoted 32 lines

This makes the dcd table options as well for v2. Also, the header offset is no longer right before the code starts.

Before this patch we have
000000 402000d1 17800000 00000000 177ffc2c 000010 177ffc20 177ffc00 00000000 00000000 000020 177ff800 00042b58 00000000 402803d2 000030 042403cc a8050e02 30000000 b0050e02 ... more DCD table
000340 cf0000f0 18000e02 7f007f00 1c000e02 000350 7f007f00 00000000 00000000 00000000 000360 00000000 00000000 00000000 00000000 *
0003f0 00000000 00000000 00000000 00000400 000400 ea000014 e59ff014 e59ff014 e59ff014

Notice offset 3fc contains 0x400. This is the header offset. There is no reason for this to be in the file, and I have removed it.

After this patch we have
000000 402000d1 17800000 00000000 177ffcd8 000010 177ffccc 177ffcac 00000000 00000000 000020 177ff8ac 000426ac 00000000 402803d2 000030 042403cc a8050e02 30000000 b0050e02 ... more DCD table
000340 cf0000f0 18000e02 7f007f00 1c000e02 000350 7f007f00 ea000014 e59ff014 e59ff014 000360 e59ff014 e59ff014 e59ff014 e59ff014

Quoted 6 lines

Notice the zeros between 0x354 and 0x3fb have been removed.

---

Hi Troy,

my test with this patch was not successful. I have tested it on a mx53loco, and the board cannot boot. It stops after printing the RAM size:

U-Boot 2012.10-00226-g673b6b8 (Oct 20 2012 - 17:40:07)

Board: MX53 LOCO
I2C:   ready
DRAM:  1 GiB

Everything works fine without the patch (patches 1-7 already applied, too). I wanted to test on V1 SOCs, too, but I stopped after seeing that on a MX53 is not working.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#92 lore raw

PATCH v3 8/32 imximage: make header variable length

Quoted 52 lines · Stefano Babic

Am 04/10/2012 03:47, schrieb Troy Kisky:

Quoted 32 lines

This makes the dcd table options as well for v2. Also, the header offset is no longer right before the code starts.

Before this patch we have
000000 402000d1 17800000 00000000 177ffc2c 000010 177ffc20 177ffc00 00000000 00000000 000020 177ff800 00042b58 00000000 402803d2 000030 042403cc a8050e02 30000000 b0050e02 ... more DCD table
000340 cf0000f0 18000e02 7f007f00 1c000e02 000350 7f007f00 00000000 00000000 00000000 000360 00000000 00000000 00000000 00000000 *
0003f0 00000000 00000000 00000000 00000400 000400 ea000014 e59ff014 e59ff014 e59ff014

Notice offset 3fc contains 0x400. This is the header offset. There is no reason for this to be in the file, and I have removed it.

After this patch we have
000000 402000d1 17800000 00000000 177ffcd8 000010 177ffccc 177ffcac 00000000 00000000 000020 177ff8ac 000426ac 00000000 402803d2 000030 042403cc a8050e02 30000000 b0050e02 ... more DCD table
000340 cf0000f0 18000e02 7f007f00 1c000e02 000350 7f007f00 ea000014 e59ff014 e59ff014 000360 e59ff014 e59ff014 e59ff014 e59ff014

Quoted 6 lines

Notice the zeros between 0x354 and 0x3fb have been removed.

---

Hi Troy,

my test with this patch was not successful. I have tested it on a mx53loco, and the board cannot boot. It stops after printing the RAM size:

U-Boot 2012.10-00226-g673b6b8 (Oct 20 2012 - 17:40:07)

Board: MX53 LOCO
I2C:   ready
DRAM:  1 GiB
Quoted 7 lines

Everything works fine without the patch (patches 1-7 already applied, too). I wanted to test on V1 SOCs, too, but I stopped after seeing that on a MX53 is not working.

Best regards,
Stefano Babic

I've tested this patch on a mx51 boards as well and it worked fine there.

For testing purposes, can you see if this change helps any? Perhaps the rom isn't loading all the code, and this will load a little more.

arch/arm/cpu/u-boot.lds +6 -0
index e49ca0c..4b303f1 100644
@@ -86,6 +86,12 @@ SECTIONS
                 __bss_end__ = .;
         }
 
+       .zdata1 : {
+               . = ALIGN(512);
+               LONG(0xdeadbeef);
+               FILL(0xefbeadde);
+               . = ALIGN(512);
+       }
         /DISCARD/ : { *(.dynstr*) }
         /DISCARD/ : { *(.dynamic*) }
         /DISCARD/ : { *(.plt*) }
#93 lore raw

PATCH v3 8/32 imximage: make header variable length

Am 21/10/2012 03:31, schrieb Troy Kisky:

Quoted 2 lines

I've tested this patch on a mx51 boards as well and it worked fine there.

Fine, thanks, this saves me time - I will not test it on that SOC.

Quoted 4 lines

For testing purposes, can you see if this change helps any? Perhaps the rom isn't loading all the code, and this will load a little more.

I had the same feeling.

In fact, increasing artificially the size with the zdata1 section helps. It boots. There should be an error by computing the total length of the image.

Best regards,
Stefano

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#94 lore raw

PATCH v3 8/32 imximage: make header variable length

Quoted 8 lines · Stefano Babic

Am 21/10/2012 03:31, schrieb Troy Kisky:

Quoted 1 line

I've tested this patch on a mx51 boards as well and it worked fine there.

Fine, thanks, this saves me time - I will not test it on that SOC.

Quoted 3 lines

For testing purposes, can you see if this change helps any? Perhaps the rom isn't loading all the code, and this will load a little more.

Quoted 9 lines

I had the same feeling.

In fact, increasing artificially the size with the zdata1 section helps. It boots. There should be an error by computing the total length of the image.

Best regards,
Stefano

Oops, my previous test patch was after bss instead of before. With this patch

arch/arm/cpu/u-boot.lds +6 -0
index e49ca0c..8352c7c 100644
@@ -78,6 +78,12 @@ SECTIONS
         .mmutable : {
                 *(.mmutable)
         }
+       .zdata1 : {
+               . = ALIGN(512);
+               LONG(0xdeadbeef);
+               FILL(0xefbeadde);
+               . = ALIGN(512);
+       }
 
         .bss __rel_dyn_start (OVERLAY) : {
                 __bss_start = .;

My mx51 board shows

U-Boot > mw.l 97841000 12345678 2000000
U-Boot > reset
resetting ...

U-Boot 2012.10-01232-g2919aa2-dirty (Oct 22 2012 - 13:17:26)

CPU: Freescale i.MX51 rev3.0 at 800 MHz
Reset cause: WDOG
Board: Nitrogen
dram_init
dram_init exit

DRAM:  256 MiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
SF: Detected SST25VF016B with page size 4 KiB, total 2 MiB

*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   FEC
Warning: failed to set MAC address

Hit any key to stop autoboot: 0
U-Boot > md.l 97841000
97841000: deadbeef deadbeef deadbeef deadbeef ................ 97841010: deadbeef deadbeef deadbeef deadbeef ................ 97841020: deadbeef deadbeef deadbeef deadbeef ................ 97841030: deadbeef deadbeef deadbeef deadbeef ................ 97841040: deadbeef deadbeef deadbeef deadbeef ................ 97841050: deadbeef deadbeef deadbeef deadbeef ................ 97841060: deadbeef deadbeef deadbeef deadbeef ................ 97841070: deadbeef deadbeef deadbeef deadbeef ................ 97841080: deadbeef deadbeef deadbeef deadbeef ................ 97841090: deadbeef deadbeef deadbeef deadbeef ................ 978410a0: deadbeef deadbeef deadbeef deadbeef ................ 978410b0: deadbeef deadbeef deadbeef deadbeef ................ 978410c0: deadbeef deadbeef deadbeef deadbeef ................ 978410d0: deadbeef deadbeef deadbeef deadbeef ................ 978410e0: deadbeef deadbeef deadbeef deadbeef ................ 978410f0: deadbeef deadbeef deadbeef deadbeef ................ U-Boot >
97841100: deadbeef deadbeef deadbeef deadbeef ................ 97841110: deadbeef deadbeef deadbeef deadbeef ................ 97841120: deadbeef deadbeef deadbeef deadbeef ................ 97841130: deadbeef deadbeef deadbeef deadbeef ................ 97841140: deadbeef deadbeef deadbeef deadbeef ................ 97841150: deadbeef deadbeef deadbeef deadbeef ................ 97841160: deadbeef deadbeef deadbeef deadbeef ................ 97841170: deadbeef deadbeef deadbeef deadbeef ................ 97841180: deadbeef deadbeef deadbeef deadbeef ................ 97841190: deadbeef deadbeef deadbeef deadbeef ................ 978411a0: deadbeef deadbeef deadbeef deadbeef ................ 978411b0: deadbeef deadbeef deadbeef deadbeef ................ 978411c0: deadbeef deadbeef deadbeef deadbeef ................ 978411d0: deadbeef deadbeef deadbeef deadbeef ................ 978411e0: deadbeef deadbeef deadbeef deadbeef ................ 978411f0: deadbeef deadbeef deadbeef deadbeef ................ U-Boot >
97841200: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 97841210: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 97841220: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 97841230: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 97841240: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 97841250: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 97841260: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 97841270: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 97841280: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 97841290: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 978412a0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 978412b0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 978412c0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 978412d0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 978412e0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 978412f0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. U-Boot >

Showing that exactly the correct number of bytes where loaded.

_________________________________________________________
_________________________________________________________

My mx6q board shows

U-Boot > mw.l 1784e000 12345678 2000000
U-Boot > reset
resetting ...

U-Boot 2012.10-01232-g2919aa2-dirty (Oct 22 2012 - 13:45:52)

CPU:   Freescale i.MX6Q rev1.0 at 792 MHz
Reset cause: WDOG
Board: MX6Q-Sabre Lite
DRAM:  1 GiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
SF: Detected SST25VF016B with page size 4 KiB, total 2 MiB
No panel detected: default to HDMI
unsupported panel HDMI
In:    serial
Out:   serial
Err:   serial
Net: FEC
Warning: FEC using MAC address from net device

Hit any key to stop autoboot: 0
U-Boot > md.l 1784e000
1784e000: deadbeef deadbeef deadbeef deadbeef ................ 1784e010: deadbeef deadbeef deadbeef deadbeef ................ 1784e020: deadbeef deadbeef deadbeef deadbeef ................ 1784e030: deadbeef deadbeef deadbeef deadbeef ................ 1784e040: deadbeef deadbeef deadbeef deadbeef ................ 1784e050: deadbeef deadbeef deadbeef deadbeef ................ 1784e060: deadbeef deadbeef deadbeef deadbeef ................ 1784e070: deadbeef deadbeef deadbeef deadbeef ................ 1784e080: deadbeef deadbeef deadbeef deadbeef ................ 1784e090: deadbeef deadbeef deadbeef deadbeef ................ 1784e0a0: deadbeef deadbeef deadbeef deadbeef ................ 1784e0b0: deadbeef deadbeef deadbeef deadbeef ................ 1784e0c0: deadbeef deadbeef deadbeef deadbeef ................ 1784e0d0: deadbeef deadbeef deadbeef deadbeef ................ 1784e0e0: deadbeef deadbeef deadbeef deadbeef ................ 1784e0f0: deadbeef deadbeef deadbeef deadbeef ................ U-Boot >
1784e100: deadbeef deadbeef deadbeef deadbeef ................ 1784e110: deadbeef deadbeef deadbeef deadbeef ................ 1784e120: deadbeef deadbeef deadbeef deadbeef ................ 1784e130: deadbeef deadbeef deadbeef deadbeef ................ 1784e140: deadbeef deadbeef deadbeef deadbeef ................ 1784e150: deadbeef deadbeef deadbeef deadbeef ................ 1784e160: deadbeef deadbeef deadbeef deadbeef ................ 1784e170: deadbeef deadbeef deadbeef deadbeef ................ 1784e180: deadbeef deadbeef deadbeef deadbeef ................ 1784e190: deadbeef deadbeef deadbeef deadbeef ................ 1784e1a0: deadbeef deadbeef deadbeef deadbeef ................ 1784e1b0: deadbeef deadbeef deadbeef deadbeef ................ 1784e1c0: deadbeef deadbeef deadbeef deadbeef ................ 1784e1d0: deadbeef deadbeef deadbeef deadbeef ................ 1784e1e0: deadbeef deadbeef deadbeef deadbeef ................ 1784e1f0: deadbeef deadbeef deadbeef deadbeef ................ U-Boot >
1784e200: 02000000 46200600 00202000 00000000 ...... F. .....
1784e210: 00000010 00004020 00000000 00004222 .... @......"B..
1784e220: 02000000 00000040 00000000 00000000 .... at ........... 1784e230: 00000000 00000400 00020002 00000000 ................ 1784e240: 00140000 00000000 00100000 00008080 ................
1784e250: 00100200 00410080 00004020 18000110 ......A. @......
1784e260: 00000000 80000a00 00000000 00000000 ................ 1784e270: 00000280 08029980 00000000 00001080 ................ 1784e280: 40000000 00800002 02802404 02a00200 ... at .....$......
1784e290: 08002000 00000000 00808400 40200200 . ............ @
1784e2a0: 40000000 00000000 00000000 00000020 ... at ........ ...
1784e2b0: 00000000 00200020 00008000 00000000 .... . .........
1784e2c0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e2d0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e2e0: 00000200 00010001 00000201 10000000 ................ 1784e2f0: 14000000 00000000 00000001 08000011 ................ U-Boot >
1784e300: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e310: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e320: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e330: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e340: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e350: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e360: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e370: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e380: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e390: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e3a0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e3b0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e3c0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e3d0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e3e0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. 1784e3f0: 12345678 12345678 12345678 12345678 xV4.xV4.xV4.xV4. U-Boot >

Showing that an extra 0x100 bytes were written.

U-Boot > sf probe
SF: Detected SST25VF016B with page size 4 KiB, total 2 MiB U-Boot > sf read 10800000 400 50000
U-Boot > md.l 1084e334
1084e334: deadbeef deadbeef deadbeef deadbeef ................ 1084e344: deadbeef deadbeef deadbeef deadbeef ................ 1084e354: deadbeef deadbeef deadbeef deadbeef ................ 1084e364: deadbeef deadbeef deadbeef deadbeef ................ 1084e374: deadbeef deadbeef deadbeef deadbeef ................ 1084e384: deadbeef deadbeef deadbeef deadbeef ................ 1084e394: deadbeef deadbeef deadbeef deadbeef ................ 1084e3a4: deadbeef deadbeef deadbeef deadbeef ................ 1084e3b4: deadbeef deadbeef deadbeef deadbeef ................ 1084e3c4: deadbeef deadbeef deadbeef deadbeef ................ 1084e3d4: deadbeef deadbeef deadbeef deadbeef ................ 1084e3e4: deadbeef deadbeef deadbeef deadbeef ................ 1084e3f4: deadbeef deadbeef deadbeef deadbeef ................ 1084e404: deadbeef deadbeef deadbeef deadbeef ................ 1084e414: deadbeef deadbeef deadbeef deadbeef ................ 1084e424: deadbeef deadbeef deadbeef deadbeef ................ U-Boot >
1084e434: deadbeef deadbeef deadbeef deadbeef ................ 1084e444: deadbeef deadbeef deadbeef deadbeef ................ 1084e454: deadbeef deadbeef deadbeef deadbeef ................ 1084e464: deadbeef deadbeef deadbeef deadbeef ................ 1084e474: deadbeef deadbeef deadbeef deadbeef ................ 1084e484: deadbeef deadbeef deadbeef deadbeef ................ 1084e494: deadbeef deadbeef deadbeef deadbeef ................ 1084e4a4: deadbeef deadbeef deadbeef deadbeef ................ 1084e4b4: deadbeef deadbeef deadbeef deadbeef ................ 1084e4c4: deadbeef deadbeef deadbeef deadbeef ................ 1084e4d4: deadbeef deadbeef deadbeef deadbeef ................ 1084e4e4: deadbeef deadbeef deadbeef deadbeef ................ 1084e4f4: deadbeef deadbeef deadbeef deadbeef ................ 1084e504: deadbeef deadbeef deadbeef deadbeef ................ 1084e514: deadbeef deadbeef deadbeef deadbeef ................ 1084e524: deadbeef deadbeef deadbeef deadbeef ................ U-Boot >
1084e534: ffffffff ffffffff ffffffff ffffffff ................ 1084e544: ffffffff ffffffff ffffffff ffffffff ................ 1084e554: ffffffff ffffffff ffffffff ffffffff ................ 1084e564: ffffffff ffffffff ffffffff ffffffff ................ 1084e574: ffffffff ffffffff ffffffff ffffffff ................ 1084e584: ffffffff ffffffff ffffffff ffffffff ................ 1084e594: ffffffff ffffffff ffffffff ffffffff ................ 1084e5a4: ffffffff ffffffff ffffffff ffffffff ................ 1084e5b4: ffffffff ffffffff ffffffff ffffffff ................ 1084e5c4: ffffffff ffffffff ffffffff ffffffff ................ 1084e5d4: ffffffff ffffffff ffffffff ffffffff ................ 1084e5e4: ffffffff ffffffff ffffffff ffffffff ................ 1084e5f4: ffffffff ffffffff ffffffff ffffffff ................ 1084e604: ffffffff ffffffff ffffffff ffffffff ................ 1084e614: ffffffff ffffffff ffffffff ffffffff ................ 1084e624: ffffffff ffffffff ffffffff ffffffff ................

And those extra 0x100 bytes are garbage, not from the eprom.

Troy

author
#95 lore raw

v4 cover imximage series

In reply to Troy Kisky

This series make the file imximage.c easier to read, as well as produces a slightly smaller file.

Only the 1st two patches are different from version 3. The 1st is a new patch which addresses an mx53 ROM bug. The 2nd is slight changes due to rebase on 1st.

Troy Kisky (11):
imximage: mx53 needs transfer length a multiple of 512
imximage: make header variable length
imximage: remove static imximage_version
imximage: prepare to move static variables to struct data_src
imximage: change parameters for set_dcd_val/set_imx_hdr
imximage: move set_imx_hdr to struct data_src
imximage: move set_dcd_val to struct data_src
imximage: enable word writes for version2 header
tools: add parse_helper file
imximage: use parse_helper functions
parse_helper: add expression evaluation

 tools/Makefile       |    2 +
 tools/imximage.c     |  437 ++++++++++++++++++++++----------------------------
 tools/imximage.h     |   37 ++---
 tools/parse_helper.c |  325 +++++++++++++++++++++++++++++++++++++
 tools/parse_helper.h |   28 ++++
 5 files changed, 564 insertions(+), 265 deletions(-)
 create mode 100644 tools/parse_helper.c
 create mode 100644 tools/parse_helper.h
Signature · 1 line
1.7.9.5
author
#96 lore raw

PATCH v4 1/11 imximage: mx53 needs transfer length a multiple of 512

The mx53 ROM will truncate the length at a multiple of 512. Transferring too much is not a problem, so round up.

Problem reported by Stefano Babic.

---
 tools/imximage.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
tools/imximage.c +9 -1
index 63f88b6..7e54e97 100644
@@ -494,6 +494,8 @@ static void imximage_print_header(const void *ptr)
 	}
 }
 
+#define ALIGN(a, b)	(((a) + (b) - 1) & ~((b) - 1))
+
 static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 				struct mkimage_params *params)
 {
@@ -515,7 +517,13 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 
 	/* Set the imx header */
 	(*set_imx_hdr)(imxhdr, dcd_len, params->ep, imxhdr->flash_offset);
-	*header_size_ptr = sbuf->st_size + imxhdr->flash_offset;
+	/*
+	 * ROM bug alert
+	 * mx53 only loads 512 byte multiples.
+	 * The remaining fraction of a block bytes would
+	 * not be loaded.
+	 */
+	*header_size_ptr = ALIGN(sbuf->st_size + imxhdr->flash_offset, 512);
 }
 
 int imximage_check_params(struct mkimage_params *params)
Signature · 1 line
1.7.9.5
#97 lore raw

PATCH v4 1/11 imximage: mx53 needs transfer length a multiple of 512

Dear Troy Kisky,

Quoted 2 lines · In message <[email protected]>…

The mx53 ROM will truncate the length at a multiple of 512. Transferring too much is not a problem, so round up.

What about other SoCs using the same code?

Quoted 1 line

+#define ALIGN(a, b) (((a) + (b) - 1) & ~((b) - 1))

NAK. This macro is mis-named; it has nothing to do with alignment - you write yourself: "round up".

And you don't have to re-invent the wheel. Please use the existing macros for this purpose.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
If something is different, it's either better or worse,  and  usually
both.                                                    - Larry Wall
author
#98 lore raw

PATCH v4 1/11 imximage: mx53 needs transfer length a multiple of 512

Quoted 12 lines · Wolfgang Denk

Dear Troy Kisky,

Quoted 2 lines · In message <[email protected]>…

The mx53 ROM will truncate the length at a multiple of 512. Transferring too much is not a problem, so round up.

What about other SoCs using the same code?

Quoted 1 line

+#define ALIGN(a, b) (((a) + (b) - 1) & ~((b) - 1))

NAK. This macro is mis-named; it has nothing to do with alignment - you write yourself: "round up".

Quoted 7 lines

And you don't have to re-invent the wheel. Please use the existing macros for this purpose.

Best regards,

Wolfgang Denk

Oddly enough, I originally called it ROUND_UP. But then I saw these lines in include/common.h

#define ALIGN(x,a) __ALIGN_MASK((x),(typeof(x))(a)-1)
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))

So, I deleted my definition of ROUND_UP and used ALIGN. But imximage.c did not automatically include common.h. Instead of trying to include common.h and all the files it pulled in, I added the ALIGN definition.

Troy

#99 lore raw

PATCH v4 1/11 imximage: mx53 needs transfer length a multiple of 512

Dear Troy Kisky,

Quoted 3 lines · In message <[email protected]> you wrote:

Oddly enough, I originally called it ROUND_UP. But then I saw these lines in include/common.h

And why didn't you find (and use) ROUND() in include/common.h ?

Best regards,

Wolfgang Denk

Signature · 6 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
My challenge to the goto-less programmer  is  to  recode  tcp_input()
without any gotos ... without any loss of efficiency (there has to be
a catch).                                             - W. R. Stevens
author
#100 lore raw

PATCH v4 1/11 imximage: mx53 needs transfer length a multiple of 512

Quoted 11 lines · Wolfgang Denk

Dear Troy Kisky,

Quoted 2 lines · In message <[email protected]> you wrote:

Oddly enough, I originally called it ROUND_UP. But then I saw these lines in include/common.h

And why didn't you find (and use) ROUND() in include/common.h ?

Best regards,

Wolfgang Denk

I did also find ROUND, so I checked to see what Linux did. Linux does not have ROUND, but it does have ALIGN.

But I personally prefer ROUND, or even better ROUND_UP. I just wanted to use the most common form. u-boot seems to use ROUND in config files and ALIGN in .c files

But the reason I didn't include common.h is because of the target specific files that it also includes. Would you mind if I moved

_________________________
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

#define ROUND(a,b)              (((a) + (b) - 1) & ~((b) - 1))
#define DIV_ROUND(n,d)          (((n) + ((d)/2)) / (d))
#define DIV_ROUND_UP(n,d)       (((n) + (d) - 1) / (d))
#define roundup(x, y)           ((((x) + ((y) - 1)) / (y)) * (y))

#define ALIGN(x,a) __ALIGN_MASK((x),(typeof(x))(a)-1)
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
-------------------------------------

from common.h to a new file common_macro.h

and included common_macro.h instead?

Perhaps you have a better alternative?

Thanks
Troy

#101 lore raw

PATCH v4 1/11 imximage: mx53 needs transfer length a multiple of 512

Dear Troy Kisky,

Quoted 3 lines · In message <[email protected]> you wrote:

But the reason I didn't include common.h is because of the target specific files that it also includes. Would you mind if I moved

Why would these hurt? They don't anywhere else.

Quoted 1 line

and included common_macro.h instead?

I see no benefit for that.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
History is only a confused heap of facts.
                                       -- Philip Earl of Chesterfield
author
#102 lore raw

PATCH v4 1/11 imximage: mx53 needs transfer length a multiple of 512

Quoted 7 lines · Wolfgang Denk

Dear Troy Kisky,

Quoted 2 lines · In message <[email protected]> you wrote:

But the reason I didn't include common.h is because of the target specific files that it also includes. Would you mind if I moved

Why would these hurt? They don't anywhere else.

I'm not saying that including common.h wouldn't work.
I'm saying that it seems wrong to include target specific include files in an executable that should generate the same code regardless of the target selected.

I really don't care enough to argue. I just want you to understand why I did it the way I did. It wasn't because I was crazy, or lazy. We just hold different priorities.

Would you like to see the Linux way of ALIGN, or ROUND?

Now, back to the other topic you raised. Should I apply the bug work-around for all version 2 headers, or find a way to distinguish mx53/mx6?

Thanks
Troy

#103 lore raw

PATCH v4 1/11 imximage: mx53 needs transfer length a multiple of 512

Dear Troy Kisky,

Quoted 2 lines · In message <[email protected]> you wrote:

Would you like to see the Linux way of ALIGN, or ROUND?

Do you align some buffer or similar, or do you round (up) a size?

Quoted 2 lines

Now, back to the other topic you raised. Should I apply the bug work-around for all version 2 headers, or find a way to distinguish mx53/mx6?

I cannot tell. Stefano, what do you think?

Best regards,

Wolfgang Denk

Signature · 4 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"Don't think; let the machine do it for you!"        - E. C. Berkeley
#104 lore raw

PATCH v4 1/11 imximage: mx53 needs transfer length a multiple of 512

Quoted 6 lines · Wolfgang Denk

Dear Troy Kisky,

Quoted 2 lines · In message <[email protected]> you wrote:

Would you like to see the Linux way of ALIGN, or ROUND?

Quoted 7 lines

Do you align some buffer or similar, or do you round (up) a size?

Quoted 2 lines

Now, back to the other topic you raised. Should I apply the bug work-around for all version 2 headers, or find a way to distinguish mx53/mx6?

I cannot tell. Stefano, what do you think?

Well, I am thinking about which are the real benefits. If we always round up the size to 512 bytes for V2 header, *maybe* we constrain the i.MX6 to load some bytes more, but it is the only drawback. And this if the i.MX6 does not suffer of the same problem found on i.MX53.

On the other side, having two different versions of V2 header is confusing. It is then undocumented by Freescale, and maybe it is possible to find a note in some errata. Having the same interface without special hacking for each SOC overcomes the increment in the footprint for the i.MX6 (in worst case 511 bytes - and not a lot compared to current size of U-Boot for MX5/MX6, usually several hundred of KB).

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
#105 lore raw

PATCH v4 1/11 imximage: mx53 needs transfer length a multiple of 512

In reply to Wolfgang Denk
Quoted 8 lines · Wolfgang Denk

Dear Troy Kisky,

Quoted 3 lines · In message <[email protected]> you wrote:

But the reason I didn't include common.h is because of the target specific files that it also includes. Would you mind if I moved

Why would these hurt? They don't anywhere else.

Personally, I think that mkimage as generic tool should not include common.h. Doing that, it does not allow to compile mkimage without running config, and let's think that we need a different mkimage for each target, and that is not true. This will break also support from distros, because their packages (for example, u-boot-tools, uboot-mkimage under Ubuntu) are compiled without configuring u-boot - and I think it is correct.

IMHO we are discussing about a single macro. We can let it in mkimage as in patch and move it in a general file only if we will have a use case with a bunch of macros.

Best regards,
Stefano Babic

Signature · 5 lines
=====================================================================
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================
author
#106 lore raw

PATCH v4 1/11 imximage: mx53 needs transfer length a multiple of 512

In reply to Wolfgang Denk
Quoted 8 lines · Wolfgang Denk

Dear Troy Kisky,

Quoted 2 lines · In message <[email protected]>…

The mx53 ROM will truncate the length at a multiple of 512. Transferring too much is not a problem, so round up.

What about other SoCs using the same code?

It would be easy to add a version 2 header test, but that would not distinguish between mx53 and mx6. Should I create a version 2bug header that I can specify in mx53's config file?

Thanks
Troy

#107 lore raw

PATCH v4 1/11 imximage: mx53 needs transfer length a multiple of 512

In reply to Troy Kisky
Quoted 9 lines

-----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 01/11] imximage: mx53 needs transfer length a multiple of 512

Quoted 6 lines

The mx53 ROM will truncate the length at a multiple of 512. Transferring too much is not a problem, so round up.

Problem reported by Stefano Babic.

Quoted 36 lines

---
tools/imximage.c | 10 +++++++++-

1 file changed, 9 insertions(+), 1 deletion(-)
tools/imximage.c index 63f88b6..7e54e97 renamed from tools/imximage.c +0 -0

100644

tools/imximage.c +9 -1
@@ -494,6 +494,8 @@ static void imximage_print_header(const void *ptr)
 	}
 }
 
+#define ALIGN(a, b)	(((a) + (b) - 1) & ~((b) - 1))
+
 static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 				struct mkimage_params *params)
 {
@@ -515,7 +517,13 @@ static void imximage_set_header(void *ptr, struct
 stat *sbuf, int ifd,
 
 	/* Set the imx header */
 	(*set_imx_hdr)(imxhdr, dcd_len, params->ep, imxhdr->flash_offset);
-	*header_size_ptr = sbuf->st_size + imxhdr->flash_offset;
+	/*
+	 * ROM bug alert
+	 * mx53 only loads 512 byte multiples.
+	 * The remaining fraction of a block bytes would
+	 * not be loaded.
+	 */
+	*header_size_ptr = ALIGN(sbuf->st_size + imxhdr->flash_offset, 512);
 }
 

int imximage_check_params(struct mkimage_params *params) --
1.7.9.5

author
#108 lore raw

PATCH v4 2/11 imximage: make header variable length

In reply to Troy Kisky

This makes the dcd table optional as well for v2. Also, the header offset is no longer right before the code starts.

Before this patch mx53loco_config produces

000000 402000d1 77800000 00000000 777ffc2c 000010 777ffc20 777ffc00 00000000 00000000 000020 777ff800 0004b200 00000000 40a001d2 000030 049c01cc 5485fa53 00003000 5885fa53 ... more DCD table
0001c0 27220200 1c90fd63 00000000 00000000 0001d0 00000000 00000000 00000000 00000000 *
0003f0 00000000 00000000 00000000 00000400 000400 ea000014 e59ff014 e59ff014 e59ff014

Notice offset 3fc contains 0x400. This
is the header offset. There is no reason for this to be in the file, and I have removed it.

After this patch we have

000000 402000d1 77800000 00000000 777ffe60 000010 777ffe54 777ffe34 00000000 00000000 000020 777ffa34 0004b000 00000000 40a001d2 000030 049c01cc 5485fa53 00003000 5885fa53 ... more DCD table
0001c0 27220200 1c90fd63 00000000 ea000014 0001d0 e59ff014 e59ff014 e59ff014 e59ff014

Notice the zeros between 0x1cc and 0x3fb have been removed.

---

v4: updated commit log, minor change to rebase on previous patch
v3: other patches split from this one

---
 tools/imximage.c |   65 ++++++++++++++++++++++++++++++++++++------------------
 tools/imximage.h |    4 ++--
 2 files changed, 46 insertions(+), 23 deletions(-)
tools/imximage.c +44 -21
index 7e54e97..8457c8e 100644
@@ -65,7 +65,6 @@ static table_entry_t imximage_versions[] = {
 	{-1,            "",     " (Invalid)",                 },
 };
 
-static struct imx_header imximage_header;
 static uint32_t imximage_version;
 
 static set_dcd_val_t set_dcd_val;
@@ -73,6 +72,9 @@ static set_dcd_rst_t set_dcd_rst;
 static set_imx_hdr_t set_imx_hdr;
 static uint32_t max_dcd_entries;
 static uint32_t *header_size_ptr;
+static uint32_t g_flash_offset;
+
+static struct image_type_params imximage_params;
 
 static uint32_t get_cfg_value(char *token, char *name,  int linenr)
 {
@@ -102,8 +104,7 @@ static uint32_t detect_imximage_version(struct imx_header *imx_hdr)
 		return IMXIMAGE_V1;
 
 	/* Try to detect V2 */
-	if ((fhdr_v2->header.tag == IVT_HEADER_TAG) &&
-		(hdr_v2->dcd_table.header.tag == DCD_HEADER_TAG))
+	if (fhdr_v2->header.tag == IVT_HEADER_TAG)
 		return IMXIMAGE_V2;
 
 	return IMXIMAGE_VER_INVALID;
@@ -195,7 +196,7 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;
 }
 
-static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
+static int set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 		uint32_t entry_point, uint32_t flash_offset)
 {
 	imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;
@@ -208,7 +209,7 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-	hdr_base = entry_point - sizeof(struct imx_header);
+	hdr_base = entry_point - header_length;
 	fhdr_v1->app_dest_ptr = hdr_base - flash_offset;
 	fhdr_v1->app_code_jump_vector = entry_point;
 
@@ -219,14 +220,18 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	fhdr_v1->app_code_csf = 0;
 	fhdr_v1->super_root_key = 0;
 	header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4);
+	return header_length;
 }
 
-static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 		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);
 
 	/* Set magic number */
 	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
@@ -235,9 +240,10 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 
 	fhdr_v2->entry = entry_point;
 	fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
-	fhdr_v2->self = hdr_base = entry_point - sizeof(struct imx_header);
+	fhdr_v2->self = hdr_base = entry_point - header_length;
 
-	fhdr_v2->dcd_ptr = hdr_base + offsetof(imx_header_v2_t, dcd_table);
+	fhdr_v2->dcd_ptr = (dcd_len) ? hdr_base
+			+ offsetof(imx_header_v2_t, dcd_table) : 0;
 	fhdr_v2->boot_data_ptr = hdr_base
 			+ offsetof(imx_header_v2_t, boot_data);
 	hdr_v2->boot_data.start = hdr_base - flash_offset;
@@ -245,6 +251,7 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	/* Security feature are not supported */
 	fhdr_v2->csf = 0;
 	header_size_ptr = &hdr_v2->boot_data.size;
+	return header_length;
 }
 
 static void set_hdr_func(struct imx_header *imxhdr)
@@ -342,9 +349,9 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
 		set_hdr_func(imxhdr);
 		break;
 	case CMD_BOOT_FROM:
-		imxhdr->flash_offset = get_table_entry_id(imximage_bootops,
+		g_flash_offset = get_table_entry_id(imximage_bootops,
 					"imximage boot option", token);
-		if (imxhdr->flash_offset == -1) {
+		if (g_flash_offset == -1) {
 			fprintf(stderr, "Error: %s[%d] -Invalid boot device"
 				"(%s)\n", name, lineno, token);
 			exit(EXIT_FAILURE);
@@ -449,7 +456,7 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
 	fclose(fd);
 
 	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if (imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
+	if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {
 		fprintf(stderr, "Error: No BOOT_FROM tag in %s\n", name);
 		exit(EXIT_FAILURE);
 	}
@@ -494,14 +501,17 @@ static void imximage_print_header(const void *ptr)
 	}
 }
 
-#define ALIGN(a, b)	(((a) + (b) - 1) & ~((b) - 1))
-
-static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
-				struct mkimage_params *params)
+int imximage_vrec_header(struct mkimage_params *params,
+		struct image_type_params *tparams)
 {
-	struct imx_header *imxhdr = (struct imx_header *)ptr;
+	struct imx_header *imxhdr;
 	uint32_t dcd_len;
 
+	imxhdr = calloc(1, MAX_HEADER_SIZE);
+	if (!imxhdr) {
+		fprintf(stderr, "Error: out of memory\n");
+		exit(EXIT_FAILURE);
+	}
 	/*
 	 * In order to not change the old imx cfg file
 	 * by adding VERSION command into it, here need
@@ -509,21 +519,35 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
 	 */
 	imximage_version = IMXIMAGE_V1;
 	/* Be able to detect if the cfg file has no BOOT_FROM tag */
-	imxhdr->flash_offset = FLASH_OFFSET_UNDEFINED;
+	g_flash_offset = FLASH_OFFSET_UNDEFINED;
 	set_hdr_func(imxhdr);
 
 	/* Parse dcd configuration file */
 	dcd_len = parse_cfg_file(imxhdr, params->imagename);
 
 	/* Set the imx header */
-	(*set_imx_hdr)(imxhdr, dcd_len, params->ep, imxhdr->flash_offset);
+	imximage_params.header_size = (*set_imx_hdr)(imxhdr, dcd_len,
+			params->ep, g_flash_offset);
+	imximage_params.hdr = imxhdr;
+	return 0;
+}
+
+#define ALIGN(a, b)	(((a) + (b) - 1) & ~((b) - 1))
+
+static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
+				struct mkimage_params *params)
+{
+	/* Set the size in header */
+	uint32_t offset = (char *)header_size_ptr - (char *)imximage_params.hdr;
+	uint32_t *p = (uint32_t *)((char *)ptr + offset);
+
 	/*
 	 * ROM bug alert
 	 * mx53 only loads 512 byte multiples.
 	 * The remaining fraction of a block bytes would
 	 * not be loaded.
 	 */
-	*header_size_ptr = ALIGN(sbuf->st_size + imxhdr->flash_offset, 512);
+	*p = ALIGN(sbuf->st_size + g_flash_offset, 512);
 }
 
 int imximage_check_params(struct mkimage_params *params)
@@ -553,8 +577,7 @@ int imximage_check_params(struct mkimage_params *params)
  */
 static struct image_type_params imximage_params = {
 	.name		= "Freescale i.MX 5x Boot Image support",
-	.header_size	= sizeof(struct imx_header),
-	.hdr		= (void *)&imximage_header,
+	.vrec_header	= imximage_vrec_header,
 	.check_image_type = imximage_check_image_types,
 	.verify_header	= imximage_verify_header,
 	.print_header	= imximage_print_header,
tools/imximage.h +2 -2
index 42b6090..0f39447 100644
@@ -30,6 +30,7 @@
 #define DCD_BARKER	0xB17219E9
 
 #define HEADER_OFFSET	0x400
+#define MAX_HEADER_SIZE	(16 << 10)
 
 #define CMD_DATA_STR	"DATA"
 #define FLASH_OFFSET_UNDEFINED	0xFFFFFFFF
@@ -156,7 +157,6 @@ struct imx_header {
 		imx_header_v1_t hdr_v1;
 		imx_header_v2_t hdr_v2;
 	} header;
-	uint32_t flash_offset;
 };
 
 typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
@@ -168,7 +168,7 @@ typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr,
 					uint32_t dcd_len,
 					char *name, int lineno);
 
-typedef void (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
+typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
 		uint32_t entry_point, uint32_t flash_offset);
 
 #endif /* _IMXIMAGE_H_ */
Signature · 1 line
1.7.9.5
#109 lore raw

PATCH v4 2/11 imximage: make header variable length

Quoted 29 lines

-----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 02/11] imximage: make header variable length

This makes the dcd table optional as well for v2.
Also, the header offset is no longer
right before the code starts.

Before this patch mx53loco_config produces

000000 402000d1 77800000 00000000 777ffc2c 000010 777ffc20 777ffc00 00000000 00000000 000020 777ff800 0004b200 00000000 40a001d2 000030 049c01cc 5485fa53 00003000 5885fa53 ... more DCD table 0001c0 27220200 1c90fd63 00000000 00000000 0001d0 00000000 00000000 00000000 00000000
*
0003f0 00000000 00000000 00000000 00000400 000400 ea000014 e59ff014 e59ff014 e59ff014

Notice offset 3fc contains 0x400. This
is the header offset. There is no reason for this to be in the file, and I have removed it.

After this patch we have

Quoted 8 lines

000000 402000d1 77800000 00000000 777ffe60 000010 777ffe54 777ffe34 00000000 00000000 000020 777ffa34 0004b000 00000000 40a001d2 000030 049c01cc 5485fa53 00003000 5885fa53 ... more DCD table 0001c0 27220200 1c90fd63 00000000 ea000014 0001d0 e59ff014 e59ff014 e59ff014 e59ff014

Notice the zeros between 0x1cc and 0x3fb have been removed.

Quoted 233 lines

---

v4: updated commit log, minor change to rebase on previous patch
v3: other patches split from this one
---
tools/imximage.c | 65 ++++++++++++++++++++++++++++++++++++--------------
----
tools/imximage.h | 4 ++--

2 files changed, 46 insertions(+), 23 deletions(-)
tools/imximage.c index 7e54e97..8457c8e renamed from tools/imximage.c +0 -0

100644

tools/imximage.c +0 -1
@@ -65,7 +65,6 @@ static table_entry_t imximage_versions[] = {
 	{-1,            "",     " (Invalid)",                 },
 };
 
-static struct imx_header imximage_header;  static uint32_t
 imximage_version;
 
 static set_dcd_val_t set_dcd_val;
@@ -73,6 +72,9 @@ static set_dcd_rst_t set_dcd_rst;  static set_imx_hdr_t

set_imx_hdr; static uint32_t max_dcd_entries; static uint32_t *header_size_ptr;

tools/imximage.c +3 -0
+static uint32_t g_flash_offset;
+
+static struct image_type_params imximage_params;

static uint32_t get_cfg_value(char *token, char *name, int linenr) { @@ - 102,8 +104,7 @@ static uint32_t detect_imximage_version(struct imx_header *imx_hdr)

		return IMXIMAGE_V1;

	/* Try to detect V2 */
tools/imximage.c +1 -2
-	if ((fhdr_v2->header.tag == IVT_HEADER_TAG) &&
-		(hdr_v2->dcd_table.header.tag == DCD_HEADER_TAG))
+	if (fhdr_v2->header.tag == IVT_HEADER_TAG)
		return IMXIMAGE_V2;

	return IMXIMAGE_VER_INVALID;
tools/imximage.c +2 -1
@@ -195,7 +196,7 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr,
 uint32_t dcd_len,
 	dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;  }
 
-static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
+static int set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 		uint32_t entry_point, uint32_t flash_offset)  {
 	imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1; @@ -208,7
+209,7 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t

dcd_len,

	/* Set magic number */
	fhdr_v1->app_code_barker = APP_CODE_BARKER;
tools/imximage.c +1 -1
-	hdr_base = entry_point - sizeof(struct imx_header);
+	hdr_base = entry_point - header_length;
	fhdr_v1->app_dest_ptr = hdr_base - flash_offset;
	fhdr_v1->app_code_jump_vector = entry_point;
tools/imximage.c +5 -1
@@ -219,14 +220,18 @@ static void set_imx_hdr_v1(struct imx_header
 *imxhdr, uint32_t dcd_len,
 	fhdr_v1->app_code_csf = 0;
 	fhdr_v1->super_root_key = 0;
 	header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4);
+	return header_length;
 }
 
-static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 		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);
 
 	/* Set magic number */
	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */ @@ -235,9

+240,10 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,

	fhdr_v2->entry = entry_point;
	fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
tools/imximage.c +3 -2
-	fhdr_v2->self = hdr_base = entry_point - sizeof(struct imx_header);
+	fhdr_v2->self = hdr_base = entry_point - header_length;
 
-	fhdr_v2->dcd_ptr = hdr_base + offsetof(imx_header_v2_t, dcd_table);
+	fhdr_v2->dcd_ptr = (dcd_len) ? hdr_base
+			+ offsetof(imx_header_v2_t, dcd_table) : 0;
	fhdr_v2->boot_data_ptr = hdr_base
			+ offsetof(imx_header_v2_t, boot_data);
	hdr_v2->boot_data.start = hdr_base - flash_offset; @@ -245,6 +251,7
@@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
	/* Security feature are not supported */
	fhdr_v2->csf = 0;
	header_size_ptr = &hdr_v2->boot_data.size;
tools/imximage.c +1 -0
+	return header_length;

}

static void set_hdr_func(struct imx_header *imxhdr) @@ -342,9 +349,9 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,

		set_hdr_func(imxhdr);
		break;
	case CMD_BOOT_FROM:
tools/imximage.c +1 -1
-		imxhdr->flash_offset = get_table_entry_id(imximage_bootops,
+		g_flash_offset = get_table_entry_id(imximage_bootops,
					"imximage boot option", token);
tools/imximage.c +1 -1
-		if (imxhdr->flash_offset == -1) {
+		if (g_flash_offset == -1) {
			fprintf(stderr, "Error: %s[%d] -Invalid boot device"
				"(%s)\n", name, lineno, token);
			exit(EXIT_FAILURE);
tools/imximage.c +1 -1
@@ -449,7 +456,7 @@ static uint32_t parse_cfg_file(struct imx_header
 *imxhdr, char *name)
 	fclose(fd);
 
 	/* Exit if there is no BOOT_FROM field specifying the flash_offset */
-	if (imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
+	if (g_flash_offset == FLASH_OFFSET_UNDEFINED) {
 		fprintf(stderr, "Error: No BOOT_FROM tag in %s\n", name);
 		exit(EXIT_FAILURE);
	}
tools/imximage.c +9 -5
@@ -494,14 +501,17 @@ static void imximage_print_header(const void *ptr)
 	}
 }
 
-#define ALIGN(a, b)	(((a) + (b) - 1) & ~((b) - 1))
-
-static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
-				struct mkimage_params *params)
+int imximage_vrec_header(struct mkimage_params *params,
+		struct image_type_params *tparams)
 {
-	struct imx_header *imxhdr = (struct imx_header *)ptr;
+	struct imx_header *imxhdr;
 	uint32_t dcd_len;
 
+	imxhdr = calloc(1, MAX_HEADER_SIZE);
+	if (!imxhdr) {
+		fprintf(stderr, "Error: out of memory\n");
+		exit(EXIT_FAILURE);
+	}
 	/*
 	 * In order to not change the old imx cfg file
 	 * by adding VERSION command into it, here need @@ -509,21
+519,35 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int

ifd,

	 */
	imximage_version = IMXIMAGE_V1;
	/* Be able to detect if the cfg file has no BOOT_FROM tag */
tools/imximage.c +1 -1
-	imxhdr->flash_offset = FLASH_OFFSET_UNDEFINED;
+	g_flash_offset = FLASH_OFFSET_UNDEFINED;
	set_hdr_func(imxhdr);

	/* Parse dcd configuration file */
	dcd_len = parse_cfg_file(imxhdr, params->imagename);

	/* Set the imx header */
tools/imximage.c +13 -1
-	(*set_imx_hdr)(imxhdr, dcd_len, params->ep, imxhdr->flash_offset);
+	imximage_params.header_size = (*set_imx_hdr)(imxhdr, dcd_len,
+			params->ep, g_flash_offset);
+	imximage_params.hdr = imxhdr;
+	return 0;
+}
+
+#define ALIGN(a, b)	(((a) + (b) - 1) & ~((b) - 1))
+
+static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
+				struct mkimage_params *params)
+{
+	/* Set the size in header */
+	uint32_t offset = (char *)header_size_ptr - (char

*)imximage_params.hdr;

tools/imximage.c +2 -0
+	uint32_t *p = (uint32_t *)((char *)ptr + offset);
+

/*
* ROM bug alert
* mx53 only loads 512 byte multiples.
* The remaining fraction of a block bytes would
* not be loaded.
*/

tools/imximage.c +1 -1
-	*header_size_ptr = ALIGN(sbuf->st_size + imxhdr->flash_offset, 512);
+	*p = ALIGN(sbuf->st_size + g_flash_offset, 512);

}

int imximage_check_params(struct mkimage_params *params) @@ -553,8 +577,7 @@ int imximage_check_params(struct mkimage_params *params)
*/
static struct image_type_params imximage_params = {
.name = "Freescale i.MX 5x Boot Image support",

tools/imximage.c +1 -2
-	.header_size	= sizeof(struct imx_header),
-	.hdr		= (void *)&imximage_header,
+	.vrec_header	= imximage_vrec_header,

.check_image_type = imximage_check_image_types,
.verify_header = imximage_verify_header,
.print_header = imximage_print_header,

tools/imximage.h index 42b6090..0f39447 renamed from tools/imximage.h +0 -0

100644

tools/imximage.h +1 -1
@@ -30,6 +30,7 @@
 #define DCD_BARKER	0xB17219E9
 
 #define HEADER_OFFSET	0x400
+#define MAX_HEADER_SIZE	(16 << 10)
 
 #define CMD_DATA_STR	"DATA"
 #define FLASH_OFFSET_UNDEFINED	0xFFFFFFFF
@@ -156,7 +157,6 @@ struct imx_header {
 		imx_header_v1_t hdr_v1;
 		imx_header_v2_t hdr_v2;
 	} header;
-	uint32_t flash_offset;
 };
 

typedef void (*set_dcd_val_t)(struct imx_header *imxhdr, @@ -168,7 +168,7 @@ typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr,

					uint32_t dcd_len,
					char *name, int lineno);
tools/imximage.h +2 -1
-typedef void (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
+typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t
+dcd_len,
		uint32_t entry_point, uint32_t flash_offset);

#endif /* _IMXIMAGE_H_ */
--
1.7.9.5

author
#110 lore raw

PATCH v4 3/11 imximage: remove static imximage_version

In reply to Troy Kisky

This variable does not need to have file scope.

---
 tools/imximage.c |   21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)
tools/imximage.c +9 -12
index 8457c8e..97e5c4b 100644
@@ -65,8 +65,6 @@ static table_entry_t imximage_versions[] = {
 	{-1,            "",     " (Invalid)",                 },
 };
 
-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;
@@ -254,7 +252,7 @@ static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	return header_length;
 }
 
-static void set_hdr_func(struct imx_header *imxhdr)
+static void set_hdr_func(struct imx_header *imxhdr, uint32_t imximage_version)
 {
 	switch (imximage_version) {
 	case IMXIMAGE_V1:
@@ -335,6 +333,7 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
 {
 	int value;
 	static int cmd_ver_first = ~0;
+	uint32_t imximage_version;
 
 	switch (cmd) {
 	case CMD_IMAGE_VERSION:
@@ -346,7 +345,7 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
 			exit(EXIT_FAILURE);
 		}
 		cmd_ver_first = 1;
-		set_hdr_func(imxhdr);
+		set_hdr_func(imxhdr, imximage_version);
 		break;
 	case CMD_BOOT_FROM:
 		g_flash_offset = get_table_entry_id(imximage_bootops,
@@ -419,6 +418,12 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
 	int dcd_len = 0;
 	int32_t cmd;
 
+	/*
+	 * In order to not change the old imx cfg file
+	 * by adding VERSION command into it, here need
+	 * set up function ptr group to V1 by default.
+	 */
+	set_hdr_func(imxhdr, IMXIMAGE_V1);
 	fd = fopen(name, "r");
 	if (fd == 0) {
 		fprintf(stderr, "Error: %s - Can't open DCD file\n", name);
@@ -512,16 +517,8 @@ int imximage_vrec_header(struct mkimage_params *params,
 		fprintf(stderr, "Error: out of memory\n");
 		exit(EXIT_FAILURE);
 	}
-	/*
-	 * In order to not change the old imx cfg file
-	 * by adding VERSION command into it, here need
-	 * set up function ptr group to V1 by default.
-	 */
-	imximage_version = IMXIMAGE_V1;
 	/* Be able to detect if the cfg file has no BOOT_FROM tag */
 	g_flash_offset = FLASH_OFFSET_UNDEFINED;
-	set_hdr_func(imxhdr);
-
 	/* Parse dcd configuration file */
 	dcd_len = parse_cfg_file(imxhdr, params->imagename);
 
Signature · 1 line
1.7.9.5
#111 lore raw

PATCH v4 3/11 imximage: remove static imximage_version

Quoted 11 lines

-----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 03/11] imximage: remove static imximage_version

This variable does not need to have file scope.

Quoted 81 lines

---
tools/imximage.c | 21 +++++++++------------

1 file changed, 9 insertions(+), 12 deletions(-)
tools/imximage.c index 8457c8e..97e5c4b renamed from tools/imximage.c +0 -0

100644

tools/imximage.c +2 -3
@@ -65,8 +65,6 @@ static table_entry_t imximage_versions[] = {
 	{-1,            "",     " (Invalid)",                 },
 };
 
-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;
@@ -254,7 +252,7 @@ static int set_imx_hdr_v2(struct imx_header *imxhdr,
 uint32_t dcd_len,
 	return header_length;
 }
 
-static void set_hdr_func(struct imx_header *imxhdr)
+static void set_hdr_func(struct imx_header *imxhdr, uint32_t
+imximage_version)
 {
	switch (imximage_version) {
	case IMXIMAGE_V1:
tools/imximage.c +2 -1
@@ -335,6 +333,7 @@ static void parse_cfg_cmd(struct imx_header *imxhdr,
 int32_t cmd, char *token,  {
 	int value;
 	static int cmd_ver_first = ~0;
+	uint32_t imximage_version;
 
 	switch (cmd) {
 	case CMD_IMAGE_VERSION:
@@ -346,7 +345,7 @@ static void parse_cfg_cmd(struct imx_header *imxhdr,
 int32_t cmd, char *token,
 			exit(EXIT_FAILURE);
 		}
 		cmd_ver_first = 1;
-		set_hdr_func(imxhdr);
+		set_hdr_func(imxhdr, imximage_version);
 		break;
 	case CMD_BOOT_FROM:

g_flash_offset = get_table_entry_id(imximage_bootops,

tools/imximage.c +6 -0
@@ -419,6 +418,12 @@ static uint32_t parse_cfg_file(struct imx_header
 *imxhdr, char *name)
 	int dcd_len = 0;
 	int32_t cmd;
 
+	/*
+	 * In order to not change the old imx cfg file
+	 * by adding VERSION command into it, here need
+	 * set up function ptr group to V1 by default.
+	 */
+	set_hdr_func(imxhdr, IMXIMAGE_V1);
 	fd = fopen(name, "r");
 	if (fd == 0) {

fprintf(stderr, "Error: %s - Can't open DCD file\n", name); @@ -
512,16 +517,8 @@ int imximage_vrec_header(struct mkimage_params *params,

		fprintf(stderr, "Error: out of memory\n");
		exit(EXIT_FAILURE);
	}
tools/imximage.c +0 -6
-	/*
-	 * In order to not change the old imx cfg file
-	 * by adding VERSION command into it, here need
-	 * set up function ptr group to V1 by default.
-	 */
-	imximage_version = IMXIMAGE_V1;
	/* Be able to detect if the cfg file has no BOOT_FROM tag */
	g_flash_offset = FLASH_OFFSET_UNDEFINED;
tools/imximage.c +0 -2
-	set_hdr_func(imxhdr);
-
	/* Parse dcd configuration file */
	dcd_len = parse_cfg_file(imxhdr, params->imagename);

--
1.7.9.5

author
#112 lore raw

PATCH v4 4/11 imximage: prepare to move static variables to struct data_src

In reply to Troy Kisky

Need to move accesses to the static variables to
a function where struct data_src is used.

---
v3: new patch

---
 tools/imximage.c |   24 +++++++++++++-----------
 tools/imximage.h |    3 +++
 2 files changed, 16 insertions(+), 11 deletions(-)
tools/imximage.c +13 -11
index 97e5c4b..3a010a6 100644
@@ -407,8 +407,11 @@ static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
 		break;
 	}
 }
-static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
+
+static int parse_cfg_file(struct imx_header *imxhdr, char *name,
+		uint32_t entry_point)
 {
+	struct data_src ds;
 	FILE *fd = NULL;
 	char *line = NULL;
 	char *token, *saveptr1, *saveptr2;
@@ -418,6 +421,10 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
 	int dcd_len = 0;
 	int32_t cmd;
 
+	/* Be able to detect if the cfg file has no BOOT_FROM tag */
+	g_flash_offset = FLASH_OFFSET_UNDEFINED;
+	memset(&ds, 0, sizeof(struct data_src));
+	ds.imxhdr = imxhdr;
 	/*
 	 * In order to not change the old imx cfg file
 	 * by adding VERSION command into it, here need
@@ -465,10 +472,10 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
 		fprintf(stderr, "Error: No BOOT_FROM tag in %s\n", name);
 		exit(EXIT_FAILURE);
 	}
-	return dcd_len;
+	/* Set the imx header */
+	return (*set_imx_hdr)(imxhdr, dcd_len, entry_point, g_flash_offset);
 }
 
-
 static int imximage_check_image_types(uint8_t type)
 {
 	if (type == IH_TYPE_IMXIMAGE)
@@ -510,21 +517,16 @@ 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);
 	if (!imxhdr) {
 		fprintf(stderr, "Error: out of memory\n");
 		exit(EXIT_FAILURE);
 	}
-	/* Be able to detect if the cfg file has no BOOT_FROM tag */
-	g_flash_offset = FLASH_OFFSET_UNDEFINED;
-	/* Parse dcd configuration file */
-	dcd_len = parse_cfg_file(imxhdr, params->imagename);
 
-	/* Set the imx header */
-	imximage_params.header_size = (*set_imx_hdr)(imxhdr, dcd_len,
-			params->ep, g_flash_offset);
+	/* Parse dcd configuration file */
+	imximage_params.header_size = parse_cfg_file(imxhdr, params->imagename,
+			params->ep);
 	imximage_params.hdr = imxhdr;
 	return 0;
 }
tools/imximage.h +3 -0
index 0f39447..2895378 100644
@@ -171,4 +171,7 @@ typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr,
 typedef int (*set_imx_hdr_t)(struct imx_header *imxhdr, uint32_t dcd_len,
 		uint32_t entry_point, uint32_t flash_offset);
 
+struct data_src {
+	struct imx_header *imxhdr;
+};
 #endif /* _IMXIMAGE_H_ */
Signature · 1 line
1.7.9.5
#113 lore raw

PATCH v4 4/11 imximage: prepare to move static variables to struct data_src

Dear Troy Kisky,

Quoted 2 lines · In message <[email protected]>…

Need to move accesses to the static variables to
a function where struct data_src is used.

Could you please elucidate why exactly this is _needed_?

tools/imximage.c static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name) · line 426

Quoted 3 lines
tools/imximage.c +3 -0
+	/* Be able to detect if the cfg file has no BOOT_FROM tag */
+	g_flash_offset = FLASH_OFFSET_UNDEFINED;
+	memset(&ds, 0, sizeof(struct data_src));

Is this initialization really needed?

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
A direct quote from the Boss: "We passed over a lot of good people to
get the ones we hired."
author
#114 lore raw

PATCH v4 4/11 imximage: prepare to move static variables to struct data_src

Quoted 6 lines · Wolfgang Denk

Dear Troy Kisky,

Quoted 2 lines · In message <[email protected]>…

Need to move accesses to the static variables to
a function where struct data_src is used.

Could you please elucidate why exactly this is _needed_?

My goal was to reduce the number of static variables, but strictly speaking it has little benefit other than giving me a warm fuzzy feeling.

I'm not that only one that dislikes static though.

Quoted 10 lines

tools/imximage.c static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name) · line 426

Quoted 4 lines
tools/imximage.c +3 -0
+	/* Be able to detect if the cfg file has no BOOT_FROM tag */
+	g_flash_offset = FLASH_OFFSET_UNDEFINED;
+	memset(&ds, 0, sizeof(struct data_src));

Is this initialization really needed?

Best regards,

Wolfgang Denk

ds is on the stack, and even if not needed now, I like to avoid future random bugs.

Troy

#115 lore raw

PATCH v4 4/11 imximage: prepare to move static variables to struct data_src

Dear Troy Kisky,

Quoted 7 lines · In message <[email protected]> you wrote:
Quoted 2 lines

Could you please elucidate why exactly this is _needed_?

My goal was to reduce the number of static variables, but strictly speaking it has little benefit other than giving me a warm fuzzy feeling.

I'm not that only one that dislikes static though.

...

Quoted 2 lines

ds is on the stack, and even if not needed now, I like to avoid future random bugs.

Did you check the impact of your changes on the memory footprint?

Changing code that uses a static variable initialized (implicitly or explicitly) to zero [which results in allocation of the BSS segment, i. e. zero space in the code or in the image file] into real code is something that is a bit of expensive just for satisfying random "dislikes".

I think you should better leave that as is. The code is pretty efficent that way, and you increase it for little or no benefit.

Best regards,

Wolfgang Denk

Signature · 5 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
The nice thing about  standards  is that there are  so many to choose
from.                                           - Andrew S. Tanenbaum
author
#116 lore raw

PATCH v4 5/11 imximage: change parameters for set_dcd_val/set_imx_hdr

In reply to Troy Kisky

Change 1st argument of set_imx_hdr/set_dcd_val
to struct data_src.

---
 tools/imximage.c |   41 +++++++++++++++++++++--------------------
 tools/imximage.h |    5 +++--
 2 files changed, 24 insertions(+), 22 deletions(-)
tools/imximage.c +21 -20
index 3a010a6..ddac95f 100644
@@ -116,10 +116,10 @@ static void err_imximage_version(int version)
 	exit(EXIT_FAILURE);
 }
 
-static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno,
+static void set_dcd_val_v1(struct data_src *ds, char *name, int lineno,
 					int fld, uint32_t value, uint32_t off)
 {
-	dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
+	dcd_v1_t *dcd_v1 = &ds->imxhdr->header.hdr_v1.dcd_table;
 
 	switch (fld) {
 	case CFG_REG_SIZE:
@@ -144,10 +144,10 @@ static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno,
 	}
 }
 
-static void set_dcd_val_v2(struct imx_header *imxhdr, 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)
 {
-	dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
+	dcd_v2_t *dcd_v2 = &ds->imxhdr->header.hdr_v2.dcd_table;
 
 	switch (fld) {
 	case CFG_REG_ADDRESS:
@@ -194,15 +194,15 @@ static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 	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 data_src *ds, uint32_t dcd_len,
 		uint32_t entry_point, uint32_t flash_offset)
 {
-	imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;
+	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 *)imxhdr));
+			- ((char *)ds->imxhdr));
 
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER;
@@ -217,19 +217,20 @@ static int set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
 	/* Security feature are not supported */
 	fhdr_v1->app_code_csf = 0;
 	fhdr_v1->super_root_key = 0;
-	header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4);
+	header_size_ptr = (uint32_t *)(((char *)ds->imxhdr) +
+			header_length - 4);
 	return header_length;
 }
 
-static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+static int set_imx_hdr_v2(struct data_src *ds, uint32_t dcd_len,
 		uint32_t entry_point, uint32_t flash_offset)
 {
-	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
+	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*)imxhdr)
-		: offsetof(imx_header_v2_t, dcd_table);
+		(char *)&hdr_v2->dcd_table.addr_data[dcd_len] -
+		((char *)ds->imxhdr) : offsetof(imx_header_v2_t, dcd_table);
 
 	/* Set magic number */
 	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
@@ -328,7 +329,7 @@ static void print_hdr_v2(struct imx_header *imx_hdr)
 	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v2->entry);
 }
 
-static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
+static void parse_cfg_cmd(struct data_src *ds, int32_t cmd, char *token,
 				char *name, int lineno, int fld, int dcd_len)
 {
 	int value;
@@ -345,7 +346,7 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
 			exit(EXIT_FAILURE);
 		}
 		cmd_ver_first = 1;
-		set_hdr_func(imxhdr, imximage_version);
+		set_hdr_func(ds->imxhdr, imximage_version);
 		break;
 	case CMD_BOOT_FROM:
 		g_flash_offset = get_table_entry_id(imximage_bootops,
@@ -360,14 +361,14 @@ 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)(ds, name, lineno, fld, value, dcd_len);
 		if (unlikely(cmd_ver_first != 1))
 			cmd_ver_first = 0;
 		break;
 	}
 }
 
-static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
+static void parse_cfg_fld(struct data_src *ds, int32_t *cmd,
 		char *token, char *name, int lineno, int fld, int *dcd_len)
 {
 	int value;
@@ -383,7 +384,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(ds, *cmd, token, name, lineno, fld, *dcd_len);
 		break;
 	case CFG_REG_ADDRESS:
 	case CFG_REG_VALUE:
@@ -391,7 +392,7 @@ 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);
+		(*set_dcd_val)(ds, name, lineno, fld, value, *dcd_len);
 
 		if (fld == CFG_REG_VALUE) {
 			(*dcd_len)++;
@@ -458,7 +459,7 @@ static int parse_cfg_file(struct imx_header *imxhdr, char *name,
 			if (token[0] == '#')
 				break;
 
-			parse_cfg_fld(imxhdr, &cmd, token, name,
+			parse_cfg_fld(&ds, &cmd, token, name,
 					lineno, fld, &dcd_len);
 		}
 
@@ -473,7 +474,7 @@ static int parse_cfg_file(struct imx_header *imxhdr, char *name,
 		exit(EXIT_FAILURE);
 	}
 	/* Set the imx header */
-	return (*set_imx_hdr)(imxhdr, dcd_len, entry_point, g_flash_offset);
+	return (*set_imx_hdr)(&ds, dcd_len, entry_point, g_flash_offset);
 }
 
 static int imximage_check_image_types(uint8_t type)
tools/imximage.h +3 -2
index 2895378..3054d55 100644
@@ -159,7 +159,8 @@ struct imx_header {
 	} header;
 };
 
-typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
+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);
@@ -168,7 +169,7 @@ 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,
+typedef int (*set_imx_hdr_t)(struct data_src *ds, uint32_t dcd_len,
 		uint32_t entry_point, uint32_t flash_offset);
 
 struct data_src {
Signature · 1 line
1.7.9.5
#117 lore raw

PATCH v4 5/11 imximage: change parameters for set_dcd_val/set_imx_hdr

Quoted 9 lines

-----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 05/11] imximage: change parameters for set_dcd_val/set_imx_hdr

Quoted 3 lines

Change 1st argument of set_imx_hdr/set_dcd_val to struct data_src.

Quoted 185 lines

---
tools/imximage.c | 41 +++++++++++++++++++++--------------------
tools/imximage.h | 5 +++--

2 files changed, 24 insertions(+), 22 deletions(-)
tools/imximage.c index 3a010a6..ddac95f renamed from tools/imximage.c +0 -0

100644

tools/imximage.c +4 -4
@@ -116,10 +116,10 @@ static void err_imximage_version(int version)
 	exit(EXIT_FAILURE);
 }
 
-static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int
 lineno,
+static void set_dcd_val_v1(struct data_src *ds, char *name, int lineno,
 					int fld, uint32_t value, uint32_t off)  {
-	dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
+	dcd_v1_t *dcd_v1 = &ds->imxhdr->header.hdr_v1.dcd_table;
 
 	switch (fld) {
 	case CFG_REG_SIZE:
@@ -144,10 +144,10 @@ static void set_dcd_val_v1(struct imx_header
 *imxhdr, char *name, int lineno,
 	}
 }
 
-static void set_dcd_val_v2(struct imx_header *imxhdr, 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)  {
-	dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table;
+	dcd_v2_t *dcd_v2 = &ds->imxhdr->header.hdr_v2.dcd_table;
 
 	switch (fld) {

case CFG_REG_ADDRESS:

tools/imximage.c +4 -3
@@ -194,15 +194,15 @@ static void set_dcd_rst_v2(struct imx_header
 *imxhdr, uint32_t dcd_len,
 	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 data_src *ds, uint32_t dcd_len,
 		uint32_t entry_point, uint32_t flash_offset)  {
-	imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;
+	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 *)imxhdr));
+			- ((char *)ds->imxhdr));
 
 	/* Set magic number */
 	fhdr_v1->app_code_barker = APP_CODE_BARKER; @@ -217,19
+217,20 @@ static int set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t

dcd_len,

	/* Security feature are not supported */
	fhdr_v1->app_code_csf = 0;
	fhdr_v1->super_root_key = 0;
tools/imximage.c +2 -1
-	header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4);
+	header_size_ptr = (uint32_t *)(((char *)ds->imxhdr) +
+			header_length - 4);
	return header_length;
}
tools/imximage.c +1 -1
-static int set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
+static int set_imx_hdr_v2(struct data_src *ds, uint32_t dcd_len,
		uint32_t entry_point, uint32_t flash_offset)  {
tools/imximage.c +1 -1
-	imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
+	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) ?
tools/imximage.c +0 -1
-		(char *)&hdr_v2->dcd_table.addr_data[dcd_len] -

((char*)imxhdr)

tools/imximage.c +2 -1
-		: offsetof(imx_header_v2_t, dcd_table);
+		(char *)&hdr_v2->dcd_table.addr_data[dcd_len] -
+		((char *)ds->imxhdr) : offsetof(imx_header_v2_t, dcd_table);
	/* Set magic number */
	fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */ @@ -328,7
+329,7 @@ static void print_hdr_v2(struct imx_header *imx_hdr)
	printf("Entry Point:  %08x\n", (uint32_t)fhdr_v2->entry);  }

-static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,

tools/imximage.c +2 -0
+static void parse_cfg_cmd(struct data_src *ds, int32_t cmd, char
+*token,
				char *name, int lineno, int fld, int dcd_len)  {
	int value;
tools/imximage.c +1 -1
@@ -345,7 +346,7 @@ static void parse_cfg_cmd(struct imx_header *imxhdr,
 int32_t cmd, char *token,
 			exit(EXIT_FAILURE);
 		}
 		cmd_ver_first = 1;
-		set_hdr_func(imxhdr, imximage_version);
+		set_hdr_func(ds->imxhdr, imximage_version);
 		break;
 	case CMD_BOOT_FROM:

g_flash_offset = get_table_entry_id(imximage_bootops,

tools/imximage.c +3 -3
@@ -360,14 +361,14 @@ 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)(ds, name, lineno, fld, value, dcd_len);
 		if (unlikely(cmd_ver_first != 1))
 			cmd_ver_first = 0;
 		break;
 	}
 }
 
-static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
+static void parse_cfg_fld(struct data_src *ds, int32_t *cmd,
 		char *token, char *name, int lineno, int fld, int *dcd_len)  {
 	int value;
@@ -383,7 +384,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(ds, *cmd, token, name, lineno, fld, *dcd_len);
 		break;

case CFG_REG_ADDRESS:
case CFG_REG_VALUE:

tools/imximage.c +1 -1
@@ -391,7 +392,7 @@ 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);
+		(*set_dcd_val)(ds, name, lineno, fld, value, *dcd_len);
 
 		if (fld == CFG_REG_VALUE) {
			(*dcd_len)++;
tools/imximage.c +2 -2
@@ -458,7 +459,7 @@ static int parse_cfg_file(struct imx_header *imxhdr,
 char *name,
 			if (token[0] == '#')
 				break;
 
-			parse_cfg_fld(imxhdr, &cmd, token, name,
+			parse_cfg_fld(&ds, &cmd, token, name,
 					lineno, fld, &dcd_len);
 		}
@@ -473,7 +474,7 @@ static int parse_cfg_file(struct imx_header *imxhdr,
 char *name,
 		exit(EXIT_FAILURE);
 	}
 	/* Set the imx header */
-	return (*set_imx_hdr)(imxhdr, dcd_len, entry_point, g_flash_offset);
+	return (*set_imx_hdr)(&ds, dcd_len, entry_point, g_flash_offset);
 }
 

static int imximage_check_image_types(uint8_t type) diff --git a/tools/imximage.h b/tools/imximage.h index 2895378..3054d55 100644

tools/imximage.h +3 -2
@@ -159,7 +159,8 @@ struct imx_header {
 	} header;
 };
 
-typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
+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);
@@ -168,7 +169,7 @@ 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,
+typedef int (*set_imx_hdr_t)(struct data_src *ds, uint32_t dcd_len,
 		uint32_t entry_point, uint32_t flash_offset);
 

struct data_src {
--
1.7.9.5