blob: 40ab3b49f94ecca487920c92804e91a060c630e1 [file] [log] [blame]
Stephen Warren4b0e5d02012-11-28 11:44:50 -07001/*
2 * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
Anton Staafc6244272011-02-24 10:17:50 -080015 *
16 * See file CREDITS for list of people who contributed to this
17 * project.
Anton Staafc6244272011-02-24 10:17:50 -080018 */
19
20#include "cbootimage.h"
Anton Staafc6244272011-02-24 10:17:50 -080021#include "data_layout.h"
22#include "context.h"
Anton Staafe517a4f2011-03-14 12:28:06 -070023#include "parse.h"
Peer Chen6f2cbc72012-03-13 11:12:39 +080024#include "t20/nvboot_bct_t20.h"
Anton Staafc6244272011-02-24 10:17:50 -080025#include <string.h>
26
Penny Chiu5f4e2a32012-12-21 21:17:37 +080027int enable_debug;
28cbootimage_soc_config * g_soc_config;
Peer Chen6f2cbc72012-03-13 11:12:39 +080029
Penny Chiu3d0bff52014-04-11 17:50:37 +080030static void format_u32_hex8(char const * message, void * data);
31static void format_u32(char const * message, void * data);
32
33typedef void (*format_function)(char const * message, void * data);
34
Anton Staafc6244272011-02-24 10:17:50 -080035typedef struct {
Peer Chen6f2cbc72012-03-13 11:12:39 +080036 parse_token id;
Anton Staafc6244272011-02-24 10:17:50 -080037 char const * message;
Penny Chiu3d0bff52014-04-11 17:50:37 +080038 format_function format;
Anton Staafc6244272011-02-24 10:17:50 -080039} value_data;
40
Stephen Warrenb258a012012-11-29 17:53:51 -070041static value_data const values[] = {
Penny Chiu3d0bff52014-04-11 17:50:37 +080042 { token_boot_data_version, "Version = ", format_u32_hex8 },
Penny Chiu19eae542014-04-11 17:50:41 +080043 { token_block_size, "BlockSize = ", format_u32_hex8 },
44 { token_page_size, "PageSize = ", format_u32_hex8 },
Penny Chiu3d0bff52014-04-11 17:50:37 +080045 { token_partition_size, "PartitionSize = ", format_u32_hex8 },
46 { token_odm_data, "OdmData = ", format_u32_hex8 },
47 { token_bootloader_used, "# Bootloader used = ", format_u32 },
48 { token_bootloaders_max, "# Bootloaders max = ", format_u32 },
49 { token_bct_size, "# BCT size = ", format_u32 },
50 { token_hash_size, "# Hash size = ", format_u32 },
51 { token_crypto_offset, "# Crypto offset = ", format_u32 },
52 { token_crypto_length, "# Crypto length = ", format_u32 },
53 { token_max_bct_search_blks, "# Max BCT search blocks = ", format_u32 },
Anton Staafc6244272011-02-24 10:17:50 -080054};
55
Stephen Warrenb258a012012-11-29 17:53:51 -070056static value_data const bl_values[] = {
Penny Chiu3d0bff52014-04-11 17:50:37 +080057 { token_bl_version, "Version = ", format_u32_hex8 },
58 { token_bl_start_blk, "Start block = ", format_u32 },
59 { token_bl_start_page, "Start page = ", format_u32 },
60 { token_bl_length, "Length = ", format_u32 },
61 { token_bl_load_addr, "Load address = ", format_u32_hex8 },
62 { token_bl_entry_point, "Entry point = ", format_u32_hex8 },
63 { token_bl_attribute, "Attributes = ", format_u32_hex8 },
Vincent Palatin99475842011-03-07 16:09:25 -050064};
65
Anton Staafe517a4f2011-03-14 12:28:06 -070066/*****************************************************************************/
Penny Chiu3d0bff52014-04-11 17:50:37 +080067static void format_u32_hex8(char const * message, void * data)
68{
69 printf("%s0x%08x;\n", message, *((u_int32_t *) data));
70}
71
72static void format_u32(char const * message, void * data)
73{
74 printf("%s%d;\n", message, *((u_int32_t *) data));
75}
76
77/*****************************************************************************/
Anton Staafe517a4f2011-03-14 12:28:06 -070078static void usage(void)
Anton Staafc6244272011-02-24 10:17:50 -080079{
80 printf("Usage: bct_dump bctfile\n");
Peer Chen6f2cbc72012-03-13 11:12:39 +080081 printf(" bctfile BCT filename to read and display\n");
Anton Staafc6244272011-02-24 10:17:50 -080082}
Anton Staafe517a4f2011-03-14 12:28:06 -070083/*****************************************************************************/
84static int max_width(field_item const * table)
85{
86 int width = 0;
87 int i;
Anton Staafc6244272011-02-24 10:17:50 -080088
Peer Chen6f2cbc72012-03-13 11:12:39 +080089 for (i = 0; table[i].name != NULL; ++i) {
Anton Staafe517a4f2011-03-14 12:28:06 -070090 int length = strlen(table[i].name);
91
92 if (width < length)
93 width = length;
94 }
95
96 return width;
97}
98/*****************************************************************************/
Anton Staaf20379c12011-03-14 15:38:59 -070099static enum_item const * find_enum_item(build_image_context *context,
100 enum_item const * table,
101 u_int32_t value)
102{
103 int i;
104
Peer Chen6f2cbc72012-03-13 11:12:39 +0800105 for (i = 0; table[i].name != NULL; ++i) {
106 if (table[i].value == value)
Anton Staaf20379c12011-03-14 15:38:59 -0700107 return table + i;
108 }
109
110 return NULL;
111}
112/*****************************************************************************/
113static void display_enum_value(build_image_context *context,
114 enum_item const * table,
115 u_int32_t value)
116{
117 enum_item const * e_item = find_enum_item(context, table, value);
118
119 if (e_item)
120 printf("%s", e_item->name);
121 else
122 printf("<UNKNOWN ENUM VALUE (%d)>", value);
123}
124/*****************************************************************************/
125static int display_field_value(build_image_context *context,
126 field_item const * item,
127 u_int32_t value)
Anton Staafe517a4f2011-03-14 12:28:06 -0700128{
Peer Chen6f2cbc72012-03-13 11:12:39 +0800129 switch (item->type) {
Anton Staafe517a4f2011-03-14 12:28:06 -0700130 case field_type_enum:
Anton Staaf20379c12011-03-14 15:38:59 -0700131 display_enum_value(context, item->enum_table, value);
132 break;
Anton Staafe517a4f2011-03-14 12:28:06 -0700133
134 case field_type_u32:
135 printf("0x%08x", value);
136 break;
137
138 case field_type_u8:
Anton Staaf20379c12011-03-14 15:38:59 -0700139 printf("%d", value);
Anton Staafe517a4f2011-03-14 12:28:06 -0700140 break;
141
142 default:
143 printf("<UNKNOWN FIELD TYPE (%d)>", item->type);
144 return 1;
145 }
146
147 return 0;
148}
149/*****************************************************************************/
150int main(int argc, char *argv[])
Anton Staafc6244272011-02-24 10:17:50 -0800151{
152 int e;
153 build_image_context context;
154 u_int32_t bootloaders_used;
Anton Staaf496f9652011-03-02 09:23:27 -0800155 u_int32_t parameters_used;
Vincent Palatin99475842011-03-07 16:09:25 -0500156 u_int32_t sdram_used;
Anton Staaf496f9652011-03-02 09:23:27 -0800157 nvboot_dev_type type;
Anton Staafc6244272011-02-24 10:17:50 -0800158 u_int32_t data;
159 int i;
160 int j;
161
162 if (argc != 2)
163 usage();
164
165 memset(&context, 0, sizeof(build_image_context));
Peer Chen6f2cbc72012-03-13 11:12:39 +0800166 context.bct_filename = argv[1];
Anton Staafc6244272011-02-24 10:17:50 -0800167
Peer Chen6f2cbc72012-03-13 11:12:39 +0800168 e = read_bct_file(&context);
169 if (e != 0)
170 return e;
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800171
Anton Staaf496f9652011-03-02 09:23:27 -0800172 /* Display root values */
Anton Staafc6244272011-02-24 10:17:50 -0800173 for (i = 0; i < sizeof(values) / sizeof(values[0]); ++i) {
Penny Chiu0cb60ab2014-04-11 17:50:40 +0800174 if (!g_soc_config->token_supported(values[i].id))
175 continue;
176
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800177 e = g_soc_config->get_value(values[i].id,
Peer Chen6f2cbc72012-03-13 11:12:39 +0800178 &data,
179 context.bct);
Anton Staaf20379c12011-03-14 15:38:59 -0700180
181 if (e != 0)
182 data = -1;
Anton Staaf20379c12011-03-14 15:38:59 -0700183
Penny Chiu3d0bff52014-04-11 17:50:37 +0800184 values[i].format(values[i].message, &data);
Anton Staafc6244272011-02-24 10:17:50 -0800185 }
186
Anton Staaf496f9652011-03-02 09:23:27 -0800187 /* Display bootloader values */
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800188 e = g_soc_config->get_value(token_bootloader_used,
Anton Staaf2b6c88c2011-03-02 09:22:25 -0800189 &bootloaders_used,
190 context.bct);
Anton Staafc6244272011-02-24 10:17:50 -0800191
Anton Staaf20379c12011-03-14 15:38:59 -0700192 if ((e == 0) && (bootloaders_used > 0)) {
193 int bl_count = sizeof(bl_values) / sizeof(bl_values[0]);
Anton Staafc6244272011-02-24 10:17:50 -0800194
Anton Staaf20379c12011-03-14 15:38:59 -0700195 printf("#\n"
196 "# These values are set by cbootimage using the\n"
197 "# bootloader provided by the Bootloader=...\n"
198 "# configuration option.\n"
199 "#\n");
200
201 for (i = 0; i < bootloaders_used; ++i) {
202 for (j = 0; j < bl_count; ++j) {
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800203 e = g_soc_config->getbl_param(i,
Anton Staaf20379c12011-03-14 15:38:59 -0700204 bl_values[j].id,
205 &data,
206 context.bct);
207 printf("# Bootloader[%d].", i);
208
209 if (e != 0)
210 data = -1;
211
Penny Chiu3d0bff52014-04-11 17:50:37 +0800212 bl_values[j].format(bl_values[j].message, &data);
Anton Staaf20379c12011-03-14 15:38:59 -0700213 }
Anton Staafc6244272011-02-24 10:17:50 -0800214 }
215 }
216
Anton Staaf20379c12011-03-14 15:38:59 -0700217 /* Display flash device parameters */
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800218 e = g_soc_config->get_value(token_num_param_sets,
Anton Staaf496f9652011-03-02 09:23:27 -0800219 &parameters_used,
220 context.bct);
221
222 for (i = 0; (e == 0) && (i < parameters_used); ++i) {
Anton Staafe517a4f2011-03-14 12:28:06 -0700223 field_item const * device_field_table = NULL;
Anton Staaf20379c12011-03-14 15:38:59 -0700224 char const * prefix = NULL;
Anton Staafe517a4f2011-03-14 12:28:06 -0700225 field_item const * item;
226
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800227 e = g_soc_config->get_dev_param(&context,
Peer Chen6f2cbc72012-03-13 11:12:39 +0800228 i,
229 token_dev_type,
230 &type);
Anton Staaf20379c12011-03-14 15:38:59 -0700231 printf("\n"
232 "DevType[%d] = ", i);
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800233 display_enum_value(&context, g_soc_config->devtype_table, type);
Anton Staaf20379c12011-03-14 15:38:59 -0700234 printf(";\n");
235
Peer Chen6f2cbc72012-03-13 11:12:39 +0800236 switch (type) {
Anton Staaf496f9652011-03-02 09:23:27 -0800237 case nvboot_dev_type_spi:
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800238 device_field_table = g_soc_config->spiflash_table;
Anton Staaf20379c12011-03-14 15:38:59 -0700239 prefix = "SpiFlashParams";
Anton Staaf496f9652011-03-02 09:23:27 -0800240 break;
241
242 case nvboot_dev_type_sdmmc:
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800243 device_field_table = g_soc_config->sdmmc_table;
Anton Staaf20379c12011-03-14 15:38:59 -0700244 prefix = "SdmmcParams";
Anton Staafe517a4f2011-03-14 12:28:06 -0700245 break;
246
247 case nvboot_dev_type_nand:
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800248 device_field_table = g_soc_config->nand_table;
Anton Staaf20379c12011-03-14 15:38:59 -0700249 prefix = "NandParams";
Anton Staaf496f9652011-03-02 09:23:27 -0800250 break;
251
252 default:
Anton Staafe517a4f2011-03-14 12:28:06 -0700253 device_field_table = NULL;
Anton Staaf20379c12011-03-14 15:38:59 -0700254 prefix = "";
Anton Staaf496f9652011-03-02 09:23:27 -0800255 break;
256 }
257
Anton Staafe517a4f2011-03-14 12:28:06 -0700258 if (!device_field_table)
259 continue;
Anton Staaf496f9652011-03-02 09:23:27 -0800260
Anton Staafe517a4f2011-03-14 12:28:06 -0700261 int width = max_width(device_field_table);
262
263 for (item = device_field_table; item->name != NULL; ++item) {
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800264 g_soc_config->get_dev_param(&context,
Peer Chen6f2cbc72012-03-13 11:12:39 +0800265 i,
266 item->token,
267 &data);
Anton Staaf20379c12011-03-14 15:38:59 -0700268 printf("DeviceParam[%d].%s.%-*s = ",
269 i, prefix, width, item->name);
270
271 if (e != 0)
272 printf("<ERROR reading parameter (%d)>", e);
273 else
274 display_field_value(&context, item, data);
275
276 printf(";\n");
Anton Staaf496f9652011-03-02 09:23:27 -0800277 }
278 }
279
Anton Staaf20379c12011-03-14 15:38:59 -0700280 /* Display SDRAM parameters */
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800281 e = g_soc_config->get_value(token_num_sdram_sets,
Vincent Palatin99475842011-03-07 16:09:25 -0500282 &sdram_used,
283 context.bct);
284
285 for (i = 0; (e == 0) && (i < sdram_used); ++i) {
Peer Chen6f2cbc72012-03-13 11:12:39 +0800286 field_item const *item;
Anton Staafe517a4f2011-03-14 12:28:06 -0700287
Anton Staaf20379c12011-03-14 15:38:59 -0700288 printf("\n");
289
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800290 int width = max_width(g_soc_config->sdram_field_table);
Peer Chen6f2cbc72012-03-13 11:12:39 +0800291
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800292 for (item = g_soc_config->sdram_field_table; item->name != NULL; ++item) {
293 e = g_soc_config->get_sdram_param(&context,
Peer Chen6f2cbc72012-03-13 11:12:39 +0800294 i,
295 item->token,
296 &data);
Anton Staaf20379c12011-03-14 15:38:59 -0700297 printf("SDRAM[%d].%-*s = ", i, width, item->name);
Anton Staafe517a4f2011-03-14 12:28:06 -0700298
299 if (e != 0)
300 printf("<ERROR reading parameter (%d)>", e);
301 else
Anton Staaf20379c12011-03-14 15:38:59 -0700302 display_field_value(&context, item, data);
Anton Staafe517a4f2011-03-14 12:28:06 -0700303
Anton Staaf20379c12011-03-14 15:38:59 -0700304 printf(";\n");
Vincent Palatin99475842011-03-07 16:09:25 -0500305 }
306 }
307
Anton Staafc6244272011-02-24 10:17:50 -0800308 /* Clean up memory. */
309 cleanup_context(&context);
310
311 return e;
312}
Anton Staaf20379c12011-03-14 15:38:59 -0700313/*****************************************************************************/