blob: 36237889e94ee3527d27dbc966843f44807952af [file] [log] [blame]
Peer Chen8d782ee2011-01-18 21:34:18 -05001/**
2 * Copyright (c) 2011 NVIDIA Corporation. All rights reserved.
3 *
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/*
24 * set.c - State setting support for the cbootimage tool
25 */
26
Peer Chen7557d9b2011-02-24 09:29:23 -080027#include <math.h>
Peer Chen8d782ee2011-01-18 21:34:18 -050028#include "set.h"
29#include "cbootimage.h"
30#include "crypto.h"
31#include "data_layout.h"
32
33/*
34 * Function prototypes
35 *
36 * ParseXXX() parses XXX in the input
37 * SetXXX() sets state based on the parsing results but does not perform
38 * any parsing of its own
39 * A ParseXXX() function may call other parse functions and set functions.
40 * A SetXXX() function may not call any parseing functions.
41 */
42
Peer Chen7557d9b2011-02-24 09:29:23 -080043#define NV_MAX(a, b) (((a) > (b)) ? (a) : (b))
44
45#define CASE_DEVICE_VALUE(prefix, id) \
46 case token_##id: \
47 (void)context->bctlib.setdev_param(index, \
48 nvbct_lib_id_##prefix##_##id, \
49 value, \
50 context->bct); \
51 break
52
Peer Chen3a834ed2011-03-04 09:30:05 -080053#define CASE_SDRAM_VALUE(id) \
54 case token_##id: \
55 (void)context->bctlib.set_sdram_params(index, \
56 nvbct_lib_id_sdram_##id, \
57 value, \
58 context->bct); \
59 break
60
Peer Chen7557d9b2011-02-24 09:29:23 -080061#define DEFAULT() \
62 default: \
63 printf("Unexpected token %d at line %d\n", \
64 token, __LINE__); \
65 return 1
66
Peer Chen8d782ee2011-01-18 21:34:18 -050067int
68read_from_image(char *filename,
69 u_int32_t page_size,
70 u_int8_t **image,
71 u_int32_t *storage_size,
72 u_int32_t *actual_size,
73 file_type f_type)
74{
75 int result = 0; /* 0 = success, 1 = failure */
76 FILE *fp;
77 struct stat stats;
78
79 fp = fopen(filename, "r");
80 if (fp == NULL) {
81 result = 1;
82 return result;
83 }
84
85 if (stat(filename, &stats) != 0) {
86 printf("Error: Unable to query info on bootloader path %s\n",
Peer Chen7557d9b2011-02-24 09:29:23 -080087 filename);
Peer Chen8d782ee2011-01-18 21:34:18 -050088 result = 1;
89 goto cleanup;
90 }
91
92 *actual_size = (u_int32_t)stats.st_size;
93 *storage_size =
94 (u_int32_t)(ICEIL(stats.st_size, page_size) * page_size);
95
96 if (f_type == file_type_bl) {
97 if (stats.st_size > MAX_BOOTLOADER_SIZE) {
98 printf("Error: Bootloader file %s is too large.\n",
99 filename);
100 result = 1;
101 goto cleanup;
102 }
103
104
105 /* Workaround for a bug in release 1.0 of the boot rom.
106 * Any BL whose padded size is an integral multiple of page size
107 * has its length extended by 16 bytes to bump it to end on a
108 * partial page.
109 */
110 if ((*storage_size - *actual_size) < 16) {
111 *actual_size += 16;
112 *storage_size += page_size;
113 }
114 }
115 *image = malloc(*storage_size);
116 if (*image == NULL) {
117 result = 1;
118 goto cleanup;
119 }
120
121 memset(*image, 0, *storage_size);
122
123 if (fread(*image, 1, (size_t)stats.st_size, fp) != stats.st_size) {
124 result = 1;
125 goto cleanup;
126 }
127
128cleanup:
129 fclose(fp);
130 return result;
131}
132
133
134/*
135 * set_bootloader(): Processes commands to set a bootloader.
136 */
137int
138set_bootloader(build_image_context *context,
139 char *filename,
140 u_int32_t load_addr,
141 u_int32_t entry_point)
142{
143 context->newbl_filename = filename;
144 context->newbl_load_addr = load_addr;
145 context->newbl_entry_point = entry_point;
146 return update_bl(context);
147}
148
149#define DEFAULT() \
150 default: \
151 printf("Unexpected token %d at line %d\n", \
152 token, __LINE__); \
153 return 1
154
155/*
156 * context_set_array(): Sets an array value.
157 */
158int
159context_set_array(build_image_context *context,
160 u_int32_t index,
161 parse_token token,
162 u_int32_t value)
163{
164 assert(context != NULL);
165 assert(context->bct != NULL);
166
167 switch (token) {
168 case token_attribute:
169 (void)context->bctlib.setbl_param(index,
170 nvbct_lib_id_bl_attribute,
171 &value,
172 context->bct);
173 break;
174
Peer Chen7557d9b2011-02-24 09:29:23 -0800175 case token_dev_type:
176 (void)context->bctlib.setdev_param(index,
177 nvbct_lib_id_dev_type,
178 value,
179 context->bct);
180 break;
181
182 DEFAULT();
Peer Chen8d782ee2011-01-18 21:34:18 -0500183 }
184 return 0;
185}
186
187/*
188 * context_set_value(): General handler for setting values in config files.
189 */
190int context_set_value(build_image_context *context,
191 parse_token token,
192 u_int32_t value)
193{
194 assert(context != NULL);
195
196 switch (token) {
197 case token_attribute:
198 context->newbl_attr = value;
199 break;
200
Peer Chen7557d9b2011-02-24 09:29:23 -0800201 case token_block_size:
202 context->block_size = value;
203 context->block_size_log2 = log2(value);
204
205 if (context->memory != NULL) {
206 printf("Error: Too late to change block size.\n");
207 return 1;
208 }
209
210 if (value != (u_int32_t)(1 << context->block_size_log2)) {
211 printf("Error: Block size must be a power of 2.\n");
212 return 1;
213 }
214 context->pages_per_blk= 1 << (context->block_size_log2-
215 context->page_size_log2);
216 SET_VALUE(block_size_log2, context->block_size_log2);
217 break;
218
219 case token_partition_size:
220 if (context->memory != NULL) {
221 printf("Error: Too late to change block size.\n");
222 return 1;
223 }
224
225 context->partition_size= value;
226 SET_VALUE(partition_size, value);
227 break;
228
Peer Chen8d782ee2011-01-18 21:34:18 -0500229 case token_page_size:
230 context->page_size = value;
Peer Chen7557d9b2011-02-24 09:29:23 -0800231 context->page_size_log2 = log2(value);
232 context->pages_per_blk= 1 << (context->block_size_log2-
233 context->page_size_log2);
234
235 SET_VALUE(page_size_log2, context->page_size_log2);
Peer Chen8d782ee2011-01-18 21:34:18 -0500236 break;
237 case token_redundancy:
238 context->redundancy = value;
239 break;
240
241 case token_version:
242 context->version = value;
243 break;
244
245 DEFAULT();
246 }
247
248 return 0;
249}
250
251int
252set_addon_filename(build_image_context *context,
253 char *filename,
254 int index)
255{
256
257 struct addon_item_rec **current;
258 int i;
259
260 current = &(context->addon_tbl.addon_item_list);
261
262 for(i = 0; i <= index; i++) {
263 if (*current == NULL) {
264 (*current) = malloc(sizeof(struct addon_item_rec));
265 if (*current == NULL)
266 return -ENOMEM;
267 memset((*current), 0, sizeof(struct addon_item_rec));
268 memcpy((*current)->addon_filename,
269 filename, MAX_BUFFER);
270 (*current)->item_index = index;
271 (*current)->next = NULL;
272 context->addon_tbl.addon_item_no++;
273 } else if ((*current)->item_index == index) {
274 memcpy((*current)->addon_filename,
275 filename, MAX_BUFFER);
276 } else
277 current = &((*current)->next);
278 }
279 return 0;
280}
281
282int set_addon_attr(build_image_context *context,
283 u_int32_t file_attr,
284 int index)
285{
286 struct addon_item_rec **current;
287 int i;
288
289 current = &(context->addon_tbl.addon_item_list);
290
291 for(i = 0; i <= index; i++) {
292 if (*current == NULL) {
293 (*current) = malloc(sizeof(struct addon_item_rec));
294 if (*current == NULL)
295 return -ENOMEM;
296 memset((*current), 0, sizeof(struct addon_item_rec));
297 (*current)->item.attribute= file_attr;
298 (*current)->item_index = index;
299 (*current)->next = NULL;
300 context->addon_tbl.addon_item_no++;
301 } else if ((*current)->item_index == index) {
302 (*current)->item.attribute= file_attr;
303 } else
304 current = &((*current)->next);
305 }
306 return 0;
307}
308
309int set_unique_name(build_image_context *context, char *uname, int index)
310{
311 struct addon_item_rec **current;
312 int i;
313
314 current = &(context->addon_tbl.addon_item_list);
315
316 for(i = 0; i <= index; i++) {
317 if (*current == NULL) {
318 (*current) = malloc(sizeof(struct addon_item_rec));
319 if (*current == NULL)
320 return -ENOMEM;
321 memset((*current), 0, sizeof(struct addon_item_rec));
322 memcpy((*current)->item.unique_name, uname, 4);
323 (*current)->item_index = index;
324 (*current)->next = NULL;
325 context->addon_tbl.addon_item_no++;
326 } else if ((*current)->item_index == index) {
327 memcpy((*current)->item.unique_name, uname, 4);
328 } else
329 current = &((*current)->next);
330 }
331 return 0;
332}
333
334int
335set_other_field(build_image_context *context,
336 char *other_str,
337 int other,
338 int index)
339{
340 struct addon_item_rec **current;
341 int i;
342
343 current = &(context->addon_tbl.addon_item_list);
344
345 for(i = 0; i <= index; i++) {
346 if (*current == NULL) {
347 (*current) = malloc(sizeof(struct addon_item_rec));
348 if (*current == NULL)
349 return -ENOMEM;
350 memset((*current), 0, sizeof(struct addon_item_rec));
351 if (other_str == NULL)
352 (*current)->item.reserve[0] = other;
353 else
354 memcpy((*current)->item.reserve,
355 other_str, 16);
356 (*current)->item_index = index;
357 (*current)->next = NULL;
358 context->addon_tbl.addon_item_no++;
359 } else if ((*current)->item_index == index) {
360 if (other_str == NULL)
361 (*current)->item.reserve[0] = other;
362 else
363 memcpy((*current)->item.reserve,
364 other_str, 16);
365 } else
366 current = &((*current)->next);
367 }
368 return 0;
369
370}
371
Peer Chen7557d9b2011-02-24 09:29:23 -0800372static void
373update_num_param_sets(build_image_context *context, u_int32_t index)
374{
375 u_int32_t num_params;
376
377 GET_VALUE(num_param_sets, &num_params);
378 num_params = NV_MAX(num_params, index + 1);
379 SET_VALUE(num_param_sets, num_params);
380}
381
382/*
Peer Chen053d5782011-03-03 10:12:58 -0800383 * set_nand_param(): Processes commands to set Nand parameters.
384 */
385int
386set_nand_param(build_image_context *context,
387 u_int32_t index,
388 parse_token token,
389 u_int32_t value)
390{
391 assert(context != NULL);
392 assert(context->bct != NULL);
393
394 update_num_param_sets(context, index);
395
396 switch (token) {
397 CASE_DEVICE_VALUE(nand, clock_divider);
398 CASE_DEVICE_VALUE(nand, nand_timing);
399 CASE_DEVICE_VALUE(nand, nand_timing2);
400 CASE_DEVICE_VALUE(nand, block_size_log2);
401 CASE_DEVICE_VALUE(nand, page_size_log2);
402 DEFAULT();
403 }
404
405 return 0;
406}
407
408/*
Peer Chen7557d9b2011-02-24 09:29:23 -0800409 * set_sdmmc_param(): Processes commands to set MoviNand parameters.
410 */
411int
412set_sdmmc_param(build_image_context *context,
413 u_int32_t index,
414 parse_token token,
415 u_int32_t value)
416{
417 assert(context != NULL);
418 assert(context->bct != NULL);
419
420 update_num_param_sets(context, index);
421
422 switch (token) {
423 CASE_DEVICE_VALUE(sdmmc, clock_divider);
424 CASE_DEVICE_VALUE(sdmmc, data_width);
425 CASE_DEVICE_VALUE(sdmmc, max_power_class_supported);
426 DEFAULT();
427 }
428
429 return 0;
430}
431
432/*
433 * set_spiflash_param(): Processes commands to set SpiFlash parameters.
434 */
435int
436set_spiflash_param(build_image_context *context,
437 u_int32_t index,
438 parse_token token,
439 u_int32_t value)
440{
441 assert(context != NULL);
442 assert(context->bct != NULL);
443
444 update_num_param_sets(context, index);
445
446 switch (token) {
447 CASE_DEVICE_VALUE(spiflash, clock_divider);
448 CASE_DEVICE_VALUE(spiflash, clock_source);
449 CASE_DEVICE_VALUE(spiflash, read_command_type_fast);
450 DEFAULT();
451 }
452
453 return 0;
454}
Peer Chen3a834ed2011-03-04 09:30:05 -0800455
456int
457set_sdram_param(build_image_context *context,
458 u_int32_t index,
459 parse_token token,
460 u_int32_t value)
461{
462 u_int32_t num_sdram_sets;
463
464 assert(context != NULL);
465 assert(context->bct != NULL);
466
467 // Update the number of SDRAM parameter sets.
468 GET_VALUE(num_sdram_sets, &num_sdram_sets);
469 num_sdram_sets = NV_MAX(num_sdram_sets, index + 1);
470 SET_VALUE(num_sdram_sets, num_sdram_sets);
471
472 switch (token) {
473
474 CASE_SDRAM_VALUE(memory_type);
475 CASE_SDRAM_VALUE(pllm_charge_pump_setup_ctrl);
476 CASE_SDRAM_VALUE(pllm_loop_filter_setup_ctrl);
477 CASE_SDRAM_VALUE(pllm_input_divider);
478 CASE_SDRAM_VALUE(pllm_feedback_divider);
479 CASE_SDRAM_VALUE(pllm_post_divider);
480 CASE_SDRAM_VALUE(pllm_stable_time);
481 CASE_SDRAM_VALUE(emc_clock_divider);
482 CASE_SDRAM_VALUE(emc_auto_cal_interval);
483 CASE_SDRAM_VALUE(emc_auto_cal_config);
484 CASE_SDRAM_VALUE(emc_auto_cal_wait);
485 CASE_SDRAM_VALUE(emc_pin_program_wait);
486 CASE_SDRAM_VALUE(emc_rc);
487 CASE_SDRAM_VALUE(emc_rfc);
488 CASE_SDRAM_VALUE(emc_ras);
489 CASE_SDRAM_VALUE(emc_rp);
490 CASE_SDRAM_VALUE(emc_r2w);
491 CASE_SDRAM_VALUE(emc_w2r);
492 CASE_SDRAM_VALUE(emc_r2p);
493 CASE_SDRAM_VALUE(emc_w2p);
494 CASE_SDRAM_VALUE(emc_rd_rcd);
495 CASE_SDRAM_VALUE(emc_wr_rcd);
496 CASE_SDRAM_VALUE(emc_rrd);
497 CASE_SDRAM_VALUE(emc_rext);
498 CASE_SDRAM_VALUE(emc_wdv);
499 CASE_SDRAM_VALUE(emc_quse);
500 CASE_SDRAM_VALUE(emc_qrst);
501 CASE_SDRAM_VALUE(emc_qsafe);
502 CASE_SDRAM_VALUE(emc_rdv);
503 CASE_SDRAM_VALUE(emc_refresh);
504 CASE_SDRAM_VALUE(emc_burst_refresh_num);
505 CASE_SDRAM_VALUE(emc_pdex2wr);
506 CASE_SDRAM_VALUE(emc_pdex2rd);
507 CASE_SDRAM_VALUE(emc_pchg2pden);
508 CASE_SDRAM_VALUE(emc_act2pden);
509 CASE_SDRAM_VALUE(emc_ar2pden);
510 CASE_SDRAM_VALUE(emc_rw2pden);
511 CASE_SDRAM_VALUE(emc_txsr);
512 CASE_SDRAM_VALUE(emc_tcke);
513 CASE_SDRAM_VALUE(emc_tfaw);
514 CASE_SDRAM_VALUE(emc_trpab);
515 CASE_SDRAM_VALUE(emc_tclkstable);
516 CASE_SDRAM_VALUE(emc_tclkstop);
517 CASE_SDRAM_VALUE(emc_trefbw);
518 CASE_SDRAM_VALUE(emc_quse_extra);
519 CASE_SDRAM_VALUE(emc_fbio_cfg1);
520 CASE_SDRAM_VALUE(emc_fbio_dqsib_dly);
521 CASE_SDRAM_VALUE(emc_fbio_dqsib_dly_msb);
522 CASE_SDRAM_VALUE(emc_fbio_quse_dly);
523 CASE_SDRAM_VALUE(emc_fbio_quse_dly_msb);
524 CASE_SDRAM_VALUE(emc_fbio_cfg5);
525 CASE_SDRAM_VALUE(emc_fbio_cfg6);
526 CASE_SDRAM_VALUE(emc_fbio_spare);
527 CASE_SDRAM_VALUE(emc_mrs);
528 CASE_SDRAM_VALUE(emc_emrs);
529 CASE_SDRAM_VALUE(emc_mrw1);
530 CASE_SDRAM_VALUE(emc_mrw2);
531 CASE_SDRAM_VALUE(emc_mrw3);
532 CASE_SDRAM_VALUE(emc_mrw_reset_command);
533 CASE_SDRAM_VALUE(emc_mrw_reset_ninit_wait);
534 CASE_SDRAM_VALUE(emc_adr_cfg);
535 CASE_SDRAM_VALUE(emc_adr_cfg1);
536 CASE_SDRAM_VALUE(mc_emem_Cfg);
537 CASE_SDRAM_VALUE(mc_lowlatency_config);
538 CASE_SDRAM_VALUE(emc_cfg);
539 CASE_SDRAM_VALUE(emc_cfg2);
540 CASE_SDRAM_VALUE(emc_dbg);
541 CASE_SDRAM_VALUE(ahb_arbitration_xbar_ctrl);
542 CASE_SDRAM_VALUE(emc_cfg_dig_dll);
543 CASE_SDRAM_VALUE(emc_dll_xform_dqs);
544 CASE_SDRAM_VALUE(emc_dll_xform_quse);
545 CASE_SDRAM_VALUE(warm_boot_wait);
546 CASE_SDRAM_VALUE(emc_ctt_term_ctrl);
547 CASE_SDRAM_VALUE(emc_odt_write);
548 CASE_SDRAM_VALUE(emc_odt_read);
549 CASE_SDRAM_VALUE(emc_zcal_ref_cnt);
550 CASE_SDRAM_VALUE(emc_zcal_wait_cnt);
551 CASE_SDRAM_VALUE(emc_zcal_mrw_cmd);
552 CASE_SDRAM_VALUE(emc_mrs_reset_dll);
553 CASE_SDRAM_VALUE(emc_mrw_zq_init_dev0);
554 CASE_SDRAM_VALUE(emc_mrw_zq_init_dev1);
555 CASE_SDRAM_VALUE(emc_mrw_zq_init_wait);
556 CASE_SDRAM_VALUE(emc_mrs_reset_dll_wait);
557 CASE_SDRAM_VALUE(emc_emrs_emr2);
558 CASE_SDRAM_VALUE(emc_emrs_emr3);
559 CASE_SDRAM_VALUE(emc_emrs_ddr2_dll_enable);
560 CASE_SDRAM_VALUE(emc_mrs_ddr2_dll_reset);
561 CASE_SDRAM_VALUE(emc_emrs_ddr2_ocd_calib);
562 CASE_SDRAM_VALUE(emc_ddr2_wait);
563 CASE_SDRAM_VALUE(emc_cfg_clktrim0);
564 CASE_SDRAM_VALUE(emc_cfg_clktrim1);
565 CASE_SDRAM_VALUE(emc_cfg_clktrim2);
566 CASE_SDRAM_VALUE(pmc_ddr_pwr);
567 CASE_SDRAM_VALUE(apb_misc_gp_xm2cfga_pad_ctrl);
568 CASE_SDRAM_VALUE(apb_misc_gp_xm2cfgc_pad_ctrl);
569 CASE_SDRAM_VALUE(apb_misc_gp_xm2cfgc_pad_ctrl2);
570 CASE_SDRAM_VALUE(apb_misc_gp_xm2cfgd_pad_ctrl);
571 CASE_SDRAM_VALUE(apb_misc_gp_xm2cfgd_pad_ctrl2);
572 CASE_SDRAM_VALUE(apb_misc_gp_xm2clkcfg_Pad_ctrl);
573 CASE_SDRAM_VALUE(apb_misc_gp_xm2comp_pad_ctrl);
574 CASE_SDRAM_VALUE(apb_misc_gp_xm2vttgen_pad_ctrl);
575
576 DEFAULT();
577 }
578 return 0;
579}