From patchwork Wed Nov 28 01:31:42 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Troy Kisky X-Patchwork-Id: 202344 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 321482C0082 for ; Wed, 28 Nov 2012 12:33:58 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id F34B64A0FA; Wed, 28 Nov 2012 02:33:18 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id xqaHYFfKv340; Wed, 28 Nov 2012 02:33:18 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 873164A105; Wed, 28 Nov 2012 02:32:14 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id DB3A54A0BF for ; Wed, 28 Nov 2012 02:32:06 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id JiVOHc8vhHUF for ; Wed, 28 Nov 2012 02:32:02 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pb0-f44.google.com (mail-pb0-f44.google.com [209.85.160.44]) by theia.denx.de (Postfix) with ESMTPS id 200CA4A0AA for ; Wed, 28 Nov 2012 02:31:53 +0100 (CET) Received: by mail-pb0-f44.google.com with SMTP id uo1so8838983pbc.3 for ; Tue, 27 Nov 2012 17:31:51 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=fozqmXkh3SCp6qZcmLzIdUEu/Q/6aTjcgf7QtaFcxVw=; b=IjqkgaT7Q0+nKvIo0CoVslP1/TZrWnQSJZfoPKlKsXEsqcrb+YBRGuN3oNWdOqb1zZ hxZgir3irqtvjBlqSFHcc2hLGeJ5r0wYiu82KicHFM9UDsL51ow0HvF6vYsALBagvbif a2nUNgq0ajk1ThouBK1WmEdRM7cgOiaRx0gDUWtXeHj0PK4TscyYTynoc13o7kDqGU8f hlZNh6m5Id3/WHRevdKu62cJijbj7HxGrQH0VGdbSGTQxnmbsIXvfjoOWhZoQ3kNZ1or FzhA7Q/sCXZhHtfxsUSGD903RXq/zqk9DF/NoRIpFCBnSgRajFdi/nvtw/e2ckcR3xdB s4Yg== Received: by 10.68.194.101 with SMTP id hv5mr53251598pbc.121.1354066311688; Tue, 27 Nov 2012 17:31:51 -0800 (PST) Received: from officeserver-2 ([70.96.116.236]) by mx.google.com with ESMTPS id ip8sm2103772pbc.36.2012.11.27.17.31.48 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 27 Nov 2012 17:31:51 -0800 (PST) Received: from tkisky by officeserver-2 with local (Exim 4.76) (envelope-from ) id 1TdWVC-0007l7-ID; Tue, 27 Nov 2012 18:31:50 -0700 From: Troy Kisky To: sbabic@denx.de Date: Tue, 27 Nov 2012 18:31:42 -0700 Message-Id: <1354066303-29762-11-git-send-email-troy.kisky@boundarydevices.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1354066303-29762-1-git-send-email-troy.kisky@boundarydevices.com> References: <1349315254-21151-9-git-send-email-troy.kisky@boundarydevices.com> <1354066303-29762-1-git-send-email-troy.kisky@boundarydevices.com> X-Gm-Message-State: ALoCoQmrNeGACpU+qPc1bta+edHbVB2RzkLmgEt/3hFHUyBiOE6ptNwi+sDN6tkkirsh3CNVnS2I Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH V4 10/11] imximage: use parse_helper functions X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Use parse_helper functions to pulling tokens instead of pushing them. Remove need for switch statements to process commands. Signed-off-by: Troy Kisky Acked-by: Jason Liu --- v2: uses file parse_helper added in previous patch changed patch subject, was cleanup parsing --- tools/imximage.c | 267 +++++++++++++++++++----------------------------------- tools/imximage.h | 17 ++-- 2 files changed, 101 insertions(+), 183 deletions(-) diff --git a/tools/imximage.c b/tools/imximage.c index 2f5ee14..5147989 100644 --- a/tools/imximage.c +++ b/tools/imximage.c @@ -25,9 +25,6 @@ * MA 02111-1307 USA */ -/* Required to obtain the getline prototype from stdio.h */ -#define _GNU_SOURCE - #include "mkimage.h" #include #include "imximage.h" @@ -70,21 +67,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; @@ -112,53 +94,36 @@ static void err_imximage_version(int version) exit(EXIT_FAILURE); } -static void set_dcd_val_v1(struct data_src *ds, char *name, int lineno, - int fld, uint32_t value) +static int set_dcd_val_v1(struct data_src *ds, uint32_t *data) { dcd_v1_t *dcd_v1 = &ds->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); - } - *ds->p_entry++ = value; - break; - case CFG_REG_ADDRESS: - *ds->p_entry++ = value; - break; - case CFG_REG_VALUE: - *ds->p_entry++ = value; - dcd_v1->preamble.length = (char *)ds->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; } + *ds->p_entry++ = val; + *ds->p_entry++ = *data++; + *ds->p_entry++ = *data++; + dcd_v1->preamble.length = (char *)ds->p_entry - (char *)&dcd_v1-> + addr_data[0].type; + return 0; } -static void set_dcd_val_v2(struct data_src *ds, char *name, int lineno, - int fld, uint32_t value) +static int set_dcd_val_v2(struct data_src *ds, uint32_t *data) { uint32_t len; dcd_v2_t *dcd_v2 = &ds->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 (ds->p_dcd && (ds->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 (!(ds->p_dcd && (ds->p_dcd->param == val))) { if (!ds->p_dcd) { dcd_v2->header.tag = DCD_HEADER_TAG; dcd_v2->header.version = DCD_VERSION; @@ -166,24 +131,19 @@ static void set_dcd_val_v2(struct data_src *ds, char *name, int lineno, } else { ds->p_dcd = (write_dcd_command_t *)ds->p_entry; } - ds->p_dcd->param = value; + ds->p_dcd->param = val; ds->p_dcd->tag = DCD_COMMAND_TAG; ds->p_entry = (uint32_t *)(ds->p_dcd + 1); - break; - case CFG_REG_ADDRESS: - *ds->p_entry++ = cpu_to_be32(value); - break; - case CFG_REG_VALUE: - *ds->p_entry++ = cpu_to_be32(value); - len = (char *)ds->p_entry - (char *)&dcd_v2->header; - dcd_v2->header.length = cpu_to_be16(len); - len = (char *)ds->p_entry - (char *)ds->p_dcd; - ds->p_dcd->length = cpu_to_be16(len); - break; - default: - break; - } + val = *data++; + *ds->p_entry++ = cpu_to_be32(val); + val = *data++; + *ds->p_entry++ = cpu_to_be32(val); + len = (char *)ds->p_entry - (char *)&dcd_v2->header; + dcd_v2->header.length = cpu_to_be16(len); + len = (char *)ds->p_entry - (char *)ds->p_dcd; + ds->p_dcd->length = cpu_to_be16(len); + return 0; } static int set_imx_hdr_v1(struct data_src *ds, @@ -323,95 +283,71 @@ 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 data_src *ds, int32_t cmd, char *token, - char *name, int lineno, int fld) +static int parse_cmd_data(struct data_src *ds) +{ + uint32_t data[3]; + int ret = ph_get_array(&ds->ph, data, 3); + + if (ret < 0) + return ret; + ret = (*ds->set_dcd_val)(ds, data); + if (ret) + return ret; + if (ds->p_entry > ds->p_max_dcd) { + uint32_t size = (char *)ds->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 value; - static int cmd_ver_first = ~0; + int ret; uint32_t imximage_version; - 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); - } - cmd_ver_first = 1; - set_hdr_func(ds, imximage_version); - 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); - } - if (unlikely(cmd_ver_first != 1)) - cmd_ver_first = 0; - break; - case CMD_DATA: - value = get_cfg_value(token, name, lineno); - (*ds->set_dcd_val)(ds, name, lineno, fld, value); - if (unlikely(cmd_ver_first != 1)) - cmd_ver_first = 0; - break; + ret = ph_get_value(&ds->ph, &imximage_version); + if (ret) + return ret; + if (ds->cmd_cnt) { + fprintf(stderr, "Error: IMAGE_VERSION command needs be " + "before other valid commands in the file\n"); + return -1; } + set_hdr_func(ds, imximage_version); + return 0; } -static void parse_cfg_fld(struct data_src *ds, int32_t *cmd, - char *token, char *name, int lineno, int fld) +static int parse_boot_from(struct data_src *ds) { - 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(ds, *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); - (*ds->set_dcd_val)(ds, name, lineno, fld, value); - if (ds->p_entry > ds->p_max_dcd) { - uint32_t size = (char *)ds->p_max_dcd - - (char *)ds->imxhdr; - fprintf(stderr, "Error: %s[%d] -" - "header exceeds maximum size(%d)\n", - name, lineno, size); - exit(EXIT_FAILURE); - } - break; - default: - break; + g_flash_offset = ph_get_table_entry_id(&ds->ph, imximage_bootops, + "imximage boot option"); + if (g_flash_offset == -1) { + fprintf(stderr, "Error: Invalid boot device\n"); + return -1; } + return 0; +} + +static const parse_fld_t cmd_table[] = { + parse_image_version, parse_boot_from, parse_cmd_data +}; + +static int parse_command(struct data_src *ds) +{ + int cmd = ph_get_table_entry_id(&ds->ph, imximage_cmds, + "imximage commands"); + if (cmd < 0) + return cmd; + return cmd_table[cmd](ds); } 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; - int lineno = 0; - int fld; - size_t len; - int32_t cmd; + struct parse_helper *ph = &ds.ph; /* Be able to detect if the cfg file has no BOOT_FROM tag */ g_flash_offset = FLASH_OFFSET_UNDEFINED; @@ -423,8 +359,7 @@ static int parse_cfg_file(struct imx_header *imxhdr, char *name, * set up function ptr group to V1 by default. */ set_hdr_func(&ds, IMXIMAGE_V1); - fd = fopen(name, "r"); - if (fd == 0) { + if (ph_open(ph, name)) { fprintf(stderr, "Error: %s - Can't open DCD file\n", name); exit(EXIT_FAILURE); } @@ -432,31 +367,19 @@ static int 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(&ds, &cmd, token, name, - lineno, fld); + for (;;) { + ph->cmd_started = 0; + if (ph_skip_separators(ph)) + break; + ph->cmd_started = 1; + if (parse_command(&ds)) { + fprintf(stderr, "Error: invalid token %s[%d](%s)\n", + name, ph->lineno, ph->p); + exit(EXIT_FAILURE); } - + ds.cmd_cnt++; } - fclose(fd); - + ph_close(ph); /* 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", name); @@ -546,12 +469,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: diff --git a/tools/imximage.h b/tools/imximage.h index 196bb51..6bcd082 100644 --- a/tools/imximage.h +++ b/tools/imximage.h @@ -23,6 +23,7 @@ #ifndef _IMXIMAGE_H_ #define _IMXIMAGE_H_ +#include "parse_helper.h" #define MAX_HW_CFG_SIZE_V2 121 /* Max number of registers imx can set for v2 */ #define MAX_HW_CFG_SIZE_V1 60 /* Max number of registers imx can set for v1 */ @@ -49,20 +50,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, @@ -159,14 +151,17 @@ struct imx_header { }; struct data_src; -typedef void (*set_dcd_val_t)(struct data_src *ds, char *name, - int lineno, int fld, uint32_t value); +typedef int (*parse_fld_t)(struct data_src *ds); + +typedef int (*set_dcd_val_t)(struct data_src *ds, uint32_t *data); typedef int (*set_imx_hdr_t)(struct data_src *ds, uint32_t entry_point, uint32_t flash_offset); struct data_src { + struct parse_helper ph; struct imx_header *imxhdr; + int cmd_cnt; set_imx_hdr_t set_imx_hdr; set_dcd_val_t set_dcd_val; uint32_t *p_max_dcd;