[PATCH 14/23] scripts: imx: move config file parser to separate file

Sascha Hauer s.hauer at pengutronix.de
Fri Jan 29 02:43:54 PST 2016


To make the config parser usable by imx-usb-loader also move
it to a separate file.

Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
---
 scripts/imx/Makefile    |   4 +-
 scripts/imx/imx-image.c | 326 ----------------------------------------------
 scripts/imx/imx.c       | 336 ++++++++++++++++++++++++++++++++++++++++++++++++
 scripts/imx/imx.h       |  13 +-
 4 files changed, 350 insertions(+), 329 deletions(-)
 create mode 100644 scripts/imx/imx.c

diff --git a/scripts/imx/Makefile b/scripts/imx/Makefile
index ee0acc1..6883659 100644
--- a/scripts/imx/Makefile
+++ b/scripts/imx/Makefile
@@ -8,5 +8,5 @@ HOSTLOADLIBES_imx-usb-loader  = `pkg-config --libs libusb-1.0`
 
 HOSTCFLAGS_imx-image.o = -I$(srctree)
 
-imx-usb-loader-objs := imx-usb-loader.o
-imx-image-objs := imx-image.o
+imx-usb-loader-objs := imx-usb-loader.o imx.o
+imx-image-objs := imx-image.o imx.o
diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
index 03afcb6..d6ed120 100644
--- a/scripts/imx/imx-image.c
+++ b/scripts/imx/imx-image.c
@@ -37,15 +37,6 @@
 #define HEADER_LEN 0x1000	/* length of the blank area + IVT + DCD */
 #define CSF_LEN 0x2000		/* length of the CSF (needed for HAB) */
 
-struct config_data {
-	uint32_t image_load_addr;
-	uint32_t image_dcd_offset;
-	int header_version;
-	int cpu_type;
-	int (*check)(struct config_data *data, uint32_t cmd, uint32_t addr, uint32_t mask);
-	int (*write_mem)(struct config_data *data, uint32_t addr, uint32_t val, int width);
-};
-
 static uint32_t dcdtable[MAX_DCD];
 static int curdcd;
 static int add_barebox_header;
@@ -194,50 +185,6 @@ static void usage(const char *prgname)
 	exit(1);
 }
 
-#define MAXARGS 5
-
-static int parse_line(char *line, char *argv[])
-{
-	int nargs = 0;
-
-	while (nargs < MAXARGS) {
-
-		/* skip any white space */
-		while ((*line == ' ') || (*line == '\t'))
-			++line;
-
-		if (*line == '\0')	/* end of line, no more args	*/
-			argv[nargs] = NULL;
-
-		if (*line == '\0') {	/* end of line, no more args	*/
-			argv[nargs] = NULL;
-			return nargs;
-		}
-
-		argv[nargs++] = line;	/* begin of argument string	*/
-
-		/* find end of string */
-		while (*line && (*line != ' ') && (*line != '\t'))
-			++line;
-
-		if (*line == '\0') {	/* end of line, no more args	*/
-			argv[nargs] = NULL;
-			return nargs;
-		}
-
-		*line++ = '\0';		/* terminate current arg	 */
-	}
-
-	printf("** Too many args (max. %d) **\n", MAXARGS);
-
-	return nargs;
-}
-
-struct command {
-	const char *name;
-	int (*parse)(struct config_data *data, int argc, char *argv[]);
-};
-
 static uint32_t last_write_cmd;
 static int last_cmd_len;
 static uint32_t *last_dcd;
@@ -283,279 +230,6 @@ static int write_mem_v2(uint32_t addr, uint32_t val, int width)
 	return 0;
 }
 
