diff options
-rw-r--r-- | pcilib/unit.h | 4 | ||||
-rw-r--r-- | pcilib/views.c | 233 | ||||
-rw-r--r-- | pcilib/xml.c | 3 | ||||
-rw-r--r-- | pcitool/cli.c | 52 |
4 files changed, 114 insertions, 178 deletions
diff --git a/pcilib/unit.h b/pcilib/unit.h index f9991f1..4a99f5b 100644 --- a/pcilib/unit.h +++ b/pcilib/unit.h @@ -3,6 +3,8 @@ #include "pcilib.h" +#define PCILIB_MAX_TRANSFORMS_PER_UNIT 16 + typedef struct pcilib_unit_s pcilib_unit_t; typedef struct pcilib_transform_unit_s pcilib_transform_unit_t; @@ -19,7 +21,7 @@ struct pcilib_transform_unit_s{ */ struct pcilib_unit_s{ char* name; - pcilib_transform_unit_t* other_units; + pcilib_transform_unit_t other_units[PCILIB_MAX_TRANSFORMS_PER_UNIT]; }; /** diff --git a/pcilib/views.c b/pcilib/views.c index 2a0969c..86675f5 100644 --- a/pcilib/views.c +++ b/pcilib/views.c @@ -9,73 +9,6 @@ #include "unit.h" /** - * - * replace a substring within a string by another - * @param[in] txt - the string to be modified - *@param[in] before - the substring in the string that will be replaced - *@param[in] after - the new value of before substring - *@return the modified txt string - */ -static char* -pcilib_view_formula_replace (const char *txt, const char *before, const char *after) -{ - const char *pos; - char *return_txt; - size_t pos_return_txt; - size_t len; - size_t allocated_size; - - /*get the first occurence of before. then we need one time to be out of the loop to correctly set the diverses varaibles (malloc instead of realloc notably)*/ - pos = strstr (txt, before); - - if (pos == NULL) - { - pcilib_warning("problem with a formula"); - } - - /* get the position of this occurence*/ - len = (size_t)pos - (size_t)txt; - allocated_size = len + strlen (after) + 1; - return_txt = malloc (allocated_size); - pos_return_txt = 0; - - /* we copy there the in a newly allocated string the start of txt before the "before" occurence, and then we copy after instead*/ - strncpy (return_txt + pos_return_txt, txt, len); - pos_return_txt += len; - txt = pos + strlen (before); - - len = strlen (after); - strncpy (return_txt + pos_return_txt, after, len); - pos_return_txt += len; - - /* we then iterate with the same principle to all occurences of before*/ - pos = strstr (txt, before); - while (pos != NULL) - { - len = (size_t)pos - (size_t)txt; - allocated_size += len + strlen (after); - return_txt = (char *)realloc (return_txt, allocated_size); - - strncpy (return_txt + pos_return_txt, txt, len); - pos_return_txt += len; - - txt = pos + strlen (before); - - len = strlen (after); - strncpy (return_txt + pos_return_txt, after, len); - pos_return_txt += len; - pos = strstr (txt, before); - } - /* put the rest of txt string at the end*/ - len = strlen (txt) + 1; - allocated_size += len; - return_txt = realloc (return_txt, allocated_size); - strncpy (return_txt + pos_return_txt, txt, len); - - return return_txt; -} - -/** * function used to get the substring of a string s, from the starting and ending indexes * @param[in] s string containing the substring we want to extract. * @param[in] start the start index of the substring. @@ -111,62 +44,6 @@ pcilib_view_str_sub (const char *s, unsigned int start, unsigned int end) /** - * get the bank name associated with a register name - */ -static const char* -pcilib_view_get_bank_from_reg_name(pcilib_t* ctx,char* reg_name){ - int k; - for(k=0;ctx->registers[k].bits;k++){ - if(!(strcasecmp(reg_name,ctx->registers[k].name))){ - return ctx->banks[pcilib_find_register_bank_by_addr(ctx,ctx->registers[k].bank)].name; - } - } - return NULL; -} - -/** - * replace plain registers name in a formula by their value - */ -static char* -pcilib_view_compute_plain_registers(pcilib_t* ctx, char* formula, int direction){ - int j,k; - char *substr, *substr2; - char temp[66]; - pcilib_register_value_t value; - - /*we get recursively all registers of string , and if they are not equel to '@reg', then we get their value and put it in formula*/ - for(j=0;j<strlen((char*)formula);j++){ - if(formula[j]=='@'){ - k=j+1; - while((formula[k]!=' ' && formula[k]!=')' && formula[k]!='/' && formula[k]!='+' && formula[k]!='-' && formula[k]!='*' && formula[k]!='=') && (k<strlen((char*)formula))){ - k++; - } - substr2=pcilib_view_str_sub((char*)formula,j,k-1); /**< we get the name of the register+@*/ - substr=pcilib_view_str_sub(substr2,1,k-j/*length of substr2*/); /**< we get the name of the register*/ - if(direction==0){ - if((strcasecmp(substr,"reg"))){ - /* we get the bank name associated to the register, and read its value*/ - pcilib_read_register(ctx, pcilib_view_get_bank_from_reg_name(ctx, substr),substr,&value); - /* we put the value in formula*/ - sprintf(temp,"%i",value); - formula = pcilib_view_formula_replace(formula,substr2,temp); - } - } - else if(direction==1){ - if((strcasecmp(substr,"value"))){ - /* we get the bank name associated to the register, and read its value*/ - pcilib_read_register(ctx, pcilib_view_get_bank_from_reg_name(ctx, substr),substr,&value); - /* we put the value in formula*/ - sprintf(temp,"%i",value); - formula = pcilib_view_formula_replace(formula,substr2,temp); - } - } - } - } - return formula; -} - -/** * this function calls the python script and the function "evaluate" in it to evaluate the given formula *@param[in] the formula to be evaluated *@return the integer value of the evaluated formula (maybe go to float instead) @@ -192,27 +69,58 @@ pcilib_view_eval_formula(char* formula){ return value; } + /** - * function to apply a unit for the views of type formula - *@param[in] view - the view we want to get the units supported - *@param[in] unit - the requested unit in which we want to get the value - *@param[in,out] value - the number that needs to get transformed + * */ -static void -pcilib_view_apply_unit(pcilib_transform_unit_t unit_desc, const char* unit,pcilib_register_value_t* value){ - char* formula; +static char* +pcilib_view_compute_formula(pcilib_t* ctx, char* formula,char* reg_value_string){ + char *src=(char*)formula; + char *reg,*regend; + char *dst=malloc(6*strlen(src)*sizeof(char)); char temp[66]; + pcilib_register_value_t value; + int offset=0; - formula=malloc(strlen(unit_desc.transform_formula)*sizeof(char)); - strcpy(formula,unit_desc.transform_formula); - sprintf(temp,"%i",*value); - formula=pcilib_view_formula_replace(formula,"@self",temp); - *value=(int)pcilib_view_eval_formula(formula); + /*we get recursively all registers of string , and if they are not equel to '@reg', then we get their value and put it in formula*/ + while(1){ + reg = strchr(src, '@'); + if (!reg) { + strcpy(dst, src); + break; + } + regend = strchr(reg + 1, '@'); + if (!regend){ + pcilib_error("formula corresponding is malformed"); + return NULL; + } + strncpy(dst+offset, src, reg - src); + offset+=reg-src; + *regend = 0; + /* Now (reg + 1) contains the proper register name, you can compare +it to reg/value and either get the value of current register or the +specified one. Add it to the register*/ + if(!(strcasecmp(reg,"@value")) || !(strcasecmp(reg,"@reg")) || !(strcasecmp(reg,"@self"))){ + strncpy(dst+offset,reg_value_string,strlen(reg_value_string)); + offset+=strlen(reg_value_string); + + }else{ + pcilib_read_register(ctx, NULL,reg+1,&value); + sprintf(temp,"%i",value); + strncpy(dst+offset,temp,strlen(temp)); + offset+=strlen(temp); + } + src = regend + 1; + } + + return dst; } -static void -pcilib_view_apply_formula(pcilib_t* ctx, char* formula, pcilib_register_value_t reg_value, pcilib_register_value_t* out_value, int direction) + + +static int +pcilib_view_apply_formula(pcilib_t* ctx, char* formula, pcilib_register_value_t* reg_value) { /* when applying a formula, we need to: 1) compute the values of all registers present in plain name in the formulas and replace their name with their value : for example, if we have the formula" ((1./4)*(@reg - 1200)) if @freq==0 else ((3./10)*(@reg - 1000)) " we need to get the value of the register "freq" @@ -227,17 +135,38 @@ pcilib_view_apply_formula(pcilib_t* ctx, char* formula, pcilib_register_value_t */ char reg_value_string[66]; /* to register reg_value as a string, need to check the length*/ - sprintf(reg_value_string,"%u",reg_value); + sprintf(reg_value_string,"%u",*reg_value); - /*computation of plain registers in the formula*/ - formula=pcilib_view_compute_plain_registers(ctx,formula,direction); - /* computation of @reg with register value*/ - if(direction==0) formula=pcilib_view_formula_replace(formula,"@reg",reg_value_string); - else if (direction==1) formula=pcilib_view_formula_replace(formula,"@value",reg_value_string); + formula=pcilib_view_compute_formula(ctx,formula,reg_value_string); + if(!(formula)){ + pcilib_error("computing of formula failed"); + return PCILIB_ERROR_INVALID_DATA; + } + /* evaluation of the formula*/ - *out_value= pcilib_view_eval_formula(formula); + *reg_value= pcilib_view_eval_formula(formula); + return 0; } +/** + * function to apply a unit for the views of type formula + *@param[in] view - the view we want to get the units supported + *@param[in] unit - the requested unit in which we want to get the value + *@param[in,out] value - the number that needs to get transformed + */ +static void +pcilib_view_apply_unit(pcilib_transform_unit_t unit_desc, const char* unit,pcilib_register_value_t* value){ + char* formula; + + formula=malloc(strlen(unit_desc.transform_formula)*sizeof(char)); + strcpy(formula,unit_desc.transform_formula); + pcilib_view_apply_formula(NULL,formula, value); + + free(formula); +} + + + int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const char *unit, size_t value_size, void *value) { int i,j,err=0; @@ -352,7 +281,7 @@ int operation_enum(pcilib_t *ctx, void *params, char* name, int view2reg, pcilib int operation_formula(pcilib_t *ctx, void *params, char* unit, int view2reg, pcilib_register_value_t *regval, size_t viewval_size, void* viewval){ int j=0; pcilib_register_value_t value=0; - char* formula; + char* formula=NULL; if(view2reg==0){ if(!(strcasecmp(unit, ((pcilib_view_t*)viewval)->base_unit.name))){ @@ -362,8 +291,8 @@ int operation_formula(pcilib_t *ctx, void *params, char* unit, int view2reg, pci return PCILIB_ERROR_MEMORY; } strncpy(formula,((pcilib_formula_t*)params)->read_formula,strlen(((pcilib_formula_t*)params)->read_formula)); - pcilib_view_apply_formula(ctx,formula,*regval,&value,0); - return value; + pcilib_view_apply_formula(ctx,formula,regval); + return 0; } for(j=0; ((pcilib_view_t*)viewval)->base_unit.other_units[j].name;j++){ @@ -375,16 +304,16 @@ int operation_formula(pcilib_t *ctx, void *params, char* unit, int view2reg, pci return PCILIB_ERROR_MEMORY; } strncpy(formula,((pcilib_formula_t*)params)->read_formula,strlen(((pcilib_formula_t*)params)->read_formula)); - pcilib_view_apply_formula(ctx,formula, *regval,&value,0); + pcilib_view_apply_formula(ctx,formula, regval); pcilib_view_apply_unit(((pcilib_view_t*)viewval)->base_unit.other_units[j],unit,&value); - return value; + return 0; } } }else if(view2reg==1){ if(!(strcasecmp(unit, ((pcilib_view_t*)viewval)->base_unit.name))){ formula=malloc(sizeof(char)*strlen(((pcilib_formula_t*)params)->write_formula)); strncpy(formula,((pcilib_formula_t*)params)->write_formula,strlen(((pcilib_formula_t*)params)->write_formula)); - pcilib_view_apply_formula(ctx,formula,*regval,&value,1); + pcilib_view_apply_formula(ctx,formula,regval); return 0; } @@ -394,13 +323,13 @@ int operation_formula(pcilib_t *ctx, void *params, char* unit, int view2reg, pci formula=malloc(sizeof(char)*strlen(((pcilib_formula_t*)params)->write_formula)); strncpy(formula,((pcilib_formula_t*)params)->write_formula,strlen((( pcilib_formula_t*)params)->write_formula)); pcilib_view_apply_unit(((pcilib_view_t*)viewval)->base_unit.other_units[j],unit,&value); - pcilib_view_apply_formula(ctx,formula,*regval,&value,1); - *regval=value; + pcilib_view_apply_formula(ctx,formula,regval); /* we maybe need some error checking there , like temp_value >min and <max*/ return 0; } } } + free(formula); return PCILIB_ERROR_INVALID_REQUEST; } diff --git a/pcilib/xml.c b/pcilib/xml.c index fe25cf7..5be5abd 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -138,6 +138,7 @@ pcilib_get_associated_views(pcilib_t* ctx, const char* reg_name,xmlXPathContextP } xmlXPathFreeObject(nodes); + free(path); return 0; } @@ -507,7 +508,6 @@ pcilib_xml_create_unit(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, x attr=node->properties; value=(char*)attr->children->content; desc.name=value; - desc.other_units=malloc(sizeof(pcilib_transform_unit_t)); for (cur = node->children; cur != NULL; cur = cur->next) { if (!cur->children) continue; @@ -520,7 +520,6 @@ pcilib_xml_create_unit(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDocPtr doc, x if (!value || !attr) continue; if (!strcasecmp(name, "convert_unit")) { - desc.other_units=realloc(desc.other_units,(i+1)*sizeof(pcilib_transform_unit_t)); desc.other_units[i].name=value2; desc.other_units[i].transform_formula=value; i++; diff --git a/pcitool/cli.c b/pcitool/cli.c index bd52270..378b8ba 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -1024,14 +1024,15 @@ int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info, int i; int err; const char *format; - char *s1,*s2,*s3; + char *s1,*regname,*viewname; + char* fullreg=strdup(reg); pcilib_register_bank_t bank_id; pcilib_register_bank_addr_t bank_addr = 0; pcilib_register_value_t value; - if (reg && !(strchr(reg,'/'))) { + if (reg && !(strchr(fullreg,'/'))) { pcilib_register_t regid = pcilib_find_register(handle, bank, reg); bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[regid].bank); format = model_info->banks[bank_id].format; @@ -1045,28 +1046,30 @@ int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info, printf(format, value); printf("\n"); } - }else if(reg && (s1=strchr(reg,'/'))){ + }else if(reg && (s1=strchr(fullreg,'/'))){ char* enum_command=malloc(sizeof(char*)); if(!enum_command){ printf("Error allocating memory for the result\n"); return PCILIB_ERROR_MEMORY; } - s2=pcilib_view_str_sub(reg,0,s1-reg-1); - s3=pcilib_view_str_sub(reg,s1-reg+1,strlen(reg)); - if(!(strcasecmp(s3,"name"))){ - err = pcilib_read_view(handle,bank,s2,NULL,sizeof(char*),enum_command); - if (err) printf("Error reading register %s\n", reg); + *s1=0; + regname=fullreg; + viewname=fullreg+1; + if(!strcasecmp(viewname,"name")){ + err = pcilib_read_view(handle,bank,regname,viewname,sizeof(char*),enum_command); + if (err) printf("Error reading register %s with an enum view\n", reg); else { printf("%s = %s\n", reg, (char*)enum_command); } + free(enum_command); }else{ - pcilib_register_t regid = pcilib_find_register(handle, bank, s2); + pcilib_register_t regid = pcilib_find_register(handle, bank, regname); bank_id = pcilib_find_register_bank_by_addr(handle, model_info->registers[regid].bank); format = model_info->banks[bank_id].format; if (!format) format = "%lu"; - err = pcilib_read_view(handle,bank,s2,s3,sizeof(pcilib_register_value_t),&value); - if (err) printf("Error reading register %s\n", reg); + err = pcilib_read_view(handle,bank,regname,viewname,sizeof(pcilib_register_value_t),&value); + if (err) printf("Error reading register %s with a formula view\n", reg); else { printf("%s = ", reg); printf(format, value); @@ -1074,7 +1077,6 @@ int ReadRegister(pcilib_t *handle, const pcilib_model_description_t *model_info, } } } else { - printf("da\n"); // Adding DMA registers pcilib_get_dma_description(handle); @@ -1285,11 +1287,14 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info pcilib_register_t regid; const char *format = NULL; - char *s1,*s2=NULL; + char *s1,*regname=NULL; - if((s1=strchr(reg,'/'))){ - s2=pcilib_view_str_sub(reg,0,s1-reg-1); - regid=pcilib_find_register(handle,bank,s2); + char *fullregister=strdup(reg); + + if((s1=strchr(fullregister,'/'))){ + *s1=0; + regname=fullregister; + regid=pcilib_find_register(handle,bank,regname); }else{ regid = pcilib_find_register(handle, bank, reg); } @@ -1317,23 +1322,24 @@ int WriteRegister(pcilib_t *handle, const pcilib_model_description_t *model_info } format = "0x%lx"; - } else { + } else if((data) && !(regname)){ err = pcilib_write_view(handle,bank,reg,*data,0,NULL); if(err) Error("can't write to the register using an enum view"); else return 0; } - /* should i put strchr not null here? + /* should i put strchr not null here?* } else { Error("Can't parse data value (%s) is not valid decimal number", *data); }*/ value = val; - if((s1=strchr(reg,'/'))){ - char *s3; - s3=pcilib_view_str_sub(reg,s1-reg+1,strlen(reg)); - err = pcilib_write_view(handle,bank,s2,s3,sizeof(pcilib_register_value_t),&value); - if (err) printf("Error writing register %s using view %s\n",s2,s3); + if((regname)){ + char *view_name; + view_name=fullregister+1;; + err = pcilib_write_view(handle,bank,regname,view_name,sizeof(pcilib_register_value_t),&value); + if (err) printf("Error writing register %s using view %s\n",regname,view_name); + free(fullregister); }else{ err = pcilib_write_register(handle, bank, reg, value); if (err) Error("Error writting register %s\n", reg); |