diff options
Diffstat (limited to 'pcilib')
-rw-r--r-- | pcilib/pci.c | 6 | ||||
-rw-r--r-- | pcilib/xml.c | 1172 | ||||
-rw-r--r-- | pcilib/xml.h | 90 |
3 files changed, 361 insertions, 907 deletions
diff --git a/pcilib/pci.c b/pcilib/pci.c index 03b2623..8a0ee29 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -109,8 +109,6 @@ pcilib_t *pcilib_open(const char *device, const char *model) { size_t i; pcilib_t *ctx = malloc(sizeof(pcilib_t)); - xmlDocPtr* docs=NULL; - if (!model) model = getenv("PCILIB_MODEL"); @@ -174,9 +172,7 @@ pcilib_t *pcilib_open(const char *device, const char *model) { if (!ctx->model) ctx->model = strdup(model?model:"pci"); - pcilib_init_xml(docs); - pcilib_xml_initialize_banks(ctx,docs); - pcilib_xml_initialize_registers(ctx,docs); + pcilib_init_xml(ctx); ctx->model_info.registers = ctx->registers; ctx->model_info.banks = ctx->banks; diff --git a/pcilib/xml.c b/pcilib/xml.c index ad76dcc..d4c84be 100644 --- a/pcilib/xml.c +++ b/pcilib/xml.c @@ -17,20 +17,20 @@ #include <stdio.h> #include <string.h> #include <assert.h> -//#include <Python.h> #include "pci.h" #include "bank.h" #include "register.h" #include <libxml/xmlschemastypes.h> -//#define VIEW_OK -//#define UNIT_OK -/** - * pcilib_xml_getdoc +#include <dirent.h> +#include <errno.h> + +/** pcilib_xml_getdoc * this function takes a string and will create an abtract syntax tree from the xml file represented by the string * @param[in] filename the the name of the xml file containing registers and banks */ -xmlDocPtr pcilib_xml_getdoc(char* filename){ +static xmlDocPtr +pcilib_xml_getdoc(char* filename){ xmlDocPtr doc; doc=xmlParseFile(filename); /**<the creation of the AST from a libxml2 funtion*/ @@ -43,22 +43,20 @@ xmlDocPtr pcilib_xml_getdoc(char* filename){ } /** pcilib_xml_getsetproperty - * * this function takes a context from an AST and an XPath expression, to produce an object containing the nodes corresponding to the xpath expression * @param[in] doc the AST of the xml file * @param[in] xpath the xpath expression that will be evaluated */ -xmlXPathObjectPtr pcilib_xml_getsetproperty(xmlXPathContextPtr doc, xmlChar *xpath){ +static xmlXPathObjectPtr +pcilib_xml_getsetproperty(xmlXPathContextPtr doc, xmlChar *xpath){ xmlXPathObjectPtr result; result=xmlXPathEvalExpression(xpath, doc); /**<the creation of the resulting object*/ if(result==NULL){ -// pcilib_warning(" warning : the path is empty: %s",xpath); return NULL; } if(xmlXPathNodeSetIsEmpty(result->nodesetval)){ xmlXPathFreeObject(result); -// pcilib_warning("warning : no results found for: %s",xpath); return NULL; } @@ -69,7 +67,8 @@ xmlXPathObjectPtr pcilib_xml_getsetproperty(xmlXPathContextPtr doc, xmlChar *xpa * this function create a context in an AST (ie initialize XPAth for the AST). * @param[in] doc the AST of the xml file. */ -xmlXPathContextPtr pcilib_xml_getcontext(xmlDocPtr doc){ +static xmlXPathContextPtr +pcilib_xml_getcontext(xmlDocPtr doc){ xmlXPathContextPtr context; context= xmlXPathNewContext(doc); /**<the creation of the context using a libxml2's function */ if(context==NULL){ @@ -81,16 +80,19 @@ xmlXPathContextPtr pcilib_xml_getcontext(xmlDocPtr doc){ /** validation - * - * function to validate the xml file against the xsd, so that it does not require extern software + * function to validate the xml file against the xsd + * @param[in] xml_filename path to the xml file + * @param[in] xsd_filename path to the xsd file */ -void validation(char* xml_filename, char* xsd_filename) +static int +validation(char* xml_filename, char* xsd_filename) { xmlDocPtr doc; xmlSchemaPtr schema = NULL; xmlSchemaParserCtxtPtr ctxt; int ret=1; +/** we first parse the xsd file for AST with validation*/ ctxt = xmlSchemaNewParserCtxt(xsd_filename); schema = xmlSchemaParse(ctxt); xmlSchemaFreeParserCtxt(ctxt); @@ -115,338 +117,160 @@ if(schema != NULL) xmlSchemaFree(schema); xmlSchemaCleanupTypes(); -if(ret!=0) pcilib_error("xml file \"%s\" does not validate against the schema",xml_filename); +if(ret!=0) pcilib_warning("\nxml file \"%s\" does not validate against the schema, its register won't be used",xml_filename); + return ret; } -void pcilib_init_xml(xmlDocPtr* docs){ - char *path,*command,*command_xsd, *line, *line_xsd; - FILE *in, *in2; - int i=1; - - path=malloc(sizeof(char*)); - command=malloc(sizeof(char*)); - command_xsd=malloc(sizeof(char*)); - line=malloc(sizeof(char*)); - line_xsd=malloc(sizeof(char*)); - docs=malloc(sizeof(xmlDocPtr)); - - path=getenv("PCILIB_MODEL_DIR"); - if((strcmp(path,"(null)"))==0) pcilib_error("can't find environment variable for xml files"); - sprintf(command,"find %s -name *.xml -print",path); - sprintf(command_xsd,"find %s -name *.xsd -print",path); - - if(!(in=popen(command,"r"))) pcilib_error("fail popen xml"); - if(!((in2=popen(command_xsd,"r")))) pcilib_error("fail popen xsd"); - - while(fgets(line_xsd,sizeof(line_xsd),in2)!=NULL) { - if((strstr(line_xsd,"units"))!=NULL) break; - } - if(line_xsd==NULL) pcilib_error("no xsd file found"); - -while((fgets(line,sizeof(line),in))!=NULL) { - validation(line,line_xsd); - docs=(xmlDocPtr*) realloc(docs,i*sizeof(xmlDocPtr)); - docs[i-1]=pcilib_xml_getdoc(line); - i++; - } - - docs=(xmlDocPtr*) realloc(docs,i*sizeof(xmlDocPtr)); - docs[i]=NULL; - free(path); - free(command); - free(command_xsd); - free(line); - free(line_xsd); - free(in); - free(in2); - fclose(in); - fclose(in2); -} - -/** pcilib_xml_create_register. - * this function create a register structure from the results of xml parsing. - * @param[out] myregister the register we want to create - * @param[in] adress the adress of the future register - * @param[in] offset the offset of the future register - * @param[in] size the size of the future register - * @param[in] defvalue the defaut value of the future register - * @param[in] rwmask the rwmask of the future register - * @param[in] mode the mode of the future register - * @param[in] type the type of the future register - * @param[in] bank the bank of the future register - * @param[in] name the name of the future register - * @param[in] description the description of the future register - */ -void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlChar* adress, xmlChar *offset, xmlChar *size, xmlChar *defvalue, xmlChar *rwmask, xmlChar *mode, xmlChar *type, xmlChar *bank, xmlChar *name, xmlChar *description){ - - char* ptr; - - /* we recreate here each sub property of the register structure given the results of xml parsing - note :the use of strtol permits to get as well hexadecimal and decimal values - */ - - myregister->addr=(pcilib_register_addr_t)strtol((char*)adress,&ptr,0); - myregister->offset=(pcilib_register_size_t)strtol((char*)offset,&ptr,0); - myregister->bits=(pcilib_register_size_t)strtol((char*)size,&ptr,0); - myregister->defvalue=(pcilib_register_value_t)strtol((char*)defvalue,&ptr,0); - - if(strcmp((char*)rwmask,"all bits")==0){ - myregister->rwmask=PCILIB_REGISTER_ALL_BITS; - }else if(strcmp((char*)rwmask,"0")==0){ - myregister->rwmask=0; - }else{ - myregister->rwmask=(pcilib_register_value_t)strtol((char*)rwmask,&ptr,0); - } - - if(strcmp((char*)mode,"R")==0){ - myregister->mode=PCILIB_REGISTER_R; - }else if(strcmp((char*)mode,"W")==0){ - myregister->mode=PCILIB_REGISTER_W; - }else if(strcmp((char*)mode,"RW")==0){ - myregister->mode=PCILIB_REGISTER_RW; - }else if(strcmp((char*)mode,"W")==0){ - myregister->mode=PCILIB_REGISTER_W; - }else if(strcmp((char*)mode,"RW1C")==0){ - myregister->mode=PCILIB_REGISTER_RW1C; - }else if(strcmp((char*)mode,"W1C")==0){ - myregister->mode=PCILIB_REGISTER_W1C; - } - - if(strcmp((char*)type,"standard")==0){ - myregister->type=PCILIB_REGISTER_STANDARD; - }else if(strcmp((char*)type,"bits")==0){ - myregister->type=PCILIB_REGISTER_BITS; - }else if(strcmp((char*)type,"fifo")==0){ - myregister->type=PCILIB_REGISTER_FIFO; - } - - if(strcmp((char*)bank,"bank 0")==0){ - myregister->bank=PCILIB_REGISTER_BANK0; - }else if(strcmp((char*)bank,"bank 1")==0){ - myregister->bank=PCILIB_REGISTER_BANK1; - }else if(strcmp((char*)bank,"bank 2")==0){ - myregister->bank=PCILIB_REGISTER_BANK2; - }else if(strcmp((char*)bank,"bank 3")==0){ - myregister->bank=PCILIB_REGISTER_BANK3; - }else if(strcmp((char*)bank,"DMA bank")==0){ - myregister->bank=PCILIB_REGISTER_BANK_DMA; - }else if (strcmp((char*)bank,"dynamic bank")==0){ - myregister->addr=PCILIB_REGISTER_BANK_DYNAMIC; - }else{ - myregister->bank=PCILIB_REGISTER_BANK_INVALID; - } - - myregister->name=(char*)name; - myregister->description=(char*)description; -} - -/** pcilib_xml_getnumberbanks - * - * get the number of banks nodes in the AST, used to have some malloc in pci - * @param[in] doc the Xpath context of the xml file. - * @return the number of banks. - */ -int pcilib_xml_getnumberbanks(xmlXPathContextPtr doc){ - xmlNodeSetPtr nodesetadress=NULL; - xmlXPathObjectPtr temp; - temp=pcilib_xml_getsetproperty(doc,BANK_ADDR_PATH); /**< we first get a structure containing all the banks nodes*/ - if(temp!=NULL) nodesetadress=temp->nodesetval; - else pcilib_error("no bank in the xml file"); - return nodesetadress->nodeNr; /**< we then return the number of said nodes */ -} /** pcilib_xml_create_bank * - * this function create a bank structure from the results of xml parsing + * this function create a bank structure from a xml bank node * @param[out] mybank the created bank. - * @param[in] adress the adress of the bank that will be created. - * @param[in] bar the bar of the bank that will be created. - * @param[in] size the size of the bank that will be created. - * @param[in] protocol the protocol of the bank that will be created. - * @param[in] read_addr the read adress for protocol of the bank that will be created. - * @param[in] write_addr the write adress for the protocol of the bank that will be created. - * @param[in] access the word size of the bank that will be created. - * @param[in] endianess the endianess of the bank that will be created. - * @param[in] format the format of the bank that will be created. - * @param[in] name the name of the bank that will be created. - * @param[in] description the description of the bank that will be created. + * @param[in] my node the xml node used to create the bank + * @param[in] doc the AST of the xml file, used for used lixbml functions */ -void pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* adress, xmlChar *bar, xmlChar *size, xmlChar *protocol, xmlChar *read_addr, xmlChar *write_addr, xmlChar *access, xmlChar *endianess, xmlChar *format, xmlChar *name,xmlChar *description){ +static void +pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank, xmlNodePtr mynode, xmlDocPtr doc){ - char* ptr; + char* ptr; + xmlNodePtr cur; + xmlChar *value; - /** we recreate each sub property of banks' structure given the results of xml parsing - note : strtol is used here to get hexadecimal and decimal values from the xml file as well*/ + cur=mynode->children; /** we place ourselves in the childrens of the bank node*/ - if (strcmp((char*)adress,"bank 0")==0){ - mybank->addr=PCILIB_REGISTER_BANK0; - }else if (strcmp((char*)adress,"bank 1")==0){ - mybank->addr=PCILIB_REGISTER_BANK1; - }else if (strcmp((char*)adress,"bank 2")==0){ - mybank->addr=PCILIB_REGISTER_BANK2; - }else if (strcmp((char*)adress,"bank 3")==0){ - mybank->addr=PCILIB_REGISTER_BANK3; - }else if (strcmp((char*)adress,"DMA bank")==0){ - mybank->addr=PCILIB_REGISTER_BANK_DMA; - }else if (strcmp((char*)adress,"DMAconf bank")==0){ - mybank->addr=PCILIB_REGISTER_BANK_DMACONF; - }else if (strcmp((char*)adress,"dynamic bank")==0){ - mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC; - }else{ - mybank->addr=PCILIB_REGISTER_BANK_INVALID; - } - - if(strcmp((char*)bar,"0")==0){ - mybank->bar=PCILIB_BAR0; - }else if(strcmp((char*)bar,"1")==0){ - mybank->bar=PCILIB_BAR1; - }else if(strcmp((char*)bar,"no_bar")==0){ - mybank->bar=PCILIB_BAR_NOBAR; - }else{ - mybank->bar=PCILIB_BAR_INVALID; - } - - mybank->bar=(pcilib_bar_t)strtol((char*)bar,&ptr,0); - mybank->size=(size_t)strtol((char*)size,&ptr,0); - - if(strcmp((char*)protocol,"default")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT; - }else if(strcmp((char*)protocol,"0")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL0; - }else if(strcmp((char*)protocol,"dma")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_DMA; - }else if(strcmp((char*)protocol,"dynamic")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_DYNAMIC; - }else if (strcmp((char*)protocol,"software")==0){ - mybank->protocol=PCILIB_REGISTER_PROTOCOL_SOFTWARE; - }else mybank->protocol=PCILIB_REGISTER_PROTOCOL_INVALID; - - mybank->read_addr=(uintptr_t)strtol((char*)read_addr,&ptr,0); - mybank->write_addr=(uintptr_t)strtol((char*)write_addr,&ptr,0); - mybank->access=(uint8_t)strtol((char*)access,&ptr,0); - - if(strcmp((char*)endianess,"little")==0){ - mybank->endianess=PCILIB_LITTLE_ENDIAN; - }else if(strcmp((char*)endianess,"big")==0){ - mybank->endianess=PCILIB_BIG_ENDIAN; - }else if(strcmp((char*)endianess,"host")==0){ - mybank->endianess=PCILIB_HOST_ENDIAN; - } - mybank->format=(char*)format; - mybank->raw_endianess=mybank->endianess; + /** we iterate through all children, representing bank properties, to fill the structure*/ + while(cur!=NULL){ + /** we get each time the name of the node, corresponding to one property, and the value of the node*/ + value=xmlNodeListGetString(doc,cur->children,1); + + if(strcmp((char*)cur->name,"adress")==0){ + if (strcmp((char*)value,"bank 0")==0){ + mybank->addr=PCILIB_REGISTER_BANK0; + }else if (strcmp((char*)value,"bank 1")==0){ + mybank->addr=PCILIB_REGISTER_BANK1; + }else if (strcmp((char*)value,"bank 2")==0){ + mybank->addr=PCILIB_REGISTER_BANK2; + }else if (strcmp((char*)value,"bank 3")==0){ + mybank->addr=PCILIB_REGISTER_BANK3; + }else if (strcmp((char*)value,"DMA bank")==0){ + mybank->addr=PCILIB_REGISTER_BANK_DMA; + }else if (strcmp((char*)value,"DMAconf bank")==0){ + mybank->addr=PCILIB_REGISTER_BANK_DMACONF; + }else if (strcmp((char*)value,"dynamic bank")==0){ + mybank->addr=PCILIB_REGISTER_BANK_DYNAMIC; + }else{ + mybank->addr=PCILIB_REGISTER_BANK_INVALID; + } + + }else if(strcmp((char*)cur->name,"bar")==0){ + if(strcmp((char*)value,"0")==0){ + mybank->bar=PCILIB_BAR0; + }else if(strcmp((char*)value,"1")==0){ + mybank->bar=PCILIB_BAR1; + }else if(strcmp((char*)value,"no_bar")==0){ + mybank->bar=PCILIB_BAR_NOBAR; + }else{ + mybank->bar=PCILIB_BAR_INVALID; + } + mybank->bar=(pcilib_bar_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"size")==0){ + mybank->size=(size_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"protocol")==0){ + if(strcmp((char*)value,"default")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DEFAULT; + }else if(strcmp((char*)value,"0")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL0; + }else if(strcmp((char*)value,"dma")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DMA; + }else if(strcmp((char*)value,"dynamic")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_DYNAMIC; + }else if (strcmp((char*)value,"software")==0){ + mybank->protocol=PCILIB_REGISTER_PROTOCOL_SOFTWARE; + }else mybank->protocol=PCILIB_REGISTER_PROTOCOL_INVALID; + + }else if(strcmp((char*)cur->name,"read_adress")==0){ + mybank->read_addr=(uintptr_t)strtol((char*)value,&ptr,0); - mybank->name=(char*)name; - mybank->description=(char*)description; -} + }else if(strcmp((char*)cur->name,"write_adress")==0){ + mybank->write_addr=(uintptr_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"word_size")==0){ + mybank->access=(uint8_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"endianess")==0){ + if(strcmp((char*)value,"little")==0){ + mybank->endianess=PCILIB_LITTLE_ENDIAN; + }else if(strcmp((char*)value,"big")==0){ + mybank->endianess=PCILIB_BIG_ENDIAN; + }else if(strcmp((char*)value,"host")==0){ + mybank->endianess=PCILIB_HOST_ENDIAN; + } + mybank->raw_endianess=mybank->endianess; + + }else if(strcmp((char*)cur->name,"format")==0){ + mybank->format=(char*)value; + + }else if(strcmp((char*)cur->name,"name")==0){ + mybank->name=(char*)value; + + }else if(strcmp((char*)cur->name,"description")==0){ + mybank->description=(char*)value; + } + + cur=cur->next; + } +} + + /** pcilib_xml_initialize_banks * * function to create the structures to store the banks from the AST - * @see pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* adress, xmlChar *bar, xmlChar *size, xmlChar *protocol,xmlChar *read_addr, xmlChar *write_addr, xmlChar *access, xmlChar *endianess, xmlChar *format, xmlChar *name,xmlChar *description, xmlNodePtr node). + * @see pcilib_xml_create_bank( * @param[in] doc the AST of the xml file. - * @param[in,out] mybanks the structure containing the banks. + * @param[in] pci the pcilib_t running, which will be filled */ -void pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr* docs){ +static void +pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr doc){ pcilib_register_bank_description_t mybank; - xmlNodeSetPtr nodesetadress=NULL,nodesetbar=NULL,nodesetsize=NULL,nodesetprotocol=NULL,nodesetread_addr=NULL,nodesetwrite_addr=NULL,nodesetaccess=NULL,nodesetendianess=NULL,nodesetformat=NULL,nodesetname=NULL,nodesetdescription=NULL; - xmlChar *adress=NULL,*bar=NULL,*size=NULL,*protocol=NULL,*read_addr=NULL,*write_addr=NULL,*access=NULL,*endianess=NULL,*format=NULL,*name=NULL,*description=NULL; + xmlNodeSetPtr nodesetadress=NULL; xmlNodePtr mynode; - int number_banks; pcilib_register_bank_description_t* banks; xmlXPathContextPtr context; - int i,p; - xmlXPathObjectPtr temp; - mynode=malloc(sizeof(xmlNode)); - p=0; - while(docs[p]!=NULL){ - context=pcilib_xml_getcontext(docs[p]); - number_banks=pcilib_xml_getnumberbanks(context); - if(number_banks) banks=calloc((number_banks),sizeof(pcilib_register_bank_description_t)); - else return; + int i; - /** we first get the nodes corresponding to the properties we want*/ -/* -----> certainly not necessary if we validate xml each time*/ - temp=pcilib_xml_getsetproperty(context,BANK_ADDR_PATH); - if(temp!=NULL) nodesetadress=temp->nodesetval; - else pcilib_error("there is no adress for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_BAR_PATH); - if(temp!=NULL) nodesetbar=temp->nodesetval; - else pcilib_error("there is no bar for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_SIZE_PATH); - if(temp!=NULL) nodesetsize=temp->nodesetval; - else pcilib_error("there is no size for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_PROTOCOL_PATH); - if(temp!=NULL) nodesetprotocol= temp->nodesetval; - else pcilib_error("there is no protocol for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_READ_ADDR_PATH); - if(temp!=NULL) nodesetread_addr=temp->nodesetval; - else pcilib_error("there is no read_adress for banks in the xml"); + mynode=malloc(sizeof(xmlNode)); + context=pcilib_xml_getcontext(doc); - temp=pcilib_xml_getsetproperty(context,BANK_WRITE_ADDR_PATH); - if(temp!=NULL)nodesetwrite_addr=temp->nodesetval; - else pcilib_error("there is no write_adress for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_ACCESS_PATH); - if(temp!=NULL)nodesetaccess=temp->nodesetval; - else pcilib_error("there is no access for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_ENDIANESS_PATH); - if(temp!=NULL) nodesetendianess=temp->nodesetval; - else pcilib_error("there is no endianess for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_FORMAT_PATH); - if(temp!=NULL) nodesetformat=temp->nodesetval; - else pcilib_error("there is no format for banks in the xml"); - - temp=pcilib_xml_getsetproperty(context,BANK_NAME_PATH); - if(temp!=NULL)nodesetname=temp->nodesetval; - else pcilib_error("there is no name for banks in the xml"); + /** we get the bank nodes using xpath expression*/ + nodesetadress=pcilib_xml_getsetproperty(context,BANKS_PATH)->nodesetval; + if(nodesetadress->nodeNr>0) banks=calloc((nodesetadress->nodeNr),sizeof(pcilib_register_bank_description_t)); + else return; - temp=pcilib_xml_getsetproperty(context,BANK_DESCRIPTION_PATH); - if(temp!=NULL)nodesetdescription=temp->nodesetval; - pci->banks_xml_nodes=calloc(nodesetadress->nodeNr,sizeof(xmlNodePtr)); - if(!(pci->banks_xml_nodes)) pcilib_warning("can't create bank xml nodes for pcilib_t struct"); - - for(i=0;i<nodesetadress->nodeNr;i++){ - /** we then get each node from the structures above*/ - adress=xmlNodeListGetString(docs[p],nodesetadress->nodeTab[i]->xmlChildrenNode, 1); - bar=xmlNodeListGetString(docs[p],nodesetbar->nodeTab[i]->xmlChildrenNode, 1); - size=xmlNodeListGetString(docs[p],nodesetsize->nodeTab[i]->xmlChildrenNode, 1); - protocol=xmlNodeListGetString(docs[p],nodesetprotocol->nodeTab[i]->xmlChildrenNode, 1); - read_addr=xmlNodeListGetString(docs[p],nodesetread_addr->nodeTab[i]->xmlChildrenNode, 1); - write_addr=xmlNodeListGetString(docs[p],nodesetwrite_addr->nodeTab[i]->xmlChildrenNode, 1); - access=xmlNodeListGetString(docs[p],nodesetaccess->nodeTab[i]->xmlChildrenNode, 1); - endianess=xmlNodeListGetString(docs[p],nodesetendianess->nodeTab[i]->xmlChildrenNode, 1); - format=xmlNodeListGetString(docs[p],nodesetformat->nodeTab[i]->xmlChildrenNode, 1); - name=xmlNodeListGetString(docs[p],nodesetname->nodeTab[i]->xmlChildrenNode, 1); - description=xmlNodeListGetString(docs[p],nodesetdescription->nodeTab[i]->xmlChildrenNode, 1); - - mynode=nodesetadress->nodeTab[i]->parent; - - /** the following function will create the given structure for banks*/ - pcilib_xml_create_bank(&mybank,adress,bar,size,protocol,read_addr,write_addr,access,endianess,format, name, description); - banks[i]=mybank; - pci->banks_xml_nodes[i]=mynode; + if(!(pci->banks_xml_nodes)) pcilib_warning("can't create bank xml nodes for pcilib_t struct"); + /** for each of the bank nodes, we create the associated structure*/ + for(i=0;i<nodesetadress->nodeNr;i++){ + mynode=nodesetadress->nodeTab[i]; + pcilib_xml_create_bank(&mybank,mynode,doc); + banks[i]=mybank; + pci->banks_xml_nodes[i]=mynode; } - - pcilib_add_register_banks(pci,number_banks,banks); - p++; - } + /** we push our banks structures in the pcilib environnement*/ + pcilib_add_register_banks(pci,nodesetadress->nodeNr,banks); } /* - * next 3 functions are for the implementation of a merge sort algorithm + * next 2 functions are for the implementation of a merge sort algorithm, because we need a stable algorithm */ -void topdownmerge(pcilib_register_description_t *A, int start, int middle, int end, pcilib_register_description_t *B){ +static void +pcilib_xml_topdownmerge(pcilib_register_description_t *A, int start, int middle, int end, pcilib_register_description_t *B){ int i0,i1,j; i0= start; i1=middle; @@ -463,58 +287,154 @@ void topdownmerge(pcilib_register_description_t *A, int start, int middle, int e } } -void copyarray(pcilib_register_description_t *B, int start,int end, pcilib_register_description_t *A){ - int k; - for (k=start; k<end;k++) A[k]=B[k]; -} - -void topdownsplitmerge(pcilib_register_description_t *A, int start, int end, pcilib_register_description_t *B){ +static void +pcilib_xml_topdownsplitmerge(pcilib_register_description_t *A, int start, int end, pcilib_register_description_t *B){ int middle; if(end-start <2) return; middle =(end+start)/2; - topdownsplitmerge(A,start, middle,B); - topdownsplitmerge(A,middle,end,B); - topdownmerge(A,start,middle,end,B); - copyarray(B,start,end,A); + pcilib_xml_topdownsplitmerge(A,start, middle,B); + pcilib_xml_topdownsplitmerge(A,middle,end,B); + pcilib_xml_topdownmerge(A,start,middle,end,B); + memcpy(&A[start],&B[start],(end-start)*sizeof(pcilib_register_description_t)); } /** pcilib_xml_arrange_registers - * - * after the complete structure containing the registers has been created from the xml, this function rearrange them by address in order to add them in pcilib_open, which consider the adding of registers in order of adress + * after the complete structure containing the registers has been created from the xml, this function rearrange them by address in order to add them in pcilib_open, which don't consider the adding of registers in order of adress * @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){ pcilib_register_description_t* temp; temp=malloc(size*sizeof(pcilib_register_description_t)); - topdownsplitmerge(registers,0,size,temp); + pcilib_xml_topdownsplitmerge(registers,0,size,temp); free(temp); } -/** pcilib_xml_getnumberregisters - * - * get the number of registers in the xml document, for further mallocs - * @param[in] doc the xpath context of the xml file. - * @return the numbers of registers in xml file. +/** pcilib_xml_create_register. + * this function create a register structure from a xml register node. + * @param[out] myregister the register we want to create + * @param[in] type the type of the future register, because this property can't be parsed + * @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 */ -int pcilib_xml_getnumberregisters(xmlXPathContextPtr doc){ - xmlNodeSetPtr nodesetadress=NULL,nodesetsuboffset=NULL; - xmlXPathObjectPtr temp,temp2; - temp=pcilib_xml_getsetproperty(doc,ADRESS_PATH); /**<we get the structure with all standards registers here*/ - if(temp!=NULL) nodesetadress=temp->nodesetval; /**<we get the structure with all standards registers here*/ - else { - pcilib_error("no registers found in the xml file"); - return 0; +void pcilib_xml_create_register(pcilib_register_description_t *myregister,xmlNodePtr mynode, xmlDocPtr doc, xmlChar* type){ + + char* ptr; + xmlNodePtr cur; + xmlChar *value; + xmlChar *bank; + + /**we get the children of the register xml nodes, that contains the properties for it*/ + cur=mynode->children; + + while(cur!=NULL){ + value=xmlNodeListGetString(doc,cur->children,1); + /* we iterate throug each children to get the associated property + note :the use of strtol permits to get as well hexadecimal and decimal values + */ + if(strcmp((char*)cur->name,"adress")==0){ + myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"offset")==0){ + myregister->offset=(pcilib_register_size_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"size")==0){ + myregister->bits=(pcilib_register_size_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"default")==0){ + myregister->defvalue=(pcilib_register_value_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"rwmask")==0){ + if(strcmp((char*)value,"all bits")==0){ + myregister->rwmask=PCILIB_REGISTER_ALL_BITS; + }else if(strcmp((char*)value,"0")==0){ + myregister->rwmask=0; + }else{ + myregister->rwmask=(pcilib_register_value_t)strtol((char*)value,&ptr,0); + } + + }else if(strcmp((char*)cur->name,"mode")==0){ + if(strcmp((char*)value,"R")==0){ + myregister->mode=PCILIB_REGISTER_R; + }else if(strcmp((char*)value,"W")==0){ + myregister->mode=PCILIB_REGISTER_W; + }else if(strcmp((char*)value,"RW")==0){ + myregister->mode=PCILIB_REGISTER_RW; + }else if(strcmp((char*)value,"W")==0){ + myregister->mode=PCILIB_REGISTER_W; + }else if(strcmp((char*)value,"RW1C")==0){ + myregister->mode=PCILIB_REGISTER_RW1C; + }else if(strcmp((char*)value,"W1C")==0){ + myregister->mode=PCILIB_REGISTER_W1C; + } + + }else if(strcmp((char*)cur->name,"name")==0){ + myregister->name=(char*)value; + + }else if(strcmp((char*)cur->name,"value_min")==0){ + /* not implemented yet*/ // myregister->value_min=(pcilib_register_value_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"value_max")==0){ + /* not implemented yet*/ // myregister->value_max=(pcilib_register_value_t)strtol((char*)value,&ptr,0); + + }else if(strcmp((char*)cur->name,"description")==0){ + myregister->description=(char*)value; } + + cur=cur->next; + } - temp2=pcilib_xml_getsetproperty(doc,SUB_OFFSET_PATH);/**< we get the structure with all bits registers here */ - if(temp2!=NULL) nodesetsuboffset=temp2->nodesetval;/**< we get the structure with all bits registers here */ - else nodesetsuboffset->nodeNr=0; - return nodesetadress->nodeNr + nodesetsuboffset->nodeNr; /**<we sum the number of nodes in the first structure to the number of nodes in the second one*/ -} + /** we then get properties that can not be parsed as the previous ones*/ + if(strcmp((char*)type,"standard")==0){ + myregister->type=PCILIB_REGISTER_STANDARD; + bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent))->xmlChildrenNode,1); /**<we get the bank adress node*/ + + }else if(strcmp((char*)type,"bits")==0){ + myregister->type=PCILIB_REGISTER_BITS; + bank=xmlNodeListGetString(doc,xmlFirstElementChild(xmlFirstElementChild(mynode->parent->parent->parent->parent))->xmlChildrenNode,1);/**<we get the bank adress node*/ + + /* we then get the properties from the parent standard regsiter, and that are not present for the bit register*/ + cur=mynode->parent->parent->children; /**<get the parent standard register*/ + while(cur!=NULL){ + value=xmlNodeListGetString(doc,cur->children,1); + if(strcmp((char*)cur->name,"adress")==0){ + myregister->addr=(pcilib_register_addr_t)strtol((char*)value,&ptr,0); + }else if(strcmp((char*)cur->name,"default")==0){ + myregister->defvalue=(pcilib_register_value_t)strtol((char*)value,&ptr,0); + }else if(strcmp((char*)cur->name,"rwmask")==0){ + if(strcmp((char*)value,"all bits")==0){ + myregister->rwmask=PCILIB_REGISTER_ALL_BITS; + }else if(strcmp((char*)value,"0")==0){ + myregister->rwmask=0; + }else{ + myregister->rwmask=(pcilib_register_value_t)strtol((char*)value,&ptr,0); + } + } + cur=cur->next; + } + + }else if(strcmp((char*)type,"fifo")==0){ + /* not implemented yet*/ myregister->type=PCILIB_REGISTER_FIFO; + } + if(strcmp((char*)bank,"bank 0")==0){ + myregister->bank=PCILIB_REGISTER_BANK0; + }else if(strcmp((char*)bank,"bank 1")==0){ + myregister->bank=PCILIB_REGISTER_BANK1; + }else if(strcmp((char*)bank,"bank 2")==0){ + myregister->bank=PCILIB_REGISTER_BANK2; + }else if(strcmp((char*)bank,"bank 3")==0){ + myregister->bank=PCILIB_REGISTER_BANK3; + }else if(strcmp((char*)bank,"DMA bank")==0){ + myregister->bank=PCILIB_REGISTER_BANK_DMA; + }else if (strcmp((char*)bank,"dynamic bank")==0){ + myregister->addr=PCILIB_REGISTER_BANK_DYNAMIC; + }else{ + myregister->bank=PCILIB_REGISTER_BANK_INVALID; + } +} /** pcilib_xml_initialize_registers * @@ -522,508 +442,128 @@ int pcilib_xml_getnumberregisters(xmlXPathContextPtr doc){ * * variables who need change if xml structure change : bank,description, sub_description, sub_adress, sub_bank, sub_rwmask (we consider it to be equal to the standard register), sub_defvalue(same to standard register normally) * @param[in] doc the xpath context of the xml file. - * @param[in,out] registers in: initialized list out: the list of the created registers. + * @param[in] pci the pcilib_t struct running, that will get filled */ -void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr* docs){ +void pcilib_xml_initialize_registers(pcilib_t* pci,xmlDocPtr doc){ - xmlNodeSetPtr nodesetadress=NULL,nodesetoffset=NULL,nodesetdefvalue=NULL,nodesetrwmask=NULL,nodesetsize=NULL,nodesetmode=NULL,nodesetname=NULL; - xmlChar *adress=NULL,*offset=NULL,*defvalue=NULL,*rwmask=NULL,*size=NULL,*mode=NULL,*name=NULL,*bank=NULL,*type=NULL,*description=NULL; + xmlNodeSetPtr nodesetadress=NULL, nodesetsubadress=NULL; + xmlChar *type=NULL; xmlNodePtr mynode; - xmlNodePtr tempnode; xmlXPathContextPtr context; -int number_registers, count=0; + int number_registers; pcilib_register_description_t *registers=NULL; - -while(docs[count]!=NULL){ - context=pcilib_xml_getcontext(docs[count]); - number_registers=pcilib_xml_getnumberregisters(context); - if(number_registers) registers=calloc(number_registers,sizeof(pcilib_register_description_t)); - else return; - - xmlXPathObjectPtr temp; - - /** get the sructures containing each property of standard regsiter */ -/* -----> certainly not necessary if we validate xml each time*/ - - temp=pcilib_xml_getsetproperty(context,ADRESS_PATH); - if(temp!=NULL)nodesetadress=temp->nodesetval; - else pcilib_error("no adress for registers found in xml"); - - temp=pcilib_xml_getsetproperty(context,OFFSET_PATH); - if(temp!=NULL)nodesetoffset=temp->nodesetval; - else pcilib_error("no offset for registers found in xml"); - - temp=pcilib_xml_getsetproperty(context,DEFVALUE_PATH); - if(temp!=NULL)nodesetdefvalue=temp->nodesetval; - else pcilib_error("no defvalue for registers found in xml"); - - temp=pcilib_xml_getsetproperty(context,RWMASK_PATH); - if(temp!=NULL)nodesetrwmask=temp->nodesetval; - else pcilib_error("no rwmask for registers found in xml"); - - temp=pcilib_xml_getsetproperty(context,SIZE_PATH); - if(temp!=NULL)nodesetsize=temp->nodesetval; - else pcilib_error("no size for registers found in xml"); - - temp=pcilib_xml_getsetproperty(context,MODE_PATH); - if(temp!=NULL)nodesetmode=temp->nodesetval; - else pcilib_error("no mode for registers found in xml"); - - temp=pcilib_xml_getsetproperty(context,NAME_PATH); - if(temp!=NULL)nodesetname=temp->nodesetval; - else pcilib_error("no name for registers found in xml"); - - xmlNodeSetPtr nodesetsuboffset=NULL,nodesetsubsize=NULL,nodesetsubmode=NULL,nodesetsubname=NULL; - xmlChar *subadress=NULL,*suboffset=NULL,*subdefvalue=NULL,*subrwmask=NULL,*subsize=NULL,*submode=NULL,*subname=NULL,*subbank=NULL,*subtype=NULL,*subdescription=NULL; - - /**get the structures containing each property of bits registers */ - temp=pcilib_xml_getsetproperty(context,SUB_OFFSET_PATH); - if(temp!=NULL)nodesetsuboffset=temp->nodesetval; - else pcilib_error("no offset for registers bits found in xml"); - - temp=pcilib_xml_getsetproperty(context,SUB_SIZE_PATH); - if(temp!=NULL)nodesetsubsize=temp->nodesetval; - else pcilib_error("no size for registers bits found in xml"); - - temp=pcilib_xml_getsetproperty(context,SUB_MODE_PATH); - if(temp!=NULL)nodesetsubmode=temp->nodesetval; - else pcilib_error("no mode for registers bits found in xml"); - - temp=pcilib_xml_getsetproperty(context,SUB_NAME_PATH); - if(temp!=NULL)nodesetsubname=temp->nodesetval; - else pcilib_error("no name for registers bits found in xml"); - - pcilib_register_description_t myregister; - int i,j; + + context=pcilib_xml_getcontext(doc); + + /** we first get the nodes of standard and bits registers*/ + nodesetadress=pcilib_xml_getsetproperty(context,REGISTERS_PATH)->nodesetval; + nodesetsubadress=pcilib_xml_getsetproperty(context,BITS_REGISTERS_PATH)->nodesetval; + if(nodesetadress->nodeNr>0)registers=calloc(nodesetadress->nodeNr+nodesetsubadress->nodeNr,sizeof(pcilib_register_description_t)); + else return; - pci->registers_xml_nodes=calloc(nodesetadress->nodeNr+nodesetsuboffset->nodeNr,sizeof(xmlNodePtr)); + pci->registers_xml_nodes=calloc(nodesetadress->nodeNr+nodesetsubadress->nodeNr,sizeof(xmlNodePtr)); if(!(pci->registers_xml_nodes)) pcilib_warning("can't create registers xml nodes in pcilib_t struct"); + /** we then iterate through standard registers nodes to create registers structures*/ for(i=0;i<nodesetadress->nodeNr;i++){ - /** get each sub property of each standard registers*/ - adress=xmlNodeListGetString(docs[count],nodesetadress->nodeTab[i]->xmlChildrenNode, 1); - tempnode=xmlFirstElementChild(xmlFirstElementChild(nodesetadress->nodeTab[i]->parent->parent->parent)); - if(strcmp("adress",(char*)tempnode->name)==0) bank=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode,1); - else pcilib_error("the xml file is malformed"); - offset=xmlNodeListGetString(docs[count],nodesetoffset->nodeTab[i]->xmlChildrenNode, 1); - size=xmlNodeListGetString(docs[count],nodesetsize->nodeTab[i]->xmlChildrenNode, 1); - defvalue=xmlNodeListGetString(docs[count],nodesetdefvalue->nodeTab[i]->xmlChildrenNode, 1); - rwmask=xmlNodeListGetString(docs[count],nodesetrwmask->nodeTab[i]->xmlChildrenNode, 1); - mode=xmlNodeListGetString(docs[count],nodesetmode->nodeTab[i]->xmlChildrenNode, 1); - name=xmlNodeListGetString(docs[count],nodesetname->nodeTab[i]->xmlChildrenNode, 1); type=(xmlChar*)"standard"; - if(nodesetname->nodeTab[i]->next->next!= NULL && strcmp((char*)nodesetname->nodeTab[i]->next->next->name,"description")==0){ - description=xmlNodeListGetString(docs[count],nodesetname->nodeTab[i]->next->next->xmlChildrenNode,1); - }else{ - description=(xmlChar*)""; - } - mynode=nodesetadress->nodeTab[i]->parent; - /**creation of a register with the given previous properties*/ - pcilib_xml_create_register(&myregister,adress,offset,size,defvalue,rwmask,mode, type, bank, name, description); + mynode=nodesetadress->nodeTab[i]; + pcilib_xml_create_register(&myregister,mynode,doc,type); registers[i]=myregister; pci->registers_xml_nodes[i]=mynode; } j=i; - - for(i=0;i<nodesetsuboffset->nodeNr;i++){ - /** we get there each subproperty of each bits register*/ - tempnode=xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent); - if(strcmp((char*)tempnode->name,"adress")==0)subadress=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode, 1); - else pcilib_error("xml file is malformed"); - tempnode= xmlFirstElementChild(xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent->parent->parent)); - if(strcmp((char*)tempnode->name,"adress")==0) subbank=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode,1); - else pcilib_error("xml file is malformed"); - suboffset=xmlNodeListGetString(docs[count],nodesetsuboffset->nodeTab[i]->xmlChildrenNode, 1); - subsize=xmlNodeListGetString(docs[count],nodesetsubsize->nodeTab[i]->xmlChildrenNode, 1); - tempnode=xmlFirstElementChild(nodesetsuboffset->nodeTab[i]->parent->parent->parent)->next->next->next->next->next->next; - if(strcmp((char*)tempnode->name,"default")==0)subdefvalue=xmlNodeListGetString(docs[count],tempnode->xmlChildrenNode, 1); - else pcilib_error("xml file is malformed"); - subrwmask=xmlNodeListGetString(docs[count],nodesetsuboffset->nodeTab[i]->parent->parent->prev->prev->prev->prev->prev->prev->xmlChildrenNode, 1); - submode=xmlNodeListGetString(docs[count],nodesetsubmode->nodeTab[i]->xmlChildrenNode, 1); - subname=xmlNodeListGetString(docs[count],nodesetsubname->nodeTab[i]->xmlChildrenNode, 1); - subtype=(xmlChar*)"bits"; - if(nodesetsubname->nodeTab[i]->next->next!= NULL && strcmp((char*)nodesetsubname->nodeTab[i]->next->next->name,"sub_description")==0){ - subdescription=xmlNodeListGetString(docs[count],nodesetsubname->nodeTab[i]->next->next->xmlChildrenNode,1); - }else{ - subdescription=(xmlChar*)""; - } - mynode=nodesetsuboffset->nodeTab[i]->parent; - /** creation of a bits register given the previous properties*/ - pcilib_xml_create_register(&myregister,subadress,suboffset,subsize,subdefvalue,subrwmask,submode, subtype, subbank, subname, subdescription); + /** we then iterate through bits registers nodes to create registers structures*/ + for(i=0;i<nodesetsubadress->nodeNr;i++){ + type=(xmlChar*)"bits"; + mynode=nodesetsubadress->nodeTab[i]; + pcilib_xml_create_register(&myregister,mynode,doc,type); registers[i+j]=myregister; pci->registers_xml_nodes[i+j]=mynode; } - - pcilib_xml_arrange_registers(registers,number_registers); - pcilib_add_registers(pci,number_registers,registers); - count++; - } -} - -#ifdef VIEW_OK -/* pcilib_xml_getnumberformulaviews - * - * function to get the number of views of type formula, for further malloc - */ -int pcilib_xml_getnumberformulaviews(xmlXPathContextPtr doc){ - int j; - xmlNodeSetPtr nodeviewsset=NULL; - nodeviewsset=pcilib_xml_getsetproperty(doc,VIEW_FORMULA_PATH)->nodesetval; - j=nodeviewsset->nodeNr; - return j; + /**we arrange the register for them to be well placed for pci-l*/ + pcilib_xml_arrange_registers(registers,nodesetadress->nodeNr+nodesetsubadress->nodeNr); + /**we fille the pcilib_t struct*/ + pcilib_add_registers(pci,number_registers,registers); } -/* pcilib_xml_getnumberenumviews - * - * function to get the number of views of type enum, for further malloc - */ -int pcilib_xml_getnumberenumviews(xmlXPathContextPtr doc){ - int j; - xmlNodeSetPtr nodeviewsset=NULL; - nodeviewsset=pcilib_xml_getsetproperty(doc,VIEW_ENUM_PATH)->nodesetval; - j=nodeviewsset->nodeNr; - return j; - - -} -/* pcilib_xml_initialize_viewsformula - * - * function to create the structures to store the views of type formula from the xml - * - * values that need to be changed when xml file change: name, formula, +/** pcilib_init_xml + * this function will initialize the registers and banks from the xml files + * @param[in,out] ctx the pciilib_t running that gets filled with structures */ -void pcilib_xml_initialize_viewsformula(xmlDocPtr doc, pcilib_view_formula_ptr_t* myviewsformula){ - xmlNodeSetPtr viewsetformula, viewformula, viewreverseformula, viewunit, viewformulaname, nodesetviewregister,nodesetviewregisterbit,nodesetregister,nodesetsubregister; - xmlChar *formula, *name,*reverseformula,*registername,*bankname,*unit; - int i,j,registernumber,viewnumber,k,l,externregisternumber,enregistrement,u; - - char *substr; - - xmlXPathContextPtr context; - context=pcilib_xml_getcontext(doc); - - viewsetformula=pcilib_xml_getsetproperty(context,VIEW_FORMULA_PATH)->nodesetval; - viewformula=pcilib_xml_getsetproperty(context,VIEW_FORMULA_FORMULA_PATH)->nodesetval; - viewreverseformula=pcilib_xml_getsetproperty(context,VIEW_FORMULA_REVERSE_FORMULA_PATH)->nodesetval; - viewunit=pcilib_xml_getsetproperty(context,VIEW_FORMULA_UNIT_PATH)->nodesetval; - viewformulaname=pcilib_xml_getsetproperty(context,VIEW_FORMULA_NAME_PATH)->nodesetval; - +int pcilib_init_xml(pcilib_t* ctx){ + char *path,*pwd, **line, *line_xsd=NULL; + int i=1,k; + xmlDocPtr* docs; + DIR* rep=NULL; + struct dirent* file=NULL; + int err; -viewnumber=0; - + path=malloc(sizeof(char*)); + line=malloc(sizeof(char*)); + line[0]=NULL; + + /** 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; + } - nodesetviewregisterbit=pcilib_xml_getsetproperty(context,VIEW_BITS_REGISTER)->nodesetval; - nodesetviewregister=pcilib_xml_getsetproperty(context,VIEW_STANDARD_REGISTER)->nodesetval; - nodesetregister=pcilib_xml_getsetproperty(context,NAME_PATH)->nodesetval; - nodesetsubregister=pcilib_xml_getsetproperty(context,SUB_NAME_PATH)->nodesetval; - - myviewsformula->viewsformula=calloc(myviewsformula->size,sizeof(pcilib_view_formula_t)); - for(i=0;i<viewsetformula->nodeNr;i++){ - registernumber=0; - name=xmlNodeListGetString(doc,viewformulaname->nodeTab[i]->xmlChildrenNode,1); - formula=xmlNodeListGetString(doc,viewformula->nodeTab[i]->xmlChildrenNode,1); - reverseformula=xmlNodeListGetString(doc,viewreverseformula->nodeTab[i]->xmlChildrenNode,1); - unit=xmlNodeListGetString(doc,viewunit->nodeTab[i]->xmlChildrenNode,1); - - xmlXPathObjectPtr temp,temp2; - - char* path; - path=malloc(sizeof(char*)); - sprintf(path, VIEW_STANDARD_REGISTER_PLUS,(char*)name); - temp=pcilib_xml_getsetproperty(context,(xmlChar*)path); - if(temp!=NULL) nodesetviewregister= temp->nodesetval; - - char* path2; - path2=malloc(sizeof(char*)); - sprintf(path2, VIEW_BITS_REGISTER_PLUS,(char*)name); - temp2= pcilib_xml_getsetproperty(context,(xmlChar*)path2); - if(temp2!=NULL) nodesetviewregisterbit= temp2->nodesetval; - - j=0; - if(temp!=NULL) j+=nodesetviewregister->nodeNr; - if(temp2!=NULL) j+=nodesetviewregisterbit->nodeNr; - - myviewsformula->viewsformula[viewnumber].depending_registers=calloc((j),sizeof(pcilib_register_for_read_t)); - myviewsformula->viewsformula[viewnumber].number_depending_registers=j; - registernumber=0; - if (temp!=NULL){ - for(j=0; j<nodesetviewregister->nodeNr;j++){ - myviewsformula->viewsformula[viewnumber].depending_registers[registernumber].name=(char*)xmlNodeListGetString(doc,nodesetviewregister->nodeTab[j]->parent->parent->last->prev->prev->prev->xmlChildrenNode,1); - bankname=xmlNodeListGetString(doc,xmlFirstElementChild(nodesetviewregister->nodeTab[j]->parent->parent->parent->parent)->last->prev->prev->prev->xmlChildrenNode,1); - myviewsformula->viewsformula[viewnumber].depending_registers[registernumber].bank_name=(char*)bankname; - registernumber++; - } - } - - if(temp2!=NULL){ - for(j=0; j<nodesetviewregisterbit->nodeNr;j++){ - myviewsformula->viewsformula[viewnumber].depending_registers[registernumber].name=(char*)xmlNodeListGetString(doc,nodesetviewregisterbit->nodeTab[j]->parent->parent->last->prev->prev->prev->xmlChildrenNode,1); - bankname=xmlNodeListGetString(doc,(xmlFirstElementChild(nodesetviewregisterbit->nodeTab[j]->parent->parent->parent->parent->parent->parent))->last->prev->prev->prev->xmlChildrenNode,1); - myviewsformula->viewsformula[viewnumber].depending_registers[registernumber].bank_name=(char*)bankname; - registernumber++; - } - } - - myviewsformula->viewsformula[viewnumber].name=(char*) name; - myviewsformula->viewsformula[viewnumber].formula=(char*) formula; - myviewsformula->viewsformula[viewnumber].reverseformula=(char*) reverseformula; - myviewsformula->viewsformula[viewnumber].unit=(char*) unit; - - /* we then get the extern registers for the formula, which names are directly put in the formula*/ - externregisternumber=0; - k=0; - u=0; - myviewsformula->viewsformula[viewnumber].extern_registers=calloc(1,sizeof(pcilib_register_for_read_t)); - myviewsformula->viewsformula[viewnumber].number_extern_registers=0; - - /* we first get the name of a register put in the formula, by getting indexes of start and end for this name*/ - 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++; - } - enregistrement=1; - substr=str_sub((char*)formula,j+1,k-1); - /* we verify the register is not the depending register*/ - if(strcmp("reg",substr)!=0){ - - /* we then get recursively each standard register and test if it's the extern register or not*/ - for(l=0;l<nodesetregister->nodeNr;l++){ - registername=xmlNodeListGetString(doc,nodesetregister->nodeTab[l]->xmlChildrenNode,1); - if(strcmp((char*)registername,substr)==0){ - bankname=xmlNodeListGetString(doc,(xmlFirstElementChild(nodesetregister->nodeTab[l]->parent->parent->parent))->last->prev->prev->prev->xmlChildrenNode,1); - /*before registering the extern register, as it matches, we tast if the said register was already registered or not*/ - for(u=0;u<externregisternumber;u++){ - if(strcmp(myviewsformula->viewsformula[viewnumber].extern_registers[u].name,(char*)registername)==0){ - enregistrement=0; - } - } - if(enregistrement==1){ - myviewsformula->viewsformula[viewnumber].number_extern_registers++; - myviewsformula->viewsformula[viewnumber].extern_registers=realloc(myviewsformula->viewsformula[viewnumber].extern_registers,myviewsformula->viewsformula[viewnumber].number_extern_registers*sizeof(pcilib_register_for_read_t)); - myviewsformula->viewsformula[viewnumber].extern_registers[externregisternumber].name=(char*)registername; - myviewsformula->viewsformula[viewnumber].extern_registers[externregisternumber].bank_name=(char*)bankname; - enregistrement=0; - externregisternumber++; - } - break; - } - } - if(enregistrement==1){ - /* we get recursively each bits register and test if it's the extern register of the formula or not*/ - for(l=0;l<nodesetsubregister->nodeNr;l++){ - registername=xmlNodeListGetString(doc,nodesetsubregister->nodeTab[l]->xmlChildrenNode, 1); - if(strcmp((char*)registername,substr)==0){ - bankname=xmlNodeListGetString(doc,(xmlFirstElementChild(nodesetsubregister->nodeTab[l]->parent->parent->parent->parent->parent))->last->prev->prev->prev->xmlChildrenNode,1); - /* check to test if the register has already been registered or not*/ - for(u=0;u<externregisternumber;u++){ - if(strcmp(myviewsformula->viewsformula[viewnumber].extern_registers[u].name,(char*)registername)==0){ - enregistrement=0; - break; - } - } - if(enregistrement==1){ - myviewsformula->viewsformula[viewnumber].number_extern_registers++; - myviewsformula->viewsformula[viewnumber].extern_registers=realloc(myviewsformula->viewsformula[viewnumber].extern_registers,myviewsformula->viewsformula[viewnumber].number_extern_registers*sizeof(pcilib_register_for_read_t)); - myviewsformula->viewsformula[viewnumber].extern_registers[externregisternumber].name=(char*)registername; - myviewsformula->viewsformula[viewnumber].extern_registers[externregisternumber].bank_name=(char*)bankname; - externregisternumber++; - enregistrement=0; - } - break; - } - } - } - } - } - } - viewnumber++; - } - - free(path); - free(path2); -} - -/* pcilib_xml_initialize_viewsenum - * - * function to create the structures to store the views of type enum from the xml - * - * values that need to be changed when xml file change: current, -* - */ -void pcilib_xml_initialize_viewsenum(xmlDocPtr doc, pcilib_view_enum_ptr_t* myviewsenum){ - xmlNodeSetPtr viewsetenum,viewsetregister3, viewsetregister4; - xmlChar *name; - int i,k,viewnumber,j,registernumber; - - xmlXPathContextPtr context; - context=pcilib_xml_getcontext(doc); - - xmlXPathObjectPtr temp,temp2; - - xmlNodePtr current; - viewsetenum=pcilib_xml_getsetproperty(context,VIEW_ENUM_PATH)->nodesetval; - xmlAttr *attr2,*attr3; - viewnumber=0; - int enumnumber=0; - - myviewsenum->viewsenum=calloc(myviewsenum->size,sizeof(pcilib_view_enum_t)); - for(i=0;i<viewsetenum->nodeNr;i++){ - enumnumber=0; - k=0; - registernumber=0; - name=xmlNodeListGetString(doc,xmlFirstElementChild(viewsetenum->nodeTab[i])->xmlChildrenNode,1); - myviewsenum->viewsenum[viewnumber].name=(char*)name; - myviewsenum->viewsenum[viewnumber].registerenum=calloc(1,sizeof(char*)); - myviewsenum->viewsenum[viewnumber].number_registerenum=0; - registernumber=0; - - char* path; - path=malloc(sizeof(char*)); - sprintf(path, VIEW_STANDARD_REGISTER_PLUS,(char*)name); - temp=pcilib_xml_getsetproperty(context,(xmlChar*)path); - if(temp!=NULL) viewsetregister3= temp->nodesetval; - - char* path2; - path2=malloc(sizeof(char*)); - sprintf(path2, VIEW_BITS_REGISTER_PLUS,(char*)name); - temp2= pcilib_xml_getsetproperty(context,(xmlChar*)path2); - if(temp2!=NULL) viewsetregister4= temp2->nodesetval; - - j=0; - if(temp!=NULL) j+=viewsetregister3->nodeNr; - if(temp2!=NULL) j+=viewsetregister4->nodeNr; - myviewsenum->viewsenum[viewnumber].registerenum=malloc(j*sizeof(char*)); - myviewsenum->viewsenum[viewnumber].number_registerenum=j; - if(temp!=NULL){ - for(j=0; j<viewsetregister3->nodeNr;j++){ - myviewsenum->viewsenum[viewnumber].registerenum[registernumber]=(char*)xmlNodeListGetString(doc,viewsetregister3->nodeTab[j]->parent->parent->last->prev->prev->prev->xmlChildrenNode,1); - registernumber++; - } - } - if(temp2!=NULL){ - for(j=0; j<viewsetregister4->nodeNr;j++){ - myviewsenum->viewsenum[viewnumber].registerenum[registernumber]=(char*)xmlNodeListGetString(doc,viewsetregister4->nodeTab[j]->parent->parent->last->prev->prev->prev->xmlChildrenNode,1); - registernumber++; - } - } - - - current=xmlFirstElementChild(viewsetenum->nodeTab[i])->next->next->next->next; - while(current!=viewsetenum->nodeTab[i]->last->prev){ - k++; - current=current->next->next; - } - - myviewsenum->viewsenum[viewnumber].myenums=calloc((k+1),sizeof(pcilib_enum_t)); - myviewsenum->viewsenum[viewnumber].number_enums=k+1; - - /* we get here each enum for a said view except the last one*/ - current=xmlFirstElementChild(viewsetenum->nodeTab[i])->next->next; - while(current!=viewsetenum->nodeTab[i]->last->prev->prev->prev){ - attr2 = current->properties; - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].command=(char*)xmlNodeListGetString(doc,current->xmlChildrenNode,1); - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value=(char*)attr2->children->content; - attr2=attr2->next; - /* and we take the properties that are given about range*/ - if(attr2!=NULL){ - if(strcmp((char*)attr2->name,"min")==0){ - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=(char*)attr2->children->content; - attr3=attr2->next; - if(attr3 !=NULL){ - if(strcmp((char*)attr3->name,"max")==0){ - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=(char*)attr3->children->content; - }else pcilib_error("problem in xml file at enum"); - - }else{ - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value; - } - - }else if(strcmp((char*)attr2->name,"max")==0){ - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value; - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=(char*)attr2->children->content; - }else pcilib_error("problem in xml file at enum"); - }else{ - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value; - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value; - } - enumnumber++; - current=current->next->next; - } - /* get the last enum and the given properties */ - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].command=(char*)xmlNodeListGetString(doc,current->xmlChildrenNode,1); - attr2 = current->properties; - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value=(char*)attr2->children->content; - attr2=attr2->next; - if(attr2!=NULL){ - if(strcmp((char*)attr2->name,"min")==0){ - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=(char*)attr2->children->content; - attr3=attr2->next; - if(attr3 !=NULL){ - if(strcmp((char*)attr3->name,"max")==0){ - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=(char*)attr3->children->content; - }else pcilib_error("problem in xml file at enum"); - }else{ - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value; - } - - }else if(strcmp((char*)attr2->name,"max")==0){ - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value; - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=(char*)attr2->children->content; - }else pcilib_error("problem in xml file at enum"); - }else{ - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].min=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value; - myviewsenum->viewsenum[viewnumber].myenums[enumnumber].max=myviewsenum->viewsenum[viewnumber].myenums[enumnumber].value; - } - - viewnumber++; - - } - - free(path); - free(path2); -} -#endif + /** we then open the directory corresponding to the ctx model*/ + pwd=malloc((strlen(path)+strlen(ctx->model))*sizeof(char)); + sprintf(pwd,"%s%s/",path,ctx->model); + if((rep=opendir(pwd))==NULL){ + pcilib_warning("could not open the directory for xml files: error %i\n",errno); + return 1; + } -#ifdef UNIT_OK + /** we iterate through the files of the directory, to get the xml files and the xsd file*/ + while((file=readdir(rep))!=NULL){ + if(strstr(file->d_name,".xml")!=NULL){ + line=realloc(line,i*sizeof(char*)); + line[i-1]=malloc((strlen(file->d_name)+strlen(pwd)+1)*sizeof(char)); + sprintf(line[i-1],"%s%s",pwd,file->d_name); /**< here i wanted to use realpath() function, but it was not working correctly*/ + i++; + } + if(strstr(file->d_name,".xsd")!=NULL){ + line_xsd=malloc((strlen(file->d_name)+strlen(pwd))*sizeof(char)); + sprintf(line_xsd,"%s%s",pwd,file->d_name); + } + } -void pclib_xml_initialize_units(xmlDocPtr doc, pcilib_units_ptr_t* unitsptr){ + if(line_xsd==NULL){ + pcilib_warning("no xsd file found"); + return 1; + } - xmlNodeSetPtr nodesetbaseunit=NULL, nodesettransformunit=NULL; - xmlXPathContextptr context; - context=pcilib_xml_getcontext(doc); - xmlXPathObjectPtr temp; - int i,j; - char *path; + if(line[0]==NULL){ + pcilib_warning("no xml file found"); + return 1; + } + + /** for each xml file, we validate it, and get the registers and the banks*/ + docs=malloc((i-1)*sizeof(xmlDocPtr)); + for(k=0;k<i-1;k++){ + err=validation(line[k],line_xsd); + if(err==0){ + docs[k]=pcilib_xml_getdoc(line[k]); + pcilib_xml_initialize_banks(ctx,docs[k]); + pcilib_xml_initialize_registers(ctx,docs[k]); + } + } + + // free(path); + free(pwd); + free(line); + free(line_xsd); + free(docs); + return 0; +} - temp=pcilib_xml_getsetproperty(context, BASE_UNIT_PATH); - if(temp!=NULL) nodesetbaseunit=temp->nodesetval; - else pcilib_error("the unit xml file is wrong"); - - unitsptr->list_unit=malloc(nodesetbaseunit->nodeNr*sizeof(pcilib_unit_t)); - unitsptr->size=nodesetbaseunit->nodeNr; - - for(i=0; i< nodesetbaseunit->NodeNr; i++){ - unitsptr->list_unit[i].name=nodesetbaseunit->nodeTab[i]->properties->children->content; - path=malloc(sizeof(char*)); - sprintf(path, TRANSFORM_UNIT_PATH, unitsptr->list_unit[i].name); - temp=pcilib_xml_getsetproperty(context, path); - if(temp!=NULL){ - unitsptr->list_unit[i].size_trans_units=temp->nodeNr; - unitsptr->list_unit[i].other_units=malloc(temp->nodeNr*sizeof(pcilib_transform_unit_t)); - for(j=0;j<temp->nodeNr;j++){ - unitsptr->list_unit[i].other_units[j].name=temp->nodeTab[j]->properties->children->content; - unitsptr->list_unit[i].other_units[j].transform_formula=(char*)xmlNodeListGetString(doc,temp->nodeTab[j]->xmlChildrenNode,1); - } - } - } - free(path); -} -#endif diff --git a/pcilib/xml.h b/pcilib/xml.h index 00d2374..1ef8ee5 100644 --- a/pcilib/xml.h +++ b/pcilib/xml.h @@ -12,98 +12,16 @@ #ifndef _XML_ #define _XML_ -//#include <stdlib.h> -//#include <stdio.h> -//#include <string.h> -//#include <assert.h> - -#include <libxml/tree.h> -#include <libxml/parser.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> - #include "pcilib.h" -#include "register.h" -#include "model.h" -#include "bank.h" -#include "pci.h" -//#include <Python.h> #define REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register") /**<all standard registers nodes.*/ - -#define ADRESS_PATH ((xmlChar*)"/model/banks/bank/registers/register/adress") /**<adress path for standard registers.*/ -#define OFFSET_PATH ((xmlChar*)"/model/banks/bank/registers/register/offset") /**<offset path for standard registers.*/ -#define SIZE_PATH ((xmlChar*)"/model/banks/bank/registers/register/size") /**<size path for standard registers.*/ -#define DEFVALUE_PATH ((xmlChar*)"/model/banks/bank/registers/register/default") /**<defvalue path for standard registers.*/ -#define RWMASK_PATH ((xmlChar*)"/model/banks/bank/registers/register/rwmask") /**<rwmask path for standard registers.*/ -#define MODE_PATH ((xmlChar*)"/model/banks/bank/registers/register/mode") /**<mode path for standard registers.*/ -#define NAME_PATH ((xmlChar*)"/model/banks/bank/registers/register/name") /**<name path for standard registers.*/ -#define DESCRIPTION_PATH ((xmlChar*)"/model/banks/bank/registers/register/description") /**<description. not used, is searched recursively as it may not appearing in xml. */ - -#define SUB_OFFSET_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/offset") /**<offset path for bits registers.*/ -#define SUB_SIZE_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/size") /**<size path for bits registers.*/ -#define SUB_RWMASK_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/sub_rwmask") /**<rwmask path for bits registers. not used, as the value is meant to be the same as the standard register this register depends on.*/ -#define SUB_MODE_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/mode") /**<size path for bits registers.*/ -#define SUB_NAME_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/name") /**<name path for bits registers.*/ -#define SUB_DESCRIPTION_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/adress") /**<description path for bits registers. not used, is searched recursively as it may not appear in the xml.*/ - -#define VIEW_FORMULA_PATH ((xmlChar*)"/model/views/view[@type=\"formula\"]") /**< the complete node path for views of type formula.*/ -#define VIEW_FORMULA_FORMULA_PATH ((xmlChar*)"/model/views/view[@type=\"formula\"]/read_from_register") /**< path to formula in direction read_from_register for views of type formula.*/ -#define VIEW_FORMULA_REVERSE_FORMULA_PATH ((xmlChar*)"/model/views/view[@type=\"formula\"]/write_to_register") /**< path to formula in direction write_to_register for views of type formula.*/ -#define VIEW_FORMULA_UNIT_PATH ((xmlChar*)"/model/views/view[@type=\"formula\"]/unit") /**< path to the base unit of the view of type formula. */ -#define VIEW_FORMULA_NAME_PATH ((xmlChar*)"/model/views/view[@type=\"formula\"]/name") /**<path to the name of the view of type formula.*/ - -#define VIEW_ENUM_PATH ((xmlChar*)"/model/views/view[@type=\"enum\"]") /**< the complete node path for views of type enum.*/ - -#define VIEW_BITS_REGISTER ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits/views/view") /**< @warning not used normally.*/ -#define VIEW_STANDARD_REGISTER ((xmlChar*)"/model/banks/bank/registers/register/views/view") /**< @warning not used too.*/ -#define VIEW_STANDARD_REGISTER_PLUS ((char*)"/model/banks/bank/registers/register/views/view[.=\"%s\"]") /**< path to the standard registers that depend on the given view.*/ -#define VIEW_BITS_REGISTER_PLUS ((char*)"/model/banks/bank/registers/register/registers_bits/register_bits/views/view[.=\"%s\"]") /**< path to the bits registers that depend on the given view.*/ - +#define BITS_REGISTERS_PATH ((xmlChar*)"/model/banks/bank/registers/register/registers_bits/register_bits") /**<all bits registers nodes.*/ #define BANKS_PATH ((xmlChar*)"/model/banks/bank/bank_description") /**< path to complete nodes of banks.*/ -#define BANK_ADDR_PATH ((xmlChar*)"/model/banks/bank/bank_description/adress") /**<path to adress of banks.*/ -#define BANK_BAR_PATH ((xmlChar*)"/model/banks/bank/bank_description/bar") /**<path to bar of banks.*/ -#define BANK_SIZE_PATH ((xmlChar*)"/model/banks/bank/bank_description/size") /**<path to size of banks.*/ -#define BANK_PROTOCOL_PATH ((xmlChar*)"/model/banks/bank/bank_description/protocol") /**< path to protocol of banks.*/ -#define BANK_READ_ADDR_PATH ((xmlChar*)"/model/banks/bank/bank_description/read_adress") /**<path to read_addr of banks.*/ -#define BANK_WRITE_ADDR_PATH ((xmlChar*)"/model/banks/bank/bank_description/write_adress") /**<path to write_addr of banks.*/ -#define BANK_RAW_ENDIANESS_PATH ((xmlChar*)"/model/banks/bank/bank_description/raw_endianess") /**<path to raw_endianess of banks.*/ -#define BANK_ACCESS_PATH ((xmlChar*)"/model/banks/bank/bank_description/word_size") /**<path to word_size of banks.*/ -#define BANK_ENDIANESS_PATH ((xmlChar*)"/model/banks/bank/bank_description/endianess") /**<path to endianess of banks.*/ -#define BANK_FORMAT_PATH ((xmlChar*)"/model/banks/bank/bank_description/format") /**<path to format of banks.*/ -#define BANK_NAME_PATH ((xmlChar*)"/model/banks/bank/bank_description/name") /**< path to name of banks.*/ -#define BANK_DESCRIPTION_PATH ((xmlChar*)"/model/banks/bank/bank_description/description") /**<path to description of banks.*/ - - -/** - * this path get the units in the units xml file - */ -#define BASE_UNIT_PATH ((char*)"/units/unit") - -/** - * this path permits to get the possible units one given unit can be converted into in the xml. - */ -#define TRANSFORM_UNIT_PATH ((char*)"/units/unit[@name=\"%s\"]/convert_unit") - -/** - * this function create the list of registers structures, that are manipulated during execution, from the xml file. - * @param[in] doc the xpath context of the xml file. - * @param[out] registers out: the list of the created registers. - */ -void pcilib_xml_initialize_registers(pcilib_t* pci, xmlDocPtr* doc); - -/** - * this functions initialize the structures containing banks, for use in the rest of execution, from the xml file. - * @see pcilib_xml_create_bank(pcilib_register_bank_description_t *mybank,xmlChar* adress, xmlChar *bar, xmlChar *size, xmlChar *protocol,xmlChar *read_addr, xmlChar *write_addr, xmlChar *access, xmlChar *endianess, xmlChar *format, xmlChar *name,xmlChar *description, xmlNodePtr node). - * @param[in] doc the AST of the xml file. - * @param[in,out] mybanks the structure containing the banks. - */ -void pcilib_xml_initialize_banks(pcilib_t* pci,xmlDocPtr* doc); /** - * this function gets the xml files and validates them, before returning pre-AST of them to initialize functions - *@param[out] docs the list of pre-AST of xml files parsed + * this function gets the xml files and validates them, before filling the pcilib_t struct with the registers and banks of those files + *@param[in,out] pci the pcilib_t struct running that gets filled with banks and registers */ -void pcilib_init_xml(xmlDocPtr* docs); +int pcilib_init_xml(pcilib_t* pci); #endif /*_XML_*/ |