From patchwork Wed Dec 29 12:49:27 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liu Hui-R64343 X-Patchwork-Id: 76895 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 C828EB6F1E for ; Wed, 29 Dec 2010 23:54:20 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 29CC5281CA; Wed, 29 Dec 2010 13:54:19 +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 hk3gRXqDXbsB; Wed, 29 Dec 2010 13:54:18 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C595D281CF; Wed, 29 Dec 2010 13:54:17 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 5607F281CF for ; Wed, 29 Dec 2010 13:54:14 +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 QIL7rD9lsnTb for ; Wed, 29 Dec 2010 13:54:14 +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 AM1EHSOBE006.bigfish.com (am1ehsobe006.messaging.microsoft.com [213.199.154.209]) by theia.denx.de (Postfix) with ESMTPS id 06884281CA for ; Wed, 29 Dec 2010 13:54:12 +0100 (CET) Received: from mail70-am1-R.bigfish.com (10.3.201.243) by AM1EHSOBE006.bigfish.com (10.3.204.26) with Microsoft SMTP Server id 14.1.225.8; Wed, 29 Dec 2010 12:54:11 +0000 Received: from mail70-am1 (localhost.localdomain [127.0.0.1]) by mail70-am1-R.bigfish.com (Postfix) with ESMTP id BEB071458299; Wed, 29 Dec 2010 12:54:11 +0000 (UTC) X-SpamScore: -4 X-BigFish: VS-4(zz98aLzz1202hzz8275bhz2dh2a8h668h62h) X-Spam-TCS-SCL: 1:0 X-Forefront-Antispam-Report: KIP:(null); UIP:(null); IPVD:NLI; H:de01egw02.freescale.net; RD:de01egw02.freescale.net; EFVD:NLI Received: from mail70-am1 (localhost.localdomain [127.0.0.1]) by mail70-am1 (MessageSwitch) id 1293627250424138_16044; Wed, 29 Dec 2010 12:54:10 +0000 (UTC) Received: from AM1EHSMHS012.bigfish.com (unknown [10.3.201.241]) by mail70-am1.bigfish.com (Postfix) with ESMTP id 5ADB1112004C; Wed, 29 Dec 2010 12:54:10 +0000 (UTC) Received: from de01egw02.freescale.net (192.88.165.103) by AM1EHSMHS012.bigfish.com (10.3.207.112) with Microsoft SMTP Server (TLS) id 14.1.225.8; Wed, 29 Dec 2010 12:54:09 +0000 Received: from az33smr02.freescale.net (az33smr02.freescale.net [10.64.34.200]) by de01egw02.freescale.net (8.14.3/8.14.3) with ESMTP id oBTCs8hs020325; Wed, 29 Dec 2010 05:54:08 -0700 (MST) Received: from localhost.localdomain (r64343-desktop.ap.freescale.net [10.192.242.36]) by az33smr02.freescale.net (8.13.1/8.13.0) with ESMTP id oBTCs4pB005491; Wed, 29 Dec 2010 06:54:05 -0600 (CST) From: Jason Liu To: Date: Wed, 29 Dec 2010 20:49:27 +0800 Message-ID: <1293626967-18740-1-git-send-email-r64343@freescale.com> X-Mailer: git-send-email 1.7.0.4 MIME-Version: 1.0 X-OriginatorOrg: freescale.com Subject: [U-Boot] [PATCH v3 7/8] imximage: Add MX53 boot image support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This patch add the MX53 boot image support. This patch has been tested on Freescale MX53EVK board and MX51EVK board. Signed-off-by: Jason Liu --- Changes for v2: - Address the following comments from Stefano, - Get rid of #ifdef in the imximage.h and .c file and use the runtime check for imximage version - Document the IMXIMAGE_VERSION definiton in doc/README.imximage - Move mx53evk/config.mk and mx53evk/imximage.cfg to MX53EVK board support patch. --- board/freescale/mx51evk/imximage.cfg | 4 + board/ttcontrol/vision2/imximage_hynix.cfg | 4 + doc/README.imximage | 10 +- tools/imximage.c | 357 ++++++++++++++++++++++------ tools/imximage.h | 98 ++++++-- 5 files changed, 382 insertions(+), 91 deletions(-) diff --git a/board/freescale/mx51evk/imximage.cfg b/board/freescale/mx51evk/imximage.cfg index a875e8f..11825fb 100644 --- a/board/freescale/mx51evk/imximage.cfg +++ b/board/freescale/mx51evk/imximage.cfg @@ -25,6 +25,10 @@ # # The syntax is taken as close as possible with the kwbimage +# Imximage version + +IMXIMAGE_VERSION 1 + # Boot Device : one of # spi, sd (the board has no nand neither onenand) diff --git a/board/ttcontrol/vision2/imximage_hynix.cfg b/board/ttcontrol/vision2/imximage_hynix.cfg index ed531db..cdc533d 100644 --- a/board/ttcontrol/vision2/imximage_hynix.cfg +++ b/board/ttcontrol/vision2/imximage_hynix.cfg @@ -28,6 +28,10 @@ # # The syntax is taken as close as possible with the kwbimage +# Imximage version + +IMXIMAGE_VERSION 2 + # Boot Device : one of # spi, nand, onenand, sd diff --git a/doc/README.imximage b/doc/README.imximage index 3378f7e..48ac466 100644 --- a/doc/README.imximage +++ b/doc/README.imximage @@ -57,6 +57,11 @@ Configuration command line syntax: 2. Following are the valid command strings and associated data strings:- Command string data string -------------- ----------- + IMXIMAGE_VERSION 1/2 + 1 is for mx25/mx35/mx51 compatible, + 2 is for mx53 compatible, + others is invalid and error is generated. + BOOT_FROM nand/spi/sd/onenand Example: BOOT_FROM spi @@ -69,8 +74,9 @@ Configuration command line syntax: Example (write to IOMUXC): DATA 4 0x73FA88a0 0x200 -The processor support up to 60 register programming commands. An error -is generated if more commands are found in the configuration file. +The processor support up to 60 register programming commands for IMXIMAGE_VERSION 1 +and 121 register programming commands for IMXIMAGE_VERSION 2. +An error is generated if more commands are found in the configuration file. 3. All commands are optional to program. diff --git a/tools/imximage.c b/tools/imximage.c index 39f89c2..2bbc4a6 100644 --- a/tools/imximage.c +++ b/tools/imximage.c @@ -36,6 +36,7 @@ * Supported commands for configuration file */ static table_entry_t imximage_cmds[] = { + {CMD_IMXIMAGE_VERSION, "IMXIMAGE_VERSION", "imximage version", }, {CMD_BOOT_FROM, "BOOT_FROM", "boot command", }, {CMD_DATA, "DATA", "Reg Write Data", }, {-1, "", "", }, @@ -53,6 +54,14 @@ static table_entry_t imximage_bootops[] = { {-1, "", "Invalid", }, }; +/* + * IMXIMAGE version definition for i.MX chips + */ +static table_entry_t imximage_versions[] = { + {IMXIMAGE_V1, "", " (i.MX25/35/51 compatible)", }, + {IMXIMAGE_V2, "", " (i.MX53 compatible)", }, + {-1, "", " (Invalid)", }, +}; static struct imx_header imximage_header; @@ -71,6 +80,128 @@ static uint32_t get_cfg_value(char *token, char *name, int linenr) return value; } +static void err_imximage_version(int version) +{ + fprintf(stderr, + "Error: Unsuported imximage version:%d\n", version); + + exit(EXIT_FAILURE); +} + +static void set_dcd_value_v1(struct imx_header *imxhdr, char *name, int lineno, + int fld, uint32_t value, uint32_t off) +{ + dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.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); + } + dcd_v1->addr_data[off].type = value; + break; + case CFG_REG_ADDRESS: + dcd_v1->addr_data[off].addr = value; + break; + case CFG_REG_VALUE: + dcd_v1->addr_data[off].value = value; + break; + default: + break; + + } +} + +static void set_dcd_value_v2(struct imx_header *imxhdr, char *name, int lineno, + int fld, uint32_t value, uint32_t off) +{ + dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.dcd_table; + + switch (fld) { + case CFG_REG_ADDRESS: + dcd_v2->addr_data[off].addr = cpu_to_be32(value); + break; + case CFG_REG_VALUE: + dcd_v2->addr_data[off].value = cpu_to_be32(value); + break; + default: + break; + + } +} + +static void set_dcd_value(struct imx_header *imxhdr, char *name, int lineno, + int fld, uint32_t value, uint32_t off) +{ + switch (imxhdr->imximage_version) { + case IMXIMAGE_V1: + set_dcd_value_v1(imxhdr, name, lineno, fld, value, off); + break; + case IMXIMAGE_V2: + set_dcd_value_v2(imxhdr, name, lineno, fld, value, off); + break; + default: + err_imximage_version(imxhdr->imximage_version); + break; + } +} + +static void set_dcd_rest_v1(struct imx_header *imxhdr, uint32_t dcd_len, + char *name, int lineno) +{ + 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); + } + + dcd_v1->preamble.barker = DCD_BARKER; + dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t); +} + +static void set_dcd_rest_v2(struct imx_header *imxhdr, uint32_t dcd_len, + char *name, int lineno) +{ + 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); + } + + 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 void set_dcd_rest(struct imx_header *imxhdr, uint32_t dcd_len, + char *name, int lineno) +{ + switch (imxhdr->imximage_version) { + case IMXIMAGE_V1: + set_dcd_rest_v1(imxhdr, dcd_len, name, lineno); + break; + case IMXIMAGE_V2: + set_dcd_rest_v2(imxhdr, dcd_len, name, lineno); + break; + default: + err_imximage_version(imxhdr->imximage_version); + break; + } +} + static int imximage_check_image_types(uint8_t type) { if (type == IH_TYPE_IMXIMAGE) @@ -82,44 +213,91 @@ static int imximage_check_image_types(uint8_t type) static int imximage_verify_header(unsigned char *ptr, int image_size, struct mkimage_params *params) { - struct imx_header *imx_hdr = (struct imx_header *) ptr; - flash_header_t *hdr = &imx_hdr->fhdr; + flash_header_v1_t *fhdr = &imx_hdr->header.hdr_v1.fhdr; + + if (imx_hdr->imximage_version != IMXIMAGE_V1) + return 0; /* Only a few checks can be done: search for magic numbers */ - if (hdr->app_code_barker != APP_CODE_BARKER) + if (fhdr->app_code_barker != APP_CODE_BARKER) return -FDT_ERR_BADSTRUCTURE; - if (imx_hdr->dcd_table.preamble.barker != DCD_BARKER) + if (imx_hdr->header.hdr_v1.dcd_table.preamble.barker != DCD_BARKER) return -FDT_ERR_BADSTRUCTURE; return 0; } -static void imximage_print_header(const void *ptr) +static void imximage_print_header_v1(struct imx_header *imx_hdr) { - struct imx_header *imx_hdr = (struct imx_header *) ptr; - flash_header_t *hdr = &imx_hdr->fhdr; - uint32_t size; - uint32_t length; - dcd_t *dcd = &imx_hdr->dcd_table; + imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1; + flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr; + dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table; + uint32_t size, length; - size = imx_hdr->dcd_table.preamble.length; - if (size > (MAX_HW_CFG_SIZE * sizeof(dcd_type_addr_data_t))) { + size = dcd_v1->preamble.length; + if (size > (MAX_HW_CFG_SIZE_V1 * sizeof(dcd_type_addr_data_t))) { fprintf(stderr, "Error: Image corrupt DCD size %d exceed maximum %d\n", (uint32_t)(size / sizeof(dcd_type_addr_data_t)), - MAX_HW_CFG_SIZE); + MAX_HW_CFG_SIZE_V1); exit(EXIT_FAILURE); } - length = dcd->preamble.length / sizeof(dcd_type_addr_data_t); + length = dcd_v1->preamble.length / sizeof(dcd_type_addr_data_t); + + printf("Image Type: Freescale IMX Boot Image\n"); + printf("Image Ver: %x", (uint32_t)imx_hdr->imximage_version); + printf("%s\n", get_table_entry_name(imximage_versions, + NULL, imx_hdr->imximage_version)); + printf("Data Size: "); + genimg_print_size(dcd_v1->addr_data[length].type); + printf("Load Address: %08x\n", (uint32_t)fhdr_v1->app_dest_ptr); + printf("Entry Point: %08x\n", (uint32_t)fhdr_v1->app_code_jump_vector); +} + +static void imximage_print_header_v2(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; + dcd_v2_t *dcd_v2 = &hdr_v2->dcd_table; + uint32_t size; + + 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); + } printf("Image Type: Freescale IMX Boot Image\n"); + printf("Image Ver: %x", (uint32_t)imx_hdr->imximage_version); + printf("%s\n", get_table_entry_name(imximage_versions, + NULL, imx_hdr->imximage_version)); printf("Data Size: "); - genimg_print_size(dcd->addr_data[length].type); - printf("Load Address: %08x\n", (unsigned int)hdr->app_dest_ptr); - printf("Entry Point: %08x\n", (unsigned int)hdr->app_code_jump_vector); + 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 imximage_print_header(const void *ptr) +{ + struct imx_header *imx_hdr = (struct imx_header *) ptr; + + switch (imx_hdr->imximage_version) { + case IMXIMAGE_V1: + imximage_print_header_v1(imx_hdr); + break; + case IMXIMAGE_V2: + imximage_print_header_v2(imx_hdr); + break; + default: + err_imximage_version(imx_hdr->imximage_version); + break; + } } static uint32_t imximage_parse_cfg_file(struct imx_header *imxhdr, char *name) @@ -131,7 +309,6 @@ static uint32_t imximage_parse_cfg_file(struct imx_header *imxhdr, char *name) int fld, value; size_t len; int dcd_len = 0; - dcd_t *dcd = &imxhdr->dcd_table; int32_t cmd; fd = fopen(name, "r"); @@ -176,6 +353,11 @@ static uint32_t imximage_parse_cfg_file(struct imx_header *imxhdr, char *name) break; case CFG_REG_SIZE: switch (cmd) { + case CMD_IMXIMAGE_VERSION: + imxhdr->imximage_version = + get_cfg_value(token, + name, lineno); + break; case CMD_BOOT_FROM: /* Get flash header offset */ imxhdr->flash_offset = @@ -195,92 +377,131 @@ static uint32_t imximage_parse_cfg_file(struct imx_header *imxhdr, char *name) case CMD_DATA: value = get_cfg_value(token, name, lineno); - - /* 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); - } - dcd->addr_data[dcd_len].type = value; + set_dcd_value(imxhdr, name, lineno, + fld, value, dcd_len); break; } case CFG_REG_ADDRESS: - if (cmd == CMD_DATA) - dcd->addr_data[dcd_len].addr = - get_cfg_value(token, + if (cmd == CMD_DATA) { + value = get_cfg_value(token, name, lineno); + set_dcd_value(imxhdr, name, lineno, + fld, value, dcd_len); + } break; case CFG_REG_VALUE: if (cmd == CMD_DATA) { - dcd->addr_data[dcd_len].value = - get_cfg_value(token, + value = get_cfg_value(token, name, lineno); + set_dcd_value(imxhdr, name, lineno, + fld, value, dcd_len); dcd_len++; } break; } } - if (dcd_len > MAX_HW_CFG_SIZE) { - fprintf(stderr, - "Error: %s[%d] -" - "DCD table exceeds maximum size(%d)\n", - name, lineno, MAX_HW_CFG_SIZE); - } } - dcd->preamble.barker = DCD_BARKER; - dcd->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t); - fclose(fd); + set_dcd_rest(imxhdr, dcd_len, name, lineno); + + fclose(fd); return dcd_len; } -static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd, - struct mkimage_params *params) +static void imximage_set_header_v1(struct imx_header *imxhdr, uint32_t dcd_len, + struct stat *sbuf, + struct mkimage_params *params) { - struct imx_header *hdr = (struct imx_header *)ptr; - flash_header_t *fhdr = &hdr->fhdr; - int dcd_len; - dcd_t *dcd = &hdr->dcd_table; + 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; /* Set default offset */ - hdr->flash_offset = FLASH_OFFSET_STANDARD; + imxhdr->flash_offset = FLASH_OFFSET_STANDARD; /* Set magic number */ - fhdr->app_code_barker = APP_CODE_BARKER; + fhdr_v1->app_code_barker = APP_CODE_BARKER; - /* Parse dcd configuration file */ - dcd_len = imximage_parse_cfg_file(hdr, params->imagename); - - fhdr->app_dest_ptr = params->addr; - fhdr->app_dest_ptr = params->ep - hdr->flash_offset - + fhdr_v1->app_dest_ptr = params->addr; + fhdr_v1->app_dest_ptr = params->ep - imxhdr->flash_offset - sizeof(struct imx_header); - fhdr->app_code_jump_vector = params->ep; + fhdr_v1->app_code_jump_vector = params->ep; - base_offset = fhdr->app_dest_ptr + hdr->flash_offset ; - fhdr->dcd_ptr_ptr = (uint32_t) (offsetof(flash_header_t, dcd_ptr) - - offsetof(flash_header_t, app_code_jump_vector) + + 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->dcd_ptr = base_offset + - offsetof(struct imx_header, dcd_table); + 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->addr_data[dcd_len].type = sbuf->st_size + - hdr->flash_offset + + dcd_v1->addr_data[dcd_len].type = sbuf->st_size + + imxhdr->flash_offset + sizeof(struct imx_header); /* Security feature are not supported */ - fhdr->app_code_csf = 0; - fhdr->super_root_key = 0; + fhdr_v1->app_code_csf = 0; + fhdr_v1->super_root_key = 0; +} + +static void imximage_set_header_v2(struct imx_header *imxhdr, + struct stat *sbuf, + struct mkimage_params *params) +{ + imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2; + flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr; + + /* Set default offset */ + imxhdr->flash_offset = FLASH_OFFSET_STANDARD; + + /* 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->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->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); + + /* Security feature are not supported */ + fhdr_v2->csf = 0; +} +static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd, + struct mkimage_params *params) +{ + struct imx_header *imxhdr = (struct imx_header *)ptr; + uint32_t dcd_len; + + /* Parse dcd configuration file */ + dcd_len = imximage_parse_cfg_file(imxhdr, params->imagename); + + switch (imxhdr->imximage_version) { + case IMXIMAGE_V1: + imximage_set_header_v1(imxhdr, dcd_len, sbuf, params); + break; + case IMXIMAGE_V2: + imximage_set_header_v2(imxhdr, sbuf, params); + break; + default: + err_imximage_version(imxhdr->imximage_version); + break; + } } int imximage_check_params(struct mkimage_params *params) @@ -309,7 +530,7 @@ int imximage_check_params(struct mkimage_params *params) * imximage parameters */ static struct image_type_params imximage_params = { - .name = "Freescale i.MX 51 Boot Image support", + .name = "Freescale i.MX 5x Boot Image support", .header_size = sizeof(struct imx_header), .hdr = (void *)&imximage_header, .check_image_type = imximage_check_image_types, diff --git a/tools/imximage.h b/tools/imximage.h index b4d926d..67b9022 100644 --- a/tools/imximage.h +++ b/tools/imximage.h @@ -24,12 +24,14 @@ #ifndef _IMXIMAGE_H_ #define _IMXIMAGE_H_ -#define MAX_HW_CFG_SIZE 60 /* Max number of registers imx can set */ -#define MAX_EXP_SIZE 4 +#include + +#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 */ #define APP_CODE_BARKER 0xB1 #define DCD_BARKER 0xB17219E9 -#define HEADER_OFFSET 0x400 +#define HEADER_OFFSET 0x400 #define CMD_DATA_STR "DATA" #define FLASH_OFFSET_STANDARD 0x400 @@ -38,8 +40,16 @@ #define FLASH_OFFSET_SPI FLASH_OFFSET_STANDARD #define FLASH_OFFSET_ONENAND 0x100 +#define IVT_HEADER_TAG 0xD1 +#define IVT_VERSION 0x40 +#define DCD_HEADER_TAG 0xD2 +#define DCD_COMMAND_TAG 0xCC +#define DCD_VERSION 0x40 +#define DCD_COMMAND_PARAM 0x4 + enum imximage_cmd { CMD_INVALID, + CMD_IMXIMAGE_VERSION, CMD_BOOT_FROM, CMD_DATA }; @@ -52,13 +62,10 @@ enum imximage_fld_types { CFG_REG_VALUE }; -typedef struct { - uint8_t rsa_exponent[MAX_EXP_SIZE]; /* RSA public exponent */ - uint8_t *rsa_modulus; /* RSA modulus pointer */ - uint16_t exponent_size; /* Exponent size (bytes) */ - uint16_t modulus_size; /* Modulus size (bytes) */ - uint8_t init_flag; /* key initialized */ -} hab_rsa_public_key; +enum imximage_version { + IMXIMAGE_V1 = 1, + IMXIMAGE_V2 +}; typedef struct { uint32_t type; /* Type of pointer (byte, halfword, word, wait/read) */ @@ -73,8 +80,8 @@ typedef struct { typedef struct { dcd_preamble_t preamble; - dcd_type_addr_data_t addr_data[MAX_HW_CFG_SIZE]; -} dcd_t; + dcd_type_addr_data_t addr_data[MAX_HW_CFG_SIZE_V1]; +} dcd_v1_t; typedef struct { uint32_t app_code_jump_vector; @@ -84,22 +91,71 @@ typedef struct { uint32_t super_root_key; uint32_t dcd_ptr; uint32_t app_dest_ptr; -} flash_header_t; +} flash_header_v1_t; typedef struct { uint32_t length; /* Length of data to be read from flash */ } flash_cfg_parms_t; -struct imx_header { - flash_header_t fhdr; - dcd_t dcd_table; +typedef struct { + flash_header_v1_t fhdr; + dcd_v1_t dcd_table; flash_cfg_parms_t ext_header; - uint32_t flash_offset; -}; +} imx_header_v1_t; + +typedef struct { + uint32_t addr; + uint32_t value; +} dcd_addr_data_t; + +typedef struct { + uint8_t tag; + uint16_t length; + uint8_t version; +} __attribute__((packed)) ivt_header_t; -struct reg_config { - uint32_t raddr; - uint32_t rdata; +typedef struct { + uint8_t tag; + uint16_t length; + uint8_t param; +} __attribute__((packed)) write_dcd_command_t; + +typedef struct { + ivt_header_t header; + write_dcd_command_t write_dcd_command; + dcd_addr_data_t addr_data[MAX_HW_CFG_SIZE_V2]; +} dcd_v2_t; + +typedef struct { + uint32_t start; + uint32_t size; + uint32_t plugin; +} boot_data_t; + +typedef struct { + ivt_header_t header; + uint32_t entry; + uint32_t reserved1; + uint32_t dcd_ptr; + uint32_t boot_data_ptr; + uint32_t self; + uint32_t csf; + uint32_t reserved2; +} flash_header_v2_t; + +typedef struct { + flash_header_v2_t fhdr; + boot_data_t boot_data; + dcd_v2_t dcd_table; +} imx_header_v2_t; + +struct imx_header { + union { + imx_header_v1_t hdr_v1; + imx_header_v2_t hdr_v2; + } header; + uint32_t flash_offset; + uint32_t imximage_version; }; #endif /* _IMXIMAGE_H_ */