summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pcilib/unit.h4
-rw-r--r--pcilib/views.c233
-rw-r--r--pcilib/xml.c3
-rw-r--r--pcitool/cli.c52
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);