Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: parse.c

Issue 6579034: Add the device type/parameters support for cbootimage tool. (Closed) Base URL: http://git.chromium.org/git/cbootimage.git@master
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « parse.h ('k') | set.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /** 1 /**
2 * Copyright (c) 2011 NVIDIA Corporation. All rights reserved. 2 * Copyright (c) 2011 NVIDIA Corporation. All rights reserved.
3 * 3 *
4 * See file CREDITS for list of people who contributed to this 4 * See file CREDITS for list of people who contributed to this
5 * project. 5 * project.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 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 8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of 9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version. 10 * the License, or (at your option) any later version.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 * Function prototypes 45 * Function prototypes
46 * 46 *
47 * ParseXXX() parses XXX in the input 47 * ParseXXX() parses XXX in the input
48 * SetXXX() sets state based on the parsing results but does not perform 48 * SetXXX() sets state based on the parsing results but does not perform
49 * any parsing of its own 49 * any parsing of its own
50 * A ParseXXX() function may call other parse functions and set functions. 50 * A ParseXXX() function may call other parse functions and set functions.
51 * A SetXXX() function may not call any parseing functions. 51 * A SetXXX() function may not call any parseing functions.
52 */ 52 */
53 53
54 static char *parse_u32(char *statement, u_int32_t *val); 54 static char *parse_u32(char *statement, u_int32_t *val);
55 static char *parse_u8(char *statement, u_int32_t *val);
55 static char *parse_filename(char *statement, char *name, int chars_remaining); 56 static char *parse_filename(char *statement, char *name, int chars_remaining);
57 static char *parse_enum(build_image_context *context,
58 char *statement,
59 enum_item *table,
60 u_int32_t *val);
61 static char
62 *parse_field_name(char *rest, field_item *field_table, field_item **field);
63 static char
64 *parse_field_value(build_image_context *context,
65 char *rest,
66 field_item *field,
67 u_int32_t *value);
56 static int 68 static int
57 parse_array(build_image_context *context, parse_token token, char *rest); 69 parse_array(build_image_context *context, parse_token token, char *rest);
58 static int 70 static int
59 parse_bootloader(build_image_context *context, parse_token token, char *rest); 71 parse_bootloader(build_image_context *context, parse_token token, char *rest);
60 static int 72 static int
61 parse_value_u32(build_image_context *context, parse_token token, char *rest); 73 parse_value_u32(build_image_context *context, parse_token token, char *rest);
62 static int 74 static int
63 parse_bct_file(build_image_context *context, parse_token token, char *rest); 75 parse_bct_file(build_image_context *context, parse_token token, char *rest);
64 static int 76 static int
65 parse_addon(build_image_context *context, parse_token token, char *rest); 77 parse_addon(build_image_context *context, parse_token token, char *rest);
66 static char *parse_string(char *statement, char *uname, int chars_remaining); 78 static char *parse_string(char *statement, char *uname, int chars_remaining);
67 static char 79 static char
68 *parse_end_state(char *statement, char *uname, int chars_remaining); 80 *parse_end_state(char *statement, char *uname, int chars_remaining);
81 static int
82 parse_dev_param(build_image_context *context, parse_token token, char *rest);
83
69 static int process_statement(build_image_context *context, char *statement); 84 static int process_statement(build_image_context *context, char *statement);
70 85
86 static enum_item s_devtype_table[] =
87 {
88 { "NvBootDevType_Sdmmc", nvbct_lib_id_dev_type_sdmmc },
89 { "NvBootDevType_Spi", nvbct_lib_id_dev_type_spi },
90 { "Sdmmc", nvbct_lib_id_dev_type_sdmmc },
91 { "Spi", nvbct_lib_id_dev_type_spi },
92
93 { NULL, 0 }
94 };
95
96 static enum_item s_sdmmc_data_width_table[] =
97 {
98 {
99 "NvBootSdmmcDataWidth_4Bit",
100 nvbct_lib_id_sdmmc_data_width_4bit
101 },
102 {
103 "NvBootSdmmcDataWidth_8Bit",
104 nvbct_lib_id_sdmmc_data_width_8bit
105 },
106 { "4Bit", nvbct_lib_id_sdmmc_data_width_4bit },
107 { "8Bit", nvbct_lib_id_sdmmc_data_width_8bit },
108 { NULL, 0 }
109 };
110
111 static enum_item s_spi_clock_source_table[] =
112 {
113 {
114 "NvBootSpiClockSource_PllPOut0",
115 nvbct_lib_id_spi_clock_source_pllp_out0
116 },
117 {
118 "NvBootSpiClockSource_PllCOut0",
119 nvbct_lib_id_spi_clock_source_pllc_out0
120 },
121 {
122 "NvBootSpiClockSource_PllMOut0",
123 nvbct_lib_id_spi_clock_source_pllm_out0
124 },
125 {
126 "NvBootSpiClockSource_ClockM",
127 nvbct_lib_id_spi_clock_source_clockm
128 },
129
130 { "ClockSource_PllPOut0", nvbct_lib_id_spi_clock_source_pllp_out0 },
131 { "ClockSource_PllCOut0", nvbct_lib_id_spi_clock_source_pllc_out0 },
132 { "ClockSource_PllMOut0", nvbct_lib_id_spi_clock_source_pllm_out0 },
133 { "ClockSource_ClockM", nvbct_lib_id_spi_clock_source_clockm },
134
135
136 { "PllPOut0", nvbct_lib_id_spi_clock_source_pllp_out0 },
137 { "PllCOut0", nvbct_lib_id_spi_clock_source_pllc_out0 },
138 { "PllMOut0", nvbct_lib_id_spi_clock_source_pllm_out0 },
139 { "ClockM", nvbct_lib_id_spi_clock_source_clockm },
140
141 { NULL, 0 }
142 };
143
144 static field_item s_sdmmc_table[] =
145 {
146 { "ClockDivider", token_clock_divider, field_type_u32, NULL },
147 { "DataWidth", token_data_width,
148 field_type_enum, s_sdmmc_data_width_table },
149 { "MaxPowerClassSupported", token_max_power_class_supported,
150 field_type_u32, NULL },
151
152 { NULL, 0, 0, NULL }
153 };
154
155 static field_item s_spiflash_table[] =
156 {
157 { "ReadCommandTypeFast", token_read_command_type_fast,
158 field_type_u8, NULL },
159 { "ClockDivider", token_clock_divider, field_type_u8, NULL },
160 { "ClockSource", token_clock_source,
161 field_type_enum, s_spi_clock_source_table },
162
163 { NULL, 0, 0, NULL }
164 };
165
166 static parse_subfield_item s_device_type_table[] =
167 {
168 { "SdmmcParams.", token_sdmmc_params,
169 s_sdmmc_table, set_sdmmc_param },
170 { "SpiFlashParams.", token_spiflash_params,
171 s_spiflash_table, set_spiflash_param },
172
173 { NULL, 0, NULL }
174 };
175
71 static parse_item s_top_level_items[] = 176 static parse_item s_top_level_items[] =
72 { 177 {
73 { "Bctfile=", token_bct_file, parse_bct_file }, 178 { "Bctfile=", token_bct_file, parse_bct_file },
74 { "Attribute=", token_attribute, parse_value_u32 }, 179 { "Attribute=", token_attribute, parse_value_u32 },
75 { "Attribute[", token_attribute, parse_array }, 180 { "Attribute[", token_attribute, parse_array },
181 { "PageSize=", token_page_size, parse_value_u32 },
182 { "BlockSize=", token_block_size, parse_value_u32 },
183 { "PartitionSize=", token_partition_size, parse_value_u32 },
184 { "DevType[", token_dev_type, parse_array },
185 { "DeviceParam[", token_dev_param, parse_dev_param },
76 { "BootLoader=", token_bootloader, parse_bootloader }, 186 { "BootLoader=", token_bootloader, parse_bootloader },
77 { "Redundancy=", token_redundancy, parse_value_u32 }, 187 { "Redundancy=", token_redundancy, parse_value_u32 },
78 { "Version=", token_version, parse_value_u32 }, 188 { "Version=", token_version, parse_value_u32 },
79 { "AddOn[", token_addon, parse_addon }, 189 { "AddOn[", token_addon, parse_addon },
80 { NULL, 0, NULL } /* Must be last */ 190 { NULL, 0, NULL } /* Must be last */
81 }; 191 };
82 192
83 /* Macro to simplify parser code a bit. */ 193 /* Macro to simplify parser code a bit. */
84 #define PARSE_COMMA(x) if (*rest != ',') return (x); rest++ 194 #define PARSE_COMMA(x) if (*rest != ',') return (x); rest++
85 195
(...skipping 27 matching lines...) Expand all
113 } else { 223 } else {
114 while (*statement >= '0' && *statement <= '9') { 224 while (*statement >= '0' && *statement <= '9') {
115 value = value*10 + (*statement - '0'); 225 value = value*10 + (*statement - '0');
116 statement++; 226 statement++;
117 } 227 }
118 } 228 }
119 *val = value; 229 *val = value;
120 return statement; 230 return statement;
121 } 231 }
122 232
233 char *
234 parse_u8(char *statement, u_int32_t *val)
235 {
236 char *retval;
237
238 retval = parse_u32(statement, val);
239
240 if (*val > 0xff) {
241 printf("Warning: Parsed 8-bit value that exceeded 8-bits.\n");
242 printf(" Parsed value = %d. Remaining text = %s\n",
243 *val, retval);
244 }
245
246 return retval;
247 }
248
249
123 /* This parsing code was initially borrowed from nvcamera_config_parse.c. */ 250 /* This parsing code was initially borrowed from nvcamera_config_parse.c. */
124 /* Returns the address of the character after the parsed data. */ 251 /* Returns the address of the character after the parsed data. */
125 static char * 252 static char *
126 parse_filename(char *statement, char *name, int chars_remaining) 253 parse_filename(char *statement, char *name, int chars_remaining)
127 { 254 {
128 while (((*statement >= '0') && (*statement <= '9')) || 255 while (((*statement >= '0') && (*statement <= '9')) ||
129 ((*statement >= 'a') && (*statement <= 'z')) || 256 ((*statement >= 'a') && (*statement <= 'z')) ||
130 ((*statement >= 'A') && (*statement <= 'Z')) || 257 ((*statement >= 'A') && (*statement <= 'Z')) ||
131 (*statement == '\\') || 258 (*statement == '\\') ||
132 (*statement == '/' ) || 259 (*statement == '/' ) ||
(...skipping 12 matching lines...) Expand all
145 return NULL; 272 return NULL;
146 *name++ = *statement++; 273 *name++ = *statement++;
147 } 274 }
148 275
149 /* Null terminate the filename. */ 276 /* Null terminate the filename. */
150 *name = '\0'; 277 *name = '\0';
151 278
152 return statement; 279 return statement;
153 } 280 }
154 281
282 static char
283 *parse_field_name(char *rest, field_item *field_table, field_item **field)
284 {
285 u_int32_t i;
286 u_int32_t field_name_len = 0;
287
288 assert(field_table != NULL);
289 assert(rest != NULL);
290 assert(field != NULL);
291
292 while(*(rest + field_name_len) != '=')
293 field_name_len++;
294
295 /* Parse the field name. */
296 for (i = 0; field_table[i].name != NULL; i++) {
297 if ((strlen(field_table[i].name) == field_name_len) &&
298 !strncmp(field_table[i].name,
299 rest,
300 field_name_len)) {
301
302 *field = &(field_table[i]);
303 rest = rest + field_name_len;
304 return rest;
305 }
306 }
307
308 /* Field wasn't found or a parse error occurred. */
309 return NULL;
310 }
311
312 static char
313 *parse_field_value(build_image_context *context,
314 char *rest,
315 field_item *field,
316 u_int32_t *value)
317 {
318 assert(rest != NULL);
319 assert(field != NULL);
320 assert((field->type != field_type_enum)
321 || (field->enum_table != NULL));
322
323 switch (field->type) {
324 case field_type_enum:
325 rest = parse_enum(context, rest, field->enum_table, value);
326 break;
327
328 case field_type_u32:
329 rest = parse_u32(rest, value);
330 break;
331
332 case field_type_u8:
333 rest = parse_u8(rest, value);
334 break;
335
336 default:
337 printf("Unexpected field type %d at line %d\n",
338 field->type, __LINE__);
339 rest = NULL;
340 break;
341 }
342
343 return rest;
344 }
345
346 static char *
347 parse_enum(build_image_context *context,
348 char *statement,
349 enum_item *table,
350 u_int32_t *val)
351 {
352 int i;
353 char *rest;
354 int e;
355
356 for (i = 0; table[i].name != NULL; i++) {
357 if (!strncmp(table[i].name, statement,
358 strlen(table[i].name))) {
359 /* Lookup the correct value for the token. */
360 e = context->bctlib.get_value(table[i].value,
361 val, context->bct);
362 if (e) {
363 printf("Error looking up token %d.\n", table[i].value);
364 printf("\"%s\" is not valid for this chip.\n",
365 table[i].name);
366 *val = -1;
367 }
368
369 rest = statement + strlen(table[i].name);
370 return rest;
371 }
372 }
373 return parse_u32(statement, val);
374
375 }
155 /* 376 /*
156 * parse_bootloader(): Processes commands to set a bootloader. 377 * parse_bootloader(): Processes commands to set a bootloader.
157 */ 378 */
158 static int parse_bootloader(build_image_context *context, 379 static int parse_bootloader(build_image_context *context,
159 parse_token token, 380 parse_token token,
160 char *rest) 381 char *rest)
161 { 382 {
162 char filename[MAX_BUFFER]; 383 char filename[MAX_BUFFER];
163 char e_state[MAX_STR_LEN]; 384 char e_state[MAX_STR_LEN];
164 u_int32_t load_addr; 385 u_int32_t load_addr;
165 u_int32_t entry_point; 386 u_int32_t entry_point;
166 387
167 assert(context != NULL); 388 assert(context != NULL);
168 assert(rest != NULL); 389 assert(rest != NULL);
169 390
391 if (context->generate_bct != 0)
392 return 0;
170 /* Parse the file name. */ 393 /* Parse the file name. */
171 rest = parse_filename(rest, filename, MAX_BUFFER); 394 rest = parse_filename(rest, filename, MAX_BUFFER);
172 if (rest == NULL) 395 if (rest == NULL)
173 return 1; 396 return 1;
174 397
175 PARSE_COMMA(1); 398 PARSE_COMMA(1);
176 399
177 /* Parse the load address. */ 400 /* Parse the load address. */
178 rest = parse_u32(rest, &load_addr); 401 rest = parse_u32(rest, &load_addr);
179 if (rest == NULL) 402 if (rest == NULL)
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 return 1; 444 return 1;
222 rest++; 445 rest++;
223 446
224 /* Parse the equals sign.*/ 447 /* Parse the equals sign.*/
225 if (*rest != '=') 448 if (*rest != '=')
226 return 1; 449 return 1;
227 rest++; 450 rest++;
228 451
229 /* Parse the value based on the field table. */ 452 /* Parse the value based on the field table. */
230 switch(token) { 453 switch(token) {
231 » » case token_attribute: 454 » case token_attribute:
232 » » » rest = parse_u32(rest, &value); 455 » » rest = parse_u32(rest, &value);
233 » » » break; 456 » » break;
457 » case token_dev_type:
458 » » rest = parse_enum(context, rest, s_devtype_table, &value);
459 » » break;
234 460
235 » » default: 461 » default:
236 » » /* Unknown token */ 462 » /* Unknown token */
237 » » » return 1; 463 » » return 1;
238 } 464 }
239 465
240 if (rest == NULL) 466 if (rest == NULL)
241 return 1; 467 return 1;
242 468
243 /* Store the result. */ 469 /* Store the result. */
244 return context_set_array(context, index, token, value); 470 return context_set_array(context, index, token, value);
245 } 471 }
246 472
247 /* 473 /*
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 PARSE_COMMA(1); 613 PARSE_COMMA(1);
388 614
389 rest = parse_end_state(rest, e_state, MAX_STR_LEN); 615 rest = parse_end_state(rest, e_state, MAX_STR_LEN);
390 if (rest == NULL) 616 if (rest == NULL)
391 return 1; 617 return 1;
392 if (strncmp(e_state, "Complete", strlen("Complete"))) 618 if (strncmp(e_state, "Complete", strlen("Complete")))
393 return 1; 619 return 1;
394 return 0; 620 return 0;
395 } 621 }
396 622
623 static int
624 parse_dev_param(build_image_context *context, parse_token token, char *rest)
625 {
626 u_int32_t i;
627 u_int32_t value;
628 field_item *field;
629 u_int32_t index;
630 parse_subfield_item *device_item = NULL;
631
632 assert(context != NULL);
633 assert(rest != NULL);
634
635 /* Parse the index. */
636 rest = parse_u32(rest, &index);
637 if (rest == NULL)
638 return 1;
639
640 /* Parse the closing bracket. */
641 if (*rest != ']')
642 return 1;
643 rest++;
644
645 /* Parse the following '.' */
646 if (*rest != '.')
647 return 1;
648 rest++;
649
650 /* Parse the device name. */
651 for (i = 0; s_device_type_table[i].prefix != NULL; i++) {
652 if (!strncmp(s_device_type_table[i].prefix,
653 rest, strlen(s_device_type_table[i].prefix))) {
654
655 device_item = &(s_device_type_table[i]);
656 rest = rest + strlen(s_device_type_table[i].prefix);
657
658 /* Parse the field name. */
659 rest = parse_field_name(rest,
660 s_device_type_table[i].field_table,
661 &field);
662 if (rest == NULL)
663 return 1;
664
665 /* Parse the equals sign.*/
666 if (*rest != '=')
667 return 1;
668 rest++;
669
670 /* Parse the value based on the field table. */
671 rest = parse_field_value(context, rest, field, &value);
672 if (rest == NULL)
673 return 1;
674 return device_item->process(context,
675 index, field->token, value);
676 }
677 }
678
679 return 1;
680
681 }
397 /* Return 0 on success, 1 on error */ 682 /* Return 0 on success, 1 on error */
398 static int 683 static int
399 process_statement(build_image_context *context, char *statement) 684 process_statement(build_image_context *context, char *statement)
400 { 685 {
401 int i; 686 int i;
402 char *rest; 687 char *rest;
403 688
404 for (i = 0; s_top_level_items[i].prefix != NULL; i++) { 689 for (i = 0; s_top_level_items[i].prefix != NULL; i++) {
405 if (!strncmp(s_top_level_items[i].prefix, statement, 690 if (!strncmp(s_top_level_items[i].prefix, statement,
406 strlen(s_top_level_items[i].prefix))) { 691 strlen(s_top_level_items[i].prefix))) {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 break; 803 break;
519 } 804 }
520 } 805 }
521 806
522 return; 807 return;
523 808
524 error: 809 error:
525 printf("Error parsing: %s\n", buffer); 810 printf("Error parsing: %s\n", buffer);
526 exit(1); 811 exit(1);
527 } 812 }
OLDNEW
« no previous file with comments | « parse.h ('k') | set.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698