blob: a8e3479a3ca3258274d29ea09f8ddcb90996a825 [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 },
43 { token_block_size_log2, "BlockSize = ", format_u32_hex8 },
44 { token_page_size_log2, "PageSize = ", format_u32_hex8 },
45 { 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;
Peer Chen6f2cbc72012-03-13 11:12:39 +0800183 else if (values[i].id == token_block_size_log2 ||
184 values[i].id == token_page_size_log2)
Anton Staaf20379c12011-03-14 15:38:59 -0700185 data = 1 << data;
186
Penny Chiu3d0bff52014-04-11 17:50:37 +0800187 values[i].format(values[i].message, &data);
Anton Staafc6244272011-02-24 10:17:50 -0800188 }
189
Anton Staaf496f9652011-03-02 09:23:27 -0800190 /* Display bootloader values */
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800191 e = g_soc_config->get_value(token_bootloader_used,
Anton Staaf2b6c88c2011-03-02 09:22:25 -0800192 &bootloaders_used,
193 context.bct);
Anton Staafc6244272011-02-24 10:17:50 -0800194
Anton Staaf20379c12011-03-14 15:38:59 -0700195 if ((e == 0) && (bootloaders_used > 0)) {
196 int bl_count = sizeof(bl_values) / sizeof(bl_values[0]);
Anton Staafc6244272011-02-24 10:17:50 -0800197
Anton Staaf20379c12011-03-14 15:38:59 -0700198 printf("#\n"
199 "# These values are set by cbootimage using the\n"
200 "# bootloader provided by the Bootloader=...\n"
201 "# configuration option.\n"
202 "#\n");
203
204 for (i = 0; i < bootloaders_used; ++i) {
205 for (j = 0; j < bl_count; ++j) {
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800206 e = g_soc_config->getbl_param(i,
Anton Staaf20379c12011-03-14 15:38:59 -0700207 bl_values[j].id,
208 &data,
209 context.bct);
210 printf("# Bootloader[%d].", i);
211
212 if (e != 0)
213 data = -1;
214
Penny Chiu3d0bff52014-04-11 17:50:37 +0800215 bl_values[j].format(bl_values[j].message, &data);
Anton Staaf20379c12011-03-14 15:38:59 -0700216 }
Anton Staafc6244272011-02-24 10:17:50 -0800217 }
218 }
219
Anton Staaf20379c12011-03-14 15:38:59 -0700220 /* Display flash device parameters */
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800221 e = g_soc_config->get_value(token_num_param_sets,
Anton Staaf496f9652011-03-02 09:23:27 -0800222 &parameters_used,
223 context.bct);
224
225 for (i = 0; (e == 0) && (i < parameters_used); ++i) {
Anton Staafe517a4f2011-03-14 12:28:06 -0700226 field_item const * device_field_table = NULL;
Anton Staaf20379c12011-03-14 15:38:59 -0700227 char const * prefix = NULL;
Anton Staafe517a4f2011-03-14 12:28:06 -0700228 field_item const * item;
229
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800230 e = g_soc_config->get_dev_param(&context,
Peer Chen6f2cbc72012-03-13 11:12:39 +0800231 i,
232 token_dev_type,
233 &type);
Anton Staaf20379c12011-03-14 15:38:59 -0700234 printf("\n"
235 "DevType[%d] = ", i);
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800236 display_enum_value(&context, g_soc_config->devtype_table, type);
Anton Staaf20379c12011-03-14 15:38:59 -0700237 printf(";\n");
238
Peer Chen6f2cbc72012-03-13 11:12:39 +0800239 switch (type) {
Anton Staaf496f9652011-03-02 09:23:27 -0800240 case nvboot_dev_type_spi:
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800241 device_field_table = g_soc_config->spiflash_table;
Anton Staaf20379c12011-03-14 15:38:59 -0700242 prefix = "SpiFlashParams";
Anton Staaf496f9652011-03-02 09:23:27 -0800243 break;
244
245 case nvboot_dev_type_sdmmc:
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800246 device_field_table = g_soc_config->sdmmc_table;
Anton Staaf20379c12011-03-14 15:38:59 -0700247 prefix = "SdmmcParams";
Anton Staafe517a4f2011-03-14 12:28:06 -0700248 break;
249
250 case nvboot_dev_type_nand:
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800251 device_field_table = g_soc_config->nand_table;
Anton Staaf20379c12011-03-14 15:38:59 -0700252 prefix = "NandParams";
Anton Staaf496f9652011-03-02 09:23:27 -0800253 break;
254
255 default:
Anton Staafe517a4f2011-03-14 12:28:06 -0700256 device_field_table = NULL;
Anton Staaf20379c12011-03-14 15:38:59 -0700257 prefix = "";
Anton Staaf496f9652011-03-02 09:23:27 -0800258 break;
259 }
260
Anton Staafe517a4f2011-03-14 12:28:06 -0700261 if (!device_field_table)
262 continue;
Anton Staaf496f9652011-03-02 09:23:27 -0800263
Anton Staafe517a4f2011-03-14 12:28:06 -0700264 int width = max_width(device_field_table);
265
266 for (item = device_field_table; item->name != NULL; ++item) {
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800267 g_soc_config->get_dev_param(&context,
Peer Chen6f2cbc72012-03-13 11:12:39 +0800268 i,
269 item->token,
270 &data);
Anton Staaf20379c12011-03-14 15:38:59 -0700271 printf("DeviceParam[%d].%s.%-*s = ",
272 i, prefix, width, item->name);
273
274 if (e != 0)
275 printf("<ERROR reading parameter (%d)>", e);
276 else
277 display_field_value(&context, item, data);
278
279 printf(";\n");
Anton Staaf496f9652011-03-02 09:23:27 -0800280 }
281 }
282
Anton Staaf20379c12011-03-14 15:38:59 -0700283 /* Display SDRAM parameters */
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800284 e = g_soc_config->get_value(token_num_sdram_sets,
Vincent Palatin99475842011-03-07 16:09:25 -0500285 &sdram_used,
286 context.bct);
287
288 for (i = 0; (e == 0) && (i < sdram_used); ++i) {
Peer Chen6f2cbc72012-03-13 11:12:39 +0800289 field_item const *item;
Anton Staafe517a4f2011-03-14 12:28:06 -0700290
Anton Staaf20379c12011-03-14 15:38:59 -0700291 printf("\n");
292
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800293 int width = max_width(g_soc_config->sdram_field_table);
Peer Chen6f2cbc72012-03-13 11:12:39 +0800294
Penny Chiu5f4e2a32012-12-21 21:17:37 +0800295 for (item = g_soc_config->sdram_field_table; item->name != NULL; ++item) {
296 e = g_soc_config->get_sdram_param(&context,
Peer Chen6f2cbc72012-03-13 11:12:39 +0800297 i,
298 item->token,
299 &data);
Anton Staaf20379c12011-03-14 15:38:59 -0700300 printf("SDRAM[%d].%-*s = ", i, width, item->name);
Anton Staafe517a4f2011-03-14 12:28:06 -0700301
302 if (e != 0)
303 printf("<ERROR reading parameter (%d)>", e);
304 else
Anton Staaf20379c12011-03-14 15:38:59 -0700305 display_field_value(&context, item, data);
Anton Staafe517a4f2011-03-14 12:28:06 -0700306
Anton Staaf20379c12011-03-14 15:38:59 -0700307 printf(";\n");
Vincent Palatin99475842011-03-07 16:09:25 -0500308 }
309 }
310
Anton Staafc6244272011-02-24 10:17:50 -0800311 /* Clean up memory. */
312 cleanup_context(&context);
313
314 return e;
315}
Anton Staaf20379c12011-03-14 15:38:59 -0700316/*****************************************************************************/