blob: 8e06f4dc5ea1822c04b9675e02d576ad5f94faae [file] [log] [blame]
Anton Staafc6244272011-02-24 10:17:50 -08001/**
Peer Chen6f2cbc72012-03-13 11:12:39 +08002 * Copyright (c) 2012 NVIDIA Corporation. All rights reserved.
Anton Staafc6244272011-02-24 10:17:50 -08003 *
4 * See file CREDITS for list of people who contributed to this
5 * project.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23#include "cbootimage.h"
Anton Staafc6244272011-02-24 10:17:50 -080024#include "data_layout.h"
25#include "context.h"
Anton Staafe517a4f2011-03-14 12:28:06 -070026#include "parse.h"
Peer Chen6f2cbc72012-03-13 11:12:39 +080027#include "t20/nvboot_bct_t20.h"
Anton Staafc6244272011-02-24 10:17:50 -080028#include <string.h>
29
30int enable_debug = 0;
31
Peer Chen6f2cbc72012-03-13 11:12:39 +080032bct_parse_interface *g_bct_parse_interf;
33
Anton Staafc6244272011-02-24 10:17:50 -080034typedef struct {
Peer Chen6f2cbc72012-03-13 11:12:39 +080035 parse_token id;
Anton Staafc6244272011-02-24 10:17:50 -080036 char const * message;
37} value_data;
38
39static value_data const values[] = {
Peer Chen6f2cbc72012-03-13 11:12:39 +080040 { token_boot_data_version, "Version = 0x%08x;\n" },
41 { token_block_size_log2, "BlockSize = 0x%08x;\n" },
42 { token_page_size_log2, "PageSize = 0x%08x;\n" },
43 { token_partition_size, "PartitionSize = 0x%08x;\n" },
44 { token_bootloader_used, "# Bootloader used = %d;\n" },
45 { token_bootloaders_max, "# Bootloaders max = %d;\n" },
46 { token_bct_size, "# BCT size = %d;\n" },
47 { token_hash_size, "# Hash size = %d;\n" },
48 { token_crypto_offset, "# Crypto offset = %d;\n" },
49 { token_crypto_length, "# Crypto length = %d;\n" },
50 { token_max_bct_search_blks, "# Max BCT search blocks = %d;\n" },
Anton Staafc6244272011-02-24 10:17:50 -080051};
52
53static value_data const bl_values[] = {
Peer Chen6f2cbc72012-03-13 11:12:39 +080054 { token_bl_version, "Version = 0x%08x;\n" },
55 { token_bl_start_blk, "Start block = %d;\n" },
56 { token_bl_start_page, "Start page = %d;\n" },
57 { token_bl_length, "Length = %d;\n" },
58 { token_bl_load_addr, "Load address = 0x%08x;\n" },
59 { token_bl_entry_point, "Entry point = 0x%08x;\n" },
60 { token_bl_attribute, "Attributes = 0x%08x;\n" },
Vincent Palatin99475842011-03-07 16:09:25 -050061};
62
Anton Staafe517a4f2011-03-14 12:28:06 -070063/*****************************************************************************/
64static void usage(void)
Anton Staafc6244272011-02-24 10:17:50 -080065{
66 printf("Usage: bct_dump bctfile\n");
Peer Chen6f2cbc72012-03-13 11:12:39 +080067 printf(" bctfile BCT filename to read and display\n");
Anton Staafc6244272011-02-24 10:17:50 -080068}
Anton Staafe517a4f2011-03-14 12:28:06 -070069/*****************************************************************************/
70static int max_width(field_item const * table)
71{
72 int width = 0;
73 int i;
Anton Staafc6244272011-02-24 10:17:50 -080074
Peer Chen6f2cbc72012-03-13 11:12:39 +080075 for (i = 0; table[i].name != NULL; ++i) {
Anton Staafe517a4f2011-03-14 12:28:06 -070076 int length = strlen(table[i].name);
77
78 if (width < length)
79 width = length;
80 }
81
82 return width;
83}
84/*****************************************************************************/
Anton Staaf20379c12011-03-14 15:38:59 -070085static enum_item const * find_enum_item(build_image_context *context,
86 enum_item const * table,
87 u_int32_t value)
88{
89 int i;
90
Peer Chen6f2cbc72012-03-13 11:12:39 +080091 for (i = 0; table[i].name != NULL; ++i) {
92 if (table[i].value == value)
Anton Staaf20379c12011-03-14 15:38:59 -070093 return table + i;
94 }
95
96 return NULL;
97}
98/*****************************************************************************/
99static void display_enum_value(build_image_context *context,
100 enum_item const * table,
101 u_int32_t value)
102{
103 enum_item const * e_item = find_enum_item(context, table, value);
104
105 if (e_item)
106 printf("%s", e_item->name);
107 else
108 printf("<UNKNOWN ENUM VALUE (%d)>", value);
109}
110/*****************************************************************************/
111static int display_field_value(build_image_context *context,
112 field_item const * item,
113 u_int32_t value)
Anton Staafe517a4f2011-03-14 12:28:06 -0700114{
Peer Chen6f2cbc72012-03-13 11:12:39 +0800115 switch (item->type) {
Anton Staafe517a4f2011-03-14 12:28:06 -0700116 case field_type_enum:
Anton Staaf20379c12011-03-14 15:38:59 -0700117 display_enum_value(context, item->enum_table, value);
118 break;
Anton Staafe517a4f2011-03-14 12:28:06 -0700119
120 case field_type_u32:
121 printf("0x%08x", value);
122 break;
123
124 case field_type_u8:
Anton Staaf20379c12011-03-14 15:38:59 -0700125 printf("%d", value);
Anton Staafe517a4f2011-03-14 12:28:06 -0700126 break;
127
128 default:
129 printf("<UNKNOWN FIELD TYPE (%d)>", item->type);
130 return 1;
131 }
132
133 return 0;
134}
135/*****************************************************************************/
136int main(int argc, char *argv[])
Anton Staafc6244272011-02-24 10:17:50 -0800137{
138 int e;
139 build_image_context context;
140 u_int32_t bootloaders_used;
Anton Staaf496f9652011-03-02 09:23:27 -0800141 u_int32_t parameters_used;
Vincent Palatin99475842011-03-07 16:09:25 -0500142 u_int32_t sdram_used;
Anton Staaf496f9652011-03-02 09:23:27 -0800143 nvboot_dev_type type;
Peer Chen6f2cbc72012-03-13 11:12:39 +0800144 nvboot_config_table *bct = NULL;
Anton Staafc6244272011-02-24 10:17:50 -0800145 u_int32_t data;
146 int i;
147 int j;
148
149 if (argc != 2)
150 usage();
151
152 memset(&context, 0, sizeof(build_image_context));
153
Peer Chen6f2cbc72012-03-13 11:12:39 +0800154 g_bct_parse_interf = malloc(sizeof(bct_parse_interface));
155 if (g_bct_parse_interf == NULL) {
156 printf("Insufficient memory to proceed.\n");
157 return -EINVAL;
Anton Staafc6244272011-02-24 10:17:50 -0800158 }
159
Peer Chen6f2cbc72012-03-13 11:12:39 +0800160 context.bct_filename = argv[1];
Anton Staafc6244272011-02-24 10:17:50 -0800161
Peer Chen6f2cbc72012-03-13 11:12:39 +0800162 e = read_bct_file(&context);
163 if (e != 0)
164 return e;
165 bct = (nvboot_config_table *)(context.bct);
Anton Staaf496f9652011-03-02 09:23:27 -0800166 /* Display root values */
Anton Staafc6244272011-02-24 10:17:50 -0800167 for (i = 0; i < sizeof(values) / sizeof(values[0]); ++i) {
Peer Chen6f2cbc72012-03-13 11:12:39 +0800168 e = g_bct_parse_interf->get_value(values[i].id,
169 &data,
170 context.bct);
Anton Staaf20379c12011-03-14 15:38:59 -0700171
172 if (e != 0)
173 data = -1;
Peer Chen6f2cbc72012-03-13 11:12:39 +0800174 else if (values[i].id == token_block_size_log2 ||
175 values[i].id == token_page_size_log2)
Anton Staaf20379c12011-03-14 15:38:59 -0700176 data = 1 << data;
177
178 printf(values[i].message, data);
Anton Staafc6244272011-02-24 10:17:50 -0800179 }
180
Anton Staaf496f9652011-03-02 09:23:27 -0800181 /* Display bootloader values */
Peer Chen6f2cbc72012-03-13 11:12:39 +0800182 e = g_bct_parse_interf->get_value(token_bootloader_used,
Anton Staaf2b6c88c2011-03-02 09:22:25 -0800183 &bootloaders_used,
184 context.bct);
Anton Staafc6244272011-02-24 10:17:50 -0800185
Anton Staaf20379c12011-03-14 15:38:59 -0700186 if ((e == 0) && (bootloaders_used > 0)) {
187 int bl_count = sizeof(bl_values) / sizeof(bl_values[0]);
Anton Staafc6244272011-02-24 10:17:50 -0800188
Anton Staaf20379c12011-03-14 15:38:59 -0700189 printf("#\n"
190 "# These values are set by cbootimage using the\n"
191 "# bootloader provided by the Bootloader=...\n"
192 "# configuration option.\n"
193 "#\n");
194
195 for (i = 0; i < bootloaders_used; ++i) {
196 for (j = 0; j < bl_count; ++j) {
Peer Chen6f2cbc72012-03-13 11:12:39 +0800197 e = g_bct_parse_interf->getbl_param(i,
Anton Staaf20379c12011-03-14 15:38:59 -0700198 bl_values[j].id,
199 &data,
200 context.bct);
201 printf("# Bootloader[%d].", i);
202
203 if (e != 0)
204 data = -1;
205
206 printf(bl_values[j].message, data);
207 }
Anton Staafc6244272011-02-24 10:17:50 -0800208 }
209 }
210
Anton Staaf20379c12011-03-14 15:38:59 -0700211 /* Display flash device parameters */
Peer Chen6f2cbc72012-03-13 11:12:39 +0800212 e = g_bct_parse_interf->get_value(token_num_param_sets,
Anton Staaf496f9652011-03-02 09:23:27 -0800213 &parameters_used,
214 context.bct);
215
216 for (i = 0; (e == 0) && (i < parameters_used); ++i) {
Anton Staafe517a4f2011-03-14 12:28:06 -0700217 field_item const * device_field_table = NULL;
Anton Staaf20379c12011-03-14 15:38:59 -0700218 char const * prefix = NULL;
Anton Staafe517a4f2011-03-14 12:28:06 -0700219 field_item const * item;
220
Peer Chen6f2cbc72012-03-13 11:12:39 +0800221 e = g_bct_parse_interf->get_dev_param(&context,
222 i,
223 token_dev_type,
224 &type);
Anton Staaf20379c12011-03-14 15:38:59 -0700225 printf("\n"
226 "DevType[%d] = ", i);
Peer Chen6f2cbc72012-03-13 11:12:39 +0800227 display_enum_value(&context, s_devtype_table_t20, type);
Anton Staaf20379c12011-03-14 15:38:59 -0700228 printf(";\n");
229
Peer Chen6f2cbc72012-03-13 11:12:39 +0800230 switch (type) {
Anton Staaf496f9652011-03-02 09:23:27 -0800231 case nvboot_dev_type_spi:
Peer Chen6f2cbc72012-03-13 11:12:39 +0800232 device_field_table = s_spiflash_table_t20;
Anton Staaf20379c12011-03-14 15:38:59 -0700233 prefix = "SpiFlashParams";
Anton Staaf496f9652011-03-02 09:23:27 -0800234 break;
235
236 case nvboot_dev_type_sdmmc:
Peer Chen6f2cbc72012-03-13 11:12:39 +0800237 if (bct->boot_data_version ==
238 NVBOOT_BOOTDATA_VERSION(3, 1))
239 device_field_table = s_sdmmc_table_t30;
240 else
241 device_field_table = s_sdmmc_table_t20;
Anton Staaf20379c12011-03-14 15:38:59 -0700242 prefix = "SdmmcParams";
Anton Staafe517a4f2011-03-14 12:28:06 -0700243 break;
244
245 case nvboot_dev_type_nand:
Peer Chen6f2cbc72012-03-13 11:12:39 +0800246 if (bct->boot_data_version ==
247 NVBOOT_BOOTDATA_VERSION(3, 1))
248 device_field_table = s_nand_table_t30;
249 else
250 device_field_table = s_nand_table_t20;
Anton Staaf20379c12011-03-14 15:38:59 -0700251 prefix = "NandParams";
Anton Staaf496f9652011-03-02 09:23:27 -0800252 break;
253
254 default:
Anton Staafe517a4f2011-03-14 12:28:06 -0700255 device_field_table = NULL;
Anton Staaf20379c12011-03-14 15:38:59 -0700256 prefix = "";
Anton Staaf496f9652011-03-02 09:23:27 -0800257 break;
258 }
259
Anton Staafe517a4f2011-03-14 12:28:06 -0700260 if (!device_field_table)
261 continue;
Anton Staaf496f9652011-03-02 09:23:27 -0800262
Anton Staafe517a4f2011-03-14 12:28:06 -0700263 int width = max_width(device_field_table);
264
265 for (item = device_field_table; item->name != NULL; ++item) {
Peer Chen6f2cbc72012-03-13 11:12:39 +0800266 g_bct_parse_interf->get_dev_param(&context,
267 i,
268 item->token,
269 &data);
Anton Staaf20379c12011-03-14 15:38:59 -0700270 printf("DeviceParam[%d].%s.%-*s = ",
271 i, prefix, width, item->name);
272
273 if (e != 0)
274 printf("<ERROR reading parameter (%d)>", e);
275 else
276 display_field_value(&context, item, data);
277
278 printf(";\n");
Anton Staaf496f9652011-03-02 09:23:27 -0800279 }
280 }
281
Anton Staaf20379c12011-03-14 15:38:59 -0700282 /* Display SDRAM parameters */
Peer Chen6f2cbc72012-03-13 11:12:39 +0800283 e = g_bct_parse_interf->get_value(token_num_sdram_sets,
Vincent Palatin99475842011-03-07 16:09:25 -0500284 &sdram_used,
285 context.bct);
286
287 for (i = 0; (e == 0) && (i < sdram_used); ++i) {
Peer Chen6f2cbc72012-03-13 11:12:39 +0800288 field_item const *s_sdram_field_table;
289 field_item const *item;
Anton Staafe517a4f2011-03-14 12:28:06 -0700290
Anton Staaf20379c12011-03-14 15:38:59 -0700291 printf("\n");
292
Peer Chen6f2cbc72012-03-13 11:12:39 +0800293 if (bct->boot_data_version == NVBOOT_BOOTDATA_VERSION(3, 1))
294 s_sdram_field_table = s_sdram_field_table_t30;
295 else
296 s_sdram_field_table = s_sdram_field_table_t20;
297
298 int width = max_width(s_sdram_field_table);
299
Anton Staafe517a4f2011-03-14 12:28:06 -0700300 for (item = s_sdram_field_table; item->name != NULL; ++item) {
Peer Chen6f2cbc72012-03-13 11:12:39 +0800301 e = g_bct_parse_interf ->get_sdram_param(&context,
302 i,
303 item->token,
304 &data);
Anton Staaf20379c12011-03-14 15:38:59 -0700305 printf("SDRAM[%d].%-*s = ", i, width, item->name);
Anton Staafe517a4f2011-03-14 12:28:06 -0700306
307 if (e != 0)
308 printf("<ERROR reading parameter (%d)>", e);
309 else
Anton Staaf20379c12011-03-14 15:38:59 -0700310 display_field_value(&context, item, data);
Anton Staafe517a4f2011-03-14 12:28:06 -0700311
Anton Staaf20379c12011-03-14 15:38:59 -0700312 printf(";\n");
Vincent Palatin99475842011-03-07 16:09:25 -0500313 }
314 }
315
Anton Staafc6244272011-02-24 10:17:50 -0800316 /* Clean up memory. */
317 cleanup_context(&context);
318
319 return e;
320}
Anton Staaf20379c12011-03-14 15:38:59 -0700321/*****************************************************************************/