From patchwork Wed Nov 28 01:31:40 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Troy Kisky X-Patchwork-Id: 202342 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 6DFEC2C0087 for ; Wed, 28 Nov 2012 12:33:22 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2032F4A0F0; Wed, 28 Nov 2012 02:32:58 +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 wb-tDltOdWkc; Wed, 28 Nov 2012 02:32:57 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 8D4DB4A0F2; Wed, 28 Nov 2012 02:32:10 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 41E0E4A09E for ; Wed, 28 Nov 2012 02:32:03 +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 J3tZLonfX-b0 for ; Wed, 28 Nov 2012 02:32:01 +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 185BD4A0A9 for ; Wed, 28 Nov 2012 02:31:53 +0100 (CET) Received: by mail-pb0-f44.google.com with SMTP id uo1so8838984pbc.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=q14Gl3SxFhRCrKa2t2PVROqMDFPanwXgJyrwu7+n0jg=; b=LWUKGIesythDNQ6LyNVPYCIX97T5B1A8bMcK98WBC9oBDaX1XsVB/ZdmPBVxXA25lo Pu59aEc7NmDXhjEMxrKzt7T9I2PIlXdB2xLuzJUPhV0KWAXYouVIpM9/uPSNPS2HNYcT dygFK0avLhDk5EPwkzWXt9RsO/8P/9lOKQjBQk0UeN2Psu2PD+NZJptYasTAntZ9m5qf 2jZ9VSAgy3oqxSOMQ/rd2jXNtApIKHVFdEMFuzkLW6mIX/K+MpnzGDVArAmn5HSq8WYm gUngz0sEUEUKrJKI9eJdxBHRXm60G37gQ9A8mI8xOemw2mGuRa42krkTxNgZ27WI57sq hVAw== Received: by 10.68.211.39 with SMTP id mz7mr54022534pbc.5.1354066311733; Tue, 27 Nov 2012 17:31:51 -0800 (PST) Received: from officeserver-2 ([70.96.116.236]) by mx.google.com with ESMTPS id c1sm11558433pav.23.2012.11.27.17.31.48 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 27 Nov 2012 17:31:50 -0800 (PST) Received: from tkisky by officeserver-2 with local (Exim 4.76) (envelope-from ) id 1TdWVC-0007l2-A2; Tue, 27 Nov 2012 18:31:50 -0700 From: Troy Kisky To: sbabic@denx.de Date: Tue, 27 Nov 2012 18:31:40 -0700 Message-Id: <1354066303-29762-9-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: ALoCoQmAy06CBl5zGrJEx5iQTiaoV5POcyVgdgZzx/YCj8rwvxiCo3AgeCqj1xOI4BV4A47dgB18 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH V4 08/11] imximage: enable word writes for version2 header 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 Before, only 1 write_dcd_command table was built. Now, a new table is built when the size changes. Signed-off-by: Troy Kisky Acked-by: Jason Liu --- v3: moved static variables together --- tools/imximage.c | 143 ++++++++++++++++++++++++++---------------------------- tools/imximage.h | 18 +++---- 2 files changed, 76 insertions(+), 85 deletions(-) diff --git a/tools/imximage.c b/tools/imximage.c index 6d5cfa7..2f5ee14 100644 --- a/tools/imximage.c +++ b/tools/imximage.c @@ -65,8 +65,6 @@ static table_entry_t imximage_versions[] = { {-1, "", " (Invalid)", }, }; -static set_dcd_rst_t set_dcd_rst; -static uint32_t max_dcd_entries; static uint32_t *header_size_ptr; static uint32_t g_flash_offset; @@ -115,7 +113,7 @@ static void err_imximage_version(int version) } static void set_dcd_val_v1(struct data_src *ds, char *name, int lineno, - int fld, uint32_t value, uint32_t off) + int fld, uint32_t value) { dcd_v1_t *dcd_v1 = &ds->imxhdr->header.hdr_v1.dcd_table; @@ -128,13 +126,15 @@ static void set_dcd_val_v1(struct data_src *ds, char *name, int lineno, name, lineno, value); exit(EXIT_FAILURE); } - dcd_v1->addr_data[off].type = value; + *ds->p_entry++ = value; break; case CFG_REG_ADDRESS: - dcd_v1->addr_data[off].addr = value; + *ds->p_entry++ = value; break; case CFG_REG_VALUE: - dcd_v1->addr_data[off].value = value; + *ds->p_entry++ = value; + dcd_v1->preamble.length = (char *)ds->p_entry + - (char *)&dcd_v1->addr_data[0].type; break; default: break; @@ -143,16 +143,42 @@ static void set_dcd_val_v1(struct data_src *ds, char *name, int lineno, } static void set_dcd_val_v2(struct data_src *ds, char *name, int lineno, - int fld, uint32_t value, uint32_t off) + int fld, uint32_t value) { + uint32_t len; dcd_v2_t *dcd_v2 = &ds->imxhdr->header.hdr_v2.dcd_table; switch (fld) { + case CFG_REG_SIZE: + /* Byte, halfword, word */ + if ((value != 1) && (value != 2) && (value != 4)) { + fprintf(stderr, "Error: %s[%d] - " + "Invalid register size " "(%d)\n", + name, lineno, value); + exit(EXIT_FAILURE); + } + if (ds->p_dcd && (ds->p_dcd->param == value)) + break; + if (!ds->p_dcd) { + dcd_v2->header.tag = DCD_HEADER_TAG; + dcd_v2->header.version = DCD_VERSION; + ds->p_dcd = &dcd_v2->write_dcd_command; + } else { + ds->p_dcd = (write_dcd_command_t *)ds->p_entry; + } + ds->p_dcd->param = value; + ds->p_dcd->tag = DCD_COMMAND_TAG; + ds->p_entry = (uint32_t *)(ds->p_dcd + 1); + break; case CFG_REG_ADDRESS: - dcd_v2->addr_data[off].addr = cpu_to_be32(value); + *ds->p_entry++ = cpu_to_be32(value); break; case CFG_REG_VALUE: - dcd_v2->addr_data[off].value = cpu_to_be32(value); + *ds->p_entry++ = cpu_to_be32(value); + len = (char *)ds->p_entry - (char *)&dcd_v2->header; + dcd_v2->header.length = cpu_to_be16(len); + len = (char *)ds->p_entry - (char *)ds->p_dcd; + ds->p_dcd->length = cpu_to_be16(len); break; default: break; @@ -160,47 +186,14 @@ static void set_dcd_val_v2(struct data_src *ds, char *name, int lineno, } } -/* - * Complete setting up the rest field of DCD of V1 - * such as barker code and DCD data length. - */ -static void set_dcd_rst_v1(struct imx_header *imxhdr, uint32_t dcd_len, - char *name, int lineno) -{ - dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table; - - dcd_v1->preamble.barker = DCD_BARKER; - dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t); -} - -/* - * Complete setting up the reset field of DCD of V2 - * such as DCD tag, version, length, etc. - */ -static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, - char *name, int lineno) -{ - dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table; - - dcd_v2->header.tag = DCD_HEADER_TAG; - dcd_v2->header.length = cpu_to_be16( - dcd_len * sizeof(dcd_addr_data_t) + 8); - dcd_v2->header.version = DCD_VERSION; - dcd_v2->write_dcd_command.tag = DCD_COMMAND_TAG; - dcd_v2->write_dcd_command.length = cpu_to_be16( - dcd_len * sizeof(dcd_addr_data_t) + 4); - dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM; -} - -static int set_imx_hdr_v1(struct data_src *ds, uint32_t dcd_len, +static int set_imx_hdr_v1(struct data_src *ds, uint32_t entry_point, uint32_t flash_offset) { imx_header_v1_t *hdr_v1 = &ds->imxhdr->header.hdr_v1; flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr; - dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table; uint32_t hdr_base; - uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr) - - ((char *)ds->imxhdr)); + uint32_t header_length = ((char *)ds->p_entry) + 4 + - ((char *)ds->imxhdr); /* Set magic number */ fhdr_v1->app_code_barker = APP_CODE_BARKER; @@ -220,15 +213,13 @@ static int set_imx_hdr_v1(struct data_src *ds, uint32_t dcd_len, return header_length; } -static int set_imx_hdr_v2(struct data_src *ds, uint32_t dcd_len, +static int set_imx_hdr_v2(struct data_src *ds, uint32_t entry_point, uint32_t flash_offset) { imx_header_v2_t *hdr_v2 = &ds->imxhdr->header.hdr_v2; flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr; uint32_t hdr_base; - uint32_t header_length = (dcd_len) ? - (char *)&hdr_v2->dcd_table.addr_data[dcd_len] - - ((char *)ds->imxhdr) : offsetof(imx_header_v2_t, dcd_table); + uint32_t header_length = ((char *)ds->p_entry) - ((char *)ds->imxhdr); /* Set magic number */ fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */ @@ -239,7 +230,7 @@ static int set_imx_hdr_v2(struct data_src *ds, uint32_t dcd_len, fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0; fhdr_v2->self = hdr_base = entry_point - header_length; - fhdr_v2->dcd_ptr = (dcd_len) ? hdr_base + fhdr_v2->dcd_ptr = (ds->p_dcd) ? hdr_base + offsetof(imx_header_v2_t, dcd_table) : 0; fhdr_v2->boot_data_ptr = hdr_base + offsetof(imx_header_v2_t, boot_data); @@ -256,15 +247,20 @@ static void set_hdr_func(struct data_src *ds, uint32_t imximage_version) switch (imximage_version) { case IMXIMAGE_V1: ds->set_dcd_val = set_dcd_val_v1; - set_dcd_rst = set_dcd_rst_v1; ds->set_imx_hdr = set_imx_hdr_v1; - max_dcd_entries = MAX_HW_CFG_SIZE_V1; + ds->p_entry = &ds->imxhdr->header.hdr_v1.dcd_table + .addr_data[0].type; + ds->p_max_dcd = &ds->imxhdr->header.hdr_v1.dcd_table + .addr_data[MAX_HW_CFG_SIZE_V1].type; + ds->imxhdr->header.hdr_v1.dcd_table.preamble.barker = + DCD_BARKER; break; case IMXIMAGE_V2: ds->set_dcd_val = set_dcd_val_v2; - set_dcd_rst = set_dcd_rst_v2; ds->set_imx_hdr = set_imx_hdr_v2; - max_dcd_entries = MAX_HW_CFG_SIZE_V2; + ds->p_entry = (uint32_t *)&ds->imxhdr->header.hdr_v2.dcd_table; + ds->p_max_dcd = (uint32_t *) + ((char *)ds->imxhdr + MAX_HEADER_SIZE); break; default: err_imximage_version(imximage_version); @@ -328,7 +324,7 @@ static void print_hdr_v2(struct imx_header *imx_hdr) } static void parse_cfg_cmd(struct data_src *ds, int32_t cmd, char *token, - char *name, int lineno, int fld, int dcd_len) + char *name, int lineno, int fld) { int value; static int cmd_ver_first = ~0; @@ -359,7 +355,7 @@ static void parse_cfg_cmd(struct data_src *ds, int32_t cmd, char *token, break; case CMD_DATA: value = get_cfg_value(token, name, lineno); - (*ds->set_dcd_val)(ds, name, lineno, fld, value, dcd_len); + (*ds->set_dcd_val)(ds, name, lineno, fld, value); if (unlikely(cmd_ver_first != 1)) cmd_ver_first = 0; break; @@ -367,7 +363,7 @@ static void parse_cfg_cmd(struct data_src *ds, int32_t cmd, char *token, } static void parse_cfg_fld(struct data_src *ds, int32_t *cmd, - char *token, char *name, int lineno, int fld, int *dcd_len) + char *token, char *name, int lineno, int fld) { int value; @@ -382,7 +378,7 @@ static void parse_cfg_fld(struct data_src *ds, int32_t *cmd, } break; case CFG_REG_SIZE: - parse_cfg_cmd(ds, *cmd, token, name, lineno, fld, *dcd_len); + parse_cfg_cmd(ds, *cmd, token, name, lineno, fld); break; case CFG_REG_ADDRESS: case CFG_REG_VALUE: @@ -390,16 +386,14 @@ static void parse_cfg_fld(struct data_src *ds, int32_t *cmd, return; value = get_cfg_value(token, name, lineno); - (*ds->set_dcd_val)(ds, name, lineno, fld, value, *dcd_len); - - if (fld == CFG_REG_VALUE) { - (*dcd_len)++; - if (*dcd_len > max_dcd_entries) { - fprintf(stderr, "Error: %s[%d] -" - "DCD table exceeds maximum size(%d)\n", - name, lineno, max_dcd_entries); - exit(EXIT_FAILURE); - } + (*ds->set_dcd_val)(ds, name, lineno, fld, value); + if (ds->p_entry > ds->p_max_dcd) { + uint32_t size = (char *)ds->p_max_dcd - + (char *)ds->imxhdr; + fprintf(stderr, "Error: %s[%d] -" + "header exceeds maximum size(%d)\n", + name, lineno, size); + exit(EXIT_FAILURE); } break; default: @@ -417,7 +411,6 @@ static int parse_cfg_file(struct imx_header *imxhdr, char *name, int lineno = 0; int fld; size_t len; - int dcd_len = 0; int32_t cmd; /* Be able to detect if the cfg file has no BOOT_FROM tag */ @@ -458,12 +451,10 @@ static int parse_cfg_file(struct imx_header *imxhdr, char *name, break; parse_cfg_fld(&ds, &cmd, token, name, - lineno, fld, &dcd_len); + lineno, fld); } } - - (*set_dcd_rst)(imxhdr, dcd_len, name, lineno); fclose(fd); /* Exit if there is no BOOT_FROM field specifying the flash_offset */ @@ -472,7 +463,7 @@ static int parse_cfg_file(struct imx_header *imxhdr, char *name, exit(EXIT_FAILURE); } /* Set the imx header */ - return (*ds.set_imx_hdr)(&ds, dcd_len, entry_point, g_flash_offset); + return (*ds.set_imx_hdr)(&ds, entry_point, g_flash_offset); } static int imximage_check_image_types(uint8_t type) @@ -517,7 +508,11 @@ int imximage_vrec_header(struct mkimage_params *params, { struct imx_header *imxhdr; - imxhdr = calloc(1, MAX_HEADER_SIZE); + /* + * A little extra space to avoid access violation on dcd table overflow. + * Overflow is checked after entry is added. + */ + imxhdr = calloc(1, MAX_HEADER_SIZE + 32); if (!imxhdr) { fprintf(stderr, "Error: out of memory\n"); exit(EXIT_FAILURE); diff --git a/tools/imximage.h b/tools/imximage.h index 444ddce..196bb51 100644 --- a/tools/imximage.h +++ b/tools/imximage.h @@ -47,7 +47,6 @@ #define DCD_HEADER_TAG 0xD2 #define DCD_COMMAND_TAG 0xCC #define DCD_VERSION 0x40 -#define DCD_COMMAND_PARAM 0x4 enum imximage_cmd { CMD_INVALID, @@ -160,21 +159,18 @@ struct imx_header { }; struct data_src; -typedef void (*set_dcd_val_t)(struct data_src *ds, - char *name, int lineno, - int fld, uint32_t value, - uint32_t off); +typedef void (*set_dcd_val_t)(struct data_src *ds, char *name, + int lineno, int fld, uint32_t value); -typedef void (*set_dcd_rst_t)(struct imx_header *imxhdr, - uint32_t dcd_len, - char *name, int lineno); - -typedef int (*set_imx_hdr_t)(struct data_src *ds, uint32_t dcd_len, - uint32_t entry_point, uint32_t flash_offset); +typedef int (*set_imx_hdr_t)(struct data_src *ds, uint32_t entry_point, + uint32_t flash_offset); struct data_src { struct imx_header *imxhdr; set_imx_hdr_t set_imx_hdr; set_dcd_val_t set_dcd_val; + uint32_t *p_max_dcd; + uint32_t *p_entry; + write_dcd_command_t *p_dcd; }; #endif /* _IMXIMAGE_H_ */