| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |