From d996fab54c59ca0b34d4ff7c4ab5ab8247559db0 Mon Sep 17 00:00:00 2001 From: zilio nicolas Date: Mon, 7 Sep 2015 10:35:48 +0200 Subject: further modifications --- pcilib/pci.c | 10 ++- pcilib/pci.h | 4 +- pcilib/xml.c | 200 +++++++++++++++++++++++++++++++---------------------------- pcilib/xml.h | 6 +- 4 files changed, 120 insertions(+), 100 deletions(-) (limited to 'pcilib') diff --git a/pcilib/pci.c b/pcilib/pci.c index 8bbee2f..5f3c8aa 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -172,7 +172,12 @@ pcilib_t *pcilib_open(const char *device, const char *model) { if (!ctx->model) ctx->model = strdup(model?model:"pci"); - pcilib_init_xml(ctx, ctx->model); + err = pcilib_init_xml(ctx, ctx->model); + if (err) { + pcilib_error("Error (%i) initializing xml part\n", err); + pcilib_close(ctx); + return NULL; + } ctx->model_info.registers = ctx->registers; ctx->model_info.banks = ctx->banks; @@ -357,6 +362,9 @@ void pcilib_close(pcilib_t *ctx) { } pcilib_free_register_banks(ctx); + + if(ctx->xml_ctx) + pcilib_free_xml(ctx); if (ctx->register_ctx) free(ctx->register_ctx); diff --git a/pcilib/pci.h b/pcilib/pci.h index 40cb4bf..dfbaf9b 100644 --- a/pcilib/pci.h +++ b/pcilib/pci.h @@ -73,9 +73,7 @@ struct pcilib_s { pcilib_register_bank_context_t *bank_ctx[PCILIB_MAX_REGISTER_BANKS]; /**< Contexts for registers banks if required by register protocol */ pcilib_dma_context_t *dma_ctx; /**< DMA context */ pcilib_context_t *event_ctx; /**< Implmentation context */ - xmlNodePtr* xml_banks; /** #include #include +#include "config.h" + +typedef enum{ + type_standard, + type_bits, + type_fifo +}pcilib_type_register_t; + /** pcilib_xml_get_nodeset_from_xpath * this function takes a context from an AST and an XPath expression, to produce an object containing the nodes corresponding to the xpath expression @@ -59,18 +67,6 @@ pcilib_xml_get_nodeset_from_xpath(xmlXPathContextPtr doc, xmlChar *xpath){ } -/**pcilib_xml_get_bank_node_from_register_node - * this function get the bank xml node from a standards register xml node in the xml file - *@param[in] mynode the register node we want to know the bank - *@return the bank node - */ -static xmlNodePtr -pcilib_xml_get_bank_node_from_register_node(xmlNodePtr mynode){ - return xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent)); -} - - - /** pcilib_xml_validate * function to validate the xml file against the xsd * @param[in] xml_filename path to the xml file @@ -125,14 +121,13 @@ if(ret!=0) pcilib_warning("\nxml file \"%s\" does not validate against the schem * @param[in] doc the AST of the xml file, used for used lixbml functions */ static void -pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr mynode, xmlDocPtr doc, pcilib_t* pci){ +pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr mynode, xmlDocPtr doc, pcilib_t* pci, int err){ char* ptr; xmlNodePtr cur; xmlChar *value; - static int i=0; int bar_ok=0; - int k=0, name_found=0; + int k=0; cur=mynode->children; /** we place ourselves in the childrens of the bank node*/ @@ -149,12 +144,8 @@ pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr my mybank->size=(size_t)strtol((char*)value,&ptr,0); }else if(strcasecmp((char*)cur->name,"protocol")==0){ - while(pci->protocols[k].name!=NULL){ - if(strcasecmp(pci->protocols[k].name,(char*)value)==0){ - mybank->protocol=pci->protocols[k].addr; - break; - k++; - } + if((mybank->protocol=pcilib_find_register_protocol_by_name(pci,(char*)value))==PCILIB_REGISTER_PROTOCOL_INVALID){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT; } }else if(strcasecmp((char*)cur->name,"read_address")==0){ @@ -190,20 +181,23 @@ pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr my } if(bar_ok==0) mybank->bar=PCILIB_BAR_NOBAR; - - while(pci->banks[k].name!=NULL){ - if(strcasecmp(pci->banks[k].name,mybank->name)==0){ - mybank->addr=pci->banks[k].addr; - name_found++; - break; + + k=(int)pcilib_find_register_bank_by_name(pci,mybank->name); + if(k==PCILIB_REGISTER_BANK_INVALID){ + mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC + pci->xml_ctx->nb_new_banks; + pci->xml_ctx->nb_new_banks++; + k=pci->num_banks+1; } - k++; - } - if(name_found==0) { - mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC + i; - i++; + else mybank->addr=pci->banks[k].addr; + + if(err==0){ + pci->xml_ctx->xml_banks[k]=mynode; } - pci->xml_banks[k]=mynode; + + char buffer[66]; + sprintf(buffer,"%i",mybank->addr); + printf("buffer %s \n",buffer); + xmlNewChild(mynode,NULL, BAD_CAST "address", BAD_CAST buffer); } @@ -222,7 +216,7 @@ pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ xmlNodeSetPtr nodesetaddress=NULL; xmlNodePtr mynode; xmlXPathContextPtr context; - int i; + int i,err=0; mynode=malloc(sizeof(xmlNode)); if(!(context= xmlXPathNewContext(doc))){ @@ -234,13 +228,16 @@ pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ if(!(nodesetaddress)) return; if(nodesetaddress->nodeNr==0) return; - pci->xml_banks=calloc(PCILIB_MAX_REGISTER_BANKS+1,sizeof(xmlNodePtr)); - if(!(pci->xml_banks)) pcilib_error("can't create bank xml nodes for pcilib_t struct"); + pci->xml_ctx->xml_banks=calloc(PCILIB_MAX_REGISTER_BANKS+1,sizeof(xmlNodePtr)); + if(!(pci->xml_ctx->xml_banks)){ + pcilib_error("can't create bank xml nodes for pcilib_t struct"); + err++; + } /** for each of the bank nodes, we create the associated structure, and push it in the pcilib environnement*/ for(i=0;inodeNr;i++){ mynode=nodesetaddress->nodeTab[i]; - pcilib_xml_create_bank(&mybank,mynode,doc, pci); + pcilib_xml_create_bank(&mybank,mynode,doc, pci, err); pcilib_add_register_banks(pci,1,&mybank); } @@ -267,13 +264,24 @@ pcilib_xml_compare_registers(void const *a, void const *b){ * @param[in,out] registers the list of registers in : not ranged out: ranged. * @param[in] size the number of registers. */ -void pcilib_xml_arrange_registers(pcilib_register_description_t *registers,int size){ +static void +pcilib_xml_arrange_registers(pcilib_register_description_t *registers,int size){ pcilib_register_description_t* temp; temp=malloc(size*sizeof(pcilib_register_description_t)); qsort(registers,size,sizeof(pcilib_register_description_t),pcilib_xml_compare_registers); free(temp); } +/**pcilib_get_bank_address_from_register_node + *@param[in] node the current register node + */ +static xmlChar* +pcilib_get_bank_address_from_register_node(xmlDocPtr doc, xmlNodePtr node){ + xmlChar* temp= xmlNodeListGetString(doc,xmlGetLastChild(xmlFirstElementChild(node->parent->parent))->children,1); + return temp; +} + + /** pcilib_xml_create_register. * this function create a register structure from a xml register node. * @param[out] myregister the register we want to create @@ -281,12 +289,11 @@ void pcilib_xml_arrange_registers(pcilib_register_description_t *registers,int s * @param[in] doc the AST of the xml file, required for some ibxml2 sub-fonctions * @param[in] mynode the xml node to create register from */ -void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNodePtr mynode, xmlDocPtr doc, xmlChar* type, pcilib_t* pci){ +void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNodePtr mynode, xmlDocPtr doc,pcilib_register_type_t type, pcilib_t* pci){ char* ptr; xmlNodePtr cur; xmlChar *value=NULL; - xmlNodePtr bank=NULL; int i=0; /**we get the children of the register xml nodes, that contains the properties for it*/ @@ -299,7 +306,7 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNod */ if(strcasecmp((char*)cur->name,"address")==0){ myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0); - + }else if(strcasecmp((char*)cur->name,"offset")==0){ myregister->offset=(pcilib_register_size_t)strtol((char*)value,&ptr,0); @@ -352,39 +359,19 @@ void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNod /** make sure we don't get the description from previous registers*/ if(i==0) myregister->description=NULL; - /** we then get properties that can not be parsed as the previous ones*/ - if(strcasecmp((char*)type,"standard")==0){ + if((int)type==(int)type_standard){ myregister->type=PCILIB_REGISTER_STANDARD; - bank=pcilib_xml_get_bank_node_from_register_node(mynode); - while(bank!=NULL){ - value=xmlNodeListGetString(doc,bank->children,1); - if(strcasecmp((char*)bank->name,"name")==0){ - break; - } - bank=bank->next; - } - - int k=0; - - while(pci->banks[k].name!=NULL){ - printf("name %s\n",pci->banks[k].name); - if(strcasecmp(pci->banks[k].name,(char*)value)==0){ - myregister->bank=pci->banks[k].addr; - printf("ok\n"); - break; - } - k++; - } - - }else if(strcasecmp((char*)type,"bits")==0){ + myregister->bank=(pcilib_register_bank_addr_t)strtol((char*)pcilib_get_bank_address_from_register_node(doc,mynode),&ptr,0); + + }else if((int)type==(int)type_bits){ myregister->type=PCILIB_REGISTER_BITS; - - }else if(strcasecmp((char*)type,"fifo")==0){ + + }else if((int)type==(int)type_fifo){ /* not implemented yet*/ myregister->type=PCILIB_REGISTER_FIFO; } - + } @@ -403,7 +390,7 @@ void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr doc){ xmlXPathContextPtr context; pcilib_register_description_t *registers=NULL; pcilib_register_description_t myregister; - int i,j; + int i,j,err=0; context= xmlXPathNewContext(doc); if(!(context= xmlXPathNewContext(doc))){ @@ -418,15 +405,22 @@ void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr doc){ if(nodesetaddress->nodeNr>0)registers=calloc(nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,sizeof(pcilib_register_description_t)); else return; - pci->xml_registers=calloc(nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,sizeof(xmlNodePtr)); - if(!(pci->xml_registers)) pcilib_warning("can't create registers xml nodes in pcilib_t struct"); + if(pci->xml_ctx->nb_registers==0) + pci->xml_ctx->xml_registers=calloc(nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,sizeof(xmlNodePtr)); + else + pci->xml_ctx->xml_registers=realloc(pci->xml_ctx->xml_registers,(pci->xml_ctx->nb_registers+nodesetaddress->nodeNr+nodesetsubaddress->nodeNr)*sizeof(xmlNodePtr)); + + if(!(pci->xml_ctx->xml_registers)){ + pcilib_warning("can't create registers xml nodes in pcilib_t struct: memory allocation failed"); + err++; + } /** we then iterate through standard registers nodes to create registers structures*/ for(i=0;inodeNr;i++){ mynode=nodesetaddress->nodeTab[i]; - pcilib_xml_create_register(&myregister,mynode,doc,(xmlChar*)"standard",pci); + pcilib_xml_create_register(&myregister,mynode,doc,type_standard,pci); registers[i]=myregister; - pci->xml_registers[i]=mynode; + if(err==0) pci->xml_ctx->xml_registers[pci->xml_ctx->nb_registers+i]=mynode; } j=i; @@ -434,16 +428,17 @@ void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr doc){ /** we then iterate through bits registers nodes to create registers structures*/ for(i=0;inodeNr;i++){ mynode=nodesetsubaddress->nodeTab[i]; - pcilib_xml_create_register(&myregister,mynode->parent->parent,doc,(xmlChar*)"standard",pci); - pcilib_xml_create_register(&myregister,mynode,doc,(xmlChar*)"bits",pci); + pcilib_xml_create_register(&myregister,mynode->parent->parent,doc,type_standard,pci); + pcilib_xml_create_register(&myregister,mynode,doc,type_bits,pci); registers[i+j]=myregister; - pci->xml_registers[i+j]=mynode; + if(err==0) pci->xml_ctx->xml_registers[pci->xml_ctx->nb_registers+i+j]=mynode; } /**we arrange the register for them to be well placed for pci-l*/ pcilib_xml_arrange_registers(registers,nodesetaddress->nodeNr+nodesetsubaddress->nodeNr); /**we fille the pcilib_t struct*/ pcilib_add_registers(pci,nodesetaddress->nodeNr+nodesetsubaddress->nodeNr,registers); + pci->xml_ctx->nb_registers+=nodesetaddress->nodeNr+nodesetsubaddress->nodeNr; } @@ -460,7 +455,7 @@ int pcilib_init_xml(pcilib_t* ctx, char* model){ xmlDocPtr* docs; DIR* rep=NULL; struct dirent* file=NULL; - int err; + int err, err_count=0; path=malloc(sizeof(char*)); line=malloc(sizeof(char*)); @@ -469,8 +464,7 @@ int pcilib_init_xml(pcilib_t* ctx, char* model){ /** we first get the env variable corresponding to the place of the xml files*/ path=getenv("PCILIB_MODEL_DIR"); if(path==NULL){ - pcilib_warning("can't find environment variable for xml files"); - return 1; + path=PCILIB_MODEL_DIR; } /** we then open the directory corresponding to the ctx model*/ @@ -478,7 +472,7 @@ int pcilib_init_xml(pcilib_t* ctx, char* model){ sprintf(pwd,"%s%s/",path,model); if((rep=opendir(pwd))==NULL){ pcilib_warning("could not open the directory for xml files: error %i\n",errno); - return 1; + return PCILIB_ERROR_NOTINITIALIZED; } /** we iterate through the files of the directory, to get the xml files and the xsd file*/ @@ -497,33 +491,45 @@ int pcilib_init_xml(pcilib_t* ctx, char* model){ if(line_xsd==NULL){ pcilib_warning("no xsd file found"); - return 1; + return PCILIB_ERROR_NOTINITIALIZED; } if(line[0]==NULL){ pcilib_warning("no xml file found"); - return 1; + return PCILIB_ERROR_NOTINITIALIZED; } /** for each xml file, we validate it, and get the registers and the banks*/ docs=malloc((i-1)*sizeof(xmlDocPtr)); + ctx->xml_ctx=malloc(sizeof(pcilib_xml_context_t)); + ctx->xml_ctx->docs=malloc(sizeof(xmlDocPtr)*(i-1)); + ctx->xml_ctx->nb_registers=0; + ctx->xml_ctx->nb_new_banks=0; + + if(!(ctx->xml_ctx) || !(ctx->xml_ctx->docs)) + return PCILIB_ERROR_MEMORY; + + for(k=0;kxml_context=malloc(sizeof(pcilib_xml_context_t)); - ctx->xml_context->docs=malloc(sizeof(xmlDocPtr)*(i-1)); - ctx->xml_context->docs=docs; + + ctx->xml_ctx->docs=docs; free(pwd); free(line); free(line_xsd); + if(err_count>0) return PCILIB_ERROR_NOTINITIALIZED; return 0; } @@ -531,11 +537,15 @@ int pcilib_init_xml(pcilib_t* ctx, char* model){ * this function free the xml parts of the pcilib_t running, and some libxml ashes * @param[in] pci the pcilib_t running */ -void pcilib_clean_xml(pcilib_t* pci){ - - free(pci->xml_banks); - free(pci->xml_registers); - free(pci->xml_context); +void pcilib_free_xml(pcilib_t* pci){ + + free(pci->xml_ctx->xml_banks); + free(pci->xml_ctx->xml_registers); + pci->xml_ctx->xml_banks=NULL; + pci->xml_ctx->xml_registers=NULL; + free(pci->xml_ctx); + pci->xml_ctx=NULL; + xmlCleanupParser(); xmlMemoryDump(); diff --git a/pcilib/xml.h b/pcilib/xml.h index c10a9d3..a88a8f9 100644 --- a/pcilib/xml.h +++ b/pcilib/xml.h @@ -17,6 +17,10 @@ typedef struct{ xmlDocPtr* docs; + xmlNodePtr* xml_banks; /**