diff options
Diffstat (limited to 'parse.c')
-rw-r--r-- | parse.c | 757 |
1 files changed, 273 insertions, 484 deletions
@@ -1,5 +1,5 @@ /** - * Copyright (c) 2011 NVIDIA Corporation. All rights reserved. + * Copyright (c) 2012 NVIDIA Corporation. All rights reserved. * * See file CREDITS for list of people who contributed to this * project. @@ -24,17 +24,7 @@ * parse.c - Parsing support for the cbootimage tool */ -/* - * TODO / Notes - * - Add doxygen commentary - * - Do we have endian issues to deal with? - * - Add support for device configuration data - * - Add support for bad blocks - * - Add support for different allocation modes/strategies - * - Add support for multiple BCTs in journal block - * - Add support for other missing features. - */ - +#include <ctype.h> #include "parse.h" #include "cbootimage.h" #include "data_layout.h" @@ -51,11 +41,16 @@ * A SetXXX() function may not call any parseing functions. */ -static char *parse_u32(char *statement, u_int32_t *val); -static char *parse_u8(char *statement, u_int32_t *val); -static char *parse_filename(char *statement, char *name, int chars_remaining); +static int +set_array(build_image_context *context, + u_int32_t index, + parse_token token, + u_int32_t value); +static char *parse_u32(char *str, u_int32_t *val); +static char *parse_u8(char *str, u_int32_t *val); +static char *parse_filename(char *str, char *name, int chars_remaining); static char *parse_enum(build_image_context *context, - char *statement, + char *str, enum_item *table, u_int32_t *val); static char @@ -73,269 +68,28 @@ static int parse_value_u32(build_image_context *context, parse_token token, char *rest); static int parse_bct_file(build_image_context *context, parse_token token, char *rest); -static int -parse_addon(build_image_context *context, parse_token token, char *rest); -static char *parse_string(char *statement, char *uname, int chars_remaining); static char -*parse_end_state(char *statement, char *uname, int chars_remaining); +*parse_end_state(char *str, char *uname, int chars_remaining); static int parse_dev_param(build_image_context *context, parse_token token, char *rest); static int parse_sdram_param(build_image_context *context, parse_token token, char *rest); -static int process_statement(build_image_context *context, char *statement); - -enum_item s_devtype_table[] = -{ - { "NvBootDevType_Sdmmc", nvbct_lib_id_dev_type_sdmmc }, - { "NvBootDevType_Spi", nvbct_lib_id_dev_type_spi }, - { "NvBootDevType_Nand", nvbct_lib_id_dev_type_nand }, - { "Sdmmc", nvbct_lib_id_dev_type_sdmmc }, - { "Spi", nvbct_lib_id_dev_type_spi }, - { "Nand", nvbct_lib_id_dev_type_nand }, - - { NULL, 0 } -}; - -enum_item s_sdmmc_data_width_table[] = -{ - { - "NvBootSdmmcDataWidth_4Bit", - nvbct_lib_id_sdmmc_data_width_4bit - }, - { - "NvBootSdmmcDataWidth_8Bit", - nvbct_lib_id_sdmmc_data_width_8bit - }, - { "4Bit", nvbct_lib_id_sdmmc_data_width_4bit }, - { "8Bit", nvbct_lib_id_sdmmc_data_width_8bit }, - { NULL, 0 } -}; - -enum_item s_spi_clock_source_table[] = -{ - { - "NvBootSpiClockSource_PllPOut0", - nvbct_lib_id_spi_clock_source_pllp_out0 - }, - { - "NvBootSpiClockSource_PllCOut0", - nvbct_lib_id_spi_clock_source_pllc_out0 - }, - { - "NvBootSpiClockSource_PllMOut0", - nvbct_lib_id_spi_clock_source_pllm_out0 - }, - { - "NvBootSpiClockSource_ClockM", - nvbct_lib_id_spi_clock_source_clockm - }, - - { "ClockSource_PllPOut0", nvbct_lib_id_spi_clock_source_pllp_out0 }, - { "ClockSource_PllCOut0", nvbct_lib_id_spi_clock_source_pllc_out0 }, - { "ClockSource_PllMOut0", nvbct_lib_id_spi_clock_source_pllm_out0 }, - { "ClockSource_ClockM", nvbct_lib_id_spi_clock_source_clockm }, - - - { "PllPOut0", nvbct_lib_id_spi_clock_source_pllp_out0 }, - { "PllCOut0", nvbct_lib_id_spi_clock_source_pllc_out0 }, - { "PllMOut0", nvbct_lib_id_spi_clock_source_pllm_out0 }, - { "ClockM", nvbct_lib_id_spi_clock_source_clockm }, - - { NULL, 0 } -}; - -enum_item s_nvboot_memory_type_table[] = -{ - { "NvBootMemoryType_None", nvbct_lib_id_memory_type_none }, - { "NvBootMemoryType_Ddr2", nvbct_lib_id_memory_type_ddr2 }, - { "NvBootMemoryType_Ddr", nvbct_lib_id_memory_type_ddr }, - { "NvBootMemoryType_LpDdr2", nvbct_lib_id_memory_type_lpddr2 }, - { "NvBootMemoryType_LpDdr", nvbct_lib_id_memory_type_lpddr }, - - { "None", nvbct_lib_id_memory_type_none }, - { "Ddr2", nvbct_lib_id_memory_type_ddr2 }, - { "Ddr", nvbct_lib_id_memory_type_ddr }, - { "LpDdr2", nvbct_lib_id_memory_type_lpddr2 }, - { "LpDdr", nvbct_lib_id_memory_type_lpddr }, - - { NULL, 0 } -}; - -#define TOKEN(name) \ - token_##name, nvbct_lib_id_sdram_##name, field_type_u32, NULL - -field_item s_sdram_field_table[] = -{ - { "MemoryType", token_memory_type, nvbct_lib_id_sdram_memory_type, - field_type_enum, s_nvboot_memory_type_table }, - - { "PllMChargePumpSetupControl", TOKEN(pllm_charge_pump_setup_ctrl) }, - { "PllMLoopFilterSetupControl", TOKEN(pllm_loop_filter_setup_ctrl) }, - { "PllMInputDivider", TOKEN(pllm_input_divider) }, - { "PllMFeedbackDivider", TOKEN(pllm_feedback_divider) }, - { "PllMPostDivider", TOKEN(pllm_post_divider) }, - { "PllMStableTime", TOKEN(pllm_stable_time) }, - { "EmcClockDivider", TOKEN(emc_clock_divider) }, - { "EmcAutoCalInterval", TOKEN(emc_auto_cal_interval) }, - { "EmcAutoCalConfig", TOKEN(emc_auto_cal_config) }, - { "EmcAutoCalWait", TOKEN(emc_auto_cal_wait) }, - { "EmcPinProgramWait", TOKEN(emc_pin_program_wait) }, - { "EmcRc", TOKEN(emc_rc) }, - { "EmcRfc", TOKEN(emc_rfc) }, - { "EmcRas", TOKEN(emc_ras) }, - { "EmcRp", TOKEN(emc_rp) }, - { "EmcR2w", TOKEN(emc_r2w) }, - { "EmcW2r", TOKEN(emc_w2r) }, - { "EmcR2p", TOKEN(emc_r2p) }, - { "EmcW2p", TOKEN(emc_w2p) }, - { "EmcRrd", TOKEN(emc_rrd) }, - { "EmcRdRcd", TOKEN(emc_rd_rcd) }, - { "EmcWrRcd", TOKEN(emc_wr_rcd) }, - { "EmcRext", TOKEN(emc_rext) }, - { "EmcWdv", TOKEN(emc_wdv) }, - { "EmcQUseExtra", TOKEN(emc_quse_extra) }, - { "EmcQUse", TOKEN(emc_quse) }, - { "EmcQRst", TOKEN(emc_qrst) }, - { "EmcQSafe", TOKEN(emc_qsafe) }, - { "EmcRdv", TOKEN(emc_rdv) }, - { "EmcRefresh", TOKEN(emc_refresh) }, - { "EmcBurstRefreshNum", TOKEN(emc_burst_refresh_num) }, - { "EmcPdEx2Wr", TOKEN(emc_pdex2wr) }, - { "EmcPdEx2Rd", TOKEN(emc_pdex2rd) }, - { "EmcPChg2Pden", TOKEN(emc_pchg2pden) }, - { "EmcAct2Pden", TOKEN(emc_act2pden) }, - { "EmcAr2Pden", TOKEN(emc_ar2pden) }, - { "EmcRw2Pden", TOKEN(emc_rw2pden) }, - { "EmcTxsr", TOKEN(emc_txsr) }, - { "EmcTcke", TOKEN(emc_tcke) }, - { "EmcTfaw", TOKEN(emc_tfaw) }, - { "EmcTrpab", TOKEN(emc_trpab) }, - { "EmcTClkStable", TOKEN(emc_tclkstable) }, - { "EmcTClkStop", TOKEN(emc_tclkstop) }, - { "EmcTRefBw", TOKEN(emc_trefbw) }, - { "EmcFbioCfg1", TOKEN(emc_fbio_cfg1) }, - { "EmcFbioDqsibDlyMsb", TOKEN(emc_fbio_dqsib_dly_msb) }, - { "EmcFbioDqsibDly", TOKEN(emc_fbio_dqsib_dly) }, - { "EmcFbioQuseDlyMsb", TOKEN(emc_fbio_quse_dly_msb) }, - { "EmcFbioQuseDly", TOKEN(emc_fbio_quse_dly) }, - { "EmcFbioCfg5", TOKEN(emc_fbio_cfg5) }, - { "EmcFbioCfg6", TOKEN(emc_fbio_cfg6) }, - { "EmcFbioSpare", TOKEN(emc_fbio_spare) }, - { "EmcMrsResetDllWait", TOKEN(emc_mrs_reset_dll_wait) }, - { "EmcMrsResetDll", TOKEN(emc_mrs_reset_dll) }, - { "EmcMrsDdr2DllReset", TOKEN(emc_mrs_ddr2_dll_reset) }, - { "EmcMrs", TOKEN(emc_mrs) }, - { "EmcEmrsEmr2", TOKEN(emc_emrs_emr2) }, - { "EmcEmrsEmr3", TOKEN(emc_emrs_emr3) }, - { "EmcEmrsDdr2DllEnable", TOKEN(emc_emrs_ddr2_dll_enable) }, - { "EmcEmrsDdr2OcdCalib", TOKEN(emc_emrs_ddr2_ocd_calib) }, - { "EmcEmrs", TOKEN(emc_emrs) }, - { "EmcMrw1", TOKEN(emc_mrw1) }, - { "EmcMrw2", TOKEN(emc_mrw2) }, - { "EmcMrw3", TOKEN(emc_mrw3) }, - { "EmcMrwResetCommand", TOKEN(emc_mrw_reset_command) }, - { "EmcMrwResetNInitWait", TOKEN(emc_mrw_reset_ninit_wait) }, - { "EmcAdrCfg1", TOKEN(emc_adr_cfg1) }, - { "EmcAdrCfg", TOKEN(emc_adr_cfg) }, - { "McEmemCfg", TOKEN(mc_emem_Cfg) }, - { "McLowLatencyConfig", TOKEN(mc_lowlatency_config) }, - { "EmcCfg2", TOKEN(emc_cfg2) }, - { "EmcCfgDigDll", TOKEN(emc_cfg_dig_dll) }, - { "EmcCfgClktrim0", TOKEN(emc_cfg_clktrim0) }, - { "EmcCfgClktrim1", TOKEN(emc_cfg_clktrim1) }, - { "EmcCfgClktrim2", TOKEN(emc_cfg_clktrim2) }, - { "EmcCfg", TOKEN(emc_cfg) }, - { "EmcDbg", TOKEN(emc_dbg) }, - { "AhbArbitrationXbarCtrl", TOKEN(ahb_arbitration_xbar_ctrl) }, - { "EmcDllXformDqs", TOKEN(emc_dll_xform_dqs) }, - { "EmcDllXformQUse", TOKEN(emc_dll_xform_quse) }, - { "WarmBootWait", TOKEN(warm_boot_wait) }, - { "EmcCttTermCtrl", TOKEN(emc_ctt_term_ctrl) }, - { "EmcOdtWrite", TOKEN(emc_odt_write) }, - { "EmcOdtRead", TOKEN(emc_odt_read) }, - { "EmcZcalRefCnt", TOKEN(emc_zcal_ref_cnt) }, - { "EmcZcalWaitCnt", TOKEN(emc_zcal_wait_cnt) }, - { "EmcZcalMrwCmd", TOKEN(emc_zcal_mrw_cmd) }, - { "EmcMrwZqInitDev0", TOKEN(emc_mrw_zq_init_dev0) }, - { "EmcMrwZqInitDev1", TOKEN(emc_mrw_zq_init_dev1) }, - { "EmcMrwZqInitWait", TOKEN(emc_mrw_zq_init_wait) }, - { "EmcDdr2Wait", TOKEN(emc_ddr2_wait) }, - { "PmcDdrPwr", TOKEN(pmc_ddr_pwr) }, - { "ApbMiscGpXm2CfgAPadCtrl", TOKEN(apb_misc_gp_xm2cfga_pad_ctrl) }, - { "ApbMiscGpXm2CfgCPadCtrl2", TOKEN(apb_misc_gp_xm2cfgc_pad_ctrl2) }, - { "ApbMiscGpXm2CfgCPadCtrl", TOKEN(apb_misc_gp_xm2cfgc_pad_ctrl) }, - { "ApbMiscGpXm2CfgDPadCtrl2", TOKEN(apb_misc_gp_xm2cfgd_pad_ctrl2) }, - { "ApbMiscGpXm2CfgDPadCtrl", TOKEN(apb_misc_gp_xm2cfgd_pad_ctrl) }, - { "ApbMiscGpXm2ClkCfgPadCtrl", TOKEN(apb_misc_gp_xm2clkcfg_Pad_ctrl)}, - { "ApbMiscGpXm2CompPadCtrl", TOKEN(apb_misc_gp_xm2comp_pad_ctrl) }, - { "ApbMiscGpXm2VttGenPadCtrl", TOKEN(apb_misc_gp_xm2vttgen_pad_ctrl)}, - { NULL, 0, 0, 0, NULL } -}; - -#undef TOKEN -#define TOKEN(name) \ - token_##name, nvbct_lib_id_nand_##name, field_type_u32, NULL +static int process_statement(build_image_context *context, + char *str, + u_int8_t simple_parse); -field_item s_nand_table[] = +static parse_item parse_simple_items[] = { - { "ClockDivider", TOKEN(clock_divider) }, - /* Note: NandTiming2 must appear before NandTiming, because NandTiming - * is a prefix of NandTiming2 and would otherwise match first. - */ - { "NandTiming2", TOKEN(nand_timing2) }, - { "NandTiming", TOKEN(nand_timing) }, - { "BlockSizeLog2", TOKEN(block_size_log2) }, - { "PageSizeLog2", TOKEN(page_size_log2) }, - { NULL, 0, 0, 0, NULL } -}; - -#undef TOKEN -#define TOKEN(name) \ - token_##name, nvbct_lib_id_sdmmc_##name, field_type_u32, NULL - -field_item s_sdmmc_table[] = -{ - { "ClockDivider", TOKEN(clock_divider) }, - { "DataWidth", - token_data_width, - nvbct_lib_id_sdmmc_data_width, - field_type_enum, - s_sdmmc_data_width_table }, - { "MaxPowerClassSupported", TOKEN(max_power_class_supported) }, - { NULL, 0, 0, 0, NULL } -}; - -#undef TOKEN -#define TOKEN(name) \ - token_##name, nvbct_lib_id_spiflash_##name, field_type_u8, NULL - -field_item s_spiflash_table[] = -{ - { "ReadCommandTypeFast", TOKEN(read_command_type_fast) }, - { "ClockDivider", TOKEN(clock_divider) }, - { "ClockSource", - token_clock_source, - nvbct_lib_id_spiflash_clock_source, - field_type_enum, - s_spi_clock_source_table }, - { NULL, 0, 0, 0, NULL } -}; - -static parse_subfield_item s_device_type_table[] = -{ - { "NandParams.", token_nand_params, - s_nand_table, set_nand_param }, - { "SdmmcParams.", token_sdmmc_params, - s_sdmmc_table, set_sdmmc_param }, - { "SpiFlashParams.", token_spiflash_params, - s_spiflash_table, set_spiflash_param }, - - { NULL, 0, NULL } + { "Bctfile=", token_bct_file, parse_bct_file }, + { "BootLoader=", token_bootloader, parse_bootloader }, + { "Redundancy=", token_redundancy, parse_value_u32 }, + { "Bctcopy=", token_bct_copy, parse_value_u32 }, + { "Version=", token_version, parse_value_u32 }, + { NULL, 0, NULL } /* Must be last */ }; -static parse_item s_top_level_items[] = -{ +static parse_item s_top_level_items[] = { { "Bctfile=", token_bct_file, parse_bct_file }, { "Attribute=", token_attribute, parse_value_u32 }, { "Attribute[", token_attribute, parse_array }, @@ -349,56 +103,59 @@ static parse_item s_top_level_items[] = { "Redundancy=", token_redundancy, parse_value_u32 }, { "Bctcopy=", token_bct_copy, parse_value_u32 }, { "Version=", token_version, parse_value_u32 }, - { "AddOn[", token_addon, parse_addon }, { NULL, 0, NULL } /* Must be last */ }; /* Macro to simplify parser code a bit. */ #define PARSE_COMMA(x) if (*rest != ',') return (x); rest++ -/* This parsing code was initially borrowed from nvcamera_config_parse.c. */ -/* Returns the address of the character after the parsed data. */ +/* + * Parse the given string and find the u32 dec/hex number. + * + * @param str String to parse + * @param val Returns value that was parsed + * @return the remainder of the string after the number was parsed + */ static char * -parse_u32(char *statement, u_int32_t *val) +parse_u32(char *str, u_int32_t *val) { u_int32_t value = 0; + u_int32_t digit; - while (*statement=='0') { - statement++; - } + while (*str == '0') + str++; - if (*statement=='x' || *statement=='X') { - statement++; - while (((*statement >= '0') && (*statement <= '9')) || - ((*statement >= 'a') && (*statement <= 'f')) || - ((*statement >= 'A') && (*statement <= 'F'))) { + if (tolower(*str) == 'x') { + str++; + while (isxdigit(*str)) { value *= 16; - if ((*statement >= '0') && (*statement <= '9')) { - value += (*statement - '0'); - } else if ((*statement >= 'A') && - (*statement <= 'F')) { - value += ((*statement - 'A')+10); - } else { - value += ((*statement - 'a')+10); - } - statement++; + digit = tolower(*str); + value += digit <= '9' ? digit - '0' : digit - 'a' + 10; + str++; } } else { - while (*statement >= '0' && *statement <= '9') { - value = value*10 + (*statement - '0'); - statement++; + while (*str >= '0' && *str <= '9') { + value = value*10 + (*str - '0'); + str++; } } *val = value; - return statement; + return str; } -char * -parse_u8(char *statement, u_int32_t *val) +/* + * Parse the given string and find the u8 dec/hex number. + * + * @param str String to parse + * @param val Returns value that was parsed + * @return the remainder of the string after the number was parsed + */ +static char * +parse_u8(char *str, u_int32_t *val) { char *retval; - retval = parse_u32(statement, val); + retval = parse_u32(str, val); if (*val > 0xff) { printf("Warning: Parsed 8-bit value that exceeded 8-bits.\n"); @@ -410,38 +167,46 @@ parse_u8(char *statement, u_int32_t *val) } -/* This parsing code was initially borrowed from nvcamera_config_parse.c. */ -/* Returns the address of the character after the parsed data. */ +/* + * Parse the given string and find the file name then + * return the rest of the string. + * + * @param str String to parse + * @param name Returns the filename that was parsed + * @param chars_remaining The maximum length of filename + * @return the remainder of the string after the name was parsed + */ static char * -parse_filename(char *statement, char *name, int chars_remaining) +parse_filename(char *str, char *name, int chars_remaining) { - while (((*statement >= '0') && (*statement <= '9')) || - ((*statement >= 'a') && (*statement <= 'z')) || - ((*statement >= 'A') && (*statement <= 'Z')) || - (*statement == '\\') || - (*statement == '/' ) || - (*statement == '~' ) || - (*statement == '_' ) || - (*statement == '-' ) || - (*statement == '+' ) || - (*statement == ':' ) || - (*statement == '.' )) { - /* Check if the filename buffer is out of space, preserving one - * character to null terminate the string. - */ + /* + * Check if the filename buffer is out of space, preserving one + * character to null terminate the string. + */ + while (isalnum(*str) || strchr("\\/~_-+:.", *str)) { + chars_remaining--; if (chars_remaining < 1) return NULL; - *name++ = *statement++; + *name++ = *str++; } /* Null terminate the filename. */ *name = '\0'; - return statement; + return str; } +/* + * Parse the given string and find the match field name listed + * in field table. + * + * @param rest String to parse + * @param field_table The field table to parse + * @param field Returns the field item that was parsed + * @return NULL or the remainder of the string after the field item was parsed + */ static char *parse_field_name(char *rest, field_item *field_table, field_item **field) { @@ -452,7 +217,7 @@ static char assert(rest != NULL); assert(field != NULL); - while(*(rest + field_name_len) != '=') + while (rest[field_name_len] != '=') field_name_len++; /* Parse the field name. */ @@ -472,8 +237,17 @@ static char return NULL; } +/* + * Parse the value based on the field table + * + * @param context The main context pointer + * @param rest String to parse + * @param field Field item to parse + * @param value Returns the value that was parsed + * @return the remainder of the string after the value was parsed + */ static char -*parse_field_value(build_image_context *context, +*parse_field_value(build_image_context *context, char *rest, field_item *field, u_int32_t *value) @@ -506,38 +280,45 @@ static char return rest; } +/* + * Parse the given string and find the match enum item listed + * in table. + * + * @param context The main context pointer + * @param str String to parse + * @param table Enum item table to parse + * @param value Returns the value that was parsed + * @return the remainder of the string after the item was parsed + */ static char * parse_enum(build_image_context *context, - char *statement, + char *str, enum_item *table, u_int32_t *val) { int i; char *rest; - int e; for (i = 0; table[i].name != NULL; i++) { - if (!strncmp(table[i].name, statement, + if (!strncmp(table[i].name, str, strlen(table[i].name))) { - /* Lookup the correct value for the token. */ - e = context->bctlib.get_value(table[i].value, - val, context->bct); - if (e) { - printf("Error looking up token %d.\n", table[i].value); - printf("\"%s\" is not valid for this chip.\n", - table[i].name); - *val = -1; - } - - rest = statement + strlen(table[i].name); - return rest; + *val = table[i].value; + rest = str + strlen(table[i].name); + return rest; } } - return parse_u32(statement, val); + return parse_u32(str, val); } + /* - * parse_bootloader(): Processes commands to set a bootloader. + * Parse the given string and find the bootloader file name, load address and + * entry point information then call set_bootloader function. + * + * @param context The main context pointer + * @param token The parse token value + * @param rest String to parse + * @return 0 and 1 for success and failure */ static int parse_bootloader(build_image_context *context, parse_token token, @@ -586,7 +367,12 @@ static int parse_bootloader(build_image_context *context, } /* - * parse_array(): Processes commands to set an array value. + * Parse the given string and find the array items in config file. + * + * @param context The main context pointer + * @param token The parse token value + * @param rest String to parse + * @return 0 and 1 for success and failure */ static int parse_array(build_image_context *context, parse_token token, char *rest) @@ -613,12 +399,15 @@ parse_array(build_image_context *context, parse_token token, char *rest) rest++; /* Parse the value based on the field table. */ - switch(token) { + switch (token) { case token_attribute: rest = parse_u32(rest, &value); break; case token_dev_type: - rest = parse_enum(context, rest, s_devtype_table, &value); + rest = parse_enum(context, + rest, + s_devtype_table_t20, + &value); break; default: @@ -630,11 +419,56 @@ parse_array(build_image_context *context, parse_token token, char *rest) return 1; /* Store the result. */ - return context_set_array(context, index, token, value); + return set_array(context, index, token, value); } /* - * parse_value_u32(): General handler for setting u_int32_t values in config files. + * Call hw interface to set the value for array item in bct such as device + * type and bootloader attribute. + * + * @param context The main context pointer + * @param index The index for array + * @param token The parse token value + * @param value The value to set + * @return 0 and -ENODATA for success and failure + */ + +static int +set_array(build_image_context *context, + u_int32_t index, + parse_token token, + u_int32_t value) +{ + int err = 0; + + assert(context != NULL); + + switch (token) { + case token_attribute: + err = g_bct_parse_interf->setbl_param(index, + token_bl_attribute, + &value, + context->bct); + break; + case token_dev_type: + err = g_bct_parse_interf->set_dev_param(context, + index, + token_dev_type, + value); + break; + default: + break; + } + return err; +} + +/* + * General handler for setting u_int32_t values in config files. + * + * @param context The main context pointer + * @param token The parse token value + * @param rest String to parse + * @return 0 and 1 for success and failure */ static int parse_value_u32(build_image_context *context, parse_token token, @@ -652,6 +486,14 @@ static int parse_value_u32(build_image_context *context, return context_set_value(context, token, value); } +/* + * Parse the given string and find the bct file name. + * + * @param context The main context pointer + * @param token The parse token value + * @param rest String to parse + * @return 0 and 1 for success and failure + */ static int parse_bct_file(build_image_context *context, parse_token token, char *rest) { @@ -669,120 +511,33 @@ parse_bct_file(build_image_context *context, parse_token token, char *rest) context->bct_filename = filename; /* Read the bct file to buffer */ read_bct_file(context); + update_context(context); return 0; } static char * -parse_string(char *statement, char *uname, int chars_remaining) -{ - memset(uname, 0, chars_remaining); - while (((*statement >= '0') && (*statement <= '9')) || - ((*statement >= 'A') && (*statement <= 'Z')) || - ((*statement >= 'a') && (*statement <= 'z'))) { - - *uname++ = *statement++; - if (--chars_remaining < 0) { - printf("String length beyond the boundary!!!"); - return NULL; - } - } - *uname = '\0'; - return statement; -} - -static char * -parse_end_state(char *statement, char *uname, int chars_remaining) +parse_end_state(char *str, char *uname, int chars_remaining) { - while (((*statement >= 'a') && (*statement <= 'z')) || - ((*statement >= 'A') && (*statement <= 'Z'))) { + while (isalpha(*str)) { - *uname++ = *statement++; + *uname++ = *str++; if (--chars_remaining < 0) return NULL; } *uname = '\0'; - return statement; -} - - -/* Parse the addon component */ -static int -parse_addon(build_image_context *context, parse_token token, char *rest) -{ - char filename[MAX_BUFFER]; - char u_name[4]; - char e_state[MAX_STR_LEN]; - u_int32_t index; - u_int32_t item_attr; - u_int32_t others; - char other_str[MAX_STR_LEN]; - - assert(context != NULL); - assert(rest != NULL); - - /* Parse the index. */ - rest = parse_u32(rest, &index); - if (rest == NULL) - return 1; - - /* Parse the closing bracket. */ - if (*rest != ']') - return 1; - rest++; - - /* Parse the equals sign.*/ - if (*rest != '=') - return 1; - rest++; - - rest = parse_filename(rest, filename, MAX_BUFFER); - if (rest == NULL) - return 1; - if (set_addon_filename(context, filename, index) != 0) - return 1; - - PARSE_COMMA(1); - - rest = parse_string(rest, u_name, 3); - if (rest == NULL) { - printf("Unique name should be 3 characters.\n"); - return 1; - } - if (set_unique_name(context, u_name, index) != 0) - return 1; - - PARSE_COMMA(1); - - rest = parse_u32(rest, &item_attr); - if (rest == NULL) - return 1; - if (set_addon_attr(context, item_attr, index) != 0) - return 1; - - PARSE_COMMA(1); - - if (*rest == '0' && (*(rest + 1) == 'x' ||*(rest + 1) == 'X')) { - rest = parse_u32(rest, &others); - if (set_other_field(context, NULL, others, index) != 0) - return 1; - } else { - rest = parse_string(rest, other_str, 16); - if (set_other_field(context, other_str, 0, index) != 0) - return 1; - } - if (rest == NULL) - return 1; - - PARSE_COMMA(1); - - rest = parse_end_state(rest, e_state, MAX_STR_LEN); - if (rest == NULL) - return 1; - if (strncmp(e_state, "Complete", strlen("Complete"))) - return 1; - return 0; + return str; } +/* + * Parse the given string and find device parameter listed in device table + * and value for this device parameter. If match, call the corresponding + * function in the table to set device parameter. + * + * @param context The main context pointer + * @param token The parse token value + * @param rest String to parse + * @return 0 and 1 for success and failure + */ static int parse_dev_param(build_image_context *context, parse_token token, char *rest) { @@ -790,11 +545,16 @@ parse_dev_param(build_image_context *context, parse_token token, char *rest) u_int32_t value; field_item *field; u_int32_t index; + parse_subfield_item *device_type_table; parse_subfield_item *device_item = NULL; - + assert(context != NULL); assert(rest != NULL); + if (context->boot_data_version == NVBOOT_BOOTDATA_VERSION(3, 1)) + device_type_table = s_device_type_table_t30; + else + device_type_table = s_device_type_table_t20; /* Parse the index. */ rest = parse_u32(rest, &index); if (rest == NULL) @@ -811,16 +571,16 @@ parse_dev_param(build_image_context *context, parse_token token, char *rest) rest++; /* Parse the device name. */ - for (i = 0; s_device_type_table[i].prefix != NULL; i++) { - if (!strncmp(s_device_type_table[i].prefix, - rest, strlen(s_device_type_table[i].prefix))) { + for (i = 0; device_type_table[i].prefix != NULL; i++) { + if (!strncmp(device_type_table[i].prefix, + rest, strlen(device_type_table[i].prefix))) { - device_item = &(s_device_type_table[i]); - rest = rest + strlen(s_device_type_table[i].prefix); + device_item = &(device_type_table[i]); + rest = rest + strlen(device_type_table[i].prefix); /* Parse the field name. */ rest = parse_field_name(rest, - s_device_type_table[i].field_table, + device_type_table[i].field_table, &field); if (rest == NULL) return 1; @@ -838,11 +598,18 @@ parse_dev_param(build_image_context *context, parse_token token, char *rest) index, field->token, value); } } - - return 1; - + return 1; } +/* + * Parse the given string and find sdram parameter and value in config + * file. If match, call the corresponding function set the sdram parameter. + * + * @param context The main context pointer + * @param token The parse token value + * @param rest String to parse + * @return 0 and 1 for success and failure + */ static int parse_sdram_param(build_image_context *context, parse_token token, char *rest) { @@ -869,7 +636,10 @@ parse_sdram_param(build_image_context *context, parse_token token, char *rest) rest++; /* Parse the field name. */ - rest = parse_field_name(rest, s_sdram_field_table, &field); + if (context->boot_data_version == NVBOOT_BOOTDATA_VERSION(3, 1)) + rest = parse_field_name(rest, s_sdram_field_table_t30, &field); + else + rest = parse_field_name(rest, s_sdram_field_table_t20, &field); if (rest == NULL) return 1; @@ -884,23 +654,42 @@ parse_sdram_param(build_image_context *context, parse_token token, char *rest) return 1; /* Store the result. */ - return set_sdram_param(context, index, field->token, value); - + return g_bct_parse_interf->set_sdram_param(context, + index, + field->token, + value); } -/* Return 0 on success, 1 on error */ + +/* + * Compare the given string with item listed in table. + * Execute the proper process function if match. + * + * @param context The main context pointer + * @param str String to parse + * @param simple_parse Simple parse flag + * @return 0 and 1 for success and failure + */ static int -process_statement(build_image_context *context, char *statement) +process_statement(build_image_context *context, + char *str, + u_int8_t simple_parse) { int i; char *rest; + parse_item *cfg_parse_item; + + if (simple_parse == 0) + cfg_parse_item = s_top_level_items; + else + cfg_parse_item = parse_simple_items; - for (i = 0; s_top_level_items[i].prefix != NULL; i++) { - if (!strncmp(s_top_level_items[i].prefix, statement, - strlen(s_top_level_items[i].prefix))) { - rest = statement + strlen(s_top_level_items[i].prefix); + for (i = 0; cfg_parse_item[i].prefix != NULL; i++) { + if (!strncmp(cfg_parse_item[i].prefix, str, + strlen(cfg_parse_item[i].prefix))) { + rest = str + strlen(cfg_parse_item[i].prefix); - return s_top_level_items[i].process(context, - s_top_level_items[i].token, + return cfg_parse_item[i].process(context, + cfg_parse_item[i].token, rest); } } @@ -909,13 +698,18 @@ process_statement(build_image_context *context, char *statement) return 1; } -/* Note: Basic parsing borrowed from nvcamera_config.c */ -void process_config_file(build_image_context *context) +/* + * The main function parse the config file. + * + * @param context The main context pointer + * @param simple_parse Simple parse flag + */ +void process_config_file(build_image_context *context, u_int8_t simple_parse) { char buffer[MAX_BUFFER]; int space = 0; char current; - u_int8_t c_eol_comment_start = 0; // True after first slash + u_int8_t c_eol_comment_start = 0; /* True after first slash */ u_int8_t comment = 0; u_int8_t string = 0; u_int8_t equal_encounter = 0; @@ -923,7 +717,7 @@ void process_config_file(build_image_context *context) assert(context != NULL); assert(context->config_file != NULL); - while ((current = fgetc(context->config_file)) !=EOF) { + while ((current = fgetc(context->config_file)) != EOF) { if (space >= (MAX_BUFFER-1)) { /* if we exceeded the max buffer size, it is likely due to a missing semi-colon at the end of a line */ @@ -950,30 +744,28 @@ void process_config_file(build_image_context *context) if (!string && !comment) { buffer[space++] = '\0'; - /* Process a statement. */ - if (process_statement(context, buffer)) { - goto error; - } + if (process_statement(context, + buffer, + simple_parse)) + goto error; space = 0; equal_encounter = 0; - } else if (string) { + } else if (string) buffer[space++] = current; - } break; case '/': if (!string && !comment) { if (c_eol_comment_start) { - /* EOL comment started. */ + /* EOL comment started. */ comment = 1; c_eol_comment_start = 0; } else { /* Potential start of eol comment. */ c_eol_comment_start = 1; } - } else if (!comment) { + } else if (!comment) buffer[space++] = current; - } break; /* ignore whitespace. uses fallthrough */ @@ -984,28 +776,25 @@ void process_config_file(build_image_context *context) c_eol_comment_start = 0; case ' ': case '\t': - if (string) { + if (string) buffer[space++] = current; - } break; case '#': - if (!string) { + if (!string) comment = 1; - } else { + else buffer[space++] = current; - } break; default: if (!comment) { buffer[space++] = current; if (current == '=') { - if (!equal_encounter) { + if (!equal_encounter) equal_encounter = 1; - } else { + else goto error; - } } } break; |