diff options
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | pcilib/pci.c | 12 | ||||
| -rw-r--r-- | pcilib/pci.h | 1 | ||||
| -rw-r--r-- | pcilib/views.c | 6 | ||||
| -rw-r--r-- | pcilib/views.h | 6 | ||||
| -rw-r--r-- | pcilib/xml.c | 80 | ||||
| -rw-r--r-- | pcitool/cli.c | 5 | ||||
| -rw-r--r-- | xml/test/camera.xml | 6 | 
8 files changed, 77 insertions, 41 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index d9e637f..c5cc12a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ if (NOT DISABLE_PCITOOL)      pkg_check_modules(FASTWRITER fastwriter REQUIRED)  endif (NOT DISABLE_PCITOOL) -add_definitions("-fPIC --std=c99 -Wall -O2 -gdwarf-2 -g3 -fno-omit-frame-pointer") +add_definitions("-fPIC --std=c99 -Wall -O2 -gdwarf-2 -g3 -fno-omit-frame-pointer -g")  #add_definitions("-fPIC --std=c99 -Wall -O2")  include(cmake/version.cmake) diff --git a/pcilib/pci.c b/pcilib/pci.c index b7dcbcd..8c178f6 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -139,8 +139,12 @@ pcilib_t *pcilib_open(const char *device, const char *model) {  	}  	ctx->alloc_reg = PCILIB_DEFAULT_REGISTER_SPACE; +	ctx->alloc_formula_views=PCILIB_DEFAULT_VIEW_SPACE; +	ctx->alloc_enum_views=PCILIB_DEFAULT_VIEW_SPACE;  	ctx->registers = (pcilib_register_description_t *)malloc(PCILIB_DEFAULT_REGISTER_SPACE * sizeof(pcilib_register_description_t));  	ctx->register_ctx = (pcilib_register_context_t *)malloc(PCILIB_DEFAULT_REGISTER_SPACE * sizeof(pcilib_register_context_t)); +	ctx->enum_views = (pcilib_view_enum2_t *)malloc(PCILIB_DEFAULT_VIEW_SPACE * sizeof(pcilib_view_enum2_t)); +	ctx->formula_views = (pcilib_view_formula_t*)malloc(PCILIB_DEFAULT_VIEW_SPACE * sizeof(pcilib_view_formula_t));  	if ((!ctx->registers)||(!ctx->register_ctx)) {  	    pcilib_error("Error allocating memory for register model"); @@ -148,12 +152,20 @@ pcilib_t *pcilib_open(const char *device, const char *model) {  	    return NULL;  	} +	if((!ctx->enum_views)||(!ctx->formula_views)){ +	  pcilib_error("Error allocating memory for views"); +	  pcilib_close(ctx); +	  return NULL; +	} +  	memset(ctx->registers, 0, sizeof(pcilib_register_description_t));  	memset(ctx->banks, 0, sizeof(pcilib_register_bank_description_t));  	memset(ctx->ranges, 0, sizeof(pcilib_register_range_t));  	memset(ctx->register_ctx, 0, PCILIB_DEFAULT_REGISTER_SPACE * sizeof(pcilib_register_context_t)); +	memset(ctx->enum_views,0,sizeof(pcilib_view_enum2_t)); +	memset(ctx->formula_views,0,sizeof(pcilib_view_formula_t));  	for (i = 0; pcilib_protocols[i].api; i++);  	memcpy(ctx->protocols, pcilib_protocols, i * sizeof(pcilib_register_protocol_description_t)); diff --git a/pcilib/pci.h b/pcilib/pci.h index 657c335..3b1c0e8 100644 --- a/pcilib/pci.h +++ b/pcilib/pci.h @@ -8,6 +8,7 @@  #define PCILIB_DMA_SKIP_TIMEOUT 1000000		/**< us */  #define PCILIB_MAX_BARS 6			/**< this is defined by PCI specification */  #define PCILIB_DEFAULT_REGISTER_SPACE 1024	/**< number of registers to allocate on init */ +#define PCILIB_DEFAULT_VIEW_SPACE 128    	/**< number of views to allocate on init */  #define PCILIB_MAX_REGISTER_BANKS 32		/**< maximum number of register banks to allocate space for */  #define PCILIB_MAX_REGISTER_RANGES 32		/**< maximum number of register ranges to allocate space for */  #define PCILIB_MAX_REGISTER_PROTOCOLS 32	/**< maximum number of register protocols to support */ diff --git a/pcilib/views.c b/pcilib/views.c index 44392d9..038b48d 100644 --- a/pcilib/views.c +++ b/pcilib/views.c @@ -2,7 +2,7 @@  #include "pci.h"  #include "pcilib.h"  #include <Python.h> -//#include "views.h" +#include "views.h"  #include "error.h"  #include <strings.h>  #include <stdlib.h> @@ -349,7 +349,6 @@ int pcilib_add_views_enum(pcilib_t *ctx, size_t n, const pcilib_view_enum2_t* vi  	if (!views_enum) return PCILIB_ERROR_MEMORY;  	ctx->enum_views = views_enum; -	/* context + model part ????*/  	ctx->alloc_enum_views = size;      } @@ -376,13 +375,12 @@ int pcilib_add_views_formula(pcilib_t *ctx, size_t n, const pcilib_view_formula_      }      if ((ctx->num_formula_views + n + 1) > ctx->alloc_formula_views) { -	for (size = ctx->alloc_formula_views; size < 2 * (n + ctx->num_formula_views + 1); size<<=1); +      for (size = ctx->alloc_formula_views; size < 2 * (n + ctx->num_formula_views + 1); size<<=1);  	views_formula = (pcilib_view_formula_t*)realloc(ctx->formula_views, size * sizeof(pcilib_view_formula_t));  	if (!views_formula) return PCILIB_ERROR_MEMORY;  	ctx->formula_views = views_formula; -	/* context + model part?????*/  	ctx->alloc_formula_views = size;      } diff --git a/pcilib/views.h b/pcilib/views.h index 98e3dcd..dfc9f70 100644 --- a/pcilib/views.h +++ b/pcilib/views.h @@ -24,6 +24,7 @@ struct pcilib_view_enum_s {  struct pcilib_view_enum2_s {    const char* name;    pcilib_view_enum_t* enums_list; +  const char* description;  }; @@ -35,6 +36,7 @@ struct pcilib_view_formula_s {    const char *read_formula; /**< formula to parse to read from a register*/    const char *write_formula; /**<formula to parse to write to a register*/  	// **see it later**        const char *unit; (?) +  const char *description;  };  /** @@ -47,9 +49,9 @@ int pcilib_read_view(pcilib_t *ctx, const char *bank, const char *regname, const   */  int pcilib_write_view(pcilib_t *ctx, const char *bank, const char *regname, const char *view/*, const char *unit*/, size_t value_size, void *value); -int pcilib_add_views_enum(pcilib_t* ctx,size_t n, pcilib_view_enum2_t* views); +int pcilib_add_views_enum(pcilib_t* ctx,size_t n, const pcilib_view_enum2_t* views); -int pcilib_add_views_formula(pcilib_t* ctx, size_t n, pcilib_view_formula_t* views); +int pcilib_add_views_formula(pcilib_t* ctx, size_t n, const pcilib_view_formula_t* views);  #endif diff --git a/pcilib/xml.c b/pcilib/xml.c index 852f319..ace38a6 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -75,32 +75,36 @@ static xmlNodePtr pcilib_xml_get_parent_register_node(xmlDocPtr doc, xmlNodePtr   * get the associated views of a register, to fill its register context   */  static int -pcilib_get_associated_views(pcilib_t* ctx, const char* reg_name,xmlXPathContextPtr xpath,pcilib_register_t id){ -  char* VIEWS_NAME_PATH="/model/banks/bank/registers/register[@name=\"%s\"]/views/view"; +pcilib_get_associated_views(pcilib_t* ctx, const char* reg_name,xmlXPathContextPtr xpath,pcilib_register_t id,int mode){ + +  /* i find this solution pretty elegant, but what about perf?*/ +  char* VIEWS_NAME_PATH_BITS="/model/banks/bank/registers/register[./name=\"%s\"]/registers_bits/register_bits/views/view"; +  char* VIEWS_NAME_PATH="/model/banks/bank/registers/register[./name=\"%s\"]/views/view";    char* path;    xmlXPathObjectPtr nodes;    xmlNodeSetPtr nodeset;    char* view_name;    /*we get first the nodes corresponding to the given register*/ -  path=malloc(strlen(VIEWS_NAME_PATH)+strlen(reg_name)); +  if(mode==1) path=malloc(strlen(VIEWS_NAME_PATH)+strlen(reg_name)); +  else path=malloc(strlen(VIEWS_NAME_PATH_BITS)+strlen(reg_name));    if(!(path)){      pcilib_error("can't allocate memory for getting path to get associated views of %s",reg_name);      return PCILIB_ERROR_MEMORY;    } -  sprintf(path,VIEWS_NAME_PATH,reg_name); +  if(mode==1) sprintf(path,VIEWS_NAME_PATH,reg_name); +  else sprintf(path,VIEWS_NAME_PATH_BITS,reg_name);    nodes = xmlXPathEvalExpression((xmlChar*)path, xpath);    nodeset = nodes->nodesetval; -      if (!xmlXPathNodeSetIsEmpty(nodeset)) {        int i,k,l;        /*if we correctly get a nodeset, then we iterate through the nodeset to get all views, using their names*/  	for (i = 0; i < nodeset->nodeNr; i++) {  	  view_name=(char*)nodeset->nodeTab[i]->children->content; -	   +  	  /* if the view name obtained is for an enum view, we get all pcilib_view_enum_t corresponding to the register*/ -	  for(k=0; ctx->enum_views[k].enums_list[0].value;k++){ +	  for(k=0; ctx->enum_views[k].enums_list[0].value; k++){  	    if(!(strcasecmp(view_name, ctx->enum_views[k].name))){  	      ctx->register_ctx[id].enums=malloc(sizeof(pcilib_view_enum_t)); @@ -109,29 +113,34 @@ pcilib_get_associated_views(pcilib_t* ctx, const char* reg_name,xmlXPathContextP  		return PCILIB_ERROR_MEMORY;  	      } +	      /*!!!!!!!!!!this loop here is buggy*/  	      for(l=0; ctx->enum_views[k].enums_list[l].value;l++){  		ctx->register_ctx[id].enums=realloc(ctx->register_ctx[id].enums,(l+1)*sizeof(pcilib_view_enum_t));  		ctx->register_ctx[id].enums[l]=ctx->enum_views[k].enums_list[l]; +		//		printf("names %s %s\n",ctx->register_ctx[id].enums[l].name,ctx->enum_views[k].enums_list[l].name);  	      } +	      return 0;  	    }  	  }  	  /*here it is for formula, i assume we have only one formula view per register*/  	  for(k=0; ctx->formula_views[k].name[0];k++){  	    if(!(strcasecmp(view_name,ctx->formula_views[k].name))){ +	        	      ctx->register_ctx[id].formulas=malloc(sizeof(pcilib_view_formula_t));  	      if(!(ctx->register_ctx[id].formulas)){  		pcilib_error("error allocating memory for formula views in register context %i",id);  		return PCILIB_ERROR_MEMORY;  	      } -	      ctx->register_ctx[id].formulas=&(ctx->formula_views[k]); +	      ctx->register_ctx[id].formulas[0]=ctx->formula_views[k]; +	      break;  	    }  	  }  	}      } - +       xmlXPathFreeObject(nodes);      return 0;  } @@ -247,7 +256,8 @@ static int pcilib_xml_parse_register(pcilib_t *ctx, pcilib_xml_register_descript  static int pcilib_xml_create_register(pcilib_t *ctx, pcilib_register_bank_t bank, xmlXPathContextPtr xpath, xmlDocPtr doc, xmlNodePtr node) {      int err;      int views_ok=0; -     +    int h; +      xmlXPathObjectPtr nodes;      xmlNodeSetPtr nodeset; @@ -255,7 +265,7 @@ static int pcilib_xml_create_register(pcilib_t *ctx, pcilib_register_bank_t bank      pcilib_xml_register_description_t fdesc;      pcilib_register_t reg; -     +      desc.base.bank = ctx->banks[bank].addr;      desc.base.rwmask = PCILIB_REGISTER_ALL_BITS;      desc.base.mode = PCILIB_REGISTER_R; @@ -279,7 +289,7 @@ static int pcilib_xml_create_register(pcilib_t *ctx, pcilib_register_bank_t bank      /* if the register had a node of type views, then we compute its associated registers. I do that here as i need the index for register context*/      if(views_ok){ -      err=pcilib_get_associated_views(ctx,desc.base.name,xpath,reg); +      err=pcilib_get_associated_views(ctx,desc.base.name,xpath,reg,1);        if(err) pcilib_warning("can't get correctly the associated views of the register %s",desc.base.name);      } @@ -324,7 +334,7 @@ static int pcilib_xml_create_register(pcilib_t *ctx, pcilib_register_bank_t bank  	    ctx->register_ctx[reg].min = fdesc.min;  	    ctx->register_ctx[reg].max = fdesc.max;  	    if(views_ok){ -	      err=pcilib_get_associated_views(ctx, desc.base.name,xpath,reg); +	      err=pcilib_get_associated_views(ctx, desc.base.name,xpath,reg,0);  	      if(err) pcilib_warning("can't get correctly the associated views of the register %s",fdesc.base.name);  	    }  	} @@ -503,6 +513,7 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo      enum_desc.max=0;      complete_enum_desc.name="default enum"; +    complete_enum_desc.description="default description";      complete_enum_desc.enums_list=malloc(sizeof(pcilib_view_enum_t));      if(!(complete_enum_desc.enums_list)){        pcilib_error("can't allocate memory for the complete enum type"); @@ -513,6 +524,7 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo      formula_desc.name="formula_default";      formula_desc.read_formula="@reg";      formula_desc.write_formula="@reg"; +    formula_desc.description="default description";      /* we get the attribute type of the view node*/      attr=node->properties; @@ -530,6 +542,10 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo  	if (!(strcasecmp((char*)name,"name"))) {  	  complete_enum_desc.name = value; + +	}else if (!(strcasecmp((char*)name,"description"))) { +	  complete_enum_desc.description = value; +          }else if (!(strcasecmp((char*)name,"enum"))) {  	  complete_enum_desc.enums_list=realloc(complete_enum_desc.enums_list,(i+1)*sizeof(pcilib_view_enum_t)); @@ -567,7 +583,7 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo  	      complete_enum_desc.enums_list[i].max=dat_max;  	    }  	  } -	  i++; +	  i++;	  	}        }        err=pcilib_add_views_enum(ctx,1,&complete_enum_desc); @@ -584,6 +600,7 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo  	name = (char*)cur->name;  	value = (char*)cur->children->content; +          if (!value) continue;  	if (!(strcasecmp((char*)name,"name"))) { @@ -592,6 +609,8 @@ static int pcilib_xml_create_view(pcilib_t *ctx, xmlXPathContextPtr xpath, xmlDo  	  formula_desc.read_formula=value;          }else if (!(strcasecmp((char*)name,"write_to_register"))) {  	  formula_desc.write_formula=value; +	}else if (!(strcasecmp((char*)name,"description"))) { +	  formula_desc.description=value;  	}        }        err=pcilib_add_views_formula(ctx,1,&formula_desc); @@ -619,6 +638,22 @@ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathCon      int i;      xmlErrorPtr xmlerr; +    views_nodes=xmlXPathEvalExpression(VIEWS_PATH,xpath); +    if(!views_nodes){ +	xmlerr = xmlGetLastError(); +	if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", BANKS_PATH, xmlerr->code, xmlerr->message); +	else pcilib_error("Failed to parse XPath expression %s", BANKS_PATH); +	return PCILIB_ERROR_FAILED; +    } +     +        nodeset=views_nodes->nodesetval; +    if(!xmlXPathNodeSetIsEmpty(nodeset)){ +      for(i=0;i < nodeset->nodeNr; i++){ +	pcilib_xml_create_view(ctx,xpath,doc,nodeset->nodeTab[i]); +      } +    } +    xmlXPathFreeObject(views_nodes);     +      bank_nodes = xmlXPathEvalExpression(BANKS_PATH, xpath);       if (!bank_nodes) {  	xmlerr = xmlGetLastError(); @@ -636,23 +671,6 @@ static int pcilib_xml_process_document(pcilib_t *ctx, xmlDocPtr doc, xmlXPathCon      }      xmlXPathFreeObject(bank_nodes); - -    views_nodes=xmlXPathEvalExpression(VIEWS_PATH,xpath); -    if(!views_nodes){ -	xmlerr = xmlGetLastError(); -	if (xmlerr) pcilib_error("Failed to parse XPath expression %s, xmlXPathEvalExpression reported error %d - %s", BANKS_PATH, xmlerr->code, xmlerr->message); -	else pcilib_error("Failed to parse XPath expression %s", BANKS_PATH); -	return PCILIB_ERROR_FAILED; -    } -     -    nodeset=views_nodes->nodesetval; -    if(!xmlXPathNodeSetIsEmpty(nodeset)){ -      for(i=0;i < nodeset->nodeNr; i++){ -	pcilib_xml_create_view(ctx,xpath,doc,nodeset->nodeTab[i]); -      } -    } -    xmlXPathFreeObject(views_nodes);     -      return 0;  } diff --git a/pcitool/cli.c b/pcitool/cli.c index c3663d2..7014190 100644 --- a/pcitool/cli.c +++ b/pcitool/cli.c @@ -2720,6 +2720,11 @@ int main(int argc, char **argv) {  		mode = MODE_READ;  		if (optarg) addr = optarg;  		else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; +		 +		/*		char* s; +		if(!(s=strchr(addr,'/'))){ +		mode=MODE_READ_VIEW;*/ +		    	    break;  	    case OPT_WRITE:  		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); diff --git a/xml/test/camera.xml b/xml/test/camera.xml index 5b486ee..815a50e 100644 --- a/xml/test/camera.xml +++ b/xml/test/camera.xml @@ -277,9 +277,9 @@                <size>16</size>                <mode>R</mode>                <name>sensor_temperature</name> -		<views> -		<view>formuu1</view> -		<view>formuu2</view> +              <views> +        		<view>formuu1</view> +    		    <view>formuu2</view>                  <view>enumm2</view>                </views>              </register_bits>  | 