-static const char *check_cmds[] = {
-	"while_all_bits_clear",		/* while ((*address & mask) == 0); */
-	"while_all_bits_set"	,	/* while ((*address & mask) == mask); */
-	"while_any_bit_clear",		/* while ((*address & mask) != mask); */
-	"while_any_bit_set",		/* while ((*address & mask) != 0); */
-};
-
-static void do_cmd_check_usage(void)
-{
-	fprintf(stderr,
-			"usage: check <width> <cmd> <addr> <mask>\n"
-			"<width> access width in bytes [1|2|4]\n"
-			"with <cmd> one of:\n"
-			"while_all_bits_clear: while ((*addr & mask) == 0)\n"
-			"while_all_bits_set:   while ((*addr & mask) == mask)\n"
-			"while_any_bit_clear:  while ((*addr & mask) != mask)\n"
-			"while_any_bit_set:    while ((*addr & mask) != 0)\n");
-}
-
-static int do_cmd_check(struct config_data *data, int argc, char *argv[])
-{
-	uint32_t addr, mask, cmd;
-	int i, width;
-	const char *scmd;
-
-	if (argc < 5) {
-		do_cmd_check_usage();
-		return -EINVAL;
-	}
-
-	if (!data->check)
-		return -ENOSYS;
-
-	width = strtoul(argv[1], NULL, 0) >> 3;
-	scmd = argv[2];
-	addr = strtoul(argv[3], NULL, 0);
-	mask = strtoul(argv[4], NULL, 0);
-
-	switch (width) {
-	case 1:
-	case 2:
-	case 4:
-		break;
-	default:
-		fprintf(stderr, "illegal width %d\n", width);
-		return -EINVAL;
-	};
-
-	if (curdcd > MAX_DCD - 3) {
-		fprintf(stderr, "At maximum %d dcd entried are allowed\n", MAX_DCD);
-		return -ENOMEM;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(check_cmds); i++) {
-		if (!strcmp(scmd, check_cmds[i]))
-			break;
-	}
-
-	if (i == ARRAY_SIZE(check_cmds)) {
-		do_cmd_check_usage();
-		return -EINVAL;
-	}
-
-	cmd = (TAG_CHECK << 24) | (i << 3) | width | ((sizeof(uint32_t) * 3) << 8);
-
-	return data->check(data, cmd, addr, mask);
-}
-
-static int do_cmd_write_mem(struct config_data *data, int argc, char *argv[])
-{
-	uint32_t addr, val, width;
-	char *end;
-
-	if (argc != 4) {
-		fprintf(stderr, "usage: wm [8|16|32] <addr> <val>\n");
-		return -EINVAL;
-	}
-
-	width = strtoul(argv[1], &end, 0);
-	if (*end != '\0') {
-		fprintf(stderr, "illegal width token \"%s\"\n", argv[1]);
-		return -EINVAL;
-	}
-
-	addr = strtoul(argv[2], &end, 0);
-	if (*end != '\0') {
-		fprintf(stderr, "illegal address token \"%s\"\n", argv[2]);
-		return -EINVAL;
-	}
-
-	val = strtoul(argv[3], &end, 0);
-	if (*end != '\0') {
-		fprintf(stderr, "illegal value token \"%s\"\n", argv[3]);
-		return -EINVAL;
-	}
-
-	width >>= 3;
-
-	switch (width) {
-	case 1:
-	case 2:
-	case 4:
-		break;
-	default:
-		fprintf(stderr, "illegal width %d\n", width);
-		return -EINVAL;
-	};
-
-	return data->write_mem(data, addr, val, width);
-}
-
-static int do_loadaddr(struct config_data *data, int argc, char *argv[])
-{
-	if (argc < 2)
-		return -EINVAL;
-
-	data->image_load_addr = strtoul(argv[1], NULL, 0);
-
-	return 0;
-}
-
-static int do_dcd_offset(struct config_data *data, int argc, char *argv[])
-{
-	if (argc < 2)
-		return -EINVAL;
-
-	data->image_dcd_offset = strtoul(argv[1], NULL, 0);
-
-	return 0;
-}
-
-struct soc_type {
-	char *name;
-	int header_version;
-	int cpu_type;
-};
-
-static struct soc_type socs[] = {
-	{ .name = "imx25", .header_version = 1, .cpu_type = 25},
-	{ .name = "imx35", .header_version = 1, .cpu_type = 35 },
-	{ .name = "imx51", .header_version = 1, .cpu_type = 51 },
-	{ .name = "imx53", .header_version = 2, .cpu_type = 53 },
-	{ .name = "imx6", .header_version = 2, .cpu_type = 6 },
-};
-
-static int do_soc(struct config_data *data, int argc, char *argv[])
-{
-	char *soc;
-	int i;
-
-	if (argc < 2)
-		return -EINVAL;
-
-	soc = argv[1];
-
-	for (i = 0; i < ARRAY_SIZE(socs); i++) {
-		if (!strcmp(socs[i].name, soc)) {
-			data->header_version = socs[i].header_version;
-			data->cpu_type = socs[i].cpu_type;
-			return 0;
-		}
-	}
-
-	fprintf(stderr, "unkown SoC type \"%s\". Known SoCs are:\n", soc);
-	for (i = 0; i < ARRAY_SIZE(socs); i++)
-		fprintf(stderr, "%s ", socs[i].name);
-	fprintf(stderr, "\n");
-
-	return -EINVAL;
-}
-
-struct command cmds[] = {
-	{
-		.name = "wm",
-		.parse = do_cmd_write_mem,
-	}, {
-		.name = "check",
-		.parse = do_cmd_check,
-	}, {
-		.name = "loadaddr",
-		.parse = do_loadaddr,
-	}, {
-		.name = "dcdofs",
-		.parse = do_dcd_offset,
-	}, {
-		.name = "soc",
-		.parse = do_soc,
-	},
-};
-
-static char *readcmd(struct config_data *data, FILE *f)
-{
-	static char *buf;
-	char *str;
-	ssize_t ret;
-
-	if (!buf) {
-		buf = malloc(4096);
-		if (!buf)
-			return NULL;
-	}
-
-	str = buf;
-	*str = 0;
-
-	while (1) {
-		ret = fread(str, 1, 1, f);
-		if (!ret)
-			return strlen(buf) ? buf : NULL;
-
-		if (*str == '\n' || *str == ';') {
-			*str = 0;
-			return buf;
-		}
-
-		str++;
-	}
-}
-
-static int parse_config(struct config_data *data, const char *filename)
-{
-	FILE *f;
-	int lineno = 0;
-	char *line = NULL, *tmp;
-	char *argv[MAXARGS];
-	int nargs, i, ret = 0;
-
-	f = fopen(filename, "r");
-	if (!f) {
-		fprintf(stderr, "Error: %s - Can't open DCD file\n", filename);
-		exit(1);
-	}
-
-	while (1) {
-		line = readcmd(data, f);
-		if (!line)
-			break;
-
-		lineno++;
-
-		tmp = strchr(line, '#');
-		if (tmp)
-			*tmp = 0;
-
-		nargs = parse_line(line, argv);
-		if (!nargs)
-			continue;
-
-		ret = -ENOENT;
-
-		for (i = 0; i < ARRAY_SIZE(cmds); i++) {
-			if (!strcmp(cmds[i].name, argv[0])) {
-				ret = cmds[i].parse(data, nargs, argv);
-				if (ret) {
-					fprintf(stderr, "error in line %d: %s\n",
-							lineno, strerror(-ret));
-					goto cleanup;
-				}
-				break;
-			}
-		}
-
-		if (ret == -ENOENT) {
-			fprintf(stderr, "no such command: %s\n", argv[0]);
-			goto cleanup;
-		}
-	}
-
-cleanup:
-	fclose(f);
-	return ret;
-}
-
 static int xread(int fd, void *buf, int len)
 {
 	int ret;
diff --git a/scripts/imx/imx.c b/scripts/imx/imx.c
new file mode 100644
index 0000000..fa705ff
--- /dev/null
+++ b/scripts/imx/imx.c
@@ -0,0 +1,336 @@
+/*
+ * (C) Copyright 2016 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <errno.h>
+#include "imx.h"
+
+#define MAXARGS 5
+
+static int parse_line(char *line, char *argv[])
+{
+	int nargs = 0;
+
+	while (nargs < MAXARGS) {
+
+		/* skip any white space */
+		while ((*line == ' ') || (*line == '\t'))
+			++line;
+
+		if (*line == '\0')	/* end of line, no more args	*/
+			argv[nargs] = NULL;
+
+		if (*line == '\0') {	/* end of line, no more args	*/
+			argv[nargs] = NULL;
+			return nargs;
+		}
+
+		argv[nargs++] = line;	/* begin of argument string	*/
+
+		/* find end of string */
+		while (*line && (*line != ' ') && (*line != '\t'))
+			++line;
+
+		if (*line == '\0') {	/* end of line, no more args	*/
+			argv[nargs] = NULL;
+			return nargs;
+		}
+
+		*line++ = '\0';		/* terminate current arg	 */
+	}
+
+	printf("** Too many args (max. %d) **\n", MAXARGS);
+
+	return nargs;
+}
+
+struct command {
+	const char *name;
+	int (*parse)(struct config_data *data, int argc, char *argv[]);
+};
+
+static const char *check_cmds[] = {
+	"while_all_bits_clear",		/* while ((*address & mask) == 0); */
+	"while_all_bits_set"	,	/* while ((*address & mask) == mask); */
+	"while_any_bit_clear",		/* while ((*address & mask) != mask); */
+	"while_any_bit_set",		/* while ((*address & mask) != 0); */
+};
+
+static void do_cmd_check_usage(void)
+{
+	fprintf(stderr,
+			"usage: check <width> <cmd> <addr> <mask>\n"
+			"<width> access width in bytes [1|2|4]\n"
+			"with <cmd> one of:\n"
+			"while_all_bits_clear: while ((*addr & mask) == 0)\n"
+			"while_all_bits_set:   while ((*addr & mask) == mask)\n"
+			"while_any_bit_clear:  while ((*addr & mask) != mask)\n"
+			"while_any_bit_set:    while ((*addr & mask) != 0)\n");
+}
+
+static int do_cmd_check(struct config_data *data, int argc, char *argv[])
+{
+	uint32_t addr, mask, cmd;
+	int i, width;
+	const char *scmd;
+
+	if (argc < 5) {
+		do_cmd_check_usage();
+		return -EINVAL;
+	}
+
+	if (!data->check)
+		return -ENOSYS;
+
+	width = strtoul(argv[1], NULL, 0) >> 3;
+	scmd = argv[2];
+	addr = strtoul(argv[3], NULL, 0);
+	mask = strtoul(argv[4], NULL, 0);
+
+	switch (width) {
+	case 1:
+	case 2:
+	case 4:
+		break;
+	default:
+		fprintf(stderr, "illegal width %d\n", width);
+		return -EINVAL;
+	};
+
+	for (i = 0; i < ARRAY_SIZE(check_cmds); i++) {
+		if (!strcmp(scmd, check_cmds[i]))
+			break;
+	}
+
+	if (i == ARRAY_SIZE(check_cmds)) {
+		do_cmd_check_usage();
+		return -EINVAL;
+	}
+
+	cmd = (TAG_CHECK << 24) | (i << 3) | width | ((sizeof(uint32_t) * 3) << 8);
+
+	return data->check(data, cmd, addr, mask);
+}
+
+static int do_cmd_write_mem(struct config_data *data, int argc, char *argv[])
+{
+	uint32_t addr, val, width;
+	char *end;
+
+	if (argc != 4) {
+		fprintf(stderr, "usage: wm [8|16|32] <addr> <val>\n");
+		return -EINVAL;
+	}
+
+	width = strtoul(argv[1], &end, 0);
+	if (*end != '\0') {
+		fprintf(stderr, "illegal width token \"%s\"\n", argv[1]);
+		return -EINVAL;
+	}
+
+	addr = strtoul(argv[2], &end, 0);
+	if (*end != '\0') {
+		fprintf(stderr, "illegal address token \"%s\"\n", argv[2]);
+		return -EINVAL;
+	}
+
+	val = strtoul(argv[3], &end, 0);
+	if (*end != '\0') {
+		fprintf(stderr, "illegal value token \"%s\"\n", argv[3]);
+		return -EINVAL;
+	}
+
+	width >>= 3;
+
+	switch (width) {
+	case 1:
+	case 2:
+	case 4:
+		break;
+	default:
+		fprintf(stderr, "illegal width %d\n", width);
+		return -EINVAL;
+	};
+
+	return data->write_mem(data, addr, val, width);
+}
+
+static int do_loadaddr(struct config_data *data, int argc, char *argv[])
+{
+	if (argc < 2)
+		return -EINVAL;
+
+	data->image_load_addr = strtoul(argv[1], NULL, 0);
+
+	return 0;
+}
+
+static int do_dcd_offset(struct config_data *data, int argc, char *argv[])
+{
+	if (argc < 2)
+		return -EINVAL;
+
+	data->image_dcd_offset = strtoul(argv[1], NULL, 0);
+
+	return 0;
+}
+
+struct soc_type {
+	char *name;
+	int header_version;
+	int cpu_type;
+};
+
+static struct soc_type socs[] = {
+	{ .name = "imx25", .header_version = 1, .cpu_type = 25},
+	{ .name = "imx35", .header_version = 1, .cpu_type = 35 },
+	{ .name = "imx51", .header_version = 1, .cpu_type = 51 },
+	{ .name = "imx53", .header_version = 2, .cpu_type = 53 },
+	{ .name = "imx6", .header_version = 2, .cpu_type = 6 },
+};
+
+static int do_soc(struct config_data *data, int argc, char *argv[])
+{
+	char *soc;
+	int i;
+
+	if (argc < 2)
+		return -EINVAL;
+
+	soc = argv[1];
+
+	for (i = 0; i < ARRAY_SIZE(socs); i++) {
+		if (!strcmp(socs[i].name, soc)) {
+			data->header_version = socs[i].header_version;
+			data->cpu_type = socs[i].cpu_type;
+			return 0;
+		}
+	}
+
+	fprintf(stderr, "unkown SoC type \"%s\". Known SoCs are:\n", soc);
+	for (i = 0; i < ARRAY_SIZE(socs); i++)
+		fprintf(stderr, "%s ", socs[i].name);
+	fprintf(stderr, "\n");
+
+	return -EINVAL;
+}
+
+struct command cmds[] = {
+	{
+		.name = "wm",
+		.parse = do_cmd_write_mem,
+	}, {
+		.name = "check",
+		.parse = do_cmd_check,
+	}, {
+		.name = "loadaddr",
+		.parse = do_loadaddr,
+	}, {
+		.name = "dcdofs",
+		.parse = do_dcd_offset,
+	}, {
+		.name = "soc",
+		.parse = do_soc,
+	},
+};
+
+static char *readcmd(struct config_data *data, FILE *f)
+{
+	static char *buf;
+	char *str;
+	ssize_t ret;
+
+	if (!buf) {
+		buf = malloc(4096);
+		if (!buf)
+			return NULL;
+	}
+
+	str = buf;
+	*str = 0;
+
+	while (1) {
+		ret = fread(str, 1, 1, f);
+		if (!ret)
+			return strlen(buf) ? buf : NULL;
+
+		if (*str == '\n' || *str == ';') {
+			*str = 0;
+			return buf;
+		}
+
+		str++;
+	}
+}
+
+int parse_config(struct config_data *data, const char *filename)
+{
+	FILE *f;
+	int lineno = 0;
+	char *line = NULL, *tmp;
+	char *argv[MAXARGS];
+	int nargs, i, ret = 0;
+
+	f = fopen(filename, "r");
+	if (!f) {
+		fprintf(stderr, "Error: %s - Can't open DCD file\n", filename);
+		exit(1);
+	}
+
+	while (1) {
+		line = readcmd(data, f);
+		if (!line)
+			break;
+
+		lineno++;
+
+		tmp = strchr(line, '#');
+		if (tmp)
+			*tmp = 0;
+
+		nargs = parse_line(line, argv);
+		if (!nargs)
+			continue;
+
+		ret = -ENOENT;
+
+		for (i = 0; i < ARRAY_SIZE(cmds); i++) {
+			if (!strcmp(cmds[i].name, argv[0])) {
+				ret = cmds[i].parse(data, nargs, argv);
+				if (ret) {
+					fprintf(stderr, "error in line %d: %s\n",
+							lineno, strerror(-ret));
+					goto cleanup;
+				}
+				break;
+			}
+		}
+
+		if (ret == -ENOENT) {
+			fprintf(stderr, "no such command: %s\n", argv[0]);
+			goto cleanup;
+		}
+	}
+
+cleanup:
+	fclose(f);
+	return ret;
+}
diff --git a/scripts/imx/imx.h b/scripts/imx/imx.h
index 1d23e11..41a54fb 100644
--- a/scripts/imx/imx.h
+++ b/scripts/imx/imx.h
@@ -54,4 +54,15 @@ struct imx_flash_header_v2 {
 
 	struct imx_boot_data boot_data;
 	struct imx_ivt_header dcd_header;
-} __attribute__((packed));
\ No newline at end of file
+} __attribute__((packed));
+
+struct config_data {
+	uint32_t image_load_addr;
+	uint32_t image_dcd_offset;
+	int header_version;
+	int cpu_type;
+	int (*check)(struct config_data *data, uint32_t cmd, uint32_t addr, uint32_t mask);
+	int (*write_mem)(struct config_data *data, uint32_t addr, uint32_t val, int width);
+};
+
+int parse_config(struct config_data *data, const char *filename);
-- 
2.7.0.rc3




More information about the barebox mailing list