From 8a1edd7d54096ed28232a6cfec7288cd0426d988 Mon Sep 17 00:00:00 2001 From: Liu Hui-R64343 Date: Wed, 19 Jan 2011 09:40:26 +0000 Subject: [PATCH] imximage: Add MX53 boot image support 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 --- doc/README.imximage | 12 +- tools/imximage.c | 525 ++++++++++++++++++++++++++++++++------------ tools/imximage.h | 110 ++++++++-- 3 files changed, 487 insertions(+), 160 deletions(-) diff --git a/doc/README.imximage b/doc/README.imximage index 3378f7efdb..c74239d2ad 100644 --- a/doc/README.imximage +++ b/doc/README.imximage @@ -57,6 +57,13 @@ 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. + This command need appear the fist before + other valid commands in configuration file. + BOOT_FROM nand/spi/sd/onenand Example: BOOT_FROM spi @@ -69,8 +76,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 39f89c2b93..8e81bdb9c4 100644 --- a/tools/imximage.c +++ b/tools/imximage.c @@ -36,9 +36,10 @@ * Supported commands for configuration file */ static table_entry_t imximage_cmds[] = { - {CMD_BOOT_FROM, "BOOT_FROM", "boot command", }, - {CMD_DATA, "DATA", "Reg Write Data", }, - {-1, "", "", }, + {CMD_BOOT_FROM, "BOOT_FROM", "boot command", }, + {CMD_DATA, "DATA", "Reg Write Data", }, + {CMD_IMAGE_VERSION, "IMAGE_VERSION", "image version", }, + {-1, "", "", }, }; /* @@ -53,8 +54,21 @@ 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; +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 get_cfg_value(char *token, char *name, int linenr) { @@ -71,67 +85,353 @@ static uint32_t get_cfg_value(char *token, char *name, int linenr) return value; } -static int imximage_check_image_types(uint8_t type) +static uint32_t detect_imximage_version(struct imx_header *imx_hdr) { - if (type == IH_TYPE_IMXIMAGE) - return EXIT_SUCCESS; - else - return EXIT_FAILURE; + imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1; + imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2; + flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr; + flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr; + + /* Try to detect V1 */ + if ((fhdr_v1->app_code_barker == APP_CODE_BARKER) && + (hdr_v1->dcd_table.preamble.barker == DCD_BARKER)) + return IMXIMAGE_V1; + + /* Try to detect V2 */ + if ((fhdr_v2->header.tag == IVT_HEADER_TAG) && + (hdr_v2->dcd_table.header.tag == DCD_HEADER_TAG)) + return IMXIMAGE_V2; + + return IMXIMAGE_VER_INVALID; } -static int imximage_verify_header(unsigned char *ptr, int image_size, - struct mkimage_params *params) +static void err_imximage_version(int version) { + fprintf(stderr, + "Error: Unsupported imximage version:%d\n", version); - struct imx_header *imx_hdr = (struct imx_header *) ptr; - flash_header_t *hdr = &imx_hdr->fhdr; + exit(EXIT_FAILURE); +} - /* Only a few checks can be done: search for magic numbers */ - if (hdr->app_code_barker != APP_CODE_BARKER) - return -FDT_ERR_BADSTRUCTURE; +static void set_dcd_val_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; - if (imx_hdr->dcd_table.preamble.barker != DCD_BARKER) - return -FDT_ERR_BADSTRUCTURE; + } +} - return 0; +static void set_dcd_val_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 imximage_print_header(const void *ptr) +/* + * 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) { - 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; + 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); +} + +/* + * 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; + + 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); + 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_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len, + struct stat *sbuf, + struct mkimage_params *params) +{ + 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 */ + imxhdr->flash_offset = FLASH_OFFSET_STANDARD; + + /* 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; + + 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); + + /* Security feature are not supported */ + fhdr_v1->app_code_csf = 0; + fhdr_v1->super_root_key = 0; +} + +static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len, + 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 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; + 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; + break; + default: + err_imximage_version(imximage_version); + break; + } +} - size = imx_hdr->dcd_table.preamble.length; - if (size > (MAX_HW_CFG_SIZE * sizeof(dcd_type_addr_data_t))) { +static void print_hdr_v1(struct imx_header *imx_hdr) +{ + 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, ver; + + 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_v1->preamble.length / sizeof(dcd_type_addr_data_t); + ver = detect_imximage_version(imx_hdr); + + printf("Image Type: Freescale IMX Boot Image\n"); + printf("Image Ver: %x", ver); + printf("%s\n", get_table_entry_name(imximage_versions, NULL, ver)); + 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 print_hdr_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, 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); } - length = dcd->preamble.length / sizeof(dcd_type_addr_data_t); + version = detect_imximage_version(imx_hdr); 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(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 uint32_t imximage_parse_cfg_file(struct imx_header *imxhdr, char *name) +static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token, + char *name, int lineno, int fld, int dcd_len) +{ + 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); + } + cmd_ver_first = 1; + set_hdr_func(imxhdr); + break; + case CMD_BOOT_FROM: + imxhdr->flash_offset = get_table_entry_id(imximage_bootops, + "imximage boot option", token); + if (imxhdr->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); + (*set_dcd_val)(imxhdr, 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, + char *token, char *name, int lineno, int fld, int *dcd_len) +{ + 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, *dcd_len); + 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, *dcd_len); + + if (fld == CFG_REG_VALUE) + (*dcd_len)++; + break; + default: + break; + } +} +static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name) { FILE *fd = NULL; char *line = NULL; char *token, *saveptr1, *saveptr2; int lineno = 0; - int fld, value; + int fld; size_t len; int dcd_len = 0; - dcd_t *dcd = &imxhdr->dcd_table; int32_t cmd; fd = fopen(name, "r"); @@ -161,126 +461,75 @@ static uint32_t imximage_parse_cfg_file(struct imx_header *imxhdr, char *name) if (token[0] == '#') break; - /* parse all fields in a single line */ - 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: - switch (cmd) { - case CMD_BOOT_FROM: - /* Get flash header offset */ - imxhdr->flash_offset = - get_table_entry_id( - imximage_bootops, - "imximage boot option", - token); - if (imxhdr->flash_offset == -1) { - fprintf(stderr, - "Error: %s[%d] -" - "Invalid boot device" - "(%s)\n", - name, lineno, token); - exit(EXIT_FAILURE); - } - break; - 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; - break; - } - - case CFG_REG_ADDRESS: - if (cmd == CMD_DATA) - dcd->addr_data[dcd_len].addr = - get_cfg_value(token, - name, lineno); - break; - case CFG_REG_VALUE: - if (cmd == CMD_DATA) { - dcd->addr_data[dcd_len].value = - get_cfg_value(token, - name, lineno); - dcd_len++; - } - break; - } + parse_cfg_fld(imxhdr, &cmd, token, name, + lineno, fld, &dcd_len); } - 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); + + (*set_dcd_rst)(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) -{ - struct imx_header *hdr = (struct imx_header *)ptr; - flash_header_t *fhdr = &hdr->fhdr; - int dcd_len; - dcd_t *dcd = &hdr->dcd_table; - uint32_t base_offset; - /* Set default offset */ - hdr->flash_offset = FLASH_OFFSET_STANDARD; +static int imximage_check_image_types(uint8_t type) +{ + if (type == IH_TYPE_IMXIMAGE) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; +} - /* Set magic number */ - fhdr->app_code_barker = APP_CODE_BARKER; +static int imximage_verify_header(unsigned char *ptr, int image_size, + struct mkimage_params *params) +{ + struct imx_header *imx_hdr = (struct imx_header *) ptr; - /* Parse dcd configuration file */ - dcd_len = imximage_parse_cfg_file(hdr, params->imagename); + if (detect_imximage_version(imx_hdr) == IMXIMAGE_VER_INVALID) + return -FDT_ERR_BADSTRUCTURE; - fhdr->app_dest_ptr = params->addr; - fhdr->app_dest_ptr = params->ep - hdr->flash_offset - - sizeof(struct imx_header); - fhdr->app_code_jump_vector = params->ep; + return 0; +} - 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); +static void imximage_print_header(const void *ptr) +{ + struct imx_header *imx_hdr = (struct imx_header *) ptr; + uint32_t version = detect_imximage_version(imx_hdr); + + switch (version) { + case IMXIMAGE_V1: + print_hdr_v1(imx_hdr); + break; + case IMXIMAGE_V2: + print_hdr_v2(imx_hdr); + break; + default: + err_imximage_version(version); + break; + } +} - fhdr->dcd_ptr = base_offset + - offsetof(struct imx_header, dcd_table); +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; - /* 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 + - sizeof(struct imx_header); + /* + * 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; + set_hdr_func(imxhdr); - /* Security feature are not supported */ - fhdr->app_code_csf = 0; - fhdr->super_root_key = 0; + /* Parse dcd configuration file */ + dcd_len = parse_cfg_file(imxhdr, params->imagename); + /* Set the imx header */ + (*set_imx_hdr)(imxhdr, dcd_len, sbuf, params); } int imximage_check_params(struct mkimage_params *params) @@ -309,7 +558,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 b4d926d810..38ca6be1f4 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_IMAGE_VERSION, CMD_BOOT_FROM, CMD_DATA }; @@ -52,13 +62,11 @@ 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_VER_INVALID = -1, + IMXIMAGE_V1 = 1, + IMXIMAGE_V2 +}; typedef struct { uint32_t type; /* Type of pointer (byte, halfword, word, wait/read) */ @@ -73,8 +81,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 +92,84 @@ 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; +} 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; + +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; }; -struct reg_config { - uint32_t raddr; - uint32_t rdata; -}; +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_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); #endif /* _IMXIMAGE_H_ */ -- 2.39.5