Commit 3d3bb6708a3c41723b899f7186ae79b4e9b6baa1

Authored by Ye.Li
1 parent 59ca4318ab

MLK-9714 imx: imximage tool: Fixed the bootdata.size calculation

The bootdata.size should contain the IVT offset part, but the calculation
for bootdata.size in imximage tool does not. This will cause some data at
the end of image not be loaded into memory.

Signed-off-by: Ye.Li <B37916@freescale.com>

Showing 1 changed file with 1 additions and 1 deletions Inline Diff

1 /* 1 /*
2 * (C) Copyright 2009 2 * (C) Copyright 2009
3 * Stefano Babic, DENX Software Engineering, sbabic@denx.de. 3 * Stefano Babic, DENX Software Engineering, sbabic@denx.de.
4 * 4 *
5 * (C) Copyright 2008 5 * (C) Copyright 2008
6 * Marvell Semiconductor <www.marvell.com> 6 * Marvell Semiconductor <www.marvell.com>
7 * Written-by: Prafulla Wadaskar <prafulla@marvell.com> 7 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
8 * 8 *
9 * Copyright (C) 2014 Freescale Semiconductor, Inc. 9 * Copyright (C) 2014 Freescale Semiconductor, Inc.
10 * 10 *
11 * SPDX-License-Identifier: GPL-2.0+ 11 * SPDX-License-Identifier: GPL-2.0+
12 */ 12 */
13 13
14 #include "imagetool.h" 14 #include "imagetool.h"
15 #include <image.h> 15 #include <image.h>
16 #include "imximage.h" 16 #include "imximage.h"
17 17
18 #define UNDEFINED 0xFFFFFFFF 18 #define UNDEFINED 0xFFFFFFFF
19 19
20 /* 20 /*
21 * Supported commands for configuration file 21 * Supported commands for configuration file
22 */ 22 */
23 static table_entry_t imximage_cmds[] = { 23 static table_entry_t imximage_cmds[] = {
24 {CMD_BOOT_FROM, "BOOT_FROM", "boot command", }, 24 {CMD_BOOT_FROM, "BOOT_FROM", "boot command", },
25 {CMD_BOOT_OFFSET, "BOOT_OFFSET", "Boot offset", }, 25 {CMD_BOOT_OFFSET, "BOOT_OFFSET", "Boot offset", },
26 {CMD_DATA, "DATA", "Reg Write Data", }, 26 {CMD_DATA, "DATA", "Reg Write Data", },
27 {CMD_CSF, "CSF", "Command Sequence File", }, 27 {CMD_CSF, "CSF", "Command Sequence File", },
28 {CMD_IMAGE_VERSION, "IMAGE_VERSION", "image version", }, 28 {CMD_IMAGE_VERSION, "IMAGE_VERSION", "image version", },
29 #ifdef CONFIG_USE_PLUGIN 29 #ifdef CONFIG_USE_PLUGIN
30 {CMD_PLUGIN, "PLUGIN", "file plugin_addr", }, 30 {CMD_PLUGIN, "PLUGIN", "file plugin_addr", },
31 #endif 31 #endif
32 {-1, "", "", }, 32 {-1, "", "", },
33 }; 33 };
34 34
35 /* 35 /*
36 * Supported Boot options for configuration file 36 * Supported Boot options for configuration file
37 * this is needed to set the correct flash offset 37 * this is needed to set the correct flash offset
38 */ 38 */
39 static table_entry_t imximage_boot_offset[] = { 39 static table_entry_t imximage_boot_offset[] = {
40 {FLASH_OFFSET_ONENAND, "onenand", "OneNAND Flash",}, 40 {FLASH_OFFSET_ONENAND, "onenand", "OneNAND Flash",},
41 {FLASH_OFFSET_NAND, "nand", "NAND Flash", }, 41 {FLASH_OFFSET_NAND, "nand", "NAND Flash", },
42 {FLASH_OFFSET_NOR, "nor", "NOR Flash", }, 42 {FLASH_OFFSET_NOR, "nor", "NOR Flash", },
43 {FLASH_OFFSET_SATA, "sata", "SATA Disk", }, 43 {FLASH_OFFSET_SATA, "sata", "SATA Disk", },
44 {FLASH_OFFSET_SD, "sd", "SD Card", }, 44 {FLASH_OFFSET_SD, "sd", "SD Card", },
45 {FLASH_OFFSET_SPI, "spi", "SPI Flash", }, 45 {FLASH_OFFSET_SPI, "spi", "SPI Flash", },
46 {FLASH_OFFSET_QSPI, "qspi", "QSPI Flash", }, 46 {FLASH_OFFSET_QSPI, "qspi", "QSPI Flash", },
47 {-1, "", "Invalid", }, 47 {-1, "", "Invalid", },
48 }; 48 };
49 49
50 /* 50 /*
51 * Supported Boot options for configuration file 51 * Supported Boot options for configuration file
52 * this is needed to determine the initial load size 52 * this is needed to determine the initial load size
53 */ 53 */
54 static table_entry_t imximage_boot_loadsize[] = { 54 static table_entry_t imximage_boot_loadsize[] = {
55 {FLASH_LOADSIZE_ONENAND, "onenand", "OneNAND Flash",}, 55 {FLASH_LOADSIZE_ONENAND, "onenand", "OneNAND Flash",},
56 {FLASH_LOADSIZE_NAND, "nand", "NAND Flash", }, 56 {FLASH_LOADSIZE_NAND, "nand", "NAND Flash", },
57 {FLASH_LOADSIZE_NOR, "nor", "NOR Flash", }, 57 {FLASH_LOADSIZE_NOR, "nor", "NOR Flash", },
58 {FLASH_LOADSIZE_SATA, "sata", "SATA Disk", }, 58 {FLASH_LOADSIZE_SATA, "sata", "SATA Disk", },
59 {FLASH_LOADSIZE_SD, "sd", "SD Card", }, 59 {FLASH_LOADSIZE_SD, "sd", "SD Card", },
60 {FLASH_LOADSIZE_SPI, "spi", "SPI Flash", }, 60 {FLASH_LOADSIZE_SPI, "spi", "SPI Flash", },
61 {FLASH_LOADSIZE_QSPI, "qspi", "QSPI Flash", }, 61 {FLASH_LOADSIZE_QSPI, "qspi", "QSPI Flash", },
62 {-1, "", "Invalid", }, 62 {-1, "", "Invalid", },
63 }; 63 };
64 64
65 /* 65 /*
66 * IMXIMAGE version definition for i.MX chips 66 * IMXIMAGE version definition for i.MX chips
67 */ 67 */
68 static table_entry_t imximage_versions[] = { 68 static table_entry_t imximage_versions[] = {
69 {IMXIMAGE_V1, "", " (i.MX25/35/51 compatible)", }, 69 {IMXIMAGE_V1, "", " (i.MX25/35/51 compatible)", },
70 {IMXIMAGE_V2, "", " (i.MX53/6 compatible)", }, 70 {IMXIMAGE_V2, "", " (i.MX53/6 compatible)", },
71 {-1, "", " (Invalid)", }, 71 {-1, "", " (Invalid)", },
72 }; 72 };
73 73
74 static struct imx_header imximage_header; 74 static struct imx_header imximage_header;
75 static uint32_t imximage_version; 75 static uint32_t imximage_version;
76 /* 76 /*
77 * Image Vector Table Offset 77 * Image Vector Table Offset
78 * Initialized to a wrong not 4-bytes aligned address to 78 * Initialized to a wrong not 4-bytes aligned address to
79 * check if it is was set by the cfg file. 79 * check if it is was set by the cfg file.
80 */ 80 */
81 static uint32_t imximage_ivt_offset = UNDEFINED; 81 static uint32_t imximage_ivt_offset = UNDEFINED;
82 static uint32_t imximage_csf_size = UNDEFINED; 82 static uint32_t imximage_csf_size = UNDEFINED;
83 /* Initial Load Region Size */ 83 /* Initial Load Region Size */
84 static uint32_t imximage_init_loadsize; 84 static uint32_t imximage_init_loadsize;
85 static uint32_t imximage_iram_free_start; 85 static uint32_t imximage_iram_free_start;
86 static uint32_t imximage_plugin_size; 86 static uint32_t imximage_plugin_size;
87 87
88 static set_dcd_val_t set_dcd_val; 88 static set_dcd_val_t set_dcd_val;
89 static set_dcd_rst_t set_dcd_rst; 89 static set_dcd_rst_t set_dcd_rst;
90 static set_imx_hdr_t set_imx_hdr; 90 static set_imx_hdr_t set_imx_hdr;
91 static uint32_t max_dcd_entries; 91 static uint32_t max_dcd_entries;
92 static uint32_t *header_size_ptr; 92 static uint32_t *header_size_ptr;
93 static uint32_t *csf_ptr; 93 static uint32_t *csf_ptr;
94 94
95 static uint32_t get_cfg_value(char *token, char *name, int linenr) 95 static uint32_t get_cfg_value(char *token, char *name, int linenr)
96 { 96 {
97 char *endptr; 97 char *endptr;
98 uint32_t value; 98 uint32_t value;
99 99
100 errno = 0; 100 errno = 0;
101 value = strtoul(token, &endptr, 16); 101 value = strtoul(token, &endptr, 16);
102 if (errno || (token == endptr)) { 102 if (errno || (token == endptr)) {
103 fprintf(stderr, "Error: %s[%d] - Invalid hex data(%s)\n", 103 fprintf(stderr, "Error: %s[%d] - Invalid hex data(%s)\n",
104 name, linenr, token); 104 name, linenr, token);
105 exit(EXIT_FAILURE); 105 exit(EXIT_FAILURE);
106 } 106 }
107 return value; 107 return value;
108 } 108 }
109 109
110 static uint32_t detect_imximage_version(struct imx_header *imx_hdr) 110 static uint32_t detect_imximage_version(struct imx_header *imx_hdr)
111 { 111 {
112 imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1; 112 imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1;
113 imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2; 113 imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2;
114 flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr; 114 flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
115 flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr; 115 flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
116 116
117 /* Try to detect V1 */ 117 /* Try to detect V1 */
118 if ((fhdr_v1->app_code_barker == APP_CODE_BARKER) && 118 if ((fhdr_v1->app_code_barker == APP_CODE_BARKER) &&
119 (hdr_v1->dcd_table.preamble.barker == DCD_BARKER)) 119 (hdr_v1->dcd_table.preamble.barker == DCD_BARKER))
120 return IMXIMAGE_V1; 120 return IMXIMAGE_V1;
121 121
122 /* Try to detect V2 */ 122 /* Try to detect V2 */
123 if ((fhdr_v2->header.tag == IVT_HEADER_TAG) && 123 if ((fhdr_v2->header.tag == IVT_HEADER_TAG) &&
124 (hdr_v2->data.dcd_table.header.tag == DCD_HEADER_TAG)) 124 (hdr_v2->data.dcd_table.header.tag == DCD_HEADER_TAG))
125 return IMXIMAGE_V2; 125 return IMXIMAGE_V2;
126 126
127 if ((fhdr_v2->header.tag == IVT_HEADER_TAG) && 127 if ((fhdr_v2->header.tag == IVT_HEADER_TAG) &&
128 hdr_v2->boot_data.plugin) 128 hdr_v2->boot_data.plugin)
129 return IMXIMAGE_V2; 129 return IMXIMAGE_V2;
130 130
131 return IMXIMAGE_VER_INVALID; 131 return IMXIMAGE_VER_INVALID;
132 } 132 }
133 133
134 static void err_imximage_version(int version) 134 static void err_imximage_version(int version)
135 { 135 {
136 fprintf(stderr, 136 fprintf(stderr,
137 "Error: Unsupported imximage version:%d\n", version); 137 "Error: Unsupported imximage version:%d\n", version);
138 138
139 exit(EXIT_FAILURE); 139 exit(EXIT_FAILURE);
140 } 140 }
141 141
142 static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno, 142 static void set_dcd_val_v1(struct imx_header *imxhdr, char *name, int lineno,
143 int fld, uint32_t value, uint32_t off) 143 int fld, uint32_t value, uint32_t off)
144 { 144 {
145 dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table; 145 dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
146 146
147 switch (fld) { 147 switch (fld) {
148 case CFG_REG_SIZE: 148 case CFG_REG_SIZE:
149 /* Byte, halfword, word */ 149 /* Byte, halfword, word */
150 if ((value != 1) && (value != 2) && (value != 4)) { 150 if ((value != 1) && (value != 2) && (value != 4)) {
151 fprintf(stderr, "Error: %s[%d] - " 151 fprintf(stderr, "Error: %s[%d] - "
152 "Invalid register size " "(%d)\n", 152 "Invalid register size " "(%d)\n",
153 name, lineno, value); 153 name, lineno, value);
154 exit(EXIT_FAILURE); 154 exit(EXIT_FAILURE);
155 } 155 }
156 dcd_v1->addr_data[off].type = value; 156 dcd_v1->addr_data[off].type = value;
157 break; 157 break;
158 case CFG_REG_ADDRESS: 158 case CFG_REG_ADDRESS:
159 dcd_v1->addr_data[off].addr = value; 159 dcd_v1->addr_data[off].addr = value;
160 break; 160 break;
161 case CFG_REG_VALUE: 161 case CFG_REG_VALUE:
162 dcd_v1->addr_data[off].value = value; 162 dcd_v1->addr_data[off].value = value;
163 break; 163 break;
164 default: 164 default:
165 break; 165 break;
166 166
167 } 167 }
168 } 168 }
169 169
170 static void set_dcd_val_v2(struct imx_header *imxhdr, char *name, int lineno, 170 static void set_dcd_val_v2(struct imx_header *imxhdr, char *name, int lineno,
171 int fld, uint32_t value, uint32_t off) 171 int fld, uint32_t value, uint32_t off)
172 { 172 {
173 dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.data.dcd_table; 173 dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.data.dcd_table;
174 174
175 switch (fld) { 175 switch (fld) {
176 case CFG_REG_ADDRESS: 176 case CFG_REG_ADDRESS:
177 dcd_v2->addr_data[off].addr = cpu_to_be32(value); 177 dcd_v2->addr_data[off].addr = cpu_to_be32(value);
178 break; 178 break;
179 case CFG_REG_VALUE: 179 case CFG_REG_VALUE:
180 dcd_v2->addr_data[off].value = cpu_to_be32(value); 180 dcd_v2->addr_data[off].value = cpu_to_be32(value);
181 break; 181 break;
182 default: 182 default:
183 break; 183 break;
184 184
185 } 185 }
186 } 186 }
187 187
188 /* 188 /*
189 * Complete setting up the rest field of DCD of V1 189 * Complete setting up the rest field of DCD of V1
190 * such as barker code and DCD data length. 190 * such as barker code and DCD data length.
191 */ 191 */
192 static void set_dcd_rst_v1(struct imx_header *imxhdr, uint32_t dcd_len, 192 static void set_dcd_rst_v1(struct imx_header *imxhdr, uint32_t dcd_len,
193 char *name, int lineno) 193 char *name, int lineno)
194 { 194 {
195 dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table; 195 dcd_v1_t *dcd_v1 = &imxhdr->header.hdr_v1.dcd_table;
196 196
197 dcd_v1->preamble.barker = DCD_BARKER; 197 dcd_v1->preamble.barker = DCD_BARKER;
198 dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t); 198 dcd_v1->preamble.length = dcd_len * sizeof(dcd_type_addr_data_t);
199 } 199 }
200 200
201 /* 201 /*
202 * Complete setting up the reset field of DCD of V2 202 * Complete setting up the reset field of DCD of V2
203 * such as DCD tag, version, length, etc. 203 * such as DCD tag, version, length, etc.
204 */ 204 */
205 static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len, 205 static void set_dcd_rst_v2(struct imx_header *imxhdr, uint32_t dcd_len,
206 char *name, int lineno) 206 char *name, int lineno)
207 { 207 {
208 if (!imxhdr->header.hdr_v2.boot_data.plugin) { 208 if (!imxhdr->header.hdr_v2.boot_data.plugin) {
209 dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.data.dcd_table; 209 dcd_v2_t *dcd_v2 = &imxhdr->header.hdr_v2.data.dcd_table;
210 210
211 dcd_v2->header.tag = DCD_HEADER_TAG; 211 dcd_v2->header.tag = DCD_HEADER_TAG;
212 dcd_v2->header.length = cpu_to_be16( 212 dcd_v2->header.length = cpu_to_be16(
213 dcd_len * sizeof(dcd_addr_data_t) + 8); 213 dcd_len * sizeof(dcd_addr_data_t) + 8);
214 dcd_v2->header.version = DCD_VERSION; 214 dcd_v2->header.version = DCD_VERSION;
215 dcd_v2->write_dcd_command.tag = DCD_COMMAND_TAG; 215 dcd_v2->write_dcd_command.tag = DCD_COMMAND_TAG;
216 dcd_v2->write_dcd_command.length = cpu_to_be16( 216 dcd_v2->write_dcd_command.length = cpu_to_be16(
217 dcd_len * sizeof(dcd_addr_data_t) + 4); 217 dcd_len * sizeof(dcd_addr_data_t) + 4);
218 dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM; 218 dcd_v2->write_dcd_command.param = DCD_COMMAND_PARAM;
219 } 219 }
220 } 220 }
221 221
222 static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len, 222 static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
223 uint32_t entry_point, uint32_t flash_offset) 223 uint32_t entry_point, uint32_t flash_offset)
224 { 224 {
225 imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1; 225 imx_header_v1_t *hdr_v1 = &imxhdr->header.hdr_v1;
226 flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr; 226 flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
227 dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table; 227 dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table;
228 uint32_t hdr_base; 228 uint32_t hdr_base;
229 uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr) 229 uint32_t header_length = (((char *)&dcd_v1->addr_data[dcd_len].addr)
230 - ((char *)imxhdr)); 230 - ((char *)imxhdr));
231 231
232 /* Set magic number */ 232 /* Set magic number */
233 fhdr_v1->app_code_barker = APP_CODE_BARKER; 233 fhdr_v1->app_code_barker = APP_CODE_BARKER;
234 234
235 /* TODO: check i.MX image V1 handling, for now use 'old' style */ 235 /* TODO: check i.MX image V1 handling, for now use 'old' style */
236 hdr_base = entry_point - 4096; 236 hdr_base = entry_point - 4096;
237 fhdr_v1->app_dest_ptr = hdr_base - flash_offset; 237 fhdr_v1->app_dest_ptr = hdr_base - flash_offset;
238 fhdr_v1->app_code_jump_vector = entry_point; 238 fhdr_v1->app_code_jump_vector = entry_point;
239 239
240 fhdr_v1->dcd_ptr_ptr = hdr_base + offsetof(flash_header_v1_t, dcd_ptr); 240 fhdr_v1->dcd_ptr_ptr = hdr_base + offsetof(flash_header_v1_t, dcd_ptr);
241 fhdr_v1->dcd_ptr = hdr_base + offsetof(imx_header_v1_t, dcd_table); 241 fhdr_v1->dcd_ptr = hdr_base + offsetof(imx_header_v1_t, dcd_table);
242 242
243 /* Security feature are not supported */ 243 /* Security feature are not supported */
244 fhdr_v1->app_code_csf = 0; 244 fhdr_v1->app_code_csf = 0;
245 fhdr_v1->super_root_key = 0; 245 fhdr_v1->super_root_key = 0;
246 header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4); 246 header_size_ptr = (uint32_t *)(((char *)imxhdr) + header_length - 4);
247 } 247 }
248 248
249 static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len, 249 static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
250 uint32_t entry_point, uint32_t flash_offset) 250 uint32_t entry_point, uint32_t flash_offset)
251 { 251 {
252 imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2; 252 imx_header_v2_t *hdr_v2 = &imxhdr->header.hdr_v2;
253 flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr; 253 flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
254 uint32_t hdr_base; 254 uint32_t hdr_base;
255 255
256 /* Set magic number */ 256 /* Set magic number */
257 fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */ 257 fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
258 fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t)); 258 fhdr_v2->header.length = cpu_to_be16(sizeof(flash_header_v2_t));
259 fhdr_v2->header.version = IVT_VERSION; /* 0x40 */ 259 fhdr_v2->header.version = IVT_VERSION; /* 0x40 */
260 260
261 if (!hdr_v2->boot_data.plugin) { 261 if (!hdr_v2->boot_data.plugin) {
262 fhdr_v2->entry = entry_point; 262 fhdr_v2->entry = entry_point;
263 fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0; 263 fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
264 hdr_base = entry_point - imximage_init_loadsize + 264 hdr_base = entry_point - imximage_init_loadsize +
265 flash_offset; 265 flash_offset;
266 fhdr_v2->self = hdr_base; 266 fhdr_v2->self = hdr_base;
267 fhdr_v2->dcd_ptr = hdr_base + offsetof(imx_header_v2_t, data); 267 fhdr_v2->dcd_ptr = hdr_base + offsetof(imx_header_v2_t, data);
268 fhdr_v2->boot_data_ptr = hdr_base 268 fhdr_v2->boot_data_ptr = hdr_base
269 + offsetof(imx_header_v2_t, boot_data); 269 + offsetof(imx_header_v2_t, boot_data);
270 hdr_v2->boot_data.start = entry_point - imximage_init_loadsize; 270 hdr_v2->boot_data.start = entry_point - imximage_init_loadsize;
271 271
272 fhdr_v2->csf = 0; 272 fhdr_v2->csf = 0;
273 273
274 header_size_ptr = &hdr_v2->boot_data.size; 274 header_size_ptr = &hdr_v2->boot_data.size;
275 csf_ptr = &fhdr_v2->csf; 275 csf_ptr = &fhdr_v2->csf;
276 } else { 276 } else {
277 imx_header_v2_t *next_hdr_v2; 277 imx_header_v2_t *next_hdr_v2;
278 flash_header_v2_t *next_fhdr_v2; 278 flash_header_v2_t *next_fhdr_v2;
279 279
280 if(imximage_csf_size != 0) { 280 if(imximage_csf_size != 0) {
281 fprintf(stderr, "Error: Header v2: SECURE_BOOT" 281 fprintf(stderr, "Error: Header v2: SECURE_BOOT"
282 "is only supported in DCD mode!"); 282 "is only supported in DCD mode!");
283 exit(EXIT_FAILURE); 283 exit(EXIT_FAILURE);
284 } 284 }
285 285
286 fhdr_v2->entry = imximage_iram_free_start + 286 fhdr_v2->entry = imximage_iram_free_start +
287 flash_offset + sizeof(flash_header_v2_t) + 287 flash_offset + sizeof(flash_header_v2_t) +
288 sizeof(boot_data_t); 288 sizeof(boot_data_t);
289 289
290 fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0; 290 fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
291 fhdr_v2->self = imximage_iram_free_start + flash_offset; 291 fhdr_v2->self = imximage_iram_free_start + flash_offset;
292 292
293 fhdr_v2->dcd_ptr = 0; 293 fhdr_v2->dcd_ptr = 0;
294 294
295 fhdr_v2->boot_data_ptr = fhdr_v2->self + 295 fhdr_v2->boot_data_ptr = fhdr_v2->self +
296 offsetof(imx_header_v2_t, boot_data); 296 offsetof(imx_header_v2_t, boot_data);
297 297
298 hdr_v2->boot_data.start = imximage_iram_free_start; 298 hdr_v2->boot_data.start = imximage_iram_free_start;
299 /* 299 /*
300 * The actural size of plugin image is "imximage_plugin_size + 300 * The actural size of plugin image is "imximage_plugin_size +
301 * sizeof(flash_header_v2_t) + sizeof(boot_data_t)", plus the 301 * sizeof(flash_header_v2_t) + sizeof(boot_data_t)", plus the
302 * flash_offset space.The ROM code only need to copy this size 302 * flash_offset space.The ROM code only need to copy this size
303 * to run the plugin code. However, later when copy the whole 303 * to run the plugin code. However, later when copy the whole
304 * U-Boot image to DDR, the ROM code use memcpy to copy the 304 * U-Boot image to DDR, the ROM code use memcpy to copy the
305 * first part of the image, and use the storage read function 305 * first part of the image, and use the storage read function
306 * to get the remaining part. This requires the dividing point 306 * to get the remaining part. This requires the dividing point
307 * must be multiple of storage sector size. Here we set the 307 * must be multiple of storage sector size. Here we set the
308 * first section to be 16KB for this purpose. 308 * first section to be 16KB for this purpose.
309 */ 309 */
310 hdr_v2->boot_data.size = MAX_PLUGIN_CODE_SIZE; 310 hdr_v2->boot_data.size = MAX_PLUGIN_CODE_SIZE;
311 311
312 /* Security feature are not supported */ 312 /* Security feature are not supported */
313 fhdr_v2->csf = 0; 313 fhdr_v2->csf = 0;
314 314
315 next_hdr_v2 = (imx_header_v2_t *)((char*)hdr_v2 + 315 next_hdr_v2 = (imx_header_v2_t *)((char*)hdr_v2 +
316 imximage_plugin_size); 316 imximage_plugin_size);
317 317
318 next_fhdr_v2 = &next_hdr_v2->fhdr; 318 next_fhdr_v2 = &next_hdr_v2->fhdr;
319 319
320 next_fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */ 320 next_fhdr_v2->header.tag = IVT_HEADER_TAG; /* 0xD1 */
321 next_fhdr_v2->header.length = 321 next_fhdr_v2->header.length =
322 cpu_to_be16(sizeof(flash_header_v2_t)); 322 cpu_to_be16(sizeof(flash_header_v2_t));
323 next_fhdr_v2->header.version = IVT_VERSION; /* 0x40 */ 323 next_fhdr_v2->header.version = IVT_VERSION; /* 0x40 */
324 324
325 next_fhdr_v2->entry = entry_point; 325 next_fhdr_v2->entry = entry_point;
326 hdr_base = entry_point - sizeof(struct imx_header); 326 hdr_base = entry_point - sizeof(struct imx_header);
327 next_fhdr_v2->reserved1 = next_fhdr_v2->reserved2 = 0; 327 next_fhdr_v2->reserved1 = next_fhdr_v2->reserved2 = 0;
328 next_fhdr_v2->self = hdr_base + imximage_plugin_size; 328 next_fhdr_v2->self = hdr_base + imximage_plugin_size;
329 329
330 next_fhdr_v2->dcd_ptr = 0; 330 next_fhdr_v2->dcd_ptr = 0;
331 next_fhdr_v2->boot_data_ptr = next_fhdr_v2->self + 331 next_fhdr_v2->boot_data_ptr = next_fhdr_v2->self +
332 offsetof(imx_header_v2_t, boot_data); 332 offsetof(imx_header_v2_t, boot_data);
333 333
334 next_hdr_v2->boot_data.start = hdr_base - flash_offset; 334 next_hdr_v2->boot_data.start = hdr_base - flash_offset;
335 335
336 header_size_ptr = &next_hdr_v2->boot_data.size; 336 header_size_ptr = &next_hdr_v2->boot_data.size;
337 337
338 next_hdr_v2->boot_data.plugin = 0; 338 next_hdr_v2->boot_data.plugin = 0;
339 339
340 next_fhdr_v2->csf = 0; 340 next_fhdr_v2->csf = 0;
341 } 341 }
342 } 342 }
343 343
344 static void set_hdr_func(void) 344 static void set_hdr_func(void)
345 { 345 {
346 switch (imximage_version) { 346 switch (imximage_version) {
347 case IMXIMAGE_V1: 347 case IMXIMAGE_V1:
348 set_dcd_val = set_dcd_val_v1; 348 set_dcd_val = set_dcd_val_v1;
349 set_dcd_rst = set_dcd_rst_v1; 349 set_dcd_rst = set_dcd_rst_v1;
350 set_imx_hdr = set_imx_hdr_v1; 350 set_imx_hdr = set_imx_hdr_v1;
351 max_dcd_entries = MAX_HW_CFG_SIZE_V1; 351 max_dcd_entries = MAX_HW_CFG_SIZE_V1;
352 break; 352 break;
353 case IMXIMAGE_V2: 353 case IMXIMAGE_V2:
354 set_dcd_val = set_dcd_val_v2; 354 set_dcd_val = set_dcd_val_v2;
355 set_dcd_rst = set_dcd_rst_v2; 355 set_dcd_rst = set_dcd_rst_v2;
356 set_imx_hdr = set_imx_hdr_v2; 356 set_imx_hdr = set_imx_hdr_v2;
357 max_dcd_entries = MAX_HW_CFG_SIZE_V2; 357 max_dcd_entries = MAX_HW_CFG_SIZE_V2;
358 break; 358 break;
359 default: 359 default:
360 err_imximage_version(imximage_version); 360 err_imximage_version(imximage_version);
361 break; 361 break;
362 } 362 }
363 } 363 }
364 364
365 static void print_hdr_v1(struct imx_header *imx_hdr) 365 static void print_hdr_v1(struct imx_header *imx_hdr)
366 { 366 {
367 imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1; 367 imx_header_v1_t *hdr_v1 = &imx_hdr->header.hdr_v1;
368 flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr; 368 flash_header_v1_t *fhdr_v1 = &hdr_v1->fhdr;
369 dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table; 369 dcd_v1_t *dcd_v1 = &hdr_v1->dcd_table;
370 uint32_t size, length, ver; 370 uint32_t size, length, ver;
371 371
372 size = dcd_v1->preamble.length; 372 size = dcd_v1->preamble.length;
373 if (size > (MAX_HW_CFG_SIZE_V1 * sizeof(dcd_type_addr_data_t))) { 373 if (size > (MAX_HW_CFG_SIZE_V1 * sizeof(dcd_type_addr_data_t))) {
374 fprintf(stderr, 374 fprintf(stderr,
375 "Error: Image corrupt DCD size %d exceed maximum %d\n", 375 "Error: Image corrupt DCD size %d exceed maximum %d\n",
376 (uint32_t)(size / sizeof(dcd_type_addr_data_t)), 376 (uint32_t)(size / sizeof(dcd_type_addr_data_t)),
377 MAX_HW_CFG_SIZE_V1); 377 MAX_HW_CFG_SIZE_V1);
378 exit(EXIT_FAILURE); 378 exit(EXIT_FAILURE);
379 } 379 }
380 380
381 length = dcd_v1->preamble.length / sizeof(dcd_type_addr_data_t); 381 length = dcd_v1->preamble.length / sizeof(dcd_type_addr_data_t);
382 ver = detect_imximage_version(imx_hdr); 382 ver = detect_imximage_version(imx_hdr);
383 383
384 printf("Image Type: Freescale IMX Boot Image\n"); 384 printf("Image Type: Freescale IMX Boot Image\n");
385 printf("Image Ver: %x", ver); 385 printf("Image Ver: %x", ver);
386 printf("%s\n", get_table_entry_name(imximage_versions, NULL, ver)); 386 printf("%s\n", get_table_entry_name(imximage_versions, NULL, ver));
387 printf("Data Size: "); 387 printf("Data Size: ");
388 genimg_print_size(dcd_v1->addr_data[length].type); 388 genimg_print_size(dcd_v1->addr_data[length].type);
389 printf("Load Address: %08x\n", (uint32_t)fhdr_v1->app_dest_ptr); 389 printf("Load Address: %08x\n", (uint32_t)fhdr_v1->app_dest_ptr);
390 printf("Entry Point: %08x\n", (uint32_t)fhdr_v1->app_code_jump_vector); 390 printf("Entry Point: %08x\n", (uint32_t)fhdr_v1->app_code_jump_vector);
391 } 391 }
392 392
393 static void print_hdr_v2(struct imx_header *imx_hdr) 393 static void print_hdr_v2(struct imx_header *imx_hdr)
394 { 394 {
395 imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2; 395 imx_header_v2_t *hdr_v2 = &imx_hdr->header.hdr_v2;
396 flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr; 396 flash_header_v2_t *fhdr_v2 = &hdr_v2->fhdr;
397 dcd_v2_t *dcd_v2 = &hdr_v2->data.dcd_table; 397 dcd_v2_t *dcd_v2 = &hdr_v2->data.dcd_table;
398 uint32_t size, version, plugin; 398 uint32_t size, version, plugin;
399 399
400 plugin = hdr_v2->boot_data.plugin; 400 plugin = hdr_v2->boot_data.plugin;
401 if (!plugin) { 401 if (!plugin) {
402 size = be16_to_cpu(dcd_v2->header.length) - 8; 402 size = be16_to_cpu(dcd_v2->header.length) - 8;
403 if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t))) { 403 if (size > (MAX_HW_CFG_SIZE_V2 * sizeof(dcd_addr_data_t))) {
404 fprintf(stderr, 404 fprintf(stderr,
405 "Error: Image corrupt DCD size %d exceed maximum %d\n", 405 "Error: Image corrupt DCD size %d exceed maximum %d\n",
406 (uint32_t)(size / sizeof(dcd_addr_data_t)), 406 (uint32_t)(size / sizeof(dcd_addr_data_t)),
407 MAX_HW_CFG_SIZE_V2); 407 MAX_HW_CFG_SIZE_V2);
408 exit(EXIT_FAILURE); 408 exit(EXIT_FAILURE);
409 } 409 }
410 } 410 }
411 411
412 version = detect_imximage_version(imx_hdr); 412 version = detect_imximage_version(imx_hdr);
413 413
414 printf("Image Type: Freescale IMX Boot Image\n"); 414 printf("Image Type: Freescale IMX Boot Image\n");
415 printf("Image Ver: %x", version); 415 printf("Image Ver: %x", version);
416 printf("%s\n", get_table_entry_name(imximage_versions, NULL, version)); 416 printf("%s\n", get_table_entry_name(imximage_versions, NULL, version));
417 printf("Mode: %s\n", plugin ? "PLUGIN" : "DCD"); 417 printf("Mode: %s\n", plugin ? "PLUGIN" : "DCD");
418 if (!plugin) { 418 if (!plugin) {
419 printf("Data Size: "); 419 printf("Data Size: ");
420 genimg_print_size(hdr_v2->boot_data.size); 420 genimg_print_size(hdr_v2->boot_data.size);
421 printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr); 421 printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr);
422 printf("Entry Point: %08x\n", (uint32_t)fhdr_v2->entry); 422 printf("Entry Point: %08x\n", (uint32_t)fhdr_v2->entry);
423 if (fhdr_v2->csf && (imximage_ivt_offset != UNDEFINED) && 423 if (fhdr_v2->csf && (imximage_ivt_offset != UNDEFINED) &&
424 (imximage_csf_size != UNDEFINED)) { 424 (imximage_csf_size != UNDEFINED)) {
425 printf("HAB Blocks: %08x %08x %08x\n", 425 printf("HAB Blocks: %08x %08x %08x\n",
426 (uint32_t)fhdr_v2->self, 0, 426 (uint32_t)fhdr_v2->self, 0,
427 hdr_v2->boot_data.size - imximage_ivt_offset - 427 hdr_v2->boot_data.size - imximage_ivt_offset -
428 imximage_csf_size); 428 imximage_csf_size);
429 } 429 }
430 } else { 430 } else {
431 imx_header_v2_t *next_hdr_v2; 431 imx_header_v2_t *next_hdr_v2;
432 flash_header_v2_t *next_fhdr_v2; 432 flash_header_v2_t *next_fhdr_v2;
433 433
434 /*First Header*/ 434 /*First Header*/
435 printf("Plugin Data Size: "); 435 printf("Plugin Data Size: ");
436 genimg_print_size(hdr_v2->boot_data.size); 436 genimg_print_size(hdr_v2->boot_data.size);
437 printf("Plugin Code Size: "); 437 printf("Plugin Code Size: ");
438 genimg_print_size(imximage_plugin_size); 438 genimg_print_size(imximage_plugin_size);
439 printf("Plugin Load Address: %08x\n", hdr_v2->boot_data.start); 439 printf("Plugin Load Address: %08x\n", hdr_v2->boot_data.start);
440 printf("Plugin Entry Point: %08x\n", 440 printf("Plugin Entry Point: %08x\n",
441 (uint32_t)fhdr_v2->entry); 441 (uint32_t)fhdr_v2->entry);
442 442
443 /*Second Header*/ 443 /*Second Header*/
444 next_hdr_v2 = (imx_header_v2_t *)((char*)hdr_v2 + 444 next_hdr_v2 = (imx_header_v2_t *)((char*)hdr_v2 +
445 imximage_plugin_size); 445 imximage_plugin_size);
446 next_fhdr_v2 = &next_hdr_v2->fhdr; 446 next_fhdr_v2 = &next_hdr_v2->fhdr;
447 printf("U-Boot Data Size: "); 447 printf("U-Boot Data Size: ");
448 genimg_print_size(next_hdr_v2->boot_data.size); 448 genimg_print_size(next_hdr_v2->boot_data.size);
449 printf("U-Boot Load Address: %08x\n", next_hdr_v2->boot_data.start); 449 printf("U-Boot Load Address: %08x\n", next_hdr_v2->boot_data.start);
450 printf("U-Boot Entry Point: %08x\n", 450 printf("U-Boot Entry Point: %08x\n",
451 (uint32_t)next_fhdr_v2->entry); 451 (uint32_t)next_fhdr_v2->entry);
452 } 452 }
453 } 453 }
454 454
455 #ifdef CONFIG_USE_PLUGIN 455 #ifdef CONFIG_USE_PLUGIN
456 static void copy_plugin_code(struct imx_header *imxhdr, char *plugin_file) 456 static void copy_plugin_code(struct imx_header *imxhdr, char *plugin_file)
457 { 457 {
458 int ifd = -1; 458 int ifd = -1;
459 struct stat sbuf; 459 struct stat sbuf;
460 char *plugin_buf = imxhdr->header.hdr_v2.data.plugin_code; 460 char *plugin_buf = imxhdr->header.hdr_v2.data.plugin_code;
461 char *ptr; 461 char *ptr;
462 462
463 ifd = open(plugin_file, O_RDONLY|O_BINARY); 463 ifd = open(plugin_file, O_RDONLY|O_BINARY);
464 if (fstat(ifd, &sbuf) < 0) { 464 if (fstat(ifd, &sbuf) < 0) {
465 fprintf(stderr, "Can't stat %s: %s\n", 465 fprintf(stderr, "Can't stat %s: %s\n",
466 plugin_file, 466 plugin_file,
467 strerror(errno)); 467 strerror(errno));
468 exit(EXIT_FAILURE); 468 exit(EXIT_FAILURE);
469 } 469 }
470 470
471 ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0); 471 ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0);
472 if (ptr == MAP_FAILED) { 472 if (ptr == MAP_FAILED) {
473 fprintf(stderr, "Can't read %s: %s\n", 473 fprintf(stderr, "Can't read %s: %s\n",
474 plugin_file, 474 plugin_file,
475 strerror(errno)); 475 strerror(errno));
476 exit(EXIT_FAILURE); 476 exit(EXIT_FAILURE);
477 } 477 }
478 478
479 if (sbuf.st_size > MAX_PLUGIN_CODE_SIZE) { 479 if (sbuf.st_size > MAX_PLUGIN_CODE_SIZE) {
480 printf("plugin binary size too large\n"); 480 printf("plugin binary size too large\n");
481 exit(EXIT_FAILURE); 481 exit(EXIT_FAILURE);
482 } 482 }
483 483
484 memcpy(plugin_buf, ptr, sbuf.st_size); 484 memcpy(plugin_buf, ptr, sbuf.st_size);
485 imximage_plugin_size = sbuf.st_size; 485 imximage_plugin_size = sbuf.st_size;
486 486
487 (void) munmap((void *)ptr, sbuf.st_size); 487 (void) munmap((void *)ptr, sbuf.st_size);
488 (void) close(ifd); 488 (void) close(ifd);
489 489
490 imxhdr->header.hdr_v2.boot_data.plugin = 1; 490 imxhdr->header.hdr_v2.boot_data.plugin = 1;
491 } 491 }
492 #endif 492 #endif
493 493
494 static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token, 494 static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
495 char *name, int lineno, int fld, int dcd_len) 495 char *name, int lineno, int fld, int dcd_len)
496 { 496 {
497 int value; 497 int value;
498 static int cmd_ver_first = ~0; 498 static int cmd_ver_first = ~0;
499 499
500 switch (cmd) { 500 switch (cmd) {
501 case CMD_IMAGE_VERSION: 501 case CMD_IMAGE_VERSION:
502 imximage_version = get_cfg_value(token, name, lineno); 502 imximage_version = get_cfg_value(token, name, lineno);
503 if (cmd_ver_first == 0) { 503 if (cmd_ver_first == 0) {
504 fprintf(stderr, "Error: %s[%d] - IMAGE_VERSION " 504 fprintf(stderr, "Error: %s[%d] - IMAGE_VERSION "
505 "command need be the first before other " 505 "command need be the first before other "
506 "valid command in the file\n", name, lineno); 506 "valid command in the file\n", name, lineno);
507 exit(EXIT_FAILURE); 507 exit(EXIT_FAILURE);
508 } 508 }
509 cmd_ver_first = 1; 509 cmd_ver_first = 1;
510 set_hdr_func(); 510 set_hdr_func();
511 break; 511 break;
512 case CMD_BOOT_FROM: 512 case CMD_BOOT_FROM:
513 imximage_ivt_offset = get_table_entry_id(imximage_boot_offset, 513 imximage_ivt_offset = get_table_entry_id(imximage_boot_offset,
514 "imximage boot option", token); 514 "imximage boot option", token);
515 if (imximage_ivt_offset == -1) { 515 if (imximage_ivt_offset == -1) {
516 fprintf(stderr, "Error: %s[%d] -Invalid boot device" 516 fprintf(stderr, "Error: %s[%d] -Invalid boot device"
517 "(%s)\n", name, lineno, token); 517 "(%s)\n", name, lineno, token);
518 exit(EXIT_FAILURE); 518 exit(EXIT_FAILURE);
519 } 519 }
520 520
521 imximage_init_loadsize = 521 imximage_init_loadsize =
522 get_table_entry_id(imximage_boot_loadsize, 522 get_table_entry_id(imximage_boot_loadsize,
523 "imximage boot option", token); 523 "imximage boot option", token);
524 524
525 if (imximage_init_loadsize == -1) { 525 if (imximage_init_loadsize == -1) {
526 fprintf(stderr, 526 fprintf(stderr,
527 "Error: %s[%d] -Invalid boot device(%s)\n", 527 "Error: %s[%d] -Invalid boot device(%s)\n",
528 name, lineno, token); 528 name, lineno, token);
529 exit(EXIT_FAILURE); 529 exit(EXIT_FAILURE);
530 } 530 }
531 531
532 /* 532 /*
533 * The SOC loads from the storage starting at address 0 533 * The SOC loads from the storage starting at address 0
534 * then ensures that the load size contains the offset 534 * then ensures that the load size contains the offset
535 */ 535 */
536 if (imximage_init_loadsize < imximage_ivt_offset) 536 if (imximage_init_loadsize < imximage_ivt_offset)
537 imximage_init_loadsize = imximage_ivt_offset; 537 imximage_init_loadsize = imximage_ivt_offset;
538 if (unlikely(cmd_ver_first != 1)) 538 if (unlikely(cmd_ver_first != 1))
539 cmd_ver_first = 0; 539 cmd_ver_first = 0;
540 break; 540 break;
541 case CMD_BOOT_OFFSET: 541 case CMD_BOOT_OFFSET:
542 imximage_ivt_offset = get_cfg_value(token, name, lineno); 542 imximage_ivt_offset = get_cfg_value(token, name, lineno);
543 if (unlikely(cmd_ver_first != 1)) 543 if (unlikely(cmd_ver_first != 1))
544 cmd_ver_first = 0; 544 cmd_ver_first = 0;
545 break; 545 break;
546 case CMD_DATA: 546 case CMD_DATA:
547 value = get_cfg_value(token, name, lineno); 547 value = get_cfg_value(token, name, lineno);
548 (*set_dcd_val)(imxhdr, name, lineno, fld, value, dcd_len); 548 (*set_dcd_val)(imxhdr, name, lineno, fld, value, dcd_len);
549 if (unlikely(cmd_ver_first != 1)) 549 if (unlikely(cmd_ver_first != 1))
550 cmd_ver_first = 0; 550 cmd_ver_first = 0;
551 break; 551 break;
552 case CMD_CSF: 552 case CMD_CSF:
553 if (imximage_version != 2) { 553 if (imximage_version != 2) {
554 fprintf(stderr, 554 fprintf(stderr,
555 "Error: %s[%d] - CSF only supported for VERSION 2(%s)\n", 555 "Error: %s[%d] - CSF only supported for VERSION 2(%s)\n",
556 name, lineno, token); 556 name, lineno, token);
557 exit(EXIT_FAILURE); 557 exit(EXIT_FAILURE);
558 } 558 }
559 imximage_csf_size = get_cfg_value(token, name, lineno); 559 imximage_csf_size = get_cfg_value(token, name, lineno);
560 if (unlikely(cmd_ver_first != 1)) 560 if (unlikely(cmd_ver_first != 1))
561 cmd_ver_first = 0; 561 cmd_ver_first = 0;
562 break; 562 break;
563 #ifdef CONFIG_USE_PLUGIN 563 #ifdef CONFIG_USE_PLUGIN
564 case CMD_PLUGIN: 564 case CMD_PLUGIN:
565 copy_plugin_code(imxhdr, token); 565 copy_plugin_code(imxhdr, token);
566 break; 566 break;
567 #endif 567 #endif
568 } 568 }
569 } 569 }
570 570
571 static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd, 571 static void parse_cfg_fld(struct imx_header *imxhdr, int32_t *cmd,
572 char *token, char *name, int lineno, int fld, int *dcd_len) 572 char *token, char *name, int lineno, int fld, int *dcd_len)
573 { 573 {
574 int value; 574 int value;
575 575
576 switch (fld) { 576 switch (fld) {
577 case CFG_COMMAND: 577 case CFG_COMMAND:
578 *cmd = get_table_entry_id(imximage_cmds, 578 *cmd = get_table_entry_id(imximage_cmds,
579 "imximage commands", token); 579 "imximage commands", token);
580 if (*cmd < 0) { 580 if (*cmd < 0) {
581 fprintf(stderr, "Error: %s[%d] - Invalid command" 581 fprintf(stderr, "Error: %s[%d] - Invalid command"
582 "(%s)\n", name, lineno, token); 582 "(%s)\n", name, lineno, token);
583 exit(EXIT_FAILURE); 583 exit(EXIT_FAILURE);
584 } 584 }
585 break; 585 break;
586 case CFG_REG_SIZE: 586 case CFG_REG_SIZE:
587 parse_cfg_cmd(imxhdr, *cmd, token, name, lineno, fld, *dcd_len); 587 parse_cfg_cmd(imxhdr, *cmd, token, name, lineno, fld, *dcd_len);
588 break; 588 break;
589 case CFG_REG_ADDRESS: 589 case CFG_REG_ADDRESS:
590 case CFG_REG_VALUE: 590 case CFG_REG_VALUE:
591 switch (*cmd) { 591 switch (*cmd) {
592 case CMD_DATA: 592 case CMD_DATA:
593 value = get_cfg_value(token, name, lineno); 593 value = get_cfg_value(token, name, lineno);
594 (*set_dcd_val)(imxhdr, name, lineno, fld, value, 594 (*set_dcd_val)(imxhdr, name, lineno, fld, value,
595 *dcd_len); 595 *dcd_len);
596 596
597 if (fld == CFG_REG_VALUE) { 597 if (fld == CFG_REG_VALUE) {
598 (*dcd_len)++; 598 (*dcd_len)++;
599 if (*dcd_len > max_dcd_entries) { 599 if (*dcd_len > max_dcd_entries) {
600 fprintf(stderr, "Error: %s[%d] -" 600 fprintf(stderr, "Error: %s[%d] -"
601 "DCD table exceeds maximum\ 601 "DCD table exceeds maximum\
602 size(%d)\n", 602 size(%d)\n",
603 name, lineno, max_dcd_entries); 603 name, lineno, max_dcd_entries);
604 exit(EXIT_FAILURE); 604 exit(EXIT_FAILURE);
605 } 605 }
606 } 606 }
607 break; 607 break;
608 #ifdef CONFIG_USE_PLUGIN 608 #ifdef CONFIG_USE_PLUGIN
609 case CMD_PLUGIN: 609 case CMD_PLUGIN:
610 value = get_cfg_value(token, name, lineno); 610 value = get_cfg_value(token, name, lineno);
611 imximage_iram_free_start = value; 611 imximage_iram_free_start = value;
612 break; 612 break;
613 #endif 613 #endif
614 default: 614 default:
615 return; 615 return;
616 } 616 }
617 break; 617 break;
618 default: 618 default:
619 break; 619 break;
620 } 620 }
621 } 621 }
622 static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name) 622 static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
623 { 623 {
624 FILE *fd = NULL; 624 FILE *fd = NULL;
625 char *line = NULL; 625 char *line = NULL;
626 char *token, *saveptr1, *saveptr2; 626 char *token, *saveptr1, *saveptr2;
627 int lineno = 0; 627 int lineno = 0;
628 int fld; 628 int fld;
629 size_t len; 629 size_t len;
630 int dcd_len = 0; 630 int dcd_len = 0;
631 int32_t cmd; 631 int32_t cmd;
632 632
633 fd = fopen(name, "r"); 633 fd = fopen(name, "r");
634 if (fd == 0) { 634 if (fd == 0) {
635 fprintf(stderr, "Error: %s - Can't open DCD file\n", name); 635 fprintf(stderr, "Error: %s - Can't open DCD file\n", name);
636 exit(EXIT_FAILURE); 636 exit(EXIT_FAILURE);
637 } 637 }
638 638
639 /* 639 /*
640 * Very simple parsing, line starting with # are comments 640 * Very simple parsing, line starting with # are comments
641 * and are dropped 641 * and are dropped
642 */ 642 */
643 while ((getline(&line, &len, fd)) > 0) { 643 while ((getline(&line, &len, fd)) > 0) {
644 lineno++; 644 lineno++;
645 645
646 token = strtok_r(line, "\r\n", &saveptr1); 646 token = strtok_r(line, "\r\n", &saveptr1);
647 if (token == NULL) 647 if (token == NULL)
648 continue; 648 continue;
649 649
650 /* Check inside the single line */ 650 /* Check inside the single line */
651 for (fld = CFG_COMMAND, cmd = CMD_INVALID, 651 for (fld = CFG_COMMAND, cmd = CMD_INVALID,
652 line = token; ; line = NULL, fld++) { 652 line = token; ; line = NULL, fld++) {
653 token = strtok_r(line, " \t", &saveptr2); 653 token = strtok_r(line, " \t", &saveptr2);
654 if (token == NULL) 654 if (token == NULL)
655 break; 655 break;
656 656
657 /* Drop all text starting with '#' as comments */ 657 /* Drop all text starting with '#' as comments */
658 if (token[0] == '#') 658 if (token[0] == '#')
659 break; 659 break;
660 660
661 parse_cfg_fld(imxhdr, &cmd, token, name, 661 parse_cfg_fld(imxhdr, &cmd, token, name,
662 lineno, fld, &dcd_len); 662 lineno, fld, &dcd_len);
663 } 663 }
664 664
665 } 665 }
666 666
667 (*set_dcd_rst)(imxhdr, dcd_len, name, lineno); 667 (*set_dcd_rst)(imxhdr, dcd_len, name, lineno);
668 fclose(fd); 668 fclose(fd);
669 669
670 /* Exit if there is no BOOT_FROM field specifying the flash_offset */ 670 /* Exit if there is no BOOT_FROM field specifying the flash_offset */
671 if (imximage_ivt_offset == FLASH_OFFSET_UNDEFINED) { 671 if (imximage_ivt_offset == FLASH_OFFSET_UNDEFINED) {
672 fprintf(stderr, "Error: No BOOT_FROM tag in %s\n", name); 672 fprintf(stderr, "Error: No BOOT_FROM tag in %s\n", name);
673 exit(EXIT_FAILURE); 673 exit(EXIT_FAILURE);
674 } 674 }
675 return dcd_len; 675 return dcd_len;
676 } 676 }
677 677
678 678
679 static int imximage_check_image_types(uint8_t type) 679 static int imximage_check_image_types(uint8_t type)
680 { 680 {
681 if (type == IH_TYPE_IMXIMAGE) 681 if (type == IH_TYPE_IMXIMAGE)
682 return EXIT_SUCCESS; 682 return EXIT_SUCCESS;
683 else 683 else
684 return EXIT_FAILURE; 684 return EXIT_FAILURE;
685 } 685 }
686 686
687 static int imximage_verify_header(unsigned char *ptr, int image_size, 687 static int imximage_verify_header(unsigned char *ptr, int image_size,
688 struct image_tool_params *params) 688 struct image_tool_params *params)
689 { 689 {
690 struct imx_header *imx_hdr = (struct imx_header *) ptr; 690 struct imx_header *imx_hdr = (struct imx_header *) ptr;
691 691
692 if (detect_imximage_version(imx_hdr) == IMXIMAGE_VER_INVALID) 692 if (detect_imximage_version(imx_hdr) == IMXIMAGE_VER_INVALID)
693 return -FDT_ERR_BADSTRUCTURE; 693 return -FDT_ERR_BADSTRUCTURE;
694 694
695 return 0; 695 return 0;
696 } 696 }
697 697
698 static void imximage_print_header(const void *ptr) 698 static void imximage_print_header(const void *ptr)
699 { 699 {
700 struct imx_header *imx_hdr = (struct imx_header *) ptr; 700 struct imx_header *imx_hdr = (struct imx_header *) ptr;
701 uint32_t version = detect_imximage_version(imx_hdr); 701 uint32_t version = detect_imximage_version(imx_hdr);
702 702
703 switch (version) { 703 switch (version) {
704 case IMXIMAGE_V1: 704 case IMXIMAGE_V1:
705 print_hdr_v1(imx_hdr); 705 print_hdr_v1(imx_hdr);
706 break; 706 break;
707 case IMXIMAGE_V2: 707 case IMXIMAGE_V2:
708 print_hdr_v2(imx_hdr); 708 print_hdr_v2(imx_hdr);
709 break; 709 break;
710 default: 710 default:
711 err_imximage_version(version); 711 err_imximage_version(version);
712 break; 712 break;
713 } 713 }
714 } 714 }
715 715
716 static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd, 716 static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
717 struct image_tool_params *params) 717 struct image_tool_params *params)
718 { 718 {
719 struct imx_header *imxhdr = (struct imx_header *)ptr; 719 struct imx_header *imxhdr = (struct imx_header *)ptr;
720 uint32_t dcd_len; 720 uint32_t dcd_len;
721 721
722 /* 722 /*
723 * In order to not change the old imx cfg file 723 * In order to not change the old imx cfg file
724 * by adding VERSION command into it, here need 724 * by adding VERSION command into it, here need
725 * set up function ptr group to V1 by default. 725 * set up function ptr group to V1 by default.
726 */ 726 */
727 imximage_version = IMXIMAGE_V1; 727 imximage_version = IMXIMAGE_V1;
728 /* Be able to detect if the cfg file has no BOOT_FROM tag */ 728 /* Be able to detect if the cfg file has no BOOT_FROM tag */
729 imximage_ivt_offset = FLASH_OFFSET_UNDEFINED; 729 imximage_ivt_offset = FLASH_OFFSET_UNDEFINED;
730 imximage_csf_size = 0; 730 imximage_csf_size = 0;
731 set_hdr_func(); 731 set_hdr_func();
732 732
733 /* Parse dcd configuration file */ 733 /* Parse dcd configuration file */
734 dcd_len = parse_cfg_file(imxhdr, params->imagename); 734 dcd_len = parse_cfg_file(imxhdr, params->imagename);
735 735
736 if (imximage_version == IMXIMAGE_V2) { 736 if (imximage_version == IMXIMAGE_V2) {
737 if (imximage_init_loadsize < imximage_ivt_offset + 737 if (imximage_init_loadsize < imximage_ivt_offset +
738 sizeof(imx_header_v2_t)) 738 sizeof(imx_header_v2_t))
739 imximage_init_loadsize = imximage_ivt_offset + 739 imximage_init_loadsize = imximage_ivt_offset +
740 sizeof(imx_header_v2_t); 740 sizeof(imx_header_v2_t);
741 } 741 }
742 742
743 /* Set the imx header */ 743 /* Set the imx header */
744 (*set_imx_hdr)(imxhdr, dcd_len, params->ep, imximage_ivt_offset); 744 (*set_imx_hdr)(imxhdr, dcd_len, params->ep, imximage_ivt_offset);
745 745
746 /* 746 /*
747 * ROM bug alert 747 * ROM bug alert
748 * 748 *
749 * MX53 only loads 512 byte multiples in case of SD boot. 749 * MX53 only loads 512 byte multiples in case of SD boot.
750 * MX53 only loads NAND page multiples in case of NAND boot and 750 * MX53 only loads NAND page multiples in case of NAND boot and
751 * supports up to 4096 byte large pages, thus align to 4096. 751 * supports up to 4096 byte large pages, thus align to 4096.
752 * 752 *
753 * The remaining fraction of a block bytes would not be loaded! 753 * The remaining fraction of a block bytes would not be loaded!
754 */ 754 */
755 *header_size_ptr = ROUND(sbuf->st_size, 4096); 755 *header_size_ptr = ROUND((sbuf->st_size + imximage_ivt_offset), 4096);
756 756
757 if (csf_ptr && imximage_csf_size) { 757 if (csf_ptr && imximage_csf_size) {
758 *csf_ptr = params->ep - imximage_init_loadsize + 758 *csf_ptr = params->ep - imximage_init_loadsize +
759 *header_size_ptr; 759 *header_size_ptr;
760 *header_size_ptr += imximage_csf_size; 760 *header_size_ptr += imximage_csf_size;
761 } 761 }
762 } 762 }
763 763
764 int imximage_check_params(struct image_tool_params *params) 764 int imximage_check_params(struct image_tool_params *params)
765 { 765 {
766 if (!params) 766 if (!params)
767 return CFG_INVALID; 767 return CFG_INVALID;
768 if (!strlen(params->imagename)) { 768 if (!strlen(params->imagename)) {
769 fprintf(stderr, "Error: %s - Configuration file not specified, " 769 fprintf(stderr, "Error: %s - Configuration file not specified, "
770 "it is needed for imximage generation\n", 770 "it is needed for imximage generation\n",
771 params->cmdname); 771 params->cmdname);
772 return CFG_INVALID; 772 return CFG_INVALID;
773 } 773 }
774 /* 774 /*
775 * Check parameters: 775 * Check parameters:
776 * XIP is not allowed and verify that incompatible 776 * XIP is not allowed and verify that incompatible
777 * parameters are not sent at the same time 777 * parameters are not sent at the same time
778 * For example, if list is required a data image must not be provided 778 * For example, if list is required a data image must not be provided
779 */ 779 */
780 return (params->dflag && (params->fflag || params->lflag)) || 780 return (params->dflag && (params->fflag || params->lflag)) ||
781 (params->fflag && (params->dflag || params->lflag)) || 781 (params->fflag && (params->dflag || params->lflag)) ||
782 (params->lflag && (params->dflag || params->fflag)) || 782 (params->lflag && (params->dflag || params->fflag)) ||
783 (params->xflag) || !(strlen(params->imagename)); 783 (params->xflag) || !(strlen(params->imagename));
784 } 784 }
785 785
786 static int imximage_generate(struct image_tool_params *params, 786 static int imximage_generate(struct image_tool_params *params,
787 struct image_type_params *tparams) 787 struct image_type_params *tparams)
788 { 788 {
789 struct imx_header *imxhdr; 789 struct imx_header *imxhdr;
790 size_t alloc_len; 790 size_t alloc_len;
791 struct stat sbuf; 791 struct stat sbuf;
792 char *datafile = params->datafile; 792 char *datafile = params->datafile;
793 uint32_t pad_len; 793 uint32_t pad_len;
794 794
795 memset(&imximage_header, 0, sizeof(imximage_header)); 795 memset(&imximage_header, 0, sizeof(imximage_header));
796 796
797 /* 797 /*
798 * In order to not change the old imx cfg file 798 * In order to not change the old imx cfg file
799 * by adding VERSION command into it, here need 799 * by adding VERSION command into it, here need
800 * set up function ptr group to V1 by default. 800 * set up function ptr group to V1 by default.
801 */ 801 */
802 imximage_version = IMXIMAGE_V1; 802 imximage_version = IMXIMAGE_V1;
803 /* Be able to detect if the cfg file has no BOOT_FROM tag */ 803 /* Be able to detect if the cfg file has no BOOT_FROM tag */
804 imximage_ivt_offset = FLASH_OFFSET_UNDEFINED; 804 imximage_ivt_offset = FLASH_OFFSET_UNDEFINED;
805 imximage_csf_size = 0; 805 imximage_csf_size = 0;
806 set_hdr_func(); 806 set_hdr_func();
807 807
808 /* Parse dcd configuration file */ 808 /* Parse dcd configuration file */
809 parse_cfg_file(&imximage_header, params->imagename); 809 parse_cfg_file(&imximage_header, params->imagename);
810 810
811 /* TODO: check i.MX image V1 handling, for now use 'old' style */ 811 /* TODO: check i.MX image V1 handling, for now use 'old' style */
812 if (imximage_version == IMXIMAGE_V1) { 812 if (imximage_version == IMXIMAGE_V1) {
813 alloc_len = 4096; 813 alloc_len = 4096;
814 } else { 814 } else {
815 if (imximage_init_loadsize < imximage_ivt_offset + 815 if (imximage_init_loadsize < imximage_ivt_offset +
816 sizeof(imx_header_v2_t)) 816 sizeof(imx_header_v2_t))
817 imximage_init_loadsize = imximage_ivt_offset + 817 imximage_init_loadsize = imximage_ivt_offset +
818 sizeof(imx_header_v2_t); 818 sizeof(imx_header_v2_t);
819 alloc_len = imximage_init_loadsize - imximage_ivt_offset; 819 alloc_len = imximage_init_loadsize - imximage_ivt_offset;
820 } 820 }
821 821
822 if (alloc_len < sizeof(struct imx_header)) { 822 if (alloc_len < sizeof(struct imx_header)) {
823 fprintf(stderr, "%s: header error\n", 823 fprintf(stderr, "%s: header error\n",
824 params->cmdname); 824 params->cmdname);
825 exit(EXIT_FAILURE); 825 exit(EXIT_FAILURE);
826 } 826 }
827 827
828 imxhdr = malloc(alloc_len); 828 imxhdr = malloc(alloc_len);
829 829
830 if (!imxhdr) { 830 if (!imxhdr) {
831 fprintf(stderr, "%s: malloc return failure: %s\n", 831 fprintf(stderr, "%s: malloc return failure: %s\n",
832 params->cmdname, strerror(errno)); 832 params->cmdname, strerror(errno));
833 exit(EXIT_FAILURE); 833 exit(EXIT_FAILURE);
834 } 834 }
835 835
836 memset(imxhdr, 0, alloc_len); 836 memset(imxhdr, 0, alloc_len);
837 837
838 tparams->header_size = alloc_len; 838 tparams->header_size = alloc_len;
839 tparams->hdr = imxhdr; 839 tparams->hdr = imxhdr;
840 840
841 /* determine data image file length */ 841 /* determine data image file length */
842 842
843 if (stat(datafile, &sbuf) < 0) { 843 if (stat(datafile, &sbuf) < 0) {
844 fprintf(stderr, "%s: Can't stat %s: %s\n", 844 fprintf(stderr, "%s: Can't stat %s: %s\n",
845 params->cmdname, datafile, strerror(errno)); 845 params->cmdname, datafile, strerror(errno));
846 exit(EXIT_FAILURE); 846 exit(EXIT_FAILURE);
847 } 847 }
848 848
849 pad_len = ROUND(sbuf.st_size, 4096) - sbuf.st_size; 849 pad_len = ROUND(sbuf.st_size, 4096) - sbuf.st_size;
850 850
851 /* TODO: check i.MX image V1 handling, for now use 'old' style */ 851 /* TODO: check i.MX image V1 handling, for now use 'old' style */
852 if (imximage_version == IMXIMAGE_V1) 852 if (imximage_version == IMXIMAGE_V1)
853 return 0; 853 return 0;
854 else 854 else
855 return pad_len; 855 return pad_len;
856 } 856 }
857 857
858 858
859 /* 859 /*
860 * imximage parameters 860 * imximage parameters
861 */ 861 */
862 static struct image_type_params imximage_params = { 862 static struct image_type_params imximage_params = {
863 .name = "Freescale i.MX Boot Image support", 863 .name = "Freescale i.MX Boot Image support",
864 .header_size = 0, 864 .header_size = 0,
865 .hdr = NULL, 865 .hdr = NULL,
866 .check_image_type = imximage_check_image_types, 866 .check_image_type = imximage_check_image_types,
867 .verify_header = imximage_verify_header, 867 .verify_header = imximage_verify_header,
868 .print_header = imximage_print_header, 868 .print_header = imximage_print_header,
869 .set_header = imximage_set_header, 869 .set_header = imximage_set_header,
870 .check_params = imximage_check_params, 870 .check_params = imximage_check_params,
871 .vrec_header = imximage_generate, 871 .vrec_header = imximage_generate,
872 }; 872 };
873 873
874 void init_imx_image_type(void) 874 void init_imx_image_type(void)
875 { 875 {
876 register_image_type(&imximage_params); 876 register_image_type(&imximage_params);
877 } 877 }
878 878